From 595a035bee92357850fba10ab9248b5364f2bf0f Mon Sep 17 00:00:00 2001 From: Won Star Date: Wed, 13 Sep 2006 07:32:54 +0000 Subject: [PATCH] Implement file cache. needs some testing :) Fix some bugs in memory management. svn-id: r23870 --- backends/platform/gp32/Makefile | 30 ++--- backends/platform/gp32/gp32_main.cpp | 1 + backends/platform/gp32/gp32std.cpp | 8 +- backends/platform/gp32/gp32std_file.cpp | 146 ++++++++++++++++------ backends/platform/gp32/gp32std_file.h | 1 + backends/platform/gp32/gp32std_memory.cpp | 14 +-- 6 files changed, 133 insertions(+), 67 deletions(-) diff --git a/backends/platform/gp32/Makefile b/backends/platform/gp32/Makefile index 67595961b08..e91a27f33f3 100644 --- a/backends/platform/gp32/Makefile +++ b/backends/platform/gp32/Makefile @@ -28,7 +28,7 @@ CFLAGS = -marm -march=armv4t -mtune=arm920 -mapcs \ -mno-thumb-interwork \ -I$(GPSDK)/include \ -g \ - -O \ + -O2 \ -fomit-frame-pointer # -ffast-math \ # -fshort-double @@ -92,9 +92,9 @@ DEFINES += -DDISABLE_FANCY_THEMES #LIBS += -Lbackends/platform/gp32/gpmad -lgpmad # Support libminilzo. -#DEFINES += -DUSE_MINILZO -#INCLUDES += -Ibackends/platform/gp32/minilzo -#LIBS += -Lbackends/platform/gp32/minilzo -lminilzo +DEFINES += -DUSE_MINILZO +INCLUDES += -Ibackends/platform/gp32/minilzo +LIBS += -Lbackends/platform/gp32/minilzo -lminilzo # Support for 8:3 save files names (The GP32 uses FAT12/16 (no vFAT) for the file system). DEFINES += -DSHORT_SAVENAMES @@ -159,19 +159,15 @@ DISABLE_HQ_SCALERS = 1 DISABLE_SCUMM_7_8 = 1 DISABLE_HE = 1 -# ??? -DISABLE_SIMON = 1 -DISABLE_SKY = 1 -DISABLE_QUEEN = 1 -DISABLE_GOB = 1 -DISABLE_LURE = 1 -DISABLE_CINE = 1 - -# In-development engines below. -# Disable for ALL release builds. -DISABLE_SAGA = 1 -DISABLE_KYRA = 1 -DISABLE_AGI = 1 +#DISABLE_SIMON = 1 +#DISABLE_SKY = 1 +#DISABLE_QUEEN = 1 +#DISABLE_GOB = 1 +#DISABLE_LURE = 1 +#DISABLE_CINE = 1 +#DISABLE_SAGA = 1 +#DISABLE_KYRA = 1 +#DISABLE_AGI = 1 # The engines below are not supported on the GP32 port so there is # no point compiling support into the binary. diff --git a/backends/platform/gp32/gp32_main.cpp b/backends/platform/gp32/gp32_main.cpp index 58be117c99f..5a6b7a3d22d 100644 --- a/backends/platform/gp32/gp32_main.cpp +++ b/backends/platform/gp32/gp32_main.cpp @@ -67,6 +67,7 @@ void GpMain(void *arg) { //doConfig gp_initGammaTable((float)g_vars.gammaRamp / 10000); gp_setCpuSpeed(g_vars.cpuSpeed); + GPDEBUG("Set CPU Speed: %d", g_vars.cpuSpeed); // FOR DEBUG PURPOSE! //int argc = 4; diff --git a/backends/platform/gp32/gp32std.cpp b/backends/platform/gp32/gp32std.cpp index ab6bfd64504..93b5ef17602 100644 --- a/backends/platform/gp32/gp32std.cpp +++ b/backends/platform/gp32/gp32std.cpp @@ -286,7 +286,7 @@ void GPDEBUG(const char *fmt, ...) { } void NP(const char *fmt, ...) { - return; +// return; char s[256]; va_list marker; @@ -299,7 +299,7 @@ void NP(const char *fmt, ...) { } void LP(const char *fmt, ...) { - return; +// return; char s[256]; va_list marker; @@ -312,7 +312,7 @@ void LP(const char *fmt, ...) { } void SP(const char *fmt, ...) { - return; +// return; char s[256]; va_list marker; @@ -325,7 +325,7 @@ void SP(const char *fmt, ...) { } void BP(const char *fmt, ...) { - return; +// return; char s[256]; va_list marker; diff --git a/backends/platform/gp32/gp32std_file.cpp b/backends/platform/gp32/gp32std_file.cpp index 0f4e16fc247..8544c8b794a 100644 --- a/backends/platform/gp32/gp32std_file.cpp +++ b/backends/platform/gp32/gp32std_file.cpp @@ -38,11 +38,49 @@ FILE *gp_stdout = NULL; FILE *gp_stdin = NULL; // Cache Idea / Code borrowed from the ps2 port -//#define USE_CACHE +#define USE_CACHE ////////////////// //File functions + +// CACHE +inline bool gp_cacheInPos(GPFILE *stream) +{ + return (stream->cachePos <= stream->filePos && stream->filePos < stream->cachePos + stream->bytesInCache); +} + +int gp_cacheMiss(GPFILE *stream) +{ + unsigned long readcount = 0; + + int copyLen = stream->fileSize - stream->filePos; + if (copyLen > FCACHE_SIZE) + copyLen = FCACHE_SIZE; + + stream->cachePos = stream->filePos; + stream->cacheBufOffs = 0; + stream->bytesInCache = copyLen; + + ERR_CODE err = GpFileRead(stream->handle, stream->cacheData, copyLen, &readcount); + + stream->physFilePos += copyLen; + + return err; +} + +int gp_flushWriteCache(GPFILE *stream) { + ERR_CODE err = GpFileWrite(stream->handle, stream->cacheData, stream->bytesInCache); // flush cache + + stream->filePos += stream->bytesInCache; + stream->physFilePos += stream->bytesInCache; + stream->bytesInCache = 0; + + return err; +} + +/////////////////////////////////////////////////////////////// + GPFILE *gp_fopen(const char *fileName, const char *openMode) { //FIXME: allocation, mode uint32 mode; @@ -88,6 +126,9 @@ GPFILE *gp_fopen(const char *fileName, const char *openMode) { file->mode = mode; file->cachePos = 0; + file->filePos = 0; + file->cacheBufOffs = 0; + file->physFilePos = 0; file->bytesInCache = 0; return file; @@ -106,9 +147,8 @@ int gp_fclose(GPFILE *stream) { */ #ifdef USE_CACHE - if (stream->cachePos && stream->mode == OPEN_W) { - GpFileWrite(stream->handle, (char *)stream->cacheData, stream->cachePos); // flush cache - stream->cachePos = 0; + if (stream->bytesInCache && stream->mode == OPEN_W) { + gp_flushWriteCache(stream); } #endif @@ -130,18 +170,38 @@ int gp_fseek(GPFILE *stream, long offset, int whence) { whence = FROM_END; break; } - return GpFileSeek(stream->handle, whence, offset, (long *)&stream->filePos); //FIXME? + + ERR_CODE err; +#ifdef USE_CACHE + // need to flush cache + if (stream->mode == OPEN_W) { // write + gp_flushWriteCache(stream); + err = GpFileSeek(stream->handle, whence, offset, (long *)&stream->filePos); + } else { // read + if (whence == SEEK_CUR) + offset += stream->physFilePos - stream->filePos; + + err = GpFileSeek(stream->handle, whence, offset, (long *)&stream->physFilePos); + stream->filePos = stream->physFilePos; + + if (gp_cacheInPos(stream)) { + } else { // cache miss + gp_cacheMiss(stream); + } + } +#endif + + return 1; + //return 0; //FIXME? } size_t gp_fread(void *ptr, size_t size, size_t n, GPFILE *stream) { - ulong readcount = 0; - int len = size * n; - -#ifdef USE_CACHE + unsigned int len = size * n; uint8 *dest = (uint8 *)ptr; - while (len && (stream->filePos != stream->fileSize)) { - if (stream->cachePos <= filePos && filePos < stream->cachePos + stream->bytesInCache) { +#ifdef USE_CACHE + while (len && !gp_feof(stream)) { + if (gp_cacheInPos(stream)) { uint32 startPos = (stream->cacheBufOffs + (stream->filePos - stream->cachePos)) % FCACHE_SIZE; uint32 copyLen = stream->bytesInCache - (stream->filePos - stream->cachePos); if (copyLen > len) @@ -149,26 +209,28 @@ size_t gp_fread(void *ptr, size_t size, size_t n, GPFILE *stream) { if (startPos + copyLen > FCACHE_SIZE) copyLen = FCACHE_SIZE - startPos; - memcpy(dest, cacheData + startPos, copyLen); + memcpy(dest, stream->cacheData + startPos, copyLen); - filePos += copyLen; + stream->filePos += copyLen; dest += copyLen; len -= copyLen; - } else { -#endif - ERR_CODE err = GpFileRead(stream->handle, ptr, len, &readcount); - -#ifdef USE_CACHE - stream->filePos += len; + } else { // cache miss or cache empty + gp_cacheMiss(stream); } } +#else + ulong readcount = 0; + ERR_CODE err = GpFileRead(stream->handle, ptr, len, &readcount); + stream->physFilePos += len; + stream->filePos += len; #endif - return readcount / size; //FIXME? + return 1; //readcount / size; //FIXME } size_t gp_fwrite(const void *ptr, size_t size, size_t n, GPFILE *stream) { int len = size * n; + uint8 *srcBuf = (uint8 *)ptr; if (!stream) { //warning("writing to null file"); @@ -176,31 +238,37 @@ size_t gp_fwrite(const void *ptr, size_t size, size_t n, GPFILE *stream) { } #ifdef USE_CACHE - if (stream->cachePos + len < FCACHE_SIZE) { - memcpy(stream->cacheData + stream->cachePos, ptr, len); - stream->cachePos += len; - } else { - if (stream->cachePos) { - GpFileWrite(stream->handle, stream->cacheData, stream->cachePos); // flush cache - stream->cachePos = 0; - } - -#endif - ERR_CODE err = GpFileWrite(stream->handle, ptr, len); - if (!err) - return n; + while (len) { + uint32 copyLen; + if (stream->bytesInCache + len > FCACHE_SIZE) + copyLen = FCACHE_SIZE - stream->bytesInCache; else - return -err; -#ifdef USE_CACHE + copyLen = len; + + srcBuf += copyLen; + len -= copyLen; + + if (stream->bytesInCache == FCACHE_SIZE) { + ERR_CODE err = GpFileWrite(stream->handle, stream->cacheData, stream->bytesInCache); // flush cache + stream->filePos += stream->bytesInCache; + stream->physFilePos += stream->bytesInCache; + stream->bytesInCache = 0; + } } +#else + ERR_CODE err = GpFileWrite(stream->handle, ptr, len); + if (!err) + return n; + else + return -err; #endif - return 0; + return 1; } -//FIXME? use standard func long gp_ftell(GPFILE *stream) { ulong pos = 0; - ERR_CODE err = GpFileSeek(stream->handle, FROM_CURRENT, 0, (long*)&pos); + pos = stream->filePos; + //ERR_CODE err = GpFileSeek(stream->handle, FROM_CURRENT, 0, (long*)&pos); return pos; } @@ -209,7 +277,7 @@ void gp_clearerr(GPFILE *stream) } int gp_feof(GPFILE *stream) { - return gp_ftell(stream) >= stream->fileSize; + return (unsigned long)gp_ftell(stream) >= stream->fileSize; } char gp_fgetc(GPFILE *stream) { diff --git a/backends/platform/gp32/gp32std_file.h b/backends/platform/gp32/gp32std_file.h index 933ae482ffb..37824682b1e 100644 --- a/backends/platform/gp32/gp32std_file.h +++ b/backends/platform/gp32/gp32std_file.h @@ -33,6 +33,7 @@ typedef struct { unsigned long mode; unsigned long fileSize; unsigned long filePos; + unsigned long physFilePos; unsigned long cachePos; unsigned long cacheBufOffs; unsigned long bytesInCache; diff --git a/backends/platform/gp32/gp32std_memory.cpp b/backends/platform/gp32/gp32std_memory.cpp index 10a831d1f0e..08a868e78f4 100644 --- a/backends/platform/gp32/gp32std_memory.cpp +++ b/backends/platform/gp32/gp32std_memory.cpp @@ -122,8 +122,10 @@ void *MemBlock::addBlock(size_t size) } blk++; } - if(i == prevBlock) - return NULL; + if(i == prevBlock) { + prevBlock = 0; + return gm_malloc(size); + } } byte *ptr = userMem + (i * USER_BLOCK_SIZE); @@ -139,11 +141,13 @@ void *MemBlock::addBlock(size_t size) void MemBlock::deleteBlock(void *dstBlock) { + // Faster method uint32 np = (uint32) dstBlock - (uint32) userMem; if ((np / USER_BLOCK_SIZE) * USER_BLOCK_SIZE != np) { gm_free(dstBlock); // warning("wrong block! (%d / %d)", (np / USER_BLOCK_SIZE) * USER_BLOCK_SIZE, np); + return; } int i = np / USER_BLOCK_SIZE; if (i > NUM_BLOCK) { @@ -201,10 +205,6 @@ void *gp_malloc(size_t size) { int allocSize = ALIGNED_SIZE(size) + sizeof(uint32) + sizeof(uint32); if (allocSize <= USER_BLOCK_SIZE) { np = (uint32) MemBlock::addBlock(allocSize); - if (!np) { -// GPDEBUG("falling back to gm_malloc"); - np = (uint32) gm_malloc(allocSize); - } } else { np = (uint32) gm_malloc(allocSize); } @@ -276,7 +276,7 @@ static char usedMemStr[16]; int gUsedMem = 1024 * 1024; //#define CLEAN_MEMORY_WITH_0xE7 -#define CHECK_USED_MEMORY +//#define CHECK_USED_MEMORY //#define CHECK_NEW_TIME //#define CHECK_NEW_SIZE