OSDN Git Service

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