OSDN Git Service

version 表示タブを追加
[unagi/old-svn-converted.git] / client / trunk / anago / anago_frame.cpp
1 #include <wx/wx.h>
2 #include <wx/log.h>
3 #include <wx/dir.h>
4 #include <wx/thread.h>
5 #include <wx/app.h>
6 #include <cstring>
7 #include <cstdarg>
8 #include "anago_gui.h"
9 #include "widget.h"
10 #include "reader_master.h"
11 //#include "reader_kazzo.h"
12 extern const struct reader_driver DRIVER_KAZZO;
13 extern "C"{
14 #include "header.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);
19 }
20
21 //---- C++ -> C -> C++ wrapping functions ----
22 static void value_set(void *gauge, void *label, int value)
23 {
24         wxGauge *g = static_cast<wxGauge *>(gauge);
25         wxStaticText *l = static_cast<wxStaticText *>(label);
26         wxString str;
27         str.Printf(wxT("0x%06x/0x%06x"), value, g->GetRange());
28         
29         wxMutexGuiEnter();
30         g->SetValue(value);
31         l->SetLabel(str);
32         wxMutexGuiLeave();
33 }
34
35 static void value_add(void *gauge, void *label, int value)
36 {
37         wxGauge *g = static_cast<wxGauge *>(gauge);
38         value += g->GetValue();
39         
40         value_set(gauge, label, value);
41 }
42
43 static void range_set(void *gauge, int value)
44 {
45         wxGauge *g = static_cast<wxGauge *>(gauge);
46         if(value == 0){
47                 value = 1;
48         }
49         g->SetRange(value);
50 }
51
52 static void text_append_va(void *log, const char *format, va_list list)
53 {
54         wxTextCtrl *l = static_cast<wxTextCtrl *>(log);
55         wxString str;
56         str.PrintfV(format, list);
57
58         wxMutexGuiEnter();
59         *l << str;
60         wxMutexGuiLeave();
61 }
62
63 static void text_append(void *log, const char *format, ...)
64 {
65         va_list list;
66         va_start(list, format);
67         text_append_va(log, format, list);
68         va_end(list);
69 }
70
71 static void version_append_va(void *log, const char *format, va_list list)
72 {
73         wxTextCtrl *l = static_cast<wxTextCtrl *>(log);
74         wxString str;
75         str.PrintfV(format, list);
76
77         *l << str;
78 }
79
80 static void version_append(void *log, const char *format, ...)
81 {
82         va_list list;
83         va_start(list, format);
84         version_append_va(log, format, list);
85         va_end(list);
86 }
87
88 static void label_set(void *label, const char *format, ...)
89 {
90         wxStaticText *l = static_cast<wxStaticText *>(label);
91         wxString str;
92         va_list list;
93         
94         va_start(list, format);
95         str.PrintfV(format, list);
96         va_end(list);
97
98         wxMutexGuiEnter();
99         l->SetLabel(str);
100         wxMutexGuiLeave();
101 }
102
103 void choice_append(void *choice, const char *str)
104 {
105         wxChoice *c = static_cast<wxChoice *>(choice);
106         c->Append(wxString(str));
107 }
108
109 //---- script execute thread ----
110 class anago_frame;
111 class anago_dumper : public wxThread
112 {
113 private:
114         anago_frame *m_frame;
115         struct dump_config m_config;
116 protected:
117         void *Entry(void);
118         void OnExit()
119         {
120                 delete [] m_config.script;
121                 delete [] m_config.target;
122         }
123 public:
124         anago_dumper(anago_frame *f, const struct dump_config *d) : wxThread()
125         {
126                 m_frame = f;
127                 memcpy(&m_config, d, sizeof(struct dump_config));
128         }
129 };
130
131 class anago_programmer : public wxThread
132 {
133 private:
134         anago_frame *m_frame;
135         struct program_config m_config;
136 protected:
137         void *Entry(void);
138         void OnExit()
139         {
140                 delete [] m_config.script;
141                 delete [] m_config.target;
142         }
143 public:
144         anago_programmer(anago_frame *f, const struct program_config *d) : wxThread()
145         {
146                 m_frame = f;
147                 memcpy(&m_config, d, sizeof(struct program_config));
148         }
149 };
150
151 //---- main frame class ----
152 class anago_frame : public frame_main
153 {
154 private:
155         wxThread *m_anago_thread;
156         enum{
157                 STATUS_IDLE, STATUS_DUMPPING, STATUS_PROGRAMMING
158         }m_status;
159         void gauge_init(struct gauge *t)
160         {
161                 t->label_set = label_set;
162                 t->range_set = range_set;
163                 t->value_set = value_set;
164                 t->value_add = value_add;
165         }
166         void script_choice_init(wxChoice *c, wxString filespec)
167         {
168                 wxDir dir(wxGetCwd());
169                 wxString filename;
170
171                 c->Clear();
172                 if ( !dir.IsOpened() ){
173                         return;
174                 }
175                 bool cont = dir.GetFirst(&filename, filespec, wxDIR_FILES);
176                 while ( cont ){
177                         c->Append(filename);
178                         cont = dir.GetNext(&filename);
179                 }
180                 if(c->GetCount() == 0){
181                         *m_log << wxT("warning: ") << filespec << wxT(" script not found.\n");
182                 }else{
183                         c->Select(0);
184                 }
185         }
186 //---- dump mode functions ----
187         void dump_increase_init(wxChoice *c)
188         {
189                 c->Clear();
190                 c->Append(wxT("x1"));
191                 c->Append(wxT("x2"));
192                 c->Append(wxT("x4"));
193                 c->Select(0);
194         }
195         int dump_increase_get(wxChoice *c)
196         {
197                 switch(c->GetSelection()){
198                 case 0: return 1;
199                 case 1: return 2;
200                 case 2: return 4;
201                 }
202                 return 1;
203         }
204         void dump_execute(void)
205         {
206                 struct dump_config config;
207                 config.cpu.gauge.bar = m_dump_cpu_gauge;
208                 config.cpu.gauge.label = m_dump_cpu_value;
209                 gauge_init(&config.cpu.gauge);
210
211                 config.ppu.gauge.bar = m_dump_ppu_gauge;
212                 config.ppu.gauge.label = m_dump_ppu_value;
213                 gauge_init(&config.ppu.gauge);
214                 
215                 config.log.object = m_log;
216                 config.log.append = text_append;
217                 config.log.append_va = text_append_va;
218                 config.cpu.increase = dump_increase_get(m_dump_cpu_increase);
219                 config.ppu.increase = dump_increase_get(m_dump_ppu_increase);
220                 config.progress = true;
221                 config.battery = m_dump_check_battery->GetValue();
222                 {
223                         wxString str_script = m_dump_script_choice->GetStringSelection();
224                         char *t = new char[str_script.Length() + 1];
225                         config.script = t;
226                         strncpy(t, str_script.fn_str(), str_script.Length() + 1);
227                 }
228
229                 {
230                         wxString str;
231                         config.mappernum = -1;
232                         if(m_dump_check_forcemapper->GetValue() == true){
233                                 str = m_dump_text_forcemapper->GetValue();
234                                 if(str.ToLong(&config.mappernum) == false){
235                                         *m_log << wxT("bad mapper number\n");
236                                         return;
237                                 }
238                         }
239                 }
240
241                 {
242                         wxTextCtrl *text = m_dump_romimage_picker->GetTextCtrl();
243                         wxString str_rom = text->GetValue();
244                         char *t = new char[str_rom.Length() + 1];
245                         if(text->IsEmpty() == true){
246                                 *m_log << wxT("Enter filename to ROM image\n");
247                                 return;
248                         }
249                         config.target = t;
250                         strncpy(t, str_rom.fn_str(), str_rom.Length() + 1);
251                 }
252
253                 config.control = &DRIVER_KAZZO.control;
254                 config.cpu.access = &DRIVER_KAZZO.cpu;
255                 config.ppu.access = &DRIVER_KAZZO.ppu;
256
257                 m_dump_script_choice->Disable();
258                 m_dump_romimage_picker->Disable();
259                 m_dump_check_battery->Disable();
260                 m_dump_check_forcemapper->Disable();
261                 m_dump_button->SetLabel(wxT("cancel"));
262                 m_dump_text_forcemapper->Disable();
263                 m_dump_cpu_increase->Disable();
264                 m_dump_ppu_increase->Disable();
265
266 /*              if(m_anago_thread != NULL){ //???
267                         delete m_anago_thread;
268                 }*/
269                 m_anago_thread = new anago_dumper(this, &config);
270                 if(m_anago_thread->Create() != wxTHREAD_NO_ERROR){
271                         *m_log << wxT("thread creating error");
272                 }else if(m_anago_thread->Run() != wxTHREAD_NO_ERROR){
273                         *m_log << wxT("thread running error");
274                 }else{
275                         m_status = STATUS_DUMPPING;
276                 }
277         }
278         
279 //----- program mode functions ----
280         void program_padding_init(wxChoice *c)
281         {
282                 c->Clear();
283                 c->Append(wxT("full"));
284                 c->Append(wxT("top"));
285                 c->Append(wxT("bottom"));
286                 c->Append(wxT("empty"));
287                 c->Select(0);
288         }
289         bool program_rom_set(wxString device, int trans, struct memory *m, struct flash_device *f)
290         {
291                 m->offset = 0;
292                 if(flash_device_get(device, f) == false){
293                         *m_log << wxT("unknown flash memory device ");
294                         *m_log << device << wxT("\n");
295                         return false;
296                 }
297                 switch(trans){
298                 case 0: 
299                         m->transtype = TRANSTYPE_FULL;
300                         break;
301                 case 1: 
302                         m->transtype = TRANSTYPE_TOP;
303                         break;
304                 case 2: 
305                         m->transtype = TRANSTYPE_BOTTOM;
306                         break;
307                 default: 
308                         m->transtype = TRANSTYPE_EMPTY;
309                         break;
310                 }
311                 return true;
312         }
313
314         void program_execute(void)
315         {
316                 struct program_config f;
317                 
318                 f.cpu.gauge.bar = m_program_cpu_gauge;
319                 f.cpu.gauge.label = m_program_cpu_value;
320                 gauge_init(&f.cpu.gauge);
321
322                 f.ppu.gauge.bar = m_program_ppu_gauge;
323                 f.ppu.gauge.label = m_program_ppu_value;
324                 gauge_init(&f.ppu.gauge);
325                 
326                 f.log.object = m_log;
327                 f.log.append = text_append;
328                 f.log.append_va = text_append_va;
329                 
330                 {
331                         wxString str_script = m_program_script_choice->GetStringSelection();
332                         char *t = new char[str_script.Length() + 1];
333                         strncpy(t, str_script.fn_str(), str_script.Length() + 1);
334                         f.script = t;
335                 }
336
337                 {
338                         wxTextCtrl *text = m_program_romimage_picker->GetTextCtrl();
339                         wxString str_rom = text->GetValue();
340                         if(text->IsEmpty() == true){
341                                 *m_log << wxT("Enter filename to ROM image\n");
342                                 return;
343                         }
344                         char *t = new char[str_rom.Length() + 1];
345                         strncpy(t, str_rom.fn_str(), str_rom.Length() + 1);
346                         f.target = t;
347                 }
348                 f.compare = m_program_compare->GetValue();
349                 f.testrun = false;
350
351                 if(program_rom_set(
352                         m_program_cpu_device->GetStringSelection(), 
353                         m_program_cpu_padding->GetSelection(),
354                         &f.cpu.memory, &f.cpu.flash
355                 ) == false){
356                         return;
357                 }
358                 if(program_rom_set(
359                         m_program_ppu_device->GetStringSelection(), 
360                         m_program_ppu_padding->GetSelection(),
361                         &f.ppu.memory, &f.ppu.flash
362                 ) == false){
363                         return;
364                 }
365
366                 f.control = &DRIVER_KAZZO.control;
367                 f.cpu.access = &DRIVER_KAZZO.cpu;
368                 f.ppu.access = &DRIVER_KAZZO.ppu;
369
370                 m_program_script_choice->Disable();
371                 m_program_romimage_picker->Disable();
372                 m_program_compare->Disable();
373                 m_program_button->SetLabel(wxT("cancel"));
374                 m_program_cpu_padding->Disable();
375                 m_program_cpu_device->Disable();
376                 m_program_ppu_padding->Disable();
377                 m_program_ppu_device->Disable();
378                 m_program_compare->Disable();
379
380                 m_anago_thread = new anago_programmer(this, &f);
381                 if(m_anago_thread->Create() != wxTHREAD_NO_ERROR){
382                         *m_log << wxT("thread creating error");
383                 }else if(m_anago_thread->Run() != wxTHREAD_NO_ERROR){
384                         *m_log << wxT("thread running error");
385                 }else{
386                         m_status = STATUS_PROGRAMMING;
387                 }
388         }
389
390 protected:
391         void dump_button_click(wxCommandEvent& event)
392         {
393                 switch(m_status){
394                 case STATUS_IDLE:
395                         this->dump_execute();
396                         break;
397                 case STATUS_DUMPPING:
398                         m_anago_thread->Kill();
399                         this->DumpThreadFinish();
400                         m_status = STATUS_IDLE;
401                         break;
402                 default: //do nothing
403                         break;
404                 }
405         }
406         void program_button_click(wxCommandEvent& event)
407         {
408                 switch(m_status){
409                 case STATUS_IDLE:
410                         this->program_execute();
411                         break;
412                 case STATUS_PROGRAMMING:
413                         m_anago_thread->Kill();
414                         this->ProgramThreadFinish();
415                         m_status = STATUS_IDLE;
416                         break;
417                 default: //do nothing
418                         break;
419                 }
420         }
421         void mapper_change_check(wxCommandEvent& event)
422         {
423                 if(m_dump_check_forcemapper->GetValue() == true){
424                         m_dump_text_forcemapper->Enable();
425                 }else{
426                         m_dump_text_forcemapper->Disable();
427                 }
428         }
429         void menu_log_clean(wxCommandEvent& event)
430         {
431                 m_log->Clear();
432         }
433 public:
434         /** Constructor */
435         anago_frame( wxWindow* parent ) : frame_main(parent)
436         {
437                 this->script_choice_init(m_dump_script_choice, wxT("*.ad"));
438                 this->script_choice_init(m_program_script_choice, wxT("*.af"));
439                 this->dump_increase_init(m_dump_cpu_increase);
440                 this->dump_increase_init(m_dump_ppu_increase);
441
442                 struct flash_listup list;
443                 list.obj_cpu = m_program_cpu_device;
444                 list.obj_ppu = m_program_ppu_device;
445                 list.append = choice_append;
446                 flash_device_listup(&list);
447                 if(m_program_cpu_device->GetCount() == 0){
448                         *m_log << wxT("warning: flash device parameter not found\n");
449                 }else{
450                         m_program_cpu_device->Select(0);
451                         m_program_ppu_device->Select(0);
452                 }
453                 this->program_padding_init(m_program_cpu_padding);
454                 this->program_padding_init(m_program_ppu_padding);
455                 
456                 m_anago_thread = NULL;
457                 m_status = STATUS_IDLE;
458
459 //version infomation
460                 struct textcontrol detail;
461                 *m_version_detail << wxT("anago build at ") << __DATE__ << wxT("\n\n");
462                 detail.object = m_version_detail;
463                 detail.append = version_append;
464                 detail.append_va = version_append_va;
465                 qr_version_print(&detail);
466                 *m_version_detail << wxVERSION_STRING << wxT(" (c) Julian Smar");
467                 
468                 #include "okada.xpm"
469                 wxBitmap bitmap_okada(okada);
470                 wxString tooltip(wxT(
471                         "緑区 na6ko 町さん (28歳, 童貞)"
472
473                         "28年間バカにされっぱなし、ミジメ過ぎた俺の人生が anago,\n"
474                         "kazzo を持つようになった途端、突然ツキがめぐってきた。\n"
475                         "競馬をやれば連戦連勝、夢にまでみた万馬券を当て、気がつくと\n"
476                         "しんじられない事にギャンブルで稼いだお金が460万円!!\n"
477                         "元手はたった9500円。しかもたった2ヶ月で人生大逆転!!\n"
478                         "女は3P4Pヤリ放題!!勤めていた新聞屋も辞めギャンブルで\n"
479                         "身を立てていこうと思っています。実は来月の11日にラスベガスに行き\n"
480                         "勝負をかけます。結果はまた報告します。宜しく。")
481                 );
482                 m_version_photo->SetBitmap(bitmap_okada);
483                 m_version_photo->SetToolTip(tooltip);
484         }
485
486         void DumpThreadFinish(void)
487         {
488                 m_dump_script_choice->Enable();
489                 m_dump_romimage_picker->Enable();
490                 m_dump_check_battery->Enable();
491                 m_dump_check_forcemapper->Enable();
492                 m_dump_cpu_increase->Enable();
493                 m_dump_ppu_increase->Enable();
494                 m_dump_button->SetLabel(wxT("&dump"));
495                 if(m_dump_check_forcemapper->GetValue() == true){
496                         m_dump_text_forcemapper->Enable();
497                 }
498                 m_status = STATUS_IDLE;
499         }
500         
501         void ProgramThreadFinish(void)
502         {
503                 m_program_script_choice->Enable();
504                 m_program_romimage_picker->Enable();
505                 m_program_compare->Enable();
506                 m_program_button->SetLabel(wxT("&program"));
507                 m_program_cpu_padding->Enable();
508                 m_program_cpu_device->Enable();
509                 m_program_ppu_padding->Enable();
510                 m_program_ppu_device->Enable();
511                 m_status = STATUS_IDLE;
512         }
513 };
514
515
516 void *anago_dumper::Entry(void)
517 {
518         script_dump_execute(&m_config);
519         m_frame->DumpThreadFinish();
520         return NULL;
521 }
522
523 void *anago_programmer::Entry(void)
524 {
525         script_program_execute(&m_config);
526         m_frame->ProgramThreadFinish();
527         return NULL;
528 }
529
530 class MyApp : public wxApp
531 {
532 private:
533         anago_frame *m_frame;
534 public: 
535         bool OnInit()
536         {
537                 m_frame = new anago_frame(NULL);
538                 m_frame->Show();
539                 
540                 return true;
541         }
542 };
543 IMPLEMENT_APP(MyApp)