diff --git a/project/vs2010_mfc/VBA-M-WX.vcxproj b/project/vs2010_mfc/VBA-M-WX.vcxproj index 70bb1c65..d6d74b11 100644 --- a/project/vs2010_mfc/VBA-M-WX.vcxproj +++ b/project/vs2010_mfc/VBA-M-WX.vcxproj @@ -46,14 +46,14 @@ true $(ProjectDir)$(Platform)\$(Configuration)\Binary\ $(ProjectDir)$(Platform)\$(Configuration)\Build\$(ProjectName)\ - ..\..\..\dependencies\openal-soft\include\AL\;$(DXSDK_DIR)\Include;$(IncludePath) + ..\..\..\dependencies\openal-soft\include\AL;$(DXSDK_DIR)\Include;$(IncludePath) false $(ProjectDir)$(Platform)\$(Configuration)\Binary\ $(ProjectDir)$(Platform)\$(Configuration)\Build\$(ProjectName)\ true - ..\..\..\dependencies\openal-soft\include\AL\;$(DXSDK_DIR)\Include;$(IncludePath) + ..\..\..\dependencies\openal-soft\include\AL;$(DXSDK_DIR)\Include;$(IncludePath) vc_mswud_x64\ diff --git a/src/wx/cmdevents.cpp b/src/wx/cmdevents.cpp index 59740c43..0094a300 100644 --- a/src/wx/cmdevents.cpp +++ b/src/wx/cmdevents.cpp @@ -25,51 +25,61 @@ extern "C" { wxStaticCast(wxGetApp().frame->FindWindow(XRCID(n)), wxDialog) #else #define GetXRCDialog(n) \ - wxStaticCast(wxGetApp().frame->FindWindowByName(n), wxDialog) + wxStaticCast(wxGetApp().frame->FindWindowByName(n), wxDialog) #endif void GDBBreak(MainFrame* mf); bool cmditem_lt(const struct cmditem &cmd1, const struct cmditem &cmd2) { - return wxStrcmp(cmd1.cmd, cmd2.cmd) < 0; + return wxStrcmp(cmd1.cmd, cmd2.cmd) < 0; } void MainFrame::GetMenuOptionBool(const char* menuName, bool &field) { - field = !field; + field = !field; int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8)); - for(int i = 0; i < checkable_mi.size(); i++) { - if(checkable_mi[i].cmd != id) + + for (int i = 0; i < checkable_mi.size(); i++) + { + if (checkable_mi[i].cmd != id) continue; + field = checkable_mi[i].mi->IsChecked(); break; - } + } } void MainFrame::GetMenuOptionInt(const char* menuName, int &field, int mask) { int value = mask; - bool is_checked = ((field) & (mask)) != (value); + bool is_checked = ((field) & (mask)) != (value); int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8)); - for(int i = 0; i < checkable_mi.size(); i++) { - if(checkable_mi[i].cmd != id) + + for (int i = 0; i < checkable_mi.size(); i++) + { + if (checkable_mi[i].cmd != id) continue; + is_checked = checkable_mi[i].mi->IsChecked(); break; - } - field = ((field) & ~(mask)) | (is_checked ? (value) : 0); + } + + field = ((field) & ~(mask)) | (is_checked ? (value) : 0); } void MainFrame::SetMenuOption(const char* menuName, int value) { int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8)); - for(int i = 0; i < checkable_mi.size(); i++) { - if(checkable_mi[i].cmd != id) + + for (int i = 0; i < checkable_mi.size(); i++) + { + if (checkable_mi[i].cmd != id) continue; + checkable_mi[i].mi->Check(value); break; - } + } } //// File menu @@ -90,355 +100,371 @@ EVT_HANDLER(wxID_OPEN, "Open ROM...") open_dir = gopts.gbc_rom_dir; // FIXME: ignore if non-existent or not a dir - wxString pats = _( - "Archives (*.zip;*.7z;*.rar)|" - "*.zip;*.7z;*.rar" - "|GameBoy Advance Files (*.agb;*.gba;*.bin;*.elf;*.mb)|" - "*.agb;*.gba;*.bin;*.elf;*.mb" - "*.agb.gz;*.gba.gz;*.bin.gz;*.elf.gz;*.mb.gz" - "*.agb.z;*.gba.z;*.bin.z;*.elf.z;*.mb.z" - "|GameBoy Files (*.dmg;*.gb;*.gbc;*.cgb;*.sgb)|" - "*.dmg;*.gb;*.gbc;*.cgb;*.sgb" - "*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz" - "*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z" - "|" - ); - pats.append(wxALL_FILES); - wxFileDialog dlg(this, _("Open ROM file"), open_dir, wxT(""), - pats, - wxFD_OPEN|wxFD_FILE_MUST_EXIST); - dlg.SetFilterIndex(open_ft); - if(ShowModal(&dlg) == wxID_OK) + wxString pats = _( + "Archives (*.zip;*.7z;*.rar)|" + "*.zip;*.7z;*.rar" + "|GameBoy Advance Files (*.agb;*.gba;*.bin;*.elf;*.mb)|" + "*.agb;*.gba;*.bin;*.elf;*.mb" + "*.agb.gz;*.gba.gz;*.bin.gz;*.elf.gz;*.mb.gz" + "*.agb.z;*.gba.z;*.bin.z;*.elf.z;*.mb.z" + "|GameBoy Files (*.dmg;*.gb;*.gbc;*.cgb;*.sgb)|" + "*.dmg;*.gb;*.gbc;*.cgb;*.sgb" + "*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz" + "*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z" + "|" + ); + pats.append(wxALL_FILES); + wxFileDialog dlg(this, _("Open ROM file"), open_dir, wxT(""), + pats, + wxFD_OPEN | wxFD_FILE_MUST_EXIST); + dlg.SetFilterIndex(open_ft); + + if (ShowModal(&dlg) == wxID_OK) wxGetApp().pending_load = dlg.GetPath(); - open_ft = dlg.GetFilterIndex(); - open_dir = dlg.GetDirectory(); + + open_ft = dlg.GetFilterIndex(); + open_dir = dlg.GetDirectory(); } EVT_HANDLER(RecentReset, "Reset recent ROM list") { - // only save config if there were items to remove - if(gopts.recent->GetCount()) { - while(gopts.recent->GetCount()) - gopts.recent->RemoveFileFromHistory(0); - wxFileConfig *cfg = wxGetApp().cfg; - cfg->SetPath(wxT("/Recent")); - gopts.recent->Save(*cfg); - cfg->SetPath(wxT("/")); - cfg->Flush(); - } + // only save config if there were items to remove + if (gopts.recent->GetCount()) + { + while (gopts.recent->GetCount()) + gopts.recent->RemoveFileFromHistory(0); + + wxFileConfig* cfg = wxGetApp().cfg; + cfg->SetPath(wxT("/Recent")); + gopts.recent->Save(*cfg); + cfg->SetPath(wxT("/")); + cfg->Flush(); + } } EVT_HANDLER(RecentFreeze, "Freeze recent ROM list (toggle)") { - GetMenuOptionBool("RecentFreeze", gopts.recent_freeze); - update_opts(); + GetMenuOptionBool("RecentFreeze", gopts.recent_freeze); + update_opts(); } // following 10 should really be a single ranged handler // former names: Recent01 .. Recent10 EVT_HANDLER(wxID_FILE1, "Load recent ROM 1") { - panel->LoadGame(gopts.recent->GetHistoryFile(0)); + panel->LoadGame(gopts.recent->GetHistoryFile(0)); + if (gdbBreakOnLoad) GDBBreak(); } EVT_HANDLER(wxID_FILE2, "Load recent ROM 2") { - panel->LoadGame(gopts.recent->GetHistoryFile(1)); + panel->LoadGame(gopts.recent->GetHistoryFile(1)); + if (gdbBreakOnLoad) GDBBreak(); } EVT_HANDLER(wxID_FILE3, "Load recent ROM 3") { - panel->LoadGame(gopts.recent->GetHistoryFile(2)); + panel->LoadGame(gopts.recent->GetHistoryFile(2)); + if (gdbBreakOnLoad) GDBBreak(); } EVT_HANDLER(wxID_FILE4, "Load recent ROM 4") { - panel->LoadGame(gopts.recent->GetHistoryFile(3)); + panel->LoadGame(gopts.recent->GetHistoryFile(3)); + if (gdbBreakOnLoad) GDBBreak(); } EVT_HANDLER(wxID_FILE5, "Load recent ROM 5") { - panel->LoadGame(gopts.recent->GetHistoryFile(4)); + panel->LoadGame(gopts.recent->GetHistoryFile(4)); + if (gdbBreakOnLoad) GDBBreak(); } EVT_HANDLER(wxID_FILE6, "Load recent ROM 6") { - panel->LoadGame(gopts.recent->GetHistoryFile(5)); + panel->LoadGame(gopts.recent->GetHistoryFile(5)); + if (gdbBreakOnLoad) GDBBreak(); } EVT_HANDLER(wxID_FILE7, "Load recent ROM 7") { - panel->LoadGame(gopts.recent->GetHistoryFile(6)); + panel->LoadGame(gopts.recent->GetHistoryFile(6)); + if (gdbBreakOnLoad) GDBBreak(); } EVT_HANDLER(wxID_FILE8, "Load recent ROM 8") { - panel->LoadGame(gopts.recent->GetHistoryFile(7)); + panel->LoadGame(gopts.recent->GetHistoryFile(7)); + if (gdbBreakOnLoad) GDBBreak(); } EVT_HANDLER(wxID_FILE9, "Load recent ROM 9") { - panel->LoadGame(gopts.recent->GetHistoryFile(8)); + panel->LoadGame(gopts.recent->GetHistoryFile(8)); + if (gdbBreakOnLoad) GDBBreak(); } EVT_HANDLER(wxID_FILE10, "Load recent ROM 10") { - panel->LoadGame(gopts.recent->GetHistoryFile(9)); + panel->LoadGame(gopts.recent->GetHistoryFile(9)); + if (gdbBreakOnLoad) GDBBreak(); } -static const struct rom_maker { - const wxChar *code, *name; -} makers[] = { - { wxT("01"), wxT("Nintendo") }, - { wxT("02"), wxT("Rocket Games") }, - { wxT("08"), wxT("Capcom") }, - { wxT("09"), wxT("Hot B Co.") }, - { wxT("0A"), wxT("Jaleco") }, - { wxT("0B"), wxT("Coconuts Japan") }, - { wxT("0C"), wxT("Coconuts Japan/G.X.Media") }, - { wxT("0H"), wxT("Starfish") }, - { wxT("0L"), wxT("Warashi Inc.") }, - { wxT("0N"), wxT("Nowpro") }, - { wxT("0P"), wxT("Game Village") }, - { wxT("13"), wxT("Electronic Arts Japan") }, - { wxT("18"), wxT("Hudson Soft Japan") }, - { wxT("19"), wxT("S.C.P.") }, - { wxT("1A"), wxT("Yonoman") }, - { wxT("1G"), wxT("SMDE") }, - { wxT("1P"), wxT("Creatures Inc.") }, - { wxT("1Q"), wxT("TDK Deep Impresion") }, - { wxT("20"), wxT("Destination Software") }, - { wxT("22"), wxT("VR 1 Japan") }, - { wxT("25"), wxT("San-X") }, - { wxT("28"), wxT("Kemco Japan") }, - { wxT("29"), wxT("Seta") }, - { wxT("2H"), wxT("Ubisoft Japan") }, - { wxT("2K"), wxT("NEC InterChannel") }, - { wxT("2L"), wxT("Tam") }, - { wxT("2M"), wxT("Jordan") }, - { wxT("2N"), wxT("Smilesoft") }, - { wxT("2Q"), wxT("Mediakite") }, - { wxT("36"), wxT("Codemasters") }, - { wxT("37"), wxT("GAGA Communications") }, - { wxT("38"), wxT("Laguna") }, - { wxT("39"), wxT("Telstar Fun and Games") }, - { wxT("41"), wxT("Ubi Soft Entertainment") }, - { wxT("42"), wxT("Sunsoft") }, - { wxT("47"), wxT("Spectrum Holobyte") }, - { wxT("49"), wxT("IREM") }, - { wxT("4D"), wxT("Malibu Games") }, - { wxT("4F"), wxT("Eidos/U.S. Gold") }, - { wxT("4J"), wxT("Fox Interactive") }, - { wxT("4K"), wxT("Time Warner Interactive") }, - { wxT("4Q"), wxT("Disney") }, - { wxT("4S"), wxT("Black Pearl") }, - { wxT("4X"), wxT("GT Interactive") }, - { wxT("4Y"), wxT("RARE") }, - { wxT("4Z"), wxT("Crave Entertainment") }, - { wxT("50"), wxT("Absolute Entertainment") }, - { wxT("51"), wxT("Acclaim") }, - { wxT("52"), wxT("Activision") }, - { wxT("53"), wxT("American Sammy Corp.") }, - { wxT("54"), wxT("Take 2 Interactive") }, - { wxT("55"), wxT("Hi Tech") }, - { wxT("56"), wxT("LJN LTD.") }, - { wxT("58"), wxT("Mattel") }, - { wxT("5A"), wxT("Mindscape/Red Orb Ent.") }, - { wxT("5C"), wxT("Taxan") }, - { wxT("5D"), wxT("Midway") }, - { wxT("5F"), wxT("American Softworks") }, - { wxT("5G"), wxT("Majesco Sales Inc") }, - { wxT("5H"), wxT("3DO") }, - { wxT("5K"), wxT("Hasbro") }, - { wxT("5L"), wxT("NewKidCo") }, - { wxT("5M"), wxT("Telegames") }, - { wxT("5N"), wxT("Metro3D") }, - { wxT("5P"), wxT("Vatical Entertainment") }, - { wxT("5Q"), wxT("LEGO Media") }, - { wxT("5S"), wxT("Xicat Interactive") }, - { wxT("5T"), wxT("Cryo Interactive") }, - { wxT("5W"), wxT("Red Storm Ent./BKN Ent.") }, - { wxT("5X"), wxT("Microids") }, - { wxT("5Z"), wxT("Conspiracy Entertainment Corp.") }, - { wxT("60"), wxT("Titus Interactive Studios") }, - { wxT("61"), wxT("Virgin Interactive") }, - { wxT("62"), wxT("Maxis") }, - { wxT("64"), wxT("LucasArts Entertainment") }, - { wxT("67"), wxT("Ocean") }, - { wxT("69"), wxT("Electronic Arts") }, - { wxT("6E"), wxT("Elite Systems Ltd.") }, - { wxT("6F"), wxT("Electro Brain") }, - { wxT("6G"), wxT("The Learning Company") }, - { wxT("6H"), wxT("BBC") }, - { wxT("6J"), wxT("Software 2000") }, - { wxT("6L"), wxT("BAM! Entertainment") }, - { wxT("6M"), wxT("Studio 3") }, - { wxT("6Q"), wxT("Classified Games") }, - { wxT("6S"), wxT("TDK Mediactive") }, - { wxT("6U"), wxT("DreamCatcher") }, - { wxT("6V"), wxT("JoWood Productions") }, - { wxT("6W"), wxT("SEGA") }, - { wxT("6X"), wxT("Wannado Edition") }, - { wxT("6Y"), wxT("LSP") }, - { wxT("6Z"), wxT("ITE Media") }, - { wxT("70"), wxT("Infogrames") }, - { wxT("71"), wxT("Interplay") }, - { wxT("72"), wxT("JVC Musical Industries Inc") }, - { wxT("73"), wxT("Parker Brothers") }, - { wxT("75"), wxT("SCI") }, - { wxT("78"), wxT("THQ") }, - { wxT("79"), wxT("Accolade") }, - { wxT("7A"), wxT("Triffix Ent. Inc.") }, - { wxT("7C"), wxT("Microprose Software") }, - { wxT("7D"), wxT("Universal Interactive Studios") }, - { wxT("7F"), wxT("Kemco") }, - { wxT("7G"), wxT("Rage Software") }, - { wxT("7H"), wxT("Encore") }, - { wxT("7J"), wxT("Zoo") }, - { wxT("7K"), wxT("BVM") }, - { wxT("7L"), wxT("Simon & Schuster Interactive") }, - { wxT("7M"), wxT("Asmik Ace Entertainment Inc./AIA") }, - { wxT("7N"), wxT("Empire Interactive") }, - { wxT("7Q"), wxT("Jester Interactive") }, - { wxT("7T"), wxT("Scholastic") }, - { wxT("7U"), wxT("Ignition Entertainment") }, - { wxT("7W"), wxT("Stadlbauer") }, - { wxT("80"), wxT("Misawa") }, - { wxT("83"), wxT("LOZC") }, - { wxT("8B"), wxT("Bulletproof Software") }, - { wxT("8C"), wxT("Vic Tokai Inc.") }, - { wxT("8J"), wxT("General Entertainment") }, - { wxT("8N"), wxT("Success") }, - { wxT("8P"), wxT("SEGA Japan") }, - { wxT("91"), wxT("Chun Soft") }, - { wxT("92"), wxT("Video System") }, - { wxT("93"), wxT("BEC") }, - { wxT("96"), wxT("Yonezawa/S'pal") }, - { wxT("97"), wxT("Kaneko") }, - { wxT("99"), wxT("Victor Interactive Software") }, - { wxT("9A"), wxT("Nichibutsu/Nihon Bussan") }, - { wxT("9B"), wxT("Tecmo") }, - { wxT("9C"), wxT("Imagineer") }, - { wxT("9F"), wxT("Nova") }, - { wxT("9H"), wxT("Bottom Up") }, - { wxT("9L"), wxT("Hasbro Japan") }, - { wxT("9N"), wxT("Marvelous Entertainment") }, - { wxT("9P"), wxT("Keynet Inc.") }, - { wxT("9Q"), wxT("Hands-On Entertainment") }, - { wxT("A0"), wxT("Telenet") }, - { wxT("A1"), wxT("Hori") }, - { wxT("A4"), wxT("Konami") }, - { wxT("A6"), wxT("Kawada") }, - { wxT("A7"), wxT("Takara") }, - { wxT("A9"), wxT("Technos Japan Corp.") }, - { wxT("AA"), wxT("JVC") }, - { wxT("AC"), wxT("Toei Animation") }, - { wxT("AD"), wxT("Toho") }, - { wxT("AF"), wxT("Namco") }, - { wxT("AG"), wxT("Media Rings Corporation") }, - { wxT("AH"), wxT("J-Wing") }, - { wxT("AK"), wxT("KID") }, - { wxT("AL"), wxT("MediaFactory") }, - { wxT("AP"), wxT("Infogrames Hudson") }, - { wxT("AQ"), wxT("Kiratto. Ludic Inc") }, - { wxT("B0"), wxT("Acclaim Japan") }, - { wxT("B1"), wxT("ASCII") }, - { wxT("B2"), wxT("Bandai") }, - { wxT("B4"), wxT("Enix") }, - { wxT("B6"), wxT("HAL Laboratory") }, - { wxT("B7"), wxT("SNK") }, - { wxT("B9"), wxT("Pony Canyon Hanbai") }, - { wxT("BA"), wxT("Culture Brain") }, - { wxT("BB"), wxT("Sunsoft") }, - { wxT("BD"), wxT("Sony Imagesoft") }, - { wxT("BF"), wxT("Sammy") }, - { wxT("BG"), wxT("Magical") }, - { wxT("BJ"), wxT("Compile") }, - { wxT("BL"), wxT("MTO Inc.") }, - { wxT("BN"), wxT("Sunrise Interactive") }, - { wxT("BP"), wxT("Global A Entertainment") }, - { wxT("BQ"), wxT("Fuuki") }, - { wxT("C0"), wxT("Taito") }, - { wxT("C2"), wxT("Kemco") }, - { wxT("C3"), wxT("Square Soft") }, - { wxT("C5"), wxT("Data East") }, - { wxT("C6"), wxT("Tonkin House") }, - { wxT("C8"), wxT("Koei") }, - { wxT("CA"), wxT("Konami/Palcom/Ultra") }, - { wxT("CB"), wxT("Vapinc/NTVIC") }, - { wxT("CC"), wxT("Use Co.,Ltd.") }, - { wxT("CD"), wxT("Meldac") }, - { wxT("CE"), wxT("FCI/Pony Canyon") }, - { wxT("CF"), wxT("Angel") }, - { wxT("CM"), wxT("Konami Computer Entertainment Osaka") }, - { wxT("CP"), wxT("Enterbrain") }, - { wxT("D1"), wxT("Sofel") }, - { wxT("D2"), wxT("Quest") }, - { wxT("D3"), wxT("Sigma Enterprises") }, - { wxT("D4"), wxT("Ask Kodansa") }, - { wxT("D6"), wxT("Naxat") }, - { wxT("D7"), wxT("Copya System") }, - { wxT("D9"), wxT("Banpresto") }, - { wxT("DA"), wxT("TOMY") }, - { wxT("DB"), wxT("LJN Japan") }, - { wxT("DD"), wxT("NCS") }, - { wxT("DF"), wxT("Altron Corporation") }, - { wxT("DH"), wxT("Gaps Inc.") }, - { wxT("DN"), wxT("ELF") }, - { wxT("E2"), wxT("Yutaka") }, - { wxT("E3"), wxT("Varie") }, - { wxT("E5"), wxT("Epoch") }, - { wxT("E7"), wxT("Athena") }, - { wxT("E8"), wxT("Asmik Ace Entertainment Inc.") }, - { wxT("E9"), wxT("Natsume") }, - { wxT("EA"), wxT("King Records") }, - { wxT("EB"), wxT("Atlus") }, - { wxT("EC"), wxT("Epic/Sony Records") }, - { wxT("EE"), wxT("IGS") }, - { wxT("EL"), wxT("Spike") }, - { wxT("EM"), wxT("Konami Computer Entertainment Tokyo") }, - { wxT("EN"), wxT("Alphadream Corporation") }, - { wxT("F0"), wxT("A Wave") }, - { wxT("G1"), wxT("PCCW") }, - { wxT("G4"), wxT("KiKi Co Ltd") }, - { wxT("G5"), wxT("Open Sesame Inc.") }, - { wxT("G6"), wxT("Sims") }, - { wxT("G7"), wxT("Broccoli") }, - { wxT("G8"), wxT("Avex") }, - { wxT("G9"), wxT("D3 Publisher") }, - { wxT("GB"), wxT("Konami Computer Entertainment Japan") }, - { wxT("GD"), wxT("Square-Enix") }, - { wxT("HY"), wxT("Sachen") } +static const struct rom_maker +{ + const wxChar* code, *name; +} makers[] = +{ + { wxT("01"), wxT("Nintendo") }, + { wxT("02"), wxT("Rocket Games") }, + { wxT("08"), wxT("Capcom") }, + { wxT("09"), wxT("Hot B Co.") }, + { wxT("0A"), wxT("Jaleco") }, + { wxT("0B"), wxT("Coconuts Japan") }, + { wxT("0C"), wxT("Coconuts Japan/G.X.Media") }, + { wxT("0H"), wxT("Starfish") }, + { wxT("0L"), wxT("Warashi Inc.") }, + { wxT("0N"), wxT("Nowpro") }, + { wxT("0P"), wxT("Game Village") }, + { wxT("13"), wxT("Electronic Arts Japan") }, + { wxT("18"), wxT("Hudson Soft Japan") }, + { wxT("19"), wxT("S.C.P.") }, + { wxT("1A"), wxT("Yonoman") }, + { wxT("1G"), wxT("SMDE") }, + { wxT("1P"), wxT("Creatures Inc.") }, + { wxT("1Q"), wxT("TDK Deep Impresion") }, + { wxT("20"), wxT("Destination Software") }, + { wxT("22"), wxT("VR 1 Japan") }, + { wxT("25"), wxT("San-X") }, + { wxT("28"), wxT("Kemco Japan") }, + { wxT("29"), wxT("Seta") }, + { wxT("2H"), wxT("Ubisoft Japan") }, + { wxT("2K"), wxT("NEC InterChannel") }, + { wxT("2L"), wxT("Tam") }, + { wxT("2M"), wxT("Jordan") }, + { wxT("2N"), wxT("Smilesoft") }, + { wxT("2Q"), wxT("Mediakite") }, + { wxT("36"), wxT("Codemasters") }, + { wxT("37"), wxT("GAGA Communications") }, + { wxT("38"), wxT("Laguna") }, + { wxT("39"), wxT("Telstar Fun and Games") }, + { wxT("41"), wxT("Ubi Soft Entertainment") }, + { wxT("42"), wxT("Sunsoft") }, + { wxT("47"), wxT("Spectrum Holobyte") }, + { wxT("49"), wxT("IREM") }, + { wxT("4D"), wxT("Malibu Games") }, + { wxT("4F"), wxT("Eidos/U.S. Gold") }, + { wxT("4J"), wxT("Fox Interactive") }, + { wxT("4K"), wxT("Time Warner Interactive") }, + { wxT("4Q"), wxT("Disney") }, + { wxT("4S"), wxT("Black Pearl") }, + { wxT("4X"), wxT("GT Interactive") }, + { wxT("4Y"), wxT("RARE") }, + { wxT("4Z"), wxT("Crave Entertainment") }, + { wxT("50"), wxT("Absolute Entertainment") }, + { wxT("51"), wxT("Acclaim") }, + { wxT("52"), wxT("Activision") }, + { wxT("53"), wxT("American Sammy Corp.") }, + { wxT("54"), wxT("Take 2 Interactive") }, + { wxT("55"), wxT("Hi Tech") }, + { wxT("56"), wxT("LJN LTD.") }, + { wxT("58"), wxT("Mattel") }, + { wxT("5A"), wxT("Mindscape/Red Orb Ent.") }, + { wxT("5C"), wxT("Taxan") }, + { wxT("5D"), wxT("Midway") }, + { wxT("5F"), wxT("American Softworks") }, + { wxT("5G"), wxT("Majesco Sales Inc") }, + { wxT("5H"), wxT("3DO") }, + { wxT("5K"), wxT("Hasbro") }, + { wxT("5L"), wxT("NewKidCo") }, + { wxT("5M"), wxT("Telegames") }, + { wxT("5N"), wxT("Metro3D") }, + { wxT("5P"), wxT("Vatical Entertainment") }, + { wxT("5Q"), wxT("LEGO Media") }, + { wxT("5S"), wxT("Xicat Interactive") }, + { wxT("5T"), wxT("Cryo Interactive") }, + { wxT("5W"), wxT("Red Storm Ent./BKN Ent.") }, + { wxT("5X"), wxT("Microids") }, + { wxT("5Z"), wxT("Conspiracy Entertainment Corp.") }, + { wxT("60"), wxT("Titus Interactive Studios") }, + { wxT("61"), wxT("Virgin Interactive") }, + { wxT("62"), wxT("Maxis") }, + { wxT("64"), wxT("LucasArts Entertainment") }, + { wxT("67"), wxT("Ocean") }, + { wxT("69"), wxT("Electronic Arts") }, + { wxT("6E"), wxT("Elite Systems Ltd.") }, + { wxT("6F"), wxT("Electro Brain") }, + { wxT("6G"), wxT("The Learning Company") }, + { wxT("6H"), wxT("BBC") }, + { wxT("6J"), wxT("Software 2000") }, + { wxT("6L"), wxT("BAM! Entertainment") }, + { wxT("6M"), wxT("Studio 3") }, + { wxT("6Q"), wxT("Classified Games") }, + { wxT("6S"), wxT("TDK Mediactive") }, + { wxT("6U"), wxT("DreamCatcher") }, + { wxT("6V"), wxT("JoWood Productions") }, + { wxT("6W"), wxT("SEGA") }, + { wxT("6X"), wxT("Wannado Edition") }, + { wxT("6Y"), wxT("LSP") }, + { wxT("6Z"), wxT("ITE Media") }, + { wxT("70"), wxT("Infogrames") }, + { wxT("71"), wxT("Interplay") }, + { wxT("72"), wxT("JVC Musical Industries Inc") }, + { wxT("73"), wxT("Parker Brothers") }, + { wxT("75"), wxT("SCI") }, + { wxT("78"), wxT("THQ") }, + { wxT("79"), wxT("Accolade") }, + { wxT("7A"), wxT("Triffix Ent. Inc.") }, + { wxT("7C"), wxT("Microprose Software") }, + { wxT("7D"), wxT("Universal Interactive Studios") }, + { wxT("7F"), wxT("Kemco") }, + { wxT("7G"), wxT("Rage Software") }, + { wxT("7H"), wxT("Encore") }, + { wxT("7J"), wxT("Zoo") }, + { wxT("7K"), wxT("BVM") }, + { wxT("7L"), wxT("Simon & Schuster Interactive") }, + { wxT("7M"), wxT("Asmik Ace Entertainment Inc./AIA") }, + { wxT("7N"), wxT("Empire Interactive") }, + { wxT("7Q"), wxT("Jester Interactive") }, + { wxT("7T"), wxT("Scholastic") }, + { wxT("7U"), wxT("Ignition Entertainment") }, + { wxT("7W"), wxT("Stadlbauer") }, + { wxT("80"), wxT("Misawa") }, + { wxT("83"), wxT("LOZC") }, + { wxT("8B"), wxT("Bulletproof Software") }, + { wxT("8C"), wxT("Vic Tokai Inc.") }, + { wxT("8J"), wxT("General Entertainment") }, + { wxT("8N"), wxT("Success") }, + { wxT("8P"), wxT("SEGA Japan") }, + { wxT("91"), wxT("Chun Soft") }, + { wxT("92"), wxT("Video System") }, + { wxT("93"), wxT("BEC") }, + { wxT("96"), wxT("Yonezawa/S'pal") }, + { wxT("97"), wxT("Kaneko") }, + { wxT("99"), wxT("Victor Interactive Software") }, + { wxT("9A"), wxT("Nichibutsu/Nihon Bussan") }, + { wxT("9B"), wxT("Tecmo") }, + { wxT("9C"), wxT("Imagineer") }, + { wxT("9F"), wxT("Nova") }, + { wxT("9H"), wxT("Bottom Up") }, + { wxT("9L"), wxT("Hasbro Japan") }, + { wxT("9N"), wxT("Marvelous Entertainment") }, + { wxT("9P"), wxT("Keynet Inc.") }, + { wxT("9Q"), wxT("Hands-On Entertainment") }, + { wxT("A0"), wxT("Telenet") }, + { wxT("A1"), wxT("Hori") }, + { wxT("A4"), wxT("Konami") }, + { wxT("A6"), wxT("Kawada") }, + { wxT("A7"), wxT("Takara") }, + { wxT("A9"), wxT("Technos Japan Corp.") }, + { wxT("AA"), wxT("JVC") }, + { wxT("AC"), wxT("Toei Animation") }, + { wxT("AD"), wxT("Toho") }, + { wxT("AF"), wxT("Namco") }, + { wxT("AG"), wxT("Media Rings Corporation") }, + { wxT("AH"), wxT("J-Wing") }, + { wxT("AK"), wxT("KID") }, + { wxT("AL"), wxT("MediaFactory") }, + { wxT("AP"), wxT("Infogrames Hudson") }, + { wxT("AQ"), wxT("Kiratto. Ludic Inc") }, + { wxT("B0"), wxT("Acclaim Japan") }, + { wxT("B1"), wxT("ASCII") }, + { wxT("B2"), wxT("Bandai") }, + { wxT("B4"), wxT("Enix") }, + { wxT("B6"), wxT("HAL Laboratory") }, + { wxT("B7"), wxT("SNK") }, + { wxT("B9"), wxT("Pony Canyon Hanbai") }, + { wxT("BA"), wxT("Culture Brain") }, + { wxT("BB"), wxT("Sunsoft") }, + { wxT("BD"), wxT("Sony Imagesoft") }, + { wxT("BF"), wxT("Sammy") }, + { wxT("BG"), wxT("Magical") }, + { wxT("BJ"), wxT("Compile") }, + { wxT("BL"), wxT("MTO Inc.") }, + { wxT("BN"), wxT("Sunrise Interactive") }, + { wxT("BP"), wxT("Global A Entertainment") }, + { wxT("BQ"), wxT("Fuuki") }, + { wxT("C0"), wxT("Taito") }, + { wxT("C2"), wxT("Kemco") }, + { wxT("C3"), wxT("Square Soft") }, + { wxT("C5"), wxT("Data East") }, + { wxT("C6"), wxT("Tonkin House") }, + { wxT("C8"), wxT("Koei") }, + { wxT("CA"), wxT("Konami/Palcom/Ultra") }, + { wxT("CB"), wxT("Vapinc/NTVIC") }, + { wxT("CC"), wxT("Use Co.,Ltd.") }, + { wxT("CD"), wxT("Meldac") }, + { wxT("CE"), wxT("FCI/Pony Canyon") }, + { wxT("CF"), wxT("Angel") }, + { wxT("CM"), wxT("Konami Computer Entertainment Osaka") }, + { wxT("CP"), wxT("Enterbrain") }, + { wxT("D1"), wxT("Sofel") }, + { wxT("D2"), wxT("Quest") }, + { wxT("D3"), wxT("Sigma Enterprises") }, + { wxT("D4"), wxT("Ask Kodansa") }, + { wxT("D6"), wxT("Naxat") }, + { wxT("D7"), wxT("Copya System") }, + { wxT("D9"), wxT("Banpresto") }, + { wxT("DA"), wxT("TOMY") }, + { wxT("DB"), wxT("LJN Japan") }, + { wxT("DD"), wxT("NCS") }, + { wxT("DF"), wxT("Altron Corporation") }, + { wxT("DH"), wxT("Gaps Inc.") }, + { wxT("DN"), wxT("ELF") }, + { wxT("E2"), wxT("Yutaka") }, + { wxT("E3"), wxT("Varie") }, + { wxT("E5"), wxT("Epoch") }, + { wxT("E7"), wxT("Athena") }, + { wxT("E8"), wxT("Asmik Ace Entertainment Inc.") }, + { wxT("E9"), wxT("Natsume") }, + { wxT("EA"), wxT("King Records") }, + { wxT("EB"), wxT("Atlus") }, + { wxT("EC"), wxT("Epic/Sony Records") }, + { wxT("EE"), wxT("IGS") }, + { wxT("EL"), wxT("Spike") }, + { wxT("EM"), wxT("Konami Computer Entertainment Tokyo") }, + { wxT("EN"), wxT("Alphadream Corporation") }, + { wxT("F0"), wxT("A Wave") }, + { wxT("G1"), wxT("PCCW") }, + { wxT("G4"), wxT("KiKi Co Ltd") }, + { wxT("G5"), wxT("Open Sesame Inc.") }, + { wxT("G6"), wxT("Sims") }, + { wxT("G7"), wxT("Broccoli") }, + { wxT("G8"), wxT("Avex") }, + { wxT("G9"), wxT("D3 Publisher") }, + { wxT("GB"), wxT("Konami Computer Entertainment Japan") }, + { wxT("GD"), wxT("Square-Enix") }, + { wxT("HY"), wxT("Sachen") } }; #define num_makers (sizeof(makers)/sizeof(makers[0])) static bool maker_lt(const rom_maker &r1, const rom_maker &r2) { - return wxStrcmp(r1.code, r2.code) < 0; + return wxStrcmp(r1.code, r2.code) < 0; } -EVT_HANDLER_MASK(RomInformation, "ROM information...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(RomInformation, "ROM information...", CMDEN_GB | CMDEN_GBA) { - wxString s; + wxString s; #define setlab(id) do { \ /* SetLabelText is not in 2.8 */ \ s.Replace(wxT("&"), wxT("&&"), true); \ @@ -456,211 +482,277 @@ EVT_HANDLER_MASK(RomInformation, "ROM information...", CMDEN_GB|CMDEN_GBA) s = wxString((const char *)&(ts), wxConvLibc, l); \ setlab(id); \ } while(0) - switch(panel->game_type()) { - case IMAGE_GB: + + switch (panel->game_type()) { - wxDialog *dlg = GetXRCDialog("GBROMInfo"); - setlabs("Title", gbRom[0x134], 15); - setblab("Color", gbRom[0x143]); - if(gbRom[0x14b] == 0x33) - s = wxString((const char *)&gbRom[0x144], wxConvUTF8, 2); - else - s.Printf(wxT("%02x"), gbRom[0x14b]); - setlab("MakerCode"); - const rom_maker m = { s.c_str() }, *rm; - rm = std::lower_bound(&makers[0], &makers[num_makers], m, maker_lt); - if(rm < &makers[num_makers] && !wxStrcmp(m.code, rm->code)) - s = rm->name; - else - s = _("Unknown"); - setlab("MakerName"); - setblab("UnitCode", gbRom[0x146]); - const wxChar *type; - switch(gbRom[0x147]) { - case 0x00: - type = _("ROM"); - break; - case 0x01: - type = _("ROM+MBC1"); - break; - case 0x02: - type = _("ROM+MBC1+RAM"); - break; - case 0x03: - type = _("ROM+MBC1+RAM+BATT"); - break; - case 0x05: - type = _("ROM+MBC2"); - break; - case 0x06: - type = _("ROM+MBC2+BATT"); - break; - case 0x0b: - type = _("ROM+MMM01"); - break; - case 0x0c: - type = _("ROM+MMM01+RAM"); - break; - case 0x0d: - type = _("ROM+MMM01+RAM+BATT"); - break; - case 0x0f: - type = _("ROM+MBC3+TIMER+BATT"); - break; - case 0x10: - type = _("ROM+MBC3+TIMER+RAM+BATT"); - break; - case 0x11: - type = _("ROM+MBC3"); - break; - case 0x12: - type = _("ROM+MBC3+RAM"); - break; - case 0x13: - type = _("ROM+MBC3+RAM+BATT"); - break; - case 0x19: - type = _("ROM+MBC5"); - break; - case 0x1a: - type = _("ROM+MBC5+RAM"); - break; - case 0x1b: - type = _("ROM+MBC5+RAM+BATT"); - break; - case 0x1c: - type = _("ROM+MBC5+RUMBLE"); - break; - case 0x1d: - type = _("ROM+MBC5+RUMBLE+RAM"); - break; - case 0x1e: - type = _("ROM+MBC5+RUMBLE+RAM+BATT"); - break; - case 0x22: - type = _("ROM+MBC7+BATT"); - break; - case 0x55: - type = _("GameGenie"); - break; - case 0x56: - type = _("GameShark V3.0"); - break; - case 0xfc: - type = _("ROM+POCKET CAMERA"); - break; - case 0xfd: - type = _("ROM+BANDAI TAMA5"); - break; - case 0xfe: - type = _("ROM+HuC-3"); - break; - case 0xff: - type = _("ROM+HuC-1"); - break; - default: - type = _("Unknown"); - } - setblabs("DeviceType", gbRom[0x147], type); - switch(gbRom[0x148]) { - case 0: - type = wxT("32K"); - break; - case 1: - type = wxT("64K"); - break; - case 2: - type = wxT("128K"); - break; - case 3: - type = wxT("256K"); - break; - case 4: - type = wxT("512K"); - break; - case 5: - type = wxT("1M"); - break; - case 6: - type = wxT("2M"); - break; - case 7: - type = wxT("4M"); - break; - default: - type = _("Unknown"); - } - setblabs("ROMSize", gbRom[0x148], type); - switch(gbRom[0x149]) { - case 0: - type = _("None"); - break; - case 1: - type = wxT("2K"); - break; - case 2: - type = wxT("8K"); - break; - case 3: - type = wxT("32K"); - break; - case 4: - type = wxT("128K"); - break; - case 5: - type = wxT("64K"); - break; - } - setblabs("RAMSize", gbRom[0x149], type); - setblab("DestCode", gbRom[0x14a]); - setblab("LicCode", gbRom[0x14b]); - setblab("Version", gbRom[0x14c]); - u8 crc = 25; - for(int i = 0x134; i < 0x14d; i++) - crc += gbRom[i]; - crc = 256 - crc; - s.Printf(wxT("%02x (%02x)"), crc, gbRom[0x14d]); - setlab("CRC"); - u16 crc16 = 0; - for(int i = 0; i < gbRomSize; i++) - crc16 += gbRom[i]; - crc16 -= gbRom[0x14e] + gbRom[0x14f]; - s.Printf(wxT("%04x (%04x)"), crc16, gbRom[0x14e]*256+gbRom[0x14f]); - setlab("Checksum"); - dlg->Fit(); - ShowModal(dlg); + case IMAGE_GB: + { + wxDialog* dlg = GetXRCDialog("GBROMInfo"); + setlabs("Title", gbRom[0x134], 15); + setblab("Color", gbRom[0x143]); + + if (gbRom[0x14b] == 0x33) + s = wxString((const char*)&gbRom[0x144], wxConvUTF8, 2); + else + s.Printf(wxT("%02x"), gbRom[0x14b]); + + setlab("MakerCode"); + const rom_maker m = { s.c_str() }, *rm; + rm = std::lower_bound(&makers[0], &makers[num_makers], m, maker_lt); + + if (rm < &makers[num_makers] && !wxStrcmp(m.code, rm->code)) + s = rm->name; + else + s = _("Unknown"); + + setlab("MakerName"); + setblab("UnitCode", gbRom[0x146]); + const wxChar* type; + + switch (gbRom[0x147]) + { + case 0x00: + type = _("ROM"); + break; + + case 0x01: + type = _("ROM+MBC1"); + break; + + case 0x02: + type = _("ROM+MBC1+RAM"); + break; + + case 0x03: + type = _("ROM+MBC1+RAM+BATT"); + break; + + case 0x05: + type = _("ROM+MBC2"); + break; + + case 0x06: + type = _("ROM+MBC2+BATT"); + break; + + case 0x0b: + type = _("ROM+MMM01"); + break; + + case 0x0c: + type = _("ROM+MMM01+RAM"); + break; + + case 0x0d: + type = _("ROM+MMM01+RAM+BATT"); + break; + + case 0x0f: + type = _("ROM+MBC3+TIMER+BATT"); + break; + + case 0x10: + type = _("ROM+MBC3+TIMER+RAM+BATT"); + break; + + case 0x11: + type = _("ROM+MBC3"); + break; + + case 0x12: + type = _("ROM+MBC3+RAM"); + break; + + case 0x13: + type = _("ROM+MBC3+RAM+BATT"); + break; + + case 0x19: + type = _("ROM+MBC5"); + break; + + case 0x1a: + type = _("ROM+MBC5+RAM"); + break; + + case 0x1b: + type = _("ROM+MBC5+RAM+BATT"); + break; + + case 0x1c: + type = _("ROM+MBC5+RUMBLE"); + break; + + case 0x1d: + type = _("ROM+MBC5+RUMBLE+RAM"); + break; + + case 0x1e: + type = _("ROM+MBC5+RUMBLE+RAM+BATT"); + break; + + case 0x22: + type = _("ROM+MBC7+BATT"); + break; + + case 0x55: + type = _("GameGenie"); + break; + + case 0x56: + type = _("GameShark V3.0"); + break; + + case 0xfc: + type = _("ROM+POCKET CAMERA"); + break; + + case 0xfd: + type = _("ROM+BANDAI TAMA5"); + break; + + case 0xfe: + type = _("ROM+HuC-3"); + break; + + case 0xff: + type = _("ROM+HuC-1"); + break; + + default: + type = _("Unknown"); + } + + setblabs("DeviceType", gbRom[0x147], type); + + switch (gbRom[0x148]) + { + case 0: + type = wxT("32K"); + break; + + case 1: + type = wxT("64K"); + break; + + case 2: + type = wxT("128K"); + break; + + case 3: + type = wxT("256K"); + break; + + case 4: + type = wxT("512K"); + break; + + case 5: + type = wxT("1M"); + break; + + case 6: + type = wxT("2M"); + break; + + case 7: + type = wxT("4M"); + break; + + default: + type = _("Unknown"); + } + + setblabs("ROMSize", gbRom[0x148], type); + + switch (gbRom[0x149]) + { + case 0: + type = _("None"); + break; + + case 1: + type = wxT("2K"); + break; + + case 2: + type = wxT("8K"); + break; + + case 3: + type = wxT("32K"); + break; + + case 4: + type = wxT("128K"); + break; + + case 5: + type = wxT("64K"); + break; + } + + setblabs("RAMSize", gbRom[0x149], type); + setblab("DestCode", gbRom[0x14a]); + setblab("LicCode", gbRom[0x14b]); + setblab("Version", gbRom[0x14c]); + u8 crc = 25; + + for (int i = 0x134; i < 0x14d; i++) + crc += gbRom[i]; + + crc = 256 - crc; + s.Printf(wxT("%02x (%02x)"), crc, gbRom[0x14d]); + setlab("CRC"); + u16 crc16 = 0; + + for (int i = 0; i < gbRomSize; i++) + crc16 += gbRom[i]; + + crc16 -= gbRom[0x14e] + gbRom[0x14f]; + s.Printf(wxT("%04x (%04x)"), crc16, gbRom[0x14e] * 256 + gbRom[0x14f]); + setlab("Checksum"); + dlg->Fit(); + ShowModal(dlg); } break; - case IMAGE_GBA: + + case IMAGE_GBA: { - wxDialog *dlg = GetXRCDialog("GBAROMInfo"); - setlabs("Title", rom[0xa0], 12); - setlabs("GameCode", rom[0xac], 4); - setlabs("MakerCode", rom[0xb0], 2); - const rom_maker m = { s.c_str() }, *rm; - rm = std::lower_bound(&makers[0], &makers[num_makers], m, maker_lt); - if(rm < &makers[num_makers] && !wxStrcmp(m.code, rm->code)) - s = rm->name; - else - s = _("Unknown"); - setlab("MakerName"); - setblab("UnitCode", rom[0xb3]); - s.Printf(wxT("%02x"), (unsigned int)rom[0xb4]); - if(rom[0xb4] & 0x80) - s.append(wxT(" (DACS)")); - setlab("DeviceType"); - setblab("Version", rom[0xbc]); - u8 crc = 0x19; - for(int i = 0xa0; i < 0xbd; i++) - crc += rom[i]; - crc = -crc; - s.Printf(wxT("%02x (%02x)"), crc, rom[0xbd]); - setlab("CRC"); - dlg->Fit(); - ShowModal(dlg); + wxDialog* dlg = GetXRCDialog("GBAROMInfo"); + setlabs("Title", rom[0xa0], 12); + setlabs("GameCode", rom[0xac], 4); + setlabs("MakerCode", rom[0xb0], 2); + const rom_maker m = { s.c_str() }, *rm; + rm = std::lower_bound(&makers[0], &makers[num_makers], m, maker_lt); + + if (rm < &makers[num_makers] && !wxStrcmp(m.code, rm->code)) + s = rm->name; + else + s = _("Unknown"); + + setlab("MakerName"); + setblab("UnitCode", rom[0xb3]); + s.Printf(wxT("%02x"), (unsigned int)rom[0xb4]); + + if (rom[0xb4] & 0x80) + s.append(wxT(" (DACS)")); + + setlab("DeviceType"); + setblab("Version", rom[0xbc]); + u8 crc = 0x19; + + for (int i = 0xa0; i < 0xbd; i++) + crc += rom[i]; + + crc = -crc; + s.Printf(wxT("%02x (%02x)"), crc, rom[0xbd]); + setlab("CRC"); + dlg->Fit(); + ShowModal(dlg); } break; - } + } } static wxString loaddotcodefile_path; @@ -669,13 +761,15 @@ static wxString savedotcodefile_path; EVT_HANDLER_MASK(LoadDotCodeFile, "Load e-Reader Dot Code...", CMDEN_GBA) { wxFileDialog dlg(this, _("Select Dot Code file"), loaddotcodefile_path, wxEmptyString, - _( - "e-Reader Dot Code (*.bin;*.raw)|" - "*.bin;*.raw" - ), wxFD_OPEN | wxFD_FILE_MUST_EXIST); + _( + "e-Reader Dot Code (*.bin;*.raw)|" + "*.bin;*.raw" + ), wxFD_OPEN | wxFD_FILE_MUST_EXIST); int ret = ShowModal(&dlg); + if (ret != wxID_OK) return; + loaddotcodefile_path = dlg.GetPath(); SetLoadDotCodeFile(loaddotcodefile_path.mb_str(wxConvUTF8)); } @@ -683,419 +777,540 @@ EVT_HANDLER_MASK(LoadDotCodeFile, "Load e-Reader Dot Code...", CMDEN_GBA) EVT_HANDLER_MASK(SaveDotCodeFile, "Save e-Reader Dot Code...", CMDEN_GBA) { wxFileDialog dlg(this, _("Select Dot Code file"), savedotcodefile_path, wxEmptyString, - _( - "e-Reader Dot Code (*.bin;*.raw)|" - "*.bin;*.raw" - ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + _( + "e-Reader Dot Code (*.bin;*.raw)|" + "*.bin;*.raw" + ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); int ret = ShowModal(&dlg); + if (ret != wxID_OK) return; + savedotcodefile_path = dlg.GetPath(); SetLoadDotCodeFile(savedotcodefile_path.mb_str(wxConvUTF8)); } static wxString batimp_path; -EVT_HANDLER_MASK(ImportBatteryFile, "Import battery file...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(ImportBatteryFile, "Import battery file...", CMDEN_GB | CMDEN_GBA) { - if(!batimp_path.size()) - batimp_path = panel->bat_dir(); - wxFileDialog dlg(this, _("Select battery file"), batimp_path, wxEmptyString, - _("Battery file (*.sav)|*.sav|Flash save (*.dat)|*.dat"), wxFD_OPEN|wxFD_FILE_MUST_EXIST); - int ret = ShowModal(&dlg); - batimp_path = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - wxString fn = dlg.GetPath(); - ret = wxMessageBox(_("Importing a battery file will erase any saved games (permanently after the next write). Do you want to continue?"), - _("Confirm import"), wxYES_NO|wxICON_EXCLAMATION); - if(ret == wxYES) { - wxString msg; - if(panel->emusys->emuReadBattery(fn.mb_fn_str())) - msg.Printf(_("Loaded battery %s"), fn.c_str()); - else - msg.Printf(_("Error loading battery %s"), fn.c_str()); - systemScreenMessage(msg); - } + if (!batimp_path.size()) + batimp_path = panel->bat_dir(); + + wxFileDialog dlg(this, _("Select battery file"), batimp_path, wxEmptyString, + _("Battery file (*.sav)|*.sav|Flash save (*.dat)|*.dat"), wxFD_OPEN | wxFD_FILE_MUST_EXIST); + int ret = ShowModal(&dlg); + batimp_path = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + wxString fn = dlg.GetPath(); + ret = wxMessageBox(_("Importing a battery file will erase any saved games (permanently after the next write). Do you want to continue?"), + _("Confirm import"), wxYES_NO | wxICON_EXCLAMATION); + + if (ret == wxYES) + { + wxString msg; + + if (panel->emusys->emuReadBattery(fn.mb_fn_str())) + msg.Printf(_("Loaded battery %s"), fn.c_str()); + else + msg.Printf(_("Error loading battery %s"), fn.c_str()); + + systemScreenMessage(msg); + } } -EVT_HANDLER_MASK(ImportGamesharkCodeFile, "Import GameShark code file...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(ImportGamesharkCodeFile, "Import GameShark code file...", CMDEN_GB | CMDEN_GBA) { - static wxString path; - wxFileDialog dlg(this, _("Select code file"), path, wxEmptyString, - panel->game_type() == IMAGE_GBA ? - _("Gameshark Code File (*.spc;*.xpc)|*.spc;*.xpc"): - _("Gameshark Code File (*.gcf)|*.gcf"), - wxFD_OPEN|wxFD_FILE_MUST_EXIST); - int ret = ShowModal(&dlg); - path = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - wxString fn = dlg.GetPath(); - ret = wxMessageBox(_("Importing a code file will replace any loaded cheats. Do you want to continue?"), - _("Confirm import"), wxYES_NO|wxICON_EXCLAMATION); - if(ret == wxYES) { - wxString msg; - bool res; - if(panel->game_type() == IMAGE_GB) - // FIXME: this routine will not work on big-endian systems - // if the underlying file format is little-endian - // (fix in gb/gbCheats.cpp) - res = gbCheatReadGSCodeFile(fn.mb_fn_str()); - else { - // need to select game first - wxFFile f(fn, wxT("rb")); - if(!f.IsOpened()) { - wxLogError(_("Cannot open file %s"), fn.c_str()); - return; - } - // FIXME: in my code, I assume file format is little-endian - // however, in core code, it is assumed to be native-endian - u32 len; - char buf[14]; - if(f.Read(&len, sizeof(len)) != sizeof(len) || - wxUINT32_SWAP_ON_BE(len) != 14 || - f.Read(buf, 14) != 14 || memcmp(buf, "SharkPortCODES", 14)) { - wxLogError(_("Unsupported code file %s"), fn.c_str()); - return; - } - f.Seek(0x1e); - if(f.Read(&len, sizeof(len)) != sizeof(len)) - len = 0; - u32 game = 0; - if(len > 1) { - wxDialog *seldlg = GetXRCDialog("CodeSelect"); - wxControlWithItems *lst = XRCCTRL(*seldlg, "CodeList", wxControlWithItems); - lst->Clear(); - while(len-- > 0) { - u32 slen; - if(f.Read(&slen, sizeof(slen)) != sizeof(slen) || - slen > 1024) // arbitrary upper bound - break; - char buf[1024]; - if(f.Read(buf, slen) != slen) - break; - lst->Append(wxString(buf, wxConvLibc, slen)); - u32 ncodes; - if(f.Read(&ncodes, sizeof(ncodes)) != sizeof(ncodes)) - break; - for(; ncodes > 0; ncodes--) { - if(f.Read(&slen, sizeof(slen)) != sizeof(slen)) - break; - f.Seek(slen, wxFromCurrent); - if(f.Read(&slen, sizeof(slen)) != sizeof(slen)) - break; - f.Seek(slen + 4, wxFromCurrent); - if(f.Read(&slen, sizeof(slen)) != sizeof(slen)) - break; - f.Seek(slen * 12, wxFromCurrent); - } - } - int sel = ShowModal(seldlg); - if(sel != wxID_OK) - return; - game = lst->GetSelection(); - if(game == wxNOT_FOUND) - game = 0; - } - bool v3 = fn.size() >= 4 && - wxString(fn.substr(fn.size() - 4)).IsSameAs(wxT(".xpc"), false); + static wxString path; + wxFileDialog dlg(this, _("Select code file"), path, wxEmptyString, + panel->game_type() == IMAGE_GBA ? + _("Gameshark Code File (*.spc;*.xpc)|*.spc;*.xpc") : + _("Gameshark Code File (*.gcf)|*.gcf"), + wxFD_OPEN | wxFD_FILE_MUST_EXIST); + int ret = ShowModal(&dlg); + path = dlg.GetDirectory(); - // FIXME: this routine will not work on big-endian systems - // if the underlying file format is little-endian - // (fix in gba/Cheats.cpp) - res = cheatsImportGSACodeFile(fn.mb_fn_str(), game, v3); + if (ret != wxID_OK) + return; + + wxString fn = dlg.GetPath(); + ret = wxMessageBox(_("Importing a code file will replace any loaded cheats. Do you want to continue?"), + _("Confirm import"), wxYES_NO | wxICON_EXCLAMATION); + + if (ret == wxYES) + { + wxString msg; + bool res; + + if (panel->game_type() == IMAGE_GB) + // FIXME: this routine will not work on big-endian systems + // if the underlying file format is little-endian + // (fix in gb/gbCheats.cpp) + res = gbCheatReadGSCodeFile(fn.mb_fn_str()); + else + { + // need to select game first + wxFFile f(fn, wxT("rb")); + + if (!f.IsOpened()) + { + wxLogError(_("Cannot open file %s"), fn.c_str()); + return; + } + + // FIXME: in my code, I assume file format is little-endian + // however, in core code, it is assumed to be native-endian + u32 len; + char buf[14]; + + if (f.Read(&len, sizeof(len)) != sizeof(len) || + wxUINT32_SWAP_ON_BE(len) != 14 || + f.Read(buf, 14) != 14 || memcmp(buf, "SharkPortCODES", 14)) + { + wxLogError(_("Unsupported code file %s"), fn.c_str()); + return; + } + + f.Seek(0x1e); + + if (f.Read(&len, sizeof(len)) != sizeof(len)) + len = 0; + + u32 game = 0; + + if (len > 1) + { + wxDialog* seldlg = GetXRCDialog("CodeSelect"); + wxControlWithItems* lst = XRCCTRL(*seldlg, "CodeList", wxControlWithItems); + lst->Clear(); + + while (len-- > 0) + { + u32 slen; + + if (f.Read(&slen, sizeof(slen)) != sizeof(slen) || + slen > 1024) // arbitrary upper bound + break; + + char buf[1024]; + + if (f.Read(buf, slen) != slen) + break; + + lst->Append(wxString(buf, wxConvLibc, slen)); + u32 ncodes; + + if (f.Read(&ncodes, sizeof(ncodes)) != sizeof(ncodes)) + break; + + for (; ncodes > 0; ncodes--) + { + if (f.Read(&slen, sizeof(slen)) != sizeof(slen)) + break; + + f.Seek(slen, wxFromCurrent); + + if (f.Read(&slen, sizeof(slen)) != sizeof(slen)) + break; + + f.Seek(slen + 4, wxFromCurrent); + + if (f.Read(&slen, sizeof(slen)) != sizeof(slen)) + break; + + f.Seek(slen * 12, wxFromCurrent); + } + } + + int sel = ShowModal(seldlg); + + if (sel != wxID_OK) + return; + + game = lst->GetSelection(); + + if (game == wxNOT_FOUND) + game = 0; + } + + bool v3 = fn.size() >= 4 && + wxString(fn.substr(fn.size() - 4)).IsSameAs(wxT(".xpc"), false); + // FIXME: this routine will not work on big-endian systems + // if the underlying file format is little-endian + // (fix in gba/Cheats.cpp) + res = cheatsImportGSACodeFile(fn.mb_fn_str(), game, v3); + } + + if (res) + msg.Printf(_("Loaded code file %s"), fn.c_str()); + else + msg.Printf(_("Error loading code file %s"), fn.c_str()); + + systemScreenMessage(msg); } - if(res) - msg.Printf(_("Loaded code file %s"), fn.c_str()); - else - msg.Printf(_("Error loading code file %s"), fn.c_str()); - systemScreenMessage(msg); - } } static wxString gss_path; EVT_HANDLER_MASK(ImportGamesharkActionReplaySnapshot, - "Import GameShark Action Replay snapshot...", CMDEN_GB|CMDEN_GBA) + "Import GameShark Action Replay snapshot...", CMDEN_GB | CMDEN_GBA) { - wxFileDialog dlg(this, _("Select snapshot file"), gss_path, wxEmptyString, - panel->game_type() == IMAGE_GBA ? - _("GS & PAC Snapshots (*.sps;*.xps)|*.sps;*.xps|GameShark SP Snapshots (*.gsv)|*.gsv"): - _("Gameboy Snapshot (*.gbs)|*.gbs"), - wxFD_OPEN|wxFD_FILE_MUST_EXIST); - int ret = ShowModal(&dlg); - gss_path = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - wxString fn = dlg.GetPath(); - ret = wxMessageBox(_("Importing a snapshot file will erase any saved games (permanently after the next write). Do you want to continue?"), - _("Confirm import"), wxYES_NO|wxICON_EXCLAMATION); - if(ret == wxYES) { - wxString msg; - bool res; - if(panel->game_type() == IMAGE_GB) - res = gbReadGSASnapshot(fn.mb_fn_str()); - else { - bool gsv = fn.size() >= 4 && - wxString(fn.substr(fn.size() - 4)).IsSameAs(wxT(".gsv"), false); - if(gsv) - // FIXME: this will fail on big-endian machines if - // file format is little-endian - // fix in GBA.cpp - res = CPUReadGSASPSnapshot(fn.mb_fn_str()); - else - // FIXME: this will fail on big-endian machines if - // file format is little-endian - // fix in GBA.cpp - res = CPUReadGSASnapshot(fn.mb_fn_str()); + wxFileDialog dlg(this, _("Select snapshot file"), gss_path, wxEmptyString, + panel->game_type() == IMAGE_GBA ? + _("GS & PAC Snapshots (*.sps;*.xps)|*.sps;*.xps|GameShark SP Snapshots (*.gsv)|*.gsv") : + _("Gameboy Snapshot (*.gbs)|*.gbs"), + wxFD_OPEN | wxFD_FILE_MUST_EXIST); + int ret = ShowModal(&dlg); + gss_path = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + wxString fn = dlg.GetPath(); + ret = wxMessageBox(_("Importing a snapshot file will erase any saved games (permanently after the next write). Do you want to continue?"), + _("Confirm import"), wxYES_NO | wxICON_EXCLAMATION); + + if (ret == wxYES) + { + wxString msg; + bool res; + + if (panel->game_type() == IMAGE_GB) + res = gbReadGSASnapshot(fn.mb_fn_str()); + else + { + bool gsv = fn.size() >= 4 && + wxString(fn.substr(fn.size() - 4)).IsSameAs(wxT(".gsv"), false); + + if (gsv) + // FIXME: this will fail on big-endian machines if + // file format is little-endian + // fix in GBA.cpp + res = CPUReadGSASPSnapshot(fn.mb_fn_str()); + else + // FIXME: this will fail on big-endian machines if + // file format is little-endian + // fix in GBA.cpp + res = CPUReadGSASnapshot(fn.mb_fn_str()); + } + + if (res) + msg.Printf(_("Loaded snapshot file %s"), fn.c_str()); + else + msg.Printf(_("Error loading snapshot file %s"), fn.c_str()); + + systemScreenMessage(msg); } - if(res) - msg.Printf(_("Loaded snapshot file %s"), fn.c_str()); - else - msg.Printf(_("Error loading snapshot file %s"), fn.c_str()); - systemScreenMessage(msg); - } } -EVT_HANDLER_MASK(ExportBatteryFile, "Export battery file...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(ExportBatteryFile, "Export battery file...", CMDEN_GB | CMDEN_GBA) { - if(!batimp_path.size()) - batimp_path = panel->bat_dir(); - wxFileDialog dlg(this, _("Select battery file"), batimp_path, wxEmptyString, - _("Battery file (*.sav)|*.sav|Flash save (*.dat)|*.dat"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT); - int ret = ShowModal(&dlg); - batimp_path = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - wxString fn = dlg.GetPath(); - wxString msg; - if(panel->emusys->emuWriteBattery(fn.mb_fn_str())) - msg.Printf(_("Wrote battery %s"), fn.c_str()); - else - msg.Printf(_("Error writing battery %s"), fn.c_str()); - systemScreenMessage(msg); + if (!batimp_path.size()) + batimp_path = panel->bat_dir(); + + wxFileDialog dlg(this, _("Select battery file"), batimp_path, wxEmptyString, + _("Battery file (*.sav)|*.sav|Flash save (*.dat)|*.dat"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + int ret = ShowModal(&dlg); + batimp_path = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + wxString fn = dlg.GetPath(); + wxString msg; + + if (panel->emusys->emuWriteBattery(fn.mb_fn_str())) + msg.Printf(_("Wrote battery %s"), fn.c_str()); + else + msg.Printf(_("Error writing battery %s"), fn.c_str()); + + systemScreenMessage(msg); } EVT_HANDLER_MASK(ExportGamesharkSnapshot, "Export GameShark snapshot...", CMDEN_GBA) { - if(eepromInUse) { - wxLogError(_("EEPROM saves cannot be exported")); - return; - } - wxString def_name = panel->game_name(); - def_name.append(wxT(".sps")); - wxFileDialog dlg(this, _("Select snapshot file"), gss_path, def_name, - _("Gameshark Snapshot (*.sps)|*.sps"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT); - int ret = ShowModal(&dlg); - gss_path = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - wxString fn = dlg.GetPath(); - wxDialog *infodlg = GetXRCDialog("ExportSPS"); - wxTextCtrl *tit = XRCCTRL(*infodlg, "Title", wxTextCtrl), - *dsc = XRCCTRL(*infodlg, "Description", wxTextCtrl), - *n = XRCCTRL(*infodlg, "Notes", wxTextCtrl); - tit->SetValue(wxString((const char *)&rom[0xa0], wxConvLibc, 12)); - dsc->SetValue(wxDateTime::Now().Format(wxT("%c"))); - n->SetValue(_("Exported from VisualBoyAdvance-M")); - if(ShowModal(infodlg) != wxID_OK) - return; - wxString msg; + if (eepromInUse) + { + wxLogError(_("EEPROM saves cannot be exported")); + return; + } - // FIXME: this will fail on big-endian machines if file format is - // little-endian - // fix in GBA.cpp - if(CPUWriteGSASnapshot(fn.mb_fn_str(), tit->GetValue().utf8_str(), - dsc->GetValue().utf8_str(), n->GetValue().utf8_str())) - msg.Printf(_("Saved snapshot file %s"), fn.c_str()); - else - msg.Printf(_("Error saving snapshot file %s"), fn.c_str()); - systemScreenMessage(msg); + wxString def_name = panel->game_name(); + def_name.append(wxT(".sps")); + wxFileDialog dlg(this, _("Select snapshot file"), gss_path, def_name, + _("Gameshark Snapshot (*.sps)|*.sps"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + int ret = ShowModal(&dlg); + gss_path = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + wxString fn = dlg.GetPath(); + wxDialog* infodlg = GetXRCDialog("ExportSPS"); + wxTextCtrl* tit = XRCCTRL(*infodlg, "Title", wxTextCtrl), + *dsc = XRCCTRL(*infodlg, "Description", wxTextCtrl), + *n = XRCCTRL(*infodlg, "Notes", wxTextCtrl); + tit->SetValue(wxString((const char*)&rom[0xa0], wxConvLibc, 12)); + dsc->SetValue(wxDateTime::Now().Format(wxT("%c"))); + n->SetValue(_("Exported from VisualBoyAdvance-M")); + + if (ShowModal(infodlg) != wxID_OK) + return; + + wxString msg; + + // FIXME: this will fail on big-endian machines if file format is + // little-endian + // fix in GBA.cpp + if (CPUWriteGSASnapshot(fn.mb_fn_str(), tit->GetValue().utf8_str(), + dsc->GetValue().utf8_str(), n->GetValue().utf8_str())) + msg.Printf(_("Saved snapshot file %s"), fn.c_str()); + else + msg.Printf(_("Error saving snapshot file %s"), fn.c_str()); + + systemScreenMessage(msg); } -EVT_HANDLER_MASK(ScreenCapture, "Screen capture...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(ScreenCapture, "Screen capture...", CMDEN_GB | CMDEN_GBA) { - static wxString scap_path; - if(!scap_path.size()) { - scap_path = gopts.scrshot_dir; - if(scap_path.size()) { - wxFileName sp(scap_path, wxEmptyString); - if(!sp.IsAbsolute()) - scap_path = panel->game_dir() + wxT('/') + gopts.scrshot_dir; - wxFileName::Mkdir(scap_path, 0777, wxPATH_MKDIR_FULL); + static wxString scap_path; + + if (!scap_path.size()) + { + scap_path = gopts.scrshot_dir; + + if (scap_path.size()) + { + wxFileName sp(scap_path, wxEmptyString); + + if (!sp.IsAbsolute()) + scap_path = panel->game_dir() + wxT('/') + gopts.scrshot_dir; + + wxFileName::Mkdir(scap_path, 0777, wxPATH_MKDIR_FULL); + } } - } - wxString def_name = panel->game_name(); - if(captureFormat == 0) - def_name.append(wxT(".png")); - else - def_name.append(wxT(".bmp")); - wxFileDialog dlg(this, _("Select output file"), scap_path, def_name, - _("PNG images|*.png|BMP images|*.bmp"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT); - dlg.SetFilterIndex(captureFormat); - int ret = ShowModal(&dlg); - scap_path = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - wxString fn = dlg.GetPath(); - int fmt = dlg.GetFilterIndex(); - if(fn.size() >= 4) { - if(wxString(fn.substr(fn.size() - 4)).IsSameAs(wxT(".bmp"), false)) - fmt = 1; - else if(wxString(fn.substr(fn.size() - 4)).IsSameAs(wxT(".png"), false)) - fmt = 0; - } - if(fmt == 0) - panel->emusys->emuWritePNG(fn.mb_fn_str()); - else - panel->emusys->emuWriteBMP(fn.mb_fn_str()); - wxString msg; - msg.Printf(_("Wrote snapshot %s"), fn.c_str()); - systemScreenMessage(msg); + + wxString def_name = panel->game_name(); + + if (captureFormat == 0) + def_name.append(wxT(".png")); + else + def_name.append(wxT(".bmp")); + + wxFileDialog dlg(this, _("Select output file"), scap_path, def_name, + _("PNG images|*.png|BMP images|*.bmp"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + dlg.SetFilterIndex(captureFormat); + int ret = ShowModal(&dlg); + scap_path = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + wxString fn = dlg.GetPath(); + int fmt = dlg.GetFilterIndex(); + + if (fn.size() >= 4) + { + if (wxString(fn.substr(fn.size() - 4)).IsSameAs(wxT(".bmp"), false)) + fmt = 1; + else if (wxString(fn.substr(fn.size() - 4)).IsSameAs(wxT(".png"), false)) + fmt = 0; + } + + if (fmt == 0) + panel->emusys->emuWritePNG(fn.mb_fn_str()); + else + panel->emusys->emuWriteBMP(fn.mb_fn_str()); + + wxString msg; + msg.Printf(_("Wrote snapshot %s"), fn.c_str()); + systemScreenMessage(msg); } EVT_HANDLER_MASK(RecordSoundStartRecording, "Start sound recording...", CMDEN_NSREC) { #ifndef NO_FFMPEG - static wxString sound_exts; - static int sound_extno; - static wxString sound_path; + static wxString sound_exts; + static int sound_extno; + static wxString sound_path; - if(!sound_exts.size()) { - sound_extno = -1; - int extno; - AVOutputFormat *fmt; - for(fmt = NULL, extno = 0; (fmt = av_oformat_next(fmt)); ) { - if(!fmt->extensions) - continue; - if(fmt->audio_codec == CODEC_ID_NONE) - continue; - sound_exts.append(wxString(fmt->long_name ? fmt->long_name : fmt->name, wxConvLibc)); - sound_exts.append(_(" files (")); - wxString ext(fmt->extensions, wxConvLibc); - ext.Replace(wxT(","), wxT(";*.")); - ext.insert(0, wxT("*.")); - if(sound_extno < 0 && ext.find(wxT("*.wav")) != wxString::npos) - sound_extno = extno; - sound_exts.append(ext); - sound_exts.append(wxT(")|")); - sound_exts.append(ext); - sound_exts.append(wxT('|')); - extno++; + if (!sound_exts.size()) + { + sound_extno = -1; + int extno; + AVOutputFormat* fmt; + + for (fmt = NULL, extno = 0; (fmt = av_oformat_next(fmt));) + { + if (!fmt->extensions) + continue; + + if (fmt->audio_codec == CODEC_ID_NONE) + continue; + + sound_exts.append(wxString(fmt->long_name ? fmt->long_name : fmt->name, wxConvLibc)); + sound_exts.append(_(" files (")); + wxString ext(fmt->extensions, wxConvLibc); + ext.Replace(wxT(","), wxT(";*.")); + ext.insert(0, wxT("*.")); + + if (sound_extno < 0 && ext.find(wxT("*.wav")) != wxString::npos) + sound_extno = extno; + + sound_exts.append(ext); + sound_exts.append(wxT(")|")); + sound_exts.append(ext); + sound_exts.append(wxT('|')); + extno++; + } + + sound_exts.append(wxALL_FILES); + + if (sound_extno < 0) + sound_extno = extno; } - sound_exts.append(wxALL_FILES); - if(sound_extno < 0) - sound_extno = extno; - } - if(!sound_path.size()) { - if(!gopts.recording_dir.size()) - sound_path = panel->game_dir(); - else { - wxFileName sp(gopts.recording_dir, wxEmptyString); - if(sp.IsAbsolute()) - sound_path = gopts.recording_dir; - else - sound_path = panel->game_dir() + wxT('/') + gopts.recording_dir; + + if (!sound_path.size()) + { + if (!gopts.recording_dir.size()) + sound_path = panel->game_dir(); + else + { + wxFileName sp(gopts.recording_dir, wxEmptyString); + + if (sp.IsAbsolute()) + sound_path = gopts.recording_dir; + else + sound_path = panel->game_dir() + wxT('/') + gopts.recording_dir; + } + + wxFileName::Mkdir(sound_path, 0777, wxPATH_MKDIR_FULL); } - wxFileName::Mkdir(sound_path, 0777, wxPATH_MKDIR_FULL); - } - wxString def_name = panel->game_name(); - const wxChar *extoff = sound_exts.c_str(); - for(int i = 0; i < sound_extno; i++) { - extoff = wxStrchr(extoff, wxT('|')) + 1; - extoff = wxStrchr(extoff, wxT('|')) + 1; - } - extoff = wxStrchr(extoff, wxT('|')) + 2; // skip * - def_name += wxString(extoff, wxStrcspn(extoff, wxT(";|"))); - wxFileDialog dlg(this, _("Select output file"), sound_path, def_name, - sound_exts, wxFD_SAVE|wxFD_OVERWRITE_PROMPT); - dlg.SetFilterIndex(sound_extno); - int ret = ShowModal(&dlg); - sound_extno = dlg.GetFilterIndex(); - sound_path = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - panel->StartSoundRecording(dlg.GetPath()); + + wxString def_name = panel->game_name(); + const wxChar* extoff = sound_exts.c_str(); + + for (int i = 0; i < sound_extno; i++) + { + extoff = wxStrchr(extoff, wxT('|')) + 1; + extoff = wxStrchr(extoff, wxT('|')) + 1; + } + + extoff = wxStrchr(extoff, wxT('|')) + 2; // skip * + def_name += wxString(extoff, wxStrcspn(extoff, wxT(";|"))); + wxFileDialog dlg(this, _("Select output file"), sound_path, def_name, + sound_exts, wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + dlg.SetFilterIndex(sound_extno); + int ret = ShowModal(&dlg); + sound_extno = dlg.GetFilterIndex(); + sound_path = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + panel->StartSoundRecording(dlg.GetPath()); #endif } EVT_HANDLER_MASK(RecordSoundStopRecording, "Stop sound recording", CMDEN_SREC) { #ifndef NO_FFMPEG - panel->StopSoundRecording(); + panel->StopSoundRecording(); #endif } EVT_HANDLER_MASK(RecordAVIStartRecording, "Start video recording...", CMDEN_NVREC) { #ifndef NO_FFMPEG - static wxString vid_exts; - static int vid_extno; - static wxString vid_path; + static wxString vid_exts; + static int vid_extno; + static wxString vid_path; - if(!vid_exts.size()) { - vid_extno = -1; - int extno; - AVOutputFormat *fmt; - for(fmt = NULL, extno = 0; (fmt = av_oformat_next(fmt)); ) { - if(!fmt->extensions) - continue; - if(fmt->video_codec == CODEC_ID_NONE) - continue; - vid_exts.append(wxString(fmt->long_name ? fmt->long_name : fmt->name, wxConvLibc)); - vid_exts.append(_(" files (")); - wxString ext(fmt->extensions, wxConvLibc); - ext.Replace(wxT(","), wxT(";*.")); - ext.insert(0, wxT("*.")); - if(vid_extno < 0 && ext.find(wxT("*.avi")) != wxString::npos) - vid_extno = extno; - vid_exts.append(ext); - vid_exts.append(wxT(")|")); - vid_exts.append(ext); - vid_exts.append(wxT('|')); - extno++; + if (!vid_exts.size()) + { + vid_extno = -1; + int extno; + AVOutputFormat* fmt; + + for (fmt = NULL, extno = 0; (fmt = av_oformat_next(fmt));) + { + if (!fmt->extensions) + continue; + + if (fmt->video_codec == CODEC_ID_NONE) + continue; + + vid_exts.append(wxString(fmt->long_name ? fmt->long_name : fmt->name, wxConvLibc)); + vid_exts.append(_(" files (")); + wxString ext(fmt->extensions, wxConvLibc); + ext.Replace(wxT(","), wxT(";*.")); + ext.insert(0, wxT("*.")); + + if (vid_extno < 0 && ext.find(wxT("*.avi")) != wxString::npos) + vid_extno = extno; + + vid_exts.append(ext); + vid_exts.append(wxT(")|")); + vid_exts.append(ext); + vid_exts.append(wxT('|')); + extno++; + } + + vid_exts.append(wxALL_FILES); + + if (vid_extno < 0) + vid_extno = extno; } - vid_exts.append(wxALL_FILES); - if(vid_extno < 0) - vid_extno = extno; - } - if(!vid_path.size()) { - if(!gopts.recording_dir.size()) - vid_path = panel->game_dir(); - else { - wxFileName sp(gopts.recording_dir, wxEmptyString); - if(sp.IsAbsolute()) - vid_path = gopts.recording_dir; - else - vid_path = panel->game_dir() + wxT('/') + gopts.recording_dir; + + if (!vid_path.size()) + { + if (!gopts.recording_dir.size()) + vid_path = panel->game_dir(); + else + { + wxFileName sp(gopts.recording_dir, wxEmptyString); + + if (sp.IsAbsolute()) + vid_path = gopts.recording_dir; + else + vid_path = panel->game_dir() + wxT('/') + gopts.recording_dir; + } + + wxFileName::Mkdir(vid_path, 0777, wxPATH_MKDIR_FULL); } - wxFileName::Mkdir(vid_path, 0777, wxPATH_MKDIR_FULL); - } - wxString def_name = panel->game_name(); - const wxChar *extoff = vid_exts.c_str(); - for(int i = 0; i < vid_extno; i++) { - extoff = wxStrchr(extoff, wxT('|')) + 1; - extoff = wxStrchr(extoff, wxT('|')) + 1; - } - extoff = wxStrchr(extoff, wxT('|')) + 2; // skip * - def_name += wxString(extoff, wxStrcspn(extoff, wxT(";|"))); - wxFileDialog dlg(this, _("Select output file"), vid_path, def_name, - vid_exts, wxFD_SAVE|wxFD_OVERWRITE_PROMPT); - dlg.SetFilterIndex(vid_extno); - int ret = ShowModal(&dlg); - vid_extno = dlg.GetFilterIndex(); - vid_path = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - panel->StartVidRecording(dlg.GetPath()); + + wxString def_name = panel->game_name(); + const wxChar* extoff = vid_exts.c_str(); + + for (int i = 0; i < vid_extno; i++) + { + extoff = wxStrchr(extoff, wxT('|')) + 1; + extoff = wxStrchr(extoff, wxT('|')) + 1; + } + + extoff = wxStrchr(extoff, wxT('|')) + 2; // skip * + def_name += wxString(extoff, wxStrcspn(extoff, wxT(";|"))); + wxFileDialog dlg(this, _("Select output file"), vid_path, def_name, + vid_exts, wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + dlg.SetFilterIndex(vid_extno); + int ret = ShowModal(&dlg); + vid_extno = dlg.GetFilterIndex(); + vid_path = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + panel->StartVidRecording(dlg.GetPath()); #endif } EVT_HANDLER_MASK(RecordAVIStopRecording, "Stop video recording", CMDEN_VREC) { #ifndef NO_FFMPEG - panel->StopVidRecording(); + panel->StopVidRecording(); #endif } @@ -1103,586 +1318,619 @@ static wxString mov_path; EVT_HANDLER_MASK(RecordMovieStartRecording, "Start game recording...", CMDEN_NGREC) { - if(!mov_path.size()) { - if(!gopts.recording_dir.size()) - mov_path = panel->game_dir(); - else { - wxFileName sp(gopts.recording_dir, wxEmptyString); - if(sp.IsAbsolute()) - mov_path = gopts.recording_dir; - else - mov_path = panel->game_dir() + wxT('/') + gopts.recording_dir; + if (!mov_path.size()) + { + if (!gopts.recording_dir.size()) + mov_path = panel->game_dir(); + else + { + wxFileName sp(gopts.recording_dir, wxEmptyString); + + if (sp.IsAbsolute()) + mov_path = gopts.recording_dir; + else + mov_path = panel->game_dir() + wxT('/') + gopts.recording_dir; + } + + wxFileName::Mkdir(mov_path, 0777, wxPATH_MKDIR_FULL); } - wxFileName::Mkdir(mov_path, 0777, wxPATH_MKDIR_FULL); - } - wxString def_name = panel->game_name() + wxT(".vmv"); - wxFileDialog dlg(this, _("Select output file"), mov_path, def_name, - _("VBA Movie files|*.vmv"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT); - int ret = ShowModal(&dlg); - mov_path = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - systemStartGameRecording(dlg.GetPath()); + + wxString def_name = panel->game_name() + wxT(".vmv"); + wxFileDialog dlg(this, _("Select output file"), mov_path, def_name, + _("VBA Movie files|*.vmv"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + int ret = ShowModal(&dlg); + mov_path = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + systemStartGameRecording(dlg.GetPath()); } EVT_HANDLER_MASK(RecordMovieStopRecording, "Stop game recording", CMDEN_GREC) { - systemStopGameRecording(); + systemStopGameRecording(); } -EVT_HANDLER_MASK(PlayMovieStartPlaying, "Start playing movie...", CMDEN_NGREC|CMDEN_NGPLAY) +EVT_HANDLER_MASK(PlayMovieStartPlaying, "Start playing movie...", CMDEN_NGREC | CMDEN_NGPLAY) { - if(!mov_path.size()) { - if(!gopts.recording_dir.size()) - mov_path = panel->game_dir(); - else { - wxFileName sp(gopts.recording_dir, wxEmptyString); - if(sp.IsAbsolute()) - mov_path = gopts.recording_dir; - else - mov_path = panel->game_dir() + wxT('/') + gopts.recording_dir; + if (!mov_path.size()) + { + if (!gopts.recording_dir.size()) + mov_path = panel->game_dir(); + else + { + wxFileName sp(gopts.recording_dir, wxEmptyString); + + if (sp.IsAbsolute()) + mov_path = gopts.recording_dir; + else + mov_path = panel->game_dir() + wxT('/') + gopts.recording_dir; + } + + if (!wxFileName::DirExists(mov_path)) + mov_path = wxFileName::GetCwd(); } - if(!wxFileName::DirExists(mov_path)) - mov_path = wxFileName::GetCwd(); - } - systemStopGamePlayback(); - wxString def_name = panel->game_name() + wxT(".vmv"); - wxFileDialog dlg(this, _("Select file"), mov_path, def_name, - _("VBA Movie files|*.vmv"), wxFD_OPEN|wxFD_FILE_MUST_EXIST); - int ret = ShowModal(&dlg); - mov_path = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - systemStartGamePlayback(dlg.GetPath()); + + systemStopGamePlayback(); + wxString def_name = panel->game_name() + wxT(".vmv"); + wxFileDialog dlg(this, _("Select file"), mov_path, def_name, + _("VBA Movie files|*.vmv"), wxFD_OPEN | wxFD_FILE_MUST_EXIST); + int ret = ShowModal(&dlg); + mov_path = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + systemStartGamePlayback(dlg.GetPath()); } EVT_HANDLER_MASK(PlayMovieStopPlaying, "Stop playing movie", CMDEN_GPLAY) { - systemStopGamePlayback(); + systemStopGamePlayback(); } // formerly Close -EVT_HANDLER_MASK(wxID_CLOSE, "Close", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(wxID_CLOSE, "Close", CMDEN_GB | CMDEN_GBA) { - panel->UnloadGame(); + panel->UnloadGame(); } // formerly Exit EVT_HANDLER(wxID_EXIT, "Exit") { - Close(false); + Close(false); } // Emulation menu EVT_HANDLER(Pause, "Pause (toggle)") { - GetMenuOptionBool("Pause", paused); - if(paused) - panel->Pause(); - else if(!IsPaused()) - panel->Resume(); - // undo next-frame's zeroing of frameskip - int fs = frameSkip; - if(fs >= 0) + GetMenuOptionBool("Pause", paused); + + if (paused) + panel->Pause(); + else if (!IsPaused()) + panel->Resume(); + + // undo next-frame's zeroing of frameskip + int fs = frameSkip; + + if (fs >= 0) systemFrameSkip = fs; } // new -EVT_HANDLER_MASK(EmulatorSpeedupToggle, "Turbo mode (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(EmulatorSpeedupToggle, "Turbo mode (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionBool("EmulatorSpeedupToggle", turbo); + GetMenuOptionBool("EmulatorSpeedupToggle", turbo); } -EVT_HANDLER_MASK(Reset, "Reset", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(Reset, "Reset", CMDEN_GB | CMDEN_GBA) { - panel->emusys->emuReset(); - // systemScreenMessage("Reset"); + panel->emusys->emuReset(); + // systemScreenMessage("Reset"); } EVT_HANDLER(ToggleFullscreen, "Full screen (toggle)") { - panel->ShowFullScreen(!IsFullScreen()); + panel->ShowFullScreen(!IsFullScreen()); } EVT_HANDLER(JoypadAutofireA, "Autofire A (toggle)") { - GetMenuOptionInt("JoypadAutofireA", autofire, KEYM_A); + GetMenuOptionInt("JoypadAutofireA", autofire, KEYM_A); } EVT_HANDLER(JoypadAutofireB, "Autofire B (toggle)") { - GetMenuOptionInt("JoypadAutofireB", autofire, KEYM_B); + GetMenuOptionInt("JoypadAutofireB", autofire, KEYM_B); } EVT_HANDLER(JoypadAutofireL, "Autofire L (toggle)") { - GetMenuOptionInt("JoypadAutofireL", autofire, KEYM_LEFT); + GetMenuOptionInt("JoypadAutofireL", autofire, KEYM_LEFT); } EVT_HANDLER(JoypadAutofireR, "Autofire R (toggle)") { - GetMenuOptionInt("JoypadAutofireR", autofire, KEYM_RIGHT); + GetMenuOptionInt("JoypadAutofireR", autofire, KEYM_RIGHT); } EVT_HANDLER_MASK(LoadGameRecent, "Load most recent save", CMDEN_SAVST) { - panel->LoadState(); + panel->LoadState(); } EVT_HANDLER(LoadGameAutoLoad, "Auto load most recent save (toggle)") { - GetMenuOptionBool("LoadGameAutoLoad", gopts.autoload_state); - update_opts(); + GetMenuOptionBool("LoadGameAutoLoad", gopts.autoload_state); + update_opts(); } EVT_HANDLER_MASK(LoadGame01, "Load saved state 1", CMDEN_SAVST) { - panel->LoadState(1); + panel->LoadState(1); } EVT_HANDLER_MASK(LoadGame02, "Load saved state 2", CMDEN_SAVST) { - panel->LoadState(2); + panel->LoadState(2); } EVT_HANDLER_MASK(LoadGame03, "Load saved state 3", CMDEN_SAVST) { - panel->LoadState(3); + panel->LoadState(3); } EVT_HANDLER_MASK(LoadGame04, "Load saved state 4", CMDEN_SAVST) { - panel->LoadState(4); + panel->LoadState(4); } EVT_HANDLER_MASK(LoadGame05, "Load saved state 5", CMDEN_SAVST) { - panel->LoadState(5); + panel->LoadState(5); } EVT_HANDLER_MASK(LoadGame06, "Load saved state 6", CMDEN_SAVST) { - panel->LoadState(6); + panel->LoadState(6); } EVT_HANDLER_MASK(LoadGame07, "Load saved state 7", CMDEN_SAVST) { - panel->LoadState(7); + panel->LoadState(7); } EVT_HANDLER_MASK(LoadGame08, "Load saved state 8", CMDEN_SAVST) { - panel->LoadState(8); + panel->LoadState(8); } EVT_HANDLER_MASK(LoadGame09, "Load saved state 9", CMDEN_SAVST) { - panel->LoadState(9); + panel->LoadState(9); } EVT_HANDLER_MASK(LoadGame10, "Load saved state 10", CMDEN_SAVST) { - panel->LoadState(10); + panel->LoadState(10); } static wxString st_dir; -EVT_HANDLER_MASK(Load, "Load state...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(Load, "Load state...", CMDEN_GB | CMDEN_GBA) { - if(st_dir.empty()) - st_dir = panel->state_dir(); - wxFileDialog dlg(this, _("Select state file"), st_dir, wxEmptyString, - _("VisualBoyAdvance saved game files|*.sgm"), wxFD_OPEN|wxFD_FILE_MUST_EXIST); - int ret = ShowModal(&dlg); - st_dir = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - panel->LoadState(dlg.GetPath()); + if (st_dir.empty()) + st_dir = panel->state_dir(); + + wxFileDialog dlg(this, _("Select state file"), st_dir, wxEmptyString, + _("VisualBoyAdvance saved game files|*.sgm"), wxFD_OPEN | wxFD_FILE_MUST_EXIST); + int ret = ShowModal(&dlg); + st_dir = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + panel->LoadState(dlg.GetPath()); } // new EVT_HANDLER(KeepSaves, "Do not load battery saves (toggle)") { - GetMenuOptionInt("KeepSaves", skipSaveGameBattery, 1); - update_opts(); + GetMenuOptionInt("KeepSaves", skipSaveGameBattery, 1); + update_opts(); } // new EVT_HANDLER(KeepCheats, "Do not change cheat list (toggle)") { - GetMenuOptionInt("KeepCheats", skipSaveGameCheats, 1); - update_opts(); + GetMenuOptionInt("KeepCheats", skipSaveGameCheats, 1); + update_opts(); } -EVT_HANDLER_MASK(SaveGameOldest, "Save state to oldest slot", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGameOldest, "Save state to oldest slot", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(); + panel->SaveState(); } -EVT_HANDLER_MASK(SaveGame01, "Save state 1", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGame01, "Save state 1", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(1); + panel->SaveState(1); } -EVT_HANDLER_MASK(SaveGame02, "Save state 2", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGame02, "Save state 2", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(2); + panel->SaveState(2); } -EVT_HANDLER_MASK(SaveGame03, "Save state 3", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGame03, "Save state 3", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(3); + panel->SaveState(3); } -EVT_HANDLER_MASK(SaveGame04, "Save state 4", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGame04, "Save state 4", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(4); + panel->SaveState(4); } -EVT_HANDLER_MASK(SaveGame05, "Save state 5", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGame05, "Save state 5", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(5); + panel->SaveState(5); } -EVT_HANDLER_MASK(SaveGame06, "Save state 6", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGame06, "Save state 6", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(6); + panel->SaveState(6); } -EVT_HANDLER_MASK(SaveGame07, "Save state 7", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGame07, "Save state 7", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(7); + panel->SaveState(7); } -EVT_HANDLER_MASK(SaveGame08, "Save state 8", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGame08, "Save state 8", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(8); + panel->SaveState(8); } -EVT_HANDLER_MASK(SaveGame09, "Save state 9", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGame09, "Save state 9", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(9); + panel->SaveState(9); } -EVT_HANDLER_MASK(SaveGame10, "Save state 10", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGame10, "Save state 10", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(10); + panel->SaveState(10); } -EVT_HANDLER_MASK(Save, "Save state as...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(Save, "Save state as...", CMDEN_GB | CMDEN_GBA) { - if(st_dir.empty()) - st_dir = panel->state_dir(); - wxFileDialog dlg(this, _("Select state file"), st_dir, wxEmptyString, - _("VisualBoyAdvance saved game files|*.sgm"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT); - int ret = ShowModal(&dlg); - st_dir = dlg.GetDirectory(); - if(ret != wxID_OK) - return; - panel->SaveState(dlg.GetPath()); + if (st_dir.empty()) + st_dir = panel->state_dir(); + + wxFileDialog dlg(this, _("Select state file"), st_dir, wxEmptyString, + _("VisualBoyAdvance saved game files|*.sgm"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + int ret = ShowModal(&dlg); + st_dir = dlg.GetDirectory(); + + if (ret != wxID_OK) + return; + + panel->SaveState(dlg.GetPath()); } static int state_slot = 0; // new -EVT_HANDLER_MASK(LoadGameSlot, "Load current state slot", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(LoadGameSlot, "Load current state slot", CMDEN_GB | CMDEN_GBA) { - panel->LoadState(state_slot + 1); + panel->LoadState(state_slot + 1); } // new -EVT_HANDLER_MASK(SaveGameSlot, "Save current state slot", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SaveGameSlot, "Save current state slot", CMDEN_GB | CMDEN_GBA) { - panel->SaveState(state_slot + 1); + panel->SaveState(state_slot + 1); } // new -EVT_HANDLER_MASK(IncrGameSlot, "Increase state slot number", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(IncrGameSlot, "Increase state slot number", CMDEN_GB | CMDEN_GBA) { - state_slot = (state_slot + 1) % 10; + state_slot = (state_slot + 1) % 10; } // new -EVT_HANDLER_MASK(DecrGameSlot, "Decrease state slot number", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(DecrGameSlot, "Decrease state slot number", CMDEN_GB | CMDEN_GBA) { - state_slot = (state_slot + 9) % 10; + state_slot = (state_slot + 9) % 10; } // new -EVT_HANDLER_MASK(IncrGameSlotSave, "Increase state slot number and save", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(IncrGameSlotSave, "Increase state slot number and save", CMDEN_GB | CMDEN_GBA) { - state_slot = (state_slot + 1) % 10; - panel->SaveState(state_slot + 1); + state_slot = (state_slot + 1) % 10; + panel->SaveState(state_slot + 1); } EVT_HANDLER_MASK(Rewind, "Rewind", CMDEN_REWIND) { - MainFrame *mf = wxGetApp().frame; - GameArea *panel = mf->GetPanel(); - int rew_st = (panel->next_rewind_state + NUM_REWINDS - 1) % NUM_REWINDS; - // if within 5 seconds of last one, and > 1 state, delete last state & move back - // FIXME: 5 should actually be user-configurable - // maybe instead of 5, 10% of rewind_interval - if(panel->num_rewind_states > 1 && - (gopts.rewind_interval <= 5 || - panel->rewind_time / 6 > gopts.rewind_interval - 5)) { - --panel->num_rewind_states; - panel->next_rewind_state = rew_st; - if(gopts.rewind_interval > 5) - rew_st = (rew_st + NUM_REWINDS - 1) % NUM_REWINDS; - } - panel->emusys->emuReadMemState(&panel->rewind_mem[rew_st * REWIND_SIZE], - REWIND_SIZE); - InterframeCleanup(); - // FIXME: if(paused) blank screen - panel->do_rewind = false; - panel->rewind_time = gopts.rewind_interval * 6; + MainFrame* mf = wxGetApp().frame; + GameArea* panel = mf->GetPanel(); + int rew_st = (panel->next_rewind_state + NUM_REWINDS - 1) % NUM_REWINDS; + + // if within 5 seconds of last one, and > 1 state, delete last state & move back + // FIXME: 5 should actually be user-configurable + // maybe instead of 5, 10% of rewind_interval + if (panel->num_rewind_states > 1 && + (gopts.rewind_interval <= 5 || + panel->rewind_time / 6 > gopts.rewind_interval - 5)) + { + --panel->num_rewind_states; + panel->next_rewind_state = rew_st; + + if (gopts.rewind_interval > 5) + rew_st = (rew_st + NUM_REWINDS - 1) % NUM_REWINDS; + } + + panel->emusys->emuReadMemState(&panel->rewind_mem[rew_st * REWIND_SIZE], + REWIND_SIZE); + InterframeCleanup(); + // FIXME: if(paused) blank screen + panel->do_rewind = false; + panel->rewind_time = gopts.rewind_interval * 6; // systemScreenMessage(_("Rewinded")); } -EVT_HANDLER_MASK(CheatsList, "List cheats...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(CheatsList, "List cheats...", CMDEN_GB | CMDEN_GBA) { - wxDialog *dlg = GetXRCDialog("CheatList"); - ShowModal(dlg); + wxDialog* dlg = GetXRCDialog("CheatList"); + ShowModal(dlg); } -EVT_HANDLER_MASK(CheatsSearch, "Create cheat...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(CheatsSearch, "Create cheat...", CMDEN_GB | CMDEN_GBA) { - wxDialog *dlg = GetXRCDialog("CheatCreate"); - ShowModal(dlg); + wxDialog* dlg = GetXRCDialog("CheatCreate"); + ShowModal(dlg); } // new EVT_HANDLER(CheatsAutoSaveLoad, "Auto save/load cheats (toggle)") { - GetMenuOptionBool("CheatsAutoSaveLoad", gopts.autoload_cheats); - update_opts(); + GetMenuOptionBool("CheatsAutoSaveLoad", gopts.autoload_cheats); + update_opts(); } // was CheatsDisable // changed for convenience to match internal variable functionality EVT_HANDLER(CheatsEnable, "Enable cheats (toggle)") { - GetMenuOptionInt("CheatsEnable", cheatsEnabled, 1); - update_opts(); + GetMenuOptionInt("CheatsEnable", cheatsEnabled, 1); + update_opts(); } // Debug menu -EVT_HANDLER_MASK(VideoLayersBG0, "Video layer BG0 (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(VideoLayersBG0, "Video layer BG0 (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("VideoLayersBG0", layerSettings, (1<<8)); - layerEnable = DISPCNT & layerSettings; - CPUUpdateRenderBuffers(false); + GetMenuOptionInt("VideoLayersBG0", layerSettings, (1 << 8)); + layerEnable = DISPCNT & layerSettings; + CPUUpdateRenderBuffers(false); } -EVT_HANDLER_MASK(VideoLayersBG1, "Video layer BG1 (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(VideoLayersBG1, "Video layer BG1 (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("VideoLayersBG1", layerSettings, (1<<9)); - layerEnable = DISPCNT & layerSettings; - CPUUpdateRenderBuffers(false); + GetMenuOptionInt("VideoLayersBG1", layerSettings, (1 << 9)); + layerEnable = DISPCNT & layerSettings; + CPUUpdateRenderBuffers(false); } -EVT_HANDLER_MASK(VideoLayersBG2, "Video layer BG2 (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(VideoLayersBG2, "Video layer BG2 (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("VideoLayersBG2", layerSettings, (1<<10)); - layerEnable = DISPCNT & layerSettings; - CPUUpdateRenderBuffers(false); + GetMenuOptionInt("VideoLayersBG2", layerSettings, (1 << 10)); + layerEnable = DISPCNT & layerSettings; + CPUUpdateRenderBuffers(false); } -EVT_HANDLER_MASK(VideoLayersBG3, "Video layer BG3 (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(VideoLayersBG3, "Video layer BG3 (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("VideoLayersBG3", layerSettings, (1<<11)); - layerEnable = DISPCNT & layerSettings; - CPUUpdateRenderBuffers(false); + GetMenuOptionInt("VideoLayersBG3", layerSettings, (1 << 11)); + layerEnable = DISPCNT & layerSettings; + CPUUpdateRenderBuffers(false); } -EVT_HANDLER_MASK(VideoLayersOBJ, "Video layer OBJ (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(VideoLayersOBJ, "Video layer OBJ (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("VideoLayersOBJ", layerSettings, (1<<12)); - layerEnable = DISPCNT & layerSettings; - CPUUpdateRenderBuffers(false); + GetMenuOptionInt("VideoLayersOBJ", layerSettings, (1 << 12)); + layerEnable = DISPCNT & layerSettings; + CPUUpdateRenderBuffers(false); } -EVT_HANDLER_MASK(VideoLayersWIN0, "Video layer WIN0 (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(VideoLayersWIN0, "Video layer WIN0 (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("VideoLayersWIN0", layerSettings, (1<<13)); - layerEnable = DISPCNT & layerSettings; - CPUUpdateRenderBuffers(false); + GetMenuOptionInt("VideoLayersWIN0", layerSettings, (1 << 13)); + layerEnable = DISPCNT & layerSettings; + CPUUpdateRenderBuffers(false); } -EVT_HANDLER_MASK(VideoLayersWIN1, "Video layer WIN1 (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(VideoLayersWIN1, "Video layer WIN1 (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("VideoLayersWIN1", layerSettings, (1<<14)); - layerEnable = DISPCNT & layerSettings; - CPUUpdateRenderBuffers(false); + GetMenuOptionInt("VideoLayersWIN1", layerSettings, (1 << 14)); + layerEnable = DISPCNT & layerSettings; + CPUUpdateRenderBuffers(false); } -EVT_HANDLER_MASK(VideoLayersOBJWIN, "Video layer OBJWIN (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(VideoLayersOBJWIN, "Video layer OBJWIN (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("VideoLayersOBJWIN", layerSettings, (1<<15)); - layerEnable = DISPCNT & layerSettings; - CPUUpdateRenderBuffers(false); + GetMenuOptionInt("VideoLayersOBJWIN", layerSettings, (1 << 15)); + layerEnable = DISPCNT & layerSettings; + CPUUpdateRenderBuffers(false); } // not in menu -EVT_HANDLER_MASK(VideoLayersReset, "Show all video layers", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(VideoLayersReset, "Show all video layers", CMDEN_GB | CMDEN_GBA) { #define set_vl(s) do { \ int id = XRCID(s); \ for(int i = 0; i < checkable_mi.size(); i++) \ - if(checkable_mi[i].cmd == id) { \ - checkable_mi[i].mi->Check(true); \ - break; \ - } \ + if(checkable_mi[i].cmd == id) { \ + checkable_mi[i].mi->Check(true); \ + break; \ + } \ } while(0) - layerSettings = 0x7f00; - layerEnable = DISPCNT & layerSettings; - set_vl("VideoLayersBG0"); - set_vl("VideoLayersBG1"); - set_vl("VideoLayersBG2"); - set_vl("VideoLayersBG3"); - set_vl("VideoLayersOBJ"); - set_vl("VideoLayersWIN0"); - set_vl("VideoLayersWIN1"); - set_vl("VideoLayersOBJWIN"); - CPUUpdateRenderBuffers(false); + layerSettings = 0x7f00; + layerEnable = DISPCNT & layerSettings; + set_vl("VideoLayersBG0"); + set_vl("VideoLayersBG1"); + set_vl("VideoLayersBG2"); + set_vl("VideoLayersBG3"); + set_vl("VideoLayersOBJ"); + set_vl("VideoLayersWIN0"); + set_vl("VideoLayersWIN1"); + set_vl("VideoLayersOBJWIN"); + CPUUpdateRenderBuffers(false); } -EVT_HANDLER_MASK(SoundChannel1, "Sound Channel 1 (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SoundChannel1, "Sound Channel 1 (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("SoundChannel1", gopts.sound_en, (1<<0)); - soundSetEnable(gopts.sound_en); - update_opts(); + GetMenuOptionInt("SoundChannel1", gopts.sound_en, (1 << 0)); + soundSetEnable(gopts.sound_en); + update_opts(); } -EVT_HANDLER_MASK(SoundChannel2, "Sound Channel 2 (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SoundChannel2, "Sound Channel 2 (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("SoundChannel2", gopts.sound_en, (1<<1)); - soundSetEnable(gopts.sound_en); - update_opts(); + GetMenuOptionInt("SoundChannel2", gopts.sound_en, (1 << 1)); + soundSetEnable(gopts.sound_en); + update_opts(); } -EVT_HANDLER_MASK(SoundChannel3, "Sound Channel 3 (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SoundChannel3, "Sound Channel 3 (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("SoundChannel3", gopts.sound_en, (1<<2)); - soundSetEnable(gopts.sound_en); - update_opts(); + GetMenuOptionInt("SoundChannel3", gopts.sound_en, (1 << 2)); + soundSetEnable(gopts.sound_en); + update_opts(); } -EVT_HANDLER_MASK(SoundChannel4, "Sound Channel 4 (toggle)", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(SoundChannel4, "Sound Channel 4 (toggle)", CMDEN_GB | CMDEN_GBA) { - GetMenuOptionInt("SoundChannel4", gopts.sound_en, (1<<3)); - soundSetEnable(gopts.sound_en); - update_opts(); + GetMenuOptionInt("SoundChannel4", gopts.sound_en, (1 << 3)); + soundSetEnable(gopts.sound_en); + update_opts(); } EVT_HANDLER_MASK(DirectSoundA, "Direct Sound A (toggle)", CMDEN_GBA) { - GetMenuOptionInt("DirectSoundA", gopts.sound_en, (1<<8)); - soundSetEnable(gopts.sound_en); - update_opts(); + GetMenuOptionInt("DirectSoundA", gopts.sound_en, (1 << 8)); + soundSetEnable(gopts.sound_en); + update_opts(); } EVT_HANDLER_MASK(DirectSoundB, "Direct Sound B (toggle)", CMDEN_GBA) { - GetMenuOptionInt("DirectSoundB", gopts.sound_en, (1<<9)); - soundSetEnable(gopts.sound_en); - update_opts(); + GetMenuOptionInt("DirectSoundB", gopts.sound_en, (1 << 9)); + soundSetEnable(gopts.sound_en); + update_opts(); } EVT_HANDLER(ToggleSound, "Enable/disable all sound channels") { - bool en = gopts.sound_en == 0; - gopts.sound_en = en ? 0x30f : 0; + bool en = gopts.sound_en == 0; + gopts.sound_en = en ? 0x30f : 0; SetMenuOption("SoundChannel1", en); SetMenuOption("SoundChannel2", en); SetMenuOption("SoundChannel3", en); SetMenuOption("SoundChannel4", en); SetMenuOption("DirectSoundA", en); SetMenuOption("DirectSoundB", en); - soundSetEnable(gopts.sound_en); - update_opts(); - systemScreenMessage(en ? _("Sound enabled") : _("Sound disabled")); + soundSetEnable(gopts.sound_en); + update_opts(); + systemScreenMessage(en ? _("Sound enabled") : _("Sound disabled")); } EVT_HANDLER(IncreaseVolume, "Increase volume") { - gopts.sound_vol += 5; - if(gopts.sound_vol > 200) - gopts.sound_vol = 200; - update_opts(); - soundSetVolume((float)gopts.sound_vol / 100.0); - wxString msg; - msg.Printf(_("Volume: %d%%"), gopts.sound_vol); - systemScreenMessage(msg); + gopts.sound_vol += 5; + + if (gopts.sound_vol > 200) + gopts.sound_vol = 200; + + update_opts(); + soundSetVolume((float)gopts.sound_vol / 100.0); + wxString msg; + msg.Printf(_("Volume: %d%%"), gopts.sound_vol); + systemScreenMessage(msg); } EVT_HANDLER(DecreaseVolume, "Decrease volume") { - gopts.sound_vol -= 5; - if(gopts.sound_vol < 0) - gopts.sound_vol = 0; - update_opts(); - soundSetVolume((float)gopts.sound_vol / 100.0); - wxString msg; - msg.Printf(_("Volume: %d%%"), gopts.sound_vol); - systemScreenMessage(msg); + gopts.sound_vol -= 5; + + if (gopts.sound_vol < 0) + gopts.sound_vol = 0; + + update_opts(); + soundSetVolume((float)gopts.sound_vol / 100.0); + wxString msg; + msg.Printf(_("Volume: %d%%"), gopts.sound_vol); + systemScreenMessage(msg); } -EVT_HANDLER_MASK(NextFrame, "Next Frame", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(NextFrame, "Next Frame", CMDEN_GB | CMDEN_GBA) { SetMenuOption("Pause", true); - paused = true; - pause_next = true; - if(!IsPaused()) - panel->Resume(); - systemFrameSkip = 0; + paused = true; + pause_next = true; + + if (!IsPaused()) + panel->Resume(); + + systemFrameSkip = 0; } -EVT_HANDLER_MASK(Disassemble, "Disassemble...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(Disassemble, "Disassemble...", CMDEN_GB | CMDEN_GBA) { - Disassemble(); + Disassemble(); } // only GBA generates the log messages this handles // you could view them even w/o a gba cart, but why? EVT_HANDLER_MASK(Logging, "Logging...", CMDEN_GBA) { - wxDialog *dlg = wxGetApp().frame->logdlg; - dlg->Show(); - dlg->Raise(); + wxDialog* dlg = wxGetApp().frame->logdlg; + dlg->Show(); + dlg->Raise(); } EVT_HANDLER_MASK(IOViewer, "I/O Viewer...", CMDEN_GBA) { - IOViewer(); + IOViewer(); } -EVT_HANDLER_MASK(MapViewer, "Map Viewer...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(MapViewer, "Map Viewer...", CMDEN_GB | CMDEN_GBA) { - MapViewer(); + MapViewer(); } -EVT_HANDLER_MASK(MemoryViewer, "Memory Viewer...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(MemoryViewer, "Memory Viewer...", CMDEN_GB | CMDEN_GBA) { - MemViewer(); + MemViewer(); } -EVT_HANDLER_MASK(OAMViewer, "OAM Viewer...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(OAMViewer, "OAM Viewer...", CMDEN_GB | CMDEN_GBA) { - OAMViewer(); + OAMViewer(); } -EVT_HANDLER_MASK(PaletteViewer, "Palette Viewer...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(PaletteViewer, "Palette Viewer...", CMDEN_GB | CMDEN_GBA) { - PaletteViewer(); + PaletteViewer(); } -EVT_HANDLER_MASK(TileViewer, "Tile Viewer...", CMDEN_GB|CMDEN_GBA) +EVT_HANDLER_MASK(TileViewer, "Tile Viewer...", CMDEN_GB | CMDEN_GBA) { - TileViewer(); + TileViewer(); } extern int remotePort; @@ -1692,18 +1940,18 @@ int GetGDBPort(MainFrame* mf) ModalPause mp; return wxGetNumberFromUser( #ifdef __WXMSW__ - wxEmptyString, + wxEmptyString, #else - _("Set to 0 for pseudo tty"), + _("Set to 0 for pseudo tty"), #endif - _("Port to wait for connection:"), - _("GDB Connection"), gdbPort, + _("Port to wait for connection:"), + _("GDB Connection"), gdbPort, #ifdef __WXMSW__ - 1025, + 1025, #else - 0, + 0, #endif - 65535, mf); + 65535, mf); } EVT_HANDLER(DebugGDBPort, "Configure port...") @@ -1728,14 +1976,18 @@ void MainFrame::GDBBreak() update_opts(); } - if (gdbPort != 0) { + if (gdbPort != 0) + { if (!remotePort) { wxString msg; #ifndef __WXMSW__ - if (!gdbPort) { + + if (!gdbPort) + { if (!debugOpenPty()) return; + msg.Printf(_("Waiting for connection at %s"), debugGetSlavePty().c_str()); } else @@ -1743,29 +1995,36 @@ void MainFrame::GDBBreak() { if (!debugStartListen(gdbPort)) return; + msg.Printf(_("Waiting for connection on port %d"), gdbPort); } + wxProgressDialog dlg(_("Waiting for GDB..."), msg, 100, this, - wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME); + wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME); bool connected = false; - while (dlg.Pulse()) { + + while (dlg.Pulse()) + { #ifndef __WXMSW__ + if (!gdbPort) connected = debugWaitPty(); else #endif connected = debugWaitSocket(); + if (connected) break; + // sleep a bit more in case of infinite loop wxMilliSleep(10); } - if (connected) { + if (connected) + { remotePort = gdbPort; debugger = true; emulating = 1; - dbgMain = remoteStubMain; dbgSignal = remoteStubSignal; dbgOutput = remoteOutput; @@ -1780,14 +2039,17 @@ void MainFrame::GDBBreak() } else { - if (armState) { + if (armState) + { armNextPC -= 4; reg[15].I -= 4; } - else { + else + { armNextPC -= 2; reg[15].I -= 2; } + debugger = true; } } @@ -1800,189 +2062,238 @@ EVT_HANDLER_MASK(DebugGDBBreak, "Break into GDB", CMDEN_NGDB_GBA | CMDEN_GDB) EVT_HANDLER_MASK(DebugGDBDisconnect, "Disconnect GDB", CMDEN_GDB) { - debugger = false; - dbgMain = NULL; - dbgSignal = NULL; - dbgOutput = NULL; - remoteCleanUp(); - cmd_enable &= ~CMDEN_GDB; - cmd_enable |= CMDEN_NGDB_GBA|CMDEN_NGDB_ANY; - enable_menus(); + debugger = false; + dbgMain = NULL; + dbgSignal = NULL; + dbgOutput = NULL; + remoteCleanUp(); + cmd_enable &= ~CMDEN_GDB; + cmd_enable |= CMDEN_NGDB_GBA | CMDEN_NGDB_ANY; + enable_menus(); } // Options menu EVT_HANDLER(GeneralConfigure, "General options...") { - int rew = gopts.rewind_interval; - wxDialog *dlg = GetXRCDialog("GeneralConfig"); - if(ShowModal(dlg) == wxID_OK) - update_opts(); - if(panel->game_type() != IMAGE_UNKNOWN) - soundSetThrottle(throttle); - if(rew != gopts.rewind_interval) { - if(!gopts.rewind_interval) { - if(panel->num_rewind_states) { - cmd_enable &= ~CMDEN_REWIND; - enable_menus(); - } - panel->num_rewind_states = 0; - panel->do_rewind = false; - } else { - if(!panel->num_rewind_states) - panel->do_rewind = true; - panel->rewind_time = gopts.rewind_interval * 6; + int rew = gopts.rewind_interval; + wxDialog* dlg = GetXRCDialog("GeneralConfig"); + + if (ShowModal(dlg) == wxID_OK) + update_opts(); + + if (panel->game_type() != IMAGE_UNKNOWN) + soundSetThrottle(throttle); + + if (rew != gopts.rewind_interval) + { + if (!gopts.rewind_interval) + { + if (panel->num_rewind_states) + { + cmd_enable &= ~CMDEN_REWIND; + enable_menus(); + } + + panel->num_rewind_states = 0; + panel->do_rewind = false; + } + else + { + if (!panel->num_rewind_states) + panel->do_rewind = true; + + panel->rewind_time = gopts.rewind_interval * 6; + } } - } } EVT_HANDLER(GameBoyConfigure, "Game Boy options...") { - wxDialog *dlg = GetXRCDialog("GameBoyConfig"); - wxChoice *c = XRCCTRL(*dlg, "Borders", wxChoice); - bool borderon = gbBorderOn; - if(!gbBorderOn && !gbBorderAutomatic) - c->SetSelection(0); - else if(gbBorderOn) - c->SetSelection(1); - else - c->SetSelection(2); - if(ShowModal(dlg) != wxID_OK) - return; - switch(c->GetSelection()) { - case 0: - gbBorderOn = gbBorderAutomatic = false; - break; - case 1: - gbBorderOn = true; - break; - case 2: - gbBorderOn = false; - gbBorderAutomatic = true; - break; - } - // this value might have been overwritten by FrameSkip - if(panel->game_type() == IMAGE_GB) { - if(borderon != gbBorderOn) { - if(gbBorderOn) { - panel->AddBorder(); - gbSgbRenderBorder(); - } else - panel->DelBorder(); + wxDialog* dlg = GetXRCDialog("GameBoyConfig"); + wxChoice* c = XRCCTRL(*dlg, "Borders", wxChoice); + bool borderon = gbBorderOn; + + if (!gbBorderOn && !gbBorderAutomatic) + c->SetSelection(0); + else if (gbBorderOn) + c->SetSelection(1); + else + c->SetSelection(2); + + if (ShowModal(dlg) != wxID_OK) + return; + + switch (c->GetSelection()) + { + case 0: + gbBorderOn = gbBorderAutomatic = false; + break; + + case 1: + gbBorderOn = true; + break; + + case 2: + gbBorderOn = false; + gbBorderAutomatic = true; + break; } - // don't want to have to reset to change colors - memcpy(gbPalette, &systemGbPalette[gbPaletteOption * 8], 8 * sizeof(systemGbPalette[0])); - } + + // this value might have been overwritten by FrameSkip + if (panel->game_type() == IMAGE_GB) + { + if (borderon != gbBorderOn) + { + if (gbBorderOn) + { + panel->AddBorder(); + gbSgbRenderBorder(); + } + else + panel->DelBorder(); + } + + // don't want to have to reset to change colors + memcpy(gbPalette, &systemGbPalette[gbPaletteOption * 8], 8 * sizeof(systemGbPalette[0])); + } + update_opts(); } EVT_HANDLER(GameBoyAdvanceConfigure, "Game Boy Advance options...") { - wxDialog *dlg = GetXRCDialog("GameBoyAdvanceConfig"); - wxTextCtrl *ovcmt = XRCCTRL(*dlg, "Comment", wxTextCtrl); - wxString cmt; - wxChoice *ovrtc = XRCCTRL(*dlg, "OvRTC", wxChoice), - *ovst = XRCCTRL(*dlg, "OvSaveType", wxChoice), - *ovfs = XRCCTRL(*dlg, "OvFlashSize", wxChoice), - *ovmir = XRCCTRL(*dlg, "OvMirroring", wxChoice); - if(panel->game_type() == IMAGE_GBA) { - wxString s = wxString((const char *)&rom[0xac], wxConvLibc, 4); - XRCCTRL(*dlg, "GameCode", wxControl)->SetLabel(s); - cmt = wxString((const char *)&rom[0xa0], wxConvLibc, 12); - wxFileConfig *cfg = wxGetApp().overrides; - if(cfg->HasGroup(s)) { - cfg->SetPath(s); - cmt = cfg->Read(wxT("comment"), cmt); - ovcmt->SetValue(cmt); - ovrtc->SetSelection(cfg->Read(wxT("rtcEnabled"), -1) + 1); - ovst->SetSelection(cfg->Read(wxT("saveType"), -1) + 1); - ovfs->SetSelection((cfg->Read(wxT("flashSize"), -1) >> 17) + 1); - ovmir->SetSelection(cfg->Read(wxT("mirroringEnabled"), -1) + 1); - cfg->SetPath(wxT("/")); - } else { - ovcmt->SetValue(cmt); - ovrtc->SetSelection(0); - ovst->SetSelection(0); - ovfs->SetSelection(0); - ovmir->SetSelection(0); - } - } else { - XRCCTRL(*dlg, "GameCode", wxControl)->SetLabel(wxEmptyString); - ovcmt->SetValue(wxEmptyString); - ovrtc->SetSelection(0); - ovst->SetSelection(0); - ovfs->SetSelection(0); - ovmir->SetSelection(0); - } - if(ShowModal(dlg) != wxID_OK) - return; - if(panel->game_type() == IMAGE_GBA) { - agbPrintEnable(agbPrint); - wxString s = wxString((const char *)&rom[0xac], wxConvLibc, 4); - wxFileConfig *cfg = wxGetApp().overrides; - bool chg; - if(cfg->HasGroup(s)) { - cfg->SetPath(s); - chg = - ovcmt->GetValue() != cmt || - ovrtc->GetSelection() != cfg->Read(wxT("rtcEnabled"), -1) + 1 || - ovst->GetSelection() != cfg->Read(wxT("saveType"), -1) + 1 || - ovfs->GetSelection() != (cfg->Read(wxT("flashSize"), -1) >> 17) + 1 || - ovmir->GetSelection() != cfg->Read(wxT("mirroringEnabled"), -1) + 1; - cfg->SetPath(wxT("/")); - } else - chg = ovrtc->GetSelection() != 0 || ovst->GetSelection() != 0 || - ovfs->GetSelection() != 0 || ovmir->GetSelection() != 0; - if(chg) { - wxString vba_over; - wxFileName fn(wxStandardPaths::Get().GetUserDataDir(), wxT("vba-over.ini")); - if(fn.FileExists()) { - wxFileInputStream fis(fn.GetFullPath()); - wxStringOutputStream sos(&vba_over); - fis.Read(sos); - } - if(cfg->HasGroup(s)) { - cfg->SetPath(s); - if(cfg->Read(wxT("path"), wxEmptyString) == fn.GetPath()) { - // EOL can be either \n (unix), \r\n (dos), or \r (old mac) - wxString res(wxT("(^|[\n\r])" // a new line - L"(" // capture group as \2 - L"(#[^\n\r]*(\r?\n|\r))?" // an optional comment line - L"\\[")); // the group header - res += s; - res += wxT( "\\]" - L"([^[#]" // non-comment non-group-start chars - L"|[^\r\n \t][ \t]*[[#]" // or comment/grp start chars in middle of line - L"|#[^\n\r]*(\r?\n|\r)[^[]" // or comments not followed by grp start - L")*" - L")" // end of group - // no need to try to describe what's next - // as the regex should maximize match size - ); - wxRegEx re(res); - // there may be more than one group if it was hand-edited - // so remove them all - // could use re.Replace(), but this is more reliable - while(re.Matches(vba_over)) { - size_t beg, end; - re.GetMatch(&beg, &end, 2); - vba_over.erase(beg, end - beg); - } + wxDialog* dlg = GetXRCDialog("GameBoyAdvanceConfig"); + wxTextCtrl* ovcmt = XRCCTRL(*dlg, "Comment", wxTextCtrl); + wxString cmt; + wxChoice* ovrtc = XRCCTRL(*dlg, "OvRTC", wxChoice), + *ovst = XRCCTRL(*dlg, "OvSaveType", wxChoice), + *ovfs = XRCCTRL(*dlg, "OvFlashSize", wxChoice), + *ovmir = XRCCTRL(*dlg, "OvMirroring", wxChoice); + + if (panel->game_type() == IMAGE_GBA) + { + wxString s = wxString((const char*)&rom[0xac], wxConvLibc, 4); + XRCCTRL(*dlg, "GameCode", wxControl)->SetLabel(s); + cmt = wxString((const char*)&rom[0xa0], wxConvLibc, 12); + wxFileConfig* cfg = wxGetApp().overrides; + + if (cfg->HasGroup(s)) + { + cfg->SetPath(s); + cmt = cfg->Read(wxT("comment"), cmt); + ovcmt->SetValue(cmt); + ovrtc->SetSelection(cfg->Read(wxT("rtcEnabled"), -1) + 1); + ovst->SetSelection(cfg->Read(wxT("saveType"), -1) + 1); + ovfs->SetSelection((cfg->Read(wxT("flashSize"), -1) >> 17) + 1); + ovmir->SetSelection(cfg->Read(wxT("mirroringEnabled"), -1) + 1); + cfg->SetPath(wxT("/")); } - cfg->SetPath(wxT("/")); - cfg->DeleteGroup(s); - } - cfg->SetPath(s); - cfg->Write(wxT("path"), fn.GetPath()); - cfg->Write(wxT("comment"), ovcmt->GetValue()); - vba_over.append(wxT("# ")); - vba_over.append(ovcmt->GetValue()); - vba_over.append(wxTextFile::GetEOL()); - vba_over.append(wxT('[')); - vba_over.append(s); - vba_over.append(wxT(']')); - vba_over.append(wxTextFile::GetEOL()); - int sel; + else + { + ovcmt->SetValue(cmt); + ovrtc->SetSelection(0); + ovst->SetSelection(0); + ovfs->SetSelection(0); + ovmir->SetSelection(0); + } + } + else + { + XRCCTRL(*dlg, "GameCode", wxControl)->SetLabel(wxEmptyString); + ovcmt->SetValue(wxEmptyString); + ovrtc->SetSelection(0); + ovst->SetSelection(0); + ovfs->SetSelection(0); + ovmir->SetSelection(0); + } + + if (ShowModal(dlg) != wxID_OK) + return; + + if (panel->game_type() == IMAGE_GBA) + { + agbPrintEnable(agbPrint); + wxString s = wxString((const char*)&rom[0xac], wxConvLibc, 4); + wxFileConfig* cfg = wxGetApp().overrides; + bool chg; + + if (cfg->HasGroup(s)) + { + cfg->SetPath(s); + chg = + ovcmt->GetValue() != cmt || + ovrtc->GetSelection() != cfg->Read(wxT("rtcEnabled"), -1) + 1 || + ovst->GetSelection() != cfg->Read(wxT("saveType"), -1) + 1 || + ovfs->GetSelection() != (cfg->Read(wxT("flashSize"), -1) >> 17) + 1 || + ovmir->GetSelection() != cfg->Read(wxT("mirroringEnabled"), -1) + 1; + cfg->SetPath(wxT("/")); + } + else + chg = ovrtc->GetSelection() != 0 || ovst->GetSelection() != 0 || + ovfs->GetSelection() != 0 || ovmir->GetSelection() != 0; + + if (chg) + { + wxString vba_over; + wxFileName fn(wxStandardPaths::Get().GetUserDataDir(), wxT("vba-over.ini")); + + if (fn.FileExists()) + { + wxFileInputStream fis(fn.GetFullPath()); + wxStringOutputStream sos(&vba_over); + fis.Read(sos); + } + + if (cfg->HasGroup(s)) + { + cfg->SetPath(s); + + if (cfg->Read(wxT("path"), wxEmptyString) == fn.GetPath()) + { + // EOL can be either \n (unix), \r\n (dos), or \r (old mac) + wxString res(wxT("(^|[\n\r])" // a new line + L"(" // capture group as \2 + L"(#[^\n\r]*(\r?\n|\r))?" // an optional comment line + L"\\[")); // the group header + res += s; + res += wxT("\\]" + L"([^[#]" // non-comment non-group-start chars + L"|[^\r\n \t][ \t]*[[#]" // or comment/grp start chars in middle of line + L"|#[^\n\r]*(\r?\n|\r)[^[]" // or comments not followed by grp start + L")*" + L")" // end of group + // no need to try to describe what's next + // as the regex should maximize match size + ); + wxRegEx re(res); + + // there may be more than one group if it was hand-edited + // so remove them all + // could use re.Replace(), but this is more reliable + while (re.Matches(vba_over)) + { + size_t beg, end; + re.GetMatch(&beg, &end, 2); + vba_over.erase(beg, end - beg); + } + } + + cfg->SetPath(wxT("/")); + cfg->DeleteGroup(s); + } + + cfg->SetPath(s); + cfg->Write(wxT("path"), fn.GetPath()); + cfg->Write(wxT("comment"), ovcmt->GetValue()); + vba_over.append(wxT("# ")); + vba_over.append(ovcmt->GetValue()); + vba_over.append(wxTextFile::GetEOL()); + vba_over.append(wxT('[')); + vba_over.append(s); + vba_over.append(wxT(']')); + vba_over.append(wxTextFile::GetEOL()); + int sel; #define appendval(n) do { \ vba_over.append(wxT(n)); \ vba_over.append(wxT('=')); \ @@ -1990,162 +2301,189 @@ EVT_HANDLER(GameBoyAdvanceConfigure, "Game Boy Advance options...") vba_over.append(wxTextFile::GetEOL()); \ cfg->Write(wxT(n), sel - 1); \ } while(0) - if((sel = ovrtc->GetSelection()) > 0) - appendval("rtcEnabled"); - if((sel = ovst->GetSelection()) > 0) - appendval("saveType"); - if((sel = ovfs->GetSelection()) > 0) { - vba_over.append(wxT("flashSize=")); - vba_over.append(sel == 1 ? wxT("65536") : wxT("131072")); - vba_over.append(wxTextFile::GetEOL()); - cfg->Write(wxT("flashSize"), 0x10000 << (sel - 1)); - } - if((sel = ovmir->GetSelection()) > 0) - appendval("mirroringEnabled"); - cfg->SetPath(wxT("/")); - vba_over.append(wxTextFile::GetEOL()); - fn.Mkdir(0777, wxPATH_MKDIR_FULL); - wxTempFileOutputStream fos(fn.GetFullPath()); - fos.Write(vba_over.mb_str(), vba_over.size()); - fos.Commit(); + + if ((sel = ovrtc->GetSelection()) > 0) + appendval("rtcEnabled"); + + if ((sel = ovst->GetSelection()) > 0) + appendval("saveType"); + + if ((sel = ovfs->GetSelection()) > 0) + { + vba_over.append(wxT("flashSize=")); + vba_over.append(sel == 1 ? wxT("65536") : wxT("131072")); + vba_over.append(wxTextFile::GetEOL()); + cfg->Write(wxT("flashSize"), 0x10000 << (sel - 1)); + } + + if ((sel = ovmir->GetSelection()) > 0) + appendval("mirroringEnabled"); + + cfg->SetPath(wxT("/")); + vba_over.append(wxTextFile::GetEOL()); + fn.Mkdir(0777, wxPATH_MKDIR_FULL); + wxTempFileOutputStream fos(fn.GetFullPath()); + fos.Write(vba_over.mb_str(), vba_over.size()); + fos.Commit(); + } } - } + update_opts(); } EVT_HANDLER_MASK(DisplayConfigure, "Display options...", CMDEN_NREC_ANY) { - bool fs = fullScreen; - wxVideoMode dm = gopts.fs_mode; - - if(gopts.max_threads != 1) - { + bool fs = fullScreen; + wxVideoMode dm = gopts.fs_mode; + + if (gopts.max_threads != 1) + { gopts.max_threads = wxThread::GetCPUCount(); - } - //Just in case GetCPUCount() returns 0 - if(!gopts.max_threads) + } + + //Just in case GetCPUCount() returns 0 + if (!gopts.max_threads) gopts.max_threads = 1; - - wxDialog *dlg = GetXRCDialog("DisplayConfig"); - if(ShowModal(dlg) != wxID_OK) + + wxDialog* dlg = GetXRCDialog("DisplayConfig"); + + if (ShowModal(dlg) != wxID_OK) return; if (frameSkip >= 0) systemFrameSkip = frameSkip; - if(fs != fullScreen) + if (fs != fullScreen) { panel->ShowFullScreen(fullScreen); - } - else if(panel->IsFullScreen() && dm != gopts.fs_mode) - { + } + else if (panel->IsFullScreen() && dm != gopts.fs_mode) + { // maybe not the best way to do this.. panel->ShowFullScreen(false); panel->ShowFullScreen(true); } - if(panel->panel) + + if (panel->panel) { panel->panel->Delete(); panel->panel = NULL; - } + } + update_opts(); } EVT_HANDLER_MASK(ChangeFilter, "Change Pixel Filter", CMDEN_NREC_ANY) { int filt = gopts.filter; - if(filt == FF_PLUGIN || - ++gopts.filter == FF_PLUGIN && gopts.filter_plugin.empty()) - { - gopts.filter = 0; - } + + if (filt == FF_PLUGIN || + ++gopts.filter == FF_PLUGIN && gopts.filter_plugin.empty()) + { + gopts.filter = 0; + } + update_opts(); - if(panel->panel) { + + if (panel->panel) + { panel->panel->Delete(); panel->panel = NULL; - } + } } EVT_HANDLER_MASK(ChangeIFB, "Change Interframe Blending", CMDEN_NREC_ANY) { - gopts.ifb = (gopts.ifb + 1) % 3; - update_opts(); - if(panel->panel) - { + gopts.ifb = (gopts.ifb + 1) % 3; + update_opts(); + + if (panel->panel) + { panel->panel->Delete(); panel->panel = NULL; - } + } } EVT_HANDLER_MASK(SoundConfigure, "Sound options...", CMDEN_NREC_ANY) { - int oqual = gopts.sound_qual, oapi = gopts.audio_api; - bool oupmix = gopts.upmix, ohw = gopts.dsound_hw_accel; - wxString odev = gopts.audio_dev; - wxDialog *dlg = GetXRCDialog("SoundConfig"); - if(ShowModal(dlg) != wxID_OK) - return; - switch(panel->game_type()) { - case IMAGE_GB: - gb_effects_config.echo = (float)gopts.gb_echo / 100.0; - gb_effects_config.stereo = (float)gopts.gb_stereo / 100.0; - // note that setting declick may reset gb sound engine - gbSoundSetDeclicking(gopts.gb_declick); - gbSoundSetSampleRate(!gopts.sound_qual ? 48000 : - 44100 / (1 << (gopts.sound_qual - 1))); - break; - case IMAGE_GBA: + int oqual = gopts.sound_qual, oapi = gopts.audio_api; + bool oupmix = gopts.upmix, ohw = gopts.dsound_hw_accel; + wxString odev = gopts.audio_dev; + wxDialog* dlg = GetXRCDialog("SoundConfig"); + + if (ShowModal(dlg) != wxID_OK) + return; + + switch (panel->game_type()) + { + case IMAGE_GB: + gb_effects_config.echo = (float)gopts.gb_echo / 100.0; + gb_effects_config.stereo = (float)gopts.gb_stereo / 100.0; + // note that setting declick may reset gb sound engine + gbSoundSetDeclicking(gopts.gb_declick); + gbSoundSetSampleRate(!gopts.sound_qual ? 48000 : + 44100 / (1 << (gopts.sound_qual - 1))); + break; + + case IMAGE_GBA: case IMAGE_UNKNOWN: soundSetSampleRate(!gopts.sound_qual ? 48000 : - 44100 / (1 << (gopts.sound_qual - 1))); - break; - } - // changing sample rate causes driver reload, so no explicit reload needed - if(oqual == gopts.sound_qual && - // otherwise reload if API changes - (oapi != gopts.audio_api || odev != gopts.audio_dev || - // or init-only options - (oapi == AUD_XAUDIO2 && oupmix != gopts.upmix) || - (oapi == AUD_DIRECTSOUND && ohw != gopts.dsound_hw_accel))) { - soundShutdown(); - soundInit(); - } - soundSetVolume((float)gopts.sound_vol / 100.0); + 44100 / (1 << (gopts.sound_qual - 1))); + break; + } + + // changing sample rate causes driver reload, so no explicit reload needed + if (oqual == gopts.sound_qual && + // otherwise reload if API changes + (oapi != gopts.audio_api || odev != gopts.audio_dev || + // or init-only options + (oapi == AUD_XAUDIO2 && oupmix != gopts.upmix) || + (oapi == AUD_DIRECTSOUND && ohw != gopts.dsound_hw_accel))) + { + soundShutdown(); + soundInit(); + } + + soundSetVolume((float)gopts.sound_vol / 100.0); update_opts(); } EVT_HANDLER(EmulatorDirectories, "Directories...") { - wxDialog *dlg = GetXRCDialog("DirectoriesConfig"); - if(ShowModal(dlg) == wxID_OK) - update_opts(); + wxDialog* dlg = GetXRCDialog("DirectoriesConfig"); + + if (ShowModal(dlg) == wxID_OK) + update_opts(); } EVT_HANDLER(JoypadConfigure, "Joypad options...") { - wxDialog *dlg = GetXRCDialog("JoypadConfig"); - joy.Attach(NULL); - joy.Add(); - if(ShowModal(dlg) == wxID_OK) - update_opts(); - SetJoystick(); + wxDialog* dlg = GetXRCDialog("JoypadConfig"); + joy.Attach(NULL); + joy.Add(); + + if (ShowModal(dlg) == wxID_OK) + update_opts(); + + SetJoystick(); } EVT_HANDLER(Customize, "Customize UI...") { - wxDialog *dlg = GetXRCDialog("AccelConfig"); - if(ShowModal(dlg) == wxID_OK) - update_opts(); + wxDialog* dlg = GetXRCDialog("AccelConfig"); + + if (ShowModal(dlg) == wxID_OK) + update_opts(); } EVT_HANDLER(BugReport, "Report bugs...") { - wxLaunchDefaultBrowser(wxT("http://sourceforge.net/tracker/?group_id=212795&atid=1023154")); + wxLaunchDefaultBrowser(wxT("http://sourceforge.net/tracker/?group_id=212795&atid=1023154")); } EVT_HANDLER(FAQ, "VBA-M support forum") { - wxLaunchDefaultBrowser(wxT("http://vba-m.com/forum/")); + wxLaunchDefaultBrowser(wxT("http://vba-m.com/forum/")); } EVT_HANDLER(Translate, "Translations") @@ -2156,54 +2494,53 @@ EVT_HANDLER(Translate, "Translations") // was About EVT_HANDLER(wxID_ABOUT, "About...") { - wxAboutDialogInfo ai; - ai.SetName(wxT("VisualBoyAdvance-M")); - ai.SetVersion(wxT("")); - // setting website, icon, license uses custom aboutbox on win32 & macosx - // but at least win32 standard about is nothing special - ai.SetWebSite(wxT("http://www.vba-m.com/")); - ai.SetIcon(GetIcon()); - ai.SetDescription(_("Nintendo GameBoy (+Color+Advance) emulator.")); - ai.SetCopyright(_("Copyright (C) 1999-2003 Forgotten\nCopyright (C) 2004-2006 VBA development team\nCopyright (C) 2007-2015 VBA-M development team")); - ai.SetLicense(_("This program is free software: you can redistribute it and/or modify\n" - "it under the terms of the GNU General Public License as published by\n" - "the Free Software Foundation, either version 2 of the License, or\n" - "(at your option) any later version.\n\n" - "This program is distributed in the hope that it will be useful,\n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - "GNU General Public License for more details.\n\n" - "You should have received a copy of the GNU General Public License\n" - "along with this program. If not, see http://www.gnu.org/licenses .")); - // from gtk - ai.AddDeveloper(wxT("Forgotten")); - ai.AddDeveloper(wxT("kxu")); - ai.AddDeveloper(wxT("Pokemonhacker")); - ai.AddDeveloper(wxT("Spacy51")); - ai.AddDeveloper(wxT("mudlord")); - ai.AddDeveloper(wxT("Nach")); - ai.AddDeveloper(wxT("jbo_85")); - ai.AddDeveloper(wxT("bgK")); - ai.AddArtist(wxT("Matteo Drera")); - ai.AddArtist(wxT("Jakub Steiner")); - ai.AddArtist(wxT("Jones Lee")); - // from win32 - ai.AddDeveloper(wxT("Jonas Quinn")); - ai.AddDeveloper(wxT("DJRobX")); - ai.AddDeveloper(wxT("Spacy")); - ai.AddDeveloper(wxT("Squall Leonhart")); - // wx - ai.AddDeveloper(wxT("Thomas J. Moore")); - // from win32 "thanks" - ai.AddDeveloper(wxT("blargg")); - ai.AddDeveloper(wxT("Costis")); - ai.AddDeveloper(wxT("chrono")); - ai.AddDeveloper(wxT("xKiv")); - ai.AddDeveloper(wxT("Skidau")); - ai.AddDeveloper(wxT("TheCanadianBacon")); - ai.AddDeveloper(wxT("Orig. VBA team")); - - wxAboutBox(ai); + wxAboutDialogInfo ai; + ai.SetName(wxT("VisualBoyAdvance-M")); + ai.SetVersion(wxT("")); + // setting website, icon, license uses custom aboutbox on win32 & macosx + // but at least win32 standard about is nothing special + ai.SetWebSite(wxT("http://www.vba-m.com/")); + ai.SetIcon(GetIcon()); + ai.SetDescription(_("Nintendo GameBoy (+Color+Advance) emulator.")); + ai.SetCopyright(_("Copyright (C) 1999-2003 Forgotten\nCopyright (C) 2004-2006 VBA development team\nCopyright (C) 2007-2015 VBA-M development team")); + ai.SetLicense(_("This program is free software: you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as published by\n" + "the Free Software Foundation, either version 2 of the License, or\n" + "(at your option) any later version.\n\n" + "This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n\n" + "You should have received a copy of the GNU General Public License\n" + "along with this program. If not, see http://www.gnu.org/licenses .")); + // from gtk + ai.AddDeveloper(wxT("Forgotten")); + ai.AddDeveloper(wxT("kxu")); + ai.AddDeveloper(wxT("Pokemonhacker")); + ai.AddDeveloper(wxT("Spacy51")); + ai.AddDeveloper(wxT("mudlord")); + ai.AddDeveloper(wxT("Nach")); + ai.AddDeveloper(wxT("jbo_85")); + ai.AddDeveloper(wxT("bgK")); + ai.AddArtist(wxT("Matteo Drera")); + ai.AddArtist(wxT("Jakub Steiner")); + ai.AddArtist(wxT("Jones Lee")); + // from win32 + ai.AddDeveloper(wxT("Jonas Quinn")); + ai.AddDeveloper(wxT("DJRobX")); + ai.AddDeveloper(wxT("Spacy")); + ai.AddDeveloper(wxT("Squall Leonhart")); + // wx + ai.AddDeveloper(wxT("Thomas J. Moore")); + // from win32 "thanks" + ai.AddDeveloper(wxT("blargg")); + ai.AddDeveloper(wxT("Costis")); + ai.AddDeveloper(wxT("chrono")); + ai.AddDeveloper(wxT("xKiv")); + ai.AddDeveloper(wxT("Skidau")); + ai.AddDeveloper(wxT("TheCanadianBacon")); + ai.AddDeveloper(wxT("Orig. VBA team")); + wxAboutBox(ai); } EVT_HANDLER(Bilinear, "Use bilinear filter with 3d renderer") @@ -2226,6 +2563,7 @@ EVT_HANDLER(Printer, "Enable printer emulation") #else gbSerialFunction = NULL; #endif + if (winGbPrinterEnabled) gbSerialFunction = gbPrinterSend; @@ -2365,15 +2703,14 @@ void MainFrame::EnableNetworkMenu() enable_menus(); } -void SetLinkTypeMenu(const char *type, int value) +void SetLinkTypeMenu(const char* type, int value) { - MainFrame *mf = wxGetApp().frame; + MainFrame* mf = wxGetApp().frame; mf->SetMenuOption("LinkType0Nothing", 0); mf->SetMenuOption("LinkType1Cable", 0); mf->SetMenuOption("LinkType2Wireless", 0); mf->SetMenuOption("LinkType3GameCube", 0); mf->SetMenuOption("LinkType4Gameboy", 0); - mf->SetMenuOption(type, 1); gopts.gba_link_type = value; update_opts(); @@ -2385,19 +2722,22 @@ EVT_HANDLER_MASK(LanLink, "Start Network link", CMDEN_LINK_ANY) #ifndef NO_LINK LinkMode mode = GetLinkMode(); - if (mode != LINK_DISCONNECTED) { + if (mode != LINK_DISCONNECTED) + { // while we could deactivate the command when connected, it is more // user-friendly to display a message indidcating why wxLogError(_("LAN link is already active. Disable link mode to disconnect.")); return; } - if (gopts.link_proto) { + + if (gopts.link_proto) + { // see above comment wxLogError(_("Network is not supported in local mode.")); return; } - wxDialog *dlg = GetXRCDialog("NetLink"); + wxDialog* dlg = GetXRCDialog("NetLink"); ShowModal(dlg); panel->SetFrameTitle(); #endif @@ -2444,7 +2784,6 @@ EVT_HANDLER(LinkProto, "Local host IPC") { GetMenuOptionInt("LinkProto", gopts.link_proto, 1); update_opts(); - enable_menus(); EnableNetworkMenu(); } @@ -2452,17 +2791,14 @@ EVT_HANDLER(LinkProto, "Local host IPC") EVT_HANDLER(LinkConfigure, "Link options...") { #ifndef NO_LINK + wxDialog* dlg = GetXRCDialog("LinkConfig"); - wxDialog *dlg = GetXRCDialog("LinkConfig"); if (ShowModal(dlg) != wxID_OK) return; SetLinkTimeout(linkTimeout); - update_opts(); - EnableNetworkMenu(); - #endif } diff --git a/src/wx/drawing.h b/src/wx/drawing.h index e65264f8..377fb987 100644 --- a/src/wx/drawing.h +++ b/src/wx/drawing.h @@ -4,16 +4,16 @@ class BasicDrawingPanel : public DrawingPanel, public wxPanel { public: - BasicDrawingPanel(wxWindow *parent, int _width, int _height); - wxWindow *GetWindow() { return this; } - void Delete() { Destroy(); } + BasicDrawingPanel(wxWindow* parent, int _width, int _height); + wxWindow* GetWindow() { return this; } + void Delete() { Destroy(); } protected: - void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); } - void DrawArea(wxWindowDC &dc); + void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); } + void DrawArea(wxWindowDC &dc); - DECLARE_CLASS() - DECLARE_EVENT_TABLE() + DECLARE_CLASS() + DECLARE_EVENT_TABLE() }; #ifndef NO_OGL @@ -22,25 +22,25 @@ protected: class GLDrawingPanel : public DrawingPanel, public wxGLCanvas { public: - GLDrawingPanel(wxWindow *parent, int _width, int _height); - virtual ~GLDrawingPanel(); - wxWindow *GetWindow() { return this; } - void Delete() { Destroy(); } + GLDrawingPanel(wxWindow* parent, int _width, int _height); + virtual ~GLDrawingPanel(); + wxWindow* GetWindow() { return this; } + void Delete() { Destroy(); } protected: - void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); } - void OnSize(wxSizeEvent &); - void DrawArea(wxWindowDC &dc); + void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); } + void OnSize(wxSizeEvent &); + void DrawArea(wxWindowDC &dc); #if wxCHECK_VERSION(2,9,0) || !defined(__WXMAC__) - wxGLContext ctx; + wxGLContext ctx; #endif - bool did_init; - void Init(); - GLuint texid, vlist; - int texsize; + bool did_init; + void Init(); + GLuint texid, vlist; + int texsize; - DECLARE_CLASS() - DECLARE_EVENT_TABLE() + DECLARE_CLASS() + DECLARE_EVENT_TABLE() }; #endif @@ -48,18 +48,18 @@ protected: class DXDrawingPanel : public DrawingPanel, public wxPanel { public: - DXDrawingPanel(wxWindow *parent, int _width, int _height); - wxWindow *GetWindow() { return this; } - void Delete() { Destroy(); } + DXDrawingPanel(wxWindow* parent, int _width, int _height); + wxWindow* GetWindow() { return this; } + void Delete() { Destroy(); } protected: - void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); } - void DrawArea(wxWindowDC&); - bool did_init; - void Init(); + void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); } + void DrawArea(wxWindowDC &); + bool did_init; + void Init(); - DECLARE_CLASS() - DECLARE_EVENT_TABLE() + DECLARE_CLASS() + DECLARE_EVENT_TABLE() }; #endif @@ -69,18 +69,18 @@ protected: class CairoDrawingPanel : public DrawingPanel, public wxPanel { public: - CairoDrawingPanel(wxWindow *parent, int _width, int _height); - ~CairoDrawingPanel(); - wxWindow *GetWindow() { return this; } - void Delete() { Destroy(); } + CairoDrawingPanel(wxWindow* parent, int _width, int _height); + ~CairoDrawingPanel(); + wxWindow* GetWindow() { return this; } + void Delete() { Destroy(); } protected: - void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); } - void DrawArea(wxWindowDC&); - cairo_surface_t *conv_surf; + void PaintEv2(wxPaintEvent &ev) { PaintEv(ev); } + void DrawArea(wxWindowDC &); + cairo_surface_t* conv_surf; - DECLARE_CLASS() - DECLARE_EVENT_TABLE() + DECLARE_CLASS() + DECLARE_EVENT_TABLE() }; #endif diff --git a/src/wx/dsound.cpp b/src/wx/dsound.cpp index cdca4566..d1199215 100644 --- a/src/wx/dsound.cpp +++ b/src/wx/dsound.cpp @@ -24,7 +24,7 @@ private: LPDIRECTSOUNDNOTIFY dsbNotify; HANDLE dsbEvent; WAVEFORMATEX wfx; // Primary buffer wave format - int soundBufferLen; + int soundBufferLen; int soundBufferTotalLen; unsigned int soundNextPosition; @@ -36,7 +36,7 @@ public: void pause(); // pause the secondary sound buffer void reset(); // stop and reset the secondary sound buffer void resume(); // resume the secondary sound buffer - void write(u16 * finalWave, int length); // write the emulated sound to the secondary sound buffer + void write(u16* finalWave, int length); // write the emulated sound to the secondary sound buffer }; @@ -47,7 +47,6 @@ DirectSound::DirectSound() dsbSecondary = NULL; dsbNotify = NULL; dsbEvent = NULL; - soundBufferTotalLen = 14700; soundNextPosition = 0; } @@ -55,23 +54,28 @@ DirectSound::DirectSound() DirectSound::~DirectSound() { - if(dsbNotify) { + if (dsbNotify) + { dsbNotify->Release(); dsbNotify = NULL; } - if(dsbEvent) { + if (dsbEvent) + { CloseHandle(dsbEvent); dsbEvent = NULL; } - if(pDirectSound) { - if(dsbPrimary) { + if (pDirectSound) + { + if (dsbPrimary) + { dsbPrimary->Release(); dsbPrimary = NULL; } - if(dsbSecondary) { + if (dsbSecondary) + { dsbSecondary->Release(); dsbSecondary = NULL; } @@ -88,39 +92,47 @@ bool DirectSound::init(long sampleRate) DWORD freq; DSBUFFERDESC dsbdesc; int i; + hr = CoCreateInstance(CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound8, (LPVOID*)&pDirectSound); - hr = CoCreateInstance( CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound8, (LPVOID *)&pDirectSound ); - if( hr != S_OK ) { + if (hr != S_OK) + { wxLogError(_("Cannot create DirectSound %08x"), hr); return false; } GUID dev; - if(gopts.audio_dev.empty()) + + if (gopts.audio_dev.empty()) dev = DSDEVID_DefaultPlayback; else - CLSIDFromString(const_cast(gopts.audio_dev.wx_str()), &dev); - pDirectSound->Initialize( &dev ); - if( hr != DS_OK ) { + CLSIDFromString(const_cast(gopts.audio_dev.wx_str()), &dev); + + pDirectSound->Initialize(&dev); + + if (hr != DS_OK) + { wxLogError(_("Cannot create DirectSound %08x"), hr); return false; } - if( FAILED( hr = pDirectSound->SetCooperativeLevel( (HWND)wxGetApp().frame->GetHandle(), DSSCL_EXCLUSIVE ) ) ) { + if (FAILED(hr = pDirectSound->SetCooperativeLevel((HWND)wxGetApp().frame->GetHandle(), DSSCL_EXCLUSIVE))) + { wxLogError(_("Cannot SetCooperativeLevel %08x"), hr); return false; } - // Create primary sound buffer - ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); + ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; - if( !gopts.dsound_hw_accel ) { + + if (!gopts.dsound_hw_accel) + { dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE; } - if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbPrimary, NULL ) ) ) { + if (FAILED(hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbPrimary, NULL))) + { wxLogError(_("Cannot CreateSoundBuffer %08x"), hr); return false; } @@ -128,11 +140,10 @@ bool DirectSound::init(long sampleRate) freq = sampleRate; // calculate the number of samples per frame first // then multiply it with the size of a sample frame (16 bit * stereo) - soundBufferLen = ( freq / 60 ) * 4; + soundBufferLen = (freq / 60) * 4; soundBufferTotalLen = soundBufferLen * 10; soundNextPosition = 0; - - ZeroMemory( &wfx, sizeof(WAVEFORMATEX) ); + ZeroMemory(&wfx, sizeof(WAVEFORMATEX)); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 2; wfx.nSamplesPerSec = freq; @@ -140,42 +151,50 @@ bool DirectSound::init(long sampleRate) wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; - if( FAILED( hr = dsbPrimary->SetFormat( &wfx ) ) ) { - wxLogError( _("CreateSoundBuffer(primary) failed %08x"), hr ); + if (FAILED(hr = dsbPrimary->SetFormat(&wfx))) + { + wxLogError(_("CreateSoundBuffer(primary) failed %08x"), hr); return false; } - // Create secondary sound buffer - ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); + ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS; - if( !gopts.dsound_hw_accel ) { + + if (!gopts.dsound_hw_accel) + { dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE; } + dsbdesc.dwBufferBytes = soundBufferTotalLen; dsbdesc.lpwfxFormat = &wfx; - if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbSecondary, NULL ) ) ) { - wxLogError(_("CreateSoundBuffer(secondary) failed %08x"), hr ); + if (FAILED(hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL))) + { + wxLogError(_("CreateSoundBuffer(secondary) failed %08x"), hr); return false; } - if( FAILED( hr = dsbSecondary->SetCurrentPosition( 0 ) ) ) { - wxLogError(_("dsbSecondary->SetCurrentPosition failed %08x"), hr ); + if (FAILED(hr = dsbSecondary->SetCurrentPosition(0))) + { + wxLogError(_("dsbSecondary->SetCurrentPosition failed %08x"), hr); return false; } - - if( SUCCEEDED( hr = dsbSecondary->QueryInterface( IID_IDirectSoundNotify8, (LPVOID*)&dsbNotify ) ) ) { - dsbEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); + if (SUCCEEDED(hr = dsbSecondary->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)&dsbNotify))) + { + dsbEvent = CreateEvent(NULL, FALSE, FALSE, NULL); DSBPOSITIONNOTIFY notify[10]; - for( i = 0; i < 10; i++ ) { + + for (i = 0; i < 10; i++) + { notify[i].dwOffset = i * soundBufferLen; notify[i].hEventNotify = dsbEvent; } - if( FAILED( dsbNotify->SetNotificationPositions( 10, notify ) ) ) { + if (FAILED(dsbNotify->SetNotificationPositions(10, notify))) + { dsbNotify->Release(); dsbNotify = NULL; CloseHandle(dsbEvent); @@ -183,10 +202,10 @@ bool DirectSound::init(long sampleRate) } } - // Play primary buffer - if( FAILED( hr = dsbPrimary->Play( 0, 0, DSBPLAY_LOOPING ) ) ) { - wxLogError( _("Cannot Play primary %08x"), hr ); + if (FAILED(hr = dsbPrimary->Play(0, 0, DSBPLAY_LOOPING))) + { + wxLogError(_("Cannot Play primary %08x"), hr); return false; } @@ -196,40 +215,36 @@ bool DirectSound::init(long sampleRate) void DirectSound::pause() { - if( dsbSecondary == NULL ) return; + if (dsbSecondary == NULL) return; DWORD status; + dsbSecondary->GetStatus(&status); - dsbSecondary->GetStatus( &status ); - - if( status & DSBSTATUS_PLAYING ) dsbSecondary->Stop(); + if (status & DSBSTATUS_PLAYING) dsbSecondary->Stop(); } void DirectSound::reset() { - if( dsbSecondary == NULL ) return; + if (dsbSecondary == NULL) return; dsbSecondary->Stop(); - - dsbSecondary->SetCurrentPosition( 0 ); - + dsbSecondary->SetCurrentPosition(0); soundNextPosition = 0; } void DirectSound::resume() { - if( dsbSecondary == NULL ) return; + if (dsbSecondary == NULL) return; - dsbSecondary->Play( 0, 0, DSBPLAY_LOOPING ); + dsbSecondary->Play(0, 0, DSBPLAY_LOOPING); } -void DirectSound::write(u16 * finalWave, int length) +void DirectSound::write(u16* finalWave, int length) { - if(!pDirectSound) return; - + if (!pDirectSound) return; HRESULT hr; DWORD status = 0; @@ -239,88 +254,103 @@ void DirectSound::write(u16 * finalWave, int length) LPVOID lpvPtr2; DWORD dwBytes2 = 0; - if (!speedup && throttle && !gba_joybus_active) { + if (!speedup && throttle && !gba_joybus_active) + { hr = dsbSecondary->GetStatus(&status); - if( status & DSBSTATUS_PLAYING ) { - if( !soundPaused ) { - while( true ) { + + if (status & DSBSTATUS_PLAYING) + { + if (!soundPaused) + { + while (true) + { dsbSecondary->GetCurrentPosition(&play, NULL); - int BufferLeft = ((soundNextPosition <= play) ? - play - soundNextPosition : - soundBufferTotalLen - soundNextPosition + play); + int BufferLeft = ((soundNextPosition <= play) ? + play - soundNextPosition : + soundBufferTotalLen - soundNextPosition + play); - if(BufferLeft > soundBufferLen) - { - if (BufferLeft > soundBufferTotalLen - (soundBufferLen * 3)) - soundBufferLow = true; - break; - } - soundBufferLow = false; + if (BufferLeft > soundBufferLen) + { + if (BufferLeft > soundBufferTotalLen - (soundBufferLen * 3)) + soundBufferLow = true; - if(dsbEvent) { - WaitForSingleObject(dsbEvent, 50); - } - } + break; + } + + soundBufferLow = false; + + if (dsbEvent) + { + WaitForSingleObject(dsbEvent, 50); + } + } } }/* else { - // TODO: remove? - setsoundPaused(true); - }*/ - } + // TODO: remove? + setsoundPaused(true); + }*/ + } // Obtain memory address of write block. // This will be in two parts if the block wraps around. - if( DSERR_BUFFERLOST == ( hr = dsbSecondary->Lock( - soundNextPosition, - soundBufferLen, - &lpvPtr1, - &dwBytes1, - &lpvPtr2, - &dwBytes2, - 0 ) ) ) { - // If DSERR_BUFFERLOST is returned, restore and retry lock. - dsbSecondary->Restore(); - hr = dsbSecondary->Lock( - soundNextPosition, - soundBufferLen, - &lpvPtr1, - &dwBytes1, - &lpvPtr2, - &dwBytes2, - 0 ); + if (DSERR_BUFFERLOST == (hr = dsbSecondary->Lock( + soundNextPosition, + soundBufferLen, + &lpvPtr1, + &dwBytes1, + &lpvPtr2, + &dwBytes2, + 0))) + { + // If DSERR_BUFFERLOST is returned, restore and retry lock. + dsbSecondary->Restore(); + hr = dsbSecondary->Lock( + soundNextPosition, + soundBufferLen, + &lpvPtr1, + &dwBytes1, + &lpvPtr2, + &dwBytes2, + 0); } soundNextPosition += soundBufferLen; soundNextPosition = soundNextPosition % soundBufferTotalLen; - if( SUCCEEDED( hr ) ) { + if (SUCCEEDED(hr)) + { // Write to pointers. - CopyMemory( lpvPtr1, finalWave, dwBytes1 ); - if ( lpvPtr2 ) { - CopyMemory( lpvPtr2, finalWave + dwBytes1, dwBytes2 ); + CopyMemory(lpvPtr1, finalWave, dwBytes1); + + if (lpvPtr2) + { + CopyMemory(lpvPtr2, finalWave + dwBytes1, dwBytes2); } // Release the data back to DirectSound. - hr = dsbSecondary->Unlock( lpvPtr1, dwBytes1, lpvPtr2, dwBytes2 ); - } else { - wxLogError(_("dsbSecondary->Lock() failed: %08x"), hr ); + hr = dsbSecondary->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); + } + else + { + wxLogError(_("dsbSecondary->Lock() failed: %08x"), hr); return; } } -SoundDriver *newDirectSound() +SoundDriver* newDirectSound() { return new DirectSound(); } -struct devnames { - wxArrayString *names, *ids; +struct devnames +{ + wxArrayString* names, *ids; }; static BOOL CALLBACK DSEnumCB(LPGUID guid, LPCTSTR desc, LPCTSTR drvnam, LPVOID user) { - devnames *dn = (devnames *)user; + devnames* dn = (devnames*)user; dn->names->push_back(desc); WCHAR buf[32 + 4 + 2 + 1]; // hex digits + "-" + "{}" + \0 StringFromGUID2(*guid, buf, sizeof(buf)); diff --git a/src/wx/filters.h b/src/wx/filters.h index 86cddcdb..1018a0a7 100644 --- a/src/wx/filters.h +++ b/src/wx/filters.h @@ -6,77 +6,77 @@ // most 16-bit filters require space in src rounded up to u32 // those that take delta take 1 src line of pixels, rounded up to u32 size // initial value appears to be all-0xff -void Pixelate32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void Pixelate(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h); +void Pixelate32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void Pixelate(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h); // next 3*2 use Init_2xSaI(555|565) and do not take into account int Init_2xSaI(u32 BitFormat); // endianness or bit shift variables in init. // next 4*2 may be MMX-accelerated -void _2xSaI32(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h); -void _2xSaI(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h); +void _2xSaI32(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h); +void _2xSaI(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h); // void Scale_2xSaI(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void Super2xSaI32(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h); -void Super2xSaI(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h); -void SuperEagle32(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h); -void SuperEagle(u8 *src, u32 spitch, u8 *delta, u8 *dst, u32 dstp, int w, int h); -void AdMame2x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void AdMame2x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); +void Super2xSaI32(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h); +void Super2xSaI(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h); +void SuperEagle32(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h); +void SuperEagle(u8* src, u32 spitch, u8* delta, u8* dst, u32 dstp, int w, int h); +void AdMame2x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void AdMame2x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); // next 4 convert to rgb24 in internal buffers first, and then back again -void Bilinear32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void Bilinear(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void BilinearPlus32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void BilinearPlus(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void Scanlines32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void Scanlines(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void ScanlinesTV32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); +void Bilinear32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void Bilinear(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void BilinearPlus32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void BilinearPlus(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void Scanlines32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void Scanlines(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void ScanlinesTV32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); // "TV" here means each pixel is faded horizontally & vertically rather than // inserting black scanlines // this depends on RGB_LOW_BITS_MASK extern int RGB_LOW_BITS_MASK; -void ScanlinesTV(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); +void ScanlinesTV(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); // next 2 require calling hq2x_init first and whenever bpp changes void hq2x_init(unsigned bpp); -void hq2x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void hq2x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void lq2x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void lq2x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); +void hq2x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void hq2x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void lq2x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void lq2x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); // the simple ones could greatly benefit from correct usage of preprocessor.. // in any case, they are worthless, since all renderers do "simple" or // better by default -void Simple2x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void Simple2x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void Simple3x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void Simple3x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void Simple4x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void Simple4x(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); +void Simple2x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void Simple2x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void Simple3x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void Simple3x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void Simple4x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void Simple4x(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); // note: 16-bit input for asm version only! -void hq3x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); +void hq3x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); // this takes 32-bit input // (by converting to 16-bit first in asm version) -void hq3x32_32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void hq3x16(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); +void hq3x32_32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void hq3x16(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); // note: 16-bit input for asm version only! -void hq4x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); +void hq4x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); // this takes 32-bit input // (by converting to 16-bit first in asm version) -void hq4x32_32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void hq4x16(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); +void hq4x32_32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void hq4x16(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); -void xbrz2x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void xbrz3x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void xbrz4x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); -void xbrz5x32(u8 *src, u32 spitch, u8 *, u8 *dst, u32 dstp, int w, int h); +void xbrz2x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void xbrz3x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void xbrz4x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); +void xbrz5x32(u8* src, u32 spitch, u8*, u8* dst, u32 dstp, int w, int h); // call ifc to ignore previous frame / when starting new void InterframeCleanup(); // all 4 are MMX-accelerated if enabled -void SmartIB(u8 *src, u32 spitch, int width, int height); -void SmartIB32(u8 *src, u32 spitch, int width, int height); -void MotionBlurIB(u8 *src, u32 spitch, int width, int height); -void MotionBlurIB32(u8 *src, u32 spitch, int width, int height); -void SmartIB(u8 *src, u32 spitch, int width, int starty, int height); -void SmartIB32(u8 *src, u32 spitch, int width, int starty, int height); -void MotionBlurIB(u8 *src, u32 spitch, int width, int starty, int height); -void MotionBlurIB32(u8 *src, u32 spitch, int width, int starty, int height); +void SmartIB(u8* src, u32 spitch, int width, int height); +void SmartIB32(u8* src, u32 spitch, int width, int height); +void MotionBlurIB(u8* src, u32 spitch, int width, int height); +void MotionBlurIB32(u8* src, u32 spitch, int width, int height); +void SmartIB(u8* src, u32 spitch, int width, int starty, int height); +void SmartIB32(u8* src, u32 spitch, int width, int starty, int height); +void MotionBlurIB(u8* src, u32 spitch, int width, int starty, int height); +void MotionBlurIB32(u8* src, u32 spitch, int width, int starty, int height); #endif /* FILTERS_H */ diff --git a/src/wx/gfxviewers.cpp b/src/wx/gfxviewers.cpp index 39fb8bfd..98cca1f8 100644 --- a/src/wx/gfxviewers.cpp +++ b/src/wx/gfxviewers.cpp @@ -16,7 +16,7 @@ #define getlab(v, n, mv) do { \ v = XRCCTRL(*this, n, wxControl); \ if(!v) \ - baddialog(); \ + baddialog(); \ v->SetLabel(wxT(mv)); \ } while(0) @@ -24,212 +24,256 @@ extern u8 gbInvertTab[256]; // avoid exporting classes -namespace Viewers { - class MapViewer : public GfxViewer - { - public: +namespace Viewers +{ +class MapViewer : public GfxViewer +{ +public: MapViewer() : GfxViewer(wxT("MapViewer"), 1024, 1024) { - frame = bg = 0; - getradio(fr0 = , "Frame0", frame, 0); - getradio(fr1 = , "Frame1", frame, 0xa000); - getradio(bg0 = , "BG0", bg, 0); - getradio(bg1 = , "BG1", bg, 1); - getradio(bg2 = , "BG2", bg, 2); - getradio(bg3 = , "BG3", bg, 3); - getlab(modelab, "Mode", "8"); - getlab(mapbase, "MapBase", "0xWWWWWWWW"); - getlab(charbase, "CharBase", "0xWWWWWWWW"); - getlab(size, "Size", "1024x1024"); - getlab(colors, "Colors", "2WW"); - getlab(prio, "Priority", "3"); - getlab(mosaic, "Mosaic", "0"); - getlab(overflow, "Overflow", "0"); - getlab(coords, "Coords", "(1023,1023)"); - getlab(addr, "Address", "0xWWWWWWWW"); - getlab(tile, "Tile", "1023"); - getlab(flip, "Flip", "HV"); - getlab(palette, "Palette", "---"); - Fit(); - selx = sely = -1; - Update(); + frame = bg = 0; + getradio(fr0 = , "Frame0", frame, 0); + getradio(fr1 = , "Frame1", frame, 0xa000); + getradio(bg0 = , "BG0", bg, 0); + getradio(bg1 = , "BG1", bg, 1); + getradio(bg2 = , "BG2", bg, 2); + getradio(bg3 = , "BG3", bg, 3); + getlab(modelab, "Mode", "8"); + getlab(mapbase, "MapBase", "0xWWWWWWWW"); + getlab(charbase, "CharBase", "0xWWWWWWWW"); + getlab(size, "Size", "1024x1024"); + getlab(colors, "Colors", "2WW"); + getlab(prio, "Priority", "3"); + getlab(mosaic, "Mosaic", "0"); + getlab(overflow, "Overflow", "0"); + getlab(coords, "Coords", "(1023,1023)"); + getlab(addr, "Address", "0xWWWWWWWW"); + getlab(tile, "Tile", "1023"); + getlab(flip, "Flip", "HV"); + getlab(palette, "Palette", "---"); + Fit(); + selx = sely = -1; + Update(); } void Update() { - mode = DISPCNT & 7; - switch(bg) { - case 0: - control = BG0CNT; - break; - case 1: - control = BG1CNT; - break; - case 2: - control = BG2CNT; - break; - case 3: - control = BG3CNT; - break; - } - bool fr0en = true, fr1en = true, bg0en = true, bg1en = true, - bg2en = true, bg3en = true; - switch(mode) { - case 0: - fr0en = fr1en = false; - renderTextScreen(); - break; - case 1: - fr0en = fr1en = false; - bg3en = false; - if(bg == 3) { - bg = 0; - control = BG0CNT; - bg0->SetValue(true); - } - if(bg < 2) - renderTextScreen(); - else - renderRotScreen(); - break; - case 2: - fr0en = fr1en = false; - bg0en = bg1en = false; - if(bg < 2) { - bg = 2; - control = BG2CNT; - bg2->SetValue(true); - } - renderRotScreen(); - break; - case 3: - fr0en = fr1en = false; - bg0en = bg1en = bg2en = bg3en = false; - bg = 2; - bg2->SetValue(true); - renderMode3(); - break; - case 4: - bg0en = bg1en = bg2en = bg3en = false; - bg = 2; - bg2->SetValue(true); - renderMode4(); - break; - case 5: - case 6: - case 7: - bg = 2; - bg2->SetValue(true); - renderMode5(); - break; - } - ChangeBMP(); - fr0->Enable(fr0en); - fr1->Enable(fr1en); - bg0->Enable(bg0en); - bg1->Enable(bg1en); - bg2->Enable(bg2en); - bg3->Enable(bg3en); + mode = DISPCNT & 7; - wxString s; - s.Printf(wxT("%d"), (int)mode); - modelab->SetLabel(s); - if(mode >= 3) { - mapbase->SetLabel(wxEmptyString); - charbase->SetLabel(wxEmptyString); - } else { - s.Printf(wxT("0x%08X"), ((control >> 8) & 0x1f) * 0x800 + 0x6000000); - mapbase->SetLabel(s); - s.Printf(wxT("0x%08X"), ((control >> 2) & 0x03) * 0x4000 + 0x6000000); - charbase->SetLabel(s); - } - s.Printf(wxT("%dx%d"), gv->bmw, gv->bmh); - size->SetLabel(s); - colors->SetLabel(control & 0x80 ? wxT("256") : wxT("16")); - s.Printf(wxT("%d"), control & 3); - prio->SetLabel(s); - mosaic->SetLabel(control & 0x40 ? wxT("1") : wxT("0")); - overflow->SetLabel(bg <= 1 ? wxEmptyString : - control & 0x2000 ? wxT("1") : wxT("0")); - UpdateMouseInfo(); + switch (bg) + { + case 0: + control = BG0CNT; + break; + + case 1: + control = BG1CNT; + break; + + case 2: + control = BG2CNT; + break; + + case 3: + control = BG3CNT; + break; + } + + bool fr0en = true, fr1en = true, bg0en = true, bg1en = true, + bg2en = true, bg3en = true; + + switch (mode) + { + case 0: + fr0en = fr1en = false; + renderTextScreen(); + break; + + case 1: + fr0en = fr1en = false; + bg3en = false; + + if (bg == 3) + { + bg = 0; + control = BG0CNT; + bg0->SetValue(true); + } + + if (bg < 2) + renderTextScreen(); + else + renderRotScreen(); + + break; + + case 2: + fr0en = fr1en = false; + bg0en = bg1en = false; + + if (bg < 2) + { + bg = 2; + control = BG2CNT; + bg2->SetValue(true); + } + + renderRotScreen(); + break; + + case 3: + fr0en = fr1en = false; + bg0en = bg1en = bg2en = bg3en = false; + bg = 2; + bg2->SetValue(true); + renderMode3(); + break; + + case 4: + bg0en = bg1en = bg2en = bg3en = false; + bg = 2; + bg2->SetValue(true); + renderMode4(); + break; + + case 5: + case 6: + case 7: + bg = 2; + bg2->SetValue(true); + renderMode5(); + break; + } + + ChangeBMP(); + fr0->Enable(fr0en); + fr1->Enable(fr1en); + bg0->Enable(bg0en); + bg1->Enable(bg1en); + bg2->Enable(bg2en); + bg3->Enable(bg3en); + wxString s; + s.Printf(wxT("%d"), (int)mode); + modelab->SetLabel(s); + + if (mode >= 3) + { + mapbase->SetLabel(wxEmptyString); + charbase->SetLabel(wxEmptyString); + } + else + { + s.Printf(wxT("0x%08X"), ((control >> 8) & 0x1f) * 0x800 + 0x6000000); + mapbase->SetLabel(s); + s.Printf(wxT("0x%08X"), ((control >> 2) & 0x03) * 0x4000 + 0x6000000); + charbase->SetLabel(s); + } + + s.Printf(wxT("%dx%d"), gv->bmw, gv->bmh); + size->SetLabel(s); + colors->SetLabel(control & 0x80 ? wxT("256") : wxT("16")); + s.Printf(wxT("%d"), control & 3); + prio->SetLabel(s); + mosaic->SetLabel(control & 0x40 ? wxT("1") : wxT("0")); + overflow->SetLabel(bg <= 1 ? wxEmptyString : + control & 0x2000 ? wxT("1") : wxT("0")); + UpdateMouseInfo(); } void UpdateMouseInfoEv(wxMouseEvent &ev) { - selx = ev.GetX(); - sely = ev.GetY(); - UpdateMouseInfo(); // note that this will be inaccurate if game - // not paused since last refresh + selx = ev.GetX(); + sely = ev.GetY(); + UpdateMouseInfo(); // note that this will be inaccurate if game + // not paused since last refresh } u32 AddressFromSel() { - u32 base = ((control >> 8) & 0x1f) * 0x800 + 0x6000000; - // all text bgs (16 bits) - if(mode == 0 || (mode < 3 && bg < 2) || mode == 6 || mode == 7) { - if(sely > 255) { - base += 0x800; - if(gv->bmw > 256) - base += 0x800; + u32 base = ((control >> 8) & 0x1f) * 0x800 + 0x6000000; + + // all text bgs (16 bits) + if (mode == 0 || (mode < 3 && bg < 2) || mode == 6 || mode == 7) + { + if (sely > 255) + { + base += 0x800; + + if (gv->bmw > 256) + base += 0x800; + } + + if (selx >= 256) + base += 0x800; + + return base + ((selx & 0xff) >> 3) * 2 + 64 * ((sely & 0xff) >> 3); } - if(selx >= 256) - base += 0x800; - return base + ((selx & 0xff) >> 3) * 2 + 64 * ((sely & 0xff) >> 3); - } - // rot bgs (8 bits) - if(mode < 3) - return base + (selx>>3) + (gv->bmw>>3) * (sely >> 3); - // mode 3/5 (16 bits) - if(mode != 4) - return 0x6000000 + 0xa000*frame + (selx + gv->bmw * sely) * 2; - // mode 4 (8 bits) - return 0x6000000 + 0xa000*frame + selx + gv->bmw * sely; + + // rot bgs (8 bits) + if (mode < 3) + return base + (selx >> 3) + (gv->bmw >> 3) * (sely >> 3); + + // mode 3/5 (16 bits) + if (mode != 4) + return 0x6000000 + 0xa000 * frame + (selx + gv->bmw * sely) * 2; + + // mode 4 (8 bits) + return 0x6000000 + 0xa000 * frame + selx + gv->bmw * sely; } void UpdateMouseInfo() { - if(selx > gv->bmw || sely > gv->bmh) - selx = sely = -1; - if(selx < 0) { - coords->SetLabel(wxEmptyString); - addr->SetLabel(wxEmptyString); - tile->SetLabel(wxEmptyString); - flip->SetLabel(wxEmptyString); - palette->SetLabel(wxEmptyString); - } else { - wxString s; - s.Printf(wxT("(%d,%d)"), selx, sely); - coords->SetLabel(s); - u32 address = AddressFromSel(); - s.Printf(wxT("0x%08X"), address); - addr->SetLabel(s); + if (selx > gv->bmw || sely > gv->bmh) + selx = sely = -1; - if(!mode || (mode < 3 || mode > 5) && bg < 2) { - u16 value = *((u16 *)&vram[address - 0x6000000]); - s.Printf(wxT("%d"), value & 1023); - tile->SetLabel(s); - s = value & 1024 ? wxT('H') : wxT('-'); - s += value & 2048 ? wxT('V') : wxT('-'); - flip->SetLabel(s); - if(control & 0x80) - palette->SetLabel(wxT("---")); - else { - s.Printf(wxT("%d"), (value >> 12) & 15); - palette->SetLabel(s); - } - } else { - tile->SetLabel(wxT("---")); - flip->SetLabel(wxT("--")); - palette->SetLabel(wxT("---")); + if (selx < 0) + { + coords->SetLabel(wxEmptyString); + addr->SetLabel(wxEmptyString); + tile->SetLabel(wxEmptyString); + flip->SetLabel(wxEmptyString); + palette->SetLabel(wxEmptyString); + } + else + { + wxString s; + s.Printf(wxT("(%d,%d)"), selx, sely); + coords->SetLabel(s); + u32 address = AddressFromSel(); + s.Printf(wxT("0x%08X"), address); + addr->SetLabel(s); + + if (!mode || (mode < 3 || mode > 5) && bg < 2) + { + u16 value = *((u16*)&vram[address - 0x6000000]); + s.Printf(wxT("%d"), value & 1023); + tile->SetLabel(s); + s = value & 1024 ? wxT('H') : wxT('-'); + s += value & 2048 ? wxT('V') : wxT('-'); + flip->SetLabel(s); + + if (control & 0x80) + palette->SetLabel(wxT("---")); + else + { + s.Printf(wxT("%d"), (value >> 12) & 15); + palette->SetLabel(s); + } + } + else + { + tile->SetLabel(wxT("---")); + flip->SetLabel(wxT("--")); + palette->SetLabel(wxT("---")); + } } - } } - protected: +protected: u16 control, mode; int frame, bg; - wxRadioButton *fr0, *fr1, *bg0, *bg1, *bg2, *bg3; - wxControl *modelab, *mapbase, *charbase, *size, *colors, *prio, *mosaic, - *overflow; - wxControl *coords, *addr, *tile, *flip, *palette; + wxRadioButton* fr0, *fr1, *bg0, *bg1, *bg2, *bg3; + wxControl* modelab, *mapbase, *charbase, *size, *colors, *prio, *mosaic, + *overflow; + wxControl* coords, *addr, *tile, *flip, *palette; int selx, sely; // following routines were copied from win32/MapView.cpp with little @@ -239,512 +283,589 @@ namespace Viewers { void renderTextScreen() { - u16 *palette = (u16 *)paletteRAM; - u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000]; - u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800]; - u8 *bmp = image.GetData(); + u16* palette = (u16*)paletteRAM; + u8* charBase = &vram[((control >> 2) & 0x03) * 0x4000]; + u16* screenBase = (u16*)&vram[((control >> 8) & 0x1f) * 0x800]; + u8* bmp = image.GetData(); + int sizeX = 256; + int sizeY = 256; - int sizeX = 256; - int sizeY = 256; - switch((control >> 14) & 3) { - case 0: - break; - case 1: - sizeX = 512; - break; - case 2: - sizeY = 512; - break; - case 3: - sizeX = 512; - sizeY = 512; - break; - } + switch ((control >> 14) & 3) + { + case 0: + break; - BMPSize(sizeX, sizeY); + case 1: + sizeX = 512; + break; - if(control & 0x80) { - for(int y = 0; y < sizeY; y++) { - int yy = y & 255; + case 2: + sizeY = 512; + break; - if(y == 256 && sizeY > 256) { - screenBase += 0x400; - if(sizeX > 256) - screenBase += 0x400; - } - u16 *screenSource = screenBase + ((yy>>3)*32); - - for(int x = 0; x < sizeX; x++) { - u16 data = *screenSource; - - int tile = data & 0x3FF; - int tileX = (x & 7); - int tileY = y & 7; - - if(data & 0x0400) - tileX = 7 - tileX; - if(data & 0x0800) - tileY = 7 - tileY; - - u8 c = charBase[tile * 64 + tileY * 8 + tileX]; - - u16 color = palette[c]; - - *bmp++ = (color & 0x1f) << 3; - *bmp++ = ((color >> 5) & 0x1f) << 3; - *bmp++ = ((color >> 10) & 0x1f) << 3; - - if(data & 0x0400) { - if(tileX == 0) - screenSource++; - } else if(tileX == 7) - screenSource++; - if(x == 255 && sizeX > 256) { - screenSource = screenBase + 0x400 + ((yy>>3)*32); - } - } - bmp += 3 * (1024 - sizeX); + case 3: + sizeX = 512; + sizeY = 512; + break; } - } else { - for(int y = 0; y < sizeY; y++) { - int yy = y & 255; - if(y == 256 && sizeY > 256) { - screenBase += 0x400; - if(sizeX > 256) - screenBase += 0x400; - } - u16 *screenSource = screenBase + ((yy>>3)*32); + BMPSize(sizeX, sizeY); - for(int x = 0; x < sizeX; x++) { - u16 data = *screenSource; + if (control & 0x80) + { + for (int y = 0; y < sizeY; y++) + { + int yy = y & 255; - int tile = data & 0x3FF; - int tileX = (x & 7); - int tileY = y & 7; + if (y == 256 && sizeY > 256) + { + screenBase += 0x400; - if(data & 0x0400) - tileX = 7 - tileX; - if(data & 0x0800) - tileY = 7 - tileY; + if (sizeX > 256) + screenBase += 0x400; + } - u8 color = charBase[tile * 32 + tileY * 4 + (tileX>>1)]; + u16* screenSource = screenBase + ((yy >> 3) * 32); - if(tileX & 1) { - color = (color >> 4); - } else { - color &= 0x0F; + for (int x = 0; x < sizeX; x++) + { + u16 data = *screenSource; + int tile = data & 0x3FF; + int tileX = (x & 7); + int tileY = y & 7; + + if (data & 0x0400) + tileX = 7 - tileX; + + if (data & 0x0800) + tileY = 7 - tileY; + + u8 c = charBase[tile * 64 + tileY * 8 + tileX]; + u16 color = palette[c]; + *bmp++ = (color & 0x1f) << 3; + *bmp++ = ((color >> 5) & 0x1f) << 3; + *bmp++ = ((color >> 10) & 0x1f) << 3; + + if (data & 0x0400) + { + if (tileX == 0) + screenSource++; + } + else if (tileX == 7) + screenSource++; + + if (x == 255 && sizeX > 256) + { + screenSource = screenBase + 0x400 + ((yy >> 3) * 32); + } + } + + bmp += 3 * (1024 - sizeX); } - - int pal = (*screenSource>>8) & 0xF0; - u16 color2 = palette[pal + color]; - - *bmp++ = (color2 & 0x1f) << 3; - *bmp++ = ((color2 >> 5) & 0x1f) << 3; - *bmp++ = ((color2 >> 10) & 0x1f) << 3; - - if(data & 0x0400) { - if(tileX == 0) - screenSource++; - } else if(tileX == 7) - screenSource++; - - if(x == 255 && sizeX > 256) { - screenSource = screenBase + 0x400 + ((yy>>3)*32); - } - } - bmp += 3 * (1024 - sizeX); } - } + else + { + for (int y = 0; y < sizeY; y++) + { + int yy = y & 255; + + if (y == 256 && sizeY > 256) + { + screenBase += 0x400; + + if (sizeX > 256) + screenBase += 0x400; + } + + u16* screenSource = screenBase + ((yy >> 3) * 32); + + for (int x = 0; x < sizeX; x++) + { + u16 data = *screenSource; + int tile = data & 0x3FF; + int tileX = (x & 7); + int tileY = y & 7; + + if (data & 0x0400) + tileX = 7 - tileX; + + if (data & 0x0800) + tileY = 7 - tileY; + + u8 color = charBase[tile * 32 + tileY * 4 + (tileX >> 1)]; + + if (tileX & 1) + { + color = (color >> 4); + } + else + { + color &= 0x0F; + } + + int pal = (*screenSource >> 8) & 0xF0; + u16 color2 = palette[pal + color]; + *bmp++ = (color2 & 0x1f) << 3; + *bmp++ = ((color2 >> 5) & 0x1f) << 3; + *bmp++ = ((color2 >> 10) & 0x1f) << 3; + + if (data & 0x0400) + { + if (tileX == 0) + screenSource++; + } + else if (tileX == 7) + screenSource++; + + if (x == 255 && sizeX > 256) + { + screenSource = screenBase + 0x400 + ((yy >> 3) * 32); + } + } + + bmp += 3 * (1024 - sizeX); + } + } + #if 0 - switch(bg) { - case 0: - renderView(BG0HOFS<<8, BG0VOFS<<8, - 0x100, 0x000, - 0x000, 0x100, - (sizeX -1) <<8, - (sizeY -1) << 8, - true); - break; - case 1: - renderView(BG1HOFS<<8, BG1VOFS<<8, - 0x100, 0x000, - 0x000, 0x100, - (sizeX -1) <<8, - (sizeY -1) << 8, - true); - break; - case 2: - renderView(BG2HOFS<<8, BG2VOFS<<8, - 0x100, 0x000, - 0x000, 0x100, - (sizeX -1) <<8, - (sizeY -1) << 8, - true); - break; - case 3: - renderView(BG3HOFS<<8, BG3VOFS<<8, - 0x100, 0x000, - 0x000, 0x100, - (sizeX -1) <<8, - (sizeY -1) << 8, - true); - break; - } + + switch (bg) + { + case 0: + renderView(BG0HOFS << 8, BG0VOFS << 8, + 0x100, 0x000, + 0x000, 0x100, + (sizeX - 1) << 8, + (sizeY - 1) << 8, + true); + break; + + case 1: + renderView(BG1HOFS << 8, BG1VOFS << 8, + 0x100, 0x000, + 0x000, 0x100, + (sizeX - 1) << 8, + (sizeY - 1) << 8, + true); + break; + + case 2: + renderView(BG2HOFS << 8, BG2VOFS << 8, + 0x100, 0x000, + 0x000, 0x100, + (sizeX - 1) << 8, + (sizeY - 1) << 8, + true); + break; + + case 3: + renderView(BG3HOFS << 8, BG3VOFS << 8, + 0x100, 0x000, + 0x000, 0x100, + (sizeX - 1) << 8, + (sizeY - 1) << 8, + true); + break; + } + #endif } void renderRotScreen() { - u16 *palette = (u16 *)paletteRAM; - u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000]; - u8 *screenBase = (u8 *)&vram[((control >> 8) & 0x1f) * 0x800]; - u8 *bmp = image.GetData(); + u16* palette = (u16*)paletteRAM; + u8* charBase = &vram[((control >> 2) & 0x03) * 0x4000]; + u8* screenBase = (u8*)&vram[((control >> 8) & 0x1f) * 0x800]; + u8* bmp = image.GetData(); + int sizeX = 128; + int sizeY = 128; - int sizeX = 128; - int sizeY = 128; - switch((control >> 14) & 3) { - case 0: - break; - case 1: - sizeX = sizeY = 256; - break; - case 2: - sizeX = sizeY = 512; - break; - case 3: - sizeX = sizeY = 1024; - break; - } + switch ((control >> 14) & 3) + { + case 0: + break; - BMPSize(sizeX, sizeY); + case 1: + sizeX = sizeY = 256; + break; - if(control & 0x80) { - for(int y = 0; y < sizeY; y++) { - for(int x = 0; x < sizeX; x++) { - int tile = screenBase[(x>>3) + (y>>3)*(sizeX>>3)]; + case 2: + sizeX = sizeY = 512; + break; - int tileX = (x & 7); - int tileY = y & 7; - - u8 color = charBase[tile * 64 + tileY * 8 + tileX]; - u16 color2 = palette[color]; - - *bmp++ = (color2 & 0x1f) << 3; - *bmp++ = ((color2 >> 5) & 0x1f) << 3; - *bmp++ = ((color2 >> 10) & 0x1f) << 3; - } + case 3: + sizeX = sizeY = 1024; + break; } - bmp += 3 * (1024 - sizeX); - } else { - for(int y = 0; y < sizeY; y++) { - for(int x = 0; x < sizeX; x++) { - int tile = screenBase[(x>>3) + (y>>3)*(sizeX>>3)]; - int tileX = (x & 7); - int tileY = y & 7; + BMPSize(sizeX, sizeY); - u8 color = charBase[tile * 64 + tileY * 8 + tileX]; - u16 color2 = palette[color]; + if (control & 0x80) + { + for (int y = 0; y < sizeY; y++) + { + for (int x = 0; x < sizeX; x++) + { + int tile = screenBase[(x >> 3) + (y >> 3) * (sizeX >> 3)]; + int tileX = (x & 7); + int tileY = y & 7; + u8 color = charBase[tile * 64 + tileY * 8 + tileX]; + u16 color2 = palette[color]; + *bmp++ = (color2 & 0x1f) << 3; + *bmp++ = ((color2 >> 5) & 0x1f) << 3; + *bmp++ = ((color2 >> 10) & 0x1f) << 3; + } + } - *bmp++ = (color2 & 0x1f) << 3; - *bmp++ = ((color2 >> 5) & 0x1f) << 3; - *bmp++ = ((color2 >> 10) & 0x1f) << 3; - } + bmp += 3 * (1024 - sizeX); } - bmp += 3 * (1024 - sizeX); - } + else + { + for (int y = 0; y < sizeY; y++) + { + for (int x = 0; x < sizeX; x++) + { + int tile = screenBase[(x >> 3) + (y >> 3) * (sizeX >> 3)]; + int tileX = (x & 7); + int tileY = y & 7; + u8 color = charBase[tile * 64 + tileY * 8 + tileX]; + u16 color2 = palette[color]; + *bmp++ = (color2 & 0x1f) << 3; + *bmp++ = ((color2 >> 5) & 0x1f) << 3; + *bmp++ = ((color2 >> 10) & 0x1f) << 3; + } + } - u32 xx; - u32 yy; - - switch(bg) { - case 2: - xx = BG2X_L | BG2X_H << 16; - yy = BG2Y_L | BG2Y_H << 16; + bmp += 3 * (1024 - sizeX); + } + u32 xx; + u32 yy; + switch (bg) + { + case 2: + xx = BG2X_L | BG2X_H << 16; + yy = BG2Y_L | BG2Y_H << 16; #if 0 - renderView(xx, yy, - BG2PA, BG2PC, - BG2PB, BG2PD, - (sizeX -1) <<8, - (sizeY -1) << 8, - (control & 0x2000) != 0); + renderView(xx, yy, + BG2PA, BG2PC, + BG2PB, BG2PD, + (sizeX - 1) << 8, + (sizeY - 1) << 8, + (control & 0x2000) != 0); #endif - break; - case 3: - xx = BG3X_L | BG3X_H << 16; - yy = BG3Y_L | BG3Y_H << 16; + break; + + case 3: + xx = BG3X_L | BG3X_H << 16; + yy = BG3Y_L | BG3Y_H << 16; #if 0 - renderView(xx, yy, - BG3PA, BG3PC, - BG3PB, BG3PD, - (sizeX -1) <<8, - (sizeY -1) << 8, - (control & 0x2000) != 0); + renderView(xx, yy, + BG3PA, BG3PC, + BG3PB, BG3PD, + (sizeX - 1) << 8, + (sizeY - 1) << 8, + (control & 0x2000) != 0); #endif - break; - } + break; + } } void renderMode3() { - u8 *bmp = image.GetData(); - u16 *src = (u16 *)&vram[0]; + u8* bmp = image.GetData(); + u16* src = (u16*)&vram[0]; + BMPSize(240, 160); - BMPSize(240, 160); + for (int y = 0; y < 160; y++) + { + for (int x = 0; x < 240; x++) + { + u16 data = *src++; + *bmp++ = (data & 0x1f) << 3; + *bmp++ = ((data >> 5) & 0x1f) << 3; + *bmp++ = ((data >> 10) & 0x1f) << 3; + } - for(int y = 0; y < 160; y++) { - for(int x = 0; x < 240; x++) { - u16 data = *src++; - *bmp++ = (data & 0x1f) << 3; - *bmp++ = ((data >> 5) & 0x1f) << 3; - *bmp++ = ((data >> 10) & 0x1f) << 3; + bmp += 3 * (1024 - 240); } - bmp += 3 * (1024 - 240); - } } void renderMode4() { - u8 *bmp = image.GetData(); - u8 *src = frame ? &vram[0xa000] : &vram[0]; - u16 *pal = (u16 *)&paletteRAM[0]; + u8* bmp = image.GetData(); + u8* src = frame ? &vram[0xa000] : &vram[0]; + u16* pal = (u16*)&paletteRAM[0]; + BMPSize(240, 160); - BMPSize(240, 160); + for (int y = 0; y < 160; y++) + { + for (int x = 0; x < 240; x++) + { + u8 c = *src++; + u16 data = pal[c]; + *bmp++ = (data & 0x1f) << 3; + *bmp++ = ((data >> 5) & 0x1f) << 3; + *bmp++ = ((data >> 10) & 0x1f) << 3; + } - for(int y = 0; y < 160; y++) { - for(int x = 0; x < 240; x++) { - u8 c = *src++; - u16 data = pal[c]; - *bmp++ = (data & 0x1f) << 3; - *bmp++ = ((data >> 5) & 0x1f) << 3; - *bmp++ = ((data >> 10) & 0x1f) << 3; + bmp += 3 * (1024 - 240); } - bmp += 3 * (1024 - 240); - } } void renderMode5() { - u8 *bmp = image.GetData(); - u16 *src = (u16 *)(frame ? &vram[0xa000] : &vram[0]); + u8* bmp = image.GetData(); + u16* src = (u16*)(frame ? &vram[0xa000] : &vram[0]); + BMPSize(160, 128); - BMPSize(160, 128); + for (int y = 0; y < 128; y++) + { + for (int x = 0; x < 160; x++) + { + u16 data = *src++; + *bmp++ = (data & 0x1f) << 3; + *bmp++ = ((data >> 5) & 0x1f) << 3; + *bmp++ = ((data >> 10) & 0x1f) << 3; + } - for(int y = 0; y < 128; y++) { - for(int x = 0; x < 160; x++) { - u16 data = *src++; - *bmp++ = (data & 0x1f) << 3; - *bmp++ = ((data >> 5) & 0x1f) << 3; - *bmp++ = ((data >> 10) & 0x1f) << 3; + bmp += 3 * (1024 - 160); } - bmp += 3 * (1024 - 160); - } } DECLARE_EVENT_TABLE() - }; +}; - BEGIN_EVENT_TABLE(MapViewer, GfxViewer) +BEGIN_EVENT_TABLE(MapViewer, GfxViewer) EVT_GFX_CLICK(wxID_ANY, MapViewer::UpdateMouseInfoEv) - END_EVENT_TABLE() - - class GBMapViewer : public GfxViewer - { - public: +END_EVENT_TABLE() + +class GBMapViewer : public GfxViewer +{ +public: GBMapViewer() : GfxViewer(wxT("GBMapViewer"), 256, 256) { - getradio(,"CharBase0", charbase, 0x0000); - getradio(,"CharBase1", charbase, 0x0800); - getradio(,"MapBase0", mapbase, 0x1800); - getradio(,"MapBase1", mapbase, 0x1c00); - getlab(coords, "Coords", "(2WW,2WW)"); - getlab(addr, "Address", "0xWWWW"); - getlab(tile, "Tile", "2WW"); - getlab(flip, "Flip", "HV"); - getlab(palette, "Palette", "---"); - getlab(prio, "Priority", "P"); - Fit(); - selx = sely = -1; - Update(); + getradio(, "CharBase0", charbase, 0x0000); + getradio(, "CharBase1", charbase, 0x0800); + getradio(, "MapBase0", mapbase, 0x1800); + getradio(, "MapBase1", mapbase, 0x1c00); + getlab(coords, "Coords", "(2WW,2WW)"); + getlab(addr, "Address", "0xWWWW"); + getlab(tile, "Tile", "2WW"); + getlab(flip, "Flip", "HV"); + getlab(palette, "Palette", "---"); + getlab(prio, "Priority", "P"); + Fit(); + selx = sely = -1; + Update(); } void Update() { - u8 *bank0, *bank1; - if(gbCgbMode) { - bank0 = &gbVram[0x0000]; - bank1 = &gbVram[0x2000]; - } else { - bank0 = &gbMemory[0x8000]; - bank1 = NULL; - } - int tile_map_address = mapbase; + u8* bank0, *bank1; - // following copied almost verbatim from win32/GBMapView.cpp - int tile = 0; - for(int y = 0; y < 32; y++) { - for(int x = 0; x < 32; x++) { - u8 *bmp = &image.GetData()[y * 8 * 32 * 24 + x*24]; - u8 attrs = 0; - if(bank1 != NULL) - attrs = bank1[tile_map_address]; - u8 tile = bank0[tile_map_address]; - tile_map_address++; - - if(charbase) { - if(tile < 128) tile += 128; - else tile -= 128; - } - for(int j = 0; j < 8; j++) { - int charbase_address = attrs & 0x40 ? - charbase + tile*16 + (7-j)*2: - charbase + tile*16+j*2; - - u8 tile_a = 0; - u8 tile_b = 0; - - if(attrs & 0x08) { - tile_a = bank1[charbase_address++]; - tile_b = bank1[charbase_address]; - } else { - tile_a = bank0[charbase_address++]; - tile_b = bank0[charbase_address]; - } - - if(attrs & 0x20) { - tile_a = gbInvertTab[tile_a]; - tile_b = gbInvertTab[tile_b]; - } - - u8 mask = 0x80; - - while(mask > 0) { - u8 c = (tile_a & mask) ? 1 : 0; - c += (tile_b & mask) ? 2 : 0; - - if(gbCgbMode) - c = c + (attrs & 7)*4; - - u16 color = gbPalette[c]; - - *bmp++ = (color & 0x1f) << 3; - *bmp++ = ((color >> 5) & 0x1f) << 3; - *bmp++ = ((color >> 10) & 0x1f) << 3; - - mask >>= 1; - } - bmp += 31*24; - } + if (gbCgbMode) + { + bank0 = &gbVram[0x0000]; + bank1 = &gbVram[0x2000]; } - } - ChangeBMP(); - UpdateMouseInfo(); + else + { + bank0 = &gbMemory[0x8000]; + bank1 = NULL; + } + + int tile_map_address = mapbase; + // following copied almost verbatim from win32/GBMapView.cpp + int tile = 0; + + for (int y = 0; y < 32; y++) + { + for (int x = 0; x < 32; x++) + { + u8* bmp = &image.GetData()[y * 8 * 32 * 24 + x * 24]; + u8 attrs = 0; + + if (bank1 != NULL) + attrs = bank1[tile_map_address]; + + u8 tile = bank0[tile_map_address]; + tile_map_address++; + + if (charbase) + { + if (tile < 128) tile += 128; + else tile -= 128; + } + + for (int j = 0; j < 8; j++) + { + int charbase_address = attrs & 0x40 ? + charbase + tile * 16 + (7 - j) * 2 : + charbase + tile * 16 + j * 2; + u8 tile_a = 0; + u8 tile_b = 0; + + if (attrs & 0x08) + { + tile_a = bank1[charbase_address++]; + tile_b = bank1[charbase_address]; + } + else + { + tile_a = bank0[charbase_address++]; + tile_b = bank0[charbase_address]; + } + + if (attrs & 0x20) + { + tile_a = gbInvertTab[tile_a]; + tile_b = gbInvertTab[tile_b]; + } + + u8 mask = 0x80; + + while (mask > 0) + { + u8 c = (tile_a & mask) ? 1 : 0; + c += (tile_b & mask) ? 2 : 0; + + if (gbCgbMode) + c = c + (attrs & 7) * 4; + + u16 color = gbPalette[c]; + *bmp++ = (color & 0x1f) << 3; + *bmp++ = ((color >> 5) & 0x1f) << 3; + *bmp++ = ((color >> 10) & 0x1f) << 3; + mask >>= 1; + } + + bmp += 31 * 24; + } + } + } + + ChangeBMP(); + UpdateMouseInfo(); } void UpdateMouseInfoEv(wxMouseEvent &ev) { - selx = ev.GetX(); - sely = ev.GetY(); - UpdateMouseInfo(); // note that this will be inaccurate if game - // not paused since last refresh + selx = ev.GetX(); + sely = ev.GetY(); + UpdateMouseInfo(); // note that this will be inaccurate if game + // not paused since last refresh } void UpdateMouseInfo() { - if(selx > gv->bmw || sely > gv->bmh) - selx = sely = -1; - if(selx < 0) { - coords->SetLabel(wxEmptyString); - addr->SetLabel(wxEmptyString); - tile->SetLabel(wxEmptyString); - flip->SetLabel(wxEmptyString); - palette->SetLabel(wxEmptyString); - prio->SetLabel(wxEmptyString); - } else { - wxString s; - s.Printf(wxT("(%d,%d)"), selx, sely); - coords->SetLabel(s); - u16 address = mapbase + 0x8000 + (sely >> 3) * 32 + (selx >> 3); - s.Printf(wxT("0x%04X"), address); - addr->SetLabel(s); - u8 attrs = 0; - u8 tilev = gbMemoryMap[9][address & 0xfff]; - if(gbCgbMode) { - attrs = gbVram[0x2000 + address - 0x8000]; - tilev = gbVram[address & 0x1fff]; + if (selx > gv->bmw || sely > gv->bmh) + selx = sely = -1; + + if (selx < 0) + { + coords->SetLabel(wxEmptyString); + addr->SetLabel(wxEmptyString); + tile->SetLabel(wxEmptyString); + flip->SetLabel(wxEmptyString); + palette->SetLabel(wxEmptyString); + prio->SetLabel(wxEmptyString); } - if(charbase) { - if(tilev >= 128) - tilev -= 128; - else - tilev += 128; + else + { + wxString s; + s.Printf(wxT("(%d,%d)"), selx, sely); + coords->SetLabel(s); + u16 address = mapbase + 0x8000 + (sely >> 3) * 32 + (selx >> 3); + s.Printf(wxT("0x%04X"), address); + addr->SetLabel(s); + u8 attrs = 0; + u8 tilev = gbMemoryMap[9][address & 0xfff]; + + if (gbCgbMode) + { + attrs = gbVram[0x2000 + address - 0x8000]; + tilev = gbVram[address & 0x1fff]; + } + + if (charbase) + { + if (tilev >= 128) + tilev -= 128; + else + tilev += 128; + } + + s.Printf(wxT("%d"), (int)tilev); + tile->SetLabel(s); + s = attrs & 0x20 ? wxT('H') : wxT('-'); + s += attrs & 0x40 ? wxT('V') : wxT('-'); + flip->SetLabel(s); + + if (gbCgbMode) + { + s.Printf(wxT("%d"), attrs & 7); + palette->SetLabel(s); + } + else + palette->SetLabel(wxT("---")); + + prio->SetLabel(wxString(attrs & 0x80 ? wxT('P') : wxT('-'))); } - s.Printf(wxT("%d"), (int)tilev); - tile->SetLabel(s); - s = attrs & 0x20 ? wxT('H') : wxT('-'); - s += attrs & 0x40 ? wxT('V') : wxT('-'); - flip->SetLabel(s); - if(gbCgbMode) { - s.Printf(wxT("%d"), attrs & 7); - palette->SetLabel(s); - } else - palette->SetLabel(wxT("---")); - prio->SetLabel(wxString(attrs & 0x80 ? wxT('P') : wxT('-'))); - } } - protected: +protected: int charbase, mapbase; - wxControl *coords, *addr, *tile, *flip, *palette, *prio; + wxControl* coords, *addr, *tile, *flip, *palette, *prio; int selx, sely; DECLARE_EVENT_TABLE() - }; +}; - BEGIN_EVENT_TABLE(GBMapViewer, GfxViewer) +BEGIN_EVENT_TABLE(GBMapViewer, GfxViewer) EVT_GFX_CLICK(wxID_ANY, GBMapViewer::UpdateMouseInfoEv) - END_EVENT_TABLE() +END_EVENT_TABLE() } void MainFrame::MapViewer() { - switch(panel->game_type()) { - case IMAGE_GBA: - LoadXRCViewer(Map); - break; - case IMAGE_GB: - LoadXRCViewer(GBMap); - break; - } + switch (panel->game_type()) + { + case IMAGE_GBA: + LoadXRCViewer(Map); + break; + + case IMAGE_GB: + LoadXRCViewer(GBMap); + break; + } } -namespace Viewers { - class OAMViewer : public GfxViewer - { - public: - OAMViewer() : GfxViewer(wxT("OAMViewer"), 544, 496) +namespace Viewers +{ +class OAMViewer : public GfxViewer +{ +public: + OAMViewer() : GfxViewer(wxT("OAMViewer"), 544, 496) { - sprite = 0; - getspin(,"Sprite", sprite); - getlab(pos, "Pos", "5WW,2WW"); - getlab(mode, "Mode", "3"); - getlab(colors, "Colors", "256"); - getlab(pallab, "Palette", "1W"); - getlab(tile, "Tile", "1WWW"); - getlab(prio, "Priority", "3"); - getlab(size, "Size", "64x64"); - getlab(rot, "Rotation", "3W"); - getlab(flg, "Flags", "RHVMD"); - Fit(); - Update(); + sprite = 0; + getspin(, "Sprite", sprite); + getlab(pos, "Pos", "5WW,2WW"); + getlab(mode, "Mode", "3"); + getlab(colors, "Colors", "256"); + getlab(pallab, "Palette", "1W"); + getlab(tile, "Tile", "1WWW"); + getlab(prio, "Priority", "3"); + getlab(size, "Size", "64x64"); + getlab(rot, "Rotation", "3W"); + getlab(flg, "Flags", "RHVMD"); + Fit(); + Update(); } void Update() { BMPSize(544, 496); - wxImage screen(240, 160); systemRedShift = 19; systemGreenShift = 11; @@ -756,55 +877,67 @@ namespace Viewers { for (int sprite_no = 0; sprite_no < 128; sprite_no++) { - u16 *sparms = &((u16 *)oam)[4 * sprite_no]; + u16* sparms = &((u16*)oam)[4 * sprite_no]; u16 a0 = sparms[0], a1 = sparms[1], a2 = sparms[2]; - u16 *pal = &((u16 *)paletteRAM)[0x100]; - + u16* pal = &((u16*)paletteRAM)[0x100]; int sizeX = 8, sizeY = 8; // following is almost verbatim from OamView.cpp // shape = (a0 >> 14) & 3; // size = (a1 >> 14) & 3; - switch (((a0 >> 12) & 0xc) | (a1 >> 14)) { + switch (((a0 >> 12) & 0xc) | (a1 >> 14)) + { case 0: break; + case 1: sizeX = sizeY = 16; break; + case 2: sizeX = sizeY = 32; break; + case 3: sizeX = sizeY = 64; break; + case 4: sizeX = 16; break; + case 5: sizeX = 32; break; + case 6: sizeX = 32; sizeY = 16; break; + case 7: sizeX = 64; sizeY = 32; break; + case 8: sizeY = 16; break; + case 9: sizeY = 32; break; + case 10: sizeX = 16; sizeY = 32; break; + case 11: sizeX = 32; sizeY = 64; break; + default: pos->SetLabel(wxEmptyString); mode->SetLabel(wxEmptyString); @@ -819,46 +952,57 @@ namespace Viewers { } wxImage spriteData(64, 64); - u8 *bmp = spriteData.GetData(); - + u8* bmp = spriteData.GetData(); int sy = (a0 & 255); - if (a0 & 0x2000) { + if (a0 & 0x2000) + { int c = (a2 & 0x3FF); //if((DISPCNT & 7) > 2 && (c < 512)) // return; int inc = 32; + if (DISPCNT & 0x40) inc = sizeX >> 2; else c &= 0x3FE; - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { + for (int y = 0; y < sizeY; y++) + { + for (int x = 0; x < sizeX; x++) + { u32 color = vram[0x10000 + (((c + (y >> 3) * inc) * - 32 + (y & 7) * 8 + (x >> 3) * 64 + - (x & 7)) & 0x7FFF)]; + 32 + (y & 7) * 8 + (x >> 3) * 64 + + (x & 7)) & 0x7FFF)]; color = pal[color]; *bmp++ = (color & 0x1f) << 3; *bmp++ = ((color >> 5) & 0x1f) << 3; *bmp++ = ((color >> 10) & 0x1f) << 3; } + bmp += (64 - sizeX) * 3; } } - else { + else + { int c = (a2 & 0x3FF); //if((DISPCNT & 7) > 2 && (c < 512)) // return; int inc = 32; + if (DISPCNT & 0x40) inc = sizeX >> 3; + int palette = (a2 >> 8) & 0xF0; - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { + + for (int y = 0; y < sizeY; y++) + { + for (int x = 0; x < sizeX; x++) + { u32 color = vram[0x10000 + (((c + (y >> 3) * inc) * - 32 + (y & 7) * 4 + (x >> 3) * 32 + - ((x & 7) >> 1)) & 0x7FFF)]; + 32 + (y & 7) * 4 + (x >> 3) * 32 + + ((x & 7) >> 1)) & 0x7FFF)]; + if (x & 1) color >>= 4; else @@ -869,6 +1013,7 @@ namespace Viewers { *bmp++ = ((color >> 5) & 0x1f) << 3; *bmp++ = ((color >> 10) & 0x1f) << 3; } + bmp += (64 - sizeX) * 3; } } @@ -890,31 +1035,41 @@ namespace Viewers { s.Printf(wxT("%dx%d"), sizeX, sizeY); s.Printf(wxT("%dx%d"), 0, 0); size->SetLabel(s); - if(a0 & 512) { - s.Printf(wxT("%d"), (a1 >> 9) & 31); - rot->SetLabel(s); - } else - rot->SetLabel(wxEmptyString); - s = wxEmptyString; - if(a0 & 512) - s.append(wxT("R--")); - else { - s.append(wxT('-')); - s.append(a1 & 4096 ? wxT('H') : wxT('-')); - s.append(a1 & 8192 ? wxT('V') : wxT('-')); + + if (a0 & 512) + { + s.Printf(wxT("%d"), (a1 >> 9) & 31); + rot->SetLabel(s); } + else + rot->SetLabel(wxEmptyString); + + s = wxEmptyString; + + if (a0 & 512) + s.append(wxT("R--")); + else + { + s.append(wxT('-')); + s.append(a1 & 4096 ? wxT('H') : wxT('-')); + s.append(a1 & 8192 ? wxT('V') : wxT('-')); + } + s.append(a0 & 4096 ? wxT('M') : wxT('-')); s.append(a0 & 1024 ? wxT('D') : wxT('-')); flg->SetLabel(s); - - u8 *box = spriteData.GetData(); + u8* box = spriteData.GetData(); int sprite_posx = a1 & 511; int sprite_posy = a0 & 255; - u8 *screen_box = screen.GetData(); + u8* screen_box = screen.GetData(); + if (sprite_posx >= 0 && sprite_posx <= (239 - sizeY) && sprite_posy >= 0 && sprite_posy <= (159 - sizeX)) screen_box += (sprite_posx * 3) + (sprite_posy * screen.GetWidth() * 3); - for (int y = 0; y < sizeY; y++) { - for (int x = 0; x < sizeX; x++) { + + for (int y = 0; y < sizeY; y++) + { + for (int x = 0; x < sizeX; x++) + { u32 color = 0; if (y == 0 || y == sizeY - 1 || x == 0 || x == sizeX - 1) @@ -923,6 +1078,7 @@ namespace Viewers { *box++ = (color & 0x1f) << 3; *box++ = ((color >> 5) & 0x1f) << 3; *box++ = ((color >> 10) & 0x1f) << 3; + if (sprite_posx >= 0 && sprite_posx <= (239 - sizeY) && sprite_posy >= 0 && sprite_posy <= (159 - sizeX)) { *screen_box++ = (color & 0x1f) << 3; @@ -933,11 +1089,14 @@ namespace Viewers { else { box += 3; + if (sprite_posx >= 0 && sprite_posx <= (239 - sizeY) && sprite_posy >= 0 && sprite_posy <= (159 - sizeX)) screen_box += 3; } } + box += (spriteData.GetWidth() - sizeX) * 3; + if (sprite_posx >= 0 && sprite_posx <= (239 - sizeY) && sprite_posy >= 0 && sprite_posy <= (159 - sizeX)) screen_box += (screen.GetWidth() - sizeX) * 3; } @@ -947,168 +1106,189 @@ namespace Viewers { } image.Paste(screen, 0, 304); - ChangeBMP(); } - protected: +protected: int sprite; - wxControl *pos, *mode, *colors, *pallab, *tile, *prio, *size, *rot, *flg; - }; + wxControl* pos, *mode, *colors, *pallab, *tile, *prio, *size, *rot, *flg; +}; - class GBOAMViewer : public GfxViewer - { - public: +class GBOAMViewer : public GfxViewer +{ +public: GBOAMViewer() : GfxViewer(wxT("GBOAMViewer"), 8, 16) { - sprite = 0; - getspin(,"Sprite", sprite); - getlab(pos, "Pos", "2WW,2WW"); - getlab(tilelab, "Tile", "2WW"); - getlab(prio, "Priority", "W"); - getlab(oap, "OAP", "W"); - getlab(pallab, "Palette", "W"); - getlab(flg, "Flags", "HV"); - getlab(banklab, "Bank", "W"); - Fit(); - Update(); + sprite = 0; + getspin(, "Sprite", sprite); + getlab(pos, "Pos", "2WW,2WW"); + getlab(tilelab, "Tile", "2WW"); + getlab(prio, "Priority", "W"); + getlab(oap, "OAP", "W"); + getlab(pallab, "Palette", "W"); + getlab(flg, "Flags", "HV"); + getlab(banklab, "Bank", "W"); + Fit(); + Update(); } void Update() { - u8 *bmp = image.GetData(); + u8* bmp = image.GetData(); + // following is almost verbatim from GBOamView.cpp + u16 addr = sprite * 4 + 0xfe00; + int size = register_LCDC & 4; + u8 y = gbMemory[addr++]; + u8 x = gbMemory[addr++]; + u8 tile = gbMemory[addr++]; - // following is almost verbatim from GBOamView.cpp - u16 addr = sprite * 4 + 0xfe00; + if (size) + tile &= 254; - int size = register_LCDC & 4; + u8 flags = gbMemory[addr++]; + int w = 8; + int h = size ? 16 : 8; + BMPSize(w, h); + u8* bank0; + u8* bank1; - u8 y = gbMemory[addr++]; - u8 x = gbMemory[addr++]; - u8 tile = gbMemory[addr++]; - if(size) - tile &= 254; - u8 flags = gbMemory[addr++]; - - int w = 8; - int h = size ? 16 : 8; - BMPSize(w, h); - - u8 * bank0; - u8 * bank1; - if(gbCgbMode) { - if(register_VBK & 1) { - bank0 = &gbVram[0x0000]; - bank1 = &gbVram[0x2000]; - } else { - bank0 = &gbVram[0x0000]; - bank1 = &gbVram[0x2000]; + if (gbCgbMode) + { + if (register_VBK & 1) + { + bank0 = &gbVram[0x0000]; + bank1 = &gbVram[0x2000]; + } + else + { + bank0 = &gbVram[0x0000]; + bank1 = &gbVram[0x2000]; + } } - } else { - bank0 = &gbMemory[0x8000]; - bank1 = NULL; - } - - int init = 0x0000; - - u8 *pal = gbObp0; - - if((flags & 0x10)) - pal = gbObp1; - - for(int yy = 0; yy < h; yy++) { - int address = init + tile * 16 + 2*yy; - int a = 0; - int b = 0; - - if(gbCgbMode && flags & 0x08) { - a = bank1[address++]; - b = bank1[address++]; - } else { - a = bank0[address++]; - b = bank0[address++]; + else + { + bank0 = &gbMemory[0x8000]; + bank1 = NULL; } - for(int xx = 0; xx < 8; xx++) { - u8 mask = 1 << (7-xx); - u8 c = 0; - if( (a & mask)) - c++; - if( (b & mask)) - c+=2; + int init = 0x0000; + u8* pal = gbObp0; - // make sure that sprites will work even in CGB mode - if(gbCgbMode) { - c = c + (flags & 0x07)*4 + 32; - } else { - c = pal[c]; - } + if ((flags & 0x10)) + pal = gbObp1; - u16 color = gbPalette[c]; - *bmp++ = (color & 0x1f) << 3; - *bmp++ = ((color >> 5) & 0x1f) << 3; - *bmp++ = ((color >> 10) & 0x1f) << 3; + for (int yy = 0; yy < h; yy++) + { + int address = init + tile * 16 + 2 * yy; + int a = 0; + int b = 0; + + if (gbCgbMode && flags & 0x08) + { + a = bank1[address++]; + b = bank1[address++]; + } + else + { + a = bank0[address++]; + b = bank0[address++]; + } + + for (int xx = 0; xx < 8; xx++) + { + u8 mask = 1 << (7 - xx); + u8 c = 0; + + if ((a & mask)) + c++; + + if ((b & mask)) + c += 2; + + // make sure that sprites will work even in CGB mode + if (gbCgbMode) + { + c = c + (flags & 0x07) * 4 + 32; + } + else + { + c = pal[c]; + } + + u16 color = gbPalette[c]; + *bmp++ = (color & 0x1f) << 3; + *bmp++ = ((color >> 5) & 0x1f) << 3; + *bmp++ = ((color >> 10) & 0x1f) << 3; + } } - } - ChangeBMP(); - wxString s; - s.Printf(wxT("%d,%d"), x, y); - pos->SetLabel(s); - s.Printf(wxT("%d"), tile); - tilelab->SetLabel(s); - prio->SetLabel(flags & 0x80 ? wxT("1") : wxT("0")); - oap->SetLabel(flags & 0x08 ? wxT("1") : wxT("0")); - s.Printf(wxT("%d"), flags & 7); - pallab->SetLabel(s); - s = flags & 0x20 ? wxT('H') : wxT('-'); - s.append(flags & 0x40 ? wxT('V') : wxT('-')); - flg->SetLabel(s); - banklab->SetLabel(flags & 0x10 ? wxT("1") : wxT("0")); + ChangeBMP(); + wxString s; + s.Printf(wxT("%d,%d"), x, y); + pos->SetLabel(s); + s.Printf(wxT("%d"), tile); + tilelab->SetLabel(s); + prio->SetLabel(flags & 0x80 ? wxT("1") : wxT("0")); + oap->SetLabel(flags & 0x08 ? wxT("1") : wxT("0")); + s.Printf(wxT("%d"), flags & 7); + pallab->SetLabel(s); + s = flags & 0x20 ? wxT('H') : wxT('-'); + s.append(flags & 0x40 ? wxT('V') : wxT('-')); + flg->SetLabel(s); + banklab->SetLabel(flags & 0x10 ? wxT("1") : wxT("0")); } - protected: +protected: int sprite; - wxControl *pos, *tilelab, *prio, *oap, *pallab, *flg, *banklab; - }; + wxControl* pos, *tilelab, *prio, *oap, *pallab, *flg, *banklab; +}; } void MainFrame::OAMViewer() { - switch(panel->game_type()) { - case IMAGE_GBA: - LoadXRCViewer(OAM); - break; - case IMAGE_GB: - LoadXRCViewer(GBOAM); - break; - } + switch (panel->game_type()) + { + case IMAGE_GBA: + LoadXRCViewer(OAM); + break; + + case IMAGE_GB: + LoadXRCViewer(GBOAM); + break; + } } -namespace Viewers { - static int ptype = 0; - static wxString pdir; - void savepal(wxWindow *parent, const u8 *data, int ncols, const wxChar *type) - { +namespace Viewers +{ +static int ptype = 0; +static wxString pdir; +void savepal(wxWindow* parent, const u8* data, int ncols, const wxChar* type) +{ // no attempt is made here to translate the palette type name // it's just a suggested name, anyway wxString def_name = wxGetApp().frame->GetPanel()->game_name() + wxT('-') + type; - if(ptype == 2) - def_name += wxT(".act"); + + if (ptype == 2) + def_name += wxT(".act"); else - def_name += wxT(".pal"); + def_name += wxT(".pal"); + wxFileDialog dlg(parent, _("Select output file and type"), pdir, def_name, - _("Windows Palette (*.pal)|*.pal|PaintShop Palette (*.pal)|*.pal|Adobe Color Table (*.act)|*.act"), - wxFD_SAVE|wxFD_OVERWRITE_PROMPT); + _("Windows Palette (*.pal)|*.pal|PaintShop Palette (*.pal)|*.pal|Adobe Color Table (*.act)|*.act"), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT); dlg.SetFilterIndex(ptype); int ret = dlg.ShowModal(); ptype = dlg.GetFilterIndex(); pdir = dlg.GetDirectory(); - if(ret != wxID_OK) - return; + + if (ret != wxID_OK) + return; + wxFFile f(dlg.GetPath(), wxT("wb")); + // FIXME: check for errors - switch(ptype) { + switch (ptype) + { case 0: // Windows palette - { + { f.Write("RIFF", 4); u32 d = wxUINT32_SWAP_ON_BE(256 * 4 + 16); f.Write(&d, 4); @@ -1119,505 +1299,579 @@ namespace Viewers { f.Write(&w, 2); w = wxUINT16_SWAP_ON_BE(256); // cuases problems if not 16 or 256 f.Write(&w, 2); - for(int i = 0; i < ncols; i++, data += 3) { - f.Write(data, 3); - u8 z = 0; - f.Write(&z, 1); + + for (int i = 0; i < ncols; i++, data += 3) + { + f.Write(data, 3); + u8 z = 0; + f.Write(&z, 1); } - for(int i = ncols; i < 256; i++) { - d = 0; - f.Write(&d, 4); + + for (int i = ncols; i < 256; i++) + { + d = 0; + f.Write(&d, 4); } - } - break; + } + break; + case 1: // PaintShop palette - { + { #define jasc_head "JASC-PAL\r\n0100\r\n256\r\n" f.Write(jasc_head, sizeof(jasc_head) - 1); - for(int i = 0; i < ncols; i++, data += 3) { - char buf[14]; - int l = sprintf(buf, "%d %d %d\r\n", data[0], data[1], data[2]); - f.Write(buf, l); + + for (int i = 0; i < ncols; i++, data += 3) + { + char buf[14]; + int l = sprintf(buf, "%d %d %d\r\n", data[0], data[1], data[2]); + f.Write(buf, l); } - for(int i = ncols; i < 256; i++) - f.Write("0 0 0\r\n", 7); + + for (int i = ncols; i < 256; i++) + f.Write("0 0 0\r\n", 7); + break; - } + } + case 2: // Adobe color table - { + { f.Write(data, ncols * 3); u32 d = 0; - for(int i = ncols; i < 256; i++) - f.Write(&d, 3); - } - break; - } - f.Close(); // FIXME: check for errors - } - class PaletteViewer : public Viewer - { - public: + for (int i = ncols; i < 256; i++) + f.Write(&d, 3); + } + break; + } + + f.Close(); // FIXME: check for errors +} + +class PaletteViewer : public Viewer +{ +public: PaletteViewer() : Viewer(wxT("PaletteViewer")) { - colorctrl(cv, "Color"); - pixview(bpv, "Background", 16, 16, cv); - pixview(spv, "Sprite", 16, 16, cv); - getlab(addr, "Address", "0x5000WWW"); - getlab(val, "Value", "0xWWWW"); - Fit(); - Update(); + colorctrl(cv, "Color"); + pixview(bpv, "Background", 16, 16, cv); + pixview(spv, "Sprite", 16, 16, cv); + getlab(addr, "Address", "0x5000WWW"); + getlab(val, "Value", "0xWWWW"); + Fit(); + Update(); } void Update() { - if(paletteRAM) { - u16 *pp = (u16 *)paletteRAM; - u8 *bmp = colbmp; - for(int i = 0; i < 512; i++, pp++) { - *bmp++ = (*pp & 0x1f) << 3; - *bmp++ = (*pp & 0x3e0) >> 2; - *bmp++ = (*pp & 0x7c00) >> 7; + if (paletteRAM) + { + u16* pp = (u16*)paletteRAM; + u8* bmp = colbmp; + + for (int i = 0; i < 512; i++, pp++) + { + *bmp++ = (*pp & 0x1f) << 3; + *bmp++ = (*pp & 0x3e0) >> 2; + *bmp++ = (*pp & 0x7c00) >> 7; + } } - } else - memset(colbmp, 0, sizeof(colbmp)); - bpv->SetData(colbmp, 16, 0, 0); - spv->SetData(colbmp + 16*16*3, 16, 0, 0); - ShowSel(); + else + memset(colbmp, 0, sizeof(colbmp)); + + bpv->SetData(colbmp, 16, 0, 0); + spv->SetData(colbmp + 16 * 16 * 3, 16, 0, 0); + ShowSel(); } void SelBG(wxMouseEvent &ev) { - spv->SetSel(-1, -1, false); - ShowSel(); + spv->SetSel(-1, -1, false); + ShowSel(); } void SelSprite(wxMouseEvent &ev) { - bpv->SetSel(-1, -1, false); - ShowSel(); + bpv->SetSel(-1, -1, false); + ShowSel(); } void ShowSel() { - int x, y; - bool isbg = true; - bpv->GetSel(x, y); - if(x < 0) { - isbg = false; - spv->GetSel(x, y); - if(x < 0) { - addr->SetLabel(wxEmptyString); - val->SetLabel(wxEmptyString); - return; + int x, y; + bool isbg = true; + bpv->GetSel(x, y); + + if (x < 0) + { + isbg = false; + spv->GetSel(x, y); + + if (x < 0) + { + addr->SetLabel(wxEmptyString); + val->SetLabel(wxEmptyString); + return; + } } - } - int off = x + y * 16; - if(!isbg) - off += 16 * 16; - u8 *pix = &colbmp[off * 3]; - u16 v = (pix[0] >> 3) + ((pix[1] >> 3) << 5) + ((pix[2] >> 3) << 10); - wxString s; - s.Printf(wxT("0x%04X"), (int)v); - val->SetLabel(s); - s.Printf(wxT("0x%08X"), 0x5000000 + 2 * off); - addr->SetLabel(s); + + int off = x + y * 16; + + if (!isbg) + off += 16 * 16; + + u8* pix = &colbmp[off * 3]; + u16 v = (pix[0] >> 3) + ((pix[1] >> 3) << 5) + ((pix[2] >> 3) << 10); + wxString s; + s.Printf(wxT("0x%04X"), (int)v); + val->SetLabel(s); + s.Printf(wxT("0x%08X"), 0x5000000 + 2 * off); + addr->SetLabel(s); } void SaveBG(wxCommandEvent &ev) { - savepal(this, colbmp, 16 * 16, wxT("bg")); + savepal(this, colbmp, 16 * 16, wxT("bg")); } void SaveOBJ(wxCommandEvent &ev) { - savepal(this, colbmp + 16 * 16 * 3, 16 * 16, wxT("obj")); + savepal(this, colbmp + 16 * 16 * 3, 16 * 16, wxT("obj")); } void ChangeBackdrop(wxCommandEvent &ev) { - // FIXME: this should really be a preference - // should also have some way of indicating selection - // perhaps replace w/ checkbox + colorpickerctrl - static wxColourData *cd = NULL; - wxColourDialog dlg(this, cd); - if(dlg.ShowModal() == wxID_OK) { - if(!cd) - cd = new wxColourData(); - *cd = dlg.GetColourData(); - wxColour c = cd->GetColour(); - //Binary or the upper 5 bits of each color choice - customBackdropColor = - (c.Red() >> 3) || - ((c.Green() >> 3) << 5) || - ((c.Blue() >> 3) << 10); - } else - // kind of an unintuitive way to turn it off... - customBackdropColor = -1; + // FIXME: this should really be a preference + // should also have some way of indicating selection + // perhaps replace w/ checkbox + colorpickerctrl + static wxColourData* cd = NULL; + wxColourDialog dlg(this, cd); + + if (dlg.ShowModal() == wxID_OK) + { + if (!cd) + cd = new wxColourData(); + + *cd = dlg.GetColourData(); + wxColour c = cd->GetColour(); + //Binary or the upper 5 bits of each color choice + customBackdropColor = + (c.Red() >> 3) || + ((c.Green() >> 3) << 5) || + ((c.Blue() >> 3) << 10); + } + else + // kind of an unintuitive way to turn it off... + customBackdropColor = -1; } - protected: - ColorView *cv; - PixView *bpv, *spv; - u8 colbmp[16*16*3*2]; - wxControl *addr, *val; +protected: + ColorView* cv; + PixView* bpv, *spv; + u8 colbmp[16 * 16 * 3 * 2]; + wxControl* addr, *val; DECLARE_EVENT_TABLE() - }; +}; - BEGIN_EVENT_TABLE(PaletteViewer, Viewer) +BEGIN_EVENT_TABLE(PaletteViewer, Viewer) EVT_BUTTON(XRCID("SaveBG"), PaletteViewer::SaveBG) EVT_BUTTON(XRCID("SaveOBJ"), PaletteViewer::SaveOBJ) EVT_BUTTON(XRCID("ChangeBackdrop"), PaletteViewer::ChangeBackdrop) EVT_GFX_CLICK(XRCID("Background"), PaletteViewer::SelBG) EVT_GFX_CLICK(XRCID("Sprite"), PaletteViewer::SelSprite) - END_EVENT_TABLE() +END_EVENT_TABLE() - class GBPaletteViewer : public Viewer - { - public: +class GBPaletteViewer : public Viewer +{ +public: GBPaletteViewer() : Viewer(wxT("GBPaletteViewer")) { - colorctrl(cv, "Color"); - pixview(bpv, "Background", 4, 8, cv); - pixview(spv, "Sprite", 4, 8, cv); - getlab(idx, "Index", "3W"); - getlab(val, "Value", "0xWWWW"); - Fit(); - Update(); + colorctrl(cv, "Color"); + pixview(bpv, "Background", 4, 8, cv); + pixview(spv, "Sprite", 4, 8, cv); + getlab(idx, "Index", "3W"); + getlab(val, "Value", "0xWWWW"); + Fit(); + Update(); } void Update() { - u16 *pp = gbPalette; - u8 *bmp = colbmp; - for(int i = 0; i < 64; i++, pp++) { - *bmp++ = (*pp & 0x1f) << 3; - *bmp++ = (*pp & 0x3e0) >> 2; - *bmp++ = (*pp & 0x7c00) >> 7; - } - bpv->SetData(colbmp, 4, 0, 0); - spv->SetData(colbmp + 4*8*3, 4, 0, 0); - ShowSel(); + u16* pp = gbPalette; + u8* bmp = colbmp; + + for (int i = 0; i < 64; i++, pp++) + { + *bmp++ = (*pp & 0x1f) << 3; + *bmp++ = (*pp & 0x3e0) >> 2; + *bmp++ = (*pp & 0x7c00) >> 7; + } + + bpv->SetData(colbmp, 4, 0, 0); + spv->SetData(colbmp + 4 * 8 * 3, 4, 0, 0); + ShowSel(); } void SelBG(wxMouseEvent &ev) { - spv->SetSel(-1, -1, false); - ShowSel(); + spv->SetSel(-1, -1, false); + ShowSel(); } void SelSprite(wxMouseEvent &ev) { - bpv->SetSel(-1, -1, false); - ShowSel(); + bpv->SetSel(-1, -1, false); + ShowSel(); } void ShowSel() { - int x, y; - bool isbg = true; - bpv->GetSel(x, y); - if(x < 0) { - isbg = false; - spv->GetSel(x, y); - if(x < 0) { - idx->SetLabel(wxEmptyString); - val->SetLabel(wxEmptyString); - return; + int x, y; + bool isbg = true; + bpv->GetSel(x, y); + + if (x < 0) + { + isbg = false; + spv->GetSel(x, y); + + if (x < 0) + { + idx->SetLabel(wxEmptyString); + val->SetLabel(wxEmptyString); + return; + } } - } - u8 *pix = &colbmp[(x + y * 4) * 3]; - if(isbg) - pix += 4 * 8 * 3; - u16 v = (pix[0] >> 3) + ((pix[1] >> 3) << 5) + ((pix[2] >> 3) << 10); - wxString s; - s.Printf(wxT("0x%04X"), (int)v); - val->SetLabel(s); - s.Printf(wxT("%d"), x + y * 4); - idx->SetLabel(s); + + u8* pix = &colbmp[(x + y * 4) * 3]; + + if (isbg) + pix += 4 * 8 * 3; + + u16 v = (pix[0] >> 3) + ((pix[1] >> 3) << 5) + ((pix[2] >> 3) << 10); + wxString s; + s.Printf(wxT("0x%04X"), (int)v); + val->SetLabel(s); + s.Printf(wxT("%d"), x + y * 4); + idx->SetLabel(s); } void SaveBG(wxCommandEvent &ev) { - savepal(this, colbmp, 4 * 8, wxT("bg")); + savepal(this, colbmp, 4 * 8, wxT("bg")); } void SaveOBJ(wxCommandEvent &ev) { - savepal(this, colbmp + 4 * 8 * 3, 4 * 8, wxT("obj")); + savepal(this, colbmp + 4 * 8 * 3, 4 * 8, wxT("obj")); } - protected: - ColorView *cv; - PixView *bpv, *spv; - u8 colbmp[4*8*3*2]; - wxControl *idx, *val; +protected: + ColorView* cv; + PixView* bpv, *spv; + u8 colbmp[4 * 8 * 3 * 2]; + wxControl* idx, *val; DECLARE_EVENT_TABLE() - }; +}; - BEGIN_EVENT_TABLE(GBPaletteViewer, Viewer) +BEGIN_EVENT_TABLE(GBPaletteViewer, Viewer) EVT_BUTTON(XRCID("SaveBG"), GBPaletteViewer::SaveBG) EVT_BUTTON(XRCID("SaveOBJ"), GBPaletteViewer::SaveOBJ) EVT_GFX_CLICK(XRCID("Background"), GBPaletteViewer::SelBG) EVT_GFX_CLICK(XRCID("Sprite"), GBPaletteViewer::SelSprite) - END_EVENT_TABLE() +END_EVENT_TABLE() } void MainFrame::PaletteViewer() { - switch(panel->game_type()) { - case IMAGE_GBA: - LoadXRCViewer(Palette); - break; - case IMAGE_GB: - LoadXRCViewer(GBPalette); - break; - } + switch (panel->game_type()) + { + case IMAGE_GBA: + LoadXRCViewer(Palette); + break; + + case IMAGE_GB: + LoadXRCViewer(GBPalette); + break; + } } -namespace Viewers { - class TileViewer : public GfxViewer - { - public: - TileViewer() : GfxViewer(wxT("TileViewer"), 32*8, 32*8) +namespace Viewers +{ +class TileViewer : public GfxViewer +{ +public: + TileViewer() : GfxViewer(wxT("TileViewer"), 32 * 8, 32 * 8) { - is256 = charbase = 0; - getradio(,"Color16", is256, 0); - getradio(,"Color256", is256, 1); - getradio(,"CharBase0", charbase, 0); - getradio(,"CharBase1", charbase, 0x4000); - getradio(,"CharBase2", charbase, 0x8000); - getradio(,"CharBase3", charbase, 0xc000); - getradio(,"CharBase4", charbase, 0x10000); - getslider(,"Palette", palette); - getlab(tileno, "Tile", "1WWW"); - getlab(addr, "Address", "06WWWWWW"); - selx = sely = -1; - Fit(); - Update(); + is256 = charbase = 0; + getradio(, "Color16", is256, 0); + getradio(, "Color256", is256, 1); + getradio(, "CharBase0", charbase, 0); + getradio(, "CharBase1", charbase, 0x4000); + getradio(, "CharBase2", charbase, 0x8000); + getradio(, "CharBase3", charbase, 0xc000); + getradio(, "CharBase4", charbase, 0x10000); + getslider(, "Palette", palette); + getlab(tileno, "Tile", "1WWW"); + getlab(addr, "Address", "06WWWWWW"); + selx = sely = -1; + Fit(); + Update(); } void Update() { - // Following copied almost verbatim from TileView.cpp - u16 *palette = (u16 *)paletteRAM; - u8 *charBase = &vram[charbase]; + // Following copied almost verbatim from TileView.cpp + u16* palette = (u16*)paletteRAM; + u8* charBase = &vram[charbase]; + int maxY; - int maxY; + if (is256) + { + int tile = 0; + maxY = 16; - if(is256) { - int tile = 0; - maxY = 16; - for(int y = 0; y < maxY; y++) { - for(int x = 0; x < 32; x++) { - if(charbase == 4 * 0x4000) - render256(tile, x, y, charBase, &palette[256]); - else - render256(tile, x, y, charBase, palette); - tile++; - } + for (int y = 0; y < maxY; y++) + { + for (int x = 0; x < 32; x++) + { + if (charbase == 4 * 0x4000) + render256(tile, x, y, charBase, &palette[256]); + else + render256(tile, x, y, charBase, palette); + + tile++; + } + } + + BMPSize(32 * 8, maxY * 8); } - BMPSize(32*8, maxY*8); - } else { - int tile = 0; - maxY = 32; - if(charbase == 3 * 0x4000) - maxY = 16; - for(int y = 0; y < maxY; y++) { - for(int x = 0; x < 32; x++) { - render16(tile, x, y, charBase, palette); - tile++; - } + else + { + int tile = 0; + maxY = 32; + + if (charbase == 3 * 0x4000) + maxY = 16; + + for (int y = 0; y < maxY; y++) + { + for (int x = 0; x < 32; x++) + { + render16(tile, x, y, charBase, palette); + tile++; + } + } + + BMPSize(32 * 8, maxY * 8); } - BMPSize(32*8, maxY*8); - } - ChangeBMP(); - UpdateMouseInfo(); + + ChangeBMP(); + UpdateMouseInfo(); } void UpdateMouseInfoEv(wxMouseEvent &ev) { - selx = ev.GetX(); - sely = ev.GetY(); - UpdateMouseInfo(); + selx = ev.GetX(); + sely = ev.GetY(); + UpdateMouseInfo(); } void UpdateMouseInfo() { - if(selx > gv->bmw || sely > gv->bmh) - selx = sely = -1; - if(selx < 0) { - addr->SetLabel(wxEmptyString); - tileno->SetLabel(wxEmptyString); - } else { - int x = selx / 8; - int y = sely / 8; - int t = 32 * y + x; - if(is256) - t *= 2; - wxString s; - s.Printf(wxT("%d"), t); - tileno->SetLabel(s); - s.Printf(wxT("%08X"), 0x6000000 + charbase + 32 * t); - addr->SetLabel(s); - } + if (selx > gv->bmw || sely > gv->bmh) + selx = sely = -1; + + if (selx < 0) + { + addr->SetLabel(wxEmptyString); + tileno->SetLabel(wxEmptyString); + } + else + { + int x = selx / 8; + int y = sely / 8; + int t = 32 * y + x; + + if (is256) + t *= 2; + + wxString s; + s.Printf(wxT("%d"), t); + tileno->SetLabel(s); + s.Printf(wxT("%08X"), 0x6000000 + charbase + 32 * t); + addr->SetLabel(s); + } } // following 2 functions copied almost verbatim from TileView.cpp - void render256(int tile, int x, int y, u8 *charBase, u16 *palette) + void render256(int tile, int x, int y, u8* charBase, u16* palette) { - u8 *bmp = &image.GetData()[24*x + 8*32*24*y]; + u8* bmp = &image.GetData()[24 * x + 8 * 32 * 24 * y]; - for(int j = 0; j < 8; j++) { - for(int i = 0; i < 8; i++) { - u8 c = charBase[tile*64 + j * 8 + i]; - - u16 color = palette[c]; - - *bmp++ = (color & 0x1f) << 3; - *bmp++ = ((color >> 5) & 0x1f) << 3; - *bmp++ = ((color >> 10) & 0x1f) << 3; + for (int j = 0; j < 8; j++) + { + for (int i = 0; i < 8; i++) + { + u8 c = charBase[tile * 64 + j * 8 + i]; + u16 color = palette[c]; + *bmp++ = (color & 0x1f) << 3; + *bmp++ = ((color >> 5) & 0x1f) << 3; + *bmp++ = ((color >> 10) & 0x1f) << 3; + } + bmp += 31 * 24; // advance line } - bmp += 31*24; // advance line - } } - void render16(int tile, int x, int y, u8 *charBase, u16 *palette) + void render16(int tile, int x, int y, u8* charBase, u16* palette) { - u8 *bmp = &image.GetData()[24*x + 8*32*24*y]; + u8* bmp = &image.GetData()[24 * x + 8 * 32 * 24 * y]; + int pal = this->palette; - int pal = this->palette; + if (this->charbase == 4 * 0x4000) + pal += 16; - if(this->charbase == 4 * 0x4000) - pal += 16; + for (int j = 0; j < 8; j++) + { + for (int i = 0; i < 8; i++) + { + u8 c = charBase[tile * 32 + j * 4 + (i >> 1)]; - for(int j = 0; j < 8; j++) { - for(int i = 0; i < 8; i++) { - u8 c = charBase[tile*32 + j * 4 + (i>>1)]; + if (i & 1) + c = c >> 4; + else + c = c & 15; - if(i & 1) - c = c>>4; - else - c = c & 15; + u16 color = palette[pal * 16 + c]; + *bmp++ = (color & 0x1f) << 3; + *bmp++ = ((color >> 5) & 0x1f) << 3; + *bmp++ = ((color >> 10) & 0x1f) << 3; + } - u16 color = palette[pal*16+c]; - - *bmp++ = (color & 0x1f) << 3; - *bmp++ = ((color >> 5) & 0x1f) << 3; - *bmp++ = ((color >> 10) & 0x1f) << 3; + bmp += 31 * 24; // advance line } - bmp += 31*24; // advance line - } } - protected: +protected: int charbase, is256, palette; - wxControl *tileno, *addr; + wxControl* tileno, *addr; int selx, sely; DECLARE_EVENT_TABLE() - }; +}; - BEGIN_EVENT_TABLE(TileViewer, GfxViewer) +BEGIN_EVENT_TABLE(TileViewer, GfxViewer) EVT_GFX_CLICK(wxID_ANY, TileViewer::UpdateMouseInfoEv) - END_EVENT_TABLE() +END_EVENT_TABLE() - class GBTileViewer : public GfxViewer - { - public: - GBTileViewer() : GfxViewer(wxT("GBTileViewer"), 16*8, 16*8) +class GBTileViewer : public GfxViewer +{ +public: + GBTileViewer() : GfxViewer(wxT("GBTileViewer"), 16 * 8, 16 * 8) { - bank = charbase = 0; - getradio(,"Bank0", bank, 0); - getradio(,"Bank1", bank, 0x2000); - getradio(,"CharBase0", charbase, 0); - getradio(,"CharBase1", charbase, 0x800); - getslider(,"Palette", palette); - getlab(tileno, "Tile", "2WW"); - getlab(addr, "Address", "WWWW"); - selx = sely = -1; - Fit(); - Update(); + bank = charbase = 0; + getradio(, "Bank0", bank, 0); + getradio(, "Bank1", bank, 0x2000); + getradio(, "CharBase0", charbase, 0); + getradio(, "CharBase1", charbase, 0x800); + getslider(, "Palette", palette); + getlab(tileno, "Tile", "2WW"); + getlab(addr, "Address", "WWWW"); + selx = sely = -1; + Fit(); + Update(); } void Update() { - // following copied almost verbatim from GBTileView.cpp - u8 *charBase = (gbVram != NULL) ? - &gbVram[bank+charbase] : - &gbMemory[0x8000+charbase]; + // following copied almost verbatim from GBTileView.cpp + u8* charBase = (gbVram != NULL) ? + &gbVram[bank + charbase] : + &gbMemory[0x8000 + charbase]; + int tile = 0; - int tile = 0; - for(int y = 0; y < 16; y++) { - for(int x = 0; x < 16; x++) { - render(tile, x, y, charBase); - tile++; + for (int y = 0; y < 16; y++) + { + for (int x = 0; x < 16; x++) + { + render(tile, x, y, charBase); + tile++; + } } - } - ChangeBMP(); - UpdateMouseInfo(); + + ChangeBMP(); + UpdateMouseInfo(); } void UpdateMouseInfoEv(wxMouseEvent &ev) { - selx = ev.GetX(); - sely = ev.GetY(); - UpdateMouseInfo(); + selx = ev.GetX(); + sely = ev.GetY(); + UpdateMouseInfo(); } void UpdateMouseInfo() { - if(selx > gv->bmw || sely > gv->bmh) - selx = sely = -1; - if(selx < 0) { - addr->SetLabel(wxEmptyString); - tileno->SetLabel(wxEmptyString); - } else { - int x = selx / 8; - int y = sely / 8; - int t = 16 * y + x; - wxString s; - s.Printf(wxT("%d"), t); - tileno->SetLabel(s); - s.Printf(wxT("%04X"), 0x8000 + charbase + 16 * t); - addr->SetLabel(s); - } + if (selx > gv->bmw || sely > gv->bmh) + selx = sely = -1; + + if (selx < 0) + { + addr->SetLabel(wxEmptyString); + tileno->SetLabel(wxEmptyString); + } + else + { + int x = selx / 8; + int y = sely / 8; + int t = 16 * y + x; + wxString s; + s.Printf(wxT("%d"), t); + tileno->SetLabel(s); + s.Printf(wxT("%04X"), 0x8000 + charbase + 16 * t); + addr->SetLabel(s); + } } // following function copied almost verbatim from GBTileView.cpp - void render(int tile, int x, int y, u8 *charBase) + void render(int tile, int x, int y, u8* charBase) { - u8 *bmp = &image.GetData()[24*x + 8*16*24*y]; + u8* bmp = &image.GetData()[24 * x + 8 * 16 * 24 * y]; - for(int j = 0; j < 8; j++) { - u8 mask = 0x80; - u8 tile_a = charBase[tile*16+j*2]; - u8 tile_b = charBase[tile*16+j*2+1]; + for (int j = 0; j < 8; j++) + { + u8 mask = 0x80; + u8 tile_a = charBase[tile * 16 + j * 2]; + u8 tile_b = charBase[tile * 16 + j * 2 + 1]; - for(int i = 0; i < 8; i++) { - u8 c = (tile_a & mask) ? 1 : 0; - c += ((tile_b & mask) ? 2 : 0); + for (int i = 0; i < 8; i++) + { + u8 c = (tile_a & mask) ? 1 : 0; + c += ((tile_b & mask) ? 2 : 0); - if(gbCgbMode) { - c = c + palette*4; - } else { - c = gbBgp[c]; - } + if (gbCgbMode) + { + c = c + palette * 4; + } + else + { + c = gbBgp[c]; + } - u16 color = gbPalette[c]; + u16 color = gbPalette[c]; + *bmp++ = (color & 0x1f) << 3; + *bmp++ = ((color >> 5) & 0x1f) << 3; + *bmp++ = ((color >> 10) & 0x1f) << 3; + mask >>= 1; + } - *bmp++ = (color & 0x1f) << 3; - *bmp++ = ((color >> 5) & 0x1f) << 3; - *bmp++ = ((color >> 10) & 0x1f) << 3; - - mask >>= 1; + bmp += 15 * 24; // advance line } - bmp += 15*24; // advance line - } } - protected: +protected: int bank, charbase, palette; - wxControl *addr, *tileno; + wxControl* addr, *tileno; int selx, sely; DECLARE_EVENT_TABLE() - }; +}; - BEGIN_EVENT_TABLE(GBTileViewer, GfxViewer) +BEGIN_EVENT_TABLE(GBTileViewer, GfxViewer) EVT_GFX_CLICK(wxID_ANY, GBTileViewer::UpdateMouseInfoEv) - END_EVENT_TABLE() +END_EVENT_TABLE() } void MainFrame::TileViewer() { - switch(panel->game_type()) { - case IMAGE_GBA: - LoadXRCViewer(Tile); - break; - case IMAGE_GB: - LoadXRCViewer(GBTile); - break; - } + switch (panel->game_type()) + { + case IMAGE_GBA: + LoadXRCViewer(Tile); + break; + + case IMAGE_GB: + LoadXRCViewer(GBTile); + break; + } } diff --git a/src/wx/guiinit.cpp b/src/wx/guiinit.cpp index a4920e7a..07aeb1a9 100644 --- a/src/wx/guiinit.cpp +++ b/src/wx/guiinit.cpp @@ -35,12 +35,13 @@ const // this is supposed to happen automatically if a parent is marked recursive // but some dialogs don't do it (propertydialog?) // so go ahead and mark all dialogs for fully recursive validation -static void mark_recursive(wxWindowBase *w) +static void mark_recursive(wxWindowBase* w) { - w->SetExtraStyle(w->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY); - wxWindowList l = w->GetChildren(); - for(wxWindowList::iterator ch = l.begin(); ch != l.end(); ch++) - mark_recursive(*ch); + w->SetExtraStyle(w->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY); + wxWindowList l = w->GetChildren(); + + for (wxWindowList::iterator ch = l.begin(); ch != l.end(); ch++) + mark_recursive(*ch); } #if (wxMAJOR_VERSION < 3) @@ -48,7 +49,7 @@ static void mark_recursive(wxWindowBase *w) wxStaticCast(wxGetApp().frame->FindWindow(XRCID(n)), wxDialog) #else #define GetXRCDialog(n) \ - wxStaticCast(wxGetApp().frame->FindWindowByName(n), wxDialog) + wxStaticCast(wxGetApp().frame->FindWindowByName(n), wxDialog) #endif // Event handlers must be methods of wxEvtHandler-derived objects @@ -58,103 +59,107 @@ static void mark_recursive(wxWindowBase *w) static class NetLink_t : public wxEvtHandler { public: - wxDialog *dlg; - int n_players; - bool server; - NetLink_t() : n_players(2), server(false) {} - wxButton *okb; - void ServerOKButton(wxCommandEvent &ev) - { + wxDialog* dlg; + int n_players; + bool server; + NetLink_t() : n_players(2), server(false) {} + wxButton* okb; + void ServerOKButton(wxCommandEvent &ev) + { okb->SetLabel(_("Start!")); - } - void ClientOKButton(wxCommandEvent &ev) - { + } + void ClientOKButton(wxCommandEvent &ev) + { okb->SetLabel(_("Connect")); - } - // attached to OK, so skip when OK - void NetConnect(wxCommandEvent &ev) - { + } + // attached to OK, so skip when OK + void NetConnect(wxCommandEvent &ev) + { static const int length = 256; - if(!dlg->Validate() || !dlg->TransferDataFromWindow()) + + if (!dlg->Validate() || !dlg->TransferDataFromWindow()) return; - if (!server) + if (!server) { bool valid = SetLinkServerHost(gopts.link_host.mb_str()); + if (!valid) { wxMessageBox(_("You must enter a valid host name"), - _("Host name invalid"), wxICON_ERROR | wxOK); + _("Host name invalid"), wxICON_ERROR | wxOK); return; } } linkNumPlayers = n_players; - update_opts(); // save fast flag and client host - // Close any previous link CloseLink(); - wxString connmsg; wxString title; - SetLinkTimeout(linkTimeout); EnableSpeedHacks(linkHacks); EnableLinkServer(server, linkNumPlayers - 1); - if (server) { + if (server) + { char host[length]; GetLinkServerHost(host, length); - title.Printf(_("Waiting for clients...")); connmsg.Printf(_("Server IP address is: %s\n"), wxString(host, wxConvLibc).c_str()); - } else { + } + else + { title.Printf(_("Waiting for connection...")); connmsg.Printf(_("Connecting to %s\n"), gopts.link_host.c_str()); } // Init link - MainFrame *mf = wxGetApp().frame; + MainFrame* mf = wxGetApp().frame; ConnectionState state = InitLink(mf->GetConfiguredLinkMode()); // Display a progress dialog while the connection is establishing - if (state == LINK_NEEDS_UPDATE) { + if (state == LINK_NEEDS_UPDATE) + { wxProgressDialog pdlg(title, connmsg, - 100, dlg, wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME); + 100, dlg, wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME); - while (state == LINK_NEEDS_UPDATE) { + while (state == LINK_NEEDS_UPDATE) + { // Ask the core for updates char message[length]; state = ConnectLinkUpdate(message, length); - connmsg = wxString(message, wxConvLibc); // Does the user want to abort? - if (!pdlg.Pulse(connmsg)) { + if (!pdlg.Pulse(connmsg)) + { state = LINK_ABORT; } } } // The user canceled the connection attempt - if (state == LINK_ABORT) { + if (state == LINK_ABORT) + { CloseLink(); } // Something failed during init - if (state == LINK_ERROR) { + if (state == LINK_ERROR) + { CloseLink(); wxLogError(_("Error occurred.\nPlease try again.")); } - if(GetLinkMode() != LINK_DISCONNECTED) { + if (GetLinkMode() != LINK_DISCONNECTED) + { connmsg.Replace(wxT("\n"), wxT(" ")); systemScreenMessage(connmsg); - ev.Skip(); // all OK } - } + } } net_link_handler; #endif @@ -162,475 +167,591 @@ public: static class CheatList_t : public wxEvtHandler { public: - wxDialog *dlg; - wxCheckedListCtrl *list; - wxListItem item0, item1; - int col1minw; - wxString cheatdir, cheatfn, deffn; - bool isgb; - bool *dirty; + wxDialog* dlg; + wxCheckedListCtrl* list; + wxListItem item0, item1; + int col1minw; + wxString cheatdir, cheatfn, deffn; + bool isgb; + bool* dirty; - // add/edit dialog - wxString ce_desc; - wxString ce_codes; - wxChoice *ce_type_ch; - wxControl *ce_codes_tc; - int ce_type; + // add/edit dialog + wxString ce_desc; + wxString ce_codes; + wxChoice* ce_type_ch; + wxControl* ce_codes_tc; + int ce_type; - void Reload() - { + void Reload() + { list->DeleteAllItems(); Reload(0); - } - - void Reload(int start) - { - if(isgb) { - for(int i = start; i < gbCheatNumber; i++) { - item0.SetId(i); - item0.SetText(wxString(gbCheatList[i].cheatCode, wxConvLibc)); - list->InsertItem(item0); - item1.SetId(i); - item1.SetText(wxString(gbCheatList[i].cheatDesc, wxConvUTF8)); - list->SetItem(item1); - list->Check(i, gbCheatList[i].enabled); - } - } else { - for(int i = start; i < cheatsNumber; i++) { - item0.SetId(i); - item0.SetText(wxString(cheatsList[i].codestring, wxConvLibc)); - list->InsertItem(item0); - item1.SetId(i); - item1.SetText(wxString(cheatsList[i].desc, wxConvUTF8)); - list->SetItem(item1); - list->Check(i, cheatsList[i].enabled); - } } - AdjustDescWidth(); - } - void Tool(wxCommandEvent &ev) - { - switch(ev.GetId()) { - case wxID_OPEN: - { + void Reload(int start) + { + if (isgb) + { + for (int i = start; i < gbCheatNumber; i++) + { + item0.SetId(i); + item0.SetText(wxString(gbCheatList[i].cheatCode, wxConvLibc)); + list->InsertItem(item0); + item1.SetId(i); + item1.SetText(wxString(gbCheatList[i].cheatDesc, wxConvUTF8)); + list->SetItem(item1); + list->Check(i, gbCheatList[i].enabled); + } + } + else + { + for (int i = start; i < cheatsNumber; i++) + { + item0.SetId(i); + item0.SetText(wxString(cheatsList[i].codestring, wxConvLibc)); + list->InsertItem(item0); + item1.SetId(i); + item1.SetText(wxString(cheatsList[i].desc, wxConvUTF8)); + list->SetItem(item1); + list->Check(i, cheatsList[i].enabled); + } + } + + AdjustDescWidth(); + } + + void Tool(wxCommandEvent &ev) + { + switch (ev.GetId()) + { + case wxID_OPEN: + { wxFileDialog subdlg(dlg, _("Select cheat file"), cheatdir, - cheatfn, _("VBA cheat lists (*.clt)|*.clt"), - wxFD_OPEN|wxFD_FILE_MUST_EXIST); + cheatfn, _("VBA cheat lists (*.clt)|*.clt"), + wxFD_OPEN | wxFD_FILE_MUST_EXIST); int ret = subdlg.ShowModal(); cheatdir = subdlg.GetDirectory(); cheatfn = subdlg.GetPath(); - if(ret != wxID_OK) + + if (ret != wxID_OK) break; + bool cld; - if(isgb) + + if (isgb) cld = gbCheatsLoadCheatList(cheatfn.mb_fn_str()); else cld = cheatsLoadCheatList(cheatfn.mb_fn_str()); - if(cld) { + + if (cld) + { *dirty = cheatfn != deffn; systemScreenMessage(_("Loaded cheats")); - } else + } + else *dirty = true; // attempted load always clears + Reload(); } break; - case wxID_SAVE: - { + + case wxID_SAVE: + { wxFileDialog subdlg(dlg, _("Select cheat file"), cheatdir, - cheatfn, _("VBA cheat lists (*.clt)|*.clt"), - wxFD_SAVE|wxFD_OVERWRITE_PROMPT); + cheatfn, _("VBA cheat lists (*.clt)|*.clt"), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT); int ret = subdlg.ShowModal(); cheatdir = subdlg.GetDirectory(); cheatfn = subdlg.GetPath(); - if(ret != wxID_OK) + + if (ret != wxID_OK) break; + // note that there is no way to test for succes of save - if(isgb) + if (isgb) gbCheatsSaveCheatList(cheatfn.mb_fn_str()); else cheatsSaveCheatList(cheatfn.mb_fn_str()); - if(cheatfn == deffn) + + if (cheatfn == deffn) *dirty = false; + systemScreenMessage(_("Saved cheats")); - } - break; - case wxID_ADD: - { + } + break; + + case wxID_ADD: + { int ncheats = isgb ? gbCheatNumber : cheatsNumber; ce_codes = wxEmptyString; - wxDialog *subdlg = GetXRCDialog("CheatEdit"); + wxDialog* subdlg = GetXRCDialog("CheatEdit"); subdlg->ShowModal(); AddCheat(); Reload(ncheats); - } - break; - case wxID_REMOVE: - { + } + break; + + case wxID_REMOVE: + { bool asked = false, restore; - for(int i = list->GetItemCount() - 1; i >= 0; i--) - if(list->GetItemState(i, wxLIST_STATE_SELECTED)) { - list->DeleteItem(i); - if(isgb) - gbCheatRemove(i); - else { - if(!asked) { - asked = true; - restore = wxMessageBox(_("Restore old values?"), - _("Removing cheats"), - wxYES_NO|wxICON_QUESTION) == wxYES; + + for (int i = list->GetItemCount() - 1; i >= 0; i--) + if (list->GetItemState(i, wxLIST_STATE_SELECTED)) + { + list->DeleteItem(i); + + if (isgb) + gbCheatRemove(i); + else + { + if (!asked) + { + asked = true; + restore = wxMessageBox(_("Restore old values?"), + _("Removing cheats"), + wxYES_NO | wxICON_QUESTION) == wxYES; + } + + cheatsDelete(i, restore); } - cheatsDelete(i, restore); } - } - } - break; - case wxID_CLEAR: - if(isgb) { - if(gbCheatNumber) { - *dirty = true; - gbCheatRemoveAll(); - } - } else { - if(cheatsNumber) { - bool restore = wxMessageBox(_("Restore old values?"), - _("Removing cheats"), - wxYES_NO|wxICON_QUESTION) == wxYES; - *dirty = true; - cheatsDeleteAll(restore); - } - } - Reload(); - break; - case wxID_SELECTALL: - // FIXME: probably ought to limit to selected items if any items - // are selected - *dirty = true; - if(isgb) { - int i; - for(i = 0; i < gbCheatNumber; i++) - if(!gbCheatList[i].enabled) - break; - if(i < gbCheatNumber) - for(; i < gbCheatNumber; i++) { - gbCheatEnable(i); - list->Check(i, true); + } + break; + + case wxID_CLEAR: + if (isgb) + { + if (gbCheatNumber) + { + *dirty = true; + gbCheatRemoveAll(); } + } else - for(i = 0; i < gbCheatNumber; i++) { - gbCheatDisable(i); - list->Check(i, false); + { + if (cheatsNumber) + { + bool restore = wxMessageBox(_("Restore old values?"), + _("Removing cheats"), + wxYES_NO | wxICON_QUESTION) == wxYES; + *dirty = true; + cheatsDeleteAll(restore); } - } else { - int i; - for(i = 0; i < cheatsNumber; i++) - if(!cheatsList[i].enabled) - break; - if(i < cheatsNumber) - for(; i < cheatsNumber; i++) { - cheatsEnable(i); - list->Check(i, true); - } - else - for(i = 0; i < cheatsNumber; i++) { - cheatsDisable(i); - list->Check(i, false); - } - } - break; - } - } - - void Check(wxListEvent &ev) - { - int ch = ev.GetIndex(); - if(isgb) { - if(!gbCheatList[ch].enabled) { - gbCheatEnable(ev.GetIndex()); - *dirty = true; - } - } else { - if(!cheatsList[ch].enabled) { - cheatsEnable(ev.GetIndex()); - *dirty = true; - } - } - } - - void UnCheck(wxListEvent &ev) - { - int ch = ev.GetIndex(); - if(isgb) { - if(gbCheatList[ch].enabled) { - gbCheatDisable(ev.GetIndex()); - *dirty = true; - } - } else { - if(cheatsList[ch].enabled) { - cheatsDisable(ev.GetIndex()); - *dirty = true; - } - } - } - - void AddCheat() - { - wxStringTokenizer tk(ce_codes.MakeUpper()); - while(tk.HasMoreTokens()) { - wxString tok = tk.GetNextToken(); - if(isgb) { - if(!ce_type) - gbAddGsCheat(tok.mb_str(), ce_desc.mb_str()); - else - gbAddGgCheat(tok.mb_str(), ce_desc.mb_str()); - } else { - if(!ce_type) - cheatsAddCheatCode(tok.mb_str(), ce_desc.mb_str()); - // following determination of type by lengths is - // same used by win32 and gtk code - // and like win32/gtk code, user-chosen fmt is ignored - else if(tok.size() == 12) { - tok = tok.substr(0, 8) + wxT(' ') + tok.substr(8); - cheatsAddCBACode(tok.mb_str(), ce_desc.mb_str()); - } else if(tok.size() == 16) - // not sure why 1-tok is !v3 and 2-tok is v3.. - cheatsAddGSACode(tok.mb_str(), ce_desc.mb_str(), false); - // CBA codes are assumed to be N+4, and anything else - // is assumed to be GSA v3 (although I assume the - // actual formats should be 8+4 and 8+8) - else { - if(!tk.HasMoreTokens()) { - // throw an error appropriate to chosen type - if(ce_type == 1) // GSA - cheatsAddGSACode(tok.mb_str(), ce_desc.mb_str(), false); - else - cheatsAddCBACode(tok.mb_str(), ce_desc.mb_str()); - } else { - wxString tok2 = tk.GetNextToken(); - if(tok2.size() == 4) { - tok += wxT(' ') + tok2; - cheatsAddCBACode(tok.mb_str(), ce_desc.mb_str()); - } else { - tok += tok2; - cheatsAddGSACode(tok.mb_str(), ce_desc.mb_str(), true); } - } - } - } - } - } - void Edit(wxListEvent &ev) - { - int id = ev.GetIndex(); + Reload(); + break; - // GetItem() followed by GetText doesn't work, so retrieve from - // source - wxString odesc, ocode; - bool ochecked; - int otype; - if(isgb) { - ochecked = gbCheatList[id].enabled; - ce_codes = ocode = wxString(gbCheatList[id].cheatCode, wxConvLibc); - ce_desc = odesc = wxString(gbCheatList[id].cheatDesc, wxConvUTF8); - if(ce_codes.find(wxT('-')) == wxString::npos) - otype = ce_type = 0; - else - otype = ce_type = 1; - } else { - ochecked = cheatsList[id].enabled; - ce_codes = ocode = wxString(cheatsList[id].codestring, wxConvLibc); - ce_desc = odesc = wxString(cheatsList[id].desc, wxConvUTF8); - if(ce_codes.find(wxT(':')) != wxString::npos) - otype = ce_type = 0; - else if(ce_codes.find(wxT(' ')) == wxString::npos) - otype = ce_type = 1; - else - otype = ce_type = 2; - } - wxDialog *subdlg = GetXRCDialog("CheatEdit"); - if(subdlg->ShowModal() != wxID_OK) - return; - if(otype != ce_type || ocode != ce_codes) { - // vba core certainly doesn't make this easy - // there is no "change" function, so the only way to retain - // the old order is to delete this and all subsequent items, and - // then re-add them - // The MFC code got around this by not even supporting edits on - // gba codes (which have order dependencies) and just forcing - // edited codes to the rear on gb codes. - // It might be safest to only support desc edits, and force the - // user to re-enter codes to change them - int ncodes = isgb ? gbCheatNumber : cheatsNumber; - if(ncodes > id + 1) { - wxString codes[100]; - wxString descs[100]; - bool checked[100]; - bool v3[100]; - for(int i = id + 1; i < ncodes; i++) { - codes[i - id - 1] = wxString(isgb ? - gbCheatList[i].cheatCode : - cheatsList[i].codestring, - wxConvLibc); - descs[i - id - 1] = wxString(isgb ? - gbCheatList[i].cheatDesc : - cheatsList[i].desc, - wxConvUTF8); - checked[i - id - 1] = isgb ? gbCheatList[i].enabled : - cheatsList[i].enabled; - v3[i - id - 1] = isgb ? false : cheatsList[i].code == 257; - } - for(int i = ncodes - 1; i >= id; i--) { - list->DeleteItem(i); - if(isgb) - gbCheatRemove(i); - else - cheatsDelete(i, cheatsList[i].enabled); - } - AddCheat(); - if(!ochecked) { - if(isgb) - gbCheatDisable(id); - else - cheatsDisable(id); - } - for(int i = id + 1; i < ncodes; i++) { - ce_codes = codes[i - id - 1]; - ce_desc = descs[i - id - 1]; - if(isgb) - { - if(ce_codes.find(wxT('-')) == wxString::npos) - ce_type = 0; - else - ce_type = 1; - } - else - { - if(ce_codes.find(wxT(':')) != wxString::npos) - ce_type = 0; - else if(ce_codes.find(wxT(' ')) == wxString::npos) - { - ce_type = 1; - if(v3[i - id - 1]) - ce_codes.insert(8, 1, wxT(' ')); - } - else - { - ce_type = 2; - } - } - AddCheat(); - if(!checked[i - id - 1]) - { - if(isgb) - gbCheatDisable(i); - else - cheatsDisable(i); - } - } - } - else - { - list->DeleteItem(id); - if(isgb) - gbCheatRemove(id); - else - cheatsDelete(id, cheatsList[id].enabled); - AddCheat(); - if(!ochecked) { - if(isgb) - gbCheatDisable(id); - else - cheatsDisable(id); - } - } - Reload(id); - } else if(ce_desc != odesc) { - *dirty = true; - char *p = isgb ? gbCheatList[id].cheatDesc : cheatsList[id].desc; - strncpy(p, ce_desc.mb_str(), sizeof(cheatsList[0].desc)); - p[sizeof(cheatsList[0].desc) - 1] = 0; - item1.SetId(id); - item1.SetText(wxString(p, wxConvUTF8)); - list->SetItem(item1); - } - } + case wxID_SELECTALL: + // FIXME: probably ought to limit to selected items if any items + // are selected + *dirty = true; - void AdjustDescWidth() - { - // why is it so hard to get an accurate measurement out of wx? - // on msw, wxLIST_AUTOSIZE might actually be accurate. On wxGTK, - // and probably wxMAC (both of which use generic impl) wrong - // font is used both for rendering (col 0's font) and for - // wxLIST_AUTOSIZE calculation (the widget's font). - // The only way to defeat this is to calculate size manually - // Instead, this just allows user to set max size, and retains - // it. - int ow = list->GetColumnWidth(1); - list->SetColumnWidth(1, wxLIST_AUTOSIZE); - int cw = list->GetColumnWidth(1); - // subtracted in renderer from width avail for text - // but not added in wxLIST_AUTOSIZE - cw += 8; - if(cw < col1minw) - cw = col1minw; - if(cw < ow) - cw = ow; - list->SetColumnWidth(1, cw); - } + if (isgb) + { + int i; + + for (i = 0; i < gbCheatNumber; i++) + if (!gbCheatList[i].enabled) + break; + + if (i < gbCheatNumber) + for (; i < gbCheatNumber; i++) + { + gbCheatEnable(i); + list->Check(i, true); + } + else + for (i = 0; i < gbCheatNumber; i++) + { + gbCheatDisable(i); + list->Check(i, false); + } + } + else + { + int i; + + for (i = 0; i < cheatsNumber; i++) + if (!cheatsList[i].enabled) + break; + + if (i < cheatsNumber) + for (; i < cheatsNumber; i++) + { + cheatsEnable(i); + list->Check(i, true); + } + else + for (i = 0; i < cheatsNumber; i++) + { + cheatsDisable(i); + list->Check(i, false); + } + } + + break; + } + } + + void Check(wxListEvent &ev) + { + int ch = ev.GetIndex(); + + if (isgb) + { + if (!gbCheatList[ch].enabled) + { + gbCheatEnable(ev.GetIndex()); + *dirty = true; + } + } + else + { + if (!cheatsList[ch].enabled) + { + cheatsEnable(ev.GetIndex()); + *dirty = true; + } + } + } + + void UnCheck(wxListEvent &ev) + { + int ch = ev.GetIndex(); + + if (isgb) + { + if (gbCheatList[ch].enabled) + { + gbCheatDisable(ev.GetIndex()); + *dirty = true; + } + } + else + { + if (cheatsList[ch].enabled) + { + cheatsDisable(ev.GetIndex()); + *dirty = true; + } + } + } + + void AddCheat() + { + wxStringTokenizer tk(ce_codes.MakeUpper()); + + while (tk.HasMoreTokens()) + { + wxString tok = tk.GetNextToken(); + + if (isgb) + { + if (!ce_type) + gbAddGsCheat(tok.mb_str(), ce_desc.mb_str()); + else + gbAddGgCheat(tok.mb_str(), ce_desc.mb_str()); + } + else + { + if (!ce_type) + cheatsAddCheatCode(tok.mb_str(), ce_desc.mb_str()); + // following determination of type by lengths is + // same used by win32 and gtk code + // and like win32/gtk code, user-chosen fmt is ignored + else if (tok.size() == 12) + { + tok = tok.substr(0, 8) + wxT(' ') + tok.substr(8); + cheatsAddCBACode(tok.mb_str(), ce_desc.mb_str()); + } + else if (tok.size() == 16) + // not sure why 1-tok is !v3 and 2-tok is v3.. + cheatsAddGSACode(tok.mb_str(), ce_desc.mb_str(), false); + // CBA codes are assumed to be N+4, and anything else + // is assumed to be GSA v3 (although I assume the + // actual formats should be 8+4 and 8+8) + else + { + if (!tk.HasMoreTokens()) + { + // throw an error appropriate to chosen type + if (ce_type == 1) // GSA + cheatsAddGSACode(tok.mb_str(), ce_desc.mb_str(), false); + else + cheatsAddCBACode(tok.mb_str(), ce_desc.mb_str()); + } + else + { + wxString tok2 = tk.GetNextToken(); + + if (tok2.size() == 4) + { + tok += wxT(' ') + tok2; + cheatsAddCBACode(tok.mb_str(), ce_desc.mb_str()); + } + else + { + tok += tok2; + cheatsAddGSACode(tok.mb_str(), ce_desc.mb_str(), true); + } + } + } + } + } + } + + void Edit(wxListEvent &ev) + { + int id = ev.GetIndex(); + // GetItem() followed by GetText doesn't work, so retrieve from + // source + wxString odesc, ocode; + bool ochecked; + int otype; + + if (isgb) + { + ochecked = gbCheatList[id].enabled; + ce_codes = ocode = wxString(gbCheatList[id].cheatCode, wxConvLibc); + ce_desc = odesc = wxString(gbCheatList[id].cheatDesc, wxConvUTF8); + + if (ce_codes.find(wxT('-')) == wxString::npos) + otype = ce_type = 0; + else + otype = ce_type = 1; + } + else + { + ochecked = cheatsList[id].enabled; + ce_codes = ocode = wxString(cheatsList[id].codestring, wxConvLibc); + ce_desc = odesc = wxString(cheatsList[id].desc, wxConvUTF8); + + if (ce_codes.find(wxT(':')) != wxString::npos) + otype = ce_type = 0; + else if (ce_codes.find(wxT(' ')) == wxString::npos) + otype = ce_type = 1; + else + otype = ce_type = 2; + } + + wxDialog* subdlg = GetXRCDialog("CheatEdit"); + + if (subdlg->ShowModal() != wxID_OK) + return; + + if (otype != ce_type || ocode != ce_codes) + { + // vba core certainly doesn't make this easy + // there is no "change" function, so the only way to retain + // the old order is to delete this and all subsequent items, and + // then re-add them + // The MFC code got around this by not even supporting edits on + // gba codes (which have order dependencies) and just forcing + // edited codes to the rear on gb codes. + // It might be safest to only support desc edits, and force the + // user to re-enter codes to change them + int ncodes = isgb ? gbCheatNumber : cheatsNumber; + + if (ncodes > id + 1) + { + wxString codes[100]; + wxString descs[100]; + bool checked[100]; + bool v3[100]; + + for (int i = id + 1; i < ncodes; i++) + { + codes[i - id - 1] = wxString(isgb ? + gbCheatList[i].cheatCode : + cheatsList[i].codestring, + wxConvLibc); + descs[i - id - 1] = wxString(isgb ? + gbCheatList[i].cheatDesc : + cheatsList[i].desc, + wxConvUTF8); + checked[i - id - 1] = isgb ? gbCheatList[i].enabled : + cheatsList[i].enabled; + v3[i - id - 1] = isgb ? false : cheatsList[i].code == 257; + } + + for (int i = ncodes - 1; i >= id; i--) + { + list->DeleteItem(i); + + if (isgb) + gbCheatRemove(i); + else + cheatsDelete(i, cheatsList[i].enabled); + } + + AddCheat(); + + if (!ochecked) + { + if (isgb) + gbCheatDisable(id); + else + cheatsDisable(id); + } + + for (int i = id + 1; i < ncodes; i++) + { + ce_codes = codes[i - id - 1]; + ce_desc = descs[i - id - 1]; + + if (isgb) + { + if (ce_codes.find(wxT('-')) == wxString::npos) + ce_type = 0; + else + ce_type = 1; + } + else + { + if (ce_codes.find(wxT(':')) != wxString::npos) + ce_type = 0; + else if (ce_codes.find(wxT(' ')) == wxString::npos) + { + ce_type = 1; + + if (v3[i - id - 1]) + ce_codes.insert(8, 1, wxT(' ')); + } + else + { + ce_type = 2; + } + } + + AddCheat(); + + if (!checked[i - id - 1]) + { + if (isgb) + gbCheatDisable(i); + else + cheatsDisable(i); + } + } + } + else + { + list->DeleteItem(id); + + if (isgb) + gbCheatRemove(id); + else + cheatsDelete(id, cheatsList[id].enabled); + + AddCheat(); + + if (!ochecked) + { + if (isgb) + gbCheatDisable(id); + else + cheatsDisable(id); + } + } + + Reload(id); + } + else if (ce_desc != odesc) + { + *dirty = true; + char* p = isgb ? gbCheatList[id].cheatDesc : cheatsList[id].desc; + strncpy(p, ce_desc.mb_str(), sizeof(cheatsList[0].desc)); + p[sizeof(cheatsList[0].desc) - 1] = 0; + item1.SetId(id); + item1.SetText(wxString(p, wxConvUTF8)); + list->SetItem(item1); + } + } + + void AdjustDescWidth() + { + // why is it so hard to get an accurate measurement out of wx? + // on msw, wxLIST_AUTOSIZE might actually be accurate. On wxGTK, + // and probably wxMAC (both of which use generic impl) wrong + // font is used both for rendering (col 0's font) and for + // wxLIST_AUTOSIZE calculation (the widget's font). + // The only way to defeat this is to calculate size manually + // Instead, this just allows user to set max size, and retains + // it. + int ow = list->GetColumnWidth(1); + list->SetColumnWidth(1, wxLIST_AUTOSIZE); + int cw = list->GetColumnWidth(1); + // subtracted in renderer from width avail for text + // but not added in wxLIST_AUTOSIZE + cw += 8; + + if (cw < col1minw) + cw = col1minw; + + if (cw < ow) + cw = ow; + + list->SetColumnWidth(1, cw); + } } cheat_list_handler; // onshow handler for above, in the form of an overzealous validator class CheatListFill : public wxValidator { public: - CheatListFill() : wxValidator() {} - CheatListFill(const CheatListFill &e) : wxValidator() {} - wxObject *Clone() const { return new CheatListFill(*this); } - bool TransferFromWindow() { return true; } - bool Validate(wxWindow *p) { return true; } - bool TransferToWindow() { - CheatList_t &clh = cheat_list_handler; - GameArea *panel = wxGetApp().frame->GetPanel(); - clh.isgb = panel->game_type() == IMAGE_GB; - clh.dirty = &panel->cheats_dirty; - clh.cheatfn = panel->game_name() + wxT(".clt"); - clh.cheatdir = panel->game_dir(); - clh.deffn = wxFileName(clh.cheatdir, clh.cheatfn).GetFullPath(); - clh.Reload(); + CheatListFill() : wxValidator() {} + CheatListFill(const CheatListFill &e) : wxValidator() {} + wxObject* Clone() const { return new CheatListFill(*this); } + bool TransferFromWindow() { return true; } + bool Validate(wxWindow* p) { return true; } + bool TransferToWindow() + { + CheatList_t &clh = cheat_list_handler; + GameArea* panel = wxGetApp().frame->GetPanel(); + clh.isgb = panel->game_type() == IMAGE_GB; + clh.dirty = &panel->cheats_dirty; + clh.cheatfn = panel->game_name() + wxT(".clt"); + clh.cheatdir = panel->game_dir(); + clh.deffn = wxFileName(clh.cheatdir, clh.cheatfn).GetFullPath(); + clh.Reload(); + clh.ce_desc = wxEmptyString; + wxChoice* ch = clh.ce_type_ch; + ch->Clear(); - clh.ce_desc = wxEmptyString; - wxChoice *ch = clh.ce_type_ch; - ch->Clear(); - if(clh.isgb) { - ch->Append(_("GameShark")); - ch->Append(_("GameGenie")); - } else { - ch->Append(_("Generic Code")); - ch->Append(_("GameShark Advance")); - ch->Append(_("CodeBreaker Advance")); + if (clh.isgb) + { + ch->Append(_("GameShark")); + ch->Append(_("GameGenie")); + } + else + { + ch->Append(_("Generic Code")); + ch->Append(_("GameShark Advance")); + ch->Append(_("CodeBreaker Advance")); + } + + ch->SetSelection(0); + return true; } - ch->SetSelection(0); - - return true; - } }; // manage the cheat search dialog -enum cf_vfmt { - CFVFMT_SD, CFVFMT_UD, CFVFMT_UH +enum cf_vfmt +{ + CFVFMT_SD, CFVFMT_UD, CFVFMT_UH }; // virtual ListCtrl for cheat search results class CheatListCtrl : public wxListCtrl { - public: - wxArrayInt addrs; - int cap_size; // size in effect when addrs were generated - int count8, count16, count32; // number of aligned addresses in addrs - wxString OnGetItemText(long item, long column) const; +public: + wxArrayInt addrs; + int cap_size; // size in effect when addrs were generated + int count8, count16, count32; // number of aligned addresses in addrs + wxString OnGetItemText(long item, long column) const; - DECLARE_DYNAMIC_CLASS() + DECLARE_DYNAMIC_CLASS() }; IMPLEMENT_DYNAMIC_CLASS(CheatListCtrl, wxListCtrl); @@ -638,760 +759,943 @@ IMPLEMENT_DYNAMIC_CLASS(CheatListCtrl, wxListCtrl); static class CheatFind_t : public wxEvtHandler { public: - wxDialog *dlg; - int valsrc, size, op, fmt; - int ofmt, osize; - wxString val_s; - wxTextCtrl *val_tc; - CheatListCtrl *list; + wxDialog* dlg; + int valsrc, size, op, fmt; + int ofmt, osize; + wxString val_s; + wxTextCtrl* val_tc; + CheatListCtrl* list; - // for enable/disable - wxRadioButton *old_rb, *val_rb; - wxControl *update_b, *clear_b, *add_b; + // for enable/disable + wxRadioButton* old_rb, *val_rb; + wxControl* update_b, *clear_b, *add_b; - bool isgb; + bool isgb; - // add dialog - wxString ca_desc, ca_val; - wxTextCtrl *ca_val_tc; - wxControl *ca_fmt, *ca_addr; + // add dialog + wxString ca_desc, ca_val; + wxTextCtrl* ca_val_tc; + wxControl* ca_fmt, *ca_addr; - CheatFind_t() : wxEvtHandler(), valsrc(0), size(0), op(0), fmt(0), val_s() {} - ~CheatFind_t() - { - // not that it matters to anyone but mem leak detectors.. - cheatSearchCleanup(&cheatSearchData); - } - - void Search(wxCommandEvent &ev) - { - dlg->TransferDataFromWindow(); - if(!valsrc && val_s.empty()) { - wxLogError(_("Number cannot be empty")); - return; + CheatFind_t() : wxEvtHandler(), valsrc(0), size(0), op(0), fmt(0), val_s() {} + ~CheatFind_t() + { + // not that it matters to anyone but mem leak detectors.. + cheatSearchCleanup(&cheatSearchData); } - if(!cheatSearchData.count) - ResetSearch(ev); - if(valsrc) - cheatSearch(&cheatSearchData, op, size, fmt == CFVFMT_SD); - else - cheatSearchValue(&cheatSearchData, op, size, fmt == CFVFMT_SD, - SignedValue()); - Deselect(); - list->addrs.clear(); - list->count8 = list->count16 = list->count32 = 0; - list->cap_size = size; - for(int i = 0; i < cheatSearchData.count; i++) { - CheatSearchBlock *block = &cheatSearchData.blocks[i]; - for(int j = 0; j < block->size; j += (1 << size)) { - if(IS_BIT_SET(block->bits, j)) { - list->addrs.push_back((i << 28) + j); - if(!(j & 1)) - list->count16++; - if(!(j & 3)) - list->count32++; - // since listctrl is virtual, it should be able to handle - // at least 256k results, which is about the most you - // will ever get -#if 0 - if(list->addrs.size() > 1000) { - wxLogError(_("Search produced %d results. Please refine better"), - list->addrs.size()); - list->addrs.clear(); + + void Search(wxCommandEvent &ev) + { + dlg->TransferDataFromWindow(); + + if (!valsrc && val_s.empty()) + { + wxLogError(_("Number cannot be empty")); return; - } -#endif } - } - } - if(list->addrs.empty()) { - wxLogError(_("Search produced no results")); - // no point in keeping empty search results around - ResetSearch(ev); - if(old_rb->GetValue()) { - val_rb->SetValue(true); - // SetValue doesn't generate an event - val_tc->Enable(); - } - old_rb->Disable(); - update_b->Disable(); - clear_b->Disable(); - } else { - switch(size) { - case BITS_32: - list->count16 = list->count32 * 2; - // fall through - case BITS_16: - list->count8 = list->count16 * 2; - break; - case BITS_8: - list->count8 = list->addrs.size(); - } - old_rb->Enable(); - update_b->Enable(); - clear_b->Enable(); - } - list->SetItemCount(list->addrs.size()); - list->Refresh(); - } - void UpdateVals(wxCommandEvent &ev) - { - if(cheatSearchData.count) { - cheatSearchUpdateValues(&cheatSearchData); - if(list->count8) - list->Refresh(); - update_b->Disable(); - } - } + if (!cheatSearchData.count) + ResetSearch(ev); - void ResetSearch(wxCommandEvent &ev) - { - if(!cheatSearchData.count) { - CheatSearchBlock *block = cheatSearchData.blocks; - - if(isgb) { - block->offset = 0xa000; - if(gbRam) - block->data = gbRam; + if (valsrc) + cheatSearch(&cheatSearchData, op, size, fmt == CFVFMT_SD); else - block->data = &gbMemory[0xa000]; - block->saved = (u8 *)malloc(gbRamSize); - block->size = gbRamSize; - block->bits = (u8 *)malloc(gbRamSize >> 3); - if(gbCgbMode) { - block++; - block->offset = 0xc000; - block->data = &gbMemory[0xc000]; - block->saved = (u8 *)malloc(0x1000); - block->size = 0x1000; - block->bits = (u8 *)malloc(0x1000 >> 3); - block++; - block->offset = 0xd000; - block->data = gbWram; - block->saved = (u8 *)malloc(0x8000); - block->size = 0x8000; - block->bits = (u8 *)malloc(0x8000 >> 3); - } else { - block++; - block->offset = 0xc000; - block->data = &gbMemory[0xc000]; - block->saved = (u8 *)malloc(0x2000); - block->size = 0x2000; - block->bits = (u8 *)malloc(0x2000 >> 3); + cheatSearchValue(&cheatSearchData, op, size, fmt == CFVFMT_SD, + SignedValue()); + + Deselect(); + list->addrs.clear(); + list->count8 = list->count16 = list->count32 = 0; + list->cap_size = size; + + for (int i = 0; i < cheatSearchData.count; i++) + { + CheatSearchBlock* block = &cheatSearchData.blocks[i]; + + for (int j = 0; j < block->size; j += (1 << size)) + { + if (IS_BIT_SET(block->bits, j)) + { + list->addrs.push_back((i << 28) + j); + + if (!(j & 1)) + list->count16++; + + if (!(j & 3)) + list->count32++; + + // since listctrl is virtual, it should be able to handle + // at least 256k results, which is about the most you + // will ever get +#if 0 + + if (list->addrs.size() > 1000) + { + wxLogError(_("Search produced %d results. Please refine better"), + list->addrs.size()); + list->addrs.clear(); + return; + } + +#endif + } + } } - } else { - block->size = 0x40000; - block->offset = 0x2000000; - block->bits = (u8 *)malloc(0x40000 >> 3); - block->data = workRAM; - block->saved = (u8 *)malloc(0x40000); - block++; - block->size = 0x8000; - block->offset = 0x3000000; - block->bits = (u8 *)malloc(0x8000 >> 3); - block->data = internalRAM; - block->saved = (u8 *)malloc(0x8000); - } - cheatSearchData.count = (int)((block + 1) - cheatSearchData.blocks); - } - cheatSearchStart(&cheatSearchData); - if(list->count8) { - Deselect(); - list->count8 = list->count16 = list->count32 = 0; - list->addrs.clear(); - list->SetItemCount(0); - list->Refresh(); - if(old_rb->GetValue()) { - val_rb->SetValue(true); - // SetValue doesn't generate an event - val_tc->Enable(); - } - old_rb->Disable(); - update_b->Disable(); - clear_b->Disable(); - } - } - void Deselect() - { + if (list->addrs.empty()) + { + wxLogError(_("Search produced no results")); + // no point in keeping empty search results around + ResetSearch(ev); + + if (old_rb->GetValue()) + { + val_rb->SetValue(true); + // SetValue doesn't generate an event + val_tc->Enable(); + } + + old_rb->Disable(); + update_b->Disable(); + clear_b->Disable(); + } + else + { + switch (size) + { + case BITS_32: + list->count16 = list->count32 * 2; + + // fall through + case BITS_16: + list->count8 = list->count16 * 2; + break; + + case BITS_8: + list->count8 = list->addrs.size(); + } + + old_rb->Enable(); + update_b->Enable(); + clear_b->Enable(); + } + + list->SetItemCount(list->addrs.size()); + list->Refresh(); + } + + void UpdateVals(wxCommandEvent &ev) + { + if (cheatSearchData.count) + { + cheatSearchUpdateValues(&cheatSearchData); + + if (list->count8) + list->Refresh(); + + update_b->Disable(); + } + } + + void ResetSearch(wxCommandEvent &ev) + { + if (!cheatSearchData.count) + { + CheatSearchBlock* block = cheatSearchData.blocks; + + if (isgb) + { + block->offset = 0xa000; + + if (gbRam) + block->data = gbRam; + else + block->data = &gbMemory[0xa000]; + + block->saved = (u8*)malloc(gbRamSize); + block->size = gbRamSize; + block->bits = (u8*)malloc(gbRamSize >> 3); + + if (gbCgbMode) + { + block++; + block->offset = 0xc000; + block->data = &gbMemory[0xc000]; + block->saved = (u8*)malloc(0x1000); + block->size = 0x1000; + block->bits = (u8*)malloc(0x1000 >> 3); + block++; + block->offset = 0xd000; + block->data = gbWram; + block->saved = (u8*)malloc(0x8000); + block->size = 0x8000; + block->bits = (u8*)malloc(0x8000 >> 3); + } + else + { + block++; + block->offset = 0xc000; + block->data = &gbMemory[0xc000]; + block->saved = (u8*)malloc(0x2000); + block->size = 0x2000; + block->bits = (u8*)malloc(0x2000 >> 3); + } + } + else + { + block->size = 0x40000; + block->offset = 0x2000000; + block->bits = (u8*)malloc(0x40000 >> 3); + block->data = workRAM; + block->saved = (u8*)malloc(0x40000); + block++; + block->size = 0x8000; + block->offset = 0x3000000; + block->bits = (u8*)malloc(0x8000 >> 3); + block->data = internalRAM; + block->saved = (u8*)malloc(0x8000); + } + + cheatSearchData.count = (int)((block + 1) - cheatSearchData.blocks); + } + + cheatSearchStart(&cheatSearchData); + + if (list->count8) + { + Deselect(); + list->count8 = list->count16 = list->count32 = 0; + list->addrs.clear(); + list->SetItemCount(0); + list->Refresh(); + + if (old_rb->GetValue()) + { + val_rb->SetValue(true); + // SetValue doesn't generate an event + val_tc->Enable(); + } + + old_rb->Disable(); + update_b->Disable(); + clear_b->Disable(); + } + } + + void Deselect() + { int idx = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if(idx >= 0) + + if (idx >= 0) list->SetItemState(idx, 0, wxLIST_STATE_SELECTED); + add_b->Disable(); - } + } - void Select(wxListEvent &ev) - { + void Select(wxListEvent &ev) + { add_b->Enable(list->GetItemState(ev.GetIndex(), wxLIST_STATE_SELECTED) != 0); - } + } - void AddCheatB(wxCommandEvent &ev) - { + void AddCheatB(wxCommandEvent &ev) + { int idx = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if(idx >= 0) + + if (idx >= 0) AddCheat(idx); - } + } - void AddCheatL(wxListEvent &ev) - { + void AddCheatL(wxListEvent &ev) + { AddCheat(ev.GetIndex()); - } + } - void AddCheat(int idx) - { + void AddCheat(int idx) + { wxString addr_s = list->OnGetItemText(idx, 0); ca_addr->SetLabel(addr_s); wxString s; - switch(size) { - case BITS_8: - s = _("8-bit "); + + switch (size) + { + case BITS_8: + s = _("8-bit "); break; - case BITS_16: - s = _("16-bit "); + + case BITS_16: + s = _("16-bit "); break; - case BITS_32: - s = _("32-bit "); + + case BITS_32: + s = _("32-bit "); break; - } - switch(fmt) { - case CFVFMT_SD: - s += _("signed decimal"); - break; - case CFVFMT_UD: - s += _("unsigned decimal"); - break; - case CFVFMT_UH: - s += _("unsigned hexadecimal"); - break; - } - ca_fmt->SetLabel(s); - // probably pointless (but inoffensive) to suggest a value - ca_val = list->OnGetItemText(idx, 2); // sugest "New" value - SetValVal(ca_val_tc); - wxDialog *subdlg = GetXRCDialog("CheatAdd"); - if(subdlg->ShowModal() != wxID_OK) - return; - if(ca_val.empty()) { - wxLogError(_("Number cannot be empty")); - return; - } - u32 val = GetValue(ca_val, fmt); - if(isgb) { - long bank, addr; - addr_s.ToLong(&bank, 16); - addr_s.erase(0, 3); - addr_s.ToLong(&addr, 16); - if(addr >= 0xd000) - bank += 0x90; - else - bank = 1; - for(int i = 0; i < (1 << size); i++) { - addr_s.Printf(wxT("%02X%02X%02X%02X"), bank, val & 0xff, - addr & 0xff, addr >> 8); - gbAddGsCheat(addr_s.mb_str(), ca_desc.mb_str()); - val >>= 8; - addr++; - } - } else { - wxString s; - switch(size) { - case BITS_8: - s.Printf(wxT(":%02X"), val); - break; - case BITS_16: - s.Printf(wxT(":%04X"), val); - break; - case BITS_32: - s.Printf(wxT(":%08X"), val); - break; - } - addr_s.append(s); - cheatsAddCheatCode(addr_s.mb_str(), ca_desc.mb_str()); - } - } - - void SetValVal(wxTextCtrl *tc) - { - wxTextValidator *v = wxStaticCast(tc->GetValidator(), wxTextValidator); - switch(fmt) { - case CFVFMT_SD: - v->SetIncludes(val_sigdigits); - break; - case CFVFMT_UD: - v->SetIncludes(val_unsdigits); - break; - case CFVFMT_UH: - v->SetIncludes(val_hexdigits); - break; - } - } - - u32 GetValue(wxString &s, int fmt) - { - long val; - // FIXME: probably ought to throw an error if ToLong - // returns false or val is out of range - s.ToLong(&val, fmt == CFVFMT_UH ? 16 : 10); - if(size != BITS_32) - val &= size == BITS_8 ? 0xff : 0xffff; - return val; - } - - u32 GetValue(int fmt) - { - return GetValue(val_s, fmt); - } - - u32 GetValue() - { - return GetValue(fmt); - } - - s32 SignedValue(wxString &s, int fmt) - { - s32 val = GetValue(s, fmt); - if(fmt == CFVFMT_SD) { - if(size == BITS_8) - val = (s32)(s8)val; - else if(size == BITS_16) - val = (s32)(s16)val; - } - return val; - } - - s32 SignedValue(int fmt) - { - return SignedValue(val_s, fmt); - } - - s32 SignedValue() - { - return SignedValue(fmt); - } - - void FormatValue(s32 val, wxString &s) - { - if(fmt != CFVFMT_SD && size != BITS_32) - val &= size == BITS_8 ? 0xff : 0xffff; - switch(fmt) { - case CFVFMT_SD: - s.Printf(wxT("%d"), val); - break; - case CFVFMT_UD: - s.Printf(wxT("%u"), val); - break; - case CFVFMT_UH: - switch(size) { - case BITS_8: - s.Printf(wxT("%02X"), val); - break; - case BITS_16: - s.Printf(wxT("%04X"), val); - break; - case BITS_32: - s.Printf(wxT("%08X"), val); - break; - } - } - } - - void UpdateView(wxCommandEvent &ev) - { - dlg->TransferDataFromWindow(); - if(ofmt != fmt && !val_s.empty()) { - s32 val = GetValue(ofmt); - switch(fmt) { - case CFVFMT_SD: - switch(size) { - case BITS_8: - val = (s32)(s8)val; - break; - case BITS_16: - val = (s32)(s16)val; } - val_s.Printf(wxT("%d"), val); - break; - case CFVFMT_UD: - val_s.Printf(wxT("%u"), val); - break; - case CFVFMT_UH: - val_s.Printf(wxT("%x"), val); - break; - } - val_tc->SetValue(val_s); - } - if(ofmt != fmt) - SetValVal(val_tc); - if(list->count8 && osize != size) { - switch(size) { - case BITS_32: - list->SetItemCount(list->count32); - break; - case BITS_16: - list->SetItemCount(list->count16); - break; - case BITS_8: - list->SetItemCount(list->count8); - break; - } - } - if(ofmt != fmt || osize != size) - list->Refresh(); - ofmt = fmt; - osize = size; - } - void EnableVal(wxCommandEvent &ev) - { - val_tc->Enable(ev.GetId() == XRCID("SpecificValue")); - } + switch (fmt) + { + case CFVFMT_SD: + s += _("signed decimal"); + break; + + case CFVFMT_UD: + s += _("unsigned decimal"); + break; + + case CFVFMT_UH: + s += _("unsigned hexadecimal"); + break; + } + + ca_fmt->SetLabel(s); + // probably pointless (but inoffensive) to suggest a value + ca_val = list->OnGetItemText(idx, 2); // sugest "New" value + SetValVal(ca_val_tc); + wxDialog* subdlg = GetXRCDialog("CheatAdd"); + + if (subdlg->ShowModal() != wxID_OK) + return; + + if (ca_val.empty()) + { + wxLogError(_("Number cannot be empty")); + return; + } + + u32 val = GetValue(ca_val, fmt); + + if (isgb) + { + long bank, addr; + addr_s.ToLong(&bank, 16); + addr_s.erase(0, 3); + addr_s.ToLong(&addr, 16); + + if (addr >= 0xd000) + bank += 0x90; + else + bank = 1; + + for (int i = 0; i < (1 << size); i++) + { + addr_s.Printf(wxT("%02X%02X%02X%02X"), bank, val & 0xff, + addr & 0xff, addr >> 8); + gbAddGsCheat(addr_s.mb_str(), ca_desc.mb_str()); + val >>= 8; + addr++; + } + } + else + { + wxString s; + + switch (size) + { + case BITS_8: + s.Printf(wxT(":%02X"), val); + break; + + case BITS_16: + s.Printf(wxT(":%04X"), val); + break; + + case BITS_32: + s.Printf(wxT(":%08X"), val); + break; + } + + addr_s.append(s); + cheatsAddCheatCode(addr_s.mb_str(), ca_desc.mb_str()); + } + } + + void SetValVal(wxTextCtrl* tc) + { + wxTextValidator* v = wxStaticCast(tc->GetValidator(), wxTextValidator); + + switch (fmt) + { + case CFVFMT_SD: + v->SetIncludes(val_sigdigits); + break; + + case CFVFMT_UD: + v->SetIncludes(val_unsdigits); + break; + + case CFVFMT_UH: + v->SetIncludes(val_hexdigits); + break; + } + } + + u32 GetValue(wxString &s, int fmt) + { + long val; + // FIXME: probably ought to throw an error if ToLong + // returns false or val is out of range + s.ToLong(&val, fmt == CFVFMT_UH ? 16 : 10); + + if (size != BITS_32) + val &= size == BITS_8 ? 0xff : 0xffff; + + return val; + } + + u32 GetValue(int fmt) + { + return GetValue(val_s, fmt); + } + + u32 GetValue() + { + return GetValue(fmt); + } + + s32 SignedValue(wxString &s, int fmt) + { + s32 val = GetValue(s, fmt); + + if (fmt == CFVFMT_SD) + { + if (size == BITS_8) + val = (s32)(s8)val; + else if (size == BITS_16) + val = (s32)(s16)val; + } + + return val; + } + + s32 SignedValue(int fmt) + { + return SignedValue(val_s, fmt); + } + + s32 SignedValue() + { + return SignedValue(fmt); + } + + void FormatValue(s32 val, wxString &s) + { + if (fmt != CFVFMT_SD && size != BITS_32) + val &= size == BITS_8 ? 0xff : 0xffff; + + switch (fmt) + { + case CFVFMT_SD: + s.Printf(wxT("%d"), val); + break; + + case CFVFMT_UD: + s.Printf(wxT("%u"), val); + break; + + case CFVFMT_UH: + switch (size) + { + case BITS_8: + s.Printf(wxT("%02X"), val); + break; + + case BITS_16: + s.Printf(wxT("%04X"), val); + break; + + case BITS_32: + s.Printf(wxT("%08X"), val); + break; + } + } + } + + void UpdateView(wxCommandEvent &ev) + { + dlg->TransferDataFromWindow(); + + if (ofmt != fmt && !val_s.empty()) + { + s32 val = GetValue(ofmt); + + switch (fmt) + { + case CFVFMT_SD: + switch (size) + { + case BITS_8: + val = (s32)(s8)val; + break; + + case BITS_16: + val = (s32)(s16)val; + } + + val_s.Printf(wxT("%d"), val); + break; + + case CFVFMT_UD: + val_s.Printf(wxT("%u"), val); + break; + + case CFVFMT_UH: + val_s.Printf(wxT("%x"), val); + break; + } + + val_tc->SetValue(val_s); + } + + if (ofmt != fmt) + SetValVal(val_tc); + + if (list->count8 && osize != size) + { + switch (size) + { + case BITS_32: + list->SetItemCount(list->count32); + break; + + case BITS_16: + list->SetItemCount(list->count16); + break; + + case BITS_8: + list->SetItemCount(list->count8); + break; + } + } + + if (ofmt != fmt || osize != size) + list->Refresh(); + + ofmt = fmt; + osize = size; + } + + void EnableVal(wxCommandEvent &ev) + { + val_tc->Enable(ev.GetId() == XRCID("SpecificValue")); + } } cheat_find_handler; // clear cheat find dialog between games void MainFrame::ResetCheatSearch() { - CheatFind_t &cfh = cheat_find_handler; - cfh.fmt = cfh.size = cfh.op = cfh.valsrc = 0; - cfh.val_s = wxEmptyString; - cfh.Deselect(); - cfh.list->SetItemCount(0); - cfh.list->count8 = cfh.list->count16 = cfh.list->count32 = 0; - cfh.list->addrs.clear(); - cfh.ca_desc = wxEmptyString; - cheatSearchCleanup(&cheatSearchData); + CheatFind_t &cfh = cheat_find_handler; + cfh.fmt = cfh.size = cfh.op = cfh.valsrc = 0; + cfh.val_s = wxEmptyString; + cfh.Deselect(); + cfh.list->SetItemCount(0); + cfh.list->count8 = cfh.list->count16 = cfh.list->count32 = 0; + cfh.list->addrs.clear(); + cfh.ca_desc = wxEmptyString; + cheatSearchCleanup(&cheatSearchData); } // onshow handler for above, in the form of an overzealous validator class CheatFindFill : public wxValidator { public: - CheatFindFill() : wxValidator() {} - CheatFindFill(const CheatFindFill &e) : wxValidator() {} - wxObject *Clone() const { return new CheatFindFill(*this); } - bool TransferFromWindow() { return true; } - bool Validate(wxWindow *p) { return true; } - bool TransferToWindow() { - CheatFind_t &cfh = cheat_find_handler; - GameArea *panel = wxGetApp().frame->GetPanel(); - cfh.isgb = panel->game_type() == IMAGE_GB; - cfh.val_tc->Enable(!cfh.valsrc); - cfh.ofmt = cfh.fmt; - cfh.SetValVal(cfh.val_tc); - return true; - } + CheatFindFill() : wxValidator() {} + CheatFindFill(const CheatFindFill &e) : wxValidator() {} + wxObject* Clone() const { return new CheatFindFill(*this); } + bool TransferFromWindow() { return true; } + bool Validate(wxWindow* p) { return true; } + bool TransferToWindow() + { + CheatFind_t &cfh = cheat_find_handler; + GameArea* panel = wxGetApp().frame->GetPanel(); + cfh.isgb = panel->game_type() == IMAGE_GB; + cfh.val_tc->Enable(!cfh.valsrc); + cfh.ofmt = cfh.fmt; + cfh.SetValVal(cfh.val_tc); + return true; + } }; // the implementation of the virtual list ctrl for search results // requires CheatFind_t to be implemented wxString CheatListCtrl::OnGetItemText(long item, long column) const { - wxString s; - CheatFind_t &cfh = cheat_find_handler; - // allowing GUI to change format after search makes this a little - // more complicated than necessary... - int off = 0; - int size = cfh.size; - if(cap_size > size) { - off = (item & ((1 << (cap_size - size)) - 1)) << size; - item >>= cap_size - size; - } else if(cap_size < size) { - for(int i = 0; i < addrs.size(); i++) { - if(!(addrs[i] & ((1 << size) - 1)) && !item--) { - item = i; - break; - } - } - } - CheatSearchBlock *block = &cheatSearchData.blocks[addrs[item] >> 28]; - off += addrs[item] & 0xfffffff; + wxString s; + CheatFind_t &cfh = cheat_find_handler; + // allowing GUI to change format after search makes this a little + // more complicated than necessary... + int off = 0; + int size = cfh.size; - switch(column) { - case 0: // address - if(cfh.isgb) { - int bank = 0; - int addr = block->offset; - if(block->offset == 0xa000) { - bank = off / 0x2000; - addr += off % 0x2000; - } else if(block->offset == 0xd000) { - bank = off / 0x1000; - addr += off % 0x1000; - } else - addr += off; - s.Printf(wxT("%02X:%04X"), bank, addr); - } else - s.Printf(wxT("%08X"), block->offset + off); - break; - case 1: // old - cfh.FormatValue(cheatSearchSignedRead(block->saved, off, size), s); - break; - case 2: // new - cfh.FormatValue(cheatSearchSignedRead(block->data, off, size), s); - break; - } - return s; + if (cap_size > size) + { + off = (item & ((1 << (cap_size - size)) - 1)) << size; + item >>= cap_size - size; + } + else if (cap_size < size) + { + for (int i = 0; i < addrs.size(); i++) + { + if (!(addrs[i] & ((1 << size) - 1)) && !item--) + { + item = i; + break; + } + } + } + + CheatSearchBlock* block = &cheatSearchData.blocks[addrs[item] >> 28]; + off += addrs[item] & 0xfffffff; + + switch (column) + { + case 0: // address + if (cfh.isgb) + { + int bank = 0; + int addr = block->offset; + + if (block->offset == 0xa000) + { + bank = off / 0x2000; + addr += off % 0x2000; + } + else if (block->offset == 0xd000) + { + bank = off / 0x1000; + addr += off % 0x1000; + } + else + addr += off; + + s.Printf(wxT("%02X:%04X"), bank, addr); + } + else + s.Printf(wxT("%08X"), block->offset + off); + + break; + + case 1: // old + cfh.FormatValue(cheatSearchSignedRead(block->saved, off, size), s); + break; + + case 2: // new + cfh.FormatValue(cheatSearchSignedRead(block->data, off, size), s); + break; + } + + return s; } // these are the choices for canned colors; their order must match the // names in the choice control -static const u16 defaultPalettes[][8] = { - { // Standard - 0x7FFF, 0x56B5, 0x318C, 0x0000, 0x7FFF, 0x56B5, 0x318C, 0x0000, - }, - { // Blue Sea - 0x6200, 0x7E10, 0x7C10, 0x5000, 0x6200, 0x7E10, 0x7C10, 0x5000, - }, - { // Dark Night - 0x4008, 0x4000, 0x2000, 0x2008, 0x4008, 0x4000, 0x2000, 0x2008, - }, - { // Green Forest - 0x43F0, 0x03E0, 0x4200, 0x2200, 0x43F0, 0x03E0, 0x4200, 0x2200, - }, - { // Hot Desert - 0x43FF, 0x03FF, 0x221F, 0x021F, 0x43FF, 0x03FF, 0x221F, 0x021F, - }, - { // Pink Dreams - 0x621F, 0x7E1F, 0x7C1F, 0x2010, 0x621F, 0x7E1F, 0x7C1F, 0x2010, - }, - { // Weird Colors - 0x621F, 0x401F, 0x001F, 0x2010, 0x621F, 0x401F, 0x001F, 0x2010, - }, - { // 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, - } +static const u16 defaultPalettes[][8] = +{ + { + // Standard + 0x7FFF, 0x56B5, 0x318C, 0x0000, 0x7FFF, 0x56B5, 0x318C, 0x0000, + }, + { + // Blue Sea + 0x6200, 0x7E10, 0x7C10, 0x5000, 0x6200, 0x7E10, 0x7C10, 0x5000, + }, + { + // Dark Night + 0x4008, 0x4000, 0x2000, 0x2008, 0x4008, 0x4000, 0x2000, 0x2008, + }, + { + // Green Forest + 0x43F0, 0x03E0, 0x4200, 0x2200, 0x43F0, 0x03E0, 0x4200, 0x2200, + }, + { + // Hot Desert + 0x43FF, 0x03FF, 0x221F, 0x021F, 0x43FF, 0x03FF, 0x221F, 0x021F, + }, + { + // Pink Dreams + 0x621F, 0x7E1F, 0x7C1F, 0x2010, 0x621F, 0x7E1F, 0x7C1F, 0x2010, + }, + { + // Weird Colors + 0x621F, 0x401F, 0x001F, 0x2010, 0x621F, 0x401F, 0x001F, 0x2010, + }, + { + // 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, + } }; // manage the GB color prefs' canned color selecter static class GBColorConfig_t : public wxEvtHandler { public: - wxWindow *p; - wxChoice *c; - wxColourPickerCtrl *cp[8]; - int pno; - void ColorSel(wxCommandEvent &ev) - { - if(ev.GetSelection() > 0) { - const u16 *color = defaultPalettes[ev.GetSelection() - 1]; - for(int i = 0; i < 8; i++, color++) - cp[i]->SetColour(wxColor(((*color << 3) & 0xf8), - ((*color >> 2) & 0xf8), - ((*color >> 7) & 0xf8))); - } - } - void ColorReset(wxCommandEvent &ev) - { - const u16 *color = &systemGbPalette[pno * 8]; - for(int i = 0; i < 8; i++, color++) - cp[i]->SetColour(wxColor(((*color << 3) & 0xf8), - ((*color >> 2) & 0xf8), - ((*color >> 7) & 0xf8))); - } + wxWindow* p; + wxChoice* c; + wxColourPickerCtrl* cp[8]; + int pno; + void ColorSel(wxCommandEvent &ev) + { + if (ev.GetSelection() > 0) + { + const u16* color = defaultPalettes[ev.GetSelection() - 1]; - void ColorButton(wxCommandEvent &ev) - { - c->SetSelection(0); - } + for (int i = 0; i < 8; i++, color++) + cp[i]->SetColour(wxColor(((*color << 3) & 0xf8), + ((*color >> 2) & 0xf8), + ((*color >> 7) & 0xf8))); + } + } + void ColorReset(wxCommandEvent &ev) + { + const u16* color = &systemGbPalette[pno * 8]; + + for (int i = 0; i < 8; i++, color++) + cp[i]->SetColour(wxColor(((*color << 3) & 0xf8), + ((*color >> 2) & 0xf8), + ((*color >> 7) & 0xf8))); + } + + void ColorButton(wxCommandEvent &ev) + { + c->SetSelection(0); + } } GBColorConfigHandler[3]; // disable controls if a GBA game is not loaded class GBACtrlEnabler : public wxValidator { public: - GBACtrlEnabler() : wxValidator() {} - GBACtrlEnabler(const GBACtrlEnabler &e) : wxValidator() {} - wxObject *Clone() const { return new GBACtrlEnabler(*this); } - bool TransferFromWindow() { return true; } - bool Validate(wxWindow *p) { return true; } - bool TransferToWindow() { - GetWindow()->Enable(wxGetApp().frame->GetPanel()->game_type() == IMAGE_GBA); - return true; - } + GBACtrlEnabler() : wxValidator() {} + GBACtrlEnabler(const GBACtrlEnabler &e) : wxValidator() {} + wxObject* Clone() const { return new GBACtrlEnabler(*this); } + bool TransferFromWindow() { return true; } + bool Validate(wxWindow* p) { return true; } + bool TransferToWindow() + { + GetWindow()->Enable(wxGetApp().frame->GetPanel()->game_type() == IMAGE_GBA); + return true; + } }; // manage save game area settings for GBA prefs static class BatConfig_t : public wxEvtHandler { public: - wxChoice *type, *size; - void ChangeType(wxCommandEvent &ev) - { - int i = ev.GetSelection(); - size->Enable(!i || i == 3); // automatic/flash - } - void Detect(wxCommandEvent &ev) - { - // note: win32 version just pops up a dialog stating what it found - // which is appropriate becauase it was in a menu - // this code sets the controls instead, since there right there - u32 sz = wxGetApp().frame->GetPanel()->game_size(); + wxChoice* type, *size; + void ChangeType(wxCommandEvent &ev) + { + int i = ev.GetSelection(); + size->Enable(!i || i == 3); // automatic/flash + } + void Detect(wxCommandEvent &ev) + { + // note: win32 version just pops up a dialog stating what it found + // which is appropriate becauase it was in a menu + // this code sets the controls instead, since there right there + u32 sz = wxGetApp().frame->GetPanel()->game_size(); #define ch4(a, b, c, d) \ wxUINT32_SWAP_ON_BE(a + (b << 8) + (c << 16) + (d << 24)) - for(u32 addr = 0; addr < sz - 10; addr += 4) { - switch(*(u32 *)&rom[addr]) { - case ch4('E', 'E', 'P', 'R'): - if(memcmp(&rom[addr + 4], "OM_V", 4)) - break; - // apparently no sensor autodetection - type->SetSelection(1); - size->Disable(); - return; - case ch4('S', 'R', 'A', 'M'): - if(memcmp(&rom[addr + 4], "_V", 2)) - break; - type->SetSelection(2); - size->Disable(); - return; - case ch4('F', 'L', 'A', 'S'): - if(!memcmp(&rom[addr + 4], "H_V", 3)) { - type->SetSelection(3); - size->SetSelection(0); - size->Enable(); - return; - } else if(!memcmp(&rom[addr + 4], "H1M_V", 5)) { - type->SetSelection(3); - size->SetSelection(1); - size->Enable(); - return; + + for (u32 addr = 0; addr < sz - 10; addr += 4) + { + switch (*(u32*)&rom[addr]) + { + case ch4('E', 'E', 'P', 'R'): + if (memcmp(&rom[addr + 4], "OM_V", 4)) + break; + + // apparently no sensor autodetection + type->SetSelection(1); + size->Disable(); + return; + + case ch4('S', 'R', 'A', 'M'): + if (memcmp(&rom[addr + 4], "_V", 2)) + break; + + type->SetSelection(2); + size->Disable(); + return; + + case ch4('F', 'L', 'A', 'S'): + if (!memcmp(&rom[addr + 4], "H_V", 3)) + { + type->SetSelection(3); + size->SetSelection(0); + size->Enable(); + return; + } + else if (!memcmp(&rom[addr + 4], "H1M_V", 5)) + { + type->SetSelection(3); + size->SetSelection(1); + size->Enable(); + return; + } + + break; + } } - break; - } + + type->SetSelection(5); + size->Disable(); } - type->SetSelection(5); - size->Disable(); - } } BatConfigHandler; // manage the sound prefs dialog static class SoundConfig_t : public wxEvtHandler { public: - wxSlider *vol, *bufs; - wxControl *bufinfo; - int lastapi; - wxChoice *dev; - wxControl *umix, *hwacc; - wxArrayString dev_ids; + wxSlider* vol, *bufs; + wxControl* bufinfo; + int lastapi; + wxChoice* dev; + wxControl* umix, *hwacc; + wxArrayString dev_ids; - void FullVol(wxCommandEvent &ev) - { - vol->SetValue(100); - } - void AdjustFrames(int count) - { - wxString s; - s.Printf(_("%d frames = %.2f ms"), count, (double)count / 60.0 * 1000.0); - bufinfo->SetLabel(s); - } - void AdjustFramesEv(wxCommandEvent &ev) - { - AdjustFrames(bufs->GetValue()); - } + void FullVol(wxCommandEvent &ev) + { + vol->SetValue(100); + } + void AdjustFrames(int count) + { + wxString s; + s.Printf(_("%d frames = %.2f ms"), count, (double)count / 60.0 * 1000.0); + bufinfo->SetLabel(s); + } + void AdjustFramesEv(wxCommandEvent &ev) + { + AdjustFrames(bufs->GetValue()); + } - bool FillDev(int api) - { - dev->Clear(); - dev->Append(_("Default device")); - dev_ids.clear(); - wxArrayString names; - switch(api) { - case AUD_SDL: - break; + bool FillDev(int api) + { + dev->Clear(); + dev->Append(_("Default device")); + dev_ids.clear(); + wxArrayString names; + + switch (api) + { + case AUD_SDL: + break; #ifndef NO_OAL - case AUD_OPENAL: - if(!GetOALDevices(names, dev_ids)) - return false; - break; + + case AUD_OPENAL: + if (!GetOALDevices(names, dev_ids)) + return false; + + break; #endif #ifdef __WXMSW__ - case AUD_DIRECTSOUND: - if(!(GetDSDevices(names, dev_ids))) - return false; - break; + + case AUD_DIRECTSOUND: + if (!(GetDSDevices(names, dev_ids))) + return false; + + break; #ifndef NO_XAUDIO2 - case AUD_XAUDIO2: - if(!GetXA2Devices(names, dev_ids)) - return false; - break; + + case AUD_XAUDIO2: + if (!GetXA2Devices(names, dev_ids)) + return false; + + break; #endif #endif + } + + dev->SetSelection(0); + + for (int i = 0; i < names.size(); i++) + { + dev->Append(names[i]); + + if (api == gopts.audio_api && gopts.audio_dev == dev_ids[i]) + dev->SetSelection(i + 1); + } + + umix->Enable(api == AUD_XAUDIO2); + hwacc->Enable(api == AUD_DIRECTSOUND); + lastapi = api; + return true; } - dev->SetSelection(0); - for(int i = 0; i < names.size(); i++) { - dev->Append(names[i]); - if(api == gopts.audio_api && gopts.audio_dev == dev_ids[i]) - dev->SetSelection(i + 1); + void SetAPI(wxCommandEvent &ev) + { + int api = gopts.audio_api; + wxValidator* v = wxStaticCast(ev.GetEventObject(), wxWindow)->GetValidator(); + v->TransferFromWindow(); + int newapi = gopts.audio_api; + gopts.audio_api = api; + + if (newapi == lastapi) + return; + + FillDev(newapi); } - umix->Enable(api == AUD_XAUDIO2); - hwacc->Enable(api == AUD_DIRECTSOUND); - lastapi = api; - return true; - } - void SetAPI(wxCommandEvent &ev) - { - int api = gopts.audio_api; - wxValidator *v = wxStaticCast(ev.GetEventObject(), wxWindow)->GetValidator(); - v->TransferFromWindow(); - int newapi = gopts.audio_api; - gopts.audio_api = api; - if(newapi == lastapi) - return; - FillDev(newapi); - } } sound_config_handler; // Validator/widget filler for sound device selector & time indicator class SoundConfigLoad : public wxValidator { public: - SoundConfigLoad() : wxValidator() {} - SoundConfigLoad(const SoundConfigLoad &e) : wxValidator() {} - wxObject *Clone() const { return new SoundConfigLoad(*this); } - bool Validate(wxWindow *p) { return true; } - bool TransferToWindow() { - SoundConfig_t &sch = sound_config_handler; - sch.FillDev(gopts.audio_api); - sch.AdjustFrames(gopts.audio_buffers); - return true; - } - bool TransferFromWindow() { - SoundConfig_t &sch = sound_config_handler; - int devs = sch.dev->GetSelection(); - if(!devs) - gopts.audio_dev = wxEmptyString; - else - gopts.audio_dev = sch.dev_ids[devs - 1]; - return true; - } + SoundConfigLoad() : wxValidator() {} + SoundConfigLoad(const SoundConfigLoad &e) : wxValidator() {} + wxObject* Clone() const { return new SoundConfigLoad(*this); } + bool Validate(wxWindow* p) { return true; } + bool TransferToWindow() + { + SoundConfig_t &sch = sound_config_handler; + sch.FillDev(gopts.audio_api); + sch.AdjustFrames(gopts.audio_buffers); + return true; + } + bool TransferFromWindow() + { + SoundConfig_t &sch = sound_config_handler; + int devs = sch.dev->GetSelection(); + + if (!devs) + gopts.audio_dev = wxEmptyString; + else + gopts.audio_dev = sch.dev_ids[devs - 1]; + + return true; + } }; // manage the joypad prefs' per-panel default/clear buttons static class JoyPadConfig_t : public wxEvtHandler { public: - wxWindow *p; - void JoypadConfigButtons(wxCommandEvent &ev) { - bool clear = ev.GetId() == XRCID("Clear"); - for(int i = 0; i < NUM_KEYS; i++) { - wxJoyKeyTextCtrl *tc = XRCCTRL_D(*p, wxString::FromUTF8(joynames[i]), wxJoyKeyTextCtrl); - if(clear) - tc->SetValue(wxEmptyString); - else { - wxJoyKeyBinding_v a; - if(defkeys[i*2].key) - a.push_back(defkeys[i*2]); - if(defkeys[i*2+1].joy) - a.push_back(defkeys[i*2+1]); - tc->SetValue(wxJoyKeyTextCtrl::ToString(a)); - } - } + wxWindow* p; + void JoypadConfigButtons(wxCommandEvent &ev) + { + bool clear = ev.GetId() == XRCID("Clear"); - } + for (int i = 0; i < NUM_KEYS; i++) + { + wxJoyKeyTextCtrl* tc = XRCCTRL_D(*p, wxString::FromUTF8(joynames[i]), wxJoyKeyTextCtrl); + + if (clear) + tc->SetValue(wxEmptyString); + else + { + wxJoyKeyBinding_v a; + + if (defkeys[i * 2].key) + a.push_back(defkeys[i * 2]); + + if (defkeys[i * 2 + 1].joy) + a.push_back(defkeys[i * 2 + 1]); + + tc->SetValue(wxJoyKeyTextCtrl::ToString(a)); + } + } + } } JoyPadConfigHandler[4]; // manage fullscreen mode widget @@ -1399,66 +1703,83 @@ public: class ScreenModeList : public wxValidator { public: - ScreenModeList() : wxValidator() {} - ScreenModeList(const ScreenModeList &e) : wxValidator() {} - wxObject *Clone() const { return new ScreenModeList(*this); } - bool Validate(wxWindow *p) { return true; } - bool TransferToWindow() - { - wxChoice *c = wxStaticCast(GetWindow(), wxChoice); - wxDisplay d(wxDisplay::GetFromWindow(c->GetParent())); - c->Clear(); - int modeno = 0, bestmode = 0; - int bm_bpp = 0; - c->Append(_("Desktop mode")); - // probably ought to just disable this whole control on UNIX/X11 since - // wxDisplay is so broken. - vm = d.GetModes(); - wxString s; - for(int i = 0; i < vm.size(); i++) { - s.Printf(_("%d x %d - %dbpp @ %dHz"), vm[i].w, vm[i].h, vm[i].bpp, vm[i].refresh); - c->Append(s); - if(!modeno && gopts.fs_mode.w == vm[i].w && gopts.fs_mode.h == vm[i].h) { - if(gopts.fs_mode.bpp == vm[i].bpp && gopts.fs_mode.refresh == vm[i].refresh) - modeno = i + 1; - else if(vm[i].bpp == gopts.fs_mode.bpp && - bm_bpp != gopts.fs_mode.bpp) { - bestmode = i + 1; - bm_bpp = vm[i].bpp; - } else if(bm_bpp != gopts.fs_mode.bpp && bm_bpp != 32 && - vm[i].bpp == 32) { - bm_bpp = vm[i].bpp; - bestmode = i + 1; - } else if(bm_bpp != gopts.fs_mode.bpp && bm_bpp < 24 && - vm[i].bpp == 24) { - bm_bpp = vm[i].bpp; - bestmode = i + 1; - } else if(bm_bpp != gopts.fs_mode.bpp && bm_bpp < 24 && - bm_bpp != 16 && vm[i].bpp == 16) { - bm_bpp = vm[i].bpp; - bestmode = i + 1; - } else if(!bm_bpp) { - bm_bpp = vm[i].bpp; - bestmode = i + 1; + ScreenModeList() : wxValidator() {} + ScreenModeList(const ScreenModeList &e) : wxValidator() {} + wxObject* Clone() const { return new ScreenModeList(*this); } + bool Validate(wxWindow* p) { return true; } + bool TransferToWindow() + { + wxChoice* c = wxStaticCast(GetWindow(), wxChoice); + wxDisplay d(wxDisplay::GetFromWindow(c->GetParent())); + c->Clear(); + int modeno = 0, bestmode = 0; + int bm_bpp = 0; + c->Append(_("Desktop mode")); + // probably ought to just disable this whole control on UNIX/X11 since + // wxDisplay is so broken. + vm = d.GetModes(); + wxString s; + + for (int i = 0; i < vm.size(); i++) + { + s.Printf(_("%d x %d - %dbpp @ %dHz"), vm[i].w, vm[i].h, vm[i].bpp, vm[i].refresh); + c->Append(s); + + if (!modeno && gopts.fs_mode.w == vm[i].w && gopts.fs_mode.h == vm[i].h) + { + if (gopts.fs_mode.bpp == vm[i].bpp && gopts.fs_mode.refresh == vm[i].refresh) + modeno = i + 1; + else if (vm[i].bpp == gopts.fs_mode.bpp && + bm_bpp != gopts.fs_mode.bpp) + { + bestmode = i + 1; + bm_bpp = vm[i].bpp; + } + else if (bm_bpp != gopts.fs_mode.bpp && bm_bpp != 32 && + vm[i].bpp == 32) + { + bm_bpp = vm[i].bpp; + bestmode = i + 1; + } + else if (bm_bpp != gopts.fs_mode.bpp && bm_bpp < 24 && + vm[i].bpp == 24) + { + bm_bpp = vm[i].bpp; + bestmode = i + 1; + } + else if (bm_bpp != gopts.fs_mode.bpp && bm_bpp < 24 && + bm_bpp != 16 && vm[i].bpp == 16) + { + bm_bpp = vm[i].bpp; + bestmode = i + 1; + } + else if (!bm_bpp) + { + bm_bpp = vm[i].bpp; + bestmode = i + 1; + } + } } - } + + if (!modeno && bestmode) + modeno = bestmode; + + c->SetSelection(modeno); + return true; + } + bool TransferFromWindow() + { + int bestmode = wxStaticCast(GetWindow(), wxChoice)->GetSelection(); + + if (!bestmode) + gopts.fs_mode.h = gopts.fs_mode.w = gopts.fs_mode.bpp = gopts.fs_mode.refresh = 0; + else + gopts.fs_mode = vm[bestmode - 1]; + + return true; } - if(!modeno && bestmode) - modeno = bestmode; - c->SetSelection(modeno); - return true; - } - bool TransferFromWindow() - { - int bestmode = wxStaticCast(GetWindow(), wxChoice)->GetSelection(); - if(!bestmode) - gopts.fs_mode.h = gopts.fs_mode.w = gopts.fs_mode.bpp = gopts.fs_mode.refresh = 0; - else - gopts.fs_mode = vm[bestmode - 1]; - return true; - } private: - wxArrayVideoModes vm; + wxArrayVideoModes vm; }; // enable plugin-related iff filter choice is plugin @@ -1467,9 +1788,9 @@ class PluginEnabler : public wxValidator public: PluginEnabler() : wxValidator() {} PluginEnabler(const PluginEnabler &e) : wxValidator() {} - wxObject *Clone() const { return new PluginEnabler(*this); } + wxObject* Clone() const { return new PluginEnabler(*this); } bool TransferFromWindow() { return true; } - bool Validate(wxWindow *p) { return true; } + bool Validate(wxWindow* p) { return true; } bool TransferToWindow() { GetWindow()->Enable(gopts.filter == FF_PLUGIN); @@ -1481,122 +1802,148 @@ public: static class PluginEnable_t : public wxEvtHandler { public: - wxWindow *lab, *ch; - void ToggleChoice(wxCommandEvent &ev) - { - bool en = ev.GetSelection() == FF_PLUGIN; - lab->Enable(en); - ch->Enable(en); - } + wxWindow* lab, *ch; + void ToggleChoice(wxCommandEvent &ev) + { + bool en = ev.GetSelection() == FF_PLUGIN; + lab->Enable(en); + ch->Enable(en); + } } PluginEnableHandler; // fill in plugin list class PluginListFiller : public PluginEnabler { public: - PluginListFiller(wxDialog *parent, wxControl *lab, wxChoice *ch) : - PluginEnabler(), txt(lab), dlg(parent), plugins(), filtch(ch) {} - PluginListFiller(const PluginListFiller &e) : - PluginEnabler(), txt(e.txt), dlg(e.dlg), plugins(e.plugins), - filtch(e.filtch) {} - wxObject *Clone() const { return new PluginListFiller(*this); } - bool Validate(wxWindow *p) { return true; } - bool TransferToWindow() - { - PluginEnabler::TransferToWindow(); - wxChoice *ch = wxStaticCast(GetWindow(), wxChoice); - ch->Clear(); - ch->Append(_("None")); - plugins.clear(); - const wxString &plpath = wxStandardPaths::Get().GetPluginsDir(); - wxDir::GetAllFiles(plpath, &plugins, wxT("*.rpi")); - for(int i = 0; i < plugins.size(); i++) { - wxDynamicLibrary dl(plugins[i], wxDL_VERBATIM|wxDL_NOW); - RENDPLUG_GetInfo GetInfo; - const RENDER_PLUGIN_INFO *rpi; - if(dl.IsLoaded() && - (GetInfo = (RENDPLUG_GetInfo)dl.GetSymbol(wxT("RenderPluginGetInfo"))) && - // note that in actual kega fusion plugins, rpi->Output is - // unused (as is rpi->Handle) - dl.GetSymbol(wxT("RenderPluginOutput")) && - (rpi = GetInfo()) && - // FIXME: maybe this should be >= RPI_VERISON - (rpi->Flags & 0xff) == RPI_VERSION && - // RPI_565_SUPP is not supported - // although it would be possible - // and it would make Cairo more efficient - (rpi->Flags & (RPI_555_SUPP|RPI_888_SUPP))) { - wxFileName fn(plugins[i]); - wxString s = fn.GetName(); - s += wxT(": "); - s += wxString(rpi->Name, wxConvUTF8, sizeof(rpi->Name)); - fn.MakeRelativeTo(plpath); - plugins[i] = fn.GetFullName(); - ch->Append(s); - if(plugins[i] == gopts.filter_plugin) - ch->SetSelection(i + 1); - } else - plugins.RemoveAt(i--); - } - if(ch->GetCount() == 1) { - // this is probably the only place the user can find out where - // to put the plugins... it depends on where program was - // installed, and of course OS - wxString msg; - msg.Printf(_("No usable rpi plugins found in %s"), plpath.c_str()); - systemScreenMessage(msg); - ch->Hide(); - txt->Hide(); - int cursel = filtch->GetSelection(); - if(cursel == FF_PLUGIN) - cursel = 0; - if(filtch->GetCount() == FF_PLUGIN + 1) { - filtch->Delete(FF_PLUGIN); - // apparently wxgtk loses selection after this, even - // if selection was not FF_PLUGIN - filtch->SetSelection(cursel); - } - } else { - ch->Show(); - txt->Show(); - if(filtch->GetCount() < FF_PLUGIN + 1) - filtch->Append(_("Plugin")); - } - // FIXME: this isn't enough. It only resizes 2nd time around - dlg->Fit(); - return true; - } - bool TransferFromWindow() - { - wxChoice *ch = wxStaticCast(GetWindow(), wxChoice); - if(ch->GetCount() == 1) { - gopts.filter_plugin = wxEmptyString; - // this happens if "Plugin" was selected and the entry was - // subsequently removed - if(ch->GetSelection() < 0) - ch->SetSelection(0); - if(gopts.filter < 0) - gopts.filter = 0; - } else { - int n = ch->GetSelection(); - if(n > 0) - gopts.filter_plugin = plugins[n - 1]; - else { - if(filtch->GetSelection() == FF_PLUGIN) { - wxMessageBox(_("Please select a plugin or a different filter"), - _("Plugin selection error"), wxOK|wxICON_ERROR); - return false; - } - gopts.filter_plugin = wxEmptyString; - } - } - return true; - } + PluginListFiller(wxDialog* parent, wxControl* lab, wxChoice* ch) : + PluginEnabler(), txt(lab), dlg(parent), plugins(), filtch(ch) {} + PluginListFiller(const PluginListFiller &e) : + PluginEnabler(), txt(e.txt), dlg(e.dlg), plugins(e.plugins), + filtch(e.filtch) {} + wxObject* Clone() const { return new PluginListFiller(*this); } + bool Validate(wxWindow* p) { return true; } + bool TransferToWindow() + { + PluginEnabler::TransferToWindow(); + wxChoice* ch = wxStaticCast(GetWindow(), wxChoice); + ch->Clear(); + ch->Append(_("None")); + plugins.clear(); + const wxString &plpath = wxStandardPaths::Get().GetPluginsDir(); + wxDir::GetAllFiles(plpath, &plugins, wxT("*.rpi")); + + for (int i = 0; i < plugins.size(); i++) + { + wxDynamicLibrary dl(plugins[i], wxDL_VERBATIM | wxDL_NOW); + RENDPLUG_GetInfo GetInfo; + const RENDER_PLUGIN_INFO* rpi; + + if (dl.IsLoaded() && + (GetInfo = (RENDPLUG_GetInfo)dl.GetSymbol(wxT("RenderPluginGetInfo"))) && + // note that in actual kega fusion plugins, rpi->Output is + // unused (as is rpi->Handle) + dl.GetSymbol(wxT("RenderPluginOutput")) && + (rpi = GetInfo()) && + // FIXME: maybe this should be >= RPI_VERISON + (rpi->Flags & 0xff) == RPI_VERSION && + // RPI_565_SUPP is not supported + // although it would be possible + // and it would make Cairo more efficient + (rpi->Flags & (RPI_555_SUPP | RPI_888_SUPP))) + { + wxFileName fn(plugins[i]); + wxString s = fn.GetName(); + s += wxT(": "); + s += wxString(rpi->Name, wxConvUTF8, sizeof(rpi->Name)); + fn.MakeRelativeTo(plpath); + plugins[i] = fn.GetFullName(); + ch->Append(s); + + if (plugins[i] == gopts.filter_plugin) + ch->SetSelection(i + 1); + } + else + plugins.RemoveAt(i--); + } + + if (ch->GetCount() == 1) + { + // this is probably the only place the user can find out where + // to put the plugins... it depends on where program was + // installed, and of course OS + wxString msg; + msg.Printf(_("No usable rpi plugins found in %s"), plpath.c_str()); + systemScreenMessage(msg); + ch->Hide(); + txt->Hide(); + int cursel = filtch->GetSelection(); + + if (cursel == FF_PLUGIN) + cursel = 0; + + if (filtch->GetCount() == FF_PLUGIN + 1) + { + filtch->Delete(FF_PLUGIN); + // apparently wxgtk loses selection after this, even + // if selection was not FF_PLUGIN + filtch->SetSelection(cursel); + } + } + else + { + ch->Show(); + txt->Show(); + + if (filtch->GetCount() < FF_PLUGIN + 1) + filtch->Append(_("Plugin")); + } + + // FIXME: this isn't enough. It only resizes 2nd time around + dlg->Fit(); + return true; + } + bool TransferFromWindow() + { + wxChoice* ch = wxStaticCast(GetWindow(), wxChoice); + + if (ch->GetCount() == 1) + { + gopts.filter_plugin = wxEmptyString; + + // this happens if "Plugin" was selected and the entry was + // subsequently removed + if (ch->GetSelection() < 0) + ch->SetSelection(0); + + if (gopts.filter < 0) + gopts.filter = 0; + } + else + { + int n = ch->GetSelection(); + + if (n > 0) + gopts.filter_plugin = plugins[n - 1]; + else + { + if (filtch->GetSelection() == FF_PLUGIN) + { + wxMessageBox(_("Please select a plugin or a different filter"), + _("Plugin selection error"), wxOK | wxICON_ERROR); + return false; + } + + gopts.filter_plugin = wxEmptyString; + } + } + + return true; + } private: - wxDialog *dlg; - wxControl *txt; - wxChoice *filtch; - wxArrayString plugins; + wxDialog* dlg; + wxControl* txt; + wxChoice* filtch; + wxArrayString plugins; }; @@ -1607,410 +1954,492 @@ private: class TreeInt : public wxTreeItemData { public: - TreeInt(int i) : wxTreeItemData() { val = i; } - int val; + TreeInt(int i) : wxTreeItemData() { val = i; } + int val; }; // Convert a tree selection ID to a name // root // parent // item -static bool treeid_to_name(int id, wxString &name, wxTreeCtrl *tc, - const wxTreeItemId &parent, int lev = 0) +static bool treeid_to_name(int id, wxString &name, wxTreeCtrl* tc, + const wxTreeItemId &parent, int lev = 0) { - wxTreeItemIdValue cookie; - for(wxTreeItemId tid = tc->GetFirstChild(parent, cookie); tid.IsOk(); - tid = tc->GetNextChild(parent, cookie)) { - const TreeInt *ti = static_cast(tc->GetItemData(tid)); - if(ti && ti->val == id) { - name = wxString(wxT(' '), 2 * lev) + tc->GetItemText(tid); - return true; - } - if(treeid_to_name(id, name, tc, tid, lev + 1)) { - name = wxString(wxT(' '), 2 * lev) + tc->GetItemText(tid) + wxT('\n') + name; - return true; - } - } - return false; + wxTreeItemIdValue cookie; + + for (wxTreeItemId tid = tc->GetFirstChild(parent, cookie); tid.IsOk(); + tid = tc->GetNextChild(parent, cookie)) + { + const TreeInt* ti = static_cast(tc->GetItemData(tid)); + + if (ti && ti->val == id) + { + name = wxString(wxT(' '), 2 * lev) + tc->GetItemText(tid); + return true; + } + + if (treeid_to_name(id, name, tc, tid, lev + 1)) + { + name = wxString(wxT(' '), 2 * lev) + tc->GetItemText(tid) + wxT('\n') + name; + return true; + } + } + + return false; } - + // for sorting accels by command ID static bool cmdid_lt(const wxAcceleratorEntry &a, const wxAcceleratorEntry &b) { - return a.GetCommand() < b.GetCommand(); + return a.GetCommand() < b.GetCommand(); } // manage the accel editor dialog static class AccelConfig_t : public wxEvtHandler { public: - wxTreeCtrl *tc; - wxControlWithItems *lb; - wxAcceleratorEntry_v user_accels, accels; - wxWindow *asb, *remb; - wxKeyTextCtrl *key; - wxControl *curas; + wxTreeCtrl* tc; + wxControlWithItems* lb; + wxAcceleratorEntry_v user_accels, accels; + wxWindow* asb, *remb; + wxKeyTextCtrl* key; + wxControl* curas; - // since this is not the actual dialog, derived from wxDialog, which is - // the normal way of doing things, do init on the show event instead of - // constructor - void Init(wxShowEvent &ev) - { + // since this is not the actual dialog, derived from wxDialog, which is + // the normal way of doing things, do init on the show event instead of + // constructor + void Init(wxShowEvent &ev) + { #if wxCHECK_VERSION(2,9,0) #define GetShow IsShown #endif - ev.Skip(); - if(!ev.GetShow()) - return; - lb->Clear(); - tc->Unselect(); - tc->ExpandAll(); - user_accels = gopts.accels; - key->SetValue(wxT("")); - asb->Enable(false); - remb->Enable(false); - curas->SetLabel(wxT("")); - accels = wxGetApp().frame->get_accels(user_accels); - } + ev.Skip(); - // on OK, save the accels in gopts - void Set(wxCommandEvent &ev) - { - // opts.cpp assumes that gopts.accels entries with same command ID - // are contiguous, so sort first - std::sort(gopts.accels.begin(), gopts.accels.end(), cmdid_lt); - gopts.accels = user_accels; - wxGetApp().frame->set_global_accels(); - ev.Skip(); - } + if (!ev.GetShow()) + return; - // After selecting item in command list, fill in key list - // and maybe enable asb - void CommandSel(wxTreeEvent &ev) - { - // wxTreeCtrl *tc = wxStaticCast(evt.GetEventObject(), wxTreeCtrl); - // can't use wxStaticCast; wxTreeItemData does not derive from wxObject - const TreeInt *id = static_cast(tc->GetItemData(ev.GetItem())); - if(!id) { - ev.Veto(); - return; + lb->Clear(); + tc->Unselect(); + tc->ExpandAll(); + user_accels = gopts.accels; + key->SetValue(wxT("")); + asb->Enable(false); + remb->Enable(false); + curas->SetLabel(wxT("")); + accels = wxGetApp().frame->get_accels(user_accels); } - if(ev.GetEventType() == wxEVT_COMMAND_TREE_SEL_CHANGING) { - ev.Skip(); - return; + + // on OK, save the accels in gopts + void Set(wxCommandEvent &ev) + { + // opts.cpp assumes that gopts.accels entries with same command ID + // are contiguous, so sort first + std::sort(gopts.accels.begin(), gopts.accels.end(), cmdid_lt); + gopts.accels = user_accels; + wxGetApp().frame->set_global_accels(); + ev.Skip(); } - lb->Clear(); - remb->Enable(false); - asb->Enable(!key->GetValue().empty()); - int cmd = id->val; - for(int i = 0; i < accels.size(); i++) - if(accels[i].GetCommand() == cmdtab[cmd].cmd_id) - lb->Append(wxKeyTextCtrl::ToString(accels[i].GetFlags(), - accels[i].GetKeyCode())); - } + // After selecting item in command list, fill in key list + // and maybe enable asb + void CommandSel(wxTreeEvent &ev) + { + // wxTreeCtrl *tc = wxStaticCast(evt.GetEventObject(), wxTreeCtrl); + // can't use wxStaticCast; wxTreeItemData does not derive from wxObject + const TreeInt* id = static_cast(tc->GetItemData(ev.GetItem())); - // after selecting a key in key list, enable Remove button - void KeySel(wxCommandEvent &ev) - { - remb->Enable(lb->GetSelection() != wxNOT_FOUND); - } + if (!id) + { + ev.Veto(); + return; + } - // remove selected binding - void Remove(wxCommandEvent &ev) - { - int lsel = lb->GetSelection(); - if(lsel == wxNOT_FOUND) - return; - wxString selstr = lb->GetString(lsel); - int selmod, selkey; - if(!wxKeyTextCtrl::FromString(selstr, selmod, selkey)) - return; // this should never happen - remb->Enable(false); - // if this key is currently in the shortcut field, clear out curas - if(selstr == key->GetValue()) - curas->SetLabel(wxT("")); - lb->Delete(lsel); - // first drop from user accels, if applicable - for(wxAcceleratorEntry_v::iterator i = user_accels.begin(); - i < user_accels.end(); i++) - if(i->GetFlags() == selmod && i->GetKeyCode() == selkey) { - user_accels.erase(i); - break; - } - // if it's a system accel, disable by assigning to NOOP - wxAcceleratorEntry_v &sys_accels = wxGetApp().frame->sys_accels; - for(int i = 0; i < sys_accels.size(); i++) - if(sys_accels[i].GetFlags() == selmod && - sys_accels[i].GetKeyCode() == selkey) { - wxAcceleratorEntry ne(selmod, selkey, XRCID("NOOP")); + if (ev.GetEventType() == wxEVT_COMMAND_TREE_SEL_CHANGING) + { + ev.Skip(); + return; + } + + lb->Clear(); + remb->Enable(false); + asb->Enable(!key->GetValue().empty()); + int cmd = id->val; + + for (int i = 0; i < accels.size(); i++) + if (accels[i].GetCommand() == cmdtab[cmd].cmd_id) + lb->Append(wxKeyTextCtrl::ToString(accels[i].GetFlags(), + accels[i].GetKeyCode())); + } + + // after selecting a key in key list, enable Remove button + void KeySel(wxCommandEvent &ev) + { + remb->Enable(lb->GetSelection() != wxNOT_FOUND); + } + + // remove selected binding + void Remove(wxCommandEvent &ev) + { + int lsel = lb->GetSelection(); + + if (lsel == wxNOT_FOUND) + return; + + wxString selstr = lb->GetString(lsel); + int selmod, selkey; + + if (!wxKeyTextCtrl::FromString(selstr, selmod, selkey)) + return; // this should never happen + + remb->Enable(false); + + // if this key is currently in the shortcut field, clear out curas + if (selstr == key->GetValue()) + curas->SetLabel(wxT("")); + + lb->Delete(lsel); + + // first drop from user accels, if applicable + for (wxAcceleratorEntry_v::iterator i = user_accels.begin(); + i < user_accels.end(); i++) + if (i->GetFlags() == selmod && i->GetKeyCode() == selkey) + { + user_accels.erase(i); + break; + } + + // if it's a system accel, disable by assigning to NOOP + wxAcceleratorEntry_v &sys_accels = wxGetApp().frame->sys_accels; + + for (int i = 0; i < sys_accels.size(); i++) + if (sys_accels[i].GetFlags() == selmod && + sys_accels[i].GetKeyCode() == selkey) + { + wxAcceleratorEntry ne(selmod, selkey, XRCID("NOOP")); + user_accels.push_back(ne); + } + + // finally, remove from accels instead of recomputing + for (wxAcceleratorEntry_v::iterator i = accels.begin(); + i < accels.end(); i++) + if (i->GetFlags() == selmod && i->GetKeyCode() == selkey) + { + accels.erase(i); + break; + } + } + + // wipe out all user bindings + void ResetAll(wxCommandEvent &ev) + { + if (user_accels.empty() || + wxMessageBox(_("This will clear all user-defined accelerators. Are you sure?"), + _("Confirm"), wxYES_NO) != wxYES) + return; + + user_accels.clear(); + accels = wxGetApp().frame->sys_accels; + tc->Unselect(); + lb->Clear(); + // rather than recomputing curas, just clear it + key->SetValue(wxT("")); + curas->SetLabel(wxT("")); + } + + // remove old key binding, add new key binding, and update GUI + void Assign(wxCommandEvent &ev) + { + wxTreeItemId csel = tc->GetSelection(); + wxString accel = key->GetValue(); + + if (!csel.IsOk() || accel.empty()) + return; + + int acmod, ackey; + + if (!wxKeyTextCtrl::FromString(accel, acmod, ackey)) + return; // this should never happen + + for (int i = 0; i < lb->GetCount(); i++) + if (lb->GetString(i) == accel) + return; // ignore attempts to add twice + + lb->Append(accel); + + // first drop from user accels, if applicable + for (wxAcceleratorEntry_v::iterator i = user_accels.begin(); + i < user_accels.end(); i++) + if (i->GetFlags() == acmod && i->GetKeyCode() == ackey) + { + user_accels.erase(i); + break; + } + + // then assign to this command + const TreeInt* id = static_cast(tc->GetItemData(csel)); + wxAcceleratorEntry ne(acmod, ackey, cmdtab[id->val].cmd_id); user_accels.push_back(ne); - } - // finally, remove from accels instead of recomputing - for(wxAcceleratorEntry_v::iterator i = accels.begin(); - i < accels.end(); i++) - if(i->GetFlags() == selmod && i->GetKeyCode() == selkey) { - accels.erase(i); - break; - } - } - - // wipe out all user bindings - void ResetAll(wxCommandEvent &ev) - { - if(user_accels.empty() || - wxMessageBox(_("This will clear all user-defined accelerators. Are you sure?"), - _("Confirm"), wxYES_NO) != wxYES) - return; - user_accels.clear(); - accels = wxGetApp().frame->sys_accels; - tc->Unselect(); - lb->Clear(); - // rather than recomputing curas, just clear it - key->SetValue(wxT("")); - curas->SetLabel(wxT("")); - } - - // remove old key binding, add new key binding, and update GUI - void Assign(wxCommandEvent &ev) - { - wxTreeItemId csel = tc->GetSelection(); - wxString accel = key->GetValue(); - if(!csel.IsOk() || accel.empty()) - return; - int acmod, ackey; - if(!wxKeyTextCtrl::FromString(accel, acmod, ackey)) - return; // this should never happen - for(int i = 0; i < lb->GetCount(); i++) - if(lb->GetString(i) == accel) - return; // ignore attempts to add twice - lb->Append(accel); - - // first drop from user accels, if applicable - for(wxAcceleratorEntry_v::iterator i = user_accels.begin(); - i < user_accels.end(); i++) - if(i->GetFlags() == acmod && i->GetKeyCode() == ackey) { - user_accels.erase(i); - break; - } - // then assign to this command - const TreeInt *id = static_cast(tc->GetItemData(csel)); - wxAcceleratorEntry ne(acmod, ackey, cmdtab[id->val].cmd_id); - user_accels.push_back(ne); - - // now assigned to this cmd... - wxString lab; - treeid_to_name(id->val, lab, tc, tc->GetRootItem()); - curas->SetLabel(lab); - - // finally, instead of recomputing accels, just append new accel - accels.push_back(ne); - } - - // update curas and maybe enable asb - void CheckKey(wxCommandEvent &ev) - { - wxString nkey = key->GetValue(); - if(nkey.empty()) { - curas->SetLabel(wxT("")); - asb->Enable(false); - return; + // now assigned to this cmd... + wxString lab; + treeid_to_name(id->val, lab, tc, tc->GetRootItem()); + curas->SetLabel(lab); + // finally, instead of recomputing accels, just append new accel + accels.push_back(ne); } - int acmod, ackey; - if(!wxKeyTextCtrl::FromString(nkey, acmod, ackey)) { - // this should never happen - key->SetValue(wxT("")); - asb->Enable(false); - return; + + // update curas and maybe enable asb + void CheckKey(wxCommandEvent &ev) + { + wxString nkey = key->GetValue(); + + if (nkey.empty()) + { + curas->SetLabel(wxT("")); + asb->Enable(false); + return; + } + + int acmod, ackey; + + if (!wxKeyTextCtrl::FromString(nkey, acmod, ackey)) + { + // this should never happen + key->SetValue(wxT("")); + asb->Enable(false); + return; + } + + asb->Enable(tc->GetSelection().IsOk()); + int cmd = -1; + + for (int i = 0; i < accels.size(); i++) + if (accels[i].GetFlags() == acmod && accels[i].GetKeyCode() == ackey) + { + int cmdid = accels[i].GetCommand(); + + for (cmd = 0; cmd < ncmds; cmd++) + if (cmdid == cmdtab[cmd].cmd_id) + break; + + break; + } + + if (cmd < 0 || cmdtab[cmd].cmd_id == XRCID("NOOP")) + { + curas->SetLabel(wxT("")); + return; + } + + wxString lab; + treeid_to_name(cmd, lab, tc, tc->GetRootItem()); + curas->SetLabel(lab); } - asb->Enable(tc->GetSelection().IsOk()); - int cmd = -1; - for(int i = 0; i < accels.size(); i++) - if(accels[i].GetFlags() == acmod && accels[i].GetKeyCode() == ackey) { - int cmdid = accels[i].GetCommand(); - for(cmd = 0; cmd < ncmds; cmd++) - if(cmdid == cmdtab[cmd].cmd_id) - break; - break; - } - if(cmd < 0 || cmdtab[cmd].cmd_id == XRCID("NOOP")) { - curas->SetLabel(wxT("")); - return; - } - wxString lab; - treeid_to_name(cmd, lab, tc, tc->GetRootItem()); - curas->SetLabel(lab); - } } accel_config_handler; // build initial accel tree control from menu -void MainFrame::add_menu_accels(wxTreeCtrl *tc, wxTreeItemId &parent, wxMenu *menu) +void MainFrame::add_menu_accels(wxTreeCtrl* tc, wxTreeItemId &parent, wxMenu* menu) { - wxMenuItemList mil = menu->GetMenuItems(); - for(wxMenuItemList::iterator mi = mil.begin(); mi != mil.end(); mi++) { - if((*mi)->IsSeparator()) { - tc->AppendItem(parent, wxT("-----")); - } else if((*mi)->IsSubMenu()) { - wxTreeItemId id = tc->AppendItem(parent, (*mi)->GetItemLabelText()); - add_menu_accels(tc, id, (*mi)->GetSubMenu()); - if((*mi)->GetSubMenu() == recent) { - for(int i = wxID_FILE1; i <= wxID_FILE10; i++) { - int cmdid; - for(cmdid = 0; cmdid < ncmds; cmdid++) - if(cmdtab[cmdid].cmd_id == i) - break; - TreeInt *val = new TreeInt(cmdid); - tc->AppendItem(id, cmdtab[cmdid].name, -1, -1, val); + wxMenuItemList mil = menu->GetMenuItems(); + + for (wxMenuItemList::iterator mi = mil.begin(); mi != mil.end(); mi++) + { + if ((*mi)->IsSeparator()) + { + tc->AppendItem(parent, wxT("-----")); } - } - } else { - int mid = (*mi)->GetId(); - if(mid >= wxID_FILE1 && mid <= wxID_FILE10) - continue; - int cmdid; - for(cmdid = 0; cmdid < ncmds; cmdid++) - if(cmdtab[cmdid].cmd_id == mid) - break; - if(cmdid == ncmds) - continue; // bad menu item; should inform user really - TreeInt *val = new TreeInt(cmdid); - // ugh. There has to be a better way... - // perhaps make XRCID ranges a requirement for load/save st? - // but then if the user overides main menu, that req. is broken.. - wxString txt = (*mi)->GetItemLabelText(); - for(int i = 0; i < 10; i++) - if(*mi == loadst_mi[i] || *mi == savest_mi[i]) { - txt = cmdtab[i].name; - break; + else if ((*mi)->IsSubMenu()) + { + wxTreeItemId id = tc->AppendItem(parent, (*mi)->GetItemLabelText()); + add_menu_accels(tc, id, (*mi)->GetSubMenu()); + + if ((*mi)->GetSubMenu() == recent) + { + for (int i = wxID_FILE1; i <= wxID_FILE10; i++) + { + int cmdid; + + for (cmdid = 0; cmdid < ncmds; cmdid++) + if (cmdtab[cmdid].cmd_id == i) + break; + + TreeInt* val = new TreeInt(cmdid); + tc->AppendItem(id, cmdtab[cmdid].name, -1, -1, val); + } + } + } + else + { + int mid = (*mi)->GetId(); + + if (mid >= wxID_FILE1 && mid <= wxID_FILE10) + continue; + + int cmdid; + + for (cmdid = 0; cmdid < ncmds; cmdid++) + if (cmdtab[cmdid].cmd_id == mid) + break; + + if (cmdid == ncmds) + continue; // bad menu item; should inform user really + + TreeInt* val = new TreeInt(cmdid); + // ugh. There has to be a better way... + // perhaps make XRCID ranges a requirement for load/save st? + // but then if the user overides main menu, that req. is broken.. + wxString txt = (*mi)->GetItemLabelText(); + + for (int i = 0; i < 10; i++) + if (*mi == loadst_mi[i] || *mi == savest_mi[i]) + { + txt = cmdtab[i].name; + break; + } + + tc->AppendItem(parent, txt, -1, -1, val); } - tc->AppendItem(parent, txt, -1, -1, val); } - } } // manage throttle spinctrl/canned setting choice interaction static class ThrottleCtrl_t : public wxEvtHandler { public: - wxSpinCtrl *thr; - wxChoice *thrsel; + wxSpinCtrl* thr; + wxChoice* thrsel; - // set thrsel from thr - void SetThrottleSel(wxSpinEvent &evt) - { - DoSetThrottleSel(thr->GetValue()); - } - - void DoSetThrottleSel(int val) - { - switch(val) { - case 0: - thrsel->SetSelection(1); - break; - case 25: - thrsel->SetSelection(2); - break; - case 50: - thrsel->SetSelection(3); - break; - case 100: - thrsel->SetSelection(4); - break; - case 150: - thrsel->SetSelection(5); - break; - case 200: - thrsel->SetSelection(6); - break; - default: - thrsel->SetSelection(0); - break; + // set thrsel from thr + void SetThrottleSel(wxSpinEvent &evt) + { + DoSetThrottleSel(thr->GetValue()); } - } - // set thr from thrsel - void SetThrottle(wxCommandEvent &evt) - { - switch(thrsel->GetSelection()) { - case 0: // blank; leave it alone - break; - case 1: - thr->SetValue(0); - break; - case 2: - thr->SetValue(25); - break; - case 3: - thr->SetValue(50); - break; - case 4: - thr->SetValue(100); - break; - case 5: - thr->SetValue(150); - break; - case 6: - thr->SetValue(200); - break; + void DoSetThrottleSel(int val) + { + switch (val) + { + case 0: + thrsel->SetSelection(1); + break; + + case 25: + thrsel->SetSelection(2); + break; + + case 50: + thrsel->SetSelection(3); + break; + + case 100: + thrsel->SetSelection(4); + break; + + case 150: + thrsel->SetSelection(5); + break; + + case 200: + thrsel->SetSelection(6); + break; + + default: + thrsel->SetSelection(0); + break; + } } - } - // since this is not the actual dialog, derived from wxDialog, which is - // the normal way of doing things, do init on the show event instead of - // constructor - // could've also used a validator, I guess... - void Init(wxShowEvent &ev) - { - ev.Skip(); - DoSetThrottleSel(throttle); - } + // set thr from thrsel + void SetThrottle(wxCommandEvent &evt) + { + switch (thrsel->GetSelection()) + { + case 0: // blank; leave it alone + break; + + case 1: + thr->SetValue(0); + break; + + case 2: + thr->SetValue(25); + break; + + case 3: + thr->SetValue(50); + break; + + case 4: + thr->SetValue(100); + break; + + case 5: + thr->SetValue(150); + break; + + case 6: + thr->SetValue(200); + break; + } + } + + // since this is not the actual dialog, derived from wxDialog, which is + // the normal way of doing things, do init on the show event instead of + // constructor + // could've also used a validator, I guess... + void Init(wxShowEvent &ev) + { + ev.Skip(); + DoSetThrottleSel(throttle); + } } throttle_ctrl; ///////////////////////////// //Check if a pointer from the XRC file is valid. If it's not, throw an error telling the user. template -void CheckThrowXRCError(T pointer,std::string name) +void CheckThrowXRCError(T pointer, std::string name) { - if(pointer == NULL) + if (pointer == NULL) { std::string errormessage = "Unable to load a \""; - errormessage+=typeid(pointer).name(); - errormessage+="\" from the builtin xrc file: "; - errormessage+=name; + errormessage += typeid(pointer).name(); + errormessage += "\" from the builtin xrc file: "; + errormessage += name; throw std::runtime_error(errormessage); } } -wxDialog * MainFrame::LoadXRCDialog(const char * name) +wxDialog* MainFrame::LoadXRCDialog(const char* name) { wxString dname = wxString::FromUTF8(name); - wxDialog * dialog = wxXmlResource::Get()->LoadDialog(this, dname); - CheckThrowXRCError(dialog,name); - + wxDialog* dialog = wxXmlResource::Get()->LoadDialog(this, dname); + CheckThrowXRCError(dialog, name); /* wx-2.9.1 doesn't set parent for propertysheetdialogs for some reason */ /* this will generate a gtk warning but it is necessary for later */ /* retrieval using FindWindow() */ #if (wxMAJOR_VERSION < 3) - if(!dialog->GetParent()) + + if (!dialog->GetParent()) dialog->Reparent(this); + #endif mark_recursive(dialog); return dialog; } -wxDialog * MainFrame::LoadXRCropertySheetDialog(const char * name) +wxDialog* MainFrame::LoadXRCropertySheetDialog(const char* name) { wxString dname = wxString::FromUTF8(name); //Seems like the only way to do this - wxObject * anObject = wxXmlResource::Get()->LoadObject(this, dname, wxEmptyString); - wxDialog * dialog = dynamic_cast(anObject); - CheckThrowXRCError(dialog,name); - + wxObject* anObject = wxXmlResource::Get()->LoadObject(this, dname, wxEmptyString); + wxDialog* dialog = dynamic_cast(anObject); + CheckThrowXRCError(dialog, name); /* wx-2.9.1 doesn't set parent for propertysheetdialogs for some reason */ /* this will generate a gtk warning but it is necessary for later */ /* retrieval using FindWindow() */ #if (wxMAJOR_VERSION < 3) - if(!dialog->GetParent()) + + if (!dialog->GetParent()) dialog->Reparent(this); + #endif mark_recursive(dialog); return dialog; @@ -2018,119 +2447,143 @@ wxDialog * MainFrame::LoadXRCropertySheetDialog(const char * name) //This just adds some error checking to the wx XRCCTRL macro template -T * SafeXRCCTRL( wxWindow *parent,const char * name) +T* SafeXRCCTRL(wxWindow* parent, const char* name) { wxString dname = wxString::FromUTF8(name); //This is needed to work around a bug in XRCCTRL - wxString Ldname=dname; - T * output = XRCCTRL(*parent, dname, T); - CheckThrowXRCError(output,name); + wxString Ldname = dname; + T* output = XRCCTRL(*parent, dname, T); + CheckThrowXRCError(output, name); return output; } ///Get an object, and set the appropriate validator //T is the object type, and V is the validator type -template -T * GetValidatedChild(wxWindow *parent,const char * name, V validator) +template +T* GetValidatedChild(wxWindow* parent, const char* name, V validator) { - T * child = SafeXRCCTRL(parent, name); + T* child = SafeXRCCTRL(parent, name); child->SetValidator(validator); return child; } wxAcceleratorEntry_v MainFrame::get_accels(wxAcceleratorEntry_v user_accels) { - // set global accelerators - // first system - wxAcceleratorEntry_v accels = sys_accels; - // then user overrides - // silently keep only last defined binding - // same horribly inefficent O(n*m) search for duplicates as above.. - for(int i = 0; i < user_accels.size(); i++) { - const wxAcceleratorEntry &ae = user_accels[i]; - for(wxAcceleratorEntry_v::iterator e = accels.begin(); e < accels.end(); e++) - if(ae.GetFlags() == e->GetFlags() && - ae.GetKeyCode() == e->GetKeyCode()) { - accels.erase(e); - break; - } - accels.push_back(ae); - } - return accels; + // set global accelerators + // first system + wxAcceleratorEntry_v accels = sys_accels; + + // then user overrides + // silently keep only last defined binding + // same horribly inefficent O(n*m) search for duplicates as above.. + for (int i = 0; i < user_accels.size(); i++) + { + const wxAcceleratorEntry &ae = user_accels[i]; + + for (wxAcceleratorEntry_v::iterator e = accels.begin(); e < accels.end(); e++) + if (ae.GetFlags() == e->GetFlags() && + ae.GetKeyCode() == e->GetKeyCode()) + { + accels.erase(e); + break; + } + + accels.push_back(ae); + } + + return accels; } void MainFrame::set_global_accels() { - wxAcceleratorEntry_v accels = get_accels(gopts.accels); + wxAcceleratorEntry_v accels = get_accels(gopts.accels); + // this is needed on Wine/win32 to support accels for close & quit + wxGetApp().accels = accels; - // this is needed on Wine/win32 to support accels for close & quit - wxGetApp().accels = accels; + // Update menus; this probably takes the longest + // as a side effect, any system-defined accels that weren't already in + // the menus will be added now - // Update menus; this probably takes the longest - // as a side effect, any system-defined accels that weren't already in - // the menus will be added now + // first, zero out menu item on all accels + for (int i = 0; i < accels.size(); i++) + accels[i].Set(accels[i].GetFlags(), accels[i].GetKeyCode(), + accels[i].GetCommand()); - // first, zero out menu item on all accels - for(int i = 0; i < accels.size(); i++) - accels[i].Set(accels[i].GetFlags(), accels[i].GetKeyCode(), - accels[i].GetCommand()); + // yet another O(n*m) loop. I really ought to sort the accel arrays + for (int i = 0; i < ncmds; i++) + { + wxMenuItem* mi = cmdtab[i].mi; - // yet another O(n*m) loop. I really ought to sort the accel arrays - for(int i = 0; i < ncmds; i++) { - wxMenuItem *mi = cmdtab[i].mi; - if(!mi) - continue; - // only *last* accelerator is made visible in menu - // and is flagged as such by setting menu item in accel - // the last is chosen so menu overrides non-menu and user overrides - // system - int cmd = cmdtab[i].cmd_id; - int last_accel = -1; - for(int j = 0; j < accels.size(); j++) - if(cmd == accels[j].GetCommand()) - last_accel = j; - if(last_accel >= 0) { - DoSetAccel(mi, &accels[last_accel]); - accels[last_accel].Set(accels[last_accel].GetFlags(), - accels[last_accel].GetKeyCode(), - accels[last_accel].GetCommand(), mi); - } else - // clear out user-cleared menu items - DoSetAccel(mi, NULL); - } - // Finally, install a global accelerator table for any non-menu accels - int len = 0; - for(int i = 0; i < accels.size(); i++) - if(!accels[i].GetMenuItem()) - len++; - if(len) { - wxAcceleratorEntry tab[1000]; - for(int i = 0, j = 0; i < accels.size(); i++) - if(!accels[i].GetMenuItem()) - tab[j++] = accels[i]; - wxAcceleratorTable atab(len, tab); - // set the table on the panel, where focus usually is - // otherwise accelerators are lost sometimes - panel->SetAcceleratorTable(atab); - } else - panel->SetAcceleratorTable(wxNullAcceleratorTable); + if (!mi) + continue; - // save recent accels - for(int i = 0; i < 10; i++) - recent_accel[i] = wxAcceleratorEntry(); - for(int i = 0; i < accels.size(); i++) - if(accels[i].GetCommand() >= wxID_FILE1 && - accels[i].GetCommand() <= wxID_FILE10) - recent_accel[accels[i].GetCommand() - wxID_FILE1] = accels[i]; - SetRecentAccels(); + // only *last* accelerator is made visible in menu + // and is flagged as such by setting menu item in accel + // the last is chosen so menu overrides non-menu and user overrides + // system + int cmd = cmdtab[i].cmd_id; + int last_accel = -1; + + for (int j = 0; j < accels.size(); j++) + if (cmd == accels[j].GetCommand()) + last_accel = j; + + if (last_accel >= 0) + { + DoSetAccel(mi, &accels[last_accel]); + accels[last_accel].Set(accels[last_accel].GetFlags(), + accels[last_accel].GetKeyCode(), + accels[last_accel].GetCommand(), mi); + } + else + // clear out user-cleared menu items + DoSetAccel(mi, NULL); + } + + // Finally, install a global accelerator table for any non-menu accels + int len = 0; + + for (int i = 0; i < accels.size(); i++) + if (!accels[i].GetMenuItem()) + len++; + + if (len) + { + wxAcceleratorEntry tab[1000]; + + for (int i = 0, j = 0; i < accels.size(); i++) + if (!accels[i].GetMenuItem()) + tab[j++] = accels[i]; + + wxAcceleratorTable atab(len, tab); + // set the table on the panel, where focus usually is + // otherwise accelerators are lost sometimes + panel->SetAcceleratorTable(atab); + } + else + panel->SetAcceleratorTable(wxNullAcceleratorTable); + + // save recent accels + for (int i = 0; i < 10; i++) + recent_accel[i] = wxAcceleratorEntry(); + + for (int i = 0; i < accels.size(); i++) + if (accels[i].GetCommand() >= wxID_FILE1 && + accels[i].GetCommand() <= wxID_FILE10) + recent_accel[accels[i].GetCommand() - wxID_FILE1] = accels[i]; + + SetRecentAccels(); } void MainFrame::MenuOptionBool(const char* menuName, bool &field) { int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8)); - for (int i = 0; i < checkable_mi.size(); i++) { + + for (int i = 0; i < checkable_mi.size(); i++) + { if (checkable_mi[i].cmd != id) continue; + checkable_mi[i].boolopt = &field; checkable_mi[i].mi->Check(field); break; @@ -2141,9 +2594,12 @@ void MainFrame::MenuOptionIntMask(const char* menuName, int &field, int mask) { int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8)); int value = mask; - for (int i = 0; i < checkable_mi.size(); i++) { + + for (int i = 0; i < checkable_mi.size(); i++) + { if (checkable_mi[i].cmd != id) continue; + checkable_mi[i].intopt = &field; checkable_mi[i].mask = mask; checkable_mi[i].val = value; @@ -2155,9 +2611,12 @@ void MainFrame::MenuOptionIntMask(const char* menuName, int &field, int mask) void MainFrame::MenuOptionIntRadioValue(const char* menuName, int &field, int value) { int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8)); - for (int i = 0; i < checkable_mi.size(); i++) { + + for (int i = 0; i < checkable_mi.size(); i++) + { if (checkable_mi[i].cmd != id) continue; + checkable_mi[i].intopt = &field; checkable_mi[i].val = field; checkable_mi[i].mi->Check(field == value); @@ -2174,26 +2633,29 @@ bool MainFrame::BindControls() { // Make sure display panel present and correct type panel = XRCCTRL(*this, "DisplayArea", GameArea); - if (!panel) { + + if (!panel) + { wxLogError(_("Main display panel not found")); return false; } - panel->AdjustSize(false); + panel->AdjustSize(false); // only the panel does idle events (the emulator loop) // however, do not enable until end of init, since errors will start // the idle loop on wxGTK wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED); - // could/should probably take this from xrc as well // but I don't think xrc supports icon from Windows resource wxIcon icon = wxXmlResource::Get()->LoadIcon(wxT("MainIcon")); - if (!icon.IsOk()) { + + if (!icon.IsOk()) + { wxLogInfo(_("Main icon not found")); icon = wxICON(wxvbam); } - SetIcon(icon); + SetIcon(icon); // NOOP if no status area SetStatusText(_("")); @@ -2201,11 +2663,11 @@ bool MainFrame::BindControls() for (int i = 0; i < num_def_accels; i++) sys_accels.push_back(default_accels[i]); - - - wxMenuBar *menubar = GetMenuBar(); + wxMenuBar* menubar = GetMenuBar(); ctx_menu = NULL; - if (menubar) { + + if (menubar) + { #if 0 // doesn't work in 2.9 at all (causes main menu to malfunction) // to fix, recursively copy entire menu insted of just copying // menubar. This means that every saved menu item must also be @@ -2213,7 +2675,6 @@ bool MainFrame::BindControls() // If you want the menu, just exit full-screen mode. // Either that, or add an option to retain the regular // menubar in full-screen mode - // create a context menu for fullscreen mode // FIXME: on gtk port, this gives Gtk-WARNING **: // gtk_menu_attach_to_widget(): menu already attached to GtkMenuItem @@ -2228,52 +2689,69 @@ bool MainFrame::BindControls() // Maybe this feature should just be dropped; the user would simply // have to exit fullscreen mode to use the menu. ctx_menu = new wxMenu(); + for (int i = 0; i < menubar->GetMenuCount(); i++) ctx_menu->AppendSubMenu(menubar->GetMenu(i), menubar->GetMenuLabel(i)); + #endif // save all menu items in the command table - for (int i = 0; i < ncmds; i++) { - wxMenuItem *mi = cmdtab[i].mi = XRCITEM_I(cmdtab[i].cmd_id); + for (int i = 0; i < ncmds; i++) + { + wxMenuItem* mi = cmdtab[i].mi = XRCITEM_I(cmdtab[i].cmd_id); // remove unsupported commands first #ifdef NO_FFMPEG - if (cmdtab[i].mask_flags & (CMDEN_SREC | CMDEN_NSREC | CMDEN_VREC | CMDEN_NVREC)) { + + if (cmdtab[i].mask_flags & (CMDEN_SREC | CMDEN_NSREC | CMDEN_VREC | CMDEN_NVREC)) + { if (mi) mi->GetMenu()->Remove(mi); + cmdtab[i].cmd_id = XRCID("NOOP"); cmdtab[i].mi = NULL; continue; } + #endif #ifndef GBA_LOGGING - if (cmdtab[i].cmd_id == XRCID("Logging")) { + + if (cmdtab[i].cmd_id == XRCID("Logging")) + { if (mi) mi->GetMenu()->Remove(mi); + cmdtab[i].cmd_id = XRCID("NOOP"); cmdtab[i].mi = NULL; continue; } + #endif #ifdef NO_LINK + if (cmdtab[i].cmd_id == XRCID("LanLink") || - cmdtab[i].cmd_id == XRCID("LinkType0Nothing") || - cmdtab[i].cmd_id == XRCID("LinkType1Cable") || - cmdtab[i].cmd_id == XRCID("LinkType2Wireless") || - cmdtab[i].cmd_id == XRCID("LinkType3GameCube") || - cmdtab[i].cmd_id == XRCID("LinkType4Gameboy") || - cmdtab[i].cmd_id == XRCID("LinkAuto") || - cmdtab[i].cmd_id == XRCID("SpeedOn") || - cmdtab[i].cmd_id == XRCID("LinkProto") || - cmdtab[i].cmd_id == XRCID("LinkConfigure") - ) { + cmdtab[i].cmd_id == XRCID("LinkType0Nothing") || + cmdtab[i].cmd_id == XRCID("LinkType1Cable") || + cmdtab[i].cmd_id == XRCID("LinkType2Wireless") || + cmdtab[i].cmd_id == XRCID("LinkType3GameCube") || + cmdtab[i].cmd_id == XRCID("LinkType4Gameboy") || + cmdtab[i].cmd_id == XRCID("LinkAuto") || + cmdtab[i].cmd_id == XRCID("SpeedOn") || + cmdtab[i].cmd_id == XRCID("LinkProto") || + cmdtab[i].cmd_id == XRCID("LinkConfigure") + ) + { if (mi) mi->GetMenu()->Remove(mi); + cmdtab[i].cmd_id = XRCID("NOOP"); cmdtab[i].mi = NULL; continue; } + #endif - if (mi) { + + if (mi) + { // wxgtk provides no way to retrieve stock label/accel // and does not override wxGetStockLabel() // as of 2.8.12/2.9.1 @@ -2281,40 +2759,52 @@ bool MainFrame::BindControls() // at least you still get gtk's stock icon if (mi->GetItemLabel().empty()) mi->SetItemLabel(wxGetStockLabel(mi->GetId(), - wxSTOCK_WITH_MNEMONIC | wxSTOCK_WITH_ACCELERATOR)); + wxSTOCK_WITH_MNEMONIC | wxSTOCK_WITH_ACCELERATOR)); // add accelerator to global accel table - wxAcceleratorEntry *a = mi->GetAccel(); - if (a) { + wxAcceleratorEntry* a = mi->GetAccel(); + + if (a) + { a->Set(a->GetFlags(), a->GetKeyCode(), cmdtab[i].cmd_id, mi); + // only add it if not already there for (wxAcceleratorEntry_v::iterator e = sys_accels.begin(); - e < sys_accels.end(); e++) + e < sys_accels.end(); e++) if (a->GetFlags() == e->GetFlags() && - a->GetKeyCode() == e->GetKeyCode()) { - if (e->GetMenuItem()) { + a->GetKeyCode() == e->GetKeyCode()) + { + if (e->GetMenuItem()) + { wxLogInfo(_("Duplicate menu accelerator: %s for %s and %s; keeping first"), - wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).c_str(), - e->GetMenuItem()->GetItemLabelText().c_str(), - mi->GetItemLabelText().c_str()); + wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).c_str(), + e->GetMenuItem()->GetItemLabelText().c_str(), + mi->GetItemLabelText().c_str()); delete a; a = 0; } - else { - if (e->GetCommand() != a->GetCommand()) { + else + { + if (e->GetCommand() != a->GetCommand()) + { int cmd; + for (cmd = 0; cmd < ncmds; cmd++) if (cmdtab[cmd].cmd_id == e->GetCommand()) break; + wxLogInfo(_("Menu accelerator %s for %s overrides default for %s ; keeping menu"), - wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).c_str(), - mi->GetItemLabelText().c_str(), - cmdtab[cmd].cmd); + wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).c_str(), + mi->GetItemLabelText().c_str(), + cmdtab[cmd].cmd); } + sys_accels.erase(e); } + break; } + if (a) sys_accels.push_back(*a); else @@ -2323,13 +2813,15 @@ bool MainFrame::BindControls() } // store checkable items - if (mi->IsCheckable()) { + if (mi->IsCheckable()) + { checkable_mi_t cmi = { cmdtab[i].cmd_id, mi }; checkable_mi.push_back(cmi); for (int j = 0; j < num_opts; j++) { wxString menuName = wxString(opts[j].cmd, wxConvUTF8); + if (menuName == cmdtab[i].cmd) { if (opts[j].intopt) @@ -2343,16 +2835,20 @@ bool MainFrame::BindControls() } // if a recent menu is present, save its location - wxMenuItem *recentmi = XRCITEM("RecentMenu"); - if (recentmi && recentmi->IsSubMenu()) { + wxMenuItem* recentmi = XRCITEM("RecentMenu"); + + if (recentmi && recentmi->IsSubMenu()) + { recent = recentmi->GetSubMenu(); gopts.recent->UseMenu(recent); gopts.recent->AddFilesToMenu(); } else recent = NULL; + // if save/load state menu items present, save their locations - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; i++) + { wxString n; n.Printf(wxT("LoadGame%02d"), i + 1); loadst_mi[i] = XRCITEM_D(n); @@ -2360,11 +2856,14 @@ bool MainFrame::BindControls() savest_mi[i] = XRCITEM_D(n); } } - else { + else + { recent = NULL; + for (int i = 0; i < 10; i++) loadst_mi[i] = savest_mi[i] = NULL; } + // just setting to UNLOAD_CMDEN_KEEP is invalid // so just set individual flags here cmd_enable = CMDEN_NGDB_ANY | CMDEN_NREC_ANY; @@ -2372,7 +2871,8 @@ bool MainFrame::BindControls() // set pointers for checkable menu items // and set initial checked status - if (checkable_mi.size()) { + if (checkable_mi.size()) + { MenuOptionBool("RecentFreeze", gopts.recent_freeze); MenuOptionBool("Pause", paused); MenuOptionIntMask("SoundChannel1", gopts.sound_en, (1 << 0)); @@ -2399,17 +2899,18 @@ bool MainFrame::BindControls() MenuOptionIntMask("JoypadAutofireL", autofire, KEYM_LEFT); MenuOptionIntMask("JoypadAutofireR", autofire, KEYM_RIGHT); MenuOptionBool("EmulatorSpeedupToggle", turbo); - MenuOptionIntRadioValue("LinkType0Nothing", gopts.gba_link_type, 0); MenuOptionIntRadioValue("LinkType1Cable", gopts.gba_link_type, 1); MenuOptionIntRadioValue("LinkType2Wireless", gopts.gba_link_type, 2); MenuOptionIntRadioValue("LinkType3GameCube", gopts.gba_link_type, 3); MenuOptionIntRadioValue("LinkType4Gameboy", gopts.gba_link_type, 4); } + for (int i = 0; i < checkable_mi.size(); i++) - if (!checkable_mi[i].boolopt && !checkable_mi[i].intopt) { + if (!checkable_mi[i].boolopt && !checkable_mi[i].intopt) + { wxLogError(_("Invalid menu item %s; removing"), - checkable_mi[i].mi->GetItemLabelText().c_str()); + checkable_mi[i].mi->GetItemLabelText().c_str()); checkable_mi[i].mi->GetMenu()->Remove(checkable_mi[i].mi); checkable_mi[i].mi = NULL; } @@ -2421,26 +2922,26 @@ bool MainFrame::BindControls() // note that the only verification done is to ensure no crashes. It's the // user's responsibility to ensure that the GUI works as intended after // modifications - try { - - wxDialog *d = NULL; - + try + { + wxDialog* d = NULL; //// displayed during run d = LoadXRCDialog("GBPrinter"); // just verify preview window & mag sel present { - wxPanel *prev; + wxPanel* prev; prev = SafeXRCCTRL(d, "Preview"); + if (!wxDynamicCast(prev->GetParent(), wxScrolledWindow)) throw std::runtime_error("Unable to load a dialog control from the builtin xrc file: Preview"); + SafeXRCCTRL(d, "Magnification"); d->Fit(); } - //// File menu d = LoadXRCDialog("GBAROMInfo"); // just verify fields present - wxControl *lab; + wxControl* lab; #define getlab(n) lab=SafeXRCCTRL(d, n) getlab("Title"); getlab("GameCode"); @@ -2451,7 +2952,6 @@ bool MainFrame::BindControls() getlab("Version"); getlab("CRC"); d->Fit(); - d = LoadXRCDialog("GBROMInfo"); // just verify fields present getlab("Title"); @@ -2468,38 +2968,35 @@ bool MainFrame::BindControls() getlab("LicCode"); getlab("Checksum"); d->Fit(); - d = LoadXRCDialog("CodeSelect"); // just verify list present SafeXRCCTRL(d, "CodeList"); d->Fit(); - d = LoadXRCDialog("ExportSPS"); // just verify text fields present SafeXRCCTRL(d, "Title"); SafeXRCCTRL(d, "Description"); SafeXRCCTRL(d, "Notes"); d->Fit(); - //// Emulation menu #ifndef NO_LINK d = LoadXRCDialog("NetLink"); #endif - wxRadioButton *rb; + wxRadioButton* rb; #define getrbi(n, o, v) do { \ rb=SafeXRCCTRL(d, n); \ rb->SetValidator(wxBoolIntValidator(&o, v)); \ - } while(0) + } while(0) #define getrbb(n, o) do { \ rb=SafeXRCCTRL(d, n); \ rb->SetValidator(wxGenericValidator(&o)); \ - } while(0) + } while(0) #define getrbbr(n, o) do { \ rb=SafeXRCCTRL(d, n); \ rb->SetValidator(wxBoolRevValidator(&o)); \ - } while(0) - wxBoolEnValidator *benval; - wxBoolEnHandler *ben; + } while(0) + wxBoolEnValidator* benval; + wxBoolEnHandler* ben; #define getbe(n, o, cv, t, wt) do { \ cv=SafeXRCCTRL(d, n); \ cv->SetValidator(wxBoolEnValidator(&o)); \ @@ -2507,42 +3004,42 @@ bool MainFrame::BindControls() static wxBoolEnHandler _ben; \ ben = &_ben; \ wx##wt##BoolEnHandlerConnect(cv, wxID_ANY, _ben); \ - } while(0) + } while(0) // brenval & friends are here just to allow yes/no radioboxes in place // of checkboxes. A lot of work for little benefit. - wxBoolRevEnValidator *brenval; + wxBoolRevEnValidator* brenval; #define getbre(n, o, cv, t, wt) do { \ cv=SafeXRCCTRL(d, n); \ cv->SetValidator(wxBoolRevEnValidator(&o)); \ brenval = wxStaticCast(cv->GetValidator(), wxBoolRevEnValidator); \ wx##wt##BoolEnHandlerConnect(rb, wxID_ANY, *ben); \ - } while(0) + } while(0) #define addbe(n) do { \ ben->controls.push_back(n); \ benval->controls.push_back(n); \ - } while(0) + } while(0) #define addrbe(n) do { \ addbe(n); \ brenval->controls.push_back(n); \ - } while(0) + } while(0) #define addber(n, r) do { \ ben->controls.push_back(n); \ ben->reverse.push_back(r); \ benval->controls.push_back(n); \ benval->reverse.push_back(r); \ - } while(0) + } while(0) #define addrber(n, r) do { \ addber(n, r); \ brenval->controls.push_back(n); \ brenval->reverse.push_back(r); \ - } while(0) + } while(0) #define getrbbe(n, o) getbe(n, o, rb, wxRadioButton, RBE) #define getrbbd(n, o) getbre(n, o, rb, wxRadioButton, RBD) - wxTextCtrl *tc; + wxTextCtrl* tc; #define gettc(n, o) do { \ tc=SafeXRCCTRL(d, n); \ tc->SetValidator(wxTextValidator(wxFILTER_NONE, &o)); \ - } while(0) + } while(0) #ifndef NO_LINK { net_link_handler.dlg = d; @@ -2561,32 +3058,36 @@ bool MainFrame::BindControls() addrber(lab, true); gettc("ServerIP", gopts.link_host); addrber(tc, true); - wxWindow *okb = d->FindWindow(wxID_OK); - if (okb) { // may be gone if style guidlines removed it + wxWindow* okb = d->FindWindow(wxID_OK); + + if (okb) // may be gone if style guidlines removed it + { net_link_handler.okb = wxStaticCast(okb, wxButton); d->Connect(XRCID("Server"), wxEVT_COMMAND_RADIOBUTTON_SELECTED, - wxCommandEventHandler(NetLink_t::ServerOKButton), - NULL, &net_link_handler); + wxCommandEventHandler(NetLink_t::ServerOKButton), + NULL, &net_link_handler); d->Connect(XRCID("Client"), wxEVT_COMMAND_RADIOBUTTON_SELECTED, - wxCommandEventHandler(NetLink_t::ClientOKButton), - NULL, &net_link_handler); + wxCommandEventHandler(NetLink_t::ClientOKButton), + NULL, &net_link_handler); } + // this should intercept wxID_OK before the dialog handler gets it d->Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, - wxCommandEventHandler(NetLink_t::NetConnect), - NULL, &net_link_handler); + wxCommandEventHandler(NetLink_t::NetConnect), + NULL, &net_link_handler); d->Fit(); } #endif - d = LoadXRCDialog("CheatList"); { cheat_list_handler.dlg = d; d->SetEscapeId(wxID_OK); - wxCheckedListCtrl *cl; + wxCheckedListCtrl* cl; cl = SafeXRCCTRL(d, "Cheats"); + if (!cl->Init()) throw std::runtime_error("Unable to initialize the Cheats dialog control from the builtin xrc file!"); + cheat_list_handler.list = cl; cl->SetValidator(CheatListFill()); cl->InsertColumn(0, _("Code")); @@ -2595,7 +3096,7 @@ bool MainFrame::BindControls() wxFont of = cl->GetFont(); // of.SetFamily(wxFONTFAMILY_MODERN); // doesn't work (no font change) wxFont f(of.GetPointSize(), wxFONTFAMILY_MODERN, of.GetStyle(), - of.GetWeight()); + of.GetWeight()); cheat_list_handler.item0.SetFont(f); cheat_list_handler.item0.SetColumn(0); cl->InsertColumn(1, _("Description")); @@ -2638,24 +3139,22 @@ bool MainFrame::BindControls() } cl->SetColumnWidth(0, w); #endif - d->Connect(wxEVT_COMMAND_TOOL_CLICKED, - wxCommandEventHandler(CheatList_t::Tool), - NULL, &cheat_list_handler); + wxCommandEventHandler(CheatList_t::Tool), + NULL, &cheat_list_handler); d->Connect(wxEVT_COMMAND_LIST_ITEM_CHECKED, - wxListEventHandler(CheatList_t::Check), - NULL, &cheat_list_handler); + wxListEventHandler(CheatList_t::Check), + NULL, &cheat_list_handler); d->Connect(wxEVT_COMMAND_LIST_ITEM_UNCHECKED, - wxListEventHandler(CheatList_t::UnCheck), - NULL, &cheat_list_handler); + wxListEventHandler(CheatList_t::UnCheck), + NULL, &cheat_list_handler); d->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, - wxListEventHandler(CheatList_t::Edit), - NULL, &cheat_list_handler); + wxListEventHandler(CheatList_t::Edit), + NULL, &cheat_list_handler); d->Fit(); } - d = LoadXRCDialog("CheatEdit"); - wxChoice *ch; + wxChoice* ch; { // d->Reparent(cheat_list_handler.dlg); // broken ch = GetValidatedChild(d, "Type", wxGenericValidator(&cheat_list_handler.ce_type)); @@ -2666,12 +3165,11 @@ bool MainFrame::BindControls() cheat_list_handler.ce_codes_tc = tc; d->Fit(); } - d = LoadXRCDialog("CheatCreate"); { cheat_find_handler.dlg = d; d->SetEscapeId(wxID_OK); - CheatListCtrl *list; + CheatListCtrl* list; list = SafeXRCCTRL(d, "CheatList"); cheat_find_handler.list = list; list->SetValidator(CheatFindFill()); @@ -2686,8 +3184,8 @@ bool MainFrame::BindControls() getrbi("GE", cheat_find_handler.op, SEARCH_GE); #define cf_make_update() \ rb->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, \ - wxCommandEventHandler(CheatFind_t::UpdateView), \ - NULL, &cheat_find_handler) + wxCommandEventHandler(CheatFind_t::UpdateView), \ + NULL, &cheat_find_handler) getrbi("Size8", cheat_find_handler.size, BITS_8); cf_make_update(); getrbi("Size16", cheat_find_handler.size, BITS_16); @@ -2702,8 +3200,8 @@ bool MainFrame::BindControls() cf_make_update(); #define cf_make_valen() \ rb->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, \ - wxCommandEventHandler(CheatFind_t::EnableVal), \ - NULL, &cheat_find_handler) + wxCommandEventHandler(CheatFind_t::EnableVal), \ + NULL, &cheat_find_handler) getrbi("OldValue", cheat_find_handler.valsrc, 1); cf_make_valen(); cheat_find_handler.old_rb = rb; @@ -2716,12 +3214,12 @@ bool MainFrame::BindControls() wxStaticCast(tc->GetValidator(), wxTextValidator)->SetStyle(wxFILTER_INCLUDE_CHAR_LIST); #define cf_button(n, f) \ d->Connect(XRCID(n), wxEVT_COMMAND_BUTTON_CLICKED, \ - wxCommandEventHandler(CheatFind_t::f), \ - NULL, &cheat_find_handler); + wxCommandEventHandler(CheatFind_t::f), \ + NULL, &cheat_find_handler); #define cf_enbutton(n, v) do { \ cheat_find_handler.v=SafeXRCCTRL(d, n); \ cheat_find_handler.v->Disable(); \ - } while(0) + } while(0) cf_button("Search", Search); cf_button("Update", UpdateVals); cf_enbutton("Update", update_b); @@ -2730,14 +3228,13 @@ bool MainFrame::BindControls() cf_button("AddCheat", AddCheatB); cf_enbutton("AddCheat", add_b); d->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, - wxListEventHandler(CheatFind_t::AddCheatL), - NULL, &cheat_find_handler); + wxListEventHandler(CheatFind_t::AddCheatL), + NULL, &cheat_find_handler); d->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, - wxListEventHandler(CheatFind_t::Select), - NULL, &cheat_find_handler); + wxListEventHandler(CheatFind_t::Select), + NULL, &cheat_find_handler); d->Fit(); } - d = LoadXRCDialog("CheatAdd"); { // d->Reparent(cheat_find_handler.dlg); // broken @@ -2756,24 +3253,22 @@ bool MainFrame::BindControls() cheat_find_handler.ca_addr = lab; d->Fit(); } - //// config menu d = LoadXRCDialog("GeneralConfig"); - wxCheckBox *cb; + wxCheckBox* cb; #define getcbb(n, o) do { \ cb=SafeXRCCTRL(d, n); \ cb->SetValidator(wxGenericValidator(&o)); \ - } while(0) + } while(0) #define getcbi(n, o) do { \ cb=SafeXRCCTRL(d, n); \ cb->SetValidator(wxBoolIntValidator(&o, 1)); \ - } while(0) - - wxSpinCtrl *sc; + } while(0) + wxSpinCtrl* sc; #define getsc(n, o) do { \ sc=SafeXRCCTRL(d, n); \ sc->SetValidator(wxGenericValidator(&o)); \ - } while(0) + } while(0) { getrbi("PNG", captureFormat, 0); getrbi("BMP", captureFormat, 1); @@ -2782,20 +3277,19 @@ bool MainFrame::BindControls() throttle_ctrl.thr = sc; throttle_ctrl.thrsel = SafeXRCCTRL(d, "ThrottleSel"); throttle_ctrl.thr-> - Connect(wxEVT_COMMAND_SPINCTRL_UPDATED, - wxSpinEventHandler(ThrottleCtrl_t::SetThrottleSel), - NULL, &throttle_ctrl); + Connect(wxEVT_COMMAND_SPINCTRL_UPDATED, + wxSpinEventHandler(ThrottleCtrl_t::SetThrottleSel), + NULL, &throttle_ctrl); throttle_ctrl.thrsel-> - Connect(wxEVT_COMMAND_CHOICE_SELECTED, - wxCommandEventHandler(ThrottleCtrl_t::SetThrottle), - NULL, &throttle_ctrl); + Connect(wxEVT_COMMAND_CHOICE_SELECTED, + wxCommandEventHandler(ThrottleCtrl_t::SetThrottle), + NULL, &throttle_ctrl); d->Connect(wxEVT_SHOW, wxShowEventHandler(ThrottleCtrl_t::Init), - NULL, &throttle_ctrl); + NULL, &throttle_ctrl); d->Fit(); } - #define getcbbe(n, o) getbe(n, o, cb, wxCheckBox, CB) - wxBoolIntEnValidator *bienval; + wxBoolIntEnValidator* bienval; #define getbie(n, o, v, cv, t, wt) do { \ cv=SafeXRCCTRL(d, n); \ cv->SetValidator(wxBoolIntEnValidator(&o, v, v)); \ @@ -2803,23 +3297,23 @@ bool MainFrame::BindControls() static wxBoolEnHandler _ben; \ ben = &_ben; \ wx##wt##BoolEnHandlerConnect(cv, wxID_ANY, _ben); \ - } while(0) + } while(0) #define addbie(n) do { \ ben->controls.push_back(n); \ bienval->controls.push_back(n); \ - } while(0) + } while(0) #define addbier(n, r) do { \ ben->controls.push_back(n); \ ben->reverse.push_back(r); \ bienval->controls.push_back(n); \ bienval->reverse.push_back(r); \ - } while(0) + } while(0) #define getcbie(n, o, v) getbie(n, o, v, cb, wxCheckBox, CB) - wxFilePickerCtrl *fp; + wxFilePickerCtrl* fp; #define getfp(n, o) do { \ fp=SafeXRCCTRL(d, n); \ fp->SetValidator(wxFileDirPickerValidator(&o)); \ - } while(0) + } while(0) d = LoadXRCropertySheetDialog("GameBoyConfig"); { /// System and Peripherals @@ -2835,8 +3329,10 @@ bool MainFrame::BindControls() getlab("CBootRomLab"); /// Custom Colors //getcbi("Color", gbColorOption); - wxFarRadio *r = NULL; - for (int i = 0; i < 3; i++) { + wxFarRadio* r = NULL; + + for (int i = 0; i < 3; i++) + { wxString pn; // NOTE: wx2.9.1 behaves differently for referenced nodes // than 2.8! Unless there is an actual child node, the ID field @@ -2845,37 +3341,42 @@ bool MainFrame::BindControls() // "Unable to load dialog GameBoyConfig from resources", this is // probably the reason. pn.Printf(wxT("cp%d"), i + 1); - wxWindow *w = SafeXRCCTRL(d, ToString(pn).c_str()); + wxWindow* w = SafeXRCCTRL(d, ToString(pn).c_str()); GBColorConfigHandler[i].p = w; GBColorConfigHandler[i].pno = i; - wxFarRadio *cb = SafeXRCCTRL(w, "UsePalette"); + wxFarRadio* cb = SafeXRCCTRL(w, "UsePalette"); + if (r) cb->SetGroup(r); else r = cb; + cb->SetValidator(wxBoolIntValidator(&gbPaletteOption, i)); ch = SafeXRCCTRL(w, "ColorSet"); GBColorConfigHandler[i].c = ch; - for (int j = 0; j < 8; j++) { + + for (int j = 0; j < 8; j++) + { wxString s; s.Printf(wxT("Color%d"), j); - wxColourPickerCtrl *cp = SafeXRCCTRL(w, ToString(s).c_str()); + wxColourPickerCtrl* cp = SafeXRCCTRL(w, ToString(s).c_str()); GBColorConfigHandler[i].cp[j] = cp; cp->SetValidator(wxColorValidator(&systemGbPalette[i * 8 + j])); } + w->Connect(wxEVT_COMMAND_CHOICE_SELECTED, - wxCommandEventHandler(GBColorConfig_t::ColorSel), - NULL, &GBColorConfigHandler[i]); + wxCommandEventHandler(GBColorConfig_t::ColorSel), + NULL, &GBColorConfigHandler[i]); w->Connect(XRCID("Reset"), wxEVT_COMMAND_BUTTON_CLICKED, - wxCommandEventHandler(GBColorConfig_t::ColorReset), - NULL, &GBColorConfigHandler[i]); + wxCommandEventHandler(GBColorConfig_t::ColorReset), + NULL, &GBColorConfigHandler[i]); w->Connect(wxID_ANY, wxEVT_COMMAND_COLOURPICKER_CHANGED, - wxCommandEventHandler(GBColorConfig_t::ColorButton), - NULL, &GBColorConfigHandler[i]); + wxCommandEventHandler(GBColorConfig_t::ColorButton), + NULL, &GBColorConfigHandler[i]); } + d->Fit(); } - d = LoadXRCropertySheetDialog("GameBoyAdvanceConfig"); { /// System and peripherals @@ -2884,22 +3385,20 @@ bool MainFrame::BindControls() ch = GetValidatedChild(d, "FlashSize", wxGenericValidator(&winFlashSize)); BatConfigHandler.size = ch; d->Connect(XRCID("SaveType"), wxEVT_COMMAND_CHOICE_SELECTED, - wxCommandEventHandler(BatConfig_t::ChangeType), - NULL, &BatConfigHandler); + wxCommandEventHandler(BatConfig_t::ChangeType), + NULL, &BatConfigHandler); #define getgbaw(n) do { \ wxWindow *w = d->FindWindow(XRCID(n)); \ CheckThrowXRCError(w,n); \ w->SetValidator(GBACtrlEnabler()); \ - } while(0) + } while(0) getgbaw("Detect"); d->Connect(XRCID("Detect"), wxEVT_COMMAND_BUTTON_CLICKED, - wxCommandEventHandler(BatConfig_t::Detect), - NULL, &BatConfigHandler); - + wxCommandEventHandler(BatConfig_t::Detect), + NULL, &BatConfigHandler); /// Boot ROM getfp("BootRom", gopts.gba_bios); getlab("BootRomLab"); - /// Game Overrides getgbaw("GameSettings"); // the rest must be filled in by command handler; just validate @@ -2910,7 +3409,6 @@ bool MainFrame::BindControls() SafeXRCCTRL(d, "OvMirroring"); d->Fit(); } - d = LoadXRCropertySheetDialog("DisplayConfig"); { /// Speed @@ -2919,6 +3417,7 @@ bool MainFrame::BindControls() getsc("FrameSkip", frameSkip); getlab("FrameSkipLab"); int fs = frameSkip; + if (fs >= 0) systemFrameSkip = fs; @@ -2929,7 +3428,6 @@ bool MainFrame::BindControls() // validator just for this, and spinctrl is good enough. getsc("DefaultScale", gopts.video_scale); getsc("MaxScale", maxScale); - /// Advanced getrbi("OutputSimple", gopts.render_method, RND_SIMPLE); getrbi("OutputOpenGL", gopts.render_method, RND_OPENGL); @@ -2946,8 +3444,8 @@ bool MainFrame::BindControls() #endif ch = GetValidatedChild(d, "Filter", wxGenericValidator(&gopts.filter)); // these two are filled and/or hidden at dialog load time - wxControl *pll; - wxChoice *pl; + wxControl* pll; + wxChoice* pl; pll = SafeXRCCTRL(d, "PluginLab"); pl = SafeXRCCTRL(d, "Plugin"); pll->SetValidator(PluginEnabler()); @@ -2955,34 +3453,32 @@ bool MainFrame::BindControls() PluginEnableHandler.lab = pll; PluginEnableHandler.ch = pl; ch->Connect(wxEVT_COMMAND_CHOICE_SELECTED, - wxCommandEventHandler(PluginEnable_t::ToggleChoice), - NULL, &PluginEnableHandler); + wxCommandEventHandler(PluginEnable_t::ToggleChoice), + NULL, &PluginEnableHandler); ch = GetValidatedChild(d, "IFB", wxGenericValidator(&gopts.ifb)); d->Fit(); } - d = LoadXRCropertySheetDialog("SoundConfig"); - wxSlider *sl; + wxSlider* sl; #define getsl(n, o) do { \ sl=SafeXRCCTRL(d, n); \ sl->SetValidator(wxGenericValidator(&o)); \ - } while(0) + } while(0) { /// Basic getsl("Volume", gopts.sound_vol); sound_config_handler.vol = sl; d->Connect(XRCID("Volume100"), wxEVT_COMMAND_BUTTON_CLICKED, - wxCommandEventHandler(SoundConfig_t::FullVol), - NULL, &sound_config_handler); + wxCommandEventHandler(SoundConfig_t::FullVol), + NULL, &sound_config_handler); ch = GetValidatedChild(d, "Rate", wxGenericValidator(&gopts.sound_qual)); - /// Advanced #define audapi_rb(n, v) do {\ getrbi(n, gopts.audio_api, v); \ rb->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED, \ - wxCommandEventHandler(SoundConfig_t::SetAPI), \ - NULL, &sound_config_handler); \ - } while(0) + wxCommandEventHandler(SoundConfig_t::SetAPI), \ + NULL, &sound_config_handler); \ + } while(0) audapi_rb("SDL", AUD_SDL); audapi_rb("OpenAL", AUD_OPENAL); #ifdef NO_OAL @@ -3013,29 +3509,26 @@ bool MainFrame::BindControls() getlab("BuffersInfo"); sound_config_handler.bufinfo = lab; sl->Connect(wxEVT_SCROLL_CHANGED, - wxCommandEventHandler(SoundConfig_t::AdjustFramesEv), - NULL, &sound_config_handler); + wxCommandEventHandler(SoundConfig_t::AdjustFramesEv), + NULL, &sound_config_handler); sl->Connect(wxEVT_SCROLL_THUMBTRACK, - wxCommandEventHandler(SoundConfig_t::AdjustFramesEv), - NULL, &sound_config_handler); + wxCommandEventHandler(SoundConfig_t::AdjustFramesEv), + NULL, &sound_config_handler); sound_config_handler.AdjustFrames(10); - /// Game Boy - wxPanel *p; + wxPanel* p; p = SafeXRCCTRL(d, "GBEnhanceSoundDep"); getsl("GBEcho", gopts.gb_echo); getsl("GBStereo", gopts.gb_stereo); - /// Game Boy Advance getsl("GBASoundFiltering", gopts.gba_sound_filter); d->Fit(); } - - wxDirPickerCtrl *dp; + wxDirPickerCtrl* dp; #define getdp(n, o) do { \ dp=SafeXRCCTRL(d, n); \ dp->SetValidator(wxFileDirPickerValidator(&o)); \ - } while(0) + } while(0) d = LoadXRCDialog("DirectoriesConfig"); { getdp("GBARoms", gopts.gba_rom_dir); @@ -3047,10 +3540,11 @@ bool MainFrame::BindControls() getdp("Recordings", gopts.recording_dir); d->Fit(); } + wxDialog* joyDialog = LoadXRCropertySheetDialog("JoypadConfig"); + wxFarRadio* r = 0; - wxDialog * joyDialog = LoadXRCropertySheetDialog("JoypadConfig"); - wxFarRadio *r = 0; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) + { wxString pn; // NOTE: wx2.9.1 behaves differently for referenced nodes // than 2.8! Unless there is an actual child node, the ID field @@ -3059,32 +3553,39 @@ bool MainFrame::BindControls() // "Unable to load dialog JoypadConfig from resources", this is // probably the reason. pn.Printf(wxT("joy%d"), i + 1); - wxWindow *w = SafeXRCCTRL(joyDialog, ToString(pn).c_str()); - wxFarRadio *cb; + wxWindow* w = SafeXRCCTRL(joyDialog, ToString(pn).c_str()); + wxFarRadio* cb; cb = SafeXRCCTRL(w, "DefaultConfig"); + if (r) cb->SetGroup(r); else r = cb; + cb->SetValidator(wxBoolIntValidator(&gopts.default_stick, i + 1)); - wxWindow *prev = NULL, *prevp = NULL; - for (int j = 0; j < NUM_KEYS; j++) { - wxJoyKeyTextCtrl *tc = XRCCTRL_D(*w, wxString::FromUTF8(joynames[j]), wxJoyKeyTextCtrl); + wxWindow* prev = NULL, *prevp = NULL; + + for (int j = 0; j < NUM_KEYS; j++) + { + wxJoyKeyTextCtrl* tc = XRCCTRL_D(*w, wxString::FromUTF8(joynames[j]), wxJoyKeyTextCtrl); CheckThrowXRCError(tc, ToString(joynames[j])); - wxWindow *p = tc->GetParent(); + wxWindow* p = tc->GetParent(); + if (p == prevp) tc->MoveAfterInTabOrder(prev); + prev = tc; prevp = p; tc->SetValidator(wxJoyKeyValidator(&gopts.joykey_bindings[i][j])); } + JoyPadConfigHandler[i].p = w; w->Connect(XRCID("Defaults"), wxEVT_COMMAND_BUTTON_CLICKED, - wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons), - NULL, &JoyPadConfigHandler[i]); + wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons), + NULL, &JoyPadConfigHandler[i]); w->Connect(XRCID("Clear"), wxEVT_COMMAND_BUTTON_CLICKED, - wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons), - NULL, &JoyPadConfigHandler[i]); + wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons), + NULL, &JoyPadConfigHandler[i]); joyDialog->Fit(); } @@ -3098,13 +3599,12 @@ bool MainFrame::BindControls() d->Fit(); } #endif - d = LoadXRCDialog("AccelConfig"); { - wxTreeCtrl *tc; + wxTreeCtrl* tc; tc = SafeXRCCTRL(d, "Commands"); accel_config_handler.tc = tc; - wxControlWithItems *lb; + wxControlWithItems* lb; lb = SafeXRCCTRL(d, "Current"); accel_config_handler.lb = lb; accel_config_handler.asb = SafeXRCCTRL(d, "Assign"); @@ -3115,9 +3615,13 @@ bool MainFrame::BindControls() accel_config_handler.key->SetMultikey(0); accel_config_handler.key->SetClearable(false); wxTreeItemId rid = tc->AddRoot(wxT("root")); - if (menubar) { + + if (menubar) + { wxTreeItemId mid = tc->AppendItem(rid, _("Menu commands")); - for (int i = 0; i < menubar->GetMenuCount(); i++) { + + for (int i = 0; i < menubar->GetMenuCount(); i++) + { #if wxCHECK_VERSION(2,8,8) wxTreeItemId id = tc->AppendItem(mid, menubar->GetMenuLabelText(i)); #else @@ -3129,24 +3633,32 @@ bool MainFrame::BindControls() add_menu_accels(tc, id, menubar->GetMenu(i)); } } + wxTreeItemId oid; int noop_id = XRCID("NOOP"); - for (int i = 0; i < ncmds; i++) { + + for (int i = 0; i < ncmds; i++) + { if (cmdtab[i].mi || (recent && cmdtab[i].cmd_id >= wxID_FILE1 && - cmdtab[i].cmd_id <= wxID_FILE10) || - cmdtab[i].cmd_id == noop_id) + cmdtab[i].cmd_id <= wxID_FILE10) || + cmdtab[i].cmd_id == noop_id) continue; + if (!oid.IsOk()) oid = tc->AppendItem(rid, _("Other commands")); - TreeInt *val = new TreeInt(i); + + TreeInt* val = new TreeInt(i); tc->AppendItem(oid, cmdtab[i].name, -1, -1, val); } + tc->ExpandAll(); // FIXME: make this actually show the entire line w/o scrolling // BestSize cuts off on rhs; MaxSize is completely invalid wxSize sz = tc->GetBestSize(); + if (sz.GetHeight() > 200) sz.SetHeight(200); + tc->SetSize(sz); sz.SetWidth(-1); // maybe allow it to become bigger tc->SetSizeHints(sz, sz); @@ -3155,48 +3667,53 @@ bool MainFrame::BindControls() sz.Set(w, h); lb->SetMinSize(sz); sz.Set(0, 0); - wxControl *curas = accel_config_handler.curas; - for (int i = 0; i < ncmds; i++) { + wxControl* curas = accel_config_handler.curas; + + for (int i = 0; i < ncmds; i++) + { wxString labs; treeid_to_name(i, labs, tc, tc->GetRootItem()); curas->GetTextExtent(labs, &w, &h); + if (w > sz.GetWidth()) sz.SetWidth(w); + if (h > sz.GetHeight()) sz.SetHeight(h); } + curas->SetSize(sz); curas->SetSizeHints(sz); tc->Connect(wxEVT_COMMAND_TREE_SEL_CHANGING, - wxTreeEventHandler(AccelConfig_t::CommandSel), - NULL, &accel_config_handler); + wxTreeEventHandler(AccelConfig_t::CommandSel), + NULL, &accel_config_handler); tc->Connect(wxEVT_COMMAND_TREE_SEL_CHANGED, - wxTreeEventHandler(AccelConfig_t::CommandSel), - NULL, &accel_config_handler); + wxTreeEventHandler(AccelConfig_t::CommandSel), + NULL, &accel_config_handler); d->Connect(wxEVT_SHOW, wxShowEventHandler(AccelConfig_t::Init), - NULL, &accel_config_handler); + NULL, &accel_config_handler); d->Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, - wxCommandEventHandler(AccelConfig_t::Set), - NULL, &accel_config_handler); + wxCommandEventHandler(AccelConfig_t::Set), + NULL, &accel_config_handler); d->Connect(XRCID("Assign"), wxEVT_COMMAND_BUTTON_CLICKED, - wxCommandEventHandler(AccelConfig_t::Assign), - NULL, &accel_config_handler); + wxCommandEventHandler(AccelConfig_t::Assign), + NULL, &accel_config_handler); d->Connect(XRCID("Remove"), wxEVT_COMMAND_BUTTON_CLICKED, - wxCommandEventHandler(AccelConfig_t::Remove), - NULL, &accel_config_handler); + wxCommandEventHandler(AccelConfig_t::Remove), + NULL, &accel_config_handler); d->Connect(XRCID("ResetAll"), wxEVT_COMMAND_BUTTON_CLICKED, - wxCommandEventHandler(AccelConfig_t::ResetAll), - NULL, &accel_config_handler); + wxCommandEventHandler(AccelConfig_t::ResetAll), + NULL, &accel_config_handler); lb->Connect(wxEVT_COMMAND_LISTBOX_SELECTED, - wxCommandEventHandler(AccelConfig_t::KeySel), - NULL, &accel_config_handler); + wxCommandEventHandler(AccelConfig_t::KeySel), + NULL, &accel_config_handler); d->Connect(XRCID("Shortcut"), wxEVT_COMMAND_TEXT_UPDATED, - wxCommandEventHandler(AccelConfig_t::CheckKey), - NULL, &accel_config_handler); + wxCommandEventHandler(AccelConfig_t::CheckKey), + NULL, &accel_config_handler); d->Fit(); } } - catch (std::exception& e) + catch (std::exception &e) { wxLogError(wxString::FromUTF8(e.what())); return false; @@ -3209,7 +3726,6 @@ bool MainFrame::BindControls() // The only one that can only be popped up once is logging, so allocate // and check it already. logdlg = new LogDialog; - // activate OnDropFile event handler #if !defined(__WXGTK__) || wxCHECK_VERSION(2,8,10) // may not actually do anything, but verfied to work w/ Linux/Nautilus @@ -3223,22 +3739,29 @@ bool MainFrame::BindControls() #ifndef NO_LINK LinkMode linkMode = GetConfiguredLinkMode(); - if (linkMode == LINK_GAMECUBE_DOLPHIN) { + if (linkMode == LINK_GAMECUBE_DOLPHIN) + { bool isv = !gopts.link_host.empty(); - if (isv) { + + if (isv) + { isv = SetLinkServerHost(gopts.link_host.mb_str()); } - if (!isv) { + if (!isv) + { wxLogError(_("JoyBus host invalid; disabling")); } - else { + else + { linkMode = LINK_DISCONNECTED; } } ConnectionState linkState = InitLink(linkMode); - if (linkState != LINK_OK) { + + if (linkState != LINK_OK) + { CloseLink(); } @@ -3250,16 +3773,11 @@ bool MainFrame::BindControls() } EnableNetworkMenu(); - #endif - enable_menus(); - panel->SetFrameTitle(); - // All OK; activate idle loop panel->SetExtraStyle(panel->GetExtraStyle() | wxWS_EX_PROCESS_IDLE); - return true; } diff --git a/src/wx/ioregs.h b/src/wx/ioregs.h index 1ea3097b..cbd0bd78 100644 --- a/src/wx/ioregs.h +++ b/src/wx/ioregs.h @@ -1,2072 +1,2074 @@ // this is essentially a copy of ../win32/IOViewRegisters.h using translatable // strings and more consts -struct IOData { - u16 *address; - u16 offset; - const wxChar *name; - u16 write; - const wxChar *bits[16]; +struct IOData +{ + u16* address; + u16 offset; + const wxChar* name; + u16 write; + const wxChar* bits[16]; }; -/* const */ IOData ioregs[] = { // not const so tranlation can be done once - { - &DISPCNT, 0, wxTRANSLATE("0x4000000-DISPCNT"), 0xFFF7, - { - wxT(""), - wxT(""), - wxTRANSLATE("BG Mode (3 bits)"), - wxTRANSLATE("CGB Mode"), - wxTRANSLATE("Display Frame"), - wxTRANSLATE("H-Blank Interval OBJ processing"), - wxTRANSLATE("OBJ Character mapping"), - wxTRANSLATE("Forced blank"), - wxTRANSLATE("BG0"), - wxTRANSLATE("BG1"), - wxTRANSLATE("BG2"), - wxTRANSLATE("BG3"), - wxTRANSLATE("OBJ"), - wxTRANSLATE("WIN0"), - wxTRANSLATE("WIN1"), - wxTRANSLATE("OBJWIN") - } - }, - { - &DISPSTAT, 4, wxTRANSLATE("0x4000004-DISPSTAT"), 0xFF38, - { - wxTRANSLATE("V-Blank Status"), - wxTRANSLATE("H-Blank Status"), - wxTRANSLATE("VCOUNT Evaluation"), - wxTRANSLATE("V-Blank Interrupt Enable"), - wxTRANSLATE("H-Blank Interrupt Enable"), - wxTRANSLATE("VCOUNT Match Interrupt Enable"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("VCOUNT setting (8 bits)") - } - }, - { - &VCOUNT, 6, wxTRANSLATE("0x4000006-VCOUNT"), 0x0000, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("VCOUNT (8 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT("") - } - }, - { - &BG0CNT, 8, wxTRANSLATE("0x4000008-BG0CNT"), 0xDFCF, - { - wxT(""), - wxTRANSLATE("Priority (2 bits)"), - wxT(""), - wxTRANSLATE("Char base (2 bits)"), - wxT(""), - wxT(""), - wxTRANSLATE("Mosaic"), - wxTRANSLATE("16/256 colors"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Screen Base Block (5 bits)"), - wxT(""), - wxT(""), - wxTRANSLATE("Size (2 bits)") - } - }, - { - &BG1CNT, 0xA, wxTRANSLATE("0x400000A-BG1CNT"), 0xDFCF, - { - wxT(""), - wxTRANSLATE("Priority (2 bits)"), - wxT(""), - wxTRANSLATE("Char base (2 bits)"), - wxT(""), - wxT(""), - wxTRANSLATE("Mosaic"), - wxTRANSLATE("16/256 colors"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Screen Base Block (5 bits)"), - wxT(""), - wxT(""), - wxTRANSLATE("Size (2 bits)") - } - }, - { - &BG2CNT, 0xC, wxTRANSLATE("0x400000C-BG2CNT"), 0xFFCF, - { - wxT(""), - wxTRANSLATE("Priority (2 bits)"), - wxT(""), - wxTRANSLATE("Char base (2 bits)"), - wxT(""), - wxT(""), - wxTRANSLATE("Mosaic"), - wxTRANSLATE("16/256 colors"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Screen Base Block (5 bits)"), - wxTRANSLATE("Area Overflow"), - wxT(""), - wxTRANSLATE("Size (2 bits)") - } - }, - { - &BG3CNT, 0xE, wxTRANSLATE("0x400000E-BG3CNT"), 0xFFCF, - { - wxT(""), - wxTRANSLATE("Priority (2 bits)"), - wxT(""), - wxTRANSLATE("Char base (2 bits)"), - wxT(""), - wxT(""), - wxTRANSLATE("Mosaic"), - wxTRANSLATE("16/256 colors"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Screen Base Block (5 bits)"), - wxTRANSLATE("Area Overflow"), - wxT(""), - wxTRANSLATE("Size (2 bits)") - } - }, - { - &BG0HOFS, 0x10, wxTRANSLATE("0x4000010-BG0HOFS"), 0x01FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Horizontal Offset (9 bits, W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT("") - } - }, - { - &BG0VOFS, 0x12, wxTRANSLATE("0x4000012-BG0VOFS"), 0x01FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Vertical Offset (9 bits, W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT("") - } - }, - { - &BG1HOFS, 0x14, wxTRANSLATE("0x4000014-BG1HOFS"), 0x01FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Horizontal Offset (9 bits, W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT("") - } - }, - { - &BG1VOFS, 0x16, wxTRANSLATE("0x4000016-BG1VOFS"), 0x01FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Vertical Offset (9 bits, W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT("") - } - }, - { - &BG2HOFS, 0x18, wxTRANSLATE("0x4000018-BG2HOFS"), 0x01FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Horizontal Offset (9 bits, W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT("") - } - }, - { - &BG2VOFS, 0x1A, wxTRANSLATE("0x400001A-BG2VOFS"), 0x01FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Vertical Offset (9 bits, W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT("") - } - }, - { - &BG3HOFS, 0x1C, wxTRANSLATE("0x400001C-BG3HOFS"), 0x01FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Horizontal Offset (9 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT("") - } - }, - { - &BG3VOFS, 0x1E, wxTRANSLATE("0x400001E-BG3VOFS"), 0x01FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Vertical Offset (9 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT("") - } - }, - { - &BG2PA, 0x20, wxTRANSLATE("0x4000020-BG2PA"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("dx (16 bits,W)") - } - }, - { - &BG2PB, 0x22, wxTRANSLATE("0x4000022-BG2PB"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("dmx (16 bits,W)") - } - }, - { - &BG2PC, 0x24, wxTRANSLATE("0x4000024-BG2PC"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("dy (16 bits,W)") - } - }, - { - &BG2PD, 0x26, wxTRANSLATE("0x4000026-BG2PD"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("dmy (16 bits,W)") - } - }, - { - &BG2X_L, 0x28, wxTRANSLATE("0x4000028-BG2X_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("X low bits (16 bits,W)") - } - }, - { - &BG2X_H, 0x2A, wxTRANSLATE("0x400002A-BG2X_H"), 0x0FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("X high bits (12 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &BG2Y_L, 0x2C, wxTRANSLATE("0x400002C-BG2Y_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Y low bits (16 bits,W)") - } - }, - { - &BG2Y_H, 0x2E, wxTRANSLATE("0x400002E-BG2Y_H"), 0x0FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Y hight bits (12 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &BG3PA, 0x30, wxTRANSLATE("0x4000030-BG3PA"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("dx (16 bits,W)") - } - }, - { - &BG3PB, 0x32, wxTRANSLATE("0x4000032-BG3PB"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("dmx (16 bits,W)") - } - }, - { - &BG3PC, 0x34, wxTRANSLATE("0x4000034-BG3PC"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("dy (16 bits,W)") - } - }, - { - &BG3PD, 0x36, wxTRANSLATE("0x4000036-BG3PD"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("dmy (16 bits,W)") - } - }, - { - &BG3X_L, 0x38, wxTRANSLATE("0x4000038-BG3X_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("X low bits (16 bits,W)") - } - }, - { - &BG3X_H, 0x3A, wxTRANSLATE("0x400003A-BG3X_H"), 0x0FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("X hight bits (12 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &BG3Y_L, 0x3C, wxTRANSLATE("0x400003C-BG3Y_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Y low bits (16 bits,W)") - } - }, - { - &BG3Y_H, 0x3E, wxTRANSLATE("0x400003E-BG3Y_H"), 0x0FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Y hight bits (12 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &WIN0H, 0x40, wxTRANSLATE("0x4000040-WIN0H"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Win 0 lower-right X (8 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Win 0 upper-left X (8 bits,W)"), - } - }, - { - &WIN1H, 0x42, wxTRANSLATE("0x4000042-WIN1H"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Win 1 lower-right X (8 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Win 1 upper-left (8 bits,W)"), - } - }, - { - &WIN0V, 0x44, wxTRANSLATE("0x4000044-WIN0V"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Win 0 lower-right Y (8 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Win 0 upper-left Y (8 bits,W)"), - } - }, - { - &WIN1V, 0x46, wxTRANSLATE("0x4000046-WIN1V"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Win 1 lower-right Y (8 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Win 1 upper-left Y (8 bits,W)"), - } - }, - { - &WININ, 0x48, wxTRANSLATE("0x4000048-WININ"), 0x3F3F, - { - wxTRANSLATE("WIN0 BG0"), - wxTRANSLATE("WIN0 BG1"), - wxTRANSLATE("WIN0 BG2"), - wxTRANSLATE("WIN0 BG3"), - wxTRANSLATE("WIN0 OBJ"), - wxTRANSLATE("WIN0 Special FX"), - wxT(""), - wxT(""), - wxTRANSLATE("WIN1 BG0"), - wxTRANSLATE("WIN1 BG1"), - wxTRANSLATE("WIN1 BG2"), - wxTRANSLATE("WIN1 BG3"), - wxTRANSLATE("WIN1 OBJ"), - wxTRANSLATE("WIN1 Special FX"), - wxT(""), - wxT(""), - } - }, - { - &WINOUT, 0x4A, wxTRANSLATE("0x400004A-WINOUT"), 0x3F3F, - { - wxTRANSLATE("WIN0/1 BG0"), - wxTRANSLATE("WIN0/1 BG1"), - wxTRANSLATE("WIN0/1 BG2"), - wxTRANSLATE("WIN0/1 BG3"), - wxTRANSLATE("WIN0/1 OBJ"), - wxTRANSLATE("WIN0/1 Special FX"), - wxT(""), - wxT(""), - wxTRANSLATE("OBJWIN BG0"), - wxTRANSLATE("OBJWIN BG1"), - wxTRANSLATE("OBJWIN BG2"), - wxTRANSLATE("OBJWIN BG3"), - wxTRANSLATE("OBJWIN OBJ"), - wxTRANSLATE("OBJWIN Special FX"), - wxT(""), - wxT(""), - } - }, - { - &MOSAIC, 0x4C, wxTRANSLATE("0x400004C-MOSAIC"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("BG H Size (4 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("BG V Size (4 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("OBJ H Size (4 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("OBJ V Size (4 bits,W)"), - } - }, - { - &BLDMOD, 0x50, wxTRANSLATE("0x4000050-BLDMOD"), 0x3FFF, - { - wxTRANSLATE("1st BG0"), - wxTRANSLATE("1st BG1"), - wxTRANSLATE("1st BG2"), - wxTRANSLATE("1st BG3"), - wxTRANSLATE("1st OBJ"), - wxTRANSLATE("1st BD"), - wxT(""), - wxTRANSLATE("FX Type (2 bits)"), - wxTRANSLATE("2nd BG0"), - wxTRANSLATE("2nd BG1"), - wxTRANSLATE("2nd BG2"), - wxTRANSLATE("2nd BG3"), - wxTRANSLATE("2nd OBJ"), - wxTRANSLATE("2nd BD"), - wxT(""), - wxT(""), - } - }, - { - &COLEV, 0x52, wxTRANSLATE("0x4000052-COLEV"), 0x1F1F, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Coefficient EVA (5 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Coefficient EVB (5 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &COLY, 0x54, wxTRANSLATE("0x4000054-COLEY"), 0x001F, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Coefficient EVY (5 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - NULL, 0x60, wxTRANSLATE("0x4000060-SG10_L"), 0x007F, - { - wxT(""), - wxT(""), - wxTRANSLATE("Sweep Shifts (3 bits)"), - wxTRANSLATE("Sweep addition/decrease"), - wxT(""), - wxT(""), - wxTRANSLATE("Sweep Time (3 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - NULL, 0x62, wxTRANSLATE("0x4000062-SG10_H"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Sound Length (6 bits,W)"), - wxT(""), - wxTRANSLATE("Waveform Type (2 bits)"), - wxT(""), - wxT(""), - wxTRANSLATE("Envelope Steps (3 bits)"), - wxTRANSLATE("Envelope Attenuate/Amplify"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Envelope Initial Value"), - } - }, - { - NULL, 0x64, wxTRANSLATE("0x4000064-SG11"), 0xC7FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Frequency (11 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Sound Continuous/Counter"), - wxTRANSLATE("Initialization (W)"), - } - }, - { - NULL, 0x68, wxTRANSLATE("0x4000068-SG20"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Sound Length (6 bits,W)"), - wxT(""), - wxTRANSLATE("Waveform Type (2 bits)"), - wxT(""), - wxT(""), - wxTRANSLATE("Envelope Steps (3 bits)"), - wxTRANSLATE("Envelope Attenuate/Amplify"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Envelope Initial Value"), - } - }, - { - NULL, 0x6C, wxTRANSLATE("0x400006C-SG21"), 0xC7FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Frequency (11 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Sound Continuous/Counter"), - wxTRANSLATE("Initialization (W)"), - } - }, - { - NULL, 0x70, wxTRANSLATE("0x4000070-SG30_L"), 0x00E0, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Waveform 32/64 Steps"), - wxTRANSLATE("Waveform Bank 0/1"), - wxTRANSLATE("Sound Output"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - NULL, 0x72, wxTRANSLATE("0x4000072-SG30_H"), 0xE0FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Sound Length (8 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Output Level (2 bits)"), - wxTRANSLATE("Forced 3/4 Output Level"), - } - }, - { - NULL, 0x74, wxTRANSLATE("0x4000074-SG31"), 0xC7FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Frequency (11 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Sound Continuous/Counter"), - wxTRANSLATE("Initialization (W)"), - } - }, - { - NULL, 0x78, wxTRANSLATE("0x4000078-SG40"), 0xFF3F, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Sound Length (6 bits,W)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Envelope Steps (3 bits)"), - wxTRANSLATE("Envelope Attenuate/Amplify"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Envelope Initial Value"), - } - }, - { - NULL, 0x7C, wxTRANSLATE("0x400007C-SG41"), 0xC0FF, - { - wxT(""), - wxT(""), - wxTRANSLATE("Dividing Ratio Freq. (3 bits)"), - wxTRANSLATE("Counter 15/7 Steps"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Counter Shift Clock (4 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Sound Continuous/Counter"), - wxTRANSLATE("Initialization (W)"), - } - }, - { - NULL, 0x80, wxTRANSLATE("0x4000080-SGCNT0_L"), 0xFF77, - { - wxT(""), - wxT(""), - wxTRANSLATE("Right Volume (3 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Left Volume (3 bits)"), - wxT(""), - wxTRANSLATE("Channel 1->Right"), - wxTRANSLATE("Channel 2->Right"), - wxTRANSLATE("Channel 3->Right"), - wxTRANSLATE("Channel 4->Right"), - wxTRANSLATE("Channel 1->Left"), - wxTRANSLATE("Channel 2->Left"), - wxTRANSLATE("Channel 3->Left"), - wxTRANSLATE("Channel 4->Left"), - } - }, - { - NULL, 0x82, wxTRANSLATE("0x4000082-SGCNT0_H"), 0xFF0F, - { - wxT(""), - wxTRANSLATE("Sound 1-4 Volume (2 bits)"), - wxTRANSLATE("DMA Sound A Volume"), - wxTRANSLATE("DMA Sound B Volume"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("DMA Sound A->Right"), - wxTRANSLATE("DMA Sound A->Left"), - wxTRANSLATE("DMA Sound A Timer"), - wxTRANSLATE("DMA Sound A Reset FIFO"), - wxTRANSLATE("DMA Sound B->Right"), - wxTRANSLATE("DMA Sound B->Left"), - wxTRANSLATE("DMA Sound B Timer"), - wxTRANSLATE("DMA Sound B Reset FIFO"), - } - }, - { - NULL, 0x84, wxTRANSLATE("0x4000084-SGCNT1"), 0x0080, - { - wxTRANSLATE("Sound 1 On"), - wxTRANSLATE("Sound 2 On"), - wxTRANSLATE("Sound 3 On"), - wxTRANSLATE("Sound 4 On"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Master Sound Enable"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - NULL, 0x88, wxTRANSLATE("0x4000088-SGBIAS"), 0xC3FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Bias Level (10 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Sampling Rate (2 bits)"), - } - }, - { - NULL, 0xA0, wxTRANSLATE("0x40000A0-SIGFIFOA_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Data 0 (8 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Data 1 (8 bits)"), - } - }, - { - NULL, 0xA2, wxTRANSLATE("0x40000A2-SIGFIFOA_H"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Data 2 (8 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Data 3 (8 bits)"), - } - }, - { - NULL, 0xA4, wxTRANSLATE("0x40000A4-SIGFIFOB_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Data 0 (8 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Data 1 (8 bits)"), - } - }, - { - NULL, 0xA6, wxTRANSLATE("0x40000A6-SIGFIFOB_H"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Data 2 (8 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Data 3 (8 bits)"), - } - }, - { - &DM0SAD_L, 0xB0, wxTRANSLATE("0x40000B0-DM0SAD_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Source Address (lower 16 bits)"), - } - }, - { - &DM0SAD_H, 0xB2, wxTRANSLATE("0x40000B2-DM0SAD_H"), 0x07FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Source Address (upper 11 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &DM0DAD_L, 0xB4, wxTRANSLATE("0x40000B4-DM0DAD_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address (lower 16 bits)"), - } - }, - { - &DM0DAD_H, 0xB6, wxTRANSLATE("0x40000B6-DM0DAD_H"), 0x07FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address (upper 11 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &DM0CNT_L, 0xB8, wxTRANSLATE("0x40000B8-DM0CNT_L"), 0x3FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Count (14 bits)"), - wxT(""), - wxT(""), - } - }, - { - &DM0CNT_H, 0xBA, wxTRANSLATE("0x40000BA-DM0CNT_H"), 0xF7E0, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address Control (2 bits)"), - wxT(""), - wxTRANSLATE("Source Address Control (2 bits)"), - wxTRANSLATE("Repeat"), - wxTRANSLATE("Transfer Type"), - wxT(""), - wxT(""), - wxTRANSLATE("Start Timing (2 bits)"), - wxTRANSLATE("Interrupt Request"), - wxTRANSLATE("Enable"), - } - }, - { - &DM1SAD_L, 0xBC, wxTRANSLATE("0x40000BC-DM1SAD_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Source Address (lower 16 bits)"), - } - }, - { - &DM1SAD_H, 0xBE, wxTRANSLATE("0x40000BE-DM1SAD_H"), 0x0FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Source Address (upper 12 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &DM1DAD_L, 0xC0, wxTRANSLATE("0x40000C0-DM1DAD_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address (lower 16 bits)"), - } - }, - { - &DM1DAD_H, 0xC2, wxTRANSLATE("0x40000C2-DM1DAD_H"), 0x07FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address (upper 11 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &DM1CNT_L, 0xC4, wxTRANSLATE("0x40000C4-DM1CNT_L"), 0x3FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Count (14 bits)"), - wxT(""), - wxT(""), - } - }, - { - &DM1CNT_H, 0xC6, wxTRANSLATE("0x40000C6-DM1CNT_H"), 0xF7E0, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address Control (2 bits)"), - wxT(""), - wxTRANSLATE("Source Address Control (2 bits)"), - wxTRANSLATE("Repeat"), - wxTRANSLATE("Transfer Type"), - wxT(""), - wxT(""), - wxTRANSLATE("Start Timing (2 bits)"), - wxTRANSLATE("Interrupt Request"), - wxTRANSLATE("Enable"), - } - }, - { - &DM2SAD_L, 0xC8, wxTRANSLATE("0x40000C8-DM2SAD_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Source Address (lower 16 bits)"), - } - }, - { - &DM2SAD_H, 0xCA, wxTRANSLATE("0x40000CA-DM2SAD_H"), 0x0FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Source Address (upper 12 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &DM2DAD_L, 0xCC, wxTRANSLATE("0x40000CC-DM2DAD_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address (lower 16 bits)"), - } - }, - { - &DM2DAD_H, 0xCE, wxTRANSLATE("0x40000CE-DM2DAD_H"), 0x07FF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address (upper 11 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &DM2CNT_L, 0xD0, wxTRANSLATE("0x40000D0-DM2CNT_L"), 0x3FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Count (14 bits)"), - wxT(""), - wxT(""), - } - }, - { - &DM2CNT_H, 0xD2, wxTRANSLATE("0x40000D2-DM2CNT_H"), 0xF7E0, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address Control (2 bits)"), - wxT(""), - wxTRANSLATE("Source Address Control (2 bits)"), - wxTRANSLATE("Repeat"), - wxTRANSLATE("Transfer Type"), - wxT(""), - wxT(""), - wxTRANSLATE("Start Timing (2 bits)"), - wxTRANSLATE("Interrupt Request"), - wxTRANSLATE("Enable"), - } - }, - { - &DM3SAD_L, 0xD4, wxTRANSLATE("0x40000D4-DM3SAD_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Source Address (lower 16 bits)"), - } - }, - { - &DM3SAD_H, 0xD6, wxTRANSLATE("0x40000D6-DM3SAD_H"), 0x0FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Source Address (upper 12 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &DM3DAD_L, 0xD8, wxTRANSLATE("0x40000D8-DM3DAD_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address (lower 16 bits)"), - } - }, - { - &DM3DAD_H, 0xDA, wxTRANSLATE("0x40000DA-DM3DAD_H"), 0x0FFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address (upper 12 bits)"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &DM3CNT_L, 0xDC, wxTRANSLATE("0x40000DC-DM3CNT_L"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Count (16 bits)"), - } - }, - { - &DM3CNT_H, 0xDE, wxTRANSLATE("0x40000DE-DM3CNT_H"), 0xFFE0, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Destination Address Control (2 bits)"), - wxT(""), - wxTRANSLATE("Source Address Control (2 bits)"), - wxTRANSLATE("Repeat"), - wxTRANSLATE("Transfer Type"), - wxTRANSLATE("Game Pak Data Request"), - wxT(""), - wxTRANSLATE("Start Timing (2 bits)"), - wxTRANSLATE("Interrupt Request"), - wxTRANSLATE("Enable"), - } - }, - { - &TM0D, 0x100, wxTRANSLATE("0x4000100-TM0D"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Timer Counter (16 bits)"), - } - }, - { - &TM0CNT, 0x102, wxTRANSLATE("0x4000102-TM0CNT"), 0x00C7, - { - wxT(""), - wxTRANSLATE("Scalar Selection (2 bits)"), - wxTRANSLATE("Count Up"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Interrupt Request"), - wxTRANSLATE("Enable"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &TM1D, 0x104, wxTRANSLATE("0x4000104-TM1D"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Timer Counter (16 bits)"), - } - }, - { - &TM1CNT, 0x106, wxTRANSLATE("0x4000106-TM1CNT"), 0x00C7, - { - wxT(""), - wxTRANSLATE("Scalar Selection (2 bits)"), - wxTRANSLATE("Count Up"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Interrupt Request"), - wxTRANSLATE("Enable"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &TM2D, 0x108, wxTRANSLATE("0x4000108-TM2D"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Timer Counter (16 bits)"), - } - }, - { - &TM2CNT, 0x10A, wxTRANSLATE("0x400010A-TM2CNT"), 0x00C7, - { - wxT(""), - wxTRANSLATE("Scalar Selection (2 bits)"), - wxTRANSLATE("Count Up"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Interrupt Request"), - wxTRANSLATE("Enable"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &TM3D, 0x10C, wxTRANSLATE("0x400010C-TM3D"), 0xFFFF, - { - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Timer Counter (16 bits)"), - } - }, - { - &TM3CNT, 0x10E, wxTRANSLATE("0x400010E-TM3CNT"), 0x00C7, - { - wxT(""), - wxTRANSLATE("Scalar Selection (2 bits)"), - wxTRANSLATE("Count Up"), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Interrupt Request"), - wxTRANSLATE("Enable"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - &P1, 0x130, wxTRANSLATE("0x4000130-P1"), 0x03FF, - { - wxTRANSLATE("A"), - wxTRANSLATE("B"), - wxTRANSLATE("Select"), - wxTRANSLATE("Start"), - wxTRANSLATE("Right"), - wxTRANSLATE("Left"), - wxTRANSLATE("Up"), - wxTRANSLATE("Down"), - wxTRANSLATE("Shoulder Right"), - wxTRANSLATE("Shoulder Left"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - NULL, 0x132, wxTRANSLATE("0x4000132-P1CNT"), 0xC3FF, - { - wxTRANSLATE("A"), - wxTRANSLATE("B"), - wxTRANSLATE("Select"), - wxTRANSLATE("Start"), - wxTRANSLATE("Right"), - wxTRANSLATE("Left"), - wxTRANSLATE("Up"), - wxTRANSLATE("Down"), - wxTRANSLATE("Shoulder Right"), - wxTRANSLATE("Shoulder Left"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Interrupt Request"), - wxTRANSLATE("Interrupt Condition"), - } - }, - { - &IE, 0x200, wxTRANSLATE("0x4000200-IE"), 0x3FFF, - { - wxTRANSLATE("VBlank"), - wxTRANSLATE("HBlank"), - wxTRANSLATE("VCount"), - wxTRANSLATE("Timer 0"), - wxTRANSLATE("Timer 1"), - wxTRANSLATE("Timer 2"), - wxTRANSLATE("Timer 3"), - wxTRANSLATE("Serial"), - wxTRANSLATE("DMA 0"), - wxTRANSLATE("DMA 1"), - wxTRANSLATE("DMA 2"), - wxTRANSLATE("DMA 3"), - wxTRANSLATE("Keypad"), - wxTRANSLATE("Game Pak"), - wxT(""), - wxT(""), - } - }, - { - &IF, 0x202, wxTRANSLATE("0x4000202-IF"), 0x0000, - { - wxTRANSLATE("VBlank"), - wxTRANSLATE("HBlank"), - wxTRANSLATE("VCount"), - wxTRANSLATE("Timer 0"), - wxTRANSLATE("Timer 1"), - wxTRANSLATE("Timer 2"), - wxTRANSLATE("Timer 3"), - wxTRANSLATE("Serial"), - wxTRANSLATE("DMA 0"), - wxTRANSLATE("DMA 1"), - wxTRANSLATE("DMA 2"), - wxTRANSLATE("DMA 3"), - wxTRANSLATE("Keypad"), - wxTRANSLATE("Game Pak"), - wxT(""), - wxT(""), - } - }, - { - NULL, 0x204, wxTRANSLATE("0x4000204-WAITCNT"), 0x5FFF, - { - wxT(""), - wxTRANSLATE("SRAM Wait Control (2 bits)"), - wxT(""), - wxTRANSLATE("Wait State 0 First Access (2 bits)"), - wxTRANSLATE("Wait State 0 Second Access"), - wxT(""), - wxTRANSLATE("Wait State 1 First Access (2 bits)"), - wxTRANSLATE("Wait State 1 Second Access"), - wxT(""), - wxTRANSLATE("Wait State 2 First Access (2 bits)"), - wxTRANSLATE("Wait State 2 Second Access"), - wxT(""), - wxTRANSLATE("PHI Terminal Output (2 bits)"), - wxT(""), - wxTRANSLATE("Game Pak Prefetch Buffer"), - wxTRANSLATE("Game Pak Type Flag"), - } - }, - { - &IME, 0x208, wxTRANSLATE("0x4000208-IME"), 0x0001, - { - wxTRANSLATE("Master Interrupt Enable"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - } - }, - { - NULL, 0x300, wxTRANSLATE("0x4000300-HALTCNT"), 0x8001, - { - wxTRANSLATE("First Boot"), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxT(""), - wxTRANSLATE("Power Down"), - } - }, +/* const */ IOData ioregs[] = // not const so tranlation can be done once +{ + { + &DISPCNT, 0, wxTRANSLATE("0x4000000-DISPCNT"), 0xFFF7, + { + wxT(""), + wxT(""), + wxTRANSLATE("BG Mode (3 bits)"), + wxTRANSLATE("CGB Mode"), + wxTRANSLATE("Display Frame"), + wxTRANSLATE("H-Blank Interval OBJ processing"), + wxTRANSLATE("OBJ Character mapping"), + wxTRANSLATE("Forced blank"), + wxTRANSLATE("BG0"), + wxTRANSLATE("BG1"), + wxTRANSLATE("BG2"), + wxTRANSLATE("BG3"), + wxTRANSLATE("OBJ"), + wxTRANSLATE("WIN0"), + wxTRANSLATE("WIN1"), + wxTRANSLATE("OBJWIN") + } + }, + { + &DISPSTAT, 4, wxTRANSLATE("0x4000004-DISPSTAT"), 0xFF38, + { + wxTRANSLATE("V-Blank Status"), + wxTRANSLATE("H-Blank Status"), + wxTRANSLATE("VCOUNT Evaluation"), + wxTRANSLATE("V-Blank Interrupt Enable"), + wxTRANSLATE("H-Blank Interrupt Enable"), + wxTRANSLATE("VCOUNT Match Interrupt Enable"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("VCOUNT setting (8 bits)") + } + }, + { + &VCOUNT, 6, wxTRANSLATE("0x4000006-VCOUNT"), 0x0000, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("VCOUNT (8 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT("") + } + }, + { + &BG0CNT, 8, wxTRANSLATE("0x4000008-BG0CNT"), 0xDFCF, + { + wxT(""), + wxTRANSLATE("Priority (2 bits)"), + wxT(""), + wxTRANSLATE("Char base (2 bits)"), + wxT(""), + wxT(""), + wxTRANSLATE("Mosaic"), + wxTRANSLATE("16/256 colors"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Screen Base Block (5 bits)"), + wxT(""), + wxT(""), + wxTRANSLATE("Size (2 bits)") + } + }, + { + &BG1CNT, 0xA, wxTRANSLATE("0x400000A-BG1CNT"), 0xDFCF, + { + wxT(""), + wxTRANSLATE("Priority (2 bits)"), + wxT(""), + wxTRANSLATE("Char base (2 bits)"), + wxT(""), + wxT(""), + wxTRANSLATE("Mosaic"), + wxTRANSLATE("16/256 colors"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Screen Base Block (5 bits)"), + wxT(""), + wxT(""), + wxTRANSLATE("Size (2 bits)") + } + }, + { + &BG2CNT, 0xC, wxTRANSLATE("0x400000C-BG2CNT"), 0xFFCF, + { + wxT(""), + wxTRANSLATE("Priority (2 bits)"), + wxT(""), + wxTRANSLATE("Char base (2 bits)"), + wxT(""), + wxT(""), + wxTRANSLATE("Mosaic"), + wxTRANSLATE("16/256 colors"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Screen Base Block (5 bits)"), + wxTRANSLATE("Area Overflow"), + wxT(""), + wxTRANSLATE("Size (2 bits)") + } + }, + { + &BG3CNT, 0xE, wxTRANSLATE("0x400000E-BG3CNT"), 0xFFCF, + { + wxT(""), + wxTRANSLATE("Priority (2 bits)"), + wxT(""), + wxTRANSLATE("Char base (2 bits)"), + wxT(""), + wxT(""), + wxTRANSLATE("Mosaic"), + wxTRANSLATE("16/256 colors"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Screen Base Block (5 bits)"), + wxTRANSLATE("Area Overflow"), + wxT(""), + wxTRANSLATE("Size (2 bits)") + } + }, + { + &BG0HOFS, 0x10, wxTRANSLATE("0x4000010-BG0HOFS"), 0x01FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Horizontal Offset (9 bits, W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT("") + } + }, + { + &BG0VOFS, 0x12, wxTRANSLATE("0x4000012-BG0VOFS"), 0x01FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Vertical Offset (9 bits, W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT("") + } + }, + { + &BG1HOFS, 0x14, wxTRANSLATE("0x4000014-BG1HOFS"), 0x01FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Horizontal Offset (9 bits, W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT("") + } + }, + { + &BG1VOFS, 0x16, wxTRANSLATE("0x4000016-BG1VOFS"), 0x01FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Vertical Offset (9 bits, W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT("") + } + }, + { + &BG2HOFS, 0x18, wxTRANSLATE("0x4000018-BG2HOFS"), 0x01FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Horizontal Offset (9 bits, W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT("") + } + }, + { + &BG2VOFS, 0x1A, wxTRANSLATE("0x400001A-BG2VOFS"), 0x01FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Vertical Offset (9 bits, W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT("") + } + }, + { + &BG3HOFS, 0x1C, wxTRANSLATE("0x400001C-BG3HOFS"), 0x01FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Horizontal Offset (9 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT("") + } + }, + { + &BG3VOFS, 0x1E, wxTRANSLATE("0x400001E-BG3VOFS"), 0x01FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Vertical Offset (9 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT("") + } + }, + { + &BG2PA, 0x20, wxTRANSLATE("0x4000020-BG2PA"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("dx (16 bits,W)") + } + }, + { + &BG2PB, 0x22, wxTRANSLATE("0x4000022-BG2PB"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("dmx (16 bits,W)") + } + }, + { + &BG2PC, 0x24, wxTRANSLATE("0x4000024-BG2PC"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("dy (16 bits,W)") + } + }, + { + &BG2PD, 0x26, wxTRANSLATE("0x4000026-BG2PD"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("dmy (16 bits,W)") + } + }, + { + &BG2X_L, 0x28, wxTRANSLATE("0x4000028-BG2X_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("X low bits (16 bits,W)") + } + }, + { + &BG2X_H, 0x2A, wxTRANSLATE("0x400002A-BG2X_H"), 0x0FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("X high bits (12 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &BG2Y_L, 0x2C, wxTRANSLATE("0x400002C-BG2Y_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Y low bits (16 bits,W)") + } + }, + { + &BG2Y_H, 0x2E, wxTRANSLATE("0x400002E-BG2Y_H"), 0x0FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Y hight bits (12 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &BG3PA, 0x30, wxTRANSLATE("0x4000030-BG3PA"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("dx (16 bits,W)") + } + }, + { + &BG3PB, 0x32, wxTRANSLATE("0x4000032-BG3PB"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("dmx (16 bits,W)") + } + }, + { + &BG3PC, 0x34, wxTRANSLATE("0x4000034-BG3PC"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("dy (16 bits,W)") + } + }, + { + &BG3PD, 0x36, wxTRANSLATE("0x4000036-BG3PD"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("dmy (16 bits,W)") + } + }, + { + &BG3X_L, 0x38, wxTRANSLATE("0x4000038-BG3X_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("X low bits (16 bits,W)") + } + }, + { + &BG3X_H, 0x3A, wxTRANSLATE("0x400003A-BG3X_H"), 0x0FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("X hight bits (12 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &BG3Y_L, 0x3C, wxTRANSLATE("0x400003C-BG3Y_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Y low bits (16 bits,W)") + } + }, + { + &BG3Y_H, 0x3E, wxTRANSLATE("0x400003E-BG3Y_H"), 0x0FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Y hight bits (12 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &WIN0H, 0x40, wxTRANSLATE("0x4000040-WIN0H"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Win 0 lower-right X (8 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Win 0 upper-left X (8 bits,W)"), + } + }, + { + &WIN1H, 0x42, wxTRANSLATE("0x4000042-WIN1H"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Win 1 lower-right X (8 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Win 1 upper-left (8 bits,W)"), + } + }, + { + &WIN0V, 0x44, wxTRANSLATE("0x4000044-WIN0V"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Win 0 lower-right Y (8 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Win 0 upper-left Y (8 bits,W)"), + } + }, + { + &WIN1V, 0x46, wxTRANSLATE("0x4000046-WIN1V"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Win 1 lower-right Y (8 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Win 1 upper-left Y (8 bits,W)"), + } + }, + { + &WININ, 0x48, wxTRANSLATE("0x4000048-WININ"), 0x3F3F, + { + wxTRANSLATE("WIN0 BG0"), + wxTRANSLATE("WIN0 BG1"), + wxTRANSLATE("WIN0 BG2"), + wxTRANSLATE("WIN0 BG3"), + wxTRANSLATE("WIN0 OBJ"), + wxTRANSLATE("WIN0 Special FX"), + wxT(""), + wxT(""), + wxTRANSLATE("WIN1 BG0"), + wxTRANSLATE("WIN1 BG1"), + wxTRANSLATE("WIN1 BG2"), + wxTRANSLATE("WIN1 BG3"), + wxTRANSLATE("WIN1 OBJ"), + wxTRANSLATE("WIN1 Special FX"), + wxT(""), + wxT(""), + } + }, + { + &WINOUT, 0x4A, wxTRANSLATE("0x400004A-WINOUT"), 0x3F3F, + { + wxTRANSLATE("WIN0/1 BG0"), + wxTRANSLATE("WIN0/1 BG1"), + wxTRANSLATE("WIN0/1 BG2"), + wxTRANSLATE("WIN0/1 BG3"), + wxTRANSLATE("WIN0/1 OBJ"), + wxTRANSLATE("WIN0/1 Special FX"), + wxT(""), + wxT(""), + wxTRANSLATE("OBJWIN BG0"), + wxTRANSLATE("OBJWIN BG1"), + wxTRANSLATE("OBJWIN BG2"), + wxTRANSLATE("OBJWIN BG3"), + wxTRANSLATE("OBJWIN OBJ"), + wxTRANSLATE("OBJWIN Special FX"), + wxT(""), + wxT(""), + } + }, + { + &MOSAIC, 0x4C, wxTRANSLATE("0x400004C-MOSAIC"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("BG H Size (4 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("BG V Size (4 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("OBJ H Size (4 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("OBJ V Size (4 bits,W)"), + } + }, + { + &BLDMOD, 0x50, wxTRANSLATE("0x4000050-BLDMOD"), 0x3FFF, + { + wxTRANSLATE("1st BG0"), + wxTRANSLATE("1st BG1"), + wxTRANSLATE("1st BG2"), + wxTRANSLATE("1st BG3"), + wxTRANSLATE("1st OBJ"), + wxTRANSLATE("1st BD"), + wxT(""), + wxTRANSLATE("FX Type (2 bits)"), + wxTRANSLATE("2nd BG0"), + wxTRANSLATE("2nd BG1"), + wxTRANSLATE("2nd BG2"), + wxTRANSLATE("2nd BG3"), + wxTRANSLATE("2nd OBJ"), + wxTRANSLATE("2nd BD"), + wxT(""), + wxT(""), + } + }, + { + &COLEV, 0x52, wxTRANSLATE("0x4000052-COLEV"), 0x1F1F, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Coefficient EVA (5 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Coefficient EVB (5 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &COLY, 0x54, wxTRANSLATE("0x4000054-COLEY"), 0x001F, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Coefficient EVY (5 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + NULL, 0x60, wxTRANSLATE("0x4000060-SG10_L"), 0x007F, + { + wxT(""), + wxT(""), + wxTRANSLATE("Sweep Shifts (3 bits)"), + wxTRANSLATE("Sweep addition/decrease"), + wxT(""), + wxT(""), + wxTRANSLATE("Sweep Time (3 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + NULL, 0x62, wxTRANSLATE("0x4000062-SG10_H"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Sound Length (6 bits,W)"), + wxT(""), + wxTRANSLATE("Waveform Type (2 bits)"), + wxT(""), + wxT(""), + wxTRANSLATE("Envelope Steps (3 bits)"), + wxTRANSLATE("Envelope Attenuate/Amplify"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Envelope Initial Value"), + } + }, + { + NULL, 0x64, wxTRANSLATE("0x4000064-SG11"), 0xC7FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Frequency (11 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Sound Continuous/Counter"), + wxTRANSLATE("Initialization (W)"), + } + }, + { + NULL, 0x68, wxTRANSLATE("0x4000068-SG20"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Sound Length (6 bits,W)"), + wxT(""), + wxTRANSLATE("Waveform Type (2 bits)"), + wxT(""), + wxT(""), + wxTRANSLATE("Envelope Steps (3 bits)"), + wxTRANSLATE("Envelope Attenuate/Amplify"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Envelope Initial Value"), + } + }, + { + NULL, 0x6C, wxTRANSLATE("0x400006C-SG21"), 0xC7FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Frequency (11 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Sound Continuous/Counter"), + wxTRANSLATE("Initialization (W)"), + } + }, + { + NULL, 0x70, wxTRANSLATE("0x4000070-SG30_L"), 0x00E0, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Waveform 32/64 Steps"), + wxTRANSLATE("Waveform Bank 0/1"), + wxTRANSLATE("Sound Output"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + NULL, 0x72, wxTRANSLATE("0x4000072-SG30_H"), 0xE0FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Sound Length (8 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Output Level (2 bits)"), + wxTRANSLATE("Forced 3/4 Output Level"), + } + }, + { + NULL, 0x74, wxTRANSLATE("0x4000074-SG31"), 0xC7FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Frequency (11 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Sound Continuous/Counter"), + wxTRANSLATE("Initialization (W)"), + } + }, + { + NULL, 0x78, wxTRANSLATE("0x4000078-SG40"), 0xFF3F, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Sound Length (6 bits,W)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Envelope Steps (3 bits)"), + wxTRANSLATE("Envelope Attenuate/Amplify"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Envelope Initial Value"), + } + }, + { + NULL, 0x7C, wxTRANSLATE("0x400007C-SG41"), 0xC0FF, + { + wxT(""), + wxT(""), + wxTRANSLATE("Dividing Ratio Freq. (3 bits)"), + wxTRANSLATE("Counter 15/7 Steps"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Counter Shift Clock (4 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Sound Continuous/Counter"), + wxTRANSLATE("Initialization (W)"), + } + }, + { + NULL, 0x80, wxTRANSLATE("0x4000080-SGCNT0_L"), 0xFF77, + { + wxT(""), + wxT(""), + wxTRANSLATE("Right Volume (3 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Left Volume (3 bits)"), + wxT(""), + wxTRANSLATE("Channel 1->Right"), + wxTRANSLATE("Channel 2->Right"), + wxTRANSLATE("Channel 3->Right"), + wxTRANSLATE("Channel 4->Right"), + wxTRANSLATE("Channel 1->Left"), + wxTRANSLATE("Channel 2->Left"), + wxTRANSLATE("Channel 3->Left"), + wxTRANSLATE("Channel 4->Left"), + } + }, + { + NULL, 0x82, wxTRANSLATE("0x4000082-SGCNT0_H"), 0xFF0F, + { + wxT(""), + wxTRANSLATE("Sound 1-4 Volume (2 bits)"), + wxTRANSLATE("DMA Sound A Volume"), + wxTRANSLATE("DMA Sound B Volume"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("DMA Sound A->Right"), + wxTRANSLATE("DMA Sound A->Left"), + wxTRANSLATE("DMA Sound A Timer"), + wxTRANSLATE("DMA Sound A Reset FIFO"), + wxTRANSLATE("DMA Sound B->Right"), + wxTRANSLATE("DMA Sound B->Left"), + wxTRANSLATE("DMA Sound B Timer"), + wxTRANSLATE("DMA Sound B Reset FIFO"), + } + }, + { + NULL, 0x84, wxTRANSLATE("0x4000084-SGCNT1"), 0x0080, + { + wxTRANSLATE("Sound 1 On"), + wxTRANSLATE("Sound 2 On"), + wxTRANSLATE("Sound 3 On"), + wxTRANSLATE("Sound 4 On"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Master Sound Enable"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + NULL, 0x88, wxTRANSLATE("0x4000088-SGBIAS"), 0xC3FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Bias Level (10 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Sampling Rate (2 bits)"), + } + }, + { + NULL, 0xA0, wxTRANSLATE("0x40000A0-SIGFIFOA_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Data 0 (8 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Data 1 (8 bits)"), + } + }, + { + NULL, 0xA2, wxTRANSLATE("0x40000A2-SIGFIFOA_H"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Data 2 (8 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Data 3 (8 bits)"), + } + }, + { + NULL, 0xA4, wxTRANSLATE("0x40000A4-SIGFIFOB_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Data 0 (8 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Data 1 (8 bits)"), + } + }, + { + NULL, 0xA6, wxTRANSLATE("0x40000A6-SIGFIFOB_H"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Data 2 (8 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Data 3 (8 bits)"), + } + }, + { + &DM0SAD_L, 0xB0, wxTRANSLATE("0x40000B0-DM0SAD_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Source Address (lower 16 bits)"), + } + }, + { + &DM0SAD_H, 0xB2, wxTRANSLATE("0x40000B2-DM0SAD_H"), 0x07FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Source Address (upper 11 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &DM0DAD_L, 0xB4, wxTRANSLATE("0x40000B4-DM0DAD_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address (lower 16 bits)"), + } + }, + { + &DM0DAD_H, 0xB6, wxTRANSLATE("0x40000B6-DM0DAD_H"), 0x07FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address (upper 11 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &DM0CNT_L, 0xB8, wxTRANSLATE("0x40000B8-DM0CNT_L"), 0x3FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Count (14 bits)"), + wxT(""), + wxT(""), + } + }, + { + &DM0CNT_H, 0xBA, wxTRANSLATE("0x40000BA-DM0CNT_H"), 0xF7E0, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address Control (2 bits)"), + wxT(""), + wxTRANSLATE("Source Address Control (2 bits)"), + wxTRANSLATE("Repeat"), + wxTRANSLATE("Transfer Type"), + wxT(""), + wxT(""), + wxTRANSLATE("Start Timing (2 bits)"), + wxTRANSLATE("Interrupt Request"), + wxTRANSLATE("Enable"), + } + }, + { + &DM1SAD_L, 0xBC, wxTRANSLATE("0x40000BC-DM1SAD_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Source Address (lower 16 bits)"), + } + }, + { + &DM1SAD_H, 0xBE, wxTRANSLATE("0x40000BE-DM1SAD_H"), 0x0FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Source Address (upper 12 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &DM1DAD_L, 0xC0, wxTRANSLATE("0x40000C0-DM1DAD_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address (lower 16 bits)"), + } + }, + { + &DM1DAD_H, 0xC2, wxTRANSLATE("0x40000C2-DM1DAD_H"), 0x07FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address (upper 11 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &DM1CNT_L, 0xC4, wxTRANSLATE("0x40000C4-DM1CNT_L"), 0x3FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Count (14 bits)"), + wxT(""), + wxT(""), + } + }, + { + &DM1CNT_H, 0xC6, wxTRANSLATE("0x40000C6-DM1CNT_H"), 0xF7E0, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address Control (2 bits)"), + wxT(""), + wxTRANSLATE("Source Address Control (2 bits)"), + wxTRANSLATE("Repeat"), + wxTRANSLATE("Transfer Type"), + wxT(""), + wxT(""), + wxTRANSLATE("Start Timing (2 bits)"), + wxTRANSLATE("Interrupt Request"), + wxTRANSLATE("Enable"), + } + }, + { + &DM2SAD_L, 0xC8, wxTRANSLATE("0x40000C8-DM2SAD_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Source Address (lower 16 bits)"), + } + }, + { + &DM2SAD_H, 0xCA, wxTRANSLATE("0x40000CA-DM2SAD_H"), 0x0FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Source Address (upper 12 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &DM2DAD_L, 0xCC, wxTRANSLATE("0x40000CC-DM2DAD_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address (lower 16 bits)"), + } + }, + { + &DM2DAD_H, 0xCE, wxTRANSLATE("0x40000CE-DM2DAD_H"), 0x07FF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address (upper 11 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &DM2CNT_L, 0xD0, wxTRANSLATE("0x40000D0-DM2CNT_L"), 0x3FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Count (14 bits)"), + wxT(""), + wxT(""), + } + }, + { + &DM2CNT_H, 0xD2, wxTRANSLATE("0x40000D2-DM2CNT_H"), 0xF7E0, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address Control (2 bits)"), + wxT(""), + wxTRANSLATE("Source Address Control (2 bits)"), + wxTRANSLATE("Repeat"), + wxTRANSLATE("Transfer Type"), + wxT(""), + wxT(""), + wxTRANSLATE("Start Timing (2 bits)"), + wxTRANSLATE("Interrupt Request"), + wxTRANSLATE("Enable"), + } + }, + { + &DM3SAD_L, 0xD4, wxTRANSLATE("0x40000D4-DM3SAD_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Source Address (lower 16 bits)"), + } + }, + { + &DM3SAD_H, 0xD6, wxTRANSLATE("0x40000D6-DM3SAD_H"), 0x0FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Source Address (upper 12 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &DM3DAD_L, 0xD8, wxTRANSLATE("0x40000D8-DM3DAD_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address (lower 16 bits)"), + } + }, + { + &DM3DAD_H, 0xDA, wxTRANSLATE("0x40000DA-DM3DAD_H"), 0x0FFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address (upper 12 bits)"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &DM3CNT_L, 0xDC, wxTRANSLATE("0x40000DC-DM3CNT_L"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Count (16 bits)"), + } + }, + { + &DM3CNT_H, 0xDE, wxTRANSLATE("0x40000DE-DM3CNT_H"), 0xFFE0, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Destination Address Control (2 bits)"), + wxT(""), + wxTRANSLATE("Source Address Control (2 bits)"), + wxTRANSLATE("Repeat"), + wxTRANSLATE("Transfer Type"), + wxTRANSLATE("Game Pak Data Request"), + wxT(""), + wxTRANSLATE("Start Timing (2 bits)"), + wxTRANSLATE("Interrupt Request"), + wxTRANSLATE("Enable"), + } + }, + { + &TM0D, 0x100, wxTRANSLATE("0x4000100-TM0D"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Timer Counter (16 bits)"), + } + }, + { + &TM0CNT, 0x102, wxTRANSLATE("0x4000102-TM0CNT"), 0x00C7, + { + wxT(""), + wxTRANSLATE("Scalar Selection (2 bits)"), + wxTRANSLATE("Count Up"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Interrupt Request"), + wxTRANSLATE("Enable"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &TM1D, 0x104, wxTRANSLATE("0x4000104-TM1D"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Timer Counter (16 bits)"), + } + }, + { + &TM1CNT, 0x106, wxTRANSLATE("0x4000106-TM1CNT"), 0x00C7, + { + wxT(""), + wxTRANSLATE("Scalar Selection (2 bits)"), + wxTRANSLATE("Count Up"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Interrupt Request"), + wxTRANSLATE("Enable"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &TM2D, 0x108, wxTRANSLATE("0x4000108-TM2D"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Timer Counter (16 bits)"), + } + }, + { + &TM2CNT, 0x10A, wxTRANSLATE("0x400010A-TM2CNT"), 0x00C7, + { + wxT(""), + wxTRANSLATE("Scalar Selection (2 bits)"), + wxTRANSLATE("Count Up"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Interrupt Request"), + wxTRANSLATE("Enable"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &TM3D, 0x10C, wxTRANSLATE("0x400010C-TM3D"), 0xFFFF, + { + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Timer Counter (16 bits)"), + } + }, + { + &TM3CNT, 0x10E, wxTRANSLATE("0x400010E-TM3CNT"), 0x00C7, + { + wxT(""), + wxTRANSLATE("Scalar Selection (2 bits)"), + wxTRANSLATE("Count Up"), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Interrupt Request"), + wxTRANSLATE("Enable"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + &P1, 0x130, wxTRANSLATE("0x4000130-P1"), 0x03FF, + { + wxTRANSLATE("A"), + wxTRANSLATE("B"), + wxTRANSLATE("Select"), + wxTRANSLATE("Start"), + wxTRANSLATE("Right"), + wxTRANSLATE("Left"), + wxTRANSLATE("Up"), + wxTRANSLATE("Down"), + wxTRANSLATE("Shoulder Right"), + wxTRANSLATE("Shoulder Left"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + NULL, 0x132, wxTRANSLATE("0x4000132-P1CNT"), 0xC3FF, + { + wxTRANSLATE("A"), + wxTRANSLATE("B"), + wxTRANSLATE("Select"), + wxTRANSLATE("Start"), + wxTRANSLATE("Right"), + wxTRANSLATE("Left"), + wxTRANSLATE("Up"), + wxTRANSLATE("Down"), + wxTRANSLATE("Shoulder Right"), + wxTRANSLATE("Shoulder Left"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Interrupt Request"), + wxTRANSLATE("Interrupt Condition"), + } + }, + { + &IE, 0x200, wxTRANSLATE("0x4000200-IE"), 0x3FFF, + { + wxTRANSLATE("VBlank"), + wxTRANSLATE("HBlank"), + wxTRANSLATE("VCount"), + wxTRANSLATE("Timer 0"), + wxTRANSLATE("Timer 1"), + wxTRANSLATE("Timer 2"), + wxTRANSLATE("Timer 3"), + wxTRANSLATE("Serial"), + wxTRANSLATE("DMA 0"), + wxTRANSLATE("DMA 1"), + wxTRANSLATE("DMA 2"), + wxTRANSLATE("DMA 3"), + wxTRANSLATE("Keypad"), + wxTRANSLATE("Game Pak"), + wxT(""), + wxT(""), + } + }, + { + &IF, 0x202, wxTRANSLATE("0x4000202-IF"), 0x0000, + { + wxTRANSLATE("VBlank"), + wxTRANSLATE("HBlank"), + wxTRANSLATE("VCount"), + wxTRANSLATE("Timer 0"), + wxTRANSLATE("Timer 1"), + wxTRANSLATE("Timer 2"), + wxTRANSLATE("Timer 3"), + wxTRANSLATE("Serial"), + wxTRANSLATE("DMA 0"), + wxTRANSLATE("DMA 1"), + wxTRANSLATE("DMA 2"), + wxTRANSLATE("DMA 3"), + wxTRANSLATE("Keypad"), + wxTRANSLATE("Game Pak"), + wxT(""), + wxT(""), + } + }, + { + NULL, 0x204, wxTRANSLATE("0x4000204-WAITCNT"), 0x5FFF, + { + wxT(""), + wxTRANSLATE("SRAM Wait Control (2 bits)"), + wxT(""), + wxTRANSLATE("Wait State 0 First Access (2 bits)"), + wxTRANSLATE("Wait State 0 Second Access"), + wxT(""), + wxTRANSLATE("Wait State 1 First Access (2 bits)"), + wxTRANSLATE("Wait State 1 Second Access"), + wxT(""), + wxTRANSLATE("Wait State 2 First Access (2 bits)"), + wxTRANSLATE("Wait State 2 Second Access"), + wxT(""), + wxTRANSLATE("PHI Terminal Output (2 bits)"), + wxT(""), + wxTRANSLATE("Game Pak Prefetch Buffer"), + wxTRANSLATE("Game Pak Type Flag"), + } + }, + { + &IME, 0x208, wxTRANSLATE("0x4000208-IME"), 0x0001, + { + wxTRANSLATE("Master Interrupt Enable"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + } + }, + { + NULL, 0x300, wxTRANSLATE("0x4000300-HALTCNT"), 0x8001, + { + wxTRANSLATE("First Boot"), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxT(""), + wxTRANSLATE("Power Down"), + } + }, }; #define NUM_IOREGS (sizeof(ioregs)/sizeof(ioregs[0])) diff --git a/src/wx/openal.cpp b/src/wx/openal.cpp index 8e6734e5..f66d8361 100644 --- a/src/wx/openal.cpp +++ b/src/wx/openal.cpp @@ -46,19 +46,19 @@ public: void pause(); // pause the secondary sound buffer void reset(); // stop and reset the secondary sound buffer void resume(); // play/resume the secondary sound buffer - void write(u16 * finalWave, int length); // write the emulated sound to a sound buffer + void write(u16* finalWave, int length); // write the emulated sound to a sound buffer private: static OPENALFNTABLE ALFunction; bool initialized; bool buffersLoaded; - ALCdevice *device; - ALCcontext *context; - ALuint *buffer; + ALCdevice* device; + ALCcontext* context; + ALuint* buffer; ALuint tempBuffer; ALuint source; int freq; - int soundBufferLen; + int soundBufferLen; #ifdef LOGALL void debugState(); @@ -71,8 +71,8 @@ OpenAL::OpenAL() buffersLoaded = false; device = NULL; context = NULL; - buffer = (ALuint*)malloc( gopts.audio_buffers * sizeof( ALuint ) ); - memset( buffer, 0, gopts.audio_buffers * sizeof( ALuint ) ); + buffer = (ALuint*)malloc(gopts.audio_buffers * sizeof(ALuint)); + memset(buffer, 0, gopts.audio_buffers * sizeof(ALuint)); tempBuffer = 0; source = 0; } @@ -80,33 +80,26 @@ OpenAL::OpenAL() OpenAL::~OpenAL() { - if( !initialized ) return; + if (!initialized) return; - ALFunction.alSourceStop( source ); + ALFunction.alSourceStop(source); ASSERT_SUCCESS; - - ALFunction.alSourcei( source, AL_BUFFER, 0 ); + ALFunction.alSourcei(source, AL_BUFFER, 0); ASSERT_SUCCESS; - - ALFunction.alDeleteSources( 1, &source ); + ALFunction.alDeleteSources(1, &source); ASSERT_SUCCESS; - - ALFunction.alDeleteBuffers( gopts.audio_buffers, buffer ); + ALFunction.alDeleteBuffers(gopts.audio_buffers, buffer); ASSERT_SUCCESS; - - free( buffer ); - - ALFunction.alcMakeContextCurrent( NULL ); + free(buffer); + ALFunction.alcMakeContextCurrent(NULL); // Wine incorrectly returns ALC_INVALID_VALUE // and then fails the rest of these functions as well // so there will be a leak under Wine, but that's a bug in Wine, not // this code //ASSERT_SUCCESS; - - ALFunction.alcDestroyContext( context ); + ALFunction.alcDestroyContext(context); //ASSERT_SUCCESS; - - ALFunction.alcCloseDevice( device ); + ALFunction.alcCloseDevice(device); //ASSERT_SUCCESS; ALFunction.alGetError(); // reset error state } @@ -114,81 +107,79 @@ OpenAL::~OpenAL() #ifdef LOGALL void OpenAL::debugState() { - ALint value = 0; - ALFunction.alGetSourcei( source, AL_SOURCE_STATE, &value ); + ALFunction.alGetSourcei(source, AL_SOURCE_STATE, &value); ASSERT_SUCCESS; + winlog(" soundPaused = %i\n", soundPaused); + winlog(" Source:\n"); + winlog(" State: "); - winlog( " soundPaused = %i\n", soundPaused ); - winlog( " Source:\n" ); - winlog( " State: " ); - switch( value ) + switch (value) { case AL_INITIAL: - winlog( "AL_INITIAL\n" ); + winlog("AL_INITIAL\n"); break; + case AL_PLAYING: - winlog( "AL_PLAYING\n" ); + winlog("AL_PLAYING\n"); break; + case AL_PAUSED: - winlog( "AL_PAUSED\n" ); + winlog("AL_PAUSED\n"); break; + case AL_STOPPED: - winlog( "AL_STOPPED\n" ); + winlog("AL_STOPPED\n"); break; + default: - winlog( "!unknown!\n" ); + winlog("!unknown!\n"); break; } - - ALFunction.alGetSourcei( source, AL_BUFFERS_QUEUED, &value ); + ALFunction.alGetSourcei(source, AL_BUFFERS_QUEUED, &value); ASSERT_SUCCESS; - winlog( " Buffers in queue: %i\n", value ); - - ALFunction.alGetSourcei( source, AL_BUFFERS_PROCESSED, &value ); + winlog(" Buffers in queue: %i\n", value); + ALFunction.alGetSourcei(source, AL_BUFFERS_PROCESSED, &value); ASSERT_SUCCESS; - winlog( " Buffers processed: %i\n", value ); + winlog(" Buffers processed: %i\n", value); } #endif bool OpenAL::init(long sampleRate) { - winlog( "OpenAL::init\n" ); - assert( initialized == false ); + winlog("OpenAL::init\n"); + assert(initialized == false); - if( !LoadOAL() ) { - wxLogError( _("OpenAL library could not be found on your system. Please install the runtime from http://openal.org") ); + if (!LoadOAL()) + { + wxLogError(_("OpenAL library could not be found on your system. Please install the runtime from http://openal.org")); return false; } - if( !gopts.audio_dev.empty() ) { - device = ALFunction.alcOpenDevice( gopts.audio_dev.mb_str() ); - } else { - device = ALFunction.alcOpenDevice( NULL ); + if (!gopts.audio_dev.empty()) + { + device = ALFunction.alcOpenDevice(gopts.audio_dev.mb_str()); + } + else + { + device = ALFunction.alcOpenDevice(NULL); } - assert( device != NULL ); - context = ALFunction.alcCreateContext( device, NULL ); - assert( context != NULL ); - - ALCboolean retVal = ALFunction.alcMakeContextCurrent( context ); - assert( ALC_TRUE == retVal ); - - ALFunction.alGenBuffers( gopts.audio_buffers, buffer ); + assert(device != NULL); + context = ALFunction.alcCreateContext(device, NULL); + assert(context != NULL); + ALCboolean retVal = ALFunction.alcMakeContextCurrent(context); + assert(ALC_TRUE == retVal); + ALFunction.alGenBuffers(gopts.audio_buffers, buffer); ASSERT_SUCCESS; - - ALFunction.alGenSources( 1, &source ); + ALFunction.alGenSources(1, &source); ASSERT_SUCCESS; - freq = sampleRate; - // calculate the number of samples per frame first // then multiply it with the size of a sample frame (16 bit * stereo) - soundBufferLen = ( freq / 60 ) * 4; - - + soundBufferLen = (freq / 60) * 4; initialized = true; return true; } @@ -196,142 +187,164 @@ bool OpenAL::init(long sampleRate) void OpenAL::resume() { - if( !initialized ) return; - winlog( "OpenAL::resume\n" ); - if( !buffersLoaded ) return; + if (!initialized) return; + + winlog("OpenAL::resume\n"); + + if (!buffersLoaded) return; + debugState(); - - ALint sourceState = 0; - ALFunction.alGetSourcei( source, AL_SOURCE_STATE, &sourceState ); + ALFunction.alGetSourcei(source, AL_SOURCE_STATE, &sourceState); ASSERT_SUCCESS; - if( sourceState != AL_PLAYING ) { - ALFunction.alSourcePlay( source ); + + if (sourceState != AL_PLAYING) + { + ALFunction.alSourcePlay(source); ASSERT_SUCCESS; } + debugState(); } void OpenAL::pause() { - if( !initialized ) return; - winlog( "OpenAL::pause\n" ); - if( !buffersLoaded ) return; + if (!initialized) return; + + winlog("OpenAL::pause\n"); + + if (!buffersLoaded) return; + debugState(); - - ALint sourceState = 0; - ALFunction.alGetSourcei( source, AL_SOURCE_STATE, &sourceState ); + ALFunction.alGetSourcei(source, AL_SOURCE_STATE, &sourceState); ASSERT_SUCCESS; - if( sourceState == AL_PLAYING ) { - ALFunction.alSourcePause( source ); + + if (sourceState == AL_PLAYING) + { + ALFunction.alSourcePause(source); ASSERT_SUCCESS; } + debugState(); } void OpenAL::reset() { - if( !initialized ) return; - winlog( "OpenAL::reset\n" ); - if( !buffersLoaded ) return; - debugState(); + if (!initialized) return; + winlog("OpenAL::reset\n"); + + if (!buffersLoaded) return; + + debugState(); ALint sourceState = 0; - ALFunction.alGetSourcei( source, AL_SOURCE_STATE, &sourceState ); + ALFunction.alGetSourcei(source, AL_SOURCE_STATE, &sourceState); ASSERT_SUCCESS; - if( sourceState != AL_STOPPED ) { - ALFunction.alSourceStop( source ); + + if (sourceState != AL_STOPPED) + { + ALFunction.alSourceStop(source); ASSERT_SUCCESS; } + debugState(); } -void OpenAL::write(u16 * finalWave, int length) +void OpenAL::write(u16* finalWave, int length) { - if( !initialized ) return; - winlog( "OpenAL::write\n" ); + if (!initialized) return; + winlog("OpenAL::write\n"); debugState(); - ALint sourceState = 0; ALint nBuffersProcessed = 0; - if( !buffersLoaded ) { + if (!buffersLoaded) + { // ==initial buffer filling== - winlog( " initial buffer filling\n" ); - for( int i = 0 ; i < gopts.audio_buffers ; i++ ) { + winlog(" initial buffer filling\n"); + + for (int i = 0 ; i < gopts.audio_buffers ; i++) + { // Filling the buffers explicitly with silence would be cleaner, // but the very first sample is usually silence anyway. - ALFunction.alBufferData( buffer[i], AL_FORMAT_STEREO16, finalWave, soundBufferLen, freq ); + ALFunction.alBufferData(buffer[i], AL_FORMAT_STEREO16, finalWave, soundBufferLen, freq); ASSERT_SUCCESS; } - ALFunction.alSourceQueueBuffers( source, gopts.audio_buffers, buffer ); + ALFunction.alSourceQueueBuffers(source, gopts.audio_buffers, buffer); ASSERT_SUCCESS; - buffersLoaded = true; - } else { + } + else + { // ==normal buffer refreshing== nBuffersProcessed = 0; - ALFunction.alGetSourcei( source, AL_BUFFERS_PROCESSED, &nBuffersProcessed ); + ALFunction.alGetSourcei(source, AL_BUFFERS_PROCESSED, &nBuffersProcessed); ASSERT_SUCCESS; - if( nBuffersProcessed == gopts.audio_buffers ) { + if (nBuffersProcessed == gopts.audio_buffers) + { // we only want to know about it when we are emulating at full speed or faster: - if( ( throttle >= 100 ) || ( throttle == 0 ) ) { - if( systemVerbose & VERBOSE_SOUNDOUTPUT ) { + if ((throttle >= 100) || (throttle == 0)) + { + if (systemVerbose & VERBOSE_SOUNDOUTPUT) + { static unsigned int i = 0; - log( "OpenAL: Buffers were not refilled fast enough (i=%i)\n", i++ ); + log("OpenAL: Buffers were not refilled fast enough (i=%i)\n", i++); } } } - if (!speedup && throttle && !gba_joybus_active) { + if (!speedup && throttle && !gba_joybus_active) + { // wait until at least one buffer has finished - while( nBuffersProcessed == 0 ) { - winlog( " waiting...\n" ); + while (nBuffersProcessed == 0) + { + winlog(" waiting...\n"); // wait for about half the time one buffer needs to finish // unoptimized: ( sourceBufferLen * 1000 ) / ( freq * 2 * 2 ) * 1/2 - wxMilliSleep( soundBufferLen / ( freq >> 7 ) ); - ALFunction.alGetSourcei( source, AL_BUFFERS_PROCESSED, &nBuffersProcessed ); + wxMilliSleep(soundBufferLen / (freq >> 7)); + ALFunction.alGetSourcei(source, AL_BUFFERS_PROCESSED, &nBuffersProcessed); ASSERT_SUCCESS; } - } else { - if( nBuffersProcessed == 0 ) return; + } + else + { + if (nBuffersProcessed == 0) return; } - assert( nBuffersProcessed > 0 ); - + assert(nBuffersProcessed > 0); // unqueue buffer tempBuffer = 0; - ALFunction.alSourceUnqueueBuffers( source, 1, &tempBuffer ); + ALFunction.alSourceUnqueueBuffers(source, 1, &tempBuffer); ASSERT_SUCCESS; - // refill buffer - ALFunction.alBufferData( tempBuffer, AL_FORMAT_STEREO16, finalWave, soundBufferLen, freq ); + ALFunction.alBufferData(tempBuffer, AL_FORMAT_STEREO16, finalWave, soundBufferLen, freq); ASSERT_SUCCESS; - // requeue buffer - ALFunction.alSourceQueueBuffers( source, 1, &tempBuffer ); + ALFunction.alSourceQueueBuffers(source, 1, &tempBuffer); ASSERT_SUCCESS; } // start playing the source if necessary - ALFunction.alGetSourcei( source, AL_SOURCE_STATE, &sourceState ); + ALFunction.alGetSourcei(source, AL_SOURCE_STATE, &sourceState); ASSERT_SUCCESS; - if( !soundPaused && ( sourceState != AL_PLAYING ) ) { - ALFunction.alSourcePlay( source ); + + if (!soundPaused && (sourceState != AL_PLAYING)) + { + ALFunction.alSourcePlay(source); ASSERT_SUCCESS; } } -SoundDriver *newOpenAL() +SoundDriver* newOpenAL() { - winlog( "newOpenAL\n" ); + winlog("newOpenAL\n"); return new OpenAL(); } @@ -348,23 +361,24 @@ wxDynamicLibrary OpenAL::Lib; bool OpenAL::LoadOAL() { - if(!Lib.IsLoaded() && + if (!Lib.IsLoaded() && #ifdef __WXMSW__ - // on win32, it's openal32.dll - !Lib.Load(wxT("openal32")) && + // on win32, it's openal32.dll + !Lib.Load(wxT("openal32")) && #else #ifdef __WXMAC__ - // on macosx, it's just plain OpenAL - !Lib.Load(wxT("OpenAL"), wxDL_NOW|wxDL_VERBATIM) && + // on macosx, it's just plain OpenAL + !Lib.Load(wxT("OpenAL"), wxDL_NOW | wxDL_VERBATIM) && #endif #endif - // on linux, it's libopenal.so - // try standard name on all platforms - !Lib.Load(wxDynamicLibrary::CanonicalizeName(wxT("openal")))) + // on linux, it's libopenal.so + // try standard name on all platforms + !Lib.Load(wxDynamicLibrary::CanonicalizeName(wxT("openal")))) return false; + #define loadfn(t, n) do { \ - if(!(ALFunction.n = (t)Lib.GetSymbol(wxT(#n)))) \ - return false; \ + if(!(ALFunction.n = (t)Lib.GetSymbol(wxT(#n)))) \ + return false; \ } while(0) //loadfn(LPALENABLE, alEnable); //loadfn(LPALDISABLE, alDisable); @@ -439,7 +453,6 @@ bool OpenAL::LoadOAL() //loadfn(LPALDOPPLERVELOCITY, alDopplerVelocity); //loadfn(LPALSPEEDOFSOUND, alSpeedOfSound); //loadfn(LPALDISTANCEMODEL, alDistanceModel); - loadfn(LPALCCREATECONTEXT, alcCreateContext); loadfn(LPALCMAKECONTEXTCURRENT, alcMakeContextCurrent); //loadfn(LPALCPROCESSCONTEXT, alcProcessContext); @@ -470,18 +483,24 @@ bool GetOALDevices(wxArrayString &names, wxArrayString &ids) bool OpenAL::GetDevices(wxArrayString &names, wxArrayString &ids) { - if(!OpenAL::LoadOAL()) + if (!OpenAL::LoadOAL()) return false; + #ifdef ALC_DEVICE_SPECIFIER - if(ALFunction.alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_FALSE) + + if (ALFunction.alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_FALSE) // this extension isn't critical to OpenAL operating return true; - const char *devs = ALFunction.alcGetString(NULL, ALC_DEVICE_SPECIFIER); - while(*devs) { + + const char* devs = ALFunction.alcGetString(NULL, ALC_DEVICE_SPECIFIER); + + while (*devs) + { names.push_back(wxString(devs, wxConvLibc)); ids.push_back(names[names.size() - 1]); devs += strlen(devs) + 1; } + #else // should work anyway, but must always use default driver return true; diff --git a/src/wx/openal.h b/src/wx/openal.h index a0a2abac..d8f47634 100644 --- a/src/wx/openal.h +++ b/src/wx/openal.h @@ -15,17 +15,18 @@ // since the ALC typedefs are broken on Mac: #ifdef __WXMAC__ -typedef ALCcontext * (ALC_APIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist); -typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context ); -typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context ); -typedef ALCdevice * (ALC_APIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename ); -typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device ); -typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname ); -typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param ); +typedef ALCcontext* (ALC_APIENTRY* LPALCCREATECONTEXT)(ALCdevice* device, const ALCint* attrlist); +typedef ALCboolean(ALC_APIENTRY* LPALCMAKECONTEXTCURRENT)(ALCcontext* context); +typedef void (ALC_APIENTRY* LPALCDESTROYCONTEXT)(ALCcontext* context); +typedef ALCdevice* (ALC_APIENTRY* LPALCOPENDEVICE)(const ALCchar* devicename); +typedef ALCboolean(ALC_APIENTRY* LPALCCLOSEDEVICE)(ALCdevice* device); +typedef ALCboolean(ALC_APIENTRY* LPALCISEXTENSIONPRESENT)(ALCdevice* device, const ALCchar* extname); +typedef const ALCchar* (ALC_APIENTRY* LPALCGETSTRING)(ALCdevice* device, ALCenum param); #endif // no more use of copyrighted OpenAL code just to load the stupid library -struct OPENALFNTABLE { +struct OPENALFNTABLE +{ //LPALENABLE alEnable; //LPALDISABLE alDisable; //LPALISENABLED alIsEnabled; diff --git a/src/wx/opts.cpp b/src/wx/opts.cpp index a1312d9b..b49e3a86 100644 --- a/src/wx/opts.cpp +++ b/src/wx/opts.cpp @@ -4,13 +4,13 @@ #include "../common/ConfigManager.h" /* - * disableSfx(F) -> cpuDisableSfx - * priority(2) -> threadPriority - * saveMoreCPU(F) -> Sm60FPS - * - * SDL: - * -p/--profile=hz - */ + disableSfx(F) -> cpuDisableSfx + priority(2) -> threadPriority + saveMoreCPU(F) -> Sm60FPS + + SDL: + -p/--profile=hz +*/ /* not sure how well other compilers support field-init syntax */ #define STROPT(c, n, d, v) {wxT(c), (n), d, &v} @@ -21,763 +21,954 @@ opts_t gopts; // having the standard menu accels here means they will work even without menus -const wxAcceleratorEntry default_accels[] = { - wxAcceleratorEntry(wxMOD_CMD, wxT('C'), XRCID("CheatsList")), - wxAcceleratorEntry(wxMOD_CMD, wxT('N'), XRCID("NextFrame")), - // some ports add ctrl-q anyway, so may as well make it official - // maybe make alt-f4 universal as well... - // FIXME: ctrl-Q does not work on wxMSW - // FIXME: esc does not work on wxMSW - wxAcceleratorEntry(wxMOD_NONE, WXK_ESCAPE, wxID_EXIT), - wxAcceleratorEntry(wxMOD_CMD, wxT('X'), wxID_EXIT), - wxAcceleratorEntry(wxMOD_CMD, wxT('Q'), wxID_EXIT), - // FIXME: ctrl-W does not work on wxMSW - wxAcceleratorEntry(wxMOD_CMD, wxT('W'), wxID_CLOSE), - // load most recent is more commonly used than load other - //wxAcceleratorEntry(wxMOD_CMD, wxT('L'), XRCID("Load")), - wxAcceleratorEntry(wxMOD_CMD, wxT('L'), XRCID("LoadGameRecent")), - wxAcceleratorEntry(wxMOD_NONE, WXK_F1, XRCID("LoadGame01")), - wxAcceleratorEntry(wxMOD_NONE, WXK_F2, XRCID("LoadGame02")), - wxAcceleratorEntry(wxMOD_NONE, WXK_F3, XRCID("LoadGame03")), - wxAcceleratorEntry(wxMOD_NONE, WXK_F4, XRCID("LoadGame04")), - wxAcceleratorEntry(wxMOD_NONE, WXK_F5, XRCID("LoadGame05")), - wxAcceleratorEntry(wxMOD_NONE, WXK_F6, XRCID("LoadGame06")), - wxAcceleratorEntry(wxMOD_NONE, WXK_F7, XRCID("LoadGame07")), - wxAcceleratorEntry(wxMOD_NONE, WXK_F8, XRCID("LoadGame08")), - wxAcceleratorEntry(wxMOD_NONE, WXK_F9, XRCID("LoadGame09")), - wxAcceleratorEntry(wxMOD_NONE, WXK_F10, XRCID("LoadGame10")), - wxAcceleratorEntry(wxMOD_NONE, WXK_PAUSE, XRCID("Pause")), - wxAcceleratorEntry(wxMOD_CMD, wxT('P'), XRCID("Pause")), - wxAcceleratorEntry(wxMOD_CMD, wxT('R'), XRCID("Reset")), - // save oldest is more commonly used than save other - //wxAcceleratorEntry(wxMOD_CMD, wxT('S'), XRCID("Save")), - wxAcceleratorEntry(wxMOD_CMD, wxT('S'), XRCID("SaveGameOldest")), - wxAcceleratorEntry(wxMOD_SHIFT, WXK_F1, XRCID("SaveGame01")), - wxAcceleratorEntry(wxMOD_SHIFT, WXK_F2, XRCID("SaveGame02")), - wxAcceleratorEntry(wxMOD_SHIFT, WXK_F3, XRCID("SaveGame03")), - wxAcceleratorEntry(wxMOD_SHIFT, WXK_F4, XRCID("SaveGame04")), - wxAcceleratorEntry(wxMOD_SHIFT, WXK_F5, XRCID("SaveGame05")), - wxAcceleratorEntry(wxMOD_SHIFT, WXK_F6, XRCID("SaveGame06")), - wxAcceleratorEntry(wxMOD_SHIFT, WXK_F7, XRCID("SaveGame07")), - wxAcceleratorEntry(wxMOD_SHIFT, WXK_F8, XRCID("SaveGame08")), - wxAcceleratorEntry(wxMOD_SHIFT, WXK_F9, XRCID("SaveGame09")), - wxAcceleratorEntry(wxMOD_SHIFT, WXK_F10, XRCID("SaveGame10")), - // I prefer the SDL ESC key binding - //wxAcceleratorEntry(wxMOD_NONE, WXK_ESCAPE, XRCID("ToggleFullscreen"), - // alt-enter is more standard anyway - wxAcceleratorEntry(wxMOD_ALT, WXK_RETURN, XRCID("ToggleFullscreen")), - wxAcceleratorEntry(wxMOD_ALT, wxT('1'), XRCID("JoypadAutofireA")), - wxAcceleratorEntry(wxMOD_ALT, wxT('2'), XRCID("JoypadAutofireB")), - wxAcceleratorEntry(wxMOD_ALT, wxT('3'), XRCID("JoypadAutofireL")), - wxAcceleratorEntry(wxMOD_ALT, wxT('4'), XRCID("JoypadAutofireR")), - wxAcceleratorEntry(wxMOD_CMD, wxT('1'), XRCID("VideoLayersBG0")), - wxAcceleratorEntry(wxMOD_CMD, wxT('2'), XRCID("VideoLayersBG1")), - wxAcceleratorEntry(wxMOD_CMD, wxT('3'), XRCID("VideoLayersBG2")), - wxAcceleratorEntry(wxMOD_CMD, wxT('4'), XRCID("VideoLayersBG3")), - wxAcceleratorEntry(wxMOD_CMD, wxT('5'), XRCID("VideoLayersOBJ")), - wxAcceleratorEntry(wxMOD_CMD, wxT('6'), XRCID("VideoLayersWIN0")), - wxAcceleratorEntry(wxMOD_CMD, wxT('7'), XRCID("VideoLayersWIN1")), - wxAcceleratorEntry(wxMOD_CMD, wxT('8'), XRCID("VideoLayersOBJWIN")), - wxAcceleratorEntry(wxMOD_CMD, wxT('B'), XRCID("Rewind")), - // following are not in standard menus - // FILExx are filled in when recent menu is filled - wxAcceleratorEntry(wxMOD_CMD, WXK_F1, wxID_FILE1), - wxAcceleratorEntry(wxMOD_CMD, WXK_F2, wxID_FILE2), - wxAcceleratorEntry(wxMOD_CMD, WXK_F3, wxID_FILE3), - wxAcceleratorEntry(wxMOD_CMD, WXK_F4, wxID_FILE4), - wxAcceleratorEntry(wxMOD_CMD, WXK_F5, wxID_FILE5), - wxAcceleratorEntry(wxMOD_CMD, WXK_F6, wxID_FILE6), - wxAcceleratorEntry(wxMOD_CMD, WXK_F7, wxID_FILE7), - wxAcceleratorEntry(wxMOD_CMD, WXK_F8, wxID_FILE8), - wxAcceleratorEntry(wxMOD_CMD, WXK_F9, wxID_FILE9), - wxAcceleratorEntry(wxMOD_CMD, WXK_F10, wxID_FILE10), - wxAcceleratorEntry(wxMOD_CMD, wxT('0'), XRCID("VideoLayersReset")), - wxAcceleratorEntry(wxMOD_CMD, wxT('G'), XRCID("ChangeFilter")), - wxAcceleratorEntry(wxMOD_NONE, WXK_NUMPAD_ADD, XRCID("IncreaseVolume")), - wxAcceleratorEntry(wxMOD_NONE, WXK_NUMPAD_SUBTRACT, XRCID("DecreaseVolume")), - wxAcceleratorEntry(wxMOD_NONE, WXK_NUMPAD_ENTER, XRCID("ToggleSound")) +const wxAcceleratorEntry default_accels[] = +{ + wxAcceleratorEntry(wxMOD_CMD, wxT('C'), XRCID("CheatsList")), + wxAcceleratorEntry(wxMOD_CMD, wxT('N'), XRCID("NextFrame")), + // some ports add ctrl-q anyway, so may as well make it official + // maybe make alt-f4 universal as well... + // FIXME: ctrl-Q does not work on wxMSW + // FIXME: esc does not work on wxMSW + wxAcceleratorEntry(wxMOD_NONE, WXK_ESCAPE, wxID_EXIT), + wxAcceleratorEntry(wxMOD_CMD, wxT('X'), wxID_EXIT), + wxAcceleratorEntry(wxMOD_CMD, wxT('Q'), wxID_EXIT), + // FIXME: ctrl-W does not work on wxMSW + wxAcceleratorEntry(wxMOD_CMD, wxT('W'), wxID_CLOSE), + // load most recent is more commonly used than load other + //wxAcceleratorEntry(wxMOD_CMD, wxT('L'), XRCID("Load")), + wxAcceleratorEntry(wxMOD_CMD, wxT('L'), XRCID("LoadGameRecent")), + wxAcceleratorEntry(wxMOD_NONE, WXK_F1, XRCID("LoadGame01")), + wxAcceleratorEntry(wxMOD_NONE, WXK_F2, XRCID("LoadGame02")), + wxAcceleratorEntry(wxMOD_NONE, WXK_F3, XRCID("LoadGame03")), + wxAcceleratorEntry(wxMOD_NONE, WXK_F4, XRCID("LoadGame04")), + wxAcceleratorEntry(wxMOD_NONE, WXK_F5, XRCID("LoadGame05")), + wxAcceleratorEntry(wxMOD_NONE, WXK_F6, XRCID("LoadGame06")), + wxAcceleratorEntry(wxMOD_NONE, WXK_F7, XRCID("LoadGame07")), + wxAcceleratorEntry(wxMOD_NONE, WXK_F8, XRCID("LoadGame08")), + wxAcceleratorEntry(wxMOD_NONE, WXK_F9, XRCID("LoadGame09")), + wxAcceleratorEntry(wxMOD_NONE, WXK_F10, XRCID("LoadGame10")), + wxAcceleratorEntry(wxMOD_NONE, WXK_PAUSE, XRCID("Pause")), + wxAcceleratorEntry(wxMOD_CMD, wxT('P'), XRCID("Pause")), + wxAcceleratorEntry(wxMOD_CMD, wxT('R'), XRCID("Reset")), + // save oldest is more commonly used than save other + //wxAcceleratorEntry(wxMOD_CMD, wxT('S'), XRCID("Save")), + wxAcceleratorEntry(wxMOD_CMD, wxT('S'), XRCID("SaveGameOldest")), + wxAcceleratorEntry(wxMOD_SHIFT, WXK_F1, XRCID("SaveGame01")), + wxAcceleratorEntry(wxMOD_SHIFT, WXK_F2, XRCID("SaveGame02")), + wxAcceleratorEntry(wxMOD_SHIFT, WXK_F3, XRCID("SaveGame03")), + wxAcceleratorEntry(wxMOD_SHIFT, WXK_F4, XRCID("SaveGame04")), + wxAcceleratorEntry(wxMOD_SHIFT, WXK_F5, XRCID("SaveGame05")), + wxAcceleratorEntry(wxMOD_SHIFT, WXK_F6, XRCID("SaveGame06")), + wxAcceleratorEntry(wxMOD_SHIFT, WXK_F7, XRCID("SaveGame07")), + wxAcceleratorEntry(wxMOD_SHIFT, WXK_F8, XRCID("SaveGame08")), + wxAcceleratorEntry(wxMOD_SHIFT, WXK_F9, XRCID("SaveGame09")), + wxAcceleratorEntry(wxMOD_SHIFT, WXK_F10, XRCID("SaveGame10")), + // I prefer the SDL ESC key binding + //wxAcceleratorEntry(wxMOD_NONE, WXK_ESCAPE, XRCID("ToggleFullscreen"), + // alt-enter is more standard anyway + wxAcceleratorEntry(wxMOD_ALT, WXK_RETURN, XRCID("ToggleFullscreen")), + wxAcceleratorEntry(wxMOD_ALT, wxT('1'), XRCID("JoypadAutofireA")), + wxAcceleratorEntry(wxMOD_ALT, wxT('2'), XRCID("JoypadAutofireB")), + wxAcceleratorEntry(wxMOD_ALT, wxT('3'), XRCID("JoypadAutofireL")), + wxAcceleratorEntry(wxMOD_ALT, wxT('4'), XRCID("JoypadAutofireR")), + wxAcceleratorEntry(wxMOD_CMD, wxT('1'), XRCID("VideoLayersBG0")), + wxAcceleratorEntry(wxMOD_CMD, wxT('2'), XRCID("VideoLayersBG1")), + wxAcceleratorEntry(wxMOD_CMD, wxT('3'), XRCID("VideoLayersBG2")), + wxAcceleratorEntry(wxMOD_CMD, wxT('4'), XRCID("VideoLayersBG3")), + wxAcceleratorEntry(wxMOD_CMD, wxT('5'), XRCID("VideoLayersOBJ")), + wxAcceleratorEntry(wxMOD_CMD, wxT('6'), XRCID("VideoLayersWIN0")), + wxAcceleratorEntry(wxMOD_CMD, wxT('7'), XRCID("VideoLayersWIN1")), + wxAcceleratorEntry(wxMOD_CMD, wxT('8'), XRCID("VideoLayersOBJWIN")), + wxAcceleratorEntry(wxMOD_CMD, wxT('B'), XRCID("Rewind")), + // following are not in standard menus + // FILExx are filled in when recent menu is filled + wxAcceleratorEntry(wxMOD_CMD, WXK_F1, wxID_FILE1), + wxAcceleratorEntry(wxMOD_CMD, WXK_F2, wxID_FILE2), + wxAcceleratorEntry(wxMOD_CMD, WXK_F3, wxID_FILE3), + wxAcceleratorEntry(wxMOD_CMD, WXK_F4, wxID_FILE4), + wxAcceleratorEntry(wxMOD_CMD, WXK_F5, wxID_FILE5), + wxAcceleratorEntry(wxMOD_CMD, WXK_F6, wxID_FILE6), + wxAcceleratorEntry(wxMOD_CMD, WXK_F7, wxID_FILE7), + wxAcceleratorEntry(wxMOD_CMD, WXK_F8, wxID_FILE8), + wxAcceleratorEntry(wxMOD_CMD, WXK_F9, wxID_FILE9), + wxAcceleratorEntry(wxMOD_CMD, WXK_F10, wxID_FILE10), + wxAcceleratorEntry(wxMOD_CMD, wxT('0'), XRCID("VideoLayersReset")), + wxAcceleratorEntry(wxMOD_CMD, wxT('G'), XRCID("ChangeFilter")), + wxAcceleratorEntry(wxMOD_NONE, WXK_NUMPAD_ADD, XRCID("IncreaseVolume")), + wxAcceleratorEntry(wxMOD_NONE, WXK_NUMPAD_SUBTRACT, XRCID("DecreaseVolume")), + wxAcceleratorEntry(wxMOD_NONE, WXK_NUMPAD_ENTER, XRCID("ToggleSound")) }; -const int num_def_accels = sizeof(default_accels)/sizeof(default_accels[0]); +const int num_def_accels = sizeof(default_accels) / sizeof(default_accels[0]); // Note: this must match GUI widget names or GUI won't work // This table's order determines tab order as well -const char * const joynames[NUM_KEYS] = { - ("Up"), ("Down"), ("Left"), ("Right"), - ("A"), ("B"), ("L"), ("R"), - ("Select"), ("Start"), - ("MotionUp"), ("MotionDown"), ("MotionLeft"), ("MotionRight"), - ("MotionIn"), ("MotionOut"), ("AutoA"), ("AutoB"), - ("Speed"), ("Capture"), ("GS") +const char* const joynames[NUM_KEYS] = +{ + ("Up"), ("Down"), ("Left"), ("Right"), + ("A"), ("B"), ("L"), ("R"), + ("Select"), ("Start"), + ("MotionUp"), ("MotionDown"), ("MotionLeft"), ("MotionRight"), + ("MotionIn"), ("MotionOut"), ("AutoA"), ("AutoB"), + ("Speed"), ("Capture"), ("GS") }; -wxJoyKeyBinding defkeys[NUM_KEYS * 2] = { - { WXK_UP }, { 1, WXJB_AXIS_MINUS, 1 }, { WXK_DOWN }, { 1, WXJB_AXIS_PLUS, 1 }, - { WXK_LEFT }, { 0, WXJB_AXIS_MINUS, 1 }, { WXK_RIGHT }, { 0, WXJB_AXIS_PLUS, 1 }, - { wxT('X') }, { 0, WXJB_BUTTON, 1 }, { wxT('Z') }, { 1, WXJB_BUTTON, 1 }, - { wxT('A') }, { 2, WXJB_BUTTON, 1 }, { wxT('S') }, { 3, WXJB_BUTTON, 1 }, - { WXK_BACK }, { 4, WXJB_BUTTON, 1 }, { WXK_RETURN }, { 5, WXJB_BUTTON, 1 }, - { WXK_NUMPAD_UP }, { 2, WXJB_AXIS_PLUS, 1 }, { WXK_NUMPAD_DOWN }, { 2, WXJB_AXIS_MINUS, 1 }, - { WXK_NUMPAD_LEFT }, { 3, WXJB_AXIS_MINUS, 1 }, { WXK_NUMPAD_RIGHT }, { 3, WXJB_AXIS_PLUS, 1 }, +wxJoyKeyBinding defkeys[NUM_KEYS * 2] = +{ + { WXK_UP }, { 1, WXJB_AXIS_MINUS, 1 }, { WXK_DOWN }, { 1, WXJB_AXIS_PLUS, 1 }, + { WXK_LEFT }, { 0, WXJB_AXIS_MINUS, 1 }, { WXK_RIGHT }, { 0, WXJB_AXIS_PLUS, 1 }, + { wxT('X') }, { 0, WXJB_BUTTON, 1 }, { wxT('Z') }, { 1, WXJB_BUTTON, 1 }, + { wxT('A') }, { 2, WXJB_BUTTON, 1 }, { wxT('S') }, { 3, WXJB_BUTTON, 1 }, + { WXK_BACK }, { 4, WXJB_BUTTON, 1 }, { WXK_RETURN }, { 5, WXJB_BUTTON, 1 }, + { WXK_NUMPAD_UP }, { 2, WXJB_AXIS_PLUS, 1 }, { WXK_NUMPAD_DOWN }, { 2, WXJB_AXIS_MINUS, 1 }, + { WXK_NUMPAD_LEFT }, { 3, WXJB_AXIS_MINUS, 1 }, { WXK_NUMPAD_RIGHT }, { 3, WXJB_AXIS_PLUS, 1 }, { WXK_NUMPAD_PAGEUP }, { 4, WXJB_AXIS_PLUS, 1 }, { WXK_NUMPAD_PAGEDOWN }, { 4, WXJB_AXIS_MINUS, 1 }, { wxT('W') }, { 0 }, { wxT('Q') }, { 0 }, - { WXK_SPACE }, { 0 }, { WXK_F11 }, { 0 }, - { 0 } , { 0 } + { WXK_SPACE }, { 0 }, { WXK_F11 }, { 0 }, + { 0 } , { 0 } }; wxAcceleratorEntry_v sys_accels; // Note: this table must be sorted in option name order // Both for better user display and for (fast) searching by name -opt_desc opts[] = { - /// Display - BOOLOPT("Display/Bilinear", "Bilinear", wxTRANSLATE("Use bilinear filter with 3d renderer"), gopts.bilinear), - ENUMOPT("Display/Filter", "", wxTRANSLATE("Full-screen filter to apply"), gopts.filter, - wxTRANSLATE("none|2xsai|super2xsai|supereagle|pixelate|advmame|" - L"bilinear|bilinearplus|scanlines|tvmode|hq2x|lq2x|" - L"simple2x|simple3x|hq3x|simple4x|hq4x|xbrz2x|xbrz3x|xbrz4x|xbrz5x|plugin")), - STROPT ("Display/FilterPlugin", "", wxTRANSLATE("Filter plugin library"), gopts.filter_plugin), - ENUMOPT("Display/IFB", "", wxTRANSLATE("Interframe blending function"), gopts.ifb, wxTRANSLATE("none|smart|motionblur")), - INTOPT ("Display/MaxThreads", "Multithread", wxTRANSLATE("Maximum number of threads to run filters in"), gopts.max_threads, 1, 8), +opt_desc opts[] = +{ + /// Display + BOOLOPT("Display/Bilinear", "Bilinear", wxTRANSLATE("Use bilinear filter with 3d renderer"), gopts.bilinear), + ENUMOPT("Display/Filter", "", wxTRANSLATE("Full-screen filter to apply"), gopts.filter, + wxTRANSLATE("none|2xsai|super2xsai|supereagle|pixelate|advmame|" + L"bilinear|bilinearplus|scanlines|tvmode|hq2x|lq2x|" + L"simple2x|simple3x|hq3x|simple4x|hq4x|xbrz2x|xbrz3x|xbrz4x|xbrz5x|plugin")), + STROPT("Display/FilterPlugin", "", wxTRANSLATE("Filter plugin library"), gopts.filter_plugin), + ENUMOPT("Display/IFB", "", wxTRANSLATE("Interframe blending function"), gopts.ifb, wxTRANSLATE("none|smart|motionblur")), + INTOPT("Display/MaxThreads", "Multithread", wxTRANSLATE("Maximum number of threads to run filters in"), gopts.max_threads, 1, 8), #ifdef __WXMSW__ ENUMOPT("Display/RenderMethod", "", wxTRANSLATE("Render method; if unsupported, simple method will be used"), gopts.render_method, wxTRANSLATE("simple|opengl|cairo|direct3d")), #else ENUMOPT("Display/RenderMethod", "", wxTRANSLATE("Render method; if unsupported, simple method will be used"), gopts.render_method, wxTRANSLATE("simple|opengl|cairo")), #endif - INTOPT ("Display/Scale", "", wxTRANSLATE("Default scale factor"), gopts.video_scale, 1, 6), - BOOLOPT("Display/Stretch", "RetainAspect", wxTRANSLATE("Retain aspect ratio when resizing"), gopts.retain_aspect), - - /// GB - STROPT ("GB/BiosFile", "", wxTRANSLATE("BIOS file to use for GB, if enabled"), gopts.gb_bios), - STROPT ("GB/GBCBiosFile", "", wxTRANSLATE("BIOS file to use for GBC, if enabled"), gopts.gbc_bios), - { wxT("GB/Palette0"), "", wxTRANSLATE("The default palette, as 8 comma-separated 4-digit hex integers (rgb555).") }, - { wxT("GB/Palette1"), "", wxTRANSLATE("The first user palette, as 8 comma-separated 4-digit hex integers (rgb555).") }, - { wxT("GB/Palette2"), "", wxTRANSLATE("The second user palette, as 8 comma-separated 4-digit hex integers (rgb555).") }, - BOOLOPT("GB/PrintAutoPage", "PrintGather", wxTRANSLATE("Automatically gather a full page before printing"), gopts.print_auto_page), - BOOLOPT("GB/PrintScreenCap", "PrintSnap", wxTRANSLATE("Automatically save printouts as screen captures with -print suffix"), gopts.print_screen_cap), - STROPT ("GB/ROMDir", "", wxTRANSLATE("Directory to look for ROM files"), gopts.gb_rom_dir), - STROPT ("GB/GBCROMDir", "", wxTRANSLATE("Directory to look for GBC ROM files"), gopts.gbc_rom_dir), - - /// GBA - STROPT ("GBA/BiosFile", "", wxTRANSLATE("BIOS file to use, if enabled"), gopts.gba_bios), + INTOPT("Display/Scale", "", wxTRANSLATE("Default scale factor"), gopts.video_scale, 1, 6), + BOOLOPT("Display/Stretch", "RetainAspect", wxTRANSLATE("Retain aspect ratio when resizing"), gopts.retain_aspect), + + /// GB + STROPT("GB/BiosFile", "", wxTRANSLATE("BIOS file to use for GB, if enabled"), gopts.gb_bios), + STROPT("GB/GBCBiosFile", "", wxTRANSLATE("BIOS file to use for GBC, if enabled"), gopts.gbc_bios), + { wxT("GB/Palette0"), "", wxTRANSLATE("The default palette, as 8 comma-separated 4-digit hex integers (rgb555).") }, + { wxT("GB/Palette1"), "", wxTRANSLATE("The first user palette, as 8 comma-separated 4-digit hex integers (rgb555).") }, + { wxT("GB/Palette2"), "", wxTRANSLATE("The second user palette, as 8 comma-separated 4-digit hex integers (rgb555).") }, + BOOLOPT("GB/PrintAutoPage", "PrintGather", wxTRANSLATE("Automatically gather a full page before printing"), gopts.print_auto_page), + BOOLOPT("GB/PrintScreenCap", "PrintSnap", wxTRANSLATE("Automatically save printouts as screen captures with -print suffix"), gopts.print_screen_cap), + STROPT("GB/ROMDir", "", wxTRANSLATE("Directory to look for ROM files"), gopts.gb_rom_dir), + STROPT("GB/GBCROMDir", "", wxTRANSLATE("Directory to look for GBC ROM files"), gopts.gbc_rom_dir), + + /// GBA + STROPT("GBA/BiosFile", "", wxTRANSLATE("BIOS file to use, if enabled"), gopts.gba_bios), #ifndef NO_LINK BOOLOPT("GBA/LinkAuto", "LinkAuto", wxTRANSLATE("Enable link at boot"), gopts.link_auto), - INTOPT ("GBA/LinkFast", "SpeedOn", wxTRANSLATE("Enable faster network protocol by default"), linkHacks, 0, 1), - STROPT ("GBA/LinkHost", "", wxTRANSLATE("Default network link client host"), gopts.link_host), - INTOPT ("GBA/LinkProto", "LinkProto", wxTRANSLATE("Default network protocol"), gopts.link_proto, 0, 1), - INTOPT ("GBA/LinkTimeout", "LinkTimeout", wxTRANSLATE("Link timeout (ms)"), linkTimeout, 0, 9999999), - INTOPT ("GBA/LinkType", "LinkType", wxTRANSLATE("Link cable type"), gopts.gba_link_type, 0, 5), + INTOPT("GBA/LinkFast", "SpeedOn", wxTRANSLATE("Enable faster network protocol by default"), linkHacks, 0, 1), + STROPT("GBA/LinkHost", "", wxTRANSLATE("Default network link client host"), gopts.link_host), + INTOPT("GBA/LinkProto", "LinkProto", wxTRANSLATE("Default network protocol"), gopts.link_proto, 0, 1), + INTOPT("GBA/LinkTimeout", "LinkTimeout", wxTRANSLATE("Link timeout (ms)"), linkTimeout, 0, 9999999), + INTOPT("GBA/LinkType", "LinkType", wxTRANSLATE("Link cable type"), gopts.gba_link_type, 0, 5), #endif - STROPT ("GBA/ROMDir", "", wxTRANSLATE("Directory to look for ROM files"), gopts.gba_rom_dir), - - /// General - 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), - 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), - STROPT ("General/StateDir", "", wxTRANSLATE("Directory to store saved state files (relative paths are relative to BatteryDir)"), gopts.state_dir), - - /// Joypad - { wxT("Joypad/*/*"), "", wxTRANSLATE("The parameter Joypad//