mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-27 13:44:15 +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';
|
||||
}
|
||||
|
||||
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 rtrim(std::string s);
|
||||
void Asciify( wchar_t *str );
|
||||
void Asciify2( char *str );
|
||||
|
||||
#endif // !defined(__TEXT_HPP)
|
||||
|
@ -81,11 +81,11 @@ struct gc_discHdr
|
||||
/* Magic word */
|
||||
u32 magic;
|
||||
|
||||
/* Padding */
|
||||
u8 unused2[4];
|
||||
|
||||
/* Game title */
|
||||
char title[124];
|
||||
char title[64];
|
||||
|
||||
/* Padding */
|
||||
u8 unused2[64];
|
||||
} ATTRIBUTE_PACKED;
|
||||
|
||||
#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 GB_SIZE 1073741824.0
|
||||
|
||||
#define READSIZE (32*1024)
|
||||
#define MAX_FAT_PATH 1024
|
||||
|
||||
/* Macros */
|
||||
#define round_up(x,n) (-(-(x) & -(n)))
|
||||
|
||||
|
@ -929,6 +929,7 @@ private:
|
||||
void _getGrabStatus(void);
|
||||
static void _addDiscProgress(int status, int total, void *user_data);
|
||||
static int _gameInstaller(void *obj);
|
||||
static int _GCgameInstaller(void *obj);
|
||||
wstringEx _optBoolToString(int b);
|
||||
void _stopSounds(void);
|
||||
//
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "menu.hpp"
|
||||
#include "loader/wbfs.h"
|
||||
#include "lockMutex.hpp"
|
||||
#include "loader/gc_disc.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -105,11 +106,63 @@ int CMenu::_gameInstaller(void *obj)
|
||||
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)
|
||||
{
|
||||
lwp_t thread = 0;
|
||||
static discHdr header ATTRIBUTE_ALIGN(32);
|
||||
static gc_discHdr gcheader ATTRIBUTE_ALIGN(32);
|
||||
bool done = false;
|
||||
bool upd_usb = false;
|
||||
bool upd_dml = false;
|
||||
bool out = false;
|
||||
bool del_cover = true;
|
||||
struct AutoLight { AutoLight(void) { } ~AutoLight(void) { slotLight(false); } } aw;
|
||||
@ -168,27 +221,43 @@ bool CMenu::_wbfsOp(CMenu::WBFS_OP op)
|
||||
out = true;
|
||||
break;
|
||||
}
|
||||
if (Disc_IsWii() < 0)
|
||||
if (Disc_IsWii() == 0)
|
||||
{
|
||||
error(_t("wbfsoperr3", L"This is not a Wii disc!"));
|
||||
out = true;
|
||||
break;
|
||||
}
|
||||
Disc_ReadHeader(&header);
|
||||
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;
|
||||
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;
|
||||
case CMenu::WO_REMOVE_GAME:
|
||||
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))
|
||||
{
|
||||
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();
|
||||
_initCF();
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "AifDecoder.hpp"
|
||||
#include "gecko.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -52,64 +51,64 @@ typedef struct
|
||||
# define HUGE_VAL HUGE
|
||||
#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)
|
||||
{
|
||||
double f;
|
||||
int expon;
|
||||
unsigned long hiMant, loMant;
|
||||
double f;
|
||||
int expon;
|
||||
unsigned long hiMant, loMant;
|
||||
|
||||
expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
|
||||
hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
|
||||
| ((unsigned long)(bytes[3] & 0xFF) << 16)
|
||||
| ((unsigned long)(bytes[4] & 0xFF) << 8)
|
||||
| ((unsigned long)(bytes[5] & 0xFF));
|
||||
loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
|
||||
| ((unsigned long)(bytes[7] & 0xFF) << 16)
|
||||
| ((unsigned long)(bytes[8] & 0xFF) << 8)
|
||||
| ((unsigned long)(bytes[9] & 0xFF));
|
||||
expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
|
||||
hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
|
||||
| ((unsigned long)(bytes[3] & 0xFF) << 16)
|
||||
| ((unsigned long)(bytes[4] & 0xFF) << 8)
|
||||
| ((unsigned long)(bytes[5] & 0xFF));
|
||||
loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
|
||||
| ((unsigned long)(bytes[7] & 0xFF) << 16)
|
||||
| ((unsigned long)(bytes[8] & 0xFF) << 8)
|
||||
| ((unsigned long)(bytes[9] & 0xFF));
|
||||
|
||||
if (expon == 0 && hiMant == 0 && loMant == 0) {
|
||||
f = 0;
|
||||
}
|
||||
else {
|
||||
if (expon == 0x7FFF) {
|
||||
f = HUGE_VAL;
|
||||
}
|
||||
else {
|
||||
expon -= 16383;
|
||||
f = ldexp(UnsignedToFloat(hiMant), expon-=31);
|
||||
f += ldexp(UnsignedToFloat(loMant), expon-=32);
|
||||
}
|
||||
}
|
||||
if (expon == 0 && hiMant == 0 && loMant == 0) {
|
||||
f = 0;
|
||||
}
|
||||
else {
|
||||
if (expon == 0x7FFF) {
|
||||
f = HUGE_VAL;
|
||||
}
|
||||
else {
|
||||
expon -= 16383;
|
||||
f = ldexp(UnsignedToFloat(hiMant), expon-=31);
|
||||
f += ldexp(UnsignedToFloat(loMant), expon-=32);
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes[0] & 0x80)
|
||||
return -f;
|
||||
else
|
||||
return f;
|
||||
if (bytes[0] & 0x80)
|
||||
return -f;
|
||||
else
|
||||
return f;
|
||||
}
|
||||
|
||||
AifDecoder::AifDecoder(const char * filepath)
|
||||
: SoundDecoder(filepath)
|
||||
: SoundDecoder(filepath)
|
||||
{
|
||||
SoundType = SOUND_AIF;
|
||||
SoundType = SOUND_AIF;
|
||||
|
||||
if(!file_fd)
|
||||
return;
|
||||
if(!file_fd)
|
||||
return;
|
||||
|
||||
OpenFile();
|
||||
OpenFile();
|
||||
}
|
||||
|
||||
AifDecoder::AifDecoder(const u8 * snd, int len)
|
||||
: SoundDecoder(snd, len)
|
||||
: SoundDecoder(snd, len)
|
||||
{
|
||||
SoundType = SOUND_AIF;
|
||||
SoundType = SOUND_AIF;
|
||||
|
||||
if(!file_fd)
|
||||
return;
|
||||
if(!file_fd)
|
||||
return;
|
||||
|
||||
OpenFile();
|
||||
OpenFile();
|
||||
}
|
||||
|
||||
AifDecoder::~AifDecoder()
|
||||
@ -118,8 +117,8 @@ AifDecoder::~AifDecoder()
|
||||
|
||||
void AifDecoder::OpenFile()
|
||||
{
|
||||
SWaveHdr Header;
|
||||
file_fd->read((u8 *) &Header, sizeof(SWaveHdr));
|
||||
SWaveHdr Header;
|
||||
file_fd->read((u8 *) &Header, sizeof(SWaveHdr));
|
||||
|
||||
if (Header.magicRIFF != 'FORM')
|
||||
{
|
||||
@ -131,34 +130,29 @@ void AifDecoder::OpenFile()
|
||||
CloseFile();
|
||||
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)
|
||||
{
|
||||
CloseFile();
|
||||
return;
|
||||
}
|
||||
|
||||
if(WaveChunk.magicDATA == 'COMM')
|
||||
|
||||
if(magic == 'COMM')
|
||||
break;
|
||||
|
||||
file_fd->seek(-sizeof(SWaveChunk)+1, SEEK_CUR);
|
||||
|
||||
limit++;
|
||||
|
||||
|
||||
else
|
||||
file_fd->seek(-3, SEEK_CUR);
|
||||
}
|
||||
|
||||
DataOffset = file_fd->tell()+WaveChunk.size;
|
||||
|
||||
SAIFFCommChunk CommHdr;
|
||||
file_fd->seek(file_fd->tell()-sizeof(SWaveChunk), SEEK_SET);
|
||||
file_fd->read((u8 *) &CommHdr, sizeof(SAIFFCommChunk));
|
||||
// seek back to COMM chunk start
|
||||
file_fd->seek(-sizeof(magic), SEEK_CUR);
|
||||
|
||||
SAIFFCommChunk CommHdr;
|
||||
file_fd->read((u8 *) &CommHdr, sizeof(SAIFFCommChunk));
|
||||
|
||||
if(CommHdr.fccCOMM != 'COMM')
|
||||
{
|
||||
@ -166,29 +160,37 @@ void AifDecoder::OpenFile()
|
||||
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;
|
||||
|
||||
limit = 0;
|
||||
int ret = -1;
|
||||
SWaveChunk chunkHdr;
|
||||
memset(&chunkHdr, 0, sizeof(SWaveChunk));
|
||||
|
||||
while(limit != 60)
|
||||
do
|
||||
{
|
||||
file_fd->read((u8 *) &SSndChunk, sizeof(SAIFFSSndChunk));
|
||||
|
||||
if(SSndChunk.fccSSND == 'SSND')
|
||||
break;
|
||||
// Seek to next chunk start
|
||||
file_fd->seek(chunkHdr.size, SEEK_CUR);
|
||||
ret = file_fd->read((u8 *) &chunkHdr, sizeof(SWaveChunk));
|
||||
}
|
||||
while(ret > 0 && chunkHdr.magicDATA != 'SSND');
|
||||
|
||||
file_fd->seek(-sizeof(SAIFFSSndChunk)+1, SEEK_CUR);
|
||||
DataOffset += 1;
|
||||
// Seek back to start of SSND chunk
|
||||
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;
|
||||
SampleRate = (u32) ConvertFromIeeeExtended(CommHdr.freq);
|
||||
Format = VOICE_STEREO_16BIT;
|
||||
Format = VOICE_STEREO_16BIT;
|
||||
|
||||
if(CommHdr.channels == 1 && CommHdr.bps == 8)
|
||||
Format = VOICE_MONO_8BIT;
|
||||
@ -199,35 +201,35 @@ void AifDecoder::OpenFile()
|
||||
else if (CommHdr.channels == 2 && CommHdr.bps == 16)
|
||||
Format = VOICE_STEREO_16BIT;
|
||||
|
||||
Decode();
|
||||
Decode();
|
||||
}
|
||||
|
||||
void AifDecoder::CloseFile()
|
||||
{
|
||||
if(file_fd)
|
||||
delete file_fd;
|
||||
if(file_fd)
|
||||
delete file_fd;
|
||||
|
||||
file_fd = NULL;
|
||||
file_fd = NULL;
|
||||
}
|
||||
|
||||
int AifDecoder::Read(u8 * buffer, int buffer_size, int)
|
||||
{
|
||||
if(!file_fd)
|
||||
return -1;
|
||||
if(!file_fd)
|
||||
return -1;
|
||||
|
||||
if(CurPos >= (int) DataSize)
|
||||
return 0;
|
||||
if(CurPos >= (int) DataSize)
|
||||
return 0;
|
||||
|
||||
file_fd->seek(DataOffset+CurPos, SEEK_SET);
|
||||
file_fd->seek(DataOffset+CurPos, SEEK_SET);
|
||||
|
||||
if(buffer_size > (int) DataSize-CurPos)
|
||||
buffer_size = DataSize-CurPos;
|
||||
if(buffer_size > (int) DataSize-CurPos)
|
||||
buffer_size = DataSize-CurPos;
|
||||
|
||||
int read = file_fd->read(buffer, buffer_size);
|
||||
if(read > 0)
|
||||
{
|
||||
CurPos += read;
|
||||
}
|
||||
int read = file_fd->read(buffer, buffer_size);
|
||||
if(read > 0)
|
||||
{
|
||||
CurPos += read;
|
||||
}
|
||||
|
||||
return read;
|
||||
return read;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user