6 #include <wx/fileconf.h>
11 #include "reader_master.h"
12 #include "reader_kazzo.h"
15 #include "flash_device.h"
16 #include "script_dump.h"
17 #include "script_program.h"
18 void qr_version_print(const struct textcontrol *l);
21 extern const struct reader_driver DRIVER_DUMMY;
24 #define STRNCPY wcsncpy
26 #define STRNCPY strncpy
28 //---- C++ -> C -> C++ wrapping functions ----
29 static void throw_error(const wxChar *t)
34 static void value_set(void *gauge, void *label, int value)
36 wxGauge *g = static_cast<wxGauge *>(gauge);
37 wxStaticText *l = static_cast<wxStaticText *>(label);
39 if(g->GetRange() == 1){
42 str.Printf(wxT("0x%06x/0x%06x"), value, g->GetRange());
51 static void value_add(void *gauge, void *label, int value)
53 wxGauge *g = static_cast<wxGauge *>(gauge);
54 value += g->GetValue();
56 value_set(gauge, label, value);
59 static void range_set(void *gauge, int value)
61 wxGauge *g = static_cast<wxGauge *>(gauge);
68 static void text_append_va(void *log, const wxChar *format, va_list list)
70 wxTextCtrl *l = static_cast<wxTextCtrl *>(log);
72 str.PrintfV(format, list);
79 static void text_append(void *log, const wxChar *format, ...)
82 va_start(list, format);
83 text_append_va(log, format, list);
87 static void version_append_va(void *log, const wxChar *format, va_list list)
89 wxTextCtrl *l = static_cast<wxTextCtrl *>(log);
91 str.PrintfV(format, list);
96 static void version_append(void *log, const wxChar *format, ...)
99 va_start(list, format);
100 version_append_va(log, format, list);
104 static void label_set(void *label, const wxChar *format, ...)
106 wxStaticText *l = static_cast<wxStaticText *>(label);
110 va_start(list, format);
111 str.PrintfV(format, list);
119 void choice_append(void *choice, const wxChar *str)
121 wxChoice *c = static_cast<wxChoice *>(choice);
122 c->Append(wxString(str));
125 //---- script execute thread ----
128 class anago_dumper : public wxThread
131 anago_frame *m_frame;
132 struct dump_config m_config;
133 const wxSound m_sound_success, m_sound_fail;
138 delete [] m_config.script;
139 delete [] m_config.target;
142 anago_dumper(anago_frame *f, const struct dump_config *d, wxString sound_success, wxString sound_fail)
143 : wxThread(), m_sound_success(sound_success), m_sound_fail(sound_fail)
146 m_config = *d; //struct data copy
150 class anago_programmer : public wxThread
153 anago_frame *m_frame;
154 struct program_config m_config;
155 const wxSound m_sound_success, m_sound_fail;
160 delete [] m_config.script;
161 delete [] m_config.target;
164 anago_programmer(anago_frame *f, const struct program_config *d, wxString sound_success, wxString sound_fail)
165 : wxThread(), m_sound_success(sound_success), m_sound_fail(sound_fail)
172 //---- main frame class ----
173 class anago_frame : public frame_main
176 wxThread *m_anago_thread;
177 const wxString m_config_file;
178 const struct reader_driver *m_reader;
179 wxString m_dump_sound_success, m_dump_sound_fail;
180 wxString m_program_sound_success, m_program_sound_fail;
182 STATUS_IDLE, STATUS_DUMPPING, STATUS_PROGRAMMING
185 void gauge_init(struct gauge *t)
187 t->label_set = label_set;
188 t->range_set = range_set;
189 t->value_set = value_set;
190 t->value_add = value_add;
192 void script_choice_init(wxChoice *c, wxString filespec)
194 wxDir dir(wxGetCwd());
198 if ( !dir.IsOpened() ){
201 bool cont = dir.GetFirst(&filename, filespec, wxDIR_FILES);
204 cont = dir.GetNext(&filename);
206 if(c->GetCount() == 0){
207 *m_log << wxT("warning: ") << filespec << wxT(" script not found.\n");
212 //---- dump mode functions ----
213 void dump_increase_init(wxChoice *c)
216 c->Append(wxT("x1"));
217 c->Append(wxT("x2"));
218 c->Append(wxT("x4"));
221 int dump_increase_get(wxChoice *c)
223 switch(c->GetSelection()){
230 void dump_execute(void)
232 struct dump_config config;
233 config.cpu.gauge.bar = m_dump_cpu_gauge;
234 config.cpu.gauge.label = m_dump_cpu_value;
235 gauge_init(&config.cpu.gauge);
237 config.ppu.gauge.bar = m_dump_ppu_gauge;
238 config.ppu.gauge.label = m_dump_ppu_value;
239 gauge_init(&config.ppu.gauge);
241 config.log.object = m_log;
242 config.log.append = text_append;
243 config.log.append_va = text_append_va;
244 config.except = throw_error;
245 config.cpu.increase = dump_increase_get(m_dump_cpu_increase);
246 config.ppu.increase = dump_increase_get(m_dump_ppu_increase);
247 config.progress = true;
248 config.battery = m_dump_check_battery->GetValue();
250 wxString str_script = m_dump_script_choice->GetStringSelection();
251 wxChar *t = new wxChar[str_script.Length() + 1];
253 STRNCPY(t, str_script.fn_str(), str_script.Length() + 1);
258 config.mappernum = -1;
259 if(m_dump_check_forcemapper->GetValue() == true){
260 str = m_dump_text_forcemapper->GetValue();
261 if(str.ToLong(&config.mappernum) == false){
262 *m_log << wxT("bad mapper number\n");
269 wxTextCtrl *text = m_dump_romimage_picker->GetTextCtrl();
270 wxString str_rom = text->GetValue();
271 wxChar *t = new wxChar[str_rom.Length() + 1];
272 if(text->IsEmpty() == true){
273 *m_log << wxT("Enter filename to ROM image\n");
277 STRNCPY(t, str_rom.fn_str(), str_rom.Length() + 1);
280 config.control = &m_reader->control;
281 config.cpu.access = &m_reader->cpu;
282 config.ppu.access = &m_reader->ppu;
284 m_dump_script_choice->Disable();
285 m_dump_romimage_picker->Disable();
286 m_dump_check_battery->Disable();
287 m_dump_check_forcemapper->Disable();
288 m_dump_button->SetLabel(wxT("cancel"));
289 m_dump_text_forcemapper->Disable();
290 m_dump_cpu_increase->Disable();
291 m_dump_ppu_increase->Disable();
293 /* if(m_anago_thread != NULL){ //???
294 delete m_anago_thread;
296 m_anago_thread = new anago_dumper(this, &config, m_dump_sound_success, m_dump_sound_fail);
297 if(m_anago_thread->Create() != wxTHREAD_NO_ERROR){
298 *m_log << wxT("thread creating error");
299 }else if(m_anago_thread->Run() != wxTHREAD_NO_ERROR){
300 *m_log << wxT("thread running error");
302 m_status = STATUS_DUMPPING;
306 //----- program mode functions ----
307 void program_padding_init(wxChoice *c)
310 c->Append(wxT("full"));
311 c->Append(wxT("top"));
312 c->Append(wxT("bottom"));
313 c->Append(wxT("empty"));
316 bool program_rom_set(wxString device, int trans, struct memory *m, struct flash_device *f)
319 if(flash_device_get(device, f) == false){
320 *m_log << wxT("unknown flash memory device ");
321 *m_log << device << wxT("\n");
326 m->transtype = TRANSTYPE_FULL;
329 m->transtype = TRANSTYPE_TOP;
332 m->transtype = TRANSTYPE_BOTTOM;
335 m->transtype = TRANSTYPE_EMPTY;
341 void program_execute(void)
343 struct program_config f;
345 f.cpu.gauge.bar = m_program_cpu_gauge;
346 f.cpu.gauge.label = m_program_cpu_value;
347 gauge_init(&f.cpu.gauge);
349 f.ppu.gauge.bar = m_program_ppu_gauge;
350 f.ppu.gauge.label = m_program_ppu_value;
351 gauge_init(&f.ppu.gauge);
353 f.log.object = m_log;
354 f.log.append = text_append;
355 f.log.append_va = text_append_va;
356 f.except = throw_error;
359 wxString str_script = m_program_script_choice->GetStringSelection();
360 wxChar *t = new wxChar[str_script.Length() + 1];
361 STRNCPY(t, str_script.fn_str(), str_script.Length() + 1);
366 wxTextCtrl *text = m_program_romimage_picker->GetTextCtrl();
367 wxString str_rom = text->GetValue();
368 if(text->IsEmpty() == true){
369 *m_log << wxT("Enter filename to ROM image\n");
372 wxChar *t = new wxChar[str_rom.Length() + 1];
373 STRNCPY(t, str_rom.fn_str(), str_rom.Length() + 1);
376 f.compare = m_program_compare->GetValue();
380 m_program_cpu_device->GetStringSelection(),
381 m_program_cpu_padding->GetSelection(),
382 &f.cpu.memory, &f.cpu.flash
387 m_program_ppu_device->GetStringSelection(),
388 m_program_ppu_padding->GetSelection(),
389 &f.ppu.memory, &f.ppu.flash
394 f.control = &m_reader->control;
395 f.cpu.access = &m_reader->cpu;
396 f.ppu.access = &m_reader->ppu;
398 m_program_script_choice->Disable();
399 m_program_romimage_picker->Disable();
400 m_program_compare->Disable();
401 m_program_button->SetLabel(wxT("cancel"));
402 m_program_cpu_padding->Disable();
403 m_program_cpu_device->Disable();
404 m_program_ppu_padding->Disable();
405 m_program_ppu_device->Disable();
406 m_program_compare->Disable();
408 m_anago_thread = new anago_programmer(this, &f, m_program_sound_success, m_program_sound_fail);
409 if(m_anago_thread->Create() != wxTHREAD_NO_ERROR){
410 *m_log << wxT("thread creating error");
411 }else if(m_anago_thread->Run() != wxTHREAD_NO_ERROR){
412 *m_log << wxT("thread running error");
414 m_status = STATUS_PROGRAMMING;
419 void dump_button_click(wxCommandEvent& event)
423 this->dump_execute();
425 case STATUS_DUMPPING:
426 m_anago_thread->Kill();
427 this->DumpThreadFinish();
428 m_status = STATUS_IDLE;
430 default: //do nothing
434 void program_button_click(wxCommandEvent& event)
438 this->program_execute();
440 case STATUS_PROGRAMMING:
441 m_anago_thread->Kill();
442 this->ProgramThreadFinish();
443 m_status = STATUS_IDLE;
445 default: //do nothing
449 void mapper_change_check(wxCommandEvent& event)
451 if(m_dump_check_forcemapper->GetValue() == true){
452 m_dump_text_forcemapper->Enable();
454 m_dump_text_forcemapper->Disable();
457 void menu_log_clean(wxCommandEvent& event)
463 anago_frame(wxWindow* parent, const struct reader_driver *r)
464 : frame_main(parent),
466 m_config_file(wxGetCwd() + wxT("/anago.cfg"))
468 m_config_file(wxT(".anago"))
474 wxFileConfig config(wxEmptyString, wxEmptyString, m_config_file);
477 config.Read(wxT("position.x"), &position.x, 32);
478 config.Read(wxT("position.y"), &position.y, 32);
479 this->SetPosition(position);
482 config.Read(wxT("size.x"), &size.x, 340);
483 config.Read(wxT("size.y"), &size.y, 460);
486 config.Read(wxT("program.sound.success"), &m_program_sound_success, wxT("cuckoo.wav"));
487 config.Read(wxT("program.sound.fail"), &m_program_sound_fail, wxT("doggrowl.wav"));
489 config.Read(wxT("dump.sound.success"), &m_dump_sound_success, wxT("tinkalink2.wav"));
490 config.Read(wxT("dump.sound.fail"), &m_dump_sound_fail, wxT("doggrowl.wav"));
494 this->script_choice_init(m_dump_script_choice, wxT("*.ad"));
495 this->script_choice_init(m_program_script_choice, wxT("*.af"));
496 this->dump_increase_init(m_dump_cpu_increase);
497 this->dump_increase_init(m_dump_ppu_increase);
500 struct flash_listup list;
501 list.obj_cpu = m_program_cpu_device;
502 list.obj_ppu = m_program_ppu_device;
503 list.append = choice_append;
504 flash_device_listup(&list);
506 if(m_program_cpu_device->GetCount() == 0){
507 *m_log << wxT("warning: flash device parameter not found\n");
509 m_program_cpu_device->Select(0);
510 m_program_ppu_device->Select(0);
512 this->program_padding_init(m_program_cpu_padding);
513 this->program_padding_init(m_program_ppu_padding);
515 m_anago_thread = NULL;
516 m_status = STATUS_IDLE;
520 struct textcontrol detail;
521 *m_version_detail << wxT("anago build at ") << wxT(__DATE__) << wxT("\n\n");
522 detail.object = m_version_detail;
523 detail.append = version_append;
524 detail.append_va = version_append_va;
525 qr_version_print(&detail);
526 *m_version_detail << wxVERSION_STRING << wxT(" (c) Julian Smar");
530 wxBitmap bitmap_okada(okada);
531 wxString tooltip(wxT(
532 "緑区 na6ko 町さん (28歳, 童貞)\n\n"
534 "28年間バカにされっぱなし、ミジメ過ぎた俺の人生が anago,\n"
535 "kazzo を持つようになった途端、突然ツキがめぐってきた。\n"
536 // "競馬をやれば連戦連勝、夢にまでみた万馬券を当て、気がつくと\n"
537 // "しんじられない事にギャンブルで稼いだお金が460万円!!\n"
538 "元手はたった4000円。しかもたった2ヶ月で人生大逆転!!\n"
540 // "勤めていた新聞屋も辞めギャンブルで\n"
541 // "身を立てていこうと思っています。実は来月の11日にラスベガスに\n"
542 // "行き勝負をかけます。結果はまた報告します。宜しく。"
546 wxBitmap bitmap_okada(taiyo);
547 wxString tooltip(wxT("たいよ~ほえ~るず♪"));
549 // #include "araki.xpm"
550 // wxBitmap bitmap_okada(araki);
551 m_version_photo->SetBitmap(bitmap_okada);
552 m_version_photo->SetToolTip(tooltip);
555 m_dump_romimage_picker->GetTextCtrl()->SetLabel(wxT("t.nes"));
559 void DumpThreadFinish(void)
561 m_dump_script_choice->Enable();
562 m_dump_script_choice->SetFocus();
563 m_dump_romimage_picker->Enable();
564 m_dump_check_battery->Enable();
565 m_dump_check_forcemapper->Enable();
566 m_dump_cpu_increase->Enable();
567 m_dump_ppu_increase->Enable();
568 m_dump_button->SetLabel(wxT("&dump"));
569 if(m_dump_check_forcemapper->GetValue() == true){
570 m_dump_text_forcemapper->Enable();
572 m_status = STATUS_IDLE;
575 void ProgramThreadFinish(void)
577 m_program_script_choice->Enable();
578 m_dump_script_choice->SetFocus();
579 m_program_romimage_picker->Enable();
580 m_program_compare->Enable();
581 m_program_button->SetLabel(wxT("&program"));
582 m_program_cpu_padding->Enable();
583 m_program_cpu_device->Enable();
584 m_program_ppu_padding->Enable();
585 m_program_ppu_device->Enable();
586 m_status = STATUS_IDLE;
588 void LogAppend(const wxChar *t)
592 virtual ~anago_frame(void)
594 wxFileConfig config(wxEmptyString, wxEmptyString, m_config_file);
595 wxPoint position = this->GetPosition();
597 config.Write(wxT("position.x"), position.x);
598 config.Write(wxT("position.y"), position.y);
600 wxSize size = this->GetSize();
601 config.Write(wxT("size.x"), size.x);
602 config.Write(wxT("size.y"), size.y);
607 void *anago_dumper::Entry(void)
610 if(script_dump_execute(&m_config) == true){
611 if(m_sound_success.IsOk() == true){
612 m_sound_success.Play();
615 }catch(const wxChar *t){
616 if(m_sound_fail.IsOk() == true){
619 m_frame->LogAppend(t);
621 m_frame->DumpThreadFinish();
625 void *anago_programmer::Entry(void)
628 if(script_program_execute(&m_config) == true){
629 if(m_sound_success.IsOk() == true){
630 m_sound_success.Play();
633 }catch(const wxChar *t){
634 if(m_sound_fail.IsOk() == true){
637 m_frame->LogAppend(t);
639 m_frame->ProgramThreadFinish();
645 int anago_cui(int c, wxChar **v);
647 int main(int c, wxChar **v)
650 return wxEntry(c, v);
652 return anago_cui(c, v);
656 class MyApp : public wxApp
659 anago_frame *m_frame;
663 if(DEBUG== 1 && this->argc >= 2){
664 m_frame = new anago_frame(NULL, &DRIVER_DUMMY);
666 m_frame = new anago_frame(NULL, &DRIVER_KAZZO);
676 IMPLEMENT_APP_NO_MAIN(MyApp)