1 //Gaah... wx/wx.h (contains something that breaks if included after snes/snes.hpp from bsnes v085.
4 #include <wx/statbox.h>
5 #include <wx/notebook.h>
9 #include "core/controller.hpp"
10 #include "core/instance.hpp"
11 #include "core/moviedata.hpp"
12 #include "core/moviedata.hpp"
13 #include "core/framerate.hpp"
14 #include "core/project.hpp"
15 #include "core/random.hpp"
16 #include "core/rom.hpp"
17 #include "core/settings.hpp"
18 #include "core/window.hpp"
19 #include "interface/romtype.hpp"
20 #include "interface/setting.hpp"
21 #include "library/directory.hpp"
22 #include "library/string.hpp"
23 #include "library/zip.hpp"
24 #include <boost/lexical_cast.hpp>
26 #include "platform/wxwidgets/platform.hpp"
27 #include "platform/wxwidgets/loadsave.hpp"
30 #define ASK_SRAMS_BASE (wxID_HIGHEST + 129)
31 #define ASK_SRAMS_LAST (wxID_HIGHEST + 255)
35 std::string
generate_project_id()
37 return (stringfmt() << time(NULL
) << "_" << get_random_hexstring(4)).str();
40 class textboxloadfilename
: public wxFileDropTarget
43 textboxloadfilename(wxTextCtrl
* _ctrl
)
48 bool OnDropFiles(wxCoord x
, wxCoord y
, const wxArrayString
& filenames
)
50 if(filenames
.Count() != 1)
52 ctrl
->SetValue(filenames
[0]);
61 setting_select(wxWindow
* parent
, const core_setting
& s
);
62 wxWindow
* get_label() { return label
; }
63 wxWindow
* get_control();
64 const core_setting
& get_setting() { return setting
; }
74 setting_select::setting_select(wxWindow
* parent
, const core_setting
& s
)
78 if(!setting
.is_boolean())
79 label
= new wxStaticText(parent
, wxID_ANY
, towxstring(setting
.hname
));
81 label
= new wxStaticText(parent
, wxID_ANY
, towxstring(""));
85 if(setting
.is_boolean()) {
86 check
= new wxCheckBox(parent
, wxID_ANY
, towxstring(setting
.hname
));
87 check
->SetValue(s
.dflt
!= "0");
88 } else if(setting
.is_freetext()) {
89 text
= new wxTextCtrl(parent
, wxID_ANY
, towxstring(setting
.dflt
), wxDefaultPosition
,
92 std::vector
<wxString
> _hvalues
;
93 std::string dflt
= "";
94 for(auto i
: setting
.values
) {
95 _hvalues
.push_back(towxstring(i
.hname
));
96 if(i
.iname
== setting
.dflt
)
99 combo
= new wxComboBox(parent
, wxID_ANY
, towxstring(dflt
), wxDefaultPosition
,
100 wxDefaultSize
, _hvalues
.size(), &_hvalues
[0], wxCB_READONLY
);
104 wxWindow
* setting_select::get_control()
106 if(text
) return text
;
107 if(check
) return check
;
108 if(combo
) return combo
;
112 std::string
setting_select::read()
114 if(text
) return tostdstring(text
->GetValue());
115 if(check
) return check
->GetValue() ? "1" : "0";
116 if(combo
) return setting
.hvalue_to_ivalue(tostdstring(combo
->GetValue()));
120 class wxwin_newproject
: public wxDialog
123 wxwin_newproject(wxWindow
* parent
);
125 void on_ok(wxCommandEvent
& e
);
126 void on_cancel(wxCommandEvent
& e
);
127 void on_projname_edit(wxCommandEvent
& e
);
128 void on_memorywatch_select(wxCommandEvent
& e
);
129 void on_directory_select(wxCommandEvent
& e
);
130 void on_add(wxCommandEvent
& e
);
131 void on_remove(wxCommandEvent
& e
);
132 void on_up(wxCommandEvent
& e
);
133 void on_down(wxCommandEvent
& e
);
134 void on_luasel(wxCommandEvent
& e
);
136 void reorder_scripts(int delta
);
137 wxTextCtrl
* projname
;
138 wxTextCtrl
* memwatch
;
141 wxListBox
* luascripts
;
145 wxButton
* removebutton
;
147 wxButton
* downbutton
;
152 wxwin_newproject::~wxwin_newproject()
156 wxwin_newproject::wxwin_newproject(wxWindow
* parent
)
157 : wxDialog(parent
, wxID_ANY
, wxT("New Project"), wxDefaultPosition
, wxSize(-1, -1),
158 wxSYSTEM_MENU
| wxCAPTION
| wxCLIP_CHILDREN
| wxCLOSE_BOX
)
161 wxBoxSizer
* toplevel
= new wxBoxSizer(wxVERTICAL
);
164 wxFlexGridSizer
* c_s
= new wxFlexGridSizer(1, 2, 0, 0);
165 c_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Project name:")), 0, wxGROW
);
166 c_s
->Add(projname
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)), 1,
168 projname
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
169 wxCommandEventHandler(wxwin_newproject::on_projname_edit
), NULL
, this);
172 wxFlexGridSizer
* c4_s
= new wxFlexGridSizer(1, 3, 0, 0);
173 c4_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Directory:")), 0, wxGROW
);
174 c4_s
->Add(projdir
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)), 1,
176 projdir
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
177 wxCommandEventHandler(wxwin_newproject::on_projname_edit
), NULL
, this);
178 c4_s
->Add(sdir
= new wxButton(this, wxID_ANY
, wxT("...")), 1, wxGROW
);
179 sdir
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
180 wxCommandEventHandler(wxwin_newproject::on_directory_select
), NULL
, this);
183 wxFlexGridSizer
* c5_s
= new wxFlexGridSizer(1, 2, 0, 0);
184 c5_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Prefix:")), 0, wxGROW
);
185 c5_s
->Add(projpfx
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)), 1,
187 projpfx
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
188 wxCommandEventHandler(wxwin_newproject::on_projname_edit
), NULL
, this);
191 wxFlexGridSizer
* c2_s
= new wxFlexGridSizer(1, 3, 0, 0);
192 c2_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Memory watch:")), 0, wxGROW
);
193 c2_s
->Add(memwatch
= new wxTextCtrl(this, wxID_ANY
, wxT(""),
194 wxDefaultPosition
, wxSize(350, -1)), 1, wxGROW
);
196 c2_s
->Add(swatch
= new wxButton(this, wxID_ANY
, wxT("...")), 1, wxGROW
);
197 swatch
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
198 wxCommandEventHandler(wxwin_newproject::on_memorywatch_select
), NULL
, this);
201 toplevel
->Add(new wxStaticText(this, wxID_ANY
, wxT("Autoload lua scripts:")), 0, wxGROW
);
202 toplevel
->Add(luascripts
= new wxListBox(this, wxID_ANY
, wxDefaultPosition
, wxSize(400, 100)), 1,
204 luascripts
->Connect(wxEVT_COMMAND_LISTBOX_SELECTED
,
205 wxCommandEventHandler(wxwin_newproject::on_luasel
), NULL
, this);
207 wxFlexGridSizer
* c3_s
= new wxFlexGridSizer(1, 4, 0, 0);
208 c3_s
->Add(addbutton
= new wxButton(this, wxID_ANY
, wxT("Add")), 1, wxGROW
);
209 addbutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
210 wxCommandEventHandler(wxwin_newproject::on_add
), NULL
, this);
211 c3_s
->Add(removebutton
= new wxButton(this, wxID_ANY
, wxT("Remove")), 1, wxGROW
);
212 removebutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
213 wxCommandEventHandler(wxwin_newproject::on_remove
), NULL
, this);
214 removebutton
->Disable();
215 c3_s
->Add(upbutton
= new wxButton(this, wxID_ANY
, wxT("Up")), 1, wxGROW
);
216 upbutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
217 wxCommandEventHandler(wxwin_newproject::on_up
), NULL
, this);
219 c3_s
->Add(downbutton
= new wxButton(this, wxID_ANY
, wxT("Down")), 1, wxGROW
);
220 downbutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
221 wxCommandEventHandler(wxwin_newproject::on_down
), NULL
, this);
222 downbutton
->Disable();
225 wxBoxSizer
* buttonbar
= new wxBoxSizer(wxHORIZONTAL
);
226 buttonbar
->Add(okbutton
= new wxButton(this, wxID_ANY
, wxT("OK")), 0, wxGROW
);
227 buttonbar
->AddStretchSpacer();
228 buttonbar
->Add(cancel
= new wxButton(this, wxID_CANCEL
, wxT("Cancel")), 0, wxGROW
);
229 okbutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
230 wxCommandEventHandler(wxwin_newproject::on_ok
), NULL
, this);
231 cancel
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
232 wxCommandEventHandler(wxwin_newproject::on_cancel
), NULL
, this);
233 toplevel
->Add(buttonbar
, 0, wxGROW
);
234 //This gets re-enabled later if needed.
237 toplevel
->SetSizeHints(this);
241 void wxwin_newproject::on_ok(wxCommandEvent
& e
)
243 if(!lsnes_instance
.mlogic
) {
244 show_message_ok(this, "Error", "Can't start project without movie", wxICON_EXCLAMATION
);
248 pinfo
.id
= generate_project_id();
249 pinfo
.name
= tostdstring(projname
->GetValue());
250 pinfo
.rom
= our_rom
.load_filename
;
251 pinfo
.last_save
= "";
252 pinfo
.directory
= tostdstring(projdir
->GetValue());
253 pinfo
.prefix
= tostdstring(projpfx
->GetValue());
254 auto& m
= lsnes_instance
.mlogic
.get_mfile();
255 pinfo
.gametype
= m
.gametype
->get_name();
256 pinfo
.settings
= m
.settings
;
257 pinfo
.coreversion
= m
.coreversion
;
258 pinfo
.gamename
= m
.gamename
;
259 pinfo
.authors
= m
.authors
;
260 pinfo
.movie_sram
= m
.movie_sram
;
261 pinfo
.anchor_savestate
= m
.anchor_savestate
;
262 pinfo
.movie_rtc_second
= m
.movie_rtc_second
;
263 pinfo
.movie_rtc_subsecond
= m
.movie_rtc_subsecond
;
264 pinfo
.projectid
= m
.projectid
;
265 pinfo
.active_branch
= 0;
266 pinfo
.next_branch
= 0;
267 lsnes_instance
.project
.copy_watches(pinfo
);
268 lsnes_instance
.project
.copy_macros(pinfo
, lsnes_instance
.controls
);
269 for(unsigned i
= 0; i
< ROM_SLOT_COUNT
; i
++) {
270 pinfo
.roms
[i
] = our_rom
.romimg
[i
].filename
;
271 pinfo
.romimg_sha256
[i
] = m
.romimg_sha256
[i
];
272 pinfo
.romxml_sha256
[i
] = m
.romxml_sha256
[i
];
273 pinfo
.namehint
[i
] = m
.namehint
[i
];
275 for(unsigned i
= 0; i
< luascripts
->GetCount(); i
++)
276 pinfo
.luascripts
.push_back(tostdstring(luascripts
->GetString(i
)));
277 if(memwatch
->GetValue().length() == 0)
280 std::istream
& in
= zip::openrel(tostdstring(memwatch
->GetValue()), "");
284 std::getline(in
, wname
);
285 std::getline(in
, wexpr
);
286 pinfo
.watches
[strip_CR(wname
)] = strip_CR(wexpr
);
289 } catch(std::exception
& e
) {
290 show_message_ok(this, "Error", std::string("Can't load memory watch: ") + e
.what(),
295 project_info
* pinfo2
= new project_info(pinfo
);
297 project_info
* old_proj
= lsnes_instance
.project
.get();
298 lsnes_instance
.project
.set(pinfo2
, true);
304 void wxwin_newproject::on_cancel(wxCommandEvent
& e
)
306 EndModal(wxID_CANCEL
);
309 void wxwin_newproject::on_memorywatch_select(wxCommandEvent
& e
)
312 std::string lwch
= choose_file_load(this, "Select memory watch file", ".", filetype_watch
);
314 auto& p
= zip::openrel(lwch
, "");
316 } catch(std::exception
& e
) {
317 show_message_ok(this, "File not found", "File '" + lwch
+ "' can't be opened",
321 memwatch
->SetValue(towxstring(lwch
));
326 void wxwin_newproject::on_projname_edit(wxCommandEvent
& e
)
329 ok
= ok
&& (projname
->GetValue().length() > 0);
330 ok
= ok
&& (projdir
->GetValue().length() > 0);
331 ok
= ok
&& (projpfx
->GetValue().length() > 0);
332 ok
= ok
&& directory::is_directory(tostdstring(projdir
->GetValue()));
333 okbutton
->Enable(ok
);
336 void wxwin_newproject::on_add(wxCommandEvent
& e
)
339 std::string luascript
= choose_file_load(this, "Pick lua script", ".", filetype_lua_script
);
341 auto& p
= zip::openrel(luascript
, "");
343 } catch(std::exception
& e
) {
344 show_message_ok(this, "File not found", "File '" + luascript
+ "' can't be opened",
348 luascripts
->Append(towxstring(luascript
));
353 void wxwin_newproject::on_remove(wxCommandEvent
& e
)
355 int sel
= luascripts
->GetSelection();
356 int count
= luascripts
->GetCount();
357 luascripts
->Delete(sel
);
359 luascripts
->SetSelection(sel
);
361 luascripts
->SetSelection(count
- 2);
363 luascripts
->SetSelection(wxNOT_FOUND
);
367 void wxwin_newproject::reorder_scripts(int delta
)
369 int sel
= luascripts
->GetSelection();
370 int count
= luascripts
->GetCount();
371 if(sel
== wxNOT_FOUND
|| sel
+ delta
>= count
|| sel
+ delta
< 0)
373 wxString a
= luascripts
->GetString(sel
);
374 wxString b
= luascripts
->GetString(sel
+ delta
);
375 luascripts
->SetString(sel
, b
);
376 luascripts
->SetString(sel
+ delta
, a
);
377 luascripts
->SetSelection(sel
+ delta
);
380 void wxwin_newproject::on_up(wxCommandEvent
& e
)
386 void wxwin_newproject::on_down(wxCommandEvent
& e
)
392 void wxwin_newproject::on_luasel(wxCommandEvent
& e
)
394 int sel
= luascripts
->GetSelection();
395 int count
= luascripts
->GetCount();
396 removebutton
->Enable(sel
!= wxNOT_FOUND
);
397 upbutton
->Enable(sel
!= wxNOT_FOUND
&& sel
> 0);
398 downbutton
->Enable(sel
!= wxNOT_FOUND
&& sel
< count
- 1);
401 void wxwin_newproject::on_directory_select(wxCommandEvent
& e
)
403 wxDirDialog
* d
= new wxDirDialog(this, wxT("Select project directory"), projdir
->GetValue(),
404 wxDD_DIR_MUST_EXIST
);
405 if(d
->ShowModal() == wxID_CANCEL
) {
409 projdir
->SetValue(d
->GetPath());
413 int get_setting_class(const core_setting
& a
)
422 bool compare_settings(const std::pair
<std::string
, core_setting
*>& a
,
423 const std::pair
<std::string
, core_setting
*>& b
)
425 int aclass
= get_setting_class(*a
.second
);
426 int bclass
= get_setting_class(*b
.second
);
427 if(aclass
< bclass
) return true;
428 if(aclass
> bclass
) return false;
429 if(a
.second
->hname
< b
.second
->hname
) return true;
430 if(a
.second
->hname
> b
.second
->hname
) return false;
434 std::vector
<std::pair
<std::string
, core_setting
*>> sort_settingblock(std::map
<std::string
,
435 core_setting
>& block
)
437 std::vector
<std::pair
<std::string
, core_setting
*>> ret
;
439 ret
.push_back(std::make_pair(i
.first
, &i
.second
));
440 std::sort(ret
.begin(), ret
.end(), compare_settings
);
445 class wxwin_project
: public wxDialog
450 void on_file_select(wxCommandEvent
& e
);
451 void on_new_select(wxCommandEvent
& e
);
452 void on_filename_change(wxCommandEvent
& e
);
453 void on_ask_filename(wxCommandEvent
& e
);
454 void on_quit(wxCommandEvent
& e
);
455 void on_load(wxCommandEvent
& e
);
457 struct moviefile
& make_movie();
458 std::map
<std::string
, wxTextCtrl
*> sram_files
;
459 std::map
<std::string
, wxButton
*> sram_choosers
;
460 std::map
<std::string
, setting_select
> settings
;
461 wxTextCtrl
* projectname
;
464 wxTextCtrl
* rtc_subsec
;
468 std::map
<unsigned, std::string
> sram_names
;
473 void show_projectwindow(wxWindow
* modwin
)
476 show_message_ok(modwin
, "Can't start new movie", "No ROM loaded", wxICON_EXCLAMATION
);
479 wxwin_project
* projwin
= new wxwin_project();
480 projwin
->ShowModal();
484 //------------------------------------------------------------
486 wxwin_project::wxwin_project()
487 : wxDialog(NULL
, wxID_ANY
, wxT("Project settings"), wxDefaultPosition
, wxSize(-1, -1),
488 wxMINIMIZE_BOX
| wxSYSTEM_MENU
| wxCAPTION
| wxCLIP_CHILDREN
| wxCLOSE_BOX
)
490 std::vector
<wxString
> cchoices
;
492 std::set
<std::string
> sram_set
= our_rom
.rtype
->srams();
498 wxBoxSizer
* toplevel
= new wxBoxSizer(wxVERTICAL
);
500 wxPanel
* new_panel
= new wxPanel(this);
503 //3 Page-level blocks.
504 //- Controllertypes/initRTC/Gamename/SRAMs.
505 //- Authors explanation.
507 wxFlexGridSizer
* new_sizer
= new wxFlexGridSizer(3, 1, 0, 0);
508 new_panel
->SetSizer(new_sizer
);
509 //Controllertypes/Gamename/initRTC/SRAMs.
510 auto settingblock
= our_rom
.rtype
->get_settings().settings
;
511 wxFlexGridSizer
* mainblock
= new wxFlexGridSizer(4 + settingblock
.size() + sram_set
.size(), 2, 0, 0);
512 auto _settingblock
= sort_settingblock(settingblock
);
513 for(auto i
: _settingblock
) {
514 settings
.insert(std::make_pair(i
.second
->iname
, setting_select(new_panel
, *i
.second
)));
515 mainblock
->Add(settings
.find(i
.second
->iname
)->second
.get_label());
516 mainblock
->Add(settings
.find(i
.second
->iname
)->second
.get_control());
518 mainblock
->Add(new wxStaticText(new_panel
, wxID_ANY
, wxT("Initial RTC value:")), 0, wxGROW
);
519 wxFlexGridSizer
* initrtc
= new wxFlexGridSizer(1, 3, 0, 0);
520 initrtc
->Add(rtc_sec
= new wxTextCtrl(new_panel
, wxID_ANY
, wxT("1000000000"), wxDefaultPosition
,
521 wxSize(150, -1)), 1, wxGROW
);
522 initrtc
->Add(new wxStaticText(new_panel
, wxID_ANY
, wxT(":")), 0, wxGROW
);
523 initrtc
->Add(rtc_subsec
= new wxTextCtrl(new_panel
, wxID_ANY
, wxT("0"), wxDefaultPosition
,
524 wxSize(150, -1)), 1, wxGROW
);
525 mainblock
->Add(initrtc
, 0, wxGROW
);
526 mainblock
->Add(new wxStaticText(new_panel
, wxID_ANY
, wxT("Game name:")), 0, wxGROW
);
527 mainblock
->Add(projectname
= new wxTextCtrl(new_panel
, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)),
529 mainblock
->Add(new wxStaticText(new_panel
, wxID_ANY
, wxT("Save prefix:")), 0, wxGROW
);
530 mainblock
->Add(prefix
= new wxTextCtrl(new_panel
, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)), 1,
534 for(auto i
: sram_set
) {
535 std::string name
= "SRAM " + i
;
537 name
= "Anchor savestate";
538 mainblock
->Add(new wxStaticText(new_panel
, wxID_ANY
, towxstring(name
)), 0, wxGROW
);
539 wxFlexGridSizer
* fileblock2
= new wxFlexGridSizer(1, 2, 0, 0);
540 fileblock2
->Add(sram_files
[i
] = new wxTextCtrl(new_panel
, wxID_ANY
, wxT(""), wxDefaultPosition
,
541 wxSize(500, -1)), 1, wxGROW
);
542 sram_files
[i
]->SetDropTarget(new textboxloadfilename(sram_files
[i
]));
543 fileblock2
->Add(sram_choosers
[i
] = new wxButton(new_panel
, ASK_SRAMS_BASE
+ idx
, wxT("Pick")), 0,
545 sram_files
[i
]->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
546 wxCommandEventHandler(wxwin_project::on_filename_change
), NULL
, this);
547 sram_files
[i
]->SetDropTarget(new textboxloadfilename(sram_files
[i
]));
548 sram_choosers
[i
]->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
549 wxCommandEventHandler(wxwin_project::on_ask_filename
), NULL
, this);
550 mainblock
->Add(fileblock2
, 0, wxGROW
);
554 new_sizer
->Add(mainblock
, 0, wxGROW
);
557 new_sizer
->Add(new wxStaticText(new_panel
, wxID_ANY
, wxT("Authors (one per line):")), 0, wxGROW
);
558 new_sizer
->Add(authors
= new wxTextCtrl(new_panel
, wxID_ANY
, wxT(""), wxDefaultPosition
, wxDefaultSize
,
559 wxTE_MULTILINE
), 0, wxGROW
);
560 authors
->Connect(wxEVT_COMMAND_TEXT_UPDATED
, wxCommandEventHandler(wxwin_project::on_filename_change
), NULL
,
563 toplevel
->Add(new_panel
, 1, wxGROW
);
566 wxBoxSizer
* buttonbar
= new wxBoxSizer(wxHORIZONTAL
);
567 buttonbar
->Add(load
= new wxButton(this, wxID_ANY
, wxT("Load")), 0, wxGROW
);
568 buttonbar
->AddStretchSpacer();
569 buttonbar
->Add(quit
= new wxButton(this, wxID_CANCEL
, wxT("Cancel")), 0, wxGROW
);
570 load
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
571 wxCommandEventHandler(wxwin_project::on_load
), NULL
, this);
572 quit
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
573 wxCommandEventHandler(wxwin_project::on_quit
), NULL
, this);
574 toplevel
->Add(buttonbar
, 0, wxGROW
);
576 //This gets re-enabled later if needed.
579 on_filename_change(e2
);
581 mainblock
->SetSizeHints(this);
582 new_sizer
->SetSizeHints(this);
583 toplevel
->SetSizeHints(this);
587 wxwin_project::~wxwin_project()
591 void wxwin_project::on_ask_filename(wxCommandEvent
& e
)
595 if(id
>= ASK_SRAMS_BASE
&& id
<= ASK_SRAMS_LAST
) {
596 std::string fname
= pick_file_member(this, "Choose " + sram_names
[id
- ASK_SRAMS_BASE
], ".");
597 sram_files
[sram_names
[id
- ASK_SRAMS_BASE
]]->SetValue(towxstring(fname
));
599 on_filename_change(e
);
600 } catch(canceled_exception
& e
) {
604 void wxwin_project::on_filename_change(wxCommandEvent
& e
)
607 boost::lexical_cast
<int64_t>(tostdstring(rtc_sec
->GetValue()));
608 if(boost::lexical_cast
<int64_t>(tostdstring(rtc_subsec
->GetValue())) < 0)
610 size_t lines
= authors
->GetNumberOfLines();
611 for(size_t i
= 0; i
< lines
; i
++) {
612 std::string l
= tostdstring(authors
->GetLineText(i
));
622 void wxwin_project::on_quit(wxCommandEvent
& e
)
627 void wxwin_project::on_load(wxCommandEvent
& e
)
630 moviefile
& mov
= make_movie();
631 mov
.start_paused
= false;
632 rrdata_set tmp_rdata
;
633 mov
.save("$MEMORY:wxwidgets-romload-tmp", 0, true, tmp_rdata
);
634 lsnes_instance
.iqueue
.queue("load-state $MEMORY:wxwidgets-romload-tmp");
636 } catch(std::exception
& e
) {
637 show_message_ok(this, "Error loading movie", e
.what(), wxICON_EXCLAMATION
);
642 struct moviefile
& wxwin_project::make_movie()
644 moviefile
& f
= *new moviefile
;
645 f
.force_corrupt
= false;
646 f
.gametype
= &our_rom
.rtype
->combine_region(*our_rom
.region
);
647 for(auto i
: settings
) {
648 f
.settings
[i
.first
] = i
.second
.read();
649 if(!i
.second
.get_setting().validate(f
.settings
[i
.first
]))
650 throw std::runtime_error((stringfmt() << "Bad value for setting " << i
.first
).str());
652 f
.coreversion
= our_rom
.rtype
->get_core_identifier();
653 f
.gamename
= tostdstring(projectname
->GetValue());
654 f
.projectid
= get_random_hexstring(40);
655 set_mprefix_for_project(f
.projectid
, tostdstring(prefix
->GetValue()));
657 for(size_t i
= 0; i
< ROM_SLOT_COUNT
; i
++) {
658 f
.romimg_sha256
[i
] = our_rom
.romimg
[i
].sha_256
.read();
659 f
.romxml_sha256
[i
] = our_rom
.romxml
[i
].sha_256
.read();
660 f
.namehint
[i
] = our_rom
.romimg
[i
].namehint
;
662 size_t lines
= authors
->GetNumberOfLines();
663 for(size_t i
= 0; i
< lines
; i
++) {
664 std::string l
= tostdstring(authors
->GetLineText(i
));
665 if(l
!= "" && l
!= "|")
666 f
.authors
.push_back(split_author(l
));
668 for(auto i
: sram_files
) {
669 std::string sf
= tostdstring(i
.second
->GetValue());
672 f
.movie_sram
[i
.first
] = zip::readrel(sf
, "");
675 f
.anchor_savestate
= zip::readrel(sf
, "");
678 f
.is_savestate
= false;
679 f
.movie_rtc_second
= f
.rtc_second
= boost::lexical_cast
<int64_t>(tostdstring(rtc_sec
->GetValue()));
680 f
.movie_rtc_subsecond
= f
.rtc_subsecond
= boost::lexical_cast
<int64_t>(tostdstring(rtc_subsec
->GetValue()));
681 if(f
.movie_rtc_subsecond
< 0)
682 throw std::runtime_error("RTC subsecond must be positive");
683 auto ctrldata
= our_rom
.rtype
->controllerconfig(f
.settings
);
684 port_type_set
& ports
= port_type_set::make(ctrldata
.ports
, ctrldata
.portindex());
685 f
.create_default_branch(ports
);
689 void open_new_project_window(wxWindow
* parent
)
691 if(our_rom
.rtype
->isnull()) {
692 show_message_ok(parent
, "Can't start new project", "No ROM loaded", wxICON_EXCLAMATION
);
695 wxwin_newproject
* projwin
= new wxwin_newproject(parent
);
696 projwin
->ShowModal();