mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2025-02-17 12:36:20 +01:00
* Added DML Ex GC disc dumper. This makes it possible to install GC discs and dump them straight into DML Ex format
* Fixed gc_discHdr struct * Updated aiff decoder to dimok's code (Thnx) Todo for GC disc dumper: * Add retry on read error * Add skip on read error pos * Add some more checks
This commit is contained in:
parent
6c6a57cab2
commit
d611849d6f
@ -480,3 +480,27 @@ void Asciify( wchar_t *str )
|
|||||||
}
|
}
|
||||||
*ctr = '\0';
|
*ctr = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Asciify2( char *str )
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
for( i=0; i < strlen(str); ++i )
|
||||||
|
{
|
||||||
|
if( str[i] < 0x20 || str[i] > 0x7F )
|
||||||
|
str[i] = '_';
|
||||||
|
else {
|
||||||
|
switch( str[i] )
|
||||||
|
{
|
||||||
|
case '*':
|
||||||
|
case '\"':
|
||||||
|
case ':':
|
||||||
|
case '|':
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
case '?':
|
||||||
|
str[i] = '_';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -67,5 +67,6 @@ std::string lowerCase(std::string text);
|
|||||||
std::string ltrim(std::string s);
|
std::string ltrim(std::string s);
|
||||||
std::string rtrim(std::string s);
|
std::string rtrim(std::string s);
|
||||||
void Asciify( wchar_t *str );
|
void Asciify( wchar_t *str );
|
||||||
|
void Asciify2( char *str );
|
||||||
|
|
||||||
#endif // !defined(__TEXT_HPP)
|
#endif // !defined(__TEXT_HPP)
|
||||||
|
@ -81,11 +81,11 @@ struct gc_discHdr
|
|||||||
/* Magic word */
|
/* Magic word */
|
||||||
u32 magic;
|
u32 magic;
|
||||||
|
|
||||||
/* Padding */
|
|
||||||
u8 unused2[4];
|
|
||||||
|
|
||||||
/* Game title */
|
/* Game title */
|
||||||
char title[124];
|
char title[64];
|
||||||
|
|
||||||
|
/* Padding */
|
||||||
|
u8 unused2[64];
|
||||||
} ATTRIBUTE_PACKED;
|
} ATTRIBUTE_PACKED;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
78
source/loader/gc_disc.cpp
Normal file
78
source/loader/gc_disc.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <ogcsys.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
|
#include "gc_disc.hpp"
|
||||||
|
#include "DeviceHandler.hpp"
|
||||||
|
#include "disc.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "wdvd.h"
|
||||||
|
#include "text.hpp"
|
||||||
|
|
||||||
|
s32 __DiscReadRaw(void *outbuf, u32 offset, u32 length)
|
||||||
|
{
|
||||||
|
return WDVD_UnencryptedRead(outbuf, length, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 GC_GameDumper(progress_callback_t spinner, void *spinner_data)
|
||||||
|
{
|
||||||
|
static gc_discHdr gcheader ATTRIBUTE_ALIGN(32);
|
||||||
|
|
||||||
|
FILE *f;
|
||||||
|
u8 *ReadBuffer = (u8 *)memalign(32, READSIZE);
|
||||||
|
u32 DiscSec = 0;
|
||||||
|
u32 ApploaderSize = 0;
|
||||||
|
char folder[MAX_FAT_PATH];
|
||||||
|
bzero(folder, MAX_FAT_PATH);
|
||||||
|
char gamepath[MAX_FAT_PATH];
|
||||||
|
bzero(gamepath, MAX_FAT_PATH);
|
||||||
|
|
||||||
|
Disc_ReadGCHeader(&gcheader);
|
||||||
|
Asciify2(gcheader.title);
|
||||||
|
|
||||||
|
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]", DeviceName[SD], gcheader.title, (char *)gcheader.id);
|
||||||
|
makedir((char *)folder);
|
||||||
|
|
||||||
|
snprintf(gamepath, sizeof(gamepath), "%s/game.iso", folder);
|
||||||
|
f = fopen(gamepath, "wb");
|
||||||
|
while( DiscSec < 0xAE0B )
|
||||||
|
{
|
||||||
|
__DiscReadRaw(ReadBuffer, DiscSec*READSIZE, READSIZE);
|
||||||
|
fwrite(ReadBuffer, 1, READSIZE, f);
|
||||||
|
spinner(DiscSec, 0xAE0B, spinner_data);
|
||||||
|
DiscSec++;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
snprintf(folder, sizeof(folder), "%s:/games/%s [%s]/sys", DeviceName[SD], gcheader.title, (char *)gcheader.id);
|
||||||
|
makedir((char *)folder);
|
||||||
|
snprintf(gamepath, sizeof(gamepath), "%s/boot.bin", folder);
|
||||||
|
__DiscReadRaw(ReadBuffer, 0, 0x440);
|
||||||
|
|
||||||
|
f = fopen(gamepath, "wb");
|
||||||
|
fwrite(ReadBuffer, 1, 0x440, f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
ApploaderSize = *(vu32*)(ReadBuffer+0x400);
|
||||||
|
|
||||||
|
snprintf(gamepath, sizeof(gamepath), "%s/bi2.bin", folder);
|
||||||
|
__DiscReadRaw(ReadBuffer, 0x440, 0x2000);
|
||||||
|
|
||||||
|
f = fopen(gamepath, "wb");
|
||||||
|
fwrite(ReadBuffer, 1, 0x2000, f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
snprintf(gamepath, sizeof(gamepath), "%s/apploader.img", folder);
|
||||||
|
__DiscReadRaw(ReadBuffer, 0x2440, ApploaderSize);
|
||||||
|
|
||||||
|
f = fopen(gamepath, "wb");
|
||||||
|
fwrite(ReadBuffer, 1, ApploaderSize, f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
free(ReadBuffer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
9
source/loader/gc_disc.hpp
Normal file
9
source/loader/gc_disc.hpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef GC_DISC_H_
|
||||||
|
#define GC_DISC_H_
|
||||||
|
|
||||||
|
typedef void (*progress_callback_t)(int status,int total,void *user_data);
|
||||||
|
|
||||||
|
s32 GC_GameDumper(progress_callback_t spinner, void *spinner_data);
|
||||||
|
s32 GC_DiskSpace(u64 *free);
|
||||||
|
|
||||||
|
#endif
|
@ -7,6 +7,9 @@
|
|||||||
#define MB_SIZE 1048576.0
|
#define MB_SIZE 1048576.0
|
||||||
#define GB_SIZE 1073741824.0
|
#define GB_SIZE 1073741824.0
|
||||||
|
|
||||||
|
#define READSIZE (32*1024)
|
||||||
|
#define MAX_FAT_PATH 1024
|
||||||
|
|
||||||
/* Macros */
|
/* Macros */
|
||||||
#define round_up(x,n) (-(-(x) & -(n)))
|
#define round_up(x,n) (-(-(x) & -(n)))
|
||||||
|
|
||||||
|
@ -929,6 +929,7 @@ private:
|
|||||||
void _getGrabStatus(void);
|
void _getGrabStatus(void);
|
||||||
static void _addDiscProgress(int status, int total, void *user_data);
|
static void _addDiscProgress(int status, int total, void *user_data);
|
||||||
static int _gameInstaller(void *obj);
|
static int _gameInstaller(void *obj);
|
||||||
|
static int _GCgameInstaller(void *obj);
|
||||||
wstringEx _optBoolToString(int b);
|
wstringEx _optBoolToString(int b);
|
||||||
void _stopSounds(void);
|
void _stopSounds(void);
|
||||||
//
|
//
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "menu.hpp"
|
#include "menu.hpp"
|
||||||
#include "loader/wbfs.h"
|
#include "loader/wbfs.h"
|
||||||
#include "lockMutex.hpp"
|
#include "lockMutex.hpp"
|
||||||
|
#include "loader/gc_disc.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -105,11 +106,63 @@ int CMenu::_gameInstaller(void *obj)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CMenu::_GCgameInstaller(void *obj)
|
||||||
|
{
|
||||||
|
CMenu &m = *(CMenu *)obj;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!DeviceHandler::Instance()->IsInserted(SD))
|
||||||
|
{
|
||||||
|
m.m_thrdWorking = false;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct statvfs stats;
|
||||||
|
memset(&stats, 0, sizeof(stats));
|
||||||
|
statvfs("sd:/" , &stats);
|
||||||
|
|
||||||
|
u64 free = (u64)stats.f_frsize * (u64)stats.f_bfree;
|
||||||
|
|
||||||
|
int blockfree = free/0x8000;
|
||||||
|
|
||||||
|
if (blockfree <= 44556)
|
||||||
|
{
|
||||||
|
LWP_MutexLock(m.m_mutex);
|
||||||
|
m._setThrdMsg(wfmt(m._fmt("wbfsop11", L"Not enough space : 44557 blocks needed, %d available"), blockfree), 0.f);
|
||||||
|
LWP_MutexUnlock(m.m_mutex);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
LWP_MutexLock(m.m_mutex);
|
||||||
|
m._setThrdMsg(L"", 0);
|
||||||
|
LWP_MutexUnlock(m.m_mutex);
|
||||||
|
|
||||||
|
ret=0;
|
||||||
|
|
||||||
|
ret = GC_GameDumper(CMenu::_addDiscProgress, obj);
|
||||||
|
LWP_MutexLock(m.m_mutex);
|
||||||
|
if (ret == 0)
|
||||||
|
m._setThrdMsg(m._t("wbfsop8", L"Game installed"), 1.f);
|
||||||
|
else
|
||||||
|
m._setThrdMsg(m._t("wbfsop9", L"An error has occurred"), 1.f);
|
||||||
|
LWP_MutexUnlock(m.m_mutex);
|
||||||
|
slotLight(true);
|
||||||
|
}
|
||||||
|
m.m_thrdWorking = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||||
{
|
{
|
||||||
lwp_t thread = 0;
|
lwp_t thread = 0;
|
||||||
static discHdr header ATTRIBUTE_ALIGN(32);
|
static discHdr header ATTRIBUTE_ALIGN(32);
|
||||||
|
static gc_discHdr gcheader ATTRIBUTE_ALIGN(32);
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
bool upd_usb = false;
|
||||||
|
bool upd_dml = false;
|
||||||
bool out = false;
|
bool out = false;
|
||||||
bool del_cover = true;
|
bool del_cover = true;
|
||||||
struct AutoLight { AutoLight(void) { } ~AutoLight(void) { slotLight(false); } } aw;
|
struct AutoLight { AutoLight(void) { } ~AutoLight(void) { slotLight(false); } } aw;
|
||||||
@ -168,27 +221,43 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
|||||||
out = true;
|
out = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (Disc_IsWii() < 0)
|
if (Disc_IsWii() == 0)
|
||||||
{
|
{
|
||||||
error(_t("wbfsoperr3", L"This is not a Wii disc!"));
|
Disc_ReadHeader(&header);
|
||||||
out = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Disc_ReadHeader(&header);
|
|
||||||
|
|
||||||
if (_searchGamesByID((const char *) header.id).size() != 0)
|
if (_searchGamesByID((const char *) header.id).size() != 0)
|
||||||
|
{
|
||||||
|
error(_t("wbfsoperr4", L"Game already installed"));
|
||||||
|
out = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cfPos = string((char *) header.id);
|
||||||
|
m_btnMgr.setText(m_wbfsLblDialog, wfmt(_fmt("wbfsop6", L"Installing [%s] %s..."), string((const char *)header.id, sizeof header.id).c_str(), string((const char *)header.title, sizeof header.title).c_str()));
|
||||||
|
done = true;
|
||||||
|
upd_usb = true;
|
||||||
|
m_thrdWorking = true;
|
||||||
|
m_thrdProgress = 0.f;
|
||||||
|
m_thrdMessageAdded = false;
|
||||||
|
LWP_CreateThread(&thread, (void *(*)(void *))CMenu::_gameInstaller, (void *)this, 0, 8 * 1024, 64);
|
||||||
|
}
|
||||||
|
else if(Disc_IsGC() == 0)
|
||||||
{
|
{
|
||||||
error(_t("wbfsoperr4", L"Game already installed"));
|
Disc_ReadGCHeader(&gcheader);
|
||||||
|
cfPos = string((char *) gcheader.id);
|
||||||
|
m_btnMgr.setText(m_wbfsLblDialog, wfmt(_fmt("wbfsop6", L"Installing [%s] %s..."), string((const char *)gcheader.id, sizeof gcheader.id).c_str(), string((const char *)gcheader.title, sizeof gcheader.title).c_str()));
|
||||||
|
done = true;
|
||||||
|
upd_dml = true;
|
||||||
|
m_thrdWorking = true;
|
||||||
|
m_thrdProgress = 0.f;
|
||||||
|
m_thrdMessageAdded = false;
|
||||||
|
LWP_CreateThread(&thread, (void *(*)(void *))CMenu::_GCgameInstaller, (void *)this, 0, 8 * 1024, 64);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error(_t("wbfsoperr3", L"This is not a Wii or GC disc!"));
|
||||||
out = true;
|
out = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cfPos = string((char *) header.id);
|
|
||||||
m_btnMgr.setText(m_wbfsLblDialog, wfmt(_fmt("wbfsop6", L"Installing [%s] %s..."), string((const char *)header.id, sizeof header.id).c_str(), string((const char *)header.title, sizeof header.title).c_str()));
|
|
||||||
done = true;
|
|
||||||
m_thrdWorking = true;
|
|
||||||
m_thrdProgress = 0.f;
|
|
||||||
m_thrdMessageAdded = false;
|
|
||||||
LWP_CreateThread(&thread, (void *(*)(void *))CMenu::_gameInstaller, (void *)this, 0, 8 * 1024, 64);
|
|
||||||
break;
|
break;
|
||||||
case CMenu::WO_REMOVE_GAME:
|
case CMenu::WO_REMOVE_GAME:
|
||||||
WBFS_RemoveGame((u8 *)m_cf.getId().c_str(), (char *) m_cf.getHdr()->path);
|
WBFS_RemoveGame((u8 *)m_cf.getId().c_str(), (char *) m_cf.getHdr()->path);
|
||||||
@ -228,7 +297,11 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
|||||||
if (done && (op == CMenu::WO_REMOVE_GAME || op == CMenu::WO_ADD_GAME))
|
if (done && (op == CMenu::WO_REMOVE_GAME || op == CMenu::WO_ADD_GAME))
|
||||||
{
|
{
|
||||||
m_gameList.SetLanguage(m_loc.getString(m_curLanguage, "gametdb_code", "EN").c_str());
|
m_gameList.SetLanguage(m_loc.getString(m_curLanguage, "gametdb_code", "EN").c_str());
|
||||||
UpdateCache(COVERFLOW_USB);
|
if( upd_dml )
|
||||||
|
UpdateCache(COVERFLOW_DML);
|
||||||
|
|
||||||
|
if( upd_usb )
|
||||||
|
UpdateCache(COVERFLOW_USB);
|
||||||
|
|
||||||
_loadList();
|
_loadList();
|
||||||
_initCF();
|
_initCF();
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "AifDecoder.hpp"
|
#include "AifDecoder.hpp"
|
||||||
#include "gecko.h"
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -52,64 +51,64 @@ typedef struct
|
|||||||
# define HUGE_VAL HUGE
|
# define HUGE_VAL HUGE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# 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 unsigned char* bytes)
|
||||||
{
|
{
|
||||||
double f;
|
double f;
|
||||||
int expon;
|
int expon;
|
||||||
unsigned long hiMant, loMant;
|
unsigned long 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)
|
hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
|
||||||
| ((unsigned long)(bytes[3] & 0xFF) << 16)
|
| ((unsigned long)(bytes[3] & 0xFF) << 16)
|
||||||
| ((unsigned long)(bytes[4] & 0xFF) << 8)
|
| ((unsigned long)(bytes[4] & 0xFF) << 8)
|
||||||
| ((unsigned long)(bytes[5] & 0xFF));
|
| ((unsigned long)(bytes[5] & 0xFF));
|
||||||
loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
|
loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
|
||||||
| ((unsigned long)(bytes[7] & 0xFF) << 16)
|
| ((unsigned long)(bytes[7] & 0xFF) << 16)
|
||||||
| ((unsigned long)(bytes[8] & 0xFF) << 8)
|
| ((unsigned long)(bytes[8] & 0xFF) << 8)
|
||||||
| ((unsigned long)(bytes[9] & 0xFF));
|
| ((unsigned long)(bytes[9] & 0xFF));
|
||||||
|
|
||||||
if (expon == 0 && hiMant == 0 && loMant == 0) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
AifDecoder::AifDecoder(const char * filepath)
|
AifDecoder::AifDecoder(const char * filepath)
|
||||||
: SoundDecoder(filepath)
|
: SoundDecoder(filepath)
|
||||||
{
|
{
|
||||||
SoundType = SOUND_AIF;
|
SoundType = SOUND_AIF;
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
AifDecoder::AifDecoder(const u8 * snd, int len)
|
AifDecoder::AifDecoder(const u8 * snd, int len)
|
||||||
: SoundDecoder(snd, len)
|
: SoundDecoder(snd, len)
|
||||||
{
|
{
|
||||||
SoundType = SOUND_AIF;
|
SoundType = SOUND_AIF;
|
||||||
|
|
||||||
if(!file_fd)
|
if(!file_fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OpenFile();
|
OpenFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
AifDecoder::~AifDecoder()
|
AifDecoder::~AifDecoder()
|
||||||
@ -118,8 +117,8 @@ AifDecoder::~AifDecoder()
|
|||||||
|
|
||||||
void AifDecoder::OpenFile()
|
void AifDecoder::OpenFile()
|
||||||
{
|
{
|
||||||
SWaveHdr Header;
|
SWaveHdr Header;
|
||||||
file_fd->read((u8 *) &Header, sizeof(SWaveHdr));
|
file_fd->read((u8 *) &Header, sizeof(SWaveHdr));
|
||||||
|
|
||||||
if (Header.magicRIFF != 'FORM')
|
if (Header.magicRIFF != 'FORM')
|
||||||
{
|
{
|
||||||
@ -131,34 +130,29 @@ void AifDecoder::OpenFile()
|
|||||||
CloseFile();
|
CloseFile();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWaveChunk WaveChunk;
|
|
||||||
u32 limit = 0;
|
|
||||||
|
|
||||||
while(limit != 60)
|
u32 magic = 0;
|
||||||
|
|
||||||
|
while(1)
|
||||||
{
|
{
|
||||||
int ret = file_fd->read((u8 *) &WaveChunk, sizeof(SWaveChunk));
|
int ret = file_fd->read((u8 *) &magic, sizeof(magic));
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{
|
{
|
||||||
CloseFile();
|
CloseFile();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(WaveChunk.magicDATA == 'COMM')
|
if(magic == 'COMM')
|
||||||
break;
|
break;
|
||||||
|
else
|
||||||
file_fd->seek(-sizeof(SWaveChunk)+1, SEEK_CUR);
|
file_fd->seek(-3, SEEK_CUR);
|
||||||
|
|
||||||
limit++;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataOffset = file_fd->tell()+WaveChunk.size;
|
|
||||||
|
|
||||||
SAIFFCommChunk CommHdr;
|
// seek back to COMM chunk start
|
||||||
file_fd->seek(file_fd->tell()-sizeof(SWaveChunk), SEEK_SET);
|
file_fd->seek(-sizeof(magic), SEEK_CUR);
|
||||||
file_fd->read((u8 *) &CommHdr, sizeof(SAIFFCommChunk));
|
|
||||||
|
SAIFFCommChunk CommHdr;
|
||||||
|
file_fd->read((u8 *) &CommHdr, sizeof(SAIFFCommChunk));
|
||||||
|
|
||||||
if(CommHdr.fccCOMM != 'COMM')
|
if(CommHdr.fccCOMM != 'COMM')
|
||||||
{
|
{
|
||||||
@ -166,29 +160,37 @@ void AifDecoder::OpenFile()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_fd->seek(DataOffset, SEEK_SET);
|
// Seek to next chunk start
|
||||||
|
file_fd->seek(-sizeof(SAIFFCommChunk) + sizeof(SWaveChunk) + CommHdr.size, SEEK_CUR);
|
||||||
|
|
||||||
SAIFFSSndChunk SSndChunk;
|
int ret = -1;
|
||||||
|
SWaveChunk chunkHdr;
|
||||||
limit = 0;
|
memset(&chunkHdr, 0, sizeof(SWaveChunk));
|
||||||
|
|
||||||
while(limit != 60)
|
do
|
||||||
{
|
{
|
||||||
file_fd->read((u8 *) &SSndChunk, sizeof(SAIFFSSndChunk));
|
// Seek to next chunk start
|
||||||
|
file_fd->seek(chunkHdr.size, SEEK_CUR);
|
||||||
if(SSndChunk.fccSSND == 'SSND')
|
ret = file_fd->read((u8 *) &chunkHdr, sizeof(SWaveChunk));
|
||||||
break;
|
}
|
||||||
|
while(ret > 0 && chunkHdr.magicDATA != 'SSND');
|
||||||
|
|
||||||
file_fd->seek(-sizeof(SAIFFSSndChunk)+1, SEEK_CUR);
|
// Seek back to start of SSND chunk
|
||||||
DataOffset += 1;
|
file_fd->seek(-sizeof(SWaveChunk), SEEK_CUR);
|
||||||
|
|
||||||
limit++;
|
SAIFFSSndChunk SSndChunk;
|
||||||
|
file_fd->read((u8 *) &SSndChunk, sizeof(SAIFFSSndChunk));
|
||||||
|
|
||||||
|
if(SSndChunk.fccSSND != 'SSND')
|
||||||
|
{
|
||||||
|
CloseFile();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataOffset += sizeof(SAIFFSSndChunk);
|
DataOffset = file_fd->tell();
|
||||||
DataSize = SSndChunk.size-8;
|
DataSize = SSndChunk.size-8;
|
||||||
SampleRate = (u32) ConvertFromIeeeExtended(CommHdr.freq);
|
SampleRate = (u32) ConvertFromIeeeExtended(CommHdr.freq);
|
||||||
Format = VOICE_STEREO_16BIT;
|
Format = VOICE_STEREO_16BIT;
|
||||||
|
|
||||||
if(CommHdr.channels == 1 && CommHdr.bps == 8)
|
if(CommHdr.channels == 1 && CommHdr.bps == 8)
|
||||||
Format = VOICE_MONO_8BIT;
|
Format = VOICE_MONO_8BIT;
|
||||||
@ -199,35 +201,35 @@ void AifDecoder::OpenFile()
|
|||||||
else if (CommHdr.channels == 2 && CommHdr.bps == 16)
|
else if (CommHdr.channels == 2 && CommHdr.bps == 16)
|
||||||
Format = VOICE_STEREO_16BIT;
|
Format = VOICE_STEREO_16BIT;
|
||||||
|
|
||||||
Decode();
|
Decode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AifDecoder::CloseFile()
|
void AifDecoder::CloseFile()
|
||||||
{
|
{
|
||||||
if(file_fd)
|
if(file_fd)
|
||||||
delete file_fd;
|
delete file_fd;
|
||||||
|
|
||||||
file_fd = NULL;
|
file_fd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AifDecoder::Read(u8 * buffer, int buffer_size, int)
|
int AifDecoder::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)
|
||||||
{
|
{
|
||||||
CurPos += read;
|
CurPos += read;
|
||||||
}
|
}
|
||||||
|
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user