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 '****************************************' diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60dba054..8ef081d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -85,6 +85,15 @@ else(WIN32) #endif() add_definitions( -D__QT_DRIVER__ -DQT_DEPRECATED_WARNINGS ) + 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() + message( STATUS "Address Sanitizer Disabled" ) + endif() + # Check for libminizip pkg_check_modules( MINIZIP REQUIRED minizip) @@ -578,7 +587,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) @@ -613,7 +622,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} 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; } 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/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/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 ); diff --git a/src/drivers/Qt/AviRiffViewer.cpp b/src/drivers/Qt/AviRiffViewer.cpp index 6d1e6afa..2f9b28c3 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] ); @@ -907,13 +909,6 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item ) twi->setText( 0, tr("nBitsPerSample") ); twi->setText( 2, tr(stmp) ); item->addChild(twi); - - 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 ) ) diff --git a/src/drivers/Qt/CheatsConf.cpp b/src/drivers/Qt/CheatsConf.cpp index f9af2ad1..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))); @@ -670,7 +687,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 +727,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); } @@ -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,9 +992,11 @@ void GuiCheatsDialog_t::updateCheatParameters(void) //printf("Name: %s \n", name.c_str() ); + type = typeEntry->currentData().toInt(); + 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 +1008,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 +1046,9 @@ 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())); + + typeEntry->setCurrentIndex(type); } //---------------------------------------------------------------------------- void GuiCheatsDialog_t::globalEnableCheats(int state) diff --git a/src/drivers/Qt/CheatsConf.h b/src/drivers/Qt/CheatsConf.h index 40b2836a..4eab63a9 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); @@ -67,6 +67,7 @@ protected: QLineEdit *neValEntry; QLineEdit *grValEntry; QLineEdit *ltValEntry; + QComboBox *typeEntry; QFont font; int fontCharWidth; diff --git a/src/drivers/Qt/ConsoleViewerGL.cpp b/src/drivers/Qt/ConsoleViewerGL.cpp index c473895a..f836dd88 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,9 @@ void ConsoleViewGL_t::buildTextures(void) GL_BGRA, GL_UNSIGNED_BYTE, 0 ); } + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + //glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //printf("Texture Built: %ix%i\n", w, h); } @@ -347,7 +351,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 +670,9 @@ void ConsoleViewGL_t::paintGL(void) } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + //glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if ( textureType == GL_TEXTURE_RECTANGLE ) { diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 02ad1059..fd5119c4 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)) ); @@ -1281,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); @@ -1301,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"))); @@ -1730,10 +1734,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 +3059,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); @@ -3173,6 +3177,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/HexEditor.cpp b/src/drivers/Qt/HexEditor.cpp index 0c763382..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 @@ -374,7 +378,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) ) { @@ -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 ) { @@ -3243,7 +3256,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 ); } @@ -4205,6 +4218,12 @@ int hexEditorOpenFromDebugger( int mode, int addr ) win->show(); } + else + { + win->activateWindow(); + win->raise(); + win->setFocus(); + } win->editor->setMode( mode ); win->editor->setAddr( addr ); 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); diff --git a/src/drivers/Qt/config.cpp b/src/drivers/Qt/config.cpp index 386571ee..fff49ff4 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; @@ -184,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 0bb68e78..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, @@ -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 d701fcfb..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; @@ -642,6 +645,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 +685,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; iaddWidget( 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/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/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index 0c2f1f69..1974ac29 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -95,7 +95,10 @@ static bool showSplashScreen(void) int main( int argc, char *argv[] ) { - int retval; + int retval = 0; + + fceuWrapperPreInit(argc, argv); + qInstallMessageHandler(MessageOutput); QApplication app(argc, argv); 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/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/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/common/vidblit.cpp b/src/drivers/common/vidblit.cpp index 9b6f1c22..6fcdac4e 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) { @@ -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); 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/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; diff --git a/src/drivers/win/cheat.cpp b/src/drivers/win/cheat.cpp index f2d6c83e..0153d281 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(); @@ -1081,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/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/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/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..70b8b704 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) @@ -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); @@ -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; 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 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 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 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; diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index b36e74bc..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" @@ -404,7 +407,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); @@ -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; @@ -3283,176 +3317,97 @@ POINT CalcSubWindowPos(HWND hDlg, POINT* conf) return pt; } -LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP) +static bool IsInputLegal(IsLetterLegalProc proc, int index, char letter) { - bool through = true; - INT_PTR result = 0; + return !proc || letter == VK_BACK || GetKeyState(VK_CONTROL) & 0x8000 || proc(index,letter); +} - switch (msg) +bool IsLetterLegalGG(int index, char letter) +{ + char ch = toupper(letter); + for (int i = 0; GameGenieLetters[i]; ++i) + if (GameGenieLetters[i] == ch) + return true; + return false; +} + +bool IsLetterLegalHex(int index, char letter) +{ + return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f'; +} + +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(index == 0) { - case WM_PASTE: - { - - bool (*IsLetterLegal)(char) = GetIsLetterLegal(GetDlgCtrlID(hwnd)); - - if (IsLetterLegal) - { - if (OpenClipboard(hwnd)) - { - HANDLE handle = GetClipboardData(CF_TEXT); - if (handle) - { - - // 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) - { - 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(); - } - } - } - } - break; - case WM_CHAR: - { - bool(*IsLetterLegal)(char) = GetIsLetterLegal(GetDlgCtrlID(hwnd)); - through = IsInputLegal(IsLetterLegal, wP); - if (!through) - ShowLetterIllegalBalloonTip(hwnd, IsLetterLegal); - } + if(letter == 'x' || letter == 'X' || letter == '!') + return true; } - return through ? CallWindowProc(DefaultEditCtrlProc, hwnd, msg, wP, lP) : result; + return false; } -// return a letter legal checking function for the specified control with the given id -bool inline (*GetIsLetterLegal(UINT id))(char letter) +bool IsLetterLegalHexList(int index, 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 iNES 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; + return IsLetterLegalHex(index,letter) || letter == ',' || letter == ' '; } -void ShowLetterIllegalBalloonTip(HWND hwnd, bool(*IsLetterLegal)(char letter)) +bool IsLetterLegalCheat(int index, char letter) { - wchar_t* title = L"Unacceptable Character"; - wchar_t* msg = GetLetterIllegalErrMsg(IsLetterLegal); - - EDITBALLOONTIP tip; - tip.cbStruct = sizeof(EDITBALLOONTIP); - tip.pszText = msg; - tip.pszTitle = title; - tip.ttiIcon = TTI_ERROR; - SendMessage(hwnd, EM_SHOWBALLOONTIP, 0, (LPARAM)&tip); - - // make a sound - MessageBeep(0xFFFFFFFF); + return letter >= '0' && letter <= ':' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '?'; } -inline wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter)) +bool IsLetterLegalSize(int index, char letter) { - if (IsLetterLegal == IsLetterLegalGG) + return letter >= '0' && letter <= '9' || letter == 'm' || letter == 'M' || letter == 'k' || letter == 'K' || letter == 'b' || letter == 'B'; +} + +bool IsLetterLegalDec(int index, char letter) +{ + return letter >= '0' && letter <= '9' || letter == '-' || letter == '+'; +} + +bool IsLetterLegalFloat(int index, char letter) +{ + return letter >= '0' && letter <= '9' || letter == '.' || letter == '-' || 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(int index, char letter) +{ + return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$'; +} + +wchar_t* GetLetterIllegalErrMsg(IsLetterLegalProc proc) +{ + 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" @@ -3463,7 +3418,7 @@ inline 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" @@ -3477,56 +3432,155 @@ inline wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter)) return L"Your input contains invalid characters."; } -inline bool IsInputLegal(bool (*IsLetterLegal)(char letter), char letter) +// return a letter legal checking function for the specified control with the given id +IsLetterLegalProc GetIsLetterLegalProc(UINT id) { - return !IsLetterLegal || letter == VK_BACK || GetKeyState(VK_CONTROL) & 0x8000 || IsLetterLegal(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: + 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; } -inline bool IsLetterLegalGG(char letter) +LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP) { - char ch = toupper(letter); - for (int i = 0; GameGenieLetters[i]; ++i) - if (GameGenieLetters[i] == ch) - return true; - return false; + bool through = true; + INT_PTR result = 0; + + switch (msg) + { + case WM_PASTE: + { + + IsLetterLegalProc isLetterLegal = GetIsLetterLegalProc(GetDlgCtrlID(hwnd)); + + if (isLetterLegal) + { + if (OpenClipboard(hwnd)) + { + HANDLE handle = GetClipboardData(CF_TEXT); + if (handle) + { + + // 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) + { + if (!isLetterLegal(i,clipStr[i])) + { + through = false; + // Show Edit control tip, just like the control with ES_NUMBER do + ShowLetterIllegalBalloonTip(hwnd, isLetterLegal); + break; + } + } + GlobalUnlock(handle); + CloseClipboard(); + } + } + } + } + break; + + case WM_CHAR: + { + DWORD cpBegin, cpEnd; + SendMessage(hwnd, EM_GETSEL, (LPARAM)&cpBegin, (LPARAM)&cpEnd); + IsLetterLegalProc isLetterLegal = GetIsLetterLegalProc(GetDlgCtrlID(hwnd)); + through = IsInputLegal(isLetterLegal, (int)cpBegin, wP); + if (!through) + ShowLetterIllegalBalloonTip(hwnd, isLetterLegal); + } + } + + return through ? CallWindowProc(DefaultEditCtrlProc, hwnd, msg, wP, lP) : result; } -inline bool IsLetterLegalHex(char letter) +void ShowLetterIllegalBalloonTip(HWND hwnd, IsLetterLegalProc proc) { - return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f'; -} + wchar_t* title = L"Unacceptable Character"; + wchar_t* msg = GetLetterIllegalErrMsg(proc); -inline bool IsLetterLegalHexList(char letter) -{ - return IsLetterLegalHex(letter) || letter == ',' || letter == ' '; -} + EDITBALLOONTIP tip; + tip.cbStruct = sizeof(EDITBALLOONTIP); + tip.pszText = msg; + tip.pszTitle = title; + tip.ttiIcon = TTI_ERROR; + SendMessage(hwnd, EM_SHOWBALLOONTIP, 0, (LPARAM)&tip); -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 == '$'; + // make a sound + MessageBeep(0xFFFFFFFF); } diff --git a/src/drivers/win/window.h b/src/drivers/win/window.h index 0127ad97..da716a69 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)(int index, char ch); +bool IsLetterLegalHex(int index, char letter); +void ShowLetterIllegalBalloonTip(HWND hwnd, IsLetterLegalProc); extern WNDPROC DefaultEditCtrlProc; extern LRESULT APIENTRY FilterEditCtrlProc(HWND hDlg, UINT msg, WPARAM wP, LPARAM lP); 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/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) { diff --git a/src/file.cpp b/src/file.cpp index c927be7b..e4d5b4f6 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,15 +127,10 @@ 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); + fp->size=offset+size; } fread(buf+offset,1,size,ips); } @@ -495,7 +484,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 a14b1add..92fa0bdf 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -54,9 +54,11 @@ 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 +char LoadedRomFNamePatchToUse[2048]; static int CHRRAMSize = -1; static int iNES_Init(int num); @@ -107,11 +109,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) { @@ -673,7 +675,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 +768,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; @@ -809,17 +814,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); } @@ -918,6 +917,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..267ab963 100644 --- a/src/ines.h +++ b/src/ines.h @@ -43,9 +43,11 @@ 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 +extern char LoadedRomFNamePatchToUse[2048]; extern char *iNesShortFName(void); extern const TMasterRomInfo* MasterRomInfo; extern TMasterRomInfoParams MasterRomInfoParams; @@ -242,6 +244,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 *); diff --git a/src/input.cpp b/src/input.cpp index 530f6948..592d5e50 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,18 @@ static void RamSearchOpNE(void) { #endif } +extern int globalCheatDisabled; +extern unsigned int FrozenAddressCount; +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 }; diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index b647831b..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" @@ -773,7 +776,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 +789,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); @@ -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 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) 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)}, 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; } } } 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); + } } } } diff --git a/src/state.cpp b/src/state.cpp index a29a46d0..78279c4b 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 } }; @@ -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 buffer initialized to 0 +void *FCEU_malloc(uint32 size); -// wrapper for debugging when its needed, otherwise act like -// normal malloc/free +//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); + +//free memory allocated with FCEU_gmalloc +void FCEU_gfree(void *ptr); + +//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); + +//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); diff --git a/src/video.cpp b/src/video.cpp index 531c5f3c..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"); } @@ -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_amalloc(256 * 256); + XBackBuf = (u8*)FCEU_amalloc(256 * 256); + XDBuf = (u8*)FCEU_amalloc(256 * 256); + XDBackBuf = (u8*)FCEU_amalloc(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 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)"