mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-16 00:15:08 +01:00
* GuiSound stuff rewritten it makes modular
* ogg decoder added (old oggplayer removed) * mp3 decoder added (mp3's cane use as backgroundsounds) * WAVE decoder added (but only uncompressed WAVE's) * AIFF decoder added (only uncrompressed) * BNS decoder added all soundformats can use as backgroundsounds dimoks GameSound class removed it is replaced with the new GuiSound stuff * Many small fixes and other changes
This commit is contained in:
parent
bf6b329822
commit
a0182d0c4c
9
Makefile
9
Makefile
@ -35,7 +35,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -lfat -lpngu -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -ltremor -lmxml -ljpeg
|
||||
LIBS := -lfat -lpngu -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -ltremor -lmad -lmxml -ljpeg
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
@ -67,6 +67,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)))
|
||||
MP3FILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.mp3)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
@ -81,7 +82,7 @@ export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
||||
$(sFILES:.s=.o) $(SFILES:.S=.o) \
|
||||
$(TTFFILES:.ttf=.ttf.o) $(PNGFILES:.png=.png.o) \
|
||||
$(OGGFILES:.ogg=.ogg.o) $(PCMFILES:.pcm=.pcm.o) \
|
||||
$(OGGFILES:.ogg=.ogg.o) $(PCMFILES:.pcm=.pcm.o) $(MP3FILES:.mp3=.mp3.o) \
|
||||
$(addsuffix .o,$(ELFFILES))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
@ -177,6 +178,10 @@ language: $(wildcard $(PROJECTDIR)/Languages/*.lang)
|
||||
@echo $(notdir $<)
|
||||
$(bin2o)
|
||||
|
||||
%.mp3.o : %.mp3
|
||||
@echo $(notdir $<)
|
||||
$(bin2o)
|
||||
|
||||
%.certs.o : %.certs
|
||||
@echo $(notdir $<)
|
||||
$(bin2o)
|
||||
|
@ -1,686 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009
|
||||
* by Hibernatus
|
||||
*
|
||||
* Game_Sound Class by Dimok
|
||||
* Many other modifications and adjustments by Dimok for USB Loader GX
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any
|
||||
* purpose, including commercial applications, and to alter it and
|
||||
* redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you
|
||||
* must not claim that you wrote the original software. If you use
|
||||
* this software in a product, an acknowledgment in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and
|
||||
* must not be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <ogcsys.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "usbloader/disc.h"
|
||||
#include "usbloader/wbfs.h"
|
||||
#include "prompts/PromptWindows.h"
|
||||
#include "libwbfs/libwbfs.h"
|
||||
#include "language/gettext.h"
|
||||
#include "Game_Sound.h"
|
||||
|
||||
|
||||
#define compare(src, str) ((src && str) ? strncasecmp((const char*) src, (const char *) str, strlen((const char *) str)) : -1)
|
||||
|
||||
|
||||
GameSound::GameSound(const u8 * discid)
|
||||
:GuiSound(NULL, 0, SOUND_PCM)
|
||||
{
|
||||
sound = NULL;
|
||||
length = 0;
|
||||
type = SOUND_PCM;
|
||||
voice = 2;
|
||||
volume = 100;
|
||||
loop = false;
|
||||
freq = 0;
|
||||
format = 0;
|
||||
this->LoadSound(discid);
|
||||
}
|
||||
|
||||
GameSound::~GameSound()
|
||||
{
|
||||
Stop();
|
||||
|
||||
if(sound)
|
||||
free(sound);
|
||||
sound = NULL;
|
||||
}
|
||||
|
||||
bool GameSound::Play()
|
||||
{
|
||||
Stop();
|
||||
|
||||
if (!sound || length == 0)
|
||||
return false;
|
||||
if (volume == 0)
|
||||
return true;
|
||||
|
||||
return ASND_SetVoice(voice, format, freq, 0, sound, length, volume, volume, 0) == SND_OK;
|
||||
}
|
||||
|
||||
|
||||
struct IMD5Header
|
||||
{
|
||||
u32 fcc;
|
||||
u32 filesize;
|
||||
u8 zeroes[8];
|
||||
u8 crypto[16];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct IMETHeader
|
||||
{
|
||||
u8 zeroes[64];
|
||||
u32 fcc;
|
||||
u8 unk[8];
|
||||
u32 iconSize;
|
||||
u32 bannerSize;
|
||||
u32 soundSize;
|
||||
u32 flag1;
|
||||
u8 names[7][84];
|
||||
u8 zeroes_2[0x348];
|
||||
u8 crypto[16];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct U8Header
|
||||
{
|
||||
u32 fcc;
|
||||
u32 rootNodeOffset;
|
||||
u32 headerSize;
|
||||
u32 dataOffset;
|
||||
u8 zeroes[16];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct U8Entry
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 fileType : 8;
|
||||
u32 nameOffset : 24;
|
||||
};
|
||||
u32 fileOffset;
|
||||
union
|
||||
{
|
||||
u32 fileLength;
|
||||
u32 numEntries;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
struct LZ77Info
|
||||
{
|
||||
u16 length : 4;
|
||||
u16 offset : 12;
|
||||
} __attribute__((packed));
|
||||
|
||||
static char *u8Filename(const U8Entry *fst, int i)
|
||||
{
|
||||
return (char *)(fst + fst[0].numEntries) + fst[i].nameOffset;
|
||||
}
|
||||
|
||||
struct SWaveHdr
|
||||
{
|
||||
u32 fccRIFF;
|
||||
u32 size;
|
||||
u32 fccWAVE;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct SWaveFmtChunk
|
||||
{
|
||||
u32 fccFMT;
|
||||
u32 size;
|
||||
u16 format;
|
||||
u16 channels;
|
||||
u32 freq;
|
||||
u32 avgBps;
|
||||
u16 alignment;
|
||||
u16 bps;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct SWaveChunk
|
||||
{
|
||||
u32 fcc;
|
||||
u32 size;
|
||||
u8 data;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct SAIFFCommChunk
|
||||
{
|
||||
u32 fccCOMM;
|
||||
u32 size;
|
||||
u16 channels;
|
||||
u32 samples;
|
||||
u16 bps;
|
||||
u8 freq[10];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct SAIFFSSndChunk
|
||||
{
|
||||
u32 fccSSND;
|
||||
u32 size;
|
||||
u32 offset;
|
||||
u32 blockSize;
|
||||
u8 data;
|
||||
} __attribute__((packed));
|
||||
|
||||
inline u32 le32(u32 i)
|
||||
{
|
||||
return ((i & 0xFF) << 24) | ((i & 0xFF00) << 8) | ((i & 0xFF0000) >> 8) | ((i & 0xFF000000) >> 24);
|
||||
}
|
||||
|
||||
inline u16 le16(u16 i)
|
||||
{
|
||||
return ((i & 0xFF) << 8) | ((i & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
static u8 * uncompressLZ77(const u8 *inputBuf, u32 inputLength, u32 &size)
|
||||
{
|
||||
u8 * buffer = NULL;
|
||||
if (inputLength <= 0x8 || compare(inputBuf, "LZ77") != 0 || inputBuf[4] != 0x10)
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
u32 uncSize = le32(((const u32 *)inputBuf)[1] << 8);
|
||||
const u8 *inBuf = inputBuf + 8;
|
||||
const u8 *inBufEnd = inputBuf + inputLength;
|
||||
buffer = (u8 *) malloc(uncSize);
|
||||
if (!buffer)
|
||||
return buffer;
|
||||
u8 *bufCur = buffer;
|
||||
u8 *bufEnd = buffer + uncSize;
|
||||
while (bufCur < bufEnd && inBuf < inBufEnd)
|
||||
{
|
||||
u8 flags = *inBuf;
|
||||
++inBuf;
|
||||
for (int i = 0; i < 8 && bufCur < bufEnd && inBuf < inBufEnd; ++i)
|
||||
{
|
||||
if ((flags & 0x80) != 0)
|
||||
{
|
||||
const LZ77Info &info = *(const LZ77Info *)inBuf;
|
||||
inBuf += sizeof (LZ77Info);
|
||||
int length = info.length + 3;
|
||||
if (bufCur - info.offset - 1 < buffer || bufCur + length > bufEnd)
|
||||
return buffer;
|
||||
memcpy(bufCur, bufCur - info.offset - 1, length);
|
||||
bufCur += length;
|
||||
}
|
||||
else
|
||||
{
|
||||
*bufCur = *inBuf;
|
||||
++inBuf;
|
||||
++bufCur;
|
||||
}
|
||||
flags <<= 1;
|
||||
}
|
||||
}
|
||||
size = uncSize;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void GameSound::LoadSound(const u8 *discid)
|
||||
{
|
||||
if(!discid)
|
||||
return;
|
||||
|
||||
if(sound)
|
||||
free(sound);
|
||||
sound = NULL;
|
||||
|
||||
Disc_SetUSB(NULL);
|
||||
wbfs_disc_t *disc = wbfs_open_disc(GetHddInfo(), (u8 *) discid);
|
||||
if(!disc)
|
||||
{
|
||||
WindowPrompt(tr("Can't find disc"), 0, tr("OK"));
|
||||
return;
|
||||
}
|
||||
wiidisc_t *wdisc = wd_open_disc((int (*)(void *, u32, u32, void *))wbfs_disc_read, disc);
|
||||
if(!wdisc)
|
||||
{
|
||||
WindowPrompt(tr("Could not open Disc"), 0, tr("OK"));
|
||||
return;
|
||||
}
|
||||
u32 size = 0;
|
||||
u8 * snddata = wd_extract_file(wdisc, &size, ALL_PARTITIONS, (char *) "opening.bnr");
|
||||
if(!snddata)
|
||||
{
|
||||
WindowPrompt(tr("ERROR"), tr("Failed to extract opening.bnr"), tr("OK"));
|
||||
return;
|
||||
}
|
||||
|
||||
wd_close_disc(wdisc);
|
||||
wbfs_close_disc(disc);
|
||||
|
||||
const u8 *soundBin;
|
||||
const u8 *bnrArc;
|
||||
const U8Entry *fst;
|
||||
u32 i;
|
||||
const u8 *soundChunk;
|
||||
u32 soundChunkSize;
|
||||
|
||||
const IMETHeader &imetHdr = *(IMETHeader *) snddata;
|
||||
if (compare(&imetHdr.fcc, "IMET") != 0)
|
||||
{
|
||||
WindowPrompt(tr("IMET Header wrong."), 0, tr("OK"));
|
||||
return;
|
||||
}
|
||||
bnrArc = (const u8 *)(&imetHdr + 1);
|
||||
|
||||
const U8Header &bnrArcHdr = *(U8Header *)bnrArc;
|
||||
|
||||
fst = (const U8Entry *)(bnrArc + bnrArcHdr.rootNodeOffset);
|
||||
for (i = 1; i < fst[0].numEntries; ++i)
|
||||
if (fst[i].fileType == 0 && strcasecmp(u8Filename(fst, i), "sound.bin") == 0)
|
||||
break;
|
||||
if (i >= fst[0].numEntries)
|
||||
{
|
||||
return;
|
||||
}
|
||||
soundBin = bnrArc + fst[i].fileOffset;
|
||||
if (compare((&((IMD5Header *)soundBin)->fcc), "IMD5") != 0)
|
||||
{
|
||||
WindowPrompt(tr("IMD5 Header not right."), 0, tr("OK"));
|
||||
return;
|
||||
}
|
||||
soundChunk = soundBin + sizeof (IMD5Header);
|
||||
soundChunkSize = fst[i].fileLength - sizeof (IMD5Header);
|
||||
if (compare(soundChunk, "LZ77") == 0)
|
||||
{
|
||||
u32 uncSize = NULL;
|
||||
u8 * uncompressed_data = uncompressLZ77(soundChunk, soundChunkSize, uncSize);
|
||||
if (!uncompressed_data)
|
||||
{
|
||||
WindowPrompt(tr("Can't decompress LZ77"), 0, tr("OK"));
|
||||
return;
|
||||
}
|
||||
soundChunk = uncompressed_data;
|
||||
soundChunkSize = uncSize;
|
||||
}
|
||||
|
||||
if(compare(soundChunk, "RIFF") == 0)
|
||||
{
|
||||
fromWAV(soundChunk, soundChunkSize);
|
||||
}
|
||||
else if(compare(soundChunk, "BNS ") == 0)
|
||||
{
|
||||
fromBNS(soundChunk, soundChunkSize);
|
||||
}
|
||||
else if(compare(soundChunk, "FORM") == 0)
|
||||
{
|
||||
fromAIFF(soundChunk, soundChunkSize);
|
||||
}
|
||||
|
||||
free(snddata);
|
||||
snddata = NULL;
|
||||
}
|
||||
|
||||
bool GameSound::fromWAV(const u8 *buffer, u32 size)
|
||||
{
|
||||
const u8 *bufEnd = buffer + size;
|
||||
const SWaveHdr &hdr = *(SWaveHdr *)buffer;
|
||||
if (size < sizeof hdr)
|
||||
return false;
|
||||
if (compare(&hdr.fccRIFF, "RIFF") != 0)
|
||||
return false;
|
||||
if (size < le32(hdr.size) + sizeof hdr.fccRIFF + sizeof hdr.size)
|
||||
return false;
|
||||
if (compare(&hdr.fccWAVE, "WAVE") != 0)
|
||||
return false;
|
||||
// Find fmt
|
||||
const SWaveChunk *chunk = (const SWaveChunk *)(buffer + sizeof hdr);
|
||||
while (&chunk->data < bufEnd && compare(&chunk->fcc, "fmt ") != 0)
|
||||
chunk = (const SWaveChunk *)(&chunk->data + le32(chunk->size));
|
||||
if (&chunk->data >= bufEnd)
|
||||
return false;
|
||||
const SWaveFmtChunk &fmtChunk = *(const SWaveFmtChunk *)chunk;
|
||||
// Check format
|
||||
if (le16(fmtChunk.format) != 1)
|
||||
return false;
|
||||
format = (u8)-1;
|
||||
if (le16(fmtChunk.channels) == 1 && le16(fmtChunk.bps) == 8 && le16(fmtChunk.alignment) <= 1)
|
||||
format = VOICE_MONO_8BIT;
|
||||
else if (le16(fmtChunk.channels) == 1 && le16(fmtChunk.bps) == 16 && le16(fmtChunk.alignment) <= 2)
|
||||
format = VOICE_MONO_16BIT;
|
||||
else if (le16(fmtChunk.channels) == 2 && le16(fmtChunk.bps) == 8 && le16(fmtChunk.alignment) <= 2)
|
||||
format = VOICE_STEREO_8BIT;
|
||||
else if (le16(fmtChunk.channels) == 2 && le16(fmtChunk.bps) == 16 && le16(fmtChunk.alignment) <= 4)
|
||||
format = VOICE_STEREO_16BIT;
|
||||
if (format == (u8)-1)
|
||||
return false;
|
||||
freq = le32(fmtChunk.freq);
|
||||
// Find data
|
||||
chunk = (const SWaveChunk *)(&chunk->data + le32(chunk->size));
|
||||
while (&chunk->data < bufEnd && compare(&chunk->fcc, "data") != 0)
|
||||
chunk = (const SWaveChunk *)(&chunk->data + le32(chunk->size));
|
||||
if (compare(&chunk->fcc, "data") != 0 || &chunk->data + le32(chunk->size) > bufEnd)
|
||||
return false;
|
||||
// Data found
|
||||
sound = (u8 *) malloc(le32(chunk->size));
|
||||
if (!sound)
|
||||
return false;
|
||||
memcpy(sound, &chunk->data, le32(chunk->size));
|
||||
length = le32(chunk->size);
|
||||
// Endianness
|
||||
if (le16(fmtChunk.bps) == 16)
|
||||
for (u32 i = 0; i < length / sizeof (u16); ++i)
|
||||
((u16 *) sound)[i] = le16(((u16 *) sound)[i]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------
|
||||
// Copyright (C) 1988-1991 Apple Computer, Inc.
|
||||
#ifndef HUGE_VAL
|
||||
# define HUGE_VAL HUGE
|
||||
#endif
|
||||
|
||||
# define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
|
||||
|
||||
double ConvertFromIeeeExtended(const unsigned char* bytes)
|
||||
{
|
||||
double f;
|
||||
int expon;
|
||||
unsigned long hiMant, loMant;
|
||||
|
||||
expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
|
||||
hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
|
||||
| ((unsigned long)(bytes[3] & 0xFF) << 16)
|
||||
| ((unsigned long)(bytes[4] & 0xFF) << 8)
|
||||
| ((unsigned long)(bytes[5] & 0xFF));
|
||||
loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
|
||||
| ((unsigned long)(bytes[7] & 0xFF) << 16)
|
||||
| ((unsigned long)(bytes[8] & 0xFF) << 8)
|
||||
| ((unsigned long)(bytes[9] & 0xFF));
|
||||
|
||||
if (expon == 0 && hiMant == 0 && loMant == 0) {
|
||||
f = 0;
|
||||
}
|
||||
else {
|
||||
if (expon == 0x7FFF) {
|
||||
f = HUGE_VAL;
|
||||
}
|
||||
else {
|
||||
expon -= 16383;
|
||||
f = ldexp(UnsignedToFloat(hiMant), expon-=31);
|
||||
f += ldexp(UnsignedToFloat(loMant), expon-=32);
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes[0] & 0x80)
|
||||
return -f;
|
||||
else
|
||||
return f;
|
||||
}
|
||||
// ------
|
||||
|
||||
bool GameSound::fromAIFF(const u8 *buffer, u32 size)
|
||||
{
|
||||
const u8 *bufEnd = buffer + size;
|
||||
const SWaveHdr &hdr = *(SWaveHdr *)buffer;
|
||||
if (size < sizeof hdr)
|
||||
return false;
|
||||
if (compare(&hdr.fccRIFF, "FORM") != 0)
|
||||
return false;
|
||||
if (size < hdr.size + sizeof hdr.fccRIFF + sizeof hdr.size)
|
||||
return false;
|
||||
if (compare(&hdr.fccWAVE, "AIFF") != 0)
|
||||
return false;
|
||||
// Find fmt
|
||||
const SWaveChunk *chunk = (const SWaveChunk *)(buffer + sizeof hdr);
|
||||
while (&chunk->data < bufEnd && compare(&chunk->fcc, "COMM") != 0)
|
||||
chunk = (const SWaveChunk *)(&chunk->data + chunk->size);
|
||||
if (&chunk->data >= bufEnd)
|
||||
return false;
|
||||
const SAIFFCommChunk &fmtChunk = *(const SAIFFCommChunk *)chunk;
|
||||
// Check format
|
||||
format = (u8)-1;
|
||||
if (le16(fmtChunk.channels) == 1 && fmtChunk.bps == 8)
|
||||
format = VOICE_MONO_8BIT;
|
||||
else if (fmtChunk.channels == 1 && fmtChunk.bps == 16)
|
||||
format = VOICE_MONO_16BIT;
|
||||
else if (fmtChunk.channels == 2 && fmtChunk.bps == 8)
|
||||
format = VOICE_STEREO_8BIT;
|
||||
else if (fmtChunk.channels == 2 && fmtChunk.bps == 16)
|
||||
format = VOICE_STEREO_16BIT;
|
||||
if (format == (u8)-1)
|
||||
return false;
|
||||
freq = (u32)ConvertFromIeeeExtended(fmtChunk.freq);
|
||||
// Find data
|
||||
chunk = (const SWaveChunk *)(&chunk->data + chunk->size);
|
||||
while (&chunk->data < bufEnd && compare(&chunk->fcc, "SSND") != 0)
|
||||
chunk = (const SWaveChunk *)(&chunk->data + chunk->size);
|
||||
if (compare(&chunk->fcc, "SSND") != 0 || &chunk->data + chunk->size > bufEnd)
|
||||
return false;
|
||||
// Data found
|
||||
const SAIFFSSndChunk &dataChunk = *(const SAIFFSSndChunk *)chunk;
|
||||
sound = (u8 *) malloc(dataChunk.size - 8);
|
||||
if (!sound)
|
||||
return false;
|
||||
memcpy(sound, &dataChunk.data, dataChunk.size - 8);
|
||||
length = dataChunk.size - 8;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct BNSHeader
|
||||
{
|
||||
u32 fccBNS;
|
||||
u32 magic;
|
||||
u32 size;
|
||||
u16 unk1;
|
||||
u16 unk2;
|
||||
u32 infoOffset;
|
||||
u32 infoSize;
|
||||
u32 dataOffset;
|
||||
u32 dataSize;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct BNSInfo
|
||||
{
|
||||
u32 fccINFO;
|
||||
u32 size;
|
||||
u8 codecNum;
|
||||
u8 loopFlag;
|
||||
u8 chanCount;
|
||||
u8 zero;
|
||||
u16 freq;
|
||||
u8 pad1[2];
|
||||
u32 loopStart;
|
||||
u32 loopEnd;
|
||||
u32 offsetToChanStarts;
|
||||
u8 pad2[4];
|
||||
u32 chan1StartOffset;
|
||||
u32 chan2StartOffset;
|
||||
u32 chan1Start;
|
||||
u32 coeff1Offset;
|
||||
u8 pad3[4];
|
||||
u32 chan2Start;
|
||||
u32 coeff2Offset;
|
||||
u8 pad4[4];
|
||||
s16 coefficients1[8][2];
|
||||
u16 chan1Gain;
|
||||
u16 chan1PredictiveScale;
|
||||
s16 chan1PrevSamples[2];
|
||||
u16 chan1LoopPredictiveScale;
|
||||
s16 chan1LoopPrevSamples[2];
|
||||
u16 chan1LoopPadding;
|
||||
s16 coefficients2[8][2];
|
||||
u16 chan2Gain;
|
||||
u16 chan2PredictiveScale;
|
||||
s16 chan2PrevSamples[2];
|
||||
u16 chan2LoopPredictiveScale;
|
||||
s16 chan2LoopPrevSamples[2];
|
||||
u16 chan2LoopPadding;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct BNSData
|
||||
{
|
||||
u32 fccDATA;
|
||||
u32 size;
|
||||
u8 data;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ADPCMByte
|
||||
{
|
||||
s8 sample1 : 4;
|
||||
s8 sample2 : 4;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct BNSADPCMBlock
|
||||
{
|
||||
u8 pad : 1;
|
||||
u8 coeffIndex : 3;
|
||||
u8 lshift : 4;
|
||||
ADPCMByte samples[7];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct BNSDecObj
|
||||
{
|
||||
s16 prevSamples[2];
|
||||
s16 coeff[8][2];
|
||||
};
|
||||
|
||||
static void loadBNSInfo(BNSInfo &bnsInfo, const u8 *buffer)
|
||||
{
|
||||
const u8 *ptr = buffer + 8;
|
||||
bnsInfo = *(const BNSInfo *)buffer;
|
||||
if (bnsInfo.offsetToChanStarts == 0x18 && bnsInfo.chan1StartOffset == 0x20 && bnsInfo.chan2StartOffset == 0x2C
|
||||
&& bnsInfo.coeff1Offset == 0x38 && bnsInfo.coeff2Offset == 0x68)
|
||||
return;
|
||||
bnsInfo.chan1StartOffset = *(const u32 *)(ptr + bnsInfo.offsetToChanStarts);
|
||||
bnsInfo.chan1Start = *(const u32 *)(ptr + bnsInfo.chan1StartOffset);
|
||||
bnsInfo.coeff1Offset = *(const u32 *)(ptr + bnsInfo.chan1StartOffset + 4);
|
||||
if ((u8 *)bnsInfo.coefficients1 != ptr + bnsInfo.coeff1Offset)
|
||||
memcpy(bnsInfo.coefficients1, ptr + bnsInfo.coeff1Offset, (u8 *)bnsInfo.coefficients2 - (u8 *)&bnsInfo.coefficients1);
|
||||
if (bnsInfo.chanCount == 2)
|
||||
{
|
||||
bnsInfo.chan2StartOffset = *(const u32 *)(ptr + bnsInfo.offsetToChanStarts + 4);
|
||||
bnsInfo.chan2Start = *(const u32 *)(ptr + bnsInfo.chan2StartOffset);
|
||||
bnsInfo.coeff2Offset = *(const u32 *)(ptr + bnsInfo.chan2StartOffset + 4);
|
||||
if ((u8 *)bnsInfo.coefficients2 != ptr + bnsInfo.coeff2Offset)
|
||||
memcpy(bnsInfo.coefficients2, ptr + bnsInfo.coeff2Offset, (u8 *)bnsInfo.coefficients2 - (u8 *)&bnsInfo.coefficients1);
|
||||
}
|
||||
}
|
||||
|
||||
static void decodeADPCMBlock(s16 *buffer, const BNSADPCMBlock &block, BNSDecObj &bnsDec)
|
||||
{
|
||||
int h1 = bnsDec.prevSamples[0];
|
||||
int h2 = bnsDec.prevSamples[1];
|
||||
int c1 = bnsDec.coeff[block.coeffIndex][0];
|
||||
int c2 = bnsDec.coeff[block.coeffIndex][1];
|
||||
for (int i = 0; i < 14; ++i)
|
||||
{
|
||||
int nibSample = ((i & 1) == 0) ? block.samples[i / 2].sample1 : block.samples[i / 2].sample2;
|
||||
int sampleDeltaHP = (nibSample << block.lshift) << 11;
|
||||
int predictedSampleHP = c1 * h1 + c2 * h2;
|
||||
int sampleHP = predictedSampleHP + sampleDeltaHP;
|
||||
buffer[i] = std::min(std::max(-32768, (sampleHP + 1024) >> 11), 32767);
|
||||
h2 = h1;
|
||||
h1 = buffer[i];
|
||||
}
|
||||
bnsDec.prevSamples[0] = h1;
|
||||
bnsDec.prevSamples[1] = h2;
|
||||
}
|
||||
|
||||
static u8 * decodeBNS(u32 &size, const BNSInfo &bnsInfo, const BNSData &bnsData)
|
||||
{
|
||||
static s16 smplBlock[14];
|
||||
BNSDecObj decObj;
|
||||
int numBlocks = (bnsData.size - 8) / 8;
|
||||
int numSamples = numBlocks * 14;
|
||||
const BNSADPCMBlock *inputBuf = (const BNSADPCMBlock *)&bnsData.data;
|
||||
u8 * buffer = (u8 *) malloc(numSamples * sizeof (s16));
|
||||
s16 *outputBuf;
|
||||
|
||||
if (!buffer)
|
||||
return buffer;
|
||||
memcpy(decObj.coeff, bnsInfo.coefficients1, sizeof decObj.coeff);
|
||||
memcpy(decObj.prevSamples, bnsInfo.chan1PrevSamples, sizeof decObj.prevSamples);
|
||||
outputBuf = (s16 *)buffer;
|
||||
if (bnsInfo.chanCount == 1)
|
||||
for (int i = 0; i < numBlocks; ++i)
|
||||
{
|
||||
decodeADPCMBlock(smplBlock, inputBuf[i], decObj);
|
||||
memcpy(outputBuf, smplBlock, sizeof smplBlock);
|
||||
outputBuf += 14;
|
||||
}
|
||||
else
|
||||
{
|
||||
numBlocks /= 2;
|
||||
for (int i = 0; i < numBlocks; ++i)
|
||||
{
|
||||
decodeADPCMBlock(smplBlock, inputBuf[i], decObj);
|
||||
for (int j = 0; j < 14; ++j)
|
||||
outputBuf[j * 2] = smplBlock[j];
|
||||
outputBuf += 2 * 14;
|
||||
}
|
||||
outputBuf = (s16 *)buffer + 1;
|
||||
memcpy(decObj.coeff, bnsInfo.coefficients2, sizeof decObj.coeff);
|
||||
memcpy(decObj.prevSamples, bnsInfo.chan2PrevSamples, sizeof decObj.prevSamples);
|
||||
for (int i = 0; i < numBlocks; ++i)
|
||||
{
|
||||
decodeADPCMBlock(smplBlock, inputBuf[numBlocks + i], decObj);
|
||||
for (int j = 0; j < 14; ++j)
|
||||
outputBuf[j * 2] = smplBlock[j];
|
||||
outputBuf += 2 * 14;
|
||||
}
|
||||
}
|
||||
size = numSamples * sizeof (s16);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool GameSound::fromBNS(const u8 *buffer, u32 size)
|
||||
{
|
||||
const BNSHeader &hdr = *(BNSHeader *)buffer;
|
||||
if (size < sizeof hdr)
|
||||
return false;
|
||||
if (compare(&hdr.fccBNS, "BNS ") != 0)
|
||||
return false;
|
||||
// Find info and data
|
||||
BNSInfo infoChunk;
|
||||
loadBNSInfo(infoChunk, buffer + hdr.infoOffset);
|
||||
const BNSData &dataChunk = *(const BNSData *)(buffer + hdr.dataOffset);
|
||||
// Check sizes
|
||||
if (size < hdr.size || size < hdr.infoOffset + hdr.infoSize || size < hdr.dataOffset + hdr.dataSize
|
||||
|| hdr.infoSize < 0x60 || hdr.dataSize < sizeof dataChunk
|
||||
|| infoChunk.size != hdr.infoSize || dataChunk.size != hdr.dataSize)
|
||||
return false;
|
||||
// Check format
|
||||
if (infoChunk.codecNum != 0) // Only codec i've found : 0 = ADPCM. Maybe there's also 1 and 2 for PCM 8 or 16 bits ?
|
||||
return false;
|
||||
format = (u8)-1;
|
||||
if (infoChunk.chanCount == 1 && infoChunk.codecNum == 0)
|
||||
format = VOICE_MONO_16BIT;
|
||||
else if (infoChunk.chanCount == 2 && infoChunk.codecNum == 0)
|
||||
format = VOICE_STEREO_16BIT;
|
||||
if (format == (u8)-1)
|
||||
return false;
|
||||
freq = infoChunk.freq;
|
||||
// Copy data
|
||||
if (infoChunk.codecNum == 0)
|
||||
{
|
||||
sound = decodeBNS(length, infoChunk, dataChunk);
|
||||
if (!sound)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
sound = (u8*) malloc(dataChunk.size);
|
||||
if (!sound)
|
||||
return false;
|
||||
memcpy(sound, &dataChunk.data, dataChunk.size);
|
||||
length = dataChunk.size;
|
||||
}
|
||||
return true;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2009
|
||||
* by Hibernatus
|
||||
*
|
||||
* Game_Sound Class by Dimok
|
||||
* Many other modifications and adjustments by Dimok for USB Loader GX
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any
|
||||
* purpose, including commercial applications, and to alter it and
|
||||
* redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you
|
||||
* must not claim that you wrote the original software. If you use
|
||||
* this software in a product, an acknowledgment in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and
|
||||
* must not be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
***************************************************************************/
|
||||
#ifndef _GAMESOUND_H_
|
||||
#define _GAMESOUND_H_
|
||||
|
||||
#include "libwiigui/gui.h"
|
||||
|
||||
class GameSound : public GuiSound
|
||||
{
|
||||
public:
|
||||
GameSound(const u8 * discid);
|
||||
~GameSound();
|
||||
void LoadSound(const u8 *discid);
|
||||
bool Play();
|
||||
bool fromWAV(const u8 *buffer, u32 size);
|
||||
bool fromAIFF(const u8 *buffer, u32 size);
|
||||
bool fromBNS(const u8 *buffer, u32 size);
|
||||
private:
|
||||
u8 * sound;
|
||||
u32 length;
|
||||
u32 freq;
|
||||
u8 format;
|
||||
};
|
||||
|
||||
#endif
|
@ -22,11 +22,11 @@
|
||||
#include "patches/fst.h"
|
||||
#include "usbloader/fstfile.h"
|
||||
|
||||
s32 dump_banner(const char * discid,const char * dest)
|
||||
s32 dump_banner(const u8* discid,const char * dest)
|
||||
{
|
||||
// Mount the disc
|
||||
//Disc_SetWBFS(1, (u8*)discid);
|
||||
Disc_SetUSB((u8*)discid);
|
||||
Disc_SetUSB(discid);
|
||||
|
||||
Disc_Open();
|
||||
|
||||
@ -108,16 +108,17 @@ s32 dump_banner(const char * discid,const char * dest)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
WDVD_Reset();
|
||||
WDVD_ClosePartition();
|
||||
//fatInitDefault();
|
||||
//SDCard_Init();
|
||||
|
||||
FILE *fp = NULL;
|
||||
fp = fopen(dest, "wb");
|
||||
|
||||
WDVD_SetUSBMode(NULL);
|
||||
FILE *fp = fopen(dest, "wb");
|
||||
if(fp)
|
||||
{
|
||||
fwrite(banner, 1, fst[index].filelen, fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
}
|
||||
free(fstbuffer);
|
||||
free(banner);
|
||||
|
||||
|
@ -13,7 +13,7 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
s32 dump_banner(const char * discid,const char * dest);
|
||||
s32 dump_banner(const u8 *discid,const char * dest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -24,6 +24,9 @@
|
||||
|
||||
#include "MD5.h"
|
||||
#include "banner.h"
|
||||
#include "openingbnr.h"
|
||||
#include "../ramdisk/ramdisk.h"
|
||||
#include "../listfiles.h"
|
||||
|
||||
u16 be16(const u8 *p)
|
||||
{
|
||||
@ -68,7 +71,6 @@ void md5(u8 *data, u32 len, u8 *hash)
|
||||
MD5(hash, data, len);
|
||||
}
|
||||
|
||||
static FILE *fp;
|
||||
|
||||
typedef struct {
|
||||
u8 zeroes[0x40];
|
||||
@ -113,12 +115,17 @@ typedef struct
|
||||
u8 zeroes[16];
|
||||
} U8_archive_header;
|
||||
|
||||
static void write_file(void* data, size_t size, char* name)
|
||||
static int write_file(void* data, size_t size, char* name)
|
||||
{
|
||||
size_t written=0;
|
||||
FILE *out;
|
||||
out = fopen(name, "wb");
|
||||
fwrite(data, 1, size, out);
|
||||
if(out)
|
||||
{
|
||||
written = fwrite(data, 1, size, out);
|
||||
fclose(out);
|
||||
}
|
||||
return (written == size) ? 1 : -1;
|
||||
}
|
||||
|
||||
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size)
|
||||
@ -233,7 +240,7 @@ static int write_imd5_lz77(u8* data, size_t size, char* outname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_U8_archive(void)
|
||||
static int do_U8_archive(FILE *fp)
|
||||
{
|
||||
U8_archive_header header;
|
||||
U8_node root_node;
|
||||
@ -325,7 +332,7 @@ static int do_U8_archive(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void do_imet_header(void)
|
||||
static void do_imet_header(FILE *fp)
|
||||
{
|
||||
imet_data_t header;
|
||||
|
||||
@ -409,57 +416,114 @@ void do_U8_archivebanner(FILE *fp)
|
||||
|
||||
int extractbnrfile(const char * filepath, const char * destpath)
|
||||
{
|
||||
int ret;
|
||||
|
||||
fp = fopen(filepath, "rb");
|
||||
|
||||
mkdir(destpath, 0777);
|
||||
int ret = -1;
|
||||
FILE *fp = fopen(filepath, "rb");
|
||||
if(fp)
|
||||
{
|
||||
subfoldercreate(destpath);
|
||||
chdir(destpath);
|
||||
|
||||
do_imet_header();
|
||||
ret = do_U8_archive();
|
||||
do_imet_header(fp);
|
||||
ret = do_U8_archive(fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int unpackBin(const char * filename,const char * outdir)
|
||||
{
|
||||
FILE *fp;
|
||||
fp = fopen(filename,"rb");
|
||||
FILE *fp = fopen(filename,"rb");;
|
||||
if(fp)
|
||||
{
|
||||
subfoldercreate(outdir);
|
||||
chdir(outdir);
|
||||
|
||||
if(fp!=NULL)
|
||||
do_U8_archivebanner(fp);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TMP_PATH(s) "BANNER:/dump"s
|
||||
//#define TMP_PATH(s) "SD:/dump"s
|
||||
|
||||
int unpackBanner(const u8 *gameid, int what, const char *outdir)
|
||||
{
|
||||
mkdir(outdir, 0777);
|
||||
chdir(outdir);
|
||||
|
||||
do_U8_archivebanner(fp);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unpackBanner(char * gameid, char * outdir)
|
||||
{
|
||||
s32 ret = dump_banner(gameid,"SD:/opening.bnr");
|
||||
if (ret != 1) return -1;
|
||||
|
||||
ret = extractbnrfile("SD:/opening.bnr","SD:/neu");
|
||||
if (ret != 0) return -1;
|
||||
remove("SD:/opening.bnr");
|
||||
char iconpath[60];
|
||||
snprintf(iconpath,sizeof(iconpath),"%s/meta/icon.bin",outdir);
|
||||
ret = unpackBin(iconpath,"SD:/icon");
|
||||
if (ret != 1) return -1;
|
||||
|
||||
if (unlink("/neu/meta/banner.bin") == -1) return -1;
|
||||
if (unlink("/neu/meta/icon.bin") == -1) return -1;
|
||||
if (unlink("/neu/meta/sound.bin") == -1) return -1;
|
||||
if (unlink("/neu/header.imet") == -1) return -1;
|
||||
if (unlink("/neu/meta") == -1) return -1;
|
||||
if (unlink("/neu") == -1) return -1;
|
||||
|
||||
return 1;
|
||||
char path[256];
|
||||
if(!ramdiskMount("BANNER", NULL)) return -1;
|
||||
|
||||
subfoldercreate(TMP_PATH("/"));
|
||||
s32 ret = dump_banner(gameid, TMP_PATH("/opening.bnr"));
|
||||
if (ret != 1)
|
||||
{
|
||||
ret = -1;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
ret = extractbnrfile(TMP_PATH("/opening.bnr"), TMP_PATH("/"));
|
||||
if (ret != 0)
|
||||
{
|
||||
ret = -1;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
if(what & UNPACK_BANNER_BIN)
|
||||
{
|
||||
snprintf(path, sizeof(path),"%sbanner/", outdir);
|
||||
ret = unpackBin(TMP_PATH("/meta/banner.bin"), path);
|
||||
if (ret != 1)
|
||||
{
|
||||
ret = -1;
|
||||
goto error2;
|
||||
}
|
||||
}
|
||||
if(what & UNPACK_ICON_BIN)
|
||||
{
|
||||
snprintf(path, sizeof(path),"%sicon/", outdir);
|
||||
ret = unpackBin(TMP_PATH("/meta/icon.bin"), path);
|
||||
if (ret != 1)
|
||||
{
|
||||
ret = -1;
|
||||
goto error2;
|
||||
}
|
||||
}
|
||||
if(what & UNPACK_SOUND_BIN)
|
||||
{
|
||||
snprintf(path, sizeof(path),"%ssound.bin", outdir);
|
||||
FILE *fp = fopen(TMP_PATH("/meta/sound.bin"), "rb");
|
||||
if(fp)
|
||||
{
|
||||
size_t size;
|
||||
u8 *data;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
if(!size)
|
||||
{
|
||||
ret = -1;
|
||||
goto error;
|
||||
}
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
data = (u8 *)malloc(size);
|
||||
if(!data)
|
||||
{
|
||||
ret = -1;
|
||||
goto error;
|
||||
}
|
||||
if(fread(data, 1, size, fp) != size)
|
||||
{
|
||||
ret = -1;
|
||||
goto error;
|
||||
}
|
||||
ret = write_file(data, size, path);
|
||||
}
|
||||
error: fclose(fp);
|
||||
}
|
||||
ramdiskUnmount("BANNER");
|
||||
error2:
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
return 1;
|
||||
}
|
||||
|
@ -29,8 +29,11 @@ extern "C"
|
||||
//! Files extracted: banner.bin icon.bin and sound.bin
|
||||
int extractbnrfile(const char * filepath, const char * destpath);
|
||||
int unpackBin(const char * filename,const char * outdir);
|
||||
//int unpackBanner(const char * filename,const char * outdir);
|
||||
int unpackBanner(const char * gameid, const char * outdir);
|
||||
#define UNPACK_BANNER_BIN 1 /* extract banner.bin to outdir/banner/ */
|
||||
#define UNPACK_ICON_BIN 2 /* extract icon.bin to outdir/icon/ */
|
||||
#define UNPACK_SOUND_BIN 4 /* copies sound.bin to outdir/sound.bin */
|
||||
#define UNPACK_ALL (UNPACK_SOUND_BIN | UNPACK_ICON_BIN | UNPACK_BANNER_BIN)
|
||||
int unpackBanner(const u8 * gameid, int what, const char *outdir);
|
||||
//! Extract the lz77 compressed banner, icon and sound .bin
|
||||
u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size);
|
||||
|
||||
|
209
source/bannersound.cpp
Normal file
209
source/bannersound.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
#include <stdio.h>
|
||||
#include <ogcsys.h>
|
||||
#include <unistd.h>
|
||||
#include <new>
|
||||
|
||||
#include "usbloader/disc.h"
|
||||
#include "usbloader/wbfs.h"
|
||||
#include "prompts/PromptWindows.h"
|
||||
#include "libwbfs/libwbfs.h"
|
||||
#include "language/gettext.h"
|
||||
#include "bannersound.h"
|
||||
|
||||
|
||||
struct IMD5Header
|
||||
{
|
||||
u32 fcc;
|
||||
u32 filesize;
|
||||
u8 zeroes[8];
|
||||
u8 crypto[16];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct IMETHeader
|
||||
{
|
||||
u8 zeroes[64];
|
||||
u32 fcc;
|
||||
u8 unk[8];
|
||||
u32 iconSize;
|
||||
u32 bannerSize;
|
||||
u32 soundSize;
|
||||
u32 flag1;
|
||||
u8 names[7][84];
|
||||
u8 zeroes_2[0x348];
|
||||
u8 crypto[16];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct U8Header
|
||||
{
|
||||
u32 fcc;
|
||||
u32 rootNodeOffset;
|
||||
u32 headerSize;
|
||||
u32 dataOffset;
|
||||
u8 zeroes[16];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct U8Entry
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 fileType : 8;
|
||||
u32 nameOffset : 24;
|
||||
};
|
||||
u32 fileOffset;
|
||||
union
|
||||
{
|
||||
u32 fileLength;
|
||||
u32 numEntries;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
struct LZ77Info
|
||||
{
|
||||
u16 length : 4;
|
||||
u16 offset : 12;
|
||||
} __attribute__((packed));
|
||||
|
||||
static char *u8Filename(const U8Entry *fst, int i)
|
||||
{
|
||||
return (char *)(fst + fst[0].numEntries) + fst[i].nameOffset;
|
||||
}
|
||||
|
||||
inline u32 le32(u32 i)
|
||||
{
|
||||
return ((i & 0xFF) << 24) | ((i & 0xFF00) << 8) | ((i & 0xFF0000) >> 8) | ((i & 0xFF000000) >> 24);
|
||||
}
|
||||
|
||||
inline u16 le16(u16 i)
|
||||
{
|
||||
return ((i & 0xFF) << 8) | ((i & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
static u8 *uncompressLZ77(const u8 *inBuf, u32 inLength, u32 &size)
|
||||
{
|
||||
u8 *buffer = NULL;
|
||||
if (inLength <= 0x8 || *((const u32 *)inBuf) != 0x4C5A3737 /*"LZ77"*/ || inBuf[4] != 0x10)
|
||||
return NULL;
|
||||
u32 uncSize = le32(((const u32 *)inBuf)[1] << 8);
|
||||
|
||||
const u8 *inBufEnd = inBuf + inLength;
|
||||
inBuf += 8;
|
||||
buffer = new(std::nothrow) u8[uncSize];
|
||||
if (!buffer)
|
||||
return buffer;
|
||||
|
||||
u8 *bufCur = buffer;
|
||||
u8 *bufEnd = buffer + uncSize;
|
||||
|
||||
while (bufCur < bufEnd && inBuf < inBufEnd)
|
||||
{
|
||||
u8 flags = *inBuf;
|
||||
++inBuf;
|
||||
for (int i = 0; i < 8 && bufCur < bufEnd && inBuf < inBufEnd; ++i)
|
||||
{
|
||||
if ((flags & 0x80) != 0)
|
||||
{
|
||||
const LZ77Info &info = *(const LZ77Info *)inBuf;
|
||||
inBuf += sizeof (LZ77Info);
|
||||
int length = info.length + 3;
|
||||
if (bufCur - info.offset - 1 < buffer || bufCur + length > bufEnd)
|
||||
return buffer;
|
||||
memcpy(bufCur, bufCur - info.offset - 1, length);
|
||||
bufCur += length;
|
||||
}
|
||||
else
|
||||
{
|
||||
*bufCur = *inBuf;
|
||||
++inBuf;
|
||||
++bufCur;
|
||||
}
|
||||
flags <<= 1;
|
||||
}
|
||||
}
|
||||
size = uncSize;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const u8 *LoadBannerSound(const u8 *discid, u32 *size)
|
||||
{
|
||||
if(!discid)
|
||||
return NULL;
|
||||
|
||||
Disc_SetUSB(NULL);
|
||||
wbfs_disc_t *disc = wbfs_open_disc(GetHddInfo(), (u8 *) discid);
|
||||
if(!disc)
|
||||
{
|
||||
WindowPrompt(tr("Can't find disc"), 0, tr("OK"));
|
||||
return NULL;
|
||||
}
|
||||
wiidisc_t *wdisc = wd_open_disc((int (*)(void *, u32, u32, void *))wbfs_disc_read, disc);
|
||||
if(!wdisc)
|
||||
{
|
||||
WindowPrompt(tr("Could not open Disc"), 0, tr("OK"));
|
||||
return NULL;
|
||||
}
|
||||
u32 opening_bnr_size = 0;
|
||||
u8 * opening_bnr = wd_extract_file(wdisc, &opening_bnr_size, ALL_PARTITIONS, (char *) "opening.bnr");
|
||||
if(!opening_bnr)
|
||||
{
|
||||
WindowPrompt(tr("ERROR"), tr("Failed to extract opening.bnr"), tr("OK"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wd_close_disc(wdisc);
|
||||
wbfs_close_disc(disc);
|
||||
|
||||
const U8Entry *fst;
|
||||
|
||||
const IMETHeader *imetHdr = (IMETHeader *)opening_bnr;
|
||||
if ( imetHdr->fcc != 0x494D4554 /*"IMET"*/ )
|
||||
{
|
||||
WindowPrompt(tr("IMET Header wrong."), 0, tr("OK"));
|
||||
free(opening_bnr);
|
||||
return NULL;
|
||||
}
|
||||
const U8Header *bnrArcHdr = (U8Header *)(imetHdr + 1);
|
||||
|
||||
fst = (const U8Entry *)( ((const u8 *)bnrArcHdr) + bnrArcHdr->rootNodeOffset);
|
||||
u32 i;
|
||||
for (i = 1; i < fst[0].numEntries; ++i)
|
||||
if (fst[i].fileType == 0 && strcasecmp(u8Filename(fst, i), "sound.bin") == 0)
|
||||
break;
|
||||
if (i >= fst[0].numEntries)
|
||||
{
|
||||
WindowPrompt(tr("sound.bin not found."), 0, tr("OK"));
|
||||
free(opening_bnr);
|
||||
return NULL;
|
||||
}
|
||||
const u8 *sound_bin = ((const u8 *)bnrArcHdr) + fst[i].fileOffset;
|
||||
if ( ((IMD5Header *)sound_bin)->fcc != 0x494D4435 /*"IMD5"*/ )
|
||||
{
|
||||
WindowPrompt(tr("IMD5 Header not right."), 0, tr("OK"));
|
||||
free(opening_bnr);
|
||||
return NULL;
|
||||
}
|
||||
const u8 *soundChunk = sound_bin + sizeof (IMD5Header);;
|
||||
u32 soundChunkSize = fst[i].fileLength - sizeof (IMD5Header);
|
||||
|
||||
if ( *((u32*)soundChunk) == 0x4C5A3737 /*"LZ77"*/ )
|
||||
{
|
||||
u32 uncSize = NULL;
|
||||
u8 * uncompressed_data = uncompressLZ77(soundChunk, soundChunkSize, uncSize);
|
||||
if (!uncompressed_data)
|
||||
{
|
||||
WindowPrompt(tr("Can't decompress LZ77"), 0, tr("OK"));
|
||||
free(opening_bnr);
|
||||
return NULL;
|
||||
}
|
||||
if(size) *size=uncSize;
|
||||
free(opening_bnr);
|
||||
return uncompressed_data;
|
||||
}
|
||||
u8 *out = new(std::nothrow) u8[soundChunkSize];
|
||||
if(out)
|
||||
{
|
||||
memcpy(out, soundChunk, soundChunkSize);
|
||||
if(size) *size=soundChunkSize;
|
||||
}
|
||||
free(opening_bnr);
|
||||
return out;
|
||||
}
|
6
source/bannersound.h
Normal file
6
source/bannersound.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef BANNERSOUND_H
|
||||
#define BANNERSOUND_H
|
||||
|
||||
const u8 *LoadBannerSound(const u8 *discid, u32 *size);
|
||||
|
||||
#endif /* BANNERSOUND_H */
|
@ -28,7 +28,9 @@ int CheatMenu(const char * gameID) {
|
||||
bool exit = false;
|
||||
int ret = 1;
|
||||
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
// because destroy GuiSound must wait while sound playing is finished, we use a global sound
|
||||
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
|
||||
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -45,14 +47,14 @@ int CheatMenu(const char * gameID) {
|
||||
GuiText backBtnTxt(tr("Back") , 22, THEME.prompttext);
|
||||
backBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
|
||||
GuiImage backBtnImg(&btnOutline);
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -140, 400, &trigA, NULL, &btnClick,1);
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -140, 400, &trigA, NULL, btnClick2,1);
|
||||
backBtn.SetLabel(&backBtnTxt);
|
||||
backBtn.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, &btnClick,1);
|
||||
GuiButton createBtn(&createBtnImg,&createBtnImg, 2, 3, 160, 400, &trigA, NULL, btnClick2,1);
|
||||
createBtn.SetLabel(&createBtnTxt);
|
||||
|
||||
char txtfilename[55];
|
||||
|
@ -84,9 +84,11 @@ int MenuHomebrewBrowse() {
|
||||
int slidedirection = FADE;
|
||||
|
||||
/*** Sound Variables ***/
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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 ***/
|
||||
char imgPath[150];
|
||||
@ -153,7 +155,7 @@ int MenuHomebrewBrowse() {
|
||||
backBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
backBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2,1);
|
||||
backBtn.SetLabel(&backBtnTxt);
|
||||
backBtn.SetTrigger(&trigB);
|
||||
|
||||
@ -166,7 +168,7 @@ int MenuHomebrewBrowse() {
|
||||
GoLeftBtn.SetPosition(25, -25);
|
||||
GoLeftBtn.SetImage(&GoLeftImg);
|
||||
GoLeftBtn.SetSoundOver(&btnSoundOver);
|
||||
GoLeftBtn.SetSoundClick(&btnClick);
|
||||
GoLeftBtn.SetSoundClick(btnClick2);
|
||||
GoLeftBtn.SetEffectGrow();
|
||||
GoLeftBtn.SetTrigger(&trigA);
|
||||
GoLeftBtn.SetTrigger(&trigL);
|
||||
@ -178,7 +180,7 @@ int MenuHomebrewBrowse() {
|
||||
GoRightBtn.SetPosition(-25, -25);
|
||||
GoRightBtn.SetImage(&GoRightImg);
|
||||
GoRightBtn.SetSoundOver(&btnSoundOver);
|
||||
GoRightBtn.SetSoundClick(&btnClick);
|
||||
GoRightBtn.SetSoundClick(btnClick2);
|
||||
GoRightBtn.SetEffectGrow();
|
||||
GoRightBtn.SetTrigger(&trigA);
|
||||
GoRightBtn.SetTrigger(&trigR);
|
||||
@ -315,7 +317,7 @@ int MenuHomebrewBrowse() {
|
||||
channelBtn.SetPosition(440, 400);
|
||||
channelBtn.SetImage(&channelBtnImg);
|
||||
channelBtn.SetSoundOver(&btnSoundOver);
|
||||
channelBtn.SetSoundClick(&btnClick);
|
||||
channelBtn.SetSoundClick(btnClick2);
|
||||
channelBtn.SetEffectGrow();
|
||||
channelBtn.SetTrigger(&trigA);
|
||||
|
||||
@ -766,16 +768,9 @@ int MenuHomebrewBrowse() {
|
||||
|
||||
else if (homo.GetState() == STATE_CLICKED) {
|
||||
cfg_save_global();
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) {
|
||||
bgMusic->Play();
|
||||
} else {
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
}
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
|
||||
if (choice == 3) {
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "video.h"
|
||||
#include "filelist.h"
|
||||
#include "input.h"
|
||||
#include "oggplayer.h"
|
||||
|
||||
extern FreeTypeGX *fontSystem;
|
||||
|
||||
@ -76,12 +75,6 @@ enum
|
||||
STATE_DISABLED
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SOUND_PCM,
|
||||
SOUND_OGG
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
IMAGE_TEXTURE,
|
||||
@ -123,23 +116,39 @@ typedef struct _paddata {
|
||||
#define EFFECT_ROCK_VERTICLE 1024
|
||||
#define EFFECT_GOROUND 2048
|
||||
|
||||
#define MAX_SND_VOICES 16
|
||||
#define newGuiSound
|
||||
#define verynewGuiSound
|
||||
|
||||
//!Sound conversion and playback. A wrapper for other sound libraries - ASND, libmad, ltremor, etc
|
||||
class GuiSoundDecoder;
|
||||
class GuiSound
|
||||
{
|
||||
public:
|
||||
//!Constructor
|
||||
//!\param s Pointer to the sound data
|
||||
//!\param l Length of sound data
|
||||
//!\param t Sound format type (SOUND_PCM or SOUND_OGG)
|
||||
GuiSound(const u8 * s, int l, int t);
|
||||
GuiSound(const u8 * s, int l, int t, int v);
|
||||
//!\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();
|
||||
//!Start sound playback from ogg file
|
||||
int PlayOggFile(char * path);
|
||||
//!Stop sound playback
|
||||
void Stop();
|
||||
//!Pause sound playback
|
||||
@ -156,17 +165,21 @@ class GuiSound
|
||||
//!\param l Loop (true to loop)
|
||||
void SetLoop(bool l);
|
||||
//!Get the playing time in ms for that moment (only applies to OGG)
|
||||
s32 GetPlayTime();
|
||||
//!Set the starting point or playtime for skipping (only applies to OGG)
|
||||
//!\param time in ms
|
||||
void SetPlayTime(s32 time);
|
||||
protected:
|
||||
const u8 * sound; //!< Pointer to the sound data
|
||||
int type; //!< Sound format type (SOUND_PCM or SOUND_OGG)
|
||||
s32 length; //!< Length of sound data
|
||||
s32 voice; //!< Currently assigned ASND voice channel
|
||||
s32 volume; //!< Sound volume (0-100)
|
||||
bool loop; //!< Loop sound playback
|
||||
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.
|
||||
|
@ -157,7 +157,7 @@ GuiCustomOptionBrowser::GuiCustomOptionBrowser(int w, int h, customOptionList *
|
||||
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, SOUND_PCM, Settings.sfxvolume);
|
||||
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
|
||||
|
||||
snprintf(imgPath, sizeof(imgPath), "%s%s", themePath, custombg);
|
||||
bgOptions = new GuiImageData(imgPath, imagebg);
|
||||
|
@ -770,3 +770,82 @@ SimpleLock::~SimpleLock()
|
||||
{
|
||||
element->Unlock();
|
||||
}
|
||||
#if 0
|
||||
|
||||
|
||||
GuiElement
|
||||
|
||||
|
||||
protected:
|
||||
void Lock();
|
||||
void Unlock();
|
||||
friend class SimpleLock;
|
||||
private:
|
||||
// static mutex_t mutex;
|
||||
static mutex_t _lock_mutex;
|
||||
lwp_t _lock_thread;
|
||||
u16 _lock_count;
|
||||
lwpq_t _lock_queue;
|
||||
u16 _lock_queue_count;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void GuiElement::Lock()
|
||||
{
|
||||
LWP_MutexLock(_lock_mutex);
|
||||
|
||||
if(_lock_thread = LWP_GetSelf()) // i am self
|
||||
{
|
||||
_lock_count++; // inc count of locks;
|
||||
LWP_MutexUnlock(_lock_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if(_lock_thread == THREAD_NULL) // element is not locked
|
||||
{
|
||||
_lock_thread = LWP_GetSelf();
|
||||
_lock_count = 1;
|
||||
LWP_MutexUnlock(_lock_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
// element is locked
|
||||
if(_lock_queue == LWP_TQUEUE_NULL) // no queue
|
||||
{
|
||||
LWP_InitQueue(&_lock_queue); // init queue
|
||||
_lock_queue_count = 0; // clear count of threads in queue;
|
||||
}
|
||||
_lock_queue_count++; // inc count of threads in queue;
|
||||
LWP_MutexUnlock(_lock_mutex); // unlock
|
||||
LWP_ThreadSleep(_lock_queue); // and sleep
|
||||
LWP_MutexLock(_lock_mutex); // waked up , will lock
|
||||
if(--_lock_queue_count == 0) // dec count of threads in queue;
|
||||
{
|
||||
// is the last thread in queue
|
||||
LWP_CloseQueue(_lock_queue); // close the queue
|
||||
_lock_queue = LWP_TQUEUE_NULL;
|
||||
lock(); // try lock again;
|
||||
}
|
||||
LWP_MutexUnlock(_lock_mutex)
|
||||
return;
|
||||
}
|
||||
void GuiElement::Unlock()
|
||||
{
|
||||
LWP_MutexLock(_lock_mutex);
|
||||
// only the thread was locked this element, can call unlock
|
||||
if(_lock_thread == LWP_GetSelf()) // but we check it here – safe is safe
|
||||
{
|
||||
if(--_lock_queue_count == 0) // dec count of locks;
|
||||
{
|
||||
_lock_thread = THREAD_NULL; // is the last thread in queue
|
||||
if(_lock_queue != LWP_TQUEUE_NULL) // has a queue
|
||||
LWP_ThreadSignal(_lock_queue); // wake the next thread in queue
|
||||
}
|
||||
}
|
||||
LWP_MutexUnlock(_lock_mutex)
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "gui.h"
|
||||
#include "prompts/filebrowser.h"
|
||||
#include "../settings/cfg.h"
|
||||
#include "settings/cfg.h"
|
||||
|
||||
/**
|
||||
* Constructor for the GuiFileBrowser class.
|
||||
@ -31,8 +31,8 @@ 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, SOUND_PCM);
|
||||
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM);
|
||||
btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
|
||||
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbg_browser.png", CFG.theme_path);
|
||||
|
@ -40,7 +40,7 @@ GuiGameBrowser::GuiGameBrowser(int w, int h, struct discHdr * l, int gameCnt, co
|
||||
trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
|
||||
trigHeldA = new GuiTrigger;
|
||||
trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A);
|
||||
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
|
||||
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbg_options.png", themePath);
|
||||
bgGames = new GuiImageData(imgPath, imagebg);
|
||||
|
@ -69,8 +69,8 @@ noCover(nocover_png)
|
||||
trigMinus = new GuiTrigger;
|
||||
trigMinus->SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0);
|
||||
|
||||
btnSoundClick = new GuiSound(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
btnSoundClick = new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
|
||||
btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
|
||||
|
||||
snprintf(imgPath, sizeof(imgPath), "%sstartgame_arrow_left.png", CFG.theme_path);
|
||||
imgLeft = new GuiImageData(imgPath, startgame_arrow_left_png);
|
||||
|
@ -317,8 +317,8 @@ noCover(nocoverFlat_png)
|
||||
trigMinus = new GuiTrigger;
|
||||
trigMinus->SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0);
|
||||
|
||||
btnSoundClick = new GuiSound(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
btnSoundClick = new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
|
||||
btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
|
||||
|
||||
int btnHeight = (int) lround(sqrt(RADIUS*RADIUS - 90000)-RADIUS-50);
|
||||
|
||||
|
@ -343,8 +343,8 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max, int min, int lang)
|
||||
keyLarge = new GuiImageData(keyboard_largekey_over_png);
|
||||
keyLargeOver = new GuiImageData(keyboard_largekey_over_png);
|
||||
|
||||
keySoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
keySoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
keySoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
|
||||
keySoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
|
||||
trigA = new GuiTrigger;
|
||||
trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
|
||||
trigB = new GuiTrigger;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "gui.h"
|
||||
#include "../wpad.h"
|
||||
#include "Settings/cfg.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
@ -37,7 +38,7 @@ GuiOptionBrowser::GuiOptionBrowser(int w, int h, OptionList * l, const u8 *image
|
||||
trigHeldA = new GuiTrigger;
|
||||
trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A);
|
||||
|
||||
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM);
|
||||
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
|
||||
|
||||
bgOptions = new GuiImageData(imagebg);
|
||||
bgOptionsImg = new GuiImage(bgOptions);
|
||||
@ -149,7 +150,7 @@ GuiOptionBrowser::GuiOptionBrowser(int w, int h, OptionList * l, const char *the
|
||||
trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
|
||||
trigHeldA = new GuiTrigger;
|
||||
trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A, PAD_BUTTON_A);
|
||||
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM);
|
||||
btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, Settings.sfxvolume);
|
||||
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbg_options.png", themePath);
|
||||
bgOptions = new GuiImageData(imgPath, imagebg);
|
||||
|
@ -39,8 +39,8 @@ text(NULL, 22, (GXColor) {0, 0, 0, 255}),
|
||||
buttons(0),
|
||||
keyImageData(keyboard_key_png),
|
||||
keyOverImageData(keyboard_key_over_png),
|
||||
sndOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume),
|
||||
sndClick(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume)
|
||||
sndOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume),
|
||||
sndClick(button_click_pcm, button_click_pcm_size, Settings.sfxvolume)
|
||||
{
|
||||
char imgPath[100];
|
||||
trig.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
|
||||
|
@ -5,32 +5,277 @@
|
||||
*
|
||||
* gui_sound.cpp
|
||||
*
|
||||
* decoder modification by ardi 2009
|
||||
*
|
||||
* GUI class definitions
|
||||
***************************************************************************/
|
||||
|
||||
#include "gui.h"
|
||||
#include <unistd.h>
|
||||
#include "gecko.h"
|
||||
|
||||
#include "gui_sound_decoder.h"
|
||||
|
||||
|
||||
#define BUFFER_SIZE 8192
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* D E C O D E R – L I S T
|
||||
*
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
GuiSoundDecoder::DecoderListEntry *GuiSoundDecoder::DecoderList = NULL;
|
||||
GuiSoundDecoder::DecoderListEntry &GuiSoundDecoder::RegisterDecoder(DecoderListEntry &Decoder, GuiSoundDecoderCreate fnc)
|
||||
{
|
||||
if(Decoder.fnc != fnc)
|
||||
{
|
||||
Decoder.fnc = fnc;
|
||||
Decoder.next = DecoderList;
|
||||
DecoderList = &Decoder;
|
||||
}
|
||||
return Decoder;
|
||||
}
|
||||
GuiSoundDecoder *GuiSoundDecoder::GetDecoder(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
for(DecoderListEntry *de = DecoderList; de; de=de->next)
|
||||
{
|
||||
GuiSoundDecoder *d = NULL;
|
||||
try{ d = de->fnc(snd, len, snd_is_allocated); }
|
||||
catch(const char *error){
|
||||
gprintf("%s", error); }
|
||||
catch(...){}
|
||||
if(d) return d;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* D E C O D E R – T H R E A D
|
||||
*
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
static GuiSound *GuiSoundPlayer[16] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
static lwp_t GuiSoundDecoderThreadHandle = LWP_THREAD_NULL;
|
||||
static bool GuiSoundDecoderThreadRunning = false;
|
||||
static bool GuiSoundDecoderDataRquested = false;
|
||||
|
||||
void *GuiSoundDecoderThread(void *args)
|
||||
{
|
||||
GuiSoundDecoderThreadRunning = true;
|
||||
do
|
||||
{
|
||||
if(GuiSoundDecoderDataRquested)
|
||||
{
|
||||
GuiSoundDecoderDataRquested = false;
|
||||
GuiSound **players = GuiSoundPlayer;
|
||||
for( int i = 0; i < 16; ++i , ++players)
|
||||
{
|
||||
GuiSound *player = *players;
|
||||
if(player)
|
||||
player->DecoderCallback();
|
||||
}
|
||||
}
|
||||
if(!GuiSoundDecoderDataRquested)
|
||||
usleep(50);
|
||||
} while(GuiSoundDecoderThreadRunning);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* A S N D – C A L L B A C K
|
||||
*
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
void GuiSoundPlayerCallback(s32 Voice)
|
||||
{
|
||||
if(Voice >= 0 && Voice < 16 && GuiSoundPlayer[Voice])
|
||||
{
|
||||
GuiSoundPlayer[Voice]->PlayerCallback();
|
||||
GuiSoundDecoderDataRquested = true;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* R A W - D E C O D E R
|
||||
* Decoder for Raw-PCM-Datas (16bit Stereo 48kHz)
|
||||
*
|
||||
***************************************************************/
|
||||
class GuiSoundDecoderRAW : public GuiSoundDecoder
|
||||
{
|
||||
protected:
|
||||
GuiSoundDecoderRAW(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
pcm_start = snd;
|
||||
is_allocated = snd_is_allocated;
|
||||
pcm_end = pcm_start+len;
|
||||
pos = pcm_start;
|
||||
is_running = false;
|
||||
|
||||
}
|
||||
public:
|
||||
~GuiSoundDecoderRAW()
|
||||
{
|
||||
while(is_running) usleep(50);
|
||||
if(is_allocated) delete [] pcm_start;
|
||||
}
|
||||
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
try { return new GuiSoundDecoderRAW(snd, len, snd_is_allocated); }
|
||||
catch(...) {}
|
||||
return NULL;
|
||||
}
|
||||
s32 GetFormat()
|
||||
{
|
||||
return VOICE_STEREO_16BIT;
|
||||
}
|
||||
s32 GetSampleRate()
|
||||
{
|
||||
return 48000;
|
||||
}
|
||||
/* Read reads data from stream to buffer
|
||||
return: >0 = readed bytes;
|
||||
0 = EOF;
|
||||
<0 = Error;
|
||||
*/
|
||||
int Read(u8 * buffer, int buffer_size)
|
||||
{
|
||||
if(pos >= pcm_end)
|
||||
return 0; // EOF
|
||||
|
||||
is_running = true;
|
||||
if(pos + buffer_size > pcm_end)
|
||||
buffer_size = pcm_end-pos;
|
||||
memcpy(buffer, pos, buffer_size);
|
||||
pos += buffer_size;
|
||||
is_running = false;
|
||||
return buffer_size;
|
||||
}
|
||||
int Rewind()
|
||||
{
|
||||
pos = pcm_start;
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
const u8 *pcm_start;
|
||||
const u8 *pcm_end;
|
||||
bool is_allocated;
|
||||
const u8 *pos;
|
||||
bool is_running;
|
||||
|
||||
};
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* G u i S o u n d
|
||||
*
|
||||
*
|
||||
***************************************************************/
|
||||
#define GuiSoundBufferReady 0x01
|
||||
#define GuiSoundBufferEOF 0x02
|
||||
#define GuiSoundFinish 0x04
|
||||
static int GuiSoundCount = 0;
|
||||
/**
|
||||
* Constructor for the GuiSound class.
|
||||
*/
|
||||
GuiSound::GuiSound(const u8 * snd, s32 len, int t)
|
||||
GuiSound::GuiSound(const u8 *s, int l, int v/*=100*/, bool r/*=true*/, bool a/*=false*/)
|
||||
{
|
||||
sound = snd;
|
||||
length = len;
|
||||
type = t;
|
||||
if(GuiSoundCount++ == 0 || GuiSoundDecoderThreadHandle == LWP_THREAD_NULL)
|
||||
{
|
||||
LWP_CreateThread(&GuiSoundDecoderThreadHandle,GuiSoundDecoderThread,NULL,NULL,32*1024,80);
|
||||
}
|
||||
voice = -1;
|
||||
volume = 100;
|
||||
loop = false;
|
||||
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);
|
||||
}
|
||||
|
||||
GuiSound::GuiSound(const u8 * snd, s32 len, int t, int v)
|
||||
bool GuiSound::Load(const u8 *s, int l, bool r/*=false*/, bool a/*=false*/)
|
||||
{
|
||||
sound = snd;
|
||||
length = len;
|
||||
type = t;
|
||||
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;
|
||||
volume = v;
|
||||
loop = false;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,145 +283,89 @@ GuiSound::GuiSound(const u8 * snd, s32 len, int t, int v)
|
||||
*/
|
||||
GuiSound::~GuiSound()
|
||||
{
|
||||
if(type == SOUND_OGG)
|
||||
StopOgg();
|
||||
}
|
||||
|
||||
int GuiSound::PlayOggFile(char * path)
|
||||
{ /*
|
||||
u32 filesize = 0;
|
||||
char * bufferogg = NULL;
|
||||
size_t resultogg;
|
||||
|
||||
FILE * pFile;
|
||||
pFile = fopen (path, "rb");
|
||||
|
||||
// get file size:
|
||||
fseek (pFile , 0 , SEEK_END);
|
||||
filesize = ftell (pFile);
|
||||
rewind (pFile);
|
||||
|
||||
// allocate memory to contain the whole file:
|
||||
bufferogg = (char*) malloc (sizeof(char)*filesize);
|
||||
if (bufferogg == NULL) {fputs (" Memory error",stderr); exit (2);}
|
||||
|
||||
// copy the file into the buffer:
|
||||
resultogg = fread (bufferogg,1,filesize,pFile);
|
||||
if (resultogg != filesize) {fputs (" Reading error",stderr); exit (3);}
|
||||
|
||||
fclose (pFile);
|
||||
|
||||
sound = (const u8 *) bufferogg;
|
||||
length = filesize;
|
||||
*/
|
||||
int ret = PlayOggFromFile(path, loop);
|
||||
SetVolumeOgg(255*(volume/100.0));
|
||||
return ret;
|
||||
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()
|
||||
{
|
||||
int vol;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case SOUND_PCM:
|
||||
vol = 255*(volume/100.0);
|
||||
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)
|
||||
ASND_SetVoice(voice, VOICE_STEREO_16BIT, 48000, 0,
|
||||
(u8 *)sound, length, vol, vol, NULL);
|
||||
break;
|
||||
|
||||
case SOUND_OGG:
|
||||
voice = 0;
|
||||
if(loop)
|
||||
PlayOgg(mem_open((char *)sound, length), 0, OGG_INFINITE_TIME);
|
||||
else
|
||||
PlayOgg(mem_open((char *)sound, length), 0, OGG_ONE_TIME);
|
||||
SetVolumeOgg(255*(volume/100.0));
|
||||
break;
|
||||
{
|
||||
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;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case SOUND_PCM:
|
||||
ASND_StopVoice(voice);
|
||||
break;
|
||||
|
||||
case SOUND_OGG:
|
||||
StopOgg();
|
||||
break;
|
||||
}
|
||||
if(voice < 0) return ;
|
||||
GuiSoundPlayer[voice] = NULL; // disable Callbacks
|
||||
SND_StopVoice(voice);
|
||||
voice = -1;
|
||||
}
|
||||
|
||||
void GuiSound::Pause()
|
||||
{
|
||||
if(voice < 0)
|
||||
return;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case SOUND_PCM:
|
||||
if(voice < 0) return ;
|
||||
ASND_PauseVoice(voice, 1);
|
||||
break;
|
||||
|
||||
case SOUND_OGG:
|
||||
PauseOgg(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GuiSound::Resume()
|
||||
{
|
||||
if(voice < 0)
|
||||
return;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case SOUND_PCM:
|
||||
if(voice < 0) return ;
|
||||
ASND_PauseVoice(voice, 0);
|
||||
break;
|
||||
|
||||
case SOUND_OGG:
|
||||
PauseOgg(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool GuiSound::IsPlaying()
|
||||
{
|
||||
if(ASND_StatusVoice(voice) == SND_WORKING || ASND_StatusVoice(voice) == SND_WAITING)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return voice >= 0;
|
||||
}
|
||||
|
||||
void GuiSound::SetVolume(int vol)
|
||||
{
|
||||
volume = vol;
|
||||
|
||||
if(voice < 0)
|
||||
return;
|
||||
|
||||
if(voice < 0) return ;
|
||||
int newvol = 255*(volume/100.0);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case SOUND_PCM:
|
||||
ASND_ChangeVolumeVoice(voice, newvol, newvol);
|
||||
break;
|
||||
|
||||
case SOUND_OGG:
|
||||
SetVolumeOgg(255*(volume/100.0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GuiSound::SetLoop(bool l)
|
||||
@ -184,12 +373,68 @@ void GuiSound::SetLoop(bool l)
|
||||
loop = l;
|
||||
}
|
||||
|
||||
s32 GuiSound::GetPlayTime()
|
||||
void GuiSound::DecoderCallback()
|
||||
{
|
||||
return GetTimeOgg();
|
||||
if(buffer_ready || buffer_eof) // if buffer ready or EOF -> nothing
|
||||
return;
|
||||
bool error=false;
|
||||
while(buffer_pos < BUFFER_SIZE)
|
||||
{
|
||||
int ret = decoder->Read(&play_buffer[buffer_nr][buffer_pos], BUFFER_SIZE-buffer_pos);
|
||||
if(ret > 0)
|
||||
buffer_pos += ret; // ok -> fill the buffer more
|
||||
else if(ret == 0) // EOF from decoder
|
||||
{
|
||||
if(loop)
|
||||
decoder->Rewind(); // if loop -> rewind and fill the buffer more
|
||||
else if(buffer_pos)
|
||||
break; // has data in buffer -> play the buffer
|
||||
else
|
||||
buffer_eof = true; // no data in buffer -> return EOF
|
||||
return;
|
||||
}
|
||||
else if(ret < 0) // an ERROR
|
||||
{
|
||||
if(buffer_pos)
|
||||
break; // has data in buffer -> play the buffer
|
||||
else if(loop)
|
||||
{
|
||||
if(!error) // if no prev error
|
||||
{
|
||||
decoder->Rewind(); // if loop -> rewind
|
||||
error = true; // set error-state
|
||||
continue; // and fill the buffer more
|
||||
}
|
||||
buffer_eof = true; // has prev error -> error in first block -> return EOF
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer_eof = true; // no loop -> return EOF
|
||||
return;
|
||||
}
|
||||
}
|
||||
error = false; // clear error-state
|
||||
}
|
||||
buffer_ready = true;
|
||||
}
|
||||
void GuiSound::PlayerCallback()
|
||||
{
|
||||
if(buffer_eof) // if EOF
|
||||
{
|
||||
if(ASND_TestPointer(voice, play_buffer[(buffer_nr+2)%3])==0) // test prev. Buffer
|
||||
Stop();
|
||||
}
|
||||
else if(buffer_ready) // if buffer ready
|
||||
{
|
||||
if(ASND_AddVoice(voice, play_buffer[buffer_nr], buffer_pos)==SND_OK) // add buffer
|
||||
{
|
||||
// next buffer
|
||||
buffer_nr = (buffer_nr+1)%3;
|
||||
buffer_pos = 0;
|
||||
buffer_ready= false;
|
||||
buffer_eof = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuiSound::SetPlayTime(s32 time_pos)
|
||||
{
|
||||
SetTimeOgg(time_pos);
|
||||
}
|
||||
|
111
source/libwiigui/gui_sound_decoder.h
Normal file
111
source/libwiigui/gui_sound_decoder.h
Normal file
@ -0,0 +1,111 @@
|
||||
/****************************************************************************
|
||||
* libwiigui
|
||||
*
|
||||
* Tantric 2009
|
||||
*
|
||||
* gui_sound_decoder.h
|
||||
*
|
||||
* by ardi 2009
|
||||
*
|
||||
* GUI class definitions
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef GUI_SOUND_DECODER_H
|
||||
#define GUI_SOUND_DECODER_H
|
||||
|
||||
#include <gccore.h>
|
||||
|
||||
#define REGISTER_GUI_SOUND_DECODER(decoder) GuiSoundDecoder::DecoderListEntry decoder##_l = GuiSoundDecoder::RegisterDecoder(decoder##_l, decoder::Create)
|
||||
class GuiSoundDecoder;
|
||||
typedef GuiSoundDecoder *(*GuiSoundDecoderCreate)(const u8 * snd, u32 len, bool snd_is_allocated);
|
||||
|
||||
class GuiSoundDecoder
|
||||
{
|
||||
protected:
|
||||
GuiSoundDecoder(){}; // Constructors must protected so it can create only with Init(...);
|
||||
public:
|
||||
virtual ~GuiSoundDecoder(){};
|
||||
// begin API
|
||||
// ---------
|
||||
// each Decoder must have an own static Create(...) fnc
|
||||
// static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated);
|
||||
virtual s32 GetFormat()=0;
|
||||
virtual s32 GetSampleRate()=0;
|
||||
/* Read reads data from stream to buffer
|
||||
return: >0 = readed bytes;
|
||||
0 = EOF;
|
||||
<0 = Error;
|
||||
*/
|
||||
virtual int Read(u8 * buffer, int buffer_size)=0;
|
||||
// set the stream to the start
|
||||
virtual int Rewind()=0;
|
||||
// -------
|
||||
// end API
|
||||
|
||||
|
||||
struct DecoderListEntry
|
||||
{
|
||||
GuiSoundDecoderCreate fnc;
|
||||
DecoderListEntry *next;
|
||||
};
|
||||
static DecoderListEntry &RegisterDecoder(DecoderListEntry &Decoder, GuiSoundDecoderCreate fnc);
|
||||
static GuiSoundDecoder *GetDecoder(const u8 * snd, u32 len, bool snd_is_allocated);
|
||||
private:
|
||||
static DecoderListEntry *DecoderList;
|
||||
GuiSoundDecoder(GuiSoundDecoder&); // no copy
|
||||
};
|
||||
|
||||
#define BIG_ENDIAN_HOST 1 // Wii PPC is a Big-Endian-Host
|
||||
|
||||
#if BIG_ENDIAN_HOST
|
||||
|
||||
inline uint16_t be16(const uint8_t *p8)
|
||||
{
|
||||
return *((uint16_t*)p8);
|
||||
}
|
||||
inline uint32_t be32(const uint8_t *p8)
|
||||
{
|
||||
return *((uint32_t*)p8);
|
||||
}
|
||||
inline uint16_t le16(const uint8_t *p8)
|
||||
{
|
||||
uint16_t ret = p8[1]<<8 | p8[0];
|
||||
return ret;
|
||||
}
|
||||
inline uint32_t le32(const uint8_t *p8)
|
||||
{
|
||||
uint32_t ret = p8[3]<<24 | p8[2]<<16 | p8[1]<<8 | p8[0];
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif LITTLE_ENDIAN_HOST
|
||||
inline uint16_t be16(const uint8_t *p8)
|
||||
{
|
||||
uint16_t ret = p8[0]<<8 | p8[1];
|
||||
return ret;
|
||||
}
|
||||
inline uint32_t be32(const uint8_t *p8)
|
||||
{
|
||||
uint32_t ret = p8[0]<<24 | p8[1]<<16 | p8[2]<<8 | p8[3];
|
||||
return ret;
|
||||
}
|
||||
inline uint16_t le16(const uint8_t *p8)
|
||||
{
|
||||
return *((uint16_t*)p8);
|
||||
}
|
||||
inline uint32_t le32(const uint8_t *p8)
|
||||
{
|
||||
return *((uint32_t*)p8);
|
||||
}
|
||||
#else
|
||||
#error "BIG_ENDIAN_HOST or LITTLE_ENDIAN_HOST not setted"
|
||||
#endif /* XXX_ENDIAN_HOST */
|
||||
|
||||
#define be16inc(p8) (p8+=2, be16(p8-2))
|
||||
#define le16inc(p8) (p8+=2, le16(p8-2))
|
||||
#define be32inc(p8) (p8+=4, be32(p8-4))
|
||||
#define le32inc(p8) (p8+=4, le32(p8-4))
|
||||
|
||||
|
||||
|
||||
#endif /* GUI_SOUND_DECODER_H */
|
165
source/libwiigui/gui_sound_decoder_aiff.cpp
Normal file
165
source/libwiigui/gui_sound_decoder_aiff.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
/****************************************************************************
|
||||
* libwiigui
|
||||
*
|
||||
* ardi 2009
|
||||
*
|
||||
* gui_sound_plugin_aif.cpp
|
||||
*
|
||||
* GUI class definitions
|
||||
***************************************************************************/
|
||||
|
||||
#include <limits.h>
|
||||
#include <asndlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gui_sound_decoder.h"
|
||||
|
||||
// ------
|
||||
// Copyright (C) 1988-1991 Apple Computer, Inc.
|
||||
#ifndef HUGE_VAL
|
||||
# define HUGE_VAL HUGE
|
||||
#endif
|
||||
|
||||
# define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
|
||||
|
||||
static double ConvertFromIeeeExtended(const u8* bytes)
|
||||
{
|
||||
double f;
|
||||
int expon;
|
||||
u32 hiMant, loMant;
|
||||
|
||||
expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
|
||||
hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
|
||||
| ((unsigned long)(bytes[3] & 0xFF) << 16)
|
||||
| ((unsigned long)(bytes[4] & 0xFF) << 8)
|
||||
| ((unsigned long)(bytes[5] & 0xFF));
|
||||
loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
|
||||
| ((unsigned long)(bytes[7] & 0xFF) << 16)
|
||||
| ((unsigned long)(bytes[8] & 0xFF) << 8)
|
||||
| ((unsigned long)(bytes[9] & 0xFF));
|
||||
|
||||
if (expon == 0 && hiMant == 0 && loMant == 0)
|
||||
f = 0;
|
||||
else
|
||||
{
|
||||
if (expon == 0x7FFF)
|
||||
f = HUGE_VAL;
|
||||
else
|
||||
{
|
||||
expon -= 16383;
|
||||
f = ldexp(UnsignedToFloat(hiMant), expon-=31);
|
||||
f += ldexp(UnsignedToFloat(loMant), expon-=32);
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes[0] & 0x80)
|
||||
return -f;
|
||||
else
|
||||
return f;
|
||||
}
|
||||
// ------
|
||||
|
||||
class GuiSoundDecoderAIFF : public GuiSoundDecoder
|
||||
{
|
||||
protected:
|
||||
GuiSoundDecoderAIFF(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
sound = snd;
|
||||
length =len;
|
||||
is_allocated = snd_is_allocated;
|
||||
is_running = false;
|
||||
|
||||
const u8 *in_ptr = sound;
|
||||
|
||||
if(be32inc(in_ptr) != 0x464F524D /*'FORM'*/) throw("No FORM chunk");
|
||||
if(be32inc(in_ptr)+8 != len) throw("wrong Size");
|
||||
if(be32inc(in_ptr) != 0x41494646 /*'AIFF'*/) throw("No AIFF chunk");
|
||||
|
||||
while(in_ptr+8 < sound+len)
|
||||
{
|
||||
u32 chunk_id = be32inc(in_ptr);
|
||||
u32 chunk_size = be32inc(in_ptr);
|
||||
const u8 *chunk_start = in_ptr;
|
||||
switch(chunk_id)
|
||||
{
|
||||
case 0x434F4D4D /*'COMM'*/:
|
||||
channelCount = be16inc(in_ptr);
|
||||
in_ptr += 4; // skip numSampleFrames
|
||||
bytePerSample = (be16inc(in_ptr)+7)/8;
|
||||
if(bytePerSample < 1 && bytePerSample > 2) throw("wrong bits per Sample");
|
||||
sampleRate = ConvertFromIeeeExtended(in_ptr);
|
||||
break;
|
||||
case 0x53534E44 /*'SSND'*/:
|
||||
pcm_start = in_ptr + 8;
|
||||
pcm_end = chunk_start+chunk_size;
|
||||
break;
|
||||
}
|
||||
in_ptr = chunk_start+chunk_size;
|
||||
}
|
||||
currentPos = sound;
|
||||
}
|
||||
public:
|
||||
~GuiSoundDecoderAIFF()
|
||||
{
|
||||
while(is_running) usleep(50);
|
||||
if(is_allocated) delete [] sound;
|
||||
}
|
||||
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
if(snd && len>12 && snd[0]=='F' && snd[1]=='O' && snd[2]=='R' && snd[3]=='M'
|
||||
&& snd[8]=='A' && snd[9]=='I' && snd[10]=='F' && snd[11]=='F')
|
||||
return new GuiSoundDecoderAIFF(snd, len, snd_is_allocated);
|
||||
return NULL;
|
||||
}
|
||||
s32 GetFormat()
|
||||
{
|
||||
if(bytePerSample == 2)
|
||||
return channelCount==2 ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
|
||||
else
|
||||
return channelCount==2 ? VOICE_STEREO_8BIT : VOICE_MONO_8BIT;
|
||||
}
|
||||
s32 GetSampleRate()
|
||||
{
|
||||
return sampleRate;
|
||||
}
|
||||
/* Read reads data from stream to buffer
|
||||
return: >0 = readed bytes;
|
||||
0 = EOF;
|
||||
<0 = Error;
|
||||
*/
|
||||
int Read(u8 * buffer, int buffer_size)
|
||||
{
|
||||
if(currentPos >= pcm_end)
|
||||
return 0; // EOF
|
||||
|
||||
is_running = true;
|
||||
if(currentPos + buffer_size > pcm_end)
|
||||
buffer_size = pcm_end-currentPos;
|
||||
memcpy(buffer, currentPos, buffer_size);
|
||||
currentPos += buffer_size;
|
||||
is_running = false;
|
||||
return buffer_size;
|
||||
}
|
||||
int Rewind()
|
||||
{
|
||||
while(is_running) usleep(50);
|
||||
currentPos = pcm_start;
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
const u8 *sound;
|
||||
u32 length;
|
||||
bool is_allocated;
|
||||
bool is_running;
|
||||
|
||||
u32 sampleRate;
|
||||
u16 channelCount;
|
||||
u16 bytePerSample;
|
||||
const u8 *pcm_start;
|
||||
const u8 *pcm_end;
|
||||
const u8 *currentPos;
|
||||
};
|
||||
|
||||
REGISTER_GUI_SOUND_DECODER(GuiSoundDecoderAIFF);
|
259
source/libwiigui/gui_sound_decoder_bns.cpp
Normal file
259
source/libwiigui/gui_sound_decoder_bns.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
/****************************************************************************
|
||||
* libwiigui
|
||||
*
|
||||
* Tantric 2009
|
||||
*
|
||||
* gui_sound_plugin_bns.cpp
|
||||
*
|
||||
* by ardi 2009
|
||||
*
|
||||
* Decoder for Wii bns-sound
|
||||
*
|
||||
* GUI class definitions
|
||||
***************************************************************************/
|
||||
|
||||
#include <asndlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gui_sound_decoder.h"
|
||||
#define BIG_ENDIAN_HOST 1
|
||||
|
||||
|
||||
|
||||
|
||||
class chanel_t
|
||||
{
|
||||
public:
|
||||
void Reset()
|
||||
{
|
||||
currentPos = startPos;
|
||||
hist1 = hist2 = 0;
|
||||
}
|
||||
int DecodeNextBlock()
|
||||
{
|
||||
int Offset = 0;
|
||||
if(currentPos == loopStart)
|
||||
{
|
||||
loop_hist1 = hist1;
|
||||
loop_hist2 = hist2;
|
||||
}
|
||||
if(loopStart > startPos && currentPos >= endPos)
|
||||
{
|
||||
currentPos = loopStart;
|
||||
hist1 = loop_hist1;
|
||||
hist2 = loop_hist2;
|
||||
Offset = loopOffset;
|
||||
|
||||
}
|
||||
|
||||
if(currentPos+8 <= endPos)
|
||||
{
|
||||
u16 index = (*currentPos >> 4) & 0x07;
|
||||
s32 scale = 1 << (*currentPos++ & 0x0F);
|
||||
for(int i = 0; i < 14; i+=2)
|
||||
{
|
||||
nibbles[i] = ((s8)*currentPos) >> 4;
|
||||
nibbles[i+1] = ((s8)((*currentPos++) << 4)) >> 4;
|
||||
}
|
||||
for(int i = 0; i < 14; ++i)
|
||||
{
|
||||
s32 sample = (scale * nibbles[i])<<11;
|
||||
sample += coEfficients[index * 2] * hist1;
|
||||
sample += coEfficients[index * 2 + 1] * hist2;
|
||||
sample += 1024;
|
||||
sample = sample >> 11;
|
||||
if(sample > 32767)
|
||||
sample = 32767;
|
||||
else if(sample < -32768)
|
||||
sample = -32768;
|
||||
pcm[i] = sample;
|
||||
|
||||
hist2 = hist1;
|
||||
hist1 = sample;
|
||||
}
|
||||
return Offset;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const u8* startPos;
|
||||
const u8* endPos;
|
||||
const u8* currentPos;
|
||||
s16 coEfficients[16];
|
||||
s16 nibbles[14];
|
||||
s16 pcm[14];
|
||||
s16 hist1;
|
||||
s16 hist2;
|
||||
const u8* loopStart;
|
||||
u16 loopOffset;
|
||||
s16 loop_hist1;
|
||||
s16 loop_hist2;
|
||||
};
|
||||
|
||||
class GuiSoundDecoderBNS : public GuiSoundDecoder
|
||||
{
|
||||
protected:
|
||||
GuiSoundDecoderBNS(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
sound = snd;
|
||||
is_running = false;
|
||||
is_allocated = snd_is_allocated;
|
||||
|
||||
const u8 *in_ptr = sound;
|
||||
|
||||
/////////////////
|
||||
// READ HEADER //
|
||||
/////////////////
|
||||
if(be32inc(in_ptr) != 0x424E5320 /*'BNS '*/) throw("Not a BNS");
|
||||
|
||||
in_ptr += 4; // skip 4 byte
|
||||
|
||||
u32 bnssize = be32inc(in_ptr);
|
||||
if(bnssize != len) throw("Wrong size");
|
||||
|
||||
in_ptr += 4; // skip unknown1
|
||||
|
||||
const u8* infoStart = sound + be32inc(in_ptr);
|
||||
in_ptr+=4; // skip const u8* infoEnd = infoStart + be32inc(in_ptr);
|
||||
|
||||
channel[0].startPos = sound + be32inc(in_ptr) + 8;
|
||||
channel[0].endPos = channel[0].startPos + be32inc(in_ptr) - 8;
|
||||
|
||||
///////////////
|
||||
// READ INFO //
|
||||
///////////////
|
||||
in_ptr = infoStart + 8; // skip 'INFO' and Infosize
|
||||
|
||||
in_ptr++; // skip u8 codeType = *in_ptr++;
|
||||
|
||||
in_ptr++; // u8 loopFlag = *in_ptr++;
|
||||
|
||||
channelCount = *in_ptr++;
|
||||
|
||||
in_ptr++; // skip unknown byte
|
||||
|
||||
sampleRate = be16inc(in_ptr);
|
||||
|
||||
in_ptr+=2; // skip unknown word
|
||||
|
||||
u32 loopStart = be32inc(in_ptr);
|
||||
channel[0].loopStart = channel[0].startPos + ((loopStart/14)*8);//LoopPos to BlockStart
|
||||
channel[1].loopStart = channel[1].startPos + ((loopStart/14)*8);
|
||||
channel[0].loopOffset = channel[1].loopOffset = loopStart%14;
|
||||
|
||||
in_ptr+=4; // skip u32 SampleCount = be32inc(in_ptr);
|
||||
|
||||
in_ptr+=24; // skip unknown Bytes
|
||||
|
||||
if(channelCount == 2)
|
||||
{
|
||||
in_ptr+=4; // skip unknown long
|
||||
u32 ChannelSplit = be32inc(in_ptr);
|
||||
|
||||
in_ptr+=8; // skip 2x unknown long
|
||||
|
||||
channel[1].endPos = channel[0].endPos;
|
||||
channel[0].endPos = channel[1].startPos = channel[0].startPos + ChannelSplit;
|
||||
|
||||
channel[1].loopStart = channel[1].startPos + (channel[0].loopStart - channel[0].startPos);
|
||||
}
|
||||
for (int a = 0; a < 16; a++)
|
||||
{
|
||||
channel[0].coEfficients[a] = (s16)be16inc(in_ptr);
|
||||
}
|
||||
if(channelCount == 2)
|
||||
{
|
||||
in_ptr+=16; // skip 16 byte
|
||||
for (int a = 0; a < 16; a++)
|
||||
{
|
||||
channel[1].coEfficients[a] = (s16)be16inc(in_ptr);
|
||||
}
|
||||
}
|
||||
channel[0].Reset();
|
||||
channel[1].Reset();
|
||||
currentBlockPos = 14;
|
||||
}
|
||||
public:
|
||||
~GuiSoundDecoderBNS()
|
||||
{
|
||||
while(is_running) usleep(50);
|
||||
if(is_allocated) delete [] sound;
|
||||
}
|
||||
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
if(snd && len>4 && snd[0]=='B' && snd[1]=='N' && snd[2]=='S' && snd[3]==' ')
|
||||
return new GuiSoundDecoderBNS(snd, len, snd_is_allocated);
|
||||
return NULL;
|
||||
}
|
||||
s32 GetFormat()
|
||||
{
|
||||
return channelCount==2 ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
|
||||
}
|
||||
s32 GetSampleRate()
|
||||
{
|
||||
return sampleRate;
|
||||
}
|
||||
/* Read reads data from stream to buffer
|
||||
return: >0 = readed bytes;
|
||||
0 = EOF;
|
||||
<0 = Error;
|
||||
*/
|
||||
int Read(u8 * buffer, int buffer_size)
|
||||
{
|
||||
is_running = true;
|
||||
u8 *write_pos = buffer;
|
||||
u8 *write_end = buffer+buffer_size;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(currentBlockPos >= 14)
|
||||
{
|
||||
int Offset = channel[0].DecodeNextBlock();
|
||||
if(Offset<0 || (channelCount == 2 && channel[1].DecodeNextBlock()<0) )
|
||||
{
|
||||
is_running = false;
|
||||
return write_pos-buffer;
|
||||
}
|
||||
currentBlockPos = Offset;
|
||||
}
|
||||
for(;currentBlockPos < 14; ++currentBlockPos)
|
||||
{
|
||||
if(write_pos >= write_end)
|
||||
{
|
||||
is_running = false;
|
||||
return write_pos-buffer;
|
||||
}
|
||||
*((s16*)write_pos) = channel[0].pcm[currentBlockPos];
|
||||
write_pos+=2;
|
||||
if(channelCount==2) // stereo
|
||||
{
|
||||
*((s16*)write_pos) = channel[1].pcm[currentBlockPos];
|
||||
write_pos+=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
is_running = false;
|
||||
return 0;
|
||||
}
|
||||
int Rewind()
|
||||
{
|
||||
channel[0].Reset();
|
||||
channel[1].Reset();
|
||||
currentBlockPos = 14;
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
const u8 *sound;
|
||||
bool is_allocated;
|
||||
bool is_running;
|
||||
chanel_t channel[2];
|
||||
u16 currentBlockPos;
|
||||
u16 channelCount;
|
||||
u32 sampleRate;
|
||||
// u16 loopOffset;
|
||||
// u16 bytePerSample;
|
||||
// const u8 *soundDataStart;
|
||||
// const u8 *soundDataEnd;
|
||||
// u32 soundDataLen;
|
||||
};
|
||||
REGISTER_GUI_SOUND_DECODER(GuiSoundDecoderBNS);
|
214
source/libwiigui/gui_sound_decoder_mpg.cpp
Normal file
214
source/libwiigui/gui_sound_decoder_mpg.cpp
Normal file
@ -0,0 +1,214 @@
|
||||
/****************************************************************************
|
||||
* libwiigui
|
||||
*
|
||||
* Tantric 2009
|
||||
*
|
||||
* gui_sound_plugin_mpg.cpp
|
||||
*
|
||||
* by ardi 2009
|
||||
*
|
||||
* Decoder for MPEG-Audio Mpeg-1/-2 Layer I,II and III with libmad
|
||||
*
|
||||
* GUI class definitions
|
||||
***************************************************************************/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <asndlib.h>
|
||||
#include <mad.h>
|
||||
#include <string.h>
|
||||
#include <new>
|
||||
|
||||
|
||||
#include "gui_sound_decoder.h"
|
||||
|
||||
static inline s16 FixedToShort(mad_fixed_t Fixed)
|
||||
{
|
||||
/* Clipping */
|
||||
if(Fixed>=MAD_F_ONE)
|
||||
return(SHRT_MAX);
|
||||
if(Fixed<=-MAD_F_ONE)
|
||||
return(-SHRT_MAX);
|
||||
|
||||
Fixed=Fixed>>(MAD_F_FRACBITS-15);
|
||||
return((s16)Fixed);
|
||||
}
|
||||
|
||||
#define ADMA_BUFFERSIZE (8192)
|
||||
#define DATABUFFER_SIZE (32768)
|
||||
// http://www.fr-an.de/fragen/v06/02_01.htm
|
||||
|
||||
|
||||
class GuiSoundDecoderMPG : public GuiSoundDecoder
|
||||
{
|
||||
protected:
|
||||
GuiSoundDecoderMPG(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
sound = snd;
|
||||
length = len;
|
||||
is_allocated = snd_is_allocated;
|
||||
// Init mad-structures
|
||||
mad_stream_init(&madStream);
|
||||
mad_stream_buffer(&madStream, sound, length);
|
||||
mad_frame_init(&madFrame);
|
||||
mad_synth_init(&madSynth);
|
||||
madSynthPcmPos = 0;
|
||||
mad_timer_reset(&madTimer);
|
||||
guardBuffer = NULL;
|
||||
is_running = false;
|
||||
|
||||
// decode first Frame
|
||||
if(DecodeFirstFrame())
|
||||
{
|
||||
mad_synth_finish(&madSynth);
|
||||
mad_frame_finish(&madFrame);
|
||||
mad_stream_finish(&madStream);
|
||||
throw("Stream Error");
|
||||
}
|
||||
}
|
||||
public:
|
||||
~GuiSoundDecoderMPG()
|
||||
{
|
||||
while(is_running) usleep(50);
|
||||
mad_synth_finish(&madSynth);
|
||||
mad_frame_finish(&madFrame);
|
||||
mad_stream_finish(&madStream);
|
||||
delete [] guardBuffer;
|
||||
if(is_allocated) delete [] sound;
|
||||
}
|
||||
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
struct mad_stream madStream;
|
||||
struct mad_header madHeader;
|
||||
mad_stream_init(&madStream);
|
||||
mad_stream_buffer(&madStream, snd, len);
|
||||
mad_header_init(&madHeader);
|
||||
s32 ret = mad_header_decode(&madHeader, &madStream);
|
||||
if(ret == 0 || madStream.error==MAD_ERROR_LOSTSYNC) // LOSTSYNC in first call is ok
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4 && mad_header_decode(&madHeader, &madStream)==0; i++);
|
||||
if( i == 4 )
|
||||
{
|
||||
mad_header_finish(&madHeader);
|
||||
mad_stream_finish(&madStream);
|
||||
return new GuiSoundDecoderMPG(snd, len, snd_is_allocated);
|
||||
}
|
||||
}
|
||||
mad_header_finish(&madHeader);
|
||||
mad_stream_finish(&madStream);
|
||||
return NULL;
|
||||
}
|
||||
s32 GetFormat()
|
||||
{
|
||||
return MAD_NCHANNELS(&madFrame.header)==2 ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
|
||||
}
|
||||
s32 GetSampleRate()
|
||||
{
|
||||
return madFrame.header.samplerate;
|
||||
}
|
||||
/* Read reads data from stream to buffer
|
||||
return: >0 = readed bytes;
|
||||
0 = EOF;
|
||||
<0 = Error;
|
||||
*/
|
||||
int Read(u8 * buffer, int buffer_size)
|
||||
{
|
||||
is_running = true;
|
||||
if(MAD_NCHANNELS(&madFrame.header)==2) // stereo
|
||||
buffer_size &= ~0x0003; // make size to a kind of 4
|
||||
else
|
||||
buffer_size &= ~0x0001; // make size to a kind of 2
|
||||
u8 *write_pos = buffer;
|
||||
u8 *write_end = buffer+buffer_size;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
for(;madSynthPcmPos < madSynth.pcm.length; ++madSynthPcmPos)
|
||||
{
|
||||
if(write_pos >= write_end)
|
||||
{
|
||||
is_running = false;
|
||||
return write_pos-buffer;
|
||||
}
|
||||
*((s16*)write_pos) = FixedToShort(madSynth.pcm.samples[0][madSynthPcmPos]); write_pos+=2;
|
||||
if(MAD_NCHANNELS(&madFrame.header)==2) // stereo
|
||||
{
|
||||
*((s16*)write_pos) = FixedToShort(madSynth.pcm.samples[1][madSynthPcmPos]); write_pos+=2;
|
||||
}
|
||||
}
|
||||
|
||||
madStream.error = MAD_ERROR_NONE;
|
||||
if(mad_frame_decode(&madFrame,&madStream))
|
||||
{
|
||||
if(MAD_RECOVERABLE(madStream.error))
|
||||
{
|
||||
if(madStream.error!=MAD_ERROR_LOSTSYNC || !guardBuffer)
|
||||
continue;
|
||||
}
|
||||
else if(madStream.error==MAD_ERROR_BUFLEN)
|
||||
{
|
||||
if(!guardBuffer)
|
||||
{
|
||||
u32 guardLen = (madStream.bufend-madStream.next_frame);
|
||||
guardBuffer = new(std::nothrow) u8[guardLen + MAD_BUFFER_GUARD];
|
||||
if(guardBuffer)
|
||||
{
|
||||
memcpy(guardBuffer, madStream.next_frame, guardLen);
|
||||
memset(guardBuffer+guardLen, 0, MAD_BUFFER_GUARD);
|
||||
mad_stream_buffer(&madStream, guardBuffer, guardLen + MAD_BUFFER_GUARD);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
mad_timer_add(&madTimer,madFrame.header.duration);
|
||||
mad_synth_frame(&madSynth,&madFrame);
|
||||
madSynthPcmPos = 0;
|
||||
}
|
||||
is_running = false;
|
||||
return write_pos-buffer;
|
||||
}
|
||||
int Rewind()
|
||||
{
|
||||
while(is_running) usleep(50);
|
||||
delete [] guardBuffer; guardBuffer = NULL;
|
||||
mad_stream_buffer(&madStream, sound, length);
|
||||
mad_synth_finish(&madSynth);
|
||||
mad_synth_init(&madSynth);
|
||||
madSynthPcmPos = 0;
|
||||
mad_timer_reset(&madTimer);
|
||||
// decode first Frame
|
||||
return DecodeFirstFrame();
|
||||
}
|
||||
private:
|
||||
int DecodeFirstFrame()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
madStream.error = MAD_ERROR_NONE;
|
||||
if(mad_frame_decode(&madFrame,&madStream))
|
||||
{
|
||||
if(MAD_RECOVERABLE(madStream.error))
|
||||
continue;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
mad_timer_add(&madTimer,madFrame.header.duration);
|
||||
mad_synth_frame(&madSynth,&madFrame);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
const u8 *sound;
|
||||
u32 length;
|
||||
bool is_allocated;
|
||||
struct mad_stream madStream;
|
||||
struct mad_frame madFrame;
|
||||
struct mad_synth madSynth;
|
||||
u16 madSynthPcmPos;
|
||||
mad_timer_t madTimer;
|
||||
u8 *guardBuffer;
|
||||
bool is_running;
|
||||
};
|
||||
REGISTER_GUI_SOUND_DECODER(GuiSoundDecoderMPG);
|
94
source/libwiigui/gui_sound_decoder_ogg.cpp
Normal file
94
source/libwiigui/gui_sound_decoder_ogg.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/****************************************************************************
|
||||
* libwiigui
|
||||
*
|
||||
* Tantric 2009
|
||||
*
|
||||
* gui_sound_plugin_ogg.cpp
|
||||
*
|
||||
* by ardi 2009
|
||||
*
|
||||
* Decoder for ogg-vorbis with libtremor
|
||||
*
|
||||
* GUI class definitions
|
||||
***************************************************************************/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <asndlib.h>
|
||||
#include <tremor/ivorbiscodec.h>
|
||||
#include <tremor/ivorbisfile.h>
|
||||
|
||||
#include "gui_sound_decoder.h"
|
||||
|
||||
class GuiSoundDecoderOGG : public GuiSoundDecoder
|
||||
{
|
||||
protected:
|
||||
GuiSoundDecoderOGG(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
sound = snd;
|
||||
is_allocated = snd_is_allocated;
|
||||
ogg_fd = mem_open((char *)snd, len);
|
||||
if(ogg_fd < 0) throw("mem open failed");
|
||||
|
||||
if (ov_open((FILE*)&ogg_fd, &ogg_file, NULL, 0) < 0)
|
||||
{
|
||||
mem_close(ogg_fd);
|
||||
throw("ogg open failed");
|
||||
}
|
||||
ogg_info = ov_info(&ogg_file, -1);
|
||||
bitstream = 0;
|
||||
is_running = false;
|
||||
}
|
||||
public:
|
||||
~GuiSoundDecoderOGG()
|
||||
{
|
||||
while(is_running) usleep(50);
|
||||
ov_clear(&ogg_file);
|
||||
if(is_allocated) delete [] sound;
|
||||
}
|
||||
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
if(snd && len>4 && snd[0]=='O' && snd[1]=='g' && snd[2]=='g' && snd[3]=='S')
|
||||
return new GuiSoundDecoderOGG(snd, len, snd_is_allocated);
|
||||
return NULL;
|
||||
}
|
||||
s32 GetFormat()
|
||||
{
|
||||
return ogg_info->channels==2 ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
|
||||
}
|
||||
s32 GetSampleRate()
|
||||
{
|
||||
return ogg_info->rate;
|
||||
}
|
||||
/* Read reads data from stream to buffer
|
||||
return: >0 = readed bytes;
|
||||
0 = EOF;
|
||||
<0 = Error;
|
||||
*/
|
||||
int Read(u8 * buffer, int buffer_size)
|
||||
{
|
||||
is_running = true;
|
||||
int ret = ov_read(&ogg_file, (char *)buffer, buffer_size, &bitstream);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* error in the stream. Not a problem, just reporting it in
|
||||
case we (the app) cares. In this case, we don't. */
|
||||
if (ret != OV_HOLE)
|
||||
ret = 0; // we says EOF
|
||||
}
|
||||
is_running = false;
|
||||
return ret;
|
||||
}
|
||||
int Rewind()
|
||||
{
|
||||
return ov_time_seek(&ogg_file, 0);
|
||||
}
|
||||
private:
|
||||
const u8 *sound;
|
||||
bool is_allocated;
|
||||
int ogg_fd;
|
||||
OggVorbis_File ogg_file;
|
||||
vorbis_info *ogg_info;
|
||||
int bitstream;
|
||||
bool is_running;
|
||||
};
|
||||
REGISTER_GUI_SOUND_DECODER(GuiSoundDecoderOGG);
|
236
source/libwiigui/gui_sound_decoder_wav.cpp
Normal file
236
source/libwiigui/gui_sound_decoder_wav.cpp
Normal file
@ -0,0 +1,236 @@
|
||||
/****************************************************************************
|
||||
* libwiigui
|
||||
*
|
||||
* Tantric 2009
|
||||
*
|
||||
* gui_sound_plugin_wav.cpp
|
||||
*
|
||||
* by ardi 2009
|
||||
*
|
||||
* Decoder for WAVE PCM
|
||||
*
|
||||
* GUI class definitions
|
||||
***************************************************************************/
|
||||
|
||||
#include <asndlib.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gui_sound_decoder.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 cueID;
|
||||
u32 len;
|
||||
u32 loops;
|
||||
}plst_t;
|
||||
typedef struct
|
||||
{
|
||||
const u8 *start;
|
||||
const u8 *end;
|
||||
u32 loops;
|
||||
}playlist_t;
|
||||
class GuiSoundDecoderWAV : public GuiSoundDecoder
|
||||
{
|
||||
protected:
|
||||
GuiSoundDecoderWAV(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
sound = snd;
|
||||
is_running = false;
|
||||
is_allocated = snd_is_allocated;
|
||||
|
||||
const u8 *in_ptr = sound;
|
||||
|
||||
if(be32inc(in_ptr) != 0x52494646 /*'RIFF' (WAV)*/) throw("Not a WAV");
|
||||
|
||||
u32 riffsize = le32inc(in_ptr);
|
||||
if(riffsize > (len-8)) throw("Wrong size");
|
||||
|
||||
if(be32inc(in_ptr) != 0x57415645 /*'WAVE'*/) throw("No WAVE-Tag");
|
||||
|
||||
if(be32inc(in_ptr) != 0x666D7420 /*'fmt '*/) throw("No fmt-Tag");
|
||||
|
||||
u32 fmtLen = le32inc(in_ptr);
|
||||
|
||||
if(le16inc(in_ptr) != 1) throw("Not PCM data");
|
||||
|
||||
channelCount = le16inc(in_ptr);
|
||||
if(channelCount < 1 || channelCount > 2) throw("only mono or stereo");
|
||||
|
||||
sampleRate = le32inc(in_ptr);
|
||||
|
||||
in_ptr += 6; // skip <bytes/second> and <block align>
|
||||
|
||||
bytePerSample = (le16inc(in_ptr)+7)/8;
|
||||
if(bytePerSample < 1 || bytePerSample > 2) throw("only 1-16 bit/Sample");
|
||||
|
||||
in_ptr += fmtLen-16;
|
||||
|
||||
if(be32inc(in_ptr) != 0x64617461 /*'data'*/) throw("No data-Tag");
|
||||
|
||||
|
||||
soundDataStart = in_ptr+4;
|
||||
soundDataEnd = soundDataStart + le32(in_ptr);
|
||||
|
||||
in_ptr = soundDataEnd;
|
||||
|
||||
std::map<u32, u32> cue;
|
||||
std::vector<plst_t>plst;
|
||||
|
||||
if(((u32)in_ptr) & 0x0001UL) in_ptr++;
|
||||
while((in_ptr+4) < (sound + riffsize))
|
||||
{
|
||||
u32 tag = be32inc(in_ptr);
|
||||
switch(tag)
|
||||
{
|
||||
case 0x63756520 /*'cue '*/:
|
||||
in_ptr += 4; // skip size
|
||||
for(u32 count = le32inc(in_ptr); count>0; count--)
|
||||
{
|
||||
u32 ID = be32inc(in_ptr);
|
||||
in_ptr += 4; // skip dwPosition
|
||||
if(be32inc(in_ptr) == 0x64617461 /*'data'*/)
|
||||
{
|
||||
in_ptr += 8; // skip chunkStart - dwBlockStart
|
||||
cue[ID] = le32inc(in_ptr);
|
||||
}
|
||||
else
|
||||
in_ptr += 12; // skip chunkStart - SammpleOffset
|
||||
}
|
||||
break;
|
||||
case 0x706C7374 /*' plst'*/:
|
||||
in_ptr += 4; // skip size
|
||||
for(u32 count = le32inc(in_ptr); count>0; count--)
|
||||
plst.push_back((plst_t){le32inc(in_ptr), le32inc(in_ptr), le32inc(in_ptr)});
|
||||
break;
|
||||
default:
|
||||
in_ptr -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(std::vector<plst_t>::iterator i = plst.begin(); i != plst.end(); ++i)
|
||||
{
|
||||
const u8 *start = soundDataStart + cue[i->cueID];
|
||||
const u8 *end = soundDataStart + (i->len*bytePerSample*channelCount);
|
||||
u32 loops = i->loops;
|
||||
playlist.push_back((playlist_t){start,end,loops});
|
||||
}
|
||||
if(playlist.size() == 0)
|
||||
{
|
||||
playlist.push_back((playlist_t){soundDataStart, soundDataEnd, 1});
|
||||
}
|
||||
Rewind();
|
||||
}
|
||||
public:
|
||||
~GuiSoundDecoderWAV()
|
||||
{
|
||||
while(is_running) usleep(50);
|
||||
if(is_allocated) delete [] sound;
|
||||
}
|
||||
static GuiSoundDecoder *Create(const u8 * snd, u32 len, bool snd_is_allocated)
|
||||
{
|
||||
if(snd && len>4 && snd[0]=='R' && snd[1]=='I' && snd[2]=='F' && snd[3]=='F'
|
||||
&& snd[8]=='W' && snd[9]=='A' && snd[10]=='V' && snd[11]=='E')
|
||||
return new GuiSoundDecoderWAV(snd, len, snd_is_allocated);
|
||||
return NULL;
|
||||
}
|
||||
s32 GetFormat()
|
||||
{
|
||||
if(bytePerSample == 2)
|
||||
return channelCount==2 ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
|
||||
else
|
||||
return channelCount==2 ? VOICE_STEREO_8BIT : VOICE_MONO_8BIT;
|
||||
}
|
||||
s32 GetSampleRate()
|
||||
{
|
||||
return sampleRate;
|
||||
}
|
||||
/* Read reads data from stream to buffer
|
||||
return: >0 = readed bytes;
|
||||
0 = EOF;
|
||||
<0 = Error;
|
||||
*/
|
||||
int Read(u8 * buffer, int buffer_size)
|
||||
{
|
||||
is_running = true;
|
||||
u8 *write_pos = buffer;
|
||||
u8 *write_end = buffer+buffer_size;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
while(currentPos < currentEnd)
|
||||
{
|
||||
if(write_pos >= write_end)
|
||||
{
|
||||
is_running = false;
|
||||
return write_pos-buffer;
|
||||
}
|
||||
if(bytePerSample == 2)
|
||||
{
|
||||
*((s16*)write_pos) = le16inc(currentPos);
|
||||
write_pos+=2;
|
||||
if(channelCount==2) // stereo
|
||||
{
|
||||
*((s16*)write_pos) = le16inc(currentPos);
|
||||
write_pos+=2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*write_pos++ = *currentPos++;
|
||||
if(channelCount==2) // stereo
|
||||
*write_pos++ = *currentPos++;
|
||||
}
|
||||
}
|
||||
if(currentLoops>1)
|
||||
{
|
||||
currentLoops--;
|
||||
currentPos = currentStart;
|
||||
continue;
|
||||
}
|
||||
if(currentPlaylist != playlist.end())
|
||||
currentPlaylist++;
|
||||
if(currentPlaylist != playlist.end())
|
||||
{
|
||||
currentStart = currentPos = currentPlaylist->start;
|
||||
currentEnd = currentPlaylist->end;
|
||||
currentLoops = currentPlaylist->loops;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_running = false;
|
||||
return write_pos-buffer;
|
||||
}
|
||||
}
|
||||
is_running = false;
|
||||
return 0;
|
||||
}
|
||||
int Rewind()
|
||||
{
|
||||
currentPlaylist = playlist.begin();
|
||||
currentStart = currentPos = currentPlaylist->start;
|
||||
currentEnd = currentPlaylist->end;
|
||||
currentLoops = currentPlaylist->loops;
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
const u8 *sound;
|
||||
bool is_allocated;
|
||||
bool is_running;
|
||||
|
||||
u16 channelCount;
|
||||
u32 sampleRate;
|
||||
u16 bytePerSample;
|
||||
const u8 *soundDataStart;
|
||||
const u8 *soundDataEnd;
|
||||
std::vector<playlist_t> playlist;
|
||||
std::vector<playlist_t>::iterator currentPlaylist;
|
||||
const u8 *currentStart;
|
||||
const u8 *currentEnd;
|
||||
u32 currentLoops;
|
||||
const u8 *currentPos;
|
||||
|
||||
};
|
||||
REGISTER_GUI_SOUND_DECODER(GuiSoundDecoderWAV);
|
@ -40,7 +40,7 @@ bool subfoldercreate(const char * fullpath) {
|
||||
|
||||
strlcpy(dir, fullpath, sizeof(dir));
|
||||
len = strlen(dir);
|
||||
if(len && len< sizeof(dir)-2 && dir[len-1] != '/');
|
||||
if(len && len< sizeof(dir)-2 && dir[len-1] != '/')
|
||||
{
|
||||
dir[len++] = '/';
|
||||
dir[len] = '\0';
|
||||
@ -63,7 +63,42 @@ bool subfoldercreate(const char * fullpath) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool subfolderremove(const char * fullpath, const char*fp) {
|
||||
struct stat st;
|
||||
if (stat(fullpath, &st) != 0) // fullpath not exist?
|
||||
return false;
|
||||
if(S_ISDIR(st.st_mode))
|
||||
{
|
||||
DIR_ITER *dir = NULL;
|
||||
char filename[256];
|
||||
bool cont = true;
|
||||
while(cont)
|
||||
{
|
||||
cont = false;
|
||||
dir = diropen(fullpath);
|
||||
if(dir)
|
||||
{
|
||||
char* bind = fullpath[strlen(fullpath)-1] == '/' ? "":"/";
|
||||
while (dirnext(dir,filename,&st) == 0)
|
||||
{
|
||||
if (strcmp(filename,".") != 0 && strcmp(filename,"..") != 0)
|
||||
{
|
||||
char currentname[256];
|
||||
if(S_ISDIR(st.st_mode))
|
||||
snprintf(currentname, sizeof(currentname), "%s%s%s/", fullpath, bind, filename);
|
||||
else
|
||||
snprintf(currentname, sizeof(currentname), "%s%s%s", fullpath, bind, filename);
|
||||
subfolderremove(currentname, fp);
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
return unlink(fullpath) == 0;
|
||||
}
|
||||
char * GetFileName(int i) {
|
||||
return alldirfiles[i];
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ u64 getStubDest()
|
||||
|
||||
|
||||
char *stub = (char *)0x800024C6;
|
||||
char ret[8];
|
||||
char ret[9];
|
||||
u64 retu =0;
|
||||
|
||||
ret[0] = stub[0];
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "FreeTypeGX.h"
|
||||
|
||||
extern struct SSettings Settings;
|
||||
|
||||
void DefaultSettings();
|
||||
extern FreeTypeGX *fontSystem;
|
||||
|
@ -62,6 +62,8 @@ GuiImageData * pointer[4];
|
||||
GuiImage * bgImg = NULL;
|
||||
GuiImageData * background = NULL;
|
||||
GuiSound * bgMusic = NULL;
|
||||
GuiSound *btnClick2 = NULL;
|
||||
|
||||
float gamesize;
|
||||
int currentMenu;
|
||||
int idiotFlag=-1;
|
||||
@ -371,8 +373,10 @@ int MenuDiscList() {
|
||||
}
|
||||
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_install.png", CFG.theme_path);
|
||||
GuiImageData btnInstall(imgPath, button_install_png);
|
||||
@ -485,7 +489,7 @@ int MenuDiscList() {
|
||||
installBtnImg.SetWidescreen(CFG.widescreen);
|
||||
installBtnImgOver.SetWidescreen(CFG.widescreen);
|
||||
|
||||
GuiButton installBtn(&installBtnImg, &installBtnImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.install_x, THEME.install_y, &trigA, &btnSoundOver, &btnClick, 1, &installBtnTT,24,-30, 0,5);
|
||||
GuiButton installBtn(&installBtnImg, &installBtnImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.install_x, THEME.install_y, &trigA, &btnSoundOver, btnClick2, 1, &installBtnTT,24,-30, 0,5);
|
||||
|
||||
|
||||
GuiTooltip settingsBtnTT(tr("Settings"));
|
||||
@ -496,7 +500,7 @@ int MenuDiscList() {
|
||||
settingsBtnImg.SetWidescreen(CFG.widescreen);
|
||||
GuiImage settingsBtnImgOver(&btnSettingsOver);
|
||||
settingsBtnImgOver.SetWidescreen(CFG.widescreen);
|
||||
GuiButton settingsBtn(&settingsBtnImg,&settingsBtnImgOver, 0, 3, THEME.setting_x, THEME.setting_y, &trigA, &btnSoundOver, &btnClick,1,&settingsBtnTT,65,-30,0,5);
|
||||
GuiButton settingsBtn(&settingsBtnImg,&settingsBtnImgOver, 0, 3, THEME.setting_x, THEME.setting_y, &trigA, &btnSoundOver, btnClick2,1,&settingsBtnTT,65,-30,0,5);
|
||||
|
||||
GuiTooltip homeBtnTT(tr("Back to HBC or Wii Menu"));
|
||||
if (Settings.wsprompt == yes)
|
||||
@ -506,7 +510,7 @@ int MenuDiscList() {
|
||||
homeBtnImg.SetWidescreen(CFG.widescreen);
|
||||
GuiImage homeBtnImgOver(&btnhomeOver);
|
||||
homeBtnImgOver.SetWidescreen(CFG.widescreen);
|
||||
GuiButton homeBtn(&homeBtnImg,&homeBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, &btnClick,1,&homeBtnTT,15,-30,1,5);
|
||||
GuiButton homeBtn(&homeBtnImg,&homeBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, btnClick2,1,&homeBtnTT,15,-30,1,5);
|
||||
homeBtn.RemoveSoundClick();
|
||||
homeBtn.SetTrigger(&trigHome);
|
||||
|
||||
@ -518,7 +522,7 @@ int MenuDiscList() {
|
||||
GuiImage poweroffBtnImgOver(&btnpwroffOver);
|
||||
poweroffBtnImg.SetWidescreen(CFG.widescreen);
|
||||
poweroffBtnImgOver.SetWidescreen(CFG.widescreen);
|
||||
GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, &btnClick,1,&poweroffBtnTT,-10,-30,1,5);
|
||||
GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, btnClick2,1,&poweroffBtnTT,-10,-30,1,5);
|
||||
|
||||
|
||||
GuiTooltip sdcardBtnTT(tr("Reload SD"));
|
||||
@ -529,16 +533,16 @@ int MenuDiscList() {
|
||||
GuiImage sdcardImgOver(&btnsdcardOver);
|
||||
sdcardImg.SetWidescreen(CFG.widescreen);
|
||||
sdcardImgOver.SetWidescreen(CFG.widescreen);
|
||||
GuiButton sdcardBtn(&sdcardImg,&sdcardImgOver, 0, 3, THEME.sdcard_x, THEME.sdcard_y, &trigA, &btnSoundOver, &btnClick,1,&sdcardBtnTT,15,-30,0,5);
|
||||
GuiButton sdcardBtn(&sdcardImg,&sdcardImgOver, 0, 3, THEME.sdcard_x, THEME.sdcard_y, &trigA, &btnSoundOver, btnClick2,1,&sdcardBtnTT,15,-30,0,5);
|
||||
|
||||
GuiButton gameInfo(0,0);
|
||||
gameInfo.SetTrigger(&trig2);
|
||||
gameInfo.SetSoundClick(&btnClick);
|
||||
gameInfo.SetSoundClick(btnClick2);
|
||||
|
||||
|
||||
GuiImage wiiBtnImg(&dataID);
|
||||
wiiBtnImg.SetWidescreen(CFG.widescreen);
|
||||
GuiButton wiiBtn(&wiiBtnImg,&wiiBtnImg, 0, 4, 0, -10, &trigA, &btnSoundOver, &btnClick,0);
|
||||
GuiButton wiiBtn(&wiiBtnImg,&wiiBtnImg, 0, 4, 0, -10, &trigA, &btnSoundOver, btnClick2,0);
|
||||
|
||||
GuiTooltip favoriteBtnTT(tr("Display favorites"));
|
||||
if (Settings.wsprompt == yes)
|
||||
@ -550,7 +554,7 @@ int MenuDiscList() {
|
||||
GuiImage favoriteBtnImg_g(&imgfavIcon_gray);
|
||||
if(favoriteBtnImg_g.GetImage() == NULL) { favoriteBtnImg_g = favoriteBtnImg; favoriteBtnImg_g.SetGrayscale();}
|
||||
favoriteBtnImg_g.SetWidescreen(CFG.widescreen);
|
||||
GuiButton favoriteBtn(&favoriteBtnImg_g,&favoriteBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_favorite_x, THEME.gamelist_favorite_y, &trigA, &btnSoundOver, &btnClick,1, &favoriteBtnTT, -15, 52, 0, 3);
|
||||
GuiButton favoriteBtn(&favoriteBtnImg_g,&favoriteBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_favorite_x, THEME.gamelist_favorite_y, &trigA, &btnSoundOver, btnClick2,1, &favoriteBtnTT, -15, 52, 0, 3);
|
||||
favoriteBtn.SetAlpha(180);
|
||||
|
||||
GuiTooltip searchBtnTT(tr("Set Search-Filter"));
|
||||
@ -563,7 +567,7 @@ int MenuDiscList() {
|
||||
GuiImage searchBtnImg_g(&imgsearchIcon_gray);
|
||||
if(searchBtnImg_g.GetImage() == NULL) { searchBtnImg_g = searchBtnImg; searchBtnImg_g.SetGrayscale();}
|
||||
searchBtnImg_g.SetWidescreen(CFG.widescreen);
|
||||
GuiButton searchBtn(&searchBtnImg_g,&searchBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_search_x, THEME.gamelist_search_y, &trigA, &btnSoundOver, &btnClick,1, &searchBtnTT, -15, 52, 0, 3);
|
||||
GuiButton searchBtn(&searchBtnImg_g,&searchBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_search_x, THEME.gamelist_search_y, &trigA, &btnSoundOver, btnClick2,1, &searchBtnTT, -15, 52, 0, 3);
|
||||
searchBtn.SetAlpha(180);
|
||||
|
||||
GuiTooltip abcBtnTT(Settings.fave ? tr("Sort by rank") : tr("Sort alphabetically"));
|
||||
@ -576,7 +580,7 @@ int MenuDiscList() {
|
||||
GuiImage abcBtnImg_g(Settings.fave ? &imgrankIcon_gray : &imgabcIcon_gray);
|
||||
if(abcBtnImg_g.GetImage() == NULL) { abcBtnImg_g = abcBtnImg; abcBtnImg_g.SetGrayscale();}
|
||||
abcBtnImg_g.SetWidescreen(CFG.widescreen);
|
||||
GuiButton abcBtn(&abcBtnImg_g,&abcBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_abc_x, THEME.gamelist_abc_y, &trigA, &btnSoundOver, &btnClick,1,&abcBtnTT, -15, 52, 0, 3);
|
||||
GuiButton abcBtn(&abcBtnImg_g,&abcBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_abc_x, THEME.gamelist_abc_y, &trigA, &btnSoundOver, btnClick2,1,&abcBtnTT, -15, 52, 0, 3);
|
||||
abcBtn.SetAlpha(180);
|
||||
|
||||
GuiTooltip countBtnTT(tr("Sort order by most played"));
|
||||
@ -589,7 +593,7 @@ int MenuDiscList() {
|
||||
GuiImage countBtnImg_g(&imgplayCountIcon_gray);
|
||||
if(countBtnImg_g.GetImage() == NULL) { countBtnImg_g = countBtnImg; countBtnImg_g.SetGrayscale();}
|
||||
countBtnImg_g.SetWidescreen(CFG.widescreen);
|
||||
GuiButton countBtn(&countBtnImg_g,&countBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_count_x, THEME.gamelist_count_y, &trigA, &btnSoundOver, &btnClick,1, &countBtnTT, -15, 52, 0, 3);
|
||||
GuiButton countBtn(&countBtnImg_g,&countBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_count_x, THEME.gamelist_count_y, &trigA, &btnSoundOver, btnClick2,1, &countBtnTT, -15, 52, 0, 3);
|
||||
countBtn.SetAlpha(180);
|
||||
|
||||
GuiTooltip listBtnTT(tr("Display as a list"));
|
||||
@ -602,7 +606,7 @@ int MenuDiscList() {
|
||||
GuiImage listBtnImg_g(&imgarrangeList_gray);
|
||||
if(listBtnImg_g.GetImage() == NULL) { listBtnImg_g = listBtnImg; listBtnImg_g.SetGrayscale();}
|
||||
listBtnImg_g.SetWidescreen(CFG.widescreen);
|
||||
GuiButton listBtn(&listBtnImg_g,&listBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_list_x, THEME.gamelist_list_y, &trigA, &btnSoundOver, &btnClick,1, &listBtnTT, 15, 52, 1, 3);
|
||||
GuiButton listBtn(&listBtnImg_g,&listBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_list_x, THEME.gamelist_list_y, &trigA, &btnSoundOver, btnClick2,1, &listBtnTT, 15, 52, 1, 3);
|
||||
listBtn.SetAlpha(180);
|
||||
|
||||
GuiTooltip gridBtnTT(tr("Display as a grid"));
|
||||
@ -615,7 +619,7 @@ int MenuDiscList() {
|
||||
GuiImage gridBtnImg_g(&imgarrangeGrid_gray);
|
||||
if(gridBtnImg_g.GetImage() == NULL) { gridBtnImg_g = gridBtnImg; gridBtnImg_g.SetGrayscale();}
|
||||
gridBtnImg_g.SetWidescreen(CFG.widescreen);
|
||||
GuiButton gridBtn(&gridBtnImg_g,&gridBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_grid_x, THEME.gamelist_grid_y, &trigA, &btnSoundOver, &btnClick,1, &gridBtnTT, 15, 52, 1, 3);
|
||||
GuiButton gridBtn(&gridBtnImg_g,&gridBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_grid_x, THEME.gamelist_grid_y, &trigA, &btnSoundOver, btnClick2,1, &gridBtnTT, 15, 52, 1, 3);
|
||||
gridBtn.SetAlpha(180);
|
||||
|
||||
GuiTooltip carouselBtnTT(tr("Display as a carousel"));
|
||||
@ -628,7 +632,7 @@ int MenuDiscList() {
|
||||
GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray);
|
||||
if(carouselBtnImg_g.GetImage() == NULL) { carouselBtnImg_g = carouselBtnImg; carouselBtnImg_g.SetGrayscale();}
|
||||
carouselBtnImg_g.SetWidescreen(CFG.widescreen);
|
||||
GuiButton carouselBtn(&carouselBtnImg_g,&carouselBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_carousel_x, THEME.gamelist_carousel_y, &trigA, &btnSoundOver, &btnClick,1, &carouselBtnTT, 15, 52, 1, 3);
|
||||
GuiButton carouselBtn(&carouselBtnImg_g,&carouselBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_carousel_x, THEME.gamelist_carousel_y, &trigA, &btnSoundOver, btnClick2,1, &carouselBtnTT, 15, 52, 1, 3);
|
||||
carouselBtn.SetAlpha(180);
|
||||
|
||||
GuiTooltip dvdBtnTT(tr("Mount DVD drive"));
|
||||
@ -640,7 +644,7 @@ int MenuDiscList() {
|
||||
GuiImage dvdBtnImg_g(dvdBtnImg); //dvdBtnImg_g.SetGrayscale();
|
||||
// GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray);
|
||||
dvdBtnImg_g.SetWidescreen(CFG.widescreen);
|
||||
GuiButton dvdBtn(&dvdBtnImg_g,&dvdBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_dvd_x, THEME.gamelist_dvd_y, &trigA, &btnSoundOver, &btnClick,1, &dvdBtnTT, 15, 52, 1, 3);
|
||||
GuiButton dvdBtn(&dvdBtnImg_g,&dvdBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_dvd_x, THEME.gamelist_dvd_y, &trigA, &btnSoundOver, btnClick2,1, &dvdBtnTT, 15, 52, 1, 3);
|
||||
dvdBtn.SetAlpha(180);
|
||||
|
||||
GuiTooltip homebrewBtnTT(tr("Homebrew Launcher"));
|
||||
@ -651,7 +655,7 @@ int MenuDiscList() {
|
||||
GuiImage homebrewImgOver(&homebrewImgDataOver);
|
||||
homebrewImg.SetWidescreen(CFG.widescreen);
|
||||
homebrewImgOver.SetWidescreen(CFG.widescreen);
|
||||
GuiButton homebrewBtn(&homebrewImg,&homebrewImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.homebrew_x, THEME.homebrew_y, &trigA, &btnSoundOver, &btnClick,1,&homebrewBtnTT,15,-30,1,5);
|
||||
GuiButton homebrewBtn(&homebrewImg,&homebrewImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.homebrew_x, THEME.homebrew_y, &trigA, &btnSoundOver, btnClick2,1,&homebrewBtnTT,15,-30,1,5);
|
||||
|
||||
if (Settings.fave) {
|
||||
favoriteBtn.SetImage(&favoriteBtnImg);
|
||||
@ -972,16 +976,9 @@ int MenuDiscList() {
|
||||
|
||||
} else if (homeBtn.GetState() == STATE_CLICKED) {
|
||||
gprintf("\n\thomeBtn clicked");
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) {
|
||||
bgMusic->Play();
|
||||
} else {
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
}
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
|
||||
if (choice == 3) {
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
@ -1755,7 +1752,7 @@ static int MenuInstall() {
|
||||
int ret, choice = 0;
|
||||
char name[200];
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
|
||||
|
||||
char imgPath[100];
|
||||
|
||||
@ -1849,22 +1846,15 @@ static int MenuInstall() {
|
||||
} else {
|
||||
__Menu_GetEntries(); //get the entries again
|
||||
GuiSound * instsuccess = NULL;
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
instsuccess = new GuiSound(success_ogg, success_ogg_size, SOUND_OGG, Settings.sfxvolume);
|
||||
bgMusic->Pause();
|
||||
instsuccess = new GuiSound(success_ogg, success_ogg_size, Settings.sfxvolume);
|
||||
instsuccess->SetVolume(Settings.sfxvolume);
|
||||
instsuccess->SetLoop(0);
|
||||
instsuccess->Play();
|
||||
WindowPrompt (tr("Successfully installed:"),name,tr("OK"));
|
||||
instsuccess->Stop();
|
||||
delete instsuccess;
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) {
|
||||
bgMusic->Play();
|
||||
} else {
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
}
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
menu = MENU_DISCLIST;
|
||||
break;
|
||||
}
|
||||
@ -1933,8 +1923,10 @@ static int MenuFormat() {
|
||||
}
|
||||
}
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff.png", CFG.theme_path);
|
||||
GuiImageData btnpwroff(imgPath, wiimote_poweroff_png);
|
||||
snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff_over.png", CFG.theme_path);
|
||||
@ -1958,12 +1950,12 @@ static int MenuFormat() {
|
||||
GuiImage poweroffBtnImgOver(&btnpwroffOver);
|
||||
poweroffBtnImg.SetWidescreen(CFG.widescreen);
|
||||
poweroffBtnImgOver.SetWidescreen(CFG.widescreen);
|
||||
GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, btnClick2,1);
|
||||
GuiImage exitBtnImg(&btnhome);
|
||||
GuiImage exitBtnImgOver(&btnhomeOver);
|
||||
exitBtnImg.SetWidescreen(CFG.widescreen);
|
||||
exitBtnImgOver.SetWidescreen(CFG.widescreen);
|
||||
GuiButton exitBtn(&exitBtnImg,&exitBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton exitBtn(&exitBtnImg,&exitBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, btnClick2,1);
|
||||
exitBtn.SetTrigger(&trigHome);
|
||||
|
||||
GuiCustomOptionBrowser optionBrowser(396, 280, &options, CFG.theme_path, "bg_options_settings.png", bg_options_settings_png, 0, 10);
|
||||
@ -2171,18 +2163,16 @@ int MainMenu(int menu) {
|
||||
|
||||
ResumeGui();
|
||||
|
||||
bgMusic = new GuiSound(bg_music_ogg, bg_music_ogg_size, SOUND_OGG, Settings.volume);
|
||||
bgMusic->SetVolume(Settings.volume);
|
||||
bgMusic = new GuiSound(bg_music_ogg, bg_music_ogg_size, Settings.volume);
|
||||
bgMusic->SetLoop(1); //loop music
|
||||
// startup music
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) {
|
||||
bgMusic->Play();
|
||||
} else {
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
if (strcmp("", Settings.oggload_path) && strcmp("notset", Settings.ogg_path)) {
|
||||
bgMusic->Load(Settings.ogg_path);
|
||||
}
|
||||
bgMusic->Play();
|
||||
|
||||
while (currentMenu != MENU_EXIT) {
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->SetVolume(Settings.volume);
|
||||
|
||||
switch (currentMenu) {
|
||||
case MENU_CHECK:
|
||||
|
@ -33,5 +33,6 @@ enum {
|
||||
};
|
||||
class GuiImageData;
|
||||
GuiImageData *LoadCoverImage(struct discHdr *header, bool Prefere3D=true, bool noCover=true);
|
||||
|
||||
class GuiSound;
|
||||
extern GuiSound *btnClick2;
|
||||
#endif
|
||||
|
@ -1,336 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
|
||||
All rights reserved.
|
||||
|
||||
Threading modifications/corrections by Tantric, 2009
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
- The names of the contributors may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "oggplayer.h"
|
||||
#include <gccore.h>
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* OGG control */
|
||||
|
||||
#define READ_SAMPLES 4096 // samples that it must read before to send
|
||||
#define MAX_PCMOUT 4096 // minimum size to read ogg samples
|
||||
typedef struct {
|
||||
OggVorbis_File vf;
|
||||
vorbis_info *vi;
|
||||
int current_section;
|
||||
|
||||
// OGG file operation
|
||||
int fd;
|
||||
int mode;
|
||||
int eof;
|
||||
int flag;
|
||||
int volume;
|
||||
int seek_time;
|
||||
|
||||
/* OGG buffer control */
|
||||
short pcmout[2][READ_SAMPLES + MAX_PCMOUT * 2]; /* take 4k out of the data segment, not the stack */
|
||||
int pcmout_pos;
|
||||
int pcm_indx;
|
||||
|
||||
} private_data_ogg;
|
||||
|
||||
static private_data_ogg private_ogg;
|
||||
|
||||
// OGG thread control
|
||||
|
||||
#define STACKSIZE 8192
|
||||
|
||||
static u8 oggplayer_stack[STACKSIZE];
|
||||
static lwpq_t oggplayer_queue = LWP_THREAD_NULL;
|
||||
static lwp_t h_oggplayer = LWP_THREAD_NULL;
|
||||
static int ogg_thread_running = 0;
|
||||
|
||||
static void ogg_add_callback(int voice) {
|
||||
if (!ogg_thread_running) {
|
||||
ASND_StopVoice(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (private_ogg.flag & 128)
|
||||
return; // Ogg is paused
|
||||
|
||||
if (private_ogg.pcm_indx >= READ_SAMPLES) {
|
||||
if (ASND_AddVoice(0,
|
||||
(void *) private_ogg.pcmout[private_ogg.pcmout_pos],
|
||||
private_ogg.pcm_indx << 1) == 0) {
|
||||
private_ogg.pcmout_pos ^= 1;
|
||||
private_ogg.pcm_indx = 0;
|
||||
private_ogg.flag = 0;
|
||||
LWP_ThreadSignal(oggplayer_queue);
|
||||
}
|
||||
} else {
|
||||
if (private_ogg.flag & 64) {
|
||||
private_ogg.flag &= ~64;
|
||||
LWP_ThreadSignal(oggplayer_queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void * ogg_player_thread(private_data_ogg * priv) {
|
||||
int first_time = 1;
|
||||
long ret;
|
||||
|
||||
ogg_thread_running = 0;
|
||||
//init
|
||||
LWP_InitQueue(&oggplayer_queue);
|
||||
|
||||
priv[0].vi = ov_info(&priv[0].vf, -1);
|
||||
|
||||
ASND_Pause(0);
|
||||
|
||||
priv[0].pcm_indx = 0;
|
||||
priv[0].pcmout_pos = 0;
|
||||
priv[0].eof = 0;
|
||||
priv[0].flag = 0;
|
||||
priv[0].current_section = 0;
|
||||
|
||||
ogg_thread_running = 1;
|
||||
|
||||
while (!priv[0].eof && ogg_thread_running) {
|
||||
if (priv[0].flag)
|
||||
LWP_ThreadSleep(oggplayer_queue); // wait only when i have samples to send
|
||||
|
||||
if (priv[0].flag == 0) { // wait to all samples are sended
|
||||
if (ASND_TestPointer(0, priv[0].pcmout[priv[0].pcmout_pos])
|
||||
&& ASND_StatusVoice(0) != SND_UNUSED) {
|
||||
priv[0].flag |= 64;
|
||||
continue;
|
||||
}
|
||||
if (priv[0].pcm_indx < READ_SAMPLES) {
|
||||
priv[0].flag = 3;
|
||||
|
||||
if (priv[0].seek_time >= 0) {
|
||||
ov_time_seek(&priv[0].vf, priv[0].seek_time);
|
||||
priv[0].seek_time = -1;
|
||||
}
|
||||
|
||||
ret
|
||||
= ov_read(
|
||||
&priv[0].vf,
|
||||
(void *) &priv[0].pcmout[priv[0].pcmout_pos][priv[0].pcm_indx],
|
||||
MAX_PCMOUT,/*0,2,1,*/&priv[0].current_section);
|
||||
priv[0].flag &= 192;
|
||||
if (ret == 0) {
|
||||
/* EOF */
|
||||
if (priv[0].mode & 1)
|
||||
ov_time_seek(&priv[0].vf, 0); // repeat
|
||||
else
|
||||
priv[0].eof = 1; // stops
|
||||
//
|
||||
} else if (ret < 0) {
|
||||
/* error in the stream. Not a problem, just reporting it in
|
||||
case we (the app) cares. In this case, we don't. */
|
||||
if (ret != OV_HOLE) {
|
||||
if (priv[0].mode & 1)
|
||||
ov_time_seek(&priv[0].vf, 0); // repeat
|
||||
else
|
||||
priv[0].eof = 1; // stops
|
||||
}
|
||||
} else {
|
||||
/* we don't bother dealing with sample rate changes, etc, but
|
||||
you'll have to*/
|
||||
priv[0].pcm_indx += ret >> 1; //get 16 bits samples
|
||||
}
|
||||
} else
|
||||
priv[0].flag = 1;
|
||||
}
|
||||
|
||||
if (priv[0].flag == 1) {
|
||||
if (ASND_StatusVoice(0) == SND_UNUSED || first_time) {
|
||||
first_time = 0;
|
||||
if (priv[0].vi->channels == 2) {
|
||||
ASND_SetVoice(0, VOICE_STEREO_16BIT, priv[0].vi->rate, 0,
|
||||
(void *) priv[0].pcmout[priv[0].pcmout_pos],
|
||||
priv[0].pcm_indx << 1, priv[0].volume,
|
||||
priv[0].volume, ogg_add_callback);
|
||||
priv[0].pcmout_pos ^= 1;
|
||||
priv[0].pcm_indx = 0;
|
||||
priv[0].flag = 0;
|
||||
} else {
|
||||
ASND_SetVoice(0, VOICE_MONO_16BIT, priv[0].vi->rate, 0,
|
||||
(void *) priv[0].pcmout[priv[0].pcmout_pos],
|
||||
priv[0].pcm_indx << 1, priv[0].volume,
|
||||
priv[0].volume, ogg_add_callback);
|
||||
priv[0].pcmout_pos ^= 1;
|
||||
priv[0].pcm_indx = 0;
|
||||
priv[0].flag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
usleep(100);
|
||||
}
|
||||
ov_clear(&priv[0].vf);
|
||||
priv[0].fd = -1;
|
||||
priv[0].pcm_indx = 0;
|
||||
ogg_thread_running = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void StopOgg() {
|
||||
ASND_StopVoice(0);
|
||||
ogg_thread_running = 0;
|
||||
|
||||
if (h_oggplayer != LWP_THREAD_NULL) {
|
||||
if (oggplayer_queue != LWP_TQUEUE_NULL)
|
||||
LWP_ThreadSignal(oggplayer_queue);
|
||||
LWP_JoinThread(h_oggplayer, NULL);
|
||||
h_oggplayer = LWP_THREAD_NULL;
|
||||
}
|
||||
if (oggplayer_queue != LWP_TQUEUE_NULL) {
|
||||
LWP_CloseQueue(oggplayer_queue);
|
||||
oggplayer_queue = LWP_TQUEUE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int PlayOgg(int fd, int time_pos, int mode) {
|
||||
StopOgg();
|
||||
|
||||
private_ogg.fd = fd;
|
||||
private_ogg.mode = mode;
|
||||
private_ogg.eof = 0;
|
||||
private_ogg.volume = 127;
|
||||
private_ogg.flag = 0;
|
||||
private_ogg.seek_time = -1;
|
||||
|
||||
if (time_pos > 0)
|
||||
private_ogg.seek_time = time_pos;
|
||||
|
||||
if (fd < 0) {
|
||||
private_ogg.fd = -1;
|
||||
return -1;
|
||||
}
|
||||
if (ov_open((void *) &private_ogg.fd, &private_ogg.vf, NULL, 0) < 0) {
|
||||
mem_close(private_ogg.fd); // mem_close() can too close files from devices
|
||||
private_ogg.fd = -1;
|
||||
ogg_thread_running = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (LWP_CreateThread(&h_oggplayer, (void *) ogg_player_thread,
|
||||
&private_ogg, oggplayer_stack, STACKSIZE, 80) == -1) {
|
||||
ogg_thread_running = 0;
|
||||
ov_clear(&private_ogg.vf);
|
||||
private_ogg.fd = -1;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PlayOggFromFile(char * path, int loop) {
|
||||
|
||||
StopOgg();
|
||||
u32 filesize = 0;
|
||||
char * bufferogg = NULL;
|
||||
size_t resultogg;
|
||||
|
||||
FILE * pFile;
|
||||
pFile = fopen (path, "rb");
|
||||
|
||||
//Check that pFile exist
|
||||
if (pFile==NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get file size:
|
||||
fseek (pFile , 0 , SEEK_END);
|
||||
filesize = ftell (pFile);
|
||||
rewind (pFile);
|
||||
|
||||
// allocate memory to contain the whole file:
|
||||
bufferogg = (char*) malloc (sizeof(char)*filesize);
|
||||
if (bufferogg == NULL) {
|
||||
fputs (" Memory error",stderr);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
// copy the file into the buffer:
|
||||
resultogg = fread (bufferogg,1,filesize,pFile);
|
||||
if (resultogg != filesize) {
|
||||
fputs (" Reading error",stderr);
|
||||
exit (3);
|
||||
}
|
||||
|
||||
fclose (pFile);
|
||||
|
||||
if (loop)
|
||||
return PlayOgg(mem_open((char *)bufferogg, filesize), 0, OGG_INFINITE_TIME);
|
||||
else
|
||||
return PlayOgg(mem_open((char *)bufferogg, filesize), 0, OGG_ONE_TIME);
|
||||
}
|
||||
|
||||
|
||||
void PauseOgg(int pause) {
|
||||
if (pause) {
|
||||
private_ogg.flag |= 128;
|
||||
} else {
|
||||
if (private_ogg.flag & 128) {
|
||||
private_ogg.flag |= 64;
|
||||
private_ogg.flag &= ~128;
|
||||
if (ogg_thread_running > 0) {
|
||||
LWP_ThreadSignal(oggplayer_queue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int StatusOgg() {
|
||||
if (ogg_thread_running == 0)
|
||||
return -1; // Error
|
||||
else if (private_ogg.eof)
|
||||
return 255; // EOF
|
||||
else if (private_ogg.flag & 128)
|
||||
return 2; // paused
|
||||
else
|
||||
return 1; // running
|
||||
}
|
||||
|
||||
void SetVolumeOgg(int volume) {
|
||||
private_ogg.volume = volume;
|
||||
ASND_ChangeVolumeVoice(0, volume, volume);
|
||||
}
|
||||
|
||||
s32 GetTimeOgg() {
|
||||
int ret;
|
||||
if (ogg_thread_running == 0 || private_ogg.fd < 0)
|
||||
return 0;
|
||||
ret = ((s32) ov_time_tell(&private_ogg.vf));
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SetTimeOgg(s32 time_pos) {
|
||||
if (time_pos >= 0)
|
||||
private_ogg.seek_time = time_pos;
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
- The names of the contributors may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __OGGPLAYER_H__
|
||||
#define __OGGPLAYER_H__
|
||||
|
||||
#include <asndlib.h>
|
||||
#include "tremor/ivorbiscodec.h"
|
||||
#include "tremor/ivorbisfile.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OGG_ONE_TIME 0
|
||||
#define OGG_INFINITE_TIME 1
|
||||
|
||||
#define OGG_STATUS_RUNNING 1
|
||||
#define OGG_STATUS_ERR -1
|
||||
#define OGG_STATUS_PAUSED 2
|
||||
#define OGG_STATUS_EOF 255
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* Player OGG functions */
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* int PlayOgg(int fd, int time_pos, int mode);
|
||||
|
||||
Play an Ogg file. This file can be loaded from memory (mem_open(void *ogg, int size_ogg)) or from device with open("device:file.ogg",O_RDONLY,0);
|
||||
|
||||
NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail.
|
||||
|
||||
-- Params ---
|
||||
|
||||
fd: file descriptor from open() or mem_open()
|
||||
|
||||
time_pos: initial time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
|
||||
|
||||
mode: Use OGG_ONE_TIME or OGG_INFINITE_TIME. When you use OGG_ONE_TIME the sound stops and StatusOgg() return OGG_STATUS_EOF
|
||||
|
||||
return: 0- Ok, -1 Error
|
||||
|
||||
*/
|
||||
|
||||
int PlayOgg(int fd, int time_pos, int mode);
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* int PlayOgg(char * path, int loop);
|
||||
Just give the function the full device+path to OGG to play it
|
||||
loop = 1 for Loop and 0 for one time playing
|
||||
*/
|
||||
int PlayOggFromFile(char * path, int loop);
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* void StopOgg();
|
||||
|
||||
Stop an Ogg file.
|
||||
|
||||
NOTE: The file is closed and the player thread is released
|
||||
|
||||
-- Params ---
|
||||
|
||||
|
||||
*/
|
||||
|
||||
void StopOgg();
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* void PauseOgg(int pause);
|
||||
|
||||
Pause an Ogg file.
|
||||
|
||||
-- Params ---
|
||||
|
||||
pause: 0 -> continue, 1-> pause
|
||||
|
||||
*/
|
||||
|
||||
void PauseOgg(int pause);
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* int StatusOgg();
|
||||
|
||||
Return the Ogg status
|
||||
|
||||
-- Params ---
|
||||
|
||||
|
||||
return: OGG_STATUS_RUNNING
|
||||
OGG_STATUS_ERR -> not initialized?
|
||||
OGG_STATUS_PAUSED
|
||||
OGG_STATUS_EOF -> player stopped by End Of File
|
||||
|
||||
*/
|
||||
|
||||
int StatusOgg();
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* void SetVolumeOgg(int volume);
|
||||
|
||||
Set the Ogg playing volume.
|
||||
NOTE: it change the volume of voice 0 (used for the Ogg player)
|
||||
|
||||
-- Params ---
|
||||
|
||||
volume: 0 to 255 (max)
|
||||
|
||||
*/
|
||||
|
||||
void SetVolumeOgg(int volume);
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* s32 GetTimeOgg();
|
||||
|
||||
Return the Ogg time from the starts of the file
|
||||
|
||||
-- Params ---
|
||||
|
||||
return: 0 -> Ok or error condition (you must ignore this value)
|
||||
>0 -> time in milliseconds from the starts
|
||||
|
||||
*/
|
||||
|
||||
s32 GetTimeOgg();
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* void SetTimeOgg(s32 time_pos);
|
||||
|
||||
Set the time position
|
||||
|
||||
NOTE: The file is closed by the player when you call PlayOgg(), StopOgg() or if it fail.
|
||||
|
||||
-- Params ---
|
||||
|
||||
time_pos: time position in the file (in milliseconds). For example, use 30000 to advance 30 seconds
|
||||
|
||||
*/
|
||||
|
||||
void SetTimeOgg(s32 time_pos);
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -141,8 +141,10 @@ int DiscBrowse(struct discHdr * header) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
|
||||
@ -176,7 +178,7 @@ int DiscBrowse(struct discHdr * header) {
|
||||
cancelBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
cancelBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2,1);
|
||||
cancelBtn.SetScale(0.9);
|
||||
cancelBtn.SetLabel(&cancelBtnTxt);
|
||||
cancelBtn.SetTrigger(&trigB);
|
||||
|
@ -33,11 +33,11 @@
|
||||
#include "svnrev.h"
|
||||
#include "audio.h"
|
||||
#include "xml/xml.h"
|
||||
#include "../wad/title.h"
|
||||
#include "wad/title.h"
|
||||
#include "language/UpdateLanguage.h"
|
||||
#include "gecko.h"
|
||||
#include "../lstub.h"
|
||||
#include "Game_Sound.h"
|
||||
#include "lstub.h"
|
||||
#include "bannersound.h"
|
||||
|
||||
|
||||
|
||||
@ -84,8 +84,10 @@ int OnScreenKeyboard(char * var, u32 maxlen, int min) {
|
||||
|
||||
GuiKeyboard keyboard(var, maxlen, min, keyset);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -102,7 +104,7 @@ int OnScreenKeyboard(char * var, u32 maxlen, int min) {
|
||||
okBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
okBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 5, 15, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 5, 15, &trigA, &btnSoundOver, btnClick2,1);
|
||||
okBtn.SetLabel(&okBtnTxt);
|
||||
GuiText cancelBtnTxt(tr("Cancel"), 22, THEME.prompttext);
|
||||
GuiImage cancelBtnImg(&btnOutline);
|
||||
@ -110,7 +112,7 @@ int OnScreenKeyboard(char * var, u32 maxlen, int min) {
|
||||
cancelBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
cancelBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 1, 4, -5, 15, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 1, 4, -5, 15, &trigA, &btnSoundOver, btnClick2,1);
|
||||
cancelBtn.SetLabel(&cancelBtnTxt);
|
||||
cancelBtn.SetTrigger(&trigB);
|
||||
|
||||
@ -154,10 +156,9 @@ void WindowCredits() {
|
||||
int angle = 0;
|
||||
GuiSound * creditsMusic = NULL;
|
||||
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
StopOgg();
|
||||
bgMusic->Pause();
|
||||
|
||||
creditsMusic = new GuiSound(credits_music_ogg, credits_music_ogg_size, SOUND_OGG, 55);
|
||||
creditsMusic = new GuiSound(credits_music_ogg, credits_music_ogg_size, 55);
|
||||
creditsMusic->SetVolume(60);
|
||||
creditsMusic->SetLoop(1);
|
||||
creditsMusic->Play();
|
||||
@ -366,13 +367,7 @@ void WindowCredits() {
|
||||
}
|
||||
ResumeGui();
|
||||
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) {
|
||||
bgMusic->Play();
|
||||
} else {
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
}
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -450,8 +445,10 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
promptWindow.SetPosition(0, -10);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
|
||||
@ -484,7 +481,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
btn1Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
|
||||
GuiButton btn1(&btn1Img, &btn1Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1);
|
||||
GuiButton btn1(&btn1Img, &btn1Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
|
||||
btn1.SetLabel(&btn1Txt);
|
||||
btn1.SetState(STATE_SELECTED);
|
||||
|
||||
@ -494,7 +491,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
btn2Txt.SetWidescreen(CFG.widescreen);
|
||||
btn2Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn2(&btn2Img, &btn2Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1);
|
||||
GuiButton btn2(&btn2Img, &btn2Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
|
||||
btn2.SetLabel(&btn2Txt);
|
||||
if (!btn3Label && !btn4Label)
|
||||
btn2.SetTrigger(&trigB);
|
||||
@ -505,7 +502,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
btn3Txt.SetWidescreen(CFG.widescreen);
|
||||
btn3Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn3(&btn3Img, &btn3Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1);
|
||||
GuiButton btn3(&btn3Img, &btn3Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
|
||||
btn3.SetLabel(&btn3Txt);
|
||||
if (!btn4Label)
|
||||
btn3.SetTrigger(&trigB);
|
||||
@ -516,7 +513,7 @@ int WindowPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
btn4Txt.SetWidescreen(CFG.widescreen);
|
||||
btn4Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn4(&btn4Img, &btn4Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1);
|
||||
GuiButton btn4(&btn4Img, &btn4Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
|
||||
btn4.SetLabel(&btn4Txt);
|
||||
if (btn4Label)
|
||||
btn4.SetTrigger(&trigB);
|
||||
@ -696,13 +693,13 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
gprintf("\nWindowExitPrompt()");
|
||||
|
||||
GuiSound * homein = NULL;
|
||||
homein = new GuiSound(menuin_ogg, menuin_ogg_size, SOUND_OGG, Settings.sfxvolume);
|
||||
homein = new GuiSound(menuin_ogg, menuin_ogg_size, Settings.sfxvolume);
|
||||
homein->SetVolume(Settings.sfxvolume);
|
||||
homein->SetLoop(0);
|
||||
homein->Play();
|
||||
|
||||
GuiSound * homeout = NULL;
|
||||
homeout = new GuiSound(menuout_ogg, menuout_ogg_size, SOUND_OGG, Settings.sfxvolume);
|
||||
homeout = new GuiSound(menuout_ogg, menuout_ogg_size, Settings.sfxvolume);
|
||||
homeout->SetVolume(Settings.sfxvolume);
|
||||
homeout->SetLoop(0);
|
||||
|
||||
@ -717,8 +714,10 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
GuiWindow promptWindow(640,480);
|
||||
promptWindow.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
|
||||
promptWindow.SetPosition(0, 0);
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
GuiImageData topOver(exit_top_over_png);
|
||||
@ -810,7 +809,7 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
|
||||
GuiImage btn1Img(&top);
|
||||
GuiImage btn1OverImg(&topOver);
|
||||
GuiButton btn1(&btn1Img,&btn1OverImg, 0, 3, 0, 0, &trigA, &btnSoundOver, &btnClick,0);
|
||||
GuiButton btn1(&btn1Img,&btn1OverImg, 0, 3, 0, 0, &trigA, &btnSoundOver, btnClick2,0);
|
||||
btn1.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50);
|
||||
|
||||
GuiText btn2Txt(btn1Label, 28, (GXColor) {0, 0, 0, 255});
|
||||
@ -819,7 +818,7 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
btn2Txt.SetWidescreen(CFG.widescreen);
|
||||
btn2Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn2(&btn2Img,&btn2Img, 2, 5, -150, 0, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn2(&btn2Img,&btn2Img, 2, 5, -150, 0, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btn2.SetLabel(&btn2Txt);
|
||||
btn2.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 50);
|
||||
btn2.SetRumble(false);
|
||||
@ -832,7 +831,7 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
btn3Txt.SetWidescreen(CFG.widescreen);
|
||||
btn3Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn3(&btn3Img,&btn3Img, 2, 5, 150, 0, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn3(&btn3Img,&btn3Img, 2, 5, 150, 0, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btn3.SetLabel(&btn3Txt);
|
||||
btn3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 50);
|
||||
btn3.SetRumble(false);
|
||||
@ -840,7 +839,7 @@ WindowExitPrompt(const char *title, const char *msg, const char *btn1Label,
|
||||
|
||||
GuiImage btn4Img(&bottom);
|
||||
GuiImage btn4OverImg(&bottomOver);
|
||||
GuiButton btn4(&btn4Img,&btn4OverImg, 0, 4, 0, 0, &trigA, &btnSoundOver, &btnClick,0);
|
||||
GuiButton btn4(&btn4Img,&btn4OverImg, 0, 4, 0, 0, &trigA, &btnSoundOver, btnClick2,0);
|
||||
btn4.SetTrigger(&trigB);
|
||||
btn4.SetTrigger(&trigHome);
|
||||
btn4.SetEffect(EFFECT_SLIDE_BOTTOM | EFFECT_SLIDE_IN, 50);
|
||||
@ -1025,14 +1024,16 @@ int GameWindowPrompt() {
|
||||
char ID[5];
|
||||
char IDFull[7];
|
||||
|
||||
GameSound * gameSound = NULL;
|
||||
GuiSound * gameSound = NULL;
|
||||
|
||||
gprintf("\nGameWindowPrompt()");
|
||||
GuiWindow promptWindow(472,320);
|
||||
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
promptWindow.SetPosition(0, -10);
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -1082,7 +1083,7 @@ int GameWindowPrompt() {
|
||||
nameBtn.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
nameBtn.SetPosition(0,-122);
|
||||
nameBtn.SetSoundOver(&btnSoundOver);
|
||||
nameBtn.SetSoundClick(&btnClick);
|
||||
nameBtn.SetSoundClick(btnClick2);
|
||||
if (!mountMethod) nameBtn.SetToolTip(&nameBtnTT,24,-30, ALIGN_LEFT);
|
||||
|
||||
if (Settings.godmode == 1 && !mountMethod) {
|
||||
@ -1116,7 +1117,7 @@ int GameWindowPrompt() {
|
||||
btn1.SetImage(&diskImg);
|
||||
|
||||
btn1.SetSoundOver(&btnSoundOver);
|
||||
btn1.SetSoundClick(&btnClick);
|
||||
btn1.SetSoundClick(btnClick2);
|
||||
btn1.SetTrigger(&trigA);
|
||||
btn1.SetState(STATE_SELECTED);
|
||||
|
||||
@ -1126,7 +1127,7 @@ int GameWindowPrompt() {
|
||||
btn2Txt.SetWidescreen(CFG.widescreen);
|
||||
btn2Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn2(&btn2Img,&btn2Img, 1, 5, 0, 0, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn2(&btn2Img,&btn2Img, 1, 5, 0, 0, &trigA, &btnSoundOver, btnClick2,1);
|
||||
if (Settings.godmode == 1 && mountMethod!=2 && mountMethod!=3) {
|
||||
btn2.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
|
||||
btn2.SetPosition(-50, -40);
|
||||
@ -1144,7 +1145,7 @@ int GameWindowPrompt() {
|
||||
btn3Txt.SetWidescreen(CFG.widescreen);
|
||||
btn3Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn3(&btn3Img,&btn3Img, 0, 4, 50, -40, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn3(&btn3Img,&btn3Img, 0, 4, 50, -40, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btn3.SetLabel(&btn3Txt);
|
||||
|
||||
GuiImage btnFavoriteImg1;
|
||||
@ -1165,17 +1166,17 @@ int GameWindowPrompt() {
|
||||
GuiButton btnFavorite4(imgFavorite.GetWidth(), imgFavorite.GetHeight());
|
||||
GuiButton btnFavorite5(imgFavorite.GetWidth(), imgFavorite.GetHeight());
|
||||
|
||||
SetupFavoriteButton(&btnFavorite1, -198, &btnFavoriteImg1, &btnSoundOver, &btnClick, &trigA);
|
||||
SetupFavoriteButton(&btnFavorite2, -171, &btnFavoriteImg2, &btnSoundOver, &btnClick, &trigA);
|
||||
SetupFavoriteButton(&btnFavorite3, -144, &btnFavoriteImg3, &btnSoundOver, &btnClick, &trigA);
|
||||
SetupFavoriteButton(&btnFavorite4, -117, &btnFavoriteImg4, &btnSoundOver, &btnClick, &trigA);
|
||||
SetupFavoriteButton(&btnFavorite5, -90, &btnFavoriteImg5, &btnSoundOver, &btnClick, &trigA);
|
||||
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);
|
||||
|
||||
GuiImage btnLeftImg(&imgLeft);
|
||||
if (Settings.wsprompt == yes) {
|
||||
btnLeftImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btnLeft(&btnLeftImg,&btnLeftImg, 0, 5, 20, 0, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btnLeft(&btnLeftImg,&btnLeftImg, 0, 5, 20, 0, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btnLeft.SetTrigger(&trigL);
|
||||
btnLeft.SetTrigger(&trigMinus);
|
||||
|
||||
@ -1183,7 +1184,7 @@ int GameWindowPrompt() {
|
||||
if (Settings.wsprompt == yes) {
|
||||
btnRightImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btnRight(&btnRightImg,&btnRightImg, 1, 5, -20, 0, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btnRight(&btnRightImg,&btnRightImg, 1, 5, -20, 0, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btnRight.SetTrigger(&trigR);
|
||||
btnRight.SetTrigger(&trigPlus);
|
||||
|
||||
@ -1233,20 +1234,23 @@ int GameWindowPrompt() {
|
||||
|
||||
//load disc image based or what game is seleted
|
||||
struct discHdr * header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]);
|
||||
|
||||
if(Settings.gamesound)
|
||||
{
|
||||
if(gameSound)
|
||||
{
|
||||
gameSound->Stop();
|
||||
delete gameSound;
|
||||
gameSound = NULL;
|
||||
}
|
||||
|
||||
gameSound = new GameSound(header->id);
|
||||
u32 gameSoundDataLen;
|
||||
const u8 *gameSoundData = LoadBannerSound(header->id, &gameSoundDataLen);
|
||||
if(gameSoundData)
|
||||
{
|
||||
gameSound = new GuiSound(gameSoundData, gameSoundDataLen, Settings.gamesoundvolume, false, true);
|
||||
bgMusic->SetVolume(0);
|
||||
gameSound->SetVolume(Settings.gamesoundvolume);
|
||||
gameSound->Play();
|
||||
}
|
||||
}
|
||||
snprintf (ID,sizeof(ID),"%c%c%c", header->id[0], header->id[1], header->id[2]);
|
||||
snprintf (IDFull,sizeof(IDFull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]);
|
||||
|
||||
@ -1455,7 +1459,7 @@ int GameWindowPrompt() {
|
||||
else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == no)) {//next game
|
||||
promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50);
|
||||
changed = 1;
|
||||
btnClick.Play();
|
||||
btnClick2->Play();
|
||||
gameSelected = (gameSelected + 1) % gameCnt;
|
||||
btnRight.ResetState();
|
||||
break;
|
||||
@ -1464,7 +1468,7 @@ int GameWindowPrompt() {
|
||||
else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == no)) {//previous game
|
||||
promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50);
|
||||
changed = 2;
|
||||
btnClick.Play();
|
||||
btnClick2->Play();
|
||||
gameSelected = (gameSelected - 1 + gameCnt) % gameCnt;
|
||||
btnLeft.ResetState();
|
||||
break;
|
||||
@ -1473,7 +1477,7 @@ int GameWindowPrompt() {
|
||||
else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == yes)) {//previous game
|
||||
promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50);
|
||||
changed = 2;
|
||||
btnClick.Play();
|
||||
btnClick2->Play();
|
||||
gameSelected = (gameSelected - 1 + gameCnt) % gameCnt;
|
||||
btnRight.ResetState();
|
||||
break;
|
||||
@ -1482,7 +1486,7 @@ int GameWindowPrompt() {
|
||||
else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == yes)) {//next game
|
||||
promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50);
|
||||
changed = 1;
|
||||
btnClick.Play();
|
||||
btnClick2->Play();
|
||||
gameSelected = (gameSelected + 1) % gameCnt;
|
||||
btnLeft.ResetState();
|
||||
break;
|
||||
@ -1491,7 +1495,7 @@ int GameWindowPrompt() {
|
||||
else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == sysmenu)) {//previous game
|
||||
promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50);
|
||||
changed = 2;
|
||||
btnClick.Play();
|
||||
btnClick2->Play();
|
||||
gameSelected = (gameSelected + 1) % gameCnt;
|
||||
btnRight.ResetState();
|
||||
break;
|
||||
@ -1500,7 +1504,7 @@ int GameWindowPrompt() {
|
||||
else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == sysmenu)) {//next game
|
||||
promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50);
|
||||
changed = 1;
|
||||
btnClick.Play();
|
||||
btnClick2->Play();
|
||||
gameSelected = (gameSelected - 1 + gameCnt) % gameCnt;
|
||||
btnLeft.ResetState();
|
||||
break;
|
||||
@ -1509,7 +1513,7 @@ int GameWindowPrompt() {
|
||||
else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == wtf)) {//previous game
|
||||
promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50);
|
||||
changed = 1;
|
||||
btnClick.Play();
|
||||
btnClick2->Play();
|
||||
gameSelected = (gameSelected - 1 + gameCnt) % gameCnt;
|
||||
btnRight.ResetState();
|
||||
break;
|
||||
@ -1518,7 +1522,7 @@ int GameWindowPrompt() {
|
||||
else if ((btnLeft.GetState() == STATE_CLICKED) && (Settings.xflip == wtf)) {//next game
|
||||
promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50);
|
||||
changed = 2;
|
||||
btnClick.Play();
|
||||
btnClick2->Play();
|
||||
gameSelected = (gameSelected + 1) % gameCnt;
|
||||
btnLeft.ResetState();
|
||||
break;
|
||||
@ -1527,7 +1531,7 @@ int GameWindowPrompt() {
|
||||
else if ((btnRight.GetState() == STATE_CLICKED) && (Settings.xflip == disk3d)) {//next game
|
||||
// diskImg.SetBetaRotateEffect(45, 90);
|
||||
changed = 3;
|
||||
btnClick.Play();
|
||||
btnClick2->Play();
|
||||
gameSelected = (gameSelected + 1) % gameCnt;
|
||||
btnRight.ResetState();
|
||||
break;
|
||||
@ -1537,7 +1541,7 @@ int GameWindowPrompt() {
|
||||
// diskImg.SetBetaRotateEffect(-45, 90);
|
||||
// promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 1/*50*/);
|
||||
changed = 4;
|
||||
btnClick.Play();
|
||||
btnClick2->Play();
|
||||
gameSelected = (gameSelected - 1 + gameCnt) % gameCnt;
|
||||
btnLeft.ResetState();
|
||||
break;
|
||||
@ -1557,6 +1561,7 @@ int GameWindowPrompt() {
|
||||
|
||||
if(gameSound)
|
||||
{
|
||||
gameSound->Stop();
|
||||
delete gameSound;
|
||||
gameSound = NULL;
|
||||
}
|
||||
@ -1577,8 +1582,10 @@ DiscWait(const char *title, const char *msg, const char *btn1Label, const char *
|
||||
GuiWindow promptWindow(472,320);
|
||||
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
promptWindow.SetPosition(0, -10);
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -1609,7 +1616,7 @@ DiscWait(const char *title, const char *msg, const char *btn1Label, const char *
|
||||
btn1Txt.SetWidescreen(CFG.widescreen);
|
||||
btn1Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 1, 5, 0, 0, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 1, 5, 0, 0, &trigA, &btnSoundOver, btnClick2,1);
|
||||
|
||||
if (btn2Label) {
|
||||
btn1.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
|
||||
@ -1629,7 +1636,7 @@ DiscWait(const char *title, const char *msg, const char *btn1Label, const char *
|
||||
btn2Txt.SetWidescreen(CFG.widescreen);
|
||||
btn2Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn2(&btn2Img,&btn2Img, 1, 4, -20, -25, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn2(&btn2Img,&btn2Img, 1, 4, -20, -25, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btn2.SetLabel(&btn2Txt);
|
||||
|
||||
if ((Settings.wsprompt == yes) && (CFG.widescreen)) {/////////////adjust buttons for widescreen
|
||||
@ -1771,8 +1778,10 @@ bool SearchMissingImages(int choice2) {
|
||||
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
promptWindow.SetPosition(0, -10);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -1890,8 +1899,10 @@ bool NetworkInitPrompt() {
|
||||
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
promptWindow.SetPosition(0, -10);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -1922,7 +1933,7 @@ bool NetworkInitPrompt() {
|
||||
btn1Txt.SetWidescreen(CFG.widescreen);
|
||||
btn1Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -45, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -45, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btn1.SetLabel(&btn1Txt);
|
||||
btn1.SetState(STATE_SELECTED);
|
||||
|
||||
@ -1990,8 +2001,10 @@ ProgressDownloadWindow(int choice2) {
|
||||
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
promptWindow.SetPosition(0, -10);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -2050,7 +2063,7 @@ ProgressDownloadWindow(int choice2) {
|
||||
btn1Txt.SetWidescreen(CFG.widescreen);
|
||||
btn1Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -45, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -45, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btn1.SetLabel(&btn1Txt);
|
||||
btn1.SetState(STATE_SELECTED);
|
||||
|
||||
@ -2472,8 +2485,10 @@ int ProgressUpdateWindow() {
|
||||
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
promptWindow.SetPosition(0, -10);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -2535,7 +2550,7 @@ int ProgressUpdateWindow() {
|
||||
btn1Txt.SetWidescreen(CFG.widescreen);
|
||||
btn1Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btn1.SetLabel(&btn1Txt);
|
||||
btn1.SetState(STATE_SELECTED);
|
||||
|
||||
@ -2800,7 +2815,9 @@ int ProgressUpdateWindow() {
|
||||
promptWindow.SetPosition(0, -10);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
// because destroy GuiSound must wait while sound playing is finished, we use a global sound
|
||||
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -3103,8 +3120,10 @@ int CodeDownload(const char *id) {
|
||||
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
promptWindow.SetPosition(0, -10);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -3142,7 +3161,7 @@ int CodeDownload(const char *id) {
|
||||
btn1Txt.SetWidescreen(CFG.widescreen);
|
||||
btn1Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -40, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btn1.SetLabel(&btn1Txt);
|
||||
btn1.SetState(STATE_SELECTED);
|
||||
|
||||
@ -3278,8 +3297,10 @@ HBCWindowPrompt(const char *name, const char *coder, const char *version,
|
||||
GuiTrigger trigD;
|
||||
trigD.SetButtonOnlyTrigger(-1, WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN, PAD_BUTTON_DOWN);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
|
||||
@ -3312,7 +3333,7 @@ HBCWindowPrompt(const char *name, const char *coder, const char *version,
|
||||
arrowUpBtn.SetTrigger(&trigA);
|
||||
arrowUpBtn.SetTrigger(&trigU);
|
||||
arrowUpBtn.SetEffectOnOver(EFFECT_SCALE, 50, 130);
|
||||
arrowUpBtn.SetSoundClick(&btnClick);
|
||||
arrowUpBtn.SetSoundClick(btnClick2);
|
||||
|
||||
GuiButton arrowDownBtn(arrowDownImg.GetWidth(), arrowDownImg.GetHeight());
|
||||
arrowDownBtn.SetImage(&arrowDownImg);
|
||||
@ -3321,7 +3342,7 @@ HBCWindowPrompt(const char *name, const char *coder, const char *version,
|
||||
arrowDownBtn.SetTrigger(&trigA);
|
||||
arrowDownBtn.SetTrigger(&trigD);
|
||||
arrowDownBtn.SetEffectOnOver(EFFECT_SCALE, 50, 130);
|
||||
arrowDownBtn.SetSoundClick(&btnClick);
|
||||
arrowDownBtn.SetSoundClick(btnClick2);
|
||||
|
||||
GuiImageData *iconData =NULL;
|
||||
GuiImage *iconImg =NULL;
|
||||
@ -3415,7 +3436,7 @@ HBCWindowPrompt(const char *name, const char *coder, const char *version,
|
||||
btn1Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
|
||||
GuiButton btn1(&btn1Img, &btn1Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1);
|
||||
GuiButton btn1(&btn1Img, &btn1Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
|
||||
btn1.SetLabel(&btn1Txt);
|
||||
btn1.SetState(STATE_SELECTED);
|
||||
|
||||
@ -3425,7 +3446,7 @@ HBCWindowPrompt(const char *name, const char *coder, const char *version,
|
||||
btn2Txt.SetWidescreen(CFG.widescreen);
|
||||
btn2Img.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton btn2(&btn2Img, &btn2Img, 0,3,0,0,&trigA,&btnSoundOver,&btnClick,1);
|
||||
GuiButton btn2(&btn2Img, &btn2Img, 0,3,0,0,&trigA,&btnSoundOver,btnClick2,1);
|
||||
btn2.SetLabel(&btn2Txt);
|
||||
btn2.SetTrigger(&trigB);
|
||||
|
||||
|
@ -230,8 +230,10 @@ int TitleBrowser(u32 type) {
|
||||
if (IsNetworkInit())
|
||||
ResumeNetworkWait();
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
|
||||
@ -265,7 +267,7 @@ int TitleBrowser(u32 type) {
|
||||
cancelBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
cancelBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2,1);
|
||||
cancelBtn.SetScale(0.9);
|
||||
cancelBtn.SetLabel(&cancelBtnTxt);
|
||||
cancelBtn.SetTrigger(&trigB);
|
||||
|
@ -304,8 +304,10 @@ int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*=
|
||||
GuiTrigger trigB;
|
||||
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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(icon_folder_png);
|
||||
GuiImage folderImg(&folderImgData);
|
||||
@ -354,7 +356,7 @@ int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*=
|
||||
okBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
okBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 40, -35, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 40, -35, &trigA, &btnSoundOver, btnClick2,1);
|
||||
okBtn.SetLabel(&okBtnTxt);
|
||||
|
||||
GuiFileBrowser fileBrowser(396, 248);
|
||||
|
@ -148,8 +148,8 @@ int showGameInfo(char *ID) {
|
||||
txtWindow.SetAlignment(ALIGN_CENTRE, ALIGN_RIGHT);
|
||||
txtWindow.SetPosition(95, 55);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define NAMELENMAX 0x80
|
||||
#define MAXPATHLEN 0x100
|
||||
|
||||
#define FPRINTF(f, ...) {FILE*_fp=fopen("SD:/log.log", "a"); if(_fp) { fprintf(_fp, "%s(%i):" f "\n", __FILE__, __LINE__, ##__VA_ARGS__); fclose(_fp);}}
|
||||
|
||||
|
||||
|
||||
@ -533,7 +532,6 @@ static inline RAMDISK_PARTITION* ramdiskFS_getPartitionFromPath(const char* path
|
||||
//---------------------------------------------------------------------------------
|
||||
static int ramdiskFS_open_r(struct _reent *r, void *file_Struct, const char *path, int flags, int mode) {
|
||||
//---------------------------------------------------------------------------------
|
||||
FPRINTF("ramdiskFS_open_r(%s)", path);
|
||||
FILE_STRUCT *fileStruct = (FILE_STRUCT*)file_Struct;
|
||||
|
||||
|
||||
@ -543,7 +541,6 @@ FPRINTF("ramdiskFS_open_r(%s)", path);
|
||||
r->_errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
FPRINTF("ramdiskFS_open_r Partition found");
|
||||
|
||||
if ((flags & 0x03) == O_RDONLY) {
|
||||
// Open the file for read-only access
|
||||
@ -569,14 +566,12 @@ FPRINTF("ramdiskFS_open_r Partition found");
|
||||
r->_errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
FPRINTF("ok");
|
||||
// It should not be a directory if we're openning a file,
|
||||
if (entry && entry->IsDir())
|
||||
{
|
||||
r->_errno = EISDIR;
|
||||
return -1;
|
||||
}
|
||||
FPRINTF("ok");
|
||||
|
||||
fileStruct->isLink = entry ? entry->IsLink() : false;
|
||||
fileStruct->file = entry ? entry->IsFile() : NULL;
|
||||
@ -600,7 +595,6 @@ FPRINTF("ok");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
FPRINTF("ok");
|
||||
if(fileStruct->file)
|
||||
{
|
||||
fileStruct->current_pos = 0;
|
||||
@ -610,7 +604,6 @@ FPRINTF("ok");
|
||||
if (flags & O_APPEND)
|
||||
fileStruct->current_pos = fileStruct->file->file_len;
|
||||
return 0;
|
||||
FPRINTF("ramdiskFS_open_r ok");
|
||||
}
|
||||
r->_errno = ENOENT;
|
||||
return(-1);
|
||||
@ -641,7 +634,6 @@ static off_t ramdiskFS_seek_r(struct _reent *r, int fd, off_t pos, int dir) {
|
||||
//---------------------------------------------------------------------------------
|
||||
//need check for eof here...
|
||||
FILE_STRUCT *fileStruct = (FILE_STRUCT*)fd;
|
||||
FPRINTF("ramdiskFS_seek_r(%s)", fileStruct->file->name);
|
||||
|
||||
switch(dir)
|
||||
{
|
||||
@ -663,7 +655,6 @@ FPRINTF("ramdiskFS_seek_r(%s)", fileStruct->file->name);
|
||||
//---------------------------------------------------------------------------------
|
||||
static int ramdiskFS_fstat_r(struct _reent *r, int fd, struct stat *st) {
|
||||
//---------------------------------------------------------------------------------
|
||||
FPRINTF("ramdiskFS_fstat_r");
|
||||
FILE_STRUCT *fileStruct = (FILE_STRUCT*)fd;
|
||||
|
||||
st->st_mode = fileStruct->isLink ? S_IFLNK : S_IFREG;
|
||||
@ -674,7 +665,6 @@ FPRINTF("ramdiskFS_fstat_r");
|
||||
//---------------------------------------------------------------------------------
|
||||
static int ramdiskFS_stat_r(struct _reent *r, const char *file, struct stat *st) {
|
||||
//---------------------------------------------------------------------------------
|
||||
FPRINTF("ramdiskFS_stat_r(%s)", file);
|
||||
FILE_STRUCT fileStruct;
|
||||
DIR_STRUCT dirStruct;
|
||||
DIR_ITER dirState;
|
||||
@ -700,7 +690,6 @@ FPRINTF("ramdiskFS_stat_r(%s)", file);
|
||||
//---------------------------------------------------------------------------------
|
||||
static int ramdiskFS_unlink_r(struct _reent *r, const char *name) {
|
||||
//---------------------------------------------------------------------------------
|
||||
FPRINTF("ramdiskFS_unlink_r(%s)", name);
|
||||
RAMDISK_PARTITION *partition = ramdiskFS_getPartitionFromPath(name);
|
||||
if ( partition == NULL )
|
||||
{
|
||||
@ -744,7 +733,6 @@ FPRINTF("ramdiskFS_unlink_r(%s)", name);
|
||||
//---------------------------------------------------------------------------------
|
||||
static int ramdiskFS_chdir_r(struct _reent *r, const char *name) {
|
||||
//---------------------------------------------------------------------------------
|
||||
FPRINTF("ramdiskFS_chdir_r(%s)", name);
|
||||
DIR_STRUCT dirStruct;
|
||||
DIR_ITER dirState;
|
||||
dirState.dirStruct=&dirStruct;
|
||||
@ -765,14 +753,12 @@ FPRINTF("ramdiskFS_chdir_r(%s)", name);
|
||||
}
|
||||
partition->cwd = dirStruct.dir;
|
||||
ramdiskFS_dirclose_r(r, &dirState);
|
||||
FPRINTF("ok");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
static int ramdiskFS_mkdir_r(struct _reent *r, const char *path, int mode) {
|
||||
//---------------------------------------------------------------------------------
|
||||
FPRINTF("ramdiskFS_mkdir_r(%s)", path);
|
||||
RAMDISK_PARTITION *partition = ramdiskFS_getPartitionFromPath(path);
|
||||
if ( partition == NULL )
|
||||
{
|
||||
@ -802,12 +788,10 @@ FPRINTF("ramdiskFS_mkdir_r(%s)", path);
|
||||
static DIR_ITER* ramdiskFS_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path) {
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
FPRINTF("DirOpen %s", path);
|
||||
DIR_STRUCT *dirStruct = (DIR_STRUCT*)dirState->dirStruct;
|
||||
char *cptr;
|
||||
|
||||
RAMDISK_PARTITION *partition = ramdiskFS_getPartitionFromPath(path);
|
||||
FPRINTF("partition %p", partition);
|
||||
if ( partition == NULL )
|
||||
{
|
||||
r->_errno = ENODEV;
|
||||
@ -828,7 +812,6 @@ static DIR_ITER* ramdiskFS_diropen_r(struct _reent *r, DIR_ITER *dirState, const
|
||||
dirStruct->dir = partition->cwd; //else use current working dir
|
||||
|
||||
RAMDISK_BASE_ENTRY *entry = dirStruct->dir->FindEntry(path);
|
||||
FPRINTF("entry %p", entry);
|
||||
if(entry==NULL)
|
||||
{
|
||||
r->_errno = ENOENT;
|
||||
@ -860,20 +843,15 @@ static int ramdiskFS_dirnext_r(struct _reent *r, DIR_ITER *dirState, char *filen
|
||||
DIR_STRUCT *dirStruct = (DIR_STRUCT*)dirState->dirStruct;
|
||||
// RAMDISK_BASE_ENTRY **dirStruct = (RAMDISK_BASE_ENTRY**)dirState->dirStruct;
|
||||
|
||||
FPRINTF("DirNext");
|
||||
|
||||
if(dirStruct->current_entry)
|
||||
{
|
||||
FPRINTF("current_entry = %s",dirStruct->current_entry->name);
|
||||
strcpy(filename, dirStruct->current_entry->name);
|
||||
if(dirStruct->current_entry->IsDir())
|
||||
{
|
||||
FPRINTF("IsDir");
|
||||
if(st) st->st_mode=S_IFDIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
FPRINTF("IsFile");
|
||||
if(st) st->st_mode=0;
|
||||
}
|
||||
dirStruct->current_entry = dirStruct->current_entry->next;
|
||||
@ -947,7 +925,6 @@ extern "C" void ramdiskUnmount(const char *mountpoint) {
|
||||
//---------------------------------------------------------------------------------
|
||||
int ramdiskFS_Mount(const char *mountpoint, void *handle) {
|
||||
//---------------------------------------------------------------------------------
|
||||
FPRINTF("Mount %s", mountpoint);
|
||||
devoptab_t* devops;
|
||||
char* nameCopy;
|
||||
RAMDISK_PARTITION** partition;
|
||||
@ -989,14 +966,12 @@ int ramdiskFS_Mount(const char *mountpoint, void *handle) {
|
||||
else
|
||||
*partition = new RAMDISK_PARTITION(Mountpoint, true);
|
||||
devops->deviceData = partition;
|
||||
FPRINTF("devops=%p nameCopy=%p(%s) partition=%p", devops, nameCopy, nameCopy, partition);
|
||||
|
||||
if(AddDevice(devops)<0)
|
||||
{
|
||||
free(devops);
|
||||
return false;
|
||||
}
|
||||
FPRINTF("mounted");
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -71,9 +71,11 @@ int MenuSettings()
|
||||
|
||||
int slidedirection = FADE;
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
|
||||
@ -135,7 +137,7 @@ int MenuSettings()
|
||||
backBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
backBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2,1);
|
||||
backBtn.SetLabel(&backBtnTxt);
|
||||
backBtn.SetTrigger(&trigB);
|
||||
|
||||
@ -184,7 +186,7 @@ int MenuSettings()
|
||||
GoLeftBtn.SetPosition(25, -25);
|
||||
GoLeftBtn.SetImage(&GoLeftImg);
|
||||
GoLeftBtn.SetSoundOver(&btnSoundOver);
|
||||
GoLeftBtn.SetSoundClick(&btnClick);
|
||||
GoLeftBtn.SetSoundClick(btnClick2);
|
||||
GoLeftBtn.SetEffectGrow();
|
||||
GoLeftBtn.SetTrigger(&trigA);
|
||||
GoLeftBtn.SetTrigger(&trigL);
|
||||
@ -196,7 +198,7 @@ int MenuSettings()
|
||||
GoRightBtn.SetPosition(-25, -25);
|
||||
GoRightBtn.SetImage(&GoRightImg);
|
||||
GoRightBtn.SetSoundOver(&btnSoundOver);
|
||||
GoRightBtn.SetSoundClick(&btnClick);
|
||||
GoRightBtn.SetSoundClick(btnClick2);
|
||||
GoRightBtn.SetEffectGrow();
|
||||
GoRightBtn.SetTrigger(&trigA);
|
||||
GoRightBtn.SetTrigger(&trigR);
|
||||
@ -665,15 +667,9 @@ int MenuSettings()
|
||||
{
|
||||
cfg_save_global();
|
||||
optionBrowser2.SetState(STATE_DISABLED);
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path))
|
||||
bgMusic->Play();
|
||||
else
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
if (choice == 3)
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
else if (choice == 2)
|
||||
@ -908,15 +904,9 @@ int MenuSettings()
|
||||
{
|
||||
cfg_save_global();
|
||||
optionBrowser2.SetState(STATE_DISABLED);
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path))
|
||||
bgMusic->Play();
|
||||
else
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
if (choice == 3)
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
if (choice == 2)
|
||||
@ -1060,15 +1050,9 @@ int MenuSettings()
|
||||
{
|
||||
cfg_save_global();
|
||||
optionBrowser2.SetState(STATE_DISABLED);
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path))
|
||||
bgMusic->Play();
|
||||
else
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
if (choice == 3)
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
else if (choice == 2)
|
||||
@ -1238,15 +1222,9 @@ int MenuSettings()
|
||||
{
|
||||
cfg_save_global();
|
||||
optionBrowser2.SetState(STATE_DISABLED);
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path))
|
||||
bgMusic->Play();
|
||||
else
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
if (choice == 3)
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
else if (choice == 2)
|
||||
@ -1298,7 +1276,7 @@ int MenuSettings()
|
||||
Settings.volume += 10;
|
||||
if (Settings.volume > 100)
|
||||
Settings.volume = 0;
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->SetVolume(Settings.volume);
|
||||
}
|
||||
if (Settings.volume > 0)
|
||||
options2.SetValue(Idx,"%i", Settings.volume);
|
||||
@ -1315,7 +1293,7 @@ int MenuSettings()
|
||||
if (Settings.sfxvolume > 100)
|
||||
Settings.sfxvolume = 0;
|
||||
btnSoundOver.SetVolume(Settings.sfxvolume);
|
||||
btnClick.SetVolume(Settings.sfxvolume);
|
||||
btnClick2->SetVolume(Settings.sfxvolume);
|
||||
btnClick1.SetVolume(Settings.sfxvolume);
|
||||
}
|
||||
if (Settings.sfxvolume > 0)
|
||||
@ -1420,15 +1398,9 @@ int MenuSettings()
|
||||
{
|
||||
cfg_save_global();
|
||||
optionBrowser2.SetState(STATE_DISABLED);
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path))
|
||||
bgMusic->Play();
|
||||
else
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
if (choice == 3)
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
else if (choice == 2)
|
||||
@ -2010,15 +1982,9 @@ int MenuSettings()
|
||||
{
|
||||
cfg_save_global();
|
||||
optionBrowser2.SetState(STATE_DISABLED);
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path))
|
||||
bgMusic->Play();
|
||||
else
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
|
||||
if (choice == 3)
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
@ -2070,9 +2036,11 @@ int GameSettings(struct discHdr * header)
|
||||
|
||||
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
|
||||
@ -2124,7 +2092,7 @@ int GameSettings(struct discHdr * header)
|
||||
backBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
backBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2,1);
|
||||
backBtn.SetLabel(&backBtnTxt);
|
||||
backBtn.SetTrigger(&trigB);
|
||||
|
||||
@ -2139,7 +2107,7 @@ int GameSettings(struct discHdr * header)
|
||||
saveBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
saveBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton saveBtn(&saveBtnImg,&saveBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton saveBtn(&saveBtnImg,&saveBtnImg, 2, 3, 180, 400, &trigA, &btnSoundOver, btnClick2,1);
|
||||
saveBtn.SetLabel(&saveBtnTxt);
|
||||
|
||||
|
||||
@ -2384,15 +2352,9 @@ int GameSettings(struct discHdr * header)
|
||||
{
|
||||
cfg_save_global();
|
||||
optionBrowser2.SetState(STATE_DISABLED);
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path))
|
||||
bgMusic->Play();
|
||||
else
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
if (choice == 3)
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
else if (choice == 2)
|
||||
@ -2654,15 +2616,9 @@ int GameSettings(struct discHdr * header)
|
||||
{
|
||||
cfg_save_global();
|
||||
optionBrowser2.SetState(STATE_DISABLED);
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path))
|
||||
bgMusic->Play();
|
||||
else
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
if (choice == 3)
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
else if (choice == 2)
|
||||
@ -2860,24 +2816,9 @@ int GameSettings(struct discHdr * header)
|
||||
{
|
||||
cfg_save_global();
|
||||
optionBrowser2.SetState(STATE_DISABLED);
|
||||
s32 thetimeofbg = bgMusic->GetPlayTime();
|
||||
bgMusic->Stop();
|
||||
bgMusic->Pause();
|
||||
choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0);
|
||||
/*
|
||||
// if language has changed, reload titles
|
||||
int opt_langnew = 0;
|
||||
game_cfg = CFG_get_game_opt(header->id);
|
||||
if (game_cfg) opt_langnew = game_cfg->language;
|
||||
if (Settings.titlesOverride==1 && opt_lang != opt_langnew)
|
||||
OpenXMLDatabase(Settings.titlestxt_path, Settings.db_language, Settings.db_JPtoEN, false, Settings.titlesOverride==1?true:false, true); // open file, reload titles, keep in memory
|
||||
// titles are refreshed in menu.cpp as soon as this function returns
|
||||
*/
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path))
|
||||
bgMusic->Play();
|
||||
else
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
bgMusic->SetPlayTime(thetimeofbg);
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->Resume();
|
||||
|
||||
if (choice == 3)
|
||||
Sys_LoadMenu(); // Back to System Menu
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "fatmounter.h"
|
||||
#include "filelist.h"
|
||||
#include "sys.h"
|
||||
#include "menu.h"
|
||||
|
||||
|
||||
/*** Extern variables ***/
|
||||
@ -36,8 +37,10 @@ bool MenuOGG() {
|
||||
int scrollon, nothingchanged = 0;
|
||||
bool returnhere = false;
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
|
||||
@ -73,7 +76,7 @@ bool MenuOGG() {
|
||||
pathBtn.SetPosition(0,28);
|
||||
pathBtn.SetLabel(&titleTxt);
|
||||
pathBtn.SetSoundOver(&btnSoundOver);
|
||||
pathBtn.SetSoundClick(&btnClick);
|
||||
pathBtn.SetSoundClick(btnClick2);
|
||||
pathBtn.SetTrigger(&trigA);
|
||||
pathBtn.SetEffectGrow();
|
||||
|
||||
@ -94,7 +97,7 @@ bool MenuOGG() {
|
||||
backBtn.SetLabel(&backBtnTxt);
|
||||
backBtn.SetImage(&backBtnImg);
|
||||
backBtn.SetSoundOver(&btnSoundOver);
|
||||
backBtn.SetSoundClick(&btnClick);
|
||||
backBtn.SetSoundClick(btnClick2);
|
||||
backBtn.SetTrigger(&trigA);
|
||||
backBtn.SetTrigger(&trigB);
|
||||
backBtn.SetEffectGrow();
|
||||
@ -112,7 +115,7 @@ bool MenuOGG() {
|
||||
defaultBtn.SetLabel(&defaultBtnTxt);
|
||||
defaultBtn.SetImage(&defaultBtnImg);
|
||||
defaultBtn.SetSoundOver(&btnSoundOver);
|
||||
defaultBtn.SetSoundClick(&btnClick);
|
||||
defaultBtn.SetSoundClick(btnClick2);
|
||||
defaultBtn.SetTrigger(&trigA);
|
||||
defaultBtn.SetEffectGrow();
|
||||
|
||||
@ -145,7 +148,7 @@ bool MenuOGG() {
|
||||
playBtn.SetPosition(50, 400);
|
||||
playBtn.SetImage(&playBtnImg);
|
||||
playBtn.SetSoundOver(&btnSoundOver);
|
||||
playBtn.SetSoundClick(&btnClick);
|
||||
playBtn.SetSoundClick(btnClick2);
|
||||
playBtn.SetTrigger(&trigA);
|
||||
playBtn.SetTrigger(&trigPlus);
|
||||
playBtn.SetEffectGrow();
|
||||
@ -157,7 +160,7 @@ bool MenuOGG() {
|
||||
stopBtn.SetPosition(-15, 400);
|
||||
stopBtn.SetImage(&stopBtnImg);
|
||||
stopBtn.SetSoundOver(&btnSoundOver);
|
||||
stopBtn.SetSoundClick(&btnClick);
|
||||
stopBtn.SetSoundClick(btnClick2);
|
||||
stopBtn.SetTrigger(&trigA);
|
||||
stopBtn.SetTrigger(&trigMinus);
|
||||
stopBtn.SetEffectGrow();
|
||||
@ -187,11 +190,12 @@ bool MenuOGG() {
|
||||
|
||||
if (backBtn.GetState() == STATE_CLICKED) {
|
||||
if (nothingchanged == 1 && countoggs > 0) {
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) {
|
||||
bgMusic->Play();
|
||||
if (strcmp("", Settings.oggload_path) && strcmp("notset", Settings.ogg_path)) {
|
||||
bgMusic->Load(Settings.ogg_path);
|
||||
} else {
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
bgMusic->Load(bg_music_ogg, bg_music_ogg_size, true);
|
||||
}
|
||||
bgMusic->Play();
|
||||
}
|
||||
backBtn.ResetState();
|
||||
break;
|
||||
@ -201,8 +205,9 @@ bool MenuOGG() {
|
||||
choice = WindowPrompt(tr("Loading standard music."),0,tr("OK"), tr("Cancel"));
|
||||
if (choice == 1) {
|
||||
sprintf(Settings.ogg_path, "notset");
|
||||
bgMusic->Load(bg_music_ogg, bg_music_ogg_size, true);
|
||||
bgMusic->Play();
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->SetVolume(Settings.volume);
|
||||
cfg_save_global();
|
||||
}
|
||||
defaultBtn.ResetState();
|
||||
@ -255,20 +260,18 @@ bool MenuOGG() {
|
||||
if (ret>=0) {
|
||||
choice = WindowPrompt(tr("Set as backgroundmusic?"),GetFileName(ret),tr("Yes"),tr("No"));
|
||||
if (choice == 1) {
|
||||
StopOgg();
|
||||
snprintf(fullpath,150,"%s%s",Settings.oggload_path,GetFileName(ret));
|
||||
choice = bgMusic->PlayOggFile(fullpath);
|
||||
if (choice < 0) {
|
||||
if (!bgMusic->Load(fullpath)) {
|
||||
WindowPrompt(tr("Not supported format!"), tr("Loading standard music."), tr("OK"));
|
||||
sprintf(Settings.ogg_path, "notset");
|
||||
bgMusic->Play();
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
} else {
|
||||
snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s", fullpath);
|
||||
cfg_save_global();
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->SetVolume(Settings.volume);
|
||||
nothingchanged = 0;
|
||||
}
|
||||
bgMusic->Play();
|
||||
bgMusic->SetVolume(Settings.volume);
|
||||
}
|
||||
optionBrowser4.SetFocus(1);
|
||||
}
|
||||
@ -277,16 +280,11 @@ bool MenuOGG() {
|
||||
if (countoggs > 0) {
|
||||
ret = optionBrowser4.GetSelectedOption();
|
||||
snprintf(fullpath, 150,"%s%s", Settings.oggload_path,GetFileName(ret));
|
||||
choice = bgMusic->PlayOggFile(fullpath);
|
||||
if (choice < 0) {
|
||||
if (!bgMusic->Load(fullpath)) {
|
||||
WindowPrompt(tr("Not supported format!"), tr("Loading standard music."), tr("OK"));
|
||||
if (!strcmp("", Settings.oggload_path) || !strcmp("notset", Settings.ogg_path)) {
|
||||
}
|
||||
bgMusic->Play();
|
||||
} else {
|
||||
bgMusic->PlayOggFile(Settings.ogg_path);
|
||||
}
|
||||
}
|
||||
SetVolumeOgg(255*(Settings.volume/100.0));
|
||||
bgMusic->SetVolume(Settings.volume);
|
||||
nothingchanged = 1;
|
||||
optionBrowser4.SetFocus(1);
|
||||
}
|
||||
@ -295,7 +293,7 @@ bool MenuOGG() {
|
||||
|
||||
if (stopBtn.GetState() == STATE_CLICKED) {
|
||||
if (countoggs > 0) {
|
||||
StopOgg();
|
||||
bgMusic->Stop();
|
||||
nothingchanged = 1;
|
||||
optionBrowser4.SetFocus(1);
|
||||
}
|
||||
@ -322,8 +320,10 @@ int MenuLanguageSelect() {
|
||||
int scrollon;
|
||||
int returnhere = 0;
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
|
||||
@ -354,7 +354,7 @@ int MenuLanguageSelect() {
|
||||
pathBtn.SetPosition(0,28);
|
||||
pathBtn.SetLabel(&titleTxt);
|
||||
pathBtn.SetSoundOver(&btnSoundOver);
|
||||
pathBtn.SetSoundClick(&btnClick);
|
||||
pathBtn.SetSoundClick(btnClick2);
|
||||
pathBtn.SetTrigger(&trigA);
|
||||
pathBtn.SetEffectGrow();
|
||||
|
||||
@ -375,7 +375,7 @@ int MenuLanguageSelect() {
|
||||
backBtn.SetLabel(&backBtnTxt);
|
||||
backBtn.SetImage(&backBtnImg);
|
||||
backBtn.SetSoundOver(&btnSoundOver);
|
||||
backBtn.SetSoundClick(&btnClick);
|
||||
backBtn.SetSoundClick(btnClick2);
|
||||
backBtn.SetTrigger(&trigA);
|
||||
backBtn.SetTrigger(&trigB);
|
||||
backBtn.SetEffectGrow();
|
||||
@ -393,7 +393,7 @@ int MenuLanguageSelect() {
|
||||
defaultBtn.SetLabel(&defaultBtnTxt);
|
||||
defaultBtn.SetImage(&defaultBtnImg);
|
||||
defaultBtn.SetSoundOver(&btnSoundOver);
|
||||
defaultBtn.SetSoundClick(&btnClick);
|
||||
defaultBtn.SetSoundClick(btnClick2);
|
||||
defaultBtn.SetTrigger(&trigA);
|
||||
defaultBtn.SetEffectGrow();
|
||||
|
||||
@ -410,7 +410,7 @@ int MenuLanguageSelect() {
|
||||
updateBtn.SetLabel(&updateBtnTxt);
|
||||
updateBtn.SetImage(&updateBtnImg);
|
||||
updateBtn.SetSoundOver(&btnSoundOver);
|
||||
updateBtn.SetSoundClick(&btnClick);
|
||||
updateBtn.SetSoundClick(btnClick2);
|
||||
updateBtn.SetTrigger(&trigA);
|
||||
updateBtn.SetEffectGrow();
|
||||
|
||||
|
@ -421,6 +421,7 @@ extern "C" {
|
||||
u8 discart;
|
||||
short gamesound;
|
||||
};
|
||||
extern struct SSettings Settings;
|
||||
|
||||
void CFG_LoadGlobal(void);
|
||||
bool cfg_save_global(void);
|
||||
|
Binary file not shown.
@ -119,8 +119,10 @@ static void Theme_Prompt(const char *title, const char *author, GuiImageData *th
|
||||
{
|
||||
bool leave = false;
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -165,7 +167,7 @@ static void Theme_Prompt(const char *title, const char *author, GuiImageData *th
|
||||
downloadBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
downloadBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton downloadBtn(&downloadBtnImg,&downloadBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 170, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton downloadBtn(&downloadBtnImg,&downloadBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 170, &trigA, &btnSoundOver, btnClick2,1);
|
||||
downloadBtn.SetLabel(&downloadBtnTxt);
|
||||
downloadBtn.SetScale(0.9);
|
||||
|
||||
@ -177,7 +179,7 @@ static void Theme_Prompt(const char *title, const char *author, GuiImageData *th
|
||||
backBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
backBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 220, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 220, &trigA, &btnSoundOver, btnClick2,1);
|
||||
backBtn.SetLabel(&backBtnTxt);
|
||||
backBtn.SetTrigger(&trigB);
|
||||
backBtn.SetScale(0.9);
|
||||
@ -253,9 +255,11 @@ int Theme_Downloader()
|
||||
char THEME_LINK[30] = "http://wii.spiffy360.com/";
|
||||
|
||||
/*** Sound Variables ***/
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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 ***/
|
||||
char imgPath[150];
|
||||
@ -341,7 +345,7 @@ int Theme_Downloader()
|
||||
backBtnTxt.SetWidescreen(CFG.widescreen);
|
||||
backBtnImg.SetWidescreen(CFG.widescreen);
|
||||
}
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2,1);
|
||||
backBtn.SetLabel(&backBtnTxt);
|
||||
backBtn.SetTrigger(&trigB);
|
||||
|
||||
@ -354,7 +358,7 @@ int Theme_Downloader()
|
||||
GoLeftBtn.SetPosition(25, -25);
|
||||
GoLeftBtn.SetImage(&GoLeftImg);
|
||||
GoLeftBtn.SetSoundOver(&btnSoundOver);
|
||||
GoLeftBtn.SetSoundClick(&btnClick);
|
||||
GoLeftBtn.SetSoundClick(btnClick2);
|
||||
GoLeftBtn.SetEffectGrow();
|
||||
GoLeftBtn.SetTrigger(&trigA);
|
||||
GoLeftBtn.SetTrigger(&trigL);
|
||||
@ -366,7 +370,7 @@ int Theme_Downloader()
|
||||
GoRightBtn.SetPosition(-25, -25);
|
||||
GoRightBtn.SetImage(&GoRightImg);
|
||||
GoRightBtn.SetSoundOver(&btnSoundOver);
|
||||
GoRightBtn.SetSoundClick(&btnClick);
|
||||
GoRightBtn.SetSoundClick(btnClick2);
|
||||
GoRightBtn.SetEffectGrow();
|
||||
GoRightBtn.SetTrigger(&trigA);
|
||||
GoRightBtn.SetTrigger(&trigR);
|
||||
|
@ -234,7 +234,7 @@ s32 Disc_Wait(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 Disc_SetUSB(u8 *id) {
|
||||
s32 Disc_SetUSB(const u8 *id) {
|
||||
/* Set USB mode */
|
||||
return WDVD_SetUSBMode(id);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ extern "C" {
|
||||
s32 Disc_Open(void);
|
||||
s32 Disc_Wait(void);
|
||||
void __Disc_SetLowMem(void);
|
||||
s32 Disc_SetUSB(u8 *);
|
||||
s32 Disc_SetUSB(const u8 *);
|
||||
s32 Disc_ReadHeader(void *);
|
||||
s32 Disc_IsWii(void);
|
||||
s32 Disc_BootPartition(u64, u8, u8, u8, u8, u8, u8, u32);
|
||||
|
@ -306,7 +306,7 @@ s32 WDVD_DisableReset(u8 val) {
|
||||
}
|
||||
|
||||
/** Hermes **/
|
||||
s32 WDVD_SetUSBMode(u8 *id) {
|
||||
s32 WDVD_SetUSBMode(const u8 *id) {
|
||||
s32 ret;
|
||||
|
||||
memset(inbuf, 0, sizeof(inbuf));
|
||||
|
@ -22,7 +22,7 @@ extern "C" {
|
||||
s32 WDVD_WaitForDisc(void);
|
||||
s32 WDVD_GetCoverStatus(u32 *);
|
||||
s32 WDVD_DisableReset(u8);
|
||||
s32 WDVD_SetUSBMode(u8 *);
|
||||
s32 WDVD_SetUSBMode(const u8 *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -124,8 +124,10 @@ s32 Wad_Install(FILE *fp)
|
||||
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
promptWindow.SetPosition(0, -10);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -144,7 +146,7 @@ s32 Wad_Install(FILE *fp)
|
||||
if (Settings.wsprompt == yes){
|
||||
btn1Txt.SetWidescreen(CFG.widescreen);
|
||||
btn1Img.SetWidescreen(CFG.widescreen);}
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -35, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -35, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btn1.SetLabel(&btn1Txt);
|
||||
btn1.SetState(STATE_SELECTED);
|
||||
|
||||
@ -453,8 +455,10 @@ s32 Wad_Uninstall(FILE *fp)
|
||||
promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
promptWindow.SetPosition(0, -10);
|
||||
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
|
||||
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);
|
||||
|
||||
char imgPath[100];
|
||||
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
|
||||
@ -473,7 +477,7 @@ s32 Wad_Uninstall(FILE *fp)
|
||||
if (Settings.wsprompt == yes){
|
||||
btn1Txt.SetWidescreen(CFG.widescreen);
|
||||
btn1Img.SetWidescreen(CFG.widescreen);}
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -55, &trigA, &btnSoundOver, &btnClick,1);
|
||||
GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -55, &trigA, &btnSoundOver, btnClick2,1);
|
||||
btn1.SetLabel(&btn1Txt);
|
||||
btn1.SetState(STATE_SELECTED);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user