diff --git a/CMakeLists.txt b/CMakeLists.txt index add8d5ba..adb0d59c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,6 +110,8 @@ endif() option(ENABLE_FFMPEG "Enable ffmpeg A/V recording" ${FFMPEG_DEFAULT}) +option(ENABLE_ONLINEUPDATES "Enable online update checks" ON) + set(LTO_DEFAULT ON) # lto produces buggy binaries for 64 bit win32 @@ -293,6 +295,10 @@ if(ENABLE_FFMPEG) endif() endif() +if(NOT ENABLE_ONLINEUPDATES) + add_definitions(-DNO_ONLINEUPDATES) +endif() + if(NOT ENABLE_FFMPEG) add_definitions(-DNO_FFMPEG) endif() @@ -444,7 +450,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) if(X86_32 OR AMD64) set(MY_C_OPT_FLAGS ${MY_C_OPT_FLAGS} -mtune=generic) endif() - + # common debug flags if(CMAKE_COMPILER_IS_GNUCXX) set(MY_C_DBG_FLAGS -ggdb3 -Og -fno-omit-frame-pointer) diff --git a/README.md b/README.md index a1a32f74..726ccb0f 100644 --- a/README.md +++ b/README.md @@ -177,6 +177,7 @@ Here is the complete list: | ENABLE_LINK | Enable GBA linking functionality (requires SFML) | ON | | ENABLE_LIRC | Enable LIRC support | OFF | | ENABLE_FFMPEG | Enable ffmpeg A/V recording | OFF | +| ENABLE_ONLINEUPDATES | Enable online update checks | ON | | ENABLE_LTO | Compile with Link Time Optimization (gcc and clang only) | ON for release build | | ENABLE_GBA_LOGGING | Enable extended GBA logging | ON | | ENABLE_DIRECT3D | Direct3D rendering for wxWidgets (Windows, **NOT IMPLEMENTED!!!**) | ON | diff --git a/src/common/ConfigManager.cpp b/src/common/ConfigManager.cpp index 9cf829fb..f40a2b3a 100644 --- a/src/common/ConfigManager.cpp +++ b/src/common/ConfigManager.cpp @@ -38,7 +38,6 @@ extern "C" { #else // _WIN32 #include #define GETCWD _getcwd -#define snprintf sprintf #define stat _stat #define mkdir(X,Y) (_mkdir(X)) // from: https://www.linuxquestions.org/questions/programming-9/porting-to-win32-429334/ diff --git a/src/gb/GB.cpp b/src/gb/GB.cpp index 1ae77582..d2da5abc 100644 --- a/src/gb/GB.cpp +++ b/src/gb/GB.cpp @@ -4830,16 +4830,16 @@ void gbEmulate(int ticksToStop) //(fixes a part of Carmaggedon problem) if ((register_LCDC & 0x01 || gbCgbMode) && (register_LCDC & 0x20) && (gbWindowLine != -2)) { - int inUseRegister_WY = 0; + int tempinUseRegister_WY = inUseRegister_WY; int tempgbWindowLine = gbWindowLine; if ((tempgbWindowLine == -1) || (tempgbWindowLine > 144)) { - inUseRegister_WY = oldRegister_WY; + tempinUseRegister_WY = oldRegister_WY; if (register_LY > oldRegister_WY) tempgbWindowLine = 146; } - if (register_LY >= inUseRegister_WY) { + if (register_LY >= tempinUseRegister_WY) { if (tempgbWindowLine == -1) tempgbWindowLine = 0; diff --git a/src/libretro/UtilRetro.cpp b/src/libretro/UtilRetro.cpp index bd0965b7..1776ec1b 100644 --- a/src/libretro/UtilRetro.cpp +++ b/src/libretro/UtilRetro.cpp @@ -2,6 +2,8 @@ #include #include +#include + #include "NLS.h" #include "System.h" #include "Util.h" @@ -111,63 +113,59 @@ bool utilIsGBImage(const char* file) return false; } -// strip .gz or .z off end -void utilStripDoubleExtension(const char* file, char* buffer) -{ - if (buffer != file) // allows conversion in place - strcpy(buffer, file); -} - -static bool utilIsImage(const char* file) -{ - return utilIsGBAImage(file) || utilIsGBImage(file); -} - IMAGE_TYPE utilFindType(const char* file) { - //char buffer[2048]; - if (!utilIsImage(file)) // TODO: utilIsArchive() instead? - { - return IMAGE_UNKNOWN; - } - return utilIsGBAImage(file) ? IMAGE_GBA : IMAGE_GB; + if (utilIsGBAImage(file)) + return IMAGE_GBA; + + if (utilIsGBImage(file)) + return IMAGE_GB; + + return IMAGE_UNKNOWN; } static int utilGetSize(int size) { - int res = 1; - while(res < size) - res <<= 1; - return res; + int res = 1; + while(res < size) + res <<= 1; + return res; } uint8_t *utilLoad(const char *file, bool (*accept)(const char *), uint8_t *data, int &size) { - FILE *fp = NULL; - //char *buf = NULL; + FILE *fp = NULL; - fp = fopen(file,"rb"); - if(!fp) return NULL; - fseek(fp, 0, SEEK_END); //go to end - size = ftell(fp); // get position at end (length) - rewind(fp); + fp = fopen(file,"rb"); + if (!fp) + { + log("Failed to open file %s", file); + return NULL; + } + fseek(fp, 0, SEEK_END); //go to end - uint8_t *image = data; - if(image == NULL) - { - //allocate buffer memory if none was passed to the function - image = (uint8_t *)malloc(utilGetSize(size)); - if(image == NULL) - { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "data"); - return NULL; - } - } + size = ftell(fp); // get position at end (length) + rewind(fp); - FREAD_UNCHECKED(image, 1, size, fp); // read into buffer - fclose(fp); - return image; + uint8_t *image = data; + if(image == NULL) + { + image = (uint8_t *)malloc(utilGetSize(size)); + if(image == NULL) + { + log("Failed to allocate memory for %s", file); + return NULL; + } + } + + if (fread(image, 1, size, fp) != size) { + log("Failed to read from %s", file); + fclose(fp); + return NULL; + } + + fclose(fp); + return image; } void utilGBAFindSave(const int size) @@ -220,12 +218,10 @@ void utilGBAFindSave(const int size) p++; } // if no matches found, then set it to NONE - if (detectedSaveType == 0) { + if (detectedSaveType == 0) detectedSaveType = 5; - } - if (detectedSaveType == 4) { + if (detectedSaveType == 4) detectedSaveType = 3; - } cpuSaveType = detectedSaveType; rtcEnabled = rtcFound_; @@ -234,30 +230,20 @@ void utilGBAFindSave(const int size) void utilUpdateSystemColorMaps(bool lcd) { - switch (systemColorDepth) { - case 16: { - for (int i = 0; i < 0x10000; i++) { - systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | (((i & 0x3e0) >> 5) << systemGreenShift) | (((i & 0x7c00) >> 10) << systemBlueShift); - } - } break; - case 24: - case 32: { - for (int i = 0; i < 0x10000; i++) { - systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | (((i & 0x3e0) >> 5) << systemGreenShift) | (((i & 0x7c00) >> 10) << systemBlueShift); - } - } break; - } -} + int i = 0; -// Check for existence of file. -bool utilFileExists(const char* filename) -{ - FILE* f = fopen(filename, "r"); - if (f == NULL) { - return false; - } else { - fclose(f); - return true; + (void)lcd; + + switch (systemColorDepth) { + case 16: + for (i = 0; i < 0x10000; i++) + systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | (((i & 0x3e0) >> 5) << systemGreenShift) | (((i & 0x7c00) >> 10) << systemBlueShift); + break; + case 24: + case 32: + for (i = 0; i < 0x10000; i++) + systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | (((i & 0x3e0) >> 5) << systemGreenShift) | (((i & 0x7c00) >> 10) << systemBlueShift); + break; } } diff --git a/src/libretro/libretro.cpp b/src/libretro/libretro.cpp index 06ca7979..bf1aa312 100644 --- a/src/libretro/libretro.cpp +++ b/src/libretro/libretro.cpp @@ -156,57 +156,63 @@ uint16_t systemGbPalette[24] = { GS555(0x1f), GS555(0x15), GS555(0x0c), 0 }; -static const uint16_t defaultGBPalettes[][8] = { +struct palettes_t { + char name[40]; + uint16_t data[8]; +}; + +static struct palettes_t defaultGBPalettes[] = { { - // Standard - 0x7FFF, 0x56B5, 0x318C, 0x0000, 0x7FFF, 0x56B5, 0x318C, 0x0000, + "Standard", + { 0x7FFF, 0x56B5, 0x318C, 0x0000, 0x7FFF, 0x56B5, 0x318C, 0x0000 }, }, { - // Blue Sea - 0x6200, 0x7E10, 0x7C10, 0x5000, 0x6200, 0x7E10, 0x7C10, 0x5000, + "Blue Sea", + { 0x6200, 0x7E10, 0x7C10, 0x5000, 0x6200, 0x7E10, 0x7C10, 0x5000 }, }, { - // Dark Night - 0x4008, 0x4000, 0x2000, 0x2008, 0x4008, 0x4000, 0x2000, 0x2008, + "Dark Night", + { 0x4008, 0x4000, 0x2000, 0x2008, 0x4008, 0x4000, 0x2000, 0x2008 }, }, { - // Green Forest - 0x43F0, 0x03E0, 0x4200, 0x2200, 0x43F0, 0x03E0, 0x4200, 0x2200, + "Green Forest", + { 0x43F0, 0x03E0, 0x4200, 0x2200, 0x43F0, 0x03E0, 0x4200, 0x2200 }, }, { - // Hot Desert - 0x43FF, 0x03FF, 0x221F, 0x021F, 0x43FF, 0x03FF, 0x221F, 0x021F, + "Hot Desert", + { 0x43FF, 0x03FF, 0x221F, 0x021F, 0x43FF, 0x03FF, 0x221F, 0x021F }, }, { - // Pink Dreams - 0x621F, 0x7E1F, 0x7C1F, 0x2010, 0x621F, 0x7E1F, 0x7C1F, 0x2010, + "Pink Dreams", + { 0x621F, 0x7E1F, 0x7C1F, 0x2010, 0x621F, 0x7E1F, 0x7C1F, 0x2010 }, }, { - // Weird Colors - 0x621F, 0x401F, 0x001F, 0x2010, 0x621F, 0x401F, 0x001F, 0x2010, + "Weird Colors", + { 0x621F, 0x401F, 0x001F, 0x2010, 0x621F, 0x401F, 0x001F, 0x2010 } }, { - // Real GB Colors - 0x1B8E, 0x02C0, 0x0DA0, 0x1140, 0x1B8E, 0x02C0, 0x0DA0, 0x1140, + "Real GB Colors", + { 0x1B8E, 0x02C0, 0x0DA0, 0x1140, 0x1B8E, 0x02C0, 0x0DA0, 0x1140 }, }, { - // Real 'GB on GBASP' Colors - 0x7BDE, /*0x23F0*/ 0x5778, /*0x5DC0*/ 0x5640, 0x0000, 0x7BDE, /*0x3678*/ 0x529C, /*0x0980*/ 0x2990, 0x0000, + "Real GB on GBASP Colors", + { 0x7BDE, 0x5778, 0x5640, 0x0000, 0x7BDE, 0x529C, 0x2990, 0x0000 }, } }; static void set_gbPalette(void) { - const uint16_t *pal = defaultGBPalettes[current_gbPalette]; - if (type != IMAGE_GB) return; if (gbCgbMode || gbSgbMode) return; - for (int i = 0; i < 8; i++) - gbPalette[i] = pal[i]; + const uint16_t *pal = defaultGBPalettes[current_gbPalette].data; + for (int i = 0; i < 8; i++) { + uint16_t val = pal[i]; + gbPalette[i] = val; + } } static void set_gbColorCorrection(int value) @@ -329,16 +335,17 @@ void* retro_get_memory_data(unsigned id) return vram; } } - else if (type == IMAGE_GB) { + + if (type == IMAGE_GB) { switch (id) { case RETRO_MEMORY_SAVE_RAM: if (gbBattery) return gbRam; return NULL; case RETRO_MEMORY_SYSTEM_RAM: - return gbMemoryMap[0x0c]; + return (gbCgbMode ? gbWram : (gbMemory + 0xC000)); case RETRO_MEMORY_VIDEO_RAM: - return gbMemoryMap[0x08] ; + return (gbCgbMode ? gbVram : (gbMemory + 0x8000)); } } @@ -363,16 +370,17 @@ size_t retro_get_memory_size(unsigned id) return SIZE_VRAM - 0x2000; // usuable vram is only 0x18000 } } - else if (type == IMAGE_GB) { + + if (type == IMAGE_GB) { switch (id) { case RETRO_MEMORY_SAVE_RAM: if (gbBattery) return gbRamSize; return 0; case RETRO_MEMORY_SYSTEM_RAM: - return 0x2000; + return gbCgbMode ? 0x8000 : 0x2000; case RETRO_MEMORY_VIDEO_RAM: - return 0x2000; + return gbCgbMode ? 0x4000 : 0x2000; } } @@ -1486,7 +1494,7 @@ bool retro_load_game(const struct retro_game_info *game) gb_init(); unsigned addr, i; - struct retro_memory_descriptor desc[17]; + struct retro_memory_descriptor desc[18]; struct retro_memory_map retromap; memset(desc, 0, sizeof(desc)); @@ -1509,22 +1517,39 @@ bool retro_load_game(const struct retro_game_info *game) // $0000-$00FF Restart and Interrupt Vectors // http://gameboy.mongenel.com/dmg/asmmemmap.html for (addr = 0, i = 0; addr < 16; addr++) { - if (gbMemoryMap[addr] != NULL) { - desc[i].ptr = gbMemoryMap[addr]; - desc[i].start = addr * 0x1000; - desc[i].len = 4096; - if (addr < 4) desc[i].flags = RETRO_MEMDESC_CONST; + if (addr == 13) continue; + if (addr == 14) continue; + if (addr == 12) { // WRAM, bank 0-1 + if (!gbCgbMode) { // WRAM-GB + if (!gbMemory) continue; + desc[i].ptr = gbMemory + 0xC000; + } else { // WRAM GBC + if (!gbWram) continue; + desc[i].ptr = gbWram; + } + desc[i].start = addr * 0x1000; + desc[i].len = 0x2000; i++; + continue; + } else { // Everything else map + if (gbMemoryMap[addr]) { + desc[i].ptr = gbMemoryMap[addr]; + desc[i].start = addr * 0x1000; + desc[i].len = 0x1000; + if (addr < 4) + desc[i].flags = RETRO_MEMDESC_CONST; + i++; + } } } - if (gbCgbMode) { // banks 2-7 of GBC work ram banks at $10000 - desc[i].ptr = (void*)gbWram; - desc[i].offset = 0x2000; - desc[i].start = 0x10000; - desc[i].select = 0xFFFF0000; - desc[i].len = 0x6000; - i++; + if (gbWram && gbCgbMode) { // banks 2-7 of GBC work ram banks at $10000 + desc[i].ptr = gbWram; + desc[i].offset = 0x2000; + desc[i].start = 0x10000; + desc[i].select = 0xFFFFA000; + desc[i].len = 0x6000; + i++; } retromap.descriptors = desc; diff --git a/src/wx/cmdevents.cpp b/src/wx/cmdevents.cpp index fcdcc7e3..4ea98779 100644 --- a/src/wx/cmdevents.cpp +++ b/src/wx/cmdevents.cpp @@ -89,6 +89,24 @@ void MainFrame::SetMenuOption(const char* menuName, int value) } } +static void toggleBooleanVar(bool *menuValue, bool *globalVar) +{ + if (*menuValue == *globalVar) // used accelerator + *globalVar = !(*globalVar); + else // used menu item + *globalVar = *menuValue; +} + +static void toggleBitVar(bool *menuValue, int *globalVar, int mask) +{ + bool isEnabled = ((*globalVar) & (mask)) != (mask); + if (*menuValue == isEnabled) + *globalVar = ((*globalVar) & ~(mask)) | (!isEnabled ? (mask) : 0); + else + *globalVar = ((*globalVar) & ~(mask)) | (*menuValue ? (mask) : 0); + *menuValue = ((*globalVar) & (mask)) != (mask); +} + //// File menu static int open_ft = 0; @@ -188,7 +206,10 @@ EVT_HANDLER(RecentReset, "Reset recent ROM list") EVT_HANDLER(RecentFreeze, "Freeze recent ROM list (toggle)") { - GetMenuOptionBool("RecentFreeze", gopts.recent_freeze); + bool menuPress; + GetMenuOptionBool("RecentFreeze", menuPress); + toggleBooleanVar(&menuPress, &gopts.recent_freeze); + SetMenuOption("RecentFreeze", gopts.recent_freeze ? 1 : 0); update_opts(); } @@ -1355,18 +1376,8 @@ EVT_HANDLER(Pause, "Pause (toggle)") { bool menuPress; GetMenuOptionBool("Pause", menuPress); - - if (paused == menuPress) - { - // used accelerator - paused = !paused; - SetMenuOption("Pause", paused ? 1 : 0); - } - else - { - // used menu item - paused = menuPress; - } + toggleBooleanVar(&menuPress, &paused); + SetMenuOption("Pause", paused ? 1 : 0); if (paused) panel->Pause(); @@ -1383,7 +1394,10 @@ EVT_HANDLER(Pause, "Pause (toggle)") // new EVT_HANDLER_MASK(EmulatorSpeedupToggle, "Turbo mode (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionBool("EmulatorSpeedupToggle", turbo); + bool menuPress; + GetMenuOptionBool("EmulatorSpeedupToggle", menuPress); + toggleBooleanVar(&menuPress, &turbo); + SetMenuOption("EmulatorSpeedupToggle", turbo ? 1 : 0); } EVT_HANDLER_MASK(Reset, "Reset", CMDEN_GB | CMDEN_GBA) @@ -1399,21 +1413,37 @@ EVT_HANDLER(ToggleFullscreen, "Full screen (toggle)") EVT_HANDLER(JoypadAutofireA, "Autofire A (toggle)") { + bool menuPress; + GetMenuOptionBool("JoypadAutofireA", menuPress); + toggleBitVar(&menuPress, &autofire, KEYM_A); + SetMenuOption("JoypadAutofireA", menuPress ? 1 : 0); GetMenuOptionInt("JoypadAutofireA", autofire, KEYM_A); } EVT_HANDLER(JoypadAutofireB, "Autofire B (toggle)") { + bool menuPress; + GetMenuOptionBool("JoypadAutofireB", menuPress); + toggleBitVar(&menuPress, &autofire, KEYM_B); + SetMenuOption("JoypadAutofireB", menuPress ? 1 : 0); GetMenuOptionInt("JoypadAutofireB", autofire, KEYM_B); } EVT_HANDLER(JoypadAutofireL, "Autofire L (toggle)") { + bool menuPress; + GetMenuOptionBool("JoypadAutofireL", menuPress); + toggleBitVar(&menuPress, &autofire, KEYM_LEFT); + SetMenuOption("JoypadAutofireL", menuPress ? 1 : 0); GetMenuOptionInt("JoypadAutofireL", autofire, KEYM_LEFT); } EVT_HANDLER(JoypadAutofireR, "Autofire R (toggle)") { + bool menuPress; + GetMenuOptionBool("JoypadAutofireR", menuPress); + toggleBitVar(&menuPress, &autofire, KEYM_RIGHT); + SetMenuOption("JoypadAutofireR", menuPress ? 1 : 0); GetMenuOptionInt("JoypadAutofireR", autofire, KEYM_RIGHT); } @@ -1424,7 +1454,10 @@ EVT_HANDLER_MASK(LoadGameRecent, "Load most recent save", CMDEN_SAVST) EVT_HANDLER(LoadGameAutoLoad, "Auto load most recent save (toggle)") { - GetMenuOptionBool("LoadGameAutoLoad", gopts.autoload_state); + bool menuPress; + GetMenuOptionBool("LoadGameAutoLoad", menuPress); + toggleBooleanVar(&menuPress, &gopts.autoload_state); + SetMenuOption("LoadGameAutoLoad", gopts.autoload_state ? 1 : 0); update_opts(); } @@ -1499,6 +1532,10 @@ EVT_HANDLER_MASK(Load, "Load state...", CMDEN_GB | CMDEN_GBA) // new EVT_HANDLER(KeepSaves, "Do not load battery saves (toggle)") { + bool menuPress; + GetMenuOptionBool("KeepSaves", menuPress); + toggleBitVar(&menuPress, &skipSaveGameBattery, 1); + SetMenuOption("KeepSaves", menuPress ? 1 : 0); GetMenuOptionInt("KeepSaves", skipSaveGameBattery, 1); update_opts(); } @@ -1506,6 +1543,10 @@ EVT_HANDLER(KeepSaves, "Do not load battery saves (toggle)") // new EVT_HANDLER(KeepCheats, "Do not change cheat list (toggle)") { + bool menuPress; + GetMenuOptionBool("KeepCheats", menuPress); + toggleBitVar(&menuPress, &skipSaveGameCheats, 1); + SetMenuOption("KeepCheats", menuPress ? 1 : 0); GetMenuOptionInt("KeepCheats", skipSaveGameCheats, 1); update_opts(); } @@ -1655,7 +1696,10 @@ EVT_HANDLER_MASK(CheatsSearch, "Create cheat...", CMDEN_GB | CMDEN_GBA) // new EVT_HANDLER(CheatsAutoSaveLoad, "Auto save/load cheats (toggle)") { - GetMenuOptionBool("CheatsAutoSaveLoad", gopts.autoload_cheats); + bool menuPress; + GetMenuOptionBool("CheatsAutoSaveLoad", menuPress); + toggleBooleanVar(&menuPress, &gopts.autoload_cheats); + SetMenuOption("CheatsAutoSaveLoad", gopts.autoload_cheats ? 1 : 0); update_opts(); } @@ -1663,6 +1707,10 @@ EVT_HANDLER(CheatsAutoSaveLoad, "Auto save/load cheats (toggle)") // changed for convenience to match internal variable functionality EVT_HANDLER(CheatsEnable, "Enable cheats (toggle)") { + bool menuPress; + GetMenuOptionBool("CheatsEnable", menuPress); + toggleBitVar(&menuPress, &cheatsEnabled, 1); + SetMenuOption("CheatsEnable", menuPress ? 1 : 0); GetMenuOptionInt("CheatsEnable", cheatsEnabled, 1); update_opts(); } diff --git a/src/wx/guiinit.cpp b/src/wx/guiinit.cpp index 77ae7871..e1b6a5d4 100644 --- a/src/wx/guiinit.cpp +++ b/src/wx/guiinit.cpp @@ -1646,6 +1646,18 @@ public: { bool clear = ev.GetId() == XRCID("Clear"); + // For the individual clear buttons, we assume their name is + // "Clear" + joynames[i] + // ClearUp for Up; ClearR for R etc + for (int i = 0; i < NUM_KEYS; ++i) { + wxJoyKeyTextCtrl* tc = XRCCTRL_D(*p, joynames[i], wxJoyKeyTextCtrl); + wxString singleClearButton("Clear" + joynames[i]); + if (ev.GetId() == XRCID(singleClearButton)) { + tc->SetValue(wxEmptyString); + return; + } + } + for (int i = 0; i < NUM_KEYS; i++) { wxJoyKeyTextCtrl* tc = XRCCTRL_D(*p, joynames[i], wxJoyKeyTextCtrl); @@ -3324,16 +3336,43 @@ bool MainFrame::BindControls() sc = SafeXRCCTRL(d, n); \ sc->SetValidator(wxGenericValidator(&o)); \ } while (0) -#define getsc_uint(n, o) \ +#define getsc_uint(n, o) \ do { \ sc = SafeXRCCTRL(d, n); \ - sc->SetValidator(wxUIntValidator(&o)); \ + sc->SetValidator(wxUIntValidator(&o)); \ } while (0) { +#ifndef NO_ONLINEUPDATES // Online Auto Update check frequency getrbi("UpdateNever", gopts.onlineupdates, 0); getrbi("UpdateDaily", gopts.onlineupdates, 1); getrbi("UpdateWeekly", gopts.onlineupdates, 7); +#else + wxWindowList &children = d->GetChildren(); + std::vector forDeletion; + for (wxWindowList::Node *node = children.GetFirst(); node; node = node->GetNext()) + { + wxWindow *current = (wxWindow *)node->GetData(); + if (dynamic_cast(current)) + { + if (((wxStaticText *)current)->GetName() == wxT("OnlineUpdates")) + forDeletion.push_back(current); + } + else if (dynamic_cast(current)) + { + wxString tmp = ((wxRadioButton *)current)->GetName(); + if (tmp == wxT("UpdateNever") || + tmp == wxT("UpdateDaily") || + tmp == wxT("UpdateWeekly")) + forDeletion.push_back(current); + } + } + for (unsigned i = 0; i < forDeletion.size(); ++i) + { + delete forDeletion[i]; + } + std::vector().swap(forDeletion); +#endif // NO_ONLINEUPDATES getrbi("PNG", captureFormat, 0); getrbi("BMP", captureFormat, 1); getsc("RewindInterval", gopts.rewind_interval); @@ -3405,10 +3444,10 @@ bool MainFrame::BindControls() } while (0) #define getcbie(n, o, v) getbie(n, o, v, cb, wxCheckBox, CB) wxFilePickerCtrl* fp; -#define getfp(n, o) \ - do { \ - fp = SafeXRCCTRL(d, n); \ - fp->SetValidator(wxFileDirPickerValidator(&o)); \ +#define getfp(n, o, l) \ + do { \ + fp = SafeXRCCTRL(d, n); \ + fp->SetValidator(wxFileDirPickerValidator(&o, l)); \ } while (0) d = LoadXRCropertySheetDialog("GameBoyConfig"); { @@ -3418,10 +3457,15 @@ bool MainFrame::BindControls() // in command handler. Plus making changes might require resizing // game area. Validation only here. SafeXRCCTRL(d, "Borders"); - /// Boot ROM - getfp("BootRom", gopts.gb_bios); + /// GB Boot ROM + wxStaticText *label = SafeXRCCTRL(d, "BiosFile"); + if (!gopts.gb_bios.empty()) label->SetLabel(gopts.gb_bios); + getfp("BootRom", gopts.gb_bios, label); getlab("BootRomLab"); - getfp("CBootRom", gopts.gbc_bios); + /// GBC + wxStaticText *clabel = SafeXRCCTRL(d, "CBiosFile"); + if (!gopts.gbc_bios.empty()) clabel->SetLabel(gopts.gbc_bios); + getfp("CBootRom", gopts.gbc_bios, clabel); getlab("CBootRomLab"); /// Custom Colors //getcbi("Color", gbColorOption); @@ -3492,7 +3536,9 @@ bool MainFrame::BindControls() wxCommandEventHandler(BatConfig_t::Detect), NULL, &BatConfigHandler); /// Boot ROM - getfp("BootRom", gopts.gba_bios); + wxStaticText *label = SafeXRCCTRL(d, "BiosFile"); + if (!gopts.gba_bios.empty()) label->SetLabel(gopts.gba_bios); + getfp("BootRom", gopts.gba_bios, label); getlab("BootRomLab"); /// Game Overrides getgbaw("GameSettings"); @@ -3691,6 +3737,12 @@ bool MainFrame::BindControls() w->Connect(XRCID("Clear"), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons), NULL, &JoyPadConfigHandler[i]); + for (int j = 0; j < NUM_KEYS; ++j) { + w->Connect(XRCID(wxString("Clear" + joynames[j])), + wxEVT_COMMAND_BUTTON_CLICKED, + wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons), + NULL, &JoyPadConfigHandler[i]); + } joyDialog->Fit(); } diff --git a/src/wx/opts.cpp b/src/wx/opts.cpp index ac7fced6..3ae7854d 100644 --- a/src/wx/opts.cpp +++ b/src/wx/opts.cpp @@ -143,18 +143,27 @@ const wxString joynames[NUM_KEYS] = { }; wxJoyKeyBinding defkeys_keyboard[NUM_KEYS] = { - WJKB(WXK_UP), WJKB(WXK_DOWN), WJKB(WXK_LEFT), WJKB(WXK_RIGHT), - WJKB(wxT('Z')), WJKB(wxT('X')), WJKB(wxT('A')), WJKB(wxT('S')), - WJKB(wxT('C')), WJKB(wxT('V')), + WJKB(wxT('W')), WJKB(wxT('S')), WJKB(wxT('A')), WJKB(wxT('D')), + WJKB(wxT('L')), WJKB(wxT('K')), WJKB(wxT('I')), WJKB(wxT('O')), + WJKB(WXK_BACK), WJKB(WXK_RETURN), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(WXK_SPACE), WJKB(0), WJKB(0) }; wxJoyKeyBinding defkeys_joystick[NUM_KEYS] = { + WJKB(0, WXJB_HAT_N, 1), WJKB(0, WXJB_HAT_S, 1), WJKB(0, WXJB_HAT_W, 1), WJKB(0, WXJB_HAT_E, 1), + WJKB(0, WXJB_BUTTON, 1), WJKB(1, WXJB_BUTTON, 1), WJKB(4, WXJB_BUTTON, 1), WJKB(5, WXJB_BUTTON, 1), + WJKB(6, WXJB_BUTTON, 1), WJKB(7, WXJB_BUTTON, 1), + WJKB(0), WJKB(0), WJKB(0), WJKB(0), + WJKB(0), WJKB(0), WJKB(0), WJKB(0), + WJKB(0), WJKB(0), WJKB(0) +}; + +wxJoyKeyBinding extrakeys_joystick[NUM_KEYS] = { WJKB(1, WXJB_AXIS_MINUS, 1), WJKB(1, WXJB_AXIS_PLUS, 1), WJKB(0, WXJB_AXIS_MINUS, 1), WJKB(0, WXJB_AXIS_PLUS, 1), - WJKB(0, WXJB_BUTTON, 1), WJKB(1, WXJB_BUTTON, 1), WJKB(2, WXJB_BUTTON, 1), WJKB(3, WXJB_BUTTON, 1), - WJKB(4, WXJB_BUTTON, 1), WJKB(5, WXJB_BUTTON, 1), + WJKB(0), WJKB(0), WJKB(0), WJKB(0), + WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0), WJKB(0) @@ -225,7 +234,9 @@ opt_desc opts[] = { BOOLOPT("General/AutoLoadLastState", "", wxTRANSLATE("Automatically load last saved state"), gopts.autoload_state), STROPT("General/BatteryDir", "", wxTRANSLATE("Directory to store game save files (relative paths are relative to ROM; blank is config dir)"), gopts.battery_dir), BOOLOPT("General/FreezeRecent", "", wxTRANSLATE("Freeze recent load list"), gopts.recent_freeze), +#ifndef NO_ONLINEUPDATES ENUMOPT("General/OnlineUpdates", "", wxTRANSLATE("Automatically check for online updates"), gopts.onlineupdates, wxTRANSLATE("never|daily|weekly")), +#endif // NO_ONLINEUPDATES STROPT("General/RecordingDir", "", wxTRANSLATE("Directory to store A/V and game recordings (relative paths are relative to ROM)"), gopts.recording_dir), INTOPT("General/RewindInterval", "", wxTRANSLATE("Number of seconds between rewind snapshots (0 to disable)"), gopts.rewind_interval, 0, 600), STROPT("General/ScreenshotDir", "", wxTRANSLATE("Directory to store screenshots (relative paths are relative to ROM)"), gopts.scrshot_dir), @@ -346,18 +357,13 @@ opts_t::opts_t() bilinear = true; default_stick = 1; - for (int i = 0; i < NUM_KEYS; i++) { - if (defkeys_keyboard[i].key) - joykey_bindings[0][i].push_back(defkeys_keyboard[i]); - if (defkeys_joystick[i].key) - joykey_bindings[0][i].push_back(defkeys_joystick[i]); - } - recent = new wxFileHistory(10); autofire_rate = 1; print_auto_page = true; autoPatch = true; +#ifndef NO_ONLINEUPDATES onlineupdates = 1; +#endif // NO_ONLINEUPDATES // quick fix for issues #48 and #445 link_host = "127.0.0.1"; } @@ -368,6 +374,19 @@ bool opt_lt(const opt_desc& opt1, const opt_desc& opt2) return wxStrcmp(opt1.opt, opt2.opt) < 0; } +// set default input keys +void set_default_keys() +{ + for (int i = 0; i < NUM_KEYS; i++) { + if (defkeys_keyboard[i].key) + gopts.joykey_bindings[0][i].push_back(defkeys_keyboard[i]); + if (defkeys_joystick[i].joy) + gopts.joykey_bindings[0][i].push_back(defkeys_joystick[i]); + if (extrakeys_joystick[i].joy) + gopts.joykey_bindings[0][i].push_back(extrakeys_joystick[i]); + } +} + // FIXME: simulate MakeInstanceFilename(vbam.ini) using subkeys (Slave%d/*) void load_opts() { diff --git a/src/wx/opts.h b/src/wx/opts.h index c7b37bb9..e24c525f 100644 --- a/src/wx/opts.h +++ b/src/wx/opts.h @@ -42,7 +42,9 @@ extern struct opts_t { /// General bool autoload_state, autoload_cheats; wxString battery_dir; +#ifndef NO_ONLINEUPDATES int onlineupdates; +#endif // NO_ONLINEUPDATES long last_update; wxString last_updated_filename; bool recent_freeze; @@ -115,6 +117,8 @@ extern const int num_opts; extern const wxAcceleratorEntry default_accels[]; extern const int num_def_accels; +// call to setup default keys. +void set_default_keys(); // call to load config (once) // will write defaults for options not present and delete bad opts // will also initialize opts[] array translations diff --git a/src/wx/panel.cpp b/src/wx/panel.cpp index f7743950..a522c69c 100644 --- a/src/wx/panel.cpp +++ b/src/wx/panel.cpp @@ -923,7 +923,7 @@ void GameArea::Pause() // when the game is paused like this, we should not allow any // input to remain pressed, because they could be released - // outside of the game zone and we would not know about it. + // outside of the game zone and we would not know about it. clear_input_press(); if (loaded != IMAGE_UNKNOWN) @@ -2296,12 +2296,10 @@ DXDrawingPanel::DXDrawingPanel(wxWindow* parent, int _width, int _height) : DrawingPanel(parent, _width, _height) { // FIXME: implement - } void DXDrawingPanel::DrawArea(wxWindowDC& dc) { - // FIXME: implement if (!did_init) { DrawingPanelInit(); diff --git a/src/wx/sys.cpp b/src/wx/sys.cpp index 2653c15f..af397a93 100644 --- a/src/wx/sys.cpp +++ b/src/wx/sys.cpp @@ -1294,8 +1294,10 @@ bool debugWaitSocket() void log(const char* defaultMsg, ...) { va_list valist; + char buf[2048]; va_start(valist, defaultMsg); - wxString msg = wxString::Format(defaultMsg, valist); + vsnprintf(buf, 2048, defaultMsg, valist); + wxString msg = wxString(buf, wxConvLibc); va_end(valist); wxGetApp().log.append(msg); diff --git a/src/wx/widgets/wx/wxmisc.h b/src/wx/widgets/wx/wxmisc.h index ee0be8b6..d5367e2a 100644 --- a/src/wx/widgets/wx/wxmisc.h +++ b/src/wx/widgets/wx/wxmisc.h @@ -114,22 +114,26 @@ protected: bool* vptr; }; +#include + // wxFilePickerCtrl/wxDirPickerCtrl copy-only vvalidator class wxFileDirPickerValidator : public wxValidator { public: - wxFileDirPickerValidator(wxString* _vptr) + wxFileDirPickerValidator(wxString* _vptr, wxStaticText* _label = NULL) : wxValidator() , vptr(_vptr) + , vlabel(_label) { } wxFileDirPickerValidator(const wxFileDirPickerValidator& v) : wxValidator() , vptr(v.vptr) + , vlabel(v.vlabel) { } wxObject* Clone() const { - return new wxFileDirPickerValidator(vptr); + return new wxFileDirPickerValidator(vptr, vlabel); } bool TransferToWindow(); bool TransferFromWindow(); @@ -141,6 +145,7 @@ public: protected: wxString* vptr; + wxStaticText* vlabel; }; // color copy-only validator that supports either 32-bit or 16-bit color diff --git a/src/wx/widgets/wxmisc.cpp b/src/wx/widgets/wxmisc.cpp index e9cc0a00..136d0655 100644 --- a/src/wx/widgets/wxmisc.cpp +++ b/src/wx/widgets/wxmisc.cpp @@ -230,6 +230,7 @@ bool wxFileDirPickerValidator::TransferFromWindow() if (fp) { *vptr = fp->GetPath(); + if (vlabel) vlabel->SetLabel(*vptr); return true; } @@ -237,6 +238,7 @@ bool wxFileDirPickerValidator::TransferFromWindow() if (dp) { *vptr = dp->GetPath(); + if (vlabel) vlabel->SetLabel(*vptr); return true; } diff --git a/src/wx/wxvbam.cpp b/src/wx/wxvbam.cpp index fc33b096..25665d9f 100644 --- a/src/wx/wxvbam.cpp +++ b/src/wx/wxvbam.cpp @@ -56,9 +56,9 @@ static void get_config_path(wxPathList& path, bool exists = true) if ((wxDirExists(s) && wxIsWritable(s)) || ((!exists || !wxDirExists(s)) && parent.IsDirWritable())) \ path.Add(s); \ } while (0) -#define add_nonstandard_path(p) \ +#define add_nonstandard_path(p) \ do { \ - const wxString& s = p; \ + const wxString& s = p; \ wxFileName parent = wxFileName::DirName(s + wxT("//..")); \ parent.MakeAbsolute(); \ if ((wxDirExists(s) && wxIsWritable(s)) || ((!exists || !wxDirExists(s)) && parent.IsDirWritable())) \ @@ -165,6 +165,8 @@ wxString wxvbamApp::GetConfigurationPath() break; } } + // use default keys for input. + set_default_keys(); } return data_path; @@ -488,7 +490,7 @@ void wxvbamApp::OnInitCmdLine(wxCmdLineParser& cl) N_("Print configuration path and exit"), wxCMD_LINE_VAL_NONE, 0 }, { wxCMD_LINE_SWITCH, t("f"), t("fullscreen"), - N_("Start in full-screen mode"), + N_("Start in full-screen mode"), wxCMD_LINE_VAL_NONE, 0 }, #if !defined(NO_LINK) && !defined(__WXMSW__) { wxCMD_LINE_SWITCH, t("s"), t("delete-shared-state"), diff --git a/src/wx/xrc/GameBoyAdvanceConfig.xrc b/src/wx/xrc/GameBoyAdvanceConfig.xrc index 6006e907..8f600d9f 100644 --- a/src/wx/xrc/GameBoyAdvanceConfig.xrc +++ b/src/wx/xrc/GameBoyAdvanceConfig.xrc @@ -105,6 +105,27 @@ + + wxALL|wxEXPAND + 5 + + wxHORIZONTAL + + + + + wxALL|wxALIGN_CENTRE_VERTICAL + 5 + + + + + + wxALL|wxALIGN_CENTRE_VERTICAL + 5 + + + wxVERTICAL wxALL|wxEXPAND diff --git a/src/wx/xrc/GameBoyConfig.xrc b/src/wx/xrc/GameBoyConfig.xrc index c14fa24a..5a49ed5c 100644 --- a/src/wx/xrc/GameBoyConfig.xrc +++ b/src/wx/xrc/GameBoyConfig.xrc @@ -81,7 +81,7 @@ wxHORIZONTAL - + wxALL|wxALIGN_CENTRE_VERTICAL 5 @@ -121,6 +121,48 @@ wxEXPAND + + wxALL|wxEXPAND + 5 + + wxHORIZONTAL + + + + + wxALL|wxALIGN_CENTRE_VERTICAL + 5 + + + + + + wxALL|wxALIGN_CENTRE_VERTICAL + 5 + + + + + wxALL|wxEXPAND + 5 + + wxHORIZONTAL + + + + + wxALL|wxALIGN_CENTRE_VERTICAL + 5 + + + + + + wxALL|wxALIGN_CENTRE_VERTICAL + 5 + + + diff --git a/src/wx/xrc/GeneralConfig.xrc b/src/wx/xrc/GeneralConfig.xrc index fc8a6cd6..bcd0433e 100644 --- a/src/wx/xrc/GeneralConfig.xrc +++ b/src/wx/xrc/GeneralConfig.xrc @@ -22,7 +22,7 @@ - + wxALL|wxALIGN_CENTRE_VERTICAL diff --git a/src/wx/xrc/JoyPanel.xrc b/src/wx/xrc/JoyPanel.xrc index 9d11b18f..79aa1bf5 100644 --- a/src/wx/xrc/JoyPanel.xrc +++ b/src/wx/xrc/JoyPanel.xrc @@ -24,6 +24,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -39,6 +47,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -54,6 +70,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -69,6 +93,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -84,6 +116,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -99,6 +139,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -114,6 +162,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -130,6 +186,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -145,6 +209,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -160,8 +232,16 @@ wxALL|wxEXPAND 5 - 4 - 1,3 + + + + + + wxALL + 5 + + 6 + 1,2,4,5 @@ -183,6 +263,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -197,6 +285,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -211,6 +307,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -225,6 +329,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -239,6 +351,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -253,6 +373,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -267,6 +395,14 @@ wxALL|wxGROW 5 + + + + + + wxALL + 5 + @@ -281,6 +417,14 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + @@ -295,6 +439,17 @@ wxALL|wxEXPAND 5 + + + + + + wxALL + 5 + + + wxEXPAND + wxEXPAND @@ -315,6 +470,14 @@ wxALL|wxGROW 5 + + + + + + wxALL + 5 + @@ -329,8 +492,16 @@ wxALL|wxEXPAND 5 - 4 - 1,3 + + + + + + wxALL + 5 + + 6 + 1,2,4,5 @@ -355,7 +526,7 @@ - + wxALL 5 diff --git a/src/wx/xrc/MainMenu.xrc b/src/wx/xrc/MainMenu.xrc index c3662316..c9b9b12d 100644 --- a/src/wx/xrc/MainMenu.xrc +++ b/src/wx/xrc/MainMenu.xrc @@ -296,7 +296,7 @@ 1 - + @@ -357,11 +357,11 @@ - 0 + 0 - 0 + 0 @@ -372,7 +372,7 @@ 1 - + 1 @@ -391,7 +391,7 @@ - + @@ -417,7 +417,7 @@ - + 1 @@ -482,7 +482,7 @@ - + 1