diff --git a/Makefile b/Makefile index 6e979142..68ee12a0 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ SOURCES := source \ source/xml \ source/network \ source/settings \ + source/settings/menus \ source/prompts \ source/wad \ source/banner \ @@ -43,6 +44,7 @@ SOURCES := source \ source/memory \ source/FileOperations \ source/ImageOperations \ + source/SoundOperations \ source/utils \ source/utils/minizip \ source/usbloader/wbfs @@ -53,7 +55,7 @@ INCLUDES := source # options for code generation #--------------------------------------------------------------------------------- -CFLAGS = -g -O4 -Wall $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H +CFLAGS = -g -O4 -Wall -Wno-multichar $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H CXXFLAGS = -Xassembler -aln=$@.lst $(CFLAGS) LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00000,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size -include $(PROJECTDIR)/Make.config @@ -93,6 +95,7 @@ TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf))) PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg))) PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm))) +WAVFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.wav))) DOLFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.dol))) MP3FILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.mp3))) @@ -110,7 +113,7 @@ export OFILES := $(addsuffix .o,$(BINFILES)) \ $(sFILES:.s=.o) $(SFILES:.S=.o) \ $(TTFFILES:.ttf=.ttf.o) $(PNGFILES:.png=.png.o) $(addsuffix .o,$(DOLFILES))\ $(OGGFILES:.ogg=.ogg.o) $(PCMFILES:.pcm=.pcm.o) $(MP3FILES:.mp3=.mp3.o) \ - $(addsuffix .o,$(ELFFILES)) $(CURDIR)/data/magic_patcher.o + $(WAVFILES:.wav=.wav.o) $(addsuffix .o,$(ELFFILES)) $(CURDIR)/data/magic_patcher.o #--------------------------------------------------------------------------------- # build a list of include paths @@ -215,6 +218,10 @@ language: $(wildcard $(PROJECTDIR)/Languages/*.lang) %.pcm.o : %.pcm @echo $(notdir $<) @bin2s -a 32 $< | $(AS) -o $(@) + +%.wav.o : %.wav + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) %.mp3.o : %.mp3 @echo $(notdir $<) diff --git a/gui.pnproj b/gui.pnproj index 1cf7bd39..621e2f15 100644 --- a/gui.pnproj +++ b/gui.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/gui.pnps b/gui.pnps index cbff6d41..ce6765fe 100644 --- a/gui.pnps +++ b/gui.pnps @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/source/FileOperations/File.cpp b/source/FileOperations/File.cpp new file mode 100644 index 00000000..ce68add3 --- /dev/null +++ b/source/FileOperations/File.cpp @@ -0,0 +1,145 @@ +#include +#include "File.hpp" + +CFile::CFile() +{ + file_fd = NULL; + mem_file = NULL; + filesize = 0; + Pos = 0; +} + +CFile::CFile(const char * filepath, const char * mode) +{ + file_fd = NULL; + open(filepath, mode); +} + +CFile::CFile(const u8 * mem, int size) +{ + file_fd = NULL; + open(mem, size); +} + +CFile::~CFile() +{ + close(); +} + +int CFile::open(const char * filepath, const char * mode) +{ + close(); + + file_fd = fopen(filepath, mode); + if(!file_fd) + return -1; + + fseek(file_fd, 0, SEEK_END); + filesize = ftell(file_fd); + rewind(); + + return 0; +} + +int CFile::open(const u8 * mem, int size) +{ + close(); + + mem_file = mem; + filesize = size; + + return 0; +} + +void CFile::close() +{ + if(file_fd) + fclose(file_fd); + + file_fd = NULL; + mem_file = NULL; + filesize = 0; + Pos = 0; +} + +int CFile::read(u8 * ptr, size_t size) +{ + if(file_fd) + { + int ret = fread(ptr, 1, size, file_fd); + if(ret > 0) + Pos += ret; + return ret; + } + + int readsize = size; + + if(readsize > (long int) filesize-Pos) + readsize = filesize-Pos; + + if(readsize <= 0) + return readsize; + + if(mem_file != NULL) + { + memcpy(ptr, mem_file+Pos, readsize); + Pos += readsize; + return readsize; + } + + return -1; +} + +int CFile::write(const u8 * ptr, size_t size) +{ + if(size < 0) + return size; + + if(file_fd) + { + int ret = fwrite(ptr, 1, size, file_fd); + if(ret > 0) + Pos += ret; + return ret; + } + + return -1; +} + +int CFile::seek(long int offset, int origin) +{ + int ret = 0; + + if(origin == SEEK_SET) + { + Pos = offset; + } + else if(origin == SEEK_CUR) + { + Pos += offset; + } + else if(origin == SEEK_END) + { + Pos = filesize+offset; + } + if(Pos < 0) + { + Pos = 0; + return -1; + } + + if(file_fd) + ret = fseek(file_fd, Pos, SEEK_SET); + + if(mem_file != NULL) + { + if(Pos > (long int) filesize) + { + Pos = filesize; + return -1; + } + } + + return ret; +} + diff --git a/source/FileOperations/File.hpp b/source/FileOperations/File.hpp new file mode 100644 index 00000000..b5e1af75 --- /dev/null +++ b/source/FileOperations/File.hpp @@ -0,0 +1,30 @@ +#ifndef FILE_HPP_ +#define FILE_HPP_ + +#include +#include + +class CFile +{ + public: + CFile(); + CFile(const char * filepath, const char * mode); + CFile(const u8 * memory, int memsize); + ~CFile(); + int open(const char * filepath, const char * mode); + int open(const u8 * memory, int memsize); + void close(); + int read(u8 * ptr, size_t size); + int write(const u8 * ptr, size_t size); + int seek(long int offset, int origin); + long int tell() { return Pos; }; + long int size() { return filesize; }; + void rewind() { seek(0, SEEK_SET); }; + protected: + FILE * file_fd; + const u8 * mem_file; + u64 filesize; + long int Pos; +}; + +#endif diff --git a/source/SoundOperations/AifDecoder.cpp b/source/SoundOperations/AifDecoder.cpp new file mode 100644 index 00000000..3fa2f2b8 --- /dev/null +++ b/source/SoundOperations/AifDecoder.cpp @@ -0,0 +1,214 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include +#include "AifDecoder.hpp" + +typedef struct +{ + u32 fccCOMM; + u32 size; + u16 channels; + u8 frames[4]; + u16 bps; + u8 freq[10]; +} SAIFFCommChunk; + +typedef struct +{ + u32 fccSSND; + u32 size; + u32 offset; + u32 blockSize; +} SAIFFSSndChunk; + +// ------ +// 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 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; +} + +AifDecoder::AifDecoder(const char * filepath) + : SoundDecoder(filepath) +{ + SoundType = SOUND_AIF; + + if(!file_fd) + return; + + OpenFile(); +} + +AifDecoder::AifDecoder(const u8 * snd, int len) + : SoundDecoder(snd, len) +{ + SoundType = SOUND_AIF; + + if(!file_fd) + return; + + OpenFile(); +} + +AifDecoder::~AifDecoder() +{ +} + +void AifDecoder::OpenFile() +{ + SWaveHdr Header; + file_fd->read((u8 *) &Header, sizeof(SWaveHdr)); + + if (Header.magicRIFF != 'FORM') + { + CloseFile(); + return; + } + else if(Header.magicWAVE != 'AIFF') + { + CloseFile(); + return; + } + + SWaveChunk WaveChunk; + do + { + int ret = file_fd->read((u8 *) &WaveChunk, sizeof(SWaveChunk)); + if(ret <= 0) + { + CloseFile(); + return; + } + } + while(WaveChunk.magicDATA != 'COMM'); + + DataOffset = file_fd->tell()+WaveChunk.size; + + SAIFFCommChunk CommHdr; + file_fd->seek(file_fd->tell()-sizeof(SWaveChunk), SEEK_SET); + file_fd->read((u8 *) &CommHdr, sizeof(SAIFFCommChunk)); + + if(CommHdr.fccCOMM != 'COMM') + { + CloseFile(); + return; + } + + file_fd->seek(DataOffset, SEEK_SET); + + SAIFFSSndChunk SSndChunk; + file_fd->read((u8 *) &SSndChunk, sizeof(SAIFFSSndChunk)); + + if(SSndChunk.fccSSND != 'SSND') + { + CloseFile(); + return; + } + + DataOffset += sizeof(SAIFFSSndChunk); + DataSize = SSndChunk.size-8; + SampleRate = (u32) ConvertFromIeeeExtended(CommHdr.freq); + Format = VOICE_STEREO_16BIT; + + if(CommHdr.channels == 1 && CommHdr.bps == 8) + Format = VOICE_MONO_8BIT; + else if (CommHdr.channels == 1 && CommHdr.bps == 16) + Format = VOICE_MONO_16BIT; + else if (CommHdr.channels == 2 && CommHdr.bps == 8) + Format = VOICE_STEREO_8BIT; + else if (CommHdr.channels == 2 && CommHdr.bps == 16) + Format = VOICE_STEREO_16BIT; + + Decode(); +} + +void AifDecoder::CloseFile() +{ + if(file_fd) + delete file_fd; + + file_fd = NULL; +} + +int AifDecoder::Read(u8 * buffer, int buffer_size, int pos) +{ + if(!file_fd) + return -1; + + if(CurPos >= (int) DataSize) + return 0; + + file_fd->seek(DataOffset+CurPos, SEEK_SET); + + if(buffer_size > (int) DataSize-CurPos) + buffer_size = DataSize-CurPos; + + int read = file_fd->read(buffer, buffer_size); + if(read > 0) + { + CurPos += read; + } + + return read; +} diff --git a/source/SoundOperations/AifDecoder.hpp b/source/SoundOperations/AifDecoder.hpp new file mode 100644 index 00000000..f9c6fd91 --- /dev/null +++ b/source/SoundOperations/AifDecoder.hpp @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#ifndef AIFDECODER_HPP_ +#define AIFDECODER_HPP_ + +#include "SoundDecoder.hpp" +#include "WavDecoder.hpp" + +class AifDecoder : public SoundDecoder +{ + public: + AifDecoder(const char * filepath); + AifDecoder(const u8 * snd, int len); + ~AifDecoder(); + int GetFormat() { return Format; }; + int GetSampleRate() { return SampleRate; }; + int Read(u8 * buffer, int buffer_size, int pos); + protected: + void OpenFile(); + void CloseFile(); + u32 DataOffset; + u32 DataSize; + u32 SampleRate; + u8 Format; +}; + +#endif diff --git a/source/SoundOperations/BNSDecoder.cpp b/source/SoundOperations/BNSDecoder.cpp new file mode 100644 index 00000000..e79a2442 --- /dev/null +++ b/source/SoundOperations/BNSDecoder.cpp @@ -0,0 +1,363 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include +#include +#include +#include "BNSDecoder.hpp" + +BNSDecoder::BNSDecoder(const char * filepath) + : SoundDecoder(filepath) +{ + SoundType = SOUND_BNS; + memset(&SoundData, 0, sizeof(SoundBlock)); + + if(!file_fd) + return; + + OpenFile(); +} + +BNSDecoder::BNSDecoder(const u8 * snd, int len) + : SoundDecoder(snd, len) +{ + SoundType = SOUND_BNS; + memset(&SoundData, 0, sizeof(SoundBlock)); + + if(!file_fd) + return; + + OpenFile(); +} + +BNSDecoder::~BNSDecoder() +{ + ExitRequested = true; + while(Decoding) + usleep(100); + + if(SoundData.buffer != NULL) + free(SoundData.buffer); + + SoundData.buffer = NULL; +} + +void BNSDecoder::OpenFile() +{ + u8 * tempbuff = new (std::nothrow) u8[file_fd->size()]; + if(!tempbuff) + { + CloseFile(); + return; + } + + int done = 0; + + while(done < file_fd->size()) + { + int read = file_fd->read(tempbuff, file_fd->size()); + if(read > 0) + done += read; + else + { + CloseFile(); + return; + } + } + + SoundData = DecodefromBNS(tempbuff, done); + if(SoundData.buffer == NULL) + { + CloseFile(); + return; + } + + delete [] tempbuff; + tempbuff = NULL; + + Decode(); +} + +void BNSDecoder::CloseFile() +{ + if(file_fd) + delete file_fd; + + file_fd = NULL; +} + +int BNSDecoder::Read(u8 * buffer, int buffer_size, int pos) +{ + if(!SoundData.buffer) + return -1; + + if(SoundData.loopFlag) + { + int factor = SoundData.format == VOICE_STEREO_16BIT ? 4 : 2; + if(CurPos >= (int) SoundData.loopEnd*factor) + CurPos = SoundData.loopStart*factor; + + if(buffer_size > (int) SoundData.loopEnd*factor-CurPos) + buffer_size = SoundData.loopEnd*factor-CurPos; + } + else + { + if(CurPos >= (int) SoundData.size) + return 0; + + if(buffer_size > (int) SoundData.size-CurPos) + buffer_size = SoundData.size-CurPos; + } + + memcpy(buffer, SoundData.buffer+CurPos, buffer_size); + CurPos += buffer_size; + + return buffer_size; +} + +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; +} + +SoundBlock DecodefromBNS(const u8 *buffer, u32 size) +{ + SoundBlock OutBlock; + memset(&OutBlock, 0, sizeof(SoundBlock)); + + const BNSHeader &hdr = *(BNSHeader *)buffer; + if (size < sizeof hdr) + return OutBlock; + if (hdr.fccBNS != 'BNS ') + return OutBlock; + // 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 OutBlock; + // 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 OutBlock; + u8 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 OutBlock; + u32 freq = (u32) infoChunk.freq; + u32 length = 0; + // Copy data + if (infoChunk.codecNum == 0) + { + OutBlock.buffer = decodeBNS(length, infoChunk, dataChunk); + if (!OutBlock.buffer) + return OutBlock; + } + else + { + OutBlock.buffer = (u8*) malloc(dataChunk.size); + if (!OutBlock.buffer) + return OutBlock; + memcpy(OutBlock.buffer, &dataChunk.data, dataChunk.size); + length = dataChunk.size; + } + + OutBlock.frequency = freq; + OutBlock.format = format; + OutBlock.size = length; + OutBlock.loopStart = infoChunk.loopStart; + OutBlock.loopEnd = infoChunk.loopEnd; + OutBlock.loopFlag = infoChunk.loopFlag; + + return OutBlock; +} diff --git a/source/SoundOperations/BNSDecoder.hpp b/source/SoundOperations/BNSDecoder.hpp new file mode 100644 index 00000000..4c9d76c3 --- /dev/null +++ b/source/SoundOperations/BNSDecoder.hpp @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#ifndef BNSDECODER_HPP_ +#define BNSDECODER_HPP_ + +#include "SoundDecoder.hpp" + +typedef struct _SoundBlock +{ + u8 * buffer; + u32 size; + u8 format; + u32 frequency; + u32 loopStart; + u32 loopEnd; + u8 loopFlag; +} SoundBlock; + +class BNSDecoder : public SoundDecoder +{ + public: + BNSDecoder(const char * filepath); + BNSDecoder(const u8 * snd, int len); + ~BNSDecoder(); + int GetFormat() { return SoundData.format; }; + int GetSampleRate() { return SoundData.frequency; }; + int Read(u8 * buffer, int buffer_size, int pos); + protected: + void OpenFile(); + void CloseFile(); + SoundBlock SoundData; +}; + +SoundBlock DecodefromBNS(const u8 *buffer, u32 size); + +#endif diff --git a/source/SoundOperations/BufferCircle.cpp b/source/SoundOperations/BufferCircle.cpp new file mode 100644 index 00000000..a8ff1e44 --- /dev/null +++ b/source/SoundOperations/BufferCircle.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include "BufferCircle.hpp" + +#define ALIGN32(x) (((x) + 31) & ~31) + +BufferCircle::BufferCircle() +{ + which = 0; + BufferBlockSize = 0; +} + +BufferCircle::~BufferCircle() +{ + FreeBuffer(); + SoundBuffer.clear(); + BufferSize.clear(); + BufferReady.clear(); +} + +void BufferCircle::SetBufferBlockSize(int size) +{ + if(size < 0) + return; + + BufferBlockSize = size; + + for(int i = 0; i < Size(); i++) + { + if(SoundBuffer[i] != NULL) + free(SoundBuffer[i]); + + SoundBuffer[i] = (u8 *) memalign(32, ALIGN32(BufferBlockSize)); + BufferSize[i] = 0; + BufferReady[i] = false; + } +} + +void BufferCircle::Resize(int size) +{ + while(size < Size()) + RemoveBuffer(Size()-1); + + int oldSize = Size(); + + SoundBuffer.resize(size); + BufferSize.resize(size); + BufferReady.resize(size); + + for(int i = oldSize; i < Size(); i++) + { + if(BufferBlockSize > 0) + SoundBuffer[i] = (u8 *) memalign(32, ALIGN32(BufferBlockSize)); + else + SoundBuffer[i] = NULL; + BufferSize[i] = 0; + BufferReady[i] = false; + } +} + +void BufferCircle::RemoveBuffer(int pos) +{ + if(!Valid(pos)) + return; + + if(SoundBuffer[pos] != NULL) + free(SoundBuffer[pos]); + + SoundBuffer.erase(SoundBuffer.begin()+pos); + BufferSize.erase(BufferSize.begin()+pos); + BufferReady.erase(BufferReady.begin()+pos); +} + +void BufferCircle::ClearBuffer() +{ + for(int i = 0; i < Size(); i++) + { + BufferSize[i] = 0; + BufferReady[i] = false; + } + which = 0; +} + +void BufferCircle::FreeBuffer() +{ + for(int i = 0; i < Size(); i++) + { + if(SoundBuffer[i] != NULL) + free(SoundBuffer[i]); + + SoundBuffer[i] = NULL; + BufferSize[i] = 0; + BufferReady[i] = false; + } +} + +void BufferCircle::LoadNext() +{ + int pos = (which+Size()-1) % Size(); + BufferReady[pos] = false; + BufferSize[pos] = 0; + + which = (which+1) % Size(); +} + +void BufferCircle::SetBufferReady(int pos, bool state) +{ + if(!Valid(pos)) + return; + + BufferReady[pos] = state; +} + +void BufferCircle::SetBufferSize(int pos, int size) +{ + if(!Valid(pos)) + return; + + BufferSize[pos] = size; +} diff --git a/source/SoundOperations/BufferCircle.hpp b/source/SoundOperations/BufferCircle.hpp new file mode 100644 index 00000000..56ab0898 --- /dev/null +++ b/source/SoundOperations/BufferCircle.hpp @@ -0,0 +1,92 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#ifndef BUFFER_CIRCLE_HPP_ +#define BUFFER_CIRCLE_HPP_ + +#include +#include + +class BufferCircle +{ + public: + //!> Constructor + BufferCircle(); + //!> Destructor + ~BufferCircle(); + //!> Set circle size + void Resize(int size); + //!> Get the circle size + int Size() { return SoundBuffer.size(); }; + //!> Set/resize the buffer size + void SetBufferBlockSize(int size); + //!> Remove a buffer + void RemoveBuffer(int pos); + //!> Set all buffers clear + void ClearBuffer(); + //!> Free all buffers + void FreeBuffer(); + //!> Switch to next buffer + void LoadNext(); + //!> Get the current buffer + u8 * GetBuffer() { if(!Valid(which)) return 0; return SoundBuffer[which]; }; + //!> Get a buffer at a position + u8 * GetBuffer(int pos) { if(!Valid(pos)) return NULL; else return SoundBuffer[pos]; }; + //!> Get next buffer + u8 * GetNextBuffer() { if(Size() <= 0) return 0; else return SoundBuffer[(which+1) % Size()]; }; + //!> Get previous buffer + u8 * GetLastBuffer() { if(Size() <= 0) return 0; else return SoundBuffer[(which+Size()-1) % Size()]; }; + //!> Get current buffer size + u32 GetBufferSize() { if(!Valid(which)) return 0; else return BufferSize[which]; }; + //!> Get buffer size at position + u32 GetBufferSize(int pos) { if(!Valid(pos)) return 0; else return BufferSize[pos]; }; + //!> Get previous buffer size + u32 GetLastBufferSize() { if(Size() <= 0) return 0; else return BufferSize[(which+Size()-1) % Size()]; }; + //!> Is current buffer ready + bool IsBufferReady() { if(!Valid(which)) return false; else return BufferReady[which]; }; + //!> Is a buffer at a position ready + bool IsBufferReady(int pos) { if(!Valid(pos)) return false; else return BufferReady[pos]; }; + //!> Is next buffer ready + bool IsNextBufferReady() { if(Size() <= 0) return false; else return BufferReady[(which+1) % Size()]; }; + //!> Is last buffer ready + bool IsLastBufferReady() { if(Size() <= 0) return false; else return BufferReady[(which+Size()-1) % Size()]; }; + //!> Set a buffer at a position to a ready state + void SetBufferReady(int pos, bool st); + //!> Set the buffersize at a position + void SetBufferSize(int pos, int size); + //!> Get the current position in the circle + u16 Which() { return which; }; + protected: + //!> Check if the position is a valid position in the vector + bool Valid(int pos) { return !(which < 0 || which >= Size()); }; + + u16 which; + u32 BufferBlockSize; + std::vector SoundBuffer; + std::vector BufferSize; + std::vector BufferReady; +}; + +#endif diff --git a/source/SoundOperations/Mp3Decoder.cpp b/source/SoundOperations/Mp3Decoder.cpp new file mode 100644 index 00000000..13dd0ae7 --- /dev/null +++ b/source/SoundOperations/Mp3Decoder.cpp @@ -0,0 +1,216 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "Mp3Decoder.hpp" + +Mp3Decoder::Mp3Decoder(const char * filepath) + : SoundDecoder(filepath) +{ + SoundType = SOUND_MP3; + ReadBuffer = NULL; + mad_timer_reset(&Timer); + mad_stream_init(&Stream); + mad_frame_init(&Frame); + mad_synth_init(&Synth); + + if(!file_fd) + return; + + OpenFile(); +} + +Mp3Decoder::Mp3Decoder(const u8 * snd, int len) + : SoundDecoder(snd, len) +{ + SoundType = SOUND_MP3; + ReadBuffer = NULL; + mad_timer_reset(&Timer); + mad_stream_init(&Stream); + mad_frame_init(&Frame); + mad_synth_init(&Synth); + + if(!file_fd) + return; + + OpenFile(); +} + +Mp3Decoder::~Mp3Decoder() +{ + ExitRequested = true; + while(Decoding) + usleep(100); + + mad_synth_finish(&Synth); + mad_frame_finish(&Frame); + mad_stream_finish(&Stream); + + if(ReadBuffer) + free(ReadBuffer); + ReadBuffer = NULL; +} + +void Mp3Decoder::OpenFile() +{ + GuardPtr = NULL; + ReadBuffer = (u8 *) memalign(32, SoundBlockSize*SoundBlocks); + if(!ReadBuffer) + { + if(file_fd) + delete file_fd; + file_fd = NULL; + return; + } + + u8 dummybuff[4096]; + int ret = Read((u8 *) &dummybuff, 4096, 0); + if(ret <= 0) + { + if(file_fd) + delete file_fd; + file_fd = NULL; + return; + } + + SampleRate = (u32) Frame.header.samplerate; + Format = ((MAD_NCHANNELS(&Frame.header) == 2) ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT); + Rewind(); + Decode(); +} + +int Mp3Decoder::Rewind() +{ + mad_synth_finish(&Synth); + mad_frame_finish(&Frame); + mad_stream_finish(&Stream); + mad_timer_reset(&Timer); + mad_stream_init(&Stream); + mad_frame_init(&Frame); + mad_synth_init(&Synth); + SynthPos = 0; + GuardPtr = NULL; + + if(!file_fd) + return -1; + + return SoundDecoder::Rewind(); +} + +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); +} + +int Mp3Decoder::Read(u8 * buffer, int buffer_size, int pos) +{ + if(!file_fd) + return -1; + + if(Format == VOICE_STEREO_16BIT) + buffer_size &= ~0x0003; + else + buffer_size &= ~0x0001; + + u8 * write_pos = buffer; + u8 * write_end = buffer+buffer_size; + + while(1) + { + while(SynthPos < Synth.pcm.length) + { + if(write_pos >= write_end) + return write_pos-buffer; + + *((s16 *) write_pos) = FixedToShort(Synth.pcm.samples[0][SynthPos]); + write_pos += 2; + + if(MAD_NCHANNELS(&Frame.header) == 2) + { + *((s16 *) write_pos) = FixedToShort(Synth.pcm.samples[1][SynthPos]); + write_pos += 2; + } + SynthPos++; + } + + if(Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN) + { + u8 * ReadStart = ReadBuffer; + int ReadSize = SoundBlockSize*SoundBlocks; + int Remaining = 0; + + if(Stream.next_frame != NULL) + { + Remaining = Stream.bufend - Stream.next_frame; + memmove(ReadBuffer, Stream.next_frame, Remaining); + ReadStart += Remaining; + ReadSize -= Remaining; + } + + ReadSize = file_fd->read(ReadStart, ReadSize); + if(ReadSize <= 0) + { + GuardPtr = ReadStart; + memset(GuardPtr, 0, MAD_BUFFER_GUARD); + ReadSize = MAD_BUFFER_GUARD; + } + + CurPos += ReadSize; + mad_stream_buffer(&Stream, ReadBuffer, Remaining+ReadSize); + } + + if(mad_frame_decode(&Frame,&Stream)) + { + if(MAD_RECOVERABLE(Stream.error)) + { + if(Stream.error != MAD_ERROR_LOSTSYNC || !GuardPtr) + continue; + } + else + { + if(Stream.error != MAD_ERROR_BUFLEN) + return -1; + else if(Stream.error == MAD_ERROR_BUFLEN && GuardPtr) + return -1; + } + } + + mad_timer_add(&Timer,Frame.header.duration); + mad_synth_frame(&Synth,&Frame); + SynthPos = 0; + } +} diff --git a/source/SoundOperations/Mp3Decoder.hpp b/source/SoundOperations/Mp3Decoder.hpp new file mode 100644 index 00000000..a622f1f3 --- /dev/null +++ b/source/SoundOperations/Mp3Decoder.hpp @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include + +#include "SoundDecoder.hpp" + +class Mp3Decoder : public SoundDecoder +{ + public: + Mp3Decoder(const char * filepath); + Mp3Decoder(const u8 * sound, int len); + ~Mp3Decoder(); + int GetFormat() { return Format; }; + int GetSampleRate() { return SampleRate; }; + int Rewind(); + int Read(u8 * buffer, int buffer_size, int pos); + protected: + void OpenFile(); + struct mad_stream Stream; + struct mad_frame Frame; + struct mad_synth Synth; + mad_timer_t Timer; + u8 * GuardPtr; + u8 * ReadBuffer; + u8 Format; + u32 SampleRate; + u32 SynthPos; +}; diff --git a/source/SoundOperations/OggDecoder.cpp b/source/SoundOperations/OggDecoder.cpp new file mode 100644 index 00000000..904270ac --- /dev/null +++ b/source/SoundOperations/OggDecoder.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include +#include "OggDecoder.hpp" + +extern "C" int ogg_read(void * punt, int bytes, int blocks, int *f) +{ + return ((CFile *) f)->read((u8 *) punt, bytes*blocks); +} + +extern "C" int ogg_seek(int *f, ogg_int64_t offset, int mode) +{ + return ((CFile *) f)->seek((u64) offset, mode); +} + +extern "C" int ogg_close(int *f) +{ + ((CFile *) f)->close(); + return 0; +} + +extern "C" long ogg_tell(int *f) +{ + return (long) ((CFile *) f)->tell(); +} + +static ov_callbacks callbacks = { + (size_t (*)(void *, size_t, size_t, void *)) ogg_read, + (int (*)(void *, ogg_int64_t, int)) ogg_seek, + (int (*)(void *)) ogg_close, + (long (*)(void *)) ogg_tell +}; + +OggDecoder::OggDecoder(const char * filepath) + : SoundDecoder(filepath) +{ + SoundType = SOUND_OGG; + + if(!file_fd) + return; + + OpenFile(); +} + +OggDecoder::OggDecoder(const u8 * snd, int len) + : SoundDecoder(snd, len) +{ + SoundType = SOUND_OGG; + + if(!file_fd) + return; + + OpenFile(); +} + +OggDecoder::~OggDecoder() +{ + ExitRequested = true; + while(Decoding) + usleep(100); + + if(file_fd) + ov_clear(&ogg_file); +} + +void OggDecoder::OpenFile() +{ + if (ov_open_callbacks(file_fd, &ogg_file, NULL, 0, callbacks) < 0) + { + delete file_fd; + file_fd = NULL; + return; + } + + ogg_info = ov_info(&ogg_file, -1); + Decode(); +} + +int OggDecoder::GetFormat() +{ + if(!file_fd) + return VOICE_STEREO_16BIT; + + return ((ogg_info->channels == 2) ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT); +} + +int OggDecoder::GetSampleRate() +{ + if(!file_fd) + return 0; + + return (int) ogg_info->rate; +} + +int OggDecoder::Rewind() +{ + if(!file_fd) + return -1; + + int ret = ov_time_seek(&ogg_file, 0); + CurPos = 0; + EndOfFile = false; + + return ret; +} + +int OggDecoder::Read(u8 * buffer, int buffer_size, int pos) +{ + if(!file_fd) + return -1; + + int bitstream = 0; + + int read = ov_read(&ogg_file, (char *) buffer, buffer_size, &bitstream); + + if(read > 0) + CurPos += read; + + return read; +} diff --git a/source/SoundOperations/OggDecoder.hpp b/source/SoundOperations/OggDecoder.hpp new file mode 100644 index 00000000..49de225e --- /dev/null +++ b/source/SoundOperations/OggDecoder.hpp @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include + +#include "SoundDecoder.hpp" + +class OggDecoder : public SoundDecoder +{ + public: + OggDecoder(const char * filepath); + OggDecoder(const u8 * snd, int len); + ~OggDecoder(); + int GetFormat(); + int GetSampleRate(); + int Rewind(); + int Read(u8 * buffer, int buffer_size, int pos); + protected: + void OpenFile(); + OggVorbis_File ogg_file; + vorbis_info *ogg_info; +}; diff --git a/source/SoundOperations/SoundDecoder.cpp b/source/SoundOperations/SoundDecoder.cpp new file mode 100644 index 00000000..f4bc6ecb --- /dev/null +++ b/source/SoundOperations/SoundDecoder.cpp @@ -0,0 +1,156 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 3Band resampling thanks to libmad + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include +#include +#include +#include "SoundDecoder.hpp" +#include "main.h" + +SoundDecoder::SoundDecoder() +{ + file_fd = NULL; + Init(); +} + +SoundDecoder::SoundDecoder(const char * filepath) +{ + file_fd = new CFile(filepath, "rb"); + Init(); +} + +SoundDecoder::SoundDecoder(const u8 * buffer, int size) +{ + file_fd = new CFile(buffer, size); + Init(); +} + +SoundDecoder::~SoundDecoder() +{ + ExitRequested = true; + while(Decoding) + usleep(100); + + if(file_fd) + delete file_fd; + file_fd = NULL; +} + +void SoundDecoder::Init() +{ + SoundType = SOUND_RAW; + SoundBlocks = 8; + SoundBlockSize = 8192; + CurPos = 0; + Loop = false; + EndOfFile = false; + Decoding = false; + ExitRequested = false; + SoundBuffer.SetBufferBlockSize(SoundBlockSize); + SoundBuffer.Resize(SoundBlocks); +} + +int SoundDecoder::Rewind() +{ + CurPos = 0; + EndOfFile = false; + file_fd->rewind(); + + return 0; +} + +int SoundDecoder::Read(u8 * buffer, int buffer_size, int pos) +{ + int ret = file_fd->read(buffer, buffer_size); + CurPos += ret; + + return ret; +} + +void SoundDecoder::Decode() +{ + if(!file_fd || ExitRequested || EndOfFile) + return; + + u16 newWhich = SoundBuffer.Which(); + u16 i = 0; + for (i = 0; i < SoundBuffer.Size()-2; i++) + { + if(!SoundBuffer.IsBufferReady(newWhich)) + break; + + newWhich = (newWhich+1) % SoundBuffer.Size(); + } + + if(i == SoundBuffer.Size()-2) + return; + + Decoding = true; + + int done = 0; + u8 * write_buf = SoundBuffer.GetBuffer(newWhich); + if(!write_buf) + { + ExitRequested = true; + Decoding = false; + return; + } + + while(done < SoundBlockSize) + { + int ret = Read(&write_buf[done], SoundBlockSize-done, Tell()); + + if(ret <= 0) + { + if(Loop) + { + Rewind(); + continue; + } + else + { + EndOfFile = true; + break; + } + } + + done += ret; + } + + if(done > 0) + { + SoundBuffer.SetBufferSize(newWhich, done); + SoundBuffer.SetBufferReady(newWhich, true); + } + + if(!SoundBuffer.IsBufferReady((newWhich+1) % SoundBuffer.Size())) + Decode(); + + Decoding = false; +} + diff --git a/source/SoundOperations/SoundDecoder.hpp b/source/SoundOperations/SoundDecoder.hpp new file mode 100644 index 00000000..b9e71ad4 --- /dev/null +++ b/source/SoundOperations/SoundDecoder.hpp @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#ifndef SOUND_DECODER_HPP +#define SOUND_DECODER_HPP + +#include +#include +#include +#include "utils/timer.h" +#include "FileOperations/File.hpp" +#include "BufferCircle.hpp" + +enum +{ + SOUND_RAW = 0, + SOUND_MP3, + SOUND_OGG, + SOUND_WAV, + SOUND_BNS, + SOUND_AIF +}; + +class SoundDecoder +{ + public: + SoundDecoder(); + SoundDecoder(const char * filepath); + SoundDecoder(const u8 * buffer, int size); + ~SoundDecoder(); + virtual int Read(u8 * buffer, int buffer_size, int pos); + virtual int Tell() { return CurPos; }; + virtual int Seek(int pos) { CurPos = pos; return file_fd->seek(CurPos, SEEK_SET); }; + virtual int Rewind(); + virtual int GetFormat() { return VOICE_STEREO_16BIT; }; + virtual int GetSampleRate() { return 48000; }; + virtual void Decode(); + virtual u32 GetBufferSize() { return SoundBuffer.GetBufferSize(); }; + virtual u8 * GetBuffer() { return SoundBuffer.GetBuffer(); }; + virtual u8 * GetNextBuffer() { return SoundBuffer.GetNextBuffer(); }; + virtual u8 * GetLastBuffer() { return SoundBuffer.GetLastBuffer(); }; + virtual void LoadNext() { SoundBuffer.LoadNext(); }; + virtual bool IsBufferReady() { return SoundBuffer.IsBufferReady(); }; + virtual bool IsNextBufferReady() { return SoundBuffer.IsNextBufferReady(); }; + virtual bool IsLastBufferReady() { return SoundBuffer.IsLastBufferReady(); }; + virtual bool IsEOF() { return EndOfFile; }; + virtual void SetLoop(bool l) { Loop = l; }; + virtual u8 GetSoundType() { return SoundType; }; + virtual void ClearBuffer() { SoundBuffer.ClearBuffer(); }; + virtual bool IsStereo() { return (GetFormat() == VOICE_STEREO_16BIT || GetFormat() == VOICE_STEREO_8BIT); }; + virtual bool Is16Bit() { return (GetFormat() == VOICE_STEREO_16BIT || GetFormat() == VOICE_MONO_16BIT); }; + protected: + void Init(); + + CFile * file_fd; + BufferCircle SoundBuffer; + u8 SoundType; + u16 SoundBlocks; + int SoundBlockSize; + int CurPos; + bool Loop; + bool EndOfFile; + bool Decoding; + bool ExitRequested; +}; + +#endif diff --git a/source/SoundOperations/SoundHandler.cpp b/source/SoundOperations/SoundHandler.cpp new file mode 100644 index 00000000..a4548886 --- /dev/null +++ b/source/SoundOperations/SoundHandler.cpp @@ -0,0 +1,271 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include +#include "SoundHandler.hpp" +#include "Mp3Decoder.hpp" +#include "OggDecoder.hpp" +#include "WavDecoder.hpp" +#include "AifDecoder.hpp" +#include "BNSDecoder.hpp" + +SoundHandler * SoundHandler::instance = NULL; + +SoundHandler::SoundHandler() +{ + Decoding = false; + ExitRequested = false; + for(u32 i = 0; i < MAX_DECODERS; ++i) + DecoderList[i] = NULL; + + ThreadStack = (u8 *) memalign(32, 32768); + if(!ThreadStack) + return; + + LWP_CreateThread(&SoundThread, UpdateThread, this, ThreadStack, 32768, 80); +} + +SoundHandler::~SoundHandler() +{ + ExitRequested = true; + ThreadSignal(); + LWP_JoinThread(SoundThread, NULL); + SoundThread = LWP_THREAD_NULL; + if(ThreadStack) + free(ThreadStack); + + ClearDecoderList(); +} + +SoundHandler * SoundHandler::Instance() +{ + if (instance == NULL) + { + instance = new SoundHandler(); + } + return instance; +} + +void SoundHandler::DestroyInstance() +{ + if(instance) + { + delete instance; + } + instance = NULL; +} + +void SoundHandler::AddDecoder(int voice, const char * filepath) +{ + if(voice < 0 || voice >= MAX_DECODERS) + return; + + if(DecoderList[voice] != NULL) + RemoveDecoder(voice); + + DecoderList[voice] = GetSoundDecoder(filepath); +} + +void SoundHandler::AddDecoder(int voice, const u8 * snd, int len) +{ + if(voice < 0 || voice >= MAX_DECODERS) + return; + + if(DecoderList[voice] != NULL) + RemoveDecoder(voice); + + DecoderList[voice] = GetSoundDecoder(snd, len); +} + +void SoundHandler::RemoveDecoder(int voice) +{ + if(voice < 0 || voice >= MAX_DECODERS) + return; + + if(DecoderList[voice] != NULL) + { + if(DecoderList[voice]->GetSoundType() == SOUND_OGG) delete ((OggDecoder *) DecoderList[voice]); + else if(DecoderList[voice]->GetSoundType() == SOUND_MP3) delete ((Mp3Decoder *) DecoderList[voice]); + else if(DecoderList[voice]->GetSoundType() == SOUND_WAV) delete ((WavDecoder *) DecoderList[voice]); + else if(DecoderList[voice]->GetSoundType() == SOUND_AIF) delete ((AifDecoder *) DecoderList[voice]); + else if(DecoderList[voice]->GetSoundType() == SOUND_BNS) delete ((BNSDecoder *) DecoderList[voice]); + else delete DecoderList[voice]; + } + + DecoderList[voice] = NULL; +} + +void SoundHandler::ClearDecoderList() +{ + for(u32 i = 0; i < MAX_DECODERS; ++i) + RemoveDecoder(i); +} + +static inline bool CheckMP3Signature(const u8 * buffer) +{ + const char MP3_Magic[][3] = + { + {'I', 'D', '3'}, //'ID3' + {0xff, 0xfe}, //'MPEG ADTS, layer III, v1.0 [protected]', 'mp3', 'audio/mpeg'), + {0xff, 0xff}, //'MPEG ADTS, layer III, v1.0', 'mp3', 'audio/mpeg'), + {0xff, 0xfa}, //'MPEG ADTS, layer III, v1.0 [protected]', 'mp3', 'audio/mpeg'), + {0xff, 0xfb}, //'MPEG ADTS, layer III, v1.0', 'mp3', 'audio/mpeg'), + {0xff, 0xf2}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'), + {0xff, 0xf3}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'), + {0xff, 0xf4}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'), + {0xff, 0xf5}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'), + {0xff, 0xf6}, //'MPEG ADTS, layer III, v2.0 [protected]', 'mp3', 'audio/mpeg'), + {0xff, 0xf7}, //'MPEG ADTS, layer III, v2.0', 'mp3', 'audio/mpeg'), + {0xff, 0xe2}, //'MPEG ADTS, layer III, v2.5 [protected]', 'mp3', 'audio/mpeg'), + {0xff, 0xe3}, //'MPEG ADTS, layer III, v2.5', 'mp3', 'audio/mpeg'), + }; + + if(buffer[0] == MP3_Magic[0][0] && buffer[1] == MP3_Magic[0][1] && + buffer[2] == MP3_Magic[0][2]) + { + return true; + } + + for(int i = 1; i < 13; i++) + { + if(buffer[0] == MP3_Magic[i][0] && buffer[1] == MP3_Magic[i][1]) + return true; + } + + return false; +} + +SoundDecoder * SoundHandler::GetSoundDecoder(const char * filepath) +{ + u32 magic; + CFile f(filepath, "rb"); + if(f.size() == 0) + return NULL; + + do + { + f.read((u8 *) &magic, 1); + } + while(((u8 *) &magic)[0] == 0 && f.tell() < f.size()); + + if(f.tell() == f.size()) + return NULL; + + f.seek(f.tell()-1, SEEK_SET); + f.read((u8 *) &magic, 4); + f.close(); + + if(magic == 'OggS') + { + return new OggDecoder(filepath); + } + else if(magic == 'RIFF') + { + return new WavDecoder(filepath); + } + else if(magic == 'BNS ') + { + return new BNSDecoder(filepath); + } + else if(magic == 'FORM') + { + return new AifDecoder(filepath); + } + else if(CheckMP3Signature((u8 *) &magic) == true) + { + return new Mp3Decoder(filepath); + } + + return new SoundDecoder(filepath); +} + +SoundDecoder * SoundHandler::GetSoundDecoder(const u8 * sound, int length) +{ + const u8 * check = sound; + int counter = 0; + + while(check[0] == 0 && counter < length) + { + check++; + counter++; + } + + if(counter >= length) + return NULL; + + u32 * magic = (u32 *) check; + + if(magic[0] == 'OggS') + { + return new OggDecoder(sound, length); + } + else if(magic[0] == 'RIFF') + { + return new WavDecoder(sound, length); + } + else if(magic[0] == 'BNS ') + { + return new BNSDecoder(sound, length); + } + else if(magic[0] == 'FORM') + { + return new AifDecoder(sound, length); + } + else if(CheckMP3Signature(check) == true) + { + return new Mp3Decoder(sound, length); + } + + return new SoundDecoder(sound, length); +} + +void * SoundHandler::UpdateThread(void *arg) +{ + ((SoundHandler *) arg)->InternalSoundUpdates(); + return NULL; +} + +void SoundHandler::InternalSoundUpdates() +{ + u16 i = 0; + LWP_InitQueue(&ThreadQueue); + while (!ExitRequested) + { + LWP_ThreadSleep(ThreadQueue); + + for(i = 0; i < MAX_DECODERS; ++i) + { + if(DecoderList[i] == NULL) + continue; + + Decoding = true; + DecoderList[i]->Decode(); + } + Decoding = false; + } + LWP_CloseQueue(ThreadQueue); + ThreadQueue = LWP_TQUEUE_NULL; +} diff --git a/source/SoundOperations/SoundHandler.hpp b/source/SoundOperations/SoundHandler.hpp new file mode 100644 index 00000000..b10953ec --- /dev/null +++ b/source/SoundOperations/SoundHandler.hpp @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#ifndef SOUNDHANDLER_H_ +#define SOUNDHANDLER_H_ + +#include +#include +#include "SoundDecoder.hpp" + +#define MAX_DECODERS 16 + +class SoundHandler +{ + public: + static SoundHandler * Instance(); + static void DestroyInstance(); + + void AddDecoder(int voice, const char * filepath); + void AddDecoder(int voice, const u8 * snd, int len); + void RemoveDecoder(int voice); + void DestroyDecoder(SoundDecoder * decoder); + + SoundDecoder * Decoder(int i) { return ((i < 0 || i >= MAX_DECODERS) ? NULL : DecoderList[i]); }; + void ThreadSignal() { LWP_ThreadSignal(ThreadQueue); }; + bool IsDecoding() { return Decoding; }; + protected: + SoundHandler(); + ~SoundHandler(); + static void * UpdateThread(void *arg); + void InternalSoundUpdates(); + void ClearDecoderList(); + SoundDecoder * GetSoundDecoder(const char * filepath); + SoundDecoder * GetSoundDecoder(const u8 * sound, int length); + + static SoundHandler * instance; + u8 * ThreadStack; + lwp_t SoundThread; + lwpq_t ThreadQueue; + bool Decoding; + bool ExitRequested; + + SoundDecoder * DecoderList[MAX_DECODERS]; +}; + +#endif diff --git a/source/SoundOperations/WavDecoder.cpp b/source/SoundOperations/WavDecoder.cpp new file mode 100644 index 00000000..3f37b95b --- /dev/null +++ b/source/SoundOperations/WavDecoder.cpp @@ -0,0 +1,155 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include "WavDecoder.hpp" +#include "utils/uncompress.h" + +WavDecoder::WavDecoder(const char * filepath) + : SoundDecoder(filepath) +{ + SoundType = SOUND_WAV; + SampleRate = 48000; + Format = VOICE_STEREO_16BIT; + + if(!file_fd) + return; + + OpenFile(); +} + +WavDecoder::WavDecoder(const u8 * snd, int len) + : SoundDecoder(snd, len) +{ + SoundType = SOUND_WAV; + SampleRate = 48000; + Format = VOICE_STEREO_16BIT; + + if(!file_fd) + return; + + OpenFile(); +} + +WavDecoder::~WavDecoder() +{ +} + +void WavDecoder::OpenFile() +{ + SWaveHdr Header; + SWaveFmtChunk FmtChunk; + memset(&Header, 0, sizeof(SWaveHdr)); + memset(&FmtChunk, 0, sizeof(SWaveFmtChunk)); + + file_fd->read((u8 *) &Header, sizeof(SWaveHdr)); + file_fd->read((u8 *) &FmtChunk, sizeof(SWaveFmtChunk)); + + if (Header.magicRIFF != 'RIFF') + { + CloseFile(); + return; + } + else if(Header.magicWAVE != 'WAVE') + { + CloseFile(); + return; + } + else if(FmtChunk.magicFMT != 'fmt ') + { + CloseFile(); + return; + } + + DataOffset = sizeof(SWaveHdr)+le32(FmtChunk.size)+8; + file_fd->seek(DataOffset, SEEK_SET); + SWaveChunk DataChunk; + file_fd->read((u8 *) &DataChunk, sizeof(SWaveChunk)); + + if(DataChunk.magicDATA == 'fact') + { + DataOffset += 8+le32(DataChunk.size); + file_fd->seek(DataOffset, SEEK_SET); + file_fd->read((u8 *) &DataChunk, sizeof(SWaveChunk)); + } + if(DataChunk.magicDATA != 'data') + { + CloseFile(); + return; + } + + DataOffset += 8; + DataSize = le32(DataChunk.size); + Is16Bit = (le16(FmtChunk.bps) == 16); + SampleRate = le32(FmtChunk.freq); + + 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; + + Decode(); +} + +void WavDecoder::CloseFile() +{ + if(file_fd) + delete file_fd; + + file_fd = NULL; +} + +int WavDecoder::Read(u8 * buffer, int buffer_size, int pos) +{ + if(!file_fd) + return -1; + + if(CurPos >= (int) DataSize) + return 0; + + file_fd->seek(DataOffset+CurPos, SEEK_SET); + + if(buffer_size > (int) DataSize-CurPos) + buffer_size = DataSize-CurPos; + + int read = file_fd->read(buffer, buffer_size); + if(read > 0) + { + if (Is16Bit) + { + read &= ~0x0001; + + for (u32 i = 0; i < (u32) (read / sizeof (u16)); ++i) + ((u16 *) buffer)[i] = le16(((u16 *) buffer)[i]); + } + CurPos += read; + } + + return read; +} diff --git a/source/SoundOperations/WavDecoder.hpp b/source/SoundOperations/WavDecoder.hpp new file mode 100644 index 00000000..4681bf2b --- /dev/null +++ b/source/SoundOperations/WavDecoder.hpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#ifndef WAVDECODER_HPP_ +#define WAVDECODER_HPP_ + +#include "SoundDecoder.hpp" + +typedef struct +{ + u32 magicRIFF; + u32 size; + u32 magicWAVE; +} SWaveHdr; + +typedef struct +{ + u32 magicFMT; + u32 size; + u16 format; + u16 channels; + u32 freq; + u32 avgBps; + u16 alignment; + u16 bps; +} SWaveFmtChunk; + +typedef struct +{ + u32 magicDATA; + u32 size; +} SWaveChunk; + +class WavDecoder : public SoundDecoder +{ + public: + WavDecoder(const char * filepath); + WavDecoder(const u8 * snd, int len); + ~WavDecoder(); + int GetFormat() { return Format; }; + int GetSampleRate() { return SampleRate; }; + int Read(u8 * buffer, int buffer_size, int pos); + protected: + void OpenFile(); + void CloseFile(); + u32 DataOffset; + u32 DataSize; + u32 SampleRate; + u8 Format; + bool Is16Bit; +}; + +#endif diff --git a/source/libwiigui/gui_bgm.cpp b/source/SoundOperations/gui_bgm.cpp similarity index 87% rename from source/libwiigui/gui_bgm.cpp rename to source/SoundOperations/gui_bgm.cpp index 98c89533..c56bd4fd 100644 --- a/source/libwiigui/gui_bgm.cpp +++ b/source/SoundOperations/gui_bgm.cpp @@ -1,236 +1,224 @@ -/**************************************************************************** - * SettingsPrompts - * USB Loader GX 2009 - * - * Backgroundmusic - ***************************************************************************/ -#include -#include "gui_bgm.h" -#include "menu.h" - -GuiBGM::GuiBGM(const u8 *s, int l, int v) : - GuiSound(s, l, v) -{ - loop = 0; - loopMode = ONCE; - currentPath = NULL; - currentPlaying = 0; - - //shouldn't be needed but - //fixes some kind of weird bug in ogg system - GuiSound::Load(s, l, v); -} - -GuiBGM::~GuiBGM() -{ - if (currentPath) delete[] currentPath; - - ClearList(); -} -; - -void GuiBGM::SetLoop(bool l) -{ -} - -void GuiBGM::SetLoop(int l) -{ - loop = false; - loopMode = ONCE; - - if (l == LOOP) - { - loop = true; - } - else loopMode = l; -} - -bool GuiBGM::Load(const char *path) -{ - if (!path) - { - LoadStandard(); - return false; - } - if (strcmp(path, "") == 0) - { - LoadStandard(); - return false; - } - - if (!GuiSound::Load(path)) - { - LoadStandard(); - return false; - } - - return ParsePath(path); -} - -bool GuiBGM::LoadStandard() -{ - ClearList(); - if (currentPath) - { - delete[] currentPath; - currentPath = NULL; - } - - strcpy(Settings.ogg_path, ""); - - bool ret = GuiSound::Load(bg_music_ogg, bg_music_ogg_size, true); - - if (ret) Play(); - - return ret; -} - -bool GuiBGM::ParsePath(const char * folderpath) -{ - ClearList(); - - if (currentPath) delete[] currentPath; - - currentPath = new char[strlen(folderpath) + 1]; - sprintf(currentPath, "%s", folderpath); - - char * isdirpath = strrchr(folderpath, '.'); - if (isdirpath) - { - char * pathptr = strrchr(currentPath, '/'); - if (pathptr) - { - pathptr++; - pathptr[0] = 0; - } - } - - char * LoadedFilename = strrchr(folderpath, '/') + 1; - - char filename[1024]; - struct stat st; - - DIR_ITER * dir = diropen(currentPath); - if (dir == NULL) - { - LoadStandard(); - return false; - } - u32 counter = 0; - - while (dirnext(dir, filename, &st) == 0) - { - char * fileext = strrchr(filename, '.'); - if (fileext) - { - if (strcasecmp(fileext, ".mp3") == 0 || strcasecmp(fileext, ".ogg") == 0 || strcasecmp(fileext, ".wav") - == 0) - { - AddEntrie(filename); - - if (strcmp(LoadedFilename, filename) == 0) currentPlaying = counter; - - counter++; - } - } - } - - dirclose(dir); - - snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s", folderpath); - - return true; -} - -void GuiBGM::AddEntrie(const char * filename) -{ - if (!filename) return; - - char * NewEntrie = new char[strlen(filename) + 1]; - sprintf(NewEntrie, "%s", filename); - - PlayList.push_back(NewEntrie); -} - -void GuiBGM::ClearList() -{ - for (u32 i = 0; i < PlayList.size(); i++) - { - if (PlayList.at(i) != NULL) - { - delete[] PlayList.at(i); - PlayList.at(i) = NULL; - } - } - - PlayList.clear(); -} - -bool GuiBGM::PlayNext() -{ - if (!currentPath) return false; - - currentPlaying++; - if (currentPlaying >= (int) PlayList.size()) currentPlaying = 0; - - snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s%s", currentPath, PlayList.at(currentPlaying)); - - if (!GuiSound::Load(Settings.ogg_path)) return false; - - Play(); - - return true; -} - -bool GuiBGM::PlayPrevious() -{ - if (!currentPath) return false; - - currentPlaying--; - if (currentPlaying < 0) currentPlaying = PlayList.size() - 1; - - snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s%s", currentPath, PlayList.at(currentPlaying)); - - if (!GuiSound::Load(Settings.ogg_path)) return false; - - Play(); - - return true; -} - -bool GuiBGM::PlayRandom() -{ - if (!currentPath) return false; - - srand(time(NULL)); - - currentPlaying = rand() % PlayList.size(); - - //just in case - if (currentPlaying < 0) - currentPlaying = PlayList.size() - 1; - else if (currentPlaying >= (int) PlayList.size()) currentPlaying = 0; - - snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s%s", currentPath, PlayList.at(currentPlaying)); - - if (!GuiSound::Load(Settings.ogg_path)) return false; - - Play(); - - return true; -} - -void GuiBGM::UpdateState() -{ - if (!IsPlaying()) - { - if (loopMode == DIR_LOOP) - { - PlayNext(); - } - else if (loopMode == RANDOM_BGM) - { - PlayRandom(); - } - } -} +/**************************************************************************** + * SettingsPrompts + * USB Loader GX 2009 + * + * Backgroundmusic + ***************************************************************************/ +#include +#include "gui_bgm.h" +#include "menu.h" + +GuiBGM::GuiBGM(const u8 *s, int l, int v) : + GuiSound(s, l, v, false, 0) +{ + loop = 0; + loopMode = ONCE; + currentPath = NULL; + currentPlaying = 0; + voice = 0; +} + +GuiBGM::~GuiBGM() +{ + if (currentPath) delete[] currentPath; + + ClearList(); +} +; + +void GuiBGM::SetLoop(u8 l) +{ + loopMode = l; + + GuiSound::SetLoop(l == LOOP); +} + +bool GuiBGM::Load(const char *path) +{ + if (!path) + { + LoadStandard(); + return false; + } + if (strcmp(path, "") == 0) + { + LoadStandard(); + return false; + } + + if (!GuiSound::Load(path)) + { + LoadStandard(); + return false; + } + + return ParsePath(path); +} + +bool GuiBGM::LoadStandard() +{ + ClearList(); + if (currentPath) + { + delete[] currentPath; + currentPath = NULL; + } + + strcpy(Settings.ogg_path, ""); + + bool ret = GuiSound::Load(bg_music_ogg, bg_music_ogg_size, false); + + if (ret) Play(); + + return ret; +} + +bool GuiBGM::ParsePath(const char * folderpath) +{ + ClearList(); + + if (currentPath) delete[] currentPath; + + currentPath = new char[strlen(folderpath) + 1]; + sprintf(currentPath, "%s", folderpath); + + char * isdirpath = strrchr(folderpath, '.'); + if (isdirpath) + { + char * pathptr = strrchr(currentPath, '/'); + if (pathptr) + { + pathptr++; + pathptr[0] = 0; + } + } + + char * LoadedFilename = strrchr(folderpath, '/') + 1; + + char filename[1024]; + struct stat st; + + DIR_ITER * dir = diropen(currentPath); + if (dir == NULL) + { + LoadStandard(); + return false; + } + u32 counter = 0; + + while (dirnext(dir, filename, &st) == 0) + { + char * fileext = strrchr(filename, '.'); + if (fileext) + { + if (strcasecmp(fileext, ".mp3") == 0 || strcasecmp(fileext, ".ogg") == 0 || strcasecmp(fileext, ".wav") + == 0) + { + AddEntrie(filename); + + if (strcmp(LoadedFilename, filename) == 0) currentPlaying = counter; + + counter++; + } + } + } + + dirclose(dir); + + snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s", folderpath); + + return true; +} + +void GuiBGM::AddEntrie(const char * filename) +{ + if (!filename) return; + + char * NewEntrie = new char[strlen(filename) + 1]; + sprintf(NewEntrie, "%s", filename); + + PlayList.push_back(NewEntrie); +} + +void GuiBGM::ClearList() +{ + for (u32 i = 0; i < PlayList.size(); i++) + { + if (PlayList.at(i) != NULL) + { + delete[] PlayList.at(i); + PlayList.at(i) = NULL; + } + } + + PlayList.clear(); +} + +bool GuiBGM::PlayNext() +{ + if (!currentPath) return false; + + currentPlaying++; + if (currentPlaying >= (int) PlayList.size()) currentPlaying = 0; + + snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s%s", currentPath, PlayList.at(currentPlaying)); + + if (!GuiSound::Load(Settings.ogg_path)) return false; + + Play(); + + return true; +} + +bool GuiBGM::PlayPrevious() +{ + if (!currentPath) return false; + + currentPlaying--; + if (currentPlaying < 0) currentPlaying = PlayList.size() - 1; + + snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s%s", currentPath, PlayList.at(currentPlaying)); + + if (!GuiSound::Load(Settings.ogg_path)) return false; + + Play(); + + return true; +} + +bool GuiBGM::PlayRandom() +{ + if (!currentPath) return false; + + srand(time(NULL)); + + currentPlaying = rand() % PlayList.size(); + + //just in case + if (currentPlaying < 0) + currentPlaying = PlayList.size() - 1; + else if (currentPlaying >= (int) PlayList.size()) currentPlaying = 0; + + snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s%s", currentPath, PlayList.at(currentPlaying)); + + if (!GuiSound::Load(Settings.ogg_path)) return false; + + Play(); + + return true; +} + +void GuiBGM::UpdateState() +{ + if (!IsPlaying()) + { + if (loopMode == DIR_LOOP) + { + PlayNext(); + } + else if (loopMode == RANDOM_BGM) + { + PlayRandom(); + } + } +} diff --git a/source/libwiigui/gui_bgm.h b/source/SoundOperations/gui_bgm.h similarity index 86% rename from source/libwiigui/gui_bgm.h rename to source/SoundOperations/gui_bgm.h index 8fe076d1..741ce36a 100644 --- a/source/libwiigui/gui_bgm.h +++ b/source/SoundOperations/gui_bgm.h @@ -1,42 +1,42 @@ -/**************************************************************************** - * SettingsPrompts - * USB Loader GX 2009 - * - * Backgroundmusic - ***************************************************************************/ - -#ifndef _BGM_H_ -#define _BGM_H_ - -#include "libwiigui/gui.h" - -enum -{ - ONCE = 0, LOOP, RANDOM_BGM, DIR_LOOP -}; - -class GuiBGM: public GuiSound -{ - public: - GuiBGM(const u8 *s, int l, int v); - ~GuiBGM(); - bool Load(const char *path); - bool LoadStandard(); - bool ParsePath(const char * folderpath); - bool PlayNext(); - bool PlayPrevious(); - bool PlayRandom(); - void SetLoop(bool l); - void SetLoop(int l); - void UpdateState(); - protected: - void AddEntrie(const char * filename); - void ClearList(); - - int currentPlaying; - int loopMode; - char * currentPath; - std::vector PlayList; -}; - -#endif +/**************************************************************************** + * SettingsPrompts + * USB Loader GX 2009 + * + * Backgroundmusic + ***************************************************************************/ + +#ifndef _BGM_H_ +#define _BGM_H_ + +#include +#include "gui_sound.h" + +enum +{ + ONCE = 0, LOOP, RANDOM_BGM, DIR_LOOP +}; + +class GuiBGM: public GuiSound +{ + public: + GuiBGM(const u8 *s, int l, int v); + ~GuiBGM(); + bool Load(const char *path); + bool LoadStandard(); + bool ParsePath(const char * folderpath); + bool PlayNext(); + bool PlayPrevious(); + bool PlayRandom(); + void SetLoop(u8 l); + void UpdateState(); + protected: + void AddEntrie(const char * filename); + void ClearList(); + + int currentPlaying; + int loopMode; + char * currentPath; + std::vector PlayList; +}; + +#endif diff --git a/source/SoundOperations/gui_sound.cpp b/source/SoundOperations/gui_sound.cpp new file mode 100644 index 00000000..350ecaaf --- /dev/null +++ b/source/SoundOperations/gui_sound.cpp @@ -0,0 +1,380 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include "libwiigui/gui.h" +#include "utils/uncompress.h" +#include "FileOperations/fileops.h" +#include "SoundHandler.hpp" +#include "WavDecoder.hpp" + +#define MAX_SND_VOICES 16 + +static bool VoiceUsed[MAX_SND_VOICES] = +{ + true, false, false, false, false, false, + false, false, false, false, false, false, + false, false, false, false +}; + +static inline int GetFirstUnusedVoice() +{ + for(int i = 1; i < MAX_SND_VOICES; i++) + { + if(VoiceUsed[i] == false) + return i; + } + + return -1; +} + +extern "C" void SoundCallback(s32 voice) +{ + SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); + if(!decoder) + return; + + if(decoder->IsBufferReady()) + { + if(ASND_AddVoice(voice, decoder->GetBuffer(), decoder->GetBufferSize()) == SND_OK) + { + decoder->LoadNext(); + SoundHandler::Instance()->ThreadSignal(); + } + } + else if(decoder->IsEOF()) + { + ASND_StopVoice(voice); + //if(voice == 0) + //MusicPlayer::Instance()->SetPlaybackFinished(true); //see if next music must be played + } + else + { + SoundHandler::Instance()->ThreadSignal(); + } +} + +GuiSound::GuiSound(const char * filepath) +{ + sound = NULL; + length = 0; + voice = GetFirstUnusedVoice(); + if(voice > 0) + VoiceUsed[voice] = true; + + volume = 255; + SoundEffectLength = 0; + loop = false; + allocated = false; + Load(filepath); +} + +GuiSound::GuiSound(const u8 * snd, s32 len, int vol, bool isallocated, int v) +{ + sound = NULL; + length = 0; + if(v < 0) + voice = GetFirstUnusedVoice(); + else + voice = v; + + if(voice > 0) + VoiceUsed[voice] = true; + + volume = vol; + SoundEffectLength = 0; + loop = false; + allocated = false; + Load(snd, len, isallocated); +} + +GuiSound::~GuiSound() +{ + FreeMemory(); + if(voice > 0) + VoiceUsed[voice] = false; +} + +void GuiSound::FreeMemory() +{ + this->Stop(); + + SoundHandler::Instance()->RemoveDecoder(voice); + + if(allocated && sound != NULL) + { + free(sound); + sound = NULL; + allocated = false; + } + + SoundEffectLength = 0; +} + +bool GuiSound::Load(const char * filepath) +{ + FreeMemory(); + + if(!filepath) + return false; + + u32 magic; + FILE * f = fopen(filepath, "rb"); + if(!f) + return false; + + fread(&magic, 1, 4, f); + fclose(f); + + if(magic == 'IMD5') + { + u8 * snd = NULL; + u64 filesize = 0; + LoadFileToMem(filepath, &snd, &filesize); + return Load(snd, filesize, true); + } + + SoundHandler::Instance()->AddDecoder(voice, filepath); + + SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); + if(!decoder) + return false; + + if(!decoder->IsBufferReady()) + { + SoundHandler::Instance()->RemoveDecoder(voice); + return false; + } + + SetLoop(loop); + + return true; +} + +bool GuiSound::Load(const u8 * snd, s32 len, bool isallocated) +{ + FreeMemory(); + + if(!snd) + return false; + + if(!isallocated && *((u32 *) snd) == 'RIFF') + { + return LoadSoundEffect(snd, len); + } + + if(*((u32 *) snd) == 'IMD5') + { + UncompressSoundbin(snd, len, isallocated); + } + else + { + sound = (u8 *) snd; + length = len; + allocated = isallocated; + } + + SoundHandler::Instance()->AddDecoder(voice, sound, length); + + SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); + if(!decoder) + return false; + + if(!decoder->IsBufferReady()) + { + SoundHandler::Instance()->RemoveDecoder(voice); + return false; + } + + SetLoop(loop); + + return true; +} + +bool GuiSound::LoadSoundEffect(const u8 * snd, s32 len) +{ + WavDecoder decoder(snd, len); + decoder.Rewind(); + + u32 done = 0; + sound = (u8 *) malloc(4096); + memset(sound, 0, 4096); + + while(1) + { + u8 * tmpsnd = (u8 *) realloc(sound, done+4096); + if(!tmpsnd) + { + free(sound); + sound = NULL; + return false; + } + + sound = tmpsnd; + + int read = decoder.Read(sound+done, 4096, done); + if(read <= 0) + break; + + done += read; + } + + sound = (u8 *) realloc(sound, done); + SoundEffectLength = done; + allocated = true; + + return true; +} + +void GuiSound::Play() +{ + if(SoundEffectLength > 0) + { + ASND_StopVoice(voice); + ASND_SetVoice(voice, VOICE_STEREO_16BIT, 32000, 0, sound, SoundEffectLength, volume, volume, NULL); + return; + } + + if(IsPlaying()) + return; + + if(voice < 0 || voice >= 16) + return; + + SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); + if(!decoder) + return; + + if(decoder->IsEOF()) + { + ASND_StopVoice(voice); + decoder->ClearBuffer(); + decoder->Rewind(); + decoder->Decode(); + } + + u8 * curbuffer = decoder->GetBuffer(); + int bufsize = decoder->GetBufferSize(); + decoder->LoadNext(); + SoundHandler::Instance()->ThreadSignal(); + + ASND_SetVoice(voice, decoder->GetFormat(), decoder->GetSampleRate(), 0, curbuffer, bufsize, volume, volume, SoundCallback); +} + +void GuiSound::Stop() +{ + if(voice < 0 || voice >= 16) + return; + + ASND_StopVoice(voice); + + SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); + if(!decoder) + return; + + decoder->ClearBuffer(); + Rewind(); + SoundHandler::Instance()->ThreadSignal(); +} + +void GuiSound::Pause() +{ + if(voice < 0 || voice >= 16) + return; + + ASND_StopVoice(voice); +} + +void GuiSound::Resume() +{ + Play(); +} + +bool GuiSound::IsPlaying() +{ + if(voice < 0 || voice >= 16) + return false; + + int result = ASND_StatusVoice(voice); + + if(result == SND_WORKING || result == SND_WAITING) + return true; + + return false; +} + +void GuiSound::SetVolume(int vol) +{ + if(voice < 0 || voice >= 16) + return; + + if(vol < 0) + return; + + volume = 255*(vol/100.0); + ASND_ChangeVolumeVoice(voice, volume, volume); +} + +void GuiSound::SetLoop(u8 l) +{ + loop = l; + + SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); + if(!decoder) + return; + + decoder->SetLoop(l == 1); +} + +void GuiSound::Rewind() +{ + SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); + if(!decoder) + return; + + decoder->Rewind(); +} + +void GuiSound::UncompressSoundbin(const u8 * snd, int len, bool isallocated) +{ + const u8 * file = snd+32; + if(*((u32 *) file) == 'LZ77') + { + u32 size = 0; + sound = uncompressLZ77(file, len-32, &size); + length = size; + } + else + { + length = len-32; + sound = (u8 *) malloc(length); + memcpy(sound, file, length); + } + + if(isallocated) + free((u8 *) snd); + + allocated = true; +} diff --git a/source/SoundOperations/gui_sound.h b/source/SoundOperations/gui_sound.h new file mode 100644 index 00000000..1101b16b --- /dev/null +++ b/source/SoundOperations/gui_sound.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#ifndef GUI_SOUND_H_ +#define GUI_SOUND_H_ + +#include + +//!Sound conversion and playback. A wrapper for other sound libraries - ASND, libmad, ltremor, etc +class GuiSound +{ + public: + //!Constructor + //!\param sound Pointer to the sound data + //!\param filesize Length of sound data + GuiSound(const char * filepath); + GuiSound(const u8 * sound, int filesize, int volume, bool allocated = false, int voice = -1); + //!Destructor + ~GuiSound(); + //!Load a file and replace the old one + bool Load(const char * filepath); + //!Load a file and replace the old one + bool Load(const u8 * sound, int filesize, bool allocated = true); + //!For quick playback of the internal soundeffects + bool LoadSoundEffect(const u8 * snd, s32 len); + //!Start sound playback + void Play(); + //!Stop sound playback + void Stop(); + //!Pause sound playback + void Pause(); + //!Resume sound playback + void Resume(); + //!Checks if the sound is currently playing + //!\return true if sound is playing, false otherwise + bool IsPlaying(); + //!Rewind the music + void Rewind(); + //!Set sound volume + //!\param v Sound volume (0-100) + void SetVolume(int v); + //!\param l Loop (true to loop) + void SetLoop(u8 l); + //!Special sound case for sound.bin + void UncompressSoundbin(const u8 * snd, int len, bool isallocated); + protected: + //!Stops sound and frees all memory/closes files + void FreeMemory(); + u8 * sound; //!< Pointer to the sound data + int length; //!< Length of sound data + s32 voice; //!< Currently assigned ASND voice channel + int volume; //!< Sound volume (0-100) + u8 loop; //!< Loop sound playback + u32 SoundEffectLength; //!< Check if it is an app soundeffect for faster playback + bool allocated; //!< Is the file allocated or not +}; + +#endif diff --git a/source/bannersound.cpp b/source/bannersound.cpp index 48d11de2..8a6939ff 100644 --- a/source/bannersound.cpp +++ b/source/bannersound.cpp @@ -9,6 +9,7 @@ #include "libs/libwbfs/libwbfs.h" #include "language/gettext.h" #include "bannersound.h" +#include "utils/uncompress.h" struct IMD5Header { @@ -67,58 +68,6 @@ 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; @@ -181,7 +130,7 @@ const u8 *LoadBannerSound(const u8 *discid, u32 *size) if (*((u32*) soundChunk) == 0x4C5A3737 /*"LZ77"*/) { u32 uncSize = 0; - u8 * uncompressed_data = uncompressLZ77(soundChunk, soundChunkSize, uncSize); + u8 * uncompressed_data = uncompressLZ77(soundChunk, soundChunkSize, &uncSize); if (!uncompressed_data) { // WindowPrompt(tr("Can't decompress LZ77"), 0, tr("OK")); @@ -192,7 +141,7 @@ const u8 *LoadBannerSound(const u8 *discid, u32 *size) free(opening_bnr); return uncompressed_data; } - u8 *out = new (std::nothrow) u8[soundChunkSize]; + u8 *out = (u8 *) malloc(soundChunkSize); if (out) { memcpy(out, soundChunk, soundChunkSize); diff --git a/source/cheats/cheatmenu.cpp b/source/cheats/cheatmenu.cpp index 81684d4e..c4964e3e 100644 --- a/source/cheats/cheatmenu.cpp +++ b/source/cheats/cheatmenu.cpp @@ -30,10 +30,6 @@ int CheatMenu(const char * gameID) bool exit = false; int ret = 1; - // 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData settingsbg(Resources::GetFile("settings_background.png"), Resources::GetFileSize("settings_background.png")); GuiImage settingsbackground(&settingsbg); @@ -46,14 +42,14 @@ int CheatMenu(const char * gameID) GuiText backBtnTxt(tr( "Back" ), 22, Theme.prompttext); backBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30); GuiImage backBtnImg(&btnOutline); - GuiButton backBtn(&backBtnImg, &backBtnImg, 2, 3, -140, 400, &trigA, NULL, btnClick2, 1); + GuiButton backBtn(&backBtnImg, &backBtnImg, 2, 3, -140, 400, &trigA, NULL, btnSoundClick2, 1); backBtn.SetLabel(&backBtnTxt); backBtn.SetTrigger(&trigB); GuiText createBtnTxt(tr( "Create" ), 22, Theme.prompttext); createBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30); GuiImage createBtnImg(&btnOutline); - GuiButton createBtn(&createBtnImg, &createBtnImg, 2, 3, 160, 400, &trigA, NULL, btnClick2, 1); + GuiButton createBtn(&createBtnImg, &createBtnImg, 2, 3, 160, 400, &trigA, NULL, btnSoundClick2, 1); createBtn.SetLabel(&createBtnTxt); char txtfilename[55]; diff --git a/source/fatmounter.c b/source/fatmounter.c index b134ef77..39212be0 100644 --- a/source/fatmounter.c +++ b/source/fatmounter.c @@ -82,6 +82,7 @@ void USBDevice_deInit() fatUnmount("USB:/"); //only shutdown libogc usb and not the cios one __io_usbstorage.shutdown(); + __io_usbstorage2.shutdown(); fat_usb_mount = 0; fat_usb_sec = 0; diff --git a/source/filelist.h b/source/filelist.h index 4c6e9a47..6009cb67 100644 --- a/source/filelist.h +++ b/source/filelist.h @@ -71,14 +71,14 @@ extern const u32 credits_button_png_size; extern const u8 credits_button_over_png[]; extern const u32 credits_button_over_png_size; -extern const u8 button_over_pcm[]; -extern const u32 button_over_pcm_size; +extern const u8 button_over_wav[]; +extern const u32 button_over_wav_size; -extern const u8 button_click_pcm[]; -extern const u32 button_click_pcm_size; +extern const u8 button_click_wav[]; +extern const u32 button_click_wav_size; -extern const u8 button_click2_pcm[]; -extern const u32 button_click2_pcm_size; +extern const u8 button_click2_wav[]; +extern const u32 button_click2_wav_size; extern const u8 tooltip_left_png[]; extern const u32 tooltip_left_png_size; diff --git a/source/homebrewboot/HomebrewBrowse.cpp b/source/homebrewboot/HomebrewBrowse.cpp index f380055a..7d823952 100644 --- a/source/homebrewboot/HomebrewBrowse.cpp +++ b/source/homebrewboot/HomebrewBrowse.cpp @@ -208,13 +208,6 @@ int MenuHomebrewBrowse() int slidedirection = FADE; - /*** Sound Variables ***/ - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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); - GuiSound btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); - /*** Image Variables ***/ GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); @@ -273,7 +266,7 @@ int MenuHomebrewBrowse() backBtnTxt.SetWidescreen(Settings.widescreen); backBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton backBtn(&backBtnImg, &backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton backBtn(&backBtnImg, &backBtnImg, 2, 3, -180, 400, &trigA, btnSoundOver, btnSoundClick2, 1); backBtn.SetLabel(&backBtnTxt); backBtn.SetTrigger(&trigB); @@ -285,8 +278,8 @@ int MenuHomebrewBrowse() GoLeftBtn.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); GoLeftBtn.SetPosition(25, -25); GoLeftBtn.SetImage(&GoLeftImg); - GoLeftBtn.SetSoundOver(&btnSoundOver); - GoLeftBtn.SetSoundClick(btnClick2); + GoLeftBtn.SetSoundOver(btnSoundOver); + GoLeftBtn.SetSoundClick(btnSoundClick2); GoLeftBtn.SetEffectGrow(); GoLeftBtn.SetTrigger(&trigA); GoLeftBtn.SetTrigger(&trigL); @@ -297,8 +290,8 @@ int MenuHomebrewBrowse() GoRightBtn.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE); GoRightBtn.SetPosition(-25, -25); GoRightBtn.SetImage(&GoRightImg); - GoRightBtn.SetSoundOver(&btnSoundOver); - GoRightBtn.SetSoundClick(btnClick2); + GoRightBtn.SetSoundOver(btnSoundOver); + GoRightBtn.SetSoundClick(btnSoundClick2); GoRightBtn.SetEffectGrow(); GoRightBtn.SetTrigger(&trigA); GoRightBtn.SetTrigger(&trigR); @@ -332,8 +325,8 @@ int MenuHomebrewBrowse() MainButton1.SetLabel(&MainButton1Txt); MainButton1.SetLabel(&MainButton1DescTxt, 1); MainButton1.SetLabelOver(&MainButton1DescOverTxt, 1); - MainButton1.SetSoundOver(&btnSoundOver); - MainButton1.SetSoundClick(&btnClick1); + MainButton1.SetSoundOver(btnSoundOver); + MainButton1.SetSoundClick(btnSoundClick); MainButton1.SetEffectGrow(); MainButton1.SetTrigger(&trigA); @@ -359,8 +352,8 @@ int MenuHomebrewBrowse() MainButton2.SetLabel(&MainButton2Txt); MainButton2.SetLabel(&MainButton2DescTxt, 1); MainButton2.SetLabelOver(&MainButton2DescOverTxt, 1); - MainButton2.SetSoundOver(&btnSoundOver); - MainButton2.SetSoundClick(&btnClick1); + MainButton2.SetSoundOver(btnSoundOver); + MainButton2.SetSoundClick(btnSoundClick); MainButton2.SetEffectGrow(); MainButton2.SetTrigger(&trigA); @@ -386,8 +379,8 @@ int MenuHomebrewBrowse() MainButton3.SetLabel(&MainButton3Txt); MainButton3.SetLabel(&MainButton3DescTxt, 1); MainButton3.SetLabelOver(&MainButton3DescOverTxt, 1); - MainButton3.SetSoundOver(&btnSoundOver); - MainButton3.SetSoundClick(&btnClick1); + MainButton3.SetSoundOver(btnSoundOver); + MainButton3.SetSoundClick(btnSoundClick); MainButton3.SetEffectGrow(); MainButton3.SetTrigger(&trigA); @@ -416,8 +409,8 @@ int MenuHomebrewBrowse() MainButton4.SetLabel(&MainButton4Txt); MainButton4.SetLabel(&MainButton4DescTxt, 1); MainButton4.SetLabelOver(&MainButton4DescOverTxt, 1); - MainButton4.SetSoundOver(&btnSoundOver); - MainButton4.SetSoundClick(&btnClick1); + MainButton4.SetSoundOver(btnSoundOver); + MainButton4.SetSoundClick(btnSoundClick); MainButton4.SetEffectGrow(); MainButton4.SetTrigger(&trigA); @@ -429,8 +422,8 @@ int MenuHomebrewBrowse() GuiButton wifiBtn(wifiImg.GetWidth(), wifiImg.GetHeight()); wifiBtn.SetImage(&wifiImg); wifiBtn.SetPosition(500, 400); - wifiBtn.SetSoundOver(&btnSoundOver); - wifiBtn.SetSoundClick(&btnClick1); + wifiBtn.SetSoundOver(btnSoundOver); + wifiBtn.SetSoundClick(btnSoundClick); wifiBtn.SetEffectGrow(); wifiBtn.SetAlpha(80); wifiBtn.SetTrigger(&trigA); @@ -441,8 +434,8 @@ int MenuHomebrewBrowse() channelBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP); channelBtn.SetPosition(440, 400); channelBtn.SetImage(&channelBtnImg); - channelBtn.SetSoundOver(&btnSoundOver); - channelBtn.SetSoundClick(btnClick2); + channelBtn.SetSoundOver(btnSoundOver); + channelBtn.SetSoundClick(btnSoundClick2); channelBtn.SetEffectGrow(); channelBtn.SetTrigger(&trigA); diff --git a/source/libs/libwbfs/libwbfs.c b/source/libs/libwbfs/libwbfs.c index 120be9ea..57a4df82 100644 --- a/source/libs/libwbfs/libwbfs.c +++ b/source/libs/libwbfs/libwbfs.c @@ -1,827 +1,827 @@ -// Copyright 2009 Kwiirk -// Licensed under the terms of the GNU GPL, version 2 -// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt - -// Modified by oggzee - -#include "libwbfs.h" - -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) - -#define ERROR(x) do {wbfs_error(x);goto error;}while(0) -#define ALIGN_LBA(x) (((x)+p->hd_sec_sz-1)&(~(p->hd_sec_sz-1))) - -wbfs_t wbfs_iso_file; - -static int force_mode = 0; - -void wbfs_set_force_mode(int force) -{ - force_mode = force; -} - -static u8 size_to_shift(u32 size) -{ - u8 ret = 0; - while (size) - { - ret++; - size >>= 1; - } - return ret - 1; -} -#define read_le32_unaligned(x) ((x)[0]|((x)[1]<<8)|((x)[2]<<16)|((x)[3]<<24)) - -wbfs_t*wbfs_open_hd(rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector, void *callback_data, - int hd_sector_size, int num_hd_sector __attribute( ( unused ) ), int reset) -{ - int i = num_hd_sector, ret; - u8 *ptr, *tmp_buffer = wbfs_ioalloc( hd_sector_size ); - u8 part_table[16 * 4]; - ret = read_hdsector(callback_data, 0, 1, tmp_buffer); - if (ret) return 0; - //find wbfs partition - wbfs_memcpy( part_table, tmp_buffer + 0x1be, 16*4 ); - ptr = part_table; - for (i = 0; i < 4; i++, ptr += 16) - { - u32 part_lba = read_le32_unaligned( ptr + 0x8 ); - wbfs_head_t *head = (wbfs_head_t *) tmp_buffer; - ret = read_hdsector(callback_data, part_lba, 1, tmp_buffer); - // verify there is the magic. - if (head->magic == wbfs_htonl( WBFS_MAGIC )) - { - wbfs_t*p = wbfs_open_partition(read_hdsector, write_hdsector, callback_data, hd_sector_size, 0, part_lba, - reset); - wbfs_iofree( tmp_buffer ); - return p; - } - } - wbfs_iofree( tmp_buffer ); - if (reset)// XXX make a empty hd partition.. - { - } - return 0; -} -wbfs_t*wbfs_open_partition(rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector, - void *callback_data, int hd_sector_size, int num_hd_sector, u32 part_lba, int reset) -{ - wbfs_t *p = wbfs_malloc( sizeof( wbfs_t ) ); - - wbfs_head_t *head = wbfs_ioalloc( hd_sector_size ? hd_sector_size : 512 ); - - //constants, but put here for consistancy - p->wii_sec_sz = 0x8000; - p->wii_sec_sz_s = size_to_shift(0x8000); - p->n_wii_sec = (num_hd_sector / 0x8000) * hd_sector_size; - p->n_wii_sec_per_disc = 143432 * 2;//support for double layers discs.. - p->head = head; - p->part_lba = part_lba; - // init the partition - if (reset) - { - u8 sz_s; - wbfs_memset( head, 0, hd_sector_size ); - head->magic = wbfs_htonl( WBFS_MAGIC ); - head->hd_sec_sz_s = size_to_shift(hd_sector_size); - head->n_hd_sec = wbfs_htonl( num_hd_sector ); - // choose minimum wblk_sz that fits this partition size - for (sz_s = 6; sz_s < 11; sz_s++) - { - // ensure that wbfs_sec_sz is big enough to address every blocks using 16 bits - if (p->n_wii_sec < ((1U << 16) * (1 << sz_s))) break; - } - head->wbfs_sec_sz_s = sz_s + p->wii_sec_sz_s; - } - else read_hdsector(callback_data, p->part_lba, 1, head); - if (head->magic != wbfs_htonl( WBFS_MAGIC )) - ERROR( "bad magic" ); - if (!force_mode && hd_sector_size && head->hd_sec_sz_s != size_to_shift(hd_sector_size)) - ERROR( "hd sector size doesn't match" ); - if (!force_mode && num_hd_sector && head->n_hd_sec != wbfs_htonl( num_hd_sector )) - ERROR( "hd num sector doesn't match" ); - p->hd_sec_sz = 1 << head->hd_sec_sz_s; - p->hd_sec_sz_s = head->hd_sec_sz_s; - p->n_hd_sec = wbfs_ntohl( head->n_hd_sec ); - - p->n_wii_sec = (p->n_hd_sec / p->wii_sec_sz) * (p->hd_sec_sz); - - p->wbfs_sec_sz_s = head->wbfs_sec_sz_s; - p->wbfs_sec_sz = 1 << p->wbfs_sec_sz_s; - p->n_wbfs_sec = p->n_wii_sec >> (p->wbfs_sec_sz_s - p->wii_sec_sz_s); - p->n_wbfs_sec_per_disc = p->n_wii_sec_per_disc >> (p->wbfs_sec_sz_s - p->wii_sec_sz_s); - p->disc_info_sz = ALIGN_LBA( sizeof( wbfs_disc_info_t ) + p->n_wbfs_sec_per_disc * 2 ); - - //printf("hd_sector_size %X wii_sector size %X wbfs sector_size %X\n",p->hd_sec_sz,p->wii_sec_sz,p->wbfs_sec_sz); - p->read_hdsector = read_hdsector; - p->write_hdsector = write_hdsector; - p->callback_data = callback_data; - - p->freeblks_lba = (p->wbfs_sec_sz - p->n_wbfs_sec / 8) >> p->hd_sec_sz_s; - - if (!reset) - p->freeblks = 0; // will alloc and read only if needed - else - { - // init with all free blocks - p->freeblks = wbfs_ioalloc( ALIGN_LBA( p->n_wbfs_sec / 8 ) ); - wbfs_memset( p->freeblks, 0xff, p->n_wbfs_sec / 8 ); - } - p->max_disc = (p->freeblks_lba - 1) / (p->disc_info_sz >> p->hd_sec_sz_s); - if (p->max_disc > p->hd_sec_sz - sizeof(wbfs_head_t)) p->max_disc = p->hd_sec_sz - sizeof(wbfs_head_t); - - p->tmp_buffer = wbfs_ioalloc( p->hd_sec_sz ); - p->n_disc_open = 0; - return p; - error: wbfs_free( p ); - wbfs_iofree( head ); - return 0; - -} - -void wbfs_sync(wbfs_t*p) -{ - // copy back descriptors - if (p->write_hdsector) - { - p->write_hdsector(p->callback_data, p->part_lba + 0, 1, p->head); - - if (p->freeblks) p->write_hdsector(p->callback_data, p->part_lba + p->freeblks_lba, - ALIGN_LBA( p->n_wbfs_sec / 8 ) >> p->hd_sec_sz_s, p->freeblks); - } -} - -void wbfs_close(wbfs_t*p) -{ - wbfs_sync(p); - - if (p->n_disc_open) - ERROR( "trying to close wbfs while discs still open" ); - - wbfs_iofree( p->head ); - wbfs_iofree( p->tmp_buffer ); - if (p->freeblks) wbfs_iofree( p->freeblks ); - - wbfs_free( p ); - - error: return; -} - -wbfs_disc_t *wbfs_open_disc(wbfs_t* p, u8 *discid) -{ - u32 i; - int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; - wbfs_disc_t *d = 0; - for (i = 0; i < p->max_disc; i++) - { - if (p->head->disc_table[i]) - { - p->read_hdsector(p->callback_data, p->part_lba + 1 + i * disc_info_sz_lba, 1, p->tmp_buffer); - if (wbfs_memcmp( discid, p->tmp_buffer, 6 ) == 0) - { - d = wbfs_malloc( sizeof( *d ) ); - if (!d) - ERROR( "allocating memory" ); - d->p = p; - d->i = i; - d->header = wbfs_ioalloc( p->disc_info_sz ); - if (!d->header) - ERROR( "allocating memory" ); - p->read_hdsector(p->callback_data, p->part_lba + 1 + i * disc_info_sz_lba, disc_info_sz_lba, d->header); - p->n_disc_open++; - // for(i=0;in_wbfs_sec_per_disc;i++) - // printf("%d,",wbfs_ntohs(d->header->wlba_table[i])); - return d; - } - } - } - return 0; - error: if (d) wbfs_iofree( d ); - return 0; - -} -void wbfs_close_disc(wbfs_disc_t*d) -{ - d->p->n_disc_open--; - wbfs_iofree( d->header ); - wbfs_free( d ); -} -// offset is pointing 32bit words to address the whole dvd, although len is in bytes -int wbfs_disc_read(wbfs_disc_t*d, u32 offset, u32 len, u8 *data) -{ - if (d->p == &wbfs_iso_file) - { - return wbfs_iso_file_read(d, offset, data, len); - } - - wbfs_t *p = d->p; - u16 wlba = offset >> (p->wbfs_sec_sz_s - 2); - u32 iwlba_shift = p->wbfs_sec_sz_s - p->hd_sec_sz_s; - u32 lba_mask = (p->wbfs_sec_sz - 1) >> (p->hd_sec_sz_s); - u32 lba = (offset >> (p->hd_sec_sz_s - 2)) & lba_mask; - u32 off = offset & ((p->hd_sec_sz >> 2) - 1); - u16 iwlba = wbfs_ntohs( d->header->wlba_table[wlba] ); - u32 len_copied; - int err = 0; - u8 *ptr = data; - if (unlikely( iwlba == 0 )) return 1; - if (unlikely( off )) - { - off *= 4; - err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba << iwlba_shift) + lba, 1, p->tmp_buffer); - if (err) return err; - len_copied = p->hd_sec_sz - off; - if (likely( len < len_copied )) len_copied = len; - wbfs_memcpy( ptr, p->tmp_buffer + off, len_copied ); - len -= len_copied; - ptr += len_copied; - lba++; - if (unlikely( lba > lba_mask && len )) - { - lba = 0; - iwlba = wbfs_ntohs( d->header->wlba_table[++wlba] ); - if (unlikely( iwlba == 0 )) return 1; - } - } - while (likely( len >= p->hd_sec_sz )) - { - u32 nlb = len >> (p->hd_sec_sz_s); - - if (unlikely( lba + nlb > p->wbfs_sec_sz )) // dont cross wbfs sectors.. - nlb = p->wbfs_sec_sz - lba; - err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba << iwlba_shift) + lba, nlb, ptr); - if (err) return err; - len -= nlb << p->hd_sec_sz_s; - ptr += nlb << p->hd_sec_sz_s; - lba += nlb; - if (unlikely( lba > lba_mask && len )) - { - lba = 0; - iwlba = wbfs_ntohs( d->header->wlba_table[++wlba] ); - if (unlikely( iwlba == 0 )) return 1; - } - } - if (unlikely( len )) - { - err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba << iwlba_shift) + lba, 1, p->tmp_buffer); - if (err) return err; - wbfs_memcpy( ptr, p->tmp_buffer, len ); - } - return 0; -} - -// disc listing -u32 wbfs_count_discs(wbfs_t*p) -{ - u32 i, count = 0; - for (i = 0; i < p->max_disc; i++) - if (p->head->disc_table[i]) count++; - return count; - -} - -u32 wbfs_sector_used(wbfs_t *p, wbfs_disc_info_t *di) -{ - u32 tot_blk = 0, j; - for (j = 0; j < p->n_wbfs_sec_per_disc; j++) - if (wbfs_ntohs( di->wlba_table[j] )) tot_blk++; - return tot_blk; -} - -u32 wbfs_sector_used2(wbfs_t *p, wbfs_disc_info_t *di, u32 *last_blk) -{ - u32 tot_blk = 0, j; - for (j = 0; j < p->n_wbfs_sec_per_disc; j++) - if (wbfs_ntohs( di->wlba_table[j] )) - { - if (last_blk) *last_blk = j; - tot_blk++; - } - return tot_blk; -} - -u32 wbfs_get_disc_info(wbfs_t*p, u32 index, u8 *header, int header_size, u32 *size)//size in 32 bit -{ - u32 i, count = 0; - if (!p) return 1; - int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; - - for (i = 0; i < p->max_disc; i++) - if (p->head->disc_table[i]) - { - if (count++ == index) - { - p->read_hdsector(p->callback_data, p->part_lba + 1 + i * disc_info_sz_lba, 1, p->tmp_buffer); - if (header_size > (int) p->hd_sec_sz) header_size = p->hd_sec_sz; - u32 magic = wbfs_ntohl( *( u32* )( p->tmp_buffer + 24 ) ); - if (magic != 0x5D1C9EA3) - { - p->head->disc_table[i] = 0; - return 1; - } - memcpy(header, p->tmp_buffer, header_size); - if (size) - { - u8 *header = wbfs_ioalloc( p->disc_info_sz ); - p->read_hdsector(p->callback_data, p->part_lba + 1 + i * disc_info_sz_lba, disc_info_sz_lba, header); - u32 sec_used = wbfs_sector_used(p, (wbfs_disc_info_t *) header); - wbfs_iofree( header ); - *size = sec_used << (p->wbfs_sec_sz_s - 2); - } - return 0; - } - } - return 1; -} - -static void load_freeblocks(wbfs_t*p) -{ - if (p->freeblks) return; - // XXX should handle malloc error.. - p->freeblks = wbfs_ioalloc( ALIGN_LBA( p->n_wbfs_sec / 8 ) ); - p->read_hdsector(p->callback_data, p->part_lba + p->freeblks_lba, ALIGN_LBA( p->n_wbfs_sec / 8 ) >> p->hd_sec_sz_s, - p->freeblks); - -} -u32 wbfs_count_usedblocks(wbfs_t*p) -{ - u32 i, j, count = 0; - load_freeblocks(p); - for (i = 0; i < p->n_wbfs_sec / (8 * 4); i++) - { - u32 v = wbfs_ntohl( p->freeblks[i] ); - if (v == ~0U) - count += 32; - else if (v != 0) for (j = 0; j < 32; j++) - if (v & (1 << j)) count++; - } - return count; -} - -// write access - - -//static -int block_used(u8 *used, u32 i, u32 wblk_sz) -{ - u32 k; - i *= wblk_sz; - for (k = 0; k < wblk_sz; k++) - if (i + k < 143432 * 2 && used[i + k]) return 1; - return 0; -} - -static u32 alloc_block(wbfs_t*p) -{ - u32 i, j; - for (i = 0; i < p->n_wbfs_sec / (8 * 4); i++) - { - u32 v = wbfs_ntohl( p->freeblks[i] ); - if (v != 0) - { - for (j = 0; j < 32; j++) - if (v & (1 << j)) - { - p->freeblks[i] = wbfs_htonl( v & ~( 1 << j ) ); - return (i * 32) + j + 1; - } - } - } - return ~0; -} -static void free_block(wbfs_t *p, int bl) -{ - int i = (bl - 1) / (32); - int j = (bl - 1) & 31; - u32 v = wbfs_ntohl( p->freeblks[i] ); - p->freeblks[i] = wbfs_htonl( v | 1 << j ); -} - -u32 wbfs_add_disc(wbfs_t*p, read_wiidisc_callback_t read_src_wii_disc, void *callback_data, - progress_callback_t spinner, partition_selector_t sel, int copy_1_1) -{ - int i, discn; - u32 tot, cur; - u32 wii_sec_per_wbfs_sect = 1 << (p->wbfs_sec_sz_s - p->wii_sec_sz_s); - wiidisc_t *d = 0; - u8 *used = 0; - wbfs_disc_info_t *info = 0; - u8* copy_buffer = 0; - int retval = -1; - int num_wbfs_sect_to_copy; - u32 last_used; - used = wbfs_malloc( p->n_wii_sec_per_disc ); - - if (!used) - ERROR( "unable to alloc memory" ); - // copy_1_1 needs disk usage for layers detection - //if(!copy_1_1) - { - d = wd_open_disc(read_src_wii_disc, callback_data); - if (!d) - ERROR( "unable to open wii disc" ); - wd_build_disc_usage(d, sel, used); - wd_close_disc(d); - d = 0; - } - - for (i = 0; i < p->max_disc; i++)// find a free slot. - if (p->head->disc_table[i] == 0) break; - if (i == p->max_disc) - ERROR( "no space left on device (table full)" ); - p->head->disc_table[i] = 1; - discn = i; - load_freeblocks(p); - - // build disc info - info = wbfs_ioalloc( p->disc_info_sz ); - read_src_wii_disc(callback_data, 0, 0x100, info->disc_header_copy); - - copy_buffer = wbfs_ioalloc( p->wii_sec_sz ); - if (!copy_buffer) - ERROR( "alloc memory" ); - tot = 0; - cur = 0; - num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc; - // count total number of sectors to write - last_used = 0; - for (i = 0; i < num_wbfs_sect_to_copy; i++) - { - if (block_used(used, i, wii_sec_per_wbfs_sect)) - { - tot += wii_sec_per_wbfs_sect; - last_used = i; - } - } - if (copy_1_1) - { - // detect single or dual layer - if ((last_used + 1) > (p->n_wbfs_sec_per_disc / 2)) - { - // dual layer - num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc; - } - else - { - // single layer - num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc / 2; - } - tot = num_wbfs_sect_to_copy * wii_sec_per_wbfs_sect; - } - /* - // num of hd sectors to copy could be specified directly - if (copy_1_1 > 1) { - u32 hd_sec_per_wii_sec = p->wii_sec_sz / p->hd_sec_sz; - num_wbfs_sect_to_copy = copy_1_1 / hd_sec_per_wii_sec / wii_sec_per_wbfs_sect; - tot = num_wbfs_sect_to_copy * wii_sec_per_wbfs_sect; - }*/ - int ret = 0; - if (spinner) spinner(0, tot); - for (i = 0; i < num_wbfs_sect_to_copy; i++) - { - u16 bl = 0; - if (copy_1_1 || block_used(used, i, wii_sec_per_wbfs_sect)) - { - u16 j; - - bl = alloc_block(p); - if (bl == 0xffff) - ERROR( "no space left on device (disc full)" ); - for (j = 0; j < wii_sec_per_wbfs_sect; j++) - { - u32 offset = (i * (p->wbfs_sec_sz >> 2)) + (j * (p->wii_sec_sz >> 2)); - - ret = read_src_wii_disc(callback_data, offset, p->wii_sec_sz, copy_buffer); - if (ret) - { - if (copy_1_1 && i > p->n_wbfs_sec_per_disc / 2) - { - // end of dual layer data - if (j > 0) - { - info->wlba_table[i] = wbfs_htons( bl ); - } - spinner(tot, tot); - break; - } - //ERROR("read error"); - printf("\rWARNING: read (%u) error (%d)\n", offset, ret); - } - - //fix the partition table - if (offset == (0x40000 >> 2)) wd_fix_partition_table(d, sel, copy_buffer); - p->write_hdsector(p->callback_data, p->part_lba + bl * (p->wbfs_sec_sz / p->hd_sec_sz) + j - * (p->wii_sec_sz / p->hd_sec_sz), p->wii_sec_sz / p->hd_sec_sz, copy_buffer); - cur++; - if (spinner) spinner(cur, tot); - } - } - if (ret) break; - info->wlba_table[i] = wbfs_htons( bl ); - wbfs_sync(p); - } - // write disc info - int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; - p->write_hdsector(p->callback_data, p->part_lba + 1 + discn * disc_info_sz_lba, disc_info_sz_lba, info); - wbfs_sync(p); - retval = 0; - error: if (d) wd_close_disc(d); - if (used) wbfs_free( used ); - if (info) wbfs_iofree( info ); - if (copy_buffer) wbfs_iofree( copy_buffer ); - // init with all free blocks - - return retval; -} - -u32 wbfs_rm_disc(wbfs_t*p, u8* discid) -{ - wbfs_disc_t *d = wbfs_open_disc(p, discid); - int i; - int discn = 0; - int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; - if (!d) return 1; - load_freeblocks(p); - discn = d->i; - for (i = 0; i < p->n_wbfs_sec_per_disc; i++) - { - u32 iwlba = wbfs_ntohs( d->header->wlba_table[i] ); - if (iwlba) free_block(p, iwlba); - } - memset(d->header, 0, p->disc_info_sz); - p->write_hdsector(p->callback_data, p->part_lba + 1 + discn * disc_info_sz_lba, disc_info_sz_lba, d->header); - p->head->disc_table[discn] = 0; - wbfs_close_disc(d); - wbfs_sync(p); - return 0; -} - -u32 wbfs_ren_disc(wbfs_t*p, u8* discid, u8* newname) -{ - wbfs_disc_t *d = wbfs_open_disc(p, discid); - int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; - - if (!d) return 1; - - memset(d->header->disc_header_copy + 0x20, 0, 0x40); - strncpy((char *) d->header->disc_header_copy + 0x20, (char *) newname, 0x39); - - p->write_hdsector(p->callback_data, p->part_lba + 1 + d->i * disc_info_sz_lba, disc_info_sz_lba, d->header); - wbfs_close_disc(d); - return 0; -} - -u32 wbfs_rID_disc(wbfs_t*p, u8* discid, u8* newID) -{ - wbfs_disc_t *d = wbfs_open_disc(p, discid); - int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; - - if (!d) return 1; - - memset(d->header->disc_header_copy, 0, 0x10); - strncpy((char *) d->header->disc_header_copy, (char *) newID, 0x9); - - p->write_hdsector(p->callback_data, p->part_lba + 1 + d->i * disc_info_sz_lba, disc_info_sz_lba, d->header); - wbfs_close_disc(d); - return 0; -} - -// trim the file-system to its minimum size -u32 wbfs_trim(wbfs_t*p) -{ - u32 maxbl; - load_freeblocks(p); - maxbl = alloc_block(p); - p->n_hd_sec = maxbl << (p->wbfs_sec_sz_s - p->hd_sec_sz_s); - p->head->n_hd_sec = wbfs_htonl( p->n_hd_sec ); - // make all block full - memset(p->freeblks, 0, p->n_wbfs_sec / 8); - wbfs_sync(p); - // os layer will truncate the file. - return maxbl; -} - -// data extraction -u32 wbfs_extract_disc(wbfs_disc_t*d, rw_sector_callback_t write_dst_wii_sector, void *callback_data, - progress_callback_t spinner) -{ - wbfs_t *p = d->p; - u8* copy_buffer = 0; - int i; - int src_wbs_nlb = p->wbfs_sec_sz / p->hd_sec_sz; - int dst_wbs_nlb = p->wbfs_sec_sz / p->wii_sec_sz; - copy_buffer = wbfs_ioalloc( p->wbfs_sec_sz ); - if (!copy_buffer) - ERROR( "alloc memory" ); - - for (i = 0; i < p->n_wbfs_sec_per_disc; i++) - { - u32 iwlba = wbfs_ntohs( d->header->wlba_table[i] ); - if (iwlba) - { - - if (spinner) spinner(i, p->n_wbfs_sec_per_disc); - p->read_hdsector(p->callback_data, p->part_lba + iwlba * src_wbs_nlb, src_wbs_nlb, copy_buffer); - write_dst_wii_sector(callback_data, i * dst_wbs_nlb, dst_wbs_nlb, copy_buffer); - } - } - wbfs_iofree( copy_buffer ); - return 0; - error: return 1; -} - -float wbfs_estimate_disc(wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc, void *callback_data, - partition_selector_t sel) -{ - u8 *b; - int i; - u32 tot; - u32 wii_sec_per_wbfs_sect = 1 << (p->wbfs_sec_sz_s - p->wii_sec_sz_s); - wiidisc_t *d = 0; - u8 *used = 0; - wbfs_disc_info_t *info = 0; - - tot = 0; - - used = wbfs_malloc( p->n_wii_sec_per_disc ); - if (!used) - { - ERROR( "unable to alloc memory" ); - } - - d = wd_open_disc(read_src_wii_disc, callback_data); - if (!d) - { - ERROR( "unable to open wii disc" ); - } - - wd_build_disc_usage(d, sel, used); - wd_close_disc(d); - d = 0; - - info = wbfs_ioalloc( p->disc_info_sz ); - b = (u8 *) info; - read_src_wii_disc(callback_data, 0, 0x100, info->disc_header_copy); - - //fprintf(stderr, "estimating %c%c%c%c%c%c %s...\n",b[0], b[1], b[2], b[3], b[4], b[5], b + 0x20); - - for (i = 0; i < p->n_wbfs_sec_per_disc; i++) - { - if (block_used(used, i, wii_sec_per_wbfs_sect)) - { - tot++; - } - } - //memcpy(header, b,0x100); - - error: if (d) wd_close_disc(d); - - if (used) wbfs_free( used ); - - if (info) wbfs_iofree( info ); - - return tot * (((p->wbfs_sec_sz * 1.0) / p->hd_sec_sz) * 512); -} -u32 wbfs_size_disc(wbfs_t*p, read_wiidisc_callback_t read_src_wii_disc, void *callback_data, partition_selector_t sel, - u32 *comp_size, u32 *real_size) -{ - int i; - u32 tot = 0, last = 0; - u32 wii_sec_per_wbfs_sect = 1 << (p->wbfs_sec_sz_s - p->wii_sec_sz_s); - wiidisc_t *d = 0; - u8 *used = 0; - used = wbfs_malloc( p->n_wii_sec_per_disc ); - if (!used) - ERROR( "unable to alloc memory" ); - d = wd_open_disc(read_src_wii_disc, callback_data); - if (!d) - ERROR( "unable to open wii disc" ); - wd_build_disc_usage(d, sel, used); - wd_close_disc(d); - d = 0; - - // count total number to write for spinner - for (i = 0; i < p->n_wbfs_sec_per_disc; i++) - { - if (block_used(used, i, wii_sec_per_wbfs_sect)) - { - tot += wii_sec_per_wbfs_sect; - last = i * wii_sec_per_wbfs_sect; - } - } - - error: if (d) wd_close_disc(d); - if (used) wbfs_free( used ); - - *comp_size = tot; - *real_size = last; - - return 0; -} - -// offset is pointing 32bit words to address the whole dvd, although len is in bytes -//int wbfs_disc_read(wbfs_disc_t*d,u32 offset, u8 *data, u32 len) - -// offset points 32bit words, count counts bytes -//int (*read_wiidisc_callback_t)(void*fp,u32 offset,u32 count,void*iobuf); - -// connect wiidisc to wbfs_disc -int read_wiidisc_wbfsdisc(void*fp, u32 offset, u32 count, void*iobuf) -{ - return wbfs_disc_read((wbfs_disc_t*) fp, offset, count, iobuf); -} - -int wbfs_extract_file(wbfs_disc_t*d, char *path, void **data) -{ - wiidisc_t *wd = 0; - int ret = 0; - - wd = wd_open_disc(read_wiidisc_wbfsdisc, d); - if (!wd) - { - ERROR( "opening wbfs disc" ); - return -1; - } - wd->extracted_size = 0; - *data = wd_extract_file(wd, ONLY_GAME_PARTITION, path); - ret = wd->extracted_size; - if (!*data) - { - //ERROR("file not found"); - ret = -1; - } - wd_close_disc(wd); - error: return ret; -} - -int wbfs_get_fragments(wbfs_disc_t *d, _frag_append_t append_fragment, void *callback_data) -{ - if (!d) return -1; - wbfs_t *p = d->p; - int src_wbs_nlb = p->wbfs_sec_sz / p->hd_sec_sz; - int i, ret, last = 0; - for (i = 0; i < p->n_wbfs_sec_per_disc; i++) - { - u32 iwlba = wbfs_ntohs( d->header->wlba_table[i] ); - if (iwlba) - { - ret = append_fragment(callback_data, i * src_wbs_nlb, // offset - p->part_lba + iwlba * src_wbs_nlb, // sector - src_wbs_nlb); // count - if (ret) return ret; // error - last = i; - } - } - if (last < p->n_wbfs_sec_per_disc / 2) - { - last = p->n_wbfs_sec_per_disc / 2; - } - u32 size = last * src_wbs_nlb; - append_fragment(callback_data, size, 0, 0); // set size - return 0; -} - -// wrapper for reading .iso files using wbfs apis - -#include -#include - -// offset is pointing 32bit words to address the whole dvd, although len is in bytes -int wbfs_iso_file_read(wbfs_disc_t*d, u32 offset, u8 *data, u32 len) -{ - if (!d || d->p != &wbfs_iso_file) return -1; - int fd = (int) d->header; - off_t off = ((u64) offset) << 2; - off_t ret_off; - int ret; - ret_off = lseek(fd, off, SEEK_SET); - if (ret_off != off) return -1; - ret = read(fd, data, len); - if (ret != len) return -2; - return 0; -} - -u32 wbfs_disc_sector_used(wbfs_disc_t *d, u32 *num_blk) -{ - if (d->p == &wbfs_iso_file) - { - int fd = (int) d->header; - struct stat st; - if (fstat(fd, &st) == -1) return 0; - if (num_blk) - { - *num_blk = (st.st_size >> 9); // in 512 units - } - return st.st_blocks; // in 512 units (can be sparse) - } - u32 last_blk = 0; - u32 ret; - ret = wbfs_sector_used2(d->p, d->header, &last_blk); - if (num_blk) - { - *num_blk = last_blk + 1; - } - return ret; -} - +// Copyright 2009 Kwiirk +// Licensed under the terms of the GNU GPL, version 2 +// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + +// Modified by oggzee + +#include "libwbfs.h" + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + +#define ERROR(x) do {wbfs_error(x);goto error;}while(0) +#define ALIGN_LBA(x) (((x)+p->hd_sec_sz-1)&(~(p->hd_sec_sz-1))) + +wbfs_t wbfs_iso_file; + +static int force_mode = 0; + +void wbfs_set_force_mode(int force) +{ + force_mode = force; +} + +static u8 size_to_shift(u32 size) +{ + u8 ret = 0; + while (size) + { + ret++; + size >>= 1; + } + return ret - 1; +} +#define read_le32_unaligned(x) ((x)[0]|((x)[1]<<8)|((x)[2]<<16)|((x)[3]<<24)) + +wbfs_t*wbfs_open_hd(rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector, void *callback_data, + int hd_sector_size, int num_hd_sector __attribute( ( unused ) ), int reset) +{ + int i = num_hd_sector, ret; + u8 *ptr, *tmp_buffer = wbfs_ioalloc( hd_sector_size ); + u8 part_table[16 * 4]; + ret = read_hdsector(callback_data, 0, 1, tmp_buffer); + if (ret) return 0; + //find wbfs partition + wbfs_memcpy( part_table, tmp_buffer + 0x1be, 16*4 ); + ptr = part_table; + for (i = 0; i < 4; i++, ptr += 16) + { + u32 part_lba = read_le32_unaligned( ptr + 0x8 ); + wbfs_head_t *head = (wbfs_head_t *) tmp_buffer; + ret = read_hdsector(callback_data, part_lba, 1, tmp_buffer); + // verify there is the magic. + if (head->magic == wbfs_htonl( WBFS_MAGIC )) + { + wbfs_t*p = wbfs_open_partition(read_hdsector, write_hdsector, callback_data, hd_sector_size, 0, part_lba, + reset); + wbfs_iofree( tmp_buffer ); + return p; + } + } + wbfs_iofree( tmp_buffer ); + if (reset)// XXX make a empty hd partition.. + { + } + return 0; +} +wbfs_t*wbfs_open_partition(rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector, + void *callback_data, int hd_sector_size, int num_hd_sector, u32 part_lba, int reset) +{ + wbfs_t *p = wbfs_malloc( sizeof( wbfs_t ) ); + + wbfs_head_t *head = wbfs_ioalloc( hd_sector_size ? hd_sector_size : 512 ); + + //constants, but put here for consistancy + p->wii_sec_sz = 0x8000; + p->wii_sec_sz_s = size_to_shift(0x8000); + p->n_wii_sec = (num_hd_sector / 0x8000) * hd_sector_size; + p->n_wii_sec_per_disc = 143432 * 2;//support for double layers discs.. + p->head = head; + p->part_lba = part_lba; + // init the partition + if (reset) + { + u8 sz_s; + wbfs_memset( head, 0, hd_sector_size ); + head->magic = wbfs_htonl( WBFS_MAGIC ); + head->hd_sec_sz_s = size_to_shift(hd_sector_size); + head->n_hd_sec = wbfs_htonl( num_hd_sector ); + // choose minimum wblk_sz that fits this partition size + for (sz_s = 6; sz_s < 11; sz_s++) + { + // ensure that wbfs_sec_sz is big enough to address every blocks using 16 bits + if (p->n_wii_sec < ((1U << 16) * (1 << sz_s))) break; + } + head->wbfs_sec_sz_s = sz_s + p->wii_sec_sz_s; + } + else read_hdsector(callback_data, p->part_lba, 1, head); + if (head->magic != wbfs_htonl( WBFS_MAGIC )) + ERROR( "bad magic" ); + if (!force_mode && hd_sector_size && head->hd_sec_sz_s != size_to_shift(hd_sector_size)) + ERROR( "hd sector size doesn't match" ); + if (!force_mode && num_hd_sector && head->n_hd_sec != wbfs_htonl( num_hd_sector )) + ERROR( "hd num sector doesn't match" ); + p->hd_sec_sz = 1 << head->hd_sec_sz_s; + p->hd_sec_sz_s = head->hd_sec_sz_s; + p->n_hd_sec = wbfs_ntohl( head->n_hd_sec ); + + p->n_wii_sec = (p->n_hd_sec / p->wii_sec_sz) * (p->hd_sec_sz); + + p->wbfs_sec_sz_s = head->wbfs_sec_sz_s; + p->wbfs_sec_sz = 1 << p->wbfs_sec_sz_s; + p->n_wbfs_sec = p->n_wii_sec >> (p->wbfs_sec_sz_s - p->wii_sec_sz_s); + p->n_wbfs_sec_per_disc = p->n_wii_sec_per_disc >> (p->wbfs_sec_sz_s - p->wii_sec_sz_s); + p->disc_info_sz = ALIGN_LBA( sizeof( wbfs_disc_info_t ) + p->n_wbfs_sec_per_disc * 2 ); + + //printf("hd_sector_size %X wii_sector size %X wbfs sector_size %X\n",p->hd_sec_sz,p->wii_sec_sz,p->wbfs_sec_sz); + p->read_hdsector = read_hdsector; + p->write_hdsector = write_hdsector; + p->callback_data = callback_data; + + p->freeblks_lba = (p->wbfs_sec_sz - p->n_wbfs_sec / 8) >> p->hd_sec_sz_s; + + if (!reset) + p->freeblks = 0; // will alloc and read only if needed + else + { + // init with all free blocks + p->freeblks = wbfs_ioalloc( ALIGN_LBA( p->n_wbfs_sec / 8 ) ); + wbfs_memset( p->freeblks, 0xff, p->n_wbfs_sec / 8 ); + } + p->max_disc = (p->freeblks_lba - 1) / (p->disc_info_sz >> p->hd_sec_sz_s); + if (p->max_disc > p->hd_sec_sz - sizeof(wbfs_head_t)) p->max_disc = p->hd_sec_sz - sizeof(wbfs_head_t); + + p->tmp_buffer = wbfs_ioalloc( p->hd_sec_sz ); + p->n_disc_open = 0; + return p; + error: wbfs_free( p ); + wbfs_iofree( head ); + return 0; + +} + +void wbfs_sync(wbfs_t*p) +{ + // copy back descriptors + if (p->write_hdsector) + { + p->write_hdsector(p->callback_data, p->part_lba + 0, 1, p->head); + + if (p->freeblks) p->write_hdsector(p->callback_data, p->part_lba + p->freeblks_lba, + ALIGN_LBA( p->n_wbfs_sec / 8 ) >> p->hd_sec_sz_s, p->freeblks); + } +} + +void wbfs_close(wbfs_t*p) +{ + wbfs_sync(p); + + if (p->n_disc_open) + ERROR( "trying to close wbfs while discs still open" ); + + wbfs_iofree( p->head ); + wbfs_iofree( p->tmp_buffer ); + if (p->freeblks) wbfs_iofree( p->freeblks ); + + wbfs_free( p ); + + error: return; +} + +wbfs_disc_t *wbfs_open_disc(wbfs_t* p, u8 *discid) +{ + u32 i; + int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; + wbfs_disc_t *d = 0; + for (i = 0; i < p->max_disc; i++) + { + if (p->head->disc_table[i]) + { + p->read_hdsector(p->callback_data, p->part_lba + 1 + i * disc_info_sz_lba, 1, p->tmp_buffer); + if (wbfs_memcmp( discid, p->tmp_buffer, 6 ) == 0) + { + d = wbfs_malloc( sizeof( *d ) ); + if (!d) + ERROR( "allocating memory" ); + d->p = p; + d->i = i; + d->header = wbfs_ioalloc( p->disc_info_sz ); + if (!d->header) + ERROR( "allocating memory" ); + p->read_hdsector(p->callback_data, p->part_lba + 1 + i * disc_info_sz_lba, disc_info_sz_lba, d->header); + p->n_disc_open++; + // for(i=0;in_wbfs_sec_per_disc;i++) + // printf("%d,",wbfs_ntohs(d->header->wlba_table[i])); + return d; + } + } + } + return 0; + error: if (d) wbfs_iofree( d ); + return 0; + +} +void wbfs_close_disc(wbfs_disc_t*d) +{ + d->p->n_disc_open--; + wbfs_iofree( d->header ); + wbfs_free( d ); +} +// offset is pointing 32bit words to address the whole dvd, although len is in bytes +int wbfs_disc_read(wbfs_disc_t*d, u32 offset, u32 len, u8 *data) +{ + if (d->p == &wbfs_iso_file) + { + return wbfs_iso_file_read(d, offset, data, len); + } + + wbfs_t *p = d->p; + u16 wlba = offset >> (p->wbfs_sec_sz_s - 2); + u32 iwlba_shift = p->wbfs_sec_sz_s - p->hd_sec_sz_s; + u32 lba_mask = (p->wbfs_sec_sz - 1) >> (p->hd_sec_sz_s); + u32 lba = (offset >> (p->hd_sec_sz_s - 2)) & lba_mask; + u32 off = offset & ((p->hd_sec_sz >> 2) - 1); + u16 iwlba = wbfs_ntohs( d->header->wlba_table[wlba] ); + u32 len_copied; + int err = 0; + u8 *ptr = data; + if (unlikely( iwlba == 0 )) return 1; + if (unlikely( off )) + { + off *= 4; + err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba << iwlba_shift) + lba, 1, p->tmp_buffer); + if (err) return err; + len_copied = p->hd_sec_sz - off; + if (likely( len < len_copied )) len_copied = len; + wbfs_memcpy( ptr, p->tmp_buffer + off, len_copied ); + len -= len_copied; + ptr += len_copied; + lba++; + if (unlikely( lba > lba_mask && len )) + { + lba = 0; + iwlba = wbfs_ntohs( d->header->wlba_table[++wlba] ); + if (unlikely( iwlba == 0 )) return 1; + } + } + while (likely( len >= p->hd_sec_sz )) + { + u32 nlb = len >> (p->hd_sec_sz_s); + + if (unlikely( lba + nlb > p->wbfs_sec_sz )) // dont cross wbfs sectors.. + nlb = p->wbfs_sec_sz - lba; + err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba << iwlba_shift) + lba, nlb, ptr); + if (err) return err; + len -= nlb << p->hd_sec_sz_s; + ptr += nlb << p->hd_sec_sz_s; + lba += nlb; + if (unlikely( lba > lba_mask && len )) + { + lba = 0; + iwlba = wbfs_ntohs( d->header->wlba_table[++wlba] ); + if (unlikely( iwlba == 0 )) return 1; + } + } + if (unlikely( len )) + { + err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba << iwlba_shift) + lba, 1, p->tmp_buffer); + if (err) return err; + wbfs_memcpy( ptr, p->tmp_buffer, len ); + } + return 0; +} + +// disc listing +u32 wbfs_count_discs(wbfs_t*p) +{ + u32 i, count = 0; + for (i = 0; i < p->max_disc; i++) + if (p->head->disc_table[i]) count++; + return count; + +} + +u32 wbfs_sector_used(wbfs_t *p, wbfs_disc_info_t *di) +{ + u32 tot_blk = 0, j; + for (j = 0; j < p->n_wbfs_sec_per_disc; j++) + if (wbfs_ntohs( di->wlba_table[j] )) tot_blk++; + return tot_blk; +} + +u32 wbfs_sector_used2(wbfs_t *p, wbfs_disc_info_t *di, u32 *last_blk) +{ + u32 tot_blk = 0, j; + for (j = 0; j < p->n_wbfs_sec_per_disc; j++) + if (wbfs_ntohs( di->wlba_table[j] )) + { + if (last_blk) *last_blk = j; + tot_blk++; + } + return tot_blk; +} + +u32 wbfs_get_disc_info(wbfs_t*p, u32 index, u8 *header, int header_size, u32 *size)//size in 32 bit +{ + u32 i, count = 0; + if (!p) return 1; + int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; + + for (i = 0; i < p->max_disc; i++) + if (p->head->disc_table[i]) + { + if (count++ == index) + { + p->read_hdsector(p->callback_data, p->part_lba + 1 + i * disc_info_sz_lba, 1, p->tmp_buffer); + if (header_size > (int) p->hd_sec_sz) header_size = p->hd_sec_sz; + u32 magic = wbfs_ntohl( *( u32* )( p->tmp_buffer + 24 ) ); + if (magic != 0x5D1C9EA3) + { + p->head->disc_table[i] = 0; + return 1; + } + memcpy(header, p->tmp_buffer, header_size); + if (size) + { + u8 *header = wbfs_ioalloc( p->disc_info_sz ); + p->read_hdsector(p->callback_data, p->part_lba + 1 + i * disc_info_sz_lba, disc_info_sz_lba, header); + u32 sec_used = wbfs_sector_used(p, (wbfs_disc_info_t *) header); + wbfs_iofree( header ); + *size = sec_used << (p->wbfs_sec_sz_s - 2); + } + return 0; + } + } + return 1; +} + +static void load_freeblocks(wbfs_t*p) +{ + if (p->freeblks) return; + // XXX should handle malloc error.. + p->freeblks = wbfs_ioalloc( ALIGN_LBA( p->n_wbfs_sec / 8 ) ); + p->read_hdsector(p->callback_data, p->part_lba + p->freeblks_lba, ALIGN_LBA( p->n_wbfs_sec / 8 ) >> p->hd_sec_sz_s, + p->freeblks); + +} +u32 wbfs_count_usedblocks(wbfs_t*p) +{ + u32 i, j, count = 0; + load_freeblocks(p); + for (i = 0; i < p->n_wbfs_sec / (8 * 4); i++) + { + u32 v = wbfs_ntohl( p->freeblks[i] ); + if (v == ~0U) + count += 32; + else if (v != 0) for (j = 0; j < 32; j++) + if (v & (1 << j)) count++; + } + return count; +} + +// write access + + +//static +int block_used(u8 *used, u32 i, u32 wblk_sz) +{ + u32 k; + i *= wblk_sz; + for (k = 0; k < wblk_sz; k++) + if (i + k < 143432 * 2 && used[i + k]) return 1; + return 0; +} + +static u32 alloc_block(wbfs_t*p) +{ + u32 i, j; + for (i = 0; i < p->n_wbfs_sec / (8 * 4); i++) + { + u32 v = wbfs_ntohl( p->freeblks[i] ); + if (v != 0) + { + for (j = 0; j < 32; j++) + if (v & (1 << j)) + { + p->freeblks[i] = wbfs_htonl( v & ~( 1 << j ) ); + return (i * 32) + j + 1; + } + } + } + return ~0; +} +static void free_block(wbfs_t *p, int bl) +{ + int i = (bl - 1) / (32); + int j = (bl - 1) & 31; + u32 v = wbfs_ntohl( p->freeblks[i] ); + p->freeblks[i] = wbfs_htonl( v | 1 << j ); +} + +s32 wbfs_add_disc(wbfs_t*p, read_wiidisc_callback_t read_src_wii_disc, void *callback_data, + progress_callback_t spinner, partition_selector_t sel, int copy_1_1) +{ + int i, discn; + u32 tot, cur; + u32 wii_sec_per_wbfs_sect = 1 << (p->wbfs_sec_sz_s - p->wii_sec_sz_s); + wiidisc_t *d = 0; + u8 *used = 0; + wbfs_disc_info_t *info = 0; + u8* copy_buffer = 0; + int retval = -1; + int num_wbfs_sect_to_copy; + u32 last_used; + used = wbfs_malloc( p->n_wii_sec_per_disc ); + + if (!used) + ERROR( "unable to alloc memory" ); + // copy_1_1 needs disk usage for layers detection + //if(!copy_1_1) + { + d = wd_open_disc(read_src_wii_disc, callback_data); + if (!d) + ERROR( "unable to open wii disc" ); + wd_build_disc_usage(d, sel, used); + wd_close_disc(d); + d = 0; + } + + for (i = 0; i < p->max_disc; i++)// find a free slot. + if (p->head->disc_table[i] == 0) break; + if (i == p->max_disc) + ERROR( "no space left on device (table full)" ); + p->head->disc_table[i] = 1; + discn = i; + load_freeblocks(p); + + // build disc info + info = wbfs_ioalloc( p->disc_info_sz ); + read_src_wii_disc(callback_data, 0, 0x100, info->disc_header_copy); + + copy_buffer = wbfs_ioalloc( p->wii_sec_sz ); + if (!copy_buffer) + ERROR( "alloc memory" ); + tot = 0; + cur = 0; + num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc; + // count total number of sectors to write + last_used = 0; + for (i = 0; i < num_wbfs_sect_to_copy; i++) + { + if (block_used(used, i, wii_sec_per_wbfs_sect)) + { + tot += wii_sec_per_wbfs_sect; + last_used = i; + } + } + if (copy_1_1) + { + // detect single or dual layer + if ((last_used + 1) > (p->n_wbfs_sec_per_disc / 2)) + { + // dual layer + num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc; + } + else + { + // single layer + num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc / 2; + } + tot = num_wbfs_sect_to_copy * wii_sec_per_wbfs_sect; + } + /* + // num of hd sectors to copy could be specified directly + if (copy_1_1 > 1) { + u32 hd_sec_per_wii_sec = p->wii_sec_sz / p->hd_sec_sz; + num_wbfs_sect_to_copy = copy_1_1 / hd_sec_per_wii_sec / wii_sec_per_wbfs_sect; + tot = num_wbfs_sect_to_copy * wii_sec_per_wbfs_sect; + }*/ + int ret = 0; + if (spinner) spinner(0, tot); + for (i = 0; i < num_wbfs_sect_to_copy; i++) + { + u16 bl = 0; + if (copy_1_1 || block_used(used, i, wii_sec_per_wbfs_sect)) + { + u16 j; + + bl = alloc_block(p); + if (bl == 0xffff) + ERROR( "no space left on device (disc full)" ); + for (j = 0; j < wii_sec_per_wbfs_sect; j++) + { + u32 offset = (i * (p->wbfs_sec_sz >> 2)) + (j * (p->wii_sec_sz >> 2)); + + ret = read_src_wii_disc(callback_data, offset, p->wii_sec_sz, copy_buffer); + if (ret) + { + if (copy_1_1 && i > p->n_wbfs_sec_per_disc / 2) + { + // end of dual layer data + if (j > 0) + { + info->wlba_table[i] = wbfs_htons( bl ); + } + spinner(tot, tot); + break; + } + //ERROR("read error"); + printf("\rWARNING: read (%u) error (%d)\n", offset, ret); + } + + //fix the partition table + if (offset == (0x40000 >> 2)) wd_fix_partition_table(d, sel, copy_buffer); + p->write_hdsector(p->callback_data, p->part_lba + bl * (p->wbfs_sec_sz / p->hd_sec_sz) + j + * (p->wii_sec_sz / p->hd_sec_sz), p->wii_sec_sz / p->hd_sec_sz, copy_buffer); + cur++; + if (spinner) spinner(cur, tot); + } + } + if (ret) break; + info->wlba_table[i] = wbfs_htons( bl ); + wbfs_sync(p); + } + // write disc info + int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; + p->write_hdsector(p->callback_data, p->part_lba + 1 + discn * disc_info_sz_lba, disc_info_sz_lba, info); + wbfs_sync(p); + retval = 0; + error: if (d) wd_close_disc(d); + if (used) wbfs_free( used ); + if (info) wbfs_iofree( info ); + if (copy_buffer) wbfs_iofree( copy_buffer ); + // init with all free blocks + + return retval; +} + +u32 wbfs_rm_disc(wbfs_t*p, u8* discid) +{ + wbfs_disc_t *d = wbfs_open_disc(p, discid); + int i; + int discn = 0; + int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; + if (!d) return 1; + load_freeblocks(p); + discn = d->i; + for (i = 0; i < p->n_wbfs_sec_per_disc; i++) + { + u32 iwlba = wbfs_ntohs( d->header->wlba_table[i] ); + if (iwlba) free_block(p, iwlba); + } + memset(d->header, 0, p->disc_info_sz); + p->write_hdsector(p->callback_data, p->part_lba + 1 + discn * disc_info_sz_lba, disc_info_sz_lba, d->header); + p->head->disc_table[discn] = 0; + wbfs_close_disc(d); + wbfs_sync(p); + return 0; +} + +u32 wbfs_ren_disc(wbfs_t*p, u8* discid, u8* newname) +{ + wbfs_disc_t *d = wbfs_open_disc(p, discid); + int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; + + if (!d) return 1; + + memset(d->header->disc_header_copy + 0x20, 0, 0x40); + strncpy((char *) d->header->disc_header_copy + 0x20, (char *) newname, 0x39); + + p->write_hdsector(p->callback_data, p->part_lba + 1 + d->i * disc_info_sz_lba, disc_info_sz_lba, d->header); + wbfs_close_disc(d); + return 0; +} + +u32 wbfs_rID_disc(wbfs_t*p, u8* discid, u8* newID) +{ + wbfs_disc_t *d = wbfs_open_disc(p, discid); + int disc_info_sz_lba = p->disc_info_sz >> p->hd_sec_sz_s; + + if (!d) return 1; + + memset(d->header->disc_header_copy, 0, 0x10); + strncpy((char *) d->header->disc_header_copy, (char *) newID, 0x9); + + p->write_hdsector(p->callback_data, p->part_lba + 1 + d->i * disc_info_sz_lba, disc_info_sz_lba, d->header); + wbfs_close_disc(d); + return 0; +} + +// trim the file-system to its minimum size +u32 wbfs_trim(wbfs_t*p) +{ + u32 maxbl; + load_freeblocks(p); + maxbl = alloc_block(p); + p->n_hd_sec = maxbl << (p->wbfs_sec_sz_s - p->hd_sec_sz_s); + p->head->n_hd_sec = wbfs_htonl( p->n_hd_sec ); + // make all block full + memset(p->freeblks, 0, p->n_wbfs_sec / 8); + wbfs_sync(p); + // os layer will truncate the file. + return maxbl; +} + +// data extraction +u32 wbfs_extract_disc(wbfs_disc_t*d, rw_sector_callback_t write_dst_wii_sector, void *callback_data, + progress_callback_t spinner) +{ + wbfs_t *p = d->p; + u8* copy_buffer = 0; + int i; + int src_wbs_nlb = p->wbfs_sec_sz / p->hd_sec_sz; + int dst_wbs_nlb = p->wbfs_sec_sz / p->wii_sec_sz; + copy_buffer = wbfs_ioalloc( p->wbfs_sec_sz ); + if (!copy_buffer) + ERROR( "alloc memory" ); + + for (i = 0; i < p->n_wbfs_sec_per_disc; i++) + { + u32 iwlba = wbfs_ntohs( d->header->wlba_table[i] ); + if (iwlba) + { + + if (spinner) spinner(i, p->n_wbfs_sec_per_disc); + p->read_hdsector(p->callback_data, p->part_lba + iwlba * src_wbs_nlb, src_wbs_nlb, copy_buffer); + write_dst_wii_sector(callback_data, i * dst_wbs_nlb, dst_wbs_nlb, copy_buffer); + } + } + wbfs_iofree( copy_buffer ); + return 0; + error: return 1; +} + +float wbfs_estimate_disc(wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc, void *callback_data, + partition_selector_t sel) +{ + u8 *b; + int i; + u32 tot; + u32 wii_sec_per_wbfs_sect = 1 << (p->wbfs_sec_sz_s - p->wii_sec_sz_s); + wiidisc_t *d = 0; + u8 *used = 0; + wbfs_disc_info_t *info = 0; + + tot = 0; + + used = wbfs_malloc( p->n_wii_sec_per_disc ); + if (!used) + { + ERROR( "unable to alloc memory" ); + } + + d = wd_open_disc(read_src_wii_disc, callback_data); + if (!d) + { + ERROR( "unable to open wii disc" ); + } + + wd_build_disc_usage(d, sel, used); + wd_close_disc(d); + d = 0; + + info = wbfs_ioalloc( p->disc_info_sz ); + b = (u8 *) info; + read_src_wii_disc(callback_data, 0, 0x100, info->disc_header_copy); + + //fprintf(stderr, "estimating %c%c%c%c%c%c %s...\n",b[0], b[1], b[2], b[3], b[4], b[5], b + 0x20); + + for (i = 0; i < p->n_wbfs_sec_per_disc; i++) + { + if (block_used(used, i, wii_sec_per_wbfs_sect)) + { + tot++; + } + } + //memcpy(header, b,0x100); + + error: if (d) wd_close_disc(d); + + if (used) wbfs_free( used ); + + if (info) wbfs_iofree( info ); + + return tot * (((p->wbfs_sec_sz * 1.0) / p->hd_sec_sz) * 512); +} +u32 wbfs_size_disc(wbfs_t*p, read_wiidisc_callback_t read_src_wii_disc, void *callback_data, partition_selector_t sel, + u32 *comp_size, u32 *real_size) +{ + int i; + u32 tot = 0, last = 0; + u32 wii_sec_per_wbfs_sect = 1 << (p->wbfs_sec_sz_s - p->wii_sec_sz_s); + wiidisc_t *d = 0; + u8 *used = 0; + used = wbfs_malloc( p->n_wii_sec_per_disc ); + if (!used) + ERROR( "unable to alloc memory" ); + d = wd_open_disc(read_src_wii_disc, callback_data); + if (!d) + ERROR( "unable to open wii disc" ); + wd_build_disc_usage(d, sel, used); + wd_close_disc(d); + d = 0; + + // count total number to write for spinner + for (i = 0; i < p->n_wbfs_sec_per_disc; i++) + { + if (block_used(used, i, wii_sec_per_wbfs_sect)) + { + tot += wii_sec_per_wbfs_sect; + last = i * wii_sec_per_wbfs_sect; + } + } + + error: if (d) wd_close_disc(d); + if (used) wbfs_free( used ); + + *comp_size = tot; + *real_size = last; + + return 0; +} + +// offset is pointing 32bit words to address the whole dvd, although len is in bytes +//int wbfs_disc_read(wbfs_disc_t*d,u32 offset, u8 *data, u32 len) + +// offset points 32bit words, count counts bytes +//int (*read_wiidisc_callback_t)(void*fp,u32 offset,u32 count,void*iobuf); + +// connect wiidisc to wbfs_disc +int read_wiidisc_wbfsdisc(void*fp, u32 offset, u32 count, void*iobuf) +{ + return wbfs_disc_read((wbfs_disc_t*) fp, offset, count, iobuf); +} + +int wbfs_extract_file(wbfs_disc_t*d, char *path, void **data) +{ + wiidisc_t *wd = 0; + int ret = 0; + + wd = wd_open_disc(read_wiidisc_wbfsdisc, d); + if (!wd) + { + ERROR( "opening wbfs disc" ); + return -1; + } + wd->extracted_size = 0; + *data = wd_extract_file(wd, ONLY_GAME_PARTITION, path); + ret = wd->extracted_size; + if (!*data) + { + //ERROR("file not found"); + ret = -1; + } + wd_close_disc(wd); + error: return ret; +} + +int wbfs_get_fragments(wbfs_disc_t *d, _frag_append_t append_fragment, void *callback_data) +{ + if (!d) return -1; + wbfs_t *p = d->p; + int src_wbs_nlb = p->wbfs_sec_sz / p->hd_sec_sz; + int i, ret, last = 0; + for (i = 0; i < p->n_wbfs_sec_per_disc; i++) + { + u32 iwlba = wbfs_ntohs( d->header->wlba_table[i] ); + if (iwlba) + { + ret = append_fragment(callback_data, i * src_wbs_nlb, // offset + p->part_lba + iwlba * src_wbs_nlb, // sector + src_wbs_nlb); // count + if (ret) return ret; // error + last = i; + } + } + if (last < p->n_wbfs_sec_per_disc / 2) + { + last = p->n_wbfs_sec_per_disc / 2; + } + u32 size = last * src_wbs_nlb; + append_fragment(callback_data, size, 0, 0); // set size + return 0; +} + +// wrapper for reading .iso files using wbfs apis + +#include +#include + +// offset is pointing 32bit words to address the whole dvd, although len is in bytes +int wbfs_iso_file_read(wbfs_disc_t*d, u32 offset, u8 *data, u32 len) +{ + if (!d || d->p != &wbfs_iso_file) return -1; + int fd = (int) d->header; + off_t off = ((u64) offset) << 2; + off_t ret_off; + int ret; + ret_off = lseek(fd, off, SEEK_SET); + if (ret_off != off) return -1; + ret = read(fd, data, len); + if (ret != len) return -2; + return 0; +} + +u32 wbfs_disc_sector_used(wbfs_disc_t *d, u32 *num_blk) +{ + if (d->p == &wbfs_iso_file) + { + int fd = (int) d->header; + struct stat st; + if (fstat(fd, &st) == -1) return 0; + if (num_blk) + { + *num_blk = (st.st_size >> 9); // in 512 units + } + return st.st_blocks; // in 512 units (can be sparse) + } + u32 last_blk = 0; + u32 ret; + ret = wbfs_sector_used2(d->p, d->header, &last_blk); + if (num_blk) + { + *num_blk = last_blk + 1; + } + return ret; +} + diff --git a/source/libs/libwbfs/libwbfs.h b/source/libs/libwbfs/libwbfs.h index 8921773a..c115e5c0 100644 --- a/source/libs/libwbfs/libwbfs.h +++ b/source/libs/libwbfs/libwbfs.h @@ -185,7 +185,7 @@ extern "C" @sel: selects which partitions to copy. @copy_1_1: makes a 1:1 copy, whenever a game would not use the wii disc format, and some data is hidden outside the filesystem. */ - u32 wbfs_add_disc(wbfs_t*p, read_wiidisc_callback_t read_src_wii_disc, void *callback_data, + s32 wbfs_add_disc(wbfs_t*p, read_wiidisc_callback_t read_src_wii_disc, void *callback_data, progress_callback_t spinner, partition_selector_t sel, int copy_1_1); /*! remove a wiidvd inside a partition */ diff --git a/source/libs/libwbfs/libwbfs_os.h b/source/libs/libwbfs/libwbfs_os.h index f7670525..f0931e5e 100644 --- a/source/libs/libwbfs/libwbfs_os.h +++ b/source/libs/libwbfs/libwbfs_os.h @@ -1,32 +1,32 @@ -#ifndef LIBWBFS_GLUE_H -#define LIBWBFS_GLUE_H - -#include - -#define debug_printf(fmt, ...); - -#include -#define wbfs_fatal(x) do { printf("\nwbfs panic: %s\n\n",x); while(1); } while(0) -#define wbfs_error(x) do { printf("\nwbfs error: %s\n\n",x); } while(0) - -#include -#include - -#define wbfs_malloc(x) malloc(x) -#define wbfs_free(x) free(x) -#define wbfs_ioalloc(x) memalign(32, ((x) + 31) & ~31) -#define wbfs_iofree(x) free(x) -#define wbfs_be16(x) (*((u16*)(x))) -#define wbfs_be32(x) (*((u32*)(x))) -#define wbfs_ntohl(x) (x) -#define wbfs_htonl(x) (x) -#define wbfs_ntohs(x) (x) -#define wbfs_htons(x) (x) - -#include - -#define wbfs_memcmp(x,y,z) memcmp(x,y,z) -#define wbfs_memcpy(x,y,z) memcpy(x,y,z) -#define wbfs_memset(x,y,z) memset(x,y,z) - -#endif +#ifndef LIBWBFS_GLUE_H +#define LIBWBFS_GLUE_H + +#include + +#define debug_printf(fmt, ...); + +#include +#define wbfs_fatal(x) do { printf("\nwbfs panic: %s\n\n",x); return; } while(0) +#define wbfs_error(x) do { printf("\nwbfs error: %s\n\n",x); } while(0) + +#include +#include + +#define wbfs_malloc(x) malloc(x) +#define wbfs_free(x) free(x) +#define wbfs_ioalloc(x) memalign(32, ((x) + 31) & ~31) +#define wbfs_iofree(x) free(x) +#define wbfs_be16(x) (*((u16*)(x))) +#define wbfs_be32(x) (*((u32*)(x))) +#define wbfs_ntohl(x) (x) +#define wbfs_htonl(x) (x) +#define wbfs_ntohs(x) (x) +#define wbfs_htons(x) (x) + +#include + +#define wbfs_memcmp(x,y,z) memcmp(x,y,z) +#define wbfs_memcpy(x,y,z) memcpy(x,y,z) +#define wbfs_memset(x,y,z) memset(x,y,z) + +#endif diff --git a/source/libwiigui/gui.h b/source/libwiigui/gui.h index f1e8f74b..196524fc 100644 --- a/source/libwiigui/gui.h +++ b/source/libwiigui/gui.h @@ -46,8 +46,15 @@ #include "filelist.h" #include "input.h" #include "OptionList.hpp" +#include "SoundOperations/gui_sound.h" +#include "SoundOperations/gui_bgm.h" +//! Frequently used variables extern FreeTypeGX *fontSystem; +extern GuiSound *btnSoundClick; +extern GuiSound *btnSoundClick2; +extern GuiSound *btnSoundOver; +extern GuiBGM *bgMusic; #define SCROLL_INITIAL_DELAY 20 #define SCROLL_LOOP_DELAY 3 @@ -108,70 +115,6 @@ typedef struct _paddata #define EFFECT_ROCK_VERTICLE 1024 #define EFFECT_GOROUND 2048 -#define MAX_SND_VOICES 16 - -class GuiSoundDecoder; -class GuiSound -{ - public: - //!Constructor - //!\param s Pointer to the sound data - //!\param l Length of sound data - //!\param v Sound volume (0-100) - //!\param r RAW PCM Sound, when no decoder is found then try to play as raw-pcm - //!\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 - ~GuiSound(); - - //!Start sound playback - void Play(); - //!Stop sound playback - void Stop(); - //!Pause sound playback - void Pause(); - //!Resume sound playback - void Resume(); - //!Checks if the sound is currently playing - //!\return true if sound is playing, false otherwise - bool IsPlaying(); - //!Set sound volume - //!\param v Sound volume (0-100) - void SetVolume(int v); - //!Set the sound to loop playback (only applies to OGG) - //!\param l Loop (true to loop) - void SetLoop(bool l); - //!Get the playing time in ms for that moment (only applies to OGG) - protected: - s32 voice; // used asnd-voice - u8 *play_buffer[3]; // trpple-playbuffer - int buffer_nr; // current playbuffer - int buffer_pos; // current idx to write in buffer - bool buffer_ready; // buffer is filled and ready - 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. class GuiTrigger { diff --git a/source/libwiigui/gui_button.cpp b/source/libwiigui/gui_button.cpp index 59bccea8..2d4ade53 100644 --- a/source/libwiigui/gui_button.cpp +++ b/source/libwiigui/gui_button.cpp @@ -51,10 +51,10 @@ GuiButton::GuiButton(int w, int h) GuiButton::GuiButton(GuiImage* img, GuiImage* imgOver, int hor, int vert, int x, int y, GuiTrigger* trig, GuiSound* sndOver, GuiSound* sndClick, u8 grow) { - width = img->GetWidth(); - height = img->GetHeight(); + width = img ? img->GetWidth() : 0; + height = img ? img->GetHeight() : 0; image = img; - image->SetParent(this); + if(image) image->SetParent(this); imageOver = imgOver; if (imageOver) imageOver->SetParent(this); imageHold = NULL; @@ -97,10 +97,10 @@ GuiButton::GuiButton(GuiImage* img, GuiImage* imgOver, int hor, int vert, int x, GuiButton::GuiButton(GuiImage* img, GuiImage* imgOver, int hor, int vert, int x, int y, GuiTrigger* trig, GuiSound* sndOver, GuiSound* sndClick, u8 grow, GuiTooltip* tt, int ttx, int tty, int h_align, int v_align) { - width = img->GetWidth(); - height = img->GetHeight(); + width = img ? img->GetWidth() : 0; + height = img ? img->GetHeight() : 0; image = img; - image->SetParent(this); + if(image) image->SetParent(this); imageOver = imgOver; if (imageOver) imageOver->SetParent(this); imageHold = NULL; @@ -139,9 +139,12 @@ GuiButton::GuiButton(GuiImage* img, GuiImage* imgOver, int hor, int vert, int x, } toolTip = tt; - toolTip->SetParent(this); - toolTip->SetAlignment(h_align, v_align); - toolTip->SetPosition(ttx, tty); + if(toolTip) + { + toolTip->SetParent(this); + toolTip->SetAlignment(h_align, v_align); + toolTip->SetPosition(ttx, tty); + } time1 = time2 = 0; } diff --git a/source/libwiigui/gui_customoptionbrowser.cpp b/source/libwiigui/gui_customoptionbrowser.cpp index a3542c1e..0527717a 100644 --- a/source/libwiigui/gui_customoptionbrowser.cpp +++ b/source/libwiigui/gui_customoptionbrowser.cpp @@ -13,6 +13,7 @@ #include "../settings/CSettings.h" #include "gui_customoptionbrowser.h" #include "themes/CTheme.h" +#include "menu.h" #include @@ -26,7 +27,6 @@ GuiCustomOptionBrowser::GuiCustomOptionBrowser(int w, int h, OptionList * l, con width = w; height = h; options = l; - size = PAGESIZE; scrollbaron = scrollon; selectable = true; listOffset = this->FindMenuItem(-1, 1); @@ -38,7 +38,6 @@ GuiCustomOptionBrowser::GuiCustomOptionBrowser(int w, int h, OptionList * l, con trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trigHeldA = new GuiTrigger; trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A); - btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); bgOptions = Resources::GetImageData(custombg); @@ -104,14 +103,7 @@ GuiCustomOptionBrowser::GuiCustomOptionBrowser(int w, int h, OptionList * l, con scrollbarBoxBtn->SetHoldable(true); scrollbarBoxBtn->SetTrigger(trigHeldA); - optionIndex = new int[size]; - optionVal = new GuiText *[size]; - optionValOver = new GuiText *[size]; - optionBtn = new GuiButton *[size]; - optionTxt = new GuiText *[size]; - optionBg = new GuiImage *[size]; - - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) { optionTxt[i] = new GuiText(options->GetName(i), 20, Theme.settingstext); optionTxt[i]->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); @@ -170,9 +162,8 @@ GuiCustomOptionBrowser::~GuiCustomOptionBrowser() delete trigA; delete trigHeldA; - delete btnSoundClick; - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) { delete optionTxt[i]; delete optionVal[i]; @@ -180,20 +171,13 @@ GuiCustomOptionBrowser::~GuiCustomOptionBrowser() delete optionBg[i]; delete optionBtn[i]; } - delete[] optionIndex; - delete[] optionVal; - delete[] optionValOver; - delete[] optionBtn; - delete[] optionTxt; - delete[] optionBg; } void GuiCustomOptionBrowser::SetFocus(int f) { - LOCK( this ); focus = f; - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) optionBtn[i]->ResetState(); if (f == 1) optionBtn[selectedItem]->SetState(STATE_SELECTED); @@ -201,14 +185,13 @@ void GuiCustomOptionBrowser::SetFocus(int f) void GuiCustomOptionBrowser::ResetState() { - LOCK( this ); if (state != STATE_DISABLED) { state = STATE_DEFAULT; stateChan = -1; } - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) { optionBtn[i]->ResetState(); } @@ -217,7 +200,7 @@ void GuiCustomOptionBrowser::ResetState() int GuiCustomOptionBrowser::GetClickedOption() { int found = -1; - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) { if (optionBtn[i]->GetState() == STATE_CLICKED) { @@ -232,7 +215,7 @@ int GuiCustomOptionBrowser::GetClickedOption() int GuiCustomOptionBrowser::GetSelectedOption() { int found = -1; - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) { if (optionBtn[i]->GetState() == STATE_SELECTED) { @@ -245,7 +228,7 @@ int GuiCustomOptionBrowser::GetSelectedOption() void GuiCustomOptionBrowser::SetClickable(bool enable) { - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) { optionBtn[i]->SetClickable(enable); } @@ -284,14 +267,13 @@ int GuiCustomOptionBrowser::FindMenuItem(int currentItem, int direction) */ void GuiCustomOptionBrowser::Draw() { - LOCK( this ); if (!this->IsVisible()) return; bgOptionsImg->Draw(); int next = listOffset; - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) { if (next >= 0) { @@ -313,12 +295,12 @@ void GuiCustomOptionBrowser::Draw() void GuiCustomOptionBrowser::UpdateListEntries() { - scrollbaron = options->GetLength() > size; + scrollbaron = options->GetLength() > PAGESIZE; if (listOffset < 0) listOffset = this->FindMenuItem(-1, 1); int next = listOffset; int maxNameWidth = 0; - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) { if (next >= 0) { @@ -343,7 +325,7 @@ void GuiCustomOptionBrowser::UpdateListEntries() } } if (coL2 < (24 + maxNameWidth + 16)) coL2 = 24 + maxNameWidth + 16; - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) { if (optionBtn[i]->GetState() != STATE_DISABLED) { @@ -358,7 +340,6 @@ void GuiCustomOptionBrowser::UpdateListEntries() void GuiCustomOptionBrowser::Update(GuiTrigger * t) { - LOCK( this ); int next, prev, lang = options->GetLength(); if (state == STATE_DISABLED || !t) return; @@ -384,7 +365,7 @@ void GuiCustomOptionBrowser::Update(GuiTrigger * t) if (buttonshold != WPAD_BUTTON_UP && buttonshold != WPAD_BUTTON_DOWN) { - for (int i = 0; i < size; i++) + for (int i = 0; i < PAGESIZE; i++) { if (next >= 0) next = this->FindMenuItem(next, 1); @@ -418,7 +399,7 @@ void GuiCustomOptionBrowser::Update(GuiTrigger * t) if (next >= 0) { - if (selectedItem == size - 1) + if (selectedItem == PAGESIZE - 1) { // move list down by 1 listOffset = this->FindMenuItem(listOffset, 1); @@ -460,7 +441,7 @@ void GuiCustomOptionBrowser::Update(GuiTrigger * t) if (next >= 0) { - if (selectedItem == size - 1) + if (selectedItem == PAGESIZE - 1) { // move list down by 1 listOffset = this->FindMenuItem(listOffset, 1); @@ -506,7 +487,7 @@ void GuiCustomOptionBrowser::Update(GuiTrigger * t) } if (scrollbarBoxBtn->GetState() == STATE_HELD && scrollbarBoxBtn->GetStateChan() == t->chan && t->wpad.ir.valid - && options->GetLength() > size) + && options->GetLength() > PAGESIZE) { scrollbarBoxBtn->SetPosition(width / 2 - 18 + 7, 0); @@ -519,10 +500,10 @@ void GuiCustomOptionBrowser::Update(GuiTrigger * t) listOffset = 0; selectedItem = 0; } - else if (listOffset + size >= lang) + else if (listOffset + PAGESIZE >= lang) { - listOffset = lang - size; - selectedItem = size - 1; + listOffset = lang - PAGESIZE; + selectedItem = PAGESIZE - 1; } } int positionbar = 237 * (listOffset + selectedItem) / lang; @@ -532,17 +513,17 @@ void GuiCustomOptionBrowser::Update(GuiTrigger * t) if (t->Right()) { - if (listOffset < lang && lang > size) + if (listOffset < lang && lang > PAGESIZE) { - listOffset = listOffset + size; - if (listOffset + size >= lang) listOffset = lang - size; + listOffset = listOffset + PAGESIZE; + if (listOffset + PAGESIZE >= lang) listOffset = lang - PAGESIZE; } } else if (t->Left()) { if (listOffset > 0) { - listOffset = listOffset - size; + listOffset = listOffset - PAGESIZE; if (listOffset < 0) listOffset = 0; } } diff --git a/source/libwiigui/gui_customoptionbrowser.h b/source/libwiigui/gui_customoptionbrowser.h index f5bd304b..f6064d94 100644 --- a/source/libwiigui/gui_customoptionbrowser.h +++ b/source/libwiigui/gui_customoptionbrowser.h @@ -1,4 +1,8 @@ +#ifndef GUI_CUSTOMBROWSER_H_ +#define GUI_CUSTOMBROWSER_H_ + #include "gui.h" +#include //!Display a list of menu options class GuiCustomOptionBrowser: public GuiElement @@ -20,17 +24,16 @@ class GuiCustomOptionBrowser: public GuiElement void UpdateListEntries(); int selectedItem; int listOffset; - int size; int coL2; int scrollbaron; OptionList * options; - int * optionIndex; - GuiButton ** optionBtn; - GuiText ** optionTxt; - GuiText ** optionVal; - GuiText ** optionValOver; - GuiImage ** optionBg; + int optionIndex[PAGESIZE]; + GuiButton * optionBtn[PAGESIZE]; + GuiText * optionTxt[PAGESIZE]; + GuiText * optionVal[PAGESIZE]; + GuiText * optionValOver[PAGESIZE]; + GuiImage * optionBg[PAGESIZE]; GuiButton * arrowUpBtn; GuiButton * arrowDownBtn; @@ -55,7 +58,8 @@ class GuiCustomOptionBrowser: public GuiElement GuiImageData * scrollbarBox; GuiImageData * scrollbarBoxOver; - GuiSound * btnSoundClick; GuiTrigger * trigA; GuiTrigger * trigHeldA; }; + +#endif diff --git a/source/libwiigui/gui_filebrowser.cpp b/source/libwiigui/gui_filebrowser.cpp index 1e71fbdc..d2a5e07c 100644 --- a/source/libwiigui/gui_filebrowser.cpp +++ b/source/libwiigui/gui_filebrowser.cpp @@ -32,18 +32,15 @@ GuiFileBrowser::GuiFileBrowser(int w, int h) trigHeldA = new GuiTrigger; trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); - btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); - bgFileSelection = new GuiImageData(Resources::GetFile("bg_browser.png"), Resources::GetFileSize("bg_browser.png")); bgFileSelectionImg = new GuiImage(bgFileSelection); bgFileSelectionImg->SetParent(this); bgFileSelectionImg->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); bgFileSelectionEntry = Resources::GetImageData("bg_browser_selection.png"); - + fileFolder = Resources::GetImageData("icon_folder.png"); - + scrollbar = Resources::GetImageData("scrollbar.png"); scrollbarImg = new GuiImage(scrollbar); scrollbarImg->SetParent(this); @@ -160,8 +157,6 @@ GuiFileBrowser::~GuiFileBrowser() delete arrowUp; delete scrollbarBox; - delete btnSoundOver; - delete btnSoundClick; delete trigHeldA; delete trigA; diff --git a/source/libwiigui/gui_gamebrowser.cpp b/source/libwiigui/gui_gamebrowser.cpp index 9ab6c889..f6320859 100644 --- a/source/libwiigui/gui_gamebrowser.cpp +++ b/source/libwiigui/gui_gamebrowser.cpp @@ -17,6 +17,7 @@ #include "settings/GameTitles.h" #include "usbloader/GameList.h" #include "themes/CTheme.h" +#include "menu.h" #include #include @@ -41,7 +42,6 @@ GuiGameBrowser::GuiGameBrowser(int w, int h, int selected, int offset) trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trigHeldA = new GuiTrigger; trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A); - btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); bgGames = Resources::GetImageData("bg_options.png"); newGames = Resources::GetImageData("new.png"); @@ -182,7 +182,6 @@ GuiGameBrowser::~GuiGameBrowser() delete trigA; delete trigHeldA; - delete btnSoundClick; for (int i = 0; i < pagesize; i++) { diff --git a/source/libwiigui/gui_gamebrowser.h b/source/libwiigui/gui_gamebrowser.h index c8370dc9..3918f239 100644 --- a/source/libwiigui/gui_gamebrowser.h +++ b/source/libwiigui/gui_gamebrowser.h @@ -1,65 +1,64 @@ -#ifndef _GUIGAMEBROWSER_H_ -#define _GUIGAMEBROWSER_H_ - -#include "gui.h" -#include "../usbloader/disc.h" - -class GuiGameBrowser: public GuiElement -{ - public: - GuiGameBrowser(int w, int h, int selected = 0, int offset = 0); - ~GuiGameBrowser(); - int FindMenuItem(int c, int d); - int GetClickedOption(); - int GetSelectedOption(); - void ResetState(); - void SetFocus(int f); - void Draw(); - void Update(GuiTrigger * t); - int GetOffset(); - void Reload(); - //GuiText * optionVal[PAGESIZE]; - protected: - void UpdateListEntries(); - int selectedItem; - int listOffset; - int scrollbaron; - int pagesize; - int maxTextWidth; - - int * gameIndex; - GuiButton ** game; - GuiText ** gameTxt; - GuiText ** gameTxtOver; - GuiImage ** gameBg; - GuiImage ** newImg; - - GuiButton * arrowUpBtn; - GuiButton * arrowDownBtn; - GuiButton * scrollbarBoxBtn; - - GuiImage * bgGameImg; - GuiImage * scrollbarImg; - GuiImage * arrowDownImg; - GuiImage * arrowDownOverImg; - GuiImage * arrowUpImg; - GuiImage * arrowUpOverImg; - GuiImage * scrollbarBoxImg; - GuiImage * scrollbarBoxOverImg; - - GuiImageData * bgGames; - GuiImageData * bgGamesEntry; - GuiImageData * newGames; - GuiImageData * scrollbar; - GuiImageData * arrowDown; - GuiImageData * arrowDownOver; - GuiImageData * arrowUp; - GuiImageData * arrowUpOver; - GuiImageData * scrollbarBox; - GuiImageData * scrollbarBoxOver; - - GuiSound * btnSoundClick; - GuiTrigger * trigA; - GuiTrigger * trigHeldA; -}; -#endif +#ifndef _GUIGAMEBROWSER_H_ +#define _GUIGAMEBROWSER_H_ + +#include "gui.h" +#include "../usbloader/disc.h" + +class GuiGameBrowser: public GuiElement +{ + public: + GuiGameBrowser(int w, int h, int selected = 0, int offset = 0); + ~GuiGameBrowser(); + int FindMenuItem(int c, int d); + int GetClickedOption(); + int GetSelectedOption(); + void ResetState(); + void SetFocus(int f); + void Draw(); + void Update(GuiTrigger * t); + int GetOffset(); + void Reload(); + //GuiText * optionVal[PAGESIZE]; + protected: + void UpdateListEntries(); + int selectedItem; + int listOffset; + int scrollbaron; + int pagesize; + int maxTextWidth; + + int * gameIndex; + GuiButton ** game; + GuiText ** gameTxt; + GuiText ** gameTxtOver; + GuiImage ** gameBg; + GuiImage ** newImg; + + GuiButton * arrowUpBtn; + GuiButton * arrowDownBtn; + GuiButton * scrollbarBoxBtn; + + GuiImage * bgGameImg; + GuiImage * scrollbarImg; + GuiImage * arrowDownImg; + GuiImage * arrowDownOverImg; + GuiImage * arrowUpImg; + GuiImage * arrowUpOverImg; + GuiImage * scrollbarBoxImg; + GuiImage * scrollbarBoxOverImg; + + GuiImageData * bgGames; + GuiImageData * bgGamesEntry; + GuiImageData * newGames; + GuiImageData * scrollbar; + GuiImageData * arrowDown; + GuiImageData * arrowDownOver; + GuiImageData * arrowUp; + GuiImageData * arrowUpOver; + GuiImageData * scrollbarBox; + GuiImageData * scrollbarBoxOver; + + GuiTrigger * trigA; + GuiTrigger * trigHeldA; +}; +#endif diff --git a/source/libwiigui/gui_gamecarousel.cpp b/source/libwiigui/gui_gamecarousel.cpp index d333fa2f..2c2db0cc 100644 --- a/source/libwiigui/gui_gamecarousel.cpp +++ b/source/libwiigui/gui_gamecarousel.cpp @@ -70,9 +70,6 @@ GuiGameCarousel::GuiGameCarousel(int w, int h, const char *themePath, const u8 * trigMinus = new GuiTrigger; trigMinus->SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0); - btnSoundClick = new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); - btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - imgLeft = Resources::GetImageData("startgame_arrow_left.png"); imgRight = Resources::GetImageData("startgame_arrow_right.png"); @@ -164,8 +161,6 @@ GuiGameCarousel::~GuiGameCarousel() delete trigR; delete trigPlus; delete trigMinus; - delete btnSoundClick; - delete btnSoundOver; delete gamename; for (int i = 0; i < pagesize; i++) diff --git a/source/libwiigui/gui_gamecarousel.h b/source/libwiigui/gui_gamecarousel.h index bd8db075..ae654ac5 100644 --- a/source/libwiigui/gui_gamecarousel.h +++ b/source/libwiigui/gui_gamecarousel.h @@ -1,54 +1,52 @@ -#ifndef _GUIGAMECAROUSEL_H_ -#define _GUIGAMECAROUSEL_H_ - -#include "gui.h" -#include "../usbloader/disc.h" -class GuiImageAsync; -class GuiGameCarousel: public GuiElement -{ - public: - GuiGameCarousel(int w, int h, const char *themePath, const u8 *imagebg, int imagebgsize, int selected = 0, int offset = 0); - ~GuiGameCarousel(); - int FindMenuItem(int c, int d); - int GetClickedOption(); - int GetSelectedOption(); - void ResetState(); - void SetFocus(int f); - void Draw(); - void Update(GuiTrigger * t); - int GetOffset(); - void Reload(); - //GuiText * optionVal[PAGESIZE]; - protected: - GuiImageData noCover; - int selectedItem; - int listOffset; - int scrollbaron; - int pagesize; - int speed; - int clickedItem; - - int * gameIndex; - GuiButton ** game; - GuiImageAsync ** coverImg; - - GuiText * gamename; - - GuiButton * btnRight; - GuiButton * btnLeft; - - GuiImage * btnLeftImg; - GuiImage * btnRightImg; - - GuiImageData * imgLeft; - GuiImageData * imgRight; - - GuiSound * btnSoundOver; - GuiSound * btnSoundClick; - GuiTrigger * trigA; - GuiTrigger * trigL; - GuiTrigger * trigR; - GuiTrigger * trigPlus; - GuiTrigger * trigMinus; -}; -#endif +#ifndef _GUIGAMECAROUSEL_H_ +#define _GUIGAMECAROUSEL_H_ + +#include "gui.h" +#include "../usbloader/disc.h" +class GuiImageAsync; +class GuiGameCarousel: public GuiElement +{ + public: + GuiGameCarousel(int w, int h, const char *themePath, const u8 *imagebg, int imagebgsize, int selected = 0, int offset = 0); + ~GuiGameCarousel(); + int FindMenuItem(int c, int d); + int GetClickedOption(); + int GetSelectedOption(); + void ResetState(); + void SetFocus(int f); + void Draw(); + void Update(GuiTrigger * t); + int GetOffset(); + void Reload(); + //GuiText * optionVal[PAGESIZE]; + protected: + GuiImageData noCover; + int selectedItem; + int listOffset; + int scrollbaron; + int pagesize; + int speed; + int clickedItem; + + int * gameIndex; + GuiButton ** game; + GuiImageAsync ** coverImg; + + GuiText * gamename; + + GuiButton * btnRight; + GuiButton * btnLeft; + + GuiImage * btnLeftImg; + GuiImage * btnRightImg; + + GuiImageData * imgLeft; + GuiImageData * imgRight; + + GuiTrigger * trigA; + GuiTrigger * trigL; + GuiTrigger * trigR; + GuiTrigger * trigPlus; + GuiTrigger * trigMinus; +}; +#endif diff --git a/source/libwiigui/gui_gamegrid.cpp b/source/libwiigui/gui_gamegrid.cpp index bf04ef8d..c4c33f2c 100644 --- a/source/libwiigui/gui_gamegrid.cpp +++ b/source/libwiigui/gui_gamegrid.cpp @@ -238,9 +238,6 @@ GuiGameGrid::GuiGameGrid(int w, int h, const char *themePath, const u8 *imagebg, trigMinus = new GuiTrigger; trigMinus->SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0); - btnSoundClick = new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); - btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - int btnHeight = (int) lround(sqrt(RADIUS * RADIUS - 90000) - RADIUS - 50); // Button Left @@ -303,8 +300,6 @@ GuiGameGrid::~GuiGameGrid() delete trigMinus; delete trig1; delete trig2; - delete btnSoundClick; - delete btnSoundOver; for (int i = pagesize - 1; i >= 0; i--) { diff --git a/source/libwiigui/gui_gamegrid.h b/source/libwiigui/gui_gamegrid.h index 0dd739df..86a0cc9b 100644 --- a/source/libwiigui/gui_gamegrid.h +++ b/source/libwiigui/gui_gamegrid.h @@ -45,8 +45,6 @@ class GuiGameGrid: public GuiElement GuiImageData * imgLeft; GuiImageData * imgRight; - GuiSound * btnSoundOver; - GuiSound * btnSoundClick; GuiTrigger * trigA; GuiTrigger * trigL; GuiTrigger * trigR; diff --git a/source/libwiigui/gui_keyboard.cpp b/source/libwiigui/gui_keyboard.cpp index 59ced7df..ce4e80c1 100644 --- a/source/libwiigui/gui_keyboard.cpp +++ b/source/libwiigui/gui_keyboard.cpp @@ -13,6 +13,7 @@ #include "../settings/CSettings.h" #include #include +#include "menu.h" /** * Constructor for the GuiKeyboard class. */ @@ -136,8 +137,6 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max, int min, int lang) keyLarge = new GuiImageData(keyboard_largekey_over_png, keyboard_largekey_over_png_size); keyLargeOver = new GuiImageData(keyboard_largekey_over_png, keyboard_largekey_over_png_size); - keySoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - keySoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); trigA = new GuiTrigger; trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trigB = new GuiTrigger; @@ -161,11 +160,9 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max, int min, int lang) keyBackText = new GuiText("Back", 20, ( GXColor ) { 0, 0, 0, 0xff}); } - //GuiButton(GuiImage* img, GuiImage* imgOver, int hor, int vert, int x, int y, GuiTrigger* trig, GuiSound* sndOver, GuiSound* sndClick, u8 grow); - //keyBack = new GuiButton(keyMedium->GetWidth(), keyMedium->GetHeight()); keyBack = new GuiButton(keyBackImg, keyBackOverImg, 0, 3, 11 * 42 + 40 + eurocheck, 0 * 42 + 120, trigA, - keySoundOver, keySoundClick, 1); + btnSoundOver, btnSoundClick, 1); //keyBack->SetImage(keyBackImg); //keyBack->SetImageOver(keyBackOverImg); keyBack->SetLabel(keyBackText); @@ -366,8 +363,6 @@ GuiKeyboard::~GuiKeyboard() delete keyMediumOver; delete keyLarge; delete keyLargeOver; - delete keySoundOver; - delete keySoundClick; delete trigA; delete trigB; diff --git a/source/libwiigui/gui_numpad.cpp b/source/libwiigui/gui_numpad.cpp index 83dbd9db..a6596376 100644 --- a/source/libwiigui/gui_numpad.cpp +++ b/source/libwiigui/gui_numpad.cpp @@ -1,205 +1,201 @@ -/**************************************************************************** - * USB Loader GX - * - * r-win 2009 - * - * gui_numpad.cpp - * - * GUI class definitions - ***************************************************************************/ - -#include "gui.h" -#include "../main.h" -#include "../settings/CSettings.h" -#include -#include -/** - * Constructor for the GuiNumpad class. - */ - -#define SAFEFREE(p) if(p){free(p);p=NULL;} - -GuiNumpad::GuiNumpad(char * t, u32 max) -{ - width = 400; - height = 370; - selectable = true; - focus = 0; // allow focus - alignmentHor = ALIGN_CENTRE; - alignmentVert = ALIGN_MIDDLE; - kbtextmaxlen = max > sizeof(kbtextstr) ? sizeof(kbtextstr) : max; // limit max up to sizeof(kbtextstr) - // strlcpy(kbtextstr, t, kbtextmaxlen); - strncpy(kbtextstr, t, kbtextmaxlen); // strncpy is needed to fill the rest with \0 - kbtextstr[sizeof(kbtextstr) - 1] = 0; // terminate with \0 - - char thekeys[11] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '\0', '0' }; - memcpy(keys, thekeys, sizeof(thekeys)); - - keyTextbox = new GuiImageData(keyboard_textbox_png, keyboard_textbox_png_size); - keyTextboxImg = new GuiImage(keyTextbox); - keyTextboxImg->SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - keyTextboxImg->SetPosition(0, 40);//(0,0); - this->Append(keyTextboxImg); - - kbText = new GuiText(kbtextstr, 20, ( GXColor ) - { 0, 0, 0, 0xff}); - kbText->SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - kbText->SetPosition(0, 53);//(0, 13); - kbText->SetPassChar('*'); - this->Append(kbText); - - keyMedium = new GuiImageData(keyboard_mediumkey_over_png, keyboard_mediumkey_over_png_size); - keyMediumOver = new GuiImageData(keyboard_mediumkey_over_png, keyboard_mediumkey_over_png_size); - - keySoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - keySoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); - trigA = new GuiTrigger; - trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); - trigB = new GuiTrigger; - trigB->SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); - - keyBackImg = new GuiImage(keyMedium); - keyBackOverImg = new GuiImage(keyMediumOver); - keyBackText = new GuiText("Back", 20, ( GXColor ) - { 0, 0, 0, 0xff}); - - keyBack = new GuiButton(keyBackImg, keyBackOverImg, ALIGN_CENTRE, ALIGN_MIDDLE, 90, 80, trigA, keySoundOver, - keySoundClick, 1); - keyBack->SetLabel(keyBackText); - keyBack->SetTrigger(trigB); - this->Append(keyBack); - - keyClearImg = new GuiImage(keyMedium); - keyClearOverImg = new GuiImage(keyMediumOver); - keyClearText = new GuiText("Clear", 20, ( GXColor ) - { 0, 0, 0, 0xff}); - keyClear = new GuiButton(keyClearImg, keyClearOverImg, ALIGN_CENTRE, ALIGN_MIDDLE, -90, 80, trigA, keySoundOver, - keySoundClick, 1); - keyClear->SetLabel(keyClearText); - this->Append(keyClear); - - char txt[2] = { 0, 0 }; - for (int i = 0; i < 11; i++) - { - if (keys[i] != '\0') - { - int col = i % 3; - int row = i / 3; - - keyImg[i] = new GuiImage(keyMedium); - keyImgOver[i] = new GuiImage(keyMediumOver); - txt[0] = keys[i]; - keyTxt[i] = new GuiText(txt, 20, ( GXColor ) - { 0, 0, 0, 0xff}); - keyTxt[i]->SetAlignment(ALIGN_CENTRE, ALIGN_BOTTOM); - keyTxt[i]->SetPosition(0, -10); - keyBtn[i] = new GuiButton(keyImg[i], keyImgOver[i], ALIGN_CENTRE, ALIGN_MIDDLE, -90 + 90 * col, -70 + 50 - * row, trigA, keySoundOver, keySoundClick, 1); - keyBtn[i]->SetLabel(keyTxt[i]); - - this->Append(keyBtn[i]); - } - } -} - -/** - * Destructor for the GuiKeyboard class. - */ -GuiNumpad::~GuiNumpad() -{ - SAFEFREE( kbText ) - SAFEFREE( keyTextbox ) - SAFEFREE( keyTextboxImg ) - SAFEFREE( keyBackText ) - SAFEFREE( keyBackImg ) - SAFEFREE( keyBackOverImg ) - SAFEFREE( keyBack ) - SAFEFREE( keyClear ) - SAFEFREE( keyClearImg ) - SAFEFREE( keyClearOverImg ) - SAFEFREE( keyClearText ) - SAFEFREE( keyMedium ) - SAFEFREE( keyMediumOver ) - SAFEFREE( keySoundOver ) - SAFEFREE( keySoundClick ) - SAFEFREE( trigA ) - SAFEFREE( trigB ) - - for (int i = 0; i < 11; i++) - { - if (keys[i] != '\0') - { - SAFEFREE( keyImg[i] ) - SAFEFREE( keyImgOver[i] ) - SAFEFREE( keyTxt[i] ) - SAFEFREE( keyBtn[i] ) - } - } -} - -void GuiNumpad::Update(GuiTrigger * t) -{ - LOCK( this ); - if (_elements.size() == 0 || (state == STATE_DISABLED && parentElement)) return; - - for (u8 i = 0; i < _elements.size(); i++) - { - try - { - _elements.at(i)->Update(t); - } - catch (const std::exception& e) - { - } - } - - if (keyBack->GetState() == STATE_CLICKED) - { - if (strlen(kbtextstr) > 0) - { - kbtextstr[strlen(kbtextstr) - 1] = 0; - kbText->SetText(kbtextstr); - } - keyBack->SetState(STATE_SELECTED, t->chan); - } - else if (keyClear->GetState() == STATE_CLICKED) - { - memset(kbtextstr, 0, sizeof(kbtextstr)); - kbText->SetText(kbtextstr); - keyClear->SetState(STATE_SELECTED, t->chan); - } - - char txt[2] = { 0, 0 }; - for (int i = 0; i < 11; i++) - { - if (keys[i] != '\0') - { - if (keyBtn[i]->GetState() == STATE_CLICKED) - { - txt[0] = keys[i]; - if (strlen(kbtextstr) < kbtextmaxlen - 1) // -1 --> kbtextmaxlen means with term. '\0' - { - kbtextstr[strlen(kbtextstr)] = txt[0]; - kbText->SetText(kbtextstr); - } - keyBtn[i]->SetState(STATE_SELECTED, t->chan); - } - } - } - - kbText->SetPosition(0, 53); - - this->ToggleFocus(t); - - if (focus) // only send actions to this window if it's in focus - { - // pad/joystick navigation - if (t->Right()) - this->MoveSelectionHor(1); - else if (t->Left()) - this->MoveSelectionHor(-1); - else if (t->Down()) - this->MoveSelectionVert(1); - else if (t->Up()) this->MoveSelectionVert(-1); - } -} +/**************************************************************************** + * USB Loader GX + * + * r-win 2009 + * + * gui_numpad.cpp + * + * GUI class definitions + ***************************************************************************/ + +#include "gui.h" +#include "../main.h" +#include "../settings/CSettings.h" +#include +#include +/** + * Constructor for the GuiNumpad class. + */ + +#define SAFEFREE(p) if(p){free(p);p=NULL;} + +GuiNumpad::GuiNumpad(char * t, u32 max) +{ + width = 400; + height = 370; + selectable = true; + focus = 0; // allow focus + alignmentHor = ALIGN_CENTRE; + alignmentVert = ALIGN_MIDDLE; + kbtextmaxlen = max > sizeof(kbtextstr) ? sizeof(kbtextstr) : max; // limit max up to sizeof(kbtextstr) + // strlcpy(kbtextstr, t, kbtextmaxlen); + strncpy(kbtextstr, t, kbtextmaxlen); // strncpy is needed to fill the rest with \0 + kbtextstr[sizeof(kbtextstr) - 1] = 0; // terminate with \0 + + char thekeys[11] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '\0', '0' }; + memcpy(keys, thekeys, sizeof(thekeys)); + + keyTextbox = new GuiImageData(keyboard_textbox_png, keyboard_textbox_png_size); + keyTextboxImg = new GuiImage(keyTextbox); + keyTextboxImg->SetAlignment(ALIGN_CENTRE, ALIGN_TOP); + keyTextboxImg->SetPosition(0, 40);//(0,0); + this->Append(keyTextboxImg); + + kbText = new GuiText(kbtextstr, 20, ( GXColor ) + { 0, 0, 0, 0xff}); + kbText->SetAlignment(ALIGN_CENTRE, ALIGN_TOP); + kbText->SetPosition(0, 53);//(0, 13); + kbText->SetPassChar('*'); + this->Append(kbText); + + keyMedium = new GuiImageData(keyboard_mediumkey_over_png, keyboard_mediumkey_over_png_size); + keyMediumOver = new GuiImageData(keyboard_mediumkey_over_png, keyboard_mediumkey_over_png_size); + + trigA = new GuiTrigger; + trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + trigB = new GuiTrigger; + trigB->SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); + + keyBackImg = new GuiImage(keyMedium); + keyBackOverImg = new GuiImage(keyMediumOver); + keyBackText = new GuiText("Back", 20, ( GXColor ) + { 0, 0, 0, 0xff}); + + keyBack = new GuiButton(keyBackImg, keyBackOverImg, ALIGN_CENTRE, ALIGN_MIDDLE, 90, 80, trigA, keySoundOver, + keySoundClick, 1); + keyBack->SetLabel(keyBackText); + keyBack->SetTrigger(trigB); + this->Append(keyBack); + + keyClearImg = new GuiImage(keyMedium); + keyClearOverImg = new GuiImage(keyMediumOver); + keyClearText = new GuiText("Clear", 20, ( GXColor ) + { 0, 0, 0, 0xff}); + keyClear = new GuiButton(keyClearImg, keyClearOverImg, ALIGN_CENTRE, ALIGN_MIDDLE, -90, 80, trigA, keySoundOver, + keySoundClick, 1); + keyClear->SetLabel(keyClearText); + this->Append(keyClear); + + char txt[2] = { 0, 0 }; + for (int i = 0; i < 11; i++) + { + if (keys[i] != '\0') + { + int col = i % 3; + int row = i / 3; + + keyImg[i] = new GuiImage(keyMedium); + keyImgOver[i] = new GuiImage(keyMediumOver); + txt[0] = keys[i]; + keyTxt[i] = new GuiText(txt, 20, ( GXColor ) + { 0, 0, 0, 0xff}); + keyTxt[i]->SetAlignment(ALIGN_CENTRE, ALIGN_BOTTOM); + keyTxt[i]->SetPosition(0, -10); + keyBtn[i] = new GuiButton(keyImg[i], keyImgOver[i], ALIGN_CENTRE, ALIGN_MIDDLE, -90 + 90 * col, -70 + 50 + * row, trigA, keySoundOver, keySoundClick, 1); + keyBtn[i]->SetLabel(keyTxt[i]); + + this->Append(keyBtn[i]); + } + } +} + +/** + * Destructor for the GuiKeyboard class. + */ +GuiNumpad::~GuiNumpad() +{ + SAFEFREE( kbText ) + SAFEFREE( keyTextbox ) + SAFEFREE( keyTextboxImg ) + SAFEFREE( keyBackText ) + SAFEFREE( keyBackImg ) + SAFEFREE( keyBackOverImg ) + SAFEFREE( keyBack ) + SAFEFREE( keyClear ) + SAFEFREE( keyClearImg ) + SAFEFREE( keyClearOverImg ) + SAFEFREE( keyClearText ) + SAFEFREE( keyMedium ) + SAFEFREE( keyMediumOver ) + SAFEFREE( trigA ) + SAFEFREE( trigB ) + + for (int i = 0; i < 11; i++) + { + if (keys[i] != '\0') + { + SAFEFREE( keyImg[i] ) + SAFEFREE( keyImgOver[i] ) + SAFEFREE( keyTxt[i] ) + SAFEFREE( keyBtn[i] ) + } + } +} + +void GuiNumpad::Update(GuiTrigger * t) +{ + LOCK( this ); + if (_elements.size() == 0 || (state == STATE_DISABLED && parentElement)) return; + + for (u8 i = 0; i < _elements.size(); i++) + { + try + { + _elements.at(i)->Update(t); + } + catch (const std::exception& e) + { + } + } + + if (keyBack->GetState() == STATE_CLICKED) + { + if (strlen(kbtextstr) > 0) + { + kbtextstr[strlen(kbtextstr) - 1] = 0; + kbText->SetText(kbtextstr); + } + keyBack->SetState(STATE_SELECTED, t->chan); + } + else if (keyClear->GetState() == STATE_CLICKED) + { + memset(kbtextstr, 0, sizeof(kbtextstr)); + kbText->SetText(kbtextstr); + keyClear->SetState(STATE_SELECTED, t->chan); + } + + char txt[2] = { 0, 0 }; + for (int i = 0; i < 11; i++) + { + if (keys[i] != '\0') + { + if (keyBtn[i]->GetState() == STATE_CLICKED) + { + txt[0] = keys[i]; + if (strlen(kbtextstr) < kbtextmaxlen - 1) // -1 --> kbtextmaxlen means with term. '\0' + { + kbtextstr[strlen(kbtextstr)] = txt[0]; + kbText->SetText(kbtextstr); + } + keyBtn[i]->SetState(STATE_SELECTED, t->chan); + } + } + } + + kbText->SetPosition(0, 53); + + this->ToggleFocus(t); + + if (focus) // only send actions to this window if it's in focus + { + // pad/joystick navigation + if (t->Right()) + this->MoveSelectionHor(1); + else if (t->Left()) + this->MoveSelectionHor(-1); + else if (t->Down()) + this->MoveSelectionVert(1); + else if (t->Up()) this->MoveSelectionVert(-1); + } +} diff --git a/source/libwiigui/gui_optionbrowser.cpp b/source/libwiigui/gui_optionbrowser.cpp index 0f5dbea3..32086efb 100644 --- a/source/libwiigui/gui_optionbrowser.cpp +++ b/source/libwiigui/gui_optionbrowser.cpp @@ -38,8 +38,6 @@ GuiOptionBrowser::GuiOptionBrowser(int w, int h, OptionList * l, const char *ima trigHeldA = new GuiTrigger; trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A); - btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); - bgOptions = Resources::GetImageData(imagebg); bgOptionsImg = new GuiImage(bgOptions); bgOptionsImg->SetParent(this); @@ -152,7 +150,6 @@ GuiOptionBrowser::GuiOptionBrowser(int w, int h, OptionList * l, const char *ima trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); trigHeldA = new GuiTrigger; trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A); - btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); bgOptions = Resources::GetImageData(imagebg); @@ -276,7 +273,6 @@ GuiOptionBrowser::~GuiOptionBrowser() loaded = 0; delete trigA; - delete btnSoundClick; // delete optionBg; for (int i = 0; i < PAGESIZE; i++) diff --git a/source/libwiigui/gui_searchbar.cpp b/source/libwiigui/gui_searchbar.cpp index f05afafb..0f17ac26 100644 --- a/source/libwiigui/gui_searchbar.cpp +++ b/source/libwiigui/gui_searchbar.cpp @@ -31,9 +31,7 @@ class cSearchButton GuiSearchBar::GuiSearchBar(const wchar_t *SearchChars) : inSide(0), text((char *) NULL, 22, ( GXColor ) - { 0, 0, 0, 255}), buttons(0), keyImageData(keyboard_key_png, keyboard_key_png_size), keyOverImageData(keyboard_key_over_png, keyboard_key_over_png_size), sndOver( - button_over_pcm, button_over_pcm_size, Settings.sfxvolume), sndClick(button_click_pcm, - button_click_pcm_size, Settings.sfxvolume) + { 0, 0, 0, 255}), buttons(0), keyImageData(keyboard_key_png, keyboard_key_png_size), keyOverImageData(keyboard_key_over_png, keyboard_key_over_png_size) { trig.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); @@ -57,7 +55,7 @@ GuiSearchBar::GuiSearchBar(const wchar_t *SearchChars) : if (x == 0) y++; charstr[0] = SearchChars[i]; buttons[i] = new cSearchButton(charstr, &keyImageData, &keyOverImageData, x_start + x * 42, y_start - 42 + y - * 42, &trig, &sndOver, &sndClick); + * 42, &trig, btnSoundOver, btnSoundClick); this->Append(&(buttons[i]->button)); } height = 10 + 42 + y * 42 + 10; @@ -73,16 +71,14 @@ GuiSearchBar::GuiSearchBar(const wchar_t *SearchChars) : BacspaceBtnImg_Over = new GuiImage(imgBacspaceBtn); BacspaceBtnImg = new GuiImage(BacspaceBtnImg_Over); BacspaceBtnImg->SetGrayscale(); - BacspaceBtn = new GuiButton(BacspaceBtnImg, BacspaceBtnImg_Over, ALIGN_RIGHT, ALIGN_TOP, -52, 10, &trig, &sndOver, - &sndClick, 1); + BacspaceBtn = new GuiButton(BacspaceBtnImg, BacspaceBtnImg_Over, ALIGN_RIGHT, ALIGN_TOP, -52, 10, &trig, btnSoundOver, btnSoundClick, 1); this->Append(BacspaceBtn); imgClearBtn = Resources::GetImageData("keyboard_clear_over.png"); ClearBtnImg_Over = new GuiImage(imgClearBtn); ClearBtnImg = new GuiImage(ClearBtnImg_Over); ClearBtnImg->SetGrayscale(); - ClearBtn = new GuiButton(ClearBtnImg, ClearBtnImg_Over, ALIGN_RIGHT, ALIGN_TOP, -10, 10, &trig, &sndOver, - &sndClick, 1); + ClearBtn = new GuiButton(ClearBtnImg, ClearBtnImg_Over, ALIGN_RIGHT, ALIGN_TOP, -10, 10, &trig, btnSoundOver, btnSoundClick, 1); this->Append(ClearBtn); // SetPosition(100,100); diff --git a/source/libwiigui/gui_searchbar.h b/source/libwiigui/gui_searchbar.h index f3cd7d01..23bbb82e 100644 --- a/source/libwiigui/gui_searchbar.h +++ b/source/libwiigui/gui_searchbar.h @@ -30,7 +30,5 @@ class GuiSearchBar: public GuiWindow GuiImageData keyImageData; GuiImageData keyOverImageData; GuiTrigger trig; - GuiSound sndOver; - GuiSound sndClick; }; diff --git a/source/libwiigui/gui_sound.cpp b/source/libwiigui/gui_sound.cpp deleted file mode 100644 index 2442fed2..00000000 --- a/source/libwiigui/gui_sound.cpp +++ /dev/null @@ -1,446 +0,0 @@ -/**************************************************************************** - * libwiigui - * - * Tantric 2009 - * - * gui_sound.cpp - * - * decoder modification by ardi 2009 - * - * GUI class definitions - ***************************************************************************/ - -#include "gui.h" -#include -#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. - */ -GuiSound::GuiSound(const u8 *s, int l, int v/*=100*/, bool r/*=true*/, bool a/*=false*/) -{ - if (GuiSoundCount++ == 0 || GuiSoundDecoderThreadHandle == LWP_THREAD_NULL) - { - LWP_CreateThread(&GuiSoundDecoderThreadHandle, GuiSoundDecoderThread, NULL, NULL, 32768, 80); - } - voice = -1; - play_buffer[0] = (u8*) memalign(32, BUFFER_SIZE * 3); // tripple-buffer first is played - 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*/) -{ - Stop(); - if (!play_buffer[0]) return false; - 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; - play_buffer[0] = (u8*) memalign(32, BUFFER_SIZE * 3); // tripple-buffer first is played - 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; -} - -/** - * Destructor for the GuiSound class. - */ -GuiSound::~GuiSound() -{ - if (!loop) while (voice >= 0) - usleep(50); - Stop(); - if (--GuiSoundCount == 0 && GuiSoundDecoderThreadHandle != LWP_THREAD_NULL) - { - GuiSoundDecoderThreadRunning = false; - LWP_JoinThread(GuiSoundDecoderThreadHandle, NULL); - GuiSoundDecoderThreadHandle = LWP_THREAD_NULL; - } - delete decoder; - free(play_buffer[0]); -} - -void GuiSound::Play() -{ - Stop(); // stop playing if it played - if (!play_buffer[0]) return; - if (!decoder) return; // no decoder or no play_buffer -> no playing - // initialize the buffer - buffer_nr = 0; // allways starts with buffer 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(); - if (voice >= 0) - { - s32 vol = (255 * volume) / 100; - s32 format = decoder->GetFormat(); - s32 samplerate = decoder->GetSampleRate(); - s32 first_pos = buffer_pos; - // switch to next buffer - buffer_nr = 1; - buffer_pos = 0; - buffer_ready = false; - buffer_eof = false; - DecoderCallback(); // fill second buffer; - 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() -{ - if (voice < 0) return; - GuiSoundPlayer[voice] = NULL; // disable Callbacks - SND_StopVoice(voice); - voice = -1; -} - -void GuiSound::Pause() -{ - if (voice < 0) return; - ASND_PauseVoice(voice, 1); -} - -void GuiSound::Resume() -{ - if (voice < 0) return; - ASND_PauseVoice(voice, 0); -} - -bool GuiSound::IsPlaying() -{ - return voice >= 0; -} - -void GuiSound::SetVolume(int vol) -{ - volume = vol; - if (voice < 0) return; - int newvol = 255 * (volume / 100.0); - ASND_ChangeVolumeVoice(voice, newvol, newvol); -} - -void GuiSound::SetLoop(bool l) -{ - loop = l; -} - -void GuiSound::DecoderCallback() -{ - 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; - } - } -} - diff --git a/source/libwiigui/gui_sound_decoder.h b/source/libwiigui/gui_sound_decoder.h deleted file mode 100644 index fd81babd..00000000 --- a/source/libwiigui/gui_sound_decoder.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** - * libwiigui - * - * Tantric 2009 - * - * gui_sound_decoder.h - * - * by ardi 2009 - * - * GUI class definitions - ***************************************************************************/ - -#ifndef GUI_SOUND_DECODER_H -#define GUI_SOUND_DECODER_H - -#include - -#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 */ diff --git a/source/libwiigui/gui_sound_decoder_aiff.cpp b/source/libwiigui/gui_sound_decoder_aiff.cpp deleted file mode 100644 index 1811f7c8..00000000 --- a/source/libwiigui/gui_sound_decoder_aiff.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** - * libwiigui - * - * ardi 2009 - * - * gui_sound_plugin_aif.cpp - * - * GUI class definitions - ***************************************************************************/ - -#include -#include -#include -#include -#include - -#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 = pcm_start; - } - 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 ); diff --git a/source/libwiigui/gui_sound_decoder_bns.cpp b/source/libwiigui/gui_sound_decoder_bns.cpp deleted file mode 100644 index ac7f872d..00000000 --- a/source/libwiigui/gui_sound_decoder_bns.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/**************************************************************************** - * libwiigui - * - * Tantric 2009 - * - * gui_sound_plugin_bns.cpp - * - * by ardi 2009 - * - * Decoder for Wii bns-sound - * - * GUI class definitions - ***************************************************************************/ - -#include -#include - -#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 (loop && 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; - bool loop; - 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++; - - channel[0].loop = channel[1].loop = *in_ptr++; // u8 loopFlag; - - 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 ); diff --git a/source/libwiigui/gui_sound_decoder_mpg.cpp b/source/libwiigui/gui_sound_decoder_mpg.cpp deleted file mode 100644 index 40cb7512..00000000 --- a/source/libwiigui/gui_sound_decoder_mpg.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/**************************************************************************** - * 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 -#include -#include -#include -#include -#include - -#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 ); diff --git a/source/libwiigui/gui_sound_decoder_ogg.cpp b/source/libwiigui/gui_sound_decoder_ogg.cpp deleted file mode 100644 index 5cf4c76b..00000000 --- a/source/libwiigui/gui_sound_decoder_ogg.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/**************************************************************************** - * libwiigui - * - * Tantric 2009 - * - * gui_sound_plugin_ogg.cpp - * - * by ardi 2009 - * - * Decoder for ogg-vorbis with libtremor - * - * GUI class definitions - ***************************************************************************/ - -#include -#include -#include -#include -#include - -#include "gui_sound_decoder.h" - -/* functions to read the Ogg file from memory */ - -static struct -{ - char *mem; - int size; - int pos; -} file[4]; - -static int f_read(void * punt, int bytes, int blocks, int *f) -{ - int b; - int c = 0; - int d; - - if (bytes * blocks <= 0) return 0; - - blocks *= bytes; - - while (blocks > 0) - { - b = blocks; - if (b > 4096) b = 4096; - - d = (*f) - 0x666; - if ((unsigned) (d) <= (0x669 - 0x666)) - { - if (file[d].size == 0) return -1; - if ((file[d].pos + b) > file[d].size) b = file[d].size - file[d].pos; - if (b > 0) - { - memcpy(punt, file[d].mem + file[d].pos, b); - file[d].pos += b; - } - } - else b = read(*f, ((char *) punt) + c, b); - - if (b <= 0) - { - return c / bytes; - } - c += b; - blocks -= b; - } - return c / bytes; -} - -static int f_seek(int *f, ogg_int64_t offset, int mode) -{ - if (f == NULL) return (-1); - - int k; - mode &= 3; - - int d = (*f) - 0x666; - if ((unsigned) (d) <= (0x669 - 0x666)) - { - k = 0; - - if (file[d].size == 0) return -1; - - if (mode == 0) - { - if ((offset) >= file[d].size) - { - file[d].pos = file[d].size; - k = -1; - } - else if ((offset) < 0) - { - file[d].pos = 0; - k = -1; - } - else file[d].pos = offset; - } - else if (mode == 1) - { - if ((file[d].pos + offset) >= file[d].size) - { - file[d].pos = file[d].size; - k = -1; - } - else if ((file[d].pos + offset) < 0) - { - file[d].pos = 0; - k = -1; - } - else file[d].pos += offset; - } - else if (mode == 2) - { - - if ((file[d].size + offset) >= file[d].size) - { - file[d].pos = file[d].size; - k = -1; - } - else if ((file[d].size + offset) < 0) - { - file[d].pos = 0; - k = -1; - } - else file[d].pos = file[d].size + offset; - } - - } - else k = lseek(*f, (int) offset, mode); - - if (k < 0) - k = -1; - else k = 0; - return k; -} - -static int f_close(int *f) -{ - int d = (*f) - 0x666; - if ((unsigned) (d) <= (0x669 - 0x666)) - { - file[d].size = 0; - file[d].pos = 0; - if (file[d].mem) - { - file[d].mem = (char *) 0; - } - return 0; - } - else return close(*f); - return 0; -} - -static long f_tell(int *f) -{ - int k; - - int d = (*f) - 0x666; - if ((unsigned) (d) <= (0x669 - 0x666)) - { - k = file[d].pos; - } - else k = lseek(*f, 0, 1); - - return (long) k; -} - -static int mem_open(char * ogg, int size) -{ - static int one = 1; - int n; - if (one) - { - one = 0; - - file[0].size = 0; - file[1].size = 0; - file[2].size = 0; - file[3].size = 0; - file[0].mem = ogg; - file[0].size = size; - file[0].pos = 0; - return (0x666); - } - - for (n = 0; n < 4; n++) - { - if (file[n].size == 0) - { - file[n].mem = ogg; - file[n].size = size; - file[n].pos = 0; - return (0x666 + n); - } - } - return -1; -} - -static int mem_close(int fd) -{ - if ((unsigned) ((fd) - 0x666) <= (0x669 - 0x666)) // it is a memory file descriptor? - { - fd -= 0x666; - file[fd].size = 0; - return 0; - } - else return f_close(&fd); -} - -static ov_callbacks callbacks = { (size_t(*)(void *, size_t, size_t, void *)) f_read, - (int(*)(void *, ogg_int64_t, int)) f_seek, (int(*)(void *)) f_close, (long(*)(void *)) f_tell }; - -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_callbacks((void*) &ogg_fd, &ogg_file, NULL, 0, callbacks) < 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 ); diff --git a/source/libwiigui/gui_sound_decoder_wav.cpp b/source/libwiigui/gui_sound_decoder_wav.cpp deleted file mode 100644 index 30f4d462..00000000 --- a/source/libwiigui/gui_sound_decoder_wav.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/**************************************************************************** - * libwiigui - * - * Tantric 2009 - * - * gui_sound_plugin_wav.cpp - * - * by ardi 2009 - * - * Decoder for WAVE PCM - * - * GUI class definitions - ***************************************************************************/ - -#include -#include -#include -#include - -#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 and - - 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 cue; - std::vector 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::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; - std::vector::iterator currentPlaylist; - const u8 *currentStart; - const u8 *currentEnd; - u32 currentLoops; - const u8 *currentPos; - -}; -REGISTER_GUI_SOUND_DECODER( GuiSoundDecoderWAV ); diff --git a/source/main.cpp b/source/main.cpp index a41f852a..d68857cd 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -85,7 +85,7 @@ int main(int argc, char *argv[]) if (IosLoader::LoadAppCios() < 0) { printf("\n\tWARNING!\n"); - printf("\tUSB Loader GX needs unstubbed cIOS 222 v4 or 249 v9+\n\n"); + printf("\tUSB Loader GX needs unstubbed cIOS 222 v4+ or 249 v9+\n\n"); printf( "\tWe cannot determine the versions on your system,\n\tsince you have no patched ios 36 or 236 installed.\n"); diff --git a/source/menu.cpp b/source/menu.cpp index 2633d655..c8b62721 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -43,7 +43,9 @@ GuiImageData * pointer[4]; GuiImage * bgImg = NULL; GuiImageData * background = NULL; GuiBGM * bgMusic = NULL; -GuiSound *btnClick2 = NULL; +GuiSound *btnSoundClick = NULL; +GuiSound *btnSoundClick2 = NULL; +GuiSound *btnSoundOver = NULL; int currentMenu; u8 mountMethod = 0; @@ -265,6 +267,10 @@ int MainMenu(int menu) if (Settings.autonetwork) ResumeNetworkThread(); + btnSoundClick = new GuiSound(button_click_wav, button_click_wav_size, Settings.sfxvolume); + btnSoundClick2 = new GuiSound(button_click2_wav, button_click2_wav_size, Settings.sfxvolume); + btnSoundOver = new GuiSound(button_over_wav, button_over_wav_size, Settings.sfxvolume); + pointer[0] = Resources::GetImageData("player1_point.png"); pointer[1] = Resources::GetImageData("player2_point.png"); pointer[2] = Resources::GetImageData("player3_point.png"); @@ -279,10 +285,15 @@ int MainMenu(int menu) ResumeGui(); + gprintf("Vor bgm\n"); bgMusic = new GuiBGM(bg_music_ogg, bg_music_ogg_size, Settings.volume); + gprintf("new bgm\n"); bgMusic->SetLoop(Settings.musicloopmode); //loop music + gprintf("SetLoop\n"); bgMusic->Load(Settings.ogg_path); + gprintf("Load\n"); bgMusic->Play(); + gprintf("Nach bgm\n"); MountGamePartition(); diff --git a/source/menu.h b/source/menu.h index 28948bed..d79f0b05 100644 --- a/source/menu.h +++ b/source/menu.h @@ -11,7 +11,6 @@ #include #include "libwiigui/gui.h" -#include "libwiigui/gui_bgm.h" #include "settings/CSettings.h" #include "main.h" @@ -37,8 +36,6 @@ void ResumeGui(); void HaltGui(); GuiImageData *LoadCoverImage(struct discHdr *header, bool Prefere3D = true, bool noCover = true); -extern GuiSound *btnClick2; -extern GuiBGM *bgMusic; extern GuiImageData *pointer[4]; extern GuiImageData *background; extern GuiImage *bgImg; diff --git a/source/menu/MountGamePartition.cpp b/source/menu/MountGamePartition.cpp index bfb6349c..fa906388 100644 --- a/source/menu/MountGamePartition.cpp +++ b/source/menu/MountGamePartition.cpp @@ -161,7 +161,7 @@ int MountGamePartition(bool ShowGUI) // open database if needed, load titles if needed if (CheckFile(Settings.titlestxt_path)) - OpenXMLDatabase(Settings.titlestxt_path, Settings.db_language, Settings.db_JPtoEN, true, Settings.titlesOverride == 1 ? true : false, true); + OpenXMLDatabase(Settings.titlestxt_path, Settings.db_language, Settings.db_JPtoEN, true, Settings.titlesOverride, true); return ret; } diff --git a/source/menu/menu_disclist.cpp b/source/menu/menu_disclist.cpp index 24ffbc89..fb548de9 100644 --- a/source/menu/menu_disclist.cpp +++ b/source/menu/menu_disclist.cpp @@ -96,11 +96,6 @@ int MenuDiscList() nolist = 1; } - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnInstall(Resources::GetFile("button_install.png"), Resources::GetFileSize("button_install.png")); GuiImageData btnInstallOver(Resources::GetFile("button_install_over.png"), Resources::GetFileSize("button_install_over.png")); @@ -197,7 +192,7 @@ int MenuDiscList() installBtnImgOver.SetWidescreen(Settings.widescreen); GuiButton installBtn(&installBtnImg, &installBtnImgOver, ALIGN_LEFT, ALIGN_TOP, Theme.install_x, Theme.install_y, - &trigA, &btnSoundOver, btnClick2, 1, &installBtnTT, 24, -30, 0, 5); + &trigA, btnSoundOver, btnSoundClick2, 1, &installBtnTT, 24, -30, 0, 5); GuiTooltip settingsBtnTT(tr( "Settings" )); if (Settings.wsprompt) settingsBtnTT.SetWidescreen(Settings.widescreen); @@ -207,7 +202,7 @@ int MenuDiscList() GuiImage settingsBtnImgOver(&btnSettingsOver); settingsBtnImgOver.SetWidescreen(Settings.widescreen); GuiButton settingsBtn(&settingsBtnImg, &settingsBtnImgOver, 0, 3, Theme.setting_x, Theme.setting_y, &trigA, - &btnSoundOver, btnClick2, 1, &settingsBtnTT, 65, -30, 0, 5); + btnSoundOver, btnSoundClick2, 1, &settingsBtnTT, 65, -30, 0, 5); GuiTooltip homeBtnTT(tr( "Back to HBC or Wii Menu" )); if (Settings.wsprompt) homeBtnTT.SetWidescreen(Settings.widescreen); @@ -216,7 +211,7 @@ int MenuDiscList() homeBtnImg.SetWidescreen(Settings.widescreen); GuiImage homeBtnImgOver(&btnhomeOver); homeBtnImgOver.SetWidescreen(Settings.widescreen); - GuiButton homeBtn(&homeBtnImg, &homeBtnImgOver, 0, 3, Theme.home_x, Theme.home_y, &trigA, &btnSoundOver, btnClick2, + GuiButton homeBtn(&homeBtnImg, &homeBtnImgOver, 0, 3, Theme.home_x, Theme.home_y, &trigA, btnSoundOver, btnSoundClick2, 1, &homeBtnTT, 15, -30, 1, 5); homeBtn.RemoveSoundClick(); homeBtn.SetTrigger(&trigHome); @@ -229,7 +224,7 @@ int MenuDiscList() poweroffBtnImg.SetWidescreen(Settings.widescreen); poweroffBtnImgOver.SetWidescreen(Settings.widescreen); GuiButton poweroffBtn(&poweroffBtnImg, &poweroffBtnImgOver, 0, 3, Theme.power_x, Theme.power_y, &trigA, - &btnSoundOver, btnClick2, 1, &poweroffBtnTT, -10, -30, 1, 5); + btnSoundOver, btnSoundClick2, 1, &poweroffBtnTT, -10, -30, 1, 5); GuiTooltip sdcardBtnTT(tr( "Reload SD" )); if (Settings.wsprompt) sdcardBtnTT.SetWidescreen(Settings.widescreen); @@ -238,12 +233,12 @@ int MenuDiscList() GuiImage sdcardImgOver(&btnsdcardOver); sdcardImg.SetWidescreen(Settings.widescreen); sdcardImgOver.SetWidescreen(Settings.widescreen); - GuiButton sdcardBtn(&sdcardImg, &sdcardImgOver, 0, 3, Theme.sdcard_x, Theme.sdcard_y, &trigA, &btnSoundOver, - btnClick2, 1, &sdcardBtnTT, 15, -30, 0, 5); + GuiButton sdcardBtn(&sdcardImg, &sdcardImgOver, 0, 3, Theme.sdcard_x, Theme.sdcard_y, &trigA, btnSoundOver, + btnSoundClick2, 1, &sdcardBtnTT, 15, -30, 0, 5); GuiButton gameInfo(0, 0); gameInfo.SetTrigger(&trig2); - gameInfo.SetSoundClick(btnClick2); + gameInfo.SetSoundClick(btnSoundClick2); GuiTooltip favoriteBtnTT(tr( "Display favorites only" )); if (Settings.wsprompt) favoriteBtnTT.SetWidescreen(Settings.widescreen); @@ -253,7 +248,7 @@ int MenuDiscList() GuiImage favoriteBtnImg_g(&imgfavIcon_gray); favoriteBtnImg_g.SetWidescreen(Settings.widescreen); 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); + Theme.gamelist_favorite_y, &trigA, btnSoundOver, btnSoundClick2, 1, &favoriteBtnTT, -15, 52, 0, 3); favoriteBtn.SetAlpha(180); GuiTooltip searchBtnTT(tr( "Set Search-Filter" )); @@ -264,7 +259,7 @@ int MenuDiscList() GuiImage searchBtnImg_g(&imgsearchIcon_gray); searchBtnImg_g.SetWidescreen(Settings.widescreen); 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); + Theme.gamelist_search_y, &trigA, btnSoundOver, btnSoundClick2, 1, &searchBtnTT, -15, 52, 0, 3); searchBtn.SetAlpha(180); const char * sortTTText = NULL; @@ -292,7 +287,7 @@ int MenuDiscList() GuiImage sortBtnImg(sortImgData); sortBtnImg.SetWidescreen(Settings.widescreen); - GuiButton sortBtn(&sortBtnImg, &sortBtnImg, ALIGN_LEFT, ALIGN_TOP, Theme.gamelist_abc_x, Theme.gamelist_abc_y, &trigA, &btnSoundOver, btnClick2, 1, &sortBtnTT, -15, 52, 0, 3); + GuiButton sortBtn(&sortBtnImg, &sortBtnImg, ALIGN_LEFT, ALIGN_TOP, Theme.gamelist_abc_x, Theme.gamelist_abc_y, &trigA, btnSoundOver, btnSoundClick2, 1, &sortBtnTT, -15, 52, 0, 3); GuiTooltip listBtnTT(tr( "Display as a list" )); if (Settings.wsprompt) listBtnTT.SetWidescreen(Settings.widescreen); @@ -302,7 +297,7 @@ int MenuDiscList() GuiImage listBtnImg_g(&imgarrangeList_gray); listBtnImg_g.SetWidescreen(Settings.widescreen); 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); + Theme.gamelist_list_y, &trigA, btnSoundOver, btnSoundClick2, 1, &listBtnTT, 15, 52, 1, 3); listBtn.SetAlpha(180); GuiTooltip gridBtnTT(tr( "Display as a grid" )); @@ -313,7 +308,7 @@ int MenuDiscList() GuiImage gridBtnImg_g(&imgarrangeGrid_gray); gridBtnImg_g.SetWidescreen(Settings.widescreen); 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); + Theme.gamelist_grid_y, &trigA, btnSoundOver, btnSoundClick2, 1, &gridBtnTT, 15, 52, 1, 3); gridBtn.SetAlpha(180); GuiTooltip carouselBtnTT(tr( "Display as a carousel" )); @@ -324,7 +319,7 @@ int MenuDiscList() GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray); carouselBtnImg_g.SetWidescreen(Settings.widescreen); 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); + Theme.gamelist_carousel_y, &trigA, btnSoundOver, btnSoundClick2, 1, &carouselBtnTT, 15, 52, 1, 3); carouselBtn.SetAlpha(180); bool canUnlock = (Settings.parentalcontrol == 0 && Settings.Parental.enabled == 1); @@ -337,7 +332,7 @@ int MenuDiscList() GuiImage lockBtnImg_g(&imgLock_gray); lockBtnImg_g.SetWidescreen(Settings.widescreen); GuiButton lockBtn(&lockBtnImg_g, &lockBtnImg_g, ALIGN_LEFT, ALIGN_TOP, Theme.gamelist_lock_x, - Theme.gamelist_lock_y, &trigA, &btnSoundOver, btnClick2, 1, &lockBtnTT, 15, 52, 1, 3); + Theme.gamelist_lock_y, &trigA, btnSoundOver, btnSoundClick2, 1, &lockBtnTT, 15, 52, 1, 3); lockBtn.SetAlpha(180); GuiTooltip unlockBtnTT(tr( "Enable Parental Control" )); @@ -363,7 +358,7 @@ int MenuDiscList() GuiImage dvdBtnImg_g(dvdBtnImg); dvdBtnImg_g.SetWidescreen(Settings.widescreen); 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); + &trigA, btnSoundOver, btnSoundClick2, 1, &dvdBtnTT, 15, 52, 1, 3); dvdBtn.SetAlpha(180); GuiTooltip homebrewBtnTT(tr( "Homebrew Launcher" )); @@ -374,7 +369,7 @@ int MenuDiscList() homebrewImg.SetWidescreen(Settings.widescreen); homebrewImgOver.SetWidescreen(Settings.widescreen); GuiButton homebrewBtn(&homebrewImg, &homebrewImgOver, ALIGN_LEFT, ALIGN_TOP, Theme.homebrew_x, Theme.homebrew_y, - &trigA, &btnSoundOver, btnClick2, 1, &homebrewBtnTT, 15, -30, 1, 5); + &trigA, btnSoundOver, btnSoundClick2, 1, &homebrewBtnTT, 15, -30, 1, 5); if (Settings.GameSort & SORT_FAVORITE) { @@ -461,12 +456,12 @@ int MenuDiscList() if (Settings.godmode == 1 && mountMethod != 3) //only make the button have trigger & tooltip if in godmode { - DownloadBtn.SetSoundOver(&btnSoundOver); + DownloadBtn.SetSoundOver(btnSoundOver); DownloadBtn.SetTrigger(&trigA); DownloadBtn.SetTrigger(&trig1); DownloadBtn.SetToolTip(&DownloadBtnTT, 205, -30); - idBtn.SetSoundOver(&btnSoundOver); + idBtn.SetSoundOver(btnSoundOver); idBtn.SetTrigger(&trigA); idBtn.SetToolTip(&IDBtnTT, 205, -30); diff --git a/source/menu/menu_install.cpp b/source/menu/menu_install.cpp index 04d1192d..e6444e8c 100644 --- a/source/menu/menu_install.cpp +++ b/source/menu/menu_install.cpp @@ -25,8 +25,6 @@ int MenuInstall() int ret, choice = 0; char name[200]; - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - GuiImageData battery(Resources::GetFile("battery.png"), Resources::GetFileSize("battery.png")); GuiImageData batteryBar(Resources::GetFile("battery_bar.png"), Resources::GetFileSize("battery_bar.png")); GuiImageData batteryRed(Resources::GetFile("battery_red.png"), Resources::GetFileSize("battery_red.png")); diff --git a/source/menu/menu_partition_selection.cpp b/source/menu/menu_partition_selection.cpp index d63f8772..1728a606 100644 --- a/source/menu/menu_partition_selection.cpp +++ b/source/menu/menu_partition_selection.cpp @@ -43,10 +43,6 @@ int SelectPartitionMenu() counter++; } - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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); - GuiImageData btnpwroff(Resources::GetFile("wiimote_poweroff.png"), Resources::GetFileSize("wiimote_poweroff.png")); GuiImageData btnpwroffOver(Resources::GetFile("wiimote_poweroff_over.png"), Resources::GetFileSize("wiimote_poweroff_over.png")); GuiImageData btnhome(Resources::GetFile("menu_button.png"), Resources::GetFileSize("menu_button.png")); @@ -66,12 +62,12 @@ int SelectPartitionMenu() poweroffBtnImg.SetWidescreen(Settings.widescreen); poweroffBtnImgOver.SetWidescreen(Settings.widescreen); GuiButton poweroffBtn(&poweroffBtnImg, &poweroffBtnImgOver, 0, 3, Theme.power_x, Theme.power_y, &trigA, - &btnSoundOver, btnClick2, 1); + btnSoundOver, btnSoundClick2, 1); GuiImage exitBtnImg(&btnhome); GuiImage exitBtnImgOver(&btnhomeOver); exitBtnImg.SetWidescreen(Settings.widescreen); exitBtnImgOver.SetWidescreen(Settings.widescreen); - GuiButton exitBtn(&exitBtnImg, &exitBtnImgOver, 0, 3, Theme.home_x, Theme.home_y, &trigA, &btnSoundOver, btnClick2, + GuiButton exitBtn(&exitBtnImg, &exitBtnImgOver, 0, 3, Theme.home_x, Theme.home_y, &trigA, btnSoundOver, btnSoundClick2, 1); exitBtn.SetTrigger(&trigHome); diff --git a/source/menu/menus.h b/source/menu/menus.h index 4ea83c37..3cac187c 100644 --- a/source/menu/menus.h +++ b/source/menu/menus.h @@ -2,7 +2,6 @@ #define _MENUS_H #include "libwiigui/gui.h" -#include "libwiigui/gui_bgm.h" #include "language/gettext.h" #include "prompts/PromptWindows.h" #include "menu.h" diff --git a/source/prompts/DiscBrowser.cpp b/source/prompts/DiscBrowser.cpp index 5176939f..b205de15 100644 --- a/source/prompts/DiscBrowser.cpp +++ b/source/prompts/DiscBrowser.cpp @@ -36,7 +36,7 @@ extern u8 reset; /******************************************************************************** *Disk Browser *********************************************************************************/ -int DiscBrowse(struct discHdr * header, char * alternatedname, int alternatedname_size) +int DiscBrowse(const char * GameID, char * alternatedname, int alternatedname_size) { gprintf("\nDiscBrowser() started"); bool exit = false; @@ -44,7 +44,7 @@ int DiscBrowse(struct discHdr * header, char * alternatedname, int alternatednam HaltGui(); - wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) header->id); + wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) GameID); if (!disc) { ResumeGui(); @@ -98,11 +98,6 @@ int DiscBrowse(struct discHdr * header, char * alternatedname, int alternatednam return -1; } - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData settingsbg(Resources::GetFile("settings_background.png"), Resources::GetFileSize("settings_background.png")); @@ -113,7 +108,7 @@ int DiscBrowse(struct discHdr * header, char * alternatedname, int alternatednam GuiTrigger trigB; trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); - GuiText titleTxt(GameTitles.GetTitle(header), 28, ( GXColor ) {0, 0, 0, 255}); + GuiText titleTxt(GameTitles.GetTitle(GameID), 28, ( GXColor ) {0, 0, 0, 255}); titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); titleTxt.SetPosition(12, 40); titleTxt.SetMaxWidth(356, SCROLL_HORIZONTAL); @@ -132,7 +127,7 @@ int DiscBrowse(struct discHdr * header, char * alternatedname, int alternatednam cancelBtnTxt.SetWidescreen(Settings.widescreen); cancelBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 2, 3, 180, 400, &trigA, btnSoundOver, btnSoundClick2, 1); cancelBtn.SetScale(0.9); cancelBtn.SetLabel(&cancelBtnTxt); cancelBtn.SetTrigger(&trigB); @@ -300,7 +295,7 @@ int autoSelectDolMenu(const char *id, bool force) //Indiana Jones and the Staff of Kings (Fate of Atlantis) if (strcmp(id, "RJ8E64") == 0) { - int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Fate of Atlantis", tr( "Default" )); + int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Fate of Atlantis", tr( "Cancel" )); switch (choice) { case 1: @@ -314,7 +309,7 @@ int autoSelectDolMenu(const char *id, bool force) } if (strcmp(id, "RJ8P64") == 0) { - int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Fate of Atlantis", tr( "Default" )); + int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Fate of Atlantis", tr( "Cancel" )); switch (choice) { case 1: @@ -330,7 +325,7 @@ int autoSelectDolMenu(const char *id, bool force) //Metal Slug Anthology (Metal Slug 6) if (strcmp(id, "RMLEH4") == 0) { - int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Metal Slug 6", tr( "Default" )); + int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Metal Slug 6", tr( "Cancel" )); switch (choice) { case 1: @@ -344,7 +339,7 @@ int autoSelectDolMenu(const char *id, bool force) } if (strcmp(id, "RMLP7U") == 0) { - int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Metal Slug 6", tr( "Default" )); + int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Metal Slug 6", tr( "Cancel" )); switch (choice) { case 1: @@ -367,8 +362,7 @@ int autoSelectDolMenu(const char *id, bool force) return -1; } */ - int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Metroid Prime", "Metroid Prime 2", "Metroid Prime 3", - tr( "Default" )); + int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Metroid Prime", "Metroid Prime 2", "Metroid Prime 3", tr( "Cancel" )); switch (choice) { case 1: @@ -394,8 +388,7 @@ int autoSelectDolMenu(const char *id, bool force) return -1; } */ - int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Metroid Prime", "Metroid Prime 2", "Metroid Prime 3", - tr( "Default" )); + int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Metroid Prime", "Metroid Prime 2", "Metroid Prime 3", tr( "Cancel" )); switch (choice) { case 1: @@ -417,7 +410,7 @@ int autoSelectDolMenu(const char *id, bool force) //Rampage: Total Destruction (M1.dol=Rampage, jarvos.dol=Rampage World Tour) if (strcmp(id, "RPGP5D") == 0) { - int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Rampage", "World Tour", tr( "Default" )); + int choice = WindowPrompt(tr( "Select a DOL" ), 0, "Rampage", "World Tour", tr( "Cancel" )); switch (choice) { case 1: @@ -436,7 +429,7 @@ int autoSelectDolMenu(const char *id, bool force) //The House Of The Dead 2 & 3 Return (only to play 2) if (strcmp(id, "RHDE8P") == 0) { - int choice = WindowPrompt(tr( "Select a DOL" ), 0, "HotD 2", tr( "Default" )); + int choice = WindowPrompt(tr( "Select a DOL" ), 0, "HotD 2", tr( "Cancel" )); switch (choice) { case 1: @@ -450,7 +443,7 @@ int autoSelectDolMenu(const char *id, bool force) } if (strcmp(id, "RHDP8P") == 0) { - int choice = WindowPrompt(tr( "Select a DOL" ), 0, "HotD 2", tr( "Default" )); + int choice = WindowPrompt(tr( "Select a DOL" ), 0, "HotD 2", tr( "Cancel" )); switch (choice) { case 1: diff --git a/source/prompts/DiscBrowser.h b/source/prompts/DiscBrowser.h index 06bc538c..d285ff9d 100644 --- a/source/prompts/DiscBrowser.h +++ b/source/prompts/DiscBrowser.h @@ -8,7 +8,10 @@ #ifndef _DISCBROWSER_H_ #define _DISCBROWSER_H_ -int DiscBrowse(struct discHdr * header, char * dolname, int dolname_size); +#include +#include "usbloader/disc.h" + +int DiscBrowse(const char * GameID, char * dolname, int dolname_size); int autoSelectDol(const char *id, bool force); int autoSelectDolMenu(const char *id, bool force); u8 DiscMount(struct discHdr * header); diff --git a/source/prompts/PromptWindows.cpp b/source/prompts/PromptWindows.cpp index a7b0f4fc..2424687e 100644 --- a/source/prompts/PromptWindows.cpp +++ b/source/prompts/PromptWindows.cpp @@ -71,10 +71,6 @@ int OnScreenNumpad(char * var, u32 maxlen) GuiNumpad numpad(var, maxlen); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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); - GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiTrigger trigA; @@ -89,7 +85,7 @@ int OnScreenNumpad(char * var, u32 maxlen) okBtnTxt.SetWidescreen(Settings.widescreen); okBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton okBtn(&okBtnImg, &okBtnImg, 0, 4, 5, -15, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton okBtn(&okBtnImg, &okBtnImg, 0, 4, 5, -15, &trigA, btnSoundOver, btnSoundClick2, 1); okBtn.SetLabel(&okBtnTxt); GuiText cancelBtnTxt(tr( "Cancel" ), 22, Theme.prompttext); GuiImage cancelBtnImg(&btnOutline); @@ -98,7 +94,7 @@ int OnScreenNumpad(char * var, u32 maxlen) cancelBtnTxt.SetWidescreen(Settings.widescreen); cancelBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 1, 4, -5, -15, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 1, 4, -5, -15, &trigA, btnSoundOver, btnSoundClick2, 1); cancelBtn.SetLabel(&cancelBtnTxt); cancelBtn.SetTrigger(&trigB); @@ -148,11 +144,6 @@ int OnScreenKeyboard(char * var, u32 maxlen, int min) GuiKeyboard keyboard(var, maxlen, min, Settings.keyset); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiTrigger trigA; @@ -167,7 +158,7 @@ int OnScreenKeyboard(char * var, u32 maxlen, int min) okBtnTxt.SetWidescreen(Settings.widescreen); okBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton okBtn(&okBtnImg, &okBtnImg, 0, 4, 5, 15, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton okBtn(&okBtnImg, &okBtnImg, 0, 4, 5, 15, &trigA, btnSoundOver, btnSoundClick2, 1); okBtn.SetLabel(&okBtnTxt); GuiText cancelBtnTxt(tr( "Cancel" ), 22, Theme.prompttext); GuiImage cancelBtnImg(&btnOutline); @@ -176,7 +167,7 @@ int OnScreenKeyboard(char * var, u32 maxlen, int min) cancelBtnTxt.SetWidescreen(Settings.widescreen); cancelBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 1, 4, -5, 15, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 1, 4, -5, 15, &trigA, btnSoundOver, btnSoundClick2, 1); cancelBtn.SetLabel(&cancelBtnTxt); cancelBtn.SetTrigger(&trigB); @@ -523,10 +514,6 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label, cons promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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); - GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("dialogue_box.png"), Resources::GetFileSize("dialogue_box.png")); @@ -557,7 +544,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label, cons btn1Img.SetWidescreen(Settings.widescreen); } - GuiButton btn1(&btn1Img, &btn1Img, 0, 3, 0, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn1(&btn1Img, &btn1Img, 0, 3, 0, 0, &trigA, btnSoundOver, btnSoundClick2, 1); btn1.SetLabel(&btn1Txt); btn1.SetState(STATE_SELECTED); @@ -568,7 +555,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label, cons btn2Txt.SetWidescreen(Settings.widescreen); btn2Img.SetWidescreen(Settings.widescreen); } - GuiButton btn2(&btn2Img, &btn2Img, 0, 3, 0, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn2(&btn2Img, &btn2Img, 0, 3, 0, 0, &trigA, btnSoundOver, btnSoundClick2, 1); btn2.SetLabel(&btn2Txt); if (!btn3Label && !btn4Label) btn2.SetTrigger(&trigB); @@ -579,7 +566,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label, cons btn3Txt.SetWidescreen(Settings.widescreen); btn3Img.SetWidescreen(Settings.widescreen); } - GuiButton btn3(&btn3Img, &btn3Img, 0, 3, 0, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn3(&btn3Img, &btn3Img, 0, 3, 0, 0, &trigA, btnSoundOver, btnSoundClick2, 1); btn3.SetLabel(&btn3Txt); if (!btn4Label) btn3.SetTrigger(&trigB); @@ -590,7 +577,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label, cons btn4Txt.SetWidescreen(Settings.widescreen); btn4Img.SetWidescreen(Settings.widescreen); } - GuiButton btn4(&btn4Img, &btn4Img, 0, 3, 0, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn4(&btn4Img, &btn4Img, 0, 3, 0, 0, &trigA, btnSoundOver, btnSoundClick2, 1); btn4.SetLabel(&btn4Txt); if (btn4Label) btn4.SetTrigger(&trigB); @@ -823,11 +810,6 @@ int WindowExitPrompt() GuiWindow promptWindow(640, 480); promptWindow.SetAlignment(ALIGN_LEFT, ALIGN_TOP); promptWindow.SetPosition(0, 0); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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, exit_top_png_size); GuiImageData topOver(exit_top_over_png, exit_top_over_png_size); GuiImageData bottom(exit_bottom_png, exit_bottom_png_size); @@ -911,7 +893,7 @@ int WindowExitPrompt() GuiImage btn1Img(&top); GuiImage btn1OverImg(&topOver); - GuiButton btn1(&btn1Img, &btn1OverImg, 0, 3, 0, 0, &trigA, &btnSoundOver, btnClick2, 0); + GuiButton btn1(&btn1Img, &btn1OverImg, 0, 3, 0, 0, &trigA, btnSoundOver, btnSoundClick2, 0); btn1.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50); GuiText btn2Txt(tr( "Back to Loader" ), 28, ( GXColor ) @@ -922,7 +904,7 @@ int WindowExitPrompt() btn2Txt.SetWidescreen(Settings.widescreen); btn2Img.SetWidescreen(Settings.widescreen); } - GuiButton btn2(&btn2Img, &btn2Img, 2, 5, -150, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn2(&btn2Img, &btn2Img, 2, 5, -150, 0, &trigA, btnSoundOver, btnSoundClick2, 1); btn2.SetLabel(&btn2Txt); btn2.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 50); btn2.SetRumble(false); @@ -936,7 +918,7 @@ int WindowExitPrompt() btn3Txt.SetWidescreen(Settings.widescreen); btn3Img.SetWidescreen(Settings.widescreen); } - GuiButton btn3(&btn3Img, &btn3Img, 2, 5, 150, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn3(&btn3Img, &btn3Img, 2, 5, 150, 0, &trigA, btnSoundOver, btnSoundClick2, 1); btn3.SetLabel(&btn3Txt); btn3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 50); btn3.SetRumble(false); @@ -944,7 +926,7 @@ int WindowExitPrompt() GuiImage btn4Img(&bottom); GuiImage btn4OverImg(&bottomOver); - GuiButton btn4(&btn4Img, &btn4OverImg, 0, 4, 0, 0, &trigA, &btnSoundOver, btnClick2, 0); + GuiButton btn4(&btn4Img, &btn4OverImg, 0, 4, 0, 0, &trigA, btnSoundOver, btnSoundClick2, 0); btn4.SetTrigger(&trigB); btn4.SetTrigger(&trigHome); btn4.SetEffect(EFFECT_SLIDE_BOTTOM | EFFECT_SLIDE_IN, 50); @@ -1156,10 +1138,6 @@ int GameWindowPrompt() GuiWindow promptWindow(472, 320); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); @@ -1209,8 +1187,8 @@ int GameWindowPrompt() // nameBtn.SetLabelOver(&nameTxt); nameBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); nameBtn.SetPosition(0, -122); - nameBtn.SetSoundOver(&btnSoundOver); - nameBtn.SetSoundClick(btnClick2); + nameBtn.SetSoundOver(btnSoundOver); + nameBtn.SetSoundClick(btnSoundClick2); if (!mountMethod) nameBtn.SetToolTip(&nameBtnTT, 24, -30, ALIGN_LEFT); if (Settings.godmode == 1 && !mountMethod) @@ -1244,8 +1222,8 @@ int GameWindowPrompt() btn1.SetPosition(0, -20); btn1.SetImage(&diskImg); - btn1.SetSoundOver(&btnSoundOver); - btn1.SetSoundClick(btnClick2); + btn1.SetSoundOver(btnSoundOver); + btn1.SetSoundClick(btnSoundClick2); btn1.SetTrigger(&trigA); btn1.SetState(STATE_SELECTED); @@ -1256,7 +1234,7 @@ int GameWindowPrompt() btn2Txt.SetWidescreen(Settings.widescreen); btn2Img.SetWidescreen(Settings.widescreen); } - GuiButton btn2(&btn2Img, &btn2Img, 1, 5, 0, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn2(&btn2Img, &btn2Img, 1, 5, 0, 0, &trigA, btnSoundOver, btnSoundClick2, 1); if (Settings.godmode == 1 && mountMethod != 2 && mountMethod != 3) { btn2.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM); @@ -1278,7 +1256,7 @@ int GameWindowPrompt() btn3Txt.SetWidescreen(Settings.widescreen); btn3Img.SetWidescreen(Settings.widescreen); } - GuiButton btn3(&btn3Img, &btn3Img, 0, 4, 50, -40, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn3(&btn3Img, &btn3Img, 0, 4, 50, -40, &trigA, btnSoundOver, btnSoundClick2, 1); btn3.SetLabel(&btn3Txt); GuiImage btnFavoriteImg1; @@ -1292,25 +1270,25 @@ int GameWindowPrompt() GuiImage btnFavoriteImg5; btnFavoriteImg5.SetWidescreen(Settings.widescreen); - //GuiButton btnFavorite(&btnFavoriteImg,&btnFavoriteImg, 2, 5, -125, -60, &trigA, &btnSoundOver, &btnClick,1); + //GuiButton btnFavorite(&btnFavoriteImg,&btnFavoriteImg, 2, 5, -125, -60, &trigA, btnSoundOver, &btnClick,1); GuiButton btnFavorite1(imgFavorite.GetWidth(), imgFavorite.GetHeight()); GuiButton btnFavorite2(imgFavorite.GetWidth(), imgFavorite.GetHeight()); GuiButton btnFavorite3(imgFavorite.GetWidth(), imgFavorite.GetHeight()); GuiButton btnFavorite4(imgFavorite.GetWidth(), imgFavorite.GetHeight()); GuiButton btnFavorite5(imgFavorite.GetWidth(), imgFavorite.GetHeight()); - SetupFavoriteButton(&btnFavorite1, -198, &btnFavoriteImg1, &btnSoundOver, btnClick2, &trigA); - SetupFavoriteButton(&btnFavorite2, -171, &btnFavoriteImg2, &btnSoundOver, btnClick2, &trigA); - SetupFavoriteButton(&btnFavorite3, -144, &btnFavoriteImg3, &btnSoundOver, btnClick2, &trigA); - SetupFavoriteButton(&btnFavorite4, -117, &btnFavoriteImg4, &btnSoundOver, btnClick2, &trigA); - SetupFavoriteButton(&btnFavorite5, -90, &btnFavoriteImg5, &btnSoundOver, btnClick2, &trigA); + SetupFavoriteButton(&btnFavorite1, -198, &btnFavoriteImg1, btnSoundOver, btnSoundClick2, &trigA); + SetupFavoriteButton(&btnFavorite2, -171, &btnFavoriteImg2, btnSoundOver, btnSoundClick2, &trigA); + SetupFavoriteButton(&btnFavorite3, -144, &btnFavoriteImg3, btnSoundOver, btnSoundClick2, &trigA); + SetupFavoriteButton(&btnFavorite4, -117, &btnFavoriteImg4, btnSoundOver, btnSoundClick2, &trigA); + SetupFavoriteButton(&btnFavorite5, -90, &btnFavoriteImg5, btnSoundOver, btnSoundClick2, &trigA); GuiImage btnLeftImg(&imgLeft); if (Settings.wsprompt) { btnLeftImg.SetWidescreen(Settings.widescreen); } - GuiButton btnLeft(&btnLeftImg, &btnLeftImg, 0, 5, 20, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btnLeft(&btnLeftImg, &btnLeftImg, 0, 5, 20, 0, &trigA, btnSoundOver, btnSoundClick2, 1); btnLeft.SetTrigger(&trigL); btnLeft.SetTrigger(&trigMinus); @@ -1319,7 +1297,7 @@ int GameWindowPrompt() { btnRightImg.SetWidescreen(Settings.widescreen); } - GuiButton btnRight(&btnRightImg, &btnRightImg, 1, 5, -20, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btnRight(&btnRightImg, &btnRightImg, 1, 5, -20, 0, &trigA, btnSoundOver, btnSoundClick2, 1); btnRight.SetTrigger(&trigR); btnRight.SetTrigger(&trigPlus); @@ -1387,7 +1365,7 @@ int GameWindowPrompt() const u8 *gameSoundData = LoadBannerSound(header->id, &gameSoundDataLen); if (gameSoundData) { - gameSound = new GuiSound(gameSoundData, gameSoundDataLen, Settings.gamesoundvolume, false, true); + gameSound = new GuiSound(gameSoundData, gameSoundDataLen, Settings.gamesoundvolume, true); bgMusic->SetVolume(0); if (Settings.gamesound == 2) gameSound->SetLoop(1); gameSound->Play(); @@ -1619,7 +1597,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); changed = 1; - btnClick2->Play(); + btnSoundClick2->Play(); gameSelected = (gameSelected + 1) % gameList.size(); btnRight.ResetState(); break; @@ -1629,7 +1607,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); changed = 2; - btnClick2->Play(); + btnSoundClick2->Play(); gameSelected = (gameSelected - 1 + gameList.size()) % gameList.size(); btnLeft.ResetState(); break; @@ -1639,7 +1617,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); changed = 2; - btnClick2->Play(); + btnSoundClick2->Play(); gameSelected = (gameSelected - 1 + gameList.size()) % gameList.size(); btnRight.ResetState(); break; @@ -1649,7 +1627,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); changed = 1; - btnClick2->Play(); + btnSoundClick2->Play(); gameSelected = (gameSelected + 1) % gameList.size(); btnLeft.ResetState(); break; @@ -1659,7 +1637,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); changed = 2; - btnClick2->Play(); + btnSoundClick2->Play(); gameSelected = (gameSelected + 1) % gameList.size(); btnRight.ResetState(); break; @@ -1669,7 +1647,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); changed = 1; - btnClick2->Play(); + btnSoundClick2->Play(); gameSelected = (gameSelected - 1 + gameList.size()) % gameList.size(); btnLeft.ResetState(); break; @@ -1679,7 +1657,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); changed = 1; - btnClick2->Play(); + btnSoundClick2->Play(); gameSelected = (gameSelected - 1 + gameList.size()) % gameList.size(); btnRight.ResetState(); break; @@ -1689,7 +1667,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); changed = 2; - btnClick2->Play(); + btnSoundClick2->Play(); gameSelected = (gameSelected + 1) % gameList.size(); btnLeft.ResetState(); break; @@ -1699,7 +1677,7 @@ int GameWindowPrompt() { // diskImg.SetBetaRotateEffect(45, 90); changed = 3; - btnClick2->Play(); + btnSoundClick2->Play(); gameSelected = (gameSelected + 1) % gameList.size(); btnRight.ResetState(); break; @@ -1710,7 +1688,7 @@ int GameWindowPrompt() // diskImg.SetBetaRotateEffect(-45, 90); // promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 1/*50*/); changed = 4; - btnClick2->Play(); + btnSoundClick2->Play(); gameSelected = (gameSelected - 1 + gameList.size()) % gameList.size(); btnLeft.ResetState(); break; @@ -1752,9 +1730,6 @@ int DiscWait(const char *title, const char *msg, const char *btn1Label, const ch GuiWindow promptWindow(472, 320); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - - if (!btnClick2) btnClick2 = new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("dialogue_box.png"), Resources::GetFileSize("dialogue_box.png")); @@ -1784,7 +1759,7 @@ int DiscWait(const char *title, const char *msg, const char *btn1Label, const ch btn1Txt.SetWidescreen(Settings.widescreen); btn1Img.SetWidescreen(Settings.widescreen); } - GuiButton btn1(&btn1Img, &btn1Img, 1, 5, 0, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn1(&btn1Img, &btn1Img, 1, 5, 0, 0, &trigA, btnSoundOver, btnSoundClick2, 1); if (btn2Label) { @@ -1808,7 +1783,7 @@ int DiscWait(const char *title, const char *msg, const char *btn1Label, const ch btn2Txt.SetWidescreen(Settings.widescreen); btn2Img.SetWidescreen(Settings.widescreen); } - GuiButton btn2(&btn2Img, &btn2Img, 1, 4, -20, -25, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn2(&btn2Img, &btn2Img, 1, 4, -20, -25, &trigA, btnSoundOver, btnSoundClick2, 1); btn2.SetLabel(&btn2Txt); if (Settings.wsprompt && Settings.widescreen) /////////////adjust buttons for widescreen @@ -1971,11 +1946,6 @@ bool SearchMissingImages(int choice2) promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("dialogue_box.png"), Resources::GetFileSize("dialogue_box.png")); GuiTrigger trigA; @@ -2103,11 +2073,6 @@ bool NetworkInitPrompt() promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("dialogue_box.png"), Resources::GetFileSize("dialogue_box.png")); GuiTrigger trigA; @@ -2136,7 +2101,7 @@ bool NetworkInitPrompt() btn1Txt.SetWidescreen(Settings.widescreen); btn1Img.SetWidescreen(Settings.widescreen); } - GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -45, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -45, &trigA, btnSoundOver, btnSoundClick2, 1); btn1.SetLabel(&btn1Txt); btn1.SetState(STATE_SELECTED); @@ -2209,11 +2174,6 @@ int ProgressDownloadWindow(int choice2) promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("dialogue_box.png"), Resources::GetFileSize("dialogue_box.png")); GuiTrigger trigA; @@ -2268,7 +2228,7 @@ int ProgressDownloadWindow(int choice2) btn1Txt.SetWidescreen(Settings.widescreen); btn1Img.SetWidescreen(Settings.widescreen); } - GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -45, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -45, &trigA, btnSoundOver, btnSoundClick2, 1); btn1.SetLabel(&btn1Txt); btn1.SetState(STATE_SELECTED); @@ -2812,11 +2772,6 @@ int ProgressUpdateWindow() promptWindow.SetAlignment( ALIGN_CENTRE, ALIGN_MIDDLE ); promptWindow.SetPosition( 0, -10 ); - GuiSound btnSoundOver( button_over_pcm, button_over_pcm_size, 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, SOUND_PCM, Settings.sfxvolume); - char imgPath[100]; snprintf( imgPath, sizeof( imgPath ), "%sbutton_dialogue_box.png", Settings.theme_path ); GuiImageData btnOutline( imgPath, button_dialogue_box_png ); @@ -2880,7 +2835,7 @@ int ProgressUpdateWindow() btn1Txt.SetWidescreen( Settings.widescreen ); btn1Img.SetWidescreen( Settings.widescreen ); } - GuiButton btn1( &btn1Img, &btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, btnClick2, 1 ); + GuiButton btn1( &btn1Img, &btn1Img, 2, 4, 0, -40, &trigA, btnSoundOver, btnSoundClick2, 1 ); btn1.SetLabel( &btn1Txt ); btn1.SetState( STATE_SELECTED ); @@ -3180,11 +3135,6 @@ int ProgressUpdateWindow() promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("dialogue_box.png"), Resources::GetFileSize("dialogue_box.png")); GuiTrigger trigA; @@ -3242,7 +3192,7 @@ int ProgressUpdateWindow() btn1Txt.SetWidescreen(Settings.widescreen); btn1Img.SetWidescreen(Settings.widescreen); } - GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -40, &trigA, btnSoundOver, btnSoundClick2, 1); btn1.SetLabel(&btn1Txt); btn1.SetState(STATE_SELECTED); @@ -3575,11 +3525,6 @@ int CodeDownload(const char *id) promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("dialogue_box.png"), Resources::GetFileSize("dialogue_box.png")); GuiTrigger trigA; @@ -3613,7 +3558,7 @@ int CodeDownload(const char *id) btn1Txt.SetWidescreen(Settings.widescreen); btn1Img.SetWidescreen(Settings.widescreen); } - GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -40, &trigA, btnSoundOver, btnSoundClick2, 1); btn1.SetLabel(&btn1Txt); btn1.SetState(STATE_SELECTED); @@ -3760,11 +3705,6 @@ int HBCWindowPrompt(const char *name, const char *coder, const char *version, co GuiTrigger trigD; trigD.SetButtonOnlyTrigger(-1, WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN, PAD_BUTTON_DOWN); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("dialogue_box.png"), Resources::GetFileSize("dialogue_box.png")); GuiImageData whiteBox(Resources::GetFile("bg_options.png"), Resources::GetFileSize("bg_options.png")); @@ -3790,7 +3730,7 @@ int HBCWindowPrompt(const char *name, const char *coder, const char *version, co arrowUpBtn.SetTrigger(&trigA); arrowUpBtn.SetTrigger(&trigU); arrowUpBtn.SetEffectOnOver(EFFECT_SCALE, 50, 130); - arrowUpBtn.SetSoundClick(btnClick2); + arrowUpBtn.SetSoundClick(btnSoundClick2); GuiButton arrowDownBtn(arrowDownImg.GetWidth(), arrowDownImg.GetHeight()); arrowDownBtn.SetImage(&arrowDownImg); @@ -3799,7 +3739,7 @@ int HBCWindowPrompt(const char *name, const char *coder, const char *version, co arrowDownBtn.SetTrigger(&trigA); arrowDownBtn.SetTrigger(&trigD); arrowDownBtn.SetEffectOnOver(EFFECT_SCALE, 50, 130); - arrowDownBtn.SetSoundClick(btnClick2); + arrowDownBtn.SetSoundClick(btnSoundClick2); GuiImageData *iconData = NULL; GuiImage *iconImg = NULL; @@ -3874,7 +3814,7 @@ int HBCWindowPrompt(const char *name, const char *coder, const char *version, co btn1Img.SetWidescreen(Settings.widescreen); } - GuiButton btn1(&btn1Img, &btn1Img, 0, 3, 0, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn1(&btn1Img, &btn1Img, 0, 3, 0, 0, &trigA, btnSoundOver, btnSoundClick2, 1); btn1.SetLabel(&btn1Txt); btn1.SetState(STATE_SELECTED); @@ -3885,7 +3825,7 @@ int HBCWindowPrompt(const char *name, const char *coder, const char *version, co btn2Txt.SetWidescreen(Settings.widescreen); btn2Img.SetWidescreen(Settings.widescreen); } - GuiButton btn2(&btn2Img, &btn2Img, 0, 3, 0, 0, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn2(&btn2Img, &btn2Img, 0, 3, 0, 0, &trigA, btnSoundOver, btnSoundClick2, 1); btn2.SetLabel(&btn2Txt); btn2.SetTrigger(&trigB); diff --git a/source/prompts/TitleBrowser.cpp b/source/prompts/TitleBrowser.cpp index d002d91a..4d4a24c8 100644 --- a/source/prompts/TitleBrowser.cpp +++ b/source/prompts/TitleBrowser.cpp @@ -124,10 +124,6 @@ bool TitleSelector(char output[]) bool exit = false; - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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); - GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData settingsbg(Resources::GetFile("settings_background.png"), Resources::GetFileSize("settings_background.png")); @@ -150,7 +146,7 @@ bool TitleSelector(char output[]) cancelBtnTxt.SetWidescreen(Settings.widescreen); cancelBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 2, 3, 180, 400, &trigA, btnSoundOver, btnSoundClick2, 1); cancelBtn.SetLabel(&cancelBtnTxt); cancelBtn.SetTrigger(&trigB); @@ -350,11 +346,6 @@ int TitleBrowser() if (IsNetworkInit()) ResumeNetworkWait(); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData settingsbg(Resources::GetFile("settings_background.png"), Resources::GetFileSize("settings_background.png")); @@ -385,7 +376,7 @@ int TitleBrowser() cancelBtnTxt.SetWidescreen(Settings.widescreen); cancelBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton cancelBtn(&cancelBtnImg, &cancelBtnImg, 2, 3, 180, 400, &trigA, btnSoundOver, btnSoundClick2, 1); cancelBtn.SetScale(0.9); cancelBtn.SetLabel(&cancelBtnTxt); cancelBtn.SetTrigger(&trigB); diff --git a/source/prompts/filebrowser.cpp b/source/prompts/filebrowser.cpp index 33ff1b64..b309c810 100644 --- a/source/prompts/filebrowser.cpp +++ b/source/prompts/filebrowser.cpp @@ -295,21 +295,11 @@ int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*= } int menu = MENU_NONE; - /* - GuiText titleTxt("Browse Files", 28, (GXColor){0, 0, 0, 230}); - titleTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP); - titleTxt.SetPosition(70,20); - */ GuiTrigger trigA; trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); GuiTrigger trigB; trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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(Resources::GetFile("icon_folder.png"), Resources::GetFileSize("icon_folder.png")); GuiImage folderImg(&folderImgData); GuiButton folderBtn(folderImg.GetWidth(), folderImg.GetHeight()); @@ -320,8 +310,7 @@ int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*= folderBtn.SetEffectGrow(); GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); - GuiText ExitBtnTxt(tr( "Cancel" ), 24, ( GXColor ) - { 0, 0, 0, 255}); + GuiText ExitBtnTxt(tr( "Cancel" ), 24, ( GXColor ) {0, 0, 0, 255}); GuiImage ExitBtnImg(&btnOutline); if (Settings.wsprompt) { @@ -337,8 +326,7 @@ int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*= ExitBtn.SetTrigger(&trigB); ExitBtn.SetEffectGrow(); - GuiText usbBtnTxt(browsers[(curDevice + 1) % browsers.size()].rootdir, 24, ( GXColor ) - { 0, 0, 0, 255}); + GuiText usbBtnTxt(browsers[(curDevice + 1) % browsers.size()].rootdir, 24, ( GXColor ) {0, 0, 0, 255}); GuiImage usbBtnImg(&btnOutline); if (Settings.wsprompt) { @@ -360,7 +348,7 @@ int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*= okBtnTxt.SetWidescreen(Settings.widescreen); okBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton okBtn(&okBtnImg, &okBtnImg, 0, 4, 40, -35, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton okBtn(&okBtnImg, &okBtnImg, 0, 4, 40, -35, &trigA, btnSoundOver, btnSoundClick2, 1); okBtn.SetLabel(&okBtnTxt); GuiFileBrowser fileBrowser(396, 248); @@ -368,8 +356,7 @@ int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*= fileBrowser.SetPosition(0, 120); GuiImageData Address(Resources::GetFile("addressbar_textbox.png"), Resources::GetFileSize("addressbar_textbox.png")); - GuiText AdressText((char*) NULL, 20, ( GXColor ) - { 0, 0, 0, 255}); + GuiText AdressText((char*) NULL, 20, ( GXColor ) {0, 0, 0, 255}); AdressText.SetTextf("%s%s", browser->rootdir, browser->dir); AdressText.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); AdressText.SetPosition(20, 0); diff --git a/source/prompts/gameinfo.cpp b/source/prompts/gameinfo.cpp index aead4724..559138cf 100644 --- a/source/prompts/gameinfo.cpp +++ b/source/prompts/gameinfo.cpp @@ -137,9 +137,6 @@ int showGameInfo(char *ID) txtWindow.SetAlignment(ALIGN_CENTRE, ALIGN_RIGHT); txtWindow.SetPosition(95, 55); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); - GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox1(Resources::GetFile("gameinfo1.png"), Resources::GetFileSize("gameinfo1.png")); GuiImageData dialogBox2(Resources::GetFile("gameinfo1a.png"), Resources::GetFileSize("gameinfo1a.png")); @@ -305,7 +302,7 @@ int showGameInfo(char *ID) gameinfoWindow.Append(dialogBoxImg2); gameinfoWindow.Append(dialogBoxImg3); gameinfoWindow.Append(dialogBoxImg4); - + char imgPath[150]; snprintf(imgPath, sizeof(imgPath), "%s%s.png", Settings.covers_path, ID); cover = new GuiImageData(imgPath); //load full id image diff --git a/source/settings/Settings.cpp b/source/settings/Settings.cpp index 9345515f..c7ac0a43 100644 --- a/source/settings/Settings.cpp +++ b/source/settings/Settings.cpp @@ -1,2253 +1,25 @@ #include #include - -#include "usbloader/wbfs.h" -#include "language/gettext.h" -#include "libwiigui/gui.h" -#include "libwiigui/gui_customoptionbrowser.h" -#include "prompts/PromptWindows.h" -#include "prompts/DiscBrowser.h" -#include "settings/SettingsPrompts.h" -#include "settings/CGameSettings.h" -#include "settings/CGameStatistics.h" -#include "settings/GameTitles.h" -#include "prompts/filebrowser.h" -#include "cheats/cheatmenu.h" -#include "themes/CTheme.h" -#include "fatmounter.h" -#include "menu.h" -#include "menu/menus.h" -#include "filelist.h" -#include "FileOperations/fileops.h" -#include "sys.h" -#include "usbloader/partition_usbloader.h" -#include "usbloader/utils.h" -#include "system/IosLoader.h" -#include "xml/xml.h" -#include "wad/nandtitle.h" -#include "prompts/TitleBrowser.h" - -#define MAXOPTIONS 13 - -/*** Extern functions ***/ -extern void ResumeGui(); -extern void HaltGui(); -extern void titles_default(); - -/*** Extern variables ***/ -extern GuiWindow * mainWindow; -extern GuiBGM * bgMusic; -extern GuiImage * bgImg; -extern GuiImageData * pointer[4]; -extern GuiImageData * background; -extern u8 shutdown; -extern u8 reset; -extern u8 mountMethod; -extern struct discHdr *dvdheader; -extern PartList partitions; -extern char game_partition[6]; -extern u8 load_from_fs; - -static const char *opts_no_yes[MAX_ON_OFF] = { trNOOP( "No" ), trNOOP( "Yes" ) }; -static const char *opts_off_on[MAX_ON_OFF] = { trNOOP( "OFF" ), trNOOP( "ON" ) }; -static const char *opts_videomode[VIDEO_MODE_MAX][2] = { { "", trNOOP( "Disc Default" ) }, { - trNOOP( "System Default" ), "" }, { trNOOP( "AutoPatch" ), "" }, { trNOOP( "Force" ), " PAL50" }, { - trNOOP( "Force" ), " PAL60" }, { trNOOP( "Force" ), " NTSC" } }; -static const char *opts_language[MAX_LANGUAGE] = { trNOOP( "App Default" ), trNOOP( "Console Default" ), trNOOP( "Japanese" ), - trNOOP( "English" ), trNOOP( "German" ), trNOOP( "French" ), trNOOP( "Spanish" ), trNOOP( "Italian" ), - trNOOP( "Dutch" ), trNOOP( "SChinese" ), trNOOP( "TChinese" ), trNOOP( "Korean" ) }; -static const char *opts_lockedgames[2] = { trNOOP( "0 (Locked and Unlocked Games)" ), trNOOP( "1 (Unlocked Games Only)" ) }; -static const char *opts_parentalcontrol[5] = { trNOOP( "0 (Everyone)" ), trNOOP( "1 (Child 7+)" ), - trNOOP( "2 (Teen 12+)" ), trNOOP( "3 (Mature 16+)" ), trNOOP( "4 (Adults Only 18+)" ) }; -static const char *opts_error002[3] = { trNOOP( "No" ), trNOOP( "Yes" ), trNOOP( "Anti" ) }; -static const char *opts_partitions[3] = { trNOOP( "Game partition" ), trNOOP( "All partitions" ), - trNOOP( "Remove update" ) }; -static const char *opts_installdir[INSTALL_TO_MAX] = { trNOOP( "None" ), trNOOP( "GAMEID_Gamename" ), - trNOOP( "Gamename [GAMEID]" ) }; - - -static inline bool IsValidPartition(int fs_type, int cios) -{ - if (IosLoader::IsWaninkokoIOS() && NandTitles.VersionOf(TITLE_ID(1, cios)) < 18) - { - return fs_type == FS_TYPE_WBFS; - } - else - { - return fs_type == FS_TYPE_WBFS || fs_type == FS_TYPE_FAT32 || fs_type == FS_TYPE_NTFS; - } -} +#include "settings/menus/GlobalSettings.hpp" +#include "settings/menus/GameSettingsMenu.hpp" /**************************************************************************** * MenuSettings ***************************************************************************/ int MenuSettings() { - int menu = MENU_NONE; - int ret; - int choice = 0; - bool exit = false; + GlobalSettings * Menu = new GlobalSettings(); + mainWindow->Append(Menu); - // backup game language setting - char opt_lang[100]; - strcpy(opt_lang, Settings.language_path); - // backup title override setting - int opt_override = Settings.titlesOverride; - // backup partition index - u8 settingspartitionold = Settings.partition; + Menu->ShowMenu(); - enum - { - FADE, LEFT, RIGHT - }; + int returnMenu = MENU_NONE; - int slidedirection = FADE; + while((returnMenu = Menu->MainLoop()) == MENU_NONE); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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); - GuiSound btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); + delete Menu; - GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); - GuiImageData settingsbg(Resources::GetFile("settings_background.png"), Resources::GetFileSize("settings_background.png")); - - GuiImageData MainButtonImgData(Resources::GetFile("settings_title.png"), Resources::GetFileSize("settings_title.png")); - - GuiImageData MainButtonImgOverData(Resources::GetFile("settings_title_over.png"), Resources::GetFileSize("settings_title_over.png")); - - GuiImageData PageindicatorImgData(Resources::GetFile("pageindicator.png"), Resources::GetFileSize("pageindicator.png")); - - GuiImageData arrow_left(Resources::GetFile("startgame_arrow_left.png"), Resources::GetFileSize("startgame_arrow_left.png")); - - GuiImageData arrow_right(Resources::GetFile("startgame_arrow_right.png"), Resources::GetFileSize("startgame_arrow_right.png")); - - GuiImageData creditsImgData(Resources::GetFile("credits_button.png"), Resources::GetFileSize("credits_button.png")); - - GuiImageData creditsOver(Resources::GetFile("credits_button_over.png"), Resources::GetFileSize("credits_button_over.png")); - - GuiImage creditsImg(&creditsImgData); - GuiImage creditsImgOver(&creditsOver); - - GuiTrigger trigA; - trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); - GuiTrigger trigHome; - trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0); - GuiTrigger trigB; - trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); - GuiTrigger trigL; - trigL.SetButtonOnlyTrigger(-1, WPAD_BUTTON_LEFT | WPAD_CLASSIC_BUTTON_LEFT, PAD_BUTTON_LEFT); - GuiTrigger trigR; - trigR.SetButtonOnlyTrigger(-1, WPAD_BUTTON_RIGHT | WPAD_CLASSIC_BUTTON_RIGHT, PAD_BUTTON_RIGHT); - GuiTrigger trigMinus; - trigMinus.SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0); - GuiTrigger trigPlus; - trigPlus.SetButtonOnlyTrigger(-1, WPAD_BUTTON_PLUS | WPAD_CLASSIC_BUTTON_PLUS, 0); - - GuiText titleTxt(tr( "Settings" ), 28, ( GXColor ) {0, 0, 0, 255}); - titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - titleTxt.SetPosition(0, 40); - - GuiImage settingsbackground(&settingsbg); - - GuiText backBtnTxt(tr( "Back" ), 22, Theme.prompttext); - backBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30); - GuiImage backBtnImg(&btnOutline); - if (Settings.wsprompt == ON) - { - backBtnTxt.SetWidescreen(Settings.widescreen); - backBtnImg.SetWidescreen(Settings.widescreen); - } - GuiButton backBtn(&backBtnImg, &backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2, 1); - backBtn.SetLabel(&backBtnTxt); - backBtn.SetTrigger(&trigB); - - GuiButton homo(1, 1); - homo.SetTrigger(&trigHome); - - GuiImage PageindicatorImg1(&PageindicatorImgData); - GuiText PageindicatorTxt1("1", 22, ( GXColor ) {0, 0, 0, 255}); - GuiButton PageIndicatorBtn1(PageindicatorImg1.GetWidth(), PageindicatorImg1.GetHeight()); - PageIndicatorBtn1.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - PageIndicatorBtn1.SetPosition(165, 400); - PageIndicatorBtn1.SetImage(&PageindicatorImg1); - PageIndicatorBtn1.SetLabel(&PageindicatorTxt1); - PageIndicatorBtn1.SetSoundOver(&btnSoundOver); - PageIndicatorBtn1.SetSoundClick(&btnClick1); - PageIndicatorBtn1.SetTrigger(&trigA); - PageIndicatorBtn1.SetEffectGrow(); - - GuiImage PageindicatorImg2(&PageindicatorImgData); - GuiText PageindicatorTxt2("2", 22, ( GXColor ) {0, 0, 0, 255}); - GuiButton PageIndicatorBtn2(PageindicatorImg2.GetWidth(), PageindicatorImg2.GetHeight()); - PageIndicatorBtn2.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - PageIndicatorBtn2.SetPosition(200, 400); - PageIndicatorBtn2.SetImage(&PageindicatorImg2); - PageIndicatorBtn2.SetLabel(&PageindicatorTxt2); - PageIndicatorBtn2.SetSoundOver(&btnSoundOver); - PageIndicatorBtn2.SetSoundClick(&btnClick1); - PageIndicatorBtn2.SetTrigger(&trigA); - PageIndicatorBtn2.SetEffectGrow(); - - GuiImage PageindicatorImg3(&PageindicatorImgData); - GuiText PageindicatorTxt3("3", 22, ( GXColor ) {0, 0, 0, 255}); - GuiButton PageIndicatorBtn3(PageindicatorImg3.GetWidth(), PageindicatorImg3.GetHeight()); - PageIndicatorBtn3.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - PageIndicatorBtn3.SetPosition(235, 400); - PageIndicatorBtn3.SetImage(&PageindicatorImg3); - PageIndicatorBtn3.SetLabel(&PageindicatorTxt3); - PageIndicatorBtn3.SetSoundOver(&btnSoundOver); - PageIndicatorBtn3.SetSoundClick(&btnClick1); - PageIndicatorBtn3.SetTrigger(&trigA); - PageIndicatorBtn3.SetEffectGrow(); - - GuiImage GoLeftImg(&arrow_left); - GuiButton GoLeftBtn(GoLeftImg.GetWidth(), GoLeftImg.GetHeight()); - GoLeftBtn.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); - GoLeftBtn.SetPosition(25, -25); - GoLeftBtn.SetImage(&GoLeftImg); - GoLeftBtn.SetSoundOver(&btnSoundOver); - GoLeftBtn.SetSoundClick(btnClick2); - GoLeftBtn.SetEffectGrow(); - GoLeftBtn.SetTrigger(&trigA); - GoLeftBtn.SetTrigger(&trigL); - GoLeftBtn.SetTrigger(&trigMinus); - - GuiImage GoRightImg(&arrow_right); - GuiButton GoRightBtn(GoRightImg.GetWidth(), GoRightImg.GetHeight()); - GoRightBtn.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE); - GoRightBtn.SetPosition(-25, -25); - GoRightBtn.SetImage(&GoRightImg); - GoRightBtn.SetSoundOver(&btnSoundOver); - GoRightBtn.SetSoundClick(btnClick2); - GoRightBtn.SetEffectGrow(); - GoRightBtn.SetTrigger(&trigA); - GoRightBtn.SetTrigger(&trigR); - GoRightBtn.SetTrigger(&trigPlus); - - char MainButtonText[50]; - snprintf(MainButtonText, sizeof(MainButtonText), "%s", " "); - - GuiImage MainButton1Img(&MainButtonImgData); - GuiImage MainButton1ImgOver(&MainButtonImgOverData); - GuiText MainButton1Txt(MainButtonText, 22, ( GXColor ) {0, 0, 0, 255}); - MainButton1Txt.SetMaxWidth(MainButton1Img.GetWidth()); - GuiButton MainButton1(MainButton1Img.GetWidth(), MainButton1Img.GetHeight()); - MainButton1.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - MainButton1.SetPosition(0, 90); - MainButton1.SetImage(&MainButton1Img); - MainButton1.SetImageOver(&MainButton1ImgOver); - MainButton1.SetLabel(&MainButton1Txt); - MainButton1.SetSoundOver(&btnSoundOver); - MainButton1.SetSoundClick(&btnClick1); - MainButton1.SetEffectGrow(); - MainButton1.SetTrigger(&trigA); - - GuiImage MainButton2Img(&MainButtonImgData); - GuiImage MainButton2ImgOver(&MainButtonImgOverData); - GuiText MainButton2Txt(MainButtonText, 22, ( GXColor ) {0, 0, 0, 255}); - MainButton2Txt.SetMaxWidth(MainButton2Img.GetWidth()); - GuiButton MainButton2(MainButton2Img.GetWidth(), MainButton2Img.GetHeight()); - MainButton2.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - MainButton2.SetPosition(0, 160); - MainButton2.SetImage(&MainButton2Img); - MainButton2.SetImageOver(&MainButton2ImgOver); - MainButton2.SetLabel(&MainButton2Txt); - MainButton2.SetSoundOver(&btnSoundOver); - MainButton2.SetSoundClick(&btnClick1); - MainButton2.SetEffectGrow(); - MainButton2.SetTrigger(&trigA); - - GuiImage MainButton3Img(&MainButtonImgData); - GuiImage MainButton3ImgOver(&MainButtonImgOverData); - GuiText MainButton3Txt(MainButtonText, 22, ( GXColor ) {0, 0, 0, 255}); - MainButton3Txt.SetMaxWidth(MainButton3Img.GetWidth()); - GuiButton MainButton3(MainButton3Img.GetWidth(), MainButton3Img.GetHeight()); - MainButton3.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - MainButton3.SetPosition(0, 230); - MainButton3.SetImage(&MainButton3Img); - MainButton3.SetImageOver(&MainButton3ImgOver); - MainButton3.SetLabel(&MainButton3Txt); - MainButton3.SetSoundOver(&btnSoundOver); - MainButton3.SetSoundClick(&btnClick1); - MainButton3.SetEffectGrow(); - MainButton3.SetTrigger(&trigA); - - GuiImage MainButton4Img(&MainButtonImgData); - GuiImage MainButton4ImgOver(&MainButtonImgOverData); - GuiText MainButton4Txt(MainButtonText, 22, ( GXColor ) {0, 0, 0, 255}); - MainButton4Txt.SetMaxWidth(MainButton4Img.GetWidth()); - GuiButton MainButton4(MainButton4Img.GetWidth(), MainButton4Img.GetHeight()); - MainButton4.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - MainButton4.SetPosition(0, 300); - MainButton4.SetImage(&MainButton4Img); - MainButton4.SetImageOver(&MainButton4ImgOver); - MainButton4.SetLabel(&MainButton4Txt); - MainButton4.SetSoundOver(&btnSoundOver); - MainButton4.SetSoundClick(&btnClick1); - MainButton4.SetEffectGrow(); - MainButton4.SetTrigger(&trigA); - - OptionList options2; - GuiCustomOptionBrowser optionBrowser2(396, 280, &options2, "bg_options_settings.png", 0, 150); - optionBrowser2.SetPosition(0, 90); - optionBrowser2.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - - GuiWindow w(screenwidth, screenheight); - - int pageToDisplay = 1; - while (pageToDisplay > 0) - { - usleep(100); - - menu = MENU_NONE; - - if (pageToDisplay == 1) - { - /** Standard procedure made in all pages **/ - MainButton1.StopEffect(); - MainButton2.StopEffect(); - MainButton3.StopEffect(); - MainButton4.StopEffect(); - - if (slidedirection == RIGHT) - { - MainButton1.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - MainButton2.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - MainButton3.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - MainButton4.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - while (MainButton1.GetEffect() > 0) - usleep(50); - } - else if (slidedirection == LEFT) - { - MainButton1.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - MainButton2.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - MainButton3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - MainButton4.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - while (MainButton1.GetEffect() > 0) - usleep(50); - } - - HaltGui(); - - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "GUI Settings" )); - MainButton1Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Game Load" )); - MainButton2Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Parental Control" )); - MainButton3Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Sound" )); - MainButton4Txt.SetText(MainButtonText); - - mainWindow->RemoveAll(); - mainWindow->Append(&w); - w.RemoveAll(); - w.Append(&settingsbackground); - w.Append(&PageIndicatorBtn1); - w.Append(&PageIndicatorBtn2); - w.Append(&PageIndicatorBtn3); - w.Append(&titleTxt); - w.Append(&backBtn); - w.Append(&homo); - w.Append(&GoRightBtn); - w.Append(&GoLeftBtn); - w.Append(&MainButton1); - w.Append(&MainButton2); - w.Append(&MainButton3); - w.Append(&MainButton4); - - PageIndicatorBtn1.SetAlpha(255); - PageIndicatorBtn2.SetAlpha(50); - PageIndicatorBtn3.SetAlpha(50); - - /** Creditsbutton change **/ - MainButton4.SetImage(&MainButton4Img); - MainButton4.SetImageOver(&MainButton4ImgOver); - - /** Disable ability to click through MainButtons */ - optionBrowser2.SetClickable(false); - /** Default no scrollbar and reset position **/ - // optionBrowser2.SetScrollbar(0); - optionBrowser2.SetOffset(0); - - MainButton1.StopEffect(); - MainButton2.StopEffect(); - MainButton3.StopEffect(); - MainButton4.StopEffect(); - - MainButton1.SetEffectGrow(); - MainButton2.SetEffectGrow(); - MainButton3.SetEffectGrow(); - MainButton4.SetEffectGrow(); - - if (slidedirection == FADE) - { - MainButton1.SetEffect(EFFECT_FADE, 20); - MainButton2.SetEffect(EFFECT_FADE, 20); - MainButton3.SetEffect(EFFECT_FADE, 20); - MainButton4.SetEffect(EFFECT_FADE, 20); - } - else if (slidedirection == LEFT) - { - MainButton1.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - MainButton2.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - MainButton3.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - MainButton4.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - } - else if (slidedirection == RIGHT) - { - MainButton1.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - MainButton2.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - MainButton3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - MainButton4.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - } - - mainWindow->Append(&w); - - ResumeGui(); - - while (MainButton1.GetEffect() > 0) - usleep(50); - - } - else if (pageToDisplay == 2) - { - /** Standard procedure made in all pages **/ - MainButton1.StopEffect(); - MainButton2.StopEffect(); - MainButton3.StopEffect(); - MainButton4.StopEffect(); - - if (slidedirection == RIGHT) - { - MainButton1.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - MainButton2.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - MainButton3.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - MainButton4.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - while (MainButton1.GetEffect() > 0) - usleep(50); - } - else if (slidedirection == LEFT) - { - MainButton1.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - MainButton2.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - MainButton3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - MainButton4.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - while (MainButton1.GetEffect() > 0) - usleep(50); - } - - HaltGui(); - - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Custom Paths" )); - MainButton1Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Update" )); - MainButton2Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Default Settings" )); - MainButton3Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Credits" )); - MainButton4Txt.SetText(MainButtonText); - - mainWindow->RemoveAll(); - mainWindow->Append(&w); - w.RemoveAll(); - w.Append(&settingsbackground); - w.Append(&PageIndicatorBtn1); - w.Append(&PageIndicatorBtn2); - w.Append(&PageIndicatorBtn3); - w.Append(&titleTxt); - w.Append(&backBtn); - w.Append(&homo); - w.Append(&GoRightBtn); - w.Append(&GoLeftBtn); - w.Append(&MainButton1); - w.Append(&MainButton2); - w.Append(&MainButton3); - w.Append(&MainButton4); - - PageIndicatorBtn1.SetAlpha(50); - PageIndicatorBtn2.SetAlpha(255); - PageIndicatorBtn3.SetAlpha(50); - - /** Creditsbutton change **/ - MainButton4.SetImage(&creditsImg); - MainButton4.SetImageOver(&creditsImgOver); - - /** Disable ability to click through MainButtons */ - optionBrowser2.SetClickable(false); - /** Default no scrollbar and reset position **/ - // optionBrowser2.SetScrollbar(0); - optionBrowser2.SetOffset(0); - - MainButton1.StopEffect(); - MainButton2.StopEffect(); - MainButton3.StopEffect(); - MainButton4.StopEffect(); - - MainButton1.SetEffectGrow(); - MainButton2.SetEffectGrow(); - MainButton3.SetEffectGrow(); - MainButton4.SetEffectGrow(); - - if (slidedirection == FADE) - { - MainButton1.SetEffect(EFFECT_FADE, 20); - MainButton2.SetEffect(EFFECT_FADE, 20); - MainButton3.SetEffect(EFFECT_FADE, 20); - MainButton4.SetEffect(EFFECT_FADE, 20); - } - else if (slidedirection == LEFT) - { - MainButton1.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - MainButton2.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - MainButton3.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - MainButton4.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - } - else if (slidedirection == RIGHT) - { - MainButton1.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - MainButton2.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - MainButton3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - MainButton4.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - } - - mainWindow->Append(&w); - - ResumeGui(); - - while (MainButton1.GetEffect() > 0) - usleep(50); - - } - else if (pageToDisplay == 3) - { - /** Standard procedure made in all pages **/ - MainButton1.StopEffect(); - MainButton2.StopEffect(); - MainButton3.StopEffect(); - MainButton4.StopEffect(); - - if (slidedirection == RIGHT) - { - MainButton1.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - MainButton2.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - MainButton3.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - MainButton4.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 35); - while (MainButton1.GetEffect() > 0) - usleep(50); - } - else if (slidedirection == LEFT) - { - MainButton1.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - MainButton2.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - MainButton3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - MainButton4.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 35); - while (MainButton1.GetEffect() > 0) - usleep(50); - } - - HaltGui(); - - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Theme Downloader" )); - MainButton1Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( " " )); - MainButton2Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( " " )); - MainButton3Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( " " )); - MainButton4Txt.SetText(MainButtonText); - - mainWindow->RemoveAll(); - mainWindow->Append(&w); - w.RemoveAll(); - w.Append(&settingsbackground); - w.Append(&PageIndicatorBtn1); - w.Append(&PageIndicatorBtn2); - w.Append(&PageIndicatorBtn3); - w.Append(&titleTxt); - w.Append(&backBtn); - w.Append(&homo); - w.Append(&GoRightBtn); - w.Append(&GoLeftBtn); - w.Append(&MainButton1); - - PageIndicatorBtn1.SetAlpha(50); - PageIndicatorBtn2.SetAlpha(50); - PageIndicatorBtn3.SetAlpha(255); - - /** Disable ability to click through MainButtons */ - optionBrowser2.SetClickable(false); - /** Default no scrollbar and reset position **/ - // optionBrowser2.SetScrollbar(0); - optionBrowser2.SetOffset(0); - - MainButton1.StopEffect(); - MainButton2.StopEffect(); - MainButton3.StopEffect(); - MainButton4.StopEffect(); - - MainButton1.SetEffectGrow(); - MainButton2.SetEffectGrow(); - MainButton3.SetEffectGrow(); - MainButton4.SetEffectGrow(); - - if (slidedirection == FADE) - { - MainButton1.SetEffect(EFFECT_FADE, 20); - MainButton2.SetEffect(EFFECT_FADE, 20); - MainButton3.SetEffect(EFFECT_FADE, 20); - MainButton4.SetEffect(EFFECT_FADE, 20); - } - else if (slidedirection == LEFT) - { - MainButton1.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - MainButton2.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - MainButton3.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - MainButton4.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 35); - } - else if (slidedirection == RIGHT) - { - MainButton1.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - MainButton2.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - MainButton3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - MainButton4.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 35); - } - - mainWindow->Append(&w); - - ResumeGui(); - - while (MainButton1.GetEffect() > 0) - usleep(50); - } - - while (menu == MENU_NONE) - { - usleep(100); - - if (shutdown == 1) Sys_Shutdown(); - if (reset == 1) Sys_Reboot(); - - if (pageToDisplay == 1) - { - if (MainButton1.GetState() == STATE_CLICKED) - { - MainButton1.SetEffect(EFFECT_FADE, -20); - MainButton2.SetEffect(EFFECT_FADE, -20); - MainButton3.SetEffect(EFFECT_FADE, -20); - MainButton4.SetEffect(EFFECT_FADE, -20); - while (MainButton1.GetEffect() > 0) - usleep(50); - HaltGui(); - w.Remove(&PageIndicatorBtn1); - w.Remove(&PageIndicatorBtn2); - w.Remove(&PageIndicatorBtn3); - w.Remove(&GoRightBtn); - w.Remove(&GoLeftBtn); - w.Remove(&MainButton1); - w.Remove(&MainButton2); - w.Remove(&MainButton3); - w.Remove(&MainButton4); - titleTxt.SetText(tr( "GUI Settings" )); - exit = false; - options2.ClearList(); - // optionBrowser2.SetScrollbar(1); - w.Append(&optionBrowser2); - optionBrowser2.SetClickable(true); - ResumeGui(); - - optionBrowser2.SetEffect(EFFECT_FADE, 20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - - int returnhere = 1; - const char * languagefile = strrchr(Settings.language_path, '/'); - if(languagefile) - languagefile += 1; - else - languagefile = tr("Default"); - - bool firstRun = true; - while (!exit) - { - usleep(100); - - returnhere = 1; - - if (shutdown == 1) Sys_Shutdown(); - if (reset == 1) - Sys_Reboot(); - - else if (backBtn.GetState() == STATE_CLICKED) - { - backBtn.ResetState(); - exit = true; - break; - } - - else if (menu == MENU_DISCLIST) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - WindowCredits(); - w.Append(&optionBrowser2); - w.Append(&backBtn); - } - - else if (homo.GetState() == STATE_CLICKED) - { - Settings.Save(); - optionBrowser2.SetState(STATE_DISABLED); - bgMusic->Pause(); - choice = WindowExitPrompt(); - bgMusic->Resume(); - if (choice == 3) - Sys_LoadMenu(); // Back to System Menu - else if (choice == 2) - Sys_BackToLoader(); - else homo.ResetState(); - optionBrowser2.SetState(STATE_DEFAULT); - } - - ret = optionBrowser2.GetClickedOption(); - - if (firstRun || ret >= 0) - { - int Idx = -1; - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "App Language" )); - if (ret == Idx) - { - if (isInserted(Settings.BootDevice)) - { - if (Settings.godmode == 1) - { - w.SetEffect(EFFECT_FADE, -20); - while (w.GetEffect() > 0) - usleep(50); - mainWindow->Remove(&w); - while (returnhere == 1) - returnhere = MenuLanguageSelect(); - if (returnhere == 2) - { - menu = MENU_SETTINGS; - pageToDisplay = 0; - exit = true; - mainWindow->Append(&w); - break; - } - else - { - HaltGui(); - mainWindow->Append(&w); - w.SetEffect(EFFECT_FADE, 20); - ResumeGui(); - while (w.GetEffect() > 0) - usleep(50); - } - } - else - { - WindowPrompt(tr( "Language change:" ), - tr( "Console should be unlocked to modify it." ), tr( "OK" )); - } - } - else - { - WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to use this option." ), tr( "OK" )); - } - } - - if (!strcmp("notset", Settings.language_path)) - options2.SetValue(Idx, "%s", tr( "Default" )); - else options2.SetValue(Idx, "%s", languagefile); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Display" )); - if (ret == Idx && ++Settings.sinfo >= GAMEINFO_MAX) Settings.sinfo = 0; - static const char *opts[GAMEINFO_MAX] = { trNOOP( "Game ID" ), - trNOOP( "Game Region" ), trNOOP( "Both" ), trNOOP( "Neither" ) }; - options2.SetValue(Idx, "%s", tr( opts[Settings.sinfo] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Clock" )); - if (ret == Idx && ++Settings.hddinfo >= CLOCK_MAX) Settings.hddinfo = 0; //CLOCK - if (Settings.hddinfo == CLOCK_HR12) - options2.SetValue(Idx, "12 %s", tr( "Hour" )); - else if (Settings.hddinfo == CLOCK_HR24) - options2.SetValue(Idx, "24 %s", tr( "Hour" )); - else if (Settings.hddinfo == OFF) options2.SetValue(Idx, "%s", tr( "OFF" )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Tooltips" )); - if (ret == Idx && ++Settings.tooltips >= MAX_ON_OFF) Settings.tooltips = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[Settings.tooltips] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Flip-X" )); - if (ret == Idx && ++Settings.xflip >= XFLIP_MAX) Settings.xflip = 0; - static const char *opts[XFLIP_MAX][3] = - { { trNOOP( "Right" ), "/", trNOOP( "Next" ) }, { trNOOP( "Left" ), "/", - trNOOP( "Prev" ) }, { trNOOP( "Like SysMenu" ), "", "" }, { - trNOOP( "Right" ), "/", trNOOP( "Prev" ) }, { trNOOP( "DiskFlip" ), - "", "" } }; - options2.SetValue(Idx, "%s%s%s", tr( opts[Settings.xflip][0] ), - opts[Settings.xflip][1], tr( opts[Settings.xflip][2] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Prompts Buttons" )); - if (ret == Idx && ++Settings.wsprompt >= MAX_ON_OFF) Settings.wsprompt = 0; - static const char *opts[MAX_ON_OFF] = { trNOOP( "Normal" ), - trNOOP( "Widescreen Fix" ) }; - options2.SetValue(Idx, "%s", tr( opts[Settings.wsprompt] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Keyboard" )); - if (ret == Idx && ++Settings.keyset >= KEYBOARD_MAX) Settings.keyset = 0; - static const char *opts[KEYBOARD_MAX] = { "QWERTY", "DVORAK", - "QWERTZ", "AZERTY", "QWERTY 2" }; - options2.SetValue(Idx, "%s", opts[Settings.keyset]); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Disc Artwork Download" )); - if (ret == Idx && ++Settings.discart >= 4) Settings.discart = 0; - static const char *opts[4] = { trNOOP( "Only Original" ), trNOOP( "Only Customs" ), - trNOOP( "Original/Customs" ), trNOOP( "Customs/Original" ) }; - options2.SetValue(Idx, "%s", tr( opts[Settings.discart] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Wiilight" )); - if (ret == Idx && ++Settings.wiilight >= WIILIGHT_MAX) Settings.wiilight = 0; - static const char *opts[WIILIGHT_MAX] = { trNOOP( "OFF" ), trNOOP( "ON" ), - trNOOP( "Only for Install" ) }; - options2.SetValue(Idx, "%s", tr( opts[Settings.wiilight] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Rumble" )); - if (ret == Idx && ++Settings.rumble >= MAX_ON_OFF) Settings.rumble = 0; //RUMBLE - options2.SetValue(Idx, "%s", tr( opts_off_on[Settings.rumble] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "AutoInit Network" )); - if (ret == Idx && ++Settings.autonetwork >= MAX_ON_OFF) Settings.autonetwork - = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[Settings.autonetwork] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "BETA revisions" )); - if (ret == Idx && ++Settings.beta_upgrades >= MAX_ON_OFF) Settings.beta_upgrades - = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[Settings.beta_upgrades] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Titles from WiiTDB" )); - if (ret == Idx && ++Settings.titlesOverride >= MAX_ON_OFF) Settings.titlesOverride - = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[Settings.titlesOverride] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Screensaver" )); - if (ret == Idx && ++Settings.screensaver >= SCREENSAVER_MAX) Settings.screensaver - = 0; //RUMBLE - static const char *opts[SCREENSAVER_MAX] = { trNOOP( "OFF" ), - trNOOP( "3 min" ), trNOOP( "5 min" ), trNOOP( "10 min" ), trNOOP( "20 min" ), - trNOOP( "30 min" ), trNOOP( "1 hour" ) }; - options2.SetValue(Idx, "%s", tr( opts[Settings.screensaver] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Mark new games" )); - if (ret == Idx && ++Settings.marknewtitles >= MAX_ON_OFF) Settings.marknewtitles - = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[Settings.marknewtitles] )); - } - - firstRun = false; - } - } - optionBrowser2.SetEffect(EFFECT_FADE, -20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - titleTxt.SetText(tr( "Settings" )); - slidedirection = FADE; - if (returnhere != 2) pageToDisplay = 1; - MainButton1.ResetState(); - break; - } - - else if (MainButton2.GetState() == STATE_CLICKED) - { - MainButton1.SetEffect(EFFECT_FADE, -20); - MainButton2.SetEffect(EFFECT_FADE, -20); - MainButton3.SetEffect(EFFECT_FADE, -20); - MainButton4.SetEffect(EFFECT_FADE, -20); - while (MainButton2.GetEffect() > 0) - usleep(50); - HaltGui(); - w.Remove(&PageIndicatorBtn1); - w.Remove(&PageIndicatorBtn2); - w.Remove(&PageIndicatorBtn3); - w.Remove(&GoRightBtn); - w.Remove(&GoLeftBtn); - w.Remove(&MainButton1); - w.Remove(&MainButton2); - w.Remove(&MainButton3); - w.Remove(&MainButton4); - titleTxt.SetText(tr( "Game Load" )); - exit = false; - options2.ClearList(); - w.Append(&optionBrowser2); - optionBrowser2.SetClickable(true); - ResumeGui(); - - optionBrowser2.SetEffect(EFFECT_FADE, 20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - - bool firstRun = true; - while (!exit) - { - usleep(100); - - if (shutdown == 1) Sys_Shutdown(); - if (reset == 1) - Sys_Reboot(); - - else if (backBtn.GetState() == STATE_CLICKED) - { - backBtn.ResetState(); - exit = true; - break; - } - - else if (homo.GetState() == STATE_CLICKED) - { - Settings.Save(); - optionBrowser2.SetState(STATE_DISABLED); - bgMusic->Pause(); - choice = WindowExitPrompt(); - bgMusic->Resume(); - if (choice == 3) Sys_LoadMenu(); // Back to System Menu - if (choice == 2) - Sys_BackToLoader(); - else homo.ResetState(); - optionBrowser2.SetState(STATE_DEFAULT); - } - - ret = optionBrowser2.GetClickedOption(); - - if (firstRun || ret >= 0) - { - int Idx = -1; - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Video Mode" )); - if (ret == Idx && ++Settings.videomode >= VIDEO_MODE_MAX) Settings.videomode = 0; - options2.SetValue(Idx, "%s%s", opts_videomode[Settings.videomode][0], - tr( opts_videomode[Settings.videomode][1] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "VIDTV Patch" )); - if (ret == Idx && ++Settings.videopatch >= MAX_ON_OFF) Settings.videopatch = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[Settings.videopatch] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Game Language" )); - if (ret == Idx && ++Settings.language >= MAX_LANGUAGE) Settings.language = 0; - options2.SetValue(Idx, "%s", tr( opts_language[Settings.language] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Patch Country Strings" )); - if (ret == Idx && ++Settings.patchcountrystrings >= MAX_ON_OFF) Settings.patchcountrystrings - = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[Settings.patchcountrystrings] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "Ocarina"); - if (ret == Idx && ++Settings.ocarina >= MAX_ON_OFF) Settings.ocarina = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[Settings.ocarina] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Boot/Standard" )); - if (ret == Idx && Settings.godmode == 1) - { - char entered[4]; - snprintf(entered, sizeof(entered), "%i", Settings.cios); - if(OnScreenKeyboard(entered, sizeof(entered), 0)) - { - Settings.cios = atoi(entered); - if(Settings.cios < 200) Settings.cios = 200; - else if(Settings.cios > 255) Settings.cios = 255; - - if(NandTitles.IndexOf(TITLE_ID(1, Settings.cios)) < 0) - { - WindowPrompt(tr("Warning:"), tr("This IOS was not found on the titles list. If you are sure you have it installed than ignore this warning."), tr("OK")); - } - else if(Settings.cios == 254) - { - WindowPrompt(tr("Warning:"), tr("This IOS is the BootMii ios. If you are sure it is not BootMii and you have something else installed there than ignore this warning."), tr("OK")); - } - } - } - if (Settings.godmode == 1) - options2.SetValue(Idx, "IOS %i", Settings.cios); - else options2.SetValue(Idx, "********"); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Partition" )); - if (ret == Idx) - { - // Select the next valid partition, even if that's the same one - int fs_type = partitions.pinfo[Settings.partition].fs_type; - int ios = IOS_GetVersion(); - do - { - Settings.partition = (Settings.partition + 1) % partitions.num; - fs_type = partitions.pinfo[Settings.partition].fs_type; - } - while (!IsValidPartition(fs_type, ios)); - } - - PartInfo pInfo = partitions.pinfo[Settings.partition]; - f32 partition_size = partitions.pentry[Settings.partition].size - * (partitions.sector_size / GB_SIZE); - - // Get the partition name and it's size in GB's - options2.SetValue(Idx, "%s%d (%.2fGB)", pInfo.fs_type == FS_TYPE_FAT32 ? "FAT" - : pInfo.fs_type == FS_TYPE_NTFS ? "NTFS" : "WBFS", pInfo.index, partition_size); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "FAT: Use directories" )); - if (ret == Idx && ++Settings.FatInstallToDir >= INSTALL_TO_MAX) Settings.FatInstallToDir - = 0; - options2.SetValue(Idx, "%s", tr( opts_installdir[Settings.FatInstallToDir] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Quick Boot" )); - if (ret == Idx && ++Settings.quickboot >= MAX_ON_OFF) Settings.quickboot = 0; - options2.SetValue(Idx, "%s", tr( opts_no_yes[Settings.quickboot] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Error 002 fix" )); - if (ret == Idx && ++Settings.error002 >= 3) Settings.error002 = 0; - options2.SetValue(Idx, "%s", tr( opts_error002[Settings.error002] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Install partitions" )); - if (ret == Idx && ++Settings.InstallPartitions >= 3) Settings.InstallPartitions - = 0; - options2.SetValue(Idx, "%s", tr( opts_partitions[Settings.InstallPartitions] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Install 1:1 Copy" )); - if (ret == Idx) - { - Settings.fullcopy = Settings.fullcopy == 0 ? 1 : 0; - } - options2.SetValue(Idx, "%s", tr( opts_no_yes[Settings.fullcopy] )); - } - - if (ret == ++Idx || firstRun) - { - char* name = NULL; - if (firstRun) options2.SetName(Idx, "%s", tr( "Return To" )); - if (ret == Idx) - { - char tidChar[10]; - bool getChannel = TitleSelector(tidChar); - if (getChannel) - { - snprintf(Settings.returnTo, sizeof(Settings.returnTo), "%s", tidChar); - } - } - int haveTitle = NandTitles.FindU32(Settings.returnTo); - if (haveTitle >= 0) - { - name = (char*) NandTitles.NameFromIndex(haveTitle); - if( name && !strlen(name) ) name = NULL; - } - options2.SetValue(Idx, "%s", name ? name : tr( opts_off_on[ 0 ] )); - } - - firstRun = false; - } - } - optionBrowser2.SetEffect(EFFECT_FADE, -20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - titleTxt.SetText(tr( "Settings" )); - slidedirection = FADE; - pageToDisplay = 1; - MainButton2.ResetState(); - break; - } - - else if (MainButton3.GetState() == STATE_CLICKED) - { - MainButton1.SetEffect(EFFECT_FADE, -20); - MainButton2.SetEffect(EFFECT_FADE, -20); - MainButton3.SetEffect(EFFECT_FADE, -20); - MainButton4.SetEffect(EFFECT_FADE, -20); - while (MainButton3.GetEffect() > 0) - usleep(50); - HaltGui(); - w.Remove(&PageIndicatorBtn1); - w.Remove(&PageIndicatorBtn2); - w.Remove(&PageIndicatorBtn3); - w.Remove(&GoRightBtn); - w.Remove(&GoLeftBtn); - w.Remove(&MainButton1); - w.Remove(&MainButton2); - w.Remove(&MainButton3); - w.Remove(&MainButton4); - titleTxt.SetText(tr( "Parental Control" )); - exit = false; - options2.ClearList(); - w.Append(&optionBrowser2); - optionBrowser2.SetClickable(true); - ResumeGui(); - - optionBrowser2.SetEffect(EFFECT_FADE, 20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - - bool firstRun = true; - while (!exit) - { - usleep(100); - - if (shutdown == 1) Sys_Shutdown(); - if (reset == 1) - Sys_Reboot(); - - else if (backBtn.GetState() == STATE_CLICKED) - { - backBtn.ResetState(); - exit = true; - break; - } - - else if (homo.GetState() == STATE_CLICKED) - { - Settings.Save(); - optionBrowser2.SetState(STATE_DISABLED); - bgMusic->Pause(); - choice = WindowExitPrompt(); - bgMusic->Resume(); - if (choice == 3) - Sys_LoadMenu(); // Back to System Menu - else if (choice == 2) - Sys_BackToLoader(); - else homo.ResetState(); - optionBrowser2.SetState(STATE_DEFAULT); - } - - ret = optionBrowser2.GetClickedOption(); - - if (firstRun || ret >= 0) - { - - int Idx = -1; - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Console" )); - if (ret == Idx) - { - if (!strcmp("", Settings.unlockCode) && Settings.Parental.enabled == 0) - { - Settings.godmode = !Settings.godmode; - } - else if (Settings.godmode == 0) - { - char entered[20]; - memset(entered, 0, 20); - - //password check to unlock Install,Delete and Format - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - int result = Settings.Parental.enabled == 0 ? OnScreenKeyboard(entered, 20, 0) - : OnScreenNumpad(entered, 5); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - if (!strcmp(entered, Settings.unlockCode) || !memcmp(entered, - Settings.Parental.pin, 4)) //if password correct - { - if (Settings.godmode == 0) - { - WindowPrompt( - tr( "Correct Password" ), - tr( "All the features of USB Loader GX are unlocked." ), - tr( "OK" )); - Settings.godmode = 1; - menu = MENU_DISCLIST; - } - } - else WindowPrompt(tr( "Wrong Password" ), - tr( "USB Loader GX is protected" ), tr( "OK" )); - } - } - else - { - int choice = WindowPrompt(tr( "Lock Console" ), tr( "Are you sure?" ), - tr( "Yes" ), tr( "No" )); - if (choice == 1) - { - WindowPrompt(tr( "Console Locked" ), tr( "USB Loader GX is protected" ), - tr( "OK" )); - Settings.godmode = 0; - menu = MENU_DISCLIST; - } - } - } - static const char *opts[] = { trNOOP( "Locked" ), trNOOP( "Unlocked" ) }; - options2.SetValue(Idx, "%s", tr( opts[Settings.godmode] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Password" )); - if (ret == Idx) - { - if (Settings.godmode == 1) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[20] = ""; - strlcpy(entered, Settings.unlockCode, sizeof(entered)); - int result = OnScreenKeyboard(entered, 20, 0); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - strlcpy(Settings.unlockCode, entered, sizeof(Settings.unlockCode)); - WindowPrompt(tr( "Password Changed" ), tr( "Password has been changed" ), - tr( "OK" )); - } - } - else - { - WindowPrompt(tr( "Password Changed" ), - tr( "Console should be unlocked to modify it." ), tr( "OK" )); - } - } - if (Settings.godmode != 1) - options2.SetValue(Idx, "********"); - else if (!strcmp("", Settings.unlockCode)) - options2.SetValue(Idx, "%s", tr( "not set" )); - else options2.SetValue(Idx, Settings.unlockCode); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Controllevel" )); - if (ret == Idx && Settings.godmode == 1 && ++Settings.parentalcontrol >= 5) Settings.parentalcontrol - = 0; - if (Settings.godmode == 1) - options2.SetValue(Idx, "%s", tr( opts_parentalcontrol[Settings.parentalcontrol] )); - else options2.SetValue(Idx, "********"); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "GamesLevel" )); - if (ret == Idx && Settings.godmode == 1 && ++Settings.lockedgames >= 2) Settings.lockedgames - = 0; - if (Settings.godmode == 1) - options2.SetValue(Idx, "%s", tr( opts_lockedgames[Settings.lockedgames] )); - else options2.SetValue(Idx, "********"); - } - - firstRun = false; - } - } - optionBrowser2.SetEffect(EFFECT_FADE, -20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - titleTxt.SetText(tr( "Settings" )); - slidedirection = FADE; - pageToDisplay = 1; - MainButton3.ResetState(); - break; - } - - else if (MainButton4.GetState() == STATE_CLICKED) - { - MainButton1.SetEffect(EFFECT_FADE, -20); - MainButton2.SetEffect(EFFECT_FADE, -20); - MainButton3.SetEffect(EFFECT_FADE, -20); - MainButton4.SetEffect(EFFECT_FADE, -20); - while (MainButton4.GetEffect() > 0) - usleep(50); - HaltGui(); - w.Remove(&PageIndicatorBtn1); - w.Remove(&PageIndicatorBtn2); - w.Remove(&PageIndicatorBtn3); - w.Remove(&GoRightBtn); - w.Remove(&GoLeftBtn); - w.Remove(&MainButton1); - w.Remove(&MainButton2); - w.Remove(&MainButton3); - w.Remove(&MainButton4); - titleTxt.SetText(tr( "Sound" )); - exit = false; - options2.ClearList(); - w.Append(&optionBrowser2); - optionBrowser2.SetClickable(true); - ResumeGui(); - - optionBrowser2.SetEffect(EFFECT_FADE, 20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - - bool firstRun = true; - while (!exit) - { - usleep(100); - - bool returnhere = true; - - if (shutdown == 1) Sys_Shutdown(); - if (reset == 1) - Sys_Reboot(); - else if (backBtn.GetState() == STATE_CLICKED) - { - backBtn.ResetState(); - exit = true; - break; - } - - else if (homo.GetState() == STATE_CLICKED) - { - Settings.Save(); - optionBrowser2.SetState(STATE_DISABLED); - bgMusic->Pause(); - choice = WindowExitPrompt(); - bgMusic->Resume(); - if (choice == 3) - Sys_LoadMenu(); // Back to System Menu - else if (choice == 2) - Sys_BackToLoader(); - else homo.ResetState(); - optionBrowser2.SetState(STATE_DEFAULT); - } - - ret = optionBrowser2.GetClickedOption(); - - if (firstRun || ret >= 0) - { - int Idx = -1; - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Backgroundmusic" )); - if (ret == Idx) - { - if (isInserted(Settings.BootDevice)) - { - w.SetEffect(EFFECT_FADE, -20); - while (w.GetEffect() > 0) - usleep(50); - mainWindow->Remove(&w); - - returnhere = MenuBackgroundMusic(); - - HaltGui(); - mainWindow->Append(&w); - w.SetEffect(EFFECT_FADE, 20); - ResumeGui(); - while (w.GetEffect() > 0) - usleep(50); - } - else WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to use this option." ), tr( "OK" )); - } - - char * filename = strrchr(Settings.ogg_path, '/'); - if (filename) - { - filename += 1; - options2.SetValue(Idx, "%s", filename); - } - else options2.SetValue(Idx, "%s", tr( "Standard" )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Music Volume" )); - if (ret == Idx) - { - Settings.volume += 10; - if (Settings.volume > 100) Settings.volume = 0; - bgMusic->SetVolume(Settings.volume); - } - if (Settings.volume > 0) - options2.SetValue(Idx, "%i", Settings.volume); - else options2.SetValue(Idx, "%s", tr( "OFF" )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "SFX Volume" )); - if (ret == Idx) - { - Settings.sfxvolume += 10; - if (Settings.sfxvolume > 100) Settings.sfxvolume = 0; - btnSoundOver.SetVolume(Settings.sfxvolume); - btnClick2->SetVolume(Settings.sfxvolume); - btnClick1.SetVolume(Settings.sfxvolume); - } - if (Settings.sfxvolume > 0) - options2.SetValue(Idx, "%i", Settings.sfxvolume); - else options2.SetValue(Idx, "%s", tr( "OFF" )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Game Sound Mode" )); - if (ret == Idx) - { - Settings.gamesound++; - if (Settings.gamesound > 2) Settings.gamesound = 0; - } - - if (Settings.gamesound == 1) - options2.SetValue(Idx, "%s", tr( "Sound+BGM" )); - else if (Settings.gamesound == 2) - options2.SetValue(Idx, "%s", tr( "Loop Sound" )); - else options2.SetValue(Idx, "%s", tr( "Sound+Quiet" )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Game Sound Volume" )); - if (ret == Idx) - { - Settings.gamesoundvolume += 10; - if (Settings.gamesoundvolume > 100) Settings.gamesoundvolume = 0; - } - - if (Settings.gamesoundvolume > 0) - options2.SetValue(Idx, "%i", Settings.gamesoundvolume); - else options2.SetValue(Idx, "%s", tr( "OFF" )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Music Loop Mode" )); - if (ret == Idx) - { - Settings.musicloopmode++; - if (Settings.musicloopmode > 3) Settings.musicloopmode = 0; - bgMusic->SetLoop(Settings.musicloopmode); - } - - if (Settings.musicloopmode == ONCE) - options2.SetValue(Idx, tr( "Play Once" )); - else if (Settings.musicloopmode == LOOP) - options2.SetValue(Idx, tr( "Loop Music" )); - else if (Settings.musicloopmode == DIR_LOOP) - options2.SetValue(Idx, tr( "Loop Directory" )); - else if (Settings.musicloopmode == RANDOM_BGM) options2.SetValue(Idx, - tr( "Random Directory Music" )); - } - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Reset BG Music" )); - if (ret == Idx) - { - int result = - WindowPrompt(tr( "Reset to standard BGM?" ), 0, tr( "Yes" ), tr( "No" )); - if (result) - { - bgMusic->LoadStandard(); - bgMusic->Play(); - options2.SetValue(Idx, "%s", tr( "Standard" )); - } - } - options2.SetValue(Idx, tr( " " )); - } - - firstRun = false; - } - } - optionBrowser2.SetEffect(EFFECT_FADE, -20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - titleTxt.SetText(tr( "Settings" )); - slidedirection = FADE; - pageToDisplay = 1; - MainButton4.ResetState(); - break; - } - } - - else if (pageToDisplay == 2) - { - if (MainButton1.GetState() == STATE_CLICKED) - { - MainButton1.SetEffect(EFFECT_FADE, -20); - MainButton2.SetEffect(EFFECT_FADE, -20); - MainButton3.SetEffect(EFFECT_FADE, -20); - MainButton4.SetEffect(EFFECT_FADE, -20); - while (MainButton1.GetEffect() > 0) - usleep(50); - HaltGui(); - w.Remove(&PageIndicatorBtn1); - w.Remove(&PageIndicatorBtn2); - w.Remove(&PageIndicatorBtn3); - w.Remove(&GoRightBtn); - w.Remove(&GoLeftBtn); - w.Remove(&MainButton1); - w.Remove(&MainButton2); - w.Remove(&MainButton3); - w.Remove(&MainButton4); - titleTxt.SetText(tr( "Custom Paths" )); - exit = false; - options2.ClearList(); - // optionBrowser2.SetScrollbar(1); - w.Append(&optionBrowser2); - optionBrowser2.SetClickable(true); - ResumeGui(); - - optionBrowser2.SetEffect(EFFECT_FADE, 20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - - if (Settings.godmode) - { - bool firstRun = true; - while (!exit) - { - usleep(100); - - if (shutdown == 1) Sys_Shutdown(); - if (reset == 1) - Sys_Reboot(); - - else if (backBtn.GetState() == STATE_CLICKED) - { - backBtn.ResetState(); - exit = true; - break; - } - - else if (homo.GetState() == STATE_CLICKED) - { - Settings.Save(); - optionBrowser2.SetState(STATE_DISABLED); - bgMusic->Pause(); - choice = WindowExitPrompt(); - bgMusic->Resume(); - if (choice == 3) - Sys_LoadMenu(); // Back to System Menu - else if (choice == 2) - Sys_BackToLoader(); - else homo.ResetState(); - optionBrowser2.SetState(STATE_DEFAULT); - } - - ret = optionBrowser2.GetClickedOption(); - - if (firstRun || ret >= 0) - { - - int Idx = -1; - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "3D Cover Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.covers_path, sizeof(entered)); - titleTxt.SetText(tr( "3D Cover Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.covers_path, entered, sizeof(Settings.covers_path)); - WindowPrompt(tr( "Cover Path Changed" ), 0, tr( "OK" )); - if (!isInserted(Settings.BootDevice)) WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to save." ), tr( "OK" )); - } - } - options2.SetValue(Idx, "%s", Settings.covers_path); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "2D Cover Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.covers2d_path, sizeof(entered)); - titleTxt.SetText(tr( "2D Cover Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.covers2d_path, entered, sizeof(Settings.covers2d_path)); - WindowPrompt(tr( "Cover Path Changed" ), 0, tr( "OK" )); - if (!isInserted(Settings.BootDevice)) WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to save." ), tr( "OK" )); - } - } - options2.SetValue(Idx, "%s", Settings.covers2d_path); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Disc Artwork Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.disc_path, sizeof(entered)); - titleTxt.SetText(tr( "Disc Artwork Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.disc_path, entered, sizeof(Settings.disc_path)); - WindowPrompt(tr( "Disc Path Changed" ), 0, tr( "OK" )); - if (!isInserted(Settings.BootDevice)) WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to save." ), tr( "OK" )); - } - } - options2.SetValue(Idx, "%s", Settings.disc_path); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Theme Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - titleTxt.SetText(tr( "Theme Path" )); - strlcpy(entered, Settings.theme_path, sizeof(entered)); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - HaltGui(); - w.RemoveAll(); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.theme_path, entered, sizeof(Settings.theme_path)); - WindowPrompt(tr( "Theme Path Changed" ), 0, tr( "OK" )); - if (!isInserted(Settings.BootDevice)) - WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to save." ), tr( "OK" )); - else Settings.Save(); - mainWindow->Remove(bgImg); - HaltGui(); - Theme.Load(Settings.theme_path); - ResumeGui(); - menu = MENU_SETTINGS; - if(pointer[0]) delete pointer[0]; - if(pointer[1]) delete pointer[1]; - if(pointer[2]) delete pointer[2]; - if(pointer[3]) delete pointer[3]; - pointer[0] = Resources::GetImageData("player1_point.png"); - pointer[1] = Resources::GetImageData("player2_point.png"); - pointer[2] = Resources::GetImageData("player3_point.png"); - pointer[3] = Resources::GetImageData("player4_point.png"); - if(background) delete background; - background = Resources::GetImageData(Settings.widescreen ? "wbackground.png" : "background.png"); - if(bgImg) delete bgImg; - bgImg = new GuiImage(background); - mainWindow->Append(bgImg); - mainWindow->Append(&w); - } - w.Append(&settingsbackground); - w.Append(&titleTxt); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&backBtn); - w.Append(&optionBrowser2); - ResumeGui(); - } - options2.SetValue(Idx, "%s", Settings.theme_path); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "WiiTDB Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - titleTxt.SetText(tr( "WiiTDB Path" )); - strlcpy(entered, Settings.titlestxt_path, sizeof(entered)); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - w.Append(&optionBrowser2); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.titlestxt_path, entered, sizeof(Settings.titlestxt_path)); - WindowPrompt(tr( "WiiTDB Path changed." ), 0, tr( "OK" )); - if (isInserted(Settings.BootDevice)) - { - Settings.Save(); - HaltGui(); - Settings.Load(); - ResumeGui(); - } - else WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to save." ), tr( "OK" )); - } - } - options2.SetValue(Idx, "%s", Settings.titlestxt_path); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Update Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.update_path, sizeof(entered)); - titleTxt.SetText(tr( "Update Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.update_path, entered, sizeof(Settings.update_path)); - WindowPrompt(tr( "Update Path changed." ), 0, tr( "OK" )); - } - } - options2.SetValue(Idx, "%s", Settings.update_path); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "GCT Cheatcodes Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.Cheatcodespath, sizeof(entered)); - titleTxt.SetText(tr( "GCT Cheatcodes Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.Cheatcodespath, entered, sizeof(Settings.Cheatcodespath)); - WindowPrompt(tr( "GCT Cheatcodes Path changed" ), 0, tr( "OK" )); - } - } - options2.SetValue(Idx, "%s", Settings.Cheatcodespath); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "TXT Cheatcodes Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.TxtCheatcodespath, sizeof(entered)); - titleTxt.SetText(tr( "TXT Cheatcodes Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.TxtCheatcodespath, entered, - sizeof(Settings.TxtCheatcodespath)); - WindowPrompt(tr( "TXT Cheatcodes Path changed" ), 0, tr( "OK" )); - } - } - options2.SetValue(Idx, "%s", Settings.TxtCheatcodespath); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "DOL Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.dolpath, sizeof(entered)); - titleTxt.SetText(tr( "DOL Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.dolpath, entered, sizeof(Settings.dolpath)); - WindowPrompt(tr( "DOL path changed" ), 0, tr( "OK" )); - if (!isInserted(Settings.BootDevice)) - { - WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to save." ), tr( "OK" )); - } - } - } - options2.SetValue(Idx, "%s", Settings.dolpath); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Homebrew Apps Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.homebrewapps_path, sizeof(entered)); - titleTxt.SetText(tr( "Homebrew Apps Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.homebrewapps_path, entered, - sizeof(Settings.homebrewapps_path)); - WindowPrompt(tr( "Homebrew Appspath changed" ), 0, tr( "OK" )); - if (!isInserted(Settings.BootDevice)) - { - WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to save." ), tr( "OK" )); - } - } - } - options2.SetValue(Idx, "%s", Settings.homebrewapps_path); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Theme Download Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.theme_downloadpath, sizeof(entered)); - titleTxt.SetText(tr( "Theme Download Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.theme_downloadpath, entered, - sizeof(Settings.theme_downloadpath)); - WindowPrompt(tr( "Theme Download Path changed" ), 0, tr( "OK" )); - if (!isInserted(Settings.BootDevice)) WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to save." ), tr( "OK" )); - } - } - options2.SetValue(Idx, "%s", Settings.theme_downloadpath); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "BCA Codes Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.BcaCodepath, sizeof(entered)); - titleTxt.SetText(tr( "BCA Codes Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.BcaCodepath, entered, sizeof(Settings.BcaCodepath)); - WindowPrompt(tr( "BCA Codes Path changed" ), 0, tr( "OK" )); - if (!isInserted(Settings.BootDevice)) WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to save." ), tr( "OK" )); - } - } - options2.SetValue(Idx, "%s", Settings.BcaCodepath); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "WIP Patches Path" )); - if (ret == Idx) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - char entered[100] = ""; - strlcpy(entered, Settings.WipCodepath, sizeof(entered)); - titleTxt.SetText(tr( "WIP Patches Path" )); - int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); - titleTxt.SetText(tr( "Custom Paths" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - if (result == 1) - { - int len = (strlen(entered) - 1); - if (entered[len] != '/') strncat(entered, "/", 1); - strlcpy(Settings.WipCodepath, entered, sizeof(Settings.WipCodepath)); - WindowPrompt(tr( "WIP Patches Path changed" ), 0, tr( "OK" )); - if (!isInserted(Settings.BootDevice)) WindowPrompt(tr( "No SD-Card inserted!" ), - tr( "Insert an SD-Card to save." ), tr( "OK" )); - } - } - options2.SetValue(Idx, "%s", Settings.WipCodepath); - } - - firstRun = false; - } - } - /** If not godmode don't let him inside **/ - } - else WindowPrompt(tr( "Console Locked" ), tr( "Unlock console to use this option." ), tr( "OK" )); - optionBrowser2.SetEffect(EFFECT_FADE, -20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - titleTxt.SetText(tr( "Settings" )); - slidedirection = FADE; - pageToDisplay = 2; - MainButton1.ResetState(); - break; - } - - else if (MainButton2.GetState() == STATE_CLICKED) - { - MainButton1.SetEffect(EFFECT_FADE, -20); - MainButton2.SetEffect(EFFECT_FADE, -20); - MainButton3.SetEffect(EFFECT_FADE, -20); - MainButton4.SetEffect(EFFECT_FADE, -20); - while (MainButton2.GetEffect() > 0) - usleep(50); - w.Remove(&PageIndicatorBtn1); - w.Remove(&PageIndicatorBtn2); - w.Remove(&PageIndicatorBtn3); - w.Remove(&GoRightBtn); - w.Remove(&GoLeftBtn); - w.Remove(&MainButton1); - w.Remove(&MainButton2); - w.Remove(&MainButton3); - w.Remove(&MainButton4); - if (isInserted(Settings.BootDevice) && Settings.godmode) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - int ret = ProgressUpdateWindow(); - if (ret < 0) WindowPrompt(tr( "Update failed" ), 0, tr( "OK" )); - w.Append(&optionBrowser2); - w.Append(&backBtn); - } - else WindowPrompt(tr( "Console Locked" ), tr( "Unlock console to use this option." ), tr( "OK" )); - slidedirection = FADE; - pageToDisplay = 2; - MainButton2.ResetState(); - break; - } - - else if (MainButton3.GetState() == STATE_CLICKED) - { - MainButton1.SetEffect(EFFECT_FADE, -20); - MainButton2.SetEffect(EFFECT_FADE, -20); - MainButton3.SetEffect(EFFECT_FADE, -20); - MainButton4.SetEffect(EFFECT_FADE, -20); - while (MainButton3.GetEffect() > 0) - usleep(50); - w.Remove(&PageIndicatorBtn1); - w.Remove(&PageIndicatorBtn2); - w.Remove(&PageIndicatorBtn3); - w.Remove(&GoRightBtn); - w.Remove(&GoLeftBtn); - w.Remove(&MainButton1); - w.Remove(&MainButton2); - w.Remove(&MainButton3); - w.Remove(&MainButton4); - w.Remove(&backBtn); - w.Remove(&optionBrowser2); - if (Settings.godmode) - { - int choice = WindowPrompt(tr( "Are you sure?" ), 0, tr( "Yes" ), tr( "Cancel" )); - if (choice == 1) - { - gettextCleanUp(); - HaltGui(); - Settings.Reset(); - ResumeGui(); - menu = MENU_SETTINGS; - pageToDisplay = 0; - } - } - else WindowPrompt(tr( "Console Locked" ), tr( "Unlock console to use this option." ), tr( "OK" )); - w.Append(&backBtn); - w.Append(&optionBrowser2); - slidedirection = FADE; - pageToDisplay = 2; - MainButton3.ResetState(); - break; - } - - else if (MainButton4.GetState() == STATE_CLICKED) - { - MainButton1.SetEffect(EFFECT_FADE, -20); - MainButton2.SetEffect(EFFECT_FADE, -20); - MainButton3.SetEffect(EFFECT_FADE, -20); - MainButton4.SetEffect(EFFECT_FADE, -20); - while (MainButton4.GetEffect() > 0) - usleep(50); - w.Remove(&PageIndicatorBtn1); - w.Remove(&PageIndicatorBtn2); - w.Remove(&PageIndicatorBtn3); - w.Remove(&GoRightBtn); - w.Remove(&GoLeftBtn); - w.Remove(&MainButton1); - w.Remove(&MainButton2); - w.Remove(&MainButton3); - w.Remove(&MainButton4); - WindowCredits(); - slidedirection = FADE; - pageToDisplay = 2; - MainButton4.ResetState(); - break; - } - } - - else if (pageToDisplay == 3) - { - if (MainButton1.GetState() == STATE_CLICKED) - { - if (isInserted(Settings.BootDevice)) Settings.Save(); - menu = MENU_THEMEDOWNLOADER; - pageToDisplay = 0; - break; - } - } - - if (backBtn.GetState() == STATE_CLICKED) - { - //Add the procedure call to save the global configuration - if (isInserted(Settings.BootDevice)) Settings.Save(); - menu = MENU_DISCLIST; - pageToDisplay = 0; - backBtn.ResetState(); - break; - } - - else if (GoLeftBtn.GetState() == STATE_CLICKED) - { - pageToDisplay--; - /** Change direction of the flying buttons **/ - if (pageToDisplay < 1) pageToDisplay = 3; - slidedirection = LEFT; - GoLeftBtn.ResetState(); - break; - } - - else if (GoRightBtn.GetState() == STATE_CLICKED) - { - pageToDisplay++; - /** Change direction of the flying buttons **/ - if (pageToDisplay > 3) pageToDisplay = 1; - slidedirection = RIGHT; - GoRightBtn.ResetState(); - break; - } - else if (PageIndicatorBtn1.GetState() == STATE_CLICKED) - { - if (pageToDisplay > 1) - { - slidedirection = LEFT; - pageToDisplay = 1; - PageIndicatorBtn1.ResetState(); - break; - } - PageIndicatorBtn1.ResetState(); - } - else if (PageIndicatorBtn2.GetState() == STATE_CLICKED) - { - if (pageToDisplay < 2) - { - slidedirection = RIGHT; - pageToDisplay = 2; - PageIndicatorBtn2.ResetState(); - break; - } - else if (pageToDisplay > 2) - { - slidedirection = LEFT; - pageToDisplay = 2; - PageIndicatorBtn2.ResetState(); - break; - } - else PageIndicatorBtn2.ResetState(); - } - else if (PageIndicatorBtn3.GetState() == STATE_CLICKED) - { - if (pageToDisplay < 3) - { - slidedirection = RIGHT; - pageToDisplay = 3; - PageIndicatorBtn3.ResetState(); - break; - } - else PageIndicatorBtn3.ResetState(); - } - else if (homo.GetState() == STATE_CLICKED) - { - Settings.Save(); - optionBrowser2.SetState(STATE_DISABLED); - bgMusic->Pause(); - choice = WindowExitPrompt(); - bgMusic->Resume(); - - if (choice == 3) - Sys_LoadMenu(); // Back to System Menu - else if (choice == 2) - Sys_BackToLoader(); - else homo.ResetState(); - optionBrowser2.SetState(STATE_DEFAULT); - } - } - } - - w.SetEffect(EFFECT_FADE, -20); - while (w.GetEffect() > 0) - usleep(50); - - // if partition has changed, Reinitialize it - if (Settings.partition != settingspartitionold) - { - PartInfo pinfo = partitions.pinfo[Settings.partition]; - partitionEntry pentry = partitions.pentry[Settings.partition]; - WBFS_OpenPart(pinfo.part_fs, pinfo.index, pentry.sector, pentry.size, (char *) &game_partition); - load_from_fs = pinfo.part_fs; - } - - // if language has changed, reload titles - char opt_langnew[100]; - strcpy(opt_langnew, Settings.language_path); - int opt_overridenew = Settings.titlesOverride; - bool reloaddatabasefile = false; - if (strcmp(opt_lang, opt_langnew) || (opt_override != opt_overridenew && Settings.titlesOverride == 1) - || (Settings.partition != settingspartitionold)) - { - if (Settings.partition != settingspartitionold) - { - reloaddatabasefile = true; - CloseXMLDatabase(); - GameTitles.SetDefault(); - } - OpenXMLDatabase(Settings.titlestxt_path, Settings.db_language, Settings.db_JPtoEN, reloaddatabasefile, - Settings.titlesOverride == 1 ? true : false, true); // open file, reload titles, keep in memory - } - // disable titles from database if setting has changed - if (opt_override != opt_overridenew && Settings.titlesOverride == 0) GameTitles.SetDefault(); - - HaltGui(); - - mainWindow->RemoveAll(); - mainWindow->Append(bgImg); - - ResumeGui(); - return menu; + return returnMenu; } /******************************************************************************** @@ -2255,808 +27,16 @@ int MenuSettings() *********************************************************************************/ int MenuGameSettings(struct discHdr * header) { - int menu = MENU_NONE; - int ret; - int choice = 0; - bool exit = false; + GameSettingsMenu * Menu = new GameSettingsMenu(header); + mainWindow->Append(Menu); - int retVal = 0; + Menu->ShowMenu(); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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); - GuiSound btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); + int returnMenu = MENU_NONE; - GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); - GuiImageData settingsbg(Resources::GetFile("settings_background.png"), Resources::GetFileSize("settings_background.png")); + while((returnMenu = Menu->MainLoop()) == MENU_NONE); - GuiImageData MainButtonImgData(Resources::GetFile("settings_title.png"), Resources::GetFileSize("settings_title.png")); + delete Menu; - GuiImageData MainButtonImgOverData(Resources::GetFile("settings_title_over.png"), Resources::GetFileSize("settings_title_over.png")); - - GuiTrigger trigA; - trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); - GuiTrigger trigHome; - trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0); - GuiTrigger trigB; - trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); - - char gameName[31]; - if (!mountMethod) - { - if (strlen(GameTitles.GetTitle(header)) < (27 + 3)) - sprintf(gameName, "%s", GameTitles.GetTitle(header)); - else - { - strncpy(gameName, GameTitles.GetTitle(header), 27); - gameName[27] = '\0'; - strncat(gameName, "...", 3); - } - } - else sprintf(gameName, "%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2], header->id[3], header->id[4], - header->id[5]); - - GuiText titleTxt(!mountMethod ? GameTitles.GetTitle(header) : gameName, 28, ( GXColor ) - { 0, 0, 0, 255}); - titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - titleTxt.SetPosition(12, 40); - titleTxt.SetMaxWidth(356, SCROLL_HORIZONTAL); - - GuiImage settingsbackground(&settingsbg); - - GuiText backBtnTxt(tr( "Back" ), 22, Theme.prompttext); - backBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30); - GuiImage backBtnImg(&btnOutline); - if (Settings.wsprompt == ON) - { - backBtnTxt.SetWidescreen(Settings.widescreen); - backBtnImg.SetWidescreen(Settings.widescreen); - } - GuiButton backBtn(&backBtnImg, &backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2, 1); - backBtn.SetLabel(&backBtnTxt); - backBtn.SetTrigger(&trigB); - - GuiButton homo(1, 1); - homo.SetTrigger(&trigHome); - - GuiText saveBtnTxt(tr( "Save" ), 22, Theme.prompttext); - saveBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30); - GuiImage saveBtnImg(&btnOutline); - if (Settings.wsprompt == ON) - { - saveBtnTxt.SetWidescreen(Settings.widescreen); - saveBtnImg.SetWidescreen(Settings.widescreen); - } - GuiButton saveBtn(&saveBtnImg, &saveBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2, 1); - saveBtn.SetLabel(&saveBtnTxt); - - char MainButtonText[50]; - snprintf(MainButtonText, sizeof(MainButtonText), "%s", " "); - - GuiImage MainButton1Img(&MainButtonImgData); - GuiImage MainButton1ImgOver(&MainButtonImgOverData); - GuiText MainButton1Txt(MainButtonText, 22, ( GXColor ) - { 0, 0, 0, 255}); - MainButton1Txt.SetMaxWidth(MainButton1Img.GetWidth()); - GuiButton MainButton1(MainButton1Img.GetWidth(), MainButton1Img.GetHeight()); - MainButton1.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - MainButton1.SetPosition(0, 90); - MainButton1.SetImage(&MainButton1Img); - MainButton1.SetImageOver(&MainButton1ImgOver); - MainButton1.SetLabel(&MainButton1Txt); - MainButton1.SetSoundOver(&btnSoundOver); - MainButton1.SetSoundClick(&btnClick1); - MainButton1.SetEffectGrow(); - MainButton1.SetTrigger(&trigA); - - GuiImage MainButton2Img(&MainButtonImgData); - GuiImage MainButton2ImgOver(&MainButtonImgOverData); - GuiText MainButton2Txt(MainButtonText, 22, ( GXColor ) - { 0, 0, 0, 255}); - MainButton2Txt.SetMaxWidth(MainButton2Img.GetWidth()); - GuiButton MainButton2(MainButton2Img.GetWidth(), MainButton2Img.GetHeight()); - MainButton2.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - MainButton2.SetPosition(0, 160); - MainButton2.SetImage(&MainButton2Img); - MainButton2.SetImageOver(&MainButton2ImgOver); - MainButton2.SetLabel(&MainButton2Txt); - MainButton2.SetSoundOver(&btnSoundOver); - MainButton2.SetSoundClick(&btnClick1); - MainButton2.SetEffectGrow(); - MainButton2.SetTrigger(&trigA); - - GuiImage MainButton3Img(&MainButtonImgData); - GuiImage MainButton3ImgOver(&MainButtonImgOverData); - GuiText MainButton3Txt(MainButtonText, 22, ( GXColor ) - { 0, 0, 0, 255}); - MainButton3Txt.SetMaxWidth(MainButton3Img.GetWidth()); - GuiButton MainButton3(MainButton3Img.GetWidth(), MainButton3Img.GetHeight()); - MainButton3.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - MainButton3.SetPosition(0, 230); - MainButton3.SetImage(&MainButton3Img); - MainButton3.SetImageOver(&MainButton3ImgOver); - MainButton3.SetLabel(&MainButton3Txt); - MainButton3.SetSoundOver(&btnSoundOver); - MainButton3.SetSoundClick(&btnClick1); - MainButton3.SetEffectGrow(); - MainButton3.SetTrigger(&trigA); - - GuiImage MainButton4Img(&MainButtonImgData); - GuiImage MainButton4ImgOver(&MainButtonImgOverData); - GuiText MainButton4Txt(MainButtonText, 22, ( GXColor ) {0, 0, 0, 255}); - MainButton4Txt.SetMaxWidth(MainButton4Img.GetWidth()); - GuiButton MainButton4(MainButton4Img.GetWidth(), MainButton4Img.GetHeight()); - MainButton4.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - MainButton4.SetPosition(0, 300); - MainButton4.SetImage(&MainButton4Img); - MainButton4.SetImageOver(&MainButton4ImgOver); - MainButton4.SetLabel(&MainButton4Txt); - MainButton4.SetSoundOver(&btnSoundOver); - MainButton4.SetSoundClick(&btnClick1); - MainButton4.SetEffectGrow(); - MainButton4.SetTrigger(&trigA); - - OptionList options2; - GuiCustomOptionBrowser optionBrowser2(396, 280, &options2, "bg_options_settings.png", 0, 150); - optionBrowser2.SetPosition(0, 90); - optionBrowser2.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - - GuiWindow w(screenwidth, screenheight); - - GameCFG game_cfg; - - GameCFG* existCFG = GameSettings.GetGameCFG(header->id); - - if (existCFG) - { - memcpy(&game_cfg, existCFG, sizeof(GameCFG)); - } - else - { - snprintf(game_cfg.id, sizeof(game_cfg.id), "%s", (char *) header->id); - game_cfg.video = Settings.videomode; - game_cfg.language = Settings.language; - game_cfg.ocarina = Settings.ocarina; - game_cfg.vipatch = Settings.videopatch; - game_cfg.ios = Settings.cios; - game_cfg.parentalcontrol = 0; - game_cfg.errorfix002 = Settings.error002; - game_cfg.patchcountrystrings = Settings.patchcountrystrings; - game_cfg.loadalternatedol = OFF; - game_cfg.alternatedolstart = 0; - game_cfg.iosreloadblock = OFF; - strcpy(game_cfg.alternatedolname, ""); - game_cfg.returnTo = 1; - game_cfg.Locked = 0; - } - - int pageToDisplay = 1; - while (pageToDisplay > 0) - { - usleep(100); - - menu = MENU_NONE; - - /** Standard procedure made in all pages **/ - MainButton1.StopEffect(); - MainButton2.StopEffect(); - MainButton3.StopEffect(); - MainButton4.StopEffect(); - - HaltGui(); - - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Game Load" )); - MainButton1Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "Ocarina"); - MainButton2Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Uninstall Menu" )); - MainButton3Txt.SetText(MainButtonText); - snprintf(MainButtonText, sizeof(MainButtonText), "%s", tr( "Default Gamesettings" )); - MainButton4Txt.SetText(MainButtonText); - - mainWindow->RemoveAll(); - mainWindow->Append(&w); - w.RemoveAll(); - w.Append(&settingsbackground); - w.Append(&titleTxt); - w.Append(&backBtn); - w.Append(&homo); - w.Append(&MainButton1); - w.Append(&MainButton2); - w.Append(&MainButton3); - w.Append(&MainButton4); - - /** Disable ability to click through MainButtons */ - optionBrowser2.SetClickable(false); - /** Default no scrollbar and reset position **/ - // optionBrowser2.SetScrollbar(0); - optionBrowser2.SetOffset(0); - - MainButton1.StopEffect(); - MainButton2.StopEffect(); - MainButton3.StopEffect(); - MainButton4.StopEffect(); - - MainButton1.SetEffectGrow(); - MainButton2.SetEffectGrow(); - MainButton3.SetEffectGrow(); - MainButton4.SetEffectGrow(); - - MainButton1.SetEffect(EFFECT_FADE, 20); - MainButton2.SetEffect(EFFECT_FADE, 20); - MainButton3.SetEffect(EFFECT_FADE, 20); - MainButton4.SetEffect(EFFECT_FADE, 20); - - mainWindow->Append(&w); - - ResumeGui(); - - while (MainButton1.GetEffect() > 0) - usleep(50); - - while (menu == MENU_NONE) - { - usleep(100); - - if (shutdown == 1) Sys_Shutdown(); - if (reset == 1) Sys_Reboot(); - - if (MainButton1.GetState() == STATE_CLICKED) - { - w.Append(&saveBtn); - MainButton1.SetEffect(EFFECT_FADE, -20); - MainButton2.SetEffect(EFFECT_FADE, -20); - MainButton3.SetEffect(EFFECT_FADE, -20); - MainButton4.SetEffect(EFFECT_FADE, -20); - while (MainButton1.GetEffect() > 0) - usleep(50); - HaltGui(); - w.Remove(&MainButton1); - w.Remove(&MainButton2); - w.Remove(&MainButton3); - w.Remove(&MainButton4); - exit = false; - options2.ClearList(); - w.Append(&optionBrowser2); - optionBrowser2.SetClickable(true); - ResumeGui(); - - optionBrowser2.SetEffect(EFFECT_FADE, 20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - - int returnhere = 1; - char * languagefile; - languagefile = strrchr(Settings.language_path, '/') + 1; - - bool firstRun = true; - while (!exit) - { - usleep(100); - - returnhere = 1; - - if (shutdown == 1) Sys_Shutdown(); - if (reset == 1) Sys_Reboot(); - if (backBtn.GetState() == STATE_CLICKED) - { - backBtn.ResetState(); - exit = true; - break; - } - - else if (menu == MENU_DISCLIST) - { - w.Remove(&optionBrowser2); - w.Remove(&backBtn); - WindowCredits(); - w.Append(&optionBrowser2); - w.Append(&backBtn); - } - - else if (homo.GetState() == STATE_CLICKED) - { - Settings.Save(); - optionBrowser2.SetState(STATE_DISABLED); - bgMusic->Pause(); - choice = WindowExitPrompt(); - bgMusic->Resume(); - if (choice == 3) - Sys_LoadMenu(); // Back to System Menu - else if (choice == 2) - Sys_BackToLoader(); - else homo.ResetState(); - optionBrowser2.SetState(STATE_DEFAULT); - } - - else if (saveBtn.GetState() == STATE_CLICKED) - { - if (GameSettings.AddGame(game_cfg) && GameSettings.Save()) - { - WindowPrompt(tr( "Successfully Saved" ), 0, tr( "OK" )); - } - else - WindowPrompt(tr( "Save Failed. No device inserted?" ), 0, tr( "OK" )); - - saveBtn.ResetState(); - optionBrowser2.SetFocus(1); - } - - ret = optionBrowser2.GetClickedOption(); - - if (ret >= 0 || firstRun == true) - { - char alternatedname[100]; - int Idx = -1; - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Video Mode" )); - if (ret == Idx && ++game_cfg.video >= VIDEO_MODE_MAX) game_cfg.video = 0; - options2.SetValue(Idx, "%s%s", opts_videomode[game_cfg.video][0], - tr( opts_videomode[game_cfg.video][1] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "VIDTV Patch" )); - if (ret == Idx && ++game_cfg.vipatch >= MAX_ON_OFF) game_cfg.vipatch = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[game_cfg.vipatch] )); - - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Game Language" )); - if (ret == Idx && ++game_cfg.language >= MAX_LANGUAGE) game_cfg.language = 0; - options2.SetValue(Idx, "%s", tr( opts_language[game_cfg.language] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "Ocarina"); - if (ret == Idx && ++game_cfg.ocarina >= MAX_ON_OFF) game_cfg.ocarina = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[game_cfg.ocarina] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "IOS"); - if (ret == Idx) - { - char entered[4]; - snprintf(entered, sizeof(entered), "%i", game_cfg.ios); - if(OnScreenKeyboard(entered, sizeof(entered), 0)) - { - game_cfg.ios = atoi(entered); - if(game_cfg.ios < 200) game_cfg.ios = 200; - else if(game_cfg.ios > 255) game_cfg.ios = 255; - - if(NandTitles.IndexOf(TITLE_ID(1, game_cfg.ios)) < 0) - { - WindowPrompt(tr("Warning:"), tr("This IOS was not found on the titles list. If you are sure you have it installed than ignore this warning."), tr("OK")); - } - else if(game_cfg.ios == 254) - { - WindowPrompt(tr("Warning:"), tr("This IOS is the BootMii ios. If you are sure it is not BootMii and you have something else installed there than ignore this warning."), tr("OK")); - } - } - } - options2.SetValue(Idx, "IOS %i", game_cfg.ios); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Parental Control" )); - if (ret == Idx && ++game_cfg.parentalcontrol >= 5) game_cfg.parentalcontrol = 0; - options2.SetValue(Idx, "%s", tr( opts_parentalcontrol[game_cfg.parentalcontrol] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Error 002 fix" )); - if (ret == Idx && ++game_cfg.errorfix002 >= 3) game_cfg.errorfix002 = 0; - options2.SetValue(Idx, "%s", tr( opts_error002[game_cfg.errorfix002] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Return To" )); - if (ret == Idx && ++game_cfg.returnTo >= MAX_ON_OFF) game_cfg.returnTo = 0; - - char text[IMET_MAX_NAME_LEN]; - int channel = NandTitles.FindU32(Settings.returnTo);//is the channel set in the global settings actually installed? - - if (!game_cfg.returnTo || channel < 0)//channel is not installed or the uer wants to not use it - sprintf(text, "%s", tr( opts_off_on[ 0 ] )); - - else snprintf(text, sizeof(text), "%s", NandTitles.NameFromIndex(channel)); - - options2.SetValue(Idx, "%s", text); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Patch Country Strings" )); - if (ret == Idx && ++game_cfg.patchcountrystrings >= MAX_ON_OFF) game_cfg.patchcountrystrings = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[game_cfg.patchcountrystrings] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Alternate DOL" )); - int last_alternatedol = game_cfg.loadalternatedol; - if (ret == Idx && (game_cfg.loadalternatedol = (game_cfg.loadalternatedol + 2) % 3) >= 3) // 0->2->1->0 - game_cfg.loadalternatedol = 0; - static const char *opts[] = { trNOOP( "Default" ), trNOOP( "Load From SD/USB" ), - trNOOP( "Select a DOL" ) }; - options2.SetValue(Idx, "%s", tr( opts[game_cfg.loadalternatedol] )); - if (last_alternatedol != 1) - { - firstRun = true; // force re-init follow Entries - options2.Resize(Idx + 1); - } - } - - if (game_cfg.loadalternatedol == 2 && (ret == ++Idx || firstRun)) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Selected DOL" )); - if (ret == Idx) - { - if (game_cfg.loadalternatedol == 2) - { - char filename[10]; - snprintf(filename, 7, "%s", (char *) header->id); - int dolchoice = 0; - //alt dol menu for games that require more than a single alt dol - int autodol = autoSelectDolMenu(filename, false); - - if (autodol > 0) - { - game_cfg.alternatedolstart = autodol; - snprintf(alternatedname, sizeof(alternatedname), "%s <%i>", tr( "AUTO" ), - autodol); - } - else if (autodol == 0) - game_cfg.loadalternatedol = 0; // default was chosen - else - { - //check to see if we already know the offset of the correct dol - int autodol = autoSelectDol(filename, false); - //if we do know that offset ask if they want to use it - if (autodol > 0) - { - dolchoice - = WindowPrompt( - 0, - tr( "Do you want to use the alternate DOL that is known to be correct?" ), - tr( "Yes" ), tr( "Pick from a list" ), tr( "Cancel" )); - if (dolchoice == 0) - game_cfg.loadalternatedol = 0; - else if (dolchoice == 1) - { - game_cfg.alternatedolstart = autodol; - snprintf(alternatedname, sizeof(alternatedname), "%s <%i>", - tr( "AUTO" ), autodol); - } - else if (dolchoice == 2) //they want to search for the correct dol themselves - { - int res = DiscBrowse(header, alternatedname, sizeof(alternatedname)); - if ((res >= 0) && (res != 696969)) //if res==696969 they pressed the back button - game_cfg.alternatedolstart = res; - } - } - else - { - int res = DiscBrowse(header, alternatedname, sizeof(alternatedname)); - if ((res >= 0) && (res != 696969)) - { - game_cfg.alternatedolstart = res; - char tmp[170]; - snprintf( - tmp, - sizeof(tmp), - "%s %s - %i", - tr( "It seems that you have some information that will be helpful to us. Please pass this information along to the DEV team." ), - filename, game_cfg.alternatedolstart); - WindowPrompt(0, tmp, tr( "OK" )); - } - } - } - } - } - if (game_cfg.loadalternatedol == 0) - { - firstRun = true; // force re-init follow Entries - options2.Resize(Idx--); // remove this Entry - options2.SetValue(Idx, "%s", tr( "Default" )); // re-set prev Entry - } - else options2.SetValue(Idx, alternatedname); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Block IOS Reload" )); - if (ret == Idx && ++game_cfg.iosreloadblock >= MAX_ON_OFF) game_cfg.iosreloadblock = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[game_cfg.iosreloadblock] )); - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Game Locked" )); - if (ret == Idx && ++game_cfg.Locked >= MAX_ON_OFF) game_cfg.Locked = 0; - options2.SetValue(Idx, "%s", tr( opts_off_on[game_cfg.Locked] )); - } - - firstRun = false; - } - } - - optionBrowser2.SetEffect(EFFECT_FADE, -20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - MainButton1.ResetState(); - break; - w.Remove(&saveBtn); - } - - else if (MainButton2.GetState() == STATE_CLICKED) - { - char ID[7]; - snprintf(ID, sizeof(ID), "%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2], header->id[3], - header->id[4], header->id[5]); - CheatMenu(ID); - MainButton2.ResetState(); - break; - } - - else if (MainButton3.GetState() == STATE_CLICKED) - { - MainButton1.SetEffect(EFFECT_FADE, -20); - MainButton2.SetEffect(EFFECT_FADE, -20); - MainButton3.SetEffect(EFFECT_FADE, -20); - MainButton4.SetEffect(EFFECT_FADE, -20); - while (MainButton3.GetEffect() > 0) - usleep(50); - HaltGui(); - w.Remove(&MainButton1); - w.Remove(&MainButton2); - w.Remove(&MainButton3); - w.Remove(&MainButton4); - exit = false; - options2.ClearList(); - w.Append(&optionBrowser2); - optionBrowser2.SetClickable(true); - ResumeGui(); - - bool firstRun = true; - - optionBrowser2.SetEffect(EFFECT_FADE, 20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - - while (!exit) - { - usleep(100); - - if (shutdown == 1) Sys_Shutdown(); - if (reset == 1) Sys_Reboot(); - if (backBtn.GetState() == STATE_CLICKED) - { - backBtn.ResetState(); - exit = true; - break; - } - - else if (homo.GetState() == STATE_CLICKED) - { - Settings.Save(); - optionBrowser2.SetState(STATE_DISABLED); - bgMusic->Pause(); - choice = WindowExitPrompt(); - bgMusic->Resume(); - if (choice == 3) - Sys_LoadMenu(); // Back to System Menu - else if (choice == 2) - Sys_BackToLoader(); - else homo.ResetState(); - optionBrowser2.SetState(STATE_DEFAULT); - } - - ret = optionBrowser2.GetClickedOption(); - - if (firstRun || ret >= 0) - { - int Idx = -1; - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Uninstall Game" )); - if (ret == Idx) - { - int choice1 = WindowPrompt(tr( "Do you really want to delete:" ), gameName, - tr( "Yes" ), tr( "Cancel" )); - if (choice1 == 1 && !mountMethod) - { - GameSettings.Remove(header->id); - GameSettings.Save(); - GameStatistics.Remove(header->id); - GameStatistics.Save(); - ret = WBFS_RemoveGame(header->id); - if (ret < 0) - { - WindowPrompt(tr( "Can't delete:" ), gameName, tr( "OK" )); - } - else - { - WindowPrompt(tr( "Successfully deleted:" ), gameName, tr( "OK" )); - retVal = 1; - } - } - else if (choice1 == 0) optionBrowser2.SetFocus(1); - } - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Reset Playcounter" )); - if (ret == Idx) - { - int result = WindowPrompt(tr( "Are you sure?" ), 0, tr( "Yes" ), tr( "Cancel" )); - if (result == 1) - { - if (isInserted(Settings.BootDevice)) - { - GameStatistics.SetPlayCount(header->id, 0); - GameStatistics.Save(); - } - } - } - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Delete Cover Artwork" )); - if (ret == Idx) - { - char tmp[200]; - snprintf(tmp, sizeof(tmp), "%s%c%c%c%c%c%c.png", Settings.covers_path, header->id[0], - header->id[1], header->id[2], header->id[3], header->id[4], header->id[5]); - - int choice1 = WindowPrompt(tr( "Delete" ), tmp, tr( "Yes" ), tr( "No" )); - if (choice1 == 1) - { - if (CheckFile(tmp)) remove(tmp); - } - } - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Delete Disc Artwork" )); - if (ret == Idx) - { - char tmp[200]; - snprintf(tmp, sizeof(tmp), "%s%c%c%c%c%c%c.png", Settings.disc_path, header->id[0], - header->id[1], header->id[2], header->id[3], header->id[4], header->id[5]); - - int choice1 = WindowPrompt(tr( "Delete" ), tmp, tr( "Yes" ), tr( "No" )); - if (choice1 == 1) - { - if (CheckFile(tmp)) remove(tmp); - } - } - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Delete Cheat TXT" )); - if (ret == Idx) - { - char tmp[200]; - snprintf(tmp, sizeof(tmp), "%s%c%c%c%c%c%c.txt", Settings.TxtCheatcodespath, - header->id[0], header->id[1], header->id[2], header->id[3], header->id[4], - header->id[5]); - - int choice1 = WindowPrompt(tr( "Delete" ), tmp, tr( "Yes" ), tr( "No" )); - if (choice1 == 1) - { - if (CheckFile(tmp)) remove(tmp); - } - } - } - - if (ret == ++Idx || firstRun) - { - if (firstRun) options2.SetName(Idx, "%s", tr( "Delete Cheat GCT" )); - if (ret == Idx) - { - char tmp[200]; - snprintf(tmp, sizeof(tmp), "%s%c%c%c%c%c%c.gct", Settings.Cheatcodespath, - header->id[0], header->id[1], header->id[2], header->id[3], header->id[4], - header->id[5]); - - int choice1 = WindowPrompt(tr( "Delete" ), tmp, tr( "Yes" ), tr( "No" )); - if (choice1 == 1) - { - if (CheckFile(tmp)) remove(tmp); - } - } - } - - firstRun = false; - } - } - optionBrowser2.SetEffect(EFFECT_FADE, -20); - while (optionBrowser2.GetEffect() > 0) - usleep(50); - pageToDisplay = 1; - MainButton3.ResetState(); - break; - } - - else if (MainButton4.GetState() == STATE_CLICKED) - { - int choice1 = WindowPrompt(tr( "Are you sure?" ), 0, tr( "Yes" ), tr( "Cancel" )); - if (choice1 == 1) - { - game_cfg.video = Settings.videomode; - game_cfg.vipatch = Settings.videopatch; - game_cfg.language = Settings.language; - game_cfg.ocarina = Settings.ocarina; - game_cfg.errorfix002 = Settings.error002; - game_cfg.patchcountrystrings = Settings.patchcountrystrings; - game_cfg.loadalternatedol = OFF; - game_cfg.alternatedolstart = 0; - game_cfg.iosreloadblock = OFF; - game_cfg.ios = Settings.cios; - game_cfg.parentalcontrol = 0; - strcpy(game_cfg.alternatedolname, ""); - game_cfg.returnTo = 1; - game_cfg.Locked = 0; - GameSettings.Remove(header->id); - GameSettings.Save(); - } - - pageToDisplay = 1; - MainButton4.ResetState(); - break; - } - - else if (backBtn.GetState() == STATE_CLICKED) - { - menu = MENU_DISCLIST; - pageToDisplay = 0; - backBtn.ResetState(); - break; - } - - else if (homo.GetState() == STATE_CLICKED) - { - Settings.Save(); - optionBrowser2.SetState(STATE_DISABLED); - bgMusic->Pause(); - choice = WindowExitPrompt(); - bgMusic->Resume(); - - if (choice == 3) - Sys_LoadMenu(); // Back to System Menu - else if (choice == 2) - Sys_BackToLoader(); - else homo.ResetState(); - optionBrowser2.SetState(STATE_DEFAULT); - } - } - } - w.SetEffect(EFFECT_FADE, -20); - while (w.GetEffect() > 0) - usleep(50); - - HaltGui(); - - mainWindow->RemoveAll(); - mainWindow->Append(bgImg); - - ResumeGui(); - return retVal; + return returnMenu; } diff --git a/source/settings/SettingsPrompts.cpp b/source/settings/SettingsPrompts.cpp index 0fba7b2d..43874f90 100644 --- a/source/settings/SettingsPrompts.cpp +++ b/source/settings/SettingsPrompts.cpp @@ -23,10 +23,6 @@ extern u8 shutdown; extern u8 reset; -/*** Extern functions ***/ -extern void ResumeGui(); -extern void HaltGui(); - /**************************************************************************** * MenuOGG @@ -95,11 +91,6 @@ int MenuLanguageSelect() int scrollon; int returnhere = 0; - GuiSound btnSoundOver( button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData settingsbg(Resources::GetFile("settings_background.png"), Resources::GetFileSize("settings_background.png")); @@ -127,8 +118,8 @@ int MenuLanguageSelect() pathBtn.SetAlignment( ALIGN_CENTRE, ALIGN_TOP ); pathBtn.SetPosition( 0, 28 ); pathBtn.SetLabel( &titleTxt ); - pathBtn.SetSoundOver( &btnSoundOver ); - pathBtn.SetSoundClick( btnClick2 ); + pathBtn.SetSoundOver( btnSoundOver ); + pathBtn.SetSoundClick( btnSoundClick2 ); pathBtn.SetTrigger( &trigA ); pathBtn.SetEffectGrow(); @@ -149,8 +140,8 @@ int MenuLanguageSelect() backBtn.SetPosition( -190, 400 ); backBtn.SetLabel( &backBtnTxt ); backBtn.SetImage( &backBtnImg ); - backBtn.SetSoundOver( &btnSoundOver ); - backBtn.SetSoundClick( btnClick2 ); + backBtn.SetSoundOver( btnSoundOver ); + backBtn.SetSoundClick( btnSoundClick2 ); backBtn.SetTrigger( &trigA ); backBtn.SetTrigger( &trigB ); backBtn.SetEffectGrow(); @@ -168,8 +159,8 @@ int MenuLanguageSelect() defaultBtn.SetPosition( 190, 400 ); defaultBtn.SetLabel( &defaultBtnTxt ); defaultBtn.SetImage( &defaultBtnImg ); - defaultBtn.SetSoundOver( &btnSoundOver ); - defaultBtn.SetSoundClick( btnClick2 ); + defaultBtn.SetSoundOver( btnSoundOver ); + defaultBtn.SetSoundClick( btnSoundClick2 ); defaultBtn.SetTrigger( &trigA ); defaultBtn.SetEffectGrow(); @@ -186,8 +177,8 @@ int MenuLanguageSelect() updateBtn.SetPosition( 0, 400 ); updateBtn.SetLabel( &updateBtnTxt ); updateBtn.SetImage( &updateBtnImg ); - updateBtn.SetSoundOver( &btnSoundOver ); - updateBtn.SetSoundClick( btnClick2 ); + updateBtn.SetSoundOver( btnSoundOver ); + updateBtn.SetSoundClick( btnSoundClick2 ); updateBtn.SetTrigger( &trigA ); updateBtn.SetEffectGrow(); diff --git a/source/settings/menus/CustomPathsSM.cpp b/source/settings/menus/CustomPathsSM.cpp new file mode 100644 index 00000000..d9351244 --- /dev/null +++ b/source/settings/menus/CustomPathsSM.cpp @@ -0,0 +1,252 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 +#include "CustomPathsSM.hpp" +#include "settings/CSettings.h" +#include "prompts/PromptWindows.h" +#include "language/gettext.h" +#include "prompts/filebrowser.h" +#include "themes/CTheme.h" + +CustomPathsSM::CustomPathsSM() + : SettingsMenu(tr("Custom Paths"), &GuiOptions, MENU_NONE) +{ + int Idx = 0; + Options->SetName(Idx++, tr("3D Cover Path")); + Options->SetName(Idx++, tr("2D Cover Path")); + Options->SetName(Idx++, tr("Disc Artwork Path")); + Options->SetName(Idx++, tr("Theme Path")); + Options->SetName(Idx++, tr("WiiTDB Path")); + Options->SetName(Idx++, tr("Update Path")); + Options->SetName(Idx++, tr("GCT Cheatcodes Path")); + Options->SetName(Idx++, tr("TXT Cheatcodes Path")); + Options->SetName(Idx++, tr("DOL Path")); + Options->SetName(Idx++, tr("Homebrew Apps Path")); + Options->SetName(Idx++, tr("Theme Download Path")); + Options->SetName(Idx++, tr("BCA Codes Path")); + Options->SetName(Idx++, tr("WIP Patches Path")); + + SetOptionValues(); +} + +void CustomPathsSM::SetOptionValues() +{ + int Idx = 0; + + //! Settings: 3D Cover Path + Options->SetValue(Idx++, Settings.covers_path); + + //! Settings: 2D Cover Path + Options->SetValue(Idx++, Settings.covers2d_path); + + //! Settings: Disc Artwork Path + Options->SetValue(Idx++, Settings.disc_path); + + //! Settings: Theme Path + Options->SetValue(Idx++, Settings.theme_path); + + //! Settings: WiiTDB Path + Options->SetValue(Idx++, Settings.titlestxt_path); + + //! Settings: Update Path + Options->SetValue(Idx++, Settings.update_path); + + //! Settings: GCT Cheatcodes Path + Options->SetValue(Idx++, Settings.Cheatcodespath); + + //! Settings: TXT Cheatcodes Path + Options->SetValue(Idx++, Settings.TxtCheatcodespath); + + //! Settings: DOL Path + Options->SetValue(Idx++, Settings.dolpath); + + //! Settings: Homebrew Apps Path + Options->SetValue(Idx++, Settings.homebrewapps_path); + + //! Settings: Theme Download Path + Options->SetValue(Idx++, Settings.theme_downloadpath); + + //! Settings: BCA Codes Path + Options->SetValue(Idx++, Settings.BcaCodepath); + + //! Settings: WIP Patches Path + Options->SetValue(Idx++, Settings.WipCodepath); +} + +int CustomPathsSM::GetMenuInternal() +{ + int ret = optionBrowser->GetClickedOption(); + + if (ret < 0) + return MENU_NONE; + + int Idx = -1; + + //! Settings: 3D Cover Path + if (ret == ++Idx) + { + titleTxt->SetText(tr( "3D Cover Path" )); + ChangePath(Settings.covers_path, sizeof(Settings.covers_path)); + } + + //! Settings: 2D Cover Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "2D Cover Path" )); + ChangePath(Settings.covers2d_path, sizeof(Settings.covers2d_path)); + } + + //! Settings: Disc Artwork Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "Disc Artwork Path" )); + ChangePath(Settings.disc_path, sizeof(Settings.disc_path)); + } + + //! Settings: Theme Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "Theme Path" )); + int result = ChangePath(Settings.theme_path, sizeof(Settings.theme_path)); + if (result == 1) + { + HaltGui(); + mainWindow->Remove(bgImg); + Theme.Load(Settings.theme_path); + if(pointer[0]) delete pointer[0]; + if(pointer[1]) delete pointer[1]; + if(pointer[2]) delete pointer[2]; + if(pointer[3]) delete pointer[3]; + pointer[0] = Resources::GetImageData("player1_point.png"); + pointer[1] = Resources::GetImageData("player2_point.png"); + pointer[2] = Resources::GetImageData("player3_point.png"); + pointer[3] = Resources::GetImageData("player4_point.png"); + if(background) delete background; + background = Resources::GetImageData(Settings.widescreen ? "wbackground.png" : "background.png"); + if(bgImg) delete bgImg; + bgImg = new GuiImage(background); + mainWindow->Append(bgImg); + ResumeGui(); + return MENU_SETTINGS; + } + } + + //! Settings: WiiTDB Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "WiiTDB Path" )); + ChangePath(Settings.titlestxt_path, sizeof(Settings.titlestxt_path)); + } + + //! Settings: Update Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "Update Path" )); + ChangePath(Settings.update_path, sizeof(Settings.update_path)); + } + + //! Settings: GCT Cheatcodes Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "GCT Cheatcodes Path" )); + ChangePath(Settings.Cheatcodespath, sizeof(Settings.Cheatcodespath)); + } + + //! Settings: TXT Cheatcodes Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "TXT Cheatcodes Path" )); + ChangePath(Settings.TxtCheatcodespath, sizeof(Settings.TxtCheatcodespath)); + } + + //! Settings: DOL Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "DOL Path" )); + ChangePath(Settings.dolpath, sizeof(Settings.dolpath)); + } + + //! Settings: Homebrew Apps Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "Homebrew Apps Path" )); + ChangePath(Settings.homebrewapps_path, sizeof(Settings.homebrewapps_path)); + } + + //! Settings: Theme Download Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "Theme Download Path" )); + ChangePath(Settings.theme_downloadpath, sizeof(Settings.theme_downloadpath)); + } + + //! Settings: BCA Codes Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "BCA Codes Path" )); + ChangePath(Settings.BcaCodepath, sizeof(Settings.BcaCodepath)); + } + + //! Settings: WIP Patches Path + else if (ret == ++Idx) + { + titleTxt->SetText(tr( "WIP Patches Path" )); + ChangePath(Settings.WipCodepath, sizeof(Settings.WipCodepath)); + } + + //! Global set back of the titleTxt after a change + titleTxt->SetText(tr( "Custom Paths" )); + SetOptionValues(); + + return MENU_NONE; +} + +int CustomPathsSM::ChangePath(char * SettingsPath, int SizeOfPath) +{ + char entered[300]; + snprintf(entered, sizeof(entered), SettingsPath); + + HaltGui(); + GuiWindow * parent = (GuiWindow *) parentElement; + if(parent) parent->SetState(STATE_DISABLED); + this->SetState(STATE_DEFAULT); + this->Remove(optionBrowser); + ResumeGui(); + + int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES); + + if(parent) parent->SetState(STATE_DEFAULT); + this->Append(optionBrowser); + + if (result == 1) + { + if (entered[strlen(entered)-1] != '/') + strcat(entered, "/"); + + snprintf(SettingsPath, SizeOfPath, entered); + WindowPrompt(tr( "Path Changed" ), 0, tr( "OK" )); + } + + return result; +} diff --git a/source/settings/menus/CustomPathsSM.hpp b/source/settings/menus/CustomPathsSM.hpp new file mode 100644 index 00000000..344e7fb7 --- /dev/null +++ b/source/settings/menus/CustomPathsSM.hpp @@ -0,0 +1,43 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 CUSTOMPATHS_MENU_HPP_ +#define CUSTOMPATHS_MENU_HPP_ + +#include "SettingsMenu.hpp" + +class CustomPathsSM : public SettingsMenu +{ + public: + CustomPathsSM(); + virtual int GetType() { return CCustomPathsSM; }; + protected: + void SetOptionValues(); + int GetMenuInternal(); + int ChangePath(char * SettingsPath, int SizeOfPath); + + OptionList GuiOptions; +}; + + +#endif diff --git a/source/settings/menus/FlyingButtonsMenu.cpp b/source/settings/menus/FlyingButtonsMenu.cpp new file mode 100644 index 00000000..6db2031a --- /dev/null +++ b/source/settings/menus/FlyingButtonsMenu.cpp @@ -0,0 +1,462 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 +#include + +#include "FlyingButtonsMenu.hpp" +#include "utils/StringTools.h" +#include "language/gettext.h" +#include "themes/CTheme.h" +#include "menu/menus.h" +#include "sys.h" + +#define FADE_SPEED 20 +#define SLIDE_SPEED 35 +#define DISPLAY_BUTTONS 4 + +FlyingButtonsMenu::FlyingButtonsMenu(const char * menu_title) + : GuiWindow(screenwidth, screenheight) + +{ + currentPage = 0; + returnMenu = MENU_NONE; + CurrentMenu = NULL; + titleTxt = NULL; + GoLeftImg = NULL; + GoLeftBtn = NULL; + GoRightImg = NULL; + GoRightBtn = NULL; + MenuTitle = menu_title ? menu_title : " "; + + trigA = new GuiTrigger(); + trigHome = new GuiTrigger(); + trigB = new GuiTrigger(); + trigL = new GuiTrigger(); + trigR = new GuiTrigger(); + trigMinus = new GuiTrigger(); + trigPlus = new GuiTrigger(); + trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + trigHome->SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0); + trigB->SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); + trigL->SetButtonOnlyTrigger(-1, WPAD_BUTTON_LEFT | WPAD_CLASSIC_BUTTON_LEFT, PAD_BUTTON_LEFT); + trigR->SetButtonOnlyTrigger(-1, WPAD_BUTTON_RIGHT | WPAD_CLASSIC_BUTTON_RIGHT, PAD_BUTTON_RIGHT); + trigMinus->SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0); + trigPlus->SetButtonOnlyTrigger(-1, WPAD_BUTTON_PLUS | WPAD_CLASSIC_BUTTON_PLUS, 0); + + btnOutline = Resources::GetImageData("button_dialogue_box.png"); + settingsbg = Resources::GetImageData("settings_background.png"); + MainButtonImgData = Resources::GetImageData("settings_title.png"); + MainButtonImgOverData = Resources::GetImageData("settings_title_over.png"); + PageindicatorImgData = Resources::GetImageData("pageindicator.png"); + arrow_left = Resources::GetImageData("startgame_arrow_left.png"); + arrow_right = Resources::GetImageData("startgame_arrow_right.png"); + + settingsbackground = new GuiImage(settingsbg); + Append(settingsbackground); + + homeBtn = new GuiButton(1, 1); + homeBtn->SetTrigger(trigHome); + Append(homeBtn); + + backBtnTxt = new GuiText(tr( "Back" ), 22, Theme.prompttext); + backBtnTxt->SetMaxWidth(btnOutline->GetWidth() - 30); + backBtnImg = new GuiImage(btnOutline); + if (Settings.wsprompt == ON) + { + backBtnTxt->SetWidescreen(Settings.widescreen); + backBtnImg->SetWidescreen(Settings.widescreen); + } + backBtn = new GuiButton(backBtnImg, backBtnImg, 2, 3, -195, 400, trigA, btnSoundOver, btnSoundClick2, 1); + backBtn->SetLabel(backBtnTxt); + backBtn->SetTrigger(trigB); + Append(backBtn); + + SetEffect(EFFECT_FADE, FADE_SPEED); +} + +FlyingButtonsMenu::~FlyingButtonsMenu() +{ + ResumeGui(); + + SetEffect(EFFECT_FADE, -FADE_SPEED); + while(this->GetEffect() > 0) usleep(100); + + HaltGui(); + if(parentElement) + ((GuiWindow *) parentElement)->Remove(this); + + RemoveAll(); + HideMenu(); + + delete trigA; + delete trigHome; + delete trigB; + delete trigL; + delete trigR; + delete trigMinus; + delete trigPlus; + delete settingsbackground; + delete homeBtn; + delete btnOutline; + delete settingsbg; + delete MainButtonImgData; + delete MainButtonImgOverData; + delete PageindicatorImgData; + delete arrow_left; + delete arrow_right; + delete backBtnTxt; + delete backBtnImg; + delete backBtn; + + ResumeGui(); +} + +void FlyingButtonsMenu::SetPageIndicators() +{ + HaltGui(); + + for(u32 i = 0; i < PageIndicatorBtn.size(); ++i) + { + Remove(PageIndicatorBtn[i]); + delete PageindicatorImg[i]; + delete PageindicatorTxt[i]; + delete PageIndicatorBtn[i]; + } + PageindicatorImg.clear(); + PageindicatorTxt.clear(); + PageIndicatorBtn.clear(); + + int IndicatorCount = ceil(MainButton.size()/(1.0f*DISPLAY_BUTTONS)); + + for(int i = 0; i < IndicatorCount; ++i) + { + PageindicatorImg.push_back(new GuiImage(PageindicatorImgData)); + PageindicatorTxt.push_back(new GuiText(fmt("%i", i), 22, ( GXColor ) {0, 0, 0, 255})); + PageIndicatorBtn.push_back(new GuiButton(PageindicatorImgData->GetWidth(), PageindicatorImgData->GetHeight())); + PageIndicatorBtn[i]->SetAlignment(ALIGN_CENTRE, ALIGN_TOP); + PageIndicatorBtn[i]->SetPosition(270-IndicatorCount*35+35*i, 400); + PageIndicatorBtn[i]->SetImage(PageindicatorImg[i]); + PageIndicatorBtn[i]->SetLabel(PageindicatorTxt[i]); + PageIndicatorBtn[i]->SetSoundOver(btnSoundOver); + PageIndicatorBtn[i]->SetSoundClick(btnSoundClick); + PageIndicatorBtn[i]->SetTrigger(trigA); + PageIndicatorBtn[i]->SetEffectGrow(); + PageIndicatorBtn[i]->SetAlpha(i == currentPage ? 255 : 50); + Append(PageIndicatorBtn[i]); + } +} + +void FlyingButtonsMenu::SetMainButton(int position, const char * ButtonText, GuiImageData * imageData, GuiImageData * imageOver) +{ + //! Don't allow operating gui mode while adding/setting the buttons + HaltGui(); + + if(position < (int) MainButton.size()) + { + delete MainButtonImg[position]; + delete MainButtonImgOver[position]; + delete MainButtonTxt[position]; + delete MainButton[position]; + } + else + { + MainButtonImg.resize(position+1); + MainButtonImgOver.resize(position+1); + MainButtonTxt.resize(position+1); + MainButton.resize(position+1); + } + + MainButtonImg[position] = new GuiImage(imageData); + MainButtonImgOver[position] = new GuiImage(imageOver); + + MainButtonTxt[position] = new GuiText(ButtonText, 22, ( GXColor ) {0, 0, 0, 255}); + MainButtonTxt[position]->SetMaxWidth(MainButtonImg[position]->GetWidth()); + + MainButton[position] = new GuiButton(imageData->GetWidth(), imageData->GetHeight()); + MainButton[position]->SetAlignment(ALIGN_CENTRE, ALIGN_TOP); + MainButton[position]->SetPosition(0, 90+(position % DISPLAY_BUTTONS)*70); + MainButton[position]->SetImage(MainButtonImg[position]); + MainButton[position]->SetImageOver(MainButtonImgOver[position]); + MainButton[position]->SetLabel(MainButtonTxt[position]); + MainButton[position]->SetSoundOver(btnSoundOver); + MainButton[position]->SetSoundClick(btnSoundClick); + MainButton[position]->SetEffectGrow(); + MainButton[position]->SetTrigger(trigA); +} + +void FlyingButtonsMenu::HideMenu() +{ + HaltGui(); + + if(titleTxt) + Remove(titleTxt); + if(GoLeftBtn) + Remove(GoLeftBtn); + if(GoRightBtn) + Remove(GoRightBtn); + + if(titleTxt) + delete titleTxt; + if(GoLeftImg) + delete GoLeftImg; + if(GoLeftBtn) + delete GoLeftBtn; + if(GoRightImg) + delete GoRightImg; + if(GoRightBtn) + delete GoRightBtn; + titleTxt = NULL; + GoLeftImg = NULL; + GoLeftBtn = NULL; + GoRightImg = NULL; + GoRightBtn = NULL; + + for(u32 i = 0; i < MainButton.size(); ++i) + { + Remove(MainButton[i]); + delete MainButtonImg[i]; + delete MainButtonImgOver[i]; + delete MainButtonTxt[i]; + delete MainButton[i]; + } + for(u32 i = 0; i < PageIndicatorBtn.size(); ++i) + { + Remove(PageIndicatorBtn[i]); + delete PageindicatorImg[i]; + delete PageindicatorTxt[i]; + delete PageIndicatorBtn[i]; + } + + PageindicatorImg.clear(); + PageindicatorTxt.clear(); + PageIndicatorBtn.clear(); + MainButtonImg.clear(); + MainButtonImgOver.clear(); + MainButtonTxt.clear(); + MainButton.clear(); +} + +void FlyingButtonsMenu::ShowMenu() +{ + //! Free memory if not done yet because new is allocated + HideMenu(); + + titleTxt = new GuiText(MenuTitle.c_str(), 28, ( GXColor ) {0, 0, 0, 255}); + titleTxt->SetAlignment(ALIGN_CENTRE, ALIGN_TOP); + titleTxt->SetPosition(0, 40); + Append(titleTxt); + + GoLeftImg = new GuiImage(arrow_left); + GoLeftBtn = new GuiButton(GoLeftImg->GetWidth(), GoLeftImg->GetHeight()); + GoLeftBtn->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); + GoLeftBtn->SetPosition(25, -25); + GoLeftBtn->SetImage(GoLeftImg); + GoLeftBtn->SetSoundOver(btnSoundOver); + GoLeftBtn->SetSoundClick(btnSoundClick2); + GoLeftBtn->SetEffectGrow(); + GoLeftBtn->SetTrigger(trigA); + GoLeftBtn->SetTrigger(trigL); + GoLeftBtn->SetTrigger(trigMinus); + Append(GoLeftBtn); + + GoRightImg = new GuiImage(arrow_right); + GoRightBtn = new GuiButton(GoRightImg->GetWidth(), GoRightImg->GetHeight()); + GoRightBtn->SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE); + GoRightBtn->SetPosition(-25, -25); + GoRightBtn->SetImage(GoRightImg); + GoRightBtn->SetSoundOver(btnSoundOver); + GoRightBtn->SetSoundClick(btnSoundClick2); + GoRightBtn->SetEffectGrow(); + GoRightBtn->SetTrigger(trigA); + GoRightBtn->SetTrigger(trigR); + GoRightBtn->SetTrigger(trigPlus); + Append(GoRightBtn); + + SetupMainButtons(); + AddMainButtons(); + + ShowButtonsEffects(EFFECT_FADE, FADE_SPEED); +} + +void FlyingButtonsMenu::AddMainButtons() +{ + HaltGui(); + + for(u32 i = 0; i < MainButton.size(); ++i) + Remove(MainButton[i]); + + int FirstItem = currentPage*DISPLAY_BUTTONS; + + for(int i = FirstItem; i < (int) MainButton.size() && i < FirstItem+DISPLAY_BUTTONS; ++i) + { + Append(MainButton[i]); + } + + SetPageIndicators(); +} + +void FlyingButtonsMenu::ShowButtonsEffects(int effect, int effect_speed) +{ + int FirstItem = currentPage*DISPLAY_BUTTONS; + + if(FirstItem >= (int) MainButton.size()) + return; + + HaltGui(); + + for(int i = FirstItem; i < (int) MainButton.size() && i < FirstItem+DISPLAY_BUTTONS; ++i) + { + MainButton[i]->StopEffect(); + MainButton[i]->SetEffect(effect, effect_speed); + } + + ResumeGui(); + + //! Don't lock on fade in for initiation purpose + if(effect & EFFECT_FADE && effect_speed > 0) + return; + + while (MainButton[FirstItem]->GetEffect() > 0) + usleep(100); +} + +void FlyingButtonsMenu::SlideButtons(int direction) +{ + int SlideEffectIN = 0; + + if(direction == SLIDE_LEFT) + { + ShowButtonsEffects(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, SLIDE_SPEED); + SlideEffectIN = EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN; + + currentPage--; + + if(currentPage < 0) + currentPage = MainButton.size() > 0 ? ceil(MainButton.size()/4.0f)-1 : 0; + } + else + { + ShowButtonsEffects(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, SLIDE_SPEED); + SlideEffectIN = EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN; + + currentPage++; + + if(currentPage >= ceil(MainButton.size()/4.0f)) + currentPage = 0; + } + + AddMainButtons(); + + ShowButtonsEffects(SlideEffectIN, SLIDE_SPEED); +} + +int FlyingButtonsMenu::MainLoop() +{ + usleep(100); + + if(shutdown) + Sys_Shutdown(); + else if(reset) + Sys_Reboot(); + + if(backBtn->GetState() == STATE_CLICKED) + { + if(CurrentMenu) + { + DeleteSettingsMenu(); + ShowMenu(); + } + else + { + return MENU_DISCLIST; + } + backBtn->ResetState(); + } + else if(GoRightBtn && GoRightBtn->GetState() == STATE_CLICKED) + { + SlideButtons(SLIDE_RIGHT); + GoRightBtn->ResetState(); + } + else if(GoLeftBtn && GoLeftBtn->GetState() == STATE_CLICKED) + { + SlideButtons(SLIDE_LEFT); + GoLeftBtn->ResetState(); + } + else if(homeBtn->GetState() == STATE_CLICKED) + { + Settings.Save(); + if(CurrentMenu) CurrentMenu->SetState(STATE_DISABLED); + bgMusic->Pause(); + int choice = WindowExitPrompt(); + bgMusic->Resume(); + if (choice == 3) + Sys_LoadMenu(); // Back to System Menu + else if (choice == 2) + Sys_BackToLoader(); + homeBtn->ResetState(); + if(CurrentMenu) CurrentMenu->SetState(STATE_DEFAULT); + } + else if(CurrentMenu) + { + int newMenu = CurrentMenu->GetMenu(); + if(newMenu != MENU_NONE) + return newMenu; + } + + for(u32 i = 0; i < PageIndicatorBtn.size(); ++i) + { + if(PageIndicatorBtn[i]->GetState() != STATE_CLICKED) + continue; + + if(i < (u32) currentPage) + { + ShowButtonsEffects(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, SLIDE_SPEED); + currentPage = i; + AddMainButtons(); + ShowButtonsEffects(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, SLIDE_SPEED); + } + else if(i > (u32) currentPage) + { + ShowButtonsEffects(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, SLIDE_SPEED); + currentPage = i; + AddMainButtons(); + ShowButtonsEffects(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, SLIDE_SPEED); + } + + PageIndicatorBtn[i]->ResetState(); + } + + for(u32 i = 0; i < MainButton.size(); ++i) + { + if(MainButton[i]->GetState() != STATE_CLICKED) + continue; + + MainButton[i]->ResetState(); + + CreateSettingsMenu(i); + break; + } + + return returnMenu; +} diff --git a/source/settings/menus/FlyingButtonsMenu.hpp b/source/settings/menus/FlyingButtonsMenu.hpp new file mode 100644 index 00000000..e5d18783 --- /dev/null +++ b/source/settings/menus/FlyingButtonsMenu.hpp @@ -0,0 +1,103 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 FLYINGBUTTONSMENU_HPP_ +#define FLYINGBUTTONSMENU_HPP_ + +#include +#include +#include "libwiigui/gui.h" +#include "SettingsMenu.hpp" +#include "menu.h" + +class FlyingButtonsMenu : public GuiWindow +{ + public: + FlyingButtonsMenu(const char * menu_title); + ~FlyingButtonsMenu(); + int MainLoop(); + void HideMenu(); + void ShowMenu(); + protected: + virtual void CreateSettingsMenu(int index) { }; + virtual void DeleteSettingsMenu() { }; + virtual void SetupMainButtons() { }; + void AddMainButtons(); + void ShowButtonsEffects(int effect, int effect_speed); + void SlideButtons(int slide_direction); + void SetPageIndicators(); + void SetMainButton(int position, const char * ButtonText, GuiImageData * imageData, GuiImageData * imageOver); + + int currentPage; + int returnMenu; + std::string MenuTitle; + enum + { + SLIDE_LEFT, SLIDE_RIGHT + }; + + //!The main settings gui with browser + SettingsMenu * CurrentMenu; + + GuiImageData * btnOutline; + GuiImageData * settingsbg; + GuiImageData * MainButtonImgData; + GuiImageData * MainButtonImgOverData; + GuiImageData * PageindicatorImgData; + GuiImageData * arrow_left; + GuiImageData * arrow_right; + + GuiImage * settingsbackground; + GuiImage * backBtnImg; + GuiImage * PageindicatorImg2; + GuiImage * GoLeftImg; + GuiImage * GoRightImg; + + GuiTrigger * trigA; + GuiTrigger * trigHome; + GuiTrigger * trigB; + GuiTrigger * trigL; + GuiTrigger * trigR; + GuiTrigger * trigMinus; + GuiTrigger * trigPlus; + + GuiText * titleTxt; + GuiText * backBtnTxt; + GuiText * PageindicatorTxt1; + + GuiButton * backBtn; + GuiButton * homeBtn; + GuiButton * GoLeftBtn; + GuiButton * GoRightBtn; + + std::vectorPageindicatorImg; + std::vectorPageindicatorTxt; + std::vectorPageIndicatorBtn; + + std::vector MainButtonImg; + std::vector MainButtonImgOver; + std::vector MainButtonTxt; + std::vector MainButton; +}; + +#endif diff --git a/source/settings/menus/GUISettingsMenu.cpp b/source/settings/menus/GUISettingsMenu.cpp new file mode 100644 index 00000000..b56dd370 --- /dev/null +++ b/source/settings/menus/GUISettingsMenu.cpp @@ -0,0 +1,334 @@ + /**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 +#include "GuiSettingsMenu.hpp" +#include "settings/CSettings.h" +#include "prompts/PromptWindows.h" +#include "language/gettext.h" +#include "settings/SettingsPrompts.h" +#include "settings/GameTitles.h" +#include "xml/xml.h" +#include "fatmounter.h" + +static const char * OnOffText[MAX_ON_OFF] = +{ + trNOOP( "OFF" ), + trNOOP( "ON" ) +}; + +static const char * WiilightText[WIILIGHT_MAX] = +{ + trNOOP( "OFF" ), + trNOOP( "ON" ), + trNOOP( "Only for Install" ) +}; + +static const char * GameInfoText[GAMEINFO_MAX] = +{ + trNOOP( "Game ID" ), + trNOOP( "Game Region" ), + trNOOP( "Both" ), + trNOOP( "Neither" ) +}; + +static const char * FlipXText[XFLIP_MAX][3] = +{ + { trNOOP( "Right" ), "/", trNOOP( "Next" ) }, + { trNOOP( "Left" ), "/", trNOOP( "Prev" ) }, + { trNOOP( "Like SysMenu" ), "", "" }, + { trNOOP( "Right" ), "/", trNOOP( "Prev" ) }, + { trNOOP( "DiskFlip" ), "", "" } +}; + +static const char * PromptButtonsText[MAX_ON_OFF] = +{ + trNOOP( "Normal" ), + trNOOP( "Widescreen Fix" ), +}; + +static const char * KeyboardText[KEYBOARD_MAX] = +{ + "QWERTY", + "DVORAK", + "QWERTZ", + "AZERTY", + "QWERTY 2" +}; + +static const char * DiscArtDownloadText[4] = +{ + trNOOP( "Only Original" ), + trNOOP( "Only Customs" ), + trNOOP( "Original/Customs" ), + trNOOP( "Customs/Original" ) +}; + +static const char *ScreensaverText[SCREENSAVER_MAX] = +{ + trNOOP( "OFF" ), + trNOOP( "3 min" ), + trNOOP( "5 min" ), + trNOOP( "10 min" ), + trNOOP( "20 min" ), + trNOOP( "30 min" ), + trNOOP( "1 hour" ) +}; + +GuiSettingsMenu::GuiSettingsMenu() + : SettingsMenu(tr("GUI Settings"), &GuiOptions, MENU_NONE) +{ + int Idx = 0; + Options->SetName(Idx++, "%s", tr( "App Language" )); + Options->SetName(Idx++, "%s", tr( "Display" )); + Options->SetName(Idx++, "%s", tr( "Clock" )); + Options->SetName(Idx++, "%s", tr( "Tooltips" )); + Options->SetName(Idx++, "%s", tr( "Flip-X" )); + Options->SetName(Idx++, "%s", tr( "Prompts Buttons" )); + Options->SetName(Idx++, "%s", tr( "Keyboard" )); + Options->SetName(Idx++, "%s", tr( "Disc Artwork Download" )); + Options->SetName(Idx++, "%s", tr( "Wiilight" )); + Options->SetName(Idx++, "%s", tr( "Rumble" )); + Options->SetName(Idx++, "%s", tr( "AutoInit Network" )); + Options->SetName(Idx++, "%s", tr( "BETA revisions" )); + Options->SetName(Idx++, "%s", tr( "Titles from WiiTDB" )); + Options->SetName(Idx++, "%s", tr( "Screensaver" )); + Options->SetName(Idx++, "%s", tr( "Mark new games" )); + + SetOptionValues(); + + OldTitlesOverride = Settings.titlesOverride; +} + +GuiSettingsMenu::~GuiSettingsMenu() +{ + if (Settings.titlesOverride != OldTitlesOverride) + { + CloseXMLDatabase(); + GameTitles.SetDefault(); + if(Settings.titlesOverride) + OpenXMLDatabase(Settings.titlestxt_path, Settings.db_language, Settings.db_JPtoEN, true, Settings.titlesOverride, true); + } + +} + +void GuiSettingsMenu::SetOptionValues() +{ + int Idx = 0; + + //! Settings: App Language + const char * language = strrchr(Settings.language_path, '/'); + if(language) + language += 1; + if (!language || strcmp(Settings.language_path, "") == 0) + Options->SetValue(Idx++, "%s", tr( "Default" )); + else + Options->SetValue(Idx++, "%s", language); + + //! Settings: Display + Options->SetValue(Idx++, "%s", tr( GameInfoText[Settings.sinfo] )); + + //! Settings: Clock + if (Settings.hddinfo == CLOCK_HR12) + Options->SetValue(Idx++, "12 %s", tr( "Hour" )); + else if (Settings.hddinfo == CLOCK_HR24) + Options->SetValue(Idx++, "24 %s", tr( "Hour" )); + else if (Settings.hddinfo == OFF) + Options->SetValue(Idx++, "%s", tr( "OFF" )); + + //! Settings: Tooltips + Options->SetValue(Idx++, "%s", tr(OnOffText[Settings.tooltips])); + + //! Settings: Flip-X + Options->SetValue(Idx++, "%s%s%s", tr(FlipXText[Settings.xflip][0]), + FlipXText[Settings.xflip][1], tr( FlipXText[Settings.xflip][2] )); + + //! Settings: Prompts Buttons + Options->SetValue(Idx++, "%s", tr( PromptButtonsText[Settings.wsprompt] )); + + //! Settings: Keyboard + Options->SetValue(Idx++, "%s", KeyboardText[Settings.keyset]); + + //! Settings: Disc Artwork Download + Options->SetValue(Idx++, "%s", tr( DiscArtDownloadText[Settings.discart] )); + + //! Settings: Wiilight + Options->SetValue(Idx++, "%s", tr( WiilightText[Settings.wiilight] )); + + //! Settings: Rumble + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.rumble] )); + + //! Settings: AutoInit Network + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.autonetwork] )); + + //! Settings: BETA revisions + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.beta_upgrades] )); + + //! Settings: Titles from WiiTDB + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.titlesOverride] )); + + //! Settings: Screensaver + Options->SetValue(Idx++, "%s", tr( ScreensaverText[Settings.screensaver] )); + + //! Settings: Mark new games + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.marknewtitles] )); +} + +int GuiSettingsMenu::GetMenuInternal() +{ + int ret = optionBrowser->GetClickedOption(); + + if (ret < 0) + return MENU_NONE; + + int Idx = -1; + + //! Settings: App Language + if (ret == ++Idx) + { + if (!isInserted(Settings.BootDevice)) + { + WindowPrompt(tr( "No SD-Card inserted!" ), tr( "Insert an SD-Card to use this option." ), tr( "OK" )); + return MENU_NONE; + } + if (!Settings.godmode) + { + WindowPrompt(tr( "Language change:" ), tr( "Console should be unlocked to modify it." ), tr( "OK" )); + return MENU_NONE; + } + SetEffect(EFFECT_FADE, -20); + while (GetEffect() > 0) usleep(100); + HaltGui(); + if(parentElement) + { + ((GuiWindow *) parentElement)->Remove(this); + ((GuiWindow *) parentElement)->SetState(STATE_DISABLED); + } + ResumeGui(); + + int returnhere = 1; + while (returnhere == 1) + returnhere = MenuLanguageSelect(); + + if (returnhere == 2) + return MENU_SETTINGS; + + HaltGui(); + if(parentElement) + { + ((GuiWindow *) parentElement)->Append(this); + ((GuiWindow *) parentElement)->SetState(STATE_DEFAULT); + } + SetEffect(EFFECT_FADE, 20); + ResumeGui(); + while (GetEffect() > 0) usleep(100); + } + + //! Settings: Display + else if (ret == ++Idx) + { + if (++Settings.sinfo >= GAMEINFO_MAX) Settings.sinfo = 0; + } + + //! Settings: Clock + else if (ret == ++Idx) + { + if (++Settings.hddinfo >= CLOCK_MAX) Settings.hddinfo = 0; //CLOCK + } + + //! Settings: Tooltips + else if (ret == ++Idx) + { + if (++Settings.tooltips >= MAX_ON_OFF) Settings.tooltips = 0; + } + + //! Settings: Flip-X + else if (ret == ++Idx) + { + if (++Settings.xflip >= XFLIP_MAX) Settings.xflip = 0; + } + + //! Settings: Prompts Buttons + else if (ret == ++Idx) + { + if (++Settings.wsprompt >= MAX_ON_OFF) Settings.wsprompt = 0; + } + + //! Settings: Keyboard + else if (ret == ++Idx) + { + if (++Settings.keyset >= KEYBOARD_MAX) Settings.keyset = 0; + } + + //! Settings: Disc Artwork Download + else if (ret == ++Idx) + { + if (++Settings.discart >= 4) Settings.discart = 0; + } + + //! Settings: Wiilight + else if (ret == ++Idx) + { + if (++Settings.wiilight >= WIILIGHT_MAX) Settings.wiilight = 0; + } + + //! Settings: Rumble + else if (ret == ++Idx) + { + if (++Settings.rumble >= MAX_ON_OFF) Settings.rumble = 0; //RUMBLE + } + + //! Settings: AutoInit Network + else if (ret == ++Idx) + { + if (++Settings.autonetwork >= MAX_ON_OFF) Settings.autonetwork = 0; + } + + //! Settings: BETA revisions + else if (ret == ++Idx) + { + if (++Settings.beta_upgrades >= MAX_ON_OFF) Settings.beta_upgrades = 0; + } + + //! Settings: Titles from WiiTDB + else if (ret == ++Idx) + { + if (++Settings.titlesOverride >= MAX_ON_OFF) Settings.titlesOverride = 0; + } + + //! Settings: Screensaver + else if (ret == ++Idx) + { + if (++Settings.screensaver >= SCREENSAVER_MAX) Settings.screensaver = 0; + } + + //! Settings: Mark new games + else if (ret == ++Idx) + { + if (++Settings.marknewtitles >= MAX_ON_OFF) Settings.marknewtitles = 0; + } + + SetOptionValues(); + + return MENU_NONE; +} diff --git a/source/settings/menus/GUISettingsMenu.hpp b/source/settings/menus/GUISettingsMenu.hpp new file mode 100644 index 00000000..97680648 --- /dev/null +++ b/source/settings/menus/GUISettingsMenu.hpp @@ -0,0 +1,45 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 GUISETTINGS_MENU_HPP_ +#define GUISETTINGS_MENU_HPP_ + +#include "SettingsMenu.hpp" + +class GuiSettingsMenu : public SettingsMenu +{ + public: + GuiSettingsMenu(); + ~GuiSettingsMenu(); + virtual int GetType() { return CGUISettingsMenu; }; + protected: + void SetOptionValues(); + int GetMenuInternal(); + + int OldTitlesOverride; + + OptionList GuiOptions; +}; + + +#endif diff --git a/source/settings/menus/GameLoadSM.cpp b/source/settings/menus/GameLoadSM.cpp new file mode 100644 index 00000000..571cbc86 --- /dev/null +++ b/source/settings/menus/GameLoadSM.cpp @@ -0,0 +1,327 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 +#include "GameLoadSM.hpp" +#include "settings/CSettings.h" +#include "prompts/PromptWindows.h" +#include "language/gettext.h" +#include "wad/nandtitle.h" +#include "prompts/TitleBrowser.h" +#include "usbloader/GameList.h" +#include "usbloader/wbfs.h" +#include "usbloader/utils.h" +#include "system/IosLoader.h" +#include "settings/GameTitles.h" +#include "xml/xml.h" +#include "menu.h" + +extern PartList partitions; +extern char game_partition[6]; +extern u8 load_from_fs; + +static const char * OnOffText[MAX_ON_OFF] = +{ + trNOOP( "OFF" ), + trNOOP( "ON" ) +}; + +static const char * VideoModeText[VIDEO_MODE_MAX] = +{ + trNOOP( "Disc Default" ), + trNOOP( "System Default" ), + trNOOP( "AutoPatch" ), + trNOOP( "Force PAL50" ), + trNOOP( "Force PAL60" ), + trNOOP( "Force NTSC" ) +}; + +static const char * LanguageText[MAX_LANGUAGE] = +{ + trNOOP( "Disc Default" ), + trNOOP( "Console Default" ), + trNOOP( "Japanese" ), + trNOOP( "English" ), + trNOOP( "German" ), + trNOOP( "French" ), + trNOOP( "Spanish" ), + trNOOP( "Italian" ), + trNOOP( "Dutch" ), + trNOOP( "SChinese" ), + trNOOP( "TChinese" ), + trNOOP( "Korean" ) +}; + +static const char * InstallToText[INSTALL_TO_MAX] = +{ + trNOOP( "None" ), + trNOOP( "GAMEID_Gamename" ), + trNOOP( "Gamename [GAMEID]" ) +}; + +static const char * Error002Text[3] = +{ + trNOOP( "No" ), + trNOOP( "Yes" ), + trNOOP( "Anti" ) +}; + +static const char * InstPartitionsText[3] = +{ + trNOOP( "Game partition" ), + trNOOP( "All partitions" ), + trNOOP( "Remove update" ) +}; + +static inline bool IsValidPartition(int fs_type, int cios) +{ + if (IosLoader::IsWaninkokoIOS() && NandTitles.VersionOf(TITLE_ID(1, cios)) < 18) + { + return fs_type == FS_TYPE_WBFS; + } + else + { + return fs_type == FS_TYPE_WBFS || fs_type == FS_TYPE_FAT32 || fs_type == FS_TYPE_NTFS; + } +} + +GameLoadSM::GameLoadSM() + : SettingsMenu(tr("Game Load"), &GuiOptions, MENU_NONE) +{ + int Idx = 0; + + Options->SetName(Idx++, "%s", tr( "Video Mode" )); + Options->SetName(Idx++, "%s", tr( "VIDTV Patch" )); + Options->SetName(Idx++, "%s", tr( "Game Language" )); + Options->SetName(Idx++, "%s", tr( "Patch Country Strings" )); + Options->SetName(Idx++, "%s", tr( "Ocarina" )); + Options->SetName(Idx++, "%s", tr( "Boot/Standard" )); + Options->SetName(Idx++, "%s", tr( "Partition" )); + Options->SetName(Idx++, "%s", tr( "FAT: Use directories" )); + Options->SetName(Idx++, "%s", tr( "Quick Boot" )); + Options->SetName(Idx++, "%s", tr( "Error 002 fix" )); + Options->SetName(Idx++, "%s", tr( "Install partitions" )); + Options->SetName(Idx++, "%s", tr( "Install 1:1 Copy" )); + Options->SetName(Idx++, "%s", tr( "Return To" )); + + SetOptionValues(); + + OldSettingsPartition = Settings.partition; +} + +GameLoadSM::~GameLoadSM() +{ + // if partition has changed, Reinitialize it + if (Settings.partition != OldSettingsPartition) + { + PartInfo pinfo = partitions.pinfo[Settings.partition]; + partitionEntry pentry = partitions.pentry[Settings.partition]; + WBFS_OpenPart(pinfo.part_fs, pinfo.index, pentry.sector, pentry.size, (char *) &game_partition); + load_from_fs = pinfo.part_fs; + CloseXMLDatabase(); + GameTitles.SetDefault(); + OpenXMLDatabase(Settings.titlestxt_path, Settings.db_language, Settings.db_JPtoEN, true, Settings.titlesOverride, true); + gameList.ReadGameList(); + } +} + +void GameLoadSM::SetOptionValues() +{ + int Idx = 0; + + //! Settings: Video Mode + Options->SetValue(Idx++, "%s", tr(VideoModeText[Settings.videomode])); + + //! Settings: VIDTV Patch + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.videopatch] )); + + //! Settings: Game Language + Options->SetValue(Idx++, "%s", tr( LanguageText[Settings.language] )); + + //! Settings: Patch Country Strings + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.patchcountrystrings] )); + + //! Settings: Ocarina + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.ocarina] )); + + //! Settings: Boot/Standard + if (Settings.godmode) + Options->SetValue(Idx++, "IOS %i", Settings.cios); + else + Options->SetValue(Idx++, "********"); + + //! Settings: Partition + PartInfo pInfo = partitions.pinfo[Settings.partition]; + f32 partition_size = partitions.pentry[Settings.partition].size + * (partitions.sector_size / GB_SIZE); + + // Get the partition name and it's size in GB's + Options->SetValue(Idx++, "%s%d (%.2fGB)", pInfo.fs_type == FS_TYPE_FAT32 ? "FAT" + : pInfo.fs_type == FS_TYPE_NTFS ? "NTFS" : "WBFS", pInfo.index, partition_size); + + //! Settings: FAT: Use directories + Options->SetValue(Idx++, "%s", tr( InstallToText[Settings.FatInstallToDir] )); + + //! Settings: Quick Boot + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.quickboot] )); + + //! Settings: Error 002 fix + Options->SetValue(Idx++, "%s", tr( Error002Text[Settings.error002] )); + + //! Settings: Install partitions + Options->SetValue(Idx++, "%s", tr( InstPartitionsText[Settings.InstallPartitions] )); + + //! Settings: Install 1:1 Copy + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.fullcopy] )); + + //! Settings: Return To + const char* TitleName = NULL; + int haveTitle = NandTitles.FindU32(Settings.returnTo); + if (haveTitle >= 0) + TitleName = NandTitles.NameFromIndex(haveTitle); + Options->SetValue(Idx++, "%s", TitleName ? TitleName : strlen(Settings.returnTo) > 0 ? + Settings.returnTo : tr( OnOffText[0] )); +} + +int GameLoadSM::GetMenuInternal() +{ + int ret = optionBrowser->GetClickedOption(); + + if (ret < 0) + return MENU_NONE; + + int Idx = -1; + + //! Settings: Video Mode + if (ret == ++Idx) + { + if (++Settings.videomode >= VIDEO_MODE_MAX) Settings.videomode = 0; + } + + //! Settings: VIDTV Patch + else if (ret == ++Idx) + { + if (++Settings.videopatch >= MAX_ON_OFF) Settings.videopatch = 0; + } + + //! Settings: Game Language + else if (ret == ++Idx) + { + if (++Settings.language >= MAX_LANGUAGE) Settings.language = 0; + } + + //! Settings: Patch Country Strings + else if (ret == ++Idx) + { + if (++Settings.patchcountrystrings >= MAX_ON_OFF) Settings.patchcountrystrings = 0; + } + + //! Settings: Ocarina + else if (ret == ++Idx) + { + if (++Settings.ocarina >= MAX_ON_OFF) Settings.ocarina = 0; + } + + //! Settings: Boot/Standard + else if (ret == ++Idx) + { + if(!Settings.godmode) + return MENU_NONE; + + char entered[4]; + snprintf(entered, sizeof(entered), "%i", Settings.cios); + if(OnScreenKeyboard(entered, sizeof(entered), 0)) + { + Settings.cios = atoi(entered); + if(Settings.cios < 200) Settings.cios = 200; + else if(Settings.cios > 255) Settings.cios = 255; + + if(NandTitles.IndexOf(TITLE_ID(1, Settings.cios)) < 0) + { + WindowPrompt(tr("Warning:"), tr("This IOS was not found on the titles list. If you are sure you have it installed than ignore this warning."), tr("OK")); + } + else if(Settings.cios == 254) + { + WindowPrompt(tr("Warning:"), tr("This IOS is the BootMii ios. If you are sure it is not BootMii and you have something else installed there than ignore this warning."), tr("OK")); + } + } + } + + //! Settings: Partition + else if (ret == ++Idx) + { + // Select the next valid partition, even if that's the same one + int fs_type = partitions.pinfo[Settings.partition].fs_type; + int ios = IOS_GetVersion(); + do + { + Settings.partition = (Settings.partition + 1) % partitions.num; + fs_type = partitions.pinfo[Settings.partition].fs_type; + } + while (!IsValidPartition(fs_type, ios)); + } + + //! Settings: FAT: Use directories + else if (ret == ++Idx) + { + if (++Settings.FatInstallToDir >= INSTALL_TO_MAX) Settings.FatInstallToDir = 0; + } + + //! Settings: Quick Boot + else if (ret == ++Idx) + { + if (++Settings.quickboot >= MAX_ON_OFF) Settings.quickboot = 0; + } + + //! Settings: Error 002 fix + else if (ret == ++Idx ) + { + if (++Settings.error002 >= 3) Settings.error002 = 0; + } + + //! Settings: Install partitions + else if (ret == ++Idx) + { + if (++Settings.InstallPartitions >= 3) Settings.InstallPartitions = 0; + } + + //! Settings: Install 1:1 Copy + else if (ret == ++Idx) + { + if (++Settings.fullcopy >= MAX_ON_OFF) Settings.fullcopy = 0; + } + + //! Settings: Return To + else if (ret == ++Idx) + { + char tidChar[10]; + bool getChannel = TitleSelector(tidChar); + if (getChannel) + snprintf(Settings.returnTo, sizeof(Settings.returnTo), "%s", tidChar); + } + + SetOptionValues(); + + return MENU_NONE; +} + diff --git a/source/settings/menus/GameLoadSM.hpp b/source/settings/menus/GameLoadSM.hpp new file mode 100644 index 00000000..27fd7e7b --- /dev/null +++ b/source/settings/menus/GameLoadSM.hpp @@ -0,0 +1,45 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 GAMELOADSM_HPP_ +#define GAMELOADSM_HPP_ + +#include "SettingsMenu.hpp" + +class GameLoadSM : public SettingsMenu +{ + public: + GameLoadSM(); + ~GameLoadSM(); + virtual int GetType() { return CGameLoadSM; }; + protected: + void SetOptionValues(); + int GetMenuInternal(); + + int OldSettingsPartition; + + OptionList GuiOptions; +}; + + +#endif diff --git a/source/settings/menus/GameSettingsMenu.cpp b/source/settings/menus/GameSettingsMenu.cpp new file mode 100644 index 00000000..37ec3cc5 --- /dev/null +++ b/source/settings/menus/GameSettingsMenu.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 "GameSettingsMenu.hpp" +#include "themes/CTheme.h" +#include "prompts/PromptWindows.h" +#include "settings/GameTitles.h" +#include "language/gettext.h" +#include "wad/nandtitle.h" +#include "cheats/cheatmenu.h" +#include "IndGameLoadSM.hpp" +#include "UninstallSM.hpp" + +GameSettingsMenu::GameSettingsMenu(struct discHdr * header) + : FlyingButtonsMenu(GameTitles.GetTitle(header)) +{ + DiscHeader = header; +} + +GameSettingsMenu::~GameSettingsMenu() +{ +} + +void GameSettingsMenu::SetupMainButtons() +{ + int pos = 0; + + SetMainButton(pos++, tr( "Game Load" ), MainButtonImgData, MainButtonImgOverData); + SetMainButton(pos++, tr( "Ocarina" ), MainButtonImgData, MainButtonImgOverData); + SetMainButton(pos++, tr( "Uninstall Menu" ), MainButtonImgData, MainButtonImgOverData); + SetMainButton(pos++, tr( "Default Gamesettings" ), MainButtonImgData, MainButtonImgOverData); +} + +void GameSettingsMenu::CreateSettingsMenu(int menuNr) +{ + if(CurrentMenu) + return; + + int Idx = 0; + + //! Game Load + if(menuNr == Idx++) + { + HideMenu(); + ResumeGui(); + CurrentMenu = new IndGameLoadSM((const char *) DiscHeader->id); + Append(CurrentMenu); + } + + //! Ocarina + else if(menuNr == Idx++) + { + char ID[7]; + snprintf(ID, sizeof(ID), "%s", (char *) DiscHeader->id); + CheatMenu(ID); + } + + //! Uninstall Menu + else if(menuNr == Idx++) + { + HideMenu(); + ResumeGui(); + CurrentMenu = new UninstallSM(DiscHeader); + Append(CurrentMenu); + } + + //! Default Gamesettings + else if(menuNr == Idx++) + { + int choice = WindowPrompt(tr( "Are you sure?" ), 0, tr( "Yes" ), tr( "Cancel" )); + if (choice == 1) + { + GameSettings.Remove(DiscHeader->id); + GameSettings.Save(); + } + } +} + +void GameSettingsMenu::DeleteSettingsMenu() +{ + if(!CurrentMenu) + return; + + int type = CurrentMenu->GetType(); + + switch(type) + { + case CIndGameLoadSM: + delete ((IndGameLoadSM *) CurrentMenu); + break; + case CUninstallSM: + delete ((UninstallSM *) CurrentMenu); + break; + case CSettingsMenu: + default: + delete CurrentMenu; + break; + } + + CurrentMenu = NULL; +} diff --git a/source/settings/menus/GameSettingsMenu.hpp b/source/settings/menus/GameSettingsMenu.hpp new file mode 100644 index 00000000..91cb6b58 --- /dev/null +++ b/source/settings/menus/GameSettingsMenu.hpp @@ -0,0 +1,44 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 GAMESETTINGSMENU_HPP_ +#define GAMESETTINGSMENU_HPP_ + +#include "FlyingButtonsMenu.hpp" +#include "settings/CGameSettings.h" +#include "usbloader/disc.h" + +class GameSettingsMenu : public FlyingButtonsMenu +{ + public: + GameSettingsMenu(struct discHdr * header); + ~GameSettingsMenu(); + protected: + virtual void CreateSettingsMenu(int index); + virtual void DeleteSettingsMenu(); + virtual void SetupMainButtons(); + + struct discHdr * DiscHeader; +}; + +#endif diff --git a/source/settings/menus/GlobalSettings.cpp b/source/settings/menus/GlobalSettings.cpp new file mode 100644 index 00000000..2b4da498 --- /dev/null +++ b/source/settings/menus/GlobalSettings.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 "GlobalSettings.hpp" +#include "themes/CTheme.h" +#include "prompts/PromptWindows.h" +#include "language/gettext.h" +#include "GuiSettingsMenu.hpp" +#include "GameLoadSM.hpp" +#include "ParentalControlSM.hpp" +#include "SoundSettingsMenu.hpp" +#include "CustomPathsSM.hpp" + +GlobalSettings::GlobalSettings() + : FlyingButtonsMenu(tr("Global Settings")) +{ + creditsImgData = Resources::GetImageData("credits_button.png"); + creditsImgOverData = Resources::GetImageData("credits_button_over.png"); +} + +GlobalSettings::~GlobalSettings() +{ + Settings.Save(); + + delete creditsImgData; + delete creditsImgOverData; +} + +void GlobalSettings::SetupMainButtons() +{ + int pos = 0; + + SetMainButton(pos++, tr( "GUI Settings" ), MainButtonImgData, MainButtonImgOverData); + SetMainButton(pos++, tr( "Game Load" ), MainButtonImgData, MainButtonImgOverData); + SetMainButton(pos++, tr( "Parental Control" ), MainButtonImgData, MainButtonImgOverData); + SetMainButton(pos++, tr( "Sound" ), MainButtonImgData, MainButtonImgOverData); + SetMainButton(pos++, tr( "Custom Paths" ), MainButtonImgData, MainButtonImgOverData); + SetMainButton(pos++, tr( "Update" ), MainButtonImgData, MainButtonImgOverData); + SetMainButton(pos++, tr( "Default Settings" ), MainButtonImgData, MainButtonImgOverData); + SetMainButton(pos++, tr( "Credits" ), creditsImgData, creditsImgOverData); + SetMainButton(pos++, tr( "Theme Downloader" ), MainButtonImgData, MainButtonImgOverData); +} + +void GlobalSettings::CreateSettingsMenu(int menuNr) +{ + if(CurrentMenu) + return; + + int Idx = 0; + + //! GUI Settings + if(menuNr == Idx++) + { + HideMenu(); + ResumeGui(); + CurrentMenu = new GuiSettingsMenu(); + Append(CurrentMenu); + } + //! Game Load + else if(menuNr == Idx++) + { + HideMenu(); + ResumeGui(); + CurrentMenu = new GameLoadSM(); + Append(CurrentMenu); + } + //! Parental Control + else if(menuNr == Idx++) + { + HideMenu(); + ResumeGui(); + CurrentMenu = new ParentalControlSM(); + Append(CurrentMenu); + } + //! Sound + else if(menuNr == Idx++) + { + HideMenu(); + ResumeGui(); + CurrentMenu = new SoundSettingsMenu(); + Append(CurrentMenu); + } + //! Custom Paths + else if(menuNr == Idx++) + { + if(Settings.godmode) + { + HideMenu(); + ResumeGui(); + CurrentMenu = new CustomPathsSM(); + Append(CurrentMenu); + } + else + WindowPrompt(tr( "Console Locked" ), tr( "Unlock console to use this option." ), tr( "OK" )); + + } + //! Update + else if(menuNr == Idx++) + { + if (Settings.godmode) + { + HideMenu(); + Remove(backBtn); + ResumeGui(); + int ret = ProgressUpdateWindow(); + if (ret < 0) + WindowPrompt(tr( "Update failed" ), 0, tr( "OK" )); + Append(backBtn); + ShowMenu(); + } + else + WindowPrompt(tr( "Console Locked" ), tr( "Unlock console to use this option." ), tr( "OK" )); + } + //! Default Settings + else if(menuNr == Idx++) + { + if (Settings.godmode) + { + int choice = WindowPrompt(tr( "Are you sure you want to reset?" ), 0, tr( "Yes" ), tr( "Cancel" )); + if (choice == 1) + { + HaltGui(); + gettextCleanUp(); + Settings.Reset(); + returnMenu = MENU_SETTINGS; + ResumeGui(); + } + } + else + WindowPrompt(tr( "Console Locked" ), tr( "Unlock console to use this option." ), tr( "OK" )); + } + //! Credits + else if(menuNr == Idx++) + { + HideMenu(); + Remove(backBtn); + ResumeGui(); + WindowCredits(); + Append(backBtn); + ShowMenu(); + } + //! Theme Downloader + else if(menuNr == Idx++) + { + returnMenu = MENU_THEMEDOWNLOADER; + } +} + +void GlobalSettings::DeleteSettingsMenu() +{ + if(!CurrentMenu) + return; + + int type = CurrentMenu->GetType(); + + switch(type) + { + case CGUISettingsMenu: + delete ((GuiSettingsMenu *) CurrentMenu); + break; + case CGameLoadSM: + delete ((GameLoadSM *) CurrentMenu); + break; + case CParentalControlSM: + delete ((ParentalControlSM *) CurrentMenu); + break; + case CSoundSettingsMenu: + delete ((SoundSettingsMenu *) CurrentMenu); + break; + case CCustomPathsSM: + delete ((CustomPathsSM *) CurrentMenu); + break; + case CSettingsMenu: + default: + delete CurrentMenu; + break; + } + + CurrentMenu = NULL; +} diff --git a/source/settings/menus/GlobalSettings.hpp b/source/settings/menus/GlobalSettings.hpp new file mode 100644 index 00000000..97b9400c --- /dev/null +++ b/source/settings/menus/GlobalSettings.hpp @@ -0,0 +1,43 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 GLOBAL_SETTINGS_HPP_ +#define GLOBAL_SETTINGS_HPP_ + +#include "FlyingButtonsMenu.hpp" + +class GlobalSettings : public FlyingButtonsMenu +{ + public: + GlobalSettings(); + ~GlobalSettings(); + protected: + virtual void CreateSettingsMenu(int index); + virtual void DeleteSettingsMenu(); + virtual void SetupMainButtons(); + + GuiImageData * creditsImgData; + GuiImageData * creditsImgOverData; +}; + +#endif diff --git a/source/settings/menus/IndGameLoadSM.cpp b/source/settings/menus/IndGameLoadSM.cpp new file mode 100644 index 00000000..8c3cfce0 --- /dev/null +++ b/source/settings/menus/IndGameLoadSM.cpp @@ -0,0 +1,409 @@ + /**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 +#include +#include "settings/CSettings.h" +#include "themes/CTheme.h" +#include "prompts/PromptWindows.h" +#include "prompts/DiscBrowser.h" +#include "language/gettext.h" +#include "wad/nandtitle.h" +#include "IndGameLoadSM.hpp" + +static const char * OnOffText[MAX_ON_OFF] = +{ + trNOOP( "OFF" ), + trNOOP( "ON" ) +}; + +static const char * VideoModeText[VIDEO_MODE_MAX] = +{ + trNOOP( "Disc Default" ), + trNOOP( "System Default" ), + trNOOP( "AutoPatch" ), + trNOOP( "Force PAL50" ), + trNOOP( "Force PAL60" ), + trNOOP( "Force NTSC" ) +}; + +static const char * LanguageText[MAX_LANGUAGE] = +{ + trNOOP( "Disc Default" ), + trNOOP( "Console Default" ), + trNOOP( "Japanese" ), + trNOOP( "English" ), + trNOOP( "German" ), + trNOOP( "French" ), + trNOOP( "Spanish" ), + trNOOP( "Italian" ), + trNOOP( "Dutch" ), + trNOOP( "SChinese" ), + trNOOP( "TChinese" ), + trNOOP( "Korean" ) +}; + +static const char * Error002Text[3] = +{ + trNOOP( "No" ), + trNOOP( "Yes" ), + trNOOP( "Anti" ) +}; + +static const char * ParentalText[5] = +{ + trNOOP( "0 (Everyone)" ), + trNOOP( "1 (Child 7+)" ), + trNOOP( "2 (Teen 12+)" ), + trNOOP( "3 (Mature 16+)" ), + trNOOP( "4 (Adults Only 18+)" ) +}; + +static const char * AlternateDOLText[] = +{ + trNOOP( "OFF" ), + trNOOP( "Load From SD/USB" ), + trNOOP( "Select a DOL" ) +}; + +IndGameLoadSM::IndGameLoadSM(const char * GameID) + : SettingsMenu(tr("Game Load"), &GuiOptions, MENU_NONE) +{ + //! Setup default settings from global settings + snprintf(GameConfig.id, sizeof(GameConfig.id), "%s", (char *) GameID); + SetDefaultConfig(); + + GameCFG * existCFG = GameSettings.GetGameCFG(GameID); + + //! Overwrite with existing if available + if (existCFG) + memcpy(&GameConfig, existCFG, sizeof(GameCFG)); + + if(!btnOutline) + btnOutline = Resources::GetImageData("button_dialogue_box.png"); + if(!trigA) + trigA = new GuiTrigger(); + trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + + saveBtnTxt = new GuiText(tr( "Save" ), 22, Theme.prompttext); + saveBtnTxt->SetMaxWidth(btnOutline->GetWidth() - 30); + saveBtnImg = new GuiImage (btnOutline); + if (Settings.wsprompt == ON) + { + saveBtnTxt->SetWidescreen(Settings.widescreen); + saveBtnImg->SetWidescreen(Settings.widescreen); + } + saveBtn = new GuiButton(saveBtnImg, saveBtnImg, 2, 3, 180, 400, trigA, btnSoundOver, btnSoundClick2, 1); + saveBtn->SetLabel(saveBtnTxt); + Append(saveBtn); + + SetOptionNames(); + SetOptionValues(); +} + +IndGameLoadSM::~IndGameLoadSM() +{ + HaltGui(); + //! The rest is destroyed in SettingsMenu.cpp + Remove(saveBtn); + delete saveBtnTxt; + delete saveBtnImg; + delete saveBtn; + ResumeGui(); +} + +void IndGameLoadSM::SetDefaultConfig() +{ + GameConfig.video = Settings.videomode; + GameConfig.language = Settings.language; + GameConfig.ocarina = Settings.ocarina; + GameConfig.vipatch = Settings.videopatch; + GameConfig.ios = Settings.cios; + GameConfig.parentalcontrol = 0; + GameConfig.errorfix002 = Settings.error002; + GameConfig.patchcountrystrings = Settings.patchcountrystrings; + GameConfig.loadalternatedol = OFF; + GameConfig.alternatedolstart = 0; + GameConfig.iosreloadblock = OFF; + strcpy(GameConfig.alternatedolname, ""); + GameConfig.returnTo = 1; + GameConfig.Locked = 0; +} + +void IndGameLoadSM::SetOptionNames() +{ + int Idx = 0; + + Options->SetName(Idx++, "%s", tr( "Video Mode" )); + Options->SetName(Idx++, "%s", tr( "VIDTV Patch" )); + Options->SetName(Idx++, "%s", tr( "Game Language" )); + Options->SetName(Idx++, "%s", tr( "Patch Country Strings" )); + Options->SetName(Idx++, "%s", tr( "Ocarina" )); + Options->SetName(Idx++, "%s", tr( "Game IOS" )); + Options->SetName(Idx++, "%s", tr( "Parental Control" )); + Options->SetName(Idx++, "%s", tr( "Error 002 fix" )); + Options->SetName(Idx++, "%s", tr( "Return To" )); + Options->SetName(Idx++, "%s", tr( "Alternate DOL" )); + Options->SetName(Idx++, "%s", tr( "Select DOL Offset" )); + Options->SetName(Idx++, "%s", tr( "Block IOS Reload" )); + Options->SetName(Idx++, "%s", tr( "Game Lock" )); +} + +void IndGameLoadSM::SetOptionValues() +{ + int Idx = 0; + + //! Settings: Video Mode + Options->SetValue(Idx++, "%s", tr(VideoModeText[GameConfig.video])); + + //! Settings: VIDTV Patch + Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.vipatch])); + + //! Settings: Game Language + Options->SetValue(Idx++, "%s", tr(LanguageText[GameConfig.language])); + + //! Settings: Patch Country Strings + Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.patchcountrystrings])); + + //! Settings: Ocarina + Options->SetValue(Idx++, "%s", tr(OnOffText[GameConfig.ocarina])); + + //! Settings: Game IOS + Options->SetValue(Idx++, "%i", GameConfig.ios); + + //! Settings: Parental Control + Options->SetValue(Idx++, "%s", tr(ParentalText[GameConfig.parentalcontrol])); + + //! Settings: Error 002 fix + Options->SetValue(Idx++, "%s", tr(Error002Text[GameConfig.errorfix002])); + + //! Settings: Return To + if(GameConfig.returnTo) + { + const char* TitleName = NULL; + int haveTitle = NandTitles.FindU32(Settings.returnTo); + if (haveTitle >= 0) + TitleName = NandTitles.NameFromIndex(haveTitle); + Options->SetValue(Idx++, "%s", TitleName ? TitleName : strlen(Settings.returnTo) > 0 ? + Settings.returnTo : tr( OnOffText[0] )); + } + else + { + Options->SetValue(Idx++, "%s", tr( OnOffText[0] )); + } + + //! Settings: Alternate DOL + Options->SetValue(Idx++, "%s", tr( AlternateDOLText[GameConfig.loadalternatedol] )); + + //! Settings: Select DOL Offset + if(GameConfig.loadalternatedol != 2) + Options->SetValue(Idx++, tr("Not required")); + else + { + if(strcmp(GameConfig.alternatedolname, "") != 0) + Options->SetValue(Idx++, "%i <%s>", GameConfig.alternatedolstart, GameConfig.alternatedolname); + else + Options->SetValue(Idx++, "%i", GameConfig.alternatedolstart); + } + + //! Settings: Block IOS Reload + Options->SetValue(Idx++, "%s", tr( OnOffText[GameConfig.iosreloadblock] )); + + //! Settings: Game Lock + Options->SetValue(Idx++, "%s", tr( OnOffText[GameConfig.Locked] )); +} + +int IndGameLoadSM::GetMenuInternal() +{ + if (saveBtn->GetState() == STATE_CLICKED) + { + if (GameSettings.AddGame(GameConfig) && GameSettings.Save()) + { + WindowPrompt(tr( "Successfully Saved" ), 0, tr( "OK" )); + } + else + WindowPrompt(tr( "Save Failed. No device inserted?" ), 0, tr( "OK" )); + + saveBtn->ResetState(); + } + + int ret = optionBrowser->GetClickedOption(); + + if (ret < 0) + return MENU_NONE; + + int Idx = -1; + + //! Settings: Video Mode + if (ret == ++Idx) + { + if (++GameConfig.video >= VIDEO_MODE_MAX) GameConfig.video = 0; + } + + //! Settings: VIDTV Patch + else if (ret == ++Idx) + { + if (++GameConfig.vipatch >= MAX_ON_OFF) GameConfig.vipatch = 0; + } + + //! Settings: Game Language + else if (ret == ++Idx) + { + if (++GameConfig.language >= MAX_LANGUAGE) GameConfig.language = 0; + } + + //! Settings: Patch Country Strings + else if (ret == ++Idx) + { + if (++GameConfig.patchcountrystrings >= MAX_ON_OFF) GameConfig.patchcountrystrings = 0; + } + + //! Settings: Ocarina + else if (ret == ++Idx) + { + if (++GameConfig.ocarina >= MAX_ON_OFF) GameConfig.ocarina = 0; + } + + //! Settings: Game IOS + else if (ret == ++Idx) + { + char entered[4]; + snprintf(entered, sizeof(entered), "%i", GameConfig.ios); + if(OnScreenKeyboard(entered, sizeof(entered), 0)) + { + GameConfig.ios = atoi(entered); + if(GameConfig.ios < 200) GameConfig.ios = 200; + else if(GameConfig.ios > 255) GameConfig.ios = 255; + + if(NandTitles.IndexOf(TITLE_ID(1, GameConfig.ios)) < 0) + { + WindowPrompt(tr("Warning:"), tr("This IOS was not found on the titles list. If you are sure you have it installed than ignore this warning."), tr("OK")); + } + else if(GameConfig.ios == 254) + { + WindowPrompt(tr("Warning:"), tr("This IOS is the BootMii ios. If you are sure it is not BootMii and you have something else installed there than ignore this warning."), tr("OK")); + } + } + } + + //! Settings: Parental Control + else if (ret == ++Idx) + { + if (++GameConfig.parentalcontrol >= 5) GameConfig.parentalcontrol = 0; + } + + //! Settings: Error 002 fix + else if (ret == ++Idx) + { + if (++GameConfig.errorfix002 >= 3) GameConfig.errorfix002 = 0; + } + + //! Settings: Return To + else if (ret == ++Idx) + { + if (++GameConfig.returnTo >= MAX_ON_OFF) GameConfig.returnTo = 0; + } + + //! Settings: Alternate DOL + else if (ret == ++Idx) + { + if (--GameConfig.loadalternatedol < 0) // 0->2->1->0 + GameConfig.loadalternatedol = 2; + } + + //! Settings: Select DOL Offset + else if (ret == ++Idx && GameConfig.loadalternatedol == 2) + { + char filename[10]; + snprintf(filename, 7, "%s", GameConfig.id); + + //alt dol menu for games that require more than a single alt dol + int autodol = autoSelectDolMenu(filename, false); + + if (autodol > 0) + { + GameConfig.alternatedolstart = autodol; + snprintf(GameConfig.alternatedolname, sizeof(GameConfig.alternatedolname), "%s <%i>", tr( "AUTO" ), autodol); + SetOptionValues(); + return MENU_NONE; + } + else if (autodol == 0) + { + GameConfig.loadalternatedol = 0; + SetOptionValues(); + return MENU_NONE; + } + + //check to see if we already know the offset of the correct dol + autodol = autoSelectDol(filename, false); + //if we do know that offset ask if they want to use it + if (autodol > 0) + { + int dolchoice = WindowPrompt(0, tr( "Do you want to use the alternate DOL that is known to be correct?" ), + tr( "Yes" ), tr( "Pick from a list" ), tr( "Cancel" )); + if (dolchoice == 1) + { + GameConfig.alternatedolstart = autodol; + snprintf(GameConfig.alternatedolname, sizeof(GameConfig.alternatedolname), "%s <%i>", tr( "AUTO" ), autodol); + } + else if (dolchoice == 2) //they want to search for the correct dol themselves + { + int res = DiscBrowse(GameConfig.id, GameConfig.alternatedolname, sizeof(GameConfig.alternatedolname)); + if ((res >= 0) && (res != 696969)) //if res==696969 they pressed the back button + GameConfig.alternatedolstart = res; + } + } + else + { + int res = DiscBrowse(GameConfig.id, GameConfig.alternatedolname, sizeof(GameConfig.alternatedolname)); + if ((res >= 0) && (res != 696969)) + { + GameConfig.alternatedolstart = res; + char tmp[170]; + snprintf(tmp, sizeof(tmp), "%s %s - %i", tr( "It seems that you have some information that will be helpful to us. Please pass this information along to the DEV team." ), + filename, GameConfig.alternatedolstart); + WindowPrompt(0, tmp, tr( "OK" )); + } + } + + if(GameConfig.alternatedolstart == 0) + GameConfig.loadalternatedol = 0; + } + + //! Settings: Block IOS Reload + else if (ret == ++Idx) + { + if (++GameConfig.iosreloadblock >= MAX_ON_OFF) GameConfig.iosreloadblock = 0; + } + + //! Settings: Game Lock + else if (ret == ++Idx) + { + if (++GameConfig.Locked >= MAX_ON_OFF) GameConfig.Locked = 0; + } + + SetOptionValues(); + + return MENU_NONE; +} + diff --git a/source/settings/menus/IndGameLoadSM.hpp b/source/settings/menus/IndGameLoadSM.hpp new file mode 100644 index 00000000..9b7aaf6c --- /dev/null +++ b/source/settings/menus/IndGameLoadSM.hpp @@ -0,0 +1,51 @@ + /**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 INDIVIDUAL_GAMELOAD_SM_HPP +#define INDIVIDUAL_GAMELOAD_SM_HPP + +#include "SettingsMenu.hpp" +#include "settings/CGameSettings.h" + +class IndGameLoadSM : public SettingsMenu +{ + public: + IndGameLoadSM(const char * GameID); + ~IndGameLoadSM(); + virtual int GetType() { return CIndGameLoadSM; }; + protected: + void SetDefaultConfig(); + void SetOptionNames(); + void SetOptionValues(); + int GetMenuInternal(); + + GameCFG GameConfig; + OptionList GuiOptions; + + GuiText * saveBtnTxt; + GuiImage * saveBtnImg; + GuiButton * saveBtn; +}; + + +#endif diff --git a/source/settings/menus/ParentalControlSM.cpp b/source/settings/menus/ParentalControlSM.cpp new file mode 100644 index 00000000..c665dc1b --- /dev/null +++ b/source/settings/menus/ParentalControlSM.cpp @@ -0,0 +1,181 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 +#include "ParentalControlSM.hpp" +#include "settings/CSettings.h" +#include "prompts/PromptWindows.h" +#include "language/gettext.h" + +static const char * LockModeText[] = +{ + trNOOP( "Locked" ), + trNOOP( "Unlocked" ) +}; + +static const char * ParentalText[5] = +{ + trNOOP( "0 (Everyone)" ), + trNOOP( "1 (Child 7+)" ), + trNOOP( "2 (Teen 12+)" ), + trNOOP( "3 (Mature 16+)" ), + trNOOP( "4 (Adults Only 18+)" ) +}; + +static const char * LockedGamesText[2] = +{ + trNOOP( "0 (Locked and Unlocked Games)" ), + trNOOP( "1 (Unlocked Games Only)" ) +}; + +ParentalControlSM::ParentalControlSM() + : SettingsMenu(tr("Parental Control"), &GuiOptions, MENU_NONE) +{ + int Idx = 0; + Options->SetName(Idx++, "%s", tr( "Console" )); + Options->SetName(Idx++, "%s", tr( "Password" )); + Options->SetName(Idx++, "%s", tr( "Controllevel" )); + Options->SetName(Idx++, "%s", tr( "GamesLevel" )); + + SetOptionValues(); +} + +void ParentalControlSM::SetOptionValues() +{ + int Idx = 0; + + //! Settings: Console + Options->SetValue(Idx++, "%s", tr( LockModeText[Settings.godmode] )); + + //! Settings: Password + if (!Settings.godmode) + Options->SetValue(Idx++, "********"); + else if (strcmp(Settings.unlockCode, "") == 0) + Options->SetValue(Idx++, "%s", tr( "not set" )); + else + Options->SetValue(Idx++, Settings.unlockCode); + + //! Settings: Controllevel + if (Settings.godmode) + Options->SetValue(Idx++, "%s", tr( ParentalText[Settings.parentalcontrol] )); + else + Options->SetValue(Idx++, "********"); + + + //! Settings: GamesLevel + if (Settings.godmode) + Options->SetValue(Idx++, "%s", tr( LockedGamesText[Settings.lockedgames] )); + else + Options->SetValue(Idx++, "********"); +} + +int ParentalControlSM::GetMenuInternal() +{ + int ret = optionBrowser->GetClickedOption(); + + if (ret < 0) + return MENU_NONE; + + int Idx = -1; + + //! Settings: Console + if (ret == ++Idx) + { + if (strcmp(Settings.unlockCode, "") == 0 && !Settings.Parental.enabled) + { + Settings.godmode = !Settings.godmode; + } + else if (!Settings.godmode) + { + char entered[20]; + memset(entered, 0, 20); + + //password check to unlock Install,Delete and Format + SetState(STATE_DISABLED); + int result = Settings.Parental.enabled == 0 ? OnScreenKeyboard(entered, 20, 0) : OnScreenNumpad(entered, 5); + SetState(STATE_DEFAULT); + if (result == 1) + { + if (strcmp(entered, Settings.unlockCode) == 0 || !memcmp(entered, Settings.Parental.pin, 4)) //if password correct + { + WindowPrompt( + tr( "Correct Password" ), + tr( "All the features of USB Loader GX are unlocked." ), + tr( "OK" )); + Settings.godmode = 1; + } + else + WindowPrompt(tr( "Wrong Password" ), tr( "USB Loader GX is protected" ), tr( "OK" )); + } + } + else + { + int choice = WindowPrompt(tr( "Lock Console" ), tr( "Are you sure?" ), + tr( "Yes" ), tr( "No" )); + if (choice == 1) + { + WindowPrompt(tr( "Console Locked" ), tr( "USB Loader GX is protected" ), + tr( "OK" )); + Settings.godmode = 0; + } + } + } + + //! Settings: Password + else if (ret == ++Idx) + { + if (Settings.godmode) + { + char entered[20]; + SetState(STATE_DISABLED); + snprintf(entered, sizeof(entered), Settings.unlockCode); + int result = OnScreenKeyboard(entered, 20, 0); + SetState(STATE_DEFAULT); + if (result == 1) + { + snprintf(Settings.unlockCode, sizeof(Settings.unlockCode), entered); + WindowPrompt(tr( "Password Changed" ), tr( "Password has been changed" ), tr( "OK" )); + } + } + else + { + WindowPrompt(tr( "Password Changed" ), tr( "Console should be unlocked to modify it." ), tr( "OK" )); + } + } + + //! Settings: Controllevel + else if (ret == ++Idx) + { + if (Settings.godmode && ++Settings.parentalcontrol >= 5) Settings.parentalcontrol = 0; + } + + //! Settings: GamesLevel + else if (ret == ++Idx) + { + if (Settings.godmode && ++Settings.lockedgames >= 2) Settings.lockedgames = 0; + } + + SetOptionValues(); + + return MENU_NONE; +} diff --git a/source/settings/menus/ParentalControlSM.hpp b/source/settings/menus/ParentalControlSM.hpp new file mode 100644 index 00000000..7a6b2487 --- /dev/null +++ b/source/settings/menus/ParentalControlSM.hpp @@ -0,0 +1,42 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 PARENTALCONTROL_MENU_HPP_ +#define PARENTALCONTROL_MENU_HPP_ + +#include "SettingsMenu.hpp" + +class ParentalControlSM : public SettingsMenu +{ + public: + ParentalControlSM(); + virtual int GetType() { return CParentalControlSM; }; + protected: + void SetOptionValues(); + int GetMenuInternal(); + + OptionList GuiOptions; +}; + + +#endif diff --git a/source/settings/menus/SettingsMenu.cpp b/source/settings/menus/SettingsMenu.cpp new file mode 100644 index 00000000..f2fdf4b0 --- /dev/null +++ b/source/settings/menus/SettingsMenu.cpp @@ -0,0 +1,125 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 +#include "SettingsMenu.hpp" +#include "themes/CTheme.h" +#include "language/gettext.h" + +SettingsMenu::SettingsMenu(const char * title, OptionList * opts, int returnTo) + : GuiWindow(screenwidth, screenheight) +{ + Options = opts; + returnToMenu = returnTo; + backBtn = NULL; + trigA = NULL; + trigB = NULL; + backBtnTxt = NULL; + backBtnImg = NULL; + backBtn = NULL; + btnOutline = NULL; + + //! Skipping back button if there is no menu defined to go back to + if(returnToMenu != MENU_NONE) + { + btnOutline = Resources::GetImageData("button_dialogue_box.png"); + + trigA = new GuiTrigger(); + trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + + trigB = new GuiTrigger(); + trigB->SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); + + backBtnTxt = new GuiText(tr("Back"), 22, (GXColor){0, 0, 0, 255}); + backBtnImg = new GuiImage(btnOutline); + backBtn = new GuiButton(backBtnImg, backBtnImg, 2, 3, -180, 400, trigA, btnSoundOver, btnSoundClick2, 1); + backBtn->SetLabel(backBtnTxt); + backBtn->SetTrigger(trigB); + Append(backBtn); + } + + optionBrowser = new GuiCustomOptionBrowser(396, 280, Options, "bg_options_settings.png", 0, 150); + optionBrowser->SetPosition(0, 90); + optionBrowser->SetAlignment(ALIGN_CENTRE, ALIGN_TOP); + + titleTxt = new GuiText(title, 28, (GXColor) {0, 0, 0, 255}); + titleTxt->SetAlignment(ALIGN_CENTRE, ALIGN_TOP); + titleTxt->SetPosition(0, 40); + + Append(optionBrowser); + Append(titleTxt); + + SetEffect(EFFECT_FADE, 50); +} + +SettingsMenu::~SettingsMenu() +{ + ResumeGui(); + + SetEffect(EFFECT_FADE, -50); + while(this->GetEffect() > 0) + usleep(100); + + HaltGui(); + if(parentElement) + ((GuiWindow *) parentElement)->Remove(this); + + RemoveAll(); + + if(btnOutline) + delete btnOutline; + + if(backBtnTxt) + delete backBtnTxt; + if(backBtnImg) + delete backBtnImg; + if(backBtn) + delete backBtn; + + if(trigA) + delete trigA; + if(trigB) + delete trigB; + + delete titleTxt; + + delete optionBrowser; + + ResumeGui(); +} + +int SettingsMenu::GetClickedOption() +{ + if(!optionBrowser) + return -1; + + return optionBrowser->GetClickedOption(); +} + +int SettingsMenu::GetMenu() +{ + if(backBtn && backBtn->GetState() == STATE_CLICKED) + return returnToMenu; + + return GetMenuInternal(); +} diff --git a/source/settings/menus/SettingsMenu.hpp b/source/settings/menus/SettingsMenu.hpp new file mode 100644 index 00000000..4724d93c --- /dev/null +++ b/source/settings/menus/SettingsMenu.hpp @@ -0,0 +1,72 @@ + /**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 SETTINGS_MENU_HPP_ +#define SETTINGS_MENU_HPP_ + +#include "libwiigui/gui.h" +#include "libwiigui/gui_customoptionbrowser.h" +#include "menu.h" + +enum +{ + CSettingsMenu = 0, + CGUISettingsMenu, + CGameLoadSM, + CParentalControlSM, + CSoundSettingsMenu, + CCustomPathsSM, + CIndGameLoadSM, + CUninstallSM, +}; + +class SettingsMenu : public GuiWindow +{ + public: + SettingsMenu(const char * title, OptionList * option, int returnTo); + ~SettingsMenu(); + int GetClickedOption(); + int GetMenu(); + virtual int GetType() { return CSettingsMenu; } + protected: + virtual int GetMenuInternal() { return MENU_NONE; }; + int returnToMenu; + + GuiImageData * btnOutline; + + GuiTrigger * trigA; + GuiTrigger * trigB; + + OptionList * Options; + + GuiText * titleTxt; + GuiText * backBtnTxt; + GuiImage * backBtnImg; + GuiButton * backBtn; + + GuiCustomOptionBrowser * optionBrowser; + +}; + + +#endif diff --git a/source/settings/menus/SoundSettingsMenu.cpp b/source/settings/menus/SoundSettingsMenu.cpp new file mode 100644 index 00000000..a6b0a76e --- /dev/null +++ b/source/settings/menus/SoundSettingsMenu.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 +#include "SoundSettingsMenu.hpp" +#include "settings/CSettings.h" +#include "settings/SettingsPrompts.h" +#include "prompts/PromptWindows.h" +#include "language/gettext.h" + +static const char * GameSoundText[] = +{ + trNOOP( "Sound+Quiet" ), + trNOOP( "Sound+BGM" ), + trNOOP( "Loop Sound" ), +}; + +static const char * MusicLoopText[] = +{ + trNOOP( "Play Once" ), + trNOOP( "Loop Music" ), + trNOOP( "Random Directory Music" ), + trNOOP( "Loop Directory" ), +}; + +SoundSettingsMenu::SoundSettingsMenu() + : SettingsMenu(tr("Sound Settings"), &GuiOptions, MENU_NONE) +{ + int Idx = 0; + Options->SetName(Idx++, "%s", tr( "Backgroundmusic" )); + Options->SetName(Idx++, "%s", tr( "Music Volume" )); + Options->SetName(Idx++, "%s", tr( "SFX Volume" )); + Options->SetName(Idx++, "%s", tr( "Game Sound Mode" )); + Options->SetName(Idx++, "%s", tr( "Game Sound Volume" )); + Options->SetName(Idx++, "%s", tr( "Music Loop Mode" )); + Options->SetName(Idx++, "%s", tr( "Reset BG Music" )); + + SetOptionValues(); +} + +void SoundSettingsMenu::SetOptionValues() +{ + int Idx = 0; + + //! Settings: Backgroundmusic + const char * filename = strrchr(Settings.ogg_path, '/'); + if (filename) + Options->SetValue(Idx++, filename+1); + else + Options->SetValue(Idx++, tr( "Default" )); + + //! Settings: Music Volume + if (Settings.volume > 0) + Options->SetValue(Idx++, "%i", Settings.volume); + else + Options->SetValue(Idx++, tr( "OFF" )); + + //! Settings: SFX Volume + if (Settings.sfxvolume > 0) + Options->SetValue(Idx++, "%i", Settings.sfxvolume); + else + Options->SetValue(Idx++, tr( "OFF" )); + + //! Settings: Game Sound Mode + Options->SetValue(Idx++, "%s", tr( GameSoundText[Settings.gamesound] )); + + //! Settings: Game Sound Volume + if (Settings.gamesoundvolume > 0) + Options->SetValue(Idx++, "%i", Settings.gamesoundvolume); + else + Options->SetValue(Idx++, tr( "OFF" )); + + //! Settings: Music Loop Mode + Options->SetValue(Idx++, tr( MusicLoopText[Settings.musicloopmode] )); + + //! Settings: Reset BG Music + Options->SetValue(Idx++, " "); +} + +int SoundSettingsMenu::GetMenuInternal() +{ + int ret = optionBrowser->GetClickedOption(); + + if (ret < 0) + return MENU_NONE; + + int Idx = -1; + + //! Settings: Backgroundmusic + if (ret == ++Idx) + { + SetEffect(EFFECT_FADE, -20); + while (GetEffect() > 0) usleep(100); + HaltGui(); + GuiWindow * parent = (GuiWindow *) parentElement; + if(parent) parent->SetState(STATE_DISABLED); + ResumeGui(); + + MenuBackgroundMusic(); + + HaltGui(); + SetEffect(EFFECT_FADE, 20); + if(parent) parent->SetState(STATE_DEFAULT); + ResumeGui(); + while (GetEffect() > 0) usleep(100); + } + + //! Settings: Music Volume + else if (ret == ++Idx) + { + Settings.volume += 10; + if (Settings.volume > 100) Settings.volume = 0; + bgMusic->SetVolume(Settings.volume); + } + + //! Settings: SFX Volume + else if (ret == ++Idx) + { + Settings.sfxvolume += 10; + if (Settings.sfxvolume > 100) Settings.sfxvolume = 0; + btnSoundOver->SetVolume(Settings.sfxvolume); + btnSoundClick->SetVolume(Settings.sfxvolume); + btnSoundClick2->SetVolume(Settings.sfxvolume); + } + + //! Settings: Game Sound Mode + else if (ret == ++Idx) + { + if (++Settings.gamesound > 2) Settings.gamesound = 0; + } + + //! Settings: Game Sound Volume + else if (ret == ++Idx) + { + Settings.gamesoundvolume += 10; + if (Settings.gamesoundvolume > 100) Settings.gamesoundvolume = 0; + } + + //! Settings: Music Loop Mode + else if (ret == ++Idx) + { + if (++Settings.musicloopmode > 3) Settings.musicloopmode = 0; + bgMusic->SetLoop(Settings.musicloopmode); + } + + //! Settings: Reset BG Music + else if (ret == ++Idx) + { + int result = WindowPrompt(tr( "Reset to default BGM?" ), 0, tr( "Yes" ), tr( "No" )); + if (result) + { + bgMusic->LoadStandard(); + bgMusic->Play(); + } + } + + SetOptionValues(); + + return MENU_NONE; +} diff --git a/source/settings/menus/SoundSettingsMenu.hpp b/source/settings/menus/SoundSettingsMenu.hpp new file mode 100644 index 00000000..5f6bbb05 --- /dev/null +++ b/source/settings/menus/SoundSettingsMenu.hpp @@ -0,0 +1,42 @@ +/**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 SOUNDSETTINGS_MENU_HPP_ +#define SOUNDSETTINGS_MENU_HPP_ + +#include "SettingsMenu.hpp" + +class SoundSettingsMenu : public SettingsMenu +{ + public: + SoundSettingsMenu(); + virtual int GetType() { return CSoundSettingsMenu; }; + protected: + void SetOptionValues(); + int GetMenuInternal(); + + OptionList GuiOptions; +}; + + +#endif diff --git a/source/settings/menus/UninstallSM.cpp b/source/settings/menus/UninstallSM.cpp new file mode 100644 index 00000000..d3531edb --- /dev/null +++ b/source/settings/menus/UninstallSM.cpp @@ -0,0 +1,175 @@ + /**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 +#include "UninstallSM.hpp" +#include "FileOperations/fileops.h" +#include "settings/CSettings.h" +#include "settings/CGameSettings.h" +#include "settings/CGameStatistics.h" +#include "settings/GameTitles.h" +#include "prompts/PromptWindows.h" +#include "language/gettext.h" +#include "usbloader/wbfs.h" + +extern int mountMethod; + +UninstallSM::UninstallSM(struct discHdr * header) + : SettingsMenu(tr("Uninstall Menu"), &GuiOptions, MENU_NONE) +{ + DiscHeader = header; + + int Idx = 0; + + Options->SetName(Idx++, "%s", tr( "Uninstall Game" )); + Options->SetName(Idx++, "%s", tr( "Reset Playcounter" )); + Options->SetName(Idx++, "%s", tr( "Delete Cover Artwork" )); + Options->SetName(Idx++, "%s", tr( "Delete Disc Artwork" )); + Options->SetName(Idx++, "%s", tr( "Delete Cheat TXT" )); + Options->SetName(Idx++, "%s", tr( "Delete Cheat GCT" )); + + SetOptionValues(); +} + +void UninstallSM::SetOptionValues() +{ + int Idx = 0; + + //! Settings: Uninstall Game + Options->SetValue(Idx++, " "); + + //! Settings: Reset Playcounter + Options->SetValue(Idx++, " "); + + //! Settings: Delete Cover Artwork + Options->SetValue(Idx++, " "); + + //! Settings: Delete Disc Artwork + Options->SetValue(Idx++, " "); + + //! Settings: Delete Cheat TXT + Options->SetValue(Idx++, " "); + + //! Settings: Delete Cheat GCT + Options->SetValue(Idx++, " "); + +} + +int UninstallSM::GetMenuInternal() +{ + int ret = optionBrowser->GetClickedOption(); + + if (ret < 0) + return MENU_NONE; + + int Idx = -1; + + //! Settings: Uninstall Game + if (ret == ++Idx) + { + int choice = WindowPrompt(tr( "Do you really want to delete:" ), GameTitles.GetTitle(DiscHeader), tr( "Yes" ), tr( "Cancel" )); + if (choice == 1) + { + GameSettings.Remove(DiscHeader->id); + GameSettings.Save(); + GameStatistics.Remove(DiscHeader->id); + GameStatistics.Save(); + int ret = 0; + if(!mountMethod) + ret = WBFS_RemoveGame(DiscHeader->id); + if (ret < 0) + WindowPrompt(tr( "Can't delete:" ), GameTitles.GetTitle(DiscHeader), tr( "OK" )); + else + WindowPrompt(tr( "Successfully deleted:" ), GameTitles.GetTitle(DiscHeader), tr( "OK" )); + + return MENU_DISCLIST; + } + } + + //! Settings: Reset Playcounter + else if (ret == ++Idx) + { + int result = WindowPrompt(tr( "Are you sure?" ), 0, tr( "Yes" ), tr( "Cancel" )); + if (result == 1) + { + GameStatistics.SetPlayCount(DiscHeader->id, 0); + GameStatistics.Save(); + } + } + + //! Settings: Delete Cover Artwork + else if (ret == ++Idx) + { + char GameID[7]; + snprintf(GameID, sizeof(GameID), "%s", (char *) DiscHeader->id); + char filepath[200]; + snprintf(filepath, sizeof(filepath), "%s%s.png", Settings.covers_path, GameID); + + int choice = WindowPrompt(tr( "Delete" ), filepath, tr( "Yes" ), tr( "No" )); + if (choice == 1) + if (CheckFile(filepath)) remove(filepath); + } + + //! Settings: Delete Disc Artwork + else if (ret == ++Idx) + { + char GameID[7]; + snprintf(GameID, sizeof(GameID), "%s", (char *) DiscHeader->id); + char filepath[200]; + snprintf(filepath, sizeof(filepath), "%s%s.png", Settings.disc_path, GameID); + + int choice = WindowPrompt(tr( "Delete" ), filepath, tr( "Yes" ), tr( "No" )); + if (choice == 1) + if (CheckFile(filepath)) remove(filepath); + } + + //! Settings: Delete Cheat TXT + else if (ret == ++Idx) + { + char GameID[7]; + snprintf(GameID, sizeof(GameID), "%s", (char *) DiscHeader->id); + char filepath[200]; + snprintf(filepath, sizeof(filepath), "%s%s.txt", Settings.TxtCheatcodespath, GameID); + + int choice = WindowPrompt(tr( "Delete" ), filepath, tr( "Yes" ), tr( "No" )); + if (choice == 1) + if (CheckFile(filepath)) remove(filepath); + } + + //! Settings: Delete Cheat GCT + else if (ret == ++Idx) + { + char GameID[7]; + snprintf(GameID, sizeof(GameID), "%s", (char *) DiscHeader->id); + char filepath[200]; + snprintf(filepath, sizeof(filepath), "%s%s.gct", Settings.Cheatcodespath, GameID); + + int choice = WindowPrompt(tr( "Delete" ), filepath, tr( "Yes" ), tr( "No" )); + if (choice == 1) + if (CheckFile(filepath)) remove(filepath); + } + + SetOptionValues(); + + return MENU_NONE; +} diff --git a/source/settings/menus/UninstallSM.hpp b/source/settings/menus/UninstallSM.hpp new file mode 100644 index 00000000..e639f589 --- /dev/null +++ b/source/settings/menus/UninstallSM.hpp @@ -0,0 +1,44 @@ + /**************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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 UNINSTALL_MENU_HPP_ +#define UNINSTALL_MENU_HPP_ + +#include "SettingsMenu.hpp" + +class UninstallSM : public SettingsMenu +{ + public: + UninstallSM(struct discHdr * header); + virtual int GetType() { return CUninstallSM; }; + protected: + void SetOptionValues(); + int GetMenuInternal(); + + struct discHdr * DiscHeader; + + OptionList GuiOptions; +}; + + +#endif diff --git a/source/sounds/button_click.pcm b/source/sounds/button_click.pcm deleted file mode 100644 index de3d55e3..00000000 Binary files a/source/sounds/button_click.pcm and /dev/null differ diff --git a/source/sounds/button_click.wav b/source/sounds/button_click.wav new file mode 100644 index 00000000..b0578c50 Binary files /dev/null and b/source/sounds/button_click.wav differ diff --git a/source/sounds/button_click2.pcm b/source/sounds/button_click2.pcm deleted file mode 100644 index 113b4321..00000000 Binary files a/source/sounds/button_click2.pcm and /dev/null differ diff --git a/source/sounds/button_click2.wav b/source/sounds/button_click2.wav new file mode 100644 index 00000000..011c0ada Binary files /dev/null and b/source/sounds/button_click2.wav differ diff --git a/source/sounds/button_over.pcm b/source/sounds/button_over.pcm deleted file mode 100644 index 64f519cf..00000000 Binary files a/source/sounds/button_over.pcm and /dev/null differ diff --git a/source/sounds/button_over.wav b/source/sounds/button_over.wav new file mode 100644 index 00000000..8a06f4b0 Binary files /dev/null and b/source/sounds/button_over.wav differ diff --git a/source/sys.cpp b/source/sys.cpp index 287434fd..2bb16912 100644 --- a/source/sys.cpp +++ b/source/sys.cpp @@ -59,9 +59,14 @@ void AppCleanUp(void) extern u8 mountMethod; gprintf("Exiting main GUI. mountMethod = %d\n", mountMethod); + Settings.Save(); + ExitGUIThreads(); delete bgMusic; + delete btnSoundClick; + delete btnSoundOver; + delete btnSoundClick2; delete background; delete bgImg; delete mainWindow; diff --git a/source/themes/Theme_Downloader.cpp b/source/themes/Theme_Downloader.cpp index 27429d0a..0b7145ec 100644 --- a/source/themes/Theme_Downloader.cpp +++ b/source/themes/Theme_Downloader.cpp @@ -141,11 +141,6 @@ static int Theme_Prompt(const char *title, const char *author, GuiImageData *thu bool leave = false; int result = 0; - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("theme_dialogue_box.png"), Resources::GetFileSize("theme_dialogue_box.png")); @@ -186,8 +181,8 @@ static int Theme_Prompt(const char *title, const char *author, GuiImageData *thu downloadBtnTxt.SetWidescreen(Settings.widescreen); downloadBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton downloadBtn(&downloadBtnImg, &downloadBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 170, &trigA, &btnSoundOver, - btnClick2, 1); + GuiButton downloadBtn(&downloadBtnImg, &downloadBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 170, &trigA, btnSoundOver, + btnSoundClick2, 1); downloadBtn.SetLabel(&downloadBtnTxt); downloadBtn.SetScale(0.9); @@ -199,7 +194,7 @@ static int Theme_Prompt(const char *title, const char *author, GuiImageData *thu backBtnTxt.SetWidescreen(Settings.widescreen); backBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton backBtn(&backBtnImg, &backBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 220, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton backBtn(&backBtnImg, &backBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 220, &trigA, btnSoundOver, btnSoundClick2, 1); backBtn.SetLabel(&backBtnTxt); backBtn.SetTrigger(&trigB); backBtn.SetScale(0.9); @@ -276,13 +271,6 @@ int Theme_Downloader() char THEME_LINK[70]; sprintf(THEME_LINK, "http://wii.spiffy360.com/themes.php?xml=1&category=1&adult=%d", Settings.godmode); - /*** Sound Variables ***/ - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); - /*** Image Variables ***/ GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); @@ -339,8 +327,8 @@ int Theme_Downloader() MainButton[i] = new GuiButton(theme_box_Data.GetWidth(), theme_box_Data.GetHeight()); MainButton[i]->SetAlignment(ALIGN_LEFT, ALIGN_TOP); - MainButton[i]->SetSoundOver(&btnSoundOver); - MainButton[i]->SetSoundClick(&btnClick1); + MainButton[i]->SetSoundOver(btnSoundOver); + MainButton[i]->SetSoundClick(btnSoundClick); MainButton[i]->SetImage(theme_box_img[i]); MainButton[i]->SetEffectGrow(); MainButton[i]->SetTrigger(&trigA); @@ -360,7 +348,7 @@ int Theme_Downloader() backBtnTxt.SetWidescreen(Settings.widescreen); backBtnImg.SetWidescreen(Settings.widescreen); } - GuiButton backBtn(&backBtnImg, &backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton backBtn(&backBtnImg, &backBtnImg, 2, 3, -180, 400, &trigA, btnSoundOver, btnSoundClick2, 1); backBtn.SetLabel(&backBtnTxt); backBtn.SetTrigger(&trigB); @@ -372,8 +360,8 @@ int Theme_Downloader() GoLeftBtn.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); GoLeftBtn.SetPosition(25, -25); GoLeftBtn.SetImage(&GoLeftImg); - GoLeftBtn.SetSoundOver(&btnSoundOver); - GoLeftBtn.SetSoundClick(btnClick2); + GoLeftBtn.SetSoundOver(btnSoundOver); + GoLeftBtn.SetSoundClick(btnSoundClick2); GoLeftBtn.SetEffectGrow(); GoLeftBtn.SetTrigger(&trigA); GoLeftBtn.SetTrigger(&trigL); @@ -384,8 +372,8 @@ int Theme_Downloader() GoRightBtn.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE); GoRightBtn.SetPosition(-25, -25); GoRightBtn.SetImage(&GoRightImg); - GoRightBtn.SetSoundOver(&btnSoundOver); - GoRightBtn.SetSoundClick(btnClick2); + GoRightBtn.SetSoundOver(btnSoundOver); + GoRightBtn.SetSoundClick(btnSoundClick2); GoRightBtn.SetEffectGrow(); GoRightBtn.SetTrigger(&trigA); GoRightBtn.SetTrigger(&trigR); @@ -399,8 +387,8 @@ int Theme_Downloader() PageIndicatorBtn.SetPosition(110, 400); PageIndicatorBtn.SetImage(&PageindicatorImg); PageIndicatorBtn.SetLabel(&PageindicatorTxt); - PageIndicatorBtn.SetSoundOver(&btnSoundOver); - PageIndicatorBtn.SetSoundClick(&btnClick1); + PageIndicatorBtn.SetSoundOver(btnSoundOver); + PageIndicatorBtn.SetSoundClick(btnSoundClick); PageIndicatorBtn.SetTrigger(&trigA); PageIndicatorBtn.SetEffectGrow(); @@ -412,8 +400,8 @@ int Theme_Downloader() GuiButton wifiBtn(wifiImg.GetWidth(), wifiImg.GetHeight()); wifiBtn.SetImage(&wifiImg); wifiBtn.SetPosition(500, 400); - wifiBtn.SetSoundOver(&btnSoundOver); - wifiBtn.SetSoundClick(&btnClick1); + wifiBtn.SetSoundOver(btnSoundOver); + wifiBtn.SetSoundClick(btnSoundClick); wifiBtn.SetEffectGrow(); wifiBtn.SetTrigger(&trigA); diff --git a/source/utils/timer.c b/source/utils/timer.c new file mode 100644 index 00000000..c8b82021 --- /dev/null +++ b/source/utils/timer.c @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include +#include "timer.h" + +bool TimePassed(int limit) +{ + static time_t starttime = 0; + time_t timer = time(NULL); + + if (starttime == 0) + starttime = timer; + + if(difftime(timer, starttime) >= limit) + { + starttime = 0; + return true; + } + + return false; +} + +#define PERIOD_4 (4 * 365 + 1) +#define PERIOD_100 (PERIOD_4 * 25 - 1) +#define PERIOD_400 (PERIOD_100 * 4 + 1) +void ConvertNTFSDate(u64 ulNTFSDate, TimeStruct * ptm) +{ + unsigned year, mon, day, hour, min, sec; + u64 v64 = ulNTFSDate; + u8 ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + unsigned temp; + u32 v; + v64 /= 10000000; + sec = (unsigned)(v64 % 60); + v64 /= 60; + min = (unsigned)(v64 % 60); + v64 /= 60; + hour = (unsigned)(v64 % 24)+1; + v64 /= 24; + + v = (u32)v64; + + year = (unsigned)(1601 + v / PERIOD_400 * 400); + v %= PERIOD_400; + + temp = (unsigned)(v / PERIOD_100); + if (temp == 4) + temp = 3; + year += temp * 100; + v -= temp * PERIOD_100; + + temp = v / PERIOD_4; + if (temp == 25) + temp = 24; + year += temp * 4; + v -= temp * PERIOD_4; + + temp = v / 365; + if (temp == 4) + temp = 3; + year += temp; + v -= temp * 365; + + if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + ms[1] = 29; + for (mon = 1; mon <= 12; mon++) + { + unsigned s = ms[mon - 1]; + if (v < s) + break; + v -= s; + } + day = (unsigned)v + 1; + + ptm->tm_mday = (u32)day; + ptm->tm_mon = (u32)mon; + ptm->tm_year = (u32)year; + + ptm->tm_hour = (u32)hour; + ptm->tm_min = (u32)min; + ptm->tm_sec = (u32)sec; +} + +void ConvertDosDate(u64 ulDosDate, TimeStruct * ptm) +{ + u32 uDate; + uDate = (u32)(ulDosDate>>16); + ptm->tm_mday = (u32)(uDate&0x1f) ; + ptm->tm_mon = (u32)((((uDate)&0x1E0)/0x20)) ; + ptm->tm_year = (u32)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (u32) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (u32) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (u32) (2*(ulDosDate&0x1f)) ; +} diff --git a/source/utils/timer.h b/source/utils/timer.h new file mode 100644 index 00000000..9180a331 --- /dev/null +++ b/source/utils/timer.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#ifndef __TIMER_H +#define __TIMER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef struct _TimeStruct +{ + u32 tm_sec; /* seconds after the minute - [0,59] */ + u32 tm_min; /* minutes after the hour - [0,59] */ + u32 tm_hour; /* hours since midnight - [0,23] */ + u32 tm_mday; /* day of the month - [1,31] */ + u32 tm_mon; /* months since January - [0,11] */ + u32 tm_year; /* years - [1980..2044] */ +} TimeStruct; + +bool TimePassed(int limit); +void ConvertDosDate(u64 ulDosDate, TimeStruct * ptm); +void ConvertNTFSDate(u64 ulNTFSDate, TimeStruct * ptm); + + +#ifdef __cplusplus +} + +class Timer +{ + public: + Timer() { starttick = gettime(); }; + ~Timer() { }; + float elapsed() { return (float) (gettime()-starttick)/(1000.0f*TB_TIMER_CLOCK); }; + float elapsed_millisecs() { return 1000.0f*elapsed(); }; + void reset() { starttick = gettime(); }; + protected: + u64 starttick; +}; + +#endif //__cplusplus + +#endif //__TIMER_H diff --git a/source/utils/uncompress.c b/source/utils/uncompress.c new file mode 100644 index 00000000..049b0386 --- /dev/null +++ b/source/utils/uncompress.c @@ -0,0 +1,185 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#include +#include + +#include "uncompress.h" + +struct _LZ77Info +{ + u16 length : 4; + u16 offset : 12; +} __attribute__((packed)); + +typedef struct _LZ77Info LZ77Info; + +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 = (u8 *) malloc(uncSize); + + if (!buffer) + return buffer; + + u8 *bufCur = buffer; + u8 *bufEnd = buffer + uncSize; + + while (bufCur < bufEnd && inBuf < inBufEnd) + { + u8 flags = *inBuf; + ++inBuf; + int i = 0; + for (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; +} + +//Thanks to _demo_ for this function +//src points to the yaz0 source data (to the "real" source data, not at the header!) +//dst points to a buffer uncompressedSize bytes large (you get uncompressedSize from +//the second 4 bytes in the Yaz0 header). +void uncompressYaz0(const u8* srcBuf, u8* dst, int uncompressedSize) +{ + const u8 * src = srcBuf; + + if(memcmp(src, "Yaz0", 4) == 0) + { + src += sizeof(Yaz0_Header); + } + + int srcPlace = 0, dstPlace = 0; //current read/write positions + + u32 validBitCount = 0; //number of valid bits left in "code" byte + u8 currCodeByte = 0; + + while(dstPlace < uncompressedSize) + { + //read new "code" byte if the current one is used up + if(validBitCount == 0) + { + currCodeByte = src[srcPlace]; + ++srcPlace; + validBitCount = 8; + } + + if((currCodeByte & 0x80) != 0) + { + //straight copy + dst[dstPlace] = src[srcPlace]; + dstPlace++; + srcPlace++; + } + else + { + //RLE part + u8 byte1 = src[srcPlace]; + u8 byte2 = src[srcPlace + 1]; + srcPlace += 2; + + u32 dist = ((byte1 & 0xF) << 8) | byte2; + u32 copySource = dstPlace - (dist + 1); + + u32 numBytes = byte1 >> 4; + if(numBytes == 0) + { + numBytes = src[srcPlace] + 0x12; + srcPlace++; + } + else + numBytes += 2; + + //copy run + u32 i = 0; + for(i = 0; i < numBytes; ++i) + { + dst[dstPlace] = dst[copySource]; + copySource++; + dstPlace++; + } + } + + //use next bit from "code" byte + currCodeByte <<= 1; + validBitCount-=1; + } +} + + +u32 CheckIMD5Type(const u8 * buffer, int length) +{ + if(*((u32 *) buffer) != 'IMD5') + { + return *((u32 *) buffer); + } + + const u8 * file = buffer+32; + + if(*((u32 *) file) != 'LZ77') + { + return *((u32 *) file); + } + + u32 uncSize = 0; + u8 * uncompressed_data = uncompressLZ77(file, length-32, &uncSize); + if(!uncompressed_data) + return 0; + + u32 * magic = (u32 *) uncompressed_data; + u32 Type = magic[0]; + free(uncompressed_data); + + return Type; +} diff --git a/source/utils/uncompress.h b/source/utils/uncompress.h new file mode 100644 index 00000000..2ebb3858 --- /dev/null +++ b/source/utils/uncompress.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2010 + * by Dimok + * + * 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. + * + * for WiiXplorer 2010 + ***************************************************************************/ +#ifndef __UNCOMPRESS_H +#define __UNCOMPRESS_H + +#include + +#define le16(i) (((((u16) i) & 0xFF) << 8) | ((((u16) i) & 0xFF00) >> 8)) +#define le32(i) (((((u32) i) & 0xFF) << 24) | ((((u32) i) & 0xFF00) << 8) | \ + ((((u32) i) & 0xFF0000) >> 8) | ((((u32) i) & 0xFF000000) >> 24)) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + u32 magic; //Yaz0 + u32 decompressed_size; + u8 zeros[8]; +} Yaz0_Header; + +u8 * uncompressLZ77(const u8 *inBuf, u32 inLength, u32 * uncSize); +void uncompressYaz0(const u8* srcBuf, u8* dst, int uncompressedSize); +u32 CheckIMD5Type(const u8 * buffer, int length); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/wad/wad.cpp b/source/wad/wad.cpp index 559c5185..509fe7cb 100644 --- a/source/wad/wad.cpp +++ b/source/wad/wad.cpp @@ -120,11 +120,6 @@ s32 Wad_Install(FILE *fp) promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("dialogue_box.png"), Resources::GetFileSize("dialogue_box.png")); GuiTrigger trigA; @@ -143,7 +138,7 @@ s32 Wad_Install(FILE *fp) btn1Txt.SetWidescreen(Settings.widescreen); btn1Img.SetWidescreen(Settings.widescreen); } - GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -35, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -35, &trigA, btnSoundOver, btnSoundClick2, 1); btn1.SetLabel(&btn1Txt); btn1.SetState(STATE_SELECTED); @@ -305,7 +300,7 @@ s32 Wad_Install(FILE *fp) // Get TMD info tmd_data = (tmd *) SIGNATURE_PAYLOAD(p_tmd); - + char imgPath[150]; // Install contents @@ -439,11 +434,6 @@ s32 Wad_Uninstall(FILE *fp) promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, 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 btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png")); GuiImageData dialogBox(Resources::GetFile("dialogue_box.png"), Resources::GetFileSize("dialogue_box.png")); GuiTrigger trigA; @@ -462,7 +452,7 @@ s32 Wad_Uninstall(FILE *fp) btn1Txt.SetWidescreen(Settings.widescreen); btn1Img.SetWidescreen(Settings.widescreen); } - GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -55, &trigA, &btnSoundOver, btnClick2, 1); + GuiButton btn1(&btn1Img, &btn1Img, 2, 4, 0, -55, &trigA, btnSoundOver, btnSoundClick2, 1); btn1.SetLabel(&btn1Txt); btn1.SetState(STATE_SELECTED);