diff options
Diffstat (limited to 'backends/platform/gp32/gp32std_file.cpp')
| -rw-r--r-- | backends/platform/gp32/gp32std_file.cpp | 146 | 
1 files changed, 107 insertions, 39 deletions
| diff --git a/backends/platform/gp32/gp32std_file.cpp b/backends/platform/gp32/gp32std_file.cpp index 0f4e16fc24..8544c8b794 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) { | 
