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/moviedata.hpp"
11 #include "core/moviedata.hpp"
12 #include "core/framerate.hpp"
13 #include "core/project.hpp"
14 #include "core/rom.hpp"
15 #include "core/settings.hpp"
16 #include "core/window.hpp"
17 #include "interface/romtype.hpp"
18 #include "interface/setting.hpp"
19 #include "library/string.hpp"
20 #include "library/zip.hpp"
21 #include <boost/lexical_cast.hpp>
22 #include <boost/filesystem.hpp>
24 #include "platform/wxwidgets/platform.hpp"
25 #include "platform/wxwidgets/loadsave.hpp"
28 #define ASK_SRAMS_BASE (wxID_HIGHEST + 129)
29 #define ASK_SRAMS_LAST (wxID_HIGHEST + 255)
33 std::string
generate_project_id()
35 return (stringfmt() << time(NULL
) << "_" << get_random_hexstring(4)).str();
38 class textboxloadfilename
: public wxFileDropTarget
41 textboxloadfilename(wxTextCtrl
* _ctrl
)
46 bool OnDropFiles(wxCoord x
, wxCoord y
, const wxArrayString
& filenames
)
48 if(filenames
.Count() != 1)
50 ctrl
->SetValue(filenames
[0]);
59 setting_select(wxWindow
* parent
, const core_setting
& s
);
60 wxWindow
* get_label() { return label
; }
61 wxWindow
* get_control();
62 const core_setting
& get_setting() { return setting
; }
72 setting_select::setting_select(wxWindow
* parent
, const core_setting
& s
)
75 label
= new wxStaticText(parent
, wxID_ANY
, towxstring(setting
.hname
));
79 if(setting
.is_boolean()) {
80 check
= new wxCheckBox(parent
, wxID_ANY
, towxstring(""));
81 check
->SetValue(s
.dflt
!= "0");
82 } else if(setting
.is_freetext()) {
83 text
= new wxTextCtrl(parent
, wxID_ANY
, towxstring(setting
.dflt
), wxDefaultPosition
,
86 std::vector
<wxString
> _hvalues
;
87 std::string dflt
= "";
88 for(auto i
: setting
.values
) {
89 _hvalues
.push_back(towxstring(i
.hname
));
90 if(i
.iname
== setting
.dflt
)
93 combo
= new wxComboBox(parent
, wxID_ANY
, towxstring(dflt
), wxDefaultPosition
,
94 wxDefaultSize
, _hvalues
.size(), &_hvalues
[0], wxCB_READONLY
);
98 wxWindow
* setting_select::get_control()
100 if(text
) return text
;
101 if(check
) return check
;
102 if(combo
) return combo
;
106 std::string
setting_select::read()
108 if(text
) return tostdstring(text
->GetValue());
109 if(check
) return check
->GetValue() ? "1" : "0";
110 if(combo
) return setting
.hvalue_to_ivalue(tostdstring(combo
->GetValue()));
114 class wxwin_newproject
: public wxDialog
117 wxwin_newproject(wxWindow
* parent
);
119 void on_ok(wxCommandEvent
& e
);
120 void on_cancel(wxCommandEvent
& e
);
121 void on_projname_edit(wxCommandEvent
& e
);
122 void on_memorywatch_select(wxCommandEvent
& e
);
123 void on_directory_select(wxCommandEvent
& e
);
124 void on_add(wxCommandEvent
& e
);
125 void on_remove(wxCommandEvent
& e
);
126 void on_up(wxCommandEvent
& e
);
127 void on_down(wxCommandEvent
& e
);
128 void on_luasel(wxCommandEvent
& e
);
130 void reorder_scripts(int delta
);
131 wxTextCtrl
* projname
;
132 wxTextCtrl
* memwatch
;
135 wxListBox
* luascripts
;
139 wxButton
* removebutton
;
141 wxButton
* downbutton
;
146 wxwin_newproject::~wxwin_newproject()
150 wxwin_newproject::wxwin_newproject(wxWindow
* parent
)
151 : wxDialog(parent
, wxID_ANY
, wxT("New Project"), wxDefaultPosition
, wxSize(-1, -1),
152 wxSYSTEM_MENU
| wxCAPTION
| wxCLIP_CHILDREN
| wxCLOSE_BOX
)
155 wxBoxSizer
* toplevel
= new wxBoxSizer(wxVERTICAL
);
158 wxFlexGridSizer
* c_s
= new wxFlexGridSizer(1, 2, 0, 0);
159 c_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Project name:")), 0, wxGROW
);
160 c_s
->Add(projname
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)), 1,
162 projname
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
163 wxCommandEventHandler(wxwin_newproject::on_projname_edit
), NULL
, this);
166 wxFlexGridSizer
* c4_s
= new wxFlexGridSizer(1, 3, 0, 0);
167 c4_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Directory:")), 0, wxGROW
);
168 c4_s
->Add(projdir
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)), 1,
170 projdir
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
171 wxCommandEventHandler(wxwin_newproject::on_projname_edit
), NULL
, this);
172 c4_s
->Add(sdir
= new wxButton(this, wxID_ANY
, wxT("...")), 1, wxGROW
);
173 sdir
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
174 wxCommandEventHandler(wxwin_newproject::on_directory_select
), NULL
, this);
177 wxFlexGridSizer
* c5_s
= new wxFlexGridSizer(1, 2, 0, 0);
178 c5_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Prefix:")), 0, wxGROW
);
179 c5_s
->Add(projpfx
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)), 1,
181 projpfx
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
182 wxCommandEventHandler(wxwin_newproject::on_projname_edit
), NULL
, this);
185 wxFlexGridSizer
* c2_s
= new wxFlexGridSizer(1, 3, 0, 0);
186 c2_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Memory watch:")), 0, wxGROW
);
187 c2_s
->Add(memwatch
= new wxTextCtrl(this, wxID_ANY
, wxT(""),
188 wxDefaultPosition
, wxSize(350, -1)), 1, wxGROW
);
190 c2_s
->Add(swatch
= new wxButton(this, wxID_ANY
, wxT("...")), 1, wxGROW
);
191 swatch
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
192 wxCommandEventHandler(wxwin_newproject::on_memorywatch_select
), NULL
, this);
195 toplevel
->Add(new wxStaticText(this, wxID_ANY
, wxT("Autoload lua scripts:")), 0, wxGROW
);
196 toplevel
->Add(luascripts
= new wxListBox(this, wxID_ANY
, wxDefaultPosition
, wxSize(400, 100)), 1,
198 luascripts
->Connect(wxEVT_COMMAND_LISTBOX_SELECTED
,
199 wxCommandEventHandler(wxwin_newproject::on_luasel
), NULL
, this);
201 wxFlexGridSizer
* c3_s
= new wxFlexGridSizer(1, 4, 0, 0);
202 c3_s
->Add(addbutton
= new wxButton(this, wxID_ANY
, wxT("Add")), 1, wxGROW
);
203 addbutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
204 wxCommandEventHandler(wxwin_newproject::on_add
), NULL
, this);
205 c3_s
->Add(removebutton
= new wxButton(this, wxID_ANY
, wxT("Remove")), 1, wxGROW
);
206 removebutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
207 wxCommandEventHandler(wxwin_newproject::on_remove
), NULL
, this);
208 removebutton
->Disable();
209 c3_s
->Add(upbutton
= new wxButton(this, wxID_ANY
, wxT("Up")), 1, wxGROW
);
210 upbutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
211 wxCommandEventHandler(wxwin_newproject::on_up
), NULL
, this);
213 c3_s
->Add(downbutton
= new wxButton(this, wxID_ANY
, wxT("Down")), 1, wxGROW
);
214 downbutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
215 wxCommandEventHandler(wxwin_newproject::on_down
), NULL
, this);
216 downbutton
->Disable();
219 wxBoxSizer
* buttonbar
= new wxBoxSizer(wxHORIZONTAL
);
220 buttonbar
->Add(okbutton
= new wxButton(this, wxID_ANY
, wxT("OK")), 0, wxGROW
);
221 buttonbar
->AddStretchSpacer();
222 buttonbar
->Add(cancel
= new wxButton(this, wxID_CANCEL
, wxT("Cancel")), 0, wxGROW
);
223 okbutton
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
224 wxCommandEventHandler(wxwin_newproject::on_ok
), NULL
, this);
225 cancel
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
226 wxCommandEventHandler(wxwin_newproject::on_cancel
), NULL
, this);
227 toplevel
->Add(buttonbar
, 0, wxGROW
);
228 //This gets re-enabled later if needed.
231 toplevel
->SetSizeHints(this);
235 void wxwin_newproject::on_ok(wxCommandEvent
& e
)
238 pinfo
.id
= generate_project_id();
239 pinfo
.name
= tostdstring(projname
->GetValue());
240 pinfo
.rom
= our_rom
.load_filename
;
241 pinfo
.last_save
= "";
242 pinfo
.directory
= tostdstring(projdir
->GetValue());
243 pinfo
.prefix
= tostdstring(projpfx
->GetValue());
244 pinfo
.gametype
= our_movie
.gametype
->get_name();
245 pinfo
.settings
= our_movie
.settings
;
246 pinfo
.coreversion
= our_movie
.coreversion
;
247 pinfo
.gamename
= our_movie
.gamename
;
248 pinfo
.authors
= our_movie
.authors
;
249 pinfo
.movie_sram
= our_movie
.movie_sram
;
250 pinfo
.anchor_savestate
= our_movie
.anchor_savestate
;
251 pinfo
.movie_rtc_second
= our_movie
.movie_rtc_second
;
252 pinfo
.movie_rtc_subsecond
= our_movie
.movie_rtc_subsecond
;
253 pinfo
.projectid
= our_movie
.projectid
;
254 project_copy_watches(pinfo
);
255 project_copy_macros(pinfo
, controls
);
256 for(unsigned i
= 0; i
< ROM_SLOT_COUNT
; i
++) {
257 pinfo
.roms
[i
] = our_rom
.romimg
[i
].filename
;
258 pinfo
.romimg_sha256
[i
] = our_movie
.romimg_sha256
[i
];
259 pinfo
.romxml_sha256
[i
] = our_movie
.romxml_sha256
[i
];
260 pinfo
.namehint
[i
] = our_movie
.namehint
[i
];
262 for(unsigned i
= 0; i
< luascripts
->GetCount(); i
++)
263 pinfo
.luascripts
.push_back(tostdstring(luascripts
->GetString(i
)));
264 if(memwatch
->GetValue().length() == 0)
267 std::istream
& in
= open_file_relative(tostdstring(memwatch
->GetValue()), "");
271 std::getline(in
, wname
);
272 std::getline(in
, wexpr
);
273 pinfo
.watches
[strip_CR(wname
)] = strip_CR(wexpr
);
276 } catch(std::exception
& e
) {
277 show_message_ok(this, "Error", std::string("Can't load memory watch: ") + e
.what(),
282 project_info
* pinfo2
= new project_info(pinfo
);
283 project_flush(pinfo2
);
284 project_info
* old_proj
= project_get();
285 project_set(pinfo2
, true);
291 void wxwin_newproject::on_cancel(wxCommandEvent
& e
)
293 EndModal(wxID_CANCEL
);
296 void wxwin_newproject::on_memorywatch_select(wxCommandEvent
& e
)
299 std::string lwch
= choose_file_load(this, "Select memory watch file", ".", filetype_watch
);
301 auto& p
= open_file_relative(lwch
, "");
303 } catch(std::exception
& e
) {
304 show_message_ok(this, "File not found", "File '" + lwch
+ "' can't be opened",
308 memwatch
->SetValue(towxstring(lwch
));
313 void wxwin_newproject::on_projname_edit(wxCommandEvent
& e
)
316 ok
= ok
&& (projname
->GetValue().length() > 0);
317 ok
= ok
&& (projdir
->GetValue().length() > 0);
318 ok
= ok
&& (projpfx
->GetValue().length() > 0);
319 boost::filesystem::path
p(tostdstring(projdir
->GetValue()));
320 ok
= ok
&& boost::filesystem::is_directory(p
);
321 okbutton
->Enable(ok
);
324 void wxwin_newproject::on_add(wxCommandEvent
& e
)
327 std::string luascript
= choose_file_load(this, "Pick lua script", ".", filetype_lua_script
);
329 auto& p
= open_file_relative(luascript
, "");
331 } catch(std::exception
& e
) {
332 show_message_ok(this, "File not found", "File '" + luascript
+ "' can't be opened",
336 luascripts
->Append(towxstring(luascript
));
341 void wxwin_newproject::on_remove(wxCommandEvent
& e
)
343 int sel
= luascripts
->GetSelection();
344 int count
= luascripts
->GetCount();
345 luascripts
->Delete(sel
);
347 luascripts
->SetSelection(sel
);
349 luascripts
->SetSelection(count
- 2);
351 luascripts
->SetSelection(wxNOT_FOUND
);
355 void wxwin_newproject::reorder_scripts(int delta
)
357 int sel
= luascripts
->GetSelection();
358 int count
= luascripts
->GetCount();
359 if(sel
== wxNOT_FOUND
|| sel
+ delta
>= count
|| sel
+ delta
< 0)
361 wxString a
= luascripts
->GetString(sel
);
362 wxString b
= luascripts
->GetString(sel
+ delta
);
363 luascripts
->SetString(sel
, b
);
364 luascripts
->SetString(sel
+ delta
, a
);
365 luascripts
->SetSelection(sel
+ delta
);
368 void wxwin_newproject::on_up(wxCommandEvent
& e
)
374 void wxwin_newproject::on_down(wxCommandEvent
& e
)
380 void wxwin_newproject::on_luasel(wxCommandEvent
& e
)
382 int sel
= luascripts
->GetSelection();
383 int count
= luascripts
->GetCount();
384 removebutton
->Enable(sel
!= wxNOT_FOUND
);
385 upbutton
->Enable(sel
!= wxNOT_FOUND
&& sel
> 0);
386 downbutton
->Enable(sel
!= wxNOT_FOUND
&& sel
< count
- 1);
389 void wxwin_newproject::on_directory_select(wxCommandEvent
& e
)
391 wxDirDialog
* d
= new wxDirDialog(this, wxT("Select project directory"), projdir
->GetValue(),
392 wxDD_DIR_MUST_EXIST
);
393 if(d
->ShowModal() == wxID_CANCEL
) {
397 projdir
->SetValue(d
->GetPath());
402 class wxwin_project
: public wxDialog
407 void on_file_select(wxCommandEvent
& e
);
408 void on_new_select(wxCommandEvent
& e
);
409 void on_filename_change(wxCommandEvent
& e
);
410 void on_ask_filename(wxCommandEvent
& e
);
411 void on_quit(wxCommandEvent
& e
);
412 void on_load(wxCommandEvent
& e
);
414 struct moviefile
make_movie();
415 std::map
<std::string
, wxTextCtrl
*> sram_files
;
416 std::map
<std::string
, wxButton
*> sram_choosers
;
417 std::map
<std::string
, setting_select
> settings
;
418 wxTextCtrl
* projectname
;
421 wxTextCtrl
* rtc_subsec
;
425 std::map
<unsigned, std::string
> sram_names
;
430 void show_projectwindow(wxWindow
* modwin
)
433 show_message_ok(modwin
, "Can't start new movie", "No ROM loaded", wxICON_EXCLAMATION
);
436 wxwin_project
* projwin
= new wxwin_project();
437 projwin
->ShowModal();
441 //------------------------------------------------------------
443 wxwin_project::wxwin_project()
444 : wxDialog(NULL
, wxID_ANY
, wxT("Project settings"), wxDefaultPosition
, wxSize(-1, -1),
445 wxMINIMIZE_BOX
| wxSYSTEM_MENU
| wxCAPTION
| wxCLIP_CHILDREN
| wxCLOSE_BOX
)
447 std::vector
<wxString
> cchoices
;
449 std::set
<std::string
> sram_set
= our_rom
.rtype
->srams();
455 wxBoxSizer
* toplevel
= new wxBoxSizer(wxVERTICAL
);
457 wxPanel
* new_panel
= new wxPanel(this);
460 //3 Page-level blocks.
461 //- Controllertypes/initRTC/Gamename/SRAMs.
462 //- Authors explanation.
464 wxFlexGridSizer
* new_sizer
= new wxFlexGridSizer(3, 1, 0, 0);
465 new_panel
->SetSizer(new_sizer
);
466 //Controllertypes/Gamename/initRTC/SRAMs.
467 wxFlexGridSizer
* mainblock
= new wxFlexGridSizer(4 + our_rom
.rtype
->get_settings().settings
.size() +
468 sram_set
.size(), 2, 0, 0);
469 for(auto i
: our_rom
.rtype
->get_settings().settings
) {
470 settings
.insert(std::make_pair(i
.second
.iname
, setting_select(new_panel
, i
.second
)));
471 mainblock
->Add(settings
.find(i
.second
.iname
)->second
.get_label());
472 mainblock
->Add(settings
.find(i
.second
.iname
)->second
.get_control());
474 mainblock
->Add(new wxStaticText(new_panel
, wxID_ANY
, wxT("Initial RTC value:")), 0, wxGROW
);
475 wxFlexGridSizer
* initrtc
= new wxFlexGridSizer(1, 3, 0, 0);
476 initrtc
->Add(rtc_sec
= new wxTextCtrl(new_panel
, wxID_ANY
, wxT("1000000000"), wxDefaultPosition
,
477 wxSize(150, -1)), 1, wxGROW
);
478 initrtc
->Add(new wxStaticText(new_panel
, wxID_ANY
, wxT(":")), 0, wxGROW
);
479 initrtc
->Add(rtc_subsec
= new wxTextCtrl(new_panel
, wxID_ANY
, wxT("0"), wxDefaultPosition
,
480 wxSize(150, -1)), 1, wxGROW
);
481 mainblock
->Add(initrtc
, 0, wxGROW
);
482 mainblock
->Add(new wxStaticText(new_panel
, wxID_ANY
, wxT("Game name:")), 0, wxGROW
);
483 mainblock
->Add(projectname
= new wxTextCtrl(new_panel
, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)),
485 mainblock
->Add(new wxStaticText(new_panel
, wxID_ANY
, wxT("Save prefix:")), 0, wxGROW
);
486 mainblock
->Add(prefix
= new wxTextCtrl(new_panel
, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)), 1,
490 for(auto i
: sram_set
) {
491 std::string name
= "SRAM " + i
;
493 name
= "Anchor savestate";
494 mainblock
->Add(new wxStaticText(new_panel
, wxID_ANY
, towxstring(name
)), 0, wxGROW
);
495 wxFlexGridSizer
* fileblock2
= new wxFlexGridSizer(1, 2, 0, 0);
496 fileblock2
->Add(sram_files
[i
] = new wxTextCtrl(new_panel
, wxID_ANY
, wxT(""), wxDefaultPosition
,
497 wxSize(500, -1)), 1, wxGROW
);
498 sram_files
[i
]->SetDropTarget(new textboxloadfilename(sram_files
[i
]));
499 fileblock2
->Add(sram_choosers
[i
] = new wxButton(new_panel
, ASK_SRAMS_BASE
+ idx
, wxT("Pick")), 0,
501 sram_files
[i
]->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
502 wxCommandEventHandler(wxwin_project::on_filename_change
), NULL
, this);
503 sram_files
[i
]->SetDropTarget(new textboxloadfilename(sram_files
[i
]));
504 sram_choosers
[i
]->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
505 wxCommandEventHandler(wxwin_project::on_ask_filename
), NULL
, this);
506 mainblock
->Add(fileblock2
, 0, wxGROW
);
510 new_sizer
->Add(mainblock
, 0, wxGROW
);
513 new_sizer
->Add(new wxStaticText(new_panel
, wxID_ANY
, wxT("Authors (one per line):")), 0, wxGROW
);
514 new_sizer
->Add(authors
= new wxTextCtrl(new_panel
, wxID_ANY
, wxT(""), wxDefaultPosition
, wxDefaultSize
,
515 wxTE_MULTILINE
), 0, wxGROW
);
516 authors
->Connect(wxEVT_COMMAND_TEXT_UPDATED
, wxCommandEventHandler(wxwin_project::on_filename_change
), NULL
,
519 toplevel
->Add(new_panel
, 1, wxGROW
);
522 wxBoxSizer
* buttonbar
= new wxBoxSizer(wxHORIZONTAL
);
523 buttonbar
->Add(load
= new wxButton(this, wxID_ANY
, wxT("Load")), 0, wxGROW
);
524 buttonbar
->AddStretchSpacer();
525 buttonbar
->Add(quit
= new wxButton(this, wxID_CANCEL
, wxT("Cancel")), 0, wxGROW
);
526 load
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
527 wxCommandEventHandler(wxwin_project::on_load
), NULL
, this);
528 quit
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
529 wxCommandEventHandler(wxwin_project::on_quit
), NULL
, this);
530 toplevel
->Add(buttonbar
, 0, wxGROW
);
532 //This gets re-enabled later if needed.
535 on_filename_change(e2
);
537 mainblock
->SetSizeHints(this);
538 new_sizer
->SetSizeHints(this);
539 toplevel
->SetSizeHints(this);
543 wxwin_project::~wxwin_project()
547 void wxwin_project::on_ask_filename(wxCommandEvent
& e
)
551 if(id
>= ASK_SRAMS_BASE
&& id
<= ASK_SRAMS_LAST
) {
552 std::string fname
= pick_file_member(this, "Choose " + sram_names
[id
- ASK_SRAMS_BASE
], ".");
553 sram_files
[sram_names
[id
- ASK_SRAMS_BASE
]]->SetValue(towxstring(fname
));
555 on_filename_change(e
);
556 } catch(canceled_exception
& e
) {
560 void wxwin_project::on_filename_change(wxCommandEvent
& e
)
563 boost::lexical_cast
<int64_t>(tostdstring(rtc_sec
->GetValue()));
564 if(boost::lexical_cast
<int64_t>(tostdstring(rtc_subsec
->GetValue())) < 0)
566 size_t lines
= authors
->GetNumberOfLines();
567 for(size_t i
= 0; i
< lines
; i
++) {
568 std::string l
= tostdstring(authors
->GetLineText(i
));
578 void wxwin_project::on_quit(wxCommandEvent
& e
)
583 void wxwin_project::on_load(wxCommandEvent
& e
)
586 moviefile mov
= make_movie();
587 mov
.start_paused
= false;
588 mov
.save("$MEMORY:wxwidgets-romload-tmp", 0, true);
589 platform::queue("load-state $MEMORY:wxwidgets-romload-tmp");
591 } catch(std::exception
& e
) {
592 show_message_ok(this, "Error loading movie", e
.what(), wxICON_EXCLAMATION
);
597 struct moviefile
wxwin_project::make_movie()
600 f
.force_corrupt
= false;
601 f
.gametype
= &our_rom
.rtype
->combine_region(*our_rom
.region
);
602 for(auto i
: settings
) {
603 f
.settings
[i
.first
] = i
.second
.read();
604 if(!i
.second
.get_setting().validate(f
.settings
[i
.first
]))
605 throw std::runtime_error((stringfmt() << "Bad value for setting " << i
.first
).str());
607 f
.coreversion
= our_rom
.rtype
->get_core_identifier();
608 f
.gamename
= tostdstring(projectname
->GetValue());
609 f
.projectid
= get_random_hexstring(40);
610 set_mprefix_for_project(f
.projectid
, tostdstring(prefix
->GetValue()));
612 for(size_t i
= 0; i
< ROM_SLOT_COUNT
; i
++) {
613 f
.romimg_sha256
[i
] = our_rom
.romimg
[i
].sha_256
.read();
614 f
.romxml_sha256
[i
] = our_rom
.romxml
[i
].sha_256
.read();
615 f
.namehint
[i
] = our_rom
.romimg
[i
].namehint
;
617 size_t lines
= authors
->GetNumberOfLines();
618 for(size_t i
= 0; i
< lines
; i
++) {
619 std::string l
= tostdstring(authors
->GetLineText(i
));
620 if(l
!= "" && l
!= "|")
621 f
.authors
.push_back(split_author(l
));
623 for(auto i
: sram_files
) {
624 std::string sf
= tostdstring(i
.second
->GetValue());
627 f
.movie_sram
[i
.first
] = read_file_relative(sf
, "");
630 f
.anchor_savestate
= read_file_relative(sf
, "");
633 f
.is_savestate
= false;
634 f
.movie_rtc_second
= f
.rtc_second
= boost::lexical_cast
<int64_t>(tostdstring(rtc_sec
->GetValue()));
635 f
.movie_rtc_subsecond
= f
.rtc_subsecond
= boost::lexical_cast
<int64_t>(tostdstring(rtc_subsec
->GetValue()));
636 if(f
.movie_rtc_subsecond
< 0)
637 throw std::runtime_error("RTC subsecond must be positive");
638 auto ctrldata
= our_rom
.rtype
->controllerconfig(f
.settings
);
639 port_type_set
& ports
= port_type_set::make(ctrldata
.ports
, ctrldata
.portindex());
640 f
.input
.clear(ports
);
644 void open_new_project_window(wxWindow
* parent
)
646 if(our_rom
.rtype
->isnull()) {
647 show_message_ok(parent
, "Can't start new project", "No ROM loaded", wxICON_EXCLAMATION
);
650 wxwin_newproject
* projwin
= new wxwin_newproject(parent
);
651 projwin
->ShowModal();