#include <wx/wx.h>
-#include <wx/log.h>
-#include <wx/dir.h>
-#include <wx/thread.h>
#include <wx/app.h>
-#include <cstring>
+#include <wx/thread.h>
+#include <wx/dir.h>
+#include <wx/sound.h>
+#include <wx/fileconf.h>
+#include <wx/filename.h>
+#include <cassert>
#include <cstdarg>
+#include "type.h"
#include "anago_gui.h"
+#include "nescartxml.hh"
#include "widget.h"
#include "reader_master.h"
-//#include "reader_kazzo.h"
-extern const struct reader_driver DRIVER_KAZZO;
+#include "reader_kazzo.h"
+#include "reader_dummy.h"
extern "C"{
-#include "header.h"
-#include "flash_device.h"
-#include "script_dump.h"
-#include "script_program.h"
-void qr_version_print(const struct textcontrol *l);
+ #include "romimage.h"
+ #include "flash_device.h"
+ #include "script_dump.h"
+ #include "script_program.h"
+ void qr_version_print(const struct textcontrol *l);
}
+#ifdef _UNICODE
+ #define STRNCPY wcsncpy
+#else
+ #define STRNCPY strncpy
+#endif
+//---- C++ -> C -> C++ wrapping static functions ----
+namespace c_wrapper{
+ static void throw_error(const wxChar *t)
+ {
+ throw t;
+ }
-//---- C++ -> C -> C++ wrapping functions ----
-static void value_set(void *gauge, void *label, int value)
-{
- wxGauge *g = static_cast<wxGauge *>(gauge);
- wxStaticText *l = static_cast<wxStaticText *>(label);
- wxString str;
- str.Printf(wxT("0x%06x/0x%06x"), value, g->GetRange());
-
- wxMutexGuiEnter();
- g->SetValue(value);
- l->SetLabel(str);
- wxMutexGuiLeave();
-}
+ static void value_set(void *gauge, void *label, int value)
+ {
+ wxGauge *g = static_cast<wxGauge *>(gauge);
+ wxStaticText *l = static_cast<wxStaticText *>(label);
+ wxString str;
+ if(g->GetRange() == 1){
+ str = wxT("skip ");
+ }else{
+ str.Printf(wxT("0x%06x/0x%06x"), value, g->GetRange());
+ }
+
+ wxMutexGuiEnter();
+ g->SetValue(value);
+ if(label != NULL){
+ l->SetLabel(str);
+ }
+ wxMutexGuiLeave();
+ }
-static void value_add(void *gauge, void *label, int value)
-{
- wxGauge *g = static_cast<wxGauge *>(gauge);
- value += g->GetValue();
-
- value_set(gauge, label, value);
-}
+ static void value_add(void *gauge, void *label, int value)
+ {
+ wxGauge *g = static_cast<wxGauge *>(gauge);
+ value += g->GetValue();
+
+ value_set(gauge, label, value);
+ }
-static void range_set(void *gauge, int value)
-{
- wxGauge *g = static_cast<wxGauge *>(gauge);
- if(value == 0){
- value = 1;
+ static void range_set(void *gauge, int value)
+ {
+ wxGauge *g = static_cast<wxGauge *>(gauge);
+ if(value == 0){
+ value = 1;
+ }
+ g->SetRange(value);
}
- g->SetRange(value);
-}
-static void text_append_va(void *log, const char *format, va_list list)
-{
- wxTextCtrl *l = static_cast<wxTextCtrl *>(log);
- wxString str;
- str.PrintfV(format, list);
+ static void text_append_va(void *log, const wxChar *format, va_list list)
+ {
+ wxTextCtrl *l = static_cast<wxTextCtrl *>(log);
+ wxString str;
+ str.PrintfV(format, list);
- wxMutexGuiEnter();
- *l << str;
- wxMutexGuiLeave();
-}
+ wxMutexGuiEnter();
+ *l << str;
+ wxMutexGuiLeave();
+ }
-static void text_append(void *log, const char *format, ...)
-{
- va_list list;
- va_start(list, format);
- text_append_va(log, format, list);
- va_end(list);
-}
+ static void text_append(void *log, const wxChar *format, ...)
+ {
+ va_list list;
+ va_start(list, format);
+ text_append_va(log, format, list);
+ va_end(list);
+ }
-static void version_append_va(void *log, const char *format, va_list list)
-{
- wxTextCtrl *l = static_cast<wxTextCtrl *>(log);
- wxString str;
- str.PrintfV(format, list);
+ static void version_append_va(void *log, const wxChar *format, va_list list)
+ {
+ wxTextCtrl *l = static_cast<wxTextCtrl *>(log);
+ wxString str;
+ str.PrintfV(format, list);
- *l << str;
-}
+ *l << str;
+ }
-static void version_append(void *log, const char *format, ...)
-{
- va_list list;
- va_start(list, format);
- version_append_va(log, format, list);
- va_end(list);
-}
+ static void version_append(void *log, const wxChar *format, ...)
+ {
+ va_list list;
+ va_start(list, format);
+ version_append_va(log, format, list);
+ va_end(list);
+ }
-static void label_set(void *label, const char *format, ...)
-{
- wxStaticText *l = static_cast<wxStaticText *>(label);
- wxString str;
- va_list list;
-
- va_start(list, format);
- str.PrintfV(format, list);
- va_end(list);
+ static void label_set(void *label, const wxChar *format, ...)
+ {
+ wxStaticText *l = static_cast<wxStaticText *>(label);
+ wxString str;
+ va_list list;
+
+ va_start(list, format);
+ str.PrintfV(format, list);
+ va_end(list);
- wxMutexGuiEnter();
- l->SetLabel(str);
- wxMutexGuiLeave();
-}
+ wxMutexGuiEnter();
+ l->SetLabel(str);
+ wxMutexGuiLeave();
+ }
-void choice_append(void *choice, const char *str)
-{
- wxChoice *c = static_cast<wxChoice *>(choice);
- c->Append(wxString(str));
+ static void choice_append(void *choice, const wxChar *str)
+ {
+ wxChoice *c = static_cast<wxChoice *>(choice);
+ c->Append(wxString(str));
+ }
+
+ static void gauge_init(struct gauge *t)
+ {
+ t->label_set = label_set;
+ t->range_set = range_set;
+ t->value_set = value_set;
+ t->value_add = value_add;
+ }
}
//---- script execute thread ----
-class anago_frame;
class anago_dumper : public wxThread
{
private:
- anago_frame *m_frame;
+ wxWindow *const m_frame;
+ wxTextCtrl *const m_log;
+ const wxSound m_sound_success, m_sound_fail;
+ RomDb *const m_romdb;
+
struct dump_config m_config;
protected:
- void *Entry(void);
+ void *Entry(void)
+ {
+ try{
+ bool r = false;
+ switch(m_config.mode){
+ case MODE_ROM_DUMP:
+ r = script_dump_execute(&m_config);
+ break;
+ case MODE_RAM_READ: case MODE_RAM_WRITE:
+ r = script_workram_execute(&m_config);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ if(r == true && m_sound_success.IsOk() == true){
+ m_sound_success.Play();
+ }
+ }catch(const wxChar *t){
+ if(m_sound_fail.IsOk() == true){
+ m_sound_fail.Play();
+ }
+ *m_log << t;
+ }
+ if(m_romdb != NULL){
+ m_romdb->Search(m_config.crc, m_log);
+ }
+ wxMutexGuiEnter();
+ m_frame->Enable();
+ wxMutexGuiLeave();
+ return NULL;
+ }
void OnExit()
{
delete [] m_config.script;
delete [] m_config.target;
}
public:
- anago_dumper(anago_frame *f, const struct dump_config *d) : wxThread()
+ anago_dumper(wxWindow *f, const struct dump_config *d, wxTextCtrl *log, wxString sound_success, wxString sound_fail, RomDb *db = NULL)
+ : wxThread(), m_frame(f), m_log(log),
+ m_sound_success(sound_success), m_sound_fail(sound_fail),
+ m_romdb(db)
{
- m_frame = f;
- memcpy(&m_config, d, sizeof(struct dump_config));
+ m_config = *d; //struct data copy
}
};
class anago_programmer : public wxThread
{
private:
- anago_frame *m_frame;
+ wxWindow *const m_frame;
+ wxTextCtrl *const m_log;
struct program_config m_config;
+ const wxSound m_sound_success, m_sound_fail;
protected:
- void *Entry(void);
+ void *Entry(void)
+ {
+ try{
+ if(script_program_execute(&m_config) == true){
+ if(m_sound_success.IsOk() == true){
+ m_sound_success.Play();
+ }
+ }
+ }catch(const wxChar *t){
+ if(m_sound_fail.IsOk() == true){
+ m_sound_fail.Play();
+ }
+ *m_log << t;
+ }
+ wxMutexGuiEnter();
+ m_frame->Enable();
+ wxMutexGuiLeave();
+ return NULL;
+ }
+
void OnExit()
{
delete [] m_config.script;
delete [] m_config.target;
}
public:
- anago_programmer(anago_frame *f, const struct program_config *d) : wxThread()
+ anago_programmer(wxWindow *f, wxTextCtrl *log, const struct program_config *d, wxString sound_success, wxString sound_fail)
+ : wxThread(), m_frame(f), m_log(log),
+ m_sound_success(sound_success), m_sound_fail(sound_fail)
{
- m_frame = f;
- memcpy(&m_config, d, sizeof(struct program_config));
+ m_config = *d;
}
};
-//---- main frame class ----
-class anago_frame : public frame_main
+static void script_choice_init(wxControlWithItems *c, wxArrayString filespec, wxTextCtrl *log)
{
-private:
- wxThread *m_anago_thread;
- enum{
- STATUS_IDLE, STATUS_DUMPPING, STATUS_PROGRAMMING
- }m_status;
- void gauge_init(struct gauge *t)
- {
- t->label_set = label_set;
- t->range_set = range_set;
- t->value_set = value_set;
- t->value_add = value_add;
+ wxDir dir(wxGetCwd());
+ wxArrayString ar;
+
+ c->Clear();
+ if ( !dir.IsOpened() ){
+ return;
}
- void script_choice_init(wxChoice *c, wxString filespec)
- {
- wxDir dir(wxGetCwd());
+ for(size_t i = 0; i < filespec.GetCount(); i++){
wxString filename;
-
- c->Clear();
- if ( !dir.IsOpened() ){
- return;
- }
- bool cont = dir.GetFirst(&filename, filespec, wxDIR_FILES);
+ bool cont = dir.GetFirst(&filename, filespec[i], wxDIR_FILES);
while ( cont ){
- c->Append(filename);
+ ar.Add(filename);
cont = dir.GetNext(&filename);
}
- if(c->GetCount() == 0){
- *m_log << wxT("warning: ") << filespec << wxT(" script not found.\n");
- }else{
- c->Select(0);
- }
}
-//---- dump mode functions ----
- void dump_increase_init(wxChoice *c)
- {
- c->Clear();
- c->Append(wxT("x1"));
- c->Append(wxT("x2"));
- c->Append(wxT("x4"));
+ if(ar.GetCount() == 0){
+ *log << wxT("warning: ");
+ for(size_t i = 0; i < filespec.GetCount(); i++){
+ *log << filespec[i] << wxT(" ");
+ }
+ *log << wxT("script not found.\n");
+ }else{
+ ar.Sort(false);
+ for(size_t i = 0; i < ar.GetCount(); i++){
+ c->Append(ar[i]);
+ }
c->Select(0);
}
- int dump_increase_get(wxChoice *c)
- {
- switch(c->GetSelection()){
- case 0: return 1;
- case 1: return 2;
- case 2: return 4;
- }
- return 1;
+}
+
+static void increase_init(wxControlWithItems *c)
+{
+ c->Clear();
+ c->Append(wxT("x1"));
+ c->Append(wxT("x2"));
+ c->Append(wxT("x4"));
+ c->Select(0);
+}
+
+static int increase_get(wxControlWithItems *c)
+{
+ switch(c->GetSelection()){
+ case 0: return 1;
+ case 1: return 2;
+ case 2: return 4;
+ case 3: return INCREASE_AUTO;
}
- void dump_execute(void)
+ return 1;
+}
+
+enum anago_status{
+ STATUS_IDLE, STATUS_DUMPPING, STATUS_PROGRAMMING,
+ STATUS_RAM_READ, STATUS_RAM_WRITE
+};
+
+class anago_panel_dump : public panel_dump
+{
+private:
+ wxThread *m_anago_thread;
+ const struct reader_driver *const m_reader;
+ enum anago_status *const m_status;
+ wxTextCtrl *const m_log;
+ wxString m_sound_success, m_sound_fail;
+ wxString m_database;
+ RomDb *m_romdb;
+
+ void execute(void)
{
struct dump_config config;
- config.cpu.gauge.bar = m_dump_cpu_gauge;
- config.cpu.gauge.label = m_dump_cpu_value;
- gauge_init(&config.cpu.gauge);
-
- config.ppu.gauge.bar = m_dump_ppu_gauge;
- config.ppu.gauge.label = m_dump_ppu_value;
- gauge_init(&config.ppu.gauge);
+ config.mode = MODE_ROM_DUMP;
+ config.cpu.gauge.bar = m_cpu_gauge;
+ config.cpu.gauge.label = m_cpu_value;
+ c_wrapper::gauge_init(&config.cpu.gauge);
+
+ config.ppu.gauge.bar = m_ppu_gauge;
+ config.ppu.gauge.label = m_ppu_value;
+ c_wrapper::gauge_init(&config.ppu.gauge);
config.log.object = m_log;
- config.log.append = text_append;
- config.log.append_va = text_append_va;
- config.cpu.increase = dump_increase_get(m_dump_cpu_increase);
- config.ppu.increase = dump_increase_get(m_dump_ppu_increase);
+ config.log.append = c_wrapper::text_append;
+ config.log.append_va = c_wrapper::text_append_va;
+ config.except = c_wrapper::throw_error;
+ config.cpu.increase = increase_get(m_cpu_increase);
+ config.ppu.increase = increase_get(m_ppu_increase);
config.progress = true;
- config.battery = m_dump_check_battery->GetValue();
+ config.battery = m_check_battery->GetValue();
{
- wxString str_script = m_dump_script_choice->GetStringSelection();
- char *t = new char[str_script.Length() + 1];
+ wxString str_script = m_script_choice->GetStringSelection();
+ wxChar *t = new wxChar[str_script.Length() + 1];
config.script = t;
- strncpy(t, str_script.fn_str(), str_script.Length() + 1);
+ STRNCPY(t, str_script.c_str(), str_script.Length() + 1);
}
{
wxString str;
config.mappernum = -1;
- if(m_dump_check_forcemapper->GetValue() == true){
- str = m_dump_text_forcemapper->GetValue();
+ if(m_check_forcemapper->GetValue() == true){
+ str = m_text_forcemapper->GetValue();
if(str.ToLong(&config.mappernum) == false){
*m_log << wxT("bad mapper number\n");
return;
}
{
- wxTextCtrl *text = m_dump_romimage_picker->GetTextCtrl();
+ wxTextCtrl *text = m_romimage_picker->GetTextCtrl();
wxString str_rom = text->GetValue();
- char *t = new char[str_rom.Length() + 1];
+ wxChar *t = new wxChar[str_rom.Length() + 1];
if(text->IsEmpty() == true){
*m_log << wxT("Enter filename to ROM image\n");
return;
}
config.target = t;
- strncpy(t, str_rom.fn_str(), str_rom.Length() + 1);
+ STRNCPY(t, str_rom.c_str(), str_rom.Length() + 1);
}
- config.control = &DRIVER_KAZZO.control;
- config.cpu.access = &DRIVER_KAZZO.cpu;
- config.ppu.access = &DRIVER_KAZZO.ppu;
+ config.control = &m_reader->control;
+ config.cpu.access = &m_reader->cpu;
+ config.ppu.access = &m_reader->ppu;
- m_dump_script_choice->Disable();
- m_dump_romimage_picker->Disable();
- m_dump_check_battery->Disable();
- m_dump_check_forcemapper->Disable();
- m_dump_button->SetLabel(wxT("cancel"));
- m_dump_text_forcemapper->Disable();
- m_dump_cpu_increase->Disable();
- m_dump_ppu_increase->Disable();
+ this->Disable();
/* if(m_anago_thread != NULL){ //???
delete m_anago_thread;
}*/
- m_anago_thread = new anago_dumper(this, &config);
+ m_anago_thread = new anago_dumper(this, &config, m_log, m_sound_success, m_sound_fail, m_romdb);
if(m_anago_thread->Create() != wxTHREAD_NO_ERROR){
*m_log << wxT("thread creating error");
}else if(m_anago_thread->Run() != wxTHREAD_NO_ERROR){
*m_log << wxT("thread running error");
}else{
- m_status = STATUS_DUMPPING;
+ *m_status = STATUS_DUMPPING;
+ }
+ }
+protected:
+ void button_click(wxCommandEvent& event)
+ {
+ switch(*m_status){
+ case STATUS_IDLE:
+ this->execute();
+ break;
+ case STATUS_DUMPPING:
+ m_anago_thread->Kill();
+ this->Enable();
+ break;
+ default: //do nothing
+ break;
+ }
+ }
+
+ void mapper_change_check(wxCommandEvent& event)
+ {
+ if(m_check_forcemapper->GetValue() == true){
+ m_text_forcemapper->Enable();
+ }else{
+ m_text_forcemapper->Disable();
+ }
+ }
+
+public:
+ anago_panel_dump(wxNotebook *p, const struct reader_driver *r, enum anago_status *status, wxFileConfig *config, wxTextCtrl *log)
+ : panel_dump(p), m_reader(r), m_status(status), m_log(log)
+ {
+ config->Read(wxT("dump.database"), &m_database, wxT("NesCarts (2011-09-10).xml"));
+ if(wxFileName::FileExists(m_database) == true){
+ m_romdb = new RomDb(m_database);
+ m_romdb->Generate();
+ }else{
+ *log << wxT("m_database not found\n");
+ m_romdb = new RomDb();
+ }
+
+ config->Read(wxT("dump.sound.success"), &m_sound_success, wxT("tinkalink2.wav"));
+ config->Read(wxT("dump.sound.fail"), &m_sound_fail, wxT("doggrowl.wav"));
+
+ wxArrayString ar;
+ ar.Add(wxT("*.ad"));
+ ar.Add(wxT("*.ae"));
+ ar.Add(wxT("*.af"));
+ ar.Add(wxT("*.ag"));
+ script_choice_init(m_script_choice, ar, log);
+ ::increase_init(m_cpu_increase);
+ m_cpu_increase->Append(wxT("Auto"));
+ m_cpu_increase->Select(3);
+ ::increase_init(m_ppu_increase);
+ if(DEBUG==1){
+ m_romimage_picker->GetTextCtrl()->SetLabel(wxT("t.nes"));
+ }
+ }
+ virtual ~anago_panel_dump(void)
+ {
+ delete m_romdb;
+ }
+ bool Enable(bool t = true)
+ {
+ m_script_choice->Enable(t);
+ m_romimage_picker->Enable(t);
+ m_check_battery->Enable(t);
+ m_check_forcemapper->Enable(t);
+ m_cpu_increase->Enable(t);
+ m_ppu_increase->Enable(t);
+ if(t == true){
+ *m_status = STATUS_IDLE;
+ m_button->SetLabel(wxT("&dump"));
+ if(m_check_forcemapper->GetValue() == true){
+ m_text_forcemapper->Enable();
+ }
+ }else{
+ m_button->SetLabel(wxT("cancel"));
+ m_check_forcemapper->Disable();
}
+ m_button->SetFocus();
+ return true;
+ }
+ bool Disable(void)
+ {
+ return this->Enable(false);
}
+};
+
+class anago_panel_program : public panel_program
+{
+private:
+ wxThread *m_anago_thread;
+ const struct reader_driver *const m_reader;
+ wxString m_sound_success, m_sound_fail;
+ enum anago_status *const m_status;
+ wxTextCtrl *const m_log;
-//----- program mode functions ----
- void program_padding_init(wxChoice *c)
+ void padding_init(wxControlWithItems *c)
{
c->Clear();
c->Append(wxT("full"));
c->Append(wxT("empty"));
c->Select(0);
}
- bool program_rom_set(wxString device, int trans, struct memory *m, struct flash_device *f)
+ bool rom_set(wxString device, int trans, struct memory *m, struct flash_device *f)
{
m->offset = 0;
if(flash_device_get(device, f) == false){
return true;
}
- void program_execute(void)
+ void execute(void)
{
struct program_config f;
- f.cpu.gauge.bar = m_program_cpu_gauge;
- f.cpu.gauge.label = m_program_cpu_value;
- gauge_init(&f.cpu.gauge);
+ f.cpu.gauge.bar = m_cpu_gauge;
+ f.cpu.gauge.label = m_cpu_value;
+ c_wrapper::gauge_init(&f.cpu.gauge);
- f.ppu.gauge.bar = m_program_ppu_gauge;
- f.ppu.gauge.label = m_program_ppu_value;
- gauge_init(&f.ppu.gauge);
+ f.ppu.gauge.bar = m_ppu_gauge;
+ f.ppu.gauge.label = m_ppu_value;
+ c_wrapper::gauge_init(&f.ppu.gauge);
f.log.object = m_log;
- f.log.append = text_append;
- f.log.append_va = text_append_va;
+ f.log.append = c_wrapper::text_append;
+ f.log.append_va = c_wrapper::text_append_va;
+ f.except = c_wrapper::throw_error;
{
- wxString str_script = m_program_script_choice->GetStringSelection();
- char *t = new char[str_script.Length() + 1];
- strncpy(t, str_script.fn_str(), str_script.Length() + 1);
+ wxString str_script = m_script_choice->GetStringSelection();
+ wxChar *t = new wxChar[str_script.Length() + 1];
+ STRNCPY(t, str_script.c_str(), str_script.Length() + 1);
f.script = t;
}
{
- wxTextCtrl *text = m_program_romimage_picker->GetTextCtrl();
+ wxTextCtrl *text = m_romimage_picker->GetTextCtrl();
wxString str_rom = text->GetValue();
if(text->IsEmpty() == true){
*m_log << wxT("Enter filename to ROM image\n");
return;
}
- char *t = new char[str_rom.Length() + 1];
- strncpy(t, str_rom.fn_str(), str_rom.Length() + 1);
+ wxChar *t = new wxChar[str_rom.Length() + 1];
+ STRNCPY(t, str_rom.c_str(), str_rom.Length() + 1);
f.target = t;
}
- f.compare = m_program_compare->GetValue();
- f.testrun = false;
+ f.compare = m_compare->GetValue();
- if(program_rom_set(
- m_program_cpu_device->GetStringSelection(),
- m_program_cpu_padding->GetSelection(),
+ if(rom_set(
+ m_cpu_device->GetStringSelection(),
+ m_cpu_padding->GetSelection(),
&f.cpu.memory, &f.cpu.flash
) == false){
return;
}
- if(program_rom_set(
- m_program_ppu_device->GetStringSelection(),
- m_program_ppu_padding->GetSelection(),
+ if(rom_set(
+ m_ppu_device->GetStringSelection(),
+ m_ppu_padding->GetSelection(),
&f.ppu.memory, &f.ppu.flash
) == false){
return;
}
- f.control = &DRIVER_KAZZO.control;
- f.cpu.access = &DRIVER_KAZZO.cpu;
- f.ppu.access = &DRIVER_KAZZO.ppu;
+ f.control = &m_reader->control;
+ f.cpu.access = &m_reader->cpu;
+ f.ppu.access = &m_reader->ppu;
- m_program_script_choice->Disable();
- m_program_romimage_picker->Disable();
- m_program_compare->Disable();
- m_program_button->SetLabel(wxT("cancel"));
- m_program_cpu_padding->Disable();
- m_program_cpu_device->Disable();
- m_program_ppu_padding->Disable();
- m_program_ppu_device->Disable();
- m_program_compare->Disable();
+ this->Disable();
- m_anago_thread = new anago_programmer(this, &f);
+ m_anago_thread = new anago_programmer(this, m_log, &f, m_sound_success, m_sound_fail);
if(m_anago_thread->Create() != wxTHREAD_NO_ERROR){
*m_log << wxT("thread creating error");
}else if(m_anago_thread->Run() != wxTHREAD_NO_ERROR){
*m_log << wxT("thread running error");
}else{
- m_status = STATUS_PROGRAMMING;
+ *m_status = STATUS_PROGRAMMING;
}
}
+ void device_load(wxControlWithItems *choice, wxFileConfig *c, wxString key)
+ {
+ wxString device;
+ int val;
+ c->Read(key, &device);
+ val = choice->FindString(device);
+ if(val == wxNOT_FOUND){
+ choice->Select(0);
+ }else{
+ choice->Select(val);
+ }
+ }
protected:
- void dump_button_click(wxCommandEvent& event)
+ void button_click(wxCommandEvent& event)
{
- switch(m_status){
+ switch(*m_status){
case STATUS_IDLE:
- this->dump_execute();
+ this->execute();
break;
- case STATUS_DUMPPING:
+ case STATUS_PROGRAMMING:
m_anago_thread->Kill();
- this->DumpThreadFinish();
- m_status = STATUS_IDLE;
+ this->Enable();
break;
default: //do nothing
break;
}
}
- void program_button_click(wxCommandEvent& event)
+public:
+ anago_panel_program(wxNotebook *p, const struct reader_driver *r, enum anago_status *status, wxFileConfig *config, wxTextCtrl *log)
+ : panel_program(p), m_reader(r), m_status(status), m_log(log)
{
- switch(m_status){
+ config->Read(wxT("program.sound.success"), &m_sound_success, wxT("cuckoo.wav"));
+ config->Read(wxT("program.sound.fail"), &m_sound_fail, wxT("doggrowl.wav"));
+ {
+ wxArrayString t;
+ t.Add(wxT("*.af"));
+ t.Add(wxT("*.ag"));
+ script_choice_init(m_script_choice, t, m_log);
+ }
+ {
+ struct flash_listup list;
+ list.obj_cpu = m_cpu_device;
+ list.obj_ppu = m_ppu_device;
+ list.append = c_wrapper::choice_append;
+ flash_device_listup(&list);
+ }
+ if(m_cpu_device->GetCount() == 0){
+ *m_log << wxT("warning: flash device parameter not found\n");
+ }else{
+ device_load(m_cpu_device, config, wxT("program.cpu.device"));
+ device_load(m_ppu_device, config, wxT("program.ppu.device"));
+ }
+ this->padding_init(m_cpu_padding);
+ this->padding_init(m_ppu_padding);
+
+ m_anago_thread = NULL;
+ }
+ bool Enable(bool t = true)
+ {
+ m_script_choice->Enable(t);
+ m_romimage_picker->Enable(t);
+ m_compare->Enable(t);
+ m_cpu_padding->Enable(t);
+ m_cpu_device->Enable(t);
+ m_ppu_padding->Enable(t);
+ m_ppu_device->Enable(t);
+ if(t == true){
+ *m_status = STATUS_IDLE;
+ m_button->SetLabel(wxT("&program"));
+ }else{
+ m_button->SetLabel(wxT("cancel"));
+ }
+ m_button->SetFocus();
+ return true;
+ }
+ bool Disable(void)
+ {
+ return this->Enable(false);
+ }
+ void ConfigWrite(wxFileConfig *c)
+ {
+ c->Write(wxT("program.cpu.device"), m_cpu_device->GetStringSelection());
+ c->Write(wxT("program.ppu.device"), m_ppu_device->GetStringSelection());
+ }
+};
+
+class anago_panel_workram : public panel_workram
+{
+private:
+ wxThread *m_anago_thread;
+ const struct reader_driver *const m_reader;
+ enum anago_status *const m_status;
+ wxTextCtrl *const m_log;
+ wxString m_sound_success, m_sound_fail;
+
+ void execute(struct dump_config *c, wxControlWithItems *script, wxFilePickerCtrl *picker, enum anago_status status)
+ {
+ c->cpu.gauge.label = NULL;
+ c_wrapper::gauge_init(&c->cpu.gauge);
+
+ c->log.object = m_log;
+ c->log.append = c_wrapper::text_append;
+ c->log.append_va = c_wrapper::text_append_va;
+ c->except = c_wrapper::throw_error;
+ assert(c->cpu.increase != INCREASE_AUTO);
+ c->progress = true;
+ {
+ wxString str_script = script->GetStringSelection();
+ wxChar *t = new wxChar[str_script.Length() + 1];
+ c->script = t;
+ STRNCPY(t, str_script.c_str(), str_script.Length() + 1);
+ }
+ {
+ wxTextCtrl *text = picker->GetTextCtrl();
+ wxString str_rom = text->GetValue();
+ wxChar *t = new wxChar[str_rom.Length() + 1];
+ if(text->IsEmpty() == true){
+ *m_log << wxT("Enter filename to ROM image\n");
+ return;
+ }
+ c->target = t;
+ STRNCPY(t, str_rom.c_str(), str_rom.Length() + 1);
+ }
+ c->control = &m_reader->control;
+ c->cpu.access = &m_reader->cpu;
+ c->ppu.access = &m_reader->ppu;
+
+ m_anago_thread = new anago_dumper(this, c, m_log, m_sound_success, m_sound_fail);
+ if(m_anago_thread->Create() != wxTHREAD_NO_ERROR){
+ *m_log << wxT("thread creating error");
+ }else if(m_anago_thread->Run() != wxTHREAD_NO_ERROR){
+ *m_log << wxT("thread running error");
+ }else{
+ *m_status = status; //先に status を設定すること
+ this->Disable();
+ }
+ }
+
+ void read(void)
+ {
+ struct dump_config config;
+ config.mode = MODE_RAM_READ;
+ config.cpu.gauge.bar = m_read_gauge;
+ config.cpu.increase = ::increase_get(m_read_increase);
+ this->execute(&config, m_read_script, m_read_picker, STATUS_RAM_READ);
+ }
+ void write(void)
+ {
+ struct dump_config config;
+ config.mode = MODE_RAM_WRITE;
+ config.cpu.gauge.bar = m_write_gauge;
+ config.cpu.increase = ::increase_get(m_write_increase);
+ this->execute(&config, m_write_script, m_write_picker, STATUS_RAM_WRITE);
+ }
+protected:
+ void read_button_click(wxCommandEvent& event)
+ {
+ switch(*m_status){
case STATUS_IDLE:
- this->program_execute();
+ read();
break;
- case STATUS_PROGRAMMING:
- m_anago_thread->Kill();
- this->ProgramThreadFinish();
- m_status = STATUS_IDLE;
+ case STATUS_RAM_READ:
+ this->Enable();
break;
default: //do nothing
break;
}
}
- void mapper_change_check(wxCommandEvent& event)
+
+ void write_button_click(wxCommandEvent& event)
{
- if(m_dump_check_forcemapper->GetValue() == true){
- m_dump_text_forcemapper->Enable();
- }else{
- m_dump_text_forcemapper->Disable();
+ switch(*m_status){
+ case STATUS_IDLE:
+ write();
+ break;
+ case STATUS_RAM_WRITE:
+ this->Enable();
+ break;
+ default: //do nothing
+ break;
}
}
- void menu_log_clean(wxCommandEvent& event)
+public:
+ anago_panel_workram(wxWindow *p, const struct reader_driver *r, enum anago_status *status, wxFileConfig *config, wxTextCtrl *log)
+ : panel_workram(p), m_reader(r), m_status(status), m_log(log)
{
- m_log->Clear();
+ config->Read(wxT("workram.sound.success"), &m_sound_success, wxT("tinkalink2.wav"));
+ config->Read(wxT("workram.sound.fail"), &m_sound_fail, wxT("doggrowl.wav"));
+
+ wxArrayString ar;
+ ar.Add(wxT("*.ae"));
+ ar.Add(wxT("*.ag"));
+ ::script_choice_init(m_read_script, ar, log);
+ ::script_choice_init(m_write_script, ar, log);
+ ::increase_init(m_read_increase);
+ ::increase_init(m_write_increase);
+
+ if(DEBUG == 1){
+ m_read_picker->GetTextCtrl()->SetLabel(wxT("t.sav"));
+ }
}
-public:
- /** Constructor */
- anago_frame( wxWindow* parent ) : frame_main(parent)
- {
- this->script_choice_init(m_dump_script_choice, wxT("*.ad"));
- this->script_choice_init(m_program_script_choice, wxT("*.af"));
- this->dump_increase_init(m_dump_cpu_increase);
- this->dump_increase_init(m_dump_ppu_increase);
-
- struct flash_listup list;
- list.obj_cpu = m_program_cpu_device;
- list.obj_ppu = m_program_ppu_device;
- list.append = choice_append;
- flash_device_listup(&list);
- if(m_program_cpu_device->GetCount() == 0){
- *m_log << wxT("warning: flash device parameter not found\n");
+
+ bool Enable(bool t = true)
+ {
+ m_read_script->Enable(t);
+ m_read_picker->Enable(t);
+ m_write_script->Enable(t);
+ m_write_picker->Enable(t);
+ if(t == true){
+ switch(*m_status){
+ case STATUS_RAM_READ:
+ m_read_button->SetLabel(wxT("&read"));
+ m_read_button->SetFocus();
+ m_write_button->Enable();
+ break;
+ case STATUS_RAM_WRITE:
+ m_write_button->SetLabel(wxT("&write"));
+ m_write_button->SetFocus();
+ m_read_button->Enable();
+ break;
+ default:
+ break;
+ }
+ *m_status = STATUS_IDLE;
}else{
- m_program_cpu_device->Select(0);
- m_program_ppu_device->Select(0);
+ switch(*m_status){
+ case STATUS_RAM_READ:
+ m_read_button->SetLabel(wxT("&cancel"));
+ m_write_button->Disable();
+ break;
+ case STATUS_RAM_WRITE:
+ m_write_button->SetLabel(wxT("&cancel"));
+ m_read_button->Disable();
+ break;
+ default:
+ break;
+ }
}
- this->program_padding_init(m_program_cpu_padding);
- this->program_padding_init(m_program_ppu_padding);
-
- m_anago_thread = NULL;
- m_status = STATUS_IDLE;
+ return true;
+ }
+ bool Disable(void)
+ {
+ return this->Enable(false);
+ }
+};
+
+class anago_panel_version : public panel_version
+{
+public:
+ anago_panel_version(wxWindow *p) : panel_version(p)
+ {
//version infomation
- struct textcontrol detail;
- *m_version_detail << wxT("anago build at ") << __DATE__ << wxT("\n\n");
- detail.object = m_version_detail;
- detail.append = version_append;
- detail.append_va = version_append_va;
- qr_version_print(&detail);
- *m_version_detail << wxVERSION_STRING << wxT(" (c) Julian Smar");
+ {
+ struct textcontrol detail;
+ *m_version_detail << wxT("anago build at ") << wxT(__DATE__) << wxT("\n\n");
+ detail.object = m_version_detail;
+ detail.append = c_wrapper::version_append;
+ detail.append_va = c_wrapper::version_append_va;
+ qr_version_print(&detail);
+ *m_version_detail << wxVERSION_STRING << wxT(" (c) Julian Smar");
+ }
-#ifdef WIN32
+#if 0 //def WIN32
#include "okada.xpm"
wxBitmap bitmap_okada(okada);
wxString tooltip(wxT(
// "行き勝負をかけます。結果はまた報告します。宜しく。"
));
#else
- #include "taiyo.xpm"
- wxBitmap bitmap_okada(taiyo);
- wxString tooltip(wxT("たいよ~ほえ~るず♪"));
+ #include "slyly.xpm"
+ wxBitmap bitmap_okada(slyly);
+ wxString tooltip(wxT("CARP ピロ"));
#endif
// #include "araki.xpm"
// wxBitmap bitmap_okada(araki);
m_version_photo->SetBitmap(bitmap_okada);
m_version_photo->SetToolTip(tooltip);
}
+};
- void DumpThreadFinish(void)
+//---- main frame class ----
+class anago_frame : public frame_main
+{
+private:
+ enum anago_status m_status; //ここだけ実体, 各パネルはこのポインタ
+ const wxString m_config_file;
+ anago_panel_program *m_panel_program;
+protected:
+ void menu_log_clean(wxCommandEvent& event)
{
- m_dump_script_choice->Enable();
- m_dump_romimage_picker->Enable();
- m_dump_check_battery->Enable();
- m_dump_check_forcemapper->Enable();
- m_dump_cpu_increase->Enable();
- m_dump_ppu_increase->Enable();
- m_dump_button->SetLabel(wxT("&dump"));
- if(m_dump_check_forcemapper->GetValue() == true){
- m_dump_text_forcemapper->Enable();
- }
- m_status = STATUS_IDLE;
+ m_log->Clear();
}
- void ProgramThreadFinish(void)
- {
- m_program_script_choice->Enable();
- m_program_romimage_picker->Enable();
- m_program_compare->Enable();
- m_program_button->SetLabel(wxT("&program"));
- m_program_cpu_padding->Enable();
- m_program_cpu_device->Enable();
- m_program_ppu_padding->Enable();
- m_program_ppu_device->Enable();
- m_status = STATUS_IDLE;
- }
-};
+public:
+ /** Constructor */
+ anago_frame(wxWindow* parent, const struct reader_driver *r)
+ : frame_main(parent), m_status(STATUS_IDLE),
+#ifdef WIN32
+ m_config_file(wxGetCwd() + wxT("/anago.cfg"))
+#else
+ m_config_file(wxT(".anago"))
+#endif
+ {
+ wxFileConfig config(wxEmptyString, wxEmptyString, m_config_file);
+//form config load
+ wxPoint position;
+
+ config.Read(wxT("position.x"), &position.x, 32);
+ config.Read(wxT("position.y"), &position.y, 32);
+ this->SetPosition(position);
+
+ wxSize size;
+ config.Read(wxT("size.x"), &size.x, 340);
+ config.Read(wxT("size.y"), &size.y, 460);
+ this->SetSize(size);
+ m_notebook->AddPage(new anago_panel_dump(m_notebook, r, &m_status, &config, m_log), wxT("dump"), false);
-void *anago_dumper::Entry(void)
-{
- script_dump_execute(&m_config);
- m_frame->DumpThreadFinish();
- return NULL;
-}
+ m_panel_program = new anago_panel_program(m_notebook, r, &m_status, &config, m_log);
+ m_notebook->AddPage(m_panel_program, wxT("program"), false);
-void *anago_programmer::Entry(void)
-{
- script_program_execute(&m_config);
- m_frame->ProgramThreadFinish();
- return NULL;
-}
+ m_notebook->AddPage(new anago_panel_workram(m_notebook, r, &m_status, &config, m_log), wxT("workram"), false);
+ m_notebook->AddPage(new anago_panel_version(m_notebook), wxT("version"), false);
+
+#ifdef WIN32
+ SetIcon(wxIcon(wxT("unagi_blue")));
+#else
+ #include "unagi_blue.xpm"
+ SetIcon(wxIcon(unagi_blue));
+#endif
+ }
+
+ virtual ~anago_frame(void)
+ {
+ wxFileConfig config(wxEmptyString, wxEmptyString, m_config_file);
+ wxPoint position = this->GetPosition();
+
+ config.Write(wxT("position.x"), position.x);
+ config.Write(wxT("position.y"), position.y);
+
+ wxSize size = this->GetSize();
+ config.Write(wxT("size.x"), size.x);
+ config.Write(wxT("size.y"), size.y);
+
+ m_panel_program->ConfigWrite(&config);
+ }
+};
#ifndef WIN32
extern "C"{
- int anago_cui(int c, char **v);
+ int anago_cui(int c, wxChar **v);
}
-int main(int c, char **v)
+int main(int c, wxChar **v)
{
- if(c < 2){
+ if(c < 3){
return wxEntry(c, v);
}
return anago_cui(c, v);
public:
bool OnInit()
{
- m_frame = new anago_frame(NULL);
+ if(this->argc >= 2){
+ m_frame = new anago_frame(NULL, &DRIVER_DUMMY);
+ }else{
+ m_frame = new anago_frame(NULL, &DRIVER_KAZZO);
+ }
m_frame->Show();
return true;
}
};
+#ifdef WIN32
IMPLEMENT_APP(MyApp)
-
+#else
+IMPLEMENT_APP_NO_MAIN(MyApp)
+#endif