2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
7 [ win32 emulation i/f ]
13 #if defined(_USE_AGAR)
15 #include "agar_main.h"
16 #include "agar_logger.h"
18 # elif defined(_USE_QT)
19 //#include <SDL/SDL.h>
22 #include "agar_logger.h"
26 #ifndef FD_BASE_NUMBER
27 #define FD_BASE_NUMBER 1
29 #ifndef QD_BASE_NUMBER
30 #define QD_BASE_NUMBER 1
33 // ----------------------------------------------------------------------------
35 // ----------------------------------------------------------------------------
36 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
37 extern void get_long_full_path_name(_TCHAR* src, _TCHAR* dst);
41 #if defined(_USE_AGAR)
42 EMU::EMU(AG_Window *hwnd, AG_Widget *hinst)
43 #elif defined(_USE_QT)
44 EMU::EMU(Ui_MainWindow *hwnd, GLDrawClass *hinst)
46 EMU::EMU(HWND hwnd, HINSTANCE hinst)
51 initialize_debug_log();
55 // store main window handle
56 main_window_handle = hwnd;
57 instance_handle = hinst;
59 #if !defined(_USE_AGAR) && !defined(_USE_SDL) && !defined(_USE_QT)
61 OSVERSIONINFO os_info;
62 os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
63 GetVersionEx(&os_info);
64 vista_or_later = (os_info.dwPlatformId == 2 && os_info.dwMajorVersion >= 6);
69 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
72 _TCHAR tmp_path[PATH_MAX], *ptr;
73 my_procname.copy(tmp_path, PATH_MAX, 0);
74 get_long_full_path_name(tmp_path, app_path);
75 //AGAR_DebugLog("APPPATH=%s\n", app_path);
76 if(AG_UsingGL(AGDRIVER(main_window_handle))) {
83 pVMSemaphore = SDL_CreateSemaphore(1);
85 _TCHAR tmp_path[PATH_MAX], *ptr;
86 my_procname.copy(tmp_path, PATH_MAX, 0);
87 get_long_full_path_name(tmp_path, app_path);
88 //AGAR_DebugLog("APPPATH=%s\n", app_path);
91 VMSemaphore = new QSemaphore(1);
94 _TCHAR tmp_path[_MAX_PATH], *ptr;
95 memset(tmp_path, 0x00, _MAX_PATH);
96 GetModuleFileName(NULL, tmp_path, _MAX_PATH);
97 GetFullPathName(tmp_path, _MAX_PATH, app_path, &ptr);
101 // initialize d88 file info
102 memset(d88_file, 0, sizeof(d88_file));
106 static const int freq_table[8] = {
107 2000, 4000, 8000, 11025, 22050, 44100,
108 #ifdef OVERRIDE_SOUND_FREQ_48000HZ
109 OVERRIDE_SOUND_FREQ_48000HZ,
115 static const double late_table[5] = {0.05, 0.1, 0.2, 0.3, 0.4};
117 if(!(0 <= config.sound_frequency && config.sound_frequency < 8)) {
118 config.sound_frequency = 6; // default: 48KHz
120 if(!(0 <= config.sound_latency && config.sound_latency < 5)) {
121 config.sound_latency = 1; // default: 100msec
123 sound_rate = freq_table[config.sound_frequency];
124 sound_samples = (int)(sound_rate * late_table[config.sound_latency] + 0.5);
127 cpu_type = config.cpu_type;
129 #ifdef USE_SOUND_DEVICE_TYPE
130 sound_device_type = config.sound_device_type;
136 initialize_debugger();
142 initialize_printer();
147 # ifdef USE_DIRECT_SHOW
149 initialize_direct_show();
152 vm->initialize_sound(sound_rate, sound_samples);
154 now_suspended = false;
170 #ifdef USE_DIRECT_SHOW
171 release_direct_show();
180 #if defined(_USE_AGAR)
181 if(pVMSemaphore) SDL_DestroySemaphore(pVMSemaphore);
182 #elif defined(_USE_QT)
187 // ----------------------------------------------------------------------------
189 // ----------------------------------------------------------------------------
191 int EMU::frame_interval()
194 #ifdef SUPPORT_VARIABLE_TIMING
195 static int prev_interval = 0;
196 static double prev_fps = -1;
197 double fps = vm->frame_rate();
198 if(prev_fps != fps) {
199 prev_interval = (int)(1024. * 1000. / fps + 0.5);
202 return prev_interval;
204 return (int)(1024. * 1000. / FRAMES_PER_SEC + 0.5);
207 return (int)(1024. * 1000. / FRAMES_PER_SEC + 0.5);
214 #ifdef USE_LASER_DISC
215 if(now_movie_play && !now_movie_pause) {
219 now_suspended = false;
229 // virtual machine may be driven to fill sound buffer
230 int extra_frames = 0;
231 update_sound(&extra_frames);
233 // drive virtual machine
234 if(extra_frames == 0) {
236 // printf("VM:RUN() %d\n", AG_GetTicks());
239 rec_video_run_frames += extra_frames;
246 // check if virtual machine should be reinitialized
247 bool reinitialize = false;
249 reinitialize |= (cpu_type != config.cpu_type);
250 cpu_type = config.cpu_type;
252 #ifdef USE_SOUND_DEVICE_TYPE
253 reinitialize |= (sound_device_type != config.sound_device_type);
254 sound_device_type = config.sound_device_type;
258 if(sound_ok && sound_started) {
259 #if defined(_USE_SDL) || defined(_USE_AGAR) || defined(_USE_QT)
265 sound_started = false;
267 // reinitialize virtual machine
271 vm->initialize_sound(sound_rate, sound_samples);
274 // restore inserted medias
277 // reset virtual machine
289 #ifdef USE_SPECIAL_RESET
290 void EMU::special_reset()
292 // reset virtual machine
305 void EMU::notify_power_off()
307 vm->notify_power_off();
311 _TCHAR* EMU::bios_path(_TCHAR* file_name)
313 static _TCHAR file_path[_MAX_PATH];
314 _stprintf_s(file_path, _MAX_PATH, _T("%s%s"), app_path, file_name);
315 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
316 AGAR_DebugLog(AGAR_LOG_INFO, "LOAD BIOS: %s", file_path);
319 //#if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
320 // static _TCHAR file_path[_MAX_PATH];
321 // strcpy(file_path, app_path);
322 // strcat(file_path, file_name);
323 //#if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
324 // AGAR_DebugLog(AGAR_LOG_INFO, "LOAD BIOS: %s\n", file_path);
327 // static _TCHAR file_path[_MAX_PATH];
328 // _stprintf(file_path, _T("%s%s"), app_path, file_name);
329 // printf("LOAD: %s\n", file_path);
337 #ifdef USE_LASER_DISC
338 #ifndef _USE_QT // WILLFIX
339 if(now_movie_play && !now_movie_pause) {
341 now_movie_pause = false;
346 now_suspended = true;
350 // ----------------------------------------------------------------------------
352 // ----------------------------------------------------------------------------
354 void EMU::get_host_time(cur_time_t* t)
356 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
359 tnow = std::time(NULL);
360 tm = std::localtime(&tnow);
362 t->year = tm->tm_year + 1900;
363 t->month = tm->tm_mon + 1;
364 t->day = tm->tm_mday;
365 t->day_of_week = tm->tm_wday;
366 t->hour = tm->tm_hour;
367 t->minute = tm->tm_min;
368 t->second = tm->tm_sec;
371 GetLocalTime(&sTime);
373 t->year = sTime.wYear;
374 t->month = sTime.wMonth;
376 t->day_of_week = sTime.wDayOfWeek;
377 t->hour = sTime.wHour;
378 t->minute = sTime.wMinute;
379 t->second = sTime.wSecond;
383 // ----------------------------------------------------------------------------
385 // ----------------------------------------------------------------------------
387 void EMU::initialize_printer()
389 prn_fio = new FILEIO();
394 void EMU::release_printer()
396 close_printer_file();
400 void EMU::reset_printer()
402 close_printer_file();
407 void EMU::update_printer()
409 if(prn_fio->IsOpened() && --prn_wait_frames == 0) {
410 close_printer_file();
414 void EMU::open_printer_file()
417 get_host_time(&time);
418 _stprintf_s(prn_file_name, _MAX_PATH, _T("prn_%d-%0.2d-%0.2d_%0.2d-%0.2d-%0.2d.txt"), time.year, time.month, time.day, time.hour, time.minute, time.second);
419 prn_fio->Fopen(bios_path(prn_file_name), FILEIO_WRITE_BINARY);
422 void EMU::close_printer_file()
424 if(prn_fio->IsOpened()) {
425 // remove if the file size is less than 2 bytes
426 bool remove = (prn_fio->Ftell() < 2);
429 FILEIO::Remove(bios_path(prn_file_name));
434 void EMU::printer_out(uint8 value)
439 void EMU::printer_strobe(bool value)
441 bool falling = (prn_strobe && !value);
445 if(!prn_fio->IsOpened()) {
451 prn_fio->Fputc(prn_data);
453 #ifdef SUPPORT_VARIABLE_TIMING
454 prn_wait_frames = (int)(vm->frame_rate() * 10.0 + 0.5);
456 prn_wait_frames = (int)(FRAMES_PER_SEC * 10.0 + 0.5);
461 // ----------------------------------------------------------------------------
463 // ----------------------------------------------------------------------------
466 void EMU::initialize_debug_log()
468 #if defined(_USE_QT) || defined(_USE_AGAR) || defined(_USE_SDL)
471 debug_log = _tfopen(_T("d:\\debug.log"), _T("w"));
475 void EMU::release_debug_log()
477 #if defined(_USE_QT) || defined(_USE_AGAR) || defined(_USE_SDL)
488 void EMU::out_debug_log(const _TCHAR* format, ...)
493 static _TCHAR prev_buffer[1024] = {0};
495 va_start(ap, format);
496 _vstprintf_s(buffer, 1024, format, ap);
499 #if defined(_USE_QT) || defined(_USE_AGAR) || defined(_USE_SDL)
500 AGAR_DebugLog(AGAR_LOG_DEBUG, "%s", buffer);
502 if(_tcscmp(prev_buffer, buffer) == 0) {
505 _tcscpy_s(prev_buffer, 1024, buffer);
507 _ftprintf(debug_log, _T("%s"), buffer);
509 if((size += _tcslen(buffer)) > 0x8000000) { // 128MB
510 static int index = 1;
511 TCHAR path[_MAX_PATH];
512 _stprintf_s(path, _MAX_PATH, _T("d:\\debug_#%d.log"), ++index);
514 debug_log = _tfopen(path, _T("w"));
522 void EMU::out_message(const _TCHAR* format, ...)
525 va_start(ap, format);
526 _vstprintf_s(message, 260, format, ap); // Security for MSVC:C6386.
528 message_count = 4; // 4sec
531 // ----------------------------------------------------------------------------
533 // ----------------------------------------------------------------------------
535 static uint8 hex2uint8(char *value)
538 memset(tmp, 0, sizeof(tmp));
539 memcpy(tmp, value, 2);
540 return (uint8)strtoul(tmp, NULL, 16);
543 static uint16 hex2uint16(char *value)
546 memset(tmp, 0, sizeof(tmp));
547 memcpy(tmp, value, 4);
548 return (uint16)strtoul(tmp, NULL, 16);
551 static bool hex2bin(_TCHAR* file_path, _TCHAR* dest_path)
554 FILEIO *fio_s = new FILEIO();
555 if(fio_s->Fopen(file_path, FILEIO_READ_BINARY)) {
558 uint8 buffer[0x10000];
559 memset(buffer, 0xff, sizeof(buffer));
560 while(fio_s->Fgets(line, sizeof(line)) != NULL) {
561 if(line[0] != ':') continue;
562 int bytes = hex2uint8(line + 1);
563 int offset = hex2uint16(line + 3);
564 uint8 record_type = hex2uint8(line + 7);
565 if(record_type == 0x01) break;
566 if(record_type != 0x00) continue;
567 for(int i = 0; i < bytes; i++) {
568 if(offset + i < sizeof(buffer)) {
569 if(length < offset + i) {
572 buffer[offset + i] = hex2uint8(line + 9 + 2 * i);
577 FILEIO *fio_d = new FILEIO();
578 if(fio_d->Fopen(dest_path, FILEIO_WRITE_BINARY)) {
579 fio_d->Fwrite(buffer, length, 1);
591 void EMU::initialize_media()
594 memset(&cart_status, 0, sizeof(cart_status));
597 memset(disk_status, 0, sizeof(disk_status));
600 memset(&quickdisk_status, 0, sizeof(quickdisk_status));
603 memset(&tape_status, 0, sizeof(tape_status));
605 #ifdef USE_LASER_DISC
606 memset(&laser_disc_status, 0, sizeof(laser_disc_status));
610 #if defined(USE_FD1) || defined(USE_FD2) || defined(USE_FD3) || defined(USE_FD4) || \
611 defined(USE_FD5) || defined(USE_FD6) || defined(USE_FD7) || defined(USE_FD8)
614 void EMU::write_protect_fd(int drv, bool flag)
616 #if defined(USE_DISK_WRITE_PROTECT)
617 vm->write_protect_fd(drv, flag);
620 bool EMU::is_write_protected_fd(int drv)
622 #if defined(USE_DISK_WRITE_PROTECT)
623 return vm->is_write_protect_fd(drv);
630 void EMU::update_media()
633 for(int drv = 0; drv < MAX_FD; drv++) {
634 if(disk_status[drv].wait_count != 0 && --disk_status[drv].wait_count == 0) {
635 vm->open_disk(drv, disk_status[drv].path, disk_status[drv].bank);
636 out_message(_T("FD%d: %s"), drv + FD_BASE_NUMBER, disk_status[drv].path);
641 for(int drv = 0; drv < MAX_QD; drv++) {
642 if(quickdisk_status[drv].wait_count != 0 && --quickdisk_status[drv].wait_count == 0) {
643 vm->open_quickdisk(drv, quickdisk_status[drv].path);
644 out_message(_T("QD%d: %s"), drv + QD_BASE_NUMBER, quickdisk_status[drv].path);
649 if(tape_status.wait_count != 0 && --tape_status.wait_count == 0) {
650 if(tape_status.play) {
651 vm->play_tape(tape_status.path);
653 vm->rec_tape(tape_status.path);
655 out_message(_T("CMT: %s"), tape_status.path);
658 #ifdef USE_LASER_DISC
659 if(laser_disc_status.wait_count != 0 && --laser_disc_status.wait_count == 0) {
660 vm->open_laser_disc(laser_disc_status.path);
661 out_message(_T("LD: %s"), laser_disc_status.path);
666 void EMU::restore_media()
669 for(int drv = 0; drv < MAX_CART; drv++) {
670 if(cart_status[drv].path[0] != _T('\0')) {
671 if(check_file_extension(cart_status[drv].path, _T(".hex")) && hex2bin(cart_status[drv].path, bios_path(_T("hex2bin.$$$")))) {
672 vm->open_cart(drv, bios_path(_T("hex2bin.$$$")));
673 FILEIO::Remove(bios_path(_T("hex2bin.$$$")));
675 vm->open_cart(drv, cart_status[drv].path);
681 for(int drv = 0; drv < MAX_FD; drv++) {
682 if(disk_status[drv].path[0] != _T('\0')) {
683 vm->open_disk(drv, disk_status[drv].path, disk_status[drv].bank);
688 for(int drv = 0; drv < MAX_QD; drv++) {
689 if(quickdisk_status[drv].path[0] != _T('\0')) {
690 vm->open_quickdisk(drv, quickdisk_status[drv].path);
695 if(tape_status.path[0] != _T('\0')) {
696 if(tape_status.play) {
697 vm->play_tape(tape_status.path);
699 tape_status.path[0] = _T('\0');
703 #ifdef USE_LASER_DISC
704 if(laser_disc_status.path[0] != _T('\0')) {
705 vm->open_laser_disc(laser_disc_status.path);
711 void EMU::open_cart(int drv, _TCHAR* file_path)
714 if(check_file_extension(file_path, _T(".hex")) && hex2bin(file_path, bios_path(_T("hex2bin.$$$")))) {
715 vm->open_cart(drv, bios_path(_T("hex2bin.$$$")));
716 FILEIO::Remove(bios_path(_T("hex2bin.$$$")));
718 vm->open_cart(drv, file_path);
720 _tcscpy_s(cart_status[drv].path, _MAX_PATH, file_path);
721 out_message(_T("Cart%d: %s"), drv + 1, file_path);
724 bool s = now_rec_sound;
725 bool v = now_rec_video;
728 if(s) start_rec_sound();
729 if(v) start_rec_video(-1);
733 void EMU::close_cart(int drv)
737 clear_media_status(&cart_status[drv]);
738 out_message(_T("Cart%d: Ejected"), drv + 1);
746 bool EMU::cart_inserted(int drv)
749 return vm->cart_inserted(drv);
757 void EMU::open_disk(int drv, _TCHAR* file_path, int bank)
760 if(vm->disk_inserted(drv)) {
763 #ifdef SUPPORT_VARIABLE_TIMING
764 disk_status[drv].wait_count = (int)(vm->frame_rate() / 2);
766 disk_status[drv].wait_count = (int)(FRAMES_PER_SEC / 2);
768 out_message(_T("FD%d: Ejected"), drv + FD_BASE_NUMBER);
769 } else if(disk_status[drv].wait_count == 0) {
770 vm->open_disk(drv, file_path, bank);
771 out_message(_T("FD%d: %s"), drv + FD_BASE_NUMBER, file_path);
773 _tcscpy_s(disk_status[drv].path, _MAX_PATH, file_path);
774 disk_status[drv].bank = bank;
778 void EMU::close_disk(int drv)
782 clear_media_status(&disk_status[drv]);
783 out_message(_T("FD%d: Ejected"), drv + FD_BASE_NUMBER);
787 bool EMU::disk_inserted(int drv)
790 return vm->disk_inserted(drv);
797 int EMU::get_access_lamp(void)
800 #if defined(USE_ACCESS_LAMP)
801 # if defined(USE_FD1) || defined(USE_QD1)
802 # if !defined(_MSC_VER)
806 stat = vm->access_lamp(); // Return accessing drive number.
807 # if !defined(_MSC_VER)
817 void EMU::open_quickdisk(int drv, _TCHAR* file_path)
820 if(vm->quickdisk_inserted(drv)) {
821 vm->close_quickdisk(drv);
823 #ifdef SUPPORT_VARIABLE_TIMING
824 quickdisk_status[drv].wait_count = (int)(vm->frame_rate() / 2);
826 quickdisk_status[drv].wait_count = (int)(FRAMES_PER_SEC / 2);
828 out_message(_T("QD%d: Ejected"), drv + QD_BASE_NUMBER);
829 } else if(quickdisk_status[drv].wait_count == 0) {
830 vm->open_quickdisk(drv, file_path);
831 out_message(_T("QD%d: %s"), drv + QD_BASE_NUMBER, file_path);
833 _tcscpy_s(quickdisk_status[drv].path, _MAX_PATH, file_path);
837 void EMU::close_quickdisk(int drv)
840 vm->close_quickdisk(drv);
841 clear_media_status(&quickdisk_status[drv]);
842 out_message(_T("QD%d: Ejected"), drv + QD_BASE_NUMBER);
846 bool EMU::quickdisk_inserted(int drv)
849 return vm->quickdisk_inserted(drv);
857 void EMU::play_tape(_TCHAR* file_path)
859 if(vm->tape_inserted()) {
862 #ifdef SUPPORT_VARIABLE_TIMING
863 tape_status.wait_count = (int)(vm->frame_rate() / 2);
865 tape_status.wait_count = (int)(FRAMES_PER_SEC / 2);
867 out_message(_T("CMT: Ejected"));
868 } else if(tape_status.wait_count == 0) {
869 vm->play_tape(file_path);
870 out_message(_T("CMT: %s"), file_path);
872 _tcscpy_s(tape_status.path, _MAX_PATH, file_path);
873 tape_status.play = true;
876 void EMU::rec_tape(_TCHAR* file_path)
878 if(vm->tape_inserted()) {
881 #ifdef SUPPORT_VARIABLE_TIMING
882 tape_status.wait_count = (int)(vm->frame_rate() / 2);
884 tape_status.wait_count = (int)(FRAMES_PER_SEC / 2);
886 out_message(_T("CMT: Ejected"));
887 } else if(tape_status.wait_count == 0) {
888 vm->rec_tape(file_path);
889 out_message(_T("CMT: %s"), file_path);
891 _tcscpy_s(tape_status.path, _MAX_PATH, file_path);
892 tape_status.play = false;
895 void EMU::close_tape()
898 clear_media_status(&tape_status);
899 out_message(_T("CMT: Ejected"));
902 bool EMU::tape_inserted()
904 return vm->tape_inserted();
908 #ifdef USE_LASER_DISC
909 void EMU::open_laser_disc(_TCHAR* file_path)
911 if(vm->laser_disc_inserted()) {
912 vm->close_laser_disc();
914 #ifdef SUPPORT_VARIABLE_TIMING
915 laser_disc_status.wait_count = (int)(vm->frame_rate() / 2);
917 laser_disc_status.wait_count = (int)(FRAMES_PER_SEC / 2);
919 out_message(_T("LD: Ejected"));
920 } else if(laser_disc_status.wait_count == 0) {
921 vm->open_laser_disc(file_path);
922 out_message(_T("LD: %s"), file_path);
924 _tcscpy_s(laser_disc_status.path, _MAX_PATH, file_path);
927 void EMU::close_laser_disc()
929 vm->close_laser_disc();
930 clear_media_status(&laser_disc_status);
931 out_message(_T("LD: Ejected"));
934 bool EMU::laser_disc_inserted()
936 return vm->laser_disc_inserted();
940 #ifdef USE_TAPE_BUTTON
941 void EMU::push_play()
946 void EMU::push_stop()
951 void EMU::push_fast_forward()
953 vm->push_fast_forward();
956 void EMU::push_fast_rewind()
958 vm->push_fast_rewind();
961 void EMU::push_apss_forward()
963 vm->push_apss_forward();
966 void EMU::push_apss_rewind()
968 vm->push_apss_rewind();
972 #ifdef USE_BINARY_FILE1
973 void EMU::load_binary(int drv, _TCHAR* file_path)
975 if(drv < MAX_BINARY) {
976 if(check_file_extension(file_path, _T(".hex")) && hex2bin(file_path, bios_path(_T("hex2bin.$$$")))) {
977 vm->load_binary(drv, bios_path(_T("hex2bin.$$$")));
978 FILEIO::Remove(bios_path(_T("hex2bin.$$$")));
980 vm->load_binary(drv, file_path);
982 out_message(_T("Load: %s"), file_path);
986 void EMU::save_binary(int drv, _TCHAR* file_path)
988 if(drv < MAX_BINARY) {
989 vm->save_binary(drv, file_path);
990 out_message(_T("Save: %s"), file_path);
997 return vm->now_skip();
1000 void EMU::update_config()
1002 vm->update_config();
1006 // ----------------------------------------------------------------------------
1008 // ----------------------------------------------------------------------------
1010 #define STATE_VERSION 2
1012 void EMU::save_state()
1014 _TCHAR file_name[_MAX_PATH];
1015 _stprintf_s(file_name, _MAX_PATH, _T("%s.sta"), _T(CONFIG_NAME));
1016 save_state_tmp(bios_path(file_name));
1019 void EMU::load_state()
1021 _TCHAR file_name[_MAX_PATH];
1022 _stprintf_s(file_name, _MAX_PATH, _T("%s.sta"), _T(CONFIG_NAME));
1024 if(ffp.IsFileExists(bios_path(file_name))) {
1025 save_state_tmp(bios_path(_T("$temp$.sta")));
1026 if(!load_state_tmp(bios_path(file_name))) {
1027 out_debug_log("failed to load state file\n");
1028 load_state_tmp(bios_path(_T("$temp$.sta")));
1030 DeleteFile(bios_path(_T("$temp$.sta")));
1034 void EMU::save_state_tmp(_TCHAR* file_path)
1036 FILEIO* fio = new FILEIO();
1038 if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
1039 // save state file version
1040 fio->FputUint32(STATE_VERSION);
1042 save_config_state((void *)fio);
1043 // save inserted medias
1045 fio->Fwrite(&cart_status, sizeof(cart_status), 1);
1048 fio->Fwrite(disk_status, sizeof(disk_status), 1);
1049 fio->Fwrite(d88_file, sizeof(d88_file), 1);
1052 fio->Fwrite(&quickdisk_status, sizeof(quickdisk_status), 1);
1055 fio->Fwrite(&tape_status, sizeof(tape_status), 1);
1057 #ifdef USE_LASER_DISC
1058 fio->Fwrite(&laser_disc_status, sizeof(laser_disc_status), 1);
1061 vm->save_state(fio);
1062 // end of state file
1070 bool EMU::load_state_tmp(_TCHAR* file_path)
1072 bool result = false;
1073 FILEIO* fio = new FILEIO();
1074 if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
1075 // check state file version
1076 if(fio->FgetUint32() == STATE_VERSION) {
1078 if(load_config_state((void *)fio)) {
1079 // load inserted medias
1081 fio->Fread(&cart_status, sizeof(cart_status), 1);
1084 fio->Fread(disk_status, sizeof(disk_status), 1);
1085 fio->Fread(d88_file, sizeof(d88_file), 1);
1088 fio->Fread(&quickdisk_status, sizeof(quickdisk_status), 1);
1091 fio->Fread(&tape_status, sizeof(tape_status), 1);
1093 #ifdef USE_LASER_DISC
1094 fio->Fread(&laser_disc_status, sizeof(laser_disc_status), 1);
1096 // check if virtual machine should be reinitialized
1097 bool reinitialize = false;
1099 reinitialize |= (cpu_type != config.cpu_type);
1100 cpu_type = config.cpu_type;
1102 #ifdef USE_SOUND_DEVICE_TYPE
1103 reinitialize |= (sound_device_type != config.sound_device_type);
1104 sound_device_type = config.sound_device_type;
1108 if(sound_ok && sound_started) {
1109 #if defined(_USE_SDL) || defined(_USE_AGAR) || defined(_USE_QT)
1115 sound_started = false;
1118 // reinitialize virtual machine
1121 vm->initialize_sound(sound_rate, sound_samples);
1125 // restore inserted medias
1128 if(vm->load_state(fio)) {
1129 // check end of state
1130 result = (fio->FgetInt32() == -1);