* GuiSound stuff rewritten it makes modular

* ogg decoder added (old oggplayer removed)
  * mp3 decoder added (mp3's cane use as backgroundsounds)
  * WAVE decoder added (but only uncompressed WAVE's)
  * AIFF decoder added (only uncrompressed)
  * BNS decoder added
    all soundformats can use as backgroundsounds
    dimoks GameSound class removed it is replaced with the new GuiSound stuff

* Many small fixes and other changes
This commit is contained in:
ardi@ist-einmalig.de 2009-11-09 23:03:13 +00:00
parent bf6b329822
commit a0182d0c4c
51 changed files with 3388 additions and 2955 deletions

View File

@ -35,7 +35,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project # any extra libraries we wish to link with the project
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBS := -lfat -lpngu -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -ltremor -lmxml -ljpeg LIBS := -lfat -lpngu -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -ltremor -lmad -lmxml -ljpeg
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing
# include and lib # include and lib
@ -67,6 +67,7 @@ TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg))) OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg)))
PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm))) PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm)))
MP3FILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.mp3)))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C # use CXX for linking C++ projects, CC for standard C
@ -81,7 +82,7 @@ export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o) \ $(sFILES:.s=.o) $(SFILES:.S=.o) \
$(TTFFILES:.ttf=.ttf.o) $(PNGFILES:.png=.png.o) \ $(TTFFILES:.ttf=.ttf.o) $(PNGFILES:.png=.png.o) \
$(OGGFILES:.ogg=.ogg.o) $(PCMFILES:.pcm=.pcm.o) \ $(OGGFILES:.ogg=.ogg.o) $(PCMFILES:.pcm=.pcm.o) $(MP3FILES:.mp3=.mp3.o) \
$(addsuffix .o,$(ELFFILES)) $(addsuffix .o,$(ELFFILES))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@ -177,6 +178,10 @@ language: $(wildcard $(PROJECTDIR)/Languages/*.lang)
@echo $(notdir $<) @echo $(notdir $<)
$(bin2o) $(bin2o)
%.mp3.o : %.mp3
@echo $(notdir $<)
$(bin2o)
%.certs.o : %.certs %.certs.o : %.certs
@echo $(notdir $<) @echo $(notdir $<)
$(bin2o) $(bin2o)

View File

@ -1,686 +0,0 @@
/***************************************************************************
* Copyright (C) 2009
* by Hibernatus
*
* Game_Sound Class by Dimok
* Many other modifications and adjustments by Dimok for USB Loader GX
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include <stdio.h>
#include <ogcsys.h>
#include <unistd.h>
#include "usbloader/disc.h"
#include "usbloader/wbfs.h"
#include "prompts/PromptWindows.h"
#include "libwbfs/libwbfs.h"
#include "language/gettext.h"
#include "Game_Sound.h"
#define compare(src, str) ((src && str) ? strncasecmp((const char*) src, (const char *) str, strlen((const char *) str)) : -1)
GameSound::GameSound(const u8 * discid)
:GuiSound(NULL, 0, SOUND_PCM)
{
sound = NULL;
length = 0;
type = SOUND_PCM;
voice = 2;
volume = 100;
loop = false;
freq = 0;
format = 0;
this->LoadSound(discid);
}
GameSound::~GameSound()
{
Stop();
if(sound)
free(sound);
sound = NULL;
}
bool GameSound::Play()
{
Stop();
if (!sound || length == 0)
return false;
if (volume == 0)
return true;
return ASND_SetVoice(voice, format, freq, 0, sound, length, volume, volume, 0) == SND_OK;
}
struct IMD5Header
{
u32 fcc;
u32 filesize;
u8 zeroes[8];
u8 crypto[16];
} __attribute__((packed));
struct IMETHeader
{
u8 zeroes[64];
u32 fcc;
u8 unk[8];
u32 iconSize;
u32 bannerSize;
u32 soundSize;
u32 flag1;
u8 names[7][84];
u8 zeroes_2[0x348];
u8 crypto[16];
} __attribute__((packed));
struct U8Header
{
u32 fcc;
u32 rootNodeOffset;
u32 headerSize;
u32 dataOffset;
u8 zeroes[16];
} __attribute__((packed));
struct U8Entry
{
struct
{
u32 fileType : 8;
u32 nameOffset : 24;
};
u32 fileOffset;
union
{
u32 fileLength;
u32 numEntries;
};
} __attribute__((packed));
struct LZ77Info
{
u16 length : 4;
u16 offset : 12;
} __attribute__((packed));
static char *u8Filename(const U8Entry *fst, int i)
{
return (char *)(fst + fst[0].numEntries) + fst[i].nameOffset;
}
struct SWaveHdr
{
u32 fccRIFF;
u32 size;
u32 fccWAVE;
} __attribute__((packed));
struct SWaveFmtChunk
{
u32 fccFMT;
u32 size;
u16 format;
u16 channels;
u32 freq;
u32 avgBps;
u16 alignment;
u16 bps;
} __attribute__((packed));
struct SWaveChunk
{
u32 fcc;
u32 size;
u8 data;
} __attribute__((packed));
struct SAIFFCommChunk
{
u32 fccCOMM;
u32 size;
u16 channels;
u32 samples;
u16 bps;
u8 freq[10];
} __attribute__((packed));
struct SAIFFSSndChunk
{
u32 fccSSND;
u32 size;
u32 offset;
u32 blockSize;
u8 data;
} __attribute__((packed));
inline u32 le32(u32 i)
{
return ((i & 0xFF) << 24) | ((i & 0xFF00) << 8) | ((i & 0xFF0000) >> 8) | ((i & 0xFF000000) >> 24);
}
inline u16 le16(u16 i)
{
return ((i & 0xFF) << 8) | ((i & 0xFF00) >> 8);
}
static u8 * uncompressLZ77(const u8 *inputBuf, u32 inputLength, u32 &size)
{
u8 * buffer = NULL;
if (inputLength <= 0x8 || compare(inputBuf, "LZ77") != 0 || inputBuf[4] != 0x10)
{
return buffer;
}
u32 uncSize = le32(((const u32 *)inputBuf)[1] << 8);
const u8 *inBuf = inputBuf + 8;
const u8 *inBufEnd = inputBuf + inputLength;
buffer = (u8 *) malloc(uncSize);
if (!buffer)
return buffer;
u8 *bufCur = buffer;
u8 *bufEnd = buffer + uncSize;
while (bufCur < bufEnd && inBuf < inBufEnd)
{
u8 flags = *inBuf;
++inBuf;
for (int i = 0; i < 8 && bufCur < bufEnd && inBuf < inBufEnd; ++i)
{
if ((flags & 0x80) != 0)
{
const LZ77Info &info = *(const LZ77Info *)inBuf;
inBuf += sizeof (LZ77Info);
int length = info.length + 3;
if (bufCur - info.offset - 1 < buffer || bufCur + length > bufEnd)
return buffer;
memcpy(bufCur, bufCur - info.offset - 1, length);
bufCur += length;
}
else
{
*bufCur = *inBuf;
++inBuf;
++bufCur;
}
flags <<= 1;
}
}
size = uncSize;
return buffer;
}
void GameSound::LoadSound(const u8 *discid)
{
if(!discid)
return;
if(sound)
free(sound);
sound = NULL;
Disc_SetUSB(NULL);
wbfs_disc_t *disc = wbfs_open_disc(GetHddInfo(), (u8 *) discid);
if(!disc)
{
WindowPrompt(tr("Can't find disc"), 0, tr("OK"));
return;
}
wiidisc_t *wdisc = wd_open_disc((int (*)(void *, u32, u32, void *))wbfs_disc_read, disc);
if(!wdisc)
{
WindowPrompt(tr("Could not open Disc"), 0, tr("OK"));
return;
}
u32 size = 0;
u8 * snddata = wd_extract_file(wdisc, &size, ALL_PARTITIONS, (char *) "opening.bnr");
if(!snddata)
{
WindowPrompt(tr("ERROR"), tr("Failed to extract opening.bnr"), tr("OK"));
return;
}
wd_close_disc(wdisc);
wbfs_close_disc(disc);
const u8 *soundBin;
const u8 *bnrArc;
const U8Entry *fst;
u32 i;
const u8 *soundChunk;
u32 soundChunkSize;
const IMETHeader &imetHdr = *(IMETHeader *) snddata;
if (compare(&imetHdr.fcc, "IMET") != 0)
{
WindowPrompt(tr("IMET Header wrong."), 0, tr("OK"));
return;
}
bnrArc = (const u8 *)(&imetHdr + 1);
const U8Header &bnrArcHdr = *(U8Header *)bnrArc;
fst = (const U8Entry *)(bnrArc + bnrArcHdr.rootNodeOffset);
for (i = 1; i < fst[0].numEntries; ++i)
if (fst[i].fileType == 0 && strcasecmp(u8Filename(fst, i), "sound.bin") == 0)
break;
if (i >= fst[0].numEntries)
{
return;
}
soundBin = bnrArc + fst[i].fileOffset;
if (compare((&((IMD5Header *)soundBin)->fcc), "IMD5") != 0)
{
WindowPrompt(tr("IMD5 Header not right."), 0, tr("OK"));
return;
}
soundChunk = soundBin + sizeof (IMD5Header);
soundChunkSize = fst[i].fileLength - sizeof (IMD5Header);
if (compare(soundChunk, "LZ77") == 0)
{
u32 uncSize = NULL;
u8 * uncompressed_data = uncompressLZ77(soundChunk, soundChunkSize, uncSize);
if (!uncompressed_data)
{
WindowPrompt(tr("Can't decompress LZ77"), 0, tr("OK"));
return;
}
soundChunk = uncompressed_data;
soundChunkSize = uncSize;
}
if(compare(soundChunk, "RIFF") == 0)
{
fromWAV(soundChunk, soundChunkSize);
}
else if(compare(soundChunk, "BNS ") == 0)
{
fromBNS(soundChunk, soundChunkSize);
}
else if(compare(soundChunk, "FORM") == 0)
{
fromAIFF(soundChunk, soundChunkSize);
}
free(snddata);
snddata = NULL;
}
bool GameSound::fromWAV(const u8 *buffer, u32 size)
{
const u8 *bufEnd = buffer + size;
const SWaveHdr &hdr = *(SWaveHdr *)buffer;
if (size < sizeof hdr)
return false;
if (compare(&hdr.fccRIFF, "RIFF") != 0)
return false;
if (size < le32(hdr.size) + sizeof hdr.fccRIFF + sizeof hdr.size)
return false;
if (compare(&hdr.fccWAVE, "WAVE") != 0)
return false;
// Find fmt
const SWaveChunk *chunk = (const SWaveChunk *)(buffer + sizeof hdr);
while (&chunk->data < bufEnd && compare(&chunk->fcc, "fmt ") != 0)
chunk = (const SWaveChunk *)(&chunk->data + le32(chunk->size));
if (&chunk->data >= bufEnd)
return false;
const SWaveFmtChunk &fmtChunk = *(const SWaveFmtChunk *)chunk;
// Check format
if (le16(fmtChunk.format) != 1)
return false;
format = (u8)-1;
if (le16(fmtChunk.channels) == 1 && le16(fmtChunk.bps) == 8 && le16(fmtChunk.alignment) <= 1)
format = VOICE_MONO_8BIT;
else if (le16(fmtChunk.channels) == 1 && le16(fmtChunk.bps) == 16 && le16(fmtChunk.alignment) <= 2)
format = VOICE_MONO_16BIT;
else if (le16(fmtChunk.channels) == 2 && le16(fmtChunk.bps) == 8 && le16(fmtChunk.alignment) <= 2)
format = VOICE_STEREO_8BIT;
else if (le16(fmtChunk.channels) == 2 && le16(fmtChunk.bps) == 16 && le16(fmtChunk.alignment) <= 4)
format = VOICE_STEREO_16BIT;
if (format == (u8)-1)
return false;
freq = le32(fmtChunk.freq);
// Find data
chunk = (const SWaveChunk *)(&chunk->data + le32(chunk->size));
while (&chunk->data < bufEnd && compare(&chunk->fcc, "data") != 0)
chunk = (const SWaveChunk *)(&chunk->data + le32(chunk->size));
if (compare(&chunk->fcc, "data") != 0 || &chunk->data + le32(chunk->size) > bufEnd)
return false;
// Data found
sound = (u8 *) malloc(le32(chunk->size));
if (!sound)
return false;
memcpy(sound, &chunk->data, le32(chunk->size));
length = le32(chunk->size);
// Endianness
if (le16(fmtChunk.bps) == 16)
for (u32 i = 0; i < length / sizeof (u16); ++i)
((u16 *) sound)[i] = le16(((u16 *) sound)[i]);
return true;
}
// ------
// Copyright (C) 1988-1991 Apple Computer, Inc.
#ifndef HUGE_VAL
# define HUGE_VAL HUGE
#endif
# define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
double ConvertFromIeeeExtended(const unsigned char* bytes)
{
double f;
int expon;
unsigned long hiMant, loMant;
expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
| ((unsigned long)(bytes[3] & 0xFF) << 16)
| ((unsigned long)(bytes[4] & 0xFF) << 8)
| ((unsigned long)(bytes[5] & 0xFF));
loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
| ((unsigned long)(bytes[7] & 0xFF) << 16)
| ((unsigned long)(bytes[8] & 0xFF) << 8)
| ((unsigned long)(bytes[9] & 0xFF));
if (expon == 0 && hiMant == 0 && loMant == 0) {
f = 0;
}
else {
if (expon == 0x7FFF) {
f = HUGE_VAL;
}
else {
expon -= 16383;
f = ldexp(UnsignedToFloat(hiMant), expon-=31);
f += ldexp(UnsignedToFloat(loMant), expon-=32);
}
}
if (bytes[0] & 0x80)
return -f;
else
return f;
}
// ------
bool GameSound::fromAIFF(const u8 *buffer, u32 size)
{
const u8 *bufEnd = buffer + size;
const SWaveHdr &hdr = *(SWaveHdr *)buffer;
if (size < sizeof hdr)
return false;
if (compare(&hdr.fccRIFF, "FORM") != 0)
return false;
if (size < hdr.size + sizeof hdr.fccRIFF + sizeof hdr.size)
return false;
if (compare(&hdr.fccWAVE, "AIFF") != 0)
return false;
// Find fmt
const SWaveChunk *chunk = (const SWaveChunk *)(buffer + sizeof hdr);
while (&chunk->data < bufEnd && compare(&chunk->fcc, "COMM") != 0)
chunk = (const SWaveChunk *)(&chunk->data + chunk->size);
if (&chunk->data >= bufEnd)
return false;
const SAIFFCommChunk &fmtChunk = *(const SAIFFCommChunk *)chunk;
// Check format
format = (u8)-1;
if (le16(fmtChunk.channels) == 1 && fmtChunk.bps == 8)
format = VOICE_MONO_8BIT;
else if (fmtChunk.channels == 1 && fmtChunk.bps == 16)
format = VOICE_MONO_16BIT;
else if (fmtChunk.channels == 2 && fmtChunk.bps == 8)
format = VOICE_STEREO_8BIT;
else if (fmtChunk.channels == 2 && fmtChunk.bps == 16)
format = VOICE_STEREO_16BIT;
if (format == (u8)-1)
return false;
freq = (u32)ConvertFromIeeeExtended(fmtChunk.freq);
// Find data
chunk = (const SWaveChunk *)(&chunk->data + chunk->size);
while (&chunk->data < bufEnd && compare(&chunk->fcc, "SSND") != 0)
chunk = (const SWaveChunk *)(&chunk->data + chunk->size);
if (compare(&chunk->fcc, "SSND") != 0 || &chunk->data + chunk->size > bufEnd)
return false;
// Data found
const SAIFFSSndChunk &dataChunk = *(const SAIFFSSndChunk *)chunk;
sound = (u8 *) malloc(dataChunk.size - 8);
if (!sound)
return false;
memcpy(sound, &dataChunk.data, dataChunk.size - 8);
length = dataChunk.size - 8;
return true;
}
struct BNSHeader
{
u32 fccBNS;
u32 magic;
u32 size;
u16 unk1;
u16 unk2;
u32 infoOffset;
u32 infoSize;
u32 dataOffset;
u32 dataSize;
} __attribute__((packed));
struct BNSInfo
{
u32 fccINFO;
u32 size;
u8 codecNum;
u8 loopFlag;
u8 chanCount;
u8 zero;
u16 freq;
u8 pad1[2];
u32 loopStart;
u32 loopEnd;
u32 offsetToChanStarts;
u8 pad2[4];
u32 chan1StartOffset;
u32 chan2StartOffset;
u32 chan1Start;
u32 coeff1Offset;
u8 pad3[4];
u32 chan2Start;
u32 coeff2Offset;
u8 pad4[4];
s16 coefficients1[8][2];
u16 chan1Gain;
u16 chan1PredictiveScale;
s16 chan1PrevSamples[2];
u16 chan1LoopPredictiveScale;
s16 chan1LoopPrevSamples[2];
u16 chan1LoopPadding;
s16 coefficients2[8][2];
u16 chan2Gain;
u16 chan2PredictiveScale;
s16 chan2PrevSamples[2];
u16 chan2LoopPredictiveScale;
s16 chan2LoopPrevSamples[2];
u16 chan2LoopPadding;
} __attribute__((packed));
struct BNSData
{
u32 fccDATA;
u32 size;
u8 data;
} __attribute__((packed));
struct ADPCMByte
{
s8 sample1 : 4;
s8 sample2 : 4;
} __attribute__((packed));
struct BNSADPCMBlock
{
u8 pad : 1;
u8 coeffIndex : 3;
u8 lshift : 4;
ADPCMByte samples[7];
} __attribute__((packed));
struct BNSDecObj
{
s16 prevSamples[2];
s16 coeff[8][2];
};
static void loadBNSInfo(BNSInfo &bnsInfo, const u8 *buffer)
{
const u8 *ptr = buffer + 8;
bnsInfo = *(const BNSInfo *)buffer;
if (bnsInfo.offsetToChanStarts == 0x18 && bnsInfo.chan1StartOffset == 0x20 && bnsInfo.chan2StartOffset == 0x2C
&& bnsInfo.coeff1Offset == 0x38 && bnsInfo.coeff2Offset == 0x68)
return;
bnsInfo.chan1StartOffset = *(const u32 *)(ptr + bnsInfo.offsetToChanStarts);
bnsInfo.chan1Start = *(const u32 *)(ptr + bnsInfo.chan1StartOffset);
bnsInfo.coeff1Offset = *(const u32 *)(ptr + bnsInfo.chan1StartOffset + 4);
if ((u8 *)bnsInfo.coefficients1 != ptr + bnsInfo.coeff1Offset)
memcpy(bnsInfo.coefficients1, ptr + bnsInfo.coeff1Offset, (u8 *)bnsInfo.coefficients2 - (u8 *)&bnsInfo.coefficients1);
if (bnsInfo.chanCount == 2)
{
bnsInfo.chan2StartOffset = *(const u32 *)(ptr + bnsInfo.offsetToChanStarts + 4);
bnsInfo.chan2Start = *(const u32 *)(ptr + bnsInfo.chan2StartOffset);
bnsInfo.coeff2Offset = *(const u32 *)(ptr + bnsInfo.chan2StartOffset + 4);
if ((u8 *)bnsInfo.coefficients2 != ptr + bnsInfo.coeff2Offset)
memcpy(bnsInfo.coefficients2, ptr + bnsInfo.coeff2Offset, (u8 *)bnsInfo.coefficients2 - (u8 *)&bnsInfo.coefficients1);
}
}
static void decodeADPCMBlock(s16 *buffer, const BNSADPCMBlock &block, BNSDecObj &bnsDec)
{
int h1 = bnsDec.prevSamples[0];
int h2 = bnsDec.prevSamples[1];
int c1 = bnsDec.coeff[block.coeffIndex][0];
int c2 = bnsDec.coeff[block.coeffIndex][1];
for (int i = 0; i < 14; ++i)
{
int nibSample = ((i & 1) == 0) ? block.samples[i / 2].sample1 : block.samples[i / 2].sample2;
int sampleDeltaHP = (nibSample << block.lshift) << 11;
int predictedSampleHP = c1 * h1 + c2 * h2;
int sampleHP = predictedSampleHP + sampleDeltaHP;
buffer[i] = std::min(std::max(-32768, (sampleHP + 1024) >> 11), 32767);
h2 = h1;
h1 = buffer[i];
}
bnsDec.prevSamples[0] = h1;
bnsDec.prevSamples[1] = h2;
}
static u8 * decodeBNS(u32 &size, const BNSInfo &bnsInfo, const BNSData &bnsData)
{
static s16 smplBlock[14];
BNSDecObj decObj;
int numBlocks = (bnsData.size - 8) / 8;
int numSamples = numBlocks * 14;
const BNSADPCMBlock *inputBuf = (const BNSADPCMBlock *)&bnsData.data;
u8 * buffer = (u8 *) malloc(numSamples * sizeof (s16));
s16 *outputBuf;
if (!buffer)
return buffer;
memcpy(decObj.coeff, bnsInfo.coefficients1, sizeof decObj.coeff);
memcpy(decObj.prevSamples, bnsInfo.chan1PrevSamples, sizeof decObj.prevSamples);
outputBuf = (s16 *)buffer;
if (bnsInfo.chanCount == 1)
for (int i = 0; i < numBlocks; ++i)
{
decodeADPCMBlock(smplBlock, inputBuf[i], decObj);
memcpy(outputBuf, smplBlock, sizeof smplBlock);
outputBuf += 14;
}
else
{
numBlocks /= 2;
for (int i = 0; i < numBlocks; ++i)
{
decodeADPCMBlock(smplBlock, inputBuf[i], decObj);
for (int j = 0; j < 14; ++j)
outputBuf[j * 2] = smplBlock[j];
outputBuf += 2 * 14;
}
outputBuf = (s16 *)buffer + 1;
memcpy(decObj.coeff, bnsInfo.coefficients2, sizeof decObj.coeff);
memcpy(decObj.prevSamples, bnsInfo.chan2PrevSamples, sizeof decObj.prevSamples);
for (int i = 0; i < numBlocks; ++i)
{
decodeADPCMBlock(smplBlock, inputBuf[numBlocks + i], decObj);
for (int j = 0; j < 14; ++j)
outputBuf[j * 2] = smplBlock[j];
outputBuf += 2 * 14;
}
}
size = numSamples * sizeof (s16);
return buffer;
}
bool GameSound::fromBNS(const u8 *buffer, u32 size)
{
const BNSHeader &hdr = *(BNSHeader *)buffer;
if (size < sizeof hdr)
return false;
if (compare(&hdr.fccBNS, "BNS ") != 0)
return false;
// Find info and data
BNSInfo infoChunk;
loadBNSInfo(infoChunk, buffer + hdr.infoOffset);
const BNSData &dataChunk = *(const BNSData *)(buffer + hdr.dataOffset);
// Check sizes
if (size < hdr.size || size < hdr.infoOffset + hdr.infoSize || size < hdr.dataOffset + hdr.dataSize
|| hdr.infoSize < 0x60 || hdr.dataSize < sizeof dataChunk
|| infoChunk.size != hdr.infoSize || dataChunk.size != hdr.dataSize)
return false;
// Check format
if (infoChunk.codecNum != 0) // Only codec i've found : 0 = ADPCM. Maybe there's also 1 and 2 for PCM 8 or 16 bits ?
return false;
format = (u8)-1;
if (infoChunk.chanCount == 1 && infoChunk.codecNum == 0)
format = VOICE_MONO_16BIT;
else if (infoChunk.chanCount == 2 && infoChunk.codecNum == 0)
format = VOICE_STEREO_16BIT;
if (format == (u8)-1)
return false;
freq = infoChunk.freq;
// Copy data
if (infoChunk.codecNum == 0)
{
sound = decodeBNS(length, infoChunk, dataChunk);
if (!sound)
return false;
}
else
{
sound = (u8*) malloc(dataChunk.size);
if (!sound)
return false;
memcpy(sound, &dataChunk.data, dataChunk.size);
length = dataChunk.size;
}
return true;
}

View File

@ -1,49 +0,0 @@
/***************************************************************************
* Copyright (C) 2009
* by Hibernatus
*
* Game_Sound Class by Dimok
* Many other modifications and adjustments by Dimok for USB Loader GX
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#ifndef _GAMESOUND_H_
#define _GAMESOUND_H_
#include "libwiigui/gui.h"
class GameSound : public GuiSound
{
public:
GameSound(const u8 * discid);
~GameSound();
void LoadSound(const u8 *discid);
bool Play();
bool fromWAV(const u8 *buffer, u32 size);
bool fromAIFF(const u8 *buffer, u32 size);
bool fromBNS(const u8 *buffer, u32 size);
private:
u8 * sound;
u32 length;
u32 freq;
u8 format;
};
#endif

View File

@ -22,11 +22,11 @@
#include "patches/fst.h" #include "patches/fst.h"
#include "usbloader/fstfile.h" #include "usbloader/fstfile.h"
s32 dump_banner(const char * discid,const char * dest) s32 dump_banner(const u8* discid,const char * dest)
{ {
// Mount the disc // Mount the disc
//Disc_SetWBFS(1, (u8*)discid); //Disc_SetWBFS(1, (u8*)discid);
Disc_SetUSB((u8*)discid); Disc_SetUSB(discid);
Disc_Open(); Disc_Open();
@ -108,16 +108,17 @@ s32 dump_banner(const char * discid,const char * dest)
if (ret < 0) if (ret < 0)
return ret; return ret;
WDVD_Reset();
WDVD_ClosePartition();
//fatInitDefault(); //fatInitDefault();
//SDCard_Init(); //SDCard_Init();
WDVD_SetUSBMode(NULL);
FILE *fp = NULL; FILE *fp = fopen(dest, "wb");
fp = fopen(dest, "wb"); if(fp)
{
fwrite(banner, 1, fst[index].filelen, fp); fwrite(banner, 1, fst[index].filelen, fp);
fclose(fp); fclose(fp);
}
free(fstbuffer); free(fstbuffer);
free(banner); free(banner);

View File

@ -13,7 +13,7 @@ extern "C"
{ {
#endif #endif
s32 dump_banner(const char * discid,const char * dest); s32 dump_banner(const u8 *discid,const char * dest);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -24,6 +24,9 @@
#include "MD5.h" #include "MD5.h"
#include "banner.h" #include "banner.h"
#include "openingbnr.h"
#include "../ramdisk/ramdisk.h"
#include "../listfiles.h"
u16 be16(const u8 *p) u16 be16(const u8 *p)
{ {
@ -68,7 +71,6 @@ void md5(u8 *data, u32 len, u8 *hash)
MD5(hash, data, len); MD5(hash, data, len);
} }
static FILE *fp;
typedef struct { typedef struct {
u8 zeroes[0x40]; u8 zeroes[0x40];
@ -113,12 +115,17 @@ typedef struct
u8 zeroes[16]; u8 zeroes[16];
} U8_archive_header; } U8_archive_header;
static void write_file(void* data, size_t size, char* name) static int write_file(void* data, size_t size, char* name)
{ {
size_t written=0;
FILE *out; FILE *out;
out = fopen(name, "wb"); out = fopen(name, "wb");
fwrite(data, 1, size, out); if(out)
{
written = fwrite(data, 1, size, out);
fclose(out); fclose(out);
}
return (written == size) ? 1 : -1;
} }
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size) u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size)
@ -233,7 +240,7 @@ static int write_imd5_lz77(u8* data, size_t size, char* outname)
return 0; return 0;
} }
static int do_U8_archive(void) static int do_U8_archive(FILE *fp)
{ {
U8_archive_header header; U8_archive_header header;
U8_node root_node; U8_node root_node;
@ -325,7 +332,7 @@ static int do_U8_archive(void)
return 0; return 0;
} }
static void do_imet_header(void) static void do_imet_header(FILE *fp)
{ {
imet_data_t header; imet_data_t header;
@ -409,57 +416,114 @@ void do_U8_archivebanner(FILE *fp)
int extractbnrfile(const char * filepath, const char * destpath) int extractbnrfile(const char * filepath, const char * destpath)
{ {
int ret; int ret = -1;
FILE *fp = fopen(filepath, "rb");
fp = fopen(filepath, "rb"); if(fp)
{
mkdir(destpath, 0777); subfoldercreate(destpath);
chdir(destpath); chdir(destpath);
do_imet_header(); do_imet_header(fp);
ret = do_U8_archive(); ret = do_U8_archive(fp);
fclose(fp); fclose(fp);
}
return ret; return ret;
} }
int unpackBin(const char * filename,const char * outdir) int unpackBin(const char * filename,const char * outdir)
{ {
FILE *fp; FILE *fp = fopen(filename,"rb");;
fp = fopen(filename,"rb"); if(fp)
{
subfoldercreate(outdir);
chdir(outdir);
if(fp!=NULL) do_U8_archivebanner(fp);
fclose(fp);
return 1;
}
return 0;
}
#define TMP_PATH(s) "BANNER:/dump"s
//#define TMP_PATH(s) "SD:/dump"s
int unpackBanner(const u8 *gameid, int what, const char *outdir)
{ {
mkdir(outdir, 0777);
chdir(outdir);
do_U8_archivebanner(fp); char path[256];
fclose(fp); if(!ramdiskMount("BANNER", NULL)) return -1;
return 1;
} subfoldercreate(TMP_PATH("/"));
return 0; s32 ret = dump_banner(gameid, TMP_PATH("/opening.bnr"));
} if (ret != 1)
{
int unpackBanner(char * gameid, char * outdir) ret = -1;
{ goto error2;
s32 ret = dump_banner(gameid,"SD:/opening.bnr"); }
if (ret != 1) return -1;
ret = extractbnrfile(TMP_PATH("/opening.bnr"), TMP_PATH("/"));
ret = extractbnrfile("SD:/opening.bnr","SD:/neu"); if (ret != 0)
if (ret != 0) return -1; {
remove("SD:/opening.bnr"); ret = -1;
char iconpath[60]; goto error2;
snprintf(iconpath,sizeof(iconpath),"%s/meta/icon.bin",outdir); }
ret = unpackBin(iconpath,"SD:/icon");
if (ret != 1) return -1; if(what & UNPACK_BANNER_BIN)
{
if (unlink("/neu/meta/banner.bin") == -1) return -1; snprintf(path, sizeof(path),"%sbanner/", outdir);
if (unlink("/neu/meta/icon.bin") == -1) return -1; ret = unpackBin(TMP_PATH("/meta/banner.bin"), path);
if (unlink("/neu/meta/sound.bin") == -1) return -1; if (ret != 1)
if (unlink("/neu/header.imet") == -1) return -1; {
if (unlink("/neu/meta") == -1) return -1; ret = -1;
if (unlink("/neu") == -1) return -1; goto error2;
}
return 1; }
if(what & UNPACK_ICON_BIN)
{
snprintf(path, sizeof(path),"%sicon/", outdir);
ret = unpackBin(TMP_PATH("/meta/icon.bin"), path);
if (ret != 1)
{
ret = -1;
goto error2;
}
}
if(what & UNPACK_SOUND_BIN)
{
snprintf(path, sizeof(path),"%ssound.bin", outdir);
FILE *fp = fopen(TMP_PATH("/meta/sound.bin"), "rb");
if(fp)
{
size_t size;
u8 *data;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
if(!size)
{
ret = -1;
goto error;
}
fseek(fp, 0, SEEK_SET);
data = (u8 *)malloc(size);
if(!data)
{
ret = -1;
goto error;
}
if(fread(data, 1, size, fp) != size)
{
ret = -1;
goto error;
}
ret = write_file(data, size, path);
}
error: fclose(fp);
}
ramdiskUnmount("BANNER");
error2:
if(ret < 0)
return ret;
return 1;
} }

View File

@ -29,8 +29,11 @@ extern "C"
//! Files extracted: banner.bin icon.bin and sound.bin //! Files extracted: banner.bin icon.bin and sound.bin
int extractbnrfile(const char * filepath, const char * destpath); int extractbnrfile(const char * filepath, const char * destpath);
int unpackBin(const char * filename,const char * outdir); int unpackBin(const char * filename,const char * outdir);
//int unpackBanner(const char * filename,const char * outdir); #define UNPACK_BANNER_BIN 1 /* extract banner.bin to outdir/banner/ */
int unpackBanner(const char * gameid, const char * outdir); #define UNPACK_ICON_BIN 2 /* extract icon.bin to outdir/icon/ */
#define UNPACK_SOUND_BIN 4 /* copies sound.bin to outdir/sound.bin */
#define UNPACK_ALL (UNPACK_SOUND_BIN | UNPACK_ICON_BIN | UNPACK_BANNER_BIN)
int unpackBanner(const u8 * gameid, int what, const char *outdir);
//! Extract the lz77 compressed banner, icon and sound .bin //! Extract the lz77 compressed banner, icon and sound .bin
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size); u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size);

