mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-01 00:55:06 +01:00
Making things ready for official wiiflow svn ;)
-made wait animation faster -removed a few unneeded lines in the wait message code -fixed booting wii games from disc -fixed possible bug in wii game launching in general -gecko output again on wii game booting -converted alot of spaces to tabs, fitting the general wiiflow coding style -general cleaning up things
This commit is contained in:
parent
6cb919c7ae
commit
a36fab3cdd
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
fat.h
|
fat.h
|
||||||
Simple functionality for startup, mounting and unmounting of FAT-based devices.
|
Simple functionality for startup, mounting and unmounting of FAT-based devices.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2009
|
Copyright (c) 2006 - 2009
|
||||||
Michael "Chishm" Chisholm
|
Michael "Chishm" Chisholm
|
||||||
Dave "WinterMute" Murphy
|
Dave "WinterMute" Murphy
|
||||||
@ -71,7 +71,7 @@ extern bool fatInitDefault (void);
|
|||||||
/*
|
/*
|
||||||
Mount the device pointed to by interface, and set up a devoptab entry for it as "name:".
|
Mount the device pointed to by interface, and set up a devoptab entry for it as "name:".
|
||||||
You can then access the filesystem using "name:/".
|
You can then access the filesystem using "name:/".
|
||||||
This will mount the active partition or the first valid partition on the disc,
|
This will mount the active partition or the first valid partition on the disc,
|
||||||
and will use a cache size optimized for the host system.
|
and will use a cache size optimized for the host system.
|
||||||
*/
|
*/
|
||||||
extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface);
|
extern bool fatMountSimple (const char* name, const DISC_INTERFACE* interface);
|
||||||
|
@ -14,17 +14,9 @@
|
|||||||
#include "gecko.h"
|
#include "gecko.h"
|
||||||
#include "mem2.hpp"
|
#include "mem2.hpp"
|
||||||
|
|
||||||
#define STACK_ALIGN(type, name, cnt, alignment) \
|
|
||||||
u8 _al__##name[((sizeof(type)*(cnt)) + (alignment) + \
|
|
||||||
(((sizeof(type)*(cnt))%(alignment)) > 0 ? ((alignment) - \
|
|
||||||
((sizeof(type)*(cnt))%(alignment))) : 0))]; \
|
|
||||||
type *name = (type*)(((u32)(_al__##name)) + ((alignment) - (( \
|
|
||||||
(u32)(_al__##name))&((alignment)-1))))
|
|
||||||
|
|
||||||
void __Disc_SetLowMem(void);
|
void __Disc_SetLowMem(void);
|
||||||
void __Disc_SetTime(void);
|
void __Disc_SetTime(void);
|
||||||
void _unstub_start();
|
void _unstub_start();
|
||||||
u32 entryPoint;
|
|
||||||
|
|
||||||
extern void __exception_closeall();
|
extern void __exception_closeall();
|
||||||
|
|
||||||
@ -41,6 +33,8 @@ typedef struct _dolheader
|
|||||||
u32 padding[7];
|
u32 padding[7];
|
||||||
} __attribute__((packed)) dolheader;
|
} __attribute__((packed)) dolheader;
|
||||||
|
|
||||||
|
u32 entryPoint;
|
||||||
|
|
||||||
s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio)
|
s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio)
|
||||||
{
|
{
|
||||||
gprintf("Loading Channel...\n");
|
gprintf("Loading Channel...\n");
|
||||||
|
@ -315,7 +315,7 @@ s32 Nand::__configread(void)
|
|||||||
configloaded = configloaded ? false : true;
|
configloaded = configloaded ? false : true;
|
||||||
|
|
||||||
if(tbdec && configloaded)
|
if(tbdec && configloaded)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -422,10 +422,10 @@ u32 Nand::__configsetsetting(const char *item, const char *val)
|
|||||||
void Nand::__FATify(char *ptr, const char *str)
|
void Nand::__FATify(char *ptr, const char *str)
|
||||||
{
|
{
|
||||||
char ctr;
|
char ctr;
|
||||||
while ((ctr = *(str++)) != '\0')
|
while((ctr = *(str++)) != '\0')
|
||||||
{
|
{
|
||||||
const char *esc;
|
const char *esc;
|
||||||
switch (ctr)
|
switch(ctr)
|
||||||
{
|
{
|
||||||
case '"':
|
case '"':
|
||||||
esc = "&qt;";
|
esc = "&qt;";
|
||||||
@ -468,13 +468,20 @@ void Nand::__NANDify(char *str)
|
|||||||
{
|
{
|
||||||
if(c == '&')
|
if(c == '&')
|
||||||
{
|
{
|
||||||
if(!strncmp(src, "qt;", 3)) c = '"';
|
if(!strncmp(src, "qt;", 3))
|
||||||
else if (!strncmp(src, "st;", 3)) c = '*';
|
c = '"';
|
||||||
else if (!strncmp(src, "cl;", 3)) c = ':';
|
else if(!strncmp(src, "st;", 3))
|
||||||
else if (!strncmp(src, "lt;", 3)) c = '<';
|
c = '*';
|
||||||
else if (!strncmp(src, "gt;", 3)) c = '>';
|
else if(!strncmp(src, "cl;", 3))
|
||||||
else if (!strncmp(src, "qm;", 3)) c = '?';
|
c = ':';
|
||||||
else if (!strncmp(src, "vb;", 3)) c = '|';
|
else if(!strncmp(src, "lt;", 3))
|
||||||
|
c = '<';
|
||||||
|
else if(!strncmp(src, "gt;", 3))
|
||||||
|
c = '>';
|
||||||
|
else if(!strncmp(src, "qm;", 3))
|
||||||
|
c = '?';
|
||||||
|
else if(!strncmp(src, "vb;", 3))
|
||||||
|
c = '|';
|
||||||
|
|
||||||
if (c != '&')
|
if (c != '&')
|
||||||
src += 3;
|
src += 3;
|
||||||
@ -558,7 +565,7 @@ s32 Nand::__FlashNandFile(const char *source, const char *dest)
|
|||||||
const char *file = strrchr(dest, '/')+1;
|
const char *file = strrchr(dest, '/')+1;
|
||||||
dumper(NandDone, NandSize, fsize, FileDone, FilesDone, FoldersDone, (char *)file, data);
|
dumper(NandDone, NandSize, fsize, FileDone, FilesDone, FoldersDone, (char *)file, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gprintf(" done!\n");
|
gprintf(" done!\n");
|
||||||
FilesDone++;
|
FilesDone++;
|
||||||
if(showprogress)
|
if(showprogress)
|
||||||
@ -568,13 +575,13 @@ s32 Nand::__FlashNandFile(const char *source, const char *dest)
|
|||||||
}
|
}
|
||||||
ISFS_Close(fd);
|
ISFS_Close(fd);
|
||||||
MEM2_free(buffer);
|
MEM2_free(buffer);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Nand::__DumpNandFile(const char *source, const char *dest)
|
s32 Nand::__DumpNandFile(const char *source, const char *dest)
|
||||||
{
|
{
|
||||||
FileDone = 0;
|
FileDone = 0;
|
||||||
s32 fd = ISFS_Open(source, ISFS_OPEN_READ);
|
s32 fd = ISFS_Open(source, ISFS_OPEN_READ);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
@ -667,8 +674,8 @@ s32 Nand::__DumpNandFile(const char *source, const char *dest)
|
|||||||
dumper(NandDone, NandSize, status->file_length, FileDone, FilesDone, FoldersDone, (char *)file, data);
|
dumper(NandDone, NandSize, status->file_length, FileDone, FilesDone, FoldersDone, (char *)file, data);
|
||||||
}
|
}
|
||||||
gprintf(" done!\n");
|
gprintf(" done!\n");
|
||||||
fclose(file);
|
fclose(file);
|
||||||
ISFS_Close(fd);
|
ISFS_Close(fd);
|
||||||
MEM2_free(status);
|
MEM2_free(status);
|
||||||
MEM2_free(buffer);
|
MEM2_free(buffer);
|
||||||
|
|
||||||
@ -705,16 +712,16 @@ s32 Nand::__FlashNandFolder(const char *source, const char *dest)
|
|||||||
|
|
||||||
if(ent->d_type == DT_DIR)
|
if(ent->d_type == DT_DIR)
|
||||||
{
|
{
|
||||||
__NANDify(ndest);
|
__NANDify(ndest);
|
||||||
if(!fake)
|
if(!fake)
|
||||||
{
|
{
|
||||||
ISFS_CreateDir(ndest, 0, 3, 3, 3);
|
ISFS_CreateDir(ndest, 0, 3, 3, 3);
|
||||||
FoldersDone++;
|
FoldersDone++;
|
||||||
}
|
}
|
||||||
__FlashNandFolder(nsource, ndest);
|
__FlashNandFolder(nsource, ndest);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
__NANDify(ndest);
|
__NANDify(ndest);
|
||||||
__FlashNandFile(nsource, ndest);
|
__FlashNandFile(nsource, ndest);
|
||||||
}
|
}
|
||||||
@ -730,18 +737,18 @@ s32 Nand::__DumpNandFolder(const char *source, const char *dest)
|
|||||||
char ndest[MAX_FAT_PATH];
|
char ndest[MAX_FAT_PATH];
|
||||||
char tdest[MAX_FAT_PATH];
|
char tdest[MAX_FAT_PATH];
|
||||||
|
|
||||||
__GetNameList(source, &names, &cnt);
|
__GetNameList(source, &names, &cnt);
|
||||||
|
|
||||||
for(i = 0; i < cnt; i++)
|
for(i = 0; i < cnt; i++)
|
||||||
{
|
{
|
||||||
if(source[strlen(source)-1] == '/')
|
if(source[strlen(source)-1] == '/')
|
||||||
snprintf(nsource, sizeof(nsource), "%s%s", source, names[i].name);
|
snprintf(nsource, sizeof(nsource), "%s%s", source, names[i].name);
|
||||||
else
|
else
|
||||||
snprintf(nsource, sizeof(nsource), "%s/%s", source, names[i].name);
|
snprintf(nsource, sizeof(nsource), "%s/%s", source, names[i].name);
|
||||||
|
|
||||||
if(!names[i].type)
|
if(!names[i].type)
|
||||||
{
|
{
|
||||||
__FATify(tdest, nsource);
|
__FATify(tdest, nsource);
|
||||||
snprintf(ndest, sizeof(ndest), "%s%s", dest, tdest);
|
snprintf(ndest, sizeof(ndest), "%s%s", dest, tdest);
|
||||||
__DumpNandFile(nsource, ndest);
|
__DumpNandFile(nsource, ndest);
|
||||||
}
|
}
|
||||||
@ -749,7 +756,7 @@ s32 Nand::__DumpNandFolder(const char *source, const char *dest)
|
|||||||
{
|
{
|
||||||
if(!fake)
|
if(!fake)
|
||||||
{
|
{
|
||||||
__FATify(tdest, nsource);
|
__FATify(tdest, nsource);
|
||||||
CreatePath("%s%s", dest, tdest);
|
CreatePath("%s%s", dest, tdest);
|
||||||
FoldersDone++;
|
FoldersDone++;
|
||||||
}
|
}
|
||||||
@ -769,7 +776,7 @@ void Nand::CreatePath(const char *path, ...)
|
|||||||
if((vasprintf(&folder, path, args) >= 0) && folder)
|
if((vasprintf(&folder, path, args) >= 0) && folder)
|
||||||
{
|
{
|
||||||
if(folder[strlen(folder)-1] == '/')
|
if(folder[strlen(folder)-1] == '/')
|
||||||
folder[strlen(folder)-1] = 0;
|
folder[strlen(folder)-1] = 0;
|
||||||
|
|
||||||
char *check = folder;
|
char *check = folder;
|
||||||
while (true)
|
while (true)
|
||||||
@ -840,9 +847,9 @@ s32 Nand::FlashToNAND(const char *source, const char *dest, dump_callback_t i_du
|
|||||||
data = i_data;
|
data = i_data;
|
||||||
dumper = i_dumper;
|
dumper = i_dumper;
|
||||||
fake = false;
|
fake = false;
|
||||||
showprogress = true;
|
showprogress = true;
|
||||||
__FlashNandFolder(source, dest);
|
__FlashNandFolder(source, dest);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Nand::DoNandDump(const char *source, const char *dest, dump_callback_t i_dumper, void *i_data)
|
s32 Nand::DoNandDump(const char *source, const char *dest, dump_callback_t i_dumper, void *i_data)
|
||||||
@ -851,7 +858,7 @@ s32 Nand::DoNandDump(const char *source, const char *dest, dump_callback_t i_dum
|
|||||||
dumper = i_dumper;
|
dumper = i_dumper;
|
||||||
fake = false;
|
fake = false;
|
||||||
showprogress = true;
|
showprogress = true;
|
||||||
u32 temp = 0;
|
u32 temp = 0;
|
||||||
s32 ret = ISFS_ReadDir(source, NULL, &temp);
|
s32 ret = ISFS_ReadDir(source, NULL, &temp);
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
{
|
{
|
||||||
@ -862,10 +869,8 @@ s32 Nand::DoNandDump(const char *source, const char *dest, dump_callback_t i_dum
|
|||||||
__DumpNandFile(source, ndest);
|
__DumpNandFile(source, ndest);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
__DumpNandFolder(source, dest);
|
__DumpNandFolder(source, dest);
|
||||||
}
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Nand::CalcFlashSize(const char *source, dump_callback_t i_dumper, void *i_data)
|
s32 Nand::CalcFlashSize(const char *source, dump_callback_t i_dumper, void *i_data)
|
||||||
@ -874,8 +879,8 @@ s32 Nand::CalcFlashSize(const char *source, dump_callback_t i_dumper, void *i_da
|
|||||||
dumper = i_dumper;
|
dumper = i_dumper;
|
||||||
fake = true;
|
fake = true;
|
||||||
showprogress = true;
|
showprogress = true;
|
||||||
__FlashNandFolder(source, "");
|
__FlashNandFolder(source, "");
|
||||||
return NandSize;
|
return NandSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Nand::CalcDumpSpace(const char *source, dump_callback_t i_dumper, void *i_data)
|
s32 Nand::CalcDumpSpace(const char *source, dump_callback_t i_dumper, void *i_data)
|
||||||
@ -883,17 +888,17 @@ s32 Nand::CalcDumpSpace(const char *source, dump_callback_t i_dumper, void *i_da
|
|||||||
data = i_data;
|
data = i_data;
|
||||||
dumper = i_dumper;
|
dumper = i_dumper;
|
||||||
fake = true;
|
fake = true;
|
||||||
showprogress = true;
|
showprogress = true;
|
||||||
|
|
||||||
u32 temp = 0;
|
u32 temp = 0;
|
||||||
|
|
||||||
s32 ret = ISFS_ReadDir(source, NULL, &temp);
|
s32 ret = ISFS_ReadDir(source, NULL, &temp);
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
__DumpNandFile(source, "");
|
__DumpNandFile(source, "");
|
||||||
else
|
else
|
||||||
__DumpNandFolder(source, "");
|
__DumpNandFolder(source, "");
|
||||||
|
|
||||||
return NandSize;
|
return NandSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nand::ResetCounters(void)
|
void Nand::ResetCounters(void)
|
||||||
@ -1021,5 +1026,5 @@ s32 Nand::Do_Region_Change(string id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
__configwrite();
|
__configwrite();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
|
||||||
#define read_le32_unaligned(x) ((x)[0]|((x)[1]<<8)|((x)[2]<<16)|((x)[3]<<24))
|
|
||||||
|
|
||||||
#define ERROR(x) do {wbfs_error(x);goto error;}while(0)
|
#define ERROR(x) do {wbfs_error(x);goto error;}while(0)
|
||||||
#define ALIGN_LBA(x) (((x)+p->hd_sec_sz-1)&(~(p->hd_sec_sz-1)))
|
#define ALIGN_LBA(x) (((x)+p->hd_sec_sz-1)&(~(p->hd_sec_sz-1)))
|
||||||
|
|
||||||
@ -37,6 +35,8 @@ static u8 size_to_shift(u32 size)
|
|||||||
return ret - 1;
|
return ret - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define read_le32_unaligned(x) ((x)[0]|((x)[1]<<8)|((x)[2]<<16)|((x)[3]<<24))
|
||||||
|
|
||||||
wbfs_t *wbfs_open_hd(rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector, void *callback_data, int hd_sector_size, int num_hd_sector __attribute((unused)), int reset)
|
wbfs_t *wbfs_open_hd(rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector, void *callback_data, int hd_sector_size, int num_hd_sector __attribute((unused)), int reset)
|
||||||
{
|
{
|
||||||
int i=num_hd_sector,ret;
|
int i=num_hd_sector,ret;
|
||||||
@ -64,7 +64,6 @@ wbfs_t *wbfs_open_hd(rw_sector_callback_t read_hdsector, rw_sector_callback_t wr
|
|||||||
wbfs_iofree(tmp_buffer);
|
wbfs_iofree(tmp_buffer);
|
||||||
if(reset)// XXX make a empty hd partition..
|
if(reset)// XXX make a empty hd partition..
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -382,6 +382,7 @@ void aes_decrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len)
|
|||||||
}
|
}
|
||||||
else fraction = 16;
|
else fraction = 16;
|
||||||
|
|
||||||
|
// debug_printf("block %d: fraction = %d\n", blockno, fraction);
|
||||||
memcpy(block, inbuf + blockno * sizeof(block), fraction);
|
memcpy(block, inbuf + blockno * sizeof(block), fraction);
|
||||||
decrypt((char*) block);
|
decrypt((char*) block);
|
||||||
u8 *ctext_ptr;
|
u8 *ctext_ptr;
|
||||||
@ -391,6 +392,8 @@ void aes_decrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len)
|
|||||||
|
|
||||||
for (i = 0; i < fraction; i++)
|
for (i = 0; i < fraction; i++)
|
||||||
outbuf[blockno * sizeof(block) + i] = ctext_ptr[i] ^ block[i];
|
outbuf[blockno * sizeof(block) + i] = ctext_ptr[i] ^ block[i];
|
||||||
|
// debug_printf("Block %d output: ", blockno);
|
||||||
|
// hexdump(outbuf + blockno*sizeof(block), 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,6 +403,8 @@ void aes_encrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len)
|
|||||||
u8 block[16];
|
u8 block[16];
|
||||||
unsigned int blockno = 0, i;
|
unsigned int blockno = 0, i;
|
||||||
|
|
||||||
|
// debug_printf("aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len);
|
||||||
|
|
||||||
for (blockno = 0; blockno <= (len / sizeof(block)); blockno++)
|
for (blockno = 0; blockno <= (len / sizeof(block)); blockno++)
|
||||||
{
|
{
|
||||||
unsigned int fraction;
|
unsigned int fraction;
|
||||||
@ -411,6 +416,7 @@ void aes_encrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len)
|
|||||||
}
|
}
|
||||||
else fraction = 16;
|
else fraction = 16;
|
||||||
|
|
||||||
|
// debug_printf("block %d: fraction = %d\n", blockno, fraction);
|
||||||
memcpy(block, inbuf + blockno * sizeof(block), fraction);
|
memcpy(block, inbuf + blockno * sizeof(block), fraction);
|
||||||
|
|
||||||
for (i = 0; i < fraction; i++)
|
for (i = 0; i < fraction; i++)
|
||||||
@ -419,6 +425,8 @@ void aes_encrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len)
|
|||||||
encrypt((char*) block);
|
encrypt((char*) block);
|
||||||
memcpy(iv, block, sizeof(block));
|
memcpy(iv, block, sizeof(block));
|
||||||
memcpy(outbuf + blockno * sizeof(block), block, sizeof(block));
|
memcpy(outbuf + blockno * sizeof(block), block, sizeof(block));
|
||||||
|
// debug_printf("Block %d output: ", blockno);
|
||||||
|
// hexdump(outbuf + blockno*sizeof(block), 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
/* init-globals */
|
/* init-globals */
|
||||||
bool geckoinit = false;
|
bool geckoinit = false;
|
||||||
bool textVideoInit = false;
|
bool textVideoInit = false;
|
||||||
bool geckoDisable = false;
|
|
||||||
bool bufferMessages = true;
|
bool bufferMessages = true;
|
||||||
bool WriteToSD = false;
|
bool WriteToSD = false;
|
||||||
|
|
||||||
@ -108,8 +107,6 @@ void WriteToFile(char* tmp)
|
|||||||
//using the gprintf from crediar because it is smaller than mine
|
//using the gprintf from crediar because it is smaller than mine
|
||||||
void gprintf( const char *format, ... )
|
void gprintf( const char *format, ... )
|
||||||
{
|
{
|
||||||
if(geckoDisable)
|
|
||||||
return;
|
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, format);
|
va_start(va, format);
|
||||||
@ -184,11 +181,6 @@ bool InitGecko()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeckoDisable()
|
|
||||||
{
|
|
||||||
geckoDisable = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AllocSDGeckoBuffer()
|
void AllocSDGeckoBuffer()
|
||||||
{
|
{
|
||||||
tmpfilebuffer = (char*)MEM2_alloc(filebuffer + 1 * sizeof(char));
|
tmpfilebuffer = (char*)MEM2_alloc(filebuffer + 1 * sizeof(char));
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef _GECKO_H_
|
#ifndef _GECKO_H_
|
||||||
#define _GECKO_H_
|
#define _GECKO_H_
|
||||||
|
|
||||||
@ -7,17 +6,16 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern bool geckoinit;
|
extern bool geckoinit;
|
||||||
extern bool bufferMessages;
|
extern bool bufferMessages;
|
||||||
extern bool WriteToSD;
|
extern bool WriteToSD;
|
||||||
|
|
||||||
//use this just like printf();
|
//use this just like printf();
|
||||||
void gprintf(const char *format, ...);
|
void gprintf(const char *format, ...);
|
||||||
void ghexdump(void *d, int len);
|
void ghexdump(void *d, int len);
|
||||||
bool InitGecko();
|
bool InitGecko();
|
||||||
void AllocSDGeckoBuffer();
|
void AllocSDGeckoBuffer();
|
||||||
void ClearLogBuffer();
|
void ClearLogBuffer();
|
||||||
void GeckoDisable();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -489,7 +489,7 @@ void CVideo::_showWaitMessages(CVideo *m)
|
|||||||
m->m_showingWaitMessages = true;
|
m->m_showingWaitMessages = true;
|
||||||
u32 frames = m->m_waitMessageDelay * 50;
|
u32 frames = m->m_waitMessageDelay * 50;
|
||||||
u32 waitFrames = frames;
|
u32 waitFrames = frames;
|
||||||
|
|
||||||
u8 fadeStep = 2 * (u32) (255.f / (waitFrames * m->m_waitMessages.size()));
|
u8 fadeStep = 2 * (u32) (255.f / (waitFrames * m->m_waitMessages.size()));
|
||||||
s8 fadeDirection = 1;
|
s8 fadeDirection = 1;
|
||||||
s8 PNGfadeDirection = 1;
|
s8 PNGfadeDirection = 1;
|
||||||
@ -497,10 +497,11 @@ void CVideo::_showWaitMessages(CVideo *m)
|
|||||||
|
|
||||||
vector<STexture>::iterator waitItr = m->m_waitMessages.begin();
|
vector<STexture>::iterator waitItr = m->m_waitMessages.begin();
|
||||||
gprintf("Going to show a wait message screen, delay: %d, # images: %d\n", waitFrames, m->m_waitMessages.size());
|
gprintf("Going to show a wait message screen, delay: %d, # images: %d\n", waitFrames, m->m_waitMessages.size());
|
||||||
|
m->_clearScreen();
|
||||||
|
|
||||||
m->waitMessage(*waitItr);
|
m->prepare();
|
||||||
waitItr += PNGfadeDirection;
|
m->setup2DProjection();
|
||||||
|
GX_SetNumChans(0);
|
||||||
wiiLightSetLevel(0);
|
wiiLightSetLevel(0);
|
||||||
wiiLightOn();
|
wiiLightOn();
|
||||||
|
|
||||||
@ -523,16 +524,15 @@ void CVideo::_showWaitMessages(CVideo *m)
|
|||||||
{
|
{
|
||||||
m->waitMessage(*waitItr);
|
m->waitMessage(*waitItr);
|
||||||
waitItr += PNGfadeDirection;
|
waitItr += PNGfadeDirection;
|
||||||
|
|
||||||
if(waitItr == m->m_waitMessages.end())
|
if(waitItr == m->m_waitMessages.end())
|
||||||
waitItr = m->m_waitMessages.begin();
|
waitItr = m->m_waitMessages.begin();
|
||||||
|
|
||||||
waitFrames = frames;
|
waitFrames = frames;
|
||||||
}
|
}
|
||||||
waitFrames--;
|
|
||||||
VIDEO_WaitVSync();
|
VIDEO_WaitVSync();
|
||||||
|
waitFrames--;
|
||||||
}
|
}
|
||||||
wiiLightOff();
|
wiiLightOff();
|
||||||
|
GX_SetNumChans(1);
|
||||||
m->m_showingWaitMessages = false;
|
m->m_showingWaitMessages = false;
|
||||||
gprintf("Stop showing images\n");
|
gprintf("Stop showing images\n");
|
||||||
}
|
}
|
||||||
@ -584,26 +584,23 @@ void CVideo::waitMessage(float delay)
|
|||||||
void CVideo::waitMessage(const vector<STexture> &tex, float delay)
|
void CVideo::waitMessage(const vector<STexture> &tex, float delay)
|
||||||
{
|
{
|
||||||
hideWaitMessage();
|
hideWaitMessage();
|
||||||
|
|
||||||
if(tex.size() == 0)
|
if(tex.size() == 0)
|
||||||
{
|
{
|
||||||
m_waitMessages = m_defaultWaitMessages;
|
m_waitMessages = m_defaultWaitMessages;
|
||||||
m_waitMessageDelay = 0.2f;
|
m_waitMessageDelay = 0.1f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_waitMessages = tex;
|
m_waitMessages = tex;
|
||||||
m_waitMessageDelay = delay;
|
m_waitMessageDelay = delay;
|
||||||
}
|
}
|
||||||
_clearScreen();
|
|
||||||
|
|
||||||
if (m_waitMessages.size() == 1)
|
if(m_waitMessages.size() == 1)
|
||||||
waitMessage(m_waitMessages[0]);
|
waitMessage(m_waitMessages[0]);
|
||||||
else if(m_waitMessages.size() > 1)
|
else if(m_waitMessages.size() > 1)
|
||||||
{
|
{
|
||||||
CheckWaitThread();
|
|
||||||
m_showWaitMessage = true;
|
m_showWaitMessage = true;
|
||||||
unsigned int stack_size = (unsigned int)32768;
|
u32 stack_size = (u32)32768;
|
||||||
waitThreadStack = smartMem2Alloc(stack_size);
|
waitThreadStack = smartMem2Alloc(stack_size);
|
||||||
LWP_CreateThread(&waitThread, (void *(*)(void *))CVideo::_showWaitMessages, (void *)this, waitThreadStack.get(), stack_size, LWP_PRIO_IDLE);
|
LWP_CreateThread(&waitThread, (void *(*)(void *))CVideo::_showWaitMessages, (void *)this, waitThreadStack.get(), stack_size, LWP_PRIO_IDLE);
|
||||||
}
|
}
|
||||||
@ -614,9 +611,6 @@ void CVideo::waitMessage(const STexture &tex)
|
|||||||
Mtx modelViewMtx;
|
Mtx modelViewMtx;
|
||||||
GXTexObj texObj;
|
GXTexObj texObj;
|
||||||
|
|
||||||
prepare();
|
|
||||||
setup2DProjection();
|
|
||||||
GX_SetNumChans(0);
|
|
||||||
GX_ClearVtxDesc();
|
GX_ClearVtxDesc();
|
||||||
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
|
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||||
@ -648,7 +642,6 @@ void CVideo::waitMessage(const STexture &tex)
|
|||||||
GX_TexCoord2f32(0.f, 1.f);
|
GX_TexCoord2f32(0.f, 1.f);
|
||||||
GX_End();
|
GX_End();
|
||||||
render();
|
render();
|
||||||
GX_SetNumChans(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 CVideo::TakeScreenshot(const char *path)
|
s32 CVideo::TakeScreenshot(const char *path)
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
bool wide(void) const { return m_wide; }
|
bool wide(void) const { return m_wide; }
|
||||||
bool vid_50hz(void) const { return m_50hz; }
|
bool vid_50hz(void) const { return m_50hz; }
|
||||||
u8 getAA(void) const { return m_aa; }
|
u8 getAA(void) const { return m_aa; }
|
||||||
|
bool showingWaitMessage() { return m_showingWaitMessages; }
|
||||||
void set2DViewport(u32 w, u32 h, int x, int y);
|
void set2DViewport(u32 w, u32 h, int x, int y);
|
||||||
void prepareStencil(void);
|
void prepareStencil(void);
|
||||||
void renderStencil(void);
|
void renderStencil(void);
|
||||||
|
@ -38,13 +38,13 @@ void CachedList<T>::Load(string path, string containing, string m_lastLanguage,
|
|||||||
struct stat filestat, discinfo, cache;
|
struct stat filestat, discinfo, cache;
|
||||||
gprintf("%s\n", path.c_str());
|
gprintf("%s\n", path.c_str());
|
||||||
if(stat(path.c_str(), &filestat) == -1)
|
if(stat(path.c_str(), &filestat) == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool update_lang = m_lastLanguage != m_curLanguage;
|
bool update_lang = m_lastLanguage != m_curLanguage;
|
||||||
bool noDB = stat(m_database.c_str(), &cache) == -1;
|
bool noDB = stat(m_database.c_str(), &cache) == -1;
|
||||||
bool mtimes = filestat.st_mtime > cache.st_mtime;
|
bool mtimes = filestat.st_mtime > cache.st_mtime;
|
||||||
if(strcasestr(m_discinf.c_str(), "wbfs") != NULL && stat(m_discinf.c_str(), &discinfo) != -1)
|
if(strcasestr(m_discinf.c_str(), "wbfs") != NULL && stat(m_discinf.c_str(), &discinfo) != -1)
|
||||||
ditimes = discinfo.st_mtime > cache.st_mtime;
|
ditimes = discinfo.st_mtime > cache.st_mtime;
|
||||||
|
|
||||||
m_update = update_lang || noDB || mtimes || ditimes;
|
m_update = update_lang || noDB || mtimes || ditimes;
|
||||||
if(m_update)
|
if(m_update)
|
||||||
@ -94,7 +94,7 @@ void CachedList<T>::Load(string path, string containing, string m_lastLanguage,
|
|||||||
remove(path.c_str());
|
remove(path.c_str());
|
||||||
|
|
||||||
m_loaded = true;
|
m_loaded = true;
|
||||||
m_update = false;
|
m_update = false;
|
||||||
|
|
||||||
if(!music && pathlist.size() > 0)
|
if(!music && pathlist.size() > 0)
|
||||||
{
|
{
|
||||||
@ -103,7 +103,7 @@ void CachedList<T>::Load(string path, string containing, string m_lastLanguage,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CCache<T>(*this, m_database, LOAD);
|
CCache<T>(*this, m_database, LOAD);
|
||||||
m_loaded = true;
|
m_loaded = true;
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,10 @@ typedef void *(*app_final)();
|
|||||||
typedef void (*app_entry)(void (**init)(void (*report)(const char *fmt, ...)), int (**main)(), void *(**final)());
|
typedef void (*app_entry)(void (**init)(void (*report)(const char *fmt, ...)), int (**main)(), void *(**final)());
|
||||||
|
|
||||||
/* Apploader pointers */
|
/* Apploader pointers */
|
||||||
static u8 *appldr = (u8 *) 0x81200000;
|
static u8 *appldr = (u8 *)0x81200000;
|
||||||
|
|
||||||
/* Constants */
|
/* Constants */
|
||||||
#define APPLDR_OFFSET 0x2440
|
#define APPLDR_OFFSET 0x2440
|
||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
static u32 buffer[0x20] ATTRIBUTE_ALIGN(32);
|
static u32 buffer[0x20] ATTRIBUTE_ALIGN(32);
|
||||||
@ -57,11 +57,15 @@ s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatc
|
|||||||
/* Calculate apploader length */
|
/* Calculate apploader length */
|
||||||
appldr_len = buffer[5] + buffer[6];
|
appldr_len = buffer[5] + buffer[6];
|
||||||
|
|
||||||
|
SYS_SetArena1Hi((void *)0x816FFFF0); //Kills the possibility of codedumps with gprintf
|
||||||
|
|
||||||
/* Read apploader code */
|
/* Read apploader code */
|
||||||
ret = WDVD_Read(appldr, appldr_len, APPLDR_OFFSET + 0x20);
|
ret = WDVD_Read(appldr, appldr_len, APPLDR_OFFSET + 0x20);
|
||||||
if (ret < 0)
|
if(ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
DCFlushRange(appldr, appldr_len);
|
||||||
|
|
||||||
/* Set apploader entry function */
|
/* Set apploader entry function */
|
||||||
app_entry appldr_entry = (app_entry)buffer[4];
|
app_entry appldr_entry = (app_entry)buffer[4];
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ int get_frag_list(u8 *id, char *path, const u32 hdd_sector_size)
|
|||||||
frag_concat(fa, fs);
|
frag_concat(fa, fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
frag_list = MEM1_memalign(32, sizeof(FragList));
|
frag_list = MEM1_alloc(ALIGN32(sizeof(FragList)));
|
||||||
if(frag_list == NULL)
|
if(frag_list == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -307,10 +307,12 @@ int set_frag_list(u8 *id)
|
|||||||
DCFlushRange(frag_list, size);
|
DCFlushRange(frag_list, size);
|
||||||
|
|
||||||
gprintf("Calling WDVD_SetFragList, frag list size %d\n", size);
|
gprintf("Calling WDVD_SetFragList, frag list size %d\n", size);
|
||||||
|
/* if (size > 400) ghexdump(frag_list, 400);
|
||||||
|
else ghexdump(frag_list, size); */
|
||||||
|
|
||||||
int ret = WDVD_SetFragList(wbfsDev, frag_list, size);
|
int ret = WDVD_SetFragList(wbfsDev, frag_list, size);
|
||||||
|
|
||||||
MEM1_free(frag_list);
|
free(frag_list);
|
||||||
frag_list = NULL;
|
frag_list = NULL;
|
||||||
|
|
||||||
if(ret)
|
if(ret)
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "splits.h"
|
#include "splits.h"
|
||||||
#include "gecko/gecko.h"
|
#include "gecko.h"
|
||||||
|
|
||||||
#define off64_t off_t
|
#define off64_t off_t
|
||||||
#define FMT_llu "%llu"
|
#define FMT_llu "%llu"
|
||||||
@ -21,7 +21,7 @@
|
|||||||
#define split_error(x) do { gprintf("\nsplit error: %s\n\n",x); } while(0)
|
#define split_error(x) do { gprintf("\nsplit error: %s\n\n",x); } while(0)
|
||||||
|
|
||||||
// 1 cluster less than 4gb
|
// 1 cluster less than 4gb
|
||||||
u64 OPT_split_size = (u64) 4LL * 1024 * 1024 * 1024 - 32 * 1024;
|
u64 OPT_split_size = (u64)4LL * 1024 * 1024 * 1024 - 32 * 1024;
|
||||||
// 1 cluster less than 2gb
|
// 1 cluster less than 2gb
|
||||||
//u64 OPT_split_size = (u64)2LL * 1024 * 1024 * 1024 - 32 * 1024;
|
//u64 OPT_split_size = (u64)2LL * 1024 * 1024 * 1024 - 32 * 1024;
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ int split_fill(split_info_t *s, int idx, u64 size)
|
|||||||
int fd = split_open_file(s, idx);
|
int fd = split_open_file(s, idx);
|
||||||
|
|
||||||
off64_t fsize = lseek(fd, 0, SEEK_END);
|
off64_t fsize = lseek(fd, 0, SEEK_END);
|
||||||
if ((u64)fsize < size)
|
if((u64)fsize < size)
|
||||||
{
|
{
|
||||||
// gprintf("TRUNC %d "FMT_lld" "FMT_lld"\n", idx, size, fsize); // Wpad_WaitButtons();
|
// gprintf("TRUNC %d "FMT_lld" "FMT_lld"\n", idx, size, fsize); // Wpad_WaitButtons();
|
||||||
ftruncate(fd, size);
|
ftruncate(fd, size);
|
||||||
@ -149,7 +149,7 @@ int split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill)
|
|||||||
int split_read_sector(void *_fp, u32 lba, u32 count, void *buf)
|
int split_read_sector(void *_fp, u32 lba, u32 count, void *buf)
|
||||||
{
|
{
|
||||||
split_info_t *s = _fp;
|
split_info_t *s = _fp;
|
||||||
int fd;
|
int fd;
|
||||||
u64 off = lba;
|
u64 off = lba;
|
||||||
off *= 512ULL;
|
off *= 512ULL;
|
||||||
int i;
|
int i;
|
||||||
|
@ -53,6 +53,8 @@ wbfs_disc_t* WBFS_Ext_OpenDisc(u8 *discid, char *fname)
|
|||||||
if (fd == -1) return NULL;
|
if (fd == -1) return NULL;
|
||||||
|
|
||||||
wbfs_disc_t *iso_file = MEM2_alloc(sizeof(wbfs_disc_t));
|
wbfs_disc_t *iso_file = MEM2_alloc(sizeof(wbfs_disc_t));
|
||||||
|
memset(iso_file, 0, sizeof(wbfs_disc_t));
|
||||||
|
|
||||||
if (iso_file == NULL)
|
if (iso_file == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -14,42 +14,42 @@ static u32 Counter = 0;
|
|||||||
|
|
||||||
void do_wip_code(u8 * dst, u32 len)
|
void do_wip_code(u8 * dst, u32 len)
|
||||||
{
|
{
|
||||||
if(!CodeList)
|
if(!CodeList)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(Counter < 3)
|
if(Counter < 3)
|
||||||
{
|
{
|
||||||
Counter++;
|
Counter++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
s32 n = 0;
|
s32 n = 0;
|
||||||
s32 offset = 0;
|
s32 offset = 0;
|
||||||
|
|
||||||
for(i = 0; i < CodesCount; i++)
|
for(i = 0; i < CodesCount; i++)
|
||||||
{
|
{
|
||||||
for(n = 0; n < 4; n++)
|
for(n = 0; n < 4; n++)
|
||||||
{
|
{
|
||||||
offset = CodeList[i].offset+n-ProcessedLength;
|
offset = CodeList[i].offset+n-ProcessedLength;
|
||||||
|
|
||||||
if(offset < 0 || (u32)offset >= len)
|
if(offset < 0 || (u32)offset >= len)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(dst[offset] == ((u8 *)&CodeList[i].srcaddress)[n])
|
if(dst[offset] == ((u8 *)&CodeList[i].srcaddress)[n])
|
||||||
{
|
{
|
||||||
dst[offset] = ((u8 *)&CodeList[i].dstaddress)[n];
|
dst[offset] = ((u8 *)&CodeList[i].dstaddress)[n];
|
||||||
gprintf("WIP: %08X Address Patched.\n", CodeList[i].offset + n);
|
gprintf("WIP: %08X Address Patched.\n", CodeList[i].offset + n);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gprintf("WIP: %08X Address does not match with WIP entry.\n", CodeList[i].offset+n);
|
gprintf("WIP: %08X Address does not match with WIP entry.\n", CodeList[i].offset+n);
|
||||||
gprintf("Destination: %02X | Should be: %02X.\n", dst[offset], ((u8 *)&CodeList[i].srcaddress)[n]);
|
gprintf("Destination: %02X | Should be: %02X.\n", dst[offset], ((u8 *)&CodeList[i].srcaddress)[n]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProcessedLength += len;
|
ProcessedLength += len;
|
||||||
Counter++;
|
Counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! for internal patches only
|
//! for internal patches only
|
||||||
@ -58,7 +58,7 @@ void do_wip_code(u8 * dst, u32 len)
|
|||||||
//! if set was successful the codelist will be freed when it's done
|
//! if set was successful the codelist will be freed when it's done
|
||||||
bool set_wip_list(WIP_Code * list, int size)
|
bool set_wip_list(WIP_Code * list, int size)
|
||||||
{
|
{
|
||||||
if (!CodeList && size > 0)
|
if(!CodeList && size > 0)
|
||||||
{
|
{
|
||||||
CodeList = list;
|
CodeList = list;
|
||||||
CodesCount = size;
|
CodesCount = size;
|
||||||
@ -70,18 +70,18 @@ bool set_wip_list(WIP_Code * list, int size)
|
|||||||
|
|
||||||
void wip_reset_counter()
|
void wip_reset_counter()
|
||||||
{
|
{
|
||||||
ProcessedLength = 0;
|
ProcessedLength = 0;
|
||||||
//alternative dols don't need a skip. only main.dol.
|
//alternative dols don't need a skip. only main.dol.
|
||||||
Counter = 3;
|
Counter = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_wip()
|
void free_wip()
|
||||||
{
|
{
|
||||||
if(CodeList)
|
if(CodeList)
|
||||||
MEM2_free(CodeList);
|
MEM2_free(CodeList);
|
||||||
|
|
||||||
CodesCount = 0;
|
CodesCount = 0;
|
||||||
ProcessedLength = 0;
|
ProcessedLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_wip_patches(u8 *dir, u8 *gameid)
|
int load_wip_patches(u8 *dir, u8 *gameid)
|
||||||
@ -89,54 +89,53 @@ int load_wip_patches(u8 *dir, u8 *gameid)
|
|||||||
char filepath[150];
|
char filepath[150];
|
||||||
char GameID[8];
|
char GameID[8];
|
||||||
memset(GameID, 0, sizeof(GameID));
|
memset(GameID, 0, sizeof(GameID));
|
||||||
memcpy(GameID, gameid, 6);
|
memcpy(GameID, gameid, 6);
|
||||||
snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID);
|
snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID);
|
||||||
|
|
||||||
FILE * fp = fopen(filepath, "rb");
|
FILE *fp = fopen(filepath, "rb");
|
||||||
if (!fp)
|
if(!fp)
|
||||||
{
|
{
|
||||||
memset(GameID, 0, sizeof(GameID));
|
memset(GameID, 0, sizeof(GameID));
|
||||||
memcpy(GameID, gameid, 3);
|
memcpy(GameID, gameid, 3);
|
||||||
snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID);
|
snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID);
|
||||||
fp = fopen(filepath, "rb");
|
fp = fopen(filepath, "rb");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fp)
|
if(!fp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
char line[255];
|
char line[255];
|
||||||
gprintf("\nLoading WIP code from %s.\n", filepath);
|
gprintf("\nLoading WIP code from %s.\n", filepath);
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), fp))
|
while(fgets(line, sizeof(line), fp))
|
||||||
{
|
{
|
||||||
if (line[0] == '#') continue;
|
if(line[0] == '#' || strlen(line) < 26)
|
||||||
|
continue;
|
||||||
|
|
||||||
if(strlen(line) < 26) continue;
|
u32 offset = (u32) strtoul(line, NULL, 16);
|
||||||
|
u32 srcaddress = (u32) strtoul(line+9, NULL, 16);
|
||||||
|
u32 dstaddress = (u32) strtoul(line+18, NULL, 16);
|
||||||
|
|
||||||
u32 offset = (u32) strtoul(line, NULL, 16);
|
if(!CodeList)
|
||||||
u32 srcaddress = (u32) strtoul(line+9, NULL, 16);
|
|
||||||
u32 dstaddress = (u32) strtoul(line+18, NULL, 16);
|
|
||||||
|
|
||||||
if(!CodeList)
|
|
||||||
CodeList = MEM2_alloc(sizeof(WIP_Code));
|
CodeList = MEM2_alloc(sizeof(WIP_Code));
|
||||||
|
|
||||||
WIP_Code *tmp = MEM2_realloc(CodeList, (CodesCount+1)*sizeof(WIP_Code));
|
WIP_Code *tmp = MEM2_realloc(CodeList, (CodesCount+1)*sizeof(WIP_Code));
|
||||||
if(!tmp)
|
if(!tmp)
|
||||||
{
|
{
|
||||||
MEM2_free(CodeList);
|
MEM2_free(CodeList);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeList = tmp;
|
CodeList = tmp;
|
||||||
|
|
||||||
CodeList[CodesCount].offset = offset;
|
CodeList[CodesCount].offset = offset;
|
||||||
CodeList[CodesCount].srcaddress = srcaddress;
|
CodeList[CodesCount].srcaddress = srcaddress;
|
||||||
CodeList[CodesCount].dstaddress = dstaddress;
|
CodeList[CodesCount].dstaddress = dstaddress;
|
||||||
CodesCount++;
|
CodesCount++;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
gprintf("\n");
|
gprintf("\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ int main(int argc, char **argv)
|
|||||||
vid.init();
|
vid.init();
|
||||||
|
|
||||||
MEM2_init(47); //Should be safe to use
|
MEM2_init(47); //Should be safe to use
|
||||||
vid.waitMessage(0.2f);
|
vid.waitMessage(0.1f);
|
||||||
|
|
||||||
AllocSDGeckoBuffer();
|
AllocSDGeckoBuffer();
|
||||||
gprintf(" \nWelcome to %s (%s-r%s)!\nThis is the debug output.\n", APP_NAME, APP_VERSION, SVN_REV);
|
gprintf(" \nWelcome to %s (%s-r%s)!\nThis is the debug output.\n", APP_NAME, APP_VERSION, SVN_REV);
|
||||||
|
@ -1812,8 +1812,9 @@ void CMenu::_mainLoopCommon(bool withCF, bool blockReboot, bool adjusting)
|
|||||||
|
|
||||||
m_btnMgr.draw();
|
m_btnMgr.draw();
|
||||||
ScanInput();
|
ScanInput();
|
||||||
|
if(!m_vid.showingWaitMessage())
|
||||||
|
m_vid.render();
|
||||||
|
|
||||||
m_vid.render();
|
|
||||||
if(!blockReboot)
|
if(!blockReboot)
|
||||||
{
|
{
|
||||||
if(withCF && Sys_Exiting())
|
if(withCF && Sys_Exiting())
|
||||||
|
@ -1427,7 +1427,6 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
|||||||
|
|
||||||
if(currentPartition == 0)
|
if(currentPartition == 0)
|
||||||
SDHC_Init();
|
SDHC_Init();
|
||||||
GeckoDisable();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RunApploader(offset, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, returnTo);
|
RunApploader(offset, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, returnTo);
|
||||||
|
@ -188,11 +188,12 @@ int CMenu::GetCoverStatusAsync(CMenu *m)
|
|||||||
|
|
||||||
void CMenu::LoadView(void)
|
void CMenu::LoadView(void)
|
||||||
{
|
{
|
||||||
_showWaitMessage();
|
|
||||||
_hideMain();
|
|
||||||
|
|
||||||
m_curGameId = m_cf.getId();
|
m_curGameId = m_cf.getId();
|
||||||
|
|
||||||
|
_hideMain(true);
|
||||||
|
m_cf.clear();
|
||||||
|
_showWaitMessage();
|
||||||
|
|
||||||
_loadList();
|
_loadList();
|
||||||
_showMain();
|
_showMain();
|
||||||
_initCF();
|
_initCF();
|
||||||
@ -418,8 +419,10 @@ int CMenu::main(void)
|
|||||||
}
|
}
|
||||||
else if(m_btnMgr.selected(m_mainBtnDVD))
|
else if(m_btnMgr.selected(m_mainBtnDVD))
|
||||||
{
|
{
|
||||||
_showWaitMessage();
|
|
||||||
_hideMain(true);
|
_hideMain(true);
|
||||||
|
m_cf.clear();
|
||||||
|
_showWaitMessage();
|
||||||
|
|
||||||
dir_discHdr hdr;
|
dir_discHdr hdr;
|
||||||
memset(&hdr, 0, sizeof(dir_discHdr));
|
memset(&hdr, 0, sizeof(dir_discHdr));
|
||||||
memcpy(&hdr.id, "dvddvd", 6);
|
memcpy(&hdr.id, "dvddvd", 6);
|
||||||
|
@ -53,37 +53,39 @@ typedef struct
|
|||||||
|
|
||||||
# define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
|
# define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
|
||||||
|
|
||||||
static double ConvertFromIeeeExtended(const unsigned char* bytes)
|
static double ConvertFromIeeeExtended(const u8* bytes)
|
||||||
{
|
{
|
||||||
double f;
|
double f;
|
||||||
int expon;
|
int expon;
|
||||||
unsigned long hiMant, loMant;
|
u64 hiMant, loMant;
|
||||||
|
|
||||||
expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
|
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) {
|
hiMant = ((u64)(bytes[2] & 0xFF) << 24)
|
||||||
|
| ((u64)(bytes[3] & 0xFF) << 16)
|
||||||
|
| ((u64)(bytes[4] & 0xFF) << 8)
|
||||||
|
| ((u64)(bytes[5] & 0xFF));
|
||||||
|
|
||||||
|
loMant = ((u64)(bytes[6] & 0xFF) << 24)
|
||||||
|
| ((u64)(bytes[7] & 0xFF) << 16)
|
||||||
|
| ((u64)(bytes[8] & 0xFF) << 8)
|
||||||
|
| ((u64)(bytes[9] & 0xFF));
|
||||||
|
|
||||||
|
if(expon == 0 && hiMant == 0 && loMant == 0)
|
||||||
f = 0;
|
f = 0;
|
||||||
}
|
else
|
||||||
else {
|
{
|
||||||
if (expon == 0x7FFF) {
|
if(expon == 0x7FFF)
|
||||||
f = HUGE_VAL;
|
f = HUGE_VAL;
|
||||||
}
|
else
|
||||||
else {
|
{
|
||||||
expon -= 16383;
|
expon -= 16383;
|
||||||
f = ldexp(UnsignedToFloat(hiMant), expon-=31);
|
f = ldexp(UnsignedToFloat(hiMant), expon-=31);
|
||||||
f += ldexp(UnsignedToFloat(loMant), expon-=32);
|
f += ldexp(UnsignedToFloat(loMant), expon-=32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes[0] & 0x80)
|
if(bytes[0] & 0x80)
|
||||||
return -f;
|
return -f;
|
||||||
else
|
else
|
||||||
return f;
|
return f;
|
||||||
@ -227,9 +229,7 @@ int AifDecoder::Read(u8 * buffer, int buffer_size, int)
|
|||||||
|
|
||||||
int read = file_fd->read(buffer, buffer_size);
|
int read = file_fd->read(buffer, buffer_size);
|
||||||
if(read > 0)
|
if(read > 0)
|
||||||
{
|
|
||||||
CurPos += read;
|
CurPos += read;
|
||||||
}
|
|
||||||
|
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
@ -31,20 +31,20 @@
|
|||||||
|
|
||||||
class AifDecoder : public SoundDecoder
|
class AifDecoder : public SoundDecoder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AifDecoder(const char * filepath);
|
AifDecoder(const char *filepath);
|
||||||
AifDecoder(const u8 * snd, int len);
|
AifDecoder(const u8 *snd, int len);
|
||||||
~AifDecoder();
|
~AifDecoder();
|
||||||
int GetFormat() { return Format; };
|
int GetFormat() { return Format; };
|
||||||
int GetSampleRate() { return SampleRate; };
|
int GetSampleRate() { return SampleRate; };
|
||||||
int Read(u8 * buffer, int buffer_size, int pos);
|
int Read(u8 *buffer, int buffer_size, int pos);
|
||||||
protected:
|
protected:
|
||||||
void OpenFile();
|
void OpenFile();
|
||||||
void CloseFile();
|
void CloseFile();
|
||||||
u32 DataOffset;
|
u32 DataOffset;
|
||||||
u32 DataSize;
|
u32 DataSize;
|
||||||
u32 SampleRate;
|
u32 SampleRate;
|
||||||
u8 Format;
|
u8 Format;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,109 +32,109 @@
|
|||||||
#include "BNSDecoder.hpp"
|
#include "BNSDecoder.hpp"
|
||||||
|
|
||||||
BNSDecoder::BNSDecoder(const char * filepath)
|
BNSDecoder::BNSDecoder(const char * filepath)
|
||||||
: SoundDecoder(filepath)
|
: SoundDecoder(filepath)
|
||||||
{
|
{
|
||||||
SoundType = SOUND_BNS;
|
SoundType = SOUND_BNS;
|
||||||
memset(&SoundData, 0, sizeof(SoundBlock));
|
memset(&SoundData, 0, sizeof(SoundBlock));
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
BNSDecoder::BNSDecoder(const u8 * snd, int len)
|
BNSDecoder::BNSDecoder(const u8 * snd, int len)
|
||||||
: SoundDecoder(snd, len)
|
: SoundDecoder(snd, len)
|
||||||
{
|
{
|
||||||
SoundType = SOUND_BNS;
|
SoundType = SOUND_BNS;
|
||||||
memset(&SoundData, 0, sizeof(SoundBlock));
|
memset(&SoundData, 0, sizeof(SoundBlock));
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
BNSDecoder::~BNSDecoder()
|
BNSDecoder::~BNSDecoder()
|
||||||
{
|
{
|
||||||
ExitRequested = true;
|
ExitRequested = true;
|
||||||
while(Decoding)
|
while(Decoding)
|
||||||
usleep(100);
|
usleep(100);
|
||||||
|
|
||||||
MEM2_free(SoundData.buffer);
|
MEM2_free(SoundData.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BNSDecoder::OpenFile()
|
void BNSDecoder::OpenFile()
|
||||||
{
|
{
|
||||||
u8 * tempbuff = new (std::nothrow) u8[file_fd->size()];
|
u8 *tempbuff = new (std::nothrow) u8[file_fd->size()];
|
||||||
if(!tempbuff)
|
if(!tempbuff)
|
||||||
{
|
{
|
||||||
CloseFile();
|
CloseFile();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
|
||||||
while(done < file_fd->size())
|
while(done < file_fd->size())
|
||||||
{
|
{
|
||||||
int read = file_fd->read(tempbuff, file_fd->size());
|
int read = file_fd->read(tempbuff, file_fd->size());
|
||||||
if(read > 0)
|
if(read > 0)
|
||||||
done += read;
|
done += read;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CloseFile();
|
CloseFile();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundData = DecodefromBNS(tempbuff, done);
|
SoundData = DecodefromBNS(tempbuff, done);
|
||||||
if(SoundData.buffer == NULL)
|
if(SoundData.buffer == NULL)
|
||||||
{
|
{
|
||||||
CloseFile();
|
CloseFile();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] tempbuff;
|
delete [] tempbuff;
|
||||||
tempbuff = NULL;
|
tempbuff = NULL;
|
||||||
|
|
||||||
Decode();
|
Decode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BNSDecoder::CloseFile()
|
void BNSDecoder::CloseFile()
|
||||||
{
|
{
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
delete file_fd;
|
delete file_fd;
|
||||||
|
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BNSDecoder::Read(u8 * buffer, int buffer_size, int)
|
int BNSDecoder::Read(u8 * buffer, int buffer_size, int)
|
||||||
{
|
{
|
||||||
if(!SoundData.buffer)
|
if(!SoundData.buffer)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(SoundData.loopFlag)
|
if(SoundData.loopFlag)
|
||||||
{
|
{
|
||||||
int factor = SoundData.format == VOICE_STEREO_16BIT ? 4 : 2;
|
int factor = SoundData.format == VOICE_STEREO_16BIT ? 4 : 2;
|
||||||
if(CurPos >= (int) SoundData.loopEnd*factor)
|
if(CurPos >= (int) SoundData.loopEnd*factor)
|
||||||
CurPos = SoundData.loopStart*factor;
|
CurPos = SoundData.loopStart*factor;
|
||||||
|
|
||||||
if(buffer_size > (int) SoundData.loopEnd*factor-CurPos)
|
if(buffer_size > (int) SoundData.loopEnd*factor-CurPos)
|
||||||
buffer_size = SoundData.loopEnd*factor-CurPos;
|
buffer_size = SoundData.loopEnd*factor-CurPos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(CurPos >= (int) SoundData.size)
|
if(CurPos >= (int) SoundData.size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(buffer_size > (int) SoundData.size-CurPos)
|
if(buffer_size > (int) SoundData.size-CurPos)
|
||||||
buffer_size = SoundData.size-CurPos;
|
buffer_size = SoundData.size-CurPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buffer, SoundData.buffer+CurPos, buffer_size);
|
memcpy(buffer, SoundData.buffer+CurPos, buffer_size);
|
||||||
CurPos += buffer_size;
|
CurPos += buffer_size;
|
||||||
|
|
||||||
return buffer_size;
|
return buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BNSHeader
|
struct BNSHeader
|
||||||
@ -306,8 +306,8 @@ static u8 * decodeBNS(u32 &size, const BNSInfo &bnsInfo, const BNSData &bnsData)
|
|||||||
|
|
||||||
SoundBlock DecodefromBNS(const u8 *buffer, u32 size)
|
SoundBlock DecodefromBNS(const u8 *buffer, u32 size)
|
||||||
{
|
{
|
||||||
SoundBlock OutBlock;
|
SoundBlock OutBlock;
|
||||||
memset(&OutBlock, 0, sizeof(SoundBlock));
|
memset(&OutBlock, 0, sizeof(SoundBlock));
|
||||||
|
|
||||||
const BNSHeader &hdr = *(BNSHeader *)buffer;
|
const BNSHeader &hdr = *(BNSHeader *)buffer;
|
||||||
if (size < sizeof hdr)
|
if (size < sizeof hdr)
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
typedef struct _SoundBlock
|
typedef struct _SoundBlock
|
||||||
{
|
{
|
||||||
u8 * buffer;
|
u8 *buffer;
|
||||||
u32 size;
|
u32 size;
|
||||||
u8 format;
|
u8 format;
|
||||||
u32 frequency;
|
u32 frequency;
|
||||||
@ -41,17 +41,17 @@ typedef struct _SoundBlock
|
|||||||
|
|
||||||
class BNSDecoder : public SoundDecoder
|
class BNSDecoder : public SoundDecoder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BNSDecoder(const char * filepath);
|
BNSDecoder(const char * filepath);
|
||||||
BNSDecoder(const u8 * snd, int len);
|
BNSDecoder(const u8 * snd, int len);
|
||||||
~BNSDecoder();
|
~BNSDecoder();
|
||||||
int GetFormat() { return SoundData.format; };
|
int GetFormat() { return SoundData.format; };
|
||||||
int GetSampleRate() { return SoundData.frequency; };
|
int GetSampleRate() { return SoundData.frequency; };
|
||||||
int Read(u8 * buffer, int buffer_size, int pos);
|
int Read(u8 * buffer, int buffer_size, int pos);
|
||||||
protected:
|
protected:
|
||||||
void OpenFile();
|
void OpenFile();
|
||||||
void CloseFile();
|
void CloseFile();
|
||||||
SoundBlock SoundData;
|
SoundBlock SoundData;
|
||||||
};
|
};
|
||||||
|
|
||||||
SoundBlock DecodefromBNS(const u8 *buffer, u32 size);
|
SoundBlock DecodefromBNS(const u8 *buffer, u32 size);
|
||||||
|
@ -32,62 +32,62 @@
|
|||||||
|
|
||||||
class BufferCircle
|
class BufferCircle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//!> Constructor
|
//!> Constructor
|
||||||
BufferCircle();
|
BufferCircle();
|
||||||
//!> Destructor
|
//!> Destructor
|
||||||
~BufferCircle();
|
~BufferCircle();
|
||||||
//!> Set circle size
|
//!> Set circle size
|
||||||
void Resize(int size);
|
void Resize(int size);
|
||||||
//!> Get the circle size
|
//!> Get the circle size
|
||||||
int Size() { return SoundBuffer.size(); };
|
int Size() { return SoundBuffer.size(); };
|
||||||
//!> Set/resize the buffer size
|
//!> Set/resize the buffer size
|
||||||
void SetBufferBlockSize(int size);
|
void SetBufferBlockSize(int size);
|
||||||
//!> Remove a buffer
|
//!> Remove a buffer
|
||||||
void RemoveBuffer(int pos);
|
void RemoveBuffer(int pos);
|
||||||
//!> Set all buffers clear
|
//!> Set all buffers clear
|
||||||
void ClearBuffer();
|
void ClearBuffer();
|
||||||
//!> Free all buffers
|
//!> Free all buffers
|
||||||
void FreeBuffer();
|
void FreeBuffer();
|
||||||
//!> Switch to next buffer
|
//!> Switch to next buffer
|
||||||
void LoadNext();
|
void LoadNext();
|
||||||
//!> Get the current buffer
|
//!> Get the current buffer
|
||||||
u8 * GetBuffer() { if(!Valid(which)) return 0; return SoundBuffer[which]; };
|
u8 * GetBuffer() { if(!Valid(which)) return 0; return SoundBuffer[which]; };
|
||||||
//!> Get a buffer at a position
|
//!> Get a buffer at a position
|
||||||
u8 * GetBuffer(int pos) { if(!Valid(pos)) return NULL; else return SoundBuffer[pos]; };
|
u8 * GetBuffer(int pos) { if(!Valid(pos)) return NULL; else return SoundBuffer[pos]; };
|
||||||
//!> Get next buffer
|
//!> Get next buffer
|
||||||
u8 * GetNextBuffer() { if(Size() <= 0) return 0; else return SoundBuffer[(which+1) % Size()]; };
|
u8 * GetNextBuffer() { if(Size() <= 0) return 0; else return SoundBuffer[(which+1) % Size()]; };
|
||||||
//!> Get previous buffer
|
//!> Get previous buffer
|
||||||
u8 * GetLastBuffer() { if(Size() <= 0) return 0; else return SoundBuffer[(which+Size()-1) % Size()]; };
|
u8 * GetLastBuffer() { if(Size() <= 0) return 0; else return SoundBuffer[(which+Size()-1) % Size()]; };
|
||||||
//!> Get current buffer size
|
//!> Get current buffer size
|
||||||
u32 GetBufferSize() { if(!Valid(which)) return 0; else return BufferSize[which]; };
|
u32 GetBufferSize() { if(!Valid(which)) return 0; else return BufferSize[which]; };
|
||||||
//!> Get buffer size at position
|
//!> Get buffer size at position
|
||||||
u32 GetBufferSize(int pos) { if(!Valid(pos)) return 0; else return BufferSize[pos]; };
|
u32 GetBufferSize(int pos) { if(!Valid(pos)) return 0; else return BufferSize[pos]; };
|
||||||
//!> Get previous buffer size
|
//!> Get previous buffer size
|
||||||
u32 GetLastBufferSize() { if(Size() <= 0) return 0; else return BufferSize[(which+Size()-1) % Size()]; };
|
u32 GetLastBufferSize() { if(Size() <= 0) return 0; else return BufferSize[(which+Size()-1) % Size()]; };
|
||||||
//!> Is current buffer ready
|
//!> Is current buffer ready
|
||||||
bool IsBufferReady() { if(!Valid(which)) return false; else return BufferReady[which]; };
|
bool IsBufferReady() { if(!Valid(which)) return false; else return BufferReady[which]; };
|
||||||
//!> Is a buffer at a position ready
|
//!> Is a buffer at a position ready
|
||||||
bool IsBufferReady(int pos) { if(!Valid(pos)) return false; else return BufferReady[pos]; };
|
bool IsBufferReady(int pos) { if(!Valid(pos)) return false; else return BufferReady[pos]; };
|
||||||
//!> Is next buffer ready
|
//!> Is next buffer ready
|
||||||
bool IsNextBufferReady() { if(Size() <= 0) return false; else return BufferReady[(which+1) % Size()]; };
|
bool IsNextBufferReady() { if(Size() <= 0) return false; else return BufferReady[(which+1) % Size()]; };
|
||||||
//!> Is last buffer ready
|
//!> Is last buffer ready
|
||||||
bool IsLastBufferReady() { if(Size() <= 0) return false; else return BufferReady[(which+Size()-1) % Size()]; };
|
bool IsLastBufferReady() { if(Size() <= 0) return false; else return BufferReady[(which+Size()-1) % Size()]; };
|
||||||
//!> Set a buffer at a position to a ready state
|
//!> Set a buffer at a position to a ready state
|
||||||
void SetBufferReady(int pos, bool st);
|
void SetBufferReady(int pos, bool st);
|
||||||
//!> Set the buffersize at a position
|
//!> Set the buffersize at a position
|
||||||
void SetBufferSize(int pos, int size);
|
void SetBufferSize(int pos, int size);
|
||||||
//!> Get the current position in the circle
|
//!> Get the current position in the circle
|
||||||
u16 Which() { return which; };
|
u16 Which() { return which; };
|
||||||
protected:
|
protected:
|
||||||
//!> Check if the position is a valid position in the vector
|
//!> Check if the position is a valid position in the vector
|
||||||
bool Valid(int pos) { return !(pos < 0 || pos >= Size()); };
|
bool Valid(int pos) { return !(pos < 0 || pos >= Size()); };
|
||||||
|
|
||||||
u16 which;
|
u16 which;
|
||||||
u32 BufferBlockSize;
|
u32 BufferBlockSize;
|
||||||
std::vector<u8 *> SoundBuffer;
|
std::vector<u8 *> SoundBuffer;
|
||||||
std::vector<u32> BufferSize;
|
std::vector<u32> BufferSize;
|
||||||
std::vector<bool> BufferReady;
|
std::vector<bool> BufferReady;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,143 +3,134 @@
|
|||||||
|
|
||||||
CFile::CFile()
|
CFile::CFile()
|
||||||
{
|
{
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
mem_file = NULL;
|
mem_file = NULL;
|
||||||
filesize = 0;
|
filesize = 0;
|
||||||
Pos = 0;
|
Pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFile::CFile(const char * filepath, const char * mode)
|
CFile::CFile(const char * filepath, const char * mode)
|
||||||
{
|
{
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
open(filepath, mode);
|
open(filepath, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFile::CFile(const u8 * mem, int size)
|
CFile::CFile(const u8 * mem, int size)
|
||||||
{
|
{
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
open(mem, size);
|
open(mem, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFile::~CFile()
|
CFile::~CFile()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFile::open(const char * filepath, const char * mode)
|
int CFile::open(const char * filepath, const char * mode)
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
|
|
||||||
file_fd = fopen(filepath, mode);
|
file_fd = fopen(filepath, mode);
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
fseek(file_fd, 0, SEEK_END);
|
fseek(file_fd, 0, SEEK_END);
|
||||||
filesize = ftell(file_fd);
|
filesize = ftell(file_fd);
|
||||||
rewind();
|
rewind();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFile::open(const u8 * mem, int size)
|
int CFile::open(const u8 * mem, int size)
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
|
|
||||||
mem_file = mem;
|
mem_file = mem;
|
||||||
filesize = size;
|
filesize = size;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFile::close()
|
void CFile::close()
|
||||||
{
|
{
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
fclose(file_fd);
|
fclose(file_fd);
|
||||||
|
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
mem_file = NULL;
|
mem_file = NULL;
|
||||||
filesize = 0;
|
filesize = 0;
|
||||||
Pos = 0;
|
Pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFile::read(u8 * ptr, size_t size)
|
int CFile::read(u8 * ptr, size_t size)
|
||||||
{
|
{
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
{
|
{
|
||||||
int ret = fread(ptr, 1, size, file_fd);
|
int ret = fread(ptr, 1, size, file_fd);
|
||||||
if(ret > 0)
|
if(ret > 0)
|
||||||
Pos += ret;
|
Pos += ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int readsize = size;
|
int readsize = size;
|
||||||
|
|
||||||
if(readsize > (long int) filesize-Pos)
|
if(readsize > (long int) filesize-Pos)
|
||||||
readsize = filesize-Pos;
|
readsize = filesize-Pos;
|
||||||
|
|
||||||
if(readsize <= 0)
|
if(readsize <= 0)
|
||||||
return readsize;
|
return readsize;
|
||||||
|
|
||||||
if(mem_file != NULL)
|
if(mem_file != NULL)
|
||||||
{
|
{
|
||||||
memcpy(ptr, mem_file+Pos, readsize);
|
memcpy(ptr, mem_file+Pos, readsize);
|
||||||
Pos += readsize;
|
Pos += readsize;
|
||||||
return readsize;
|
return readsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFile::write(const u8 * ptr, size_t size)
|
int CFile::write(const u8 * ptr, size_t size)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
if(size < 0)
|
if(size < 0)
|
||||||
return size;
|
return size;
|
||||||
*/
|
*/
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
{
|
{
|
||||||
int ret = fwrite(ptr, 1, size, file_fd);
|
int ret = fwrite(ptr, 1, size, file_fd);
|
||||||
if(ret > 0)
|
if(ret > 0)
|
||||||
Pos += ret;
|
Pos += ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFile::seek(long int offset, int origin)
|
int CFile::seek(long int offset, int origin)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if(origin == SEEK_SET)
|
if(origin == SEEK_SET)
|
||||||
{
|
Pos = offset;
|
||||||
Pos = offset;
|
else if(origin == SEEK_CUR)
|
||||||
}
|
Pos += offset;
|
||||||
else if(origin == SEEK_CUR)
|
else if(origin == SEEK_END)
|
||||||
{
|
Pos = filesize+offset;
|
||||||
Pos += offset;
|
if(Pos < 0)
|
||||||
}
|
{
|
||||||
else if(origin == SEEK_END)
|
Pos = 0;
|
||||||
{
|
return -1;
|
||||||
Pos = filesize+offset;
|
}
|
||||||
}
|
|
||||||
if(Pos < 0)
|
|
||||||
{
|
|
||||||
Pos = 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
ret = fseek(file_fd, Pos, SEEK_SET);
|
ret = fseek(file_fd, Pos, SEEK_SET);
|
||||||
|
|
||||||
if(mem_file != NULL)
|
if(mem_file != NULL && Pos > (long int)filesize)
|
||||||
{
|
{
|
||||||
if(Pos > (long int) filesize)
|
Pos = filesize;
|
||||||
{
|
return -1;
|
||||||
Pos = filesize;
|
}
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -6,25 +6,25 @@
|
|||||||
|
|
||||||
class CFile
|
class CFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CFile();
|
CFile();
|
||||||
CFile(const char * filepath, const char * mode);
|
CFile(const char * filepath, const char * mode);
|
||||||
CFile(const u8 * memory, int memsize);
|
CFile(const u8 * memory, int memsize);
|
||||||
~CFile();
|
~CFile();
|
||||||
int open(const char * filepath, const char * mode);
|
int open(const char * filepath, const char * mode);
|
||||||
int open(const u8 * memory, int memsize);
|
int open(const u8 * memory, int memsize);
|
||||||
void close();
|
void close();
|
||||||
int read(u8 * ptr, size_t size);
|
int read(u8 * ptr, size_t size);
|
||||||
int write(const u8 * ptr, size_t size);
|
int write(const u8 * ptr, size_t size);
|
||||||
int seek(long int offset, int origin);
|
int seek(long int offset, int origin);
|
||||||
long int tell() { return Pos; };
|
long int tell() { return Pos; };
|
||||||
long int size() { return filesize; };
|
long int size() { return filesize; };
|
||||||
void rewind() { seek(0, SEEK_SET); };
|
void rewind() { seek(0, SEEK_SET); };
|
||||||
protected:
|
protected:
|
||||||
FILE * file_fd;
|
FILE * file_fd;
|
||||||
const u8 * mem_file;
|
const u8 * mem_file;
|
||||||
u64 filesize;
|
u64 filesize;
|
||||||
long int Pos;
|
long int Pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,94 +33,94 @@
|
|||||||
#include "mem2.hpp"
|
#include "mem2.hpp"
|
||||||
|
|
||||||
Mp3Decoder::Mp3Decoder(const char * filepath)
|
Mp3Decoder::Mp3Decoder(const char * filepath)
|
||||||
: SoundDecoder(filepath)
|
: SoundDecoder(filepath)
|
||||||
{
|
{
|
||||||
SoundType = SOUND_MP3;
|
SoundType = SOUND_MP3;
|
||||||
ReadBuffer = NULL;
|
ReadBuffer = NULL;
|
||||||
mad_timer_reset(&Timer);
|
mad_timer_reset(&Timer);
|
||||||
mad_stream_init(&Stream);
|
mad_stream_init(&Stream);
|
||||||
mad_frame_init(&Frame);
|
mad_frame_init(&Frame);
|
||||||
mad_synth_init(&Synth);
|
mad_synth_init(&Synth);
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mp3Decoder::Mp3Decoder(const u8 * snd, int len)
|
Mp3Decoder::Mp3Decoder(const u8 * snd, int len)
|
||||||
: SoundDecoder(snd, len)
|
: SoundDecoder(snd, len)
|
||||||
{
|
{
|
||||||
SoundType = SOUND_MP3;
|
SoundType = SOUND_MP3;
|
||||||
ReadBuffer = NULL;
|
ReadBuffer = NULL;
|
||||||
mad_timer_reset(&Timer);
|
mad_timer_reset(&Timer);
|
||||||
mad_stream_init(&Stream);
|
mad_stream_init(&Stream);
|
||||||
mad_frame_init(&Frame);
|
mad_frame_init(&Frame);
|
||||||
mad_synth_init(&Synth);
|
mad_synth_init(&Synth);
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mp3Decoder::~Mp3Decoder()
|
Mp3Decoder::~Mp3Decoder()
|
||||||
{
|
{
|
||||||
ExitRequested = true;
|
ExitRequested = true;
|
||||||
while(Decoding)
|
while(Decoding)
|
||||||
usleep(100);
|
usleep(100);
|
||||||
|
|
||||||
mad_synth_finish(&Synth);
|
mad_synth_finish(&Synth);
|
||||||
mad_frame_finish(&Frame);
|
mad_frame_finish(&Frame);
|
||||||
mad_stream_finish(&Stream);
|
mad_stream_finish(&Stream);
|
||||||
|
|
||||||
MEM2_free(ReadBuffer);
|
MEM2_free(ReadBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mp3Decoder::OpenFile()
|
void Mp3Decoder::OpenFile()
|
||||||
{
|
{
|
||||||
GuardPtr = NULL;
|
GuardPtr = NULL;
|
||||||
ReadBuffer = (u8 *)MEM2_alloc(SoundBlockSize * SoundBlocks);
|
ReadBuffer = (u8 *)MEM2_alloc(SoundBlockSize * SoundBlocks);
|
||||||
if(!ReadBuffer)
|
if(!ReadBuffer)
|
||||||
{
|
{
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
delete file_fd;
|
delete file_fd;
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 dummybuff[4096];
|
u8 dummybuff[4096];
|
||||||
int ret = Read((u8 *) &dummybuff, 4096, 0);
|
int ret = Read((u8 *) &dummybuff, 4096, 0);
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{
|
{
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
delete file_fd;
|
delete file_fd;
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SampleRate = (u32) Frame.header.samplerate;
|
SampleRate = (u32) Frame.header.samplerate;
|
||||||
Format = ((MAD_NCHANNELS(&Frame.header) == 2) ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT);
|
Format = ((MAD_NCHANNELS(&Frame.header) == 2) ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT);
|
||||||
Rewind();
|
Rewind();
|
||||||
Decode();
|
Decode();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Mp3Decoder::Rewind()
|
int Mp3Decoder::Rewind()
|
||||||
{
|
{
|
||||||
mad_synth_finish(&Synth);
|
mad_synth_finish(&Synth);
|
||||||
mad_frame_finish(&Frame);
|
mad_frame_finish(&Frame);
|
||||||
mad_stream_finish(&Stream);
|
mad_stream_finish(&Stream);
|
||||||
mad_timer_reset(&Timer);
|
mad_timer_reset(&Timer);
|
||||||
mad_stream_init(&Stream);
|
mad_stream_init(&Stream);
|
||||||
mad_frame_init(&Frame);
|
mad_frame_init(&Frame);
|
||||||
mad_synth_init(&Synth);
|
mad_synth_init(&Synth);
|
||||||
SynthPos = 0;
|
SynthPos = 0;
|
||||||
GuardPtr = NULL;
|
GuardPtr = NULL;
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return SoundDecoder::Rewind();
|
return SoundDecoder::Rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline s16 FixedToShort(mad_fixed_t Fixed)
|
static inline s16 FixedToShort(mad_fixed_t Fixed)
|
||||||
@ -137,38 +137,38 @@ static inline s16 FixedToShort(mad_fixed_t Fixed)
|
|||||||
|
|
||||||
int Mp3Decoder::Read(u8 * buffer, int buffer_size, int)
|
int Mp3Decoder::Read(u8 * buffer, int buffer_size, int)
|
||||||
{
|
{
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(Format == VOICE_STEREO_16BIT)
|
if(Format == VOICE_STEREO_16BIT)
|
||||||
buffer_size &= ~0x0003;
|
buffer_size &= ~0x0003;
|
||||||
else
|
else
|
||||||
buffer_size &= ~0x0001;
|
buffer_size &= ~0x0001;
|
||||||
|
|
||||||
u8 * write_pos = buffer;
|
u8 * write_pos = buffer;
|
||||||
u8 * write_end = buffer+buffer_size;
|
u8 * write_end = buffer+buffer_size;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
while(SynthPos < Synth.pcm.length)
|
while(SynthPos < Synth.pcm.length)
|
||||||
{
|
{
|
||||||
if(write_pos >= write_end)
|
if(write_pos >= write_end)
|
||||||
return write_pos-buffer;
|
return write_pos-buffer;
|
||||||
|
|
||||||
*((s16 *) write_pos) = FixedToShort(Synth.pcm.samples[0][SynthPos]);
|
*((s16 *)write_pos) = FixedToShort(Synth.pcm.samples[0][SynthPos]);
|
||||||
write_pos += 2;
|
write_pos += 2;
|
||||||
|
|
||||||
if(MAD_NCHANNELS(&Frame.header) == 2)
|
if(MAD_NCHANNELS(&Frame.header) == 2)
|
||||||
{
|
{
|
||||||
*((s16 *) write_pos) = FixedToShort(Synth.pcm.samples[1][SynthPos]);
|
*((s16 *)write_pos) = FixedToShort(Synth.pcm.samples[1][SynthPos]);
|
||||||
write_pos += 2;
|
write_pos += 2;
|
||||||
}
|
}
|
||||||
SynthPos++;
|
SynthPos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN)
|
if(Stream.buffer == NULL || Stream.error == MAD_ERROR_BUFLEN)
|
||||||
{
|
{
|
||||||
u8 * ReadStart = ReadBuffer;
|
u8 *ReadStart = ReadBuffer;
|
||||||
int ReadSize = SoundBlockSize*SoundBlocks;
|
int ReadSize = SoundBlockSize*SoundBlocks;
|
||||||
int Remaining = 0;
|
int Remaining = 0;
|
||||||
|
|
||||||
@ -181,14 +181,14 @@ int Mp3Decoder::Read(u8 * buffer, int buffer_size, int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReadSize = file_fd->read(ReadStart, ReadSize);
|
ReadSize = file_fd->read(ReadStart, ReadSize);
|
||||||
if(ReadSize <= 0)
|
if(ReadSize <= 0)
|
||||||
{
|
{
|
||||||
GuardPtr = ReadStart;
|
GuardPtr = ReadStart;
|
||||||
memset(GuardPtr, 0, MAD_BUFFER_GUARD);
|
memset(GuardPtr, 0, MAD_BUFFER_GUARD);
|
||||||
ReadSize = MAD_BUFFER_GUARD;
|
ReadSize = MAD_BUFFER_GUARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurPos += ReadSize;
|
CurPos += ReadSize;
|
||||||
mad_stream_buffer(&Stream, ReadBuffer, Remaining+ReadSize);
|
mad_stream_buffer(&Stream, ReadBuffer, Remaining+ReadSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,20 +196,20 @@ int Mp3Decoder::Read(u8 * buffer, int buffer_size, int)
|
|||||||
{
|
{
|
||||||
if(MAD_RECOVERABLE(Stream.error))
|
if(MAD_RECOVERABLE(Stream.error))
|
||||||
{
|
{
|
||||||
if(Stream.error != MAD_ERROR_LOSTSYNC || !GuardPtr)
|
if(Stream.error != MAD_ERROR_LOSTSYNC || !GuardPtr)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(Stream.error != MAD_ERROR_BUFLEN)
|
if(Stream.error != MAD_ERROR_BUFLEN)
|
||||||
return -1;
|
return -1;
|
||||||
else if(Stream.error == MAD_ERROR_BUFLEN && GuardPtr)
|
else if(Stream.error == MAD_ERROR_BUFLEN && GuardPtr)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mad_timer_add(&Timer,Frame.header.duration);
|
mad_timer_add(&Timer,Frame.header.duration);
|
||||||
mad_synth_frame(&Synth,&Frame);
|
mad_synth_frame(&Synth,&Frame);
|
||||||
SynthPos = 0;
|
SynthPos = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,23 +29,23 @@
|
|||||||
|
|
||||||
class Mp3Decoder : public SoundDecoder
|
class Mp3Decoder : public SoundDecoder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Mp3Decoder(const char * filepath);
|
Mp3Decoder(const char * filepath);
|
||||||
Mp3Decoder(const u8 * sound, int len);
|
Mp3Decoder(const u8 * sound, int len);
|
||||||
~Mp3Decoder();
|
~Mp3Decoder();
|
||||||
int GetFormat() { return Format; };
|
int GetFormat() { return Format; };
|
||||||
int GetSampleRate() { return SampleRate; };
|
int GetSampleRate() { return SampleRate; };
|
||||||
int Rewind();
|
int Rewind();
|
||||||
int Read(u8 * buffer, int buffer_size, int pos);
|
int Read(u8 * buffer, int buffer_size, int pos);
|
||||||
protected:
|
protected:
|
||||||
void OpenFile();
|
void OpenFile();
|
||||||
struct mad_stream Stream;
|
struct mad_stream Stream;
|
||||||
struct mad_frame Frame;
|
struct mad_frame Frame;
|
||||||
struct mad_synth Synth;
|
struct mad_synth Synth;
|
||||||
mad_timer_t Timer;
|
mad_timer_t Timer;
|
||||||
u8 * GuardPtr;
|
u8 * GuardPtr;
|
||||||
u8 * ReadBuffer;
|
u8 * ReadBuffer;
|
||||||
u8 Format;
|
u8 Format;
|
||||||
u32 SampleRate;
|
u32 SampleRate;
|
||||||
u32 SynthPos;
|
u32 SynthPos;
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
extern "C" int ogg_read(void * punt, int bytes, int blocks, int *f)
|
extern "C" int ogg_read(void * punt, int bytes, int blocks, int *f)
|
||||||
{
|
{
|
||||||
return ((CFile *) f)->read((u8 *) punt, bytes*blocks);
|
return ((CFile *) f)->read((u8 *) punt, bytes*blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ogg_seek(int *f, ogg_int64_t offset, int mode)
|
extern "C" int ogg_seek(int *f, ogg_int64_t offset, int mode)
|
||||||
@ -38,106 +38,106 @@ extern "C" int ogg_seek(int *f, ogg_int64_t offset, int mode)
|
|||||||
|
|
||||||
extern "C" int ogg_close(int *f)
|
extern "C" int ogg_close(int *f)
|
||||||
{
|
{
|
||||||
((CFile *) f)->close();
|
((CFile*)f)->close();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" long ogg_tell(int *f)
|
extern "C" long ogg_tell(int *f)
|
||||||
{
|
{
|
||||||
return (long) ((CFile *) f)->tell();
|
return (long)((CFile *)f)->tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ov_callbacks callbacks = {
|
static ov_callbacks callbacks = {
|
||||||
(size_t (*)(void *, size_t, size_t, void *)) ogg_read,
|
(size_t (*)(void *, size_t, size_t, void *)) ogg_read,
|
||||||
(int (*)(void *, ogg_int64_t, int)) ogg_seek,
|
(int (*)(void *, ogg_int64_t, int)) ogg_seek,
|
||||||
(int (*)(void *)) ogg_close,
|
(int (*)(void *)) ogg_close,
|
||||||
(long (*)(void *)) ogg_tell
|
(long (*)(void *)) ogg_tell
|
||||||
};
|
};
|
||||||
|
|
||||||
OggDecoder::OggDecoder(const char * filepath)
|
OggDecoder::OggDecoder(const char * filepath)
|
||||||
: SoundDecoder(filepath)
|
: SoundDecoder(filepath)
|
||||||
{
|
{
|
||||||
SoundType = SOUND_OGG;
|
SoundType = SOUND_OGG;
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
OggDecoder::OggDecoder(const u8 * snd, int len)
|
OggDecoder::OggDecoder(const u8 * snd, int len)
|
||||||
: SoundDecoder(snd, len)
|
: SoundDecoder(snd, len)
|
||||||
{
|
{
|
||||||
SoundType = SOUND_OGG;
|
SoundType = SOUND_OGG;
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
OggDecoder::~OggDecoder()
|
OggDecoder::~OggDecoder()
|
||||||
{
|
{
|
||||||
ExitRequested = true;
|
ExitRequested = true;
|
||||||
while(Decoding)
|
while(Decoding)
|
||||||
usleep(100);
|
usleep(100);
|
||||||
|
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
ov_clear(&ogg_file);
|
ov_clear(&ogg_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OggDecoder::OpenFile()
|
void OggDecoder::OpenFile()
|
||||||
{
|
{
|
||||||
if (ov_open_callbacks(file_fd, &ogg_file, NULL, 0, callbacks) < 0)
|
if(ov_open_callbacks(file_fd, &ogg_file, NULL, 0, callbacks) < 0)
|
||||||
{
|
{
|
||||||
delete file_fd;
|
delete file_fd;
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ogg_info = ov_info(&ogg_file, -1);
|
ogg_info = ov_info(&ogg_file, -1);
|
||||||
Decode();
|
Decode();
|
||||||
}
|
}
|
||||||
|
|
||||||
int OggDecoder::GetFormat()
|
int OggDecoder::GetFormat()
|
||||||
{
|
{
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return VOICE_STEREO_16BIT;
|
return VOICE_STEREO_16BIT;
|
||||||
|
|
||||||
return ((ogg_info->channels == 2) ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT);
|
return ((ogg_info->channels == 2) ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int OggDecoder::GetSampleRate()
|
int OggDecoder::GetSampleRate()
|
||||||
{
|
{
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return (int) ogg_info->rate;
|
return (int) ogg_info->rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OggDecoder::Rewind()
|
int OggDecoder::Rewind()
|
||||||
{
|
{
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int ret = ov_time_seek(&ogg_file, 0);
|
int ret = ov_time_seek(&ogg_file, 0);
|
||||||
CurPos = 0;
|
CurPos = 0;
|
||||||
EndOfFile = false;
|
EndOfFile = false;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OggDecoder::Read(u8 * buffer, int buffer_size, int)
|
int OggDecoder::Read(u8 * buffer, int buffer_size, int)
|
||||||
{
|
{
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int bitstream = 0;
|
int bitstream = 0;
|
||||||
|
|
||||||
int read = ov_read(&ogg_file, (char *) buffer, buffer_size, &bitstream);
|
int read = ov_read(&ogg_file, (char *) buffer, buffer_size, &bitstream);
|
||||||
|
|
||||||
if(read > 0)
|
if(read > 0)
|
||||||
CurPos += read;
|
CurPos += read;
|
||||||
|
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
@ -30,16 +30,16 @@
|
|||||||
|
|
||||||
class OggDecoder : public SoundDecoder
|
class OggDecoder : public SoundDecoder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OggDecoder(const char * filepath);
|
OggDecoder(const char * filepath);
|
||||||
OggDecoder(const u8 * snd, int len);
|
OggDecoder(const u8 * snd, int len);
|
||||||
~OggDecoder();
|
~OggDecoder();
|
||||||
int GetFormat();
|
int GetFormat();
|
||||||
int GetSampleRate();
|
int GetSampleRate();
|
||||||
int Rewind();
|
int Rewind();
|
||||||
int Read(u8 * buffer, int buffer_size, int pos);
|
int Read(u8 * buffer, int buffer_size, int pos);
|
||||||
protected:
|
protected:
|
||||||
void OpenFile();
|
void OpenFile();
|
||||||
OggVorbis_File ogg_file;
|
OggVorbis_File ogg_file;
|
||||||
vorbis_info *ogg_info;
|
vorbis_info *ogg_info;
|
||||||
};
|
};
|
||||||
|
@ -32,123 +32,123 @@
|
|||||||
|
|
||||||
SoundDecoder::SoundDecoder()
|
SoundDecoder::SoundDecoder()
|
||||||
{
|
{
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundDecoder::SoundDecoder(const char * filepath)
|
SoundDecoder::SoundDecoder(const char * filepath)
|
||||||
{
|
{
|
||||||
file_fd = new CFile(filepath, "rb");
|
file_fd = new CFile(filepath, "rb");
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundDecoder::SoundDecoder(const u8 * buffer, int size)
|
SoundDecoder::SoundDecoder(const u8 * buffer, int size)
|
||||||
{
|
{
|
||||||
file_fd = new CFile(buffer, size);
|
file_fd = new CFile(buffer, size);
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundDecoder::~SoundDecoder()
|
SoundDecoder::~SoundDecoder()
|
||||||
{
|
{
|
||||||
ExitRequested = true;
|
ExitRequested = true;
|
||||||
while(Decoding)
|
while(Decoding)
|
||||||
usleep(100);
|
usleep(100);
|
||||||
|
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
delete file_fd;
|
delete file_fd;
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundDecoder::Init()
|
void SoundDecoder::Init()
|
||||||
{
|
{
|
||||||
SoundType = SOUND_RAW;
|
SoundType = SOUND_RAW;
|
||||||
SoundBlocks = 8; //Settings.SoundblockCount;
|
SoundBlocks = 8; //Settings.SoundblockCount;
|
||||||
SoundBlockSize = 8092; //Settings.SoundblockSize;
|
SoundBlockSize = 8092; //Settings.SoundblockSize;
|
||||||
CurPos = 0;
|
CurPos = 0;
|
||||||
Loop = false;
|
Loop = false;
|
||||||
EndOfFile = false;
|
EndOfFile = false;
|
||||||
Decoding = false;
|
Decoding = false;
|
||||||
ExitRequested = false;
|
ExitRequested = false;
|
||||||
SoundBuffer.SetBufferBlockSize(SoundBlockSize);
|
SoundBuffer.SetBufferBlockSize(SoundBlockSize);
|
||||||
SoundBuffer.Resize(SoundBlocks);
|
SoundBuffer.Resize(SoundBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SoundDecoder::Rewind()
|
int SoundDecoder::Rewind()
|
||||||
{
|
{
|
||||||
CurPos = 0;
|
CurPos = 0;
|
||||||
EndOfFile = false;
|
EndOfFile = false;
|
||||||
file_fd->rewind();
|
file_fd->rewind();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SoundDecoder::Read(u8 * buffer, int buffer_size, int)
|
int SoundDecoder::Read(u8 * buffer, int buffer_size, int)
|
||||||
{
|
{
|
||||||
int ret = file_fd->read(buffer, buffer_size);
|
int ret = file_fd->read(buffer, buffer_size);
|
||||||
CurPos += ret;
|
CurPos += ret;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundDecoder::Decode()
|
void SoundDecoder::Decode()
|
||||||
{
|
{
|
||||||
if(!file_fd || ExitRequested || EndOfFile)
|
if(!file_fd || ExitRequested || EndOfFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u16 newWhich = SoundBuffer.Which();
|
u16 newWhich = SoundBuffer.Which();
|
||||||
u16 i = 0;
|
u16 i = 0;
|
||||||
for (i = 0; i < SoundBuffer.Size()-2; i++)
|
for(i = 0; i < SoundBuffer.Size()-2; i++)
|
||||||
{
|
{
|
||||||
if(!SoundBuffer.IsBufferReady(newWhich))
|
if(!SoundBuffer.IsBufferReady(newWhich))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
newWhich = (newWhich+1) % SoundBuffer.Size();
|
newWhich = (newWhich+1) % SoundBuffer.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i == SoundBuffer.Size()-2)
|
if(i == SoundBuffer.Size()-2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Decoding = true;
|
Decoding = true;
|
||||||
|
|
||||||
int done = 0;
|
int done = 0;
|
||||||
u8 * write_buf = SoundBuffer.GetBuffer(newWhich);
|
u8 *write_buf = SoundBuffer.GetBuffer(newWhich);
|
||||||
if(!write_buf)
|
if(!write_buf)
|
||||||
{
|
{
|
||||||
ExitRequested = true;
|
ExitRequested = true;
|
||||||
Decoding = false;
|
Decoding = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(done < SoundBlockSize)
|
while(done < SoundBlockSize)
|
||||||
{
|
{
|
||||||
int ret = Read(&write_buf[done], SoundBlockSize-done, Tell());
|
int ret = Read(&write_buf[done], SoundBlockSize-done, Tell());
|
||||||
|
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{
|
{
|
||||||
if(Loop)
|
if(Loop)
|
||||||
{
|
{
|
||||||
Rewind();
|
Rewind();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EndOfFile = true;
|
EndOfFile = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done += ret;
|
done += ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(done > 0)
|
if(done > 0)
|
||||||
{
|
{
|
||||||
SoundBuffer.SetBufferSize(newWhich, done);
|
SoundBuffer.SetBufferSize(newWhich, done);
|
||||||
SoundBuffer.SetBufferReady(newWhich, true);
|
SoundBuffer.SetBufferReady(newWhich, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!SoundBuffer.IsBufferReady((newWhich+1) % SoundBuffer.Size()))
|
if(!SoundBuffer.IsBufferReady((newWhich+1) % SoundBuffer.Size()))
|
||||||
Decode();
|
Decode();
|
||||||
|
|
||||||
Decoding = false;
|
Decoding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,35 +34,35 @@
|
|||||||
|
|
||||||
class SoundHandler
|
class SoundHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static SoundHandler * Instance();
|
static SoundHandler * Instance();
|
||||||
static void DestroyInstance();
|
static void DestroyInstance();
|
||||||
|
|
||||||
void AddDecoder(int voice, const char * filepath);
|
void AddDecoder(int voice, const char * filepath);
|
||||||
void AddDecoder(int voice, const u8 * snd, int len);
|
void AddDecoder(int voice, const u8 * snd, int len);
|
||||||
void RemoveDecoder(int voice);
|
void RemoveDecoder(int voice);
|
||||||
void DestroyDecoder(SoundDecoder * decoder);
|
void DestroyDecoder(SoundDecoder * decoder);
|
||||||
|
|
||||||
SoundDecoder * Decoder(int i) { return ((i < 0 || i >= MAX_DECODERS) ? NULL : DecoderList[i]); };
|
SoundDecoder * Decoder(int i) { return ((i < 0 || i >= MAX_DECODERS) ? NULL : DecoderList[i]); };
|
||||||
void ThreadSignal() { LWP_ThreadSignal(ThreadQueue); };
|
void ThreadSignal() { LWP_ThreadSignal(ThreadQueue); };
|
||||||
bool IsDecoding() { return Decoding; };
|
bool IsDecoding() { return Decoding; };
|
||||||
protected:
|
protected:
|
||||||
SoundHandler();
|
SoundHandler();
|
||||||
~SoundHandler();
|
~SoundHandler();
|
||||||
static void * UpdateThread(void *arg);
|
static void * UpdateThread(void *arg);
|
||||||
void InternalSoundUpdates();
|
void InternalSoundUpdates();
|
||||||
void ClearDecoderList();
|
void ClearDecoderList();
|
||||||
SoundDecoder * GetSoundDecoder(const char * filepath);
|
SoundDecoder * GetSoundDecoder(const char * filepath);
|
||||||
SoundDecoder * GetSoundDecoder(const u8 * sound, int length);
|
SoundDecoder * GetSoundDecoder(const u8 * sound, int length);
|
||||||
|
|
||||||
static SoundHandler * instance;
|
static SoundHandler * instance;
|
||||||
u8 * ThreadStack;
|
u8 * ThreadStack;
|
||||||
lwp_t SoundThread;
|
lwp_t SoundThread;
|
||||||
lwpq_t ThreadQueue;
|
lwpq_t ThreadQueue;
|
||||||
bool Decoding;
|
bool Decoding;
|
||||||
bool ExitRequested;
|
bool ExitRequested;
|
||||||
|
|
||||||
SoundDecoder * DecoderList[MAX_DECODERS];
|
SoundDecoder * DecoderList[MAX_DECODERS];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,46 +27,47 @@
|
|||||||
#include "WavDecoder.hpp"
|
#include "WavDecoder.hpp"
|
||||||
|
|
||||||
WavDecoder::WavDecoder(const char * filepath)
|
WavDecoder::WavDecoder(const char * filepath)
|
||||||
: SoundDecoder(filepath)
|
: SoundDecoder(filepath)
|
||||||
{
|
{
|
||||||
SoundType = SOUND_WAV;
|
SoundType = SOUND_WAV;
|
||||||
SampleRate = 48000;
|
SampleRate = 48000;
|
||||||
Format = VOICE_STEREO_16BIT;
|
Format = VOICE_STEREO_16BIT;
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
WavDecoder::WavDecoder(const u8 * snd, int len)
|
WavDecoder::WavDecoder(const u8 * snd, int len)
|
||||||
: SoundDecoder(snd, len)
|
: SoundDecoder(snd, len)
|
||||||
{
|
{
|
||||||
SoundType = SOUND_WAV;
|
SoundType = SOUND_WAV;
|
||||||
SampleRate = 48000;
|
SampleRate = 48000;
|
||||||
Format = VOICE_STEREO_16BIT;
|
Format = VOICE_STEREO_16BIT;
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
WavDecoder::~WavDecoder()
|
WavDecoder::~WavDecoder()
|
||||||
{
|
{
|
||||||
|
CloseFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WavDecoder::OpenFile()
|
void WavDecoder::OpenFile()
|
||||||
{
|
{
|
||||||
SWaveHdr Header;
|
SWaveHdr Header;
|
||||||
SWaveFmtChunk FmtChunk;
|
SWaveFmtChunk FmtChunk;
|
||||||
memset(&Header, 0, sizeof(SWaveHdr));
|
memset(&Header, 0, sizeof(SWaveHdr));
|
||||||
memset(&FmtChunk, 0, sizeof(SWaveFmtChunk));
|
memset(&FmtChunk, 0, sizeof(SWaveFmtChunk));
|
||||||
|
|
||||||
file_fd->read((u8 *) &Header, sizeof(SWaveHdr));
|
file_fd->read((u8 *) &Header, sizeof(SWaveHdr));
|
||||||
file_fd->read((u8 *) &FmtChunk, sizeof(SWaveFmtChunk));
|
file_fd->read((u8 *) &FmtChunk, sizeof(SWaveFmtChunk));
|
||||||
|
|
||||||
if (Header.magicRIFF != 'RIFF')
|
if(Header.magicRIFF != 'RIFF')
|
||||||
{
|
{
|
||||||
CloseFile();
|
CloseFile();
|
||||||
return;
|
return;
|
||||||
@ -82,10 +83,10 @@ void WavDecoder::OpenFile()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataOffset = sizeof(SWaveHdr)+le32(FmtChunk.size)+8;
|
DataOffset = sizeof(SWaveHdr)+le32(FmtChunk.size)+8;
|
||||||
file_fd->seek(DataOffset, SEEK_SET);
|
file_fd->seek(DataOffset, SEEK_SET);
|
||||||
SWaveChunk DataChunk;
|
SWaveChunk DataChunk;
|
||||||
file_fd->read((u8 *) &DataChunk, sizeof(SWaveChunk));
|
file_fd->read((u8 *) &DataChunk, sizeof(SWaveChunk));
|
||||||
|
|
||||||
while(DataChunk.magicDATA != 'data')
|
while(DataChunk.magicDATA != 'data')
|
||||||
{
|
{
|
||||||
@ -99,56 +100,56 @@ void WavDecoder::OpenFile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DataOffset += 8;
|
DataOffset += 8;
|
||||||
DataSize = le32(DataChunk.size);
|
DataSize = le32(DataChunk.size);
|
||||||
Is16Bit = (le16(FmtChunk.bps) == 16);
|
Is16Bit = (le16(FmtChunk.bps) == 16);
|
||||||
SampleRate = le32(FmtChunk.freq);
|
SampleRate = le32(FmtChunk.freq);
|
||||||
|
|
||||||
if (le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 1)
|
if(le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 1)
|
||||||
Format = VOICE_MONO_8BIT;
|
Format = VOICE_MONO_8BIT;
|
||||||
else if (le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 2)
|
else if(le16(FmtChunk.channels) == 1 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 2)
|
||||||
Format = VOICE_MONO_16BIT;
|
Format = VOICE_MONO_16BIT;
|
||||||
else if (le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 2)
|
else if(le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 8 && le16(FmtChunk.alignment) <= 2)
|
||||||
Format = VOICE_STEREO_8BIT;
|
Format = VOICE_STEREO_8BIT;
|
||||||
else if (le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 4)
|
else if(le16(FmtChunk.channels) == 2 && le16(FmtChunk.bps) == 16 && le16(FmtChunk.alignment) <= 4)
|
||||||
Format = VOICE_STEREO_16BIT;
|
Format = VOICE_STEREO_16BIT;
|
||||||
|
|
||||||
Decode();
|
Decode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WavDecoder::CloseFile()
|
void WavDecoder::CloseFile()
|
||||||
{
|
{
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
delete file_fd;
|
delete file_fd;
|
||||||
|
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WavDecoder::Read(u8 * buffer, int buffer_size, int)
|
int WavDecoder::Read(u8 * buffer, int buffer_size, int)
|
||||||
{
|
{
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(CurPos >= (int) DataSize)
|
if(CurPos >= (int) DataSize)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
file_fd->seek(DataOffset+CurPos, SEEK_SET);
|
file_fd->seek(DataOffset+CurPos, SEEK_SET);
|
||||||
|
|
||||||
if(buffer_size > (int) DataSize-CurPos)
|
if(buffer_size > (int) DataSize-CurPos)
|
||||||
buffer_size = DataSize-CurPos;
|
buffer_size = DataSize-CurPos;
|
||||||
|
|
||||||
int read = file_fd->read(buffer, buffer_size);
|
int read = file_fd->read(buffer, buffer_size);
|
||||||
if(read > 0)
|
if(read > 0)
|
||||||
{
|
{
|
||||||
if (Is16Bit)
|
if(Is16Bit)
|
||||||
{
|
{
|
||||||
read &= ~0x0001;
|
read &= ~0x0001;
|
||||||
|
|
||||||
for (u32 i = 0; i < (u32) (read / sizeof (u16)); ++i)
|
for(u32 i = 0; i < (u32) (read / sizeof (u16)); ++i)
|
||||||
((u16 *) buffer)[i] = le16(((u16 *) buffer)[i]);
|
((u16 *)buffer)[i] = le16(((u16 *)buffer)[i]);
|
||||||
}
|
}
|
||||||
CurPos += read;
|
CurPos += read;
|
||||||
}
|
}
|
||||||
|
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
@ -55,21 +55,21 @@ typedef struct
|
|||||||
|
|
||||||
class WavDecoder : public SoundDecoder
|
class WavDecoder : public SoundDecoder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WavDecoder(const char * filepath);
|
WavDecoder(const char * filepath);
|
||||||
WavDecoder(const u8 * snd, int len);
|
WavDecoder(const u8 * snd, int len);
|
||||||
~WavDecoder();
|
~WavDecoder();
|
||||||
int GetFormat() { return Format; };
|
int GetFormat() { return Format; };
|
||||||
int GetSampleRate() { return SampleRate; };
|
int GetSampleRate() { return SampleRate; };
|
||||||
int Read(u8 * buffer, int buffer_size, int pos);
|
int Read(u8 * buffer, int buffer_size, int pos);
|
||||||
protected:
|
protected:
|
||||||
void OpenFile();
|
void OpenFile();
|
||||||
void CloseFile();
|
void CloseFile();
|
||||||
u32 DataOffset;
|
u32 DataOffset;
|
||||||
u32 DataSize;
|
u32 DataSize;
|
||||||
u32 SampleRate;
|
u32 SampleRate;
|
||||||
u8 Format;
|
u8 Format;
|
||||||
bool Is16Bit;
|
bool Is16Bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -55,8 +55,9 @@ static inline int GetFirstUnusedVoice()
|
|||||||
|
|
||||||
extern "C" void SoundCallback(s32 voice)
|
extern "C" void SoundCallback(s32 voice)
|
||||||
{
|
{
|
||||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
SoundDecoder *decoder = SoundHandler::Instance()->Decoder(voice);
|
||||||
if(!decoder) return;
|
if(!decoder)
|
||||||
|
return;
|
||||||
|
|
||||||
if(decoder->IsBufferReady())
|
if(decoder->IsBufferReady())
|
||||||
{
|
{
|
||||||
@ -98,11 +99,12 @@ GuiSound::GuiSound(GuiSound *g)
|
|||||||
voice = -1;
|
voice = -1;
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
if (g == NULL) return;
|
if(g == NULL)
|
||||||
|
return;
|
||||||
if (g->sound != NULL)
|
|
||||||
|
if(g->sound != NULL)
|
||||||
{
|
{
|
||||||
u8 * snd = (u8 *) malloc(g->length);
|
u8 *snd = (u8 *) malloc(g->length);
|
||||||
memcpy(snd, g->sound, g->length);
|
memcpy(snd, g->sound, g->length);
|
||||||
Load(snd, g->length, true);
|
Load(snd, g->length, true);
|
||||||
}
|
}
|
||||||
@ -125,7 +127,7 @@ void GuiSound::Init()
|
|||||||
voice = GetFirstUnusedVoice();
|
voice = GetFirstUnusedVoice();
|
||||||
if(voice > 0)
|
if(voice > 0)
|
||||||
VoiceUsed[voice] = true;
|
VoiceUsed[voice] = true;
|
||||||
|
|
||||||
volume = 255;
|
volume = 255;
|
||||||
SoundEffectLength = 0;
|
SoundEffectLength = 0;
|
||||||
loop = false;
|
loop = false;
|
||||||
@ -161,7 +163,8 @@ bool GuiSound::Load(const char * filepath)
|
|||||||
|
|
||||||
FILE * f = fopen(filepath, "rb");
|
FILE * f = fopen(filepath, "rb");
|
||||||
if(!f)
|
if(!f)
|
||||||
{ gprintf("Failed to load file %s!!\n", filepath);
|
{
|
||||||
|
gprintf("Failed to load file %s!!\n", filepath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,12 +176,14 @@ bool GuiSound::Load(const char * filepath)
|
|||||||
gprintf("Loading %s using voice %d\n", filepath, voice);
|
gprintf("Loading %s using voice %d\n", filepath, voice);
|
||||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
||||||
if(!decoder)
|
if(!decoder)
|
||||||
{ gprintf("No Decoder!!!\n");
|
{
|
||||||
|
gprintf("No Decoder!!!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!decoder->IsBufferReady())
|
if(!decoder->IsBufferReady())
|
||||||
{ gprintf("Buffer not ready!!n");
|
{
|
||||||
|
gprintf("Buffer not ready!!\n");
|
||||||
SoundHandler::Instance()->RemoveDecoder(voice);
|
SoundHandler::Instance()->RemoveDecoder(voice);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -194,29 +199,26 @@ bool GuiSound::Load(const u8 * snd, u32 len, bool isallocated)
|
|||||||
FreeMemory();
|
FreeMemory();
|
||||||
this->voice = voice;
|
this->voice = voice;
|
||||||
|
|
||||||
if(!snd) return false;
|
if(!snd)
|
||||||
|
return false;
|
||||||
|
|
||||||
if(!isallocated && *((u32 *) snd) == 'RIFF')
|
if(!isallocated && *((u32 *) snd) == 'RIFF')
|
||||||
return LoadSoundEffect(snd, len);
|
return LoadSoundEffect(snd, len);
|
||||||
|
|
||||||
if(*((u32 *) snd) == 'IMD5')
|
if(*((u32 *) snd) == 'IMD5')
|
||||||
{
|
|
||||||
UncompressSoundbin(snd, len, isallocated);
|
UncompressSoundbin(snd, len, isallocated);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sound = (u8 *) snd;
|
sound = (u8 *) snd;
|
||||||
length = len;
|
length = len;
|
||||||
allocated = isallocated;
|
allocated = isallocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundHandler::Instance()->AddDecoder(this->voice, sound, length);
|
SoundHandler::Instance()->AddDecoder(this->voice, sound, length);
|
||||||
|
|
||||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
||||||
if(!decoder)
|
if(!decoder)
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if(!decoder->IsBufferReady())
|
if(!decoder->IsBufferReady())
|
||||||
{
|
{
|
||||||
@ -274,10 +276,12 @@ void GuiSound::Play(int vol, bool restart)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((IsPlaying() && !restart) || voice < 0 || voice >= 16) return;
|
if((IsPlaying() && !restart) || voice < 0 || voice >= 16)
|
||||||
|
return;
|
||||||
|
|
||||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
SoundDecoder *decoder = SoundHandler::Instance()->Decoder(voice);
|
||||||
if(!decoder) return;
|
if(!decoder)
|
||||||
|
return;
|
||||||
|
|
||||||
ASND_StopVoice(voice);
|
ASND_StopVoice(voice);
|
||||||
if(decoder->IsEOF())
|
if(decoder->IsEOF())
|
||||||
@ -303,17 +307,18 @@ void GuiSound::Play()
|
|||||||
void GuiSound::Stop()
|
void GuiSound::Stop()
|
||||||
{
|
{
|
||||||
volume = 0;
|
volume = 0;
|
||||||
if (!IsPlaying() || voice < 0 || voice >= 16)
|
if(!IsPlaying() || voice < 0 || voice >= 16)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ASND_StopVoice(voice);
|
ASND_StopVoice(voice);
|
||||||
|
|
||||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
SoundDecoder *decoder = SoundHandler::Instance()->Decoder(voice);
|
||||||
if(!decoder) return;
|
if(!decoder)
|
||||||
|
return;
|
||||||
|
|
||||||
decoder->ClearBuffer();
|
decoder->ClearBuffer();
|
||||||
Rewind();
|
Rewind();
|
||||||
|
|
||||||
SoundHandler::Instance()->ThreadSignal();
|
SoundHandler::Instance()->ThreadSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,24 +366,26 @@ void GuiSound::SetLoop(u8 l)
|
|||||||
{
|
{
|
||||||
loop = l;
|
loop = l;
|
||||||
|
|
||||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
SoundDecoder *decoder = SoundHandler::Instance()->Decoder(voice);
|
||||||
if(!decoder) return;
|
if(!decoder)
|
||||||
|
return;
|
||||||
|
|
||||||
decoder->SetLoop(l == 1);
|
decoder->SetLoop(l == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiSound::Rewind()
|
void GuiSound::Rewind()
|
||||||
{
|
{
|
||||||
SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice);
|
SoundDecoder *decoder = SoundHandler::Instance()->Decoder(voice);
|
||||||
if(!decoder) return;
|
if(!decoder)
|
||||||
|
return;
|
||||||
|
|
||||||
decoder->Rewind();
|
decoder->Rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _LZ77Info
|
struct _LZ77Info
|
||||||
{
|
{
|
||||||
u16 length : 4;
|
u16 length : 4;
|
||||||
u16 offset : 12;
|
u16 offset : 12;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
typedef struct _LZ77Info LZ77Info;
|
typedef struct _LZ77Info LZ77Info;
|
||||||
@ -397,24 +404,25 @@ u8 * uncompressLZ77(const u8 *inBuf, u32 inLength, u32 * size)
|
|||||||
|
|
||||||
buffer = (u8 *)malloc(uncSize);
|
buffer = (u8 *)malloc(uncSize);
|
||||||
|
|
||||||
if (!buffer) return buffer;
|
if(!buffer)
|
||||||
|
return buffer;
|
||||||
|
|
||||||
u8 *bufCur = buffer;
|
u8 *bufCur = buffer;
|
||||||
u8 *bufEnd = buffer + uncSize;
|
u8 *bufEnd = buffer + uncSize;
|
||||||
|
|
||||||
while (bufCur < bufEnd && inBuf < inBufEnd)
|
while(bufCur < bufEnd && inBuf < inBufEnd)
|
||||||
{
|
{
|
||||||
u8 flags = *inBuf;
|
u8 flags = *inBuf;
|
||||||
++inBuf;
|
++inBuf;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (i = 0; i < 8 && bufCur < bufEnd && inBuf < inBufEnd; ++i)
|
for(i = 0; i < 8 && bufCur < bufEnd && inBuf < inBufEnd; ++i)
|
||||||
{
|
{
|
||||||
if ((flags & 0x80) != 0)
|
if((flags & 0x80) != 0)
|
||||||
{
|
{
|
||||||
const LZ77Info * info = (const LZ77Info *)inBuf;
|
const LZ77Info * info = (const LZ77Info *)inBuf;
|
||||||
inBuf += sizeof (LZ77Info);
|
inBuf += sizeof (LZ77Info);
|
||||||
int length = info->length + 3;
|
int length = info->length + 3;
|
||||||
if (bufCur - info->offset - 1 < buffer || bufCur + length > bufEnd)
|
if(bufCur - info->offset - 1 < buffer || bufCur + length > bufEnd)
|
||||||
return buffer;
|
return buffer;
|
||||||
memcpy(bufCur, bufCur - info->offset - 1, length);
|
memcpy(bufCur, bufCur - info->offset - 1, length);
|
||||||
bufCur += length;
|
bufCur += length;
|
||||||
@ -439,7 +447,8 @@ void GuiSound::UncompressSoundbin(const u8 * snd, u32 len, bool isallocated)
|
|||||||
const u8 * file = snd+32;
|
const u8 * file = snd+32;
|
||||||
|
|
||||||
length = len-32;
|
length = len-32;
|
||||||
if (length <= 0) return;
|
if(length <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if(*((u32 *) file) == 'LZ77')
|
if(*((u32 *) file) == 'LZ77')
|
||||||
{
|
{
|
||||||
|
@ -32,69 +32,69 @@
|
|||||||
//!Sound conversion and playback. A wrapper for other sound libraries - ASND, libmad, ltremor, etc
|
//!Sound conversion and playback. A wrapper for other sound libraries - ASND, libmad, ltremor, etc
|
||||||
class GuiSound
|
class GuiSound
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//!Constructor
|
//!Constructor
|
||||||
GuiSound();
|
GuiSound();
|
||||||
//!Copy Constructor
|
//!Copy Constructor
|
||||||
GuiSound(GuiSound *g);
|
GuiSound(GuiSound *g);
|
||||||
//!Constructor
|
//!Constructor
|
||||||
//!\param sound Pointer to the sound data
|
//!\param sound Pointer to the sound data
|
||||||
//!\param filesize Length of sound data
|
//!\param filesize Length of sound data
|
||||||
GuiSound(std::string filepath, int voice = -1);
|
GuiSound(std::string filepath, int voice = -1);
|
||||||
GuiSound(const u8 * snd, u32 len, std::string name, bool allocated = false, int voice = -1);
|
GuiSound(const u8 * snd, u32 len, std::string name, bool allocated = false, int voice = -1);
|
||||||
//!Stops sound and frees all memory/closes files
|
//!Stops sound and frees all memory/closes files
|
||||||
void FreeMemory();
|
void FreeMemory();
|
||||||
//!Destructor
|
//!Destructor
|
||||||
~GuiSound();
|
~GuiSound();
|
||||||
//!Load a file and replace the old one
|
//!Load a file and replace the old one
|
||||||
bool Load(const char * filepath);
|
bool Load(const char * filepath);
|
||||||
//!Load a file and replace the old one
|
//!Load a file and replace the old one
|
||||||
bool Load(const u8 * snd, u32 len, bool allocated = true);
|
bool Load(const u8 * snd, u32 len, bool allocated = true);
|
||||||
//!For quick playback of the internal soundeffects
|
//!For quick playback of the internal soundeffects
|
||||||
bool LoadSoundEffect(const u8 * snd, u32 len);
|
bool LoadSoundEffect(const u8 * snd, u32 len);
|
||||||
//!Start sound playback
|
//!Start sound playback
|
||||||
void Play();
|
void Play();
|
||||||
//!Start sound playback
|
//!Start sound playback
|
||||||
void Play(int vol, bool restart = false);
|
void Play(int vol, bool restart = false);
|
||||||
//!Stop sound playback
|
//!Stop sound playback
|
||||||
void Stop();
|
void Stop();
|
||||||
//!Pause sound playback
|
//!Pause sound playback
|
||||||
void Pause();
|
void Pause();
|
||||||
//!Resume sound playback
|
//!Resume sound playback
|
||||||
void Resume();
|
void Resume();
|
||||||
//!Checks if a sound is currently loaded
|
//!Checks if a sound is currently loaded
|
||||||
//!\return true if sound is loaded, false otherwise
|
//!\return true if sound is loaded, false otherwise
|
||||||
bool IsLoaded() { return sound != NULL; };
|
bool IsLoaded() { return sound != NULL; };
|
||||||
//!Get the filepath for finding sounds which already have an instance.
|
//!Get the filepath for finding sounds which already have an instance.
|
||||||
//!\return the current instance's filepath
|
//!\return the current instance's filepath
|
||||||
std::string GetName() { return filepath; };
|
std::string GetName() { return filepath; };
|
||||||
//!Checks if the sound is currently playing
|
//!Checks if the sound is currently playing
|
||||||
//!\return true if sound is playing, false otherwise
|
//!\return true if sound is playing, false otherwise
|
||||||
bool IsPlaying();
|
bool IsPlaying();
|
||||||
//!Rewind the music
|
//!Rewind the music
|
||||||
void Rewind();
|
void Rewind();
|
||||||
//!Get sound volume
|
//!Get sound volume
|
||||||
//!\returns the current sound volume
|
//!\returns the current sound volume
|
||||||
int GetVolume();
|
int GetVolume();
|
||||||
//!Set sound volume
|
//!Set sound volume
|
||||||
//!\param v Sound volume (0-100)
|
//!\param v Sound volume (0-100)
|
||||||
void SetVolume(int v);
|
void SetVolume(int v);
|
||||||
//!\param l Loop (true to loop)
|
//!\param l Loop (true to loop)
|
||||||
void SetLoop(u8 l);
|
void SetLoop(u8 l);
|
||||||
private:
|
private:
|
||||||
//!Initializes the GuiSound object by setting the default values
|
//!Initializes the GuiSound object by setting the default values
|
||||||
void Init();
|
void Init();
|
||||||
//!Special sound case for sound.bin
|
//!Special sound case for sound.bin
|
||||||
void UncompressSoundbin(const u8 * snd, u32 len, bool isallocated);
|
void UncompressSoundbin(const u8 * snd, u32 len, bool isallocated);
|
||||||
protected:
|
protected:
|
||||||
std::string filepath;
|
std::string filepath;
|
||||||
u8 *sound; //!< Pointer to the sound data
|
u8 *sound; //!< Pointer to the sound data
|
||||||
u32 length; //!< Length of sound data
|
u32 length; //!< Length of sound data
|
||||||
s32 voice; //!< Currently assigned ASND voice channel
|
s32 voice; //!< Currently assigned ASND voice channel
|
||||||
int volume; //!< Sound volume (0-100)
|
int volume; //!< Sound volume (0-100)
|
||||||
u8 loop; //!< Loop sound playback
|
u8 loop; //!< Loop sound playback
|
||||||
u32 SoundEffectLength; //!< Check if it is an app soundeffect for faster playback
|
u32 SoundEffectLength; //!< Check if it is an app soundeffect for faster playback
|
||||||
bool allocated; //!< Is the file allocated or not
|
bool allocated; //!< Is the file allocated or not
|
||||||
};
|
};
|
||||||
|
|
||||||
void soundInit(void);
|
void soundInit(void);
|
||||||
|
@ -39,140 +39,96 @@
|
|||||||
|
|
||||||
ZipFile::ZipFile(const char *filepath)
|
ZipFile::ZipFile(const char *filepath)
|
||||||
{
|
{
|
||||||
File = unzOpen(filepath);
|
File = unzOpen(filepath);
|
||||||
if (File) this->LoadList();
|
if(File)
|
||||||
|
this->LoadList();
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipFile::~ZipFile()
|
ZipFile::~ZipFile()
|
||||||
{
|
{
|
||||||
unzClose(File);
|
unzClose(File);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZipFile::LoadList()
|
bool ZipFile::LoadList()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
/*
|
|
||||||
bool ZipFile::FindFile(const char *file)
|
|
||||||
{
|
|
||||||
if (!File) return false;
|
|
||||||
|
|
||||||
char filename[MAXPATHLEN];
|
|
||||||
|
|
||||||
int ret = unzGoToFirstFile(File);
|
|
||||||
if (ret != UNZ_OK) return false;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(unzGetCurrentFileInfo(File, &cur_file_info, filename, sizeof(filename), NULL, 0, NULL, 0) != UNZ_OK)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *realfilename = strrchr(filename, '/');
|
|
||||||
if(!realfilename || strlen(realfilename) == 0)
|
|
||||||
realfilename = filename;
|
|
||||||
|
|
||||||
if(strcasecmp(realfilename, file) == 0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
while(unzGoToNextFile(File) == UNZ_OK);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZipFile::FindFilePart(const char *partfilename, std::string &realname)
|
|
||||||
{
|
|
||||||
if (!File) return false;
|
|
||||||
|
|
||||||
char filename[MAXPATHLEN];
|
|
||||||
|
|
||||||
int ret = unzGoToFirstFile(File);
|
|
||||||
if (ret != UNZ_OK) return false;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(unzGetCurrentFileInfo(File, &cur_file_info, filename, sizeof(filename), NULL, 0, NULL, 0) != UNZ_OK)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(strcasestr(filename, partfilename) != 0)
|
|
||||||
{
|
|
||||||
realname = filename;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(unzGoToNextFile(File) == UNZ_OK);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
bool ZipFile::ExtractAll(const char *dest)
|
bool ZipFile::ExtractAll(const char *dest)
|
||||||
{
|
{
|
||||||
if (!File) return false;
|
if(!File)
|
||||||
|
return false;
|
||||||
|
|
||||||
bool Stop = false;
|
bool Stop = false;
|
||||||
|
|
||||||
u32 blocksize = 1024 * 50;
|
u32 blocksize = 1024 * 50;
|
||||||
u8 *buffer = new u8[blocksize];
|
u8 *buffer = new u8[blocksize];
|
||||||
|
|
||||||
if (!buffer) return false;
|
if(!buffer)
|
||||||
|
return false;
|
||||||
|
|
||||||
char writepath[MAXPATHLEN];
|
char writepath[MAXPATHLEN];
|
||||||
char filename[MAXPATHLEN];
|
char filename[MAXPATHLEN];
|
||||||
memset(filename, 0, sizeof(filename));
|
memset(filename, 0, sizeof(filename));
|
||||||
|
|
||||||
int ret = unzGoToFirstFile(File);
|
int ret = unzGoToFirstFile(File);
|
||||||
if (ret != UNZ_OK) Stop = true;
|
if(ret != UNZ_OK)
|
||||||
|
Stop = true;
|
||||||
|
|
||||||
while (!Stop)
|
while(!Stop)
|
||||||
{
|
{
|
||||||
if (unzGetCurrentFileInfo(File, &cur_file_info, filename, sizeof(filename), NULL, 0, NULL, 0) != UNZ_OK)
|
if(unzGetCurrentFileInfo(File, &cur_file_info, filename, sizeof(filename), NULL, 0, NULL, 0) != UNZ_OK)
|
||||||
Stop = true;
|
Stop = true;
|
||||||
|
|
||||||
if (!Stop && filename[strlen(filename) - 1] != '/')
|
if(!Stop && filename[strlen(filename) - 1] != '/')
|
||||||
{
|
{
|
||||||
u32 uncompressed_size = cur_file_info.uncompressed_size;
|
u32 uncompressed_size = cur_file_info.uncompressed_size;
|
||||||
|
|
||||||
u32 done = 0;
|
u32 done = 0;
|
||||||
char *pointer = NULL;
|
char *pointer = NULL;
|
||||||
|
|
||||||
ret = unzOpenCurrentFile(File);
|
ret = unzOpenCurrentFile(File);
|
||||||
|
|
||||||
snprintf(writepath, sizeof(writepath), "%s/%s", dest, filename);
|
snprintf(writepath, sizeof(writepath), "%s/%s", dest, filename);
|
||||||
|
|
||||||
pointer = strrchr(writepath, '/');
|
pointer = strrchr(writepath, '/');
|
||||||
int position = pointer - writepath + 2;
|
int position = pointer - writepath + 2;
|
||||||
|
|
||||||
char temppath[strlen(writepath)];
|
char temppath[strlen(writepath)];
|
||||||
snprintf(temppath, position, "%s", writepath);
|
snprintf(temppath, position, "%s", writepath);
|
||||||
|
|
||||||
fsop_MakeFolder(temppath);
|
fsop_MakeFolder(temppath);
|
||||||
|
|
||||||
if (ret == UNZ_OK)
|
if(ret == UNZ_OK)
|
||||||
{
|
{
|
||||||
FILE *pfile = fopen(writepath, "wb");
|
FILE *pfile = fopen(writepath, "wb");
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (uncompressed_size - done < blocksize) blocksize = uncompressed_size - done;
|
if(uncompressed_size - done < blocksize)
|
||||||
|
blocksize = uncompressed_size - done;
|
||||||
|
|
||||||
ret = unzReadCurrentFile(File, buffer, blocksize);
|
ret = unzReadCurrentFile(File, buffer, blocksize);
|
||||||
|
|
||||||
if (ret == 0) break;
|
if(ret == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
fwrite(buffer, 1, blocksize, pfile);
|
fwrite(buffer, 1, blocksize, pfile);
|
||||||
|
|
||||||
done += ret;
|
done += ret;
|
||||||
|
|
||||||
} while (done < uncompressed_size);
|
} while(done < uncompressed_size);
|
||||||
|
|
||||||
fclose(pfile);
|
fclose(pfile);
|
||||||
unzCloseCurrentFile(File);
|
unzCloseCurrentFile(File);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unzGoToNextFile(File) != UNZ_OK) Stop = true;
|
if(unzGoToNextFile(File) != UNZ_OK)
|
||||||
}
|
Stop = true;
|
||||||
|
}
|
||||||
|
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -32,27 +32,27 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
u64 offset; // ZipFile offset
|
u64 offset; // ZipFile offset
|
||||||
u64 length; // uncompressed file length in 64 bytes for sizes higher than 4GB
|
u64 length; // uncompressed file length in 64 bytes for sizes higher than 4GB
|
||||||
bool isdir; // 0 - file, 1 - directory
|
bool isdir; // 0 - file, 1 - directory
|
||||||
char filename[256]; // full filename
|
char filename[256]; // full filename
|
||||||
} FileStructure;
|
} FileStructure;
|
||||||
|
|
||||||
class ZipFile
|
class ZipFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//!Constructor
|
//!Constructor
|
||||||
ZipFile(const char *filepath);
|
ZipFile(const char *filepath);
|
||||||
//!Destructor
|
//!Destructor
|
||||||
~ZipFile();
|
~ZipFile();
|
||||||
//!Extract all files from a zip file to a directory
|
//!Extract all files from a zip file to a directory
|
||||||
//!\param dest Destination path to where to extract
|
//!\param dest Destination path to where to extract
|
||||||
bool ExtractAll(const char *dest);
|
bool ExtractAll(const char *dest);
|
||||||
protected:
|
protected:
|
||||||
bool LoadList();
|
bool LoadList();
|
||||||
unzFile File;
|
unzFile File;
|
||||||
unz_file_info cur_file_info;
|
unz_file_info cur_file_info;
|
||||||
FileStructure *FileList;
|
FileStructure *FileList;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user