2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
7 [ win32 emulation i/f ]
18 // ----------------------------------------------------------------------------
20 // ----------------------------------------------------------------------------
21 static const int sound_frequency_table[8] = {
22 2000, 4000, 8000, 11025, 22050, 44100,
23 #ifdef OVERRIDE_SOUND_FREQ_48000HZ
24 OVERRIDE_SOUND_FREQ_48000HZ,
30 static const double sound_latency_table[5] = {0.05, 0.1, 0.2, 0.3, 0.4};
33 // Please permit at least them m(.. )m
34 //extern void get_long_full_path_name(_TCHAR* src, _TCHAR* dst);
36 extern CSP_Logger *csp_logger;
40 EMU::EMU(class Ui_MainWindow *hwnd, GLDrawClass *hinst, USING_FLAGS *p)
41 #elif defined(OSD_WIN32)
42 EMU::EMU(HWND hwnd, HINSTANCE hinst)
48 // store main window handle
49 #ifdef USE_FLOPPY_DISK
50 // initialize d88 file info
51 memset(d88_file, 0, sizeof(d88_file));
54 // initialize d88 file info
55 memset(b77_file, 0, sizeof(b77_file));
59 if(!(0 <= config.sound_frequency && config.sound_frequency < 8)) {
60 config.sound_frequency = 6; // default: 48KHz
62 if(!(0 <= config.sound_latency && config.sound_latency < 5)) {
63 config.sound_latency = 1; // default: 100msec
65 sound_frequency = config.sound_frequency;
66 sound_latency = config.sound_latency;
67 sound_rate = sound_frequency_table[config.sound_frequency];
68 sound_samples = (int)(sound_rate * sound_latency_table[config.sound_latency] + 0.5);
71 cpu_type = config.cpu_type;
74 dipswitch = config.dipswitch;
77 sound_type = config.sound_type;
79 #ifdef USE_PRINTER_TYPE
80 printer_type = config.printer_type;
83 // initialize b77 file info
84 memset(b77_file, 0, sizeof(b77_file));
89 osd = new OSD(p, csp_logger);
90 osd->main_window_handle = hwnd;
93 #elif defined(OSD_WIN32)
95 osd->main_window_handle = hwnd;
96 osd->instance_handle = hinst;
98 int presented_rate, presented_samples;
99 osd->initialize(sound_rate, sound_samples, &presented_rate, &presented_samples);
100 sound_rate = presented_rate;
101 sound_samples = presented_samples;
105 # if defined(_USE_QT)
106 osd->reset_vm_node();
107 osd->update_keyname_table();
110 initialize_auto_key();
113 initialize_debugger();
115 now_waiting_in_debugger = false;
117 vm->initialize_sound(sound_rate, sound_samples);
118 #ifdef USE_SOUND_VOLUME
119 for(int i = 0; i < USE_SOUND_VOLUME; i++) {
120 vm->set_sound_device_volume(i, config.sound_volume_l[i], config.sound_volume_r[i]);
124 for(int drv = 0; drv < USE_HARD_DISK; drv++) {
125 if(config.last_hard_disk_path[drv][0] != _T('\0') && FILEIO::IsFileExisting(config.last_hard_disk_path[drv])) {
126 vm->open_hard_disk(drv, config.last_hard_disk_path[drv]);
127 my_tcscpy_s(hard_disk_status[drv].path, _MAX_PATH, config.last_hard_disk_path[drv]);
132 now_suspended = false;
154 EmuThreadClass *EMU::get_parent_handler()
156 return osd->get_parent_handler();
159 void EMU::set_parent_handler(EmuThreadClass *p, DrawThreadClass *q)
161 osd->set_parent_thread(p);
162 osd->set_draw_thread(q);
165 void EMU::set_host_cpus(int v)
167 osd->host_cpus = (v <= 0) ? 1 : v;
170 int EMU::get_host_cpus()
172 return osd->host_cpus;
176 // ----------------------------------------------------------------------------
178 // ----------------------------------------------------------------------------
180 double EMU::get_frame_rate()
182 return vm->get_frame_rate();
185 int EMU::get_frame_interval()
187 static int prev_interval = 0;
188 static double prev_fps = -1;
189 double fps = vm->get_frame_rate();
190 if(prev_fps != fps) {
191 prev_interval = (int)(1024. * 1000. / fps + 0.5);
194 return prev_interval;
197 bool EMU::is_frame_skippable()
199 return vm->is_frame_skippable();
206 now_suspended = false;
217 #if !defined(_USE_QT) // Temporally
218 osd->update_socket();
223 // virtual machine may be driven to fill sound buffer
224 int extra_frames = 0;
225 osd->update_sound(&extra_frames);
227 // drive virtual machine
228 if(extra_frames == 0) {
234 osd->add_extra_frames(extra_frames);
242 config.romaji_to_kana = false;
245 // check if virtual machine should be reinitialized
246 bool reinitialize = false;
248 reinitialize |= (cpu_type != config.cpu_type);
249 cpu_type = config.cpu_type;
252 reinitialize |= (dipswitch != config.dipswitch);
253 dipswitch = config.dipswitch;
255 #ifdef USE_SOUND_TYPE
256 reinitialize |= (sound_type != config.sound_type);
257 sound_type = config.sound_type;
259 #ifdef USE_PRINTER_TYPE
260 reinitialize |= (printer_type != config.printer_type);
261 printer_type = config.printer_type;
266 // reinitialize virtual machine
272 osd->reset_vm_node();
273 osd->update_keyname_table();
276 int presented_samples;
277 sound_rate = sound_frequency_table[config.sound_frequency];
278 sound_samples = (int)(sound_rate * sound_latency_table[config.sound_latency] + 0.5);
279 osd->initialize_sound(sound_rate, sound_samples, &presented_rate, &presented_samples);
280 if((sound_rate != presented_rate) ||
281 (sound_samples != presented_samples)) {
282 sound_rate = presented_rate;
283 sound_samples = presented_samples;
285 vm->initialize_sound(sound_rate, sound_samples);
286 #ifdef USE_SOUND_VOLUME
287 for(int i = 0; i < USE_SOUND_VOLUME; i++) {
288 vm->set_sound_device_volume(i, config.sound_volume_l[i], config.sound_volume_r[i]);
291 // restore inserted medias
296 // reset virtual machine
302 #if !defined(_USE_QT) // Temporally
304 osd->restart_record_sound();
305 osd->restart_record_video();
309 #ifdef USE_SPECIAL_RESET
310 void EMU::special_reset()
314 config.romaji_to_kana = false;
317 // reset virtual machine
322 #if !defined(_USE_QT) // Temporally
323 restart_record_sound();
324 restart_record_video();
329 #ifdef USE_NOTIFY_POWER_OFF
330 void EMU::notify_power_off()
332 vm->notify_power_off();
336 void EMU::power_off()
345 now_suspended = true;
354 void EMU::unlock_vm()
359 void EMU::force_unlock_vm()
361 osd->force_unlock_vm();
364 bool EMU::is_vm_locked()
366 return osd->is_vm_locked();
369 // ----------------------------------------------------------------------------
371 // ----------------------------------------------------------------------------
374 void EMU::key_down(int code, bool extended, bool repeat)
378 shift_pressed = true;
380 if(config.romaji_to_kana) {
382 // Page Up, Page Down, End, Home, Left, Up, Right, Down, Ins, Del, Help, and F1-F12
383 if((code >= 0x21 && code <= 0x2f) || (code >= 0x70 && code <= 0x7b)) {
385 auto_key_buffer->write(code | 0x100);
387 auto_key_buffer->write(code);
389 if(!is_auto_key_running()) {
394 } else if(!is_auto_key_running())
396 osd->key_down(code, extended, repeat);
399 void EMU::key_up(int code, bool extended)
403 shift_pressed = false;
405 if(config.romaji_to_kana) {
407 } else if(!is_auto_key_running())
409 osd->key_up(code, extended);
412 void EMU::key_char(char code)
415 if(config.romaji_to_kana) {
416 set_auto_key_char(code);
421 #ifdef USE_KEY_LOCKED
422 bool EMU::get_caps_locked()
424 return vm->get_caps_locked();
427 bool EMU::get_kana_locked()
429 return vm->get_kana_locked();
433 void EMU::key_lost_focus()
435 osd->key_lost_focus();
438 #ifdef ONE_BOARD_MICRO_COMPUTER
439 void EMU::press_button(int num)
441 int code = vm_buttons[num].code;
444 osd->key_down_native(code, false);
445 osd->get_key_buffer()[code] = KEY_KEEP_FRAMES;
447 // code=0: reset virtual machine
454 void EMU::enable_mouse()
459 void EMU::disable_mouse()
461 osd->disable_mouse();
464 void EMU::toggle_mouse()
469 bool EMU::is_mouse_enabled()
471 return osd->is_mouse_enabled();
476 static const int auto_key_table_base[][2] = {
483 {0x08, 0x000 | 0x08}, // BS
484 {0x09, 0x000 | 0x09}, // Tab
485 {0x0d, 0x000 | 0x0d}, // Enter
486 {0x1b, 0x000 | 0x1b}, // Escape
487 {0x20, 0x000 | 0x20}, // ' '
489 {0x21, 0x100 | 0x31}, // '!'
490 {0x22, 0x100 | 0xba}, // '"'
491 {0x23, 0x100 | 0x33}, // '#'
492 {0x24, 0x100 | 0x34}, // '$'
493 {0x25, 0x100 | 0x35}, // '%'
494 {0x26, 0x100 | 0x37}, // '&'
495 {0x27, 0x000 | 0xba}, // '''
496 {0x28, 0x100 | 0x39}, // '('
497 {0x29, 0x100 | 0x30}, // ')'
498 {0x2a, 0x100 | 0x38}, // '*'
499 {0x2b, 0x100 | 0xde}, // '+'
500 {0x2c, 0x000 | 0xbc}, // ','
501 {0x2d, 0x000 | 0xbd}, // '-'
502 {0x2e, 0x000 | 0xbe}, // '.'
503 {0x2f, 0x000 | 0xbf}, // '/'
505 {0x21, 0x100 | 0x31}, // '!'
506 {0x22, 0x100 | 0x32}, // '"'
507 {0x23, 0x100 | 0x33}, // '#'
508 {0x24, 0x100 | 0x34}, // '$'
509 {0x25, 0x100 | 0x35}, // '%'
510 {0x26, 0x100 | 0x36}, // '&'
511 {0x27, 0x100 | 0x37}, // '''
512 {0x28, 0x100 | 0x38}, // '('
513 {0x29, 0x100 | 0x39}, // ')'
514 {0x2a, 0x100 | 0xba}, // '*'
515 {0x2b, 0x100 | 0xbb}, // '+'
516 {0x2c, 0x000 | 0xbc}, // ','
517 {0x2d, 0x000 | 0xbd}, // '-'
518 {0x2e, 0x000 | 0xbe}, // '.'
519 {0x2f, 0x000 | 0xbf}, // '/'
521 {0x30, 0x000 | 0x30}, // '0'
522 {0x31, 0x000 | 0x31}, // '1'
523 {0x32, 0x000 | 0x32}, // '2'
524 {0x33, 0x000 | 0x33}, // '3'
525 {0x34, 0x000 | 0x34}, // '4'
526 {0x35, 0x000 | 0x35}, // '5'
527 {0x36, 0x000 | 0x36}, // '6'
528 {0x37, 0x000 | 0x37}, // '7'
529 {0x38, 0x000 | 0x38}, // '8'
530 {0x39, 0x000 | 0x39}, // '9'
532 {0x3a, 0x100 | 0xbb}, // ':'
533 {0x3b, 0x000 | 0xbb}, // ';'
534 {0x3c, 0x100 | 0xbc}, // '<'
535 {0x3d, 0x000 | 0xde}, // '='
536 {0x3e, 0x100 | 0xbe}, // '>'
537 {0x3f, 0x100 | 0xbf}, // '?'
538 {0x40, 0x100 | 0x32}, // '@'
540 {0x3a, 0x000 | 0xba}, // ':'
541 {0x3b, 0x000 | 0xbb}, // ';'
542 {0x3c, 0x100 | 0xbc}, // '<'
543 {0x3d, 0x100 | 0xbd}, // '='
544 {0x3e, 0x100 | 0xbe}, // '>'
545 {0x3f, 0x100 | 0xbf}, // '?'
546 {0x40, 0x000 | 0xc0}, // '@'
548 {0x41, 0x400 | 0x41}, // 'A'
549 {0x42, 0x400 | 0x42}, // 'B'
550 {0x43, 0x400 | 0x43}, // 'C'
551 {0x44, 0x400 | 0x44}, // 'D'
552 {0x45, 0x400 | 0x45}, // 'E'
553 {0x46, 0x400 | 0x46}, // 'F'
554 {0x47, 0x400 | 0x47}, // 'G'
555 {0x48, 0x400 | 0x48}, // 'H'
556 {0x49, 0x400 | 0x49}, // 'I'
557 {0x4a, 0x400 | 0x4a}, // 'J'
558 {0x4b, 0x400 | 0x4b}, // 'K'
559 {0x4c, 0x400 | 0x4c}, // 'L'
560 {0x4d, 0x400 | 0x4d}, // 'M'
561 {0x4e, 0x400 | 0x4e}, // 'N'
562 {0x4f, 0x400 | 0x4f}, // 'O'
563 {0x50, 0x400 | 0x50}, // 'P'
564 {0x51, 0x400 | 0x51}, // 'Q'
565 {0x52, 0x400 | 0x52}, // 'R'
566 {0x53, 0x400 | 0x53}, // 'S'
567 {0x54, 0x400 | 0x54}, // 'T'
568 {0x55, 0x400 | 0x55}, // 'U'
569 {0x56, 0x400 | 0x56}, // 'V'
570 {0x57, 0x400 | 0x57}, // 'W'
571 {0x58, 0x400 | 0x58}, // 'X'
572 {0x59, 0x400 | 0x59}, // 'Y'
573 {0x5a, 0x400 | 0x5a}, // 'Z'
575 {0x5b, 0x000 | 0xc0}, // '['
576 {0x5c, 0x000 | 0xe2}, // '\'
577 {0x5d, 0x000 | 0xdb}, // ']'
578 {0x5e, 0x100 | 0x36}, // '^'
579 {0x5f, 0x100 | 0xbd}, // '_'
580 {0x60, 0x000 | 0xdd}, // '`'
582 {0x5b, 0x000 | 0xdb}, // '['
583 {0x5c, 0x000 | 0xdc}, // '\'
584 {0x5d, 0x000 | 0xdd}, // ']'
585 {0x5e, 0x000 | 0xde}, // '^'
586 {0x5f, 0x100 | 0xe2}, // '_'
587 {0x60, 0x100 | 0xc0}, // '`'
589 {0x61, 0x800 | 0x41}, // 'a'
590 {0x62, 0x800 | 0x42}, // 'b'
591 {0x63, 0x800 | 0x43}, // 'c'
592 {0x64, 0x800 | 0x44}, // 'd'
593 {0x65, 0x800 | 0x45}, // 'e'
594 {0x66, 0x800 | 0x46}, // 'f'
595 {0x67, 0x800 | 0x47}, // 'g'
596 {0x68, 0x800 | 0x48}, // 'h'
597 {0x69, 0x800 | 0x49}, // 'i'
598 {0x6a, 0x800 | 0x4a}, // 'j'
599 {0x6b, 0x800 | 0x4b}, // 'k'
600 {0x6c, 0x800 | 0x4c}, // 'l'
601 {0x6d, 0x800 | 0x4d}, // 'm'
602 {0x6e, 0x800 | 0x4e}, // 'n'
603 {0x6f, 0x800 | 0x4f}, // 'o'
604 {0x70, 0x800 | 0x50}, // 'p'
605 {0x71, 0x800 | 0x51}, // 'q'
606 {0x72, 0x800 | 0x52}, // 'r'
607 {0x73, 0x800 | 0x53}, // 's'
608 {0x74, 0x800 | 0x54}, // 't'
609 {0x75, 0x800 | 0x55}, // 'u'
610 {0x76, 0x800 | 0x56}, // 'v'
611 {0x77, 0x800 | 0x57}, // 'w'
612 {0x78, 0x800 | 0x58}, // 'x'
613 {0x79, 0x800 | 0x59}, // 'y'
614 {0x7a, 0x800 | 0x5a}, // 'z'
616 {0x7b, 0x100 | 0xc0}, // '{'
617 {0x7c, 0x100 | 0xe2}, // '|'
618 {0x7d, 0x100 | 0xdb}, // '}'
619 {0x7e, 0x100 | 0xdd}, // '~'
621 {0x7b, 0x100 | 0xdb}, // '{'
622 {0x7c, 0x100 | 0xdc}, // '|'
623 {0x7d, 0x100 | 0xdd}, // '}'
624 {0x7e, 0x100 | 0xde}, // '~'
629 static const int auto_key_table_kana_base[][2] = {
630 {0xa1, 0x300 | 0xbe}, // '¡'
631 {0xa2, 0x300 | 0xdb}, // '¢'
632 {0xa3, 0x300 | 0xdd}, // '£'
633 {0xa4, 0x300 | 0xbc}, // '¤'
634 {0xa5, 0x300 | 0xbf}, // '¥'
635 {0xa6, 0x300 | 0x30}, // '¦'
636 {0xa7, 0x300 | 0x33}, // '§'
637 {0xa8, 0x300 | 0x45}, // '¨'
638 {0xa9, 0x300 | 0x34}, // '©'
639 {0xaa, 0x300 | 0x35}, // 'ª'
640 {0xab, 0x300 | 0x36}, // '«'
641 {0xac, 0x300 | 0x37}, // '¬'
642 {0xad, 0x300 | 0x38}, // ''
643 {0xae, 0x300 | 0x39}, // '®'
644 {0xaf, 0x300 | 0x5a}, // '¯'
645 {0xb0, 0x200 | 0xdc}, // '°'
646 {0xb1, 0x200 | 0x33}, // '±'
647 {0xb2, 0x200 | 0x45}, // '²'
648 {0xb3, 0x200 | 0x34}, // '³'
649 {0xb4, 0x200 | 0x35}, // '´'
650 {0xb5, 0x200 | 0x36}, // 'µ'
651 {0xb6, 0x200 | 0x54}, // '¶'
652 {0xb7, 0x200 | 0x47}, // '·'
653 {0xb8, 0x200 | 0x48}, // '¸'
654 {0xb9, 0x200 | 0xba}, // '¹'
655 {0xba, 0x200 | 0x42}, // 'º'
656 {0xbb, 0x200 | 0x58}, // '»'
657 {0xbc, 0x200 | 0x44}, // '¼'
658 {0xbd, 0x200 | 0x52}, // '½'
659 {0xbe, 0x200 | 0x50}, // '¾'
660 {0xbf, 0x200 | 0x43}, // '¿'
661 {0xc0, 0x200 | 0x51}, // 'À'
662 {0xc1, 0x200 | 0x41}, // 'Á'
663 {0xc2, 0x200 | 0x5a}, // 'Â'
664 {0xc3, 0x200 | 0x57}, // 'Ã'
665 {0xc4, 0x200 | 0x53}, // 'Ä'
666 {0xc5, 0x200 | 0x55}, // 'Å'
667 {0xc6, 0x200 | 0x49}, // 'Æ'
668 {0xc7, 0x200 | 0x31}, // 'Ç'
669 {0xc8, 0x200 | 0xbc}, // 'È'
670 {0xc9, 0x200 | 0x4b}, // 'É'
671 {0xca, 0x200 | 0x46}, // 'Ê'
672 {0xcb, 0x200 | 0x56}, // 'Ë'
673 {0xcc, 0x200 | 0x32}, // 'Ì'
674 {0xcd, 0x200 | 0xde}, // 'Í'
675 {0xce, 0x200 | 0xbd}, // 'Î'
676 {0xcf, 0x200 | 0x4a}, // 'Ï'
677 {0xd0, 0x200 | 0x4e}, // 'Ð'
678 {0xd1, 0x200 | 0xdd}, // 'Ñ'
679 {0xd2, 0x200 | 0xbf}, // 'Ò'
680 {0xd3, 0x200 | 0x4d}, // 'Ó'
681 {0xd4, 0x200 | 0x37}, // 'Ô'
682 {0xd5, 0x200 | 0x38}, // 'Õ'
683 {0xd6, 0x200 | 0x39}, // 'Ö'
684 {0xd7, 0x200 | 0x4f}, // '×'
685 {0xd8, 0x200 | 0x4c}, // 'Ø'
686 {0xd9, 0x200 | 0xbe}, // 'Ù'
687 {0xda, 0x200 | 0xbb}, // 'Ú'
688 {0xdb, 0x200 | 0xe2}, // 'Û'
689 {0xdc, 0x200 | 0x30}, // 'Ü'
690 {0xdd, 0x200 | 0x59}, // 'Ý'
691 {0xde, 0x200 | 0xc0}, // 'Þ'
692 {0xdf, 0x200 | 0xdb}, // 'ß'
696 static const int auto_key_table_50on_base[][2] = {
697 {0xa1, 0x300 | 0xbf}, // '¡'
698 {0xa2, 0x300 | 0xdb}, // '¢'
699 {0xa3, 0x300 | 0xdd}, // '£'
700 {0xa4, 0x300 | 0xbe}, // '¤'
701 {0xa5, 0x300 | 0xe2}, // '¥'
702 {0xa6, 0x200 | 0xbf}, // '¦'
703 {0xa7, 0x300 | 0x31}, // '§'
704 {0xa8, 0x300 | 0x32}, // '¨'
705 {0xa9, 0x300 | 0x33}, // '©'
706 {0xaa, 0x300 | 0x34}, // 'ª'
707 {0xab, 0x300 | 0x35}, // '«'
708 {0xac, 0x300 | 0x4e}, // '¬'
709 {0xad, 0x300 | 0x4d}, // ''
710 {0xae, 0x300 | 0xbc}, // '®'
711 {0xaf, 0x300 | 0x43}, // '¯'
712 {0xb0, 0x300 | 0xba}, // '°'
713 {0xb1, 0x200 | 0x31}, // '±'
714 {0xb2, 0x200 | 0x32}, // '²'
715 {0xb3, 0x200 | 0x33}, // '³'
716 {0xb4, 0x200 | 0x34}, // '´'
717 {0xb5, 0x200 | 0x35}, // 'µ'
718 {0xb6, 0x200 | 0x51}, // '¶'
719 {0xb7, 0x200 | 0x57}, // '·'
720 {0xb8, 0x200 | 0x45}, // '¸'
721 {0xb9, 0x200 | 0x52}, // '¹'
722 {0xba, 0x200 | 0x54}, // 'º'
723 {0xbb, 0x200 | 0x41}, // '»'
724 {0xbc, 0x200 | 0x53}, // '¼'
725 {0xbd, 0x200 | 0x44}, // '½'
726 {0xbe, 0x200 | 0x46}, // '¾'
727 {0xbf, 0x200 | 0x47}, // '¿'
728 {0xc0, 0x200 | 0x5a}, // 'À'
729 {0xc1, 0x200 | 0x58}, // 'Á'
730 {0xc2, 0x200 | 0x43}, // 'Â'
731 {0xc3, 0x200 | 0x56}, // 'Ã'
732 {0xc4, 0x200 | 0x42}, // 'Ä'
733 {0xc5, 0x200 | 0x36}, // 'Å'
734 {0xc6, 0x200 | 0x37}, // 'Æ'
735 {0xc7, 0x200 | 0x38}, // 'Ç'
736 {0xc8, 0x200 | 0x39}, // 'È'
737 {0xc9, 0x200 | 0x30}, // 'É'
738 {0xca, 0x200 | 0x59}, // 'Ê'
739 {0xcb, 0x200 | 0x55}, // 'Ë'
740 {0xcc, 0x200 | 0x49}, // 'Ì'
741 {0xcd, 0x200 | 0x4f}, // 'Í'
742 {0xce, 0x200 | 0x50}, // 'Î'
743 {0xcf, 0x200 | 0x48}, // 'Ï'
744 {0xd0, 0x200 | 0x4a}, // 'Ð'
745 {0xd1, 0x200 | 0x4b}, // 'Ñ'
746 {0xd2, 0x200 | 0x4c}, // 'Ò'
747 {0xd3, 0x200 | 0xbb}, // 'Ó'
748 {0xd4, 0x200 | 0x4e}, // 'Ô'
749 {0xd5, 0x200 | 0x4d}, // 'Õ'
750 {0xd6, 0x200 | 0xbc}, // 'Ö'
751 {0xd7, 0x200 | 0xbd}, // '×'
752 {0xd8, 0x200 | 0xde}, // 'Ø'
753 {0xd9, 0x200 | 0xdc}, // 'Ù'
754 {0xda, 0x200 | 0xc0}, // 'Ú'
755 {0xdb, 0x200 | 0xdb}, // 'Û'
756 {0xdc, 0x200 | 0xbe}, // 'Ü'
757 {0xdd, 0x200 | 0xe2}, // 'Ý'
758 {0xde, 0x200 | 0xba}, // 'Þ'
759 {0xdf, 0x200 | 0xdd}, // 'ß'
763 static const struct {
765 const uint8_t kana[4];
767 {"ltsu", {0xaf, 0x00}},
768 {"xtsu", {0xaf, 0x00}},
769 {"ltu", {0xaf, 0x00}},
770 {"xtu", {0xaf, 0x00}},
771 {"bya", {0xcb, 0xde, 0xac, 0x00}},
772 {"byi", {0xcb, 0xde, 0xa8, 0x00}},
773 {"byu", {0xcb, 0xde, 0xad, 0x00}},
774 {"bye", {0xcb, 0xde, 0xaa, 0x00}},
775 {"byo", {0xcb, 0xde, 0xae, 0x00}},
776 {"cha", {0xc1, 0xac, 0x00}},
777 {"chi", {0xc1, 0x00}},
778 {"chu", {0xc1, 0xad, 0x00}},
779 {"che", {0xc1, 0xaa, 0x00}},
780 {"cho", {0xc1, 0xae, 0x00}},
781 {"cya", {0xc1, 0xac, 0x00}},
782 {"cyi", {0xc1, 0xa8, 0x00}},
783 {"cyu", {0xc1, 0xad, 0x00}},
784 {"cye", {0xc1, 0xaa, 0x00}},
785 {"cyo", {0xc1, 0xae, 0x00}},
786 {"dha", {0xc3, 0xde, 0xac, 0x00}},
787 {"dhi", {0xc3, 0xde, 0xa8, 0x00}},
788 {"dhu", {0xc3, 0xde, 0xad, 0x00}},
789 {"dhe", {0xc3, 0xde, 0xaa, 0x00}},
790 {"dho", {0xc3, 0xde, 0xae, 0x00}},
791 {"dwa", {0xc4, 0xde, 0xa7, 0x00}},
792 {"dwi", {0xc4, 0xde, 0xa8, 0x00}},
793 {"dwu", {0xc4, 0xde, 0xa9, 0x00}},
794 {"dwe", {0xc4, 0xde, 0xaa, 0x00}},
795 {"dwo", {0xc4, 0xde, 0xab, 0x00}},
796 {"dya", {0xc1, 0xde, 0xac, 0x00}},
797 {"dyi", {0xc1, 0xde, 0xa8, 0x00}},
798 {"dyu", {0xc1, 0xde, 0xad, 0x00}},
799 {"dye", {0xc1, 0xde, 0xaa, 0x00}},
800 {"dyo", {0xc1, 0xde, 0xae, 0x00}},
801 {"fwa", {0xcc, 0xa7, 0x00}},
802 {"fwi", {0xcc, 0xa8, 0x00}},
803 {"fwu", {0xcc, 0xa9, 0x00}},
804 {"fwe", {0xcc, 0xaa, 0x00}},
805 {"fwo", {0xcc, 0xab, 0x00}},
806 {"fya", {0xcc, 0xac, 0x00}},
807 {"fyi", {0xcc, 0xa8, 0x00}},
808 {"fyu", {0xcc, 0xad, 0x00}},
809 {"fye", {0xcc, 0xaa, 0x00}},
810 {"fyo", {0xcc, 0xae, 0x00}},
811 {"gwa", {0xb8, 0xde, 0xa7, 0x00}},
812 {"gwi", {0xb8, 0xde, 0xa8, 0x00}},
813 {"gwu", {0xb8, 0xde, 0xa9, 0x00}},
814 {"gwe", {0xb8, 0xde, 0xaa, 0x00}},
815 {"gwo", {0xb8, 0xde, 0xab, 0x00}},
816 {"gya", {0xb7, 0xde, 0xac, 0x00}},
817 {"gyi", {0xb7, 0xde, 0xa8, 0x00}},
818 {"gyu", {0xb7, 0xde, 0xad, 0x00}},
819 {"gye", {0xb7, 0xde, 0xaa, 0x00}},
820 {"gyo", {0xb7, 0xde, 0xae, 0x00}},
821 {"hya", {0xcb, 0xac, 0x00}},
822 {"hyi", {0xcb, 0xa8, 0x00}},
823 {"hyu", {0xcb, 0xad, 0x00}},
824 {"hye", {0xcb, 0xaa, 0x00}},
825 {"hyo", {0xcb, 0xae, 0x00}},
826 {"jya", {0xbc, 0xde, 0xac, 0x00}},
827 {"jyi", {0xbc, 0xde, 0xa8, 0x00}},
828 {"jyu", {0xbc, 0xde, 0xad, 0x00}},
829 {"jye", {0xbc, 0xde, 0xaa, 0x00}},
830 {"jyo", {0xbc, 0xde, 0xae, 0x00}},
831 {"kya", {0xb7, 0xac, 0x00}},
832 {"kyi", {0xb7, 0xa8, 0x00}},
833 {"kyu", {0xb7, 0xad, 0x00}},
834 {"kye", {0xb7, 0xaa, 0x00}},
835 {"kyo", {0xb7, 0xae, 0x00}},
836 {"lya", {0xac, 0x00}},
837 {"lyi", {0xa8, 0x00}},
838 {"lyu", {0xad, 0x00}},
839 {"lye", {0xaa, 0x00}},
840 {"lyo", {0xae, 0x00}},
841 {"mya", {0xd0, 0xac, 0x00}},
842 {"myi", {0xd0, 0xa8, 0x00}},
843 {"myu", {0xd0, 0xad, 0x00}},
844 {"mye", {0xd0, 0xaa, 0x00}},
845 {"myo", {0xd0, 0xae, 0x00}},
846 {"nya", {0xc6, 0xac, 0x00}},
847 {"nyi", {0xc6, 0xa8, 0x00}},
848 {"nyu", {0xc6, 0xad, 0x00}},
849 {"nye", {0xc6, 0xaa, 0x00}},
850 {"nyo", {0xc6, 0xae, 0x00}},
851 {"pya", {0xcb, 0xdf, 0xac, 0x00}},
852 {"pyi", {0xcb, 0xdf, 0xa8, 0x00}},
853 {"pyu", {0xcb, 0xdf, 0xad, 0x00}},
854 {"pye", {0xcb, 0xdf, 0xaa, 0x00}},
855 {"pyo", {0xcb, 0xdf, 0xae, 0x00}},
856 {"qwa", {0xb8, 0xa7, 0x00}},
857 {"qwi", {0xb8, 0xa8, 0x00}},
858 {"qwu", {0xb8, 0xa9, 0x00}},
859 {"qwe", {0xb8, 0xaa, 0x00}},
860 {"qwo", {0xb8, 0xab, 0x00}},
861 {"qya", {0xb8, 0xac, 0x00}},
862 {"qyi", {0xb8, 0xa8, 0x00}},
863 {"qyu", {0xb8, 0xad, 0x00}},
864 {"qye", {0xb8, 0xaa, 0x00}},
865 {"qyo", {0xb8, 0xae, 0x00}},
866 {"rya", {0xd8, 0xac, 0x00}},
867 {"ryi", {0xd8, 0xa8, 0x00}},
868 {"ryu", {0xd8, 0xad, 0x00}},
869 {"rye", {0xd8, 0xaa, 0x00}},
870 {"ryo", {0xd8, 0xae, 0x00}},
871 {"sha", {0xbc, 0xac, 0x00}},
872 {"shi", {0xbc, 0x00}},
873 {"shu", {0xbc, 0xad, 0x00}},
874 {"she", {0xbc, 0xaa, 0x00}},
875 {"sho", {0xbc, 0xae, 0x00}},
876 {"swa", {0xbd, 0xa7, 0x00}},
877 {"swi", {0xbd, 0xa8, 0x00}},
878 {"swu", {0xbd, 0xa9, 0x00}},
879 {"swe", {0xbd, 0xaa, 0x00}},
880 {"swo", {0xbd, 0xab, 0x00}},
881 {"sya", {0xbc, 0xac, 0x00}},
882 {"syi", {0xbc, 0xa8, 0x00}},
883 {"syu", {0xbc, 0xad, 0x00}},
884 {"sye", {0xbc, 0xaa, 0x00}},
885 {"syo", {0xbc, 0xae, 0x00}},
886 {"tha", {0xc3, 0xac, 0x00}},
887 {"thi", {0xc3, 0xa8, 0x00}},
888 {"thu", {0xc3, 0xad, 0x00}},
889 {"the", {0xc3, 0xaa, 0x00}},
890 {"tho", {0xc3, 0xae, 0x00}},
891 {"tsa", {0xc2, 0xa7, 0x00}},
892 {"tsi", {0xc2, 0xa8, 0x00}},
893 {"tsu", {0xc2, 0x00}},
894 {"tse", {0xc2, 0xaa, 0x00}},
895 {"tso", {0xc2, 0xab, 0x00}},
896 {"twa", {0xc4, 0xa7, 0x00}},
897 {"twi", {0xc4, 0xa8, 0x00}},
898 {"twu", {0xc4, 0xa9, 0x00}},
899 {"twe", {0xc4, 0xaa, 0x00}},
900 {"two", {0xc4, 0xab, 0x00}},
901 {"tya", {0xc1, 0xac, 0x00}},
902 {"tyi", {0xc1, 0xa8, 0x00}},
903 {"tyu", {0xc1, 0xad, 0x00}},
904 {"tye", {0xc1, 0xaa, 0x00}},
905 {"tyo", {0xc1, 0xae, 0x00}},
906 {"vya", {0xb3, 0xde, 0xac, 0x00}},
907 {"vyi", {0xb3, 0xde, 0xa8, 0x00}},
908 {"vyu", {0xb3, 0xde, 0xad, 0x00}},
909 {"vye", {0xb3, 0xde, 0xaa, 0x00}},
910 {"vyo", {0xb3, 0xde, 0xae, 0x00}},
911 {"wha", {0xb3, 0xa7, 0x00}},
912 {"whi", {0xb3, 0xa8, 0x00}},
913 {"whu", {0xb3, 0x00}},
914 {"whe", {0xb3, 0xaa, 0x00}},
915 {"who", {0xb3, 0xab, 0x00}},
916 {"xya", {0xac, 0x00}},
917 {"xyi", {0xa8, 0x00}},
918 {"xyu", {0xad, 0x00}},
919 {"xye", {0xaa, 0x00}},
920 {"xyo", {0xae, 0x00}},
921 {"zya", {0xbc, 0xde, 0xac, 0x00}},
922 {"zyi", {0xbc, 0xde, 0xa8, 0x00}},
923 {"zyu", {0xbc, 0xde, 0xad, 0x00}},
924 {"zye", {0xbc, 0xde, 0xaa, 0x00}},
925 {"zyo", {0xbc, 0xde, 0xae, 0x00}},
926 {"ba", {0xca, 0xde, 0x00}},
927 {"bi", {0xcb, 0xde, 0x00}},
928 {"bu", {0xcc, 0xde, 0x00}},
929 {"be", {0xcd, 0xde, 0x00}},
930 {"bo", {0xce, 0xde, 0x00}},
931 {"ca", {0xb6, 0x00}},
932 {"ci", {0xbc, 0x00}},
933 {"cu", {0xb8, 0x00}},
934 {"ce", {0xbe, 0x00}},
935 {"co", {0xba, 0x00}},
936 {"da", {0xc0, 0xde, 0x00}},
937 {"di", {0xc1, 0xde, 0x00}},
938 {"du", {0xc2, 0xde, 0x00}},
939 {"de", {0xc3, 0xde, 0x00}},
940 {"do", {0xc4, 0xde, 0x00}},
941 {"fa", {0xcc, 0xa7, 0x00}},
942 {"fi", {0xcc, 0xa8, 0x00}},
943 {"fu", {0xcc, 0x00}},
944 {"fe", {0xcc, 0xaa, 0x00}},
945 {"fo", {0xcc, 0xab, 0x00}},
946 {"ga", {0xb6, 0xde, 0x00}},
947 {"gi", {0xb7, 0xde, 0x00}},
948 {"gu", {0xb8, 0xde, 0x00}},
949 {"ge", {0xb9, 0xde, 0x00}},
950 {"go", {0xba, 0xde, 0x00}},
951 {"ha", {0xca, 0x00}},
952 {"hi", {0xcb, 0x00}},
953 {"hu", {0xcc, 0x00}},
954 {"he", {0xcd, 0x00}},
955 {"ho", {0xce, 0x00}},
956 {"ja", {0xbc, 0xde, 0xac, 0x00}},
957 {"ji", {0xbc, 0xde, 0x00}},
958 {"ju", {0xbc, 0xde, 0xad, 0x00}},
959 {"je", {0xbc, 0xde, 0xaa, 0x00}},
960 {"jo", {0xbc, 0xde, 0xae, 0x00}},
961 {"ka", {0xb6, 0x00}},
962 {"ki", {0xb7, 0x00}},
963 {"ku", {0xb8, 0x00}},
964 {"ke", {0xb9, 0x00}},
965 {"ko", {0xba, 0x00}},
966 {"la", {0xa7, 0x00}},
967 {"li", {0xa8, 0x00}},
968 {"lu", {0xa9, 0x00}},
969 {"le", {0xaa, 0x00}},
970 {"lo", {0xab, 0x00}},
971 {"ma", {0xcf, 0x00}},
972 {"mi", {0xd0, 0x00}},
973 {"mu", {0xd1, 0x00}},
974 {"me", {0xd2, 0x00}},
975 {"mo", {0xd3, 0x00}},
976 {"na", {0xc5, 0x00}},
977 {"ni", {0xc6, 0x00}},
978 {"nu", {0xc7, 0x00}},
979 {"ne", {0xc8, 0x00}},
980 {"no", {0xc9, 0x00}},
981 // {"nn", {0xdd, 0x00}},
982 {"pa", {0xca, 0xdf, 0x00}},
983 {"pi", {0xcb, 0xdf, 0x00}},
984 {"pu", {0xcc, 0xdf, 0x00}},
985 {"pe", {0xcd, 0xdf, 0x00}},
986 {"po", {0xce, 0xdf, 0x00}},
987 {"qa", {0xb8, 0xa7, 0x00}},
988 {"qi", {0xb8, 0xa8, 0x00}},
989 {"qu", {0xb8, 0x00}},
990 {"qe", {0xb8, 0xaa, 0x00}},
991 {"qo", {0xb8, 0xab, 0x00}},
992 {"ra", {0xd7, 0x00}},
993 {"ri", {0xd8, 0x00}},
994 {"ru", {0xd9, 0x00}},
995 {"re", {0xda, 0x00}},
996 {"ro", {0xdb, 0x00}},
997 {"sa", {0xbb, 0x00}},
998 {"si", {0xbc, 0x00}},
999 {"su", {0xbd, 0x00}},
1000 {"se", {0xbe, 0x00}},
1001 {"so", {0xbf, 0x00}},
1002 {"ta", {0xc0, 0x00}},
1003 {"ti", {0xc1, 0x00}},
1004 {"tu", {0xc2, 0x00}},
1005 {"te", {0xc3, 0x00}},
1006 {"to", {0xc4, 0x00}},
1007 {"va", {0xb3, 0xde, 0xa7, 0x00}},
1008 {"vi", {0xb3, 0xde, 0xa8, 0x00}},
1009 {"vu", {0xb3, 0xde, 0x00}},
1010 {"ve", {0xb3, 0xde, 0xaa, 0x00}},
1011 {"vo", {0xb3, 0xde, 0xab, 0x00}},
1012 {"wa", {0xdc, 0x00}},
1013 {"wi", {0xb3, 0xa8, 0x00}},
1014 {"wu", {0xb3, 0x00}},
1015 {"we", {0xb3, 0xaa, 0x00}},
1016 {"wo", {0xa6, 0x00}},
1017 {"xa", {0xa7, 0x00}},
1018 {"xi", {0xa8, 0x00}},
1019 {"xu", {0xa9, 0x00}},
1020 {"xe", {0xaa, 0x00}},
1021 {"xo", {0xab, 0x00}},
1022 {"ya", {0xd4, 0x00}},
1023 {"yi", {0xb2, 0x00}},
1024 {"yu", {0xd5, 0x00}},
1025 {"ye", {0xb2, 0xaa, 0x00}},
1026 {"yo", {0xd6, 0x00}},
1027 {"za", {0xbb, 0xde, 0x00}},
1028 {"zi", {0xbc, 0xde, 0x00}},
1029 {"zu", {0xbd, 0xde, 0x00}},
1030 {"ze", {0xbe, 0xde, 0x00}},
1031 {"zo", {0xbf, 0xde, 0x00}},
1032 {"a", {0xb1, 0x00}},
1033 {"i", {0xb2, 0x00}},
1034 {"u", {0xb3, 0x00}},
1035 {"e", {0xb4, 0x00}},
1036 {"o", {0xb5, 0x00}},
1037 {"[", {0xa2, 0x00}},
1038 {"]", {0xa3, 0x00}},
1039 {"-", {0xb0, 0x00}},
1040 {",", {0xa4, 0x00}},
1041 {".", {0xa1, 0x00}},
1042 {"/", {0xa5, 0x00}},
1046 void EMU::initialize_auto_key()
1048 auto_key_buffer = new FIFO(65536);
1049 auto_key_buffer->clear();
1050 auto_key_phase = auto_key_shift = 0;
1051 shift_pressed = false;
1052 osd->now_auto_key = false;
1055 void EMU::release_auto_key()
1057 if(auto_key_buffer) {
1058 auto_key_buffer->release();
1059 delete auto_key_buffer;
1063 int EMU::get_auto_key_code(int code)
1065 static int auto_key_table[256];
1066 static bool initialized = false;
1067 #ifdef USE_KEYBOARD_TYPE
1068 static int keyboard_type = -1;
1070 if(keyboard_type != config.keyboard_type) {
1071 initialized = false;
1072 keyboard_type = config.keyboard_type;
1076 memset(auto_key_table, 0, sizeof(auto_key_table));
1077 for(int i = 0;; i++) {
1078 if(auto_key_table_base[i][0] == -1) {
1081 auto_key_table[auto_key_table_base[i][0]] = auto_key_table_base[i][1];
1083 #if defined(_X1TURBO) || defined(_X1TURBOZ)
1085 if(config.keyboard_type) {
1086 for(int i = 0;; i++) {
1087 if(auto_key_table_50on_base[i][0] == -1) {
1090 auto_key_table[auto_key_table_50on_base[i][0]] = auto_key_table_50on_base[i][1];
1094 for(int i = 0;; i++) {
1095 if(auto_key_table_kana_base[i][0] == -1) {
1098 auto_key_table[auto_key_table_kana_base[i][0]] = auto_key_table_kana_base[i][1];
1100 #ifdef USE_VM_AUTO_KEY_TABLE
1101 for(int i = 0;; i++) {
1102 if(vm_auto_key_table_base[i][0] == -1) {
1105 auto_key_table[vm_auto_key_table_base[i][0]] = vm_auto_key_table_base[i][1];
1110 return auto_key_table[code];
1113 void EMU::set_auto_key_code(int code)
1115 if(code == 0xf2 || (code = get_auto_key_code(code)) != 0) {
1116 if(code == 0x08 || code == 0x09 || code == 0x0d || code == 0x1b || code == 0x20 || code == 0xf2) {
1117 // VK_BACK, VK_TAB, VK_RETURN, VK_ESCAPE, VK_SPACE, VK_OEM_COPY(Katakana/Hiragana)
1118 auto_key_buffer->write(code);
1119 #ifdef USE_AUTO_KEY_NUMPAD
1120 } else if(code >= 0x30 && code <= 0x39) {
1122 auto_key_buffer->write(code - 0x30 + 0x60);
1124 } else if(code & 0x200) {
1126 auto_key_buffer->write(code & 0x1ff);
1128 // ank other than alphabet and kana
1129 auto_key_buffer->write(0xf2); // kana unlock
1130 auto_key_buffer->write(code & 0x1ff);
1131 auto_key_buffer->write(0xf2); // kana lock
1133 if(!is_auto_key_running()) {
1139 void EMU::set_auto_key_list(char *buf, int size)
1141 #if defined(USE_KEY_LOCKED)
1142 bool prev_caps = get_caps_locked();
1143 bool prev_kana = get_kana_locked();
1145 bool prev_caps = false;
1146 bool prev_kana = false;
1148 auto_key_buffer->clear();
1150 for(int i = 0; i < size; i++) {
1151 int code = buf[i] & 0xff;
1152 if((0x81 <= code && code <= 0x9f) || 0xe0 <= code) {
1155 } else if(code == 0x0a) {
1158 if((code = get_auto_key_code(code)) != 0) {
1160 bool kana = ((code & 0x200) != 0);
1161 if(prev_kana != kana) {
1162 auto_key_buffer->write(0xf2);
1165 #if defined(USE_AUTO_KEY_CAPS_LOCK)
1166 // use caps lock key to switch uppercase/lowercase of alphabet
1167 // USE_AUTO_KEY_CAPS_LOCK shows the caps lock key code
1168 bool caps = ((code & 0x400) != 0);
1169 if(prev_caps != caps) {
1170 auto_key_buffer->write(USE_AUTO_KEY_CAPS_LOCK);
1174 #if defined(USE_AUTO_KEY_CAPS_LOCK) || defined(USE_AUTO_KEY_NO_CAPS)
1175 code &= ~(0x400 | 0x800); // don't press shift key for both alphabet and ALPHABET
1176 #elif defined(USE_KEY_LOCKED)
1177 if(get_caps_locked()) {
1178 code &= ~0x400; // don't press shift key for ALPHABET
1180 code &= ~0x800; // don't press shift key for alphabet
1182 #elif defined(USE_AUTO_KEY_CAPS)
1183 code &= ~0x400; // don't press shift key for ALPHABET
1185 code &= ~0x800; // don't press shift key for alphabet
1187 if(code & (0x100 | 0x400 | 0x800)) {
1188 auto_key_buffer->write((code & 0xff) | 0x100);
1190 auto_key_buffer->write(code & 0xff);
1194 // release kana lock
1196 auto_key_buffer->write(0xf2);
1198 #if defined(USE_AUTO_KEY_CAPS_LOCK)
1199 // release caps lock
1201 auto_key_buffer->write(USE_AUTO_KEY_CAPS_LOCK);
1206 bool is_alphabet(char code)
1208 return (code >= 'a' && code <= 'z');
1211 bool is_vowel(char code)
1213 return (code == 'a' || code == 'i' || code == 'u' || code == 'e' || code == 'o');
1216 bool is_consonant(char code)
1218 return (is_alphabet(code) && !is_vowel(code));
1221 void EMU::set_auto_key_char(char code)
1223 static char codes[5] = {0};
1226 #ifdef USE_KEY_LOCKED
1227 if(!get_kana_locked())
1229 set_auto_key_code(0xf2);
1230 memset(codes, 0, sizeof(codes));
1231 } else if(code == 0) {
1233 if(codes[3] == 'n') {
1234 set_auto_key_code(0xdd); // 'Ý'
1236 set_auto_key_code(0xf2);
1237 memset(codes, 0, sizeof(codes));
1238 } else if(code == 0x08 || code == 0x09 || code == 0x0d || code == 0x1b || code == 0x20) {
1239 if(codes[3] == 'n') {
1240 set_auto_key_code(0xdd); // 'Ý'
1242 set_auto_key_code(code);
1243 memset(codes, 0, sizeof(codes));
1244 #ifdef USE_AUTO_KEY_NUMPAD
1245 } else if(code >= 0x30 && code <= 0x39) {
1246 if(codes[3] == 'n') {
1247 set_auto_key_code(0xdd); // 'Ý'
1249 set_auto_key_code(code);
1250 memset(codes, 0, sizeof(codes));
1253 codes[0] = codes[1];
1254 codes[1] = codes[2];
1255 codes[2] = codes[3];
1256 codes[3] = (code >= 'A' && code <= 'Z') ? ('a' + (code - 'A')) : code;
1259 if(codes[2] == 'n' && !is_vowel(codes[3])) {
1260 set_auto_key_code(0xdd); // 'Ý'
1261 if(codes[3] == 'n') {
1262 memset(codes, 0, sizeof(codes));
1265 } else if(codes[2] == codes[3] && is_consonant(codes[3])) {
1266 set_auto_key_code(0xaf); // '¯'
1269 for(int i = 0;; i++) {
1270 int len = strlen(romaji_table[i].romaji), comp = -1;
1273 if(!is_alphabet(codes[3])) {
1274 set_auto_key_code(codes[3]);
1275 memset(codes, 0, sizeof(codes));
1278 } else if(len == 1) {
1279 comp = strcmp(romaji_table[i].romaji, &codes[3]);
1280 } else if(len == 2) {
1281 comp = strcmp(romaji_table[i].romaji, &codes[2]);
1282 } else if(len == 3) {
1283 comp = strcmp(romaji_table[i].romaji, &codes[1]);
1284 } else if(len == 4) {
1285 comp = strcmp(romaji_table[i].romaji, &codes[0]);
1288 for(int j = 0; j < 4; j++) {
1289 if(!romaji_table[i].kana[j]) {
1293 bool handakuon_found = false;
1294 bool dakuon_found = false;
1295 #if defined(USE_TWO_STROKE_AUTOKEY_HANDAKUON)
1296 if(romaji_table[i].kana[1] == 0xdf) {
1298 for(int jj = 0;;jj++) {
1299 if(kana_handakuon_keyboard_table[jj][0] == -1) break;
1300 if(kana_handakuon_keyboard_table[jj][0] == romaji_table[i].kana[0]) {
1301 for(int l = 1; l < 6; l++) {
1302 if(kana_handakuon_keyboard_table[jj][l] == 0x00) break;
1303 auto_key_buffer->write(kana_handakuon_keyboard_table[jj][l] & 0x31ff);
1304 if(!is_auto_key_running()) {
1309 handakuon_found = true;
1315 #if defined(USE_TWO_STROKE_AUTOKEY_DAKUON)
1316 if(romaji_table[i].kana[1] == 0xde) {
1318 for(int jj = 0;;jj++) {
1319 if(kana_dakuon_keyboard_table[jj][0] == -1) break;
1320 if(kana_dakuon_keyboard_table[jj][0] == romaji_table[i].kana[0]) {
1321 for(int l = 1; l < 6; l++) {
1322 if(kana_dakuon_keyboard_table[jj][l] == 0x00) break;
1323 auto_key_buffer->write(kana_dakuon_keyboard_table[jj][l] & 0x31ff);
1324 if(!is_auto_key_running()) {
1329 dakuon_found = true;
1335 if((handakuon_found) || (dakuon_found)) {
1336 // if(!romaji_table[i].kana[j]) {
1342 set_auto_key_code(romaji_table[i].kana[j]);
1344 memset(codes, 0, sizeof(codes));
1351 void EMU::start_auto_key()
1355 osd->now_auto_key = true;
1358 void EMU::stop_auto_key()
1360 if(auto_key_shift) {
1361 osd->key_up_native(VK_LSHIFT);
1363 auto_key_phase = auto_key_shift = 0;
1364 osd->now_auto_key = false;
1367 #ifndef USE_AUTO_KEY_SHIFT
1368 #define USE_AUTO_KEY_SHIFT 0
1371 #define VK_LSHIFT 0xA0
1374 void EMU::update_auto_key()
1376 switch(auto_key_phase) {
1378 if(auto_key_buffer && !auto_key_buffer->empty()) {
1379 // update shift key status
1380 int shift = auto_key_buffer->read_not_remove(0) & 0x100;
1381 if(shift && !auto_key_shift) {
1382 osd->key_down_native(VK_LSHIFT, false);
1383 } else if(!shift && auto_key_shift) {
1384 osd->key_up_native(VK_LSHIFT);
1386 auto_key_shift = shift;
1390 case 3 + USE_AUTO_KEY_SHIFT:
1391 if(auto_key_buffer && !auto_key_buffer->empty()) {
1392 if(!(auto_key_buffer->read_not_remove(0) & 0x2000)) {
1393 osd->key_down_native(auto_key_buffer->read_not_remove(0) & 0xff, false);
1398 case USE_AUTO_KEY + USE_AUTO_KEY_SHIFT:
1399 if(auto_key_buffer && !auto_key_buffer->empty()) {
1400 if(!(auto_key_buffer->read_not_remove(0) & 0x1000)) {
1401 osd->key_up_native(auto_key_buffer->read_not_remove(0) & 0xff);
1406 case USE_AUTO_KEY_RELEASE + USE_AUTO_KEY_SHIFT:
1407 if(auto_key_buffer && !auto_key_buffer->empty()) {
1408 // wait enough while vm analyzes one line
1409 if(auto_key_buffer->read() == 0xd) {
1415 if(auto_key_buffer && !auto_key_buffer->empty()) {
1422 if(auto_key_phase) {
1430 void EMU::update_joystick()
1432 uint32_t *joy_buffer = osd->get_joy_buffer();
1433 uint8_t *key_buffer = osd->get_key_buffer();
1435 memset(joy_status, 0, sizeof(joy_status));
1437 for(int i = 0; i < 4; i++) {
1438 for(int j = 0; j < 16; j++) {
1439 if(config.joy_buttons[i][j] < 0) {
1440 int code = -config.joy_buttons[i][j];
1441 if(code < 256 && key_buffer[code]) {
1442 joy_status[i] |= (1 << j);
1443 //printf("%d %d %02x %02x\n", i, j, config.joy_buttons[i][j], joy_status[i]);
1446 int stick = config.joy_buttons[i][j] >> 5;
1447 int button = config.joy_buttons[i][j] & 0x1f;
1448 if(stick < 4 && (joy_buffer[stick & 3] & (1 << button))) {
1449 joy_status[i] |= (1 << j);
1450 //printf("%d %d %02x %02x\n", i, j, config.joy_buttons[i][j], joy_status[i]);
1458 const uint8_t* EMU::get_key_buffer()
1460 return (const uint8_t*)osd->get_key_buffer();
1464 const uint32_t* EMU::get_joy_buffer()
1466 return (const uint32_t*)joy_status;
1471 const int32_t* EMU::get_mouse_buffer()
1473 return (const int32_t*)osd->get_mouse_buffer();
1477 // ----------------------------------------------------------------------------
1479 // ----------------------------------------------------------------------------
1481 double EMU::get_window_mode_power(int mode)
1483 return osd->get_window_mode_power(mode);
1486 int EMU::get_window_mode_width(int mode)
1488 return osd->get_window_mode_width(mode);
1491 int EMU::get_window_mode_height(int mode)
1493 return osd->get_window_mode_height(mode);
1496 void EMU::set_host_window_size(int window_width, int window_height, bool window_mode)
1498 osd->set_host_window_size(window_width, window_height, window_mode);
1501 void EMU::set_vm_screen_size(int screen_width, int screen_height, int window_width, int window_height, int window_width_aspect, int window_height_aspect)
1503 osd->set_vm_screen_size(screen_width, screen_height, window_width, window_height, window_width_aspect, window_height_aspect);
1506 void EMU::set_vm_screen_lines(int lines)
1508 osd->set_vm_screen_lines(lines);
1512 int EMU::get_vm_window_width()
1514 return osd->get_vm_window_width();
1517 int EMU::get_vm_window_height()
1519 return osd->get_vm_window_height();
1522 int EMU::get_vm_window_width_aspect()
1524 return osd->get_vm_window_width_aspect();
1527 int EMU::get_vm_window_height_aspect()
1529 return osd->get_vm_window_height_aspect();
1532 #if defined(USE_MINIMUM_RENDERING)
1533 bool EMU::is_screen_changed()
1535 return vm->is_screen_changed();
1539 int EMU::draw_screen()
1541 #ifdef ONE_BOARD_MICRO_COMPUTER
1542 if(now_waiting_in_debugger) {
1543 osd->reload_bitmap();
1546 return osd->draw_screen();
1549 scrntype_t* EMU::get_screen_buffer(int y)
1551 return osd->get_vm_screen_buffer(y);
1554 #ifdef USE_SCREEN_FILTER
1555 void EMU::screen_skip_line(bool skip_line)
1557 osd->screen_skip_line = skip_line;
1561 #ifdef ONE_BOARD_MICRO_COMPUTER
1562 void EMU::get_invalidated_rect(int *left, int *top, int *right, int *bottom)
1564 #ifdef MAX_DRAW_RANGES
1565 for(int i = 0; i < MAX_DRAW_RANGES; i++) {
1567 for(int i = 0; i < vm->max_draw_ranges(); i++) { // for TK-80BS
1569 int x1 = vm_ranges[i].x;
1570 int y1 = vm_ranges[i].y;
1571 int x2 = x1 + vm_ranges[i].width;
1572 int y2 = y1 + vm_ranges[i].height;
1574 *left = (i == 0) ? x1 : min(x1, *left );
1575 *top = (i == 0) ? y1 : min(y1, *top );
1576 *right = (i == 0) ? x2 : max(x2, *right );
1577 *bottom = (i == 0) ? y2 : max(y2, *bottom);
1581 void EMU::reload_bitmap()
1583 osd->reload_bitmap();
1588 void EMU::invalidate_screen()
1590 osd->invalidate_screen();
1593 void EMU::update_screen(HDC hdc)
1595 osd->update_screen(hdc);
1599 void EMU::capture_screen()
1601 osd->capture_screen();
1604 bool EMU::start_record_video(int fps)
1606 return osd->start_record_video(fps);
1609 void EMU::stop_record_video()
1611 osd->stop_record_video();
1614 bool EMU::is_video_recording()
1616 return osd->now_record_video;
1619 // ----------------------------------------------------------------------------
1621 // ----------------------------------------------------------------------------
1623 void EMU::mute_sound()
1628 void EMU::start_record_sound()
1630 osd->start_record_sound();
1633 void EMU::stop_record_sound()
1635 osd->stop_record_sound();
1638 bool EMU::is_sound_recording()
1640 return osd->now_record_sound;
1643 // ----------------------------------------------------------------------------
1645 // ----------------------------------------------------------------------------
1647 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
1648 void EMU::get_video_buffer()
1650 osd->get_video_buffer();
1653 void EMU::mute_video_dev(bool l, bool r)
1655 osd->mute_video_dev(l, r);
1659 #ifdef USE_MOVIE_PLAYER
1660 bool EMU::open_movie_file(const _TCHAR* file_path)
1662 return osd->open_movie_file(file_path);
1665 void EMU::close_movie_file()
1667 osd->close_movie_file();
1670 void EMU::play_movie()
1675 void EMU::stop_movie()
1680 void EMU::pause_movie()
1685 double EMU::get_movie_frame_rate()
1687 return osd->get_movie_frame_rate();
1690 int EMU::get_movie_sound_rate()
1692 return osd->get_movie_sound_rate();
1695 void EMU::set_cur_movie_frame(int frame, bool relative)
1697 osd->set_cur_movie_frame(frame, relative);
1700 uint32_t EMU::get_cur_movie_frame()
1702 return osd->get_cur_movie_frame();
1706 #ifdef USE_VIDEO_CAPTURE
1707 int EMU::get_cur_capture_dev_index()
1709 return osd->get_cur_capture_dev_index();
1712 int EMU::get_num_capture_devs()
1714 return osd->get_num_capture_devs();
1717 _TCHAR* EMU::get_capture_dev_name(int index)
1719 return osd->get_capture_dev_name(index);
1722 void EMU::open_capture_dev(int index, bool pin)
1724 osd->open_capture_dev(index, pin);
1727 void EMU::close_capture_dev()
1729 osd->close_capture_dev();
1732 void EMU::show_capture_dev_filter()
1734 osd->show_capture_dev_filter();
1737 void EMU::show_capture_dev_pin()
1739 osd->show_capture_dev_pin();
1742 void EMU::show_capture_dev_source()
1744 osd->show_capture_dev_source();
1747 void EMU::set_capture_dev_channel(int ch)
1749 osd->set_capture_dev_channel(ch);
1753 // ----------------------------------------------------------------------------
1755 // ----------------------------------------------------------------------------
1758 void EMU::create_bitmap(bitmap_t *bitmap, int width, int height)
1760 osd->create_bitmap(bitmap, width, height);
1763 void EMU::release_bitmap(bitmap_t *bitmap)
1765 osd->release_bitmap(bitmap);
1768 void EMU::create_font(font_t *font, const _TCHAR *family, int width, int height, int rotate, bool bold, bool italic)
1770 osd->create_font(font, family, width, height, rotate, bold, italic);
1773 void EMU::release_font(font_t *font)
1775 osd->release_font(font);
1778 void EMU::create_pen(pen_t *pen, int width, uint8_t r, uint8_t g, uint8_t b)
1780 osd->create_pen(pen, width, r, g, b);
1783 void EMU::release_pen(pen_t *pen)
1785 osd->release_pen(pen);
1788 void EMU::clear_bitmap(bitmap_t *bitmap, uint8_t r, uint8_t g, uint8_t b)
1790 osd->clear_bitmap(bitmap, r, g, b);
1793 int EMU::get_text_width(bitmap_t *bitmap, font_t *font, const char *text)
1795 return osd->get_text_width(bitmap, font, text);
1798 void EMU::draw_text_to_bitmap(bitmap_t *bitmap, font_t *font, int x, int y, const char *text, uint8_t r, uint8_t g, uint8_t b)
1800 osd->draw_text_to_bitmap(bitmap, font, x, y, text, r, g, b);
1803 void EMU::draw_line_to_bitmap(bitmap_t *bitmap, pen_t *pen, int sx, int sy, int ex, int ey)
1805 osd->draw_line_to_bitmap(bitmap, pen, sx, sy, ex, ey);
1808 void EMU::draw_rectangle_to_bitmap(bitmap_t *bitmap, int x, int y, int width, int height, uint8_t r, uint8_t g, uint8_t b)
1810 osd->draw_rectangle_to_bitmap(bitmap, x, y, width, height, r, g, b);
1813 void EMU::draw_point_to_bitmap(bitmap_t *bitmap, int x, int y, uint8_t r, uint8_t g, uint8_t b)
1815 osd->draw_point_to_bitmap(bitmap, x, y, r, g, b);
1818 void EMU::stretch_bitmap(bitmap_t *dest, int dest_x, int dest_y, int dest_width, int dest_height, bitmap_t *source, int source_x, int source_y, int source_width, int source_height)
1820 osd->stretch_bitmap(dest, dest_x, dest_y, dest_width, dest_height, source, source_x, source_y, source_width, source_height);
1823 void EMU::write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path)
1825 osd->write_bitmap_to_file(bitmap, file_path);
1829 // ----------------------------------------------------------------------------
1831 // ----------------------------------------------------------------------------
1834 int EMU::get_socket(int ch)
1836 return osd->get_socket(ch);
1839 void EMU::notify_socket_connected(int ch)
1841 osd->notify_socket_connected(ch);
1844 void EMU::notify_socket_disconnected(int ch)
1846 osd->notify_socket_disconnected(ch);
1849 bool EMU::initialize_socket_tcp(int ch)
1851 return osd->initialize_socket_tcp(ch);
1854 bool EMU::initialize_socket_udp(int ch)
1856 return osd->initialize_socket_udp(ch);
1859 bool EMU::connect_socket(int ch, uint32_t ipaddr, int port)
1861 return osd->connect_socket(ch, ipaddr, port);
1864 void EMU::disconnect_socket(int ch)
1866 osd->disconnect_socket(ch);
1869 bool EMU::listen_socket(int ch)
1871 return osd->listen_socket(ch);
1874 void EMU::send_socket_data_tcp(int ch)
1876 osd->send_socket_data_tcp(ch);
1879 void EMU::send_socket_data_udp(int ch, uint32_t ipaddr, int port)
1881 osd->send_socket_data_udp(ch, ipaddr, port);
1884 void EMU::send_socket_data(int ch)
1886 osd->send_socket_data(ch);
1889 void EMU::recv_socket_data(int ch)
1891 osd->recv_socket_data(ch);
1895 // ---------------------------------------------------------------------------
1896 // debugger (some functions needed by libCSPcommon_vm 20190221 K.O)
1897 // ---------------------------------------------------------------------------
1899 void EMU::start_waiting_in_debugger()
1902 now_waiting_in_debugger = true;
1906 osd->start_waiting_in_debugger();
1910 void EMU::finish_waiting_in_debugger()
1913 osd->finish_waiting_in_debugger();
1914 now_waiting_in_debugger = false;
1918 void EMU::process_waiting_in_debugger()
1921 osd->process_waiting_in_debugger();
1927 // ----------------------------------------------------------------------------
1929 // ----------------------------------------------------------------------------
1932 void EMU::initialize_debug_log()
1934 _TCHAR path[_MAX_PATH];
1935 debug_log = _tfopen(create_date_file_path(_T("log")), _T("w"));
1938 void EMU::release_debug_log()
1948 static _TCHAR prev_buffer[1024] = {0};
1951 void EMU::out_debug_log(const _TCHAR* format, ...)
1953 common_initialize();
1957 _TCHAR buffer[1024];
1959 va_start(ap, format);
1960 my_vstprintf_s(buffer, 1024, format, ap);
1963 if(_tcscmp(prev_buffer, buffer) == 0) {
1966 my_tcscpy_s(prev_buffer, 1024, buffer);
1968 #if defined(_USE_QT) || defined(_USE_AGAR) || defined(_USE_SDL)
1969 csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_EMU, "%s", buffer);
1972 _ftprintf(debug_log, _T("%s"), buffer);
1973 static int size = 0;
1974 if((size += _tcslen(buffer)) > 0x8000000) { // 128MB
1976 debug_log = _tfopen(create_date_file_path(_T("log")), _T("w"));
1984 void EMU::force_out_debug_log(const _TCHAR* format, ...)
1988 _TCHAR buffer[1024];
1990 va_start(ap, format);
1991 my_vstprintf_s(buffer, 1024, format, ap);
1993 my_tcscpy_s(prev_buffer, 1024, buffer);
1995 #if defined(_USE_QT) || defined(_USE_AGAR) || defined(_USE_SDL)
1996 csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_EMU, "%s", buffer);
1999 _ftprintf(debug_log, _T("%s"), buffer);
2000 static int size = 0;
2001 if((size += _tcslen(buffer)) > 0x8000000) { // 128MB
2003 debug_log = _tfopen(create_date_file_path(_T("log")), _T("w"));
2011 void EMU::out_message(const _TCHAR* format, ...)
2013 //#if defined(_USE_QT)
2014 // _TCHAR mes_buf[1024];
2017 va_start(ap, format);
2018 my_vstprintf_s(message, 1024, format, ap); // Security for MSVC:C6386.
2019 //#if defined(_USE_QT)
2020 // memset(mes_buf, 0x00, sizeof(mes_buf));
2021 // my_vstprintf_s(mes_buf, 1024, format, ap); // Security for MSVC:C6386.
2022 // csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_EMU, "%s", mes_buf);
2025 message_count = 4; // 4sec
2028 // ----------------------------------------------------------------------------
2030 // ----------------------------------------------------------------------------
2033 void EMU::sleep(uint32_t ms)
2039 // ----------------------------------------------------------------------------
2041 // ----------------------------------------------------------------------------
2043 static uint8_t hex2uint8(char *value)
2046 memset(tmp, 0, sizeof(tmp));
2047 memcpy(tmp, value, 2);
2048 return (uint8_t)strtoul(tmp, NULL, 16);
2051 static uint16_t hex2uint16(char *value)
2054 memset(tmp, 0, sizeof(tmp));
2055 memcpy(tmp, value, 4);
2056 return (uint16_t)strtoul(tmp, NULL, 16);
2059 static bool hex2bin(const _TCHAR* file_path, const _TCHAR* dest_path)
2061 bool result = false;
2062 FILEIO *fio_s = new FILEIO();
2063 if(fio_s->Fopen(file_path, FILEIO_READ_BINARY)) {
2066 uint8_t buffer[0x10000];
2067 memset(buffer, 0xff, sizeof(buffer));
2068 while(fio_s->Fgets(line, sizeof(line)) != NULL) {
2069 if(line[0] != ':') continue;
2070 int bytes = hex2uint8(line + 1);
2071 int offset = hex2uint16(line + 3);
2072 uint8_t record_type = hex2uint8(line + 7);
2073 if(record_type == 0x01) break;
2074 if(record_type != 0x00) continue;
2075 for(int i = 0; i < bytes; i++) {
2076 if((offset + i) < (int)sizeof(buffer)) {
2077 if(length < (offset + i)) {
2078 length = offset + i;
2080 buffer[offset + i] = hex2uint8(line + 9 + 2 * i);
2085 FILEIO *fio_d = new FILEIO();
2086 if(fio_d->Fopen(dest_path, FILEIO_WRITE_BINARY)) {
2087 fio_d->Fwrite(buffer, length, 1);
2099 void EMU::initialize_media()
2102 memset(&cart_status, 0, sizeof(cart_status));
2104 #ifdef USE_FLOPPY_DISK
2105 memset(floppy_disk_status, 0, sizeof(floppy_disk_status));
2107 #ifdef USE_QUICK_DISK
2108 memset(&quick_disk_status, 0, sizeof(quick_disk_status));
2110 #ifdef USE_HARD_DISK
2111 memset(&hard_disk_status, 0, sizeof(hard_disk_status));
2114 memset(&tape_status, 0, sizeof(tape_status));
2116 #ifdef USE_COMPACT_DISC
2117 memset(&compact_disc_status, 0, sizeof(compact_disc_status));
2119 #ifdef USE_LASER_DISC
2120 memset(&laser_disc_status, 0, sizeof(laser_disc_status));
2123 memset(&bubble_casette_status, 0, sizeof(bubble_casette_status));
2128 void EMU::update_media()
2130 #ifdef USE_FLOPPY_DISK
2131 for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) {
2132 if(floppy_disk_status[drv].wait_count != 0 && --floppy_disk_status[drv].wait_count == 0) {
2133 vm->open_floppy_disk(drv, floppy_disk_status[drv].path, floppy_disk_status[drv].bank);
2134 #if USE_FLOPPY_DISK > 1
2135 out_message(_T("FD%d: %s"), drv + BASE_FLOPPY_DISK_NUM, floppy_disk_status[drv].path);
2137 out_message(_T("FD: %s"), floppy_disk_status[drv].path);
2142 #ifdef USE_QUICK_DISK
2143 for(int drv = 0; drv < USE_QUICK_DISK; drv++) {
2144 if(quick_disk_status[drv].wait_count != 0 && --quick_disk_status[drv].wait_count == 0) {
2145 vm->open_quick_disk(drv, quick_disk_status[drv].path);
2146 #if USE_QUICK_DISK > 1
2147 out_message(_T("QD%d: %s"), drv + BASE_QUICK_DISK_NUM, quick_disk_status[drv].path);
2149 out_message(_T("QD: %s"), quick_disk_status[drv].path);
2154 #ifdef USE_HARD_DISK
2155 for(int drv = 0; drv < USE_HARD_DISK; drv++) {
2156 if(hard_disk_status[drv].wait_count != 0 && --hard_disk_status[drv].wait_count == 0) {
2157 vm->open_hard_disk(drv, hard_disk_status[drv].path);
2158 #if USE_HARD_DISK > 1
2159 out_message(_T("HD%d: %s"), drv + BASE_HARD_DISK_NUM, hard_disk_status[drv].path);
2161 out_message(_T("HD: %s"), hard_disk_status[drv].path);
2167 for(int drv = 0; drv < USE_TAPE; drv++) {
2168 if(tape_status[drv].wait_count != 0 && --tape_status[drv].wait_count == 0) {
2169 if(tape_status[drv].play) {
2170 vm->play_tape(drv, tape_status[drv].path);
2172 vm->rec_tape(drv, tape_status[drv].path);
2175 out_message(_T("CMT%d: %s"), drv + BASE_TAPE_NUM, tape_status[drv].path);
2177 out_message(_T("CMT: %s"), tape_status[drv].path);
2182 #ifdef USE_COMPACT_DISC
2183 for(int drv = 0; drv < USE_COMPACT_DISC; drv++) {
2184 if(compact_disc_status[drv].wait_count != 0 && --compact_disc_status[drv].wait_count == 0) {
2185 vm->open_compact_disc(drv, compact_disc_status[drv].path);
2186 #if USE_COMPACT_DISC > 1
2187 out_message(_T("CD%d: %s"), drv + BASE_COMPACT_DISC_NUM, compact_disc_status[drv].path);
2189 out_message(_T("CD: %s"), compact_disc_status[drv].path);
2194 #ifdef USE_LASER_DISC
2195 for(int drv = 0; drv < USE_LASER_DISC; drv++) {
2196 if(laser_disc_status[drv].wait_count != 0 && --laser_disc_status[drv].wait_count == 0) {
2197 vm->open_laser_disc(drv, laser_disc_status[drv].path);
2198 #if USE_LASER_DISC > 1
2199 out_message(_T("LD%d: %s"), drv + BASE_LASER_DISC_NUM, laser_disc_status[drv].path);
2201 out_message(_T("LD: %s"), laser_disc_status[drv].path);
2207 for(int drv = 0; drv < USE_BUBBLE; drv++) {
2208 if(bubble_casette_status[drv].wait_count != 0 && --bubble_casette_status[drv].wait_count == 0) {
2209 vm->open_bubble_casette(drv, bubble_casette_status[drv].path, bubble_casette_status[drv].bank);
2211 out_message(_T("Bubble%d: %s"), drv + BASE_BUBBLE_NUM, bubble_casette_status[drv].path);
2213 out_message(_T("Bubble: %s"), bubble_casette_status[drv].path);
2220 void EMU::restore_media()
2223 for(int drv = 0; drv < USE_CART; drv++) {
2224 if(cart_status[drv].path[0] != _T('\0')) {
2225 if(check_file_extension(cart_status[drv].path, _T(".hex")) && hex2bin(cart_status[drv].path, create_local_path(_T("hex2bin.$$$")))) {
2226 vm->open_cart(drv, create_local_path(_T("hex2bin.$$$")));
2227 FILEIO::RemoveFile(create_local_path(_T("hex2bin.$$$")));
2229 vm->open_cart(drv, cart_status[drv].path);
2234 #ifdef USE_FLOPPY_DISK
2235 for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) {
2236 if(floppy_disk_status[drv].path[0] != _T('\0')) {
2237 vm->open_floppy_disk(drv, floppy_disk_status[drv].path, floppy_disk_status[drv].bank);
2241 #ifdef USE_QUICK_DISK
2242 for(int drv = 0; drv < USE_QUICK_DISK; drv++) {
2243 if(quick_disk_status[drv].path[0] != _T('\0')) {
2244 vm->open_quick_disk(drv, quick_disk_status[drv].path);
2248 #ifdef USE_HARD_DISK
2249 for(int drv = 0; drv < USE_HARD_DISK; drv++) {
2250 if(hard_disk_status[drv].path[0] != _T('\0')) {
2251 vm->open_hard_disk(drv, hard_disk_status[drv].path);
2256 for(int drv = 0; drv < USE_TAPE; drv++) {
2257 if(tape_status[drv].path[0] != _T('\0')) {
2258 if(tape_status[drv].play) {
2259 vm->play_tape(drv, tape_status[drv].path);
2261 tape_status[drv].path[0] = _T('\0');
2266 #ifdef USE_COMPACT_DISC
2267 for(int drv = 0; drv < USE_COMPACT_DISC; drv++) {
2268 if(compact_disc_status[drv].path[0] != _T('\0')) {
2269 vm->open_compact_disc(drv, compact_disc_status[drv].path);
2273 #ifdef USE_LASER_DISC
2274 for(int drv = 0; drv < USE_LASER_DISC; drv++) {
2275 if(laser_disc_status[drv].path[0] != _T('\0')) {
2276 vm->open_laser_disc(drv, laser_disc_status[drv].path);
2281 for(int drv = 0; drv < USE_BUBBLE; drv++) {
2282 if(bubble_casette_status[drv].path[0] != _T('\0')) {
2283 vm->open_bubble_casette(drv, bubble_casette_status[drv].path, bubble_casette_status[drv].bank);
2290 void EMU::open_cart(int drv, const _TCHAR* file_path)
2292 if(drv < USE_CART) {
2293 if(check_file_extension(file_path, _T(".hex")) && hex2bin(file_path, create_local_path(_T("hex2bin.$$$")))) {
2294 vm->open_cart(drv, create_local_path(_T("hex2bin.$$$")));
2295 FILEIO::RemoveFile(create_local_path(_T("hex2bin.$$$")));
2297 vm->open_cart(drv, file_path);
2299 my_tcscpy_s(cart_status[drv].path, _MAX_PATH, file_path);
2300 out_message(_T("Cart%d: %s"), drv + 1, file_path);
2301 #if !defined(_USE_QT)
2302 // restart recording
2303 bool s = osd->now_record_sound;
2304 bool v = osd->now_record_video;
2305 stop_record_sound();
2306 stop_record_video();
2308 if(s) osd->start_record_sound();
2309 if(v) osd->start_record_video(-1);
2314 void EMU::close_cart(int drv)
2316 if(drv < USE_CART) {
2317 vm->close_cart(drv);
2318 clear_media_status(&cart_status[drv]);
2320 out_message(_T("Cart%d: Ejected"), drv + BASE_CART_NUM);
2322 out_message(_T("Cart: Ejected"));
2324 #if !defined(_USE_QT)
2326 stop_record_video();
2327 stop_record_sound();
2332 bool EMU::is_cart_inserted(int drv)
2334 if(drv < USE_CART) {
2335 return vm->is_cart_inserted(drv);
2342 #ifdef USE_FLOPPY_DISK
2343 void EMU::create_bank_floppy_disk(const _TCHAR* file_path, uint8_t type)
2346 type: 0x00 = 2D, 0x10 = 2DD, 0x20 = 2HD
2354 uint32_t trkptr[164];
2357 memset(&d88_hdr, 0, sizeof(d88_hdr));
2358 my_strcpy_s(d88_hdr.title, sizeof(d88_hdr.title), "BLANK");
2359 d88_hdr.type = type;
2360 d88_hdr.size = sizeof(d88_hdr);
2362 FILEIO *fio = new FILEIO();
2363 if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
2364 fio->Fwrite(&d88_hdr, sizeof(d88_hdr), 1);
2370 void EMU::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
2372 if(drv < USE_FLOPPY_DISK) {
2373 if(vm->is_floppy_disk_inserted(drv)) {
2374 vm->close_floppy_disk(drv);
2376 floppy_disk_status[drv].wait_count = (int)(vm->get_frame_rate() / 2);
2377 #if USE_FLOPPY_DISK > 1
2378 out_message(_T("FD%d: Ejected"), drv + BASE_FLOPPY_DISK_NUM);
2380 out_message(_T("FD: Ejected"));
2382 } else if(floppy_disk_status[drv].wait_count == 0) {
2383 vm->open_floppy_disk(drv, file_path, bank);
2384 #if USE_FLOPPY_DISK > 1
2385 out_message(_T("FD%d: %s"), drv + BASE_FLOPPY_DISK_NUM, file_path);
2387 out_message(_T("FD: %s"), file_path);
2390 my_tcscpy_s(floppy_disk_status[drv].path, _MAX_PATH, file_path);
2391 floppy_disk_status[drv].bank = bank;
2395 void EMU::close_floppy_disk(int drv)
2397 if(drv < USE_FLOPPY_DISK) {
2398 vm->close_floppy_disk(drv);
2399 clear_media_status(&floppy_disk_status[drv]);
2400 #if USE_FLOPPY_DISK > 1
2401 out_message(_T("FD%d: Ejected"), drv + BASE_FLOPPY_DISK_NUM);
2403 out_message(_T("FD: Ejected"));
2408 bool EMU::is_floppy_disk_inserted(int drv)
2410 if(drv < USE_FLOPPY_DISK) {
2411 return vm->is_floppy_disk_inserted(drv);
2417 void EMU::is_floppy_disk_protected(int drv, bool value)
2419 if(drv < USE_FLOPPY_DISK) {
2420 vm->is_floppy_disk_protected(drv, value);
2424 bool EMU::is_floppy_disk_protected(int drv)
2426 if(drv < USE_FLOPPY_DISK) {
2427 return vm->is_floppy_disk_protected(drv);
2433 uint32_t EMU::is_floppy_disk_accessed()
2435 return vm->is_floppy_disk_accessed();
2439 #ifdef USE_QUICK_DISK
2440 void EMU::open_quick_disk(int drv, const _TCHAR* file_path)
2442 if(drv < USE_QUICK_DISK) {
2443 if(vm->is_quick_disk_inserted(drv)) {
2444 vm->close_quick_disk(drv);
2446 quick_disk_status[drv].wait_count = (int)(vm->get_frame_rate() / 2);
2447 #if USE_QUICK_DISK > 1
2448 out_message(_T("QD%d: Ejected"), drv + BASE_QUICK_DISK_NUM);
2450 out_message(_T("QD: Ejected"));
2452 } else if(quick_disk_status[drv].wait_count == 0) {
2453 vm->open_quick_disk(drv, file_path);
2454 #if USE_QUICK_DISK > 1
2455 out_message(_T("QD%d: %s"), drv + BASE_QUICK_DISK_NUM, file_path);
2457 out_message(_T("QD: %s"), file_path);
2460 my_tcscpy_s(quick_disk_status[drv].path, _MAX_PATH, file_path);
2464 void EMU::close_quick_disk(int drv)
2466 if(drv < USE_QUICK_DISK) {
2467 vm->close_quick_disk(drv);
2468 clear_media_status(&quick_disk_status[drv]);
2469 #if USE_QUICK_DISK > 1
2470 out_message(_T("QD%d: Ejected"), drv + BASE_QUICK_DISK_NUM);
2472 out_message(_T("QD: Ejected"));
2477 bool EMU::is_quick_disk_inserted(int drv)
2479 if(drv < USE_QUICK_DISK) {
2480 return vm->is_quick_disk_inserted(drv);
2486 uint32_t EMU::is_quick_disk_accessed()
2488 return vm->is_quick_disk_accessed();
2492 #ifdef USE_HARD_DISK
2493 void EMU::open_hard_disk(int drv, const _TCHAR* file_path)
2495 if(drv < USE_HARD_DISK) {
2496 if(vm->is_hard_disk_inserted(drv)) {
2497 vm->close_hard_disk(drv);
2499 hard_disk_status[drv].wait_count = (int)(vm->get_frame_rate() / 2);
2500 #if USE_HARD_DISK > 1
2501 out_message(_T("HD%d: Unmounted"), drv + BASE_HARD_DISK_NUM);
2503 out_message(_T("HD: Unmounted"));
2505 } else if(hard_disk_status[drv].wait_count == 0) {
2506 vm->open_hard_disk(drv, file_path);
2507 #if USE_HARD_DISK > 1
2508 out_message(_T("HD%d: %s"), drv + BASE_HARD_DISK_NUM, file_path);
2510 out_message(_T("HD: %s"), file_path);
2513 my_tcscpy_s(hard_disk_status[drv].path, _MAX_PATH, file_path);
2514 my_tcscpy_s(config.last_hard_disk_path[drv], _MAX_PATH, file_path);
2518 void EMU::close_hard_disk(int drv)
2520 if(drv < USE_HARD_DISK) {
2521 vm->close_hard_disk(drv);
2522 clear_media_status(&hard_disk_status[drv]);
2523 #if USE_HARD_DISK > 1
2524 out_message(_T("HD%d: Unmounted"), drv + BASE_HARD_DISK_NUM);
2526 out_message(_T("HD: Unmounted"));
2528 config.last_hard_disk_path[drv][0] = '\0';
2532 bool EMU::is_hard_disk_inserted(int drv)
2534 if(drv < USE_HARD_DISK) {
2535 return vm->is_hard_disk_inserted(drv);
2541 uint32_t EMU::is_hard_disk_accessed()
2543 return vm->is_hard_disk_accessed();
2548 void EMU::play_tape(int drv, const _TCHAR* file_path)
2550 if(drv < USE_TAPE) {
2551 if(vm->is_tape_inserted(drv)) {
2552 vm->close_tape(drv);
2554 tape_status[drv].wait_count = (int)(vm->get_frame_rate() / 2);
2556 out_message(_T("CMT%d: Ejected"), drv + BASE_TAPE_NUM);
2558 out_message(_T("CMT: Ejected"));
2560 } else if(tape_status[drv].wait_count == 0) {
2561 vm->play_tape(drv, file_path);
2563 out_message(_T("CMT%d: %s"), drv + BASE_TAPE_NUM, file_path);
2565 out_message(_T("CMT: %s"), file_path);
2568 my_tcscpy_s(tape_status[drv].path, _MAX_PATH, file_path);
2569 tape_status[drv].play = true;
2573 void EMU::rec_tape(int drv, const _TCHAR* file_path)
2575 if(drv < USE_TAPE) {
2576 if(vm->is_tape_inserted(drv)) {
2577 vm->close_tape(drv);
2579 tape_status[drv].wait_count = (int)(vm->get_frame_rate() / 2);
2581 out_message(_T("CMT%d: Ejected"), drv + BASE_TAPE_NUM);
2583 out_message(_T("CMT: Ejected"));
2585 } else if(tape_status[drv].wait_count == 0) {
2586 vm->rec_tape(drv, file_path);
2588 out_message(_T("CMT%d: %s"), drv + BASE_TAPE_NUM, file_path);
2590 out_message(_T("CMT: %s"), file_path);
2593 my_tcscpy_s(tape_status[drv].path, _MAX_PATH, file_path);
2594 tape_status[drv].play = false;
2598 void EMU::close_tape(int drv)
2600 if(drv < USE_TAPE) {
2601 vm->close_tape(drv);
2602 clear_media_status(&tape_status[drv]);
2604 out_message(_T("CMT%d: Ejected"), drv + BASE_TAPE_NUM);
2606 out_message(_T("CMT: Ejected"));
2611 bool EMU::is_tape_inserted(int drv)
2613 if(drv < USE_TAPE) {
2614 return vm->is_tape_inserted(drv);
2620 bool EMU::is_tape_playing(int drv)
2622 if(drv < USE_TAPE) {
2623 return vm->is_tape_playing(drv);
2629 bool EMU::is_tape_recording(int drv)
2631 if(drv < USE_TAPE) {
2632 return vm->is_tape_recording(drv);
2638 int EMU::get_tape_position(int drv)
2640 if(drv < USE_TAPE) {
2641 return vm->get_tape_position(drv);
2647 const _TCHAR* EMU::get_tape_message(int drv)
2649 if(drv < USE_TAPE) {
2650 return vm->get_tape_message(drv);
2656 void EMU::push_play(int drv)
2658 if(drv < USE_TAPE) {
2663 void EMU::push_stop(int drv)
2665 if(drv < USE_TAPE) {
2670 void EMU::push_fast_forward(int drv)
2672 if(drv < USE_TAPE) {
2673 vm->push_fast_forward(drv);
2677 void EMU::push_fast_rewind(int drv)
2679 if(drv < USE_TAPE) {
2680 vm->push_fast_rewind(drv);
2684 void EMU::push_apss_forward(int drv)
2686 if(drv < USE_TAPE) {
2687 vm->push_apss_forward(drv);
2691 void EMU::push_apss_rewind(int drv)
2693 if(drv < USE_TAPE) {
2694 vm->push_apss_rewind(drv);
2699 #ifdef USE_COMPACT_DISC
2700 void EMU::open_compact_disc(int drv, const _TCHAR* file_path)
2702 if(vm->is_compact_disc_inserted(drv)) {
2703 vm->close_compact_disc(drv);
2705 compact_disc_status[drv].wait_count = (int)(vm->get_frame_rate() / 2);
2706 #if USE_COMPACT_DISC > 1
2707 out_message(_T("CD%d: Ejected"), drv + BASE_COMPACT_DISC_NUM);
2709 out_message(_T("CD: Ejected"));
2711 } else if(compact_disc_status[drv].wait_count == 0) {
2712 vm->open_compact_disc(drv, file_path);
2713 #if USE_COMPACT_DISC > 1
2714 out_message(_T("CD%d: %s"), drv + BASE_COMPACT_DISC_NUM, file_path);
2716 out_message(_T("CD: %s"), file_path);
2719 my_tcscpy_s(compact_disc_status[drv].path, _MAX_PATH, file_path);
2722 void EMU::close_compact_disc(int drv)
2724 vm->close_compact_disc(drv);
2725 clear_media_status(&compact_disc_status[drv]);
2726 #if USE_COMPACT_DISC > 1
2727 out_message(_T("CD%d: Ejected"), drv + BASE_COMPACT_DISC_NUM);
2729 out_message(_T("CD: Ejected"));
2733 bool EMU::is_compact_disc_inserted(int drv)
2735 return vm->is_compact_disc_inserted(drv);
2738 uint32_t EMU::is_compact_disc_accessed()
2740 return vm->is_compact_disc_accessed();
2744 #ifdef USE_LASER_DISC
2745 void EMU::open_laser_disc(int drv, const _TCHAR* file_path)
2747 if(vm->is_laser_disc_inserted(drv)) {
2748 vm->close_laser_disc(drv);
2750 laser_disc_status[drv].wait_count = (int)(vm->get_frame_rate() / 2);
2751 #if USE_LASER_DISC > 1
2752 out_message(_T("LD%d: Ejected"), drv + BASE_LASER_DISC_NUM);
2754 out_message(_T("LD: Ejected"));
2756 } else if(laser_disc_status[drv].wait_count == 0) {
2757 vm->open_laser_disc(drv, file_path);
2758 #if USE_LASER_DISC > 1
2759 out_message(_T("LD%d: %s"), drv + BASE_LASER_DISC_NUM, file_path);
2761 out_message(_T("LD: %s"), file_path);
2764 my_tcscpy_s(laser_disc_status[drv].path, _MAX_PATH, file_path);
2767 void EMU::close_laser_disc(int drv)
2769 vm->close_laser_disc(drv);
2770 clear_media_status(&laser_disc_status[drv]);
2771 #if USE_LASER_DISC > 1
2772 out_message(_T("LD%d: Ejected"), drv + BASE_LASER_DISC_NUM);
2774 out_message(_T("LD: Ejected"));
2778 bool EMU::is_laser_disc_inserted(int drv)
2780 return vm->is_laser_disc_inserted(drv);
2783 uint32_t EMU::is_laser_disc_accessed()
2785 return vm->is_laser_disc_accessed();
2789 #ifdef USE_BINARY_FILE
2790 void EMU::load_binary(int drv, const _TCHAR* file_path)
2792 if(drv < USE_BINARY_FILE) {
2793 if(check_file_extension(file_path, _T(".hex")) && hex2bin(file_path, create_local_path(_T("hex2bin.$$$")))) {
2794 vm->load_binary(drv, create_local_path(_T("hex2bin.$$$")));
2795 FILEIO::RemoveFile(create_local_path(_T("hex2bin.$$$")));
2797 vm->load_binary(drv, file_path);
2799 #if USE_BINARY_FILE > 1
2800 out_message(_T("Load Binary%d: %s"), drv + BASE_BINARY_FILE_NUM, file_path);
2802 out_message(_T("Load Binary: %s"), file_path);
2807 void EMU::save_binary(int drv, const _TCHAR* file_path)
2809 if(drv < USE_BINARY_FILE) {
2810 vm->save_binary(drv, file_path);
2811 #if USE_BINARY_FILE > 1
2812 out_message(_T("Save Binary%d: %s"), drv + BASE_BINARY_FILE_NUM, file_path);
2814 out_message(_T("Save Binary: %s"), file_path);
2821 void EMU::open_bubble_casette(int drv, const _TCHAR* file_path, int bank)
2823 if(drv < USE_BUBBLE) {
2824 if(vm->is_bubble_casette_inserted(drv)) {
2825 vm->close_bubble_casette(drv);
2827 bubble_casette_status[drv].wait_count = (int)(vm->get_frame_rate() / 2);
2829 out_message(_T("Bubble%d: Ejected"), drv + BASE_BUBBLE_NUM);
2831 out_message(_T("Bubble: Ejected"));
2833 } else if(bubble_casette_status[drv].wait_count == 0) {
2834 vm->open_bubble_casette(drv, file_path, bank);
2836 out_message(_T("Bubble%d: %s"), drv + BASE_BUBBLE_NUM, file_path);
2838 out_message(_T("Bubble: %s"), file_path);
2841 my_tcscpy_s(bubble_casette_status[drv].path, _MAX_PATH, file_path);
2842 bubble_casette_status[drv].bank = bank;
2846 void EMU::close_bubble_casette(int drv)
2848 if(drv < USE_BUBBLE) {
2849 vm->close_bubble_casette(drv);
2850 clear_media_status(&bubble_casette_status[drv]);
2852 out_message(_T("Bubble%d: Ejected"), drv + BASE_BUBBLE_NUM);
2854 out_message(_T("Bubble: Ejected"));
2859 bool EMU::is_bubble_casette_inserted(int drv)
2861 if(drv < USE_BUBBLE) {
2862 return vm->is_bubble_casette_inserted(drv);
2868 bool EMU::is_bubble_casette_protected(int drv)
2870 if(drv < USE_BUBBLE) {
2871 return vm->is_bubble_casette_protected(drv);
2877 void EMU::is_bubble_casette_protected(int drv, bool flag)
2879 if(drv < USE_BUBBLE) {
2880 vm->is_bubble_casette_protected(drv, flag);
2888 #ifdef USE_LED_DEVICE
2889 uint32_t EMU::get_led_status()
2891 return vm->get_led_status();
2896 #ifdef USE_SOUND_VOLUME
2897 void EMU::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
2899 vm->set_sound_device_volume(ch, decibel_l, decibel_r);
2903 void EMU::update_config()
2905 vm->update_config();
2910 void EMU::load_sound_file(int id, const _TCHAR *name, int16_t **data, int *dst_size)
2912 osd->load_sound_file(id, name, data, dst_size);
2915 void EMU::free_sound_file(int id, int16_t **data)
2917 osd->free_sound_file(id, data);
2922 // ----------------------------------------------------------------------------
2924 // ----------------------------------------------------------------------------
2927 #define STATE_VERSION 2
2929 void EMU::save_state(const _TCHAR* file_path)
2931 FILEIO* fio = new FILEIO();
2934 if(config.compress_state) {
2935 fio->Gzopen(file_path, FILEIO_WRITE_BINARY);
2938 if(!fio->IsOpened()) {
2939 fio->Fopen(file_path, FILEIO_WRITE_BINARY);
2941 if(fio->IsOpened()) {
2942 // save state file version
2943 fio->FputUint32(STATE_VERSION);
2945 process_config_state((void *)fio, false);
2946 // save inserted medias
2948 fio->Fwrite(&cart_status, sizeof(cart_status), 1);
2950 #ifdef USE_FLOPPY_DISK
2951 fio->Fwrite(floppy_disk_status, sizeof(floppy_disk_status), 1);
2952 fio->Fwrite(d88_file, sizeof(d88_file), 1);
2954 #ifdef USE_QUICK_DISK
2955 fio->Fwrite(&quick_disk_status, sizeof(quick_disk_status), 1);
2957 #ifdef USE_HARD_DISK
2958 fio->Fwrite(&hard_disk_status, sizeof(hard_disk_status), 1);
2961 fio->Fwrite(&tape_status, sizeof(tape_status), 1);
2963 #ifdef USE_COMPACT_DISC
2964 fio->Fwrite(&compact_disc_status, sizeof(compact_disc_status), 1);
2966 #ifdef USE_LASER_DISC
2967 fio->Fwrite(&laser_disc_status, sizeof(laser_disc_status), 1);
2970 fio->Fwrite(&bubble_casette_status, sizeof(bubble_casette_status), 1);
2973 vm->process_state(fio, false);
2974 // end of state file
2975 fio->FputInt32_LE(-1);
2982 void EMU::load_state(const _TCHAR* file_path)
2984 if(FILEIO::IsFileExisting(file_path)) {
2987 config.romaji_to_kana = false;
2990 save_state(create_local_path(_T("$temp$.sta")));
2991 if(!load_state_tmp(file_path)) {
2992 out_debug_log(_T("failed to load state file\n"));
2993 load_state_tmp(create_local_path(_T("$temp$.sta")));
2995 FILEIO::RemoveFile(create_local_path(_T("$temp$.sta")));
2999 bool EMU::load_state_tmp(const _TCHAR* file_path)
3001 bool result = false;
3002 FILEIO* fio = new FILEIO();
3005 if(config.compress_state) {
3006 fio->Gzopen(file_path, FILEIO_READ_BINARY);
3009 if(!fio->IsOpened()) {
3010 fio->Fopen(file_path, FILEIO_READ_BINARY);
3012 if(fio->IsOpened()) {
3013 // check state file version
3014 if(fio->FgetUint32() == STATE_VERSION) {
3016 if(process_config_state((void *)fio, true)) {
3017 // load inserted medias
3019 fio->Fread(&cart_status, sizeof(cart_status), 1);
3021 #ifdef USE_FLOPPY_DISK
3022 fio->Fread(floppy_disk_status, sizeof(floppy_disk_status), 1);
3023 fio->Fread(d88_file, sizeof(d88_file), 1);
3025 #ifdef USE_QUICK_DISK
3026 fio->Fread(&quick_disk_status, sizeof(quick_disk_status), 1);
3028 #ifdef USE_HARD_DISK
3029 fio->Fread(&hard_disk_status, sizeof(hard_disk_status), 1);
3032 fio->Fread(&tape_status, sizeof(tape_status), 1);
3034 #ifdef USE_COMPACT_DISC
3035 fio->Fread(&compact_disc_status, sizeof(compact_disc_status), 1);
3037 #ifdef USE_LASER_DISC
3038 fio->Fread(&laser_disc_status, sizeof(laser_disc_status), 1);
3041 fio->Fread(&bubble_casette_status, sizeof(bubble_casette_status), 1);
3043 // check if virtual machine should be reinitialized
3044 bool reinitialize = false;
3046 reinitialize |= (cpu_type != config.cpu_type);
3047 cpu_type = config.cpu_type;
3049 #ifdef USE_DIPSWITCH
3050 reinitialize |= (dipswitch != config.dipswitch);
3051 dipswitch = config.dipswitch;
3053 #ifdef USE_SOUND_TYPE
3054 reinitialize |= (sound_type != config.sound_type);
3055 sound_type = config.sound_type;
3057 #ifdef USE_PRINTER_TYPE
3058 reinitialize |= (printer_type != config.printer_type);
3059 printer_type = config.printer_type;
3061 if(!(0 <= config.sound_frequency && config.sound_frequency < 8)) {
3062 config.sound_frequency = 6; // default: 48KHz
3064 if(!(0 <= config.sound_latency && config.sound_latency < 5)) {
3065 config.sound_latency = 1; // default: 100msec
3067 reinitialize |= (sound_frequency != config.sound_frequency);
3068 reinitialize |= (sound_latency != config.sound_latency);
3069 sound_frequency = config.sound_frequency;
3070 sound_latency = config.sound_latency;
3075 // reinitialize virtual machine
3080 # if defined(_USE_QT)
3081 osd->reset_vm_node();
3082 osd->update_keyname_table();
3084 vm->initialize_sound(sound_rate, sound_samples);
3085 #ifdef USE_SOUND_VOLUME
3086 for(int i = 0; i < USE_SOUND_VOLUME; i++) {
3087 vm->set_sound_device_volume(i, config.sound_volume_l[i], config.sound_volume_r[i]);
3094 // restore inserted medias
3098 if(vm->process_state(fio, true)) {
3099 // check end of state
3100 result = (fio->FgetInt32_LE() == -1);