Wxwidgets graphics plugin
[lsnes.git] / platform / wxwidgets / src / rom_patch_window.cpp
blob28b5d9dad9e4c3f024f119cfd9bd12f906cf0983
1 #include "lsnes.hpp"
2 #include <snes/snes.hpp>
3 #include <ui-libsnes/libsnes.hpp>
4 #include "rom_patch_window.hpp"
5 #include "project_select_window.hpp"
6 #include "callrom.hpp"
7 #include "zip.hpp"
8 #include "framerate.hpp"
10 namespace
12 class my_interfaced : public SNES::Interface
14 string path(SNES::Cartridge::Slot slot, const string &hint)
16 return "./";
18 } simple_interface;
21 wx_rom_patch_window::wx_rom_patch_window(loaded_rom& rom)
22 : wxFrame(NULL, wxID_ANY, wxT("Patch ROM"), wxDefaultPosition, wxSize(-1, -1),
23 primary_window_style)
25 our_rom = &rom;
26 size_t target_count = fill_rom_names(rom.rtype, targets);
28 Centre();
29 wxFlexGridSizer* top_s = new wxFlexGridSizer(5, 1, 0, 0);
30 SetSizer(top_s);
32 wxFlexGridSizer* checksums_s = new wxFlexGridSizer(target_count, 2, 0, 0);
33 for(unsigned i = 0; i < 6; i++)
34 checksums[i] = NULL;
35 for(unsigned i = 0; i < target_count; i++) {
36 checksums_s->Add(new wxStaticText(this, wxID_ANY, targets[i]), 0, wxGROW);
37 checksums_s->Add(checksums[i] = new wxStaticText(this, wxID_ANY,
38 towxstring(get_rom_slot(*our_rom, i).sha256)), 0, wxGROW);
40 top_s->Add(checksums_s, 0, wxGROW);
42 wxFlexGridSizer* pwhat_s = new wxFlexGridSizer(1, 2, 0, 0);
43 pwhat_s->Add(new wxStaticText(this, wxID_ANY, wxT("Patch what:")), 0, wxGROW);
44 pwhat_s->Add(patch_what = new wxComboBox(this, wxID_ANY, targets[0], wxDefaultPosition, wxDefaultSize,
45 target_count, targets, wxCB_READONLY), 0, wxGROW);
46 top_s->Add(pwhat_s, 0, wxGROW);
48 patchfile = new filenamebox(top_s, this, "Patch file", FNBF_PL | FNBF_OI | FNBF_PZ, this,
49 wxCommandEventHandler(wx_rom_patch_window::on_patchfile_change));
51 wxFlexGridSizer* poffset_s = new wxFlexGridSizer(1, 2, 0, 0);
52 pwhat_s->Add(new wxStaticText(this, wxID_ANY, wxT("Patch offset:")), 0, wxGROW);
53 pwhat_s->Add(patch_offset = new wxTextCtrl(this, wxID_ANY, wxT("")), 0, wxGROW);
54 patch_offset->Connect(wxEVT_COMMAND_TEXT_UPDATED,
55 wxCommandEventHandler(wx_rom_patch_window::on_patchfile_change), NULL, this);
56 top_s->Add(poffset_s, 0, wxGROW);
58 wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
59 pbutton_s->AddStretchSpacer();
60 wxButton* thats_enough = new wxButton(this, wxID_ANY, wxT("Enough"));
61 pbutton_s->Add(thats_enough, 0, wxGROW);
62 thats_enough->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
63 wxCommandEventHandler(wx_rom_patch_window::on_done), NULL, this);
64 dopatch = new wxButton(this, wxID_ANY, wxT("Patch"));
65 pbutton_s->Add(dopatch, 0, wxGROW);
66 dopatch->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
67 wxCommandEventHandler(wx_rom_patch_window::on_do_patch), NULL, this);
68 dopatch->Disable();
69 wxButton* quitbutton = new wxButton(this, wxID_EXIT, wxT("Quit"));
70 pbutton_s->Add(quitbutton, 0, wxGROW);
71 quitbutton->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
72 wxCommandEventHandler(wx_rom_patch_window::on_quit), NULL, this);
73 top_s->Add(pbutton_s, 0, wxGROW);
75 patch_offset->SetValue(wxT("0"));
77 checksums_s->SetSizeHints(this);
78 pwhat_s->SetSizeHints(this);
79 pbutton_s->SetSizeHints(this);
80 top_s->SetSizeHints(this);
81 Fit();
84 wx_rom_patch_window::~wx_rom_patch_window()
86 delete patchfile;
89 void wx_rom_patch_window::on_patchfile_change(wxCommandEvent& e)
91 //std::cerr << "wx_rom_patch_window::on_patchfile_change" << std::endl;
92 bool ok = true;
93 //std::cerr << "wx_rom_patch_window::on_patchfile_change: #1: ok=" << ok << std::endl;
94 ok = ok && patchfile->is_nonblank();
95 //std::cerr << "wx_rom_patch_window::on_patchfile_change: #2: ok=" << ok << std::endl;
96 std::string offsetv = tostdstring(patch_offset->GetValue());
97 try {
98 int32_t offset = boost::lexical_cast<int32_t>(offsetv);
99 } catch(...) {
100 ok = false;
102 //std::cerr << "wx_rom_patch_window::on_patchfile_change: #3: ok=" << ok << std::endl;
103 if(dopatch) {
104 //std::cerr << "wx_rom_patch_window::on_patchfile_change: #4: ok=" << ok << std::endl;
105 dopatch->Enable(ok);
107 //std::cerr << "wx_rom_patch_window::on_patchfile_change: #5: ok=" << ok << std::endl;
110 void wx_rom_patch_window::on_do_patch(wxCommandEvent& e)
112 try {
113 auto patch_contents = read_file_relative(patchfile->get_file(), "");
114 size_t patch_index = romname_to_index(our_rom->rtype, patch_what->GetValue());
115 if(patch_index == 6)
116 throw std::runtime_error("Internal error: Patch WHAT?");
117 loaded_slot& s = get_rom_slot(*our_rom, patch_index);
118 std::string offsetv = tostdstring(patch_offset->GetValue());
119 int32_t offset = boost::lexical_cast<int32_t>(offsetv);
120 s.patch(patch_contents, offset);
121 checksums[patch_index]->SetLabel(towxstring(s.sha256));
122 } catch(std::exception& e) {
123 wxMessageDialog* d = new wxMessageDialog(this, towxstring(e.what()),
124 wxT("Error patching ROM"), wxOK | wxICON_EXCLAMATION);
125 d->ShowModal();
126 return;
128 patchfile->clear();
131 void wx_rom_patch_window::on_quit(wxCommandEvent& e)
133 Close(true);
136 void wx_rom_patch_window::on_done(wxCommandEvent& e)
138 try {
139 SNES::interface = &simple_interface;
140 our_rom->load();
141 } catch(std::exception& e) {
142 wxMessageDialog* d = new wxMessageDialog(this, towxstring(e.what()),
143 wxT("Error loading ROM"), wxOK | wxICON_EXCLAMATION);
144 d->ShowModal();
145 return;
147 messages << "Detected region: " << gtype::tostring(our_rom->rtype, our_rom->region) << std::endl;
148 if(our_rom->region == REGION_PAL)
149 set_nominal_framerate(322445.0/6448.0);
150 else if(our_rom->region == REGION_NTSC)
151 set_nominal_framerate(10738636.0/178683.0);
153 messages << "--- Internal memory mappings ---" << std::endl;
154 dump_region_map();
155 messages << "--- End of Startup --- " << std::endl;
156 wx_project_select_window* projwin = new wx_project_select_window(*our_rom);
157 projwin->Show();
158 Destroy();