209
source/bannersound.cpp Normal file
View File

@ -0,0 +1,209 @@
#include <stdio.h>
#include <ogcsys.h>
#include <unistd.h>
#include <new>
#include "usbloader/disc.h"
#include "usbloader/wbfs.h"
#include "prompts/PromptWindows.h"
#include "libwbfs/libwbfs.h"
#include "language/gettext.h"
#include "bannersound.h"
struct IMD5Header
{
u32 fcc;
u32 filesize;
u8 zeroes[8];
u8 crypto[16];
} __attribute__((packed));
struct IMETHeader
{
u8 zeroes[64];
u32 fcc;
u8 unk[8];
u32 iconSize;
u32 bannerSize;
u32 soundSize;
u32 flag1;
u8 names[7][84];
u8 zeroes_2[0x348];
u8 crypto[16];
} __attribute__((packed));
struct U8Header
{
u32 fcc;
u32 rootNodeOffset;
u32 headerSize;
u32 dataOffset;
u8 zeroes[16];
} __attribute__((packed));
struct U8Entry
{
struct
{
u32 fileType : 8;
u32 nameOffset : 24;
};
u32 fileOffset;
union
{
u32 fileLength;
u32 numEntries;
};
} __attribute__((packed));
struct LZ77Info
{
u16 length : 4;
u16 offset : 12;
} __attribute__((packed));
static char *u8Filename(const U8Entry *fst, int i)
{
return (char *)(fst + fst[0].numEntries) + fst[i].nameOffset;
}
inline u32 le32(u32 i)
{
return ((i & 0xFF) << 24) | ((i & 0xFF00) << 8) | ((i & 0xFF0000) >> 8) | ((i & 0xFF000000) >> 24);
}
inline u16 le16(u16 i)
{
return ((i & 0xFF) << 8) | ((i & 0xFF00) >> 8);
}
static u8 *uncompressLZ77(const u8 *inBuf, u32 inLength, u32 &size)
{
u8 *buffer = NULL;
if (inLength <= 0x8 || *((const u32 *)inBuf) != 0x4C5A3737 /*"LZ77"*/ || inBuf[4] != 0x10)
return NULL;
u32 uncSize = le32(((const u32 *)inBuf)[1] << 8);
const u8 *inBufEnd = inBuf + inLength;
inBuf += 8;
buffer = new(std::nothrow) u8[uncSize];
if (!buffer)
return buffer;
u8 *bufCur = buffer;
u8 *bufEnd = buffer + uncSize;
while (bufCur < bufEnd && inBuf < inBufEnd)
{
u8 flags = *inBuf;
++inBuf;
for (int i = 0; i < 8 && bufCur < bufEnd && inBuf < inBufEnd; ++i)
{
if ((flags & 0x80) != 0)
{
const LZ77Info &info = *(const LZ77Info *)inBuf;
inBuf += sizeof (LZ77Info);
int length = info.length + 3;
if (bufCur - info.offset - 1 < buffer || bufCur + length > bufEnd)
return buffer;
memcpy(bufCur, bufCur - info.offset - 1, length);
bufCur += length;
}
else
{
*bufCur = *inBuf;
++inBuf;
++bufCur;
}
flags <<= 1;
}
}
size = uncSize;
return buffer;
}
const u8 *LoadBannerSound(const u8 *discid, u32 *size)
{
if(!discid)
return NULL;
Disc_SetUSB(NULL);
wbfs_disc_t *disc = wbfs_open_disc(GetHddInfo(), (u8 *) discid);
if(!disc)
{
WindowPrompt(tr("Can't find disc"), 0, tr("OK"));
return NULL;
}
wiidisc_t *wdisc = wd_open_disc((int (*)(void *, u32, u32, void *))wbfs_disc_read, disc);
if(!wdisc)
{
WindowPrompt(tr("Could not open Disc"), 0, tr("OK"));
return NULL;
}
u32 opening_bnr_size = 0;
u8 * opening_bnr = wd_extract_file(wdisc, &opening_bnr_size, ALL_PARTITIONS, (char *) "opening.bnr");
if(!opening_bnr)
{
WindowPrompt(tr("ERROR"), tr("Failed to extract opening.bnr"), tr("OK"));
return NULL;
}
wd_close_disc(wdisc);
wbfs_close_disc(disc);
const U8Entry *fst;
const IMETHeader *imetHdr = (IMETHeader *)opening_bnr;
if ( imetHdr->fcc != 0x494D4554 /*"IMET"*/ )
{
WindowPrompt(tr("IMET Header wrong."), 0, tr("OK"));
free(opening_bnr);
return NULL;
}
const U8Header *bnrArcHdr = (U8Header *)(imetHdr + 1);
fst = (const U8Entry *)( ((const u8 *)bnrArcHdr) + bnrArcHdr->rootNodeOffset);
u32 i;
for (i = 1; i < fst[0].numEntries; ++i)
if (fst[i].fileType == 0 && strcasecmp(u8Filename(fst, i), "sound.bin") == 0)
break;
if (i >= fst[0].numEntries)
{
WindowPrompt(tr("sound.bin not found."), 0, tr("OK"));
free(opening_bnr);
return NULL;
}
const u8 *sound_bin = ((const u8 *)bnrArcHdr) + fst[i].fileOffset;
if ( ((IMD5Header *)sound_bin)->fcc != 0x494D4435 /*"IMD5"*/ )
{
WindowPrompt(tr("IMD5 Header not right."), 0, tr("OK"));
free(opening_bnr);
return NULL;
}
const u8 *soundChunk = sound_bin + sizeof (IMD5Header);;
u32 soundChunkSize = fst[i].fileLength - sizeof (IMD5Header);
if ( *((u32*)soundChunk) == 0x4C5A3737 /*"LZ77"*/ )
{
u32 uncSize = NULL;
u8 * uncompressed_data = uncompressLZ77(soundChunk, soundChunkSize, uncSize);
if (!uncompressed_data)
{
WindowPrompt(tr("Can't decompress LZ77"), 0, tr("OK"));
free(opening_bnr);
return NULL;
}
if(size) *size=uncSize;
free(opening_bnr);
return uncompressed_data;
}
u8 *out = new(std::nothrow) u8[soundChunkSize];
if(out)
{
memcpy(out, soundChunk, soundChunkSize);
if(size) *size=soundChunkSize;
}
free(opening_bnr);
return out;
}

6
source/bannersound.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef BANNERSOUND_H
#define BANNERSOUND_H
const u8 *LoadBannerSound(const u8 *discid, u32 *size);
#endif /* BANNERSOUND_H */

View File

@ -28,7 +28,9 @@ int CheatMenu(const char * gameID) {
bool exit = false; bool exit = false;
int ret = 1; int ret = 1;
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -45,14 +47,14 @@ int CheatMenu(const char * gameID) {
GuiText backBtnTxt(tr("Back") , 22, THEME.prompttext); GuiText backBtnTxt(tr("Back") , 22, THEME.prompttext);
backBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30); backBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
GuiImage backBtnImg(&btnOutline); GuiImage backBtnImg(&btnOutline);
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -140, 400, &trigA, NULL, &btnClick,1); GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -140, 400, &trigA, NULL, btnClick2,1);
backBtn.SetLabel(&backBtnTxt); backBtn.SetLabel(&backBtnTxt);
backBtn.SetTrigger(&trigB); backBtn.SetTrigger(&trigB);
GuiText createBtnTxt(tr("Create") , 22, THEME.prompttext); GuiText createBtnTxt(tr("Create") , 22, THEME.prompttext);
createBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30); createBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
GuiImage createBtnImg(&btnOutline); GuiImage createBtnImg(&btnOutline);
GuiButton createBtn(&createBtnImg,&createBtnImg, 2, 3, 160, 400, &trigA, NULL, &btnClick,1); GuiButton createBtn(&createBtnImg,&createBtnImg, 2, 3, 160, 400, &trigA, NULL, btnClick2,1);
createBtn.SetLabel(&createBtnTxt); createBtn.SetLabel(&createBtnTxt);
char txtfilename[55]; char txtfilename[55];

View File

