From f32a98c89a6935ece0d7ec64a764e12db24fa737 Mon Sep 17 00:00:00 2001 From: harry Date: Mon, 30 May 2022 04:55:47 -0400 Subject: [PATCH 01/48] Fix libswresample-dev dependency name for ubuntu linux appveyor build script. --- pipelines/linux_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index 4d8e7474..77922b5e 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -98,7 +98,7 @@ sudo apt-get --assume-yes install libavcodec-dev sudo apt-get --assume-yes install libavformat-dev sudo apt-get --assume-yes install libavutil-dev sudo apt-get --assume-yes install libswscale-dev -sudo apt-get --assume-yes install libavresample-dev +sudo apt-get --assume-yes install libswresample-dev # Install cppcheck echo '****************************************' From a87902b427dae16a534bdfaa75e8baa68f337b82 Mon Sep 17 00:00:00 2001 From: harry Date: Mon, 30 May 2022 04:58:21 -0400 Subject: [PATCH 02/48] For Qt GUI, enable openGL GL_BLEND and set blend function to GL_ONE_MINUS_SRC_ALPHA. Fixes openGL driver issue #513 for running on wayland. --- src/drivers/Qt/ConsoleViewerGL.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/drivers/Qt/ConsoleViewerGL.cpp b/src/drivers/Qt/ConsoleViewerGL.cpp index c473895a..6f315002 100644 --- a/src/drivers/Qt/ConsoleViewerGL.cpp +++ b/src/drivers/Qt/ConsoleViewerGL.cpp @@ -84,6 +84,7 @@ ConsoleViewGL_t::ConsoleViewGL_t(QWidget *parent) setMinimumWidth( 256 ); setMinimumHeight( 224 ); setFocusPolicy(Qt::StrongFocus); + //setAttribute(Qt::WA_OpaquePaintEvent); localBufSize = (4 * GL_NES_WIDTH) * (4 * GL_NES_HEIGHT) * sizeof(uint32_t); @@ -272,6 +273,8 @@ void ConsoleViewGL_t::buildTextures(void) GL_BGRA, GL_UNSIGNED_BYTE, 0 ); } + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //printf("Texture Built: %ix%i\n", w, h); } @@ -347,7 +350,7 @@ void ConsoleViewGL_t::initializeGL(void) initializeOpenGLFunctions(); // Set up the rendering context, load shaders and other resources, etc.: //QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); chkExtnsGL(); //printf("GL Init!\n"); @@ -666,6 +669,8 @@ void ConsoleViewGL_t::paintGL(void) } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if ( textureType == GL_TEXTURE_RECTANGLE ) { From fc9f89dafce8bb76554c0ba51308503ba18043e1 Mon Sep 17 00:00:00 2001 From: harry Date: Mon, 30 May 2022 05:17:58 -0400 Subject: [PATCH 03/48] For Qt GUI build, make timestamp UTC based for reproducible builds. Patch from debian. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60dba054..75c2d5d8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -578,7 +578,7 @@ set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) # the FCEUX_BUILD_TIMESTAMP preprocessor definition. # Note: with CMake >= 3.8.0, this will respect SOURCE_DATE_EPOCH. For more info, # see . -string(TIMESTAMP BUILD_TS "%H:%M:%S %b %d %Y") +string(TIMESTAMP BUILD_TS "%H:%M:%S %b %d %Y" UTC) add_definitions( -DFCEUX_BUILD_TIMESTAMP=\"${BUILD_TS}\" ) if (WIN32) From 0287395bee150bd0d322afbbcf329b82b8d344a1 Mon Sep 17 00:00:00 2001 From: harry Date: Mon, 30 May 2022 05:38:49 -0400 Subject: [PATCH 04/48] For Qt GUI, added logic to raise and shift focus to hex editor window when opening from debugger. Fixes issue #509. --- src/drivers/Qt/HexEditor.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/drivers/Qt/HexEditor.cpp b/src/drivers/Qt/HexEditor.cpp index 0c763382..8335ca7c 100644 --- a/src/drivers/Qt/HexEditor.cpp +++ b/src/drivers/Qt/HexEditor.cpp @@ -4205,6 +4205,12 @@ int hexEditorOpenFromDebugger( int mode, int addr ) win->show(); } + else + { + win->activateWindow(); + win->raise(); + win->setFocus(); + } win->editor->setMode( mode ); win->editor->setAddr( addr ); From 971d7212eee0954c5f0ca10e9d8c257377683750 Mon Sep 17 00:00:00 2001 From: harry Date: Mon, 30 May 2022 19:58:18 -0400 Subject: [PATCH 05/48] Minor optimization of openGL alpha blending for Qt GUI. --- src/drivers/Qt/ConsoleViewerGL.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/drivers/Qt/ConsoleViewerGL.cpp b/src/drivers/Qt/ConsoleViewerGL.cpp index 6f315002..f836dd88 100644 --- a/src/drivers/Qt/ConsoleViewerGL.cpp +++ b/src/drivers/Qt/ConsoleViewerGL.cpp @@ -274,7 +274,8 @@ void ConsoleViewGL_t::buildTextures(void) } glEnable(GL_BLEND); - glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_ONE, GL_ONE); + //glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //printf("Texture Built: %ix%i\n", w, h); } @@ -670,7 +671,8 @@ void ConsoleViewGL_t::paintGL(void) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); - glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_ONE, GL_ONE); + //glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if ( textureType == GL_TEXTURE_RECTANGLE ) { From 2e70e27ba064b367a75adbd7dbee9a8201caaa1f Mon Sep 17 00:00:00 2001 From: negative Date: Wed, 1 Jun 2022 16:39:46 +0800 Subject: [PATCH 06/48] Mapper 235: Update support for 260-in-1 and add UNROM mode - Using Soft-reset with switch between multicarts or the extra PRG rom which loads Contra game. Fix: https://github.com/TASEmulators/fceux/issues/489 --- src/boards/235.cpp | 69 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/src/boards/235.cpp b/src/boards/235.cpp index 98ce11bb..aba619ad 100644 --- a/src/boards/235.cpp +++ b/src/boards/235.cpp @@ -19,36 +19,79 @@ */ #include "mapinc.h" +#include "ines.h" + +static uint16 cmdreg = 0; +static uint8 openbus = 0; + +// For carts with extra 128K prg rom (Contra) +static uint8 unrom = 0; +static uint8 unromData = 0; + +static uint32 PRGROMSize = 0; -static uint16 cmdreg; static SFORMAT StateRegs[] = { { &cmdreg, 2, "CREG" }, + { &openbus, 1, "OB" }, + { &unrom, 1, "UROM" }, + { &unromData, 1, "UDTA" }, { 0 } }; static void Sync(void) { - if (cmdreg & 0x400) - setmirror(MI_0); - else - setmirror(((cmdreg >> 13) & 1) ^ 1); - if (cmdreg & 0x800) { - setprg16(0x8000, ((cmdreg & 0x300) >> 3) | ((cmdreg & 0x1F) << 1) | ((cmdreg >> 12) & 1)); - setprg16(0xC000, ((cmdreg & 0x300) >> 3) | ((cmdreg & 0x1F) << 1) | ((cmdreg >> 12) & 1)); - } else - setprg32(0x8000, ((cmdreg & 0x300) >> 4) | (cmdreg & 0x1F)); + if (unrom) { + int PRGPageCount = PRGROMSize / (16 * 1024); + setprg16(0x8000, PRGPageCount & 0xC0 | (unromData & 7)); + setprg16(0xC000, PRGPageCount & 0xC0 | 7); + setmirror(MI_V); + } else { + uint8 bank = ((cmdreg & 0x300) >> 3) | (cmdreg & 0x1F); + if (bank >= (PRGROMSize / (32 * 1024))) { + openbus = 1; + } else { + if (cmdreg & 0x400) + setmirror(MI_0); + else + setmirror(((cmdreg >> 13) & 1) ^ 1); + if (cmdreg & 0x800) { + setprg16(0x8000, (bank << 1) | ((cmdreg >> 12) & 1)); + setprg16(0xC000, (bank << 1) | ((cmdreg >> 12) & 1)); + } else + setprg32(0x8000, bank); + } + } +} + +static DECLFR(M235Read) { + if (openbus) { + openbus = 0; + return X.DB; + } + return CartBR(A); } static DECLFW(M235Write) { cmdreg = A; + unromData = V; + Sync(); +} + +static void M235Reset(void) { + cmdreg = 0; + unromData = 0; + if (PRGROMSize & 0x20000) + unrom = (unrom + 1) & 1; Sync(); } static void M235Power(void) { setchr8(0); SetWriteHandler(0x8000, 0xFFFF, M235Write); - SetReadHandler(0x8000, 0xFFFF, CartBR); + SetReadHandler(0x8000, 0xFFFF, M235Read); cmdreg = 0; + unromData = 0; + unrom = 0; Sync(); } @@ -57,7 +100,11 @@ static void M235Restore(int version) { } void Mapper235_Init(CartInfo *info) { + info->Reset = M235Reset; info->Power = M235Power; GameStateRestore = M235Restore; AddExState(&StateRegs, ~0, 0, 0); + + // needs raw, non-pow2 PRGROM size for comparison + PRGROMSize = head.ROM_size * 16384; } From dd35f4b12aea590a6206e48f92334a949b1e0802 Mon Sep 17 00:00:00 2001 From: Dwedit Date: Thu, 28 Apr 2022 18:26:04 -0400 Subject: [PATCH 07/48] Add size limit of 32768 to strings to guard against corrupt files Add count limit for bookmarks and bookmark shortcuts --- src/drivers/common/config.cpp | 5 +++++ src/drivers/win/pref.cpp | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/drivers/common/config.cpp b/src/drivers/common/config.cpp index 7f1157e1..319067fc 100644 --- a/src/drivers/common/config.cpp +++ b/src/drivers/common/config.cpp @@ -145,6 +145,11 @@ static void GetValueR(FILE *fp, char *str, void *v, int c) { if(!c) // String, allocate some memory. { + // Windows enforces a 32767 character limit for text boxes by default + // If a string exceeds this length, it's probably a corrupt file + if (s > 32768) + goto gogl; + if(!(*(char **)v=(char*)malloc(s))) goto gogl; diff --git a/src/drivers/win/pref.cpp b/src/drivers/win/pref.cpp index 2f55f7db..78477c74 100644 --- a/src/drivers/win/pref.cpp +++ b/src/drivers/win/pref.cpp @@ -254,6 +254,9 @@ int loadDebuggerPreferences(FILE* f) // Read the number of CPU bookmarks if (fread(&size, sizeof(unsigned int), 1, f) != 1) return 1; + // If there's more than 65536 bookmarks (bookmarking every address in the whole 16-bit address space), we're probably reading a corrupt file + if (size > 65536) return 1; + bookmarks.resize(size); // Read the data of those bookmarks char buffer[256]; @@ -295,6 +298,8 @@ int loadDebuggerPreferences(FILE* f) // Read the length of the BP condition if (fread(&len, sizeof(len), 1, f) != 1) return 1; + // Windows enforces 32767 max characters for a textbox by default, if it exceeds that, it's probably a corrupt file + if (len > 32767) return 1; // Delete eventual older conditions if (watchpoint[myNumWPs].condText) @@ -312,7 +317,9 @@ int loadDebuggerPreferences(FILE* f) // Read length of the BP description if (fread(&len, sizeof(len), 1, f) != 1) return 1; - + // Windows enforces 32767 max characters for a textbox by default, if it exceeds that, it's probably a corrupt file + if (len > 32767) return 1; + // Delete eventual older description if (watchpoint[myNumWPs].desc) free(watchpoint[myNumWPs].desc); @@ -373,6 +380,8 @@ int loadHexPreferences(FILE* f, HexBookmarkList& target = hexBookmarks) if (fread(&target[i].address, sizeof(target[i].address), 1, f) != 1) return 1; // Read length of description if (fread(&len, sizeof(len), 1, f) != 1) return 1; + const int max_len = sizeof(target[i].description)/sizeof(target[i].description[0]) - 1; //value of 50 + if (len > max_len) return 1; // Read the bookmark description if (fread(target[i].description, 1, len, f) != len) return 1; } @@ -384,6 +393,8 @@ int loadHexPreferences(FILE* f, HexBookmarkList& target = hexBookmarks) if (!feof(f)) { fread(&target.shortcutCount, sizeof(target.shortcutCount), 1, f); + const int max_shortcuts = sizeof(target.shortcuts) / sizeof(target.shortcuts[0]); //value of 10 + if (target.shortcutCount > max_shortcuts) return 1; unsigned int bookmark_index, shortcut_index; // read the matching index list of the shortcuts From 2c85cc53c5540ef2ecf22c60ec20f5aa061cec24 Mon Sep 17 00:00:00 2001 From: negative Date: Sun, 5 Jun 2022 18:57:15 +0800 Subject: [PATCH 08/48] FDS: Update IRQ based on latest hardware notes - IRQ updates based on latest notes. Verified with test rom. https://www.nesdev.org/wiki/Family_Computer_Disk_System#IRQ_control_($4022) Discussion and test rom file: https://forums.nesdev.org/viewtopic.php?f=3&t=16507 test rom: https://forums.nesdev.org/viewtopic.php?p=205052#p205052 - Puff Puff Golf is still problematic and unplayable. added notes for it. - Fix typo for a previous commit. --- src/fds.cpp | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/fds.cpp b/src/fds.cpp index 35924a4a..f608436f 100644 --- a/src/fds.cpp +++ b/src/fds.cpp @@ -223,14 +223,23 @@ void FCEU_FDSSelect(void) FCEU_DispMessage("Disk %d Side %c Selected", 0, SelectDisk >> 1, (SelectDisk & 1) ? 'B' : 'A'); } -#define IRQ_Repeat (IRQa & 0x01) -#define IRQ_Enabled (IRQa & 0x02) +#define IRQ_Repeat 0x01 +#define IRQ_Enabled 0x02 static void FDSFix(int a) { - if ((IRQa & IRQ_Enabled) && IRQCount) { + if (IRQa & IRQ_Enabled) { IRQCount -= a; if (IRQCount <= 0) { IRQCount = IRQLatch; + /* Puff Puff Golf notes: + Game freezes while music playing ingame after inserting Disk Side B. + IRQ is usually fired at scanline 169 and 183 for music to work. + + At some point after inserting disk B, an IRQ is fired at scanline 174 which + will just freeze game while music plays. + + If you ignore triggering IRQ altogether, game plays but no music + */ X6502_IRQBegin(FCEU_IQEXT); if (!(IRQa & IRQ_Repeat)) { IRQa &= ~IRQ_Enabled; @@ -574,21 +583,30 @@ void FDSSoundReset(void) { static DECLFW(FDSWrite) { switch (A) { case 0x4020: - X6502_IRQEnd(FCEU_IQEXT); IRQLatch &= 0xFF00; IRQLatch |= V; break; case 0x4021: - X6502_IRQEnd(FCEU_IQEXT); IRQLatch &= 0xFF; IRQLatch |= V << 8; break; case 0x4022: - X6502_IRQEnd(FCEU_IQEXT); - IRQCount = IRQLatch; - IRQa = V & 3; + if (FDSRegs[3] & 1) { + IRQa = V & 0x03; + if (IRQa & IRQ_Enabled) { + IRQCount = IRQLatch; + } else { + X6502_IRQEnd(FCEU_IQEXT); + } + } + break; + case 0x4023: + if (!(V & 0x01)) { + IRQa &= ~IRQ_Enabled; + X6502_IRQEnd(FCEU_IQEXT); + X6502_IRQEnd(FCEU_IQEXT2); + } break; - case 0x4023: break; case 0x4024: if (mapperFDS_diskinsert && ~mapperFDS_control & 0x04) { From 14c215208e77b500c14b920b5c47186256378ade Mon Sep 17 00:00:00 2001 From: negative Date: Sun, 5 Jun 2022 19:09:17 +0800 Subject: [PATCH 09/48] Fix Apple Town Story (FDS) crash Fix https://github.com/TASEmulators/fceux/issues/487 fceumm and mednafen-nes has similar placement for SIRQStat --- src/sound.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sound.cpp b/src/sound.cpp index e17dae72..040132b0 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -534,9 +534,10 @@ static INLINE void DMCDMA(void) PrepDPCM(); else { - SIRQStat|=0x80; - if(DMCFormat&0x80) + if(DMCFormat&0x80) { + SIRQStat|=0x80; X6502_IRQBegin(FCEU_IQDPCM); + } } } } From 3fed0331cc7acd3a38ebd1d3eb01342ed04dbe46 Mon Sep 17 00:00:00 2001 From: harry Date: Tue, 2 Aug 2022 21:02:50 -0400 Subject: [PATCH 10/48] Fix for global variable SFCPU read overflow error when running with clang/gcc address sanitizer. The code that writes the save state to disk expects the parameter description to at least be 4 bytes. --- src/state.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/state.cpp b/src/state.cpp index a29a46d0..503622b1 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -110,7 +110,7 @@ SFORMAT SFCPU[]={ { &X.Y, 1, "Y\0\0"}, { &X.S, 1, "S\0\0"}, { &X.P, 1, "P\0\0"}, - { &X.DB, 1, "DB"}, + { &X.DB, 1, "DB\0"}, { &RAM, 0x800 | FCEUSTATE_INDIRECT, "RAM", }, { 0 } }; From 9d18523731a7a7de35d518783713e73c60de50b9 Mon Sep 17 00:00:00 2001 From: harry Date: Tue, 2 Aug 2022 21:06:51 -0400 Subject: [PATCH 11/48] Fix for heap read overflow in Qt Avi Riff viewer when reading avi files created by ffmpeg. Caught by running with clang/gcc address sanitizer. --- src/drivers/Qt/AviRiffViewer.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/drivers/Qt/AviRiffViewer.cpp b/src/drivers/Qt/AviRiffViewer.cpp index 6d1e6afa..36716bae 100644 --- a/src/drivers/Qt/AviRiffViewer.cpp +++ b/src/drivers/Qt/AviRiffViewer.cpp @@ -848,9 +848,11 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item ) } else if ( strcmp( strhType, "auds" ) == 0 ) { - data.malloc( item->getSize()+8 ); + size_t dataSize = item->getSize()+8; - avi->getChunkData( item->filePos(), data.buf, item->getSize()+8 ); + data.malloc( dataSize ); + + avi->getChunkData( item->filePos(), data.buf, dataSize ); sprintf( stmp, "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] ); @@ -908,12 +910,17 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item ) twi->setText( 2, tr(stmp) ); item->addChild(twi); - sprintf( stmp, "%u", data.readU16(24) ); + // ffmpeg does not write out this element. + // Check chunk size to ensure it is there to avoid heap read overflow. + if ( dataSize >= 26 ) + { + sprintf( stmp, "%u", data.readU16(24) ); - twi = new QTreeWidgetItem(); - twi->setText( 0, tr("cbSize") ); - twi->setText( 2, tr(stmp) ); - item->addChild(twi); + twi = new QTreeWidgetItem(); + twi->setText( 0, tr("cbSize") ); + twi->setText( 2, tr(stmp) ); + item->addChild(twi); + } } } else if ( isRiffTag( item->getFourcc(), &riffIdx ) ) From 1b32752800dbceab70b39ade02432b9068ec7967 Mon Sep 17 00:00:00 2001 From: harry Date: Wed, 3 Aug 2022 18:26:13 -0400 Subject: [PATCH 12/48] Removed redundant chunk size field from auds header in Avi RIFF viewer. --- src/drivers/Qt/AviRiffViewer.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/drivers/Qt/AviRiffViewer.cpp b/src/drivers/Qt/AviRiffViewer.cpp index 36716bae..2f9b28c3 100644 --- a/src/drivers/Qt/AviRiffViewer.cpp +++ b/src/drivers/Qt/AviRiffViewer.cpp @@ -909,18 +909,6 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item ) twi->setText( 0, tr("nBitsPerSample") ); twi->setText( 2, tr(stmp) ); item->addChild(twi); - - // ffmpeg does not write out this element. - // Check chunk size to ensure it is there to avoid heap read overflow. - if ( dataSize >= 26 ) - { - sprintf( stmp, "%u", data.readU16(24) ); - - twi = new QTreeWidgetItem(); - twi->setText( 0, tr("cbSize") ); - twi->setText( 2, tr(stmp) ); - item->addChild(twi); - } } } else if ( isRiffTag( item->getFourcc(), &riffIdx ) ) From 02bf3dbb4dbc611d02e465f9c18ec6f35d8c80f5 Mon Sep 17 00:00:00 2001 From: harry Date: Wed, 3 Aug 2022 18:51:10 -0400 Subject: [PATCH 13/48] Added cmake command line option to build with clang/gcc address sanitizer enabled. --- src/CMakeLists.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 75c2d5d8..dad47fd2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -85,6 +85,14 @@ else(WIN32) #endif() add_definitions( -D__QT_DRIVER__ -DQT_DEPRECATED_WARNINGS ) + if ( ${ASAN_ENABLE} ) + add_definitions( -fsanitize=address -fsanitize=bounds-strict ) + set( ASAN_LDFLAGS -lasan -lubsan) + message( STATUS "Address Sanitizer Enabled" ) + else() + message( STATUS "Address Sanitizer Disabled" ) + endif() + # Check for libminizip pkg_check_modules( MINIZIP REQUIRED minizip) @@ -613,7 +621,7 @@ add_executable( ${APP_NAME} ${SOURCES} ../resources.qrc ${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp) endif() -target_link_libraries( ${APP_NAME} +target_link_libraries( ${APP_NAME} ${ASAN_LDFLAGS} ${${Qt}Widgets_LIBRARIES} ${${Qt}Help_LIBRARIES} ${${Qt}OpenGL_LIBRARIES} From 44c8e15503f8596e1b084df47ff660525802fc91 Mon Sep 17 00:00:00 2001 From: harry Date: Thu, 4 Aug 2022 05:06:31 -0400 Subject: [PATCH 14/48] Fix for small memory leak in GetBackupFileName(). strdup allocates memory and returns a char pointer to it. However std::string allocates its own memory already. Since FCEU_MakeFName returns a std::string already, there is no reason to use strdup in between the assignment of one std::string to another. --- src/state.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/state.cpp b/src/state.cpp index 503622b1..a40e665e 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -1103,7 +1103,7 @@ string GetBackupFileName() string filename; int x; - filename = strdup(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0).c_str()); //Generate normal savestate filename + filename = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0); //Generate normal savestate filename x = filename.find_last_of("."); //Find last dot filename = filename.substr(0,x); //Chop off file extension filename.append(".bak.fc0"); //add .bak From 0c36a3575ef9f8bc274fa393ac6eb7ebf9c15401 Mon Sep 17 00:00:00 2001 From: harry Date: Thu, 4 Aug 2022 05:25:58 -0400 Subject: [PATCH 15/48] Bug fix for missing va_end on stdarg list. According to online documentation, vfprintf does not call va_end. This was caught by cppcheck. --- src/drivers/Qt/AviRecord.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/drivers/Qt/AviRecord.cpp b/src/drivers/Qt/AviRecord.cpp index f6a096a9..97652c41 100644 --- a/src/drivers/Qt/AviRecord.cpp +++ b/src/drivers/Qt/AviRecord.cpp @@ -841,6 +841,8 @@ static void log_callback( void *avcl, int level, const char *fmt, va_list vl) va_copy( vl2, vl ); vfprintf( avLogFp, fmt, vl2 ); + + va_end(vl2); } av_log_default_callback( avcl, level, fmt, vl ); From 0e9ad2f400a67f9b4c7f589affc4d283ec9bf292 Mon Sep 17 00:00:00 2001 From: harry Date: Thu, 4 Aug 2022 05:40:03 -0400 Subject: [PATCH 16/48] Bug fix for mismatched allocation/deallocation calls. Memory allocated with malloc should use free (not delete) to deallocate memory. --- src/drivers/win/oakra.h | 2 +- src/drivers/win/sound.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drivers/win/oakra.h b/src/drivers/win/oakra.h index b75f64d6..75c09f4a 100644 --- a/src/drivers/win/oakra.h +++ b/src/drivers/win/oakra.h @@ -90,7 +90,7 @@ public: ptr = ::realloc(ptr,len); return ptr; } - void free(void *ptr) { + static void free(void *ptr) { ::free(ptr); } diff --git a/src/drivers/win/sound.cpp b/src/drivers/win/sound.cpp index c751c586..f47e5efe 100644 --- a/src/drivers/win/sound.cpp +++ b/src/drivers/win/sound.cpp @@ -58,7 +58,7 @@ public: Buffer(int size) { length = 0; this->size = size; data = OAKRA_Module::malloc(size); } int getRemaining() { return size-length; } void *data; - ~Buffer() { delete data; } + ~Buffer() { if (data){ OAKRA_Module::free(data); data = nullptr; } } }; std::vector liveBuffers; From bb1fc08d8e0a0753992db54aa9a067078b9feb42 Mon Sep 17 00:00:00 2001 From: zeromus Date: Thu, 4 Aug 2022 21:23:34 -0400 Subject: [PATCH 17/48] rename all iNES Header Editor to NES Header Editor (re #519) --- src/drivers/Qt/ConsoleWindow.cpp | 8 ++++---- src/drivers/Qt/HexEditor.cpp | 2 +- src/drivers/Qt/iNesHeaderEditor.cpp | 16 ++++++++-------- src/drivers/sdl/memview.cpp | 2 +- src/drivers/win/debugger.cpp | 2 +- src/drivers/win/header_editor.cpp | 16 ++++++++-------- src/drivers/win/memview.cpp | 4 ++-- src/drivers/win/window.cpp | 4 ++-- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 02ad1059..9332dac4 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -1730,10 +1730,10 @@ void consoleWin_t::createMainMenu(void) debugMenu->addAction(ggEncodeAct); - // Debug -> iNES Header Editor - iNesEditAct = new QAction(tr("&iNES Header Editor..."), this); + // Debug -> NES Header Editor + iNesEditAct = new QAction(tr("NES Header Edito&r..."), this); //iNesEditAct->setShortcut( QKeySequence(tr("Shift+F7"))); - iNesEditAct->setStatusTip(tr("Open iNES Header Editor")); + iNesEditAct->setStatusTip(tr("Open NES Header Editor")); connect(iNesEditAct, SIGNAL(triggered()), this, SLOT(openNesHeaderEditor(void)) ); debugMenu->addAction(iNesEditAct); @@ -3055,7 +3055,7 @@ void consoleWin_t::openNesHeaderEditor(void) { iNesHeaderEditor_t *win; - //printf("Open iNES Header Editor Window\n"); + //printf("Open NES Header Editor Window\n"); win = new iNesHeaderEditor_t(this); diff --git a/src/drivers/Qt/HexEditor.cpp b/src/drivers/Qt/HexEditor.cpp index 8335ca7c..ed78bf07 100644 --- a/src/drivers/Qt/HexEditor.cpp +++ b/src/drivers/Qt/HexEditor.cpp @@ -374,7 +374,7 @@ static int writeMem( int mode, unsigned int addr, int value ) { if (addr < 16) { - fprintf( stdout, "You can't edit ROM header here, however you can use iNES Header Editor to edit the header if it's an iNES format file."); + fprintf( stdout, "You can't edit ROM header here, however you can use NES Header Editor to edit the header if it's an iNES or NES2.0 format file."); } else if ( (addr >= 16) && (addr < PRGsize[0]+16) ) { diff --git a/src/drivers/Qt/iNesHeaderEditor.cpp b/src/drivers/Qt/iNesHeaderEditor.cpp index 9342a002..47b435b6 100644 --- a/src/drivers/Qt/iNesHeaderEditor.cpp +++ b/src/drivers/Qt/iNesHeaderEditor.cpp @@ -189,7 +189,7 @@ iNesHeaderEditor_t::iNesHeaderEditor_t(QWidget *parent) fontCharWidth = fm.width(QLatin1Char('2')); #endif - setWindowTitle("iNES Header Editor"); + setWindowTitle("NES Header Editor"); //resize( 512, 512 ); @@ -197,7 +197,7 @@ iNesHeaderEditor_t::iNesHeaderEditor_t(QWidget *parent) hdrLayout = new QVBoxLayout(); hbox1 = new QHBoxLayout(); hbox = new QHBoxLayout(); - hdrBox = new QGroupBox( tr("iNES Header") ); + hdrBox = new QGroupBox( tr("NES Header") ); box = new QGroupBox( tr("Version:") ); mainLayout->addWidget( hdrBox ); @@ -550,7 +550,7 @@ iNesHeaderEditor_t::~iNesHeaderEditor_t(void) //---------------------------------------------------------------------------- void iNesHeaderEditor_t::closeEvent(QCloseEvent *event) { - //printf("iNES Header Editor Close Window Event\n"); + //printf("NES Header Editor Close Window Event\n"); done(0); deleteLater(); event->accept(); @@ -701,21 +701,21 @@ bool iNesHeaderEditor_t::loadHeader(iNES_HEADER* header) break; } case errors::INVALID_HEADER: - //MessageBox(parent, "Invalid iNES header.", "iNES Header Editor", MB_OK | MB_ICONERROR); - showErrorMsgWindow( "Invalid iNES header." ); + //MessageBox(parent, "Invalid NES header.", "NES Header Editor", MB_OK | MB_ICONERROR); + showErrorMsgWindow( "Invalid NES header." ); break; case errors::FDS_HEADER: - //MessageBox(parent, "Editing header of an FDS file is not supported.", "iNES Header Editor", MB_OK | MB_ICONERROR); + //MessageBox(parent, "Editing header of an FDS file is not supported.", "NES Header Editor", MB_OK | MB_ICONERROR); showErrorMsgWindow("Editing header of an FDS file is not supported."); break; case errors::UNIF_HEADER: - //MessageBox(parent, "Editing header of a UNIF file is not supported.", "iNES Header Editor", MB_OK | MB_ICONERROR); + //MessageBox(parent, "Editing header of a UNIF file is not supported.", "NES Header Editor", MB_OK | MB_ICONERROR); showErrorMsgWindow("Editing header of a UNIF file is not supported."); break; case errors::NSF_HEADER: // case errors::NSF2_HEADER: // case errors::NSFE_HEADER: - //MessageBox(parent, "Editing header of an NSF file is not supported.", "iNES Header Editor", MB_OK | MB_ICONERROR); + //MessageBox(parent, "Editing header of an NSF file is not supported.", "NES Header Editor", MB_OK | MB_ICONERROR); showErrorMsgWindow("Editing header of an NSF file is not supported."); break; } diff --git a/src/drivers/sdl/memview.cpp b/src/drivers/sdl/memview.cpp index c89dbf3c..bc17ee3d 100644 --- a/src/drivers/sdl/memview.cpp +++ b/src/drivers/sdl/memview.cpp @@ -277,7 +277,7 @@ struct memViewWin_t { if (addr < 16) { - fprintf( stdout, "You can't edit ROM header here, however you can use iNES Header Editor to edit the header if it's an iNES format file."); + fprintf( stdout, "You can't edit ROM header here, however you can use NES Header Editor to edit the header if it's an iNES or NES2.0 format file."); } else if ( (addr >= 16) && (addr < PRGsize[0]+16) ) { diff --git a/src/drivers/win/debugger.cpp b/src/drivers/win/debugger.cpp index 4bc61e5b..8c3156a2 100644 --- a/src/drivers/win/debugger.cpp +++ b/src/drivers/win/debugger.cpp @@ -1471,7 +1471,7 @@ INT_PTR CALLBACK PatcherCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa else iapoffset = GetNesFileAddress(GetEditHex(hwndDlg,IDC_ROMPATCHER_OFFSET)); if((iapoffset < 16) && (iapoffset != -1)){ - MessageBox(hDebug, "Sorry, iNES Header editing isn't supported by this tool. If you want to edit the header, please use iNES Header Editor", "Error", MB_OK | MB_ICONASTERISK); + MessageBox(hDebug, "Sorry, NES Header editing isn't supported by this tool. If you want to edit the header, please use NES Header Editor", "Error", MB_OK | MB_ICONASTERISK); iapoffset = -1; } if((iapoffset > PRGsize[0]) && (iapoffset != -1)){ diff --git a/src/drivers/win/header_editor.cpp b/src/drivers/win/header_editor.cpp index 8893b7d9..168a6170 100644 --- a/src/drivers/win/header_editor.cpp +++ b/src/drivers/win/header_editor.cpp @@ -186,22 +186,22 @@ bool LoadHeader(HWND parent, iNES_HEADER* header) { char buf[1024]; sprintf(buf, "Error opening %s!", LoadedRomFName); - MessageBox(parent, buf, "iNES Header Editor", MB_OK | MB_ICONERROR); + MessageBox(parent, buf, "NES Header Editor", MB_OK | MB_ICONERROR); break; } case errors::INVALID_HEADER: - MessageBox(parent, "Invalid iNES header.", "iNES Header Editor", MB_OK | MB_ICONERROR); + MessageBox(parent, "Invalid NES header.", "NES Header Editor", MB_OK | MB_ICONERROR); break; case errors::FDS_HEADER: - MessageBox(parent, "Editing header of an FDS file is not supported.", "iNES Header Editor", MB_OK | MB_ICONERROR); + MessageBox(parent, "Editing header of an FDS file is not supported.", "NES Header Editor", MB_OK | MB_ICONERROR); break; case errors::UNIF_HEADER: - MessageBox(parent, "Editing header of a UNIF file is not supported.", "iNES Header Editor", MB_OK | MB_ICONERROR); + MessageBox(parent, "Editing header of a UNIF file is not supported.", "NES Header Editor", MB_OK | MB_ICONERROR); break; case errors::NSF_HEADER: // case errors::NSF2_HEADER: // case errors::NSFE_HEADER: - MessageBox(parent, "Editing header of an NSF file is not supported.", "iNES Header Editor", MB_OK | MB_ICONERROR); + MessageBox(parent, "Editing header of an NSF file is not supported.", "NES Header Editor", MB_OK | MB_ICONERROR); break; } return false; @@ -1735,7 +1735,7 @@ int GetComboBoxByteSize(HWND hwnd, UINT id, int* value, iNES_HEADER* header) sprintf(buf, "The unit of %s size you entered is invalid, it must be B, KB or MB", name); break; case errors::MINUS_ERR: - sprintf(buf, "Negative value of %s is not supported by iNES header.", name); + sprintf(buf, "Negative value of %s is not supported by NES header.", name); break; } @@ -1880,7 +1880,7 @@ bool SaveINESFile(HWND hwnd, char* path, iNES_HEADER* header) if (!source) { sprintf(buf, "Opening source file %s failed.", LoadedRomFName); - MessageBox(hwnd, buf, "iNES Header Editor", MB_OK | MB_ICONERROR); + MessageBox(hwnd, buf, "NES Header Editor", MB_OK | MB_ICONERROR); return false; } @@ -1889,7 +1889,7 @@ bool SaveINESFile(HWND hwnd, char* path, iNES_HEADER* header) if (!target) { sprintf(buf, "Creating target file %s failed.", path); - MessageBox(hwnd, buf, "iNES Header Editor", MB_OK | MB_ICONERROR); + MessageBox(hwnd, buf, "NES Header Editor", MB_OK | MB_ICONERROR); FCEU_fclose(source); return false; } diff --git a/src/drivers/win/memview.cpp b/src/drivers/win/memview.cpp index 0eb55579..7c8af67d 100644 --- a/src/drivers/win/memview.cpp +++ b/src/drivers/win/memview.cpp @@ -346,7 +346,7 @@ static int GetFileData(uint32 offset){ } static int WriteFileData(uint32 addr,int data){ - if (addr < 16) MessageBox(hMemView, "You can't edit ROM header here, however you can use iNES Header Editor to edit the header if it's an iNES format file.", "Sorry", MB_OK | MB_ICONERROR); + if (addr < 16) MessageBox(hMemView, "You can't edit ROM header here, however you can use NES Header Editor to edit the header if it's an iNES format file.", "Sorry", MB_OK | MB_ICONERROR); if((addr >= 16) && (addr < PRGsize[0]+16)) *(uint8 *)(GetNesPRGPointer(addr-16)) = data; if((addr >= PRGsize[0]+16) && (addr < CHRsize[0]+PRGsize[0]+16)) *(uint8 *)(GetNesCHRPointer(addr-16-PRGsize[0])) = data; @@ -736,7 +736,7 @@ void UpdateColorTable() int temp_offset; for (i = 0; i < DataAmount; i++) { - temp_offset = CurOffset + i - 16; // (minus iNES header) + temp_offset = CurOffset + i - 16; // (minus NES header) if (temp_offset >= 0) { if ((unsigned int)temp_offset < cdloggerdataSize) diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index b36e74bc..d2ba531e 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -404,7 +404,7 @@ void updateGameDependentMenus() for (unsigned int i = 0; i < sizeof(menu_ids) / sizeof(*menu_ids); i++) EnableMenuItem(fceumenu, menu_ids[i], MF_BYCOMMAND | enable ? MF_ENABLED : MF_GRAYED | MF_DISABLED); - // Special treatment for the iNES head editor, only when no game is loaded or an NES game is loaded + // Special treatment for the NES header editor, only when no game is loaded or an NES game is loaded extern iNES_HEADER head; enable = GameInfo == 0 || !strncmp((const char*)&head, "NES\x1A", 4); EnableMenuItem(fceumenu, MENU_INESHEADEREDITOR, MF_BYCOMMAND | enable ? MF_ENABLED : MF_GRAYED | MF_DISABLED); @@ -3394,7 +3394,7 @@ bool inline (*GetIsLetterLegal(UINT id))(char letter) case IDC_CHEAT_TEXT: return IsLetterLegalCheat; - // PRG ROM, PRG RAM, PRG NVRAM, CHR ROM, CHR RAM and CHR NVRAM in iNES Header Editor + // PRG ROM, PRG RAM, PRG NVRAM, CHR ROM, CHR RAM and CHR NVRAM in NES Header Editor case IDC_PRGROM_EDIT: case IDC_PRGRAM_EDIT: case IDC_PRGNVRAM_EDIT: case IDC_CHRROM_EDIT: case IDC_CHRRAM_EDIT: case IDC_CHRNVRAM_EDIT: return IsLetterLegalSize; From 11f903d36395ac974680bf785aac1209a9348a62 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 7 Aug 2022 20:54:11 -0400 Subject: [PATCH 18/48] change built-in palettes to be bit-shifted properly so that whites are pure FF. fixes #540 --- src/palettes/palettes.h | 144 +++++++++++++++++++++------------------ src/palettes/rp2c04001.h | 128 +++++++++++++++++----------------- src/palettes/rp2c04002.h | 128 +++++++++++++++++----------------- src/palettes/rp2c04003.h | 128 +++++++++++++++++----------------- src/palettes/rp2c05004.h | 128 +++++++++++++++++----------------- 5 files changed, 332 insertions(+), 324 deletions(-) diff --git a/src/palettes/palettes.h b/src/palettes/palettes.h index 7721bec9..7739d120 100644 --- a/src/palettes/palettes.h +++ b/src/palettes/palettes.h @@ -4,6 +4,9 @@ #define EMPTY_PALETTE_64 EMPTY_PALETTE_16 EMPTY_PALETTE_16 EMPTY_PALETTE_16 EMPTY_PALETTE_16 #define EMPTY_PALETTE_DEEMPH_X_7 EMPTY_PALETTE_64 EMPTY_PALETTE_64 EMPTY_PALETTE_64 EMPTY_PALETTE_64 EMPTY_PALETTE_64 EMPTY_PALETTE_64 EMPTY_PALETTE_64 +//this assumes the color is already shifted <<2, as it is in these cases +#define P64RPC(x) ( ((x)&~3) | (((x)>>6)&3)) + pal rp2c04001[512] = { #include "rp2c04001.h" EMPTY_PALETTE_DEEMPH_X_7 @@ -23,12 +26,14 @@ pal rp2c05004[512] = { EMPTY_PALETTE_DEEMPH_X_7 }; +#undef P64RPC + // Fixed palette entries used by the GUI pal palette_unvarying[] = { -{ 0x00<<2,0x00<<2,0x00<<2}, // 0 = Black -{ 0x3F<<2,0x3F<<2,0x34<<2}, // 1 = White -{ 0x00<<2,0x00<<2,0x00<<2}, // 2 = Black -{ 0x1d<<2,0x1d<<2,0x24<<2}, // 3 = Greyish +{ 0x00,0x00,0x00}, // 0 = Black +{ 0xFF,0xFF,0xD3}, // 1 = White +{ 0x00,0x00,0x00}, // 2 = Black +{ 0x75,0x75,0x92}, // 3 = Greyish { 190, 0, 0}, // 4 = Reddish { 51,255, 51}, // 5 = Bright green { 49, 14,200}, // 6 = Ultramarine Blue @@ -52,73 +57,76 @@ pal palette_unvarying[] = { }; +#define P64(x) (((x)<<2)|((x>>4)&3)) + // Default palette pal palette[512] = { + { P64(0x1D), P64(0x1D), P64(0x1D)}, /* Value 0 */ + { P64(0x09), P64(0x06), P64(0x23)}, /* Value 1 */ + { P64(0x00), P64(0x00), P64(0x2A)}, /* Value 2 */ + { P64(0x11), P64(0x00), P64(0x27)}, /* Value 3 */ + { P64(0x23), P64(0x00), P64(0x1D)}, /* Value 4 */ + { P64(0x2A), P64(0x00), P64(0x04)}, /* Value 5 */ + { P64(0x29), P64(0x00), P64(0x00)}, /* Value 6 */ + { P64(0x1F), P64(0x02), P64(0x00)}, /* Value 7 */ + { P64(0x10), P64(0x0B), P64(0x00)}, /* Value 8 */ + { P64(0x00), P64(0x11), P64(0x00)}, /* Value 9 */ + { P64(0x00), P64(0x14), P64(0x00)}, /* Value 10 */ + { P64(0x00), P64(0x0F), P64(0x05)}, /* Value 11 */ + { P64(0x06), P64(0x0F), P64(0x17)}, /* Value 12 */ + { P64(0x00), P64(0x00), P64(0x00)}, /* Value 13 */ + { P64(0x00), P64(0x00), P64(0x00)}, /* Value 14 */ + { P64(0x00), P64(0x00), P64(0x00)}, /* Value 15 */ + { P64(0x2F), P64(0x2F), P64(0x2F)}, /* Value 16 */ + { P64(0x00), P64(0x1C), P64(0x3B)}, /* Value 17 */ + { P64(0x08), P64(0x0E), P64(0x3B)}, /* Value 18 */ + { P64(0x20), P64(0x00), P64(0x3C)}, /* Value 19 */ + { P64(0x2F), P64(0x00), P64(0x2F)}, /* Value 20 */ + { P64(0x39), P64(0x00), P64(0x16)}, /* Value 21 */ + { P64(0x36), P64(0x0A), P64(0x00)}, /* Value 22 */ + { P64(0x32), P64(0x13), P64(0x03)}, /* Value 23 */ + { P64(0x22), P64(0x1C), P64(0x00)}, /* Value 24 */ + { P64(0x00), P64(0x25), P64(0x00)}, /* Value 25 */ + { P64(0x00), P64(0x2A), P64(0x00)}, /* Value 26 */ + { P64(0x00), P64(0x24), P64(0x0E)}, /* Value 27 */ + { P64(0x00), P64(0x20), P64(0x22)}, /* Value 28 */ + { P64(0x00), P64(0x00), P64(0x00)}, /* Value 29 */ + { P64(0x00), P64(0x00), P64(0x00)}, /* Value 30 */ + { P64(0x00), P64(0x00), P64(0x00)}, /* Value 31 */ + { P64(0x3F), P64(0x3F), P64(0x3F)}, /* Value 32 */ + { P64(0x0F), P64(0x2F), P64(0x3F)}, /* Value 33 */ + { P64(0x17), P64(0x25), P64(0x3F)}, /* Value 34 */ + { P64(0x33), P64(0x22), P64(0x3F)}, /* Value 35 */ + { P64(0x3D), P64(0x1E), P64(0x3F)}, /* Value 36 */ + { P64(0x3F), P64(0x1D), P64(0x2D)}, /* Value 37 */ + { P64(0x3F), P64(0x1D), P64(0x18)}, /* Value 38 */ + { P64(0x3F), P64(0x26), P64(0x0E)}, /* Value 39 */ + { P64(0x3C), P64(0x2F), P64(0x0F)}, /* Value 40 */ + { P64(0x20), P64(0x34), P64(0x04)}, /* Value 41 */ + { P64(0x13), P64(0x37), P64(0x12)}, /* Value 42 */ + { P64(0x16), P64(0x3E), P64(0x26)}, /* Value 43 */ + { P64(0x00), P64(0x3A), P64(0x36)}, /* Value 44 */ + { P64(0x1E), P64(0x1E), P64(0x1E)}, /* Value 45 */ + { P64(0x00), P64(0x00), P64(0x00)}, /* Value 46 */ + { P64(0x00), P64(0x00), P64(0x00)}, /* Value 47 */ + { P64(0x3F), P64(0x3F), P64(0x3F)}, /* Value 48 */ + { P64(0x2A), P64(0x39), P64(0x3F)}, /* Value 49 */ + { P64(0x31), P64(0x35), P64(0x3F)}, /* Value 50 */ + { P64(0x35), P64(0x32), P64(0x3F)}, /* Value 51 */ + { P64(0x3F), P64(0x31), P64(0x3F)}, /* Value 52 */ + { P64(0x3F), P64(0x31), P64(0x36)}, /* Value 53 */ + { P64(0x3F), P64(0x2F), P64(0x2C)}, /* Value 54 */ + { P64(0x3F), P64(0x36), P64(0x2A)}, /* Value 55 */ + { P64(0x3F), P64(0x39), P64(0x28)}, /* Value 56 */ + { P64(0x38), P64(0x3F), P64(0x28)}, /* Value 57 */ + { P64(0x2A), P64(0x3C), P64(0x2F)}, /* Value 58 */ + { P64(0x2C), P64(0x3F), P64(0x33)}, /* Value 59 */ + { P64(0x27), P64(0x3F), P64(0x3C)}, /* Value 60 */ + { P64(0x31), P64(0x31), P64(0x31)}, /* Value 61 */ + { P64(0x00), P64(0x00), P64(0x00)}, /* Value 62 */ + { P64(0x00), P64(0x00), P64(0x00)}, /* Value 63 */ - { 0x1D<<2, 0x1D<<2, 0x1D<<2 }, /* Value 0 */ - { 0x09<<2, 0x06<<2, 0x23<<2 }, /* Value 1 */ - { 0x00<<2, 0x00<<2, 0x2A<<2 }, /* Value 2 */ - { 0x11<<2, 0x00<<2, 0x27<<2 }, /* Value 3 */ - { 0x23<<2, 0x00<<2, 0x1D<<2 }, /* Value 4 */ - { 0x2A<<2, 0x00<<2, 0x04<<2 }, /* Value 5 */ - { 0x29<<2, 0x00<<2, 0x00<<2 }, /* Value 6 */ - { 0x1F<<2, 0x02<<2, 0x00<<2 }, /* Value 7 */ - { 0x10<<2, 0x0B<<2, 0x00<<2 }, /* Value 8 */ - { 0x00<<2, 0x11<<2, 0x00<<2 }, /* Value 9 */ - { 0x00<<2, 0x14<<2, 0x00<<2 }, /* Value 10 */ - { 0x00<<2, 0x0F<<2, 0x05<<2 }, /* Value 11 */ - { 0x06<<2, 0x0F<<2, 0x17<<2 }, /* Value 12 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 13 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 14 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 15 */ - { 0x2F<<2, 0x2F<<2, 0x2F<<2 }, /* Value 16 */ - { 0x00<<2, 0x1C<<2, 0x3B<<2 }, /* Value 17 */ - { 0x08<<2, 0x0E<<2, 0x3B<<2 }, /* Value 18 */ - { 0x20<<2, 0x00<<2, 0x3C<<2 }, /* Value 19 */ - { 0x2F<<2, 0x00<<2, 0x2F<<2 }, /* Value 20 */ - { 0x39<<2, 0x00<<2, 0x16<<2 }, /* Value 21 */ - { 0x36<<2, 0x0A<<2, 0x00<<2 }, /* Value 22 */ - { 0x32<<2, 0x13<<2, 0x03<<2 }, /* Value 23 */ - { 0x22<<2, 0x1C<<2, 0x00<<2 }, /* Value 24 */ - { 0x00<<2, 0x25<<2, 0x00<<2 }, /* Value 25 */ - { 0x00<<2, 0x2A<<2, 0x00<<2 }, /* Value 26 */ - { 0x00<<2, 0x24<<2, 0x0E<<2 }, /* Value 27 */ - { 0x00<<2, 0x20<<2, 0x22<<2 }, /* Value 28 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 29 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 30 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 31 */ - { 0x3F<<2, 0x3F<<2, 0x3F<<2 }, /* Value 32 */ - { 0x0F<<2, 0x2F<<2, 0x3F<<2 }, /* Value 33 */ - { 0x17<<2, 0x25<<2, 0x3F<<2 }, /* Value 34 */ - { 0x33<<2, 0x22<<2, 0x3F<<2 }, /* Value 35 */ - { 0x3D<<2, 0x1E<<2, 0x3F<<2 }, /* Value 36 */ - { 0x3F<<2, 0x1D<<2, 0x2D<<2 }, /* Value 37 */ - { 0x3F<<2, 0x1D<<2, 0x18<<2 }, /* Value 38 */ - { 0x3F<<2, 0x26<<2, 0x0E<<2 }, /* Value 39 */ - { 0x3C<<2, 0x2F<<2, 0x0F<<2 }, /* Value 40 */ - { 0x20<<2, 0x34<<2, 0x04<<2 }, /* Value 41 */ - { 0x13<<2, 0x37<<2, 0x12<<2 }, /* Value 42 */ - { 0x16<<2, 0x3E<<2, 0x26<<2 }, /* Value 43 */ - { 0x00<<2, 0x3A<<2, 0x36<<2 }, /* Value 44 */ - { 0x1E<<2, 0x1E<<2, 0x1E<<2 }, /* Value 45 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 46 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 47 */ - { 0x3F<<2, 0x3F<<2, 0x3F<<2 }, /* Value 48 */ - { 0x2A<<2, 0x39<<2, 0x3F<<2 }, /* Value 49 */ - { 0x31<<2, 0x35<<2, 0x3F<<2 }, /* Value 50 */ - { 0x35<<2, 0x32<<2, 0x3F<<2 }, /* Value 51 */ - { 0x3F<<2, 0x31<<2, 0x3F<<2 }, /* Value 52 */ - { 0x3F<<2, 0x31<<2, 0x36<<2 }, /* Value 53 */ - { 0x3F<<2, 0x2F<<2, 0x2C<<2 }, /* Value 54 */ - { 0x3F<<2, 0x36<<2, 0x2A<<2 }, /* Value 55 */ - { 0x3F<<2, 0x39<<2, 0x28<<2 }, /* Value 56 */ - { 0x38<<2, 0x3F<<2, 0x28<<2 }, /* Value 57 */ - { 0x2A<<2, 0x3C<<2, 0x2F<<2 }, /* Value 58 */ - { 0x2C<<2, 0x3F<<2, 0x33<<2 }, /* Value 59 */ - { 0x27<<2, 0x3F<<2, 0x3C<<2 }, /* Value 60 */ - { 0x31<<2, 0x31<<2, 0x31<<2 }, /* Value 61 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 62 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 63 */ + #undef P64 //luke's .16+ palette //{0x60, 0x60, 0x60}, /* Value 0 */ diff --git a/src/palettes/rp2c04001.h b/src/palettes/rp2c04001.h index a7bdb7c0..399a5f27 100644 --- a/src/palettes/rp2c04001.h +++ b/src/palettes/rp2c04001.h @@ -1,64 +1,64 @@ -{0xfc, 0xc4, 0xd8}, -{0x40, 0x88, 0xfc}, -{0xd8, 0x28, 0x00}, -{0x5c, 0x94, 0xfc}, -{0x00, 0x80, 0x88}, -{0x00, 0x44, 0x00}, -{0x00, 0x00, 0x00}, -{0xe4, 0x00, 0x58}, -{0xfc, 0xfc, 0xfc}, -{0x74, 0x74, 0x74}, -{0xfc, 0x98, 0x38}, -{0xa8, 0x00, 0x10}, -{0x8c, 0x00, 0x74}, -{0xfc, 0x98, 0x38}, -{0x40, 0x2c, 0x00}, -{0xfc, 0xfc, 0xfc}, -{0x3c, 0xbc, 0xfc}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x80, 0xd0, 0x10}, -{0x9c, 0xfc, 0xf0}, -{0xc4, 0xd4, 0xfc}, -{0xfc, 0xbc, 0xb0}, -{0x20, 0x38, 0xec}, -{0x00, 0x00, 0x00}, -{0x58, 0xf8, 0x98}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0xfc, 0xfc, 0xfc}, -{0xbc, 0xbc, 0xbc}, -{0xf4, 0x78, 0xfc}, -{0x24, 0x18, 0x8c}, -{0x00, 0x00, 0x00}, -{0xa8, 0xe4, 0xfc}, -{0x00, 0x00, 0x00}, -{0x4c, 0xdc, 0x48}, -{0x00, 0xe8, 0xd8}, -{0x18, 0x3c, 0x5c}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x7c, 0x08, 0x00}, -{0xfc, 0xc4, 0xfc}, -{0xa4, 0x00, 0x00}, -{0x80, 0x00, 0xf0}, -{0x00, 0x00, 0xa8}, -{0xfc, 0x74, 0x60}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x94, 0x00}, -{0xbc, 0xbc, 0xbc}, -{0x00, 0x50, 0x00}, -{0xe0, 0xfc, 0xa0}, -{0x00, 0x00, 0x00}, -{0xfc, 0xd8, 0xa8}, -{0xc8, 0x4c, 0x0c}, -{0x00, 0x00, 0x00}, -{0x00, 0x70, 0xec}, -{0x00, 0x44, 0x00}, -{0x00, 0x00, 0x00}, -{0xe0, 0xfc, 0xa0}, -{0xfc, 0x74, 0xb4}, -{0x88, 0x70, 0x00}, -{0x00, 0x00, 0x00}, +{P64RPC(0xfc), P64RPC(0xc4), P64RPC(0xd8)}, +{P64RPC(0x40), P64RPC(0x88), P64RPC(0xfc)}, +{P64RPC(0xd8), P64RPC(0x28), P64RPC(0x00)}, +{P64RPC(0x5c), P64RPC(0x94), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x80), P64RPC(0x88)}, +{P64RPC(0x00), P64RPC(0x44), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xe4), P64RPC(0x00), P64RPC(0x58)}, +{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)}, +{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)}, +{P64RPC(0xfc), P64RPC(0x98), P64RPC(0x38)}, +{P64RPC(0xa8), P64RPC(0x00), P64RPC(0x10)}, +{P64RPC(0x8c), P64RPC(0x00), P64RPC(0x74)}, +{P64RPC(0xfc), P64RPC(0x98), P64RPC(0x38)}, +{P64RPC(0x40), P64RPC(0x2c), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)}, +{P64RPC(0x3c), P64RPC(0xbc), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x80), P64RPC(0xd0), P64RPC(0x10)}, +{P64RPC(0x9c), P64RPC(0xfc), P64RPC(0xf0)}, +{P64RPC(0xc4), P64RPC(0xd4), P64RPC(0xfc)}, +{P64RPC(0xfc), P64RPC(0xbc), P64RPC(0xb0)}, +{P64RPC(0x20), P64RPC(0x38), P64RPC(0xec)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x58), P64RPC(0xf8), P64RPC(0x98)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)}, +{P64RPC(0xbc), P64RPC(0xbc), P64RPC(0xbc)}, +{P64RPC(0xf4), P64RPC(0x78), P64RPC(0xfc)}, +{P64RPC(0x24), P64RPC(0x18), P64RPC(0x8c)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xa8), P64RPC(0xe4), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x4c), P64RPC(0xdc), P64RPC(0x48)}, +{P64RPC(0x00), P64RPC(0xe8), P64RPC(0xd8)}, +{P64RPC(0x18), P64RPC(0x3c), P64RPC(0x5c)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x7c), P64RPC(0x08), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xc4), P64RPC(0xfc)}, +{P64RPC(0xa4), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x80), P64RPC(0x00), P64RPC(0xf0)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0xa8)}, +{P64RPC(0xfc), P64RPC(0x74), P64RPC(0x60)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x94), P64RPC(0x00)}, +{P64RPC(0xbc), P64RPC(0xbc), P64RPC(0xbc)}, +{P64RPC(0x00), P64RPC(0x50), P64RPC(0x00)}, +{P64RPC(0xe0), P64RPC(0xfc), P64RPC(0xa0)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)}, +{P64RPC(0xc8), P64RPC(0x4c), P64RPC(0x0c)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x70), P64RPC(0xec)}, +{P64RPC(0x00), P64RPC(0x44), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xe0), P64RPC(0xfc), P64RPC(0xa0)}, +{P64RPC(0xfc), P64RPC(0x74), P64RPC(0xb4)}, +{P64RPC(0x88), P64RPC(0x70), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, diff --git a/src/palettes/rp2c04002.h b/src/palettes/rp2c04002.h index a6e448c7..299c3eaf 100644 --- a/src/palettes/rp2c04002.h +++ b/src/palettes/rp2c04002.h @@ -1,64 +1,64 @@ -{0x00, 0x00, 0x00}, -{0xfc, 0x98, 0x38}, -{0x88, 0x70, 0x00}, -{0x00, 0x00, 0x00}, -{0xa8, 0xf0, 0xbc}, -{0xfc, 0x74, 0xb4}, -{0x00, 0x00, 0x00}, -{0xa8, 0xe4, 0xfc}, -{0xd8, 0x28, 0x00}, -{0x80, 0x00, 0xf0}, -{0xfc, 0xe4, 0xa0}, -{0xfc, 0xc4, 0xfc}, -{0xfc, 0xfc, 0xfc}, -{0x40, 0x88, 0xfc}, -{0x00, 0x00, 0x00}, -{0x00, 0x3c, 0x14}, -{0x00, 0x00, 0x00}, -{0x3c, 0xbc, 0xfc}, -{0xa4, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x90, 0x38}, -{0x80, 0xd0, 0x10}, -{0x00, 0x00, 0x00}, -{0x5c, 0x94, 0xfc}, -{0x00, 0x00, 0x00}, -{0xf4, 0x78, 0xfc}, -{0x00, 0x00, 0x00}, -{0x58, 0xf8, 0x98}, -{0x00, 0x00, 0x00}, -{0x40, 0x2c, 0x00}, -{0x00, 0x00, 0x00}, -{0x44, 0x00, 0x9c}, -{0x00, 0x00, 0x00}, -{0xfc, 0xbc, 0xb0}, -{0xfc, 0x74, 0x60}, -{0xd4, 0xc8, 0xfc}, -{0x00, 0x70, 0xec}, -{0x00, 0x00, 0x00}, -{0xbc, 0xbc, 0xbc}, -{0x00, 0x00, 0xa8}, -{0xbc, 0x00, 0xbc}, -{0x00, 0x00, 0x00}, -{0x74, 0x74, 0x74}, -{0x00, 0x44, 0x00}, -{0x20, 0x38, 0xec}, -{0x00, 0x00, 0x00}, -{0xfc, 0xd8, 0xa8}, -{0xfc, 0xfc, 0xfc}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x4c, 0xdc, 0x48}, -{0xc8, 0x4c, 0x0c}, -{0x18, 0x3c, 0x5c}, -{0x24, 0x18, 0x8c}, -{0xe4, 0x00, 0x58}, -{0x00, 0x94, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0xe8, 0xd8}, -{0x7c, 0x08, 0x00}, -{0xfc, 0xd8, 0xa8}, -{0x00, 0x00, 0x00}, -{0xa8, 0x00, 0x10}, -{0x00, 0x50, 0x00}, -{0x74, 0x74, 0x74}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0x98), P64RPC(0x38)}, +{P64RPC(0x88), P64RPC(0x70), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xa8), P64RPC(0xf0), P64RPC(0xbc)}, +{P64RPC(0xfc), P64RPC(0x74), P64RPC(0xb4)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xa8), P64RPC(0xe4), P64RPC(0xfc)}, +{P64RPC(0xd8), P64RPC(0x28), P64RPC(0x00)}, +{P64RPC(0x80), P64RPC(0x00), P64RPC(0xf0)}, +{P64RPC(0xfc), P64RPC(0xe4), P64RPC(0xa0)}, +{P64RPC(0xfc), P64RPC(0xc4), P64RPC(0xfc)}, +{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)}, +{P64RPC(0x40), P64RPC(0x88), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x3c), P64RPC(0x14)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x3c), P64RPC(0xbc), P64RPC(0xfc)}, +{P64RPC(0xa4), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x90), P64RPC(0x38)}, +{P64RPC(0x80), P64RPC(0xd0), P64RPC(0x10)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x5c), P64RPC(0x94), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xf4), P64RPC(0x78), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x58), P64RPC(0xf8), P64RPC(0x98)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x40), P64RPC(0x2c), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x44), P64RPC(0x00), P64RPC(0x9c)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xbc), P64RPC(0xb0)}, +{P64RPC(0xfc), P64RPC(0x74), P64RPC(0x60)}, +{P64RPC(0xd4), P64RPC(0xc8), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x70), P64RPC(0xec)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xbc), P64RPC(0xbc), P64RPC(0xbc)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0xa8)}, +{P64RPC(0xbc), P64RPC(0x00), P64RPC(0xbc)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)}, +{P64RPC(0x00), P64RPC(0x44), P64RPC(0x00)}, +{P64RPC(0x20), P64RPC(0x38), P64RPC(0xec)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)}, +{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x4c), P64RPC(0xdc), P64RPC(0x48)}, +{P64RPC(0xc8), P64RPC(0x4c), P64RPC(0x0c)}, +{P64RPC(0x18), P64RPC(0x3c), P64RPC(0x5c)}, +{P64RPC(0x24), P64RPC(0x18), P64RPC(0x8c)}, +{P64RPC(0xe4), P64RPC(0x00), P64RPC(0x58)}, +{P64RPC(0x00), P64RPC(0x94), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0xe8), P64RPC(0xd8)}, +{P64RPC(0x7c), P64RPC(0x08), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xa8), P64RPC(0x00), P64RPC(0x10)}, +{P64RPC(0x00), P64RPC(0x50), P64RPC(0x00)}, +{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)}, diff --git a/src/palettes/rp2c04003.h b/src/palettes/rp2c04003.h index 71170876..964a6d6f 100644 --- a/src/palettes/rp2c04003.h +++ b/src/palettes/rp2c04003.h @@ -1,64 +1,64 @@ -{0x44, 0x00, 0x9c}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x74, 0x74, 0x74}, -{0x00, 0xa8, 0x00}, -{0xfc, 0xfc, 0xfc}, -{0xa8, 0xe4, 0xfc}, -{0x00, 0x44, 0x00}, -{0x24, 0x18, 0x8c}, -{0x00, 0x00, 0x00}, -{0xfc, 0xbc, 0xb0}, -{0x40, 0x2c, 0x00}, -{0xe4, 0x00, 0x58}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0xfc, 0xfc, 0xfc}, -{0x5c, 0x94, 0xfc}, -{0x00, 0x80, 0x88}, -{0x00, 0x00, 0x00}, -{0x20, 0x38, 0xec}, -{0x00, 0x94, 0x00}, -{0x88, 0x70, 0x00}, -{0xc8, 0x4c, 0x0c}, -{0x00, 0x90, 0x38}, -{0x74, 0x74, 0x74}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0xa8}, -{0xd8, 0x28, 0x00}, -{0xa4, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0xfc, 0xc4, 0xd8}, -{0x40, 0x88, 0xfc}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0xfc, 0xd8, 0xa8}, -{0x00, 0x00, 0x00}, -{0xfc, 0x98, 0x38}, -{0xfc, 0x74, 0x60}, -{0xfc, 0xfc, 0xfc}, -{0x80, 0xd0, 0x10}, -{0x00, 0x00, 0x00}, -{0x3c, 0xbc, 0xfc}, -{0xf4, 0x78, 0xfc}, -{0x00, 0x70, 0xec}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0xe8, 0xd8}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x7c, 0x08, 0x00}, -{0x4c, 0xdc, 0x48}, -{0xf0, 0xbc, 0x3c}, -{0x00, 0x00, 0x00}, -{0x00, 0x50, 0x00}, -{0x00, 0x00, 0x00}, -{0xc4, 0xd4, 0xfc}, -{0xfc, 0xd8, 0xa8}, -{0x80, 0x00, 0xf0}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x18, 0x3c, 0x5c}, +{P64RPC(0x44), P64RPC(0x00), P64RPC(0x9c)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)}, +{P64RPC(0x00), P64RPC(0xa8), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)}, +{P64RPC(0xa8), P64RPC(0xe4), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x44), P64RPC(0x00)}, +{P64RPC(0x24), P64RPC(0x18), P64RPC(0x8c)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xbc), P64RPC(0xb0)}, +{P64RPC(0x40), P64RPC(0x2c), P64RPC(0x00)}, +{P64RPC(0xe4), P64RPC(0x00), P64RPC(0x58)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)}, +{P64RPC(0x5c), P64RPC(0x94), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x80), P64RPC(0x88)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x20), P64RPC(0x38), P64RPC(0xec)}, +{P64RPC(0x00), P64RPC(0x94), P64RPC(0x00)}, +{P64RPC(0x88), P64RPC(0x70), P64RPC(0x00)}, +{P64RPC(0xc8), P64RPC(0x4c), P64RPC(0x0c)}, +{P64RPC(0x00), P64RPC(0x90), P64RPC(0x38)}, +{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0xa8)}, +{P64RPC(0xd8), P64RPC(0x28), P64RPC(0x00)}, +{P64RPC(0xa4), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xc4), P64RPC(0xd8)}, +{P64RPC(0x40), P64RPC(0x88), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0x98), P64RPC(0x38)}, +{P64RPC(0xfc), P64RPC(0x74), P64RPC(0x60)}, +{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)}, +{P64RPC(0x80), P64RPC(0xd0), P64RPC(0x10)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x3c), P64RPC(0xbc), P64RPC(0xfc)}, +{P64RPC(0xf4), P64RPC(0x78), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x70), P64RPC(0xec)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0xe8), P64RPC(0xd8)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x7c), P64RPC(0x08), P64RPC(0x00)}, +{P64RPC(0x4c), P64RPC(0xdc), P64RPC(0x48)}, +{P64RPC(0xf0), P64RPC(0xbc), P64RPC(0x3c)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x50), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xc4), P64RPC(0xd4), P64RPC(0xfc)}, +{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)}, +{P64RPC(0x80), P64RPC(0x00), P64RPC(0xf0)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x18), P64RPC(0x3c), P64RPC(0x5c)}, diff --git a/src/palettes/rp2c05004.h b/src/palettes/rp2c05004.h index a50ed704..36ae702e 100644 --- a/src/palettes/rp2c05004.h +++ b/src/palettes/rp2c05004.h @@ -1,64 +1,64 @@ -{0x88, 0x70, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x80, 0x88}, -{0xf0, 0xbc, 0x3c}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x24, 0x18, 0x8c}, -{0xc8, 0x4c, 0x0c}, -{0xbc, 0xbc, 0xbc}, -{0x00, 0x00, 0x00}, -{0x4c, 0xdc, 0x48}, -{0x00, 0x00, 0x00}, -{0xfc, 0xbc, 0xb0}, -{0xfc, 0xd8, 0xa8}, -{0x00, 0xa8, 0x00}, -{0x00, 0x00, 0x00}, -{0xfc, 0x74, 0xb4}, -{0x00, 0x00, 0x00}, -{0x20, 0x38, 0xec}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0xfc, 0x74, 0x60}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x5c, 0x94, 0xfc}, -{0x00, 0x94, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0xa8, 0xf0, 0xbc}, -{0x3c, 0xbc, 0xfc}, -{0xa8, 0x00, 0x10}, -{0x00, 0x50, 0x00}, -{0x7c, 0x08, 0x00}, -{0x00, 0x00, 0xa8}, -{0x80, 0x00, 0xf0}, -{0x00, 0x00, 0x00}, -{0x74, 0x74, 0x74}, -{0xe4, 0x00, 0x58}, -{0x18, 0x3c, 0x5c}, -{0x00, 0x00, 0x00}, -{0x00, 0x70, 0xec}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0xfc, 0xe4, 0xa0}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0x40, 0x2c, 0x00}, -{0xd8, 0x28, 0x00}, -{0x00, 0x00, 0x00}, -{0x00, 0x00, 0x00}, -{0xfc, 0xfc, 0xfc}, -{0x9c, 0xfc, 0xf0}, -{0x00, 0x00, 0x00}, -{0xfc, 0x98, 0x38}, -{0x00, 0x00, 0x00}, -{0xa8, 0xe4, 0xfc}, -{0x80, 0xd0, 0x10}, -{0x00, 0x00, 0x00}, -{0xfc, 0xfc, 0xfc}, -{0x00, 0x44, 0x00}, +{P64RPC(0x88), P64RPC(0x70), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x80), P64RPC(0x88)}, +{P64RPC(0xf0), P64RPC(0xbc), P64RPC(0x3c)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x24), P64RPC(0x18), P64RPC(0x8c)}, +{P64RPC(0xc8), P64RPC(0x4c), P64RPC(0x0c)}, +{P64RPC(0xbc), P64RPC(0xbc), P64RPC(0xbc)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x4c), P64RPC(0xdc), P64RPC(0x48)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xbc), P64RPC(0xb0)}, +{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)}, +{P64RPC(0x00), P64RPC(0xa8), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0x74), P64RPC(0xb4)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x20), P64RPC(0x38), P64RPC(0xec)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0x74), P64RPC(0x60)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x5c), P64RPC(0x94), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x94), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xa8), P64RPC(0xf0), P64RPC(0xbc)}, +{P64RPC(0x3c), P64RPC(0xbc), P64RPC(0xfc)}, +{P64RPC(0xa8), P64RPC(0x00), P64RPC(0x10)}, +{P64RPC(0x00), P64RPC(0x50), P64RPC(0x00)}, +{P64RPC(0x7c), P64RPC(0x08), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0xa8)}, +{P64RPC(0x80), P64RPC(0x00), P64RPC(0xf0)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)}, +{P64RPC(0xe4), P64RPC(0x00), P64RPC(0x58)}, +{P64RPC(0x18), P64RPC(0x3c), P64RPC(0x5c)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x70), P64RPC(0xec)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xe4), P64RPC(0xa0)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x40), P64RPC(0x2c), P64RPC(0x00)}, +{P64RPC(0xd8), P64RPC(0x28), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)}, +{P64RPC(0x9c), P64RPC(0xfc), P64RPC(0xf0)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0x98), P64RPC(0x38)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xa8), P64RPC(0xe4), P64RPC(0xfc)}, +{P64RPC(0x80), P64RPC(0xd0), P64RPC(0x10)}, +{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)}, +{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)}, +{P64RPC(0x00), P64RPC(0x44), P64RPC(0x00)}, From d225d4863c0ebb85ff507a4b75ef7c242e87c134 Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 8 Aug 2022 21:19:45 -0400 Subject: [PATCH 19/48] make scmrev command work like desmume does (using system32 directory instead of sysnative). this probably fixes #459? or if not then desmume is broken, too. I'm not sure why the 32bit version can't be used every time. I think it can be. --- vc/vc14_fceux.vcxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vc/vc14_fceux.vcxproj b/vc/vc14_fceux.vcxproj index 29cb00b5..4611ee98 100644 --- a/vc/vc14_fceux.vcxproj +++ b/vc/vc14_fceux.vcxproj @@ -146,7 +146,7 @@ - "%windir%\Sysnative\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" + "%windir%\system32\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" Disabled @@ -186,7 +186,7 @@ xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z_64.dll" "$(OutDir)" - "%windir%\Sysnative\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" + "%windir%\system32\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" write current revision number to placeholders @@ -229,7 +229,7 @@ xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z_64.dll" "$(OutDir)" - "%windir%\Sysnative\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" + "%windir%\system32\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" write current revision number to placeholders @@ -298,7 +298,7 @@ xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z_64.dll" "$(OutDir)" lua51.dll;%(DelayLoadDLLs) - "%windir%\Sysnative\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" + "%windir%\system32\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z.dll" "$(OutDir)" @@ -335,7 +335,7 @@ xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z_64.dll" "$(OutDir)" lua51.dll;%(DelayLoadDLLs) - "%windir%\Sysnative\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" + "%windir%\system32\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z.dll" "$(OutDir)" @@ -372,7 +372,7 @@ xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z_64.dll" "$(OutDir)" lua51.dll;%(DelayLoadDLLs) - "%windir%\Sysnative\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" + "%windir%\system32\cscript" /nologo /E:JScript "defaultconfig\make_scmrev.h.js" xcopy /y /d "$(ProjectDir)\..\src\drivers\win\7z.dll" "$(OutDir)" From d834ac4e53635c0b03d464155a1b89711ae6db52 Mon Sep 17 00:00:00 2001 From: harry Date: Fri, 5 Aug 2022 06:45:10 -0400 Subject: [PATCH 20/48] Qt trace logger optimization. Added code to flush data to disk when emulation is paused. This allows the file to updated with latest data when hitting breakpoints during debugging. --- src/drivers/Qt/TraceLogger.cpp | 47 ++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/drivers/Qt/TraceLogger.cpp b/src/drivers/Qt/TraceLogger.cpp index 47528131..8107eee7 100644 --- a/src/drivers/Qt/TraceLogger.cpp +++ b/src/drivers/Qt/TraceLogger.cpp @@ -26,6 +26,7 @@ #ifdef WIN32 #include #else +#include #include #include #include @@ -111,8 +112,11 @@ static int recBufHead = 0; static int recBufNum = 0; static traceRecord_t *logBuf = NULL; static int logBufMax = 3000000; -static int logBufHead = 0; -static int logBufTail = 0; +// logBufHead and logBufTail are volatile because they are shared use by both the emulation and disk logger threads. +// Ensure that the compiler doesn't do any thread caching optimizations on them so that changes to these +// variables are immediately visible by the other thread. +static volatile int logBufHead = 0; +static volatile int logBufTail = 0; static bool overrunWarningArmed = true; static TraceLoggerDialog_t *traceLogWindow = NULL; static void pushMsgToLogBuffer(const char *msg); @@ -2515,6 +2519,8 @@ void TraceLogDiskThread_t::run(void) char buf[8192]; int i,idx=0; int blockSize = 4 * 1024; + bool dataNeedsFlush = true; + bool isPaused = false; //printf("Trace Log Disk Start\n"); @@ -2557,6 +2563,8 @@ void TraceLogDiskThread_t::run(void) while ( !isInterruptionRequested() ) { + isPaused = FCEUI_EmulationPaused() ? true : false; + while (logBufHead != logBufTail) { logBuf[logBufTail].convToText(line); @@ -2582,6 +2590,41 @@ void TraceLogDiskThread_t::run(void) } idx = 0; #endif + dataNeedsFlush = true; + } + } + + if (isPaused) + { + // If paused, the user might be at a breakpoint or doing some + // debugging. So make sure all data is flushed to disk for viewing. + // Only flush data when paused, to keep write efficiency up. + if ( idx > 0 ) + { + #ifdef WIN32 + DWORD bytesWritten; + WriteFile( logFile, buf, idx, &bytesWritten, NULL ); idx = 0; + #else + if ( write( logFile, buf, idx ) < 0 ) + { + // HANDLE ERROR TODO + } + idx = 0; + #endif + dataNeedsFlush = true; + } + if (dataNeedsFlush) + { + //printf("Flushing Trace Log Disk Buffers\n"); + #ifdef WIN32 + FlushFileBuffers( logFile ); + #else + if ( fsync( logFile ) ) + { + printf("Trace Log fsync error\n"); + } + #endif + dataNeedsFlush = false; } } SDL_Delay(1); From 32bd9a7f49e64fb3f06cd480be1faf0b8e2281b1 Mon Sep 17 00:00:00 2001 From: zeromus Date: Thu, 11 Aug 2022 23:16:29 -0400 Subject: [PATCH 21/48] supper mapper218 (fixes #447) --- src/boards/datalatch.cpp | 33 +++++++++++++++++++++++++++++++++ src/cart.h | 1 + src/ines.cpp | 7 ++++++- src/ines.h | 2 ++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/boards/datalatch.cpp b/src/boards/datalatch.cpp index 026354d3..69803a9c 100644 --- a/src/boards/datalatch.cpp +++ b/src/boards/datalatch.cpp @@ -474,6 +474,39 @@ void Mapper203_Init(CartInfo *info) { Latch_Init(info, M203Sync, 0, 0x8000, 0xFFFF, 0, 0); } +//------------------ Map 218 --------------------------- + +static void Mapper218_Power() +{ + //doesn't really matter + SetReadHandler(0x6000, 0xFFFF, &CartBROB); +} + +void Mapper218_Init(CartInfo *info) +{ + info->Power = &Mapper218_Power; + + //fixed PRG mapping + setprg32(0x8000, 0); + + //this mapper is supposed to interpret the iNES header bits specially + static const uint8 mirrorings[] = {MI_V,MI_H,MI_0,MI_1}; + SetupCartMirroring(mirrorings[info->mirrorAs2Bits],1,nullptr); + + //cryptic logic to effect the CHR RAM mappings by mapping 1k blocks to NTARAM according to how the pins are wired + //this could be done by bit logic, but this is self-documenting + static const uint8 mapping[] = { + 0,1,0,1,0,1,0,1, //mirrorAs2Bits==0 + 0,0,1,1,0,0,1,1, //mirrorAs2Bits==1 + 0,0,0,0,1,1,1,1, //mirrorAs2Bits==2 + 0,0,0,0,0,0,0,0 //mirrorAs2Bits==3 + }; + for(int i=0;i<8;i++) + VPageR[i] = &NTARAM[mapping[info->mirrorAs2Bits*8+i]]; + + PPUCHRRAM = 0xFF; +} + //------------------ Map 240 --------------------------- static void M240Sync(void) { diff --git a/src/cart.h b/src/cart.h index e78c87ea..ecc67948 100644 --- a/src/cart.h +++ b/src/cart.h @@ -15,6 +15,7 @@ typedef struct { // to help support games like "Karnov" // that are not really MMC3 but are // set to mapper 4. + int mirrorAs2Bits; int battery; // Presence of an actual battery. int ines2; int submapper; // Submappers as defined by NES 2.0 diff --git a/src/ines.cpp b/src/ines.cpp index a14b1add..c468df89 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -54,6 +54,7 @@ iNES_HEADER head; static CartInfo iNESCart; uint8 Mirroring = 0; +uint8 MirroringAs2bits = 0; uint32 ROM_size = 0; uint32 VROM_size = 0; char LoadedRomFName[2048]; //mbg merge 7/17/06 added @@ -673,7 +674,7 @@ BMAPPINGLocal bmap[] = { {"", 215, UNL8237_Init}, {"", 216, Mapper216_Init}, {"", 217, Mapper217_Init}, // Redefined to a new Discrete BMC mapper -// {"", 218, Mapper218_Init}, + {"", 218, Mapper218_Init}, {"UNLA9746", 219, UNLA9746_Init}, {"Debug Mapper", 220, QTAi_Init}, {"UNLN625092", 221, UNLN625092_Init}, @@ -766,6 +767,9 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { } else Mirroring = (head.ROM_type & 1); + MirroringAs2bits = head.ROM_type & 1; + if (head.ROM_type & 8) MirroringAs2bits |= 2; + int not_round_size; if (!iNES2) { not_round_size = head.ROM_size; @@ -918,6 +922,7 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { iNESCart.battery = (head.ROM_type & 2) ? 1 : 0; iNESCart.mirror = Mirroring; + iNESCart.mirrorAs2Bits = MirroringAs2bits; int result = iNES_Init(MapperNo); switch(result) diff --git a/src/ines.h b/src/ines.h index 5561aef9..315e54f0 100644 --- a/src/ines.h +++ b/src/ines.h @@ -43,6 +43,7 @@ extern uint8 *VROM; extern uint32 VROM_size; extern uint32 ROM_size; extern uint8 *ExtraNTARAM; +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 @@ -242,6 +243,7 @@ void Mapper213_Init(CartInfo *); void Mapper214_Init(CartInfo *); void Mapper216_Init(CartInfo *); void Mapper217_Init(CartInfo *); +void Mapper218_Init(CartInfo *); void Mapper220_Init(CartInfo *); void Mapper222_Init(CartInfo *); void Mapper225_Init(CartInfo *); From 3eddaf80525ca1a7b156179bf87e09c55386aee6 Mon Sep 17 00:00:00 2001 From: harry Date: Sun, 14 Aug 2022 20:15:50 -0400 Subject: [PATCH 22/48] Fixed Qt GUI --help command line option when no window system is present (X11/wayland). There is now a pre-gui initialization sweep of command line options. Also added a --version command line option and a warning that the --no-gui option is not supported (should someone try to use it). Fixes issue #528. --- src/drivers/Qt/fceuWrapper.cpp | 24 ++++++++++++++++++++---- src/drivers/Qt/fceuWrapper.h | 1 + src/drivers/Qt/main.cpp | 5 ++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index d701fcfb..8c5ef9e7 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -642,6 +642,7 @@ static const char *DriverUsage = static void ShowUsage(const char *prog) { int i,j; + FCEUD_Message("Starting " FCEU_NAME_AND_VERSION "...\n"); printf("\nUsage is as follows:\n%s filename\n\n",prog); puts(DriverUsage); #ifdef _S9XLUA_H @@ -681,11 +682,9 @@ static void ShowUsage(const char *prog) } -int fceuWrapperInit( int argc, char *argv[] ) +// Pre-GUI initialization. +int fceuWrapperPreInit( int argc, char *argv[] ) { - int opt, error; - std::string s; - for (int i=0; i Date: Fri, 19 Aug 2022 12:37:05 -0400 Subject: [PATCH 23/48] change cheat system name buffer management to use std::string to avoid issues caused by returning the name buffer to the user who could then use it in ways the cheat system didn't expect ultimately leading to invalid strcpy(X,X) calls and possible use of buffers after freeing. this will break all frontends probably (except for windows which I fixed at this time). fixes #512 --- src/cheat.cpp | 56 +++++++++++------------------------- src/cheat.h | 2 +- src/driver.h | 6 ++-- src/drivers/common/cheat.cpp | 13 +++++---- src/drivers/win/cheat.cpp | 33 +++++++++++---------- src/drivers/win/memview.cpp | 6 ++-- src/lua-engine.cpp | 4 +-- 7 files changed, 51 insertions(+), 69 deletions(-) diff --git a/src/cheat.cpp b/src/cheat.cpp index 708fe3a1..8ae0e985 100644 --- a/src/cheat.cpp +++ b/src/cheat.cpp @@ -152,28 +152,23 @@ int FCEU_CalcCheatAffectedBytes(uint32 address, uint32 size) { return count; } -static int AddCheatEntry(const char *name, uint32 addr, uint8 val, int compare, int status, int type); +static void AddCheatEntry(const char *name, uint32 addr, uint8 val, int compare, int status, int type); static void CheatMemErr(void) { FCEUD_PrintError("Error allocating memory for cheat data."); } -static int AddCheatEntry(const char *name, uint32 addr, uint8 val, int compare, int status, int type) +static void AddCheatEntry(const char *name, uint32 addr, uint8 val, int compare, int status, int type) { - struct CHEATF *temp; - if(!(temp = (struct CHEATF *)FCEU_dmalloc(sizeof(struct CHEATF)))) - { - CheatMemErr(); - return(0); - } + CHEATF *temp = new CHEATF(); - temp->name = strcpy((char*) FCEU_dmalloc(strlen(name) + 1), name); + temp->name = name; temp->addr = addr; temp->val = val; temp->status = status; temp->compare = compare; temp->type = type; - temp->next = 0; + temp->next = nullptr; if(cheats) { @@ -182,8 +177,6 @@ static int AddCheatEntry(const char *name, uint32 addr, uint8 val, int compare, } else cheats = cheatsl = temp; - - return (1); } /* The "override_existing" parameter is used only in cheat dialog import. @@ -306,14 +299,13 @@ void FCEU_SaveGameCheats(FILE* fp, int release) fputc(':', fp); if (next->compare >= 0) - fprintf(fp, "%04x:%02x:%02x:%s\n", next->addr, next->val, next->compare, next->name); + fprintf(fp, "%04x:%02x:%02x:%s\n", next->addr, next->val, next->compare, next->name.c_str()); else - fprintf(fp, "%04x:%02x:%s\n", next->addr, next->val, next->name); + fprintf(fp, "%04x:%02x:%s\n", next->addr, next->val, next->name.c_str()); - if (release) free(next->name); struct CHEATF *t = next; next = next->next; - if (release) free(t); + if (release) delete t; } } @@ -333,8 +325,7 @@ void FCEU_FlushGameCheats(FILE *override, int nosave) { struct CHEATF *last=next; next=next->next; - free(last->name); - free(last); + delete last; if(!next) break; } cheats=cheatsl=0; @@ -379,9 +370,7 @@ void FCEU_FlushGameCheats(FILE *override, int nosave) int FCEUI_AddCheat(const char *name, uint32 addr, uint8 val, int compare, int type) { - - if(!AddCheatEntry(name, addr, val, compare, 1, type)) - return 0; + AddCheatEntry(name, addr, val, compare, 1, type); savecheats = 1; RebuildSubCheats(); @@ -415,8 +404,7 @@ int FCEUI_DelCheat(uint32 which) else cheats=cheatsl=0; // No (more) cheats. } - free(cur->name); // Now that all references to this cheat are removed, - free(cur); // free the memory. + delete cur; // free the memory. break; } // *END REMOVE THIS CHEAT* @@ -451,18 +439,18 @@ void FCEU_ApplyPeriodicCheats(void) } -void FCEUI_ListCheats(int (*callb)(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data) +void FCEUI_ListCheats(int (*callb)(const char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data) { struct CHEATF *next=cheats; while(next) { - if(!callb(next->name,next->addr,next->val,next->compare,next->status,next->type,data)) break; + if(!callb(next->name.c_str(),next->addr,next->val,next->compare,next->status,next->type,data)) break; next=next->next; } } -int FCEUI_GetCheat(uint32 which, char **name, uint32 *a, uint8 *v, int *compare, int *s, int *type) +int FCEUI_GetCheat(uint32 which, std::string *name, uint32 *a, uint8 *v, int *compare, int *s, int *type) { struct CHEATF *next=cheats; uint32 x=0; @@ -600,7 +588,7 @@ int FCEUI_DecodePAR(const char *str, int *a, int *v, int *c, int *type) /* name can be NULL if the name isn't going to be changed. */ /* same goes for a, v, and s(except the values of each one must be <0) */ -int FCEUI_SetCheat(uint32 which, const char *name, int32 a, int32 v, int c, int s, int type) +int FCEUI_SetCheat(uint32 which, const std::string *name, int32 a, int32 v, int c, int s, int type) { struct CHEATF *next = cheats; uint32 x = 0; @@ -610,13 +598,7 @@ int FCEUI_SetCheat(uint32 which, const char *name, int32 a, int32 v, int c, int if(x == which) { if(name) - { - char *t; - if((t = (char *)realloc(next->name, strlen(name) + 1))) - strcpy(next->name = t, name); - else - return 0; - } + next->name = *name; if(a >= 0) next->addr = a; if(v >= 0) @@ -911,11 +893,7 @@ int FCEU_DeleteAllCheats(void) while (cur) { next = cur->next; - if ( cur->name ) - { - free(cur->name); - } - free(cur); + delete cur; cur = next; } cheats = cheatsl = 0; diff --git a/src/cheat.h b/src/cheat.h index 82037fc7..3e11e9d3 100644 --- a/src/cheat.h +++ b/src/cheat.h @@ -42,7 +42,7 @@ typedef struct { struct CHEATF { struct CHEATF *next; - char *name; + std::string name; uint16 addr; uint8 val; int compare; /* -1 for no compare. */ diff --git a/src/driver.h b/src/driver.h index e82f7445..6f183f06 100644 --- a/src/driver.h +++ b/src/driver.h @@ -207,10 +207,10 @@ void FCEUI_CheatSearchGetRange(uint32 first, uint32 last, int (*callb)(uint32 a, void FCEUI_CheatSearchGet(int (*callb)(uint32 a, uint8 last, uint8 current, void *data), void *data); void FCEUI_CheatSearchBegin(void); void FCEUI_CheatSearchEnd(int type, uint8 v1, uint8 v2); -void FCEUI_ListCheats(int (*callb)(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data); +void FCEUI_ListCheats(int (*callb)(const char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data); -int FCEUI_GetCheat(uint32 which, char **name, uint32 *a, uint8 *v, int *compare, int *s, int *type); -int FCEUI_SetCheat(uint32 which, const char *name, int32 a, int32 v, int compare,int s, int type); +int FCEUI_GetCheat(uint32 which, std::string *name, uint32 *a, uint8 *v, int *compare, int *s, int *type); +int FCEUI_SetCheat(uint32 which, const std::string *name, int32 a, int32 v, int compare,int s, int type); void FCEUI_CheatSearchShowExcluded(void); void FCEUI_CheatSearchSetCurrentAsOriginal(void); diff --git a/src/drivers/common/cheat.cpp b/src/drivers/common/cheat.cpp index 2cff0cd6..e6803f9d 100644 --- a/src/drivers/common/cheat.cpp +++ b/src/drivers/common/cheat.cpp @@ -199,7 +199,8 @@ static void ToggleCheat(int num) static void ModifyCheat(int num) { - char *name; + std::string name; + std::string *pName; char buf[256]; uint32 A; uint8 V; @@ -211,7 +212,7 @@ static void ModifyCheat(int num) FCEUI_GetCheat(num, &name, &A, &V, &compare, &s, &type); - printf("Name [%s]: ",name); + printf("Name [%s]: ",name.c_str()); GetString(buf,256); /* This obviously doesn't allow for cheats with no names. Bah. Who wants @@ -219,9 +220,9 @@ static void ModifyCheat(int num) */ if(buf[0]) - name=buf; // Change name when FCEUI_SetCheat() is called. + pName=&name; // Change name when FCEUI_SetCheat() is called. else - name=0; // Don't change name when FCEUI_SetCheat() is called. + pName=nullptr; // Don't change name when FCEUI_SetCheat() is called. printf("Address [$%04x]: ",(unsigned int)A); A=GetH16(A); @@ -240,7 +241,7 @@ static void ModifyCheat(int num) if(t=='Y' || t=='y') s=1; else if(t=='N' || t=='n') s=0; - FCEUI_SetCheat(num,name,A,V,compare,s,type); + FCEUI_SetCheat(num,pName,A,V,compare,s,type); } @@ -320,7 +321,7 @@ static void AddCheat(void) } static int lid; -static int clistcallb(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data) +static int clistcallb(const char *name, uint32 a, uint8 v, int compare, int s, int type, void *data) { char tmp[512]; int ret; diff --git a/src/drivers/win/cheat.cpp b/src/drivers/win/cheat.cpp index f2d6c83e..ce6ee616 100644 --- a/src/drivers/win/cheat.cpp +++ b/src/drivers/win/cheat.cpp @@ -108,7 +108,7 @@ char *U8ToStr(uint8 a) } //int RedoCheatsCallB(char *name, uint32 a, uint8 v, int s) { //bbit edited: this commented out line was changed to the below for the new fceud -int RedoCheatsCallB(char *name, uint32 a, uint8 v, int c, int s, int type, void* data) +int RedoCheatsCallB(const char *name, uint32 a, uint8 v, int c, int s, int type, void* data) { char str[256] = { 0 }; GetCheatStr(str, a, v, c); @@ -123,7 +123,7 @@ int RedoCheatsCallB(char *name, uint32 a, uint8 v, int c, int s, int type, void* else lvi.iItem = SendDlgItemMessage(hCheat, IDC_LIST_CHEATS, LVM_INSERTITEM, 0, (LPARAM)&lvi); lvi.iSubItem = 1; - lvi.pszText = name; + lvi.pszText = (LPSTR)name; SendDlgItemMessage(hCheat, IDC_LIST_CHEATS, LVM_SETITEM, 0, (LPARAM)&lvi); lvi.mask = LVIF_STATE; @@ -483,11 +483,12 @@ INT_PTR CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA lvi.stateMask = LVIS_STATEIMAGEMASK; int tmpsel = SendDlgItemMessage(hCheat, IDC_LIST_CHEATS, LVM_GETNEXTITEM, -1, LVNI_ALL | LVNI_SELECTED); - char* name = ""; int s; + std::string name; + int s; while (tmpsel != -1) { FCEUI_GetCheat(tmpsel, &name, NULL, NULL, NULL, &s, NULL); - FCEUI_SetCheat(tmpsel, name, -1, -1, -2, s ^= 1, 1); + FCEUI_SetCheat(tmpsel, &name, -1, -1, -2, s ^= 1, 1); lvi.iItem = tmpsel; lvi.state = INDEXTOSTATEIMAGEMASK(s ? 2 : 1); @@ -645,12 +646,14 @@ INT_PTR CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA if (selcheat < 0) break; - char name[256]; uint32 a; uint8 v; int s; int c; - GetUICheatInfo(hwndDlg, name, &a, &v, &c); + std::string name; uint32 a; uint8 v; int s; int c; + char namebuf[256] = {0}; + GetUICheatInfo(hwndDlg, namebuf, &a, &v, &c); + name = namebuf; - FCEUI_SetCheat(selcheat, name, a, v, c, -1, 1); - FCEUI_GetCheat(selcheat, NULL, &a, &v, &c, &s, NULL); - RedoCheatsCallB(name, a, v, c, s, 1, &selcheat); + FCEUI_SetCheat(selcheat, &name, a, v, c, -1, 1); + FCEUI_GetCheat(selcheat, nullptr, &a, &v, &c, &s, NULL); + RedoCheatsCallB(name.c_str(), a, v, c, s, 1, &selcheat); SendDlgItemMessage(hwndDlg, IDC_LIST_CHEATS, LVM_SETSELECTIONMARK, 0, selcheat); SetDlgItemText(hwndDlg, IDC_CHEAT_ADDR, (LPCSTR)U16ToStr(a)); @@ -902,9 +905,9 @@ INT_PTR CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA selcheat = pNMListView->iItem; if (selcheat >= 0) { - char* name = ""; uint32 a; uint8 v; int s; int c; + std::string name; uint32 a; uint8 v; int s; int c; FCEUI_GetCheat(selcheat, &name, &a, &v, &c, &s, NULL); - SetDlgItemText(hwndDlg, IDC_CHEAT_NAME, (LPCSTR)name); + SetDlgItemText(hwndDlg, IDC_CHEAT_NAME, (LPCSTR)name.c_str()); SetDlgItemText(hwndDlg, IDC_CHEAT_ADDR, (LPCSTR)U16ToStr(a)); SetDlgItemText(hwndDlg, IDC_CHEAT_VAL, (LPCSTR)U8ToStr(v)); SetDlgItemText(hwndDlg, IDC_CHEAT_COM, (LPCSTR)(c == -1 ? "" : U8ToStr(c))); @@ -930,11 +933,11 @@ INT_PTR CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA pNMListView->uNewState & INDEXTOSTATEIMAGEMASK(2)) { int tmpsel = pNMListView->iItem; - char* name = ""; int s; + std::string name; int s; FCEUI_GetCheat(tmpsel, &name, NULL, NULL, NULL, &s, NULL); if (!s) { - FCEUI_SetCheat(tmpsel, name, -1, -1, -2, s ^= 1, 1); + FCEUI_SetCheat(tmpsel, &name, -1, -1, -2, s ^= 1, 1); UpdateCheatRelatedWindow(); UpdateCheatListGroupBoxUI(); } @@ -944,11 +947,11 @@ INT_PTR CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA pNMListView->uNewState & INDEXTOSTATEIMAGEMASK(1)) { int tmpsel = pNMListView->iItem; - char* name = ""; int s; + std::string name; int s; FCEUI_GetCheat(tmpsel, &name, NULL, NULL, NULL, &s, NULL); if (s) { - FCEUI_SetCheat(tmpsel, name, -1, -1, -2, s ^= 1, 1); + FCEUI_SetCheat(tmpsel, &name, -1, -1, -2, s ^= 1, 1); UpdateCheatRelatedWindow(); UpdateCheatListGroupBoxUI(); diff --git a/src/drivers/win/memview.cpp b/src/drivers/win/memview.cpp index 7c8af67d..2ad44edf 100644 --- a/src/drivers/win/memview.cpp +++ b/src/drivers/win/memview.cpp @@ -822,7 +822,7 @@ void UpdateColorTable() int addrtodelete; // This is a very ugly hackish method of doing this int cheatwasdeleted; // but it works and that is all that matters here. -int DeleteCheatCallB(char *name, uint32 a, uint8 v, int compare,int s,int type, void *data){ //mbg merge 6/29/06 - added arg +int DeleteCheatCallB(const char *name, uint32 a, uint8 v, int compare,int s,int type, void *data){ //mbg merge 6/29/06 - added arg if(cheatwasdeleted == -1)return 1; cheatwasdeleted++; if(a == addrtodelete){ @@ -901,7 +901,7 @@ void UnfreezeAllRam() { int i=0; - char * Cname; + std::string Cname; uint32 Caddr; int Ctype; @@ -919,7 +919,7 @@ void UnfreezeAllRam() { // would be added by the freeze command. Manual unfreeze should let them // make that mistake once or twice, in case they like it that way. FCEUI_GetCheat(i,&Cname,&Caddr,NULL,NULL,NULL,&Ctype); - if ((Cname[0] == '\0') && ((Caddr < 0x2000) || ((Caddr >= 0x6000) && (Caddr < 0x8000))) && (Ctype == 1)) { + if ((Cname.empty()) && ((Caddr < 0x2000) || ((Caddr >= 0x6000) && (Caddr < 0x8000))) && (Ctype == 1)) { // Already Added, so consider it a success FreezeRam(Caddr,-1,1); diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index b647831b..e5212fac 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -773,7 +773,7 @@ static int emu_delgamegenie(lua_State *L) { int GGaddr, GGcomp, GGval; uint32 i=0; - char * Cname; + std::string Cname; uint32 Caddr; uint8 Cval; int Ccompare, Ctype; @@ -786,7 +786,7 @@ static int emu_delgamegenie(lua_State *L) { while (FCEUI_GetCheat(i,&Cname,&Caddr,&Cval,&Ccompare,NULL,&Ctype)) { - if ((!strcmp(msg,Cname)) && (GGaddr == Caddr) && (GGval == Cval) && (GGcomp == Ccompare) && (Ctype == 1)) { + if ((Cname == msg) && (GGaddr == Caddr) && (GGval == Cval) && (GGcomp == Ccompare) && (Ctype == 1)) { // Delete cheat code if (FCEUI_DelCheat(i)) { lua_pushboolean(L, true); From f4ea3363492f71505f627bd133202ea8d51ffc1c Mon Sep 17 00:00:00 2001 From: harry Date: Fri, 19 Aug 2022 19:57:27 -0400 Subject: [PATCH 24/48] Qt GUI fixes for recent changes to fceu core cheats API. --- src/drivers/Qt/CheatsConf.cpp | 17 +++++------------ src/drivers/Qt/CheatsConf.h | 2 +- src/drivers/Qt/HexEditor.cpp | 2 +- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/drivers/Qt/CheatsConf.cpp b/src/drivers/Qt/CheatsConf.cpp index f9af2ad1..d995700d 100644 --- a/src/drivers/Qt/CheatsConf.cpp +++ b/src/drivers/Qt/CheatsConf.cpp @@ -670,7 +670,7 @@ void GuiCheatsDialog_t::lessThanValueCallback(void) FCEU_WRAPPER_UNLOCK(); } //---------------------------------------------------------------------------- -int GuiCheatsDialog_t::activeCheatListCB(char *name, uint32 a, uint8 v, int c, int s, int type, void *data) +int GuiCheatsDialog_t::activeCheatListCB(const char *name, uint32 a, uint8 v, int c, int s, int type, void *data) { QTreeWidgetItem *item; char codeStr[32]; @@ -710,7 +710,7 @@ int GuiCheatsDialog_t::activeCheatListCB(char *name, uint32 a, uint8 v, int c, i return 1; } //---------------------------------------------------------------------------- -static int activeCheatListCB(char *name, uint32 a, uint8 v, int c, int s, int type, void *data) +static int activeCheatListCB(const char *name, uint32 a, uint8 v, int c, int s, int type, void *data) { return win->activeCheatListCB(name, a, v, c, s, type, data); } @@ -971,7 +971,7 @@ void GuiCheatsDialog_t::updateCheatParameters(void) FCEU_WRAPPER_LOCK(); - FCEUI_SetCheat(row, name.c_str(), a, v, c, s, type); + FCEUI_SetCheat(row, &name, a, v, c, s, type); FCEU_WRAPPER_UNLOCK(); @@ -983,7 +983,7 @@ void GuiCheatsDialog_t::actvCheatItemClicked(QTreeWidgetItem *item, int column) uint32 a = 0; uint8 v = 0; int c = -1, s = 0, type = 0; - char *name = NULL; + std::string name; char stmp[64]; int row = actvCheatList->indexOfTopLevelItem(item); @@ -1021,14 +1021,7 @@ void GuiCheatsDialog_t::actvCheatItemClicked(QTreeWidgetItem *item, int column) cheatCmpEntry->setText(tr("")); } - if (name != NULL) - { - cheatNameEntry->setText(tr(name)); - } - else - { - cheatNameEntry->setText(tr("")); - } + cheatNameEntry->setText(tr(name.c_str())); } //---------------------------------------------------------------------------- void GuiCheatsDialog_t::globalEnableCheats(int state) diff --git a/src/drivers/Qt/CheatsConf.h b/src/drivers/Qt/CheatsConf.h index 40b2836a..c06e9f75 100644 --- a/src/drivers/Qt/CheatsConf.h +++ b/src/drivers/Qt/CheatsConf.h @@ -30,7 +30,7 @@ public: int addSearchResult(uint32_t a, uint8_t last, uint8_t current); - int activeCheatListCB(char *name, uint32 a, uint8 v, int c, int s, int type, void *data); + int activeCheatListCB(const char *name, uint32 a, uint8 v, int c, int s, int type, void *data); void showActiveCheatList(bool redraw); diff --git a/src/drivers/Qt/HexEditor.cpp b/src/drivers/Qt/HexEditor.cpp index ed78bf07..b7f1931c 100644 --- a/src/drivers/Qt/HexEditor.cpp +++ b/src/drivers/Qt/HexEditor.cpp @@ -3243,7 +3243,7 @@ void QHexEdit::addBookMarkCB(void) } } //---------------------------------------------------------------------------- -static int RamFreezeCB(char *name, uint32 a, uint8 v, int compare,int s,int type, void *data) +static int RamFreezeCB(const char *name, uint32 a, uint8 v, int compare,int s,int type, void *data) { return ((QHexEdit*)data)->FreezeRam( name, a, v, compare, s, type ); } From f3b33a628ff436f54028c7a905cb25893649ae99 Mon Sep 17 00:00:00 2001 From: harry Date: Fri, 19 Aug 2022 22:33:09 -0400 Subject: [PATCH 25/48] Minor fixes for warnings found by gcc undefined behavior sanitizer. --- src/CMakeLists.txt | 1 + src/drivers/Qt/ppuViewer.cpp | 2 +- src/movie.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dad47fd2..8ef081d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -87,6 +87,7 @@ else(WIN32) if ( ${ASAN_ENABLE} ) add_definitions( -fsanitize=address -fsanitize=bounds-strict ) + add_definitions( -fsanitize=undefined -fno-sanitize=vptr ) set( ASAN_LDFLAGS -lasan -lubsan) message( STATUS "Address Sanitizer Enabled" ) else() diff --git a/src/drivers/Qt/ppuViewer.cpp b/src/drivers/Qt/ppuViewer.cpp index 101e26de..d151da42 100644 --- a/src/drivers/Qt/ppuViewer.cpp +++ b/src/drivers/Qt/ppuViewer.cpp @@ -1133,7 +1133,7 @@ void ppuPatternView_t::paintEvent(QPaintEvent *event) xx = 0; yy = 0; - showSelector = (cycleCount < 20); + showSelector = (cycleCount < 20) && (selTile.x() >= 0) && (selTile.y() >= 0); if ( mode == 1 ) { diff --git a/src/movie.cpp b/src/movie.cpp index 6e6140cd..9bc3eb99 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -409,6 +409,7 @@ MovieData::MovieData() , rerecordCount(0) , binaryFlag(false) , loadFrameCount(-1) + , fourscore(false) , microphone(false) , RAMInitOption(0) , RAMInitSeed(0) From f7e7773b5ab7599eb30c10e4b90c356d4542d068 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sat, 20 Aug 2022 20:18:45 -0400 Subject: [PATCH 26/48] add a hotkey to disable active cheats (windows port only, but adding elsewhere would be easy now). fixes #504 --- src/drivers/win/cheat.cpp | 2 ++ src/input.cpp | 13 +++++++++++++ src/input.h | 2 ++ 3 files changed, 17 insertions(+) diff --git a/src/drivers/win/cheat.cpp b/src/drivers/win/cheat.cpp index ce6ee616..0153d281 100644 --- a/src/drivers/win/cheat.cpp +++ b/src/drivers/win/cheat.cpp @@ -1084,6 +1084,8 @@ void UpdateCheatListGroupBoxUI() SetDlgItemText(hCheat, IDC_GROUPBOX_CHEATLIST, temp); EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_EXPORTTOFILE), cheats != 0); + + CheckDlgButton(hCheat,IDC_CHEAT_GLOBAL_SWITCH,globalCheatDisabled?BST_UNCHECKED:BST_CHECKED); } //Used by cheats and external dialogs such as hex editor to update items in the cheat search dialog diff --git a/src/input.cpp b/src/input.cpp index 530f6948..c1dcd536 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -798,6 +798,7 @@ static void RamSearchOpLTE(void); static void RamSearchOpGTE(void); static void RamSearchOpEQ(void); static void RamSearchOpNE(void); +static void ToggleCheats(void); static void DebuggerStepInto(void); static void FA_SkipLag(void); static void OpenRom(void); @@ -945,6 +946,7 @@ struct EMUCMDTABLE FCEUI_CommandTable[]= { EMUCMD_TOOL_RAMSEARCHGTE, EMUCMDTYPE_TOOL, RamSearchOpGTE, 0, 0, "Ram Search - Greater Than or Equal", 0}, { EMUCMD_TOOL_RAMSEARCHEQ, EMUCMDTYPE_TOOL, RamSearchOpEQ, 0, 0, "Ram Search - Equal", 0}, { EMUCMD_TOOL_RAMSEARCHNE, EMUCMDTYPE_TOOL, RamSearchOpNE, 0, 0, "Ram Search - Not Equal", 0}, + { EMUCMD_TOOL_TOGGLECHEATS, EMUCMDTYPE_TOOL, ToggleCheats, 0, 0, "Toggle Cheats", 0}, { EMUCMD_RERECORD_DISPLAY_TOGGLE, EMUCMDTYPE_MISC, FCEUI_MovieToggleRerecordDisplay,0, 0, "Toggle Rerecord Display", EMUCMDFLAG_TASEDITOR }, { EMUCMD_TASEDITOR_REWIND, EMUCMDTYPE_TASEDITOR, TaseditorRewindOn, TaseditorRewindOff, 0, "Frame Rewind", EMUCMDFLAG_TASEDITOR }, @@ -1268,6 +1270,17 @@ static void RamSearchOpNE(void) { #endif } +extern int globalCheatDisabled; +static void ToggleCheats() +{ + FCEUI_GlobalToggleCheat(globalCheatDisabled); + FCEU_DispMessage("%d cheats active", 0, FrozenAddressCount); + #ifdef __WIN_DRIVER__ + UpdateCheatRelatedWindow(); + UpdateCheatListGroupBoxUI(); + #endif +} + static void DebuggerStepInto() { #ifdef __WIN_DRIVER__ diff --git a/src/input.h b/src/input.h index 0f89fca9..9928839f 100644 --- a/src/input.h +++ b/src/input.h @@ -259,6 +259,8 @@ enum EMUCMD EMUCMD_MOVIE_RECORD_MODE_OVERWRITE, EMUCMD_MOVIE_RECORD_MODE_INSERT, + EMUCMD_TOOL_TOGGLECHEATS, + EMUCMD_MAX }; From 6b8387b849cfcc7229b7b85ec24ae24670858641 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sat, 20 Aug 2022 21:49:30 -0400 Subject: [PATCH 27/48] fix compile errors on linux, probably --- src/input.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input.cpp b/src/input.cpp index c1dcd536..592d5e50 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1271,6 +1271,7 @@ static void RamSearchOpNE(void) { } extern int globalCheatDisabled; +extern unsigned int FrozenAddressCount; static void ToggleCheats() { FCEUI_GlobalToggleCheat(globalCheatDisabled); From 319b365787926a031d6e429d2b1299e85ff0f625 Mon Sep 17 00:00:00 2001 From: harry Date: Sun, 21 Aug 2022 14:57:03 -0400 Subject: [PATCH 28/48] Cheats config improvements for Qt GUI. Added global cheat enable/disable hotkey functionality. Added code to raise and set focus on cheat dialog when attempting to open it when it is already opened. Add code to update/refresh cheat dialog when loading a new ROM. --- src/drivers/Qt/CheatsConf.cpp | 29 ++++++++++++++++++++++++++++- src/drivers/Qt/CheatsConf.h | 1 + src/drivers/Qt/ConsoleWindow.cpp | 15 +++++++++++++++ src/drivers/Qt/ConsoleWindow.h | 1 + src/drivers/Qt/config.cpp | 3 +++ src/drivers/Qt/config.h | 2 +- src/drivers/Qt/fceuWrapper.cpp | 3 +++ 7 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/drivers/Qt/CheatsConf.cpp b/src/drivers/Qt/CheatsConf.cpp index d995700d..79cc3c60 100644 --- a/src/drivers/Qt/CheatsConf.cpp +++ b/src/drivers/Qt/CheatsConf.cpp @@ -52,6 +52,9 @@ void openCheatDialog(QWidget *parent) { if (win != NULL) { + win->activateWindow(); + win->raise(); + win->setFocus(); return; } win = new GuiCheatsDialog_t(parent); @@ -198,6 +201,18 @@ GuiCheatsDialog_t::GuiCheatsDialog_t(QWidget *parent) vbox1->addLayout(hbox); + hbox = new QHBoxLayout(); + lbl = new QLabel(tr("Type:")); + typeEntry = new QComboBox(); + typeEntry->addItem(tr("0: Periodic Set (Every Frame)"), 0 ); + typeEntry->addItem(tr("1: Substitute/Freeze"), 1 ); + typeEntry->setCurrentIndex(1); + + hbox->addWidget(lbl,1); + hbox->addWidget(typeEntry,10); + + vbox1->addLayout(hbox); + hbox = new QHBoxLayout(); addCheatBtn = new QPushButton(tr("Add")); @@ -435,6 +450,8 @@ GuiCheatsDialog_t::GuiCheatsDialog_t(QWidget *parent) setLayout(mainLayout); + modCheatBtn->setDefault(true); + connect(srchResetBtn, SIGNAL(clicked(void)), this, SLOT(resetSearchCallback(void))); connect(knownValBtn, SIGNAL(clicked(void)), this, SLOT(knownValueCallback(void))); connect(eqValBtn, SIGNAL(clicked(void)), this, SLOT(equalValueCallback(void))); @@ -719,6 +736,8 @@ void GuiCheatsDialog_t::showActiveCheatList(bool redraw) { win = this; + enaCheats->setChecked(!globalCheatDisabled); + actvCheatRedraw = redraw; if (redraw) @@ -871,6 +890,7 @@ void GuiCheatsDialog_t::addActvCheat(void) uint32 a = 0; uint8 v = 0; int c = -1; + int t = 1; std::string name, cmpStr; a = strtoul(cheatAddrEntry->displayText().toStdString().c_str(), NULL, 16); @@ -890,8 +910,10 @@ void GuiCheatsDialog_t::addActvCheat(void) name = cheatNameEntry->text().toStdString(); + t = typeEntry->currentData().toInt(); + FCEU_WRAPPER_LOCK(); - FCEUI_AddCheat(name.c_str(), a, v, c, 1); + FCEUI_AddCheat(name.c_str(), a, v, c, t); FCEU_WRAPPER_UNLOCK(); showActiveCheatList(true); @@ -921,6 +943,7 @@ void GuiCheatsDialog_t::deleteActvCheat(void) cheatAddrEntry->setText(tr("")); cheatValEntry->setText(tr("")); cheatCmpEntry->setText(tr("")); + typeEntry->setCurrentIndex(0); } //---------------------------------------------------------------------------- void GuiCheatsDialog_t::updateCheatParameters(void) @@ -969,6 +992,8 @@ void GuiCheatsDialog_t::updateCheatParameters(void) //printf("Name: %s \n", name.c_str() ); + type = typeEntry->currentData().toInt(); + FCEU_WRAPPER_LOCK(); FCEUI_SetCheat(row, &name, a, v, c, s, type); @@ -1022,6 +1047,8 @@ void GuiCheatsDialog_t::actvCheatItemClicked(QTreeWidgetItem *item, int column) } cheatNameEntry->setText(tr(name.c_str())); + + typeEntry->setCurrentIndex(type); } //---------------------------------------------------------------------------- void GuiCheatsDialog_t::globalEnableCheats(int state) diff --git a/src/drivers/Qt/CheatsConf.h b/src/drivers/Qt/CheatsConf.h index c06e9f75..4eab63a9 100644 --- a/src/drivers/Qt/CheatsConf.h +++ b/src/drivers/Qt/CheatsConf.h @@ -67,6 +67,7 @@ protected: QLineEdit *neValEntry; QLineEdit *grValEntry; QLineEdit *ltValEntry; + QComboBox *typeEntry; QFont font; int fontCharWidth; diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 9332dac4..23e4bf40 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -862,6 +862,7 @@ void consoleWin_t::initHotKeys(void) connect( Hotkeys[ HK_TOGGLE_BG ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleBackground(void)) ); connect( Hotkeys[ HK_TOGGLE_FG ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleForeground(void)) ); connect( Hotkeys[ HK_FKB_ENABLE ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleFamKeyBrdEnable(void)) ); + connect( Hotkeys[ HK_TOGGLE_ALL_CHEATS ].getShortcut(), SIGNAL(activated()), this, SLOT(toggleGlobalCheatEnable(void)) ); connect( Hotkeys[ HK_SAVE_STATE_0 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState0(void)) ); connect( Hotkeys[ HK_SAVE_STATE_1 ].getShortcut(), SIGNAL(activated()), this, SLOT(saveState1(void)) ); @@ -3173,6 +3174,20 @@ void consoleWin_t::toggleFamKeyBrdEnable(void) toggleFamilyKeyboardFunc(); } +extern int globalCheatDisabled; + +void consoleWin_t::toggleGlobalCheatEnable(void) +{ + FCEU_WRAPPER_LOCK(); + FCEUI_GlobalToggleCheat(globalCheatDisabled); + FCEU_WRAPPER_UNLOCK(); + + g_config->setOption("SDL.CheatsDisabled", globalCheatDisabled); + g_config->save(); + + updateCheatDialog(); +} + void consoleWin_t::warnAmbiguousShortcut( QShortcut *shortcut) { char stmp[256]; diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 4586e06b..d4451965 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -415,6 +415,7 @@ class consoleWin_t : public QMainWindow void toggleBackground(void); void toggleForeground(void); void toggleFamKeyBrdEnable(void); + void toggleGlobalCheatEnable(void); void saveState0(void); void saveState1(void); void saveState2(void); diff --git a/src/drivers/Qt/config.cpp b/src/drivers/Qt/config.cpp index 386571ee..25442b96 100644 --- a/src/drivers/Qt/config.cpp +++ b/src/drivers/Qt/config.cpp @@ -83,6 +83,9 @@ int getHotKeyConfig( int i, const char **nameOut, const char **keySeqOut, const case HK_CHEAT_MENU: name = "CheatMenu"; keySeq = ""; title = "Open Cheat Window"; group = "Tools"; break; + case HK_TOGGLE_ALL_CHEATS: + name = "ToggleCheats"; keySeq = ""; title = "Toggle Global Cheat Enable"; group = "Tools"; + break; case HK_BIND_STATE: name = "BindState"; keySeq = ""; title = "Bind Save State to Movie"; group = "Movie"; break; diff --git a/src/drivers/Qt/config.h b/src/drivers/Qt/config.h index 0bb68e78..d719f12d 100644 --- a/src/drivers/Qt/config.h +++ b/src/drivers/Qt/config.h @@ -53,7 +53,7 @@ enum HOTKEY { // Display HK_TOGGLE_FG, HK_TOGGLE_BG, HK_TOGGLE_INPUT_DISPLAY, HK_LAG_COUNTER_DISPLAY, - HK_CHEAT_MENU, HK_LOAD_LUA, + HK_CHEAT_MENU, HK_TOGGLE_ALL_CHEATS, HK_LOAD_LUA, HK_MUTE_CAPTURE, HK_FA_LAG_SKIP, HK_VOLUME_DOWN, HK_VOLUME_UP, diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 8c5ef9e7..12790b69 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -39,6 +39,7 @@ #include "Qt/unix-netplay.h" #include "Qt/AviRecord.h" #include "Qt/HexEditor.h" +#include "Qt/CheatsConf.h" #include "Qt/SymbolicDebug.h" #include "Qt/CodeDataLogger.h" #include "Qt/ConsoleDebugger.h" @@ -352,6 +353,8 @@ int LoadGame(const char *path, bool silent) debugSymbolTable.loadGameSymbols(); + updateCheatDialog(); + CDLoggerROMChanged(); int state_to_load; From 26c3919358d1fd20b1b14b544e0ff0169347acb7 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 21 Aug 2022 15:06:03 -0400 Subject: [PATCH 29/48] winport: tidy edit control sanitization --- src/drivers/win/window.cpp | 431 +++++++++++++++++++------------------ src/drivers/win/window.h | 16 +- 2 files changed, 226 insertions(+), 221 deletions(-) diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index d2ba531e..72e03fa9 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -3283,6 +3283,198 @@ POINT CalcSubWindowPos(HWND hDlg, POINT* conf) return pt; } +bool IsInputLegal(bool (*IsLetterLegal)(char letter), char letter) +{ + return !IsLetterLegal || letter == VK_BACK || GetKeyState(VK_CONTROL) & 0x8000 || IsLetterLegal(letter); +} + +bool IsLetterLegalGG(char letter) +{ + char ch = toupper(letter); + for (int i = 0; GameGenieLetters[i]; ++i) + if (GameGenieLetters[i] == ch) + return true; + return false; +} + +bool IsLetterLegalHex(char letter) +{ + return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f'; +} + +bool IsLetterLegalMemwatchAddress(char letter) +{ + //accept normal hex stuff + if(letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f') + return true; + + //accept prefixes + if(letter == 'x' || letter == 'X' || letter == '!') + return true; + + return false; +} + +bool IsLetterLegalHexList(char letter) +{ + return IsLetterLegalHex(letter) || letter == ',' || letter == ' '; +} + +bool IsLetterLegalCheat(char letter) +{ + return letter >= '0' && letter <= ':' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '?'; +} + +bool IsLetterLegalSize(char letter) +{ + return letter >= '0' && letter <= '9' || letter == 'm' || letter == 'M' || letter == 'k' || letter == 'K' || letter == 'b' || letter == 'B'; +} + +bool IsLetterLegalDec(char letter) +{ + return letter >= '0' && letter <= '9' || letter == '-' || letter == '+'; +} + +bool IsLetterLegalFloat(char letter) +{ + return letter >= '0' && letter <= '9' || letter == '.' || letter == '-' || letter == '+'; +} + +bool IsLetterLegalDecHexMixed(char letter) +{ + return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$' || letter == '-' || letter == '+'; +} + +bool IsLetterLegalUnsignedDecHexMixed(char letter) +{ + return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$'; +} + +wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter)) +{ + if (IsLetterLegal == &IsLetterLegalGG) + return L"You can only type Game Genie characters:\nA P Z L G I T Y E O X U K S V N"; + if (IsLetterLegal == &IsLetterLegalHex) + return L"You can only type characters for hexadecimal number (0-9,A-F)."; + if (IsLetterLegal == &IsLetterLegalHexList) + return L"You can only type characters for hexademical number (0-9,A-F), each number is separated by a comma (,)"; + if (IsLetterLegal == &IsLetterLegalCheat) + return + L"The cheat code comes into the following 2 formats:\n" + "AAAA:VV freezes the value in Address $AAAA to $VV.\n" + "AAAA?CC:VV changes the value in Address $AAAA to $VV only when it's $CC.\n" + "All the characters are hexadecimal number (0-9,A-F).\n"; + if (IsLetterLegal == &IsLetterLegalFloat) + return L"You can only type decimal number (decimal point is acceptable)."; + if (IsLetterLegal == &IsLetterLegalSize) + return L"You can only type decimal number followed with B, KB or MB."; + if (IsLetterLegal == &IsLetterLegalDec) + return L"You can only type decimal number (sign character is acceptable)."; + if (IsLetterLegal == &IsLetterLegalDecHexMixed) + return + L"You can only type decimal or hexademical number\n" + "(sign character is acceptable).\n\n" + "When your number contains letter A-F,\n" + "it is regarded as hexademical number,\n" + "however, if you want to express a heademical number\n" + "but all the digits are in 0-9,\n" + "you must add a $ prefix to prevent ambiguous.\n" + "eg. 10 is a decimal number,\n" + "$10 means a hexademical number that is 16 in decimal."; + if (IsLetterLegal == &IsLetterLegalUnsignedDecHexMixed) + return + L"You can only type decimal or hexademical number.\n\n" + "When your number contains letter A-F,\n" + "it is regarded as hexademical number,\n" + "however, if you want to express a heademical number\n" + "but all the digits are in 0-9,\n" + "you must add a $ prefix to prevent ambiguous.\n" + "eg. 10 is a decimal number,\n" + "$10 means a hexademical number that is 16 in decimal."; + + return L"Your input contains invalid characters."; +} + +// return a letter legal checking function for the specified control with the given id +IsLetterLegalProc GetIsLetterLegalProc(UINT id) +{ + switch (id) + { + // Game genie text in Cheat and Game Genie Encoder/Decoder + case IDC_CHEAT_GAME_GENIE_TEXT: + case IDC_GAME_GENIE_CODE: + return &IsLetterLegalGG; + + // Addresses in Debugger + case IDC_DEBUGGER_VAL_PCSEEK: + case IDC_DEBUGGER_VAL_PC: + case IDC_DEBUGGER_VAL_A: + case IDC_DEBUGGER_VAL_X: + case IDC_DEBUGGER_VAL_Y: + case IDC_DEBUGGER_BOOKMARK: + + // Debugger -> Add breakpoint + case IDC_ADDBP_ADDR_START: case IDC_ADDBP_ADDR_END: + + // Array Size, Init value in Symbolic Name in Debugger + case IDC_EDIT_SYMBOLIC_ARRAY: case IDC_EDIT_SYMBOLIC_INIT: + + // Address, Value, Compare, Known Value, Note equal, Greater than and Less than in Cheat + case IDC_CHEAT_ADDR: case IDC_CHEAT_VAL: case IDC_CHEAT_COM: + case IDC_CHEAT_VAL_KNOWN: case IDC_CHEAT_VAL_NE_BY: + case IDC_CHEAT_VAL_GT_BY: case IDC_CHEAT_VAL_LT_BY: + + // Address, Value and Compare in Game Genie Encoder/Decoder + case IDC_GAME_GENIE_ADDR: case IDC_GAME_GENIE_VAL: case IDC_GAME_GENIE_COMP: + + // Address controls in Memory watch + case MW_ADDR00: case MW_ADDR01: case MW_ADDR02: case MW_ADDR03: + case MW_ADDR04: case MW_ADDR05: case MW_ADDR06: case MW_ADDR07: + case MW_ADDR08: case MW_ADDR09: case MW_ADDR10: case MW_ADDR11: + case MW_ADDR12: case MW_ADDR13: case MW_ADDR14: case MW_ADDR15: + case MW_ADDR16: case MW_ADDR17: case MW_ADDR18: case MW_ADDR19: + case MW_ADDR20: case MW_ADDR21: case MW_ADDR22: case MW_ADDR23: + return &IsLetterLegalMemwatchAddress; + + case IDC_EDIT_COMPAREADDRESS: + return &IsLetterLegalHex; + + // Specific Address in RAM Search + // RAM Watch / RAM Search / Cheat -> Add watch (current only in adding watch operation) + case IDC_EDIT_COMPAREADDRESSES: + return &IsLetterLegalHexList; + + // Size multiplier and TV Aspect in Video Config + case IDC_WINSIZE_MUL_X: case IDC_WINSIZE_MUL_Y: + case IDC_TVASPECT_X: case IDC_TVASPECT_Y: + return &IsLetterLegalFloat; + + // Cheat code in Cheat + case IDC_CHEAT_TEXT: + return &IsLetterLegalCheat; + + // PRG ROM, PRG RAM, PRG NVRAM, CHR ROM, CHR RAM and CHR NVRAM in NES Header Editor + case IDC_PRGROM_EDIT: case IDC_PRGRAM_EDIT: case IDC_PRGNVRAM_EDIT: + case IDC_CHRROM_EDIT: case IDC_CHRRAM_EDIT: case IDC_CHRNVRAM_EDIT: + return &IsLetterLegalSize; + + // Specific value, Different by and Modulo in RAM search + case IDC_EDIT_COMPAREVALUE: + case IDC_EDIT_DIFFBY: + case IDC_EDIT_MODBY: + { + extern char rs_t; + switch (rs_t) + { + case 's': return &IsLetterLegalDecHexMixed; + case 'u': return &IsLetterLegalUnsignedDecHexMixed; + case 'h': return &IsLetterLegalHex; + } + } + } + return NULL; +} + LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP) { bool through = true; @@ -3291,131 +3483,53 @@ LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP) switch (msg) { case WM_PASTE: - { - - bool (*IsLetterLegal)(char) = GetIsLetterLegal(GetDlgCtrlID(hwnd)); - - if (IsLetterLegal) { - if (OpenClipboard(hwnd)) + + bool (*IsLetterLegal)(char) = GetIsLetterLegalProc(GetDlgCtrlID(hwnd)); + + if (IsLetterLegal) { - HANDLE handle = GetClipboardData(CF_TEXT); - if (handle) + if (OpenClipboard(hwnd)) { - - // get the original clipboard string - char* clipStr = (char*)GlobalLock(handle); - - // check if the text in clipboard has illegal characters - int len = strlen(clipStr); - for (int i = 0; i < len; ++i) + HANDLE handle = GetClipboardData(CF_TEXT); + if (handle) { - if (!IsLetterLegal(clipStr[i])) + + // get the original clipboard string + char* clipStr = (char*)GlobalLock(handle); + + // check if the text in clipboard has illegal characters + int len = strlen(clipStr); + for (int i = 0; i < len; ++i) { - through = false; - // Show Edit control tip, just like the control with ES_NUMBER do - ShowLetterIllegalBalloonTip(hwnd, IsLetterLegal); - break; + if (!IsLetterLegal(clipStr[i])) + { + through = false; + // Show Edit control tip, just like the control with ES_NUMBER do + ShowLetterIllegalBalloonTip(hwnd, IsLetterLegal); + break; + } } + GlobalUnlock(handle); + CloseClipboard(); } - GlobalUnlock(handle); - CloseClipboard(); } } } - } - break; + break; + case WM_CHAR: - { - bool(*IsLetterLegal)(char) = GetIsLetterLegal(GetDlgCtrlID(hwnd)); - through = IsInputLegal(IsLetterLegal, wP); - if (!through) - ShowLetterIllegalBalloonTip(hwnd, IsLetterLegal); - } + { + IsLetterLegalProc isLetterLegal = GetIsLetterLegalProc(GetDlgCtrlID(hwnd)); + through = IsInputLegal(isLetterLegal, wP); + if (!through) + ShowLetterIllegalBalloonTip(hwnd, isLetterLegal); + } } return through ? CallWindowProc(DefaultEditCtrlProc, hwnd, msg, wP, lP) : result; } -// return a letter legal checking function for the specified control with the given id -bool inline (*GetIsLetterLegal(UINT id))(char letter) -{ - switch (id) - { - - // Game genie text in Cheat and Game Genie Encoder/Decoder - case IDC_CHEAT_GAME_GENIE_TEXT: - case IDC_GAME_GENIE_CODE: - return IsLetterLegalGG; - - // Addresses in Debugger - case IDC_DEBUGGER_VAL_PCSEEK: - case IDC_DEBUGGER_VAL_PC: - case IDC_DEBUGGER_VAL_A: - case IDC_DEBUGGER_VAL_X: - case IDC_DEBUGGER_VAL_Y: - case IDC_DEBUGGER_BOOKMARK: - - // Debugger -> Add breakpoint - case IDC_ADDBP_ADDR_START: case IDC_ADDBP_ADDR_END: - - // Array Size, Init value in Symbolic Name in Debugger - case IDC_EDIT_SYMBOLIC_ARRAY: case IDC_EDIT_SYMBOLIC_INIT: - - // Address, Value, Compare, Known Value, Note equal, Greater than and Less than in Cheat - case IDC_CHEAT_ADDR: case IDC_CHEAT_VAL: case IDC_CHEAT_COM: - case IDC_CHEAT_VAL_KNOWN: case IDC_CHEAT_VAL_NE_BY: - case IDC_CHEAT_VAL_GT_BY: case IDC_CHEAT_VAL_LT_BY: - - // Address, Value and Compare in Game Genie Encoder/Decoder - case IDC_GAME_GENIE_ADDR: case IDC_GAME_GENIE_VAL: case IDC_GAME_GENIE_COMP: - - // Address controls in Memory watch - case MW_ADDR00: case MW_ADDR01: case MW_ADDR02: case MW_ADDR03: - case MW_ADDR04: case MW_ADDR05: case MW_ADDR06: case MW_ADDR07: - case MW_ADDR08: case MW_ADDR09: case MW_ADDR10: case MW_ADDR11: - case MW_ADDR12: case MW_ADDR13: case MW_ADDR14: case MW_ADDR15: - case MW_ADDR16: case MW_ADDR17: case MW_ADDR18: case MW_ADDR19: - case MW_ADDR20: case MW_ADDR21: case MW_ADDR22: case MW_ADDR23: - case IDC_EDIT_COMPAREADDRESS: - return IsLetterLegalHex; - - // Specific Address in RAM Search - // RAM Watch / RAM Search / Cheat -> Add watch (current only in adding watch operation) - case IDC_EDIT_COMPAREADDRESSES: - return IsLetterLegalHexList; - - // Size multiplier and TV Aspect in Video Config - case IDC_WINSIZE_MUL_X: case IDC_WINSIZE_MUL_Y: - case IDC_TVASPECT_X: case IDC_TVASPECT_Y: - return IsLetterLegalFloat; - - // Cheat code in Cheat - case IDC_CHEAT_TEXT: - return IsLetterLegalCheat; - - // PRG ROM, PRG RAM, PRG NVRAM, CHR ROM, CHR RAM and CHR NVRAM in NES Header Editor - case IDC_PRGROM_EDIT: case IDC_PRGRAM_EDIT: case IDC_PRGNVRAM_EDIT: - case IDC_CHRROM_EDIT: case IDC_CHRRAM_EDIT: case IDC_CHRNVRAM_EDIT: - return IsLetterLegalSize; - - // Specific value, Different by and Modulo in RAM search - case IDC_EDIT_COMPAREVALUE: - case IDC_EDIT_DIFFBY: - case IDC_EDIT_MODBY: - { - extern char rs_t; - switch (rs_t) - { - case 's': return IsLetterLegalDecHexMixed; - case 'u': return IsLetterLegalUnsignedDecHexMixed; - case 'h': return IsLetterLegalHex; - } - } - } - return NULL; -} - void ShowLetterIllegalBalloonTip(HWND hwnd, bool(*IsLetterLegal)(char letter)) { wchar_t* title = L"Unacceptable Character"; @@ -3431,102 +3545,3 @@ void ShowLetterIllegalBalloonTip(HWND hwnd, bool(*IsLetterLegal)(char letter)) // make a sound MessageBeep(0xFFFFFFFF); } - -inline wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter)) -{ - if (IsLetterLegal == IsLetterLegalGG) - return L"You can only type Game Genie characters:\nA P Z L G I T Y E O X U K S V N"; - if (IsLetterLegal == IsLetterLegalHex) - return L"You can only type characters for hexadecimal number (0-9,A-F)."; - if (IsLetterLegal == IsLetterLegalHexList) - return L"You can only type characters for hexademical number (0-9,A-F), each number is separated by a comma (,)"; - if (IsLetterLegal == IsLetterLegalCheat) - return - L"The cheat code comes into the following 2 formats:\n" - "AAAA:VV freezes the value in Address $AAAA to $VV.\n" - "AAAA?CC:VV changes the value in Address $AAAA to $VV only when it's $CC.\n" - "All the characters are hexadecimal number (0-9,A-F).\n"; - if (IsLetterLegal == IsLetterLegalFloat) - return L"You can only type decimal number (decimal point is acceptable)."; - if (IsLetterLegal == IsLetterLegalSize) - return L"You can only type decimal number followed with B, KB or MB."; - if (IsLetterLegal == IsLetterLegalDec) - return L"You can only type decimal number (sign character is acceptable)."; - if (IsLetterLegal == IsLetterLegalDecHexMixed) - return - L"You can only type decimal or hexademical number\n" - "(sign character is acceptable).\n\n" - "When your number contains letter A-F,\n" - "it is regarded as hexademical number,\n" - "however, if you want to express a heademical number\n" - "but all the digits are in 0-9,\n" - "you must add a $ prefix to prevent ambiguous.\n" - "eg. 10 is a decimal number,\n" - "$10 means a hexademical number that is 16 in decimal."; - if (IsLetterLegal == IsLetterLegalUnsignedDecHexMixed) - return - L"You can only type decimal or hexademical number.\n\n" - "When your number contains letter A-F,\n" - "it is regarded as hexademical number,\n" - "however, if you want to express a heademical number\n" - "but all the digits are in 0-9,\n" - "you must add a $ prefix to prevent ambiguous.\n" - "eg. 10 is a decimal number,\n" - "$10 means a hexademical number that is 16 in decimal."; - - return L"Your input contains invalid characters."; -} - -inline bool IsInputLegal(bool (*IsLetterLegal)(char letter), char letter) -{ - return !IsLetterLegal || letter == VK_BACK || GetKeyState(VK_CONTROL) & 0x8000 || IsLetterLegal(letter); -} - -inline bool IsLetterLegalGG(char letter) -{ - char ch = toupper(letter); - for (int i = 0; GameGenieLetters[i]; ++i) - if (GameGenieLetters[i] == ch) - return true; - return false; -} - -inline bool IsLetterLegalHex(char letter) -{ - return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f'; -} - -inline bool IsLetterLegalHexList(char letter) -{ - return IsLetterLegalHex(letter) || letter == ',' || letter == ' '; -} - -inline bool IsLetterLegalCheat(char letter) -{ - return letter >= '0' && letter <= ':' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '?'; -} - -inline bool IsLetterLegalSize(char letter) -{ - return letter >= '0' && letter <= '9' || letter == 'm' || letter == 'M' || letter == 'k' || letter == 'K' || letter == 'b' || letter == 'B'; -} - -inline bool IsLetterLegalDec(char letter) -{ - return letter >= '0' && letter <= '9' || letter == '-' || letter == '+'; -} - -inline bool IsLetterLegalFloat(char letter) -{ - return letter >= '0' && letter <= '9' || letter == '.' || letter == '-' || letter == '+'; -} - -inline bool IsLetterLegalDecHexMixed(char letter) -{ - return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$' || letter == '-' || letter == '+'; -} - -inline bool IsLetterLegalUnsignedDecHexMixed(char letter) -{ - return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$'; -} diff --git a/src/drivers/win/window.h b/src/drivers/win/window.h index 0127ad97..28d10a0a 100644 --- a/src/drivers/win/window.h +++ b/src/drivers/win/window.h @@ -128,19 +128,9 @@ struct HOTKEYMENUINDEX { void UpdateMenuHotkeys(FCEUMENU_INDEX index); int GetCurrentContextIndex(); -inline bool (*GetIsLetterLegal(UINT id))(char letter); -inline wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter)); -void ShowLetterIllegalBalloonTip(HWND hwnd, bool(*IsLetterLegal)(char letter)); -inline bool IsInputLegal(bool(*IsLetterLegal)(char letter), char letter); -inline bool IsLetterLegalGG(char letter); -inline bool IsLetterLegalHex(char letter); -inline bool IsLetterLegalHexList(char letter); -inline bool IsLetterLegalCheat(char letter); -inline bool IsLetterLegalDec(char letter); -inline bool IsLetterLegalSize(char letter); -inline bool IsLetterLegalFloat(char letter); -inline bool IsLetterLegalDecHexMixed(char letter); -inline bool IsLetterLegalUnsignedDecHexMixed(char letter); +typedef bool (*IsLetterLegalProc)(char); +bool IsLetterLegalHex(char letter); +void ShowLetterIllegalBalloonTip(HWND hwnd, IsLetterLegalProc); extern WNDPROC DefaultEditCtrlProc; extern LRESULT APIENTRY FilterEditCtrlProc(HWND hDlg, UINT msg, WPARAM wP, LPARAM lP); From f6f13d6843c112c8c8a473bb2f589ef760ef13f1 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 21 Aug 2022 15:25:13 -0400 Subject: [PATCH 30/48] winport - change input filter functions to take an index so they can search for a prefix (at index 0 perhaps) and use it on the memwatch. it's better to do these things based on strings and not chars but that's just how we have it setup for now --- src/drivers/win/debuggersp.cpp | 20 +++++----- src/drivers/win/debuggersp.h | 1 - src/drivers/win/monitor.cpp | 3 +- src/drivers/win/window.cpp | 68 ++++++++++++++++++---------------- src/drivers/win/window.h | 4 +- 5 files changed, 51 insertions(+), 45 deletions(-) diff --git a/src/drivers/win/debuggersp.cpp b/src/drivers/win/debuggersp.cpp index 1f78660f..8cf8c093 100644 --- a/src/drivers/win/debuggersp.cpp +++ b/src/drivers/win/debuggersp.cpp @@ -21,6 +21,7 @@ #include "common.h" #include "utils/xstring.h" #include "debuggersp.h" +#include "window.h" #include "../../fceu.h" #include "../../debug.h" #include "../../conddebug.h" @@ -60,6 +61,7 @@ bool symbRegNames = true; int debuggerWasActive = 0; char temp_chr[40] = {0}; char delimiterChar[2] = "#"; + INT_PTR CALLBACK nameDebuggerBookmarkCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); extern WNDPROC DefaultEditCtrlProc; @@ -153,10 +155,10 @@ int parseLine(char* line, Name* n) if (llen == 5) // Offset size of normal lines of the form $XXXX { if (line[0] != '$' - || !IsLetterLegalHex(line[1]) - || !IsLetterLegalHex(line[2]) - || !IsLetterLegalHex(line[3]) - || !IsLetterLegalHex(line[4]) + || !IsLetterLegalHex(0,line[1]) + || !IsLetterLegalHex(1,line[2]) + || !IsLetterLegalHex(2,line[3]) + || !IsLetterLegalHex(3,line[4]) ) { return 4; @@ -166,10 +168,10 @@ int parseLine(char* line, Name* n) { int i; if (line[0] != '$' - || !IsLetterLegalHex(line[1]) - || !IsLetterLegalHex(line[2]) - || !IsLetterLegalHex(line[3]) - || !IsLetterLegalHex(line[4]) + || !IsLetterLegalHex(0,line[1]) + || !IsLetterLegalHex(1,line[2]) + || !IsLetterLegalHex(2,line[3]) + || !IsLetterLegalHex(3,line[4]) || line[5] != '/' ) { @@ -178,7 +180,7 @@ int parseLine(char* line, Name* n) for (i=6;line[i];i++) { - if (!IsLetterLegalHex(line[i])) + if (!IsLetterLegalHex(i,line[i])) { return 6; } diff --git a/src/drivers/win/debuggersp.h b/src/drivers/win/debuggersp.h index 01b7d907..3bd04d65 100644 --- a/src/drivers/win/debuggersp.h +++ b/src/drivers/win/debuggersp.h @@ -61,7 +61,6 @@ void DeleteAllDebuggerBookmarks(); void FillDebuggerBookmarkListbox(HWND hwnd); void GoToDebuggerBookmark(HWND hwnd); -extern bool IsLetterLegalHex(char c); bool DoSymbolicDebugNaming(int offset, HWND parentHWND); bool DoSymbolicDebugNaming(int offset, int size, HWND parentHWND); diff --git a/src/drivers/win/monitor.cpp b/src/drivers/win/monitor.cpp index 376e96e5..037f5b73 100644 --- a/src/drivers/win/monitor.cpp +++ b/src/drivers/win/monitor.cpp @@ -3,6 +3,7 @@ #include "debugger.h" #include "debuggersp.h" #include "memwatch.h" +#include "window.h" #include "../../fceu.h" #include "../../debug.h" #include "../../conddebug.h" @@ -120,7 +121,7 @@ BOOL updateResults(HWND hwndDlg, int rule) for (unsigned int j=0;j= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f'; } -bool IsLetterLegalMemwatchAddress(char letter) +bool IsLetterLegalMemwatchAddress(int index, char letter) { //accept normal hex stuff if(letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f') return true; //accept prefixes - if(letter == 'x' || letter == 'X' || letter == '!') - return true; + if(index == 0) + { + if(letter == 'x' || letter == 'X' || letter == '!') + return true; + } return false; } -bool IsLetterLegalHexList(char letter) +bool IsLetterLegalHexList(int index, char letter) { - return IsLetterLegalHex(letter) || letter == ',' || letter == ' '; + return IsLetterLegalHex(index,letter) || letter == ',' || letter == ' '; } -bool IsLetterLegalCheat(char letter) +bool IsLetterLegalCheat(int index, char letter) { return letter >= '0' && letter <= ':' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '?'; } -bool IsLetterLegalSize(char letter) +bool IsLetterLegalSize(int index, char letter) { return letter >= '0' && letter <= '9' || letter == 'm' || letter == 'M' || letter == 'k' || letter == 'K' || letter == 'b' || letter == 'B'; } -bool IsLetterLegalDec(char letter) +bool IsLetterLegalDec(int index, char letter) { return letter >= '0' && letter <= '9' || letter == '-' || letter == '+'; } -bool IsLetterLegalFloat(char letter) +bool IsLetterLegalFloat(int index, char letter) { return letter >= '0' && letter <= '9' || letter == '.' || letter == '-' || letter == '+'; } -bool IsLetterLegalDecHexMixed(char letter) +bool IsLetterLegalDecHexMixed(int index, char letter) { return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$' || letter == '-' || letter == '+'; } -bool IsLetterLegalUnsignedDecHexMixed(char letter) +bool IsLetterLegalUnsignedDecHexMixed(int index, char letter) { return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$'; } -wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter)) +wchar_t* GetLetterIllegalErrMsg(IsLetterLegalProc proc) { - if (IsLetterLegal == &IsLetterLegalGG) + if (proc == &IsLetterLegalGG) return L"You can only type Game Genie characters:\nA P Z L G I T Y E O X U K S V N"; - if (IsLetterLegal == &IsLetterLegalHex) + if (proc == &IsLetterLegalHex) return L"You can only type characters for hexadecimal number (0-9,A-F)."; - if (IsLetterLegal == &IsLetterLegalHexList) + if (proc == &IsLetterLegalHexList) return L"You can only type characters for hexademical number (0-9,A-F), each number is separated by a comma (,)"; - if (IsLetterLegal == &IsLetterLegalCheat) + if (proc == &IsLetterLegalCheat) return L"The cheat code comes into the following 2 formats:\n" "AAAA:VV freezes the value in Address $AAAA to $VV.\n" "AAAA?CC:VV changes the value in Address $AAAA to $VV only when it's $CC.\n" "All the characters are hexadecimal number (0-9,A-F).\n"; - if (IsLetterLegal == &IsLetterLegalFloat) + if (proc == &IsLetterLegalFloat) return L"You can only type decimal number (decimal point is acceptable)."; - if (IsLetterLegal == &IsLetterLegalSize) + if (proc == &IsLetterLegalSize) return L"You can only type decimal number followed with B, KB or MB."; - if (IsLetterLegal == &IsLetterLegalDec) + if (proc == &IsLetterLegalDec) return L"You can only type decimal number (sign character is acceptable)."; - if (IsLetterLegal == &IsLetterLegalDecHexMixed) + if (proc == &IsLetterLegalDecHexMixed) return L"You can only type decimal or hexademical number\n" "(sign character is acceptable).\n\n" @@ -3381,7 +3384,7 @@ wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter)) "you must add a $ prefix to prevent ambiguous.\n" "eg. 10 is a decimal number,\n" "$10 means a hexademical number that is 16 in decimal."; - if (IsLetterLegal == &IsLetterLegalUnsignedDecHexMixed) + if (proc == &IsLetterLegalUnsignedDecHexMixed) return L"You can only type decimal or hexademical number.\n\n" "When your number contains letter A-F,\n" @@ -3485,9 +3488,9 @@ LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP) case WM_PASTE: { - bool (*IsLetterLegal)(char) = GetIsLetterLegalProc(GetDlgCtrlID(hwnd)); + IsLetterLegalProc isLetterLegal = GetIsLetterLegalProc(GetDlgCtrlID(hwnd)); - if (IsLetterLegal) + if (isLetterLegal) { if (OpenClipboard(hwnd)) { @@ -3502,11 +3505,11 @@ LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP) int len = strlen(clipStr); for (int i = 0; i < len; ++i) { - if (!IsLetterLegal(clipStr[i])) + if (!isLetterLegal(i,clipStr[i])) { through = false; // Show Edit control tip, just like the control with ES_NUMBER do - ShowLetterIllegalBalloonTip(hwnd, IsLetterLegal); + ShowLetterIllegalBalloonTip(hwnd, isLetterLegal); break; } } @@ -3520,8 +3523,9 @@ LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP) case WM_CHAR: { + int len = GetWindowTextLength(hwnd); IsLetterLegalProc isLetterLegal = GetIsLetterLegalProc(GetDlgCtrlID(hwnd)); - through = IsInputLegal(isLetterLegal, wP); + through = IsInputLegal(isLetterLegal, len, wP); if (!through) ShowLetterIllegalBalloonTip(hwnd, isLetterLegal); } @@ -3530,10 +3534,10 @@ LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP) return through ? CallWindowProc(DefaultEditCtrlProc, hwnd, msg, wP, lP) : result; } -void ShowLetterIllegalBalloonTip(HWND hwnd, bool(*IsLetterLegal)(char letter)) +void ShowLetterIllegalBalloonTip(HWND hwnd, IsLetterLegalProc proc) { wchar_t* title = L"Unacceptable Character"; - wchar_t* msg = GetLetterIllegalErrMsg(IsLetterLegal); + wchar_t* msg = GetLetterIllegalErrMsg(proc); EDITBALLOONTIP tip; tip.cbStruct = sizeof(EDITBALLOONTIP); diff --git a/src/drivers/win/window.h b/src/drivers/win/window.h index 28d10a0a..da716a69 100644 --- a/src/drivers/win/window.h +++ b/src/drivers/win/window.h @@ -128,8 +128,8 @@ struct HOTKEYMENUINDEX { void UpdateMenuHotkeys(FCEUMENU_INDEX index); int GetCurrentContextIndex(); -typedef bool (*IsLetterLegalProc)(char); -bool IsLetterLegalHex(char letter); +typedef bool (*IsLetterLegalProc)(int index, char ch); +bool IsLetterLegalHex(int index, char letter); void ShowLetterIllegalBalloonTip(HWND hwnd, IsLetterLegalProc); extern WNDPROC DefaultEditCtrlProc; From 5230d2eacd5b64b0ebf2d6c1af3ee6edcc82d3a3 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 21 Aug 2022 15:28:06 -0400 Subject: [PATCH 31/48] winport - change memwatch addresses to support lower case (partial revert of f0396ef980a8a72d39fd5541c2d04ba497162915) --- src/drivers/win/res.rc | 48 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index 2b467b92..88d77f03 100644 --- a/src/drivers/win/res.rc +++ b/src/drivers/win/res.rc @@ -684,53 +684,53 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN GROUPBOX "",IDC_STATIC,3,0,126,200 GROUPBOX "",IDC_STATIC,131,0,128,200 - EDITTEXT MW_ADDR00,6,17,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR00,6,17,30,14,0 EDITTEXT MW_NAME00,41,17,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR01,6,32,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR01,6,32,30,14,0 EDITTEXT MW_NAME01,41,32,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR02,6,47,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR02,6,47,30,14,0 EDITTEXT MW_NAME02,41,47,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR03,6,62,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR03,6,62,30,14,0 EDITTEXT MW_NAME03,41,62,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR04,6,77,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR04,6,77,30,14,0 EDITTEXT MW_NAME04,41,77,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR05,6,92,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR05,6,92,30,14,0 EDITTEXT MW_NAME05,41,92,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR06,6,107,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR06,6,107,30,14,0 EDITTEXT MW_NAME06,41,107,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR07,6,122,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR07,6,122,30,14,0 EDITTEXT MW_NAME07,41,122,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR08,6,137,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR08,6,137,30,14,0 EDITTEXT MW_NAME08,41,137,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR09,6,152,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR09,6,152,30,14,0 EDITTEXT MW_NAME09,41,152,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR10,6,167,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR10,6,167,30,14,0 EDITTEXT MW_NAME10,41,167,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR11,6,182,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR11,6,182,30,14,0 EDITTEXT MW_NAME11,41,182,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR12,135,17,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR12,135,17,30,14,0 EDITTEXT MW_NAME12,171,17,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR13,135,32,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR13,135,32,30,14,0 EDITTEXT MW_NAME13,171,32,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR14,135,47,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR14,135,47,30,14,0 EDITTEXT MW_NAME14,171,47,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR15,135,62,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR15,135,62,30,14,0 EDITTEXT MW_NAME15,171,62,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR16,135,77,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR16,135,77,30,14,0 EDITTEXT MW_NAME16,171,77,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR17,135,92,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR17,135,92,30,14,0 EDITTEXT MW_NAME17,171,92,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR18,135,107,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR18,135,107,30,14,0 EDITTEXT MW_NAME18,171,107,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR19,135,122,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR19,135,122,30,14,0 EDITTEXT MW_NAME19,171,122,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR20,135,137,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR20,135,137,30,14,0 EDITTEXT MW_NAME20,171,137,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR21,135,152,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR21,135,152,30,14,0 EDITTEXT MW_NAME21,171,152,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR22,135,167,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR22,135,167,30,14,0 EDITTEXT MW_NAME22,171,167,55,14,ES_AUTOHSCROLL - EDITTEXT MW_ADDR23,135,182,30,14,ES_UPPERCASE + EDITTEXT MW_ADDR23,135,182,30,14,0 EDITTEXT MW_NAME23,171,182,55,14,ES_AUTOHSCROLL LTEXT "Name",IDC_STATIC,41,7,20,8 LTEXT "Address",IDC_STATIC,6,7,26,8 From 7806b24388291a15b5cda04531c23ed417339ab7 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 21 Aug 2022 15:35:45 -0400 Subject: [PATCH 32/48] winport - fix prefix checking on memwatch addresses (fixes #496) --- src/drivers/win/window.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index b3f7d64b..3effd90d 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -3523,9 +3523,10 @@ LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP) case WM_CHAR: { - int len = GetWindowTextLength(hwnd); + DWORD cpBegin, cpEnd; + SendMessage(hwnd, EM_GETSEL, (LPARAM)&cpBegin, (LPARAM)&cpEnd); IsLetterLegalProc isLetterLegal = GetIsLetterLegalProc(GetDlgCtrlID(hwnd)); - through = IsInputLegal(isLetterLegal, len, wP); + through = IsInputLegal(isLetterLegal, (int)cpBegin, wP); if (!through) ShowLetterIllegalBalloonTip(hwnd, isLetterLegal); } From 77b18ba9895bdfe3a7e2a5d2657c6024f36e479f Mon Sep 17 00:00:00 2001 From: harry Date: Sun, 21 Aug 2022 22:43:35 -0400 Subject: [PATCH 33/48] Added keyboard state feedback to lua input.get() function for Qt GUI. Returned key codes are slightly different but at least it does something. Issue #536. --- src/drivers/Qt/input.cpp | 11 +++- src/drivers/Qt/input.h | 3 +- src/lua-engine.cpp | 110 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index 5cd1f347..9bddbc7c 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -158,6 +158,15 @@ int getKeyState(int k) return 0; } +const uint8_t *QtSDL_getKeyboardState( int *bufSize ) +{ + if (bufSize != nullptr) + { + *bufSize = SDL_NUM_SCANCODES; + } + return g_keyState; +} + //static int //_keyonly(int a) //{ @@ -1909,7 +1918,7 @@ static void UpdateFKB(void) } } -const uint8 *getFamilyKeyboardState(void) +const uint8_t *getFamilyKeyboardState(void) { return fkbkeys; } diff --git a/src/drivers/Qt/input.h b/src/drivers/Qt/input.h index 023d41fe..8ed5ff38 100644 --- a/src/drivers/Qt/input.h +++ b/src/drivers/Qt/input.h @@ -148,7 +148,8 @@ int saveInputSettingsToFile( const char *fileBase = NULL ); int loadInputSettingsFromFile( const char *filename = NULL ); void toggleFamilyKeyboardFunc(void); bool isFamilyKeyboardActv(void); -const uint8 *getFamilyKeyboardState(void); +const uint8_t *getFamilyKeyboardState(void); +const uint8_t *QtSDL_getKeyboardState( int *bufSize ); #endif diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index e5212fac..88950e61 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -54,6 +54,9 @@ extern TASEDITOR_LUA taseditor_lua; #ifdef __SDL__ #ifdef __QT_DRIVER__ +#include "drivers/Qt/sdl.h" +#include "drivers/Qt/main.h" +#include "drivers/Qt/input.h" #include "drivers/Qt/fceuWrapper.h" #include "drivers/Qt/TasEditor/selection.h" #include "drivers/Qt/TasEditor/laglog.h" @@ -2638,6 +2641,113 @@ static int input_get(lua_State *L) { } } } +#elif defined(__QT_DRIVER__) + // Qt/SDL + { + const uint8_t *keyBuf = QtSDL_getKeyboardState(nullptr); + + if (keyBuf) + { + int i=0; + char keyName[64]; + const char *keyOut = nullptr; + + for (int i=0; i(i) ); + + const char* name = SDL_GetKeyName(k); + + //printf("Key:%i '%s'\n", i, name); + + if ( isalpha(name[0]) || isdigit(name[0]) ) + { // If name starts with letters or number, copy name without spaces + int ii=0, jj=0; + while (name[ii] != 0) + { + if ( isalpha(name[ii]) || isdigit(name[ii]) || (name[ii] == '_') ) + { + keyName[jj] = name[ii]; jj++; + } + ii++; + } + keyName[jj] = 0; + + keyOut = keyName; + } + else + { // Handle special char names + switch (name[0]) + { + case '[': + keyOut = "LeftBracket"; + break; + case ']': + keyOut = "RightBracket"; + break; + case '{': + keyOut = "LeftBrace"; + break; + case '}': + keyOut = "RightBrace"; + break; + case ',': + keyOut = "Comma"; + break; + case '.': + keyOut = "Period"; + break; + case '~': + keyOut = "Tilde"; + break; + case '`': + keyOut = "Backtick"; + break; + case '|': + keyOut = "VerticalBar"; + break; + case '/': + keyOut = "Slash"; + break; + case '\\': + keyOut = "BackSlash"; + break; + case '+': + keyOut = "Plus"; + break; + case '=': + keyOut = "Equals"; + break; + case '_': + keyOut = "Underscore"; + break; + case '-': + keyOut = "Minus"; + break; + case ';': + keyOut = "SemiColon"; + break; + case ':': + keyOut = "Colon"; + break; + case '\'': + case '\"': + keyOut = "Quote"; + break; + default: + keyOut = name; + break; + } + + } + lua_pushboolean(L, true); + lua_setfield(L, -2, keyOut); + } + } + } + } #else //SDL TODO: implement this for keyboard!! #endif From 41feba20748d91faad4d2213468b3f1a8fb73b4c Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 22 Aug 2022 22:43:26 -0400 Subject: [PATCH 34/48] newppu - process grayscale (and maybe deemph, not sure) on a per-pixel basis to fix the FF1 polygon effect (fixes #529) --- src/ppu.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/src/ppu.cpp b/src/ppu.cpp index 01a03a79..89bd1af9 100644 --- a/src/ppu.cpp +++ b/src/ppu.cpp @@ -57,6 +57,7 @@ #define PPU_status (PPU[2]) +#define READPALNOGS(ofs) (PALRAM[(ofs)]) #define READPAL(ofs) (PALRAM[(ofs)] & (GRAYSCALE ? 0x30 : 0xFF)) #define READUPAL(ofs) (UPALRAM[(ofs)] & (GRAYSCALE ? 0x30 : 0xFF)) @@ -1987,6 +1988,7 @@ void runppu(int x) { struct BGData { struct Record { uint8 nt, pecnt, at, pt[2], qtnt; + uint8 ppu1[8]; INLINE void Read() { NTRefreshAddr = RefreshAddr = ppur.get_ntread(); @@ -1998,7 +2000,12 @@ struct BGData { } pecnt = (RefreshAddr & 1) << 3; nt = CALL_PPUREAD(RefreshAddr); - runppu(kFetchTime); + ppu1[0] = PPU[1]; + runppu(1); + ppu1[1] = PPU[1]; + runppu(1); + + RefreshAddr = ppur.get_atread(); at = CALL_PPUREAD(RefreshAddr); @@ -2010,37 +2017,57 @@ struct BGData { at <<= 2; //horizontal scroll clocked at cycle 3 and then //vertical scroll at 251 + ppu1[2] = PPU[1]; runppu(1); if (PPUON) { ppur.increment_hsc(); if (ppur.status.cycle == 251) ppur.increment_vs(); } + ppu1[3] = PPU[1]; runppu(1); ppur.par = nt; RefreshAddr = ppur.get_ptread(); if (PEC586Hack) { pt[0] = CALL_PPUREAD(RefreshAddr | pecnt); - runppu(kFetchTime); + ppu1[4] = PPU[1]; + runppu(1); + ppu1[5] = PPU[1]; + runppu(1); pt[1] = CALL_PPUREAD(RefreshAddr | pecnt); - runppu(kFetchTime); + ppu1[6] = PPU[1]; + runppu(1); + ppu1[7] = PPU[1]; + runppu(1); } else if (QTAIHack && (qtnt & 0x40)) { pt[0] = *(CHRptr[0] + RefreshAddr); - runppu(kFetchTime); + ppu1[4] = PPU[1]; + runppu(1); + ppu1[5] = PPU[1]; + runppu(1); RefreshAddr |= 8; pt[1] = *(CHRptr[0] + RefreshAddr); - runppu(kFetchTime); + ppu1[6] = PPU[1]; + runppu(1); + ppu1[7] = PPU[1]; + runppu(1); } else { if (ScreenON) RENDER_LOG(RefreshAddr); pt[0] = CALL_PPUREAD(RefreshAddr); - runppu(kFetchTime); + ppu1[4] = PPU[1]; + runppu(1); + ppu1[5] = PPU[1]; + runppu(1); RefreshAddr |= 8; if (ScreenON) RENDER_LOG(RefreshAddr); pt[1] = CALL_PPUREAD(RefreshAddr); - runppu(kFetchTime); + ppu1[6] = PPU[1]; + runppu(1); + ppu1[7] = PPU[1]; + runppu(1); } } }; @@ -2216,7 +2243,7 @@ int FCEUX_PPU_Loop(int skip) { pixel = ((pt[0] >> (7 - bgpx)) & 1) | (((pt[1] >> (7 - bgpx)) & 1) << 1) | bgdata.main[bgtile].at; } if (renderbg) - pixelcolor = READPAL(pixel); + pixelcolor = READPALNOGS(pixel); //look for a sprite to be drawn bool havepixel = false; @@ -2261,12 +2288,25 @@ int FCEUX_PPU_Loop(int skip) { spixel |= (oam[2] & 3) << 2; if (rendersprites) - pixelcolor = READPAL(0x10 + spixel); + pixelcolor = READPALNOGS(0x10 + spixel); } } - *ptr++ = PaletteAdjustPixel(pixelcolor); - *dptr++= PPU[1]>>5; //grab deemph + //apply grayscale.. kind of clunky + //really we need to read the entire palette instead of just ppu1 + //this will be needed for special color effects probably (very fine rainbows and whatnot?) + //are you allowed to chang the palette mid-line anyway? well you can definitely change the grayscale flag as we know from the FF1 "polygon" effect + if(bgdata.main[xt+2].ppu1[xp]&1) + pixelcolor &= 0x30; + + //this does deemph stuff inside it.. which is probably wrong... + *ptr = PaletteAdjustPixel(pixelcolor); + + ptr++; + + //grab deemph.. + //I guess this works the same way as the grayscale, ideally? + *dptr++ = bgdata.main[xt+2].ppu1[xp]>>5; } } } From 892e7cb5f5fbaed703243c6cf2bba6fda4f72fa3 Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 22 Aug 2022 22:52:40 -0400 Subject: [PATCH 35/48] change how memory is allocated to clean up a lot of messed up junk (mainly strange alignment adjustments which didnt completely make sense and frees which didnt match the allocation function that was used). In case there are problems on other platforms (a few seems probable), here's the idea 1. Get rid of all manual alignment adjustments 2. use FCEU_malloc or malloc, as you see fit 3. use FCEU_free (or FCEU_gfree) if you use FCEU_malloc or FCEU_gmalloc. There's no real reason to need FCEU_gfree; this rule might be eliminated in the future (at which time FCEU_gfree will be removed) 4. If you need more alignment, increase it in FCEU_malloc. It's unlikely more alignment will ever be needed. On windows, since the FCEU_*malloc functions now use aligned_alloc, we will catch instances where free() is used to free them (which happens frequently). allocates and frees should be matched. fix the free call if you ever observe this happening. also 5. In general, remove crufty error handling for allocation failures. This just gunks up the code. If allocation fails, the application terminates. --- src/drivers/common/vidblit.cpp | 10 +++--- src/ines.cpp | 14 +++----- src/state.cpp | 21 ++++++++--- src/utils/memory.cpp | 65 +++++++++++++++++++++------------- src/utils/memory.h | 22 ++++++++---- src/video.cpp | 22 ++++-------- src/video.h | 10 ++++++ 7 files changed, 97 insertions(+), 67 deletions(-) diff --git a/src/drivers/common/vidblit.cpp b/src/drivers/common/vidblit.cpp index 9b6f1c22..b2fbda24 100644 --- a/src/drivers/common/vidblit.cpp +++ b/src/drivers/common/vidblit.cpp @@ -238,18 +238,18 @@ void KillBlitToHigh(void) { if(palettetranslate) { - free(palettetranslate); + FCEU_free(palettetranslate); palettetranslate=NULL; } if(specbuf8bpp) { - free(specbuf8bpp); + FCEU_free(specbuf8bpp); specbuf8bpp = NULL; } if(specbuf32bpp) { - free(specbuf32bpp); + FCEU_free(specbuf32bpp); specbuf32bpp = NULL; } if(specbuf) @@ -259,11 +259,11 @@ void KillBlitToHigh(void) hq3x_Kill(); else hq2x_Kill(); - free(specbuf); + FCEU_free(specbuf); specbuf=NULL; } if (nes_ntsc) { - free(nes_ntsc); + FCEU_free(nes_ntsc); nes_ntsc = NULL; } if (ntscblit) { diff --git a/src/ines.cpp b/src/ines.cpp index c468df89..6766a558 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -108,11 +108,11 @@ void iNESGI(GI h) { //bbit edited: removed static keyword if (iNESCart.Close) iNESCart.Close(); if (ROM) { - free(ROM); + FCEU_free(ROM); ROM = NULL; } if (VROM) { - free(VROM); + FCEU_free(VROM); VROM = NULL; } if (trainerpoo) { @@ -813,17 +813,11 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { } } - if ((ROM = (uint8*)FCEU_malloc(ROM_size << 14)) == NULL) - return 0; + ROM = (uint8*)FCEU_malloc(ROM_size << 14); memset(ROM, 0xFF, ROM_size << 14); if (VROM_size) { - if ((VROM = (uint8*)FCEU_malloc(VROM_size << 13)) == NULL) { - free(ROM); - ROM = NULL; - FCEU_PrintError("Unable to allocate memory."); - return LOADER_HANDLED_ERROR; - } + VROM = (uint8*)FCEU_malloc(VROM_size << 13); memset(VROM, 0xFF, VROM_size << 13); } diff --git a/src/state.cpp b/src/state.cpp index a40e665e..78279c4b 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -307,13 +307,24 @@ static bool ReadStateChunks(EMUFILE* is, int32 totalsize) // load back buffer { extern uint8 *XBackBuf; - if(is->fread((char*)XBackBuf,size) != size) - ret = false; + //ignore 8 garbage bytes, whose idea was it to write these or even have them there in the first place + if(size == 256*256+8) + { + if(is->fread((char*)XBackBuf,256*256) != 256*256) + ret = false; + is->fseek(8,SEEK_CUR); + } + else + { + if(is->fread((char*)XBackBuf,size) != size) + ret = false; + } + //MBG TODO - can this be moved to a better place? //does it even make sense, displaying XBuf when its XBackBuf we just loaded? #ifdef __WIN_DRIVER__ - else + if(ret) { FCEUD_BlitScreen(XBuf); UpdateFCEUWindow(); @@ -404,7 +415,7 @@ bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel) // save back buffer { extern uint8 *XBackBuf; - uint32 size = 256 * 256 + 8; + uint32 size = 256 * 256; os->fputc(8); write32le(size, os); os->fwrite((char*)XBackBuf,size); @@ -848,7 +859,7 @@ void ResetExState(void (*PreSave)(void), void (*PostSave)(void)) for(x=0;x=0;_x-=4) *(uint32 *)&(d)[_x]=c;} -void *FCEU_malloc(uint32 size); // initialized to 0 -void *FCEU_gmalloc(uint32 size); // used by boards for WRAM etc, initialized to 0 (default) or other via RAMInitOption -void FCEU_gfree(void *ptr); -void FCEU_free(void *ptr); -void FCEU_memmove(void *d, void *s, uint32 l); +//returns a 32-aligned buffer, initialized to 0 +void *FCEU_malloc(uint32 size); -// wrapper for debugging when its needed, otherwise act like -// normal malloc/free +//returns a 32-aligned buffer, with jumbled initial contents +//used by boards for WRAM etc, initialized to 0 (default) or other via RAMInitOption +void *FCEU_gmalloc(uint32 size); + +//free memory allocated with FCEU_gmalloc +void FCEU_gfree(void *ptr); + +//free memory allocated with +void FCEU_free(void *ptr); + +//don't use these. change them if you find them. void *FCEU_dmalloc(uint32 size); + +//don't use these. change them if you find them. void FCEU_dfree(void *ptr); diff --git a/src/video.cpp b/src/video.cpp index 531c5f3c..cbad58fc 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -116,28 +116,18 @@ void FCEU_KillVirtualVideo(void) int FCEU_InitVirtualVideo(void) { //Some driver code may allocate XBuf externally. - //256 bytes per scanline, * 240 scanline maximum, +16 for alignment, + //256 bytes per scanline, * 240 scanline maximum if(XBuf) return 1; - XBuf = (u8*)FCEU_malloc(256 * 256 + 16); - XBackBuf = (u8*)FCEU_malloc(256 * 256 + 16); - XDBuf = (u8*)FCEU_malloc(256 * 256 + 16); - XDBackBuf = (u8*)FCEU_malloc(256 * 256 + 16); - if(!XBuf || !XBackBuf || !XDBuf || !XDBackBuf) - { - return 0; - } + XBuf = (u8*)FCEU_malloc(256 * 256); + XBackBuf = (u8*)FCEU_malloc(256 * 256); + XDBuf = (u8*)FCEU_malloc(256 * 256); + XDBackBuf = (u8*)FCEU_malloc(256 * 256); + xbsave = XBuf; - if( sizeof(uint8*) == 4 ) - { - uintptr_t m = (uintptr_t)XBuf; - m = ( 8 - m) & 7; - XBuf+=m; - } - memset(XBuf,128,256*256); memset(XBackBuf,128,256*256); memset(XBuf,128,256*256); diff --git a/src/video.h b/src/video.h index 64e0688b..7fbb6bad 100644 --- a/src/video.h +++ b/src/video.h @@ -7,10 +7,20 @@ int SaveSnapshot(char[]); void ResetScreenshotsCounter(); uint32 GetScreenPixel(int x, int y, bool usebackup); int GetScreenPixelPalette(int x, int y, bool usebackup); + +//in case we need more flags in the future we can change the size here +//bit0 : monochrome bit +//bit5 : emph red +//bit6 : emph green +//bit7 : emph blue +typedef uint8 xfbuf_t; + extern uint8 *XBuf; extern uint8 *XBackBuf; extern uint8 *XDBuf; extern uint8 *XDBackBuf; +extern xfbuf_t *XFBuf; + extern int ClipSidesOffset; struct GUIMESSAGE From b97b24a5e94f7549d25e3ab212de964756d16462 Mon Sep 17 00:00:00 2001 From: harry Date: Tue, 23 Aug 2022 18:18:25 -0400 Subject: [PATCH 36/48] Fix for unix build, aligned_free does not exist in unix should use plain free instead. --- src/utils/memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/memory.cpp b/src/utils/memory.cpp index e0eaf188..5ed626ea 100644 --- a/src/utils/memory.cpp +++ b/src/utils/memory.cpp @@ -52,7 +52,7 @@ static void _FCEU_free(void* ptr) #ifdef _MSC_VER _aligned_free(ptr); #else - aligned_free(ptr); + free(ptr); #endif } From d0add7a609ec818b4bfb93ca586873b41847d3a9 Mon Sep 17 00:00:00 2001 From: harry Date: Tue, 23 Aug 2022 18:36:39 -0400 Subject: [PATCH 37/48] For Qt GUI added separate hot keys for soft and hard reset functions. Changed soft reset to be default Ctrl+R and hard reset to Ctrl+Shift+R. --- src/drivers/Qt/ConsoleWindow.cpp | 11 +++++++---- src/drivers/Qt/config.cpp | 7 +++++-- src/drivers/Qt/config.h | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 23e4bf40..fd5119c4 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -1282,16 +1282,16 @@ void consoleWin_t::createMainMenu(void) connect( Hotkeys[ HK_POWER ].getShortcut(), SIGNAL(activated()), this, SLOT(powerConsoleCB(void)) ); // Emulation -> Reset - resetAct = new QAction(tr("&Reset"), this); + resetAct = new QAction(tr("Hard &Reset"), this); //resetAct->setShortcut( QKeySequence(tr("Ctrl+R"))); - resetAct->setStatusTip(tr("Reset Console")); + resetAct->setStatusTip(tr("Hard Reset of Console")); resetAct->setIcon( style()->standardIcon( QStyle::SP_DialogResetButton ) ); connect(resetAct, SIGNAL(triggered()), this, SLOT(consoleHardReset(void)) ); emuMenu->addAction(resetAct); - Hotkeys[ HK_RESET ].setAction( resetAct ); - connect( Hotkeys[ HK_RESET ].getShortcut(), SIGNAL(activated()), this, SLOT(consoleHardReset(void)) ); + Hotkeys[ HK_HARD_RESET ].setAction( resetAct ); + connect( Hotkeys[ HK_HARD_RESET ].getShortcut(), SIGNAL(activated()), this, SLOT(consoleHardReset(void)) ); // Emulation -> Soft Reset sresetAct = new QAction(tr("&Soft Reset"), this); @@ -1302,6 +1302,9 @@ void consoleWin_t::createMainMenu(void) emuMenu->addAction(sresetAct); + Hotkeys[ HK_SOFT_RESET ].setAction( sresetAct ); + connect( Hotkeys[ HK_SOFT_RESET ].getShortcut(), SIGNAL(activated()), this, SLOT(consoleSoftReset(void)) ); + // Emulation -> Pause pauseAct = new QAction(tr("&Pause"), this); //pauseAct->setShortcut( QKeySequence(tr("Pause"))); diff --git a/src/drivers/Qt/config.cpp b/src/drivers/Qt/config.cpp index 25442b96..fff49ff4 100644 --- a/src/drivers/Qt/config.cpp +++ b/src/drivers/Qt/config.cpp @@ -187,8 +187,11 @@ int getHotKeyConfig( int i, const char **nameOut, const char **keySeqOut, const case HK_POWER: name = "Power"; keySeq = ""; title = "Power"; group = "Emulation"; break; - case HK_RESET: - name = "Reset"; keySeq = "Ctrl+R"; title = "Reset"; group = "Emulation"; + case HK_SOFT_RESET: + name = "SoftReset"; keySeq = "Ctrl+R"; title = "Soft Reset"; group = "Emulation"; + break; + case HK_HARD_RESET: + name = "HardReset"; keySeq = "Ctrl+Shift+R"; title = "Hard Reset"; group = "Emulation"; break; case HK_PAUSE: name = "Pause"; keySeq = "Pause"; title = "Pause"; group = "Emulation"; diff --git a/src/drivers/Qt/config.h b/src/drivers/Qt/config.h index d719f12d..5b2beb92 100644 --- a/src/drivers/Qt/config.h +++ b/src/drivers/Qt/config.h @@ -14,7 +14,7 @@ enum HOTKEY { HK_OPEN_ROM=0, HK_CLOSE_ROM, // Emulation power, reset, pause, quit - HK_POWER, HK_RESET, HK_PAUSE, HK_QUIT, + HK_POWER, HK_SOFT_RESET, HK_HARD_RESET, HK_PAUSE, HK_QUIT, // Emulation Execution Control HK_FRAME_ADVANCE, HK_DECREASE_SPEED, HK_INCREASE_SPEED, HK_TURBO, From 179a5f0ffa41a8b1d09c054ab4f1af10d794dff6 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 23 Aug 2022 21:28:07 -0400 Subject: [PATCH 38/48] fix the size parameter of newly-introduced aligned_alloc call to be properly aligned (as the api requires) --- src/utils/memory.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/utils/memory.cpp b/src/utils/memory.cpp index 5ed626ea..066eb89c 100644 --- a/src/utils/memory.cpp +++ b/src/utils/memory.cpp @@ -30,10 +30,15 @@ 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,32); + void *ret = _aligned_malloc(size,alignment); #else - void *ret = aligned_alloc(32,size); + void *ret = aligned_alloc(alignment,size); #endif if(!ret) @@ -74,13 +79,13 @@ void *FCEU_malloc(uint32 size) return ret; } -///frees memory allocated with FCEU_gmalloc +//frees memory allocated with FCEU_gmalloc void FCEU_gfree(void *ptr) { _FCEU_free(ptr); } -///frees memory allocated with FCEU_malloc +//frees memory allocated with FCEU_malloc void FCEU_free(void *ptr) { _FCEU_free(ptr); From 96e570ae445a3a4cd06f95419e35ba530d59f81a Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 23 Aug 2022 21:48:32 -0400 Subject: [PATCH 39/48] don't doubly memzero new allocations --- src/utils/memory.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/utils/memory.cpp b/src/utils/memory.cpp index 066eb89c..c261cbf3 100644 --- a/src/utils/memory.cpp +++ b/src/utils/memory.cpp @@ -47,8 +47,6 @@ static void *_FCEU_malloc(uint32 size) exit(1); } - memset(ret, 0, size); - return ret; } From ff633d5acd33ff4ea326cdd1a6743cb663264d92 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 23 Aug 2022 22:01:11 -0400 Subject: [PATCH 40/48] add new function FCEU_abort() for calling abort() with a message; use it when memory allocation fails instead of exit() --- src/utils/memory.cpp | 11 +++++++---- src/utils/memory.h | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/utils/memory.cpp b/src/utils/memory.cpp index c261cbf3..93bc3af9 100644 --- a/src/utils/memory.cpp +++ b/src/utils/memory.cpp @@ -42,10 +42,7 @@ static void *_FCEU_malloc(uint32 size) #endif if(!ret) - { - FCEU_PrintError("Error allocating memory! Doing a hard exit."); - exit(1); - } + FCEU_abort("Error allocating memory!"); return ret; } @@ -98,3 +95,9 @@ void FCEU_dfree(void *ptr) { return FCEU_free(ptr); } + +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 174b3d31..b9e6f145 100644 --- a/src/utils/memory.h +++ b/src/utils/memory.h @@ -42,3 +42,6 @@ void *FCEU_dmalloc(uint32 size); //don't use these. change them if you find them. void FCEU_dfree(void *ptr); + +//aborts the process for fatal errors +void FCEU_abort(const char* message = nullptr); From d5a073741a9e9dba9e89695a2b513cc4bb5e9994 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 23 Aug 2022 22:56:47 -0400 Subject: [PATCH 41/48] ModernDeemphColorMap const args --- src/drivers/common/vidblit.cpp | 12 ++++++------ src/drivers/common/vidblit.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/drivers/common/vidblit.cpp b/src/drivers/common/vidblit.cpp index b2fbda24..6fcdac4e 100644 --- a/src/drivers/common/vidblit.cpp +++ b/src/drivers/common/vidblit.cpp @@ -466,7 +466,7 @@ void Blit8To8(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, in /* Todo: Make sure 24bpp code works right with big-endian cpus */ //takes a pointer to XBuf and applies fully modern deemph palettizing -template static u32 _ModernDeemphColorMap(u8* src, u8* srcbuf) +template static u32 _ModernDeemphColorMap(const u8* src, const u8* srcbuf) { u8 pixel = *src; @@ -492,7 +492,7 @@ template static u32 _ModernDeemphColorMap(u8* src, u8* srcbuf) return color; } -u32 ModernDeemphColorMap(u8* src, u8* srcbuf, int scale) +u32 ModernDeemphColorMap(const u8* src, const u8* srcbuf, int scale) { if(scale == 1) return _ModernDeemphColorMap<1>(src,srcbuf); else if(scale == 2) return _ModernDeemphColorMap<2>(src,srcbuf); @@ -503,14 +503,14 @@ u32 ModernDeemphColorMap(u8* src, u8* srcbuf, int scale) else if(scale == 7) return _ModernDeemphColorMap<7>(src,srcbuf); else if(scale == 8) return _ModernDeemphColorMap<8>(src,srcbuf); else if(scale == 9) return _ModernDeemphColorMap<9>(src,srcbuf); - else { abort(); return 0; } + else { FCEU_abort("unhandled ModernDeemphColorMap scale"); return 0; } } -typedef u32 (*ModernDeemphColorMapFuncPtr)( u8*, u8* ); +typedef u32 (*ModernDeemphColorMapFuncPtr)( const u8*, const u8* ); static ModernDeemphColorMapFuncPtr getModernDeemphColorMapFunc(int scale) { - ModernDeemphColorMapFuncPtr ptr = NULL; + ModernDeemphColorMapFuncPtr ptr; if(scale == 1) ptr = &_ModernDeemphColorMap<1>; else if(scale == 2) ptr = &_ModernDeemphColorMap<2>; @@ -521,7 +521,7 @@ static ModernDeemphColorMapFuncPtr getModernDeemphColorMapFunc(int scale) else if(scale == 7) ptr = &_ModernDeemphColorMap<7>; else if(scale == 8) ptr = &_ModernDeemphColorMap<8>; else if(scale == 9) ptr = &_ModernDeemphColorMap<9>; - else { abort(); ptr = NULL; } + else { FCEU_abort("unhandled ModernDeemphColorMap scale"); ptr = nullptr; } return ptr; } diff --git a/src/drivers/common/vidblit.h b/src/drivers/common/vidblit.h index d9581b0b..ba35b937 100644 --- a/src/drivers/common/vidblit.h +++ b/src/drivers/common/vidblit.h @@ -29,4 +29,4 @@ void Blit32to16(uint32 *src, uint16 *dest, int xr, int yr, int dpitch, int shiftr[3], int shiftl[3]); -u32 ModernDeemphColorMap(u8* src, u8* srcbuf, int scale); \ No newline at end of file +u32 ModernDeemphColorMap(const u8* src, const u8* srcbuf, int scale); From 1798fca76a3ffc8d22318e445d10fbb7b63a762b Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 23 Aug 2022 22:58:00 -0400 Subject: [PATCH 42/48] proper deemph handling for win32 aviout. used 57ec344b1fffd263c64b94cb4a87831a69b84a8c from 7 years ago as a reference (when the png writing was fixed). fixes #429 --- src/drivers/win/aviout.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/drivers/win/aviout.cpp b/src/drivers/win/aviout.cpp index b5ce0333..e0d347be 100644 --- a/src/drivers/win/aviout.cpp +++ b/src/drivers/win/aviout.cpp @@ -291,6 +291,8 @@ static void do_video_conversion(const unsigned char* buffer) { // memset(avi_file->convert_buffer, 0, VIDEO_WIDTH*(avi_file->end_scanline-avi_file->start_scanline)*3); + const unsigned char* mybuffer = buffer; + buffer += avi_file->start_scanline * VIDEO_WIDTH; for(int y=avi_file->start_scanline; yend_scanline; ++y) @@ -300,10 +302,11 @@ static void do_video_conversion(const unsigned char* buffer) for(int x=0; x>0x00)&0xFF; + *pix++=(color>>0x08)&0xFF; + *pix++=(color>>0x10)&0xFF; + buffer++; } buffer = prevbuf + VIDEO_WIDTH; From 9d831d8b8b647f0e7a84cd0ebb4baea4ba22f596 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Aug 2022 04:31:34 -0400 Subject: [PATCH 43/48] 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; From 20d03d4434ca2a473dcb33e61ce6a3da4fddcc19 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Aug 2022 04:32:23 -0400 Subject: [PATCH 44/48] 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; From 60f7b875f80958248e7def8f200efd4ba60dd003 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Aug 2022 04:33:38 -0400 Subject: [PATCH 45/48] 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; From 069727c191ff76f799abff83c62681e59747a496 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Aug 2022 04:41:45 -0400 Subject: [PATCH 46/48] 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); } From 6b0d1a52ca78a53bd8d721ac50bd2d51a0be5152 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Aug 2022 17:14:55 -0400 Subject: [PATCH 47/48] 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 | 80 ++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 33 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 (addr >= MaxSize) continue; - - switch(EditingMode) + if(EditingMode == MODE_NES_FILE) + { + ApplyPatch(CursorStartAddy, datasize, data); + } + else + { + for(int i = 0;i < datasize;i++) { - 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; + addr = CursorStartAddy+i; + + 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; + } } } CursorStartAddy+=datasize; From eaa5d6f88f8e49cca41094fbbfe7b20720b573b0 Mon Sep 17 00:00:00 2001 From: harry Date: Thu, 1 Sep 2022 20:32:51 -0400 Subject: [PATCH 48/48] For Qt GUI, added code to update debugger window ASM view when RAM or ROM edits are made from the hex editor. Fixes #508. --- src/drivers/Qt/HexEditor.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/drivers/Qt/HexEditor.cpp b/src/drivers/Qt/HexEditor.cpp index b7f1931c..38473f43 100644 --- a/src/drivers/Qt/HexEditor.cpp +++ b/src/drivers/Qt/HexEditor.cpp @@ -322,6 +322,8 @@ static void PalettePoke(uint32 addr, uint8 data) //---------------------------------------------------------------------------- static int writeMem( int mode, unsigned int addr, int value ) { + bool updateDebugger = false; + value = value & 0x000000ff; switch ( mode ) @@ -339,6 +341,8 @@ static int writeMem( int mode, unsigned int addr, int value ) { wfunc ((uint32) addr, (uint8) (value & 0x000000ff)); + + updateDebugger = true; } } else @@ -384,23 +388,32 @@ static int writeMem( int mode, unsigned int addr, int value ) { *(uint8 *)(GetNesCHRPointer(addr-16-PRGsize[0])) = value; } + updateDebugger = true; } break; } hexEditorRequestUpdateAll(); - return 0; + if ( updateDebugger ) + { + if (debuggerWindowIsOpen()) + { + updateAllDebuggerWindows(); + } + } + + return 0; } //---------------------------------------------------------------------------- static int convToXchar( int i ) { - int c = 0; + int c = 0; if ( (i >= 0) && (i < 10) ) { - c = i + '0'; + c = i + '0'; } else if ( i < 16 ) {