From 9d831d8b8b647f0e7a84cd0ebb4baea4ba22f596 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Aug 2022 04:31:34 -0400 Subject: ok, I realized we need to realloc buffers allocated by FCEU_malloc (why didn't I guess that..) which makes the fact that they're aligned be horrible. so I added FCEU_amalloc and FCEU_afree instead to do aligned allocs and frees. --- src/utils/memory.cpp | 62 ++++++++++++++++++++++++++++++++-------------------- src/utils/memory.h | 20 ++++++++++++----- src/video.cpp | 16 +++++++------- 3 files changed, 61 insertions(+), 37 deletions(-) diff --git a/src/utils/memory.cpp b/src/utils/memory.cpp index 93bc3af9..fa5d65b4 100644 --- a/src/utils/memory.cpp +++ b/src/utils/memory.cpp @@ -28,18 +28,34 @@ #include "../fceu.h" #include "memory.h" +void *FCEU_amalloc(size_t size, size_t alignment) +{ + size = (size + alignment - 1) & ~(alignment-1); + + #ifdef _MSC_VER + void *ret = _aligned_malloc(size,alignment); + #else + void *ret = aligned_alloc(alignment,size); + #endif + + if(!ret) + FCEU_abort("Error allocating memory!"); + + return ret; +} + +void FCEU_afree(void* ptr) +{ + #ifdef _MSC_VER + _aligned_free(ptr); + #else + free(ptr); + #endif +} + static void *_FCEU_malloc(uint32 size) { - //do not add an aligned allocation function. if a larger alignment is needed, change this constant to use it for all allocations. - static const int alignment = 32; - - size = (size + alignment - 1) & ~(alignment-1); - - #ifdef _MSC_VER - void *ret = _aligned_malloc(size,alignment); - #else - void *ret = aligned_alloc(alignment,size); - #endif + void* ret = malloc(size); if(!ret) FCEU_abort("Error allocating memory!"); @@ -49,22 +65,17 @@ static void *_FCEU_malloc(uint32 size) static void _FCEU_free(void* ptr) { - #ifdef _MSC_VER - _aligned_free(ptr); - #else free(ptr); - #endif } -///allocates the specified number of bytes. exits process if this fails void *FCEU_gmalloc(uint32 size) { - void *ret = _FCEU_malloc(size); + void *ret = _FCEU_malloc(size); - // initialize according to RAMInitOption, default zero - FCEU_MemoryRand((uint8*)ret,size,true); + // initialize according to RAMInitOption, default zero + FCEU_MemoryRand((uint8*)ret,size,true); - return ret; + return ret; } void *FCEU_malloc(uint32 size) @@ -74,13 +85,11 @@ void *FCEU_malloc(uint32 size) return ret; } -//frees memory allocated with FCEU_gmalloc void FCEU_gfree(void *ptr) { _FCEU_free(ptr); } -//frees memory allocated with FCEU_malloc void FCEU_free(void *ptr) { _FCEU_free(ptr); @@ -96,8 +105,13 @@ void FCEU_dfree(void *ptr) return FCEU_free(ptr); } -void FCEU_abort(const char* message) -{ +void* FCEU_realloc(void* ptr, size_t size) +{ + return realloc(ptr,size); +} + +void FCEU_abort(const char* message) +{ if(message) FCEU_PrintError(message); abort(); -} +} diff --git a/src/utils/memory.h b/src/utils/memory.h index b9e6f145..4fd97d9d 100644 --- a/src/utils/memory.h +++ b/src/utils/memory.h @@ -24,19 +24,29 @@ #define FCEU_dwmemset(d,c,n) {int _x; for(_x=n-4;_x>=0;_x-=4) *(uint32 *)&(d)[_x]=c;} -//returns a 32-aligned buffer, initialized to 0 -void *FCEU_malloc(uint32 size); +//returns a buffer initialized to 0 +void *FCEU_malloc(uint32 size); -//returns a 32-aligned buffer, with jumbled initial contents +//returns a buffer, with jumbled initial contents //used by boards for WRAM etc, initialized to 0 (default) or other via RAMInitOption -void *FCEU_gmalloc(uint32 size); +void *FCEU_gmalloc(uint32 size); //free memory allocated with FCEU_gmalloc void FCEU_gfree(void *ptr); -//free memory allocated with +//returns an aligned buffer, initialized to 0 +//the alignment will default to the largest thing you could ever sensibly want for massively aligned cache friendly buffers +void *FCEU_amalloc(size_t size, size_t alignment = 256); + +//frees memory allocated with FCEU_amalloc +void FCEU_afree(void* ptr); + +//free memory allocated with FCEU_malloc void FCEU_free(void *ptr); +//reallocate memory allocated with FCEU_malloc +void* FCEU_realloc(void* ptr, size_t size); + //don't use these. change them if you find them. void *FCEU_dmalloc(uint32 size); diff --git a/src/video.cpp b/src/video.cpp index cbad58fc..20a48e76 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -91,19 +91,19 @@ void FCEU_KillVirtualVideo(void) { if ( XBuf ) { - FCEU_free(XBuf); XBuf = NULL; + FCEU_afree(XBuf); XBuf = NULL; } if ( XBackBuf ) { - FCEU_free(XBackBuf); XBackBuf = NULL; + FCEU_afree(XBackBuf); XBackBuf = NULL; } if ( XDBuf ) { - FCEU_free(XDBuf); XDBuf = NULL; + FCEU_afree(XDBuf); XDBuf = NULL; } if ( XDBackBuf ) { - FCEU_free(XDBackBuf); XDBackBuf = NULL; + FCEU_afree(XDBackBuf); XDBackBuf = NULL; } //printf("Video Core Cleanup\n"); } @@ -120,10 +120,10 @@ int FCEU_InitVirtualVideo(void) if(XBuf) return 1; - XBuf = (u8*)FCEU_malloc(256 * 256); - XBackBuf = (u8*)FCEU_malloc(256 * 256); - XDBuf = (u8*)FCEU_malloc(256 * 256); - XDBackBuf = (u8*)FCEU_malloc(256 * 256); + XBuf = (u8*)FCEU_amalloc(256 * 256); + XBackBuf = (u8*)FCEU_amalloc(256 * 256); + XDBuf = (u8*)FCEU_amalloc(256 * 256); + XDBackBuf = (u8*)FCEU_amalloc(256 * 256); xbsave = XBuf; -- cgit v1.2.3 From 20d03d4434ca2a473dcb33e61ce6a3da4fddcc19 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Aug 2022 04:32:23 -0400 Subject: minimum framework to support loading ips files on top of already loaded roms --- src/fceu.cpp | 2 +- src/file.cpp | 20 ++++---------------- src/ines.cpp | 1 + src/ines.h | 1 + 4 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/fceu.cpp b/src/fceu.cpp index 83b8c223..28396c34 100644 --- a/src/fceu.cpp +++ b/src/fceu.cpp @@ -431,7 +431,7 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen // currently there's only one situation: // the user clicked cancel form the open from archive dialog int userCancel = 0; - fp = FCEU_fopen(name, 0, "rb", 0, -1, romextensions, &userCancel); + fp = FCEU_fopen(name, LoadedRomFNamePatchToUse[0] ? LoadedRomFNamePatchToUse : nullptr, "rb", 0, -1, romextensions, &userCancel); if (!fp) { diff --git a/src/file.cpp b/src/file.cpp index c927be7b..90d024da 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -69,7 +69,7 @@ void ApplyIPS(FILE *ips, FCEUFILE* fp) if(!ips) return; - char* buf = (char*)FCEU_dmalloc(fp->size); + char* buf = (char*)FCEU_malloc(fp->size); memcpy(buf,fp->EnsureMemorystream()->buf(),fp->size); @@ -108,13 +108,7 @@ void ApplyIPS(FILE *ips, FCEUFILE* fp) if((offset+size)>(uint32)fp->size) { // Probably a little slow. - char *newbuf=(char *)realloc(buf,offset+size); - if(!newbuf) - { - free(buf); buf=NULL; - FCEU_printf(" Oops. IPS patch %d(type RLE) goes beyond end of file. Could not allocate memory.\n",count); - goto end; - } + char *newbuf=(char *)FCEU_realloc(buf,offset+size); buf=newbuf; memset(buf+fp->size,0,offset+size-fp->size); fp->size=offset+size; @@ -133,13 +127,7 @@ void ApplyIPS(FILE *ips, FCEUFILE* fp) if((offset+size)>(uint32)fp->size) { // Probably a little slow. - char *newbuf=(char *)realloc(buf,offset+size); - if(!newbuf) - { - free(buf); buf=NULL; - FCEU_printf(" Oops. IPS patch %d(type normal) goes beyond end of file. Could not allocate memory.\n",count); - goto end; - } + char *newbuf=(char *)FCEU_realloc(buf,offset+size); buf=newbuf; memset(buf+fp->size,0,offset+size-fp->size); } @@ -495,7 +483,7 @@ void FCEUI_SetDirOverride(int which, char *n) va_list ap; int ret; - if(!(*strp=(char*)FCEU_dmalloc(2048))) //mbg merge 7/17/06 cast to char* + if(!(*strp=(char*)FCEU_malloc(2048))) //mbg merge 7/17/06 cast to char* return(0); va_start(ap,fmt); ret=vsnprintf(*strp,2048,fmt,ap); diff --git a/src/ines.cpp b/src/ines.cpp index 6766a558..92fa0bdf 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -58,6 +58,7 @@ uint8 MirroringAs2bits = 0; uint32 ROM_size = 0; uint32 VROM_size = 0; char LoadedRomFName[2048]; //mbg merge 7/17/06 added +char LoadedRomFNamePatchToUse[2048]; static int CHRRAMSize = -1; static int iNES_Init(int num); diff --git a/src/ines.h b/src/ines.h index 315e54f0..267ab963 100644 --- a/src/ines.h +++ b/src/ines.h @@ -47,6 +47,7 @@ extern uint8 **VPageR; extern int iNesSave(void); //bbit Edited: line added extern int iNesSaveAs(const char* name); extern char LoadedRomFName[2048]; //bbit Edited: line added +extern char LoadedRomFNamePatchToUse[2048]; extern char *iNesShortFName(void); extern const TMasterRomInfo* MasterRomInfo; extern TMasterRomInfoParams MasterRomInfoParams; -- cgit v1.2.3 From 60f7b875f80958248e7def8f200efd4ba60dd003 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Aug 2022 04:33:38 -0400 Subject: winport - support loading ips files on top of already loaded roms. I guess this could be factored to an FCEUI_TestFileIsPatch and an FCEUI_ReloadWithPatch?? well, that's for whoever does this on other platforms to do. --- src/drivers/win/window.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index 3effd90d..82c845b5 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -38,6 +38,9 @@ #include "video.h" #include "input.h" #include "fceu.h" +#include "types.h" +#include "cart.h" +#include "ines.h" #include "cheat.h" #include "ram_search.h" @@ -1075,6 +1078,37 @@ void CloseGame() bool ALoad(const char *nameo, char* innerFilename, bool silent) { + FCEUFILE* patchTrial = FCEU_fopen(nameo,nullptr,"rb",nullptr,-1); + if(patchTrial) + { + char sig[10] = {0}; + FCEU_fread(sig,1,5,patchTrial); + FCEU_fclose(patchTrial); + if(!strcmp(sig,"PATCH")) + { + //assuming it's a patch: + + //if nothing's loaded, we can't load this + if(!LoadedRomFName[0]) + return false; + + //ok, set this as a patch and load it + //use a temp std::string to avoid problems copying from LoadedRomFName, to LoadedRomFName + //pass nullptr as innerFilename -- see, it's not used here anyway + strcpy(LoadedRomFNamePatchToUse,nameo); + std::string tmp_LoadedRomFName = LoadedRomFName; + bool ret = ALoad(tmp_LoadedRomFName.c_str(),nullptr,silent); + + //clear the patch file. FCEUX doesn't seem to ever reload the roms (?) so it can't need to reuse it + //and if it does.. well.. it won't be patched. + //there's only so much we can do with this old framework + LoadedRomFNamePatchToUse[0] = 0; + + return ret; + } + } + + int oldPaused = EmulationPaused; // loading is not started yet, so the game can continue; -- cgit v1.2.3 From 069727c191ff76f799abff83c62681e59747a496 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Aug 2022 04:41:45 -0400 Subject: fix a bug in applying some IPS files --- src/file.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/file.cpp b/src/file.cpp index 90d024da..e4d5b4f6 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -130,6 +130,7 @@ void ApplyIPS(FILE *ips, FCEUFILE* fp) char *newbuf=(char *)FCEU_realloc(buf,offset+size); buf=newbuf; memset(buf+fp->size,0,offset+size-fp->size); + fp->size=offset+size; } fread(buf+offset,1,size,ips); } -- cgit v1.2.3 From 6b0d1a52ca78a53bd8d721ac50bd2d51a0be5152 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Aug 2022 17:14:55 -0400 Subject: winport - apply ROM file pasting as a single undoable action using the multi-byte capability already in ApplyPatch. Fixes #394 --- src/drivers/win/memview.cpp | 78 ++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/src/drivers/win/memview.cpp b/src/drivers/win/memview.cpp index 2ad44edf..70b8b704 100644 --- a/src/drivers/win/memview.cpp +++ b/src/drivers/win/memview.cpp @@ -960,14 +960,14 @@ void FreezeRam(int address, int mode, int final){ //input is expected to be an ASCII string void InputData(char *input){ //CursorEndAddy = -1; - int addr, i, j, datasize = 0; + int addr, datasize = 0; unsigned char *data; char inputc; //char str[100]; //mbg merge 7/18/06 added cast: data = (uint8 *)malloc(strlen(input) + 1); //it can't be larger than the input string, so use that as the size - for(i = 0;input[i] != 0;i++){ + for(int i = 0;input[i] != 0;i++){ if(!EditingText){ inputc = -1; if((input[i] >= 'a') && (input[i] <= 'f')) inputc = input[i]-('a'-0xA); @@ -983,9 +983,15 @@ void InputData(char *input){ { TempData = inputc; } - } else { - for(j = 0;j < 256;j++)if(chartable[j] == input[i])break; - if(j == 256)continue; + } + else + { + int j; + for(j = 0; j < 256; j++) + if(chartable[j] == input[i]) + break; + if(j == 256) + continue; data[datasize++] = j; } } @@ -1003,35 +1009,43 @@ void InputData(char *input){ //sprintf(str,"datasize = %d",datasize); //MessageBox(hMemView,str, "debug", MB_OK); - for(i = 0;i < datasize;i++){ - addr = CursorStartAddy+i; + if(EditingMode == MODE_NES_FILE) + { + ApplyPatch(CursorStartAddy, datasize, data); + } + else + { + for(int i = 0;i < datasize;i++) + { + addr = CursorStartAddy+i; - if (addr >= MaxSize) continue; + if (addr >= MaxSize) continue; - switch(EditingMode) - { - case MODE_NES_MEMORY: - // RAM (system bus) - BWrite[addr](addr, data[i]); - break; - case MODE_NES_PPU: - // PPU - addr &= 0x3FFF; - if (addr < 0x2000) - VPage[addr >> 10][addr] = data[i]; //todo: detect if this is vrom and turn it red if so - if ((addr >= 0x2000) && (addr < 0x3F00)) - vnapage[(addr >> 10) & 0x3][addr & 0x3FF] = data[i]; //todo: this causes 0x3000-0x3f00 to mirror 0x2000-0x2f00, is this correct? - if ((addr >= 0x3F00) && (addr < 0x3FFF)) - PalettePoke(addr, data[i]); - break; - case MODE_NES_OAM: - addr &= 0xFF; - SPRAM[addr] = data[i]; - break; - case MODE_NES_FILE: - // ROM - ApplyPatch(addr, 1, &data[i]); - break; + switch(EditingMode) + { + case MODE_NES_MEMORY: + // RAM (system bus) + BWrite[addr](addr, data[i]); + break; + case MODE_NES_PPU: + // PPU + addr &= 0x3FFF; + if (addr < 0x2000) + VPage[addr >> 10][addr] = data[i]; //todo: detect if this is vrom and turn it red if so + if ((addr >= 0x2000) && (addr < 0x3F00)) + vnapage[(addr >> 10) & 0x3][addr & 0x3FF] = data[i]; //todo: this causes 0x3000-0x3f00 to mirror 0x2000-0x2f00, is this correct? + if ((addr >= 0x3F00) && (addr < 0x3FFF)) + PalettePoke(addr, data[i]); + break; + case MODE_NES_OAM: + addr &= 0xFF; + SPRAM[addr] = data[i]; + break; + case MODE_NES_FILE: + // ROM + ApplyPatch(addr, 1, &data[i]); + break; + } } } CursorStartAddy+=datasize; -- cgit v1.2.3