OSDN Git Service

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