2 #include <snes/snes.hpp>
3 #include <ui-libsnes/libsnes.hpp>
4 #include "project_select_window.hpp"
7 #include "moviedata.hpp"
10 #include <boost/lexical_cast.hpp>
14 std::string
sram_name(const nall::string
& _id
, SNES::Cartridge::Slot slotname
)
16 std::string
id(_id
, _id
.length());
17 if(slotname
== SNES::Cartridge::Slot::SufamiTurboA
)
18 return "slota." + id
.substr(1);
19 if(slotname
== SNES::Cartridge::Slot::SufamiTurboB
)
20 return "slotb." + id
.substr(1);
24 porttype_t
get_controller_type(const std::string
& s
)
28 if(s
== CNAME_GAMEPAD
)
30 if(s
== CNAME_MULTITAP
)
34 if(s
== CNAME_SUPERSCOPE
)
36 if(s
== CNAME_JUSTIFIER
)
38 if(s
== CNAME_JUSTIFIERS
)
44 wx_project_select_window::wx_project_select_window(loaded_rom
& rom
)
45 : wxFrame(NULL
, wxID_ANY
, wxT("Project settings"), wxDefaultPosition
, wxSize(-1, -1),
50 cchoices
[0] = wxT(CNAME_NONE
);
51 cchoices
[1] = wxT(CNAME_GAMEPAD
);
52 cchoices
[2] = wxT(CNAME_MULTITAP
);
53 cchoices
[3] = wxT(CNAME_MOUSE
);
54 cchoices
[4] = wxT(CNAME_SUPERSCOPE
);
55 cchoices
[5] = wxT(CNAME_JUSTIFIER
);
56 cchoices
[6] = wxT(CNAME_JUSTIFIERS
);
58 std::set
<std::string
> sram_set
= get_sram_set();
61 wxFlexGridSizer
* top_s
= new wxFlexGridSizer(7 + sram_set
.size(), 1, 0, 0);
64 wxRadioButton
* file
= new wxRadioButton(this, wxID_ANY
, wxT("Load movie/savestate"), wxDefaultPosition
,
65 wxDefaultSize
, wxRB_GROUP
);
66 wxRadioButton
* newp
= new wxRadioButton(this, wxID_ANY
, wxT("New project"));
67 file
->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED
,
68 wxCommandEventHandler(wx_project_select_window::on_file_select
), NULL
, this);
69 newp
->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED
,
70 wxCommandEventHandler(wx_project_select_window::on_new_select
), NULL
, this);
71 top_s
->Add(file
, 0, wxGROW
);
72 top_s
->Add(newp
, 0, wxGROW
);
75 filename
= new filenamebox(top_s
, this, "Movie/Savestate", FNBF_PL
| FNBF_OI
, this,
76 wxCommandEventHandler(wx_project_select_window::on_filename_change
));
78 wxFlexGridSizer
* c_s
= new wxFlexGridSizer(4, 2, 0, 0);
79 controller1type
= new labeledcombobox(c_s
, this, "Controller 1 type:", cchoices
, 4, 1, false, this,
80 wxCommandEventHandler(wx_project_select_window::on_filename_change
));
81 controller2type
= new labeledcombobox(c_s
, this, "Controller 2 type:", cchoices
, 7, 0, false, this,
82 wxCommandEventHandler(wx_project_select_window::on_filename_change
));
83 c_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Initial RTC:")), 0, wxGROW
);
84 wxFlexGridSizer
* t_s
= new wxFlexGridSizer(1, 3, 0, 0);
85 t_s
->Add(rtc_sec
= new wxTextCtrl(this, wxID_ANY
, wxT("1000000000"), wxDefaultPosition
, wxSize(150, -1)), 1,
87 t_s
->Add(new wxStaticText(this, wxID_ANY
, wxT(":")), 0, wxGROW
);
88 t_s
->Add(rtc_subsec
= new wxTextCtrl(this, wxID_ANY
, wxT("0"), wxDefaultPosition
, wxSize(120, -1)), 0, wxGROW
);
89 rtc_sec
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
90 wxCommandEventHandler(wx_project_select_window::on_filename_change
), NULL
, this);
91 rtc_subsec
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
92 wxCommandEventHandler(wx_project_select_window::on_filename_change
), NULL
, this);
93 c_s
->Add(t_s
, 0, wxGROW
);
94 top_s
->Add(c_s
, 0, wxGROW
);
95 c_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Game name:")), 0, wxGROW
);
96 c_s
->Add(projectname
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)), 1, wxGROW
);
98 top_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Authors (one per line):")), 0, wxGROW
);
99 top_s
->Add(authors
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxDefaultSize
,
100 wxTE_MULTILINE
), 0, wxGROW
);
101 authors
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
102 wxCommandEventHandler(wx_project_select_window::on_filename_change
), NULL
, this);
104 for(auto i
: sram_set
)
105 srams
[i
] = new filenamebox(top_s
, this, "SRAM " + i
+ ":" , FNBF_PL
| FNBF_OI
, this,
106 wxCommandEventHandler(wx_project_select_window::on_filename_change
));
108 wxBoxSizer
* pbutton_s
= new wxBoxSizer(wxHORIZONTAL
);
109 pbutton_s
->AddStretchSpacer();
110 pbutton_s
->Add(load
= new wxButton(this, wxID_ANY
, wxT("Load")), 0, wxGROW
);
111 pbutton_s
->Add(quit
= new wxButton(this, wxID_EXIT
, wxT("Quit")), 0, wxGROW
);
112 load
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
113 wxCommandEventHandler(wx_project_select_window::on_load
), NULL
, this);
114 quit
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
115 wxCommandEventHandler(wx_project_select_window::on_quit
), NULL
, this);
116 top_s
->Add(pbutton_s
, 0, wxGROW
);
121 t_s
->SetSizeHints(this);
122 c_s
->SetSizeHints(this);
123 top_s
->SetSizeHints(this);
127 wx_project_select_window::~wx_project_select_window()
129 delete controller1type
;
130 delete controller2type
;
134 void wx_project_select_window::on_file_select(wxCommandEvent
& e
)
137 controller1type
->disable();
138 controller2type
->disable();
140 rtc_subsec
->Disable();
141 projectname
->Disable();
143 load
->SetLabel(wxT("Load"));
144 on_filename_change(e
);
150 void wx_project_select_window::on_new_select(wxCommandEvent
& e
)
153 controller1type
->enable();
154 controller2type
->enable();
156 rtc_subsec
->Enable();
157 projectname
->Enable();
159 load
->SetLabel(wxT("Start"));
160 on_filename_change(e
);
166 void wx_project_select_window::on_filename_change(wxCommandEvent
& e
)
168 if(filename
->is_enabled()) {
169 load
->Enable(filename
->is_nonblank());
172 boost::lexical_cast
<int64_t>(tostdstring(rtc_sec
->GetValue()));
173 if(boost::lexical_cast
<int64_t>(tostdstring(rtc_subsec
->GetValue())) < 0)
175 size_t lines
= authors
->GetNumberOfLines();
176 for(size_t i
= 0; i
< lines
; i
++) {
177 std::string l
= tostdstring(authors
->GetLineText(i
));
188 void wx_project_select_window::on_quit(wxCommandEvent
& e
)
193 void wx_project_select_window::on_load(wxCommandEvent
& e
)
197 boot_emulator(*our_rom
, *new moviefile(filename
->get_file()));
199 boot_emulator(*our_rom
, *new moviefile(make_movie()));
202 } catch(std::exception
& e
) {
203 wxMessageDialog
* d
= new wxMessageDialog(this, towxstring(e
.what()),
204 wxT("Error loading movie"), wxOK
| wxICON_EXCLAMATION
);
210 std::set
<std::string
> wx_project_select_window::get_sram_set()
212 std::set
<std::string
> r
;
213 for(unsigned i
= 0; i
< SNES::cartridge
.nvram
.size(); i
++) {
214 SNES::Cartridge::NonVolatileRAM
& s
= SNES::cartridge
.nvram
[i
];
215 r
.insert(sram_name(s
.id
, s
.slot
));
220 struct moviefile
wx_project_select_window::make_movie()
223 f
.force_corrupt
= false;
224 f
.gametype
= gtype::togametype(our_rom
->rtype
, our_rom
->region
);
225 f
.port1
= get_controller_type(controller1type
->get_choice());
226 f
.port2
= get_controller_type(controller2type
->get_choice());
227 f
.coreversion
= bsnes_core_version
;
228 f
.gamename
= tostdstring(projectname
->GetValue());
229 f
.projectid
= get_random_hexstring(40);
231 f
.rom_sha256
= our_rom
->rom
.sha256
;
232 f
.romxml_sha256
= our_rom
->rom_xml
.sha256
;
233 f
.slota_sha256
= our_rom
->slota
.sha256
;
234 f
.slotaxml_sha256
= our_rom
->slota_xml
.sha256
;
235 f
.slotb_sha256
= our_rom
->slotb
.sha256
;
236 f
.slotbxml_sha256
= our_rom
->slotb_xml
.sha256
;
237 size_t lines
= authors
->GetNumberOfLines();
238 for(size_t i
= 0; i
< lines
; i
++) {
239 std::string l
= tostdstring(authors
->GetLineText(i
));
240 if(l
!= "" && l
!= "|")
241 f
.authors
.push_back(split_author(l
));
244 if(i
.second
->get_file() != "")
245 f
.movie_sram
[i
.first
] = read_file_relative(i
.second
->get_file(), "");
246 f
.is_savestate
= false;
247 f
.movie_rtc_second
= f
.rtc_second
= boost::lexical_cast
<int64_t>(tostdstring(rtc_sec
->GetValue()));
248 f
.movie_rtc_subsecond
= f
.rtc_subsecond
= boost::lexical_cast
<int64_t>(tostdstring(rtc_subsec
->GetValue()));
249 if(f
.movie_rtc_subsecond
< 0)
250 throw std::runtime_error("RTC subsecond must be positive");