@ -84,9 +84,11 @@ int MenuHomebrewBrowse() {
int slidedirection = FADE; int slidedirection = FADE;
/*** Sound Variables ***/ /*** Sound Variables ***/
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume); if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
/*** Image Variables ***/ /*** Image Variables ***/
char imgPath[150]; char imgPath[150];
@ -153,7 +155,7 @@ int MenuHomebrewBrowse() {
backBtnTxt.SetWidescreen(CFG.widescreen); backBtnTxt.SetWidescreen(CFG.widescreen);
backBtnImg.SetWidescreen(CFG.widescreen); backBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, &btnClick,1); GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2,1);
backBtn.SetLabel(&backBtnTxt); backBtn.SetLabel(&backBtnTxt);
backBtn.SetTrigger(&trigB); backBtn.SetTrigger(&trigB);
@ -166,7 +168,7 @@ int MenuHomebrewBrowse() {
GoLeftBtn.SetPosition(25, -25); GoLeftBtn.SetPosition(25, -25);
GoLeftBtn.SetImage(&GoLeftImg); GoLeftBtn.SetImage(&GoLeftImg);
GoLeftBtn.SetSoundOver(&btnSoundOver); GoLeftBtn.SetSoundOver(&btnSoundOver);
GoLeftBtn.SetSoundClick(&btnClick); GoLeftBtn.SetSoundClick(btnClick2);
GoLeftBtn.SetEffectGrow(); GoLeftBtn.SetEffectGrow();
GoLeftBtn.SetTrigger(&trigA); GoLeftBtn.SetTrigger(&trigA);
GoLeftBtn.SetTrigger(&trigL); GoLeftBtn.SetTrigger(&trigL);
@ -178,7 +180,7 @@ int MenuHomebrewBrowse() {
GoRightBtn.SetPosition(-25, -25); GoRightBtn.SetPosition(-25, -25);
GoRightBtn.SetImage(&GoRightImg); GoRightBtn.SetImage(&GoRightImg);
GoRightBtn.SetSoundOver(&btnSoundOver); GoRightBtn.SetSoundOver(&btnSoundOver);
GoRightBtn.SetSoundClick(&btnClick); GoRightBtn.SetSoundClick(btnClick2);
GoRightBtn.SetEffectGrow(); GoRightBtn.SetEffectGrow();
GoRightBtn.SetTrigger(&trigA); GoRightBtn.SetTrigger(&trigA);
GoRightBtn.SetTrigger(&trigR); GoRightBtn.SetTrigger(&trigR);
@ -315,7 +317,7 @@ int MenuHomebrewBrowse() {
channelBtn.SetPosition(440, 400); channelBtn.SetPosition(440, 400);
channelBtn.SetImage(&channelBtnImg); channelBtn.SetImage(&channelBtnImg);
channelBtn.SetSoundOver(&btnSoundOver); channelBtn.SetSoundOver(&btnSoundOver);
channelBtn.SetSoundClick(&btnClick); channelBtn.SetSoundClick(btnClick2);
channelBtn.SetEffectGrow(); channelBtn.SetEffectGrow();
channelBtn.SetTrigger(&trigA); channelBtn.SetTrigger(&trigA);
@ -766,16 +768,9 @@ int MenuHomebrewBrowse() {
else if (homo.GetState() == STATE_CLICKED) { else if (homo.GetState() == STATE_CLICKED) {
cfg_save_global(); cfg_save_global();
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) { bgMusic->Resume();
bgMusic->Play();
} else {
bgMusic->PlayOggFile(Settings.ogg_path);
}
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) { if (choice == 3) {
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu

View File

@ -45,7 +45,6 @@
#include "video.h" #include "video.h"
#include "filelist.h" #include "filelist.h"
#include "input.h" #include "input.h"
#include "oggplayer.h"
extern FreeTypeGX *fontSystem; extern FreeTypeGX *fontSystem;
@ -76,12 +75,6 @@ enum
STATE_DISABLED STATE_DISABLED
}; };
enum
{
SOUND_PCM,
SOUND_OGG
};
enum enum
{ {
IMAGE_TEXTURE, IMAGE_TEXTURE,
@ -123,23 +116,39 @@ typedef struct _paddata {
#define EFFECT_ROCK_VERTICLE 1024 #define EFFECT_ROCK_VERTICLE 1024
#define EFFECT_GOROUND 2048 #define EFFECT_GOROUND 2048
#define MAX_SND_VOICES 16
#define newGuiSound
#define verynewGuiSound
//!Sound conversion and playback. A wrapper for other sound libraries - ASND, libmad, ltremor, etc class GuiSoundDecoder;
class GuiSound class GuiSound
{ {
public: public:
//!Constructor //!Constructor
//!\param s Pointer to the sound data //!\param s Pointer to the sound data
//!\param l Length of sound data //!\param l Length of sound data
//!\param t Sound format type (SOUND_PCM or SOUND_OGG) //!\param v Sound volume (0-100)
GuiSound(const u8 * s, int l, int t); //!\param r RAW PCM Sound, when no decoder is found then try to play as raw-pcm
GuiSound(const u8 * s, int l, int t, int v); //!\param a true--> Pointer to the sound data is allocated with new u8[...]
//!\ GuiSound will be destroy the buffer if it no more needed
//!\ false-> sound data buffer has to live just as long as GuiSound
GuiSound(const u8 *s, int l, int v=100, bool r=true, bool a=false);
//!Constructor
//!\param p Path to the sound data
//!\param v Sound volume (0-100)
GuiSound(const char *p, int v=100);
//!Load - stop playing and load the new sound data
//! if load not failed replace the current with new sound data
//! otherwise the current date will not changed
//!\params same as by Constructors
//!\return true ok / false = failed
bool Load(const u8 *s, int l, bool r=false, bool a=false);
bool Load(const char *p);
//!Destructor //!Destructor
~GuiSound(); ~GuiSound();
//!Start sound playback //!Start sound playback
void Play(); void Play();
//!Start sound playback from ogg file
int PlayOggFile(char * path);
//!Stop sound playback //!Stop sound playback
void Stop(); void Stop();
//!Pause sound playback //!Pause sound playback
@ -156,17 +165,21 @@ class GuiSound
//!\param l Loop (true to loop) //!\param l Loop (true to loop)
void SetLoop(bool l); void SetLoop(bool l);
//!Get the playing time in ms for that moment (only applies to OGG) //!Get the playing time in ms for that moment (only applies to OGG)
s32 GetPlayTime();
//!Set the starting point or playtime for skipping (only applies to OGG)
//!\param time in ms
void SetPlayTime(s32 time);
protected: protected:
const u8 * sound; //!< Pointer to the sound data s32 voice; // used asnd-voice
int type; //!< Sound format type (SOUND_PCM or SOUND_OGG) u8 *play_buffer[3]; // trpple-playbuffer
s32 length; //!< Length of sound data int buffer_nr; // current playbuffer
s32 voice; //!< Currently assigned ASND voice channel int buffer_pos; // current idx to write in buffer
s32 volume; //!< Sound volume (0-100) bool buffer_ready; // buffer is filled and ready
bool loop; //!< Loop sound playback bool buffer_eof; // no mor datas - will stop playing
bool loop; // play looped
s32 volume; // volume
GuiSoundDecoder *decoder;
void DecoderCallback();
void PlayerCallback();
friend void *GuiSoundDecoderThread(void *args);
friend void GuiSoundPlayerCallback(s32 Voice);
}; };
//!Menu input trigger management. Determine if action is neccessary based on input data by comparing controller input data to a specific trigger element. //!Menu input trigger management. Determine if action is neccessary based on input data by comparing controller input data to a specific trigger element.

View File

@ -157,7 +157,7 @@ GuiCustomOptionBrowser::GuiCustomOptionBrowser(int w, int h, customOptionList *
trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
trigHeldA = new GuiTrigger; trigHeldA = new GuiTrigger;
trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A); trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A);
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume); btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
snprintf(imgPath, sizeof(imgPath), "%s%s", themePath, custombg); snprintf(imgPath, sizeof(imgPath), "%s%s", themePath, custombg);
bgOptions = new GuiImageData(imgPath, imagebg); bgOptions = new GuiImageData(imgPath, imagebg);

View File

@ -770,3 +770,82 @@ SimpleLock::~SimpleLock()
{ {
element->Unlock(); element->Unlock();
} }
#if 0
GuiElement
protected:
void Lock();
void Unlock();
friend class SimpleLock;
private:
// static mutex_t mutex;
static mutex_t _lock_mutex;
lwp_t _lock_thread;
u16 _lock_count;
lwpq_t _lock_queue;
u16 _lock_queue_count;
void GuiElement::Lock()
{
LWP_MutexLock(_lock_mutex);
if(_lock_thread = LWP_GetSelf()) // i am self
{
_lock_count++; // inc count of locks;
LWP_MutexUnlock(_lock_mutex);
return;
}
if(_lock_thread == THREAD_NULL) // element is not locked
{
_lock_thread = LWP_GetSelf();
_lock_count = 1;
LWP_MutexUnlock(_lock_mutex);
return;
}
// element is locked
if(_lock_queue == LWP_TQUEUE_NULL) // no queue
{
LWP_InitQueue(&_lock_queue); // init queue
_lock_queue_count = 0; // clear count of threads in queue;
}
_lock_queue_count++; // inc count of threads in queue;
LWP_MutexUnlock(_lock_mutex); // unlock
LWP_ThreadSleep(_lock_queue); // and sleep
LWP_MutexLock(_lock_mutex); // waked up , will lock
if(--_lock_queue_count == 0) // dec count of threads in queue;
{
// is the last thread in queue
LWP_CloseQueue(_lock_queue); // close the queue
_lock_queue = LWP_TQUEUE_NULL;
lock(); // try lock again;
}
LWP_MutexUnlock(_lock_mutex)
return;
}
void GuiElement::Unlock()
{
LWP_MutexLock(_lock_mutex);
// only the thread was locked this element, can call unlock
if(_lock_thread == LWP_GetSelf()) // but we check it here safe is safe
{
if(--_lock_queue_count == 0) // dec count of locks;
{
_lock_thread = THREAD_NULL; // is the last thread in queue
if(_lock_queue != LWP_TQUEUE_NULL) // has a queue
LWP_ThreadSignal(_lock_queue); // wake the next thread in queue
}
}
LWP_MutexUnlock(_lock_mutex)
}
#endif

View File

@ -10,7 +10,7 @@
#include "gui.h" #include "gui.h"
#include "prompts/filebrowser.h" #include "prompts/filebrowser.h"
#include "../settings/cfg.h" #include "settings/cfg.h"
/** /**
* Constructor for the GuiFileBrowser class. * Constructor for the GuiFileBrowser class.
@ -31,8 +31,8 @@ GuiFileBrowser::GuiFileBrowser(int w, int h)
trigHeldA = new GuiTrigger; trigHeldA = new GuiTrigger;
trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM); btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM); btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbg_browser.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbg_browser.png", CFG.theme_path);

View File

@ -40,7 +40,7 @@ GuiGameBrowser::GuiGameBrowser(int w, int h, struct discHdr * l, int gameCnt, co
trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
trigHeldA = new GuiTrigger; trigHeldA = new GuiTrigger;
trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A); trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A);
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume); btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
snprintf(imgPath, sizeof(imgPath), "%sbg_options.png", themePath); snprintf(imgPath, sizeof(imgPath), "%sbg_options.png", themePath);
bgGames = new GuiImageData(imgPath, imagebg); bgGames = new GuiImageData(imgPath, imagebg);

View File

@ -69,8 +69,8 @@ noCover(nocover_png)
trigMinus = new GuiTrigger; trigMinus = new GuiTrigger;
trigMinus->SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0); trigMinus->SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0);
btnSoundClick = new GuiSound(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); btnSoundClick = new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
snprintf(imgPath, sizeof(imgPath), "%sstartgame_arrow_left.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sstartgame_arrow_left.png", CFG.theme_path);
imgLeft = new GuiImageData(imgPath, startgame_arrow_left_png); imgLeft = new GuiImageData(imgPath, startgame_arrow_left_png);

View File

@ -317,8 +317,8 @@ noCover(nocoverFlat_png)
trigMinus = new GuiTrigger; trigMinus = new GuiTrigger;
trigMinus->SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0); trigMinus->SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0);
btnSoundClick = new GuiSound(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); btnSoundClick = new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
int btnHeight = (int) lround(sqrt(RADIUS*RADIUS - 90000)-RADIUS-50); int btnHeight = (int) lround(sqrt(RADIUS*RADIUS - 90000)-RADIUS-50);

View File

@ -343,8 +343,8 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max, int min, int lang)
keyLarge = new GuiImageData(keyboard_largekey_over_png); keyLarge = new GuiImageData(keyboard_largekey_over_png);
keyLargeOver = new GuiImageData(keyboard_largekey_over_png); keyLargeOver = new GuiImageData(keyboard_largekey_over_png);
keySoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); keySoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
keySoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume); keySoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
trigA = new GuiTrigger; trigA = new GuiTrigger;
trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
trigB = new GuiTrigger; trigB = new GuiTrigger;

View File

@ -10,6 +10,7 @@
#include "gui.h" #include "gui.h"
#include "../wpad.h" #include "../wpad.h"
#include "Settings/cfg.h"
#include <unistd.h> #include <unistd.h>
@ -37,7 +38,7 @@ GuiOptionBrowser::GuiOptionBrowser(int w, int h, OptionList * l, const u8 *image
trigHeldA = new GuiTrigger; trigHeldA = new GuiTrigger;
trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A); trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A);
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM); btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
bgOptions = new GuiImageData(imagebg); bgOptions = new GuiImageData(imagebg);
bgOptionsImg = new GuiImage(bgOptions); bgOptionsImg = new GuiImage(bgOptions);
@ -149,7 +150,7 @@ GuiOptionBrowser::GuiOptionBrowser(int w, int h, OptionList * l, const char *the
trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
trigHeldA = new GuiTrigger; trigHeldA = new GuiTrigger;
trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A); trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A);
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM); btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
snprintf(imgPath, sizeof(imgPath), "%sbg_options.png", themePath); snprintf(imgPath, sizeof(imgPath), "%sbg_options.png", themePath);
bgOptions = new GuiImageData(imgPath, imagebg); bgOptions = new GuiImageData(imgPath, imagebg);

View File

@ -39,8 +39,8 @@ text(NULL, 22, (GXColor) {0, 0, 0, 255}),
buttons(0), buttons(0),
keyImageData(keyboard_key_png), keyImageData(keyboard_key_png),
keyOverImageData(keyboard_key_over_png), keyOverImageData(keyboard_key_over_png),
sndOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume), sndOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume),
sndClick(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume) sndClick(button_click_pcm, button_click_pcm_size, Settings.sfxvolume)
{ {
char imgPath[100]; char imgPath[100];
trig.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trig.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);

View File

@ -5,32 +5,277 @@
* *
* gui_sound.cpp * gui_sound.cpp
* *
* decoder modification by ardi 2009
*
* GUI class definitions * GUI class definitions
***************************************************************************/ ***************************************************************************/
#include "gui.h" #include "gui.h"
#include <unistd.h>
#include "gecko.h"
#include "gui_sound_decoder.h"
#define BUFFER_SIZE 8192
/***************************************************************
*
* D E C O D E R L I S T
*
*
***************************************************************/
GuiSoundDecoder::DecoderListEntry *GuiSoundDecoder::DecoderList = NULL;
GuiSoundDecoder::DecoderListEntry &GuiSoundDecoder::RegisterDecoder(DecoderListEntry &Decoder, GuiSoundDecoderCreate fnc)
{
if(Decoder.fnc != fnc)
{
Decoder.fnc = fnc;
Decoder.next = DecoderList;
DecoderList = &Decoder;
}
return Decoder;
}
GuiSoundDecoder *GuiSoundDecoder::GetDecoder(const u8 * snd, u32 len, bool snd_is_allocated)
{
for(DecoderListEntry *de = DecoderList; de; de=de->next)
{
GuiSoundDecoder *d = NULL;
try{ d = de->fnc(snd, len, snd_is_allocated); }
catch(const char *error){
gprintf("%s", error); }
catch(...){}
if(d) return d;
}
return NULL;
}
/***************************************************************
*
* D E C O D E R T H R E A D
*
*
***************************************************************/
static GuiSound *GuiSoundPlayer[16] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
static lwp_t GuiSoundDecoderThreadHandle = LWP_THREAD_NULL;
static bool GuiSoundDecoderThreadRunning = false;
static bool GuiSoundDecoderDataRquested = false;
void *GuiSoundDecoderThread(void *args)
{
GuiSoundDecoderThreadRunning = true;
do
{
if(GuiSoundDecoderDataRquested)
{
GuiSoundDecoderDataRquested = false;
GuiSound **players = GuiSoundPlayer;
for( int i = 0; i < 16; ++i , ++players)
{
GuiSound *player = *players;
if(player)
player->DecoderCallback();
}
}
if(!GuiSoundDecoderDataRquested)
usleep(50);
} while(GuiSoundDecoderThreadRunning);
return 0;
}
/***************************************************************
*
* A S N D C A L L B A C K
*
*
***************************************************************/
void GuiSoundPlayerCallback(s32 Voice)
{
if(Voice >= 0 && Voice < 16 && GuiSoundPlayer[Voice])
{
GuiSoundPlayer[Voice]->PlayerCallback();
GuiSoundDecoderDataRquested = true;
}
}
/***************************************************************
*
* R A W - D E C O D E R
* Decoder for Raw-PCM-Datas (16bit Stereo 48kHz)
*
***************************************************************/
class GuiSoundDecoderRAW : public GuiSoundDecoder
{
protected:
GuiSoundDecoderRAW(const u8 * snd, u32 len, bool snd_is_allocated)
{
pcm_start = snd;
is_allocated = snd_is_allocated;
pcm_end = pcm_start+len;
pos = pcm_start;
is_running = false;
}
public:
~GuiSoundDecoderRAW()
{
while(is_running) usleep(50);
if(is_allocated) delete [] pcm_start;
}
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
{
try { return new GuiSoundDecoderRAW(snd, len, snd_is_allocated); }
catch(...) {}
return NULL;
}
s32 GetFormat()
{
return VOICE_STEREO_16BIT;
}
s32 GetSampleRate()
{
return 48000;
}
/* Read reads data from stream to buffer
return: >0 = readed bytes;
0 = EOF;
<0 = Error;
*/
int Read(u8 * buffer, int buffer_size)
{
if(pos >= pcm_end)
return 0; // EOF
is_running = true;
if(pos + buffer_size > pcm_end)
buffer_size = pcm_end-pos;
memcpy(buffer, pos, buffer_size);
pos += buffer_size;
is_running = false;
return buffer_size;
}
int Rewind()
{
pos = pcm_start;
return 0;
}
private:
const u8 *pcm_start;
const u8 *pcm_end;
bool is_allocated;
const u8 *pos;
bool is_running;
};
/***************************************************************
*
* G u i S o u n d
*
*
***************************************************************/
#define GuiSoundBufferReady 0x01
#define GuiSoundBufferEOF 0x02
#define GuiSoundFinish 0x04
static int GuiSoundCount = 0;
/** /**
* Constructor for the GuiSound class. * Constructor for the GuiSound class.
*/ */
GuiSound::GuiSound(const u8 * snd, s32 len, int t) GuiSound::GuiSound(const u8 *s, int l, int v/*=100*/, bool r/*=true*/, bool a/*=false*/)
{ {
sound = snd; if(GuiSoundCount++ == 0 || GuiSoundDecoderThreadHandle == LWP_THREAD_NULL)
length = len; {
type = t; LWP_CreateThread(&GuiSoundDecoderThreadHandle,GuiSoundDecoderThread,NULL,NULL,32*1024,80);
}
voice = -1; voice = -1;
volume = 100; play_buffer[0] = (u8*)memalign(32, BUFFER_SIZE*3); // tripple-buffer first is played
loop = false; play_buffer[1] = play_buffer[0] + BUFFER_SIZE; // second is waiting
play_buffer[2] = play_buffer[1] + BUFFER_SIZE; // third is decoding
buffer_nr = 0; // current playbuffer
buffer_pos = 0; // current idx to write in buffer
buffer_ready = false;
buffer_eof = false;
loop = false; // play looped
volume = v; // volume
decoder = NULL;
if(play_buffer[0]) // playbuffer ok
Load(s, l, r, a);
} }
bool GuiSound::Load(const u8 *s, int l, bool r/*=false*/, bool a/*=false*/)
GuiSound::GuiSound(const u8 * snd, s32 len, int t, int v)
{ {
sound = snd; Stop();
length = len; if(!play_buffer[0]) return false;
type = t; GuiSoundDecoder *newDecoder = GuiSoundDecoder::GetDecoder(s, l, a);
if(!newDecoder && r) newDecoder = GuiSoundDecoderRAW::Create(s, l, a);
if(newDecoder)
{
delete decoder;
decoder = newDecoder;
return true;
}
else if(a)
delete [] s;
return false;
}
GuiSound::GuiSound(const char *p, int v/*=100*/)
{
if(GuiSoundCount++ == 0 || GuiSoundDecoderThreadHandle == LWP_THREAD_NULL)
{
LWP_CreateThread(&GuiSoundDecoderThreadHandle,GuiSoundDecoderThread,NULL,NULL,32*1024,80);
}
voice = -1; voice = -1;
volume = v; play_buffer[0] = (u8*)memalign(32, BUFFER_SIZE*3); // tripple-buffer first is played
loop = false; play_buffer[1] = play_buffer[0] + BUFFER_SIZE; // second is waiting
play_buffer[2] = play_buffer[1] + BUFFER_SIZE; // third is decoding
buffer_nr = 0; // current playbuffer
buffer_pos = 0; // current idx to write in buffer
buffer_ready = false;
buffer_eof = false;
loop = false; // play looped
volume = v; // volume
decoder = NULL;
if(play_buffer[0]) // playbuffer ok
Load(p);
}
bool GuiSound::Load(const char *p)
{
Stop(); // stop playing
if(!play_buffer[0]) return false;
bool ret = false;
voice = -2; // -2 marks loading from file
u32 filesize = 0;
u8 *buffer = NULL;
size_t result;
FILE * pFile = fopen (p, "rb");
if(pFile)
{
// get file size:
fseek (pFile , 0 , SEEK_END);
filesize = ftell (pFile);
fseek (pFile , 0 , SEEK_SET);
// allocate memory to contain the whole file:
buffer = new(std::nothrow) u8[filesize];
if (buffer)
{
// copy the file into the buffer:
result = fread (buffer, 1, filesize, pFile);
if (result == filesize)
ret= Load(buffer, filesize, false, true);
else
delete [] buffer;
}
fclose (pFile);
}
return ret;
} }
/** /**
@ -38,145 +283,89 @@ GuiSound::GuiSound(const u8 * snd, s32 len, int t, int v)
*/ */
GuiSound::~GuiSound() GuiSound::~GuiSound()
{ {
if(type == SOUND_OGG) if(!loop) while(voice >= 0) usleep(50);
StopOgg(); Stop();
} if(--GuiSoundCount == 0 && GuiSoundDecoderThreadHandle != LWP_THREAD_NULL)
{
int GuiSound::PlayOggFile(char * path) GuiSoundDecoderThreadRunning = false;
{ /* LWP_JoinThread(GuiSoundDecoderThreadHandle,NULL);
u32 filesize = 0; GuiSoundDecoderThreadHandle = LWP_THREAD_NULL;
char * bufferogg = NULL; }
size_t resultogg; delete decoder;
free(play_buffer[0]);
FILE * pFile;
pFile = fopen (path, "rb");
// get file size:
fseek (pFile , 0 , SEEK_END);
filesize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
bufferogg = (char*) malloc (sizeof(char)*filesize);
if (bufferogg == NULL) {fputs (" Memory error",stderr); exit (2);}
// copy the file into the buffer:
resultogg = fread (bufferogg,1,filesize,pFile);
if (resultogg != filesize) {fputs (" Reading error",stderr); exit (3);}
fclose (pFile);
sound = (const u8 *) bufferogg;
length = filesize;
*/
int ret = PlayOggFromFile(path, loop);
SetVolumeOgg(255*(volume/100.0));
return ret;
} }
void GuiSound::Play() void GuiSound::Play()
{ {
int vol; Stop(); // stop playing if it played
if(!play_buffer[0]) return;
switch(type) if(!decoder) return; // no decoder or no play_buffer -> no playing
{ // initialize the buffer
case SOUND_PCM: buffer_nr = 0; // allways starts with buffer 0
vol = 255*(volume/100.0); buffer_pos = 0; // reset position
buffer_ready = false;
buffer_eof = false;
decoder->Rewind(); // play from begin
DecoderCallback(); // fill first buffer;
if(!buffer_ready || buffer_eof) // if first buffer not ready -> no play
return;
voice = ASND_GetFirstUnusedVoice(); voice = ASND_GetFirstUnusedVoice();
if(voice >= 0) if(voice >= 0)
ASND_SetVoice(voice, VOICE_STEREO_16BIT, 48000, 0, {
(u8 *)sound, length, vol, vol, NULL); s32 vol = (255*volume)/100;
break; s32 format = decoder->GetFormat();
s32 samplerate = decoder->GetSampleRate();
case SOUND_OGG: s32 first_pos = buffer_pos;
voice = 0; // switch to next buffer
if(loop) buffer_nr = 1;
PlayOgg(mem_open((char *)sound, length), 0, OGG_INFINITE_TIME); buffer_pos = 0;
else buffer_ready = false;
PlayOgg(mem_open((char *)sound, length), 0, OGG_ONE_TIME); buffer_eof = false;
SetVolumeOgg(255*(volume/100.0)); DecoderCallback(); // fill second buffer;
break; GuiSoundPlayer[voice] = this; // activate Callbacks for this voice
// Play the voice
ASND_SetVoice(voice, format, samplerate, 0, play_buffer[0], first_pos, vol, vol, GuiSoundPlayerCallback);
} }
} }
/*
int GuiSound::PlayOggFile(char * path)
{
if(Load(path))
Play();
return 1;
}
*/
void GuiSound::Stop() void GuiSound::Stop()
{ {
if(voice < 0) if(voice < 0) return ;
return; GuiSoundPlayer[voice] = NULL; // disable Callbacks
SND_StopVoice(voice);
switch(type) voice = -1;
{
case SOUND_PCM:
ASND_StopVoice(voice);
break;
case SOUND_OGG:
StopOgg();
break;
}
} }
void GuiSound::Pause() void GuiSound::Pause()
{ {
if(voice < 0) if(voice < 0) return ;
return;
switch(type)
{
case SOUND_PCM:
ASND_PauseVoice(voice, 1); ASND_PauseVoice(voice, 1);
break;
case SOUND_OGG:
PauseOgg(1);
break;
}
} }
void GuiSound::Resume() void GuiSound::Resume()
{ {
if(voice < 0) if(voice < 0) return ;
return;
switch(type)
{
case SOUND_PCM:
ASND_PauseVoice(voice, 0); ASND_PauseVoice(voice, 0);
break;
case SOUND_OGG:
PauseOgg(0);
break;
}
} }
bool GuiSound::IsPlaying() bool GuiSound::IsPlaying()
{ {
if(ASND_StatusVoice(voice) == SND_WORKING || ASND_StatusVoice(voice) == SND_WAITING) return voice >= 0;
return true;
else
return false;
} }
void GuiSound::SetVolume(int vol) void GuiSound::SetVolume(int vol)
{ {
volume = vol; volume = vol;
if(voice < 0) return ;
if(voice < 0)
return;
int newvol = 255*(volume/100.0); int newvol = 255*(volume/100.0);
switch(type)
{
case SOUND_PCM:
ASND_ChangeVolumeVoice(voice, newvol, newvol); ASND_ChangeVolumeVoice(voice, newvol, newvol);
break;
case SOUND_OGG:
SetVolumeOgg(255*(volume/100.0));
break;
}
} }
void GuiSound::SetLoop(bool l) void GuiSound::SetLoop(bool l)
@ -184,12 +373,68 @@ void GuiSound::SetLoop(bool l)
loop = l; loop = l;
} }
s32 GuiSound::GetPlayTime() void GuiSound::DecoderCallback()
{ {
return GetTimeOgg(); if(buffer_ready || buffer_eof) // if buffer ready or EOF -> nothing
return;
bool error=false;
while(buffer_pos < BUFFER_SIZE)
{
int ret = decoder->Read(&play_buffer[buffer_nr][buffer_pos], BUFFER_SIZE-buffer_pos);
if(ret > 0)
buffer_pos += ret; // ok -> fill the buffer more
else if(ret == 0) // EOF from decoder
{
if(loop)
decoder->Rewind(); // if loop -> rewind and fill the buffer more
else if(buffer_pos)
break; // has data in buffer -> play the buffer
else
buffer_eof = true; // no data in buffer -> return EOF
return;
}
else if(ret < 0) // an ERROR
{
if(buffer_pos)
break; // has data in buffer -> play the buffer
else if(loop)
{
if(!error) // if no prev error
{
decoder->Rewind(); // if loop -> rewind
error = true; // set error-state
continue; // and fill the buffer more
}
buffer_eof = true; // has prev error -> error in first block -> return EOF
return;
}
else
{
buffer_eof = true; // no loop -> return EOF
return;
}
}
error = false; // clear error-state
}
buffer_ready = true;
}
void GuiSound::PlayerCallback()
{
if(buffer_eof) // if EOF
{
if(ASND_TestPointer(voice, play_buffer[(buffer_nr+2)%3])==0) // test prev. Buffer
Stop();
}
else if(buffer_ready) // if buffer ready
{
if(ASND_AddVoice(voice, play_buffer[buffer_nr], buffer_pos)==SND_OK) // add buffer
{
// next buffer
buffer_nr = (buffer_nr+1)%3;
buffer_pos = 0;
buffer_ready= false;
buffer_eof = false;
}
}
} }
void GuiSound::SetPlayTime(s32 time_pos)
{
SetTimeOgg(time_pos);
}

View File

@ -0,0 +1,111 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_sound_decoder.h
*
* by ardi 2009
*
* GUI class definitions
***************************************************************************/
#ifndef GUI_SOUND_DECODER_H
#define GUI_SOUND_DECODER_H
#include <gccore.h>
#define REGISTER_GUI_SOUND_DECODER(decoder) GuiSoundDecoder::DecoderListEntry decoder##_l = GuiSoundDecoder::RegisterDecoder(decoder##_l, decoder::Create)
class GuiSoundDecoder;
typedef GuiSoundDecoder *(*GuiSoundDecoderCreate)(const u8 * snd, u32 len, bool snd_is_allocated);
class GuiSoundDecoder
{
protected:
GuiSoundDecoder(){}; // Constructors must protected so it can create only with Init(...);
public:
virtual ~GuiSoundDecoder(){};
// begin API
// ---------
// each Decoder must have an own static Create(...) fnc
// static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated);
virtual s32 GetFormat()=0;
virtual s32 GetSampleRate()=0;
/* Read reads data from stream to buffer
return: >0 = readed bytes;
0 = EOF;
<0 = Error;
*/
virtual int Read(u8 * buffer, int buffer_size)=0;
// set the stream to the start
virtual int Rewind()=0;
// -------
// end API
struct DecoderListEntry
{
GuiSoundDecoderCreate fnc;
DecoderListEntry *next;
};
static DecoderListEntry &RegisterDecoder(DecoderListEntry &Decoder, GuiSoundDecoderCreate fnc);
static GuiSoundDecoder *GetDecoder(const u8 * snd, u32 len, bool snd_is_allocated);
private:
static DecoderListEntry *DecoderList;
GuiSoundDecoder(GuiSoundDecoder&); // no copy
};
#define BIG_ENDIAN_HOST 1 // Wii PPC is a Big-Endian-Host
#if BIG_ENDIAN_HOST
inline uint16_t be16(const uint8_t *p8)
{
return *((uint16_t*)p8);
}
inline uint32_t be32(const uint8_t *p8)
{
return *((uint32_t*)p8);
}
inline uint16_t le16(const uint8_t *p8)
{
uint16_t ret = p8[1]<<8 | p8[0];
return ret;
}
inline uint32_t le32(const uint8_t *p8)
{
uint32_t ret = p8[3]<<24 | p8[2]<<16 | p8[1]<<8 | p8[0];
return ret;
}
#elif LITTLE_ENDIAN_HOST
inline uint16_t be16(const uint8_t *p8)
{
uint16_t ret = p8[0]<<8 | p8[1];
return ret;
}
inline uint32_t be32(const uint8_t *p8)
{
uint32_t ret = p8[0]<<24 | p8[1]<<16 | p8[2]<<8 | p8[3];
return ret;
}
inline uint16_t le16(const uint8_t *p8)
{
return *((uint16_t*)p8);
}
inline uint32_t le32(const uint8_t *p8)
{
return *((uint32_t*)p8);
}
#else
#error "BIG_ENDIAN_HOST or LITTLE_ENDIAN_HOST not setted"
#endif /* XXX_ENDIAN_HOST */
#define be16inc(p8) (p8+=2, be16(p8-2))
#define le16inc(p8) (p8+=2, le16(p8-2))
#define be32inc(p8) (p8+=4, be32(p8-4))
#define le32inc(p8) (p8+=4, le32(p8-4))
#endif /* GUI_SOUND_DECODER_H */

View File

@ -0,0 +1,165 @@
/****************************************************************************
* libwiigui
*
* ardi 2009
*
* gui_sound_plugin_aif.cpp
*
* GUI class definitions
***************************************************************************/
#include <limits.h>
#include <asndlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include "gui_sound_decoder.h"
// ------
// Copyright (C) 1988-1991 Apple Computer, Inc.
#ifndef HUGE_VAL
# define HUGE_VAL HUGE
#endif
# define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
static double ConvertFromIeeeExtended(const u8* bytes)
{
double f;
int expon;
u32 hiMant, loMant;
expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
| ((unsigned long)(bytes[3] & 0xFF) << 16)
| ((unsigned long)(bytes[4] & 0xFF) << 8)
| ((unsigned long)(bytes[5] & 0xFF));
loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
| ((unsigned long)(bytes[7] & 0xFF) << 16)
| ((unsigned long)(bytes[8] & 0xFF) << 8)
| ((unsigned long)(bytes[9] & 0xFF));
if (expon == 0 && hiMant == 0 && loMant == 0)
f = 0;
else
{
if (expon == 0x7FFF)
f = HUGE_VAL;
else
{
expon -= 16383;
f = ldexp(UnsignedToFloat(hiMant), expon-=31);
f += ldexp(UnsignedToFloat(loMant), expon-=32);
}
}
if (bytes[0] & 0x80)
return -f;
else
return f;
}
// ------
class GuiSoundDecoderAIFF : public GuiSoundDecoder
{
protected:
GuiSoundDecoderAIFF(const u8 * snd, u32 len, bool snd_is_allocated)
{
sound = snd;
length =len;
is_allocated = snd_is_allocated;
is_running = false;
const u8 *in_ptr = sound;
if(be32inc(in_ptr) != 0x464F524D /*'FORM'*/) throw("No FORM chunk");
if(be32inc(in_ptr)+8 != len) throw("wrong Size");
if(be32inc(in_ptr) != 0x41494646 /*'AIFF'*/) throw("No AIFF chunk");
while(in_ptr+8 < sound+len)
{
u32 chunk_id = be32inc(in_ptr);
u32 chunk_size = be32inc(in_ptr);
const u8 *chunk_start = in_ptr;
switch(chunk_id)
{
case 0x434F4D4D /*'COMM'*/:
channelCount = be16inc(in_ptr);
in_ptr += 4; // skip numSampleFrames
bytePerSample = (be16inc(in_ptr)+7)/8;
if(bytePerSample < 1 && bytePerSample > 2) throw("wrong bits per Sample");
sampleRate = ConvertFromIeeeExtended(in_ptr);
break;
case 0x53534E44 /*'SSND'*/:
pcm_start = in_ptr + 8;
pcm_end = chunk_start+chunk_size;
break;
}
in_ptr = chunk_start+chunk_size;
}
currentPos = sound;
}
public:
~GuiSoundDecoderAIFF()
{
while(is_running) usleep(50);
if(is_allocated) delete [] sound;
}
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
{
if(snd && len>12 && snd[0]=='F' && snd[1]=='O' && snd[2]=='R' && snd[3]=='M'
&& snd[8]=='A' && snd[9]=='I' && snd[10]=='F' && snd[11]=='F')
return new GuiSoundDecoderAIFF(snd, len, snd_is_allocated);
return NULL;
}
s32 GetFormat()
{
if(bytePerSample == 2)
return channelCount==2 ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
else
return channelCount==2 ? VOICE_STEREO_8BIT : VOICE_MONO_8BIT;
}
s32 GetSampleRate()
{
return sampleRate;
}
/* Read reads data from stream to buffer
return: >0 = readed bytes;
0 = EOF;
<0 = Error;
*/
int Read(u8 * buffer, int buffer_size)
{
if(currentPos >= pcm_end)
return 0; // EOF
is_running = true;
if(currentPos + buffer_size > pcm_end)
buffer_size = pcm_end-currentPos;
memcpy(buffer, currentPos, buffer_size);
currentPos += buffer_size;
is_running = false;
return buffer_size;
}
int Rewind()
{
while(is_running) usleep(50);
currentPos = pcm_start;
return 0;
}
private:
const u8 *sound;
u32 length;
bool is_allocated;
bool is_running;
u32 sampleRate;
u16 channelCount;
u16 bytePerSample;
const u8 *pcm_start;
const u8 *pcm_end;
const u8 *currentPos;
};
REGISTER_GUI_SOUND_DECODER(GuiSoundDecoderAIFF);

View File

@ -0,0 +1,259 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_sound_plugin_bns.cpp
*
* by ardi 2009
*
* Decoder for Wii bns-sound
*
* GUI class definitions
***************************************************************************/
#include <asndlib.h>
#include <unistd.h>
#include "gui_sound_decoder.h"
#define BIG_ENDIAN_HOST 1
class chanel_t
{
public:
void Reset()
{
currentPos = startPos;
hist1 = hist2 = 0;
}
int DecodeNextBlock()
{
int Offset = 0;
if(currentPos == loopStart)
{
loop_hist1 = hist1;
loop_hist2 = hist2;
}
if(loopStart > startPos && currentPos >= endPos)
{
currentPos = loopStart;
hist1 = loop_hist1;
hist2 = loop_hist2;
Offset = loopOffset;
}
if(currentPos+8 <= endPos)
{
u16 index = (*currentPos >> 4) & 0x07;
s32 scale = 1 << (*currentPos++ & 0x0F);
for(int i = 0; i < 14; i+=2)
{
nibbles[i] = ((s8)*currentPos) >> 4;
nibbles[i+1] = ((s8)((*currentPos++) << 4)) >> 4;
}
for(int i = 0; i < 14; ++i)
{
s32 sample = (scale * nibbles[i])<<11;
sample += coEfficients[index * 2] * hist1;
sample += coEfficients[index * 2 + 1] * hist2;
sample += 1024;
sample = sample >> 11;
if(sample > 32767)
sample = 32767;
else if(sample < -32768)
sample = -32768;
pcm[i] = sample;
hist2 = hist1;
hist1 = sample;
}
return Offset;
}
return -1;
}
const u8* startPos;
const u8* endPos;
const u8* currentPos;
s16 coEfficients[16];
s16 nibbles[14];
s16 pcm[14];
s16 hist1;
s16 hist2;
const u8* loopStart;
u16 loopOffset;
s16 loop_hist1;
s16 loop_hist2;
};
class GuiSoundDecoderBNS : public GuiSoundDecoder
{
protected:
GuiSoundDecoderBNS(const u8 * snd, u32 len, bool snd_is_allocated)
{
sound = snd;
is_running = false;
is_allocated = snd_is_allocated;
const u8 *in_ptr = sound;
/////////////////
// READ HEADER //
/////////////////
if(be32inc(in_ptr) != 0x424E5320 /*'BNS '*/) throw("Not a BNS");
in_ptr += 4; // skip 4 byte
u32 bnssize = be32inc(in_ptr);
if(bnssize != len) throw("Wrong size");
in_ptr += 4; // skip unknown1
const u8* infoStart = sound + be32inc(in_ptr);
in_ptr+=4; // skip const u8* infoEnd = infoStart + be32inc(in_ptr);
channel[0].startPos = sound + be32inc(in_ptr) + 8;
channel[0].endPos = channel[0].startPos + be32inc(in_ptr) - 8;
///////////////
// READ INFO //
///////////////
in_ptr = infoStart + 8; // skip 'INFO' and Infosize
in_ptr++; // skip u8 codeType = *in_ptr++;
in_ptr++; // u8 loopFlag = *in_ptr++;
channelCount = *in_ptr++;
in_ptr++; // skip unknown byte
sampleRate = be16inc(in_ptr);
in_ptr+=2; // skip unknown word
u32 loopStart = be32inc(in_ptr);
channel[0].loopStart = channel[0].startPos + ((loopStart/14)*8);//LoopPos to BlockStart
channel[1].loopStart = channel[1].startPos + ((loopStart/14)*8);
channel[0].loopOffset = channel[1].loopOffset = loopStart%14;
in_ptr+=4; // skip u32 SampleCount = be32inc(in_ptr);
in_ptr+=24; // skip unknown Bytes
if(channelCount == 2)
{
in_ptr+=4; // skip unknown long
u32 ChannelSplit = be32inc(in_ptr);
in_ptr+=8; // skip 2x unknown long
channel[1].endPos = channel[0].endPos;
channel[0].endPos = channel[1].startPos = channel[0].startPos + ChannelSplit;
channel[1].loopStart = channel[1].startPos + (channel[0].loopStart - channel[0].startPos);
}
for (int a = 0; a < 16; a++)
{
channel[0].coEfficients[a] = (s16)be16inc(in_ptr);
}
if(channelCount == 2)
{
in_ptr+=16; // skip 16 byte
for (int a = 0; a < 16; a++)
{
channel[1].coEfficients[a] = (s16)be16inc(in_ptr);
}
}
channel[0].Reset();
channel[1].Reset();
currentBlockPos = 14;
}
public:
~GuiSoundDecoderBNS()
{
while(is_running) usleep(50);
if(is_allocated) delete [] sound;
}
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
{
if(snd && len>4 && snd[0]=='B' && snd[1]=='N' && snd[2]=='S' && snd[3]==' ')
return new GuiSoundDecoderBNS(snd, len, snd_is_allocated);
return NULL;
}
s32 GetFormat()
{
return channelCount==2 ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
}
s32 GetSampleRate()
{
return sampleRate;
}
/* Read reads data from stream to buffer
return: >0 = readed bytes;
0 = EOF;
<0 = Error;
*/
int Read(u8 * buffer, int buffer_size)
{
is_running = true;
u8 *write_pos = buffer;
u8 *write_end = buffer+buffer_size;
for(;;)
{
if(currentBlockPos >= 14)
{
int Offset = channel[0].DecodeNextBlock();
if(Offset<0 || (channelCount == 2 && channel[1].DecodeNextBlock()<0) )
{
is_running = false;
return write_pos-buffer;
}
currentBlockPos = Offset;
}
for(;currentBlockPos < 14; ++currentBlockPos)
{
if(write_pos >= write_end)
{
is_running = false;
return write_pos-buffer;
}
*((s16*)write_pos) = channel[0].pcm[currentBlockPos];
write_pos+=2;
if(channelCount==2) // stereo
{
*((s16*)write_pos) = channel[1].pcm[currentBlockPos];
write_pos+=2;
}
}
}
is_running = false;
return 0;
}
int Rewind()
{
channel[0].Reset();
channel[1].Reset();
currentBlockPos = 14;
return 0;
}
private:
const u8 *sound;
bool is_allocated;
bool is_running;
chanel_t channel[2];
u16 currentBlockPos;
u16 channelCount;
u32 sampleRate;
// u16 loopOffset;
// u16 bytePerSample;
// const u8 *soundDataStart;
// const u8 *soundDataEnd;
// u32 soundDataLen;
};
REGISTER_GUI_SOUND_DECODER(GuiSoundDecoderBNS);

View File

@ -0,0 +1,214 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_sound_plugin_mpg.cpp
*
* by ardi 2009
*
* Decoder for MPEG-Audio Mpeg-1/-2 Layer I,II and III with libmad
*
* GUI class definitions
***************************************************************************/
#include <unistd.h>
#include <limits.h>
#include <asndlib.h>
#include <mad.h>
#include <string.h>
#include <new>
#include "gui_sound_decoder.h"
static inline s16 FixedToShort(mad_fixed_t Fixed)
{
/* Clipping */
if(Fixed>=MAD_F_ONE)
return(SHRT_MAX);
if(Fixed<=-MAD_F_ONE)
return(-SHRT_MAX);
Fixed=Fixed>>(MAD_F_FRACBITS-15);
return((s16)Fixed);
}
#define ADMA_BUFFERSIZE (8192)
#define DATABUFFER_SIZE (32768)
// http://www.fr-an.de/fragen/v06/02_01.htm
class GuiSoundDecoderMPG : public GuiSoundDecoder
{
protected:
GuiSoundDecoderMPG(const u8 * snd, u32 len, bool snd_is_allocated)
{
sound = snd;
length = len;
is_allocated = snd_is_allocated;
// Init mad-structures
mad_stream_init(&madStream);
mad_stream_buffer(&madStream, sound, length);
mad_frame_init(&madFrame);
mad_synth_init(&madSynth);
madSynthPcmPos = 0;
mad_timer_reset(&madTimer);
guardBuffer = NULL;
is_running = false;
// decode first Frame
if(DecodeFirstFrame())
{
mad_synth_finish(&madSynth);
mad_frame_finish(&madFrame);
mad_stream_finish(&madStream);
throw("Stream Error");
}
}
public:
~GuiSoundDecoderMPG()
{
while(is_running) usleep(50);
mad_synth_finish(&madSynth);
mad_frame_finish(&madFrame);
mad_stream_finish(&madStream);
delete [] guardBuffer;
if(is_allocated) delete [] sound;
}
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
{
struct mad_stream madStream;
struct mad_header madHeader;
mad_stream_init(&madStream);
mad_stream_buffer(&madStream, snd, len);
mad_header_init(&madHeader);
s32 ret = mad_header_decode(&madHeader, &madStream);
if(ret == 0 || madStream.error==MAD_ERROR_LOSTSYNC) // LOSTSYNC in first call is ok
{
int i;
for(i=0; i<4 && mad_header_decode(&madHeader, &madStream)==0; i++);
if( i == 4 )
{
mad_header_finish(&madHeader);
mad_stream_finish(&madStream);
return new GuiSoundDecoderMPG(snd, len, snd_is_allocated);
}
}
mad_header_finish(&madHeader);
mad_stream_finish(&madStream);
return NULL;
}
s32 GetFormat()
{
return MAD_NCHANNELS(&madFrame.header)==2 ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
}
s32 GetSampleRate()
{
return madFrame.header.samplerate;
}
/* Read reads data from stream to buffer
return: >0 = readed bytes;
0 = EOF;
<0 = Error;
*/
int Read(u8 * buffer, int buffer_size)
{
is_running = true;
if(MAD_NCHANNELS(&madFrame.header)==2) // stereo
buffer_size &= ~0x0003; // make size to a kind of 4
else
buffer_size &= ~0x0001; // make size to a kind of 2
u8 *write_pos = buffer;
u8 *write_end = buffer+buffer_size;
for(;;)
{
for(;madSynthPcmPos < madSynth.pcm.length; ++madSynthPcmPos)
{
if(write_pos >= write_end)
{
is_running = false;
return write_pos-buffer;
}
*((s16*)write_pos) = FixedToShort(madSynth.pcm.samples[0][madSynthPcmPos]); write_pos+=2;
if(MAD_NCHANNELS(&madFrame.header)==2) // stereo
{
*((s16*)write_pos) = FixedToShort(madSynth.pcm.samples[1][madSynthPcmPos]); write_pos+=2;
}
}
madStream.error = MAD_ERROR_NONE;
if(mad_frame_decode(&madFrame,&madStream))
{
if(MAD_RECOVERABLE(madStream.error))
{
if(madStream.error!=MAD_ERROR_LOSTSYNC || !guardBuffer)
continue;
}
else if(madStream.error==MAD_ERROR_BUFLEN)
{
if(!guardBuffer)
{
u32 guardLen = (madStream.bufend-madStream.next_frame);
guardBuffer = new(std::nothrow) u8[guardLen + MAD_BUFFER_GUARD];
if(guardBuffer)
{
memcpy(guardBuffer, madStream.next_frame, guardLen);
memset(guardBuffer+guardLen, 0, MAD_BUFFER_GUARD);
mad_stream_buffer(&madStream, guardBuffer, guardLen + MAD_BUFFER_GUARD);
continue;
}
}
}
break;
}
mad_timer_add(&madTimer,madFrame.header.duration);
mad_synth_frame(&madSynth,&madFrame);
madSynthPcmPos = 0;
}
is_running = false;
return write_pos-buffer;
}
int Rewind()
{
while(is_running) usleep(50);
delete [] guardBuffer; guardBuffer = NULL;
mad_stream_buffer(&madStream, sound, length);
mad_synth_finish(&madSynth);
mad_synth_init(&madSynth);
madSynthPcmPos = 0;
mad_timer_reset(&madTimer);
// decode first Frame
return DecodeFirstFrame();
}
private:
int DecodeFirstFrame()
{
for(;;)
{
madStream.error = MAD_ERROR_NONE;
if(mad_frame_decode(&madFrame,&madStream))
{
if(MAD_RECOVERABLE(madStream.error))
continue;
else
return -1;
}
mad_timer_add(&madTimer,madFrame.header.duration);
mad_synth_frame(&madSynth,&madFrame);
return 0;
}
}
const u8 *sound;
u32 length;
bool is_allocated;
struct mad_stream madStream;
struct mad_frame madFrame;
struct mad_synth madSynth;
u16 madSynthPcmPos;
mad_timer_t madTimer;
u8 *guardBuffer;
bool is_running;
};
REGISTER_GUI_SOUND_DECODER(GuiSoundDecoderMPG);

View File

@ -0,0 +1,94 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_sound_plugin_ogg.cpp
*
* by ardi 2009
*
* Decoder for ogg-vorbis with libtremor
*
* GUI class definitions
***************************************************************************/
#include <unistd.h>
#include <asndlib.h>
#include <tremor/ivorbiscodec.h>
#include <tremor/ivorbisfile.h>
#include "gui_sound_decoder.h"
class GuiSoundDecoderOGG : public GuiSoundDecoder
{
protected:
GuiSoundDecoderOGG(const u8 * snd, u32 len, bool snd_is_allocated)
{
sound = snd;
is_allocated = snd_is_allocated;
ogg_fd = mem_open((char *)snd, len);
if(ogg_fd < 0) throw("mem open failed");
if (ov_open((FILE*)&ogg_fd, &ogg_file, NULL, 0) < 0)
{
mem_close(ogg_fd);
throw("ogg open failed");
}
ogg_info = ov_info(&ogg_file, -1);
bitstream = 0;
is_running = false;
}
public:
~GuiSoundDecoderOGG()
{
while(is_running) usleep(50);
ov_clear(&ogg_file);
if(is_allocated) delete [] sound;
}
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
{
if(snd && len>4 && snd[0]=='O' && snd[1]=='g' && snd[2]=='g' && snd[3]=='S')
return new GuiSoundDecoderOGG(snd, len, snd_is_allocated);
return NULL;
}
s32 GetFormat()
{
return ogg_info->channels==2 ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
}
s32 GetSampleRate()
{
return ogg_info->rate;
}
/* Read reads data from stream to buffer
return: >0 = readed bytes;
0 = EOF;
<0 = Error;
*/
int Read(u8 * buffer, int buffer_size)
{
is_running = true;
int ret = ov_read(&ogg_file, (char *)buffer, buffer_size, &bitstream);
if (ret < 0)
{
/* error in the stream. Not a problem, just reporting it in
case we (the app) cares. In this case, we don't. */
if (ret != OV_HOLE)
ret = 0; // we says EOF
}
is_running = false;
return ret;
}
int Rewind()
{
return ov_time_seek(&ogg_file, 0);
}
private:
const u8 *sound;
bool is_allocated;
int ogg_fd;
OggVorbis_File ogg_file;
vorbis_info *ogg_info;
int bitstream;
bool is_running;
};
REGISTER_GUI_SOUND_DECODER(GuiSoundDecoderOGG);

View File

@ -0,0 +1,236 @@
/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_sound_plugin_wav.cpp
*
* by ardi 2009
*
* Decoder for WAVE PCM
*
* GUI class definitions
***************************************************************************/
#include <asndlib.h>
#include <map>
#include <vector>
#include <unistd.h>
#include "gui_sound_decoder.h"
typedef struct
{
u32 cueID;
u32 len;
u32 loops;
}plst_t;
typedef struct
{
const u8 *start;
const u8 *end;
u32 loops;
}playlist_t;
class GuiSoundDecoderWAV : public GuiSoundDecoder
{
protected:
GuiSoundDecoderWAV(const u8 * snd, u32 len, bool snd_is_allocated)
{
sound = snd;
is_running = false;
is_allocated = snd_is_allocated;
const u8 *in_ptr = sound;
if(be32inc(in_ptr) != 0x52494646 /*'RIFF' (WAV)*/) throw("Not a WAV");
u32 riffsize = le32inc(in_ptr);
if(riffsize > (len-8)) throw("Wrong size");
if(be32inc(in_ptr) != 0x57415645 /*'WAVE'*/) throw("No WAVE-Tag");
if(be32inc(in_ptr) != 0x666D7420 /*'fmt '*/) throw("No fmt-Tag");
u32 fmtLen = le32inc(in_ptr);
if(le16inc(in_ptr) != 1) throw("Not PCM data");
channelCount = le16inc(in_ptr);
if(channelCount < 1 || channelCount > 2) throw("only mono or stereo");
sampleRate = le32inc(in_ptr);
in_ptr += 6; // skip <bytes/second> and <block align>
bytePerSample = (le16inc(in_ptr)+7)/8;
if(bytePerSample < 1 || bytePerSample > 2) throw("only 1-16 bit/Sample");
in_ptr += fmtLen-16;
if(be32inc(in_ptr) != 0x64617461 /*'data'*/) throw("No data-Tag");
soundDataStart = in_ptr+4;
soundDataEnd = soundDataStart + le32(in_ptr);
in_ptr = soundDataEnd;
std::map<u32, u32> cue;
std::vector<plst_t>plst;
if(((u32)in_ptr) & 0x0001UL) in_ptr++;
while((in_ptr+4) < (sound + riffsize))
{
u32 tag = be32inc(in_ptr);
switch(tag)
{
case 0x63756520 /*'cue '*/:
in_ptr += 4; // skip size
for(u32 count = le32inc(in_ptr); count>0; count--)
{
u32 ID = be32inc(in_ptr);
in_ptr += 4; // skip dwPosition
if(be32inc(in_ptr) == 0x64617461 /*'data'*/)
{
in_ptr += 8; // skip chunkStart - dwBlockStart
cue[ID] = le32inc(in_ptr);
}
else
in_ptr += 12; // skip chunkStart - SammpleOffset
}
break;
case 0x706C7374 /*' plst'*/:
in_ptr += 4; // skip size
for(u32 count = le32inc(in_ptr); count>0; count--)
plst.push_back((plst_t){le32inc(in_ptr), le32inc(in_ptr), le32inc(in_ptr)});
break;
default:
in_ptr -= 2;
break;
}
}
for(std::vector<plst_t>::iterator i = plst.begin(); i != plst.end(); ++i)
{
const u8 *start = soundDataStart + cue[i->cueID];
const u8 *end = soundDataStart + (i->len*bytePerSample*channelCount);
u32 loops = i->loops;
playlist.push_back((playlist_t){start,end,loops});
}
if(playlist.size() == 0)
{
playlist.push_back((playlist_t){soundDataStart, soundDataEnd, 1});
}
Rewind();
}
public:
~GuiSoundDecoderWAV()
{
while(is_running) usleep(50);
if(is_allocated) delete [] sound;
}
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
{
if(snd && len>4 && snd[0]=='R' && snd[1]=='I' && snd[2]=='F' && snd[3]=='F'
&& snd[8]=='W' && snd[9]=='A' && snd[10]=='V' && snd[11]=='E')
return new GuiSoundDecoderWAV(snd, len, snd_is_allocated);
return NULL;
}
s32 GetFormat()
{
if(bytePerSample == 2)
return channelCount==2 ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
else
return channelCount==2 ? VOICE_STEREO_8BIT : VOICE_MONO_8BIT;
}
s32 GetSampleRate()
{
return sampleRate;
}
/* Read reads data from stream to buffer
return: >0 = readed bytes;
0 = EOF;
<0 = Error;
*/
int Read(u8 * buffer, int buffer_size)
{
is_running = true;
u8 *write_pos = buffer;
u8 *write_end = buffer+buffer_size;
for(;;)
{
while(currentPos < currentEnd)
{
if(write_pos >= write_end)
{
is_running = false;
return write_pos-buffer;
}
if(bytePerSample == 2)
{
*((s16*)write_pos) = le16inc(currentPos);
write_pos+=2;
if(channelCount==2) // stereo
{
*((s16*)write_pos) = le16inc(currentPos);
write_pos+=2;
}
}
else
{
*write_pos++ = *currentPos++;
if(channelCount==2) // stereo
*write_pos++ = *currentPos++;
}
}
if(currentLoops>1)
{
currentLoops--;
currentPos = currentStart;
continue;
}
if(currentPlaylist != playlist.end())
currentPlaylist++;
if(currentPlaylist != playlist.end())
{
currentStart = currentPos = currentPlaylist->start;
currentEnd = currentPlaylist->end;
currentLoops = currentPlaylist->loops;
continue;
}
else
{
is_running = false;
return write_pos-buffer;
}
}
is_running = false;
return 0;
}
int Rewind()
{
currentPlaylist = playlist.begin();
currentStart = currentPos = currentPlaylist->start;
currentEnd = currentPlaylist->end;
currentLoops = currentPlaylist->loops;
return 0;
}
private:
const u8 *sound;
bool is_allocated;
bool is_running;
u16 channelCount;
u32 sampleRate;
u16 bytePerSample;
const u8 *soundDataStart;
const u8 *soundDataEnd;
std::vector<playlist_t> playlist;
std::vector<playlist_t>::iterator currentPlaylist;
const u8 *currentStart;
const u8 *currentEnd;
u32 currentLoops;
const u8 *currentPos;
};
REGISTER_GUI_SOUND_DECODER(GuiSoundDecoderWAV);

View File

@ -40,7 +40,7 @@ bool subfoldercreate(const char * fullpath) {
strlcpy(dir, fullpath, sizeof(dir)); strlcpy(dir, fullpath, sizeof(dir));
len = strlen(dir); len = strlen(dir);
if(len && len< sizeof(dir)-2 && dir[len-1] != '/'); if(len && len< sizeof(dir)-2 && dir[len-1] != '/')
{ {
dir[len++] = '/'; dir[len++] = '/';
dir[len] = '\0'; dir[len] = '\0';
@ -63,7 +63,42 @@ bool subfoldercreate(const char * fullpath) {
} }
return true; return true;
} }
bool subfolderremove(const char * fullpath, const char*fp) {
struct stat st;
if (stat(fullpath, &st) != 0) // fullpath not exist?
return false;
if(S_ISDIR(st.st_mode))
{
DIR_ITER *dir = NULL;
char filename[256];
bool cont = true;
while(cont)
{
cont = false;
dir = diropen(fullpath);
if(dir)
{
char* bind = fullpath[strlen(fullpath)-1] == '/' ? "":"/";
while (dirnext(dir,filename,&st) == 0)
{
if (strcmp(filename,".") != 0 && strcmp(filename,"..") != 0)
{
char currentname[256];
if(S_ISDIR(st.st_mode))
snprintf(currentname, sizeof(currentname), "%s%s%s/", fullpath, bind, filename);
else
snprintf(currentname, sizeof(currentname), "%s%s%s", fullpath, bind, filename);
subfolderremove(currentname, fp);
cont = true;
break;
}
}
dirclose(dir);
}
}
}
return unlink(fullpath) == 0;
}
char * GetFileName(int i) { char * GetFileName(int i) {
return alldirfiles[i]; return alldirfiles[i];
} }

View File

@ -102,7 +102,7 @@ u64 getStubDest()
char *stub = (char *)0x800024C6; char *stub = (char *)0x800024C6;
char ret[8]; char ret[9];
u64 retu =0; u64 retu =0;
ret[0] = stub[0]; ret[0] = stub[0];

View File

@ -10,7 +10,6 @@
#include "FreeTypeGX.h" #include "FreeTypeGX.h"
extern struct SSettings Settings;
void DefaultSettings(); void DefaultSettings();
extern FreeTypeGX *fontSystem; extern FreeTypeGX *fontSystem;

View File

@ -62,6 +62,8 @@ GuiImageData * pointer[4];
GuiImage * bgImg = NULL; GuiImage * bgImg = NULL;
GuiImageData * background = NULL; GuiImageData * background = NULL;
GuiSound * bgMusic = NULL; GuiSound * bgMusic = NULL;
GuiSound *btnClick2 = NULL;
float gamesize; float gamesize;
int currentMenu; int currentMenu;
int idiotFlag=-1; int idiotFlag=-1;
@ -371,8 +373,10 @@ int MenuDiscList() {
} }
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
snprintf(imgPath, sizeof(imgPath), "%sbutton_install.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_install.png", CFG.theme_path);
GuiImageData btnInstall(imgPath, button_install_png); GuiImageData btnInstall(imgPath, button_install_png);
@ -485,7 +489,7 @@ int MenuDiscList() {
installBtnImg.SetWidescreen(CFG.widescreen); installBtnImg.SetWidescreen(CFG.widescreen);
installBtnImgOver.SetWidescreen(CFG.widescreen); installBtnImgOver.SetWidescreen(CFG.widescreen);
GuiButton installBtn(&installBtnImg, &installBtnImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.install_x, THEME.install_y, &trigA, &btnSoundOver, &btnClick, 1, &installBtnTT,24,-30, 0,5); GuiButton installBtn(&installBtnImg, &installBtnImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.install_x, THEME.install_y, &trigA, &btnSoundOver, btnClick2, 1, &installBtnTT,24,-30, 0,5);
GuiTooltip settingsBtnTT(tr("Settings")); GuiTooltip settingsBtnTT(tr("Settings"));
@ -496,7 +500,7 @@ int MenuDiscList() {
settingsBtnImg.SetWidescreen(CFG.widescreen); settingsBtnImg.SetWidescreen(CFG.widescreen);
GuiImage settingsBtnImgOver(&btnSettingsOver); GuiImage settingsBtnImgOver(&btnSettingsOver);
settingsBtnImgOver.SetWidescreen(CFG.widescreen); settingsBtnImgOver.SetWidescreen(CFG.widescreen);
GuiButton settingsBtn(&settingsBtnImg,&settingsBtnImgOver, 0, 3, THEME.setting_x, THEME.setting_y, &trigA, &btnSoundOver, &btnClick,1,&settingsBtnTT,65,-30,0,5); GuiButton settingsBtn(&settingsBtnImg,&settingsBtnImgOver, 0, 3, THEME.setting_x, THEME.setting_y, &trigA, &btnSoundOver, btnClick2,1,&settingsBtnTT,65,-30,0,5);
GuiTooltip homeBtnTT(tr("Back to HBC or Wii Menu")); GuiTooltip homeBtnTT(tr("Back to HBC or Wii Menu"));
if (Settings.wsprompt == yes) if (Settings.wsprompt == yes)
@ -506,7 +510,7 @@ int MenuDiscList() {
homeBtnImg.SetWidescreen(CFG.widescreen); homeBtnImg.SetWidescreen(CFG.widescreen);
GuiImage homeBtnImgOver(&btnhomeOver); GuiImage homeBtnImgOver(&btnhomeOver);
homeBtnImgOver.SetWidescreen(CFG.widescreen); homeBtnImgOver.SetWidescreen(CFG.widescreen);
GuiButton homeBtn(&homeBtnImg,&homeBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, &btnClick,1,&homeBtnTT,15,-30,1,5); GuiButton homeBtn(&homeBtnImg,&homeBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, btnClick2,1,&homeBtnTT,15,-30,1,5);
homeBtn.RemoveSoundClick(); homeBtn.RemoveSoundClick();
homeBtn.SetTrigger(&trigHome); homeBtn.SetTrigger(&trigHome);
@ -518,7 +522,7 @@ int MenuDiscList() {
GuiImage poweroffBtnImgOver(&btnpwroffOver); GuiImage poweroffBtnImgOver(&btnpwroffOver);
poweroffBtnImg.SetWidescreen(CFG.widescreen); poweroffBtnImg.SetWidescreen(CFG.widescreen);
poweroffBtnImgOver.SetWidescreen(CFG.widescreen); poweroffBtnImgOver.SetWidescreen(CFG.widescreen);
GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, &btnClick,1,&poweroffBtnTT,-10,-30,1,5); GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, btnClick2,1,&poweroffBtnTT,-10,-30,1,5);
GuiTooltip sdcardBtnTT(tr("Reload SD")); GuiTooltip sdcardBtnTT(tr("Reload SD"));
@ -529,16 +533,16 @@ int MenuDiscList() {
GuiImage sdcardImgOver(&btnsdcardOver); GuiImage sdcardImgOver(&btnsdcardOver);
sdcardImg.SetWidescreen(CFG.widescreen); sdcardImg.SetWidescreen(CFG.widescreen);
sdcardImgOver.SetWidescreen(CFG.widescreen); sdcardImgOver.SetWidescreen(CFG.widescreen);
GuiButton sdcardBtn(&sdcardImg,&sdcardImgOver, 0, 3, THEME.sdcard_x, THEME.sdcard_y, &trigA, &btnSoundOver, &btnClick,1,&sdcardBtnTT,15,-30,0,5); GuiButton sdcardBtn(&sdcardImg,&sdcardImgOver, 0, 3, THEME.sdcard_x, THEME.sdcard_y, &trigA, &btnSoundOver, btnClick2,1,&sdcardBtnTT,15,-30,0,5);
GuiButton gameInfo(0,0); GuiButton gameInfo(0,0);
gameInfo.SetTrigger(&trig2); gameInfo.SetTrigger(&trig2);
gameInfo.SetSoundClick(&btnClick); gameInfo.SetSoundClick(btnClick2);
GuiImage wiiBtnImg(&dataID); GuiImage wiiBtnImg(&dataID);
wiiBtnImg.SetWidescreen(CFG.widescreen); wiiBtnImg.SetWidescreen(CFG.widescreen);
GuiButton wiiBtn(&wiiBtnImg,&wiiBtnImg, 0, 4, 0, -10, &trigA, &btnSoundOver, &btnClick,0); GuiButton wiiBtn(&wiiBtnImg,&wiiBtnImg, 0, 4, 0, -10, &trigA, &btnSoundOver, btnClick2,0);
GuiTooltip favoriteBtnTT(tr("Display favorites")); GuiTooltip favoriteBtnTT(tr("Display favorites"));
if (Settings.wsprompt == yes) if (Settings.wsprompt == yes)
@ -550,7 +554,7 @@ int MenuDiscList() {
GuiImage favoriteBtnImg_g(&imgfavIcon_gray); GuiImage favoriteBtnImg_g(&imgfavIcon_gray);
if(favoriteBtnImg_g.GetImage() == NULL) { favoriteBtnImg_g = favoriteBtnImg; favoriteBtnImg_g.SetGrayscale();} if(favoriteBtnImg_g.GetImage() == NULL) { favoriteBtnImg_g = favoriteBtnImg; favoriteBtnImg_g.SetGrayscale();}
favoriteBtnImg_g.SetWidescreen(CFG.widescreen); favoriteBtnImg_g.SetWidescreen(CFG.widescreen);
GuiButton favoriteBtn(&favoriteBtnImg_g,&favoriteBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_favorite_x, THEME.gamelist_favorite_y, &trigA, &btnSoundOver, &btnClick,1, &favoriteBtnTT, -15, 52, 0, 3); GuiButton favoriteBtn(&favoriteBtnImg_g,&favoriteBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_favorite_x, THEME.gamelist_favorite_y, &trigA, &btnSoundOver, btnClick2,1, &favoriteBtnTT, -15, 52, 0, 3);
favoriteBtn.SetAlpha(180); favoriteBtn.SetAlpha(180);
GuiTooltip searchBtnTT(tr("Set Search-Filter")); GuiTooltip searchBtnTT(tr("Set Search-Filter"));
@ -563,7 +567,7 @@ int MenuDiscList() {
GuiImage searchBtnImg_g(&imgsearchIcon_gray); GuiImage searchBtnImg_g(&imgsearchIcon_gray);
if(searchBtnImg_g.GetImage() == NULL) { searchBtnImg_g = searchBtnImg; searchBtnImg_g.SetGrayscale();} if(searchBtnImg_g.GetImage() == NULL) { searchBtnImg_g = searchBtnImg; searchBtnImg_g.SetGrayscale();}
searchBtnImg_g.SetWidescreen(CFG.widescreen); searchBtnImg_g.SetWidescreen(CFG.widescreen);
GuiButton searchBtn(&searchBtnImg_g,&searchBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_search_x, THEME.gamelist_search_y, &trigA, &btnSoundOver, &btnClick,1, &searchBtnTT, -15, 52, 0, 3); GuiButton searchBtn(&searchBtnImg_g,&searchBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_search_x, THEME.gamelist_search_y, &trigA, &btnSoundOver, btnClick2,1, &searchBtnTT, -15, 52, 0, 3);
searchBtn.SetAlpha(180); searchBtn.SetAlpha(180);
GuiTooltip abcBtnTT(Settings.fave ? tr("Sort by rank") : tr("Sort alphabetically")); GuiTooltip abcBtnTT(Settings.fave ? tr("Sort by rank") : tr("Sort alphabetically"));
@ -576,7 +580,7 @@ int MenuDiscList() {
GuiImage abcBtnImg_g(Settings.fave ? &imgrankIcon_gray : &imgabcIcon_gray); GuiImage abcBtnImg_g(Settings.fave ? &imgrankIcon_gray : &imgabcIcon_gray);
if(abcBtnImg_g.GetImage() == NULL) { abcBtnImg_g = abcBtnImg; abcBtnImg_g.SetGrayscale();} if(abcBtnImg_g.GetImage() == NULL) { abcBtnImg_g = abcBtnImg; abcBtnImg_g.SetGrayscale();}
abcBtnImg_g.SetWidescreen(CFG.widescreen); abcBtnImg_g.SetWidescreen(CFG.widescreen);
GuiButton abcBtn(&abcBtnImg_g,&abcBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_abc_x, THEME.gamelist_abc_y, &trigA, &btnSoundOver, &btnClick,1,&abcBtnTT, -15, 52, 0, 3); GuiButton abcBtn(&abcBtnImg_g,&abcBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_abc_x, THEME.gamelist_abc_y, &trigA, &btnSoundOver, btnClick2,1,&abcBtnTT, -15, 52, 0, 3);
abcBtn.SetAlpha(180); abcBtn.SetAlpha(180);
GuiTooltip countBtnTT(tr("Sort order by most played")); GuiTooltip countBtnTT(tr("Sort order by most played"));
@ -589,7 +593,7 @@ int MenuDiscList() {
GuiImage countBtnImg_g(&imgplayCountIcon_gray); GuiImage countBtnImg_g(&imgplayCountIcon_gray);
if(countBtnImg_g.GetImage() == NULL) { countBtnImg_g = countBtnImg; countBtnImg_g.SetGrayscale();} if(countBtnImg_g.GetImage() == NULL) { countBtnImg_g = countBtnImg; countBtnImg_g.SetGrayscale();}
countBtnImg_g.SetWidescreen(CFG.widescreen); countBtnImg_g.SetWidescreen(CFG.widescreen);
GuiButton countBtn(&countBtnImg_g,&countBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_count_x, THEME.gamelist_count_y, &trigA, &btnSoundOver, &btnClick,1, &countBtnTT, -15, 52, 0, 3); GuiButton countBtn(&countBtnImg_g,&countBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_count_x, THEME.gamelist_count_y, &trigA, &btnSoundOver, btnClick2,1, &countBtnTT, -15, 52, 0, 3);
countBtn.SetAlpha(180); countBtn.SetAlpha(180);
GuiTooltip listBtnTT(tr("Display as a list")); GuiTooltip listBtnTT(tr("Display as a list"));
@ -602,7 +606,7 @@ int MenuDiscList() {
GuiImage listBtnImg_g(&imgarrangeList_gray); GuiImage listBtnImg_g(&imgarrangeList_gray);
if(listBtnImg_g.GetImage() == NULL) { listBtnImg_g = listBtnImg; listBtnImg_g.SetGrayscale();} if(listBtnImg_g.GetImage() == NULL) { listBtnImg_g = listBtnImg; listBtnImg_g.SetGrayscale();}
listBtnImg_g.SetWidescreen(CFG.widescreen); listBtnImg_g.SetWidescreen(CFG.widescreen);
GuiButton listBtn(&listBtnImg_g,&listBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_list_x, THEME.gamelist_list_y, &trigA, &btnSoundOver, &btnClick,1, &listBtnTT, 15, 52, 1, 3); GuiButton listBtn(&listBtnImg_g,&listBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_list_x, THEME.gamelist_list_y, &trigA, &btnSoundOver, btnClick2,1, &listBtnTT, 15, 52, 1, 3);
listBtn.SetAlpha(180); listBtn.SetAlpha(180);
GuiTooltip gridBtnTT(tr("Display as a grid")); GuiTooltip gridBtnTT(tr("Display as a grid"));
@ -615,7 +619,7 @@ int MenuDiscList() {
GuiImage gridBtnImg_g(&imgarrangeGrid_gray); GuiImage gridBtnImg_g(&imgarrangeGrid_gray);
if(gridBtnImg_g.GetImage() == NULL) { gridBtnImg_g = gridBtnImg; gridBtnImg_g.SetGrayscale();} if(gridBtnImg_g.GetImage() == NULL) { gridBtnImg_g = gridBtnImg; gridBtnImg_g.SetGrayscale();}
gridBtnImg_g.SetWidescreen(CFG.widescreen); gridBtnImg_g.SetWidescreen(CFG.widescreen);
GuiButton gridBtn(&gridBtnImg_g,&gridBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_grid_x, THEME.gamelist_grid_y, &trigA, &btnSoundOver, &btnClick,1, &gridBtnTT, 15, 52, 1, 3); GuiButton gridBtn(&gridBtnImg_g,&gridBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_grid_x, THEME.gamelist_grid_y, &trigA, &btnSoundOver, btnClick2,1, &gridBtnTT, 15, 52, 1, 3);
gridBtn.SetAlpha(180); gridBtn.SetAlpha(180);
GuiTooltip carouselBtnTT(tr("Display as a carousel")); GuiTooltip carouselBtnTT(tr("Display as a carousel"));
@ -628,7 +632,7 @@ int MenuDiscList() {
GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray); GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray);
if(carouselBtnImg_g.GetImage() == NULL) { carouselBtnImg_g = carouselBtnImg; carouselBtnImg_g.SetGrayscale();} if(carouselBtnImg_g.GetImage() == NULL) { carouselBtnImg_g = carouselBtnImg; carouselBtnImg_g.SetGrayscale();}
carouselBtnImg_g.SetWidescreen(CFG.widescreen); carouselBtnImg_g.SetWidescreen(CFG.widescreen);
GuiButton carouselBtn(&carouselBtnImg_g,&carouselBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_carousel_x, THEME.gamelist_carousel_y, &trigA, &btnSoundOver, &btnClick,1, &carouselBtnTT, 15, 52, 1, 3); GuiButton carouselBtn(&carouselBtnImg_g,&carouselBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_carousel_x, THEME.gamelist_carousel_y, &trigA, &btnSoundOver, btnClick2,1, &carouselBtnTT, 15, 52, 1, 3);
carouselBtn.SetAlpha(180); carouselBtn.SetAlpha(180);
GuiTooltip dvdBtnTT(tr("Mount DVD drive")); GuiTooltip dvdBtnTT(tr("Mount DVD drive"));
@ -640,7 +644,7 @@ int MenuDiscList() {
GuiImage dvdBtnImg_g(dvdBtnImg); //dvdBtnImg_g.SetGrayscale(); GuiImage dvdBtnImg_g(dvdBtnImg); //dvdBtnImg_g.SetGrayscale();
// GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray); // GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray);
dvdBtnImg_g.SetWidescreen(CFG.widescreen); dvdBtnImg_g.SetWidescreen(CFG.widescreen);
GuiButton dvdBtn(&dvdBtnImg_g,&dvdBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_dvd_x, THEME.gamelist_dvd_y, &trigA, &btnSoundOver, &btnClick,1, &dvdBtnTT, 15, 52, 1, 3); GuiButton dvdBtn(&dvdBtnImg_g,&dvdBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_dvd_x, THEME.gamelist_dvd_y, &trigA, &btnSoundOver, btnClick2,1, &dvdBtnTT, 15, 52, 1, 3);
dvdBtn.SetAlpha(180); dvdBtn.SetAlpha(180);
GuiTooltip homebrewBtnTT(tr("Homebrew Launcher")); GuiTooltip homebrewBtnTT(tr("Homebrew Launcher"));
@ -651,7 +655,7 @@ int MenuDiscList() {
GuiImage homebrewImgOver(&homebrewImgDataOver); GuiImage homebrewImgOver(&homebrewImgDataOver);
homebrewImg.SetWidescreen(CFG.widescreen); homebrewImg.SetWidescreen(CFG.widescreen);
homebrewImgOver.SetWidescreen(CFG.widescreen); homebrewImgOver.SetWidescreen(CFG.widescreen);
GuiButton homebrewBtn(&homebrewImg,&homebrewImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.homebrew_x, THEME.homebrew_y, &trigA, &btnSoundOver, &btnClick,1,&homebrewBtnTT,15,-30,1,5); GuiButton homebrewBtn(&homebrewImg,&homebrewImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.homebrew_x, THEME.homebrew_y, &trigA, &btnSoundOver, btnClick2,1,&homebrewBtnTT,15,-30,1,5);
if (Settings.fave) { if (Settings.fave) {
favoriteBtn.SetImage(&favoriteBtnImg); favoriteBtn.SetImage(&favoriteBtnImg);
@ -972,16 +976,9 @@ int MenuDiscList() {
} else if (homeBtn.GetState() == STATE_CLICKED) { } else if (homeBtn.GetState() == STATE_CLICKED) {
gprintf("\n\thomeBtn clicked"); gprintf("\n\thomeBtn clicked");
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) { bgMusic->Resume();
bgMusic->Play();
} else {
bgMusic->PlayOggFile(Settings.ogg_path);
}
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) { if (choice == 3) {
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu
@ -1755,7 +1752,7 @@ static int MenuInstall() {
int ret, choice = 0; int ret, choice = 0;
char name[200]; char name[200];
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
@ -1849,22 +1846,15 @@ static int MenuInstall() {
} else { } else {
__Menu_GetEntries(); //get the entries again __Menu_GetEntries(); //get the entries again
GuiSound * instsuccess = NULL; GuiSound * instsuccess = NULL;
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop(); instsuccess = new GuiSound(success_ogg, success_ogg_size, Settings.sfxvolume);
instsuccess = new GuiSound(success_ogg, success_ogg_size, SOUND_OGG, Settings.sfxvolume);
instsuccess->SetVolume(Settings.sfxvolume); instsuccess->SetVolume(Settings.sfxvolume);
instsuccess->SetLoop(0); instsuccess->SetLoop(0);
instsuccess->Play(); instsuccess->Play();
WindowPrompt (tr("Successfully installed:"),name,tr("OK")); WindowPrompt (tr("Successfully installed:"),name,tr("OK"));
instsuccess->Stop(); instsuccess->Stop();
delete instsuccess; delete instsuccess;
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) { bgMusic->Resume();
bgMusic->Play();
} else {
bgMusic->PlayOggFile(Settings.ogg_path);
}
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
menu = MENU_DISCLIST; menu = MENU_DISCLIST;
break; break;
} }
@ -1933,8 +1923,10 @@ static int MenuFormat() {
} }
} }
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff.png", CFG.theme_path);
GuiImageData btnpwroff(imgPath, wiimote_poweroff_png); GuiImageData btnpwroff(imgPath, wiimote_poweroff_png);
snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff_over.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff_over.png", CFG.theme_path);
@ -1958,12 +1950,12 @@ static int MenuFormat() {
GuiImage poweroffBtnImgOver(&btnpwroffOver); GuiImage poweroffBtnImgOver(&btnpwroffOver);
poweroffBtnImg.SetWidescreen(CFG.widescreen); poweroffBtnImg.SetWidescreen(CFG.widescreen);
poweroffBtnImgOver.SetWidescreen(CFG.widescreen); poweroffBtnImgOver.SetWidescreen(CFG.widescreen);
GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, &btnClick,1); GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, btnClick2,1);
GuiImage exitBtnImg(&btnhome); GuiImage exitBtnImg(&btnhome);
GuiImage exitBtnImgOver(&btnhomeOver); GuiImage exitBtnImgOver(&btnhomeOver);
exitBtnImg.SetWidescreen(CFG.widescreen); exitBtnImg.SetWidescreen(CFG.widescreen);
exitBtnImgOver.SetWidescreen(CFG.widescreen); exitBtnImgOver.SetWidescreen(CFG.widescreen);
GuiButton exitBtn(&exitBtnImg,&exitBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, &btnClick,1); GuiButton exitBtn(&exitBtnImg,&exitBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, btnClick2,1);
exitBtn.SetTrigger(&trigHome); exitBtn.SetTrigger(&trigHome);
GuiCustomOptionBrowser optionBrowser(396, 280, &options, CFG.theme_path, "bg_options_settings.png", bg_options_settings_png, 0, 10); GuiCustomOptionBrowser optionBrowser(396, 280, &options, CFG.theme_path, "bg_options_settings.png", bg_options_settings_png, 0, 10);
@ -2171,18 +2163,16 @@ int MainMenu(int menu) {
ResumeGui(); ResumeGui();
bgMusic = new GuiSound(bg_music_ogg, bg_music_ogg_size, SOUND_OGG, Settings.volume); bgMusic = new GuiSound(bg_music_ogg, bg_music_ogg_size, Settings.volume);
bgMusic->SetVolume(Settings.volume);
bgMusic->SetLoop(1); //loop music bgMusic->SetLoop(1); //loop music
// startup music // startup music
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) { if (strcmp("", Settings.oggload_path) && strcmp("notset", Settings.ogg_path)) {
bgMusic->Play(); bgMusic->Load(Settings.ogg_path);
} else {
bgMusic->PlayOggFile(Settings.ogg_path);
} }
bgMusic->Play();
while (currentMenu != MENU_EXIT) { while (currentMenu != MENU_EXIT) {
SetVolumeOgg(255*(Settings.volume/100.0)); bgMusic->SetVolume(Settings.volume);
switch (currentMenu) { switch (currentMenu) {
case MENU_CHECK: case MENU_CHECK:

View File

@ -33,5 +33,6 @@ enum {
}; };
class GuiImageData; class GuiImageData;
GuiImageData *LoadCoverImage(struct discHdr *header, bool Prefere3D=true, bool noCover=true); GuiImageData *LoadCoverImage(struct discHdr *header, bool Prefere3D=true, bool noCover=true);
class GuiSound;
extern GuiSound *btnClick2;
#endif #endif

View File

@ -1,336 +0,0 @@
/*
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
All rights reserved.
Threading modifications/corrections by Tantric, 2009
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "oggplayer.h"
#include <gccore.h>
#include <malloc.h>
#include <stdlib.h>
#include <unistd.h>
/* OGG control */
#define READ_SAMPLES 4096 // samples that it must read before to send
#define MAX_PCMOUT 4096 // minimum size to read ogg samples
typedef struct {
OggVorbis_File vf;
vorbis_info *vi;
int current_section;
// OGG file operation
int fd;
int mode;
int eof;
int flag;
int volume;
int seek_time;
/* OGG buffer control */
short pcmout[2][READ_SAMPLES + MAX_PCMOUT * 2]; /* take 4k out of the data segment, not the stack */
int pcmout_pos;
int pcm_indx;
} private_data_ogg;
static private_data_ogg private_ogg;
// OGG thread control
#define STACKSIZE 8192
static u8 oggplayer_stack[STACKSIZE];
static lwpq_t oggplayer_queue = LWP_THREAD_NULL;
static lwp_t h_oggplayer = LWP_THREAD_NULL;
static int ogg_thread_running = 0;
static void ogg_add_callback(int voice) {
if (!ogg_thread_running) {
ASND_StopVoice(0);
return;
}
if (private_ogg.flag & 128)
return; // Ogg is paused
if (private_ogg.pcm_indx >= READ_SAMPLES) {
if (ASND_AddVoice(0,
(void *) private_ogg.pcmout[private_ogg.pcmout_pos],
private_ogg.pcm_indx << 1) == 0) {
private_ogg.pcmout_pos ^= 1;
private_ogg.pcm_indx = 0;
private_ogg.flag = 0;
LWP_ThreadSignal(oggplayer_queue);
}
} else {
if (private_ogg.flag & 64) {
private_ogg.flag &= ~64;
LWP_ThreadSignal(oggplayer_queue);
}
}
}
static void * ogg_player_thread(private_data_ogg * priv) {
int first_time = 1;
long ret;
ogg_thread_running = 0;
//init
LWP_InitQueue(&oggplayer_queue);
priv[0].vi = ov_info(&priv[0].vf, -1);
ASND_Pause(0);
priv[0].pcm_indx = 0;
priv[0].pcmout_pos = 0;
priv[0].eof = 0;
priv[0].flag = 0;
priv[0].current_section = 0;
ogg_thread_running = 1;
while (!priv[0].eof && ogg_thread_running) {
if (priv[0].flag)
LWP_ThreadSleep(oggplayer_queue); // wait only when i have samples to send
if (priv[0].flag == 0) { // wait to all samples are sended
if (ASND_TestPointer(0, priv[0].pcmout[priv[0].pcmout_pos])
&& ASND_StatusVoice(0) != SND_UNUSED) {
priv[0].flag |= 64;
continue;
}
if (priv[0].pcm_indx < READ_SAMPLES) {
priv[0].flag = 3;
if (priv[0].seek_time >= 0) {
ov_time_seek(&priv[0].vf, priv[0].seek_time);
priv[0].seek_time = -1;
}
ret
= ov_read(
&priv[0].vf,
(void *) &priv[0].pcmout[priv[0].pcmout_pos][priv[0].pcm_indx],
MAX_PCMOUT,/*0,2,1,*/&priv[0].current_section);
priv[0].flag &= 192;
if (ret == 0) {
/* EOF */
if (priv[0].mode & 1)
ov_time_seek(&priv[0].vf, 0); // repeat
else
priv[0].eof = 1; // stops
//
} else if (ret < 0) {
/* error in the stream. Not a problem, just reporting it in
case we (the app) cares. In this case, we don't. */
if (ret != OV_HOLE) {
if (priv[0].mode & 1)
ov_time_seek(&priv[0].vf, 0); // repeat
else
priv[0].eof = 1; // stops
}
} else {
/* we don't bother dealing with sample rate changes, etc, but
you'll have to*/
priv[0].pcm_indx += ret >> 1; //get 16 bits samples
}
} else
priv[0].flag = 1;
}
if (priv[0].flag == 1) {
if (ASND_StatusVoice(0) == SND_UNUSED || first_time) {
first_time = 0;
if (priv[0].vi->channels == 2) {
ASND_SetVoice(0, VOICE_STEREO_16BIT, priv[0].vi->rate, 0,
(void *) priv[0].pcmout[priv[0].pcmout_pos],
priv[0].pcm_indx << 1, priv[0].volume,
priv[0].volume, ogg_add_callback);
priv[0].pcmout_pos ^= 1;
priv[0].pcm_indx = 0;
priv[0].flag = 0;
} else {
ASND_SetVoice(0, VOICE_MONO_16BIT, priv[0].vi->rate, 0,
(void *) priv[0].pcmout[priv[0].pcmout_pos],
priv[0].pcm_indx << 1, priv[0].volume,
priv[0].volume, ogg_add_callback);
priv[0].pcmout_pos ^= 1;
priv[0].pcm_indx = 0;
priv[0].flag = 0;
}
}
}
usleep(100);
}
ov_clear(&priv[0].vf);
priv[0].fd = -1;
priv[0].pcm_indx = 0;
ogg_thread_running = 0;
return 0;
}
void StopOgg() {
ASND_StopVoice(0);
ogg_thread_running = 0;
if (h_oggplayer != LWP_THREAD_NULL) {
if (oggplayer_queue != LWP_TQUEUE_NULL)
LWP_ThreadSignal(oggplayer_queue);
LWP_JoinThread(h_oggplayer, NULL);
h_oggplayer = LWP_THREAD_NULL;
}
if (oggplayer_queue != LWP_TQUEUE_NULL) {
LWP_CloseQueue(oggplayer_queue);
oggplayer_queue = LWP_TQUEUE_NULL;
}
}
int PlayOgg(int fd, int time_pos, int mode) {
StopOgg();
private_ogg.fd = fd;
private_ogg.mode = mode;
private_ogg.eof = 0;
private_ogg.volume = 127;
private_ogg.flag = 0;
private_ogg.seek_time = -1;
if (time_pos > 0)
private_ogg.seek_time = time_pos;
if (fd < 0) {
private_ogg.fd = -1;
return -1;
}
if (ov_open((void *) &private_ogg.fd, &private_ogg.vf, NULL, 0) < 0) {
mem_close(private_ogg.fd); // mem_close() can too close files from devices
private_ogg.fd = -1;
ogg_thread_running = 0;
return -1;
}
if (LWP_CreateThread(&h_oggplayer, (void *) ogg_player_thread,
&private_ogg, oggplayer_stack, STACKSIZE, 80) == -1) {
ogg_thread_running = 0;
ov_clear(&private_ogg.vf);
private_ogg.fd = -1;
return -1;
}
return 0;
}
int PlayOggFromFile(char * path, int loop) {
StopOgg();
u32 filesize = 0;
char * bufferogg = NULL;
size_t resultogg;
FILE * pFile;
pFile = fopen (path, "rb");
//Check that pFile exist
if (pFile==NULL) {
return -1;
}
// get file size:
fseek (pFile , 0 , SEEK_END);
filesize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
bufferogg = (char*) malloc (sizeof(char)*filesize);
if (bufferogg == NULL) {
fputs (" Memory error",stderr);
exit (2);
}
// copy the file into the buffer:
resultogg = fread (bufferogg,1,filesize,pFile);
if (resultogg != filesize) {
fputs (" Reading error",stderr);
exit (3);
}
fclose (pFile);
if (loop)
return PlayOgg(mem_open((char *)bufferogg, filesize), 0, OGG_INFINITE_TIME);
else
return PlayOgg(mem_open((char *)bufferogg, filesize), 0, OGG_ONE_TIME);
}
void PauseOgg(int pause) {
if (pause) {
private_ogg.flag |= 128;
} else {
if (private_ogg.flag & 128) {
private_ogg.flag |= 64;
private_ogg.flag &= ~128;
if (ogg_thread_running > 0) {
LWP_ThreadSignal(oggplayer_queue);
}
}
}
}
int StatusOgg() {
if (ogg_thread_running == 0)
return -1; // Error
else if (private_ogg.eof)
return 255; // EOF
else if (private_ogg.flag & 128)
return 2; // paused
else
return 1; // running
}
void SetVolumeOgg(int volume) {
private_ogg.volume = volume;
ASND_ChangeVolumeVoice(0, volume, volume);
}
s32 GetTimeOgg() {
int ret;
if (ogg_thread_running == 0 || private_ogg.fd < 0)
return 0;
ret = ((s32) ov_time_tell(&private_ogg.vf));
if (ret < 0)
ret = 0;
return ret;
}
void SetTimeOgg(s32 time_pos) {
if (time_pos >= 0)
private_ogg.seek_time = time_pos;
}

View File

@ -1,175 +0,0 @@
/*
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __OGGPLAYER_H__
#define __OGGPLAYER_H__
#include <asndlib.h>
#include "tremor/ivorbiscodec.h"
#include "tremor/ivorbisfile.h"
#ifdef __cplusplus
extern "C" {
#endif
#define OGG_ONE_TIME 0
#define OGG_INFINITE_TIME 1
#define OGG_STATUS_RUNNING 1
#define OGG_STATUS_ERR -1
#define OGG_STATUS_PAUSED 2
#define OGG_STATUS_EOF 255
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* Player OGG functions */
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int PlayOgg(int fd, int time_pos, int mode);
Play an Ogg file. This file can be loaded from memory (mem_open(void *ogg, int size_ogg)) or from device with open("device:file.ogg",O_RDONLY,0);
NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail.
-- Params ---
fd: file descriptor from open() or mem_open()
time_pos: initial time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
mode: Use OGG_ONE_TIME or OGG_INFINITE_TIME. When you use OGG_ONE_TIME the sound stops and StatusOgg() return OGG_STATUS_EOF
return: 0- Ok, -1 Error
*/
int PlayOgg(int fd, int time_pos, int mode);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int PlayOgg(char * path, int loop);
Just give the function the full device+path to OGG to play it
loop = 1 for Loop and 0 for one time playing
*/
int PlayOggFromFile(char * path, int loop);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void StopOgg();
Stop an Ogg file.
NOTE: The file is closed and the player thread is released
-- Params ---
*/
void StopOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void PauseOgg(int pause);
Pause an Ogg file.
-- Params ---
pause: 0 -> continue, 1-> pause
*/
void PauseOgg(int pause);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* int StatusOgg();
Return the Ogg status
-- Params ---
return: OGG_STATUS_RUNNING
OGG_STATUS_ERR -> not initialized?
OGG_STATUS_PAUSED
OGG_STATUS_EOF -> player stopped by End Of File
*/
int StatusOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void SetVolumeOgg(int volume);
Set the Ogg playing volume.
NOTE: it change the volume of voice 0 (used for the Ogg player)
-- Params ---
volume: 0 to 255 (max)
*/
void SetVolumeOgg(int volume);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* s32 GetTimeOgg();
Return the Ogg time from the starts of the file
-- Params ---
return: 0 -> Ok or error condition (you must ignore this value)
>0 -> time in milliseconds from the starts
*/
s32 GetTimeOgg();
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* void SetTimeOgg(s32 time_pos);
Set the time position
NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail.
-- Params ---
time_pos: time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
*/
void SetTimeOgg(s32 time_pos);
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -141,8 +141,10 @@ int DiscBrowse(struct discHdr * header) {
return -1; return -1;
} }
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
@ -176,7 +178,7 @@ int DiscBrowse(struct discHdr * header) {
cancelBtnTxt.SetWidescreen(CFG.widescreen); cancelBtnTxt.SetWidescreen(CFG.widescreen);
cancelBtnImg.SetWidescreen(CFG.widescreen); cancelBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, &btnClick,1); GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2,1);
cancelBtn.SetScale(0.9); cancelBtn.SetScale(0.9);
cancelBtn.SetLabel(&cancelBtnTxt); cancelBtn.SetLabel(&cancelBtnTxt);
cancelBtn.SetTrigger(&trigB); cancelBtn.SetTrigger(&trigB);

View File

@ -33,11 +33,11 @@
#include "svnrev.h" #include "svnrev.h"
#include "audio.h" #include "audio.h"
#include "xml/xml.h" #include "xml/xml.h"
#include "../wad/title.h" #include "wad/title.h"
#include "language/UpdateLanguage.h" #include "language/UpdateLanguage.h"
#include "gecko.h" #include "gecko.h"
#include "../lstub.h" #include "lstub.h"
#include "Game_Sound.h" #include "bannersound.h"
@ -84,8 +84,10 @@ int OnScreenKeyboard(char * var, u32 maxlen, int min) {
GuiKeyboard keyboard(var, maxlen, min, keyset); GuiKeyboard keyboard(var, maxlen, min, keyset);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size,Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -102,7 +104,7 @@ int OnScreenKeyboard(char * var, u32 maxlen, int min) {
okBtnTxt.SetWidescreen(CFG.widescreen); okBtnTxt.SetWidescreen(CFG.widescreen);
okBtnImg.SetWidescreen(CFG.widescreen); okBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 5, 15, &trigA, &btnSoundOver, &btnClick,1); GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 5, 15, &trigA, &btnSoundOver, btnClick2,1);
okBtn.SetLabel(&okBtnTxt); okBtn.SetLabel(&okBtnTxt);
GuiText cancelBtnTxt(tr("Cancel"), 22, THEME.prompttext); GuiText cancelBtnTxt(tr("Cancel"), 22, THEME.prompttext);
GuiImage cancelBtnImg(&btnOutline); GuiImage cancelBtnImg(&btnOutline);
@ -110,7 +112,7 @@ int OnScreenKeyboard(char * var, u32 maxlen, int min) {
cancelBtnTxt.SetWidescreen(CFG.widescreen); cancelBtnTxt.SetWidescreen(CFG.widescreen);
cancelBtnImg.SetWidescreen(CFG.widescreen); cancelBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 1, 4, -5, 15, &trigA, &btnSoundOver, &btnClick,1); GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 1, 4, -5, 15, &trigA, &btnSoundOver, btnClick2,1);
cancelBtn.SetLabel(&cancelBtnTxt); cancelBtn.SetLabel(&cancelBtnTxt);
cancelBtn.SetTrigger(&trigB); cancelBtn.SetTrigger(&trigB);
@ -154,10 +156,9 @@ void WindowCredits() {
int angle = 0; int angle = 0;
GuiSound * creditsMusic = NULL; GuiSound * creditsMusic = NULL;
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
StopOgg();
creditsMusic = new GuiSound(credits_music_ogg, credits_music_ogg_size, SOUND_OGG, 55); creditsMusic = new GuiSound(credits_music_ogg, credits_music_ogg_size, 55);
creditsMusic->SetVolume(60); creditsMusic->SetVolume(60);
creditsMusic->SetLoop(1); creditsMusic->SetLoop(1);
creditsMusic->Play(); creditsMusic->Play();
@ -366,13 +367,7 @@ void WindowCredits() {
} }
ResumeGui(); ResumeGui();
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) { bgMusic->Resume();
bgMusic->Play();
} else {
bgMusic->PlayOggFile(Settings.ogg_path);
}
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
} }
/**************************************************************************** /****************************************************************************
@ -450,8 +445,10 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label,
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png); GuiImageData btnOutline(imgPath, button_dialogue_box_png);
@ -484,7 +481,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label,
btn1Img.SetWidescreen(CFG.widescreen); btn1Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn1(&btn1Img, &btn1Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1); GuiButton btn1(&btn1Img, &btn1Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
btn1.SetLabel(&btn1Txt); btn1.SetLabel(&btn1Txt);
btn1.SetState(STATE_SELECTED); btn1.SetState(STATE_SELECTED);
@ -494,7 +491,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label,
btn2Txt.SetWidescreen(CFG.widescreen); btn2Txt.SetWidescreen(CFG.widescreen);
btn2Img.SetWidescreen(CFG.widescreen); btn2Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn2(&btn2Img, &btn2Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1); GuiButton btn2(&btn2Img, &btn2Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
btn2.SetLabel(&btn2Txt); btn2.SetLabel(&btn2Txt);
if (!btn3Label && !btn4Label) if (!btn3Label && !btn4Label)
btn2.SetTrigger(&trigB); btn2.SetTrigger(&trigB);
@ -505,7 +502,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label,
btn3Txt.SetWidescreen(CFG.widescreen); btn3Txt.SetWidescreen(CFG.widescreen);
btn3Img.SetWidescreen(CFG.widescreen); btn3Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn3(&btn3Img, &btn3Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1); GuiButton btn3(&btn3Img, &btn3Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
btn3.SetLabel(&btn3Txt); btn3.SetLabel(&btn3Txt);
if (!btn4Label) if (!btn4Label)
btn3.SetTrigger(&trigB); btn3.SetTrigger(&trigB);
@ -516,7 +513,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label,
btn4Txt.SetWidescreen(CFG.widescreen); btn4Txt.SetWidescreen(CFG.widescreen);
btn4Img.SetWidescreen(CFG.widescreen); btn4Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn4(&btn4Img, &btn4Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1); GuiButton btn4(&btn4Img, &btn4Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
btn4.SetLabel(&btn4Txt); btn4.SetLabel(&btn4Txt);
if (btn4Label) if (btn4Label)
btn4.SetTrigger(&trigB); btn4.SetTrigger(&trigB);
@ -696,13 +693,13 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
gprintf("\nWindowExitPrompt()"); gprintf("\nWindowExitPrompt()");
GuiSound * homein = NULL; GuiSound * homein = NULL;
homein = new GuiSound(menuin_ogg, menuin_ogg_size, SOUND_OGG, Settings.sfxvolume); homein = new GuiSound(menuin_ogg, menuin_ogg_size, Settings.sfxvolume);
homein->SetVolume(Settings.sfxvolume); homein->SetVolume(Settings.sfxvolume);
homein->SetLoop(0); homein->SetLoop(0);
homein->Play(); homein->Play();
GuiSound * homeout = NULL; GuiSound * homeout = NULL;
homeout = new GuiSound(menuout_ogg, menuout_ogg_size, SOUND_OGG, Settings.sfxvolume); homeout = new GuiSound(menuout_ogg, menuout_ogg_size, Settings.sfxvolume);
homeout->SetVolume(Settings.sfxvolume); homeout->SetVolume(Settings.sfxvolume);
homeout->SetLoop(0); homeout->SetLoop(0);
@ -717,8 +714,10 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
GuiWindow promptWindow(640,480); GuiWindow promptWindow(640,480);
promptWindow.SetAlignment(ALIGN_LEFT, ALIGN_TOP); promptWindow.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
promptWindow.SetPosition(0, 0); promptWindow.SetPosition(0, 0);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
GuiImageData top(exit_top_png); GuiImageData top(exit_top_png);
GuiImageData topOver(exit_top_over_png); GuiImageData topOver(exit_top_over_png);
@ -810,7 +809,7 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
GuiImage btn1Img(&top); GuiImage btn1Img(&top);
GuiImage btn1OverImg(&topOver); GuiImage btn1OverImg(&topOver);
GuiButton btn1(&btn1Img,&btn1OverImg, 0, 3, 0, 0, &trigA, &btnSoundOver, &btnClick,0); GuiButton btn1(&btn1Img,&btn1OverImg, 0, 3, 0, 0, &trigA, &btnSoundOver, btnClick2,0);
btn1.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50); btn1.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50);
GuiText btn2Txt(btn1Label, 28, (GXColor) {0, 0, 0, 255}); GuiText btn2Txt(btn1Label, 28, (GXColor) {0, 0, 0, 255});
@ -819,7 +818,7 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
btn2Txt.SetWidescreen(CFG.widescreen); btn2Txt.SetWidescreen(CFG.widescreen);
btn2Img.SetWidescreen(CFG.widescreen); btn2Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn2(&btn2Img,&btn2Img, 2, 5, -150, 0, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn2(&btn2Img,&btn2Img, 2, 5, -150, 0, &trigA, &btnSoundOver, btnClick2,1);
btn2.SetLabel(&btn2Txt); btn2.SetLabel(&btn2Txt);
btn2.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 50); btn2.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 50);
btn2.SetRumble(false); btn2.SetRumble(false);
@ -832,7 +831,7 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
btn3Txt.SetWidescreen(CFG.widescreen); btn3Txt.SetWidescreen(CFG.widescreen);
btn3Img.SetWidescreen(CFG.widescreen); btn3Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn3(&btn3Img,&btn3Img, 2, 5, 150, 0, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn3(&btn3Img,&btn3Img, 2, 5, 150, 0, &trigA, &btnSoundOver, btnClick2,1);
btn3.SetLabel(&btn3Txt); btn3.SetLabel(&btn3Txt);
btn3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 50); btn3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 50);
btn3.SetRumble(false); btn3.SetRumble(false);
@ -840,7 +839,7 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
GuiImage btn4Img(&bottom); GuiImage btn4Img(&bottom);
GuiImage btn4OverImg(&bottomOver); GuiImage btn4OverImg(&bottomOver);
GuiButton btn4(&btn4Img,&btn4OverImg, 0, 4, 0, 0, &trigA, &btnSoundOver, &btnClick,0); GuiButton btn4(&btn4Img,&btn4OverImg, 0, 4, 0, 0, &trigA, &btnSoundOver, btnClick2,0);
btn4.SetTrigger(&trigB); btn4.SetTrigger(&trigB);
btn4.SetTrigger(&trigHome); btn4.SetTrigger(&trigHome);
btn4.SetEffect(EFFECT_SLIDE_BOTTOM | EFFECT_SLIDE_IN, 50); btn4.SetEffect(EFFECT_SLIDE_BOTTOM | EFFECT_SLIDE_IN, 50);
@ -1025,14 +1024,16 @@ int GameWindowPrompt() {
char ID[5]; char ID[5];
char IDFull[7]; char IDFull[7];
GameSound * gameSound = NULL; GuiSound * gameSound = NULL;
gprintf("\nGameWindowPrompt()"); gprintf("\nGameWindowPrompt()");
GuiWindow promptWindow(472,320); GuiWindow promptWindow(472,320);
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -1082,7 +1083,7 @@ int GameWindowPrompt() {
nameBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); nameBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
nameBtn.SetPosition(0,-122); nameBtn.SetPosition(0,-122);
nameBtn.SetSoundOver(&btnSoundOver); nameBtn.SetSoundOver(&btnSoundOver);
nameBtn.SetSoundClick(&btnClick); nameBtn.SetSoundClick(btnClick2);
if (!mountMethod) nameBtn.SetToolTip(&nameBtnTT,24,-30, ALIGN_LEFT); if (!mountMethod) nameBtn.SetToolTip(&nameBtnTT,24,-30, ALIGN_LEFT);
if (Settings.godmode == 1 && !mountMethod) { if (Settings.godmode == 1 && !mountMethod) {
@ -1116,7 +1117,7 @@ int GameWindowPrompt() {
btn1.SetImage(&diskImg); btn1.SetImage(&diskImg);
btn1.SetSoundOver(&btnSoundOver); btn1.SetSoundOver(&btnSoundOver);
btn1.SetSoundClick(&btnClick); btn1.SetSoundClick(btnClick2);
btn1.SetTrigger(&trigA); btn1.SetTrigger(&trigA);
btn1.SetState(STATE_SELECTED); btn1.SetState(STATE_SELECTED);
@ -1126,7 +1127,7 @@ int GameWindowPrompt() {
btn2Txt.SetWidescreen(CFG.widescreen); btn2Txt.SetWidescreen(CFG.widescreen);
btn2Img.SetWidescreen(CFG.widescreen); btn2Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn2(&btn2Img,&btn2Img, 1, 5, 0, 0, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn2(&btn2Img,&btn2Img, 1, 5, 0, 0, &trigA, &btnSoundOver, btnClick2,1);
if (Settings.godmode == 1 && mountMethod!=2 && mountMethod!=3) { if (Settings.godmode == 1 && mountMethod!=2 && mountMethod!=3) {
btn2.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM); btn2.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
btn2.SetPosition(-50, -40); btn2.SetPosition(-50, -40);
@ -1144,7 +1145,7 @@ int GameWindowPrompt() {
btn3Txt.SetWidescreen(CFG.widescreen); btn3Txt.SetWidescreen(CFG.widescreen);
btn3Img.SetWidescreen(CFG.widescreen); btn3Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn3(&btn3Img,&btn3Img, 0, 4, 50, -40, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn3(&btn3Img,&btn3Img, 0, 4, 50, -40, &trigA, &btnSoundOver, btnClick2,1);
btn3.SetLabel(&btn3Txt); btn3.SetLabel(&btn3Txt);
GuiImage btnFavoriteImg1; GuiImage btnFavoriteImg1;
@ -1165,17 +1166,17 @@ int GameWindowPrompt() {
GuiButton btnFavorite4(imgFavorite.GetWidth(), imgFavorite.GetHeight()); GuiButton btnFavorite4(imgFavorite.GetWidth(), imgFavorite.GetHeight());
GuiButton btnFavorite5(imgFavorite.GetWidth(), imgFavorite.GetHeight()); GuiButton btnFavorite5(imgFavorite.GetWidth(), imgFavorite.GetHeight());
SetupFavoriteButton(&btnFavorite1, -198, &btnFavoriteImg1, &btnSoundOver, &btnClick, &trigA); SetupFavoriteButton(&btnFavorite1, -198, &btnFavoriteImg1, &btnSoundOver, btnClick2, &trigA);
SetupFavoriteButton(&btnFavorite2, -171, &btnFavoriteImg2, &btnSoundOver, &btnClick, &trigA); SetupFavoriteButton(&btnFavorite2, -171, &btnFavoriteImg2, &btnSoundOver, btnClick2, &trigA);
SetupFavoriteButton(&btnFavorite3, -144, &btnFavoriteImg3, &btnSoundOver, &btnClick, &trigA); SetupFavoriteButton(&btnFavorite3, -144, &btnFavoriteImg3, &btnSoundOver, btnClick2, &trigA);
SetupFavoriteButton(&btnFavorite4, -117, &btnFavoriteImg4, &btnSoundOver, &btnClick, &trigA); SetupFavoriteButton(&btnFavorite4, -117, &btnFavoriteImg4, &btnSoundOver, btnClick2, &trigA);
SetupFavoriteButton(&btnFavorite5, -90, &btnFavoriteImg5, &btnSoundOver, &btnClick, &trigA); SetupFavoriteButton(&btnFavorite5, -90, &btnFavoriteImg5, &btnSoundOver, btnClick2, &trigA);
GuiImage btnLeftImg(&imgLeft); GuiImage btnLeftImg(&imgLeft);
if (Settings.wsprompt == yes) { if (Settings.wsprompt == yes) {
btnLeftImg.SetWidescreen(CFG.widescreen); btnLeftImg.SetWidescreen(CFG.widescreen);
} }
GuiButton btnLeft(&btnLeftImg,&btnLeftImg, 0, 5, 20, 0, &trigA, &btnSoundOver, &btnClick,1); GuiButton btnLeft(&btnLeftImg,&btnLeftImg, 0, 5, 20, 0, &trigA, &btnSoundOver, btnClick2,1);
btnLeft.SetTrigger(&trigL); btnLeft.SetTrigger(&trigL);
btnLeft.SetTrigger(&trigMinus); btnLeft.SetTrigger(&trigMinus);
@ -1183,7 +1184,7 @@ int GameWindowPrompt() {
if (Settings.wsprompt == yes) { if (Settings.wsprompt == yes) {
btnRightImg.SetWidescreen(CFG.widescreen); btnRightImg.SetWidescreen(CFG.widescreen);
} }
GuiButton btnRight(&btnRightImg,&btnRightImg, 1, 5, -20, 0, &trigA, &btnSoundOver, &btnClick,1); GuiButton btnRight(&btnRightImg,&btnRightImg, 1, 5, -20, 0, &trigA, &btnSoundOver, btnClick2,1);
btnRight.SetTrigger(&trigR); btnRight.SetTrigger(&trigR);
btnRight.SetTrigger(&trigPlus); btnRight.SetTrigger(&trigPlus);
@ -1233,20 +1234,23 @@ int GameWindowPrompt() {
//load disc image based or what game is seleted //load disc image based or what game is seleted
struct discHdr * header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); struct discHdr * header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]);
if(Settings.gamesound) if(Settings.gamesound)
{ {
if(gameSound) if(gameSound)
{ {
gameSound->Stop();
delete gameSound; delete gameSound;
gameSound = NULL; gameSound = NULL;
} }
u32 gameSoundDataLen;
gameSound = new GameSound(header->id); const u8 *gameSoundData = LoadBannerSound(header->id, &gameSoundDataLen);
if(gameSoundData)
{
gameSound = new GuiSound(gameSoundData, gameSoundDataLen, Settings.gamesoundvolume, false, true);
bgMusic->SetVolume(0); bgMusic->SetVolume(0);
gameSound->SetVolume(Settings.gamesoundvolume);
gameSound->Play(); gameSound->Play();
} }
}
snprintf (ID,sizeof(ID),"%c%c%c", header->id[0], header->id[1], header->id[2]); snprintf (ID,sizeof(ID),"%c%c%c", header->id[0], header->id[1], header->id[2]);
snprintf (IDFull,sizeof(IDFull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]); snprintf (IDFull,sizeof(IDFull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]);
@ -1455,7 +1459,7 @@ int GameWindowPrompt() {
else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == no)) {//next game else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == no)) {//next game
promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50);
changed = 1; changed = 1;
btnClick.Play(); btnClick2->Play();
gameSelected = (gameSelected + 1) % gameCnt; gameSelected = (gameSelected + 1) % gameCnt;
btnRight.ResetState(); btnRight.ResetState();
break; break;
@ -1464,7 +1468,7 @@ int GameWindowPrompt() {
else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == no)) {//previous game else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == no)) {//previous game
promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50);
changed = 2; changed = 2;
btnClick.Play(); btnClick2->Play();
gameSelected = (gameSelected - 1 + gameCnt) % gameCnt; gameSelected = (gameSelected - 1 + gameCnt) % gameCnt;
btnLeft.ResetState(); btnLeft.ResetState();
break; break;
@ -1473,7 +1477,7 @@ int GameWindowPrompt() {
else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == yes)) {//previous game else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == yes)) {//previous game
promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50);
changed = 2; changed = 2;
btnClick.Play(); btnClick2->Play();
gameSelected = (gameSelected - 1 + gameCnt) % gameCnt; gameSelected = (gameSelected - 1 + gameCnt) % gameCnt;
btnRight.ResetState(); btnRight.ResetState();
break; break;
@ -1482,7 +1486,7 @@ int GameWindowPrompt() {
else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == yes)) {//next game else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == yes)) {//next game
promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50);
changed = 1; changed = 1;
btnClick.Play(); btnClick2->Play();
gameSelected = (gameSelected + 1) % gameCnt; gameSelected = (gameSelected + 1) % gameCnt;
btnLeft.ResetState(); btnLeft.ResetState();
break; break;
@ -1491,7 +1495,7 @@ int GameWindowPrompt() {
else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == sysmenu)) {//previous game else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == sysmenu)) {//previous game
promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50);
changed = 2; changed = 2;
btnClick.Play(); btnClick2->Play();
gameSelected = (gameSelected + 1) % gameCnt; gameSelected = (gameSelected + 1) % gameCnt;
btnRight.ResetState(); btnRight.ResetState();
break; break;
@ -1500,7 +1504,7 @@ int GameWindowPrompt() {
else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == sysmenu)) {//next game else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == sysmenu)) {//next game
promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50);
changed = 1; changed = 1;
btnClick.Play(); btnClick2->Play();
gameSelected = (gameSelected - 1 + gameCnt) % gameCnt; gameSelected = (gameSelected - 1 + gameCnt) % gameCnt;
btnLeft.ResetState(); btnLeft.ResetState();
break; break;
@ -1509,7 +1513,7 @@ int GameWindowPrompt() {
else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == wtf)) {//previous game else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == wtf)) {//previous game
promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50);
changed = 1; changed = 1;
btnClick.Play(); btnClick2->Play();
gameSelected = (gameSelected - 1 + gameCnt) % gameCnt; gameSelected = (gameSelected - 1 + gameCnt) % gameCnt;
btnRight.ResetState(); btnRight.ResetState();
break; break;
@ -1518,7 +1522,7 @@ int GameWindowPrompt() {
else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == wtf)) {//next game else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == wtf)) {//next game
promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50);
changed = 2; changed = 2;
btnClick.Play(); btnClick2->Play();
gameSelected = (gameSelected + 1) % gameCnt; gameSelected = (gameSelected + 1) % gameCnt;
btnLeft.ResetState(); btnLeft.ResetState();
break; break;
@ -1527,7 +1531,7 @@ int GameWindowPrompt() {
else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == disk3d)) {//next game else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == disk3d)) {//next game
// diskImg.SetBetaRotateEffect(45, 90); // diskImg.SetBetaRotateEffect(45, 90);
changed = 3; changed = 3;
btnClick.Play(); btnClick2->Play();
gameSelected = (gameSelected + 1) % gameCnt; gameSelected = (gameSelected + 1) % gameCnt;
btnRight.ResetState(); btnRight.ResetState();
break; break;
@ -1537,7 +1541,7 @@ int GameWindowPrompt() {
// diskImg.SetBetaRotateEffect(-45, 90); // diskImg.SetBetaRotateEffect(-45, 90);
// promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 1/*50*/); // promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 1/*50*/);
changed = 4; changed = 4;
btnClick.Play(); btnClick2->Play();
gameSelected = (gameSelected - 1 + gameCnt) % gameCnt; gameSelected = (gameSelected - 1 + gameCnt) % gameCnt;
btnLeft.ResetState(); btnLeft.ResetState();
break; break;
@ -1557,6 +1561,7 @@ int GameWindowPrompt() {
if(gameSound) if(gameSound)
{ {
gameSound->Stop();
delete gameSound; delete gameSound;
gameSound = NULL; gameSound = NULL;
} }
@ -1577,8 +1582,10 @@ DiscWait(const char *title, const char *msg, const char *btn1Label, const char *
GuiWindow promptWindow(472,320); GuiWindow promptWindow(472,320);
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -1609,7 +1616,7 @@ DiscWait(const char *title, const char *msg, const char *btn1Label, const char *
btn1Txt.SetWidescreen(CFG.widescreen); btn1Txt.SetWidescreen(CFG.widescreen);
btn1Img.SetWidescreen(CFG.widescreen); btn1Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn1(&btn1Img,&btn1Img, 1, 5, 0, 0, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn1(&btn1Img,&btn1Img, 1, 5, 0, 0, &trigA, &btnSoundOver, btnClick2,1);
if (btn2Label) { if (btn2Label) {
btn1.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM); btn1.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
@ -1629,7 +1636,7 @@ DiscWait(const char *title, const char *msg, const char *btn1Label, const char *
btn2Txt.SetWidescreen(CFG.widescreen); btn2Txt.SetWidescreen(CFG.widescreen);
btn2Img.SetWidescreen(CFG.widescreen); btn2Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn2(&btn2Img,&btn2Img, 1, 4, -20, -25, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn2(&btn2Img,&btn2Img, 1, 4, -20, -25, &trigA, &btnSoundOver, btnClick2,1);
btn2.SetLabel(&btn2Txt); btn2.SetLabel(&btn2Txt);
if ((Settings.wsprompt == yes) && (CFG.widescreen)) {/////////////adjust buttons for widescreen if ((Settings.wsprompt == yes) && (CFG.widescreen)) {/////////////adjust buttons for widescreen
@ -1771,8 +1778,10 @@ bool SearchMissingImages(int choice2) {
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -1890,8 +1899,10 @@ bool NetworkInitPrompt() {
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -1922,7 +1933,7 @@ bool NetworkInitPrompt() {
btn1Txt.SetWidescreen(CFG.widescreen); btn1Txt.SetWidescreen(CFG.widescreen);
btn1Img.SetWidescreen(CFG.widescreen); btn1Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -45, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -45, &trigA, &btnSoundOver, btnClick2,1);
btn1.SetLabel(&btn1Txt); btn1.SetLabel(&btn1Txt);
btn1.SetState(STATE_SELECTED); btn1.SetState(STATE_SELECTED);
@ -1990,8 +2001,10 @@ ProgressDownloadWindow(int choice2) {
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -2050,7 +2063,7 @@ ProgressDownloadWindow(int choice2) {
btn1Txt.SetWidescreen(CFG.widescreen); btn1Txt.SetWidescreen(CFG.widescreen);
btn1Img.SetWidescreen(CFG.widescreen); btn1Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -45, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -45, &trigA, &btnSoundOver, btnClick2,1);
btn1.SetLabel(&btn1Txt); btn1.SetLabel(&btn1Txt);
btn1.SetState(STATE_SELECTED); btn1.SetState(STATE_SELECTED);
@ -2472,8 +2485,10 @@ int ProgressUpdateWindow() {
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -2535,7 +2550,7 @@ int ProgressUpdateWindow() {
btn1Txt.SetWidescreen(CFG.widescreen); btn1Txt.SetWidescreen(CFG.widescreen);
btn1Img.SetWidescreen(CFG.widescreen); btn1Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, btnClick2,1);
btn1.SetLabel(&btn1Txt); btn1.SetLabel(&btn1Txt);
btn1.SetState(STATE_SELECTED); btn1.SetState(STATE_SELECTED);
@ -2800,7 +2815,9 @@ int ProgressUpdateWindow() {
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -3103,8 +3120,10 @@ int CodeDownload(const char *id) {
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -3142,7 +3161,7 @@ int CodeDownload(const char *id) {
btn1Txt.SetWidescreen(CFG.widescreen); btn1Txt.SetWidescreen(CFG.widescreen);
btn1Img.SetWidescreen(CFG.widescreen); btn1Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, btnClick2,1);
btn1.SetLabel(&btn1Txt); btn1.SetLabel(&btn1Txt);
btn1.SetState(STATE_SELECTED); btn1.SetState(STATE_SELECTED);
@ -3278,8 +3297,10 @@ HBCWindowPrompt(const char *name, const char *coder, const char *version,
GuiTrigger trigD; GuiTrigger trigD;
trigD.SetButtonOnlyTrigger(-1, WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN, PAD_BUTTON_DOWN); trigD.SetButtonOnlyTrigger(-1, WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN, PAD_BUTTON_DOWN);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png); GuiImageData btnOutline(imgPath, button_dialogue_box_png);
@ -3312,7 +3333,7 @@ HBCWindowPrompt(const char *name, const char *coder, const char *version,
arrowUpBtn.SetTrigger(&trigA); arrowUpBtn.SetTrigger(&trigA);
arrowUpBtn.SetTrigger(&trigU); arrowUpBtn.SetTrigger(&trigU);
arrowUpBtn.SetEffectOnOver(EFFECT_SCALE, 50, 130); arrowUpBtn.SetEffectOnOver(EFFECT_SCALE, 50, 130);
arrowUpBtn.SetSoundClick(&btnClick); arrowUpBtn.SetSoundClick(btnClick2);
GuiButton arrowDownBtn(arrowDownImg.GetWidth(), arrowDownImg.GetHeight()); GuiButton arrowDownBtn(arrowDownImg.GetWidth(), arrowDownImg.GetHeight());
arrowDownBtn.SetImage(&arrowDownImg); arrowDownBtn.SetImage(&arrowDownImg);
@ -3321,7 +3342,7 @@ HBCWindowPrompt(const char *name, const char *coder, const char *version,
arrowDownBtn.SetTrigger(&trigA); arrowDownBtn.SetTrigger(&trigA);
arrowDownBtn.SetTrigger(&trigD); arrowDownBtn.SetTrigger(&trigD);
arrowDownBtn.SetEffectOnOver(EFFECT_SCALE, 50, 130); arrowDownBtn.SetEffectOnOver(EFFECT_SCALE, 50, 130);
arrowDownBtn.SetSoundClick(&btnClick); arrowDownBtn.SetSoundClick(btnClick2);
GuiImageData *iconData =NULL; GuiImageData *iconData =NULL;
GuiImage *iconImg =NULL; GuiImage *iconImg =NULL;
@ -3415,7 +3436,7 @@ HBCWindowPrompt(const char *name, const char *coder, const char *version,
btn1Img.SetWidescreen(CFG.widescreen); btn1Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn1(&btn1Img, &btn1Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1); GuiButton btn1(&btn1Img, &btn1Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
btn1.SetLabel(&btn1Txt); btn1.SetLabel(&btn1Txt);
btn1.SetState(STATE_SELECTED); btn1.SetState(STATE_SELECTED);
@ -3425,7 +3446,7 @@ HBCWindowPrompt(const char *name, const char *coder, const char *version,
btn2Txt.SetWidescreen(CFG.widescreen); btn2Txt.SetWidescreen(CFG.widescreen);
btn2Img.SetWidescreen(CFG.widescreen); btn2Img.SetWidescreen(CFG.widescreen);
} }
GuiButton btn2(&btn2Img, &btn2Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1); GuiButton btn2(&btn2Img, &btn2Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
btn2.SetLabel(&btn2Txt); btn2.SetLabel(&btn2Txt);
btn2.SetTrigger(&trigB); btn2.SetTrigger(&trigB);

View File

@ -230,8 +230,10 @@ int TitleBrowser(u32 type) {
if (IsNetworkInit()) if (IsNetworkInit())
ResumeNetworkWait(); ResumeNetworkWait();
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
@ -265,7 +267,7 @@ int TitleBrowser(u32 type) {
cancelBtnTxt.SetWidescreen(CFG.widescreen); cancelBtnTxt.SetWidescreen(CFG.widescreen);
cancelBtnImg.SetWidescreen(CFG.widescreen); cancelBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, &btnClick,1); GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2,1);
cancelBtn.SetScale(0.9); cancelBtn.SetScale(0.9);
cancelBtn.SetLabel(&cancelBtnTxt); cancelBtn.SetLabel(&cancelBtnTxt);
cancelBtn.SetTrigger(&trigB); cancelBtn.SetTrigger(&trigB);

View File

@ -304,8 +304,10 @@ int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*=
GuiTrigger trigB; GuiTrigger trigB;
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
GuiImageData folderImgData(icon_folder_png); GuiImageData folderImgData(icon_folder_png);
GuiImage folderImg(&folderImgData); GuiImage folderImg(&folderImgData);
@ -354,7 +356,7 @@ int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*=
okBtnTxt.SetWidescreen(CFG.widescreen); okBtnTxt.SetWidescreen(CFG.widescreen);
okBtnImg.SetWidescreen(CFG.widescreen); okBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 40, -35, &trigA, &btnSoundOver, &btnClick,1); GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 40, -35, &trigA, &btnSoundOver, btnClick2,1);
okBtn.SetLabel(&okBtnTxt); okBtn.SetLabel(&okBtnTxt);
GuiFileBrowser fileBrowser(396, 248); GuiFileBrowser fileBrowser(396, 248);

View File

@ -148,8 +148,8 @@ int showGameInfo(char *ID) {
txtWindow.SetAlignment(ALIGN_CENTRE, ALIGN_RIGHT); txtWindow.SetAlignment(ALIGN_CENTRE, ALIGN_RIGHT);
txtWindow.SetPosition(95, 55); txtWindow.SetPosition(95, 55);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png); GuiImageData btnOutline(imgPath, button_dialogue_box_png);

View File

@ -11,7 +11,6 @@
#define NAMELENMAX 0x80 #define NAMELENMAX 0x80
#define MAXPATHLEN 0x100 #define MAXPATHLEN 0x100
#define FPRINTF(f, ...) {FILE*_fp=fopen("SD:/log.log", "a"); if(_fp) { fprintf(_fp, "%s(%i):" f "\n", __FILE__, __LINE__, ##__VA_ARGS__); fclose(_fp);}}
@ -533,7 +532,6 @@ static inline RAMDISK_PARTITION* ramdiskFS_getPartitionFromPath(const char* path
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
static int ramdiskFS_open_r(struct _reent *r, void *file_Struct, const char *path, int flags, int mode) { static int ramdiskFS_open_r(struct _reent *r, void *file_Struct, const char *path, int flags, int mode) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
FPRINTF("ramdiskFS_open_r(%s)", path);
FILE_STRUCT *fileStruct = (FILE_STRUCT*)file_Struct; FILE_STRUCT *fileStruct = (FILE_STRUCT*)file_Struct;
@ -543,7 +541,6 @@ FPRINTF("ramdiskFS_open_r(%s)", path);
r->_errno = ENODEV; r->_errno = ENODEV;
return -1; return -1;
} }
FPRINTF("ramdiskFS_open_r Partition found");
if ((flags & 0x03) == O_RDONLY) { if ((flags & 0x03) == O_RDONLY) {
// Open the file for read-only access // Open the file for read-only access
@ -569,14 +566,12 @@ FPRINTF("ramdiskFS_open_r Partition found");
r->_errno = EEXIST; r->_errno = EEXIST;
return -1; return -1;
} }
FPRINTF("ok");
// It should not be a directory if we're openning a file, // It should not be a directory if we're openning a file,
if (entry && entry->IsDir()) if (entry && entry->IsDir())
{ {
r->_errno = EISDIR; r->_errno = EISDIR;
return -1; return -1;
} }
FPRINTF("ok");
fileStruct->isLink = entry ? entry->IsLink() : false; fileStruct->isLink = entry ? entry->IsLink() : false;
fileStruct->file = entry ? entry->IsFile() : NULL; fileStruct->file = entry ? entry->IsFile() : NULL;
@ -600,7 +595,6 @@ FPRINTF("ok");
return -1; return -1;
} }
} }
FPRINTF("ok");
if(fileStruct->file) if(fileStruct->file)
{ {
fileStruct->current_pos = 0; fileStruct->current_pos = 0;
@ -610,7 +604,6 @@ FPRINTF("ok");
if (flags & O_APPEND) if (flags & O_APPEND)
fileStruct->current_pos = fileStruct->file->file_len; fileStruct->current_pos = fileStruct->file->file_len;
return 0; return 0;
FPRINTF("ramdiskFS_open_r ok");
} }
r->_errno = ENOENT; r->_errno = ENOENT;
return(-1); return(-1);
@ -641,7 +634,6 @@ static off_t ramdiskFS_seek_r(struct _reent *r, int fd, off_t pos, int dir) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
//need check for eof here... //need check for eof here...
FILE_STRUCT *fileStruct = (FILE_STRUCT*)fd; FILE_STRUCT *fileStruct = (FILE_STRUCT*)fd;
FPRINTF("ramdiskFS_seek_r(%s)", fileStruct->file->name);
switch(dir) switch(dir)
{ {
@ -663,7 +655,6 @@ FPRINTF("ramdiskFS_seek_r(%s)", fileStruct->file->name);
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
static int ramdiskFS_fstat_r(struct _reent *r, int fd, struct stat *st) { static int ramdiskFS_fstat_r(struct _reent *r, int fd, struct stat *st) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
FPRINTF("ramdiskFS_fstat_r");
FILE_STRUCT *fileStruct = (FILE_STRUCT*)fd; FILE_STRUCT *fileStruct = (FILE_STRUCT*)fd;
st->st_mode = fileStruct->isLink ? S_IFLNK : S_IFREG; st->st_mode = fileStruct->isLink ? S_IFLNK : S_IFREG;
@ -674,7 +665,6 @@ FPRINTF("ramdiskFS_fstat_r");
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
static int ramdiskFS_stat_r(struct _reent *r, const char *file, struct stat *st) { static int ramdiskFS_stat_r(struct _reent *r, const char *file, struct stat *st) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
FPRINTF("ramdiskFS_stat_r(%s)", file);
FILE_STRUCT fileStruct; FILE_STRUCT fileStruct;
DIR_STRUCT dirStruct; DIR_STRUCT dirStruct;
DIR_ITER dirState; DIR_ITER dirState;
@ -700,7 +690,6 @@ FPRINTF("ramdiskFS_stat_r(%s)", file);
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
static int ramdiskFS_unlink_r(struct _reent *r, const char *name) { static int ramdiskFS_unlink_r(struct _reent *r, const char *name) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
FPRINTF("ramdiskFS_unlink_r(%s)", name);
RAMDISK_PARTITION *partition = ramdiskFS_getPartitionFromPath(name); RAMDISK_PARTITION *partition = ramdiskFS_getPartitionFromPath(name);
if ( partition == NULL ) if ( partition == NULL )
{ {
@ -744,7 +733,6 @@ FPRINTF("ramdiskFS_unlink_r(%s)", name);
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
static int ramdiskFS_chdir_r(struct _reent *r, const char *name) { static int ramdiskFS_chdir_r(struct _reent *r, const char *name) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
FPRINTF("ramdiskFS_chdir_r(%s)", name);
DIR_STRUCT dirStruct; DIR_STRUCT dirStruct;
DIR_ITER dirState; DIR_ITER dirState;
dirState.dirStruct=&dirStruct; dirState.dirStruct=&dirStruct;
@ -765,14 +753,12 @@ FPRINTF("ramdiskFS_chdir_r(%s)", name);
} }
partition->cwd = dirStruct.dir; partition->cwd = dirStruct.dir;
ramdiskFS_dirclose_r(r, &dirState); ramdiskFS_dirclose_r(r, &dirState);
FPRINTF("ok");
return 0; return 0;
} }
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
static int ramdiskFS_mkdir_r(struct _reent *r, const char *path, int mode) { static int ramdiskFS_mkdir_r(struct _reent *r, const char *path, int mode) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
FPRINTF("ramdiskFS_mkdir_r(%s)", path);
RAMDISK_PARTITION *partition = ramdiskFS_getPartitionFromPath(path); RAMDISK_PARTITION *partition = ramdiskFS_getPartitionFromPath(path);
if ( partition == NULL ) if ( partition == NULL )
{ {
@ -802,12 +788,10 @@ FPRINTF("ramdiskFS_mkdir_r(%s)", path);
static DIR_ITER* ramdiskFS_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path) { static DIR_ITER* ramdiskFS_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
FPRINTF("DirOpen %s", path);
DIR_STRUCT *dirStruct = (DIR_STRUCT*)dirState->dirStruct; DIR_STRUCT *dirStruct = (DIR_STRUCT*)dirState->dirStruct;
char *cptr; char *cptr;
RAMDISK_PARTITION *partition = ramdiskFS_getPartitionFromPath(path); RAMDISK_PARTITION *partition = ramdiskFS_getPartitionFromPath(path);
FPRINTF("partition %p", partition);
if ( partition == NULL ) if ( partition == NULL )
{ {
r->_errno = ENODEV; r->_errno = ENODEV;
@ -828,7 +812,6 @@ static DIR_ITER* ramdiskFS_diropen_r(struct _reent *r, DIR_ITER *dirState, const
dirStruct->dir = partition->cwd; //else use current working dir dirStruct->dir = partition->cwd; //else use current working dir
RAMDISK_BASE_ENTRY *entry = dirStruct->dir->FindEntry(path); RAMDISK_BASE_ENTRY *entry = dirStruct->dir->FindEntry(path);
FPRINTF("entry %p", entry);
if(entry==NULL) if(entry==NULL)
{ {
r->_errno = ENOENT; r->_errno = ENOENT;
@ -860,20 +843,15 @@ static int ramdiskFS_dirnext_r(struct _reent *r, DIR_ITER *dirState, char *filen
DIR_STRUCT *dirStruct = (DIR_STRUCT*)dirState->dirStruct; DIR_STRUCT *dirStruct = (DIR_STRUCT*)dirState->dirStruct;
// RAMDISK_BASE_ENTRY **dirStruct = (RAMDISK_BASE_ENTRY**)dirState->dirStruct; // RAMDISK_BASE_ENTRY **dirStruct = (RAMDISK_BASE_ENTRY**)dirState->dirStruct;
FPRINTF("DirNext");
if(dirStruct->current_entry) if(dirStruct->current_entry)
{ {
FPRINTF("current_entry = %s",dirStruct->current_entry->name);
strcpy(filename, dirStruct->current_entry->name); strcpy(filename, dirStruct->current_entry->name);
if(dirStruct->current_entry->IsDir()) if(dirStruct->current_entry->IsDir())
{ {
FPRINTF("IsDir");
if(st) st->st_mode=S_IFDIR; if(st) st->st_mode=S_IFDIR;
} }
else else
{ {
FPRINTF("IsFile");
if(st) st->st_mode=0; if(st) st->st_mode=0;
} }
dirStruct->current_entry = dirStruct->current_entry->next; dirStruct->current_entry = dirStruct->current_entry->next;
@ -947,7 +925,6 @@ extern "C" void ramdiskUnmount(const char *mountpoint) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
int ramdiskFS_Mount(const char *mountpoint, void *handle) { int ramdiskFS_Mount(const char *mountpoint, void *handle) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
FPRINTF("Mount %s", mountpoint);
devoptab_t* devops; devoptab_t* devops;
char* nameCopy; char* nameCopy;
RAMDISK_PARTITION** partition; RAMDISK_PARTITION** partition;
@ -989,14 +966,12 @@ int ramdiskFS_Mount(const char *mountpoint, void *handle) {
else else
*partition = new RAMDISK_PARTITION(Mountpoint, true); *partition = new RAMDISK_PARTITION(Mountpoint, true);
devops->deviceData = partition; devops->deviceData = partition;
FPRINTF("devops=%p nameCopy=%p(%s) partition=%p", devops, nameCopy, nameCopy, partition);
if(AddDevice(devops)<0) if(AddDevice(devops)<0)
{ {
free(devops); free(devops);
return false; return false;
} }
FPRINTF("mounted");
return true; return true;

View File

@ -71,9 +71,11 @@ int MenuSettings()
int slidedirection = FADE; int slidedirection = FADE;
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume); if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
@ -135,7 +137,7 @@ int MenuSettings()
backBtnTxt.SetWidescreen(CFG.widescreen); backBtnTxt.SetWidescreen(CFG.widescreen);
backBtnImg.SetWidescreen(CFG.widescreen); backBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, &btnClick,1); GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2,1);
backBtn.SetLabel(&backBtnTxt); backBtn.SetLabel(&backBtnTxt);
backBtn.SetTrigger(&trigB); backBtn.SetTrigger(&trigB);
@ -184,7 +186,7 @@ int MenuSettings()
GoLeftBtn.SetPosition(25, -25); GoLeftBtn.SetPosition(25, -25);
GoLeftBtn.SetImage(&GoLeftImg); GoLeftBtn.SetImage(&GoLeftImg);
GoLeftBtn.SetSoundOver(&btnSoundOver); GoLeftBtn.SetSoundOver(&btnSoundOver);
GoLeftBtn.SetSoundClick(&btnClick); GoLeftBtn.SetSoundClick(btnClick2);
GoLeftBtn.SetEffectGrow(); GoLeftBtn.SetEffectGrow();
GoLeftBtn.SetTrigger(&trigA); GoLeftBtn.SetTrigger(&trigA);
GoLeftBtn.SetTrigger(&trigL); GoLeftBtn.SetTrigger(&trigL);
@ -196,7 +198,7 @@ int MenuSettings()
GoRightBtn.SetPosition(-25, -25); GoRightBtn.SetPosition(-25, -25);
GoRightBtn.SetImage(&GoRightImg); GoRightBtn.SetImage(&GoRightImg);
GoRightBtn.SetSoundOver(&btnSoundOver); GoRightBtn.SetSoundOver(&btnSoundOver);
GoRightBtn.SetSoundClick(&btnClick); GoRightBtn.SetSoundClick(btnClick2);
GoRightBtn.SetEffectGrow(); GoRightBtn.SetEffectGrow();
GoRightBtn.SetTrigger(&trigA); GoRightBtn.SetTrigger(&trigA);
GoRightBtn.SetTrigger(&trigR); GoRightBtn.SetTrigger(&trigR);
@ -665,15 +667,9 @@ int MenuSettings()
{ {
cfg_save_global(); cfg_save_global();
optionBrowser2.SetState(STATE_DISABLED); optionBrowser2.SetState(STATE_DISABLED);
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) bgMusic->Resume();
bgMusic->Play();
else
bgMusic->PlayOggFile(Settings.ogg_path);
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) if (choice == 3)
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu
else if (choice == 2) else if (choice == 2)
@ -908,15 +904,9 @@ int MenuSettings()
{ {
cfg_save_global(); cfg_save_global();
optionBrowser2.SetState(STATE_DISABLED); optionBrowser2.SetState(STATE_DISABLED);
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) bgMusic->Resume();
bgMusic->Play();
else
bgMusic->PlayOggFile(Settings.ogg_path);
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) if (choice == 3)
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu
if (choice == 2) if (choice == 2)
@ -1060,15 +1050,9 @@ int MenuSettings()
{ {
cfg_save_global(); cfg_save_global();
optionBrowser2.SetState(STATE_DISABLED); optionBrowser2.SetState(STATE_DISABLED);
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) bgMusic->Resume();
bgMusic->Play();
else
bgMusic->PlayOggFile(Settings.ogg_path);
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) if (choice == 3)
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu
else if (choice == 2) else if (choice == 2)
@ -1238,15 +1222,9 @@ int MenuSettings()
{ {
cfg_save_global(); cfg_save_global();
optionBrowser2.SetState(STATE_DISABLED); optionBrowser2.SetState(STATE_DISABLED);
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) bgMusic->Resume();
bgMusic->Play();
else
bgMusic->PlayOggFile(Settings.ogg_path);
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) if (choice == 3)
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu
else if (choice == 2) else if (choice == 2)
@ -1298,7 +1276,7 @@ int MenuSettings()
Settings.volume += 10; Settings.volume += 10;
if (Settings.volume > 100) if (Settings.volume > 100)
Settings.volume = 0; Settings.volume = 0;
SetVolumeOgg(255*(Settings.volume/100.0)); bgMusic->SetVolume(Settings.volume);
} }
if (Settings.volume > 0) if (Settings.volume > 0)
options2.SetValue(Idx,"%i", Settings.volume); options2.SetValue(Idx,"%i", Settings.volume);
@ -1315,7 +1293,7 @@ int MenuSettings()
if (Settings.sfxvolume > 100) if (Settings.sfxvolume > 100)
Settings.sfxvolume = 0; Settings.sfxvolume = 0;
btnSoundOver.SetVolume(Settings.sfxvolume); btnSoundOver.SetVolume(Settings.sfxvolume);
btnClick.SetVolume(Settings.sfxvolume); btnClick2->SetVolume(Settings.sfxvolume);
btnClick1.SetVolume(Settings.sfxvolume); btnClick1.SetVolume(Settings.sfxvolume);
} }
if (Settings.sfxvolume > 0) if (Settings.sfxvolume > 0)
@ -1420,15 +1398,9 @@ int MenuSettings()
{ {
cfg_save_global(); cfg_save_global();
optionBrowser2.SetState(STATE_DISABLED); optionBrowser2.SetState(STATE_DISABLED);
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) bgMusic->Resume();
bgMusic->Play();
else
bgMusic->PlayOggFile(Settings.ogg_path);
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) if (choice == 3)
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu
else if (choice == 2) else if (choice == 2)
@ -2010,15 +1982,9 @@ int MenuSettings()
{ {
cfg_save_global(); cfg_save_global();
optionBrowser2.SetState(STATE_DISABLED); optionBrowser2.SetState(STATE_DISABLED);
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) bgMusic->Resume();
bgMusic->Play();
else
bgMusic->PlayOggFile(Settings.ogg_path);
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) if (choice == 3)
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu
@ -2070,9 +2036,11 @@ int GameSettings(struct discHdr * header)
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume); if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
@ -2124,7 +2092,7 @@ int GameSettings(struct discHdr * header)
backBtnTxt.SetWidescreen(CFG.widescreen); backBtnTxt.SetWidescreen(CFG.widescreen);
backBtnImg.SetWidescreen(CFG.widescreen); backBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, &btnClick,1); GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2,1);
backBtn.SetLabel(&backBtnTxt); backBtn.SetLabel(&backBtnTxt);
backBtn.SetTrigger(&trigB); backBtn.SetTrigger(&trigB);
@ -2139,7 +2107,7 @@ int GameSettings(struct discHdr * header)
saveBtnTxt.SetWidescreen(CFG.widescreen); saveBtnTxt.SetWidescreen(CFG.widescreen);
saveBtnImg.SetWidescreen(CFG.widescreen); saveBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton saveBtn(&saveBtnImg,&saveBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, &btnClick,1); GuiButton saveBtn(&saveBtnImg,&saveBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2,1);
saveBtn.SetLabel(&saveBtnTxt); saveBtn.SetLabel(&saveBtnTxt);
@ -2384,15 +2352,9 @@ int GameSettings(struct discHdr * header)
{ {
cfg_save_global(); cfg_save_global();
optionBrowser2.SetState(STATE_DISABLED); optionBrowser2.SetState(STATE_DISABLED);
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) bgMusic->Resume();
bgMusic->Play();
else
bgMusic->PlayOggFile(Settings.ogg_path);
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) if (choice == 3)
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu
else if (choice == 2) else if (choice == 2)
@ -2654,15 +2616,9 @@ int GameSettings(struct discHdr * header)
{ {
cfg_save_global(); cfg_save_global();
optionBrowser2.SetState(STATE_DISABLED); optionBrowser2.SetState(STATE_DISABLED);
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) bgMusic->Resume();
bgMusic->Play();
else
bgMusic->PlayOggFile(Settings.ogg_path);
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) if (choice == 3)
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu
else if (choice == 2) else if (choice == 2)
@ -2860,24 +2816,9 @@ int GameSettings(struct discHdr * header)
{ {
cfg_save_global(); cfg_save_global();
optionBrowser2.SetState(STATE_DISABLED); optionBrowser2.SetState(STATE_DISABLED);
s32 thetimeofbg = bgMusic->GetPlayTime(); bgMusic->Pause();
bgMusic->Stop();
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
/* bgMusic->Resume();
// if language has changed, reload titles
int opt_langnew = 0;
game_cfg = CFG_get_game_opt(header->id);
if (game_cfg) opt_langnew = game_cfg->language;
if (Settings.titlesOverride==1 && opt_lang != opt_langnew)
OpenXMLDatabase(Settings.titlestxt_path, Settings.db_language, Settings.db_JPtoEN, false, Settings.titlesOverride==1?true:false, true); // open file, reload titles, keep in memory
// titles are refreshed in menu.cpp as soon as this function returns
*/
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path))
bgMusic->Play();
else
bgMusic->PlayOggFile(Settings.ogg_path);
bgMusic->SetPlayTime(thetimeofbg);
SetVolumeOgg(255*(Settings.volume/100.0));
if (choice == 3) if (choice == 3)
Sys_LoadMenu(); // Back to System Menu Sys_LoadMenu(); // Back to System Menu

View File

@ -14,6 +14,7 @@
#include "fatmounter.h" #include "fatmounter.h"
#include "filelist.h" #include "filelist.h"
#include "sys.h" #include "sys.h"
#include "menu.h"
/*** Extern variables ***/ /*** Extern variables ***/
@ -36,8 +37,10 @@ bool MenuOGG() {
int scrollon, nothingchanged = 0; int scrollon, nothingchanged = 0;
bool returnhere = false; bool returnhere = false;
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
@ -73,7 +76,7 @@ bool MenuOGG() {
pathBtn.SetPosition(0,28); pathBtn.SetPosition(0,28);
pathBtn.SetLabel(&titleTxt); pathBtn.SetLabel(&titleTxt);
pathBtn.SetSoundOver(&btnSoundOver); pathBtn.SetSoundOver(&btnSoundOver);
pathBtn.SetSoundClick(&btnClick); pathBtn.SetSoundClick(btnClick2);
pathBtn.SetTrigger(&trigA); pathBtn.SetTrigger(&trigA);
pathBtn.SetEffectGrow(); pathBtn.SetEffectGrow();
@ -94,7 +97,7 @@ bool MenuOGG() {
backBtn.SetLabel(&backBtnTxt); backBtn.SetLabel(&backBtnTxt);
backBtn.SetImage(&backBtnImg); backBtn.SetImage(&backBtnImg);
backBtn.SetSoundOver(&btnSoundOver); backBtn.SetSoundOver(&btnSoundOver);
backBtn.SetSoundClick(&btnClick); backBtn.SetSoundClick(btnClick2);
backBtn.SetTrigger(&trigA); backBtn.SetTrigger(&trigA);
backBtn.SetTrigger(&trigB); backBtn.SetTrigger(&trigB);
backBtn.SetEffectGrow(); backBtn.SetEffectGrow();
@ -112,7 +115,7 @@ bool MenuOGG() {
defaultBtn.SetLabel(&defaultBtnTxt); defaultBtn.SetLabel(&defaultBtnTxt);
defaultBtn.SetImage(&defaultBtnImg); defaultBtn.SetImage(&defaultBtnImg);
defaultBtn.SetSoundOver(&btnSoundOver); defaultBtn.SetSoundOver(&btnSoundOver);
defaultBtn.SetSoundClick(&btnClick); defaultBtn.SetSoundClick(btnClick2);
defaultBtn.SetTrigger(&trigA); defaultBtn.SetTrigger(&trigA);
defaultBtn.SetEffectGrow(); defaultBtn.SetEffectGrow();
@ -145,7 +148,7 @@ bool MenuOGG() {
playBtn.SetPosition(50, 400); playBtn.SetPosition(50, 400);
playBtn.SetImage(&playBtnImg); playBtn.SetImage(&playBtnImg);
playBtn.SetSoundOver(&btnSoundOver); playBtn.SetSoundOver(&btnSoundOver);
playBtn.SetSoundClick(&btnClick); playBtn.SetSoundClick(btnClick2);
playBtn.SetTrigger(&trigA); playBtn.SetTrigger(&trigA);
playBtn.SetTrigger(&trigPlus); playBtn.SetTrigger(&trigPlus);
playBtn.SetEffectGrow(); playBtn.SetEffectGrow();
@ -157,7 +160,7 @@ bool MenuOGG() {
stopBtn.SetPosition(-15, 400); stopBtn.SetPosition(-15, 400);
stopBtn.SetImage(&stopBtnImg); stopBtn.SetImage(&stopBtnImg);
stopBtn.SetSoundOver(&btnSoundOver); stopBtn.SetSoundOver(&btnSoundOver);
stopBtn.SetSoundClick(&btnClick); stopBtn.SetSoundClick(btnClick2);
stopBtn.SetTrigger(&trigA); stopBtn.SetTrigger(&trigA);
stopBtn.SetTrigger(&trigMinus); stopBtn.SetTrigger(&trigMinus);
stopBtn.SetEffectGrow(); stopBtn.SetEffectGrow();
@ -187,11 +190,12 @@ bool MenuOGG() {
if (backBtn.GetState() == STATE_CLICKED) { if (backBtn.GetState() == STATE_CLICKED) {
if (nothingchanged == 1 && countoggs > 0) { if (nothingchanged == 1 && countoggs > 0) {
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) { if (strcmp("", Settings.oggload_path) && strcmp("notset", Settings.ogg_path)) {
bgMusic->Play(); bgMusic->Load(Settings.ogg_path);
} else { } else {
bgMusic->PlayOggFile(Settings.ogg_path); bgMusic->Load(bg_music_ogg, bg_music_ogg_size, true);
} }
bgMusic->Play();
} }
backBtn.ResetState(); backBtn.ResetState();
break; break;
@ -201,8 +205,9 @@ bool MenuOGG() {
choice = WindowPrompt(tr("Loading standard music."),0,tr("OK"), tr("Cancel")); choice = WindowPrompt(tr("Loading standard music."),0,tr("OK"), tr("Cancel"));
if (choice == 1) { if (choice == 1) {
sprintf(Settings.ogg_path, "notset"); sprintf(Settings.ogg_path, "notset");
bgMusic->Load(bg_music_ogg, bg_music_ogg_size, true);
bgMusic->Play(); bgMusic->Play();
SetVolumeOgg(255*(Settings.volume/100.0)); bgMusic->SetVolume(Settings.volume);
cfg_save_global(); cfg_save_global();
} }
defaultBtn.ResetState(); defaultBtn.ResetState();
@ -255,20 +260,18 @@ bool MenuOGG() {
if (ret>=0) { if (ret>=0) {
choice = WindowPrompt(tr("Set as backgroundmusic?"),GetFileName(ret),tr("Yes"),tr("No")); choice = WindowPrompt(tr("Set as backgroundmusic?"),GetFileName(ret),tr("Yes"),tr("No"));
if (choice == 1) { if (choice == 1) {
StopOgg();
snprintf(fullpath,150,"%s%s",Settings.oggload_path,GetFileName(ret)); snprintf(fullpath,150,"%s%s",Settings.oggload_path,GetFileName(ret));
choice = bgMusic->PlayOggFile(fullpath); if (!bgMusic->Load(fullpath)) {
if (choice < 0) {
WindowPrompt(tr("Not supported format!"), tr("Loading standard music."), tr("OK")); WindowPrompt(tr("Not supported format!"), tr("Loading standard music."), tr("OK"));
sprintf(Settings.ogg_path, "notset"); sprintf(Settings.ogg_path, "notset");
bgMusic->Play();
SetVolumeOgg(255*(Settings.volume/100.0));
} else { } else {
snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s", fullpath); snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s", fullpath);
cfg_save_global(); cfg_save_global();
SetVolumeOgg(255*(Settings.volume/100.0)); bgMusic->SetVolume(Settings.volume);
nothingchanged = 0; nothingchanged = 0;
} }
bgMusic->Play();
bgMusic->SetVolume(Settings.volume);
} }
optionBrowser4.SetFocus(1); optionBrowser4.SetFocus(1);
} }
@ -277,16 +280,11 @@ bool MenuOGG() {
if (countoggs > 0) { if (countoggs > 0) {
ret = optionBrowser4.GetSelectedOption(); ret = optionBrowser4.GetSelectedOption();
snprintf(fullpath, 150,"%s%s", Settings.oggload_path,GetFileName(ret)); snprintf(fullpath, 150,"%s%s", Settings.oggload_path,GetFileName(ret));
choice = bgMusic->PlayOggFile(fullpath); if (!bgMusic->Load(fullpath)) {
if (choice < 0) {
WindowPrompt(tr("Not supported format!"), tr("Loading standard music."), tr("OK")); WindowPrompt(tr("Not supported format!"), tr("Loading standard music."), tr("OK"));
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) { }
bgMusic->Play(); bgMusic->Play();
} else { bgMusic->SetVolume(Settings.volume);
bgMusic->PlayOggFile(Settings.ogg_path);
}
}
SetVolumeOgg(255*(Settings.volume/100.0));
nothingchanged = 1; nothingchanged = 1;
optionBrowser4.SetFocus(1); optionBrowser4.SetFocus(1);
} }
@ -295,7 +293,7 @@ bool MenuOGG() {
if (stopBtn.GetState() == STATE_CLICKED) { if (stopBtn.GetState() == STATE_CLICKED) {
if (countoggs > 0) { if (countoggs > 0) {
StopOgg(); bgMusic->Stop();
nothingchanged = 1; nothingchanged = 1;
optionBrowser4.SetFocus(1); optionBrowser4.SetFocus(1);
} }
@ -322,8 +320,10 @@ int MenuLanguageSelect() {
int scrollon; int scrollon;
int returnhere = 0; int returnhere = 0;
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
@ -354,7 +354,7 @@ int MenuLanguageSelect() {
pathBtn.SetPosition(0,28); pathBtn.SetPosition(0,28);
pathBtn.SetLabel(&titleTxt); pathBtn.SetLabel(&titleTxt);
pathBtn.SetSoundOver(&btnSoundOver); pathBtn.SetSoundOver(&btnSoundOver);
pathBtn.SetSoundClick(&btnClick); pathBtn.SetSoundClick(btnClick2);
pathBtn.SetTrigger(&trigA); pathBtn.SetTrigger(&trigA);
pathBtn.SetEffectGrow(); pathBtn.SetEffectGrow();
@ -375,7 +375,7 @@ int MenuLanguageSelect() {
backBtn.SetLabel(&backBtnTxt); backBtn.SetLabel(&backBtnTxt);
backBtn.SetImage(&backBtnImg); backBtn.SetImage(&backBtnImg);
backBtn.SetSoundOver(&btnSoundOver); backBtn.SetSoundOver(&btnSoundOver);
backBtn.SetSoundClick(&btnClick); backBtn.SetSoundClick(btnClick2);
backBtn.SetTrigger(&trigA); backBtn.SetTrigger(&trigA);
backBtn.SetTrigger(&trigB); backBtn.SetTrigger(&trigB);
backBtn.SetEffectGrow(); backBtn.SetEffectGrow();
@ -393,7 +393,7 @@ int MenuLanguageSelect() {
defaultBtn.SetLabel(&defaultBtnTxt); defaultBtn.SetLabel(&defaultBtnTxt);
defaultBtn.SetImage(&defaultBtnImg); defaultBtn.SetImage(&defaultBtnImg);
defaultBtn.SetSoundOver(&btnSoundOver); defaultBtn.SetSoundOver(&btnSoundOver);
defaultBtn.SetSoundClick(&btnClick); defaultBtn.SetSoundClick(btnClick2);
defaultBtn.SetTrigger(&trigA); defaultBtn.SetTrigger(&trigA);
defaultBtn.SetEffectGrow(); defaultBtn.SetEffectGrow();
@ -410,7 +410,7 @@ int MenuLanguageSelect() {
updateBtn.SetLabel(&updateBtnTxt); updateBtn.SetLabel(&updateBtnTxt);
updateBtn.SetImage(&updateBtnImg); updateBtn.SetImage(&updateBtnImg);
updateBtn.SetSoundOver(&btnSoundOver); updateBtn.SetSoundOver(&btnSoundOver);
updateBtn.SetSoundClick(&btnClick); updateBtn.SetSoundClick(btnClick2);
updateBtn.SetTrigger(&trigA); updateBtn.SetTrigger(&trigA);
updateBtn.SetEffectGrow(); updateBtn.SetEffectGrow();

View File

@ -421,6 +421,7 @@ extern "C" {
u8 discart; u8 discart;
short gamesound; short gamesound;
}; };
extern struct SSettings Settings;
void CFG_LoadGlobal(void); void CFG_LoadGlobal(void);
bool cfg_save_global(void); bool cfg_save_global(void);

Binary file not shown.

View File

@ -119,8 +119,10 @@ static void Theme_Prompt(const char *title, const char *author, GuiImageData *th
{ {
bool leave = false; bool leave = false;
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -165,7 +167,7 @@ static void Theme_Prompt(const char *title, const char *author, GuiImageData *th
downloadBtnTxt.SetWidescreen(CFG.widescreen); downloadBtnTxt.SetWidescreen(CFG.widescreen);
downloadBtnImg.SetWidescreen(CFG.widescreen); downloadBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton downloadBtn(&downloadBtnImg,&downloadBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 170, &trigA, &btnSoundOver, &btnClick,1); GuiButton downloadBtn(&downloadBtnImg,&downloadBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 170, &trigA, &btnSoundOver, btnClick2,1);
downloadBtn.SetLabel(&downloadBtnTxt); downloadBtn.SetLabel(&downloadBtnTxt);
downloadBtn.SetScale(0.9); downloadBtn.SetScale(0.9);
@ -177,7 +179,7 @@ static void Theme_Prompt(const char *title, const char *author, GuiImageData *th
backBtnTxt.SetWidescreen(CFG.widescreen); backBtnTxt.SetWidescreen(CFG.widescreen);
backBtnImg.SetWidescreen(CFG.widescreen); backBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton backBtn(&backBtnImg,&backBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 220, &trigA, &btnSoundOver, &btnClick,1); GuiButton backBtn(&backBtnImg,&backBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 220, &trigA, &btnSoundOver, btnClick2,1);
backBtn.SetLabel(&backBtnTxt); backBtn.SetLabel(&backBtnTxt);
backBtn.SetTrigger(&trigB); backBtn.SetTrigger(&trigB);
backBtn.SetScale(0.9); backBtn.SetScale(0.9);
@ -253,9 +255,11 @@ int Theme_Downloader()
char THEME_LINK[30] = "http://wii.spiffy360.com/"; char THEME_LINK[30] = "http://wii.spiffy360.com/";
/*** Sound Variables ***/ /*** Sound Variables ***/
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume); if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
/*** Image Variables ***/ /*** Image Variables ***/
char imgPath[150]; char imgPath[150];
@ -341,7 +345,7 @@ int Theme_Downloader()
backBtnTxt.SetWidescreen(CFG.widescreen); backBtnTxt.SetWidescreen(CFG.widescreen);
backBtnImg.SetWidescreen(CFG.widescreen); backBtnImg.SetWidescreen(CFG.widescreen);
} }
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, &btnClick,1); GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2,1);
backBtn.SetLabel(&backBtnTxt); backBtn.SetLabel(&backBtnTxt);
backBtn.SetTrigger(&trigB); backBtn.SetTrigger(&trigB);
@ -354,7 +358,7 @@ int Theme_Downloader()
GoLeftBtn.SetPosition(25, -25); GoLeftBtn.SetPosition(25, -25);
GoLeftBtn.SetImage(&GoLeftImg); GoLeftBtn.SetImage(&GoLeftImg);
GoLeftBtn.SetSoundOver(&btnSoundOver); GoLeftBtn.SetSoundOver(&btnSoundOver);
GoLeftBtn.SetSoundClick(&btnClick); GoLeftBtn.SetSoundClick(btnClick2);
GoLeftBtn.SetEffectGrow(); GoLeftBtn.SetEffectGrow();
GoLeftBtn.SetTrigger(&trigA); GoLeftBtn.SetTrigger(&trigA);
GoLeftBtn.SetTrigger(&trigL); GoLeftBtn.SetTrigger(&trigL);
@ -366,7 +370,7 @@ int Theme_Downloader()
GoRightBtn.SetPosition(-25, -25); GoRightBtn.SetPosition(-25, -25);
GoRightBtn.SetImage(&GoRightImg); GoRightBtn.SetImage(&GoRightImg);
GoRightBtn.SetSoundOver(&btnSoundOver); GoRightBtn.SetSoundOver(&btnSoundOver);
GoRightBtn.SetSoundClick(&btnClick); GoRightBtn.SetSoundClick(btnClick2);
GoRightBtn.SetEffectGrow(); GoRightBtn.SetEffectGrow();
GoRightBtn.SetTrigger(&trigA); GoRightBtn.SetTrigger(&trigA);
GoRightBtn.SetTrigger(&trigR); GoRightBtn.SetTrigger(&trigR);

View File

@ -234,7 +234,7 @@ s32 Disc_Wait(void) {
return 0; return 0;
} }
s32 Disc_SetUSB(u8 *id) { s32 Disc_SetUSB(const u8 *id) {
/* Set USB mode */ /* Set USB mode */
return WDVD_SetUSBMode(id); return WDVD_SetUSBMode(id);
} }

View File

@ -43,7 +43,7 @@ extern "C" {
s32 Disc_Open(void); s32 Disc_Open(void);
s32 Disc_Wait(void); s32 Disc_Wait(void);
void __Disc_SetLowMem(void); void __Disc_SetLowMem(void);
s32 Disc_SetUSB(u8 *); s32 Disc_SetUSB(const u8 *);
s32 Disc_ReadHeader(void *); s32 Disc_ReadHeader(void *);
s32 Disc_IsWii(void); s32 Disc_IsWii(void);
s32 Disc_BootPartition(u64, u8, u8, u8, u8, u8, u8, u32); s32 Disc_BootPartition(u64, u8, u8, u8, u8, u8, u8, u32);

View File

@ -306,7 +306,7 @@ s32 WDVD_DisableReset(u8 val) {
} }
/** Hermes **/ /** Hermes **/
s32 WDVD_SetUSBMode(u8 *id) { s32 WDVD_SetUSBMode(const u8 *id) {
s32 ret; s32 ret;
memset(inbuf, 0, sizeof(inbuf)); memset(inbuf, 0, sizeof(inbuf));

View File

@ -22,7 +22,7 @@ extern "C" {
s32 WDVD_WaitForDisc(void); s32 WDVD_WaitForDisc(void);
s32 WDVD_GetCoverStatus(u32 *); s32 WDVD_GetCoverStatus(u32 *);
s32 WDVD_DisableReset(u8); s32 WDVD_DisableReset(u8);
s32 WDVD_SetUSBMode(u8 *); s32 WDVD_SetUSBMode(const u8 *);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -124,8 +124,10 @@ s32 Wad_Install(FILE *fp)
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -144,7 +146,7 @@ s32 Wad_Install(FILE *fp)
if (Settings.wsprompt == yes){ if (Settings.wsprompt == yes){
btn1Txt.SetWidescreen(CFG.widescreen); btn1Txt.SetWidescreen(CFG.widescreen);
btn1Img.SetWidescreen(CFG.widescreen);} btn1Img.SetWidescreen(CFG.widescreen);}
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -35, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -35, &trigA, &btnSoundOver, btnClick2,1);
btn1.SetLabel(&btn1Txt); btn1.SetLabel(&btn1Txt);
btn1.SetState(STATE_SELECTED); btn1.SetState(STATE_SELECTED);
@ -453,8 +455,10 @@ s32 Wad_Uninstall(FILE *fp)
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
promptWindow.SetPosition(0, -10); promptWindow.SetPosition(0, -10);
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
char imgPath[100]; char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
@ -473,7 +477,7 @@ s32 Wad_Uninstall(FILE *fp)
if (Settings.wsprompt == yes){ if (Settings.wsprompt == yes){
btn1Txt.SetWidescreen(CFG.widescreen); btn1Txt.SetWidescreen(CFG.widescreen);
btn1Img.SetWidescreen(CFG.widescreen);} btn1Img.SetWidescreen(CFG.widescreen);}
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -55, &trigA, &btnSoundOver, &btnClick,1); GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -55, &trigA, &btnSoundOver, btnClick2,1);
btn1.SetLabel(&btn1Txt); btn1.SetLabel(&btn1Txt);
btn1.SetState(STATE_SELECTED); btn1.SetState(STATE_SELECTED);