2 Skelton for retropc emulator
\r
4 Author : Takeda.Toshiya
\r
7 [ win32 emulation i/f ]
\r
13 #if defined(_USE_AGAR)
\r
14 #include <SDL/SDL.h>
\r
15 #include "agar_main.h"
\r
16 #include "agar_logger.h"
\r
18 # elif defined(_USE_QT)
\r
19 #include <SDL/SDL.h>
\r
20 #include "qt_main.h"
\r
21 #include "agar_logger.h"
\r
25 #ifndef FD_BASE_NUMBER
\r
26 #define FD_BASE_NUMBER 1
\r
28 #ifndef QD_BASE_NUMBER
\r
29 #define QD_BASE_NUMBER 1
\r
32 // ----------------------------------------------------------------------------
\r
34 // ----------------------------------------------------------------------------
\r
35 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
\r
36 extern void get_long_full_path_name(_TCHAR* src, _TCHAR* dst);
\r
40 #if defined(_USE_QGAR)
\r
41 EMU::EMU(AG_Window *hwnd, AG_Widget *hinst)
\r
42 #elif defined(_USE_QT)
\r
43 EMU::EMU(Ui_MainWindow *hwnd, GLDrawClass *hinst)
\r
45 EMU::EMU(HWND hwnd, HINSTANCE hinst)
\r
49 // open debug logfile
\r
50 initialize_debug_log();
\r
54 // store main window handle
\r
55 main_window_handle = hwnd;
\r
56 instance_handle = hinst;
\r
60 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
63 _TCHAR tmp_path[PATH_MAX], *ptr;
\r
64 my_procname.copy(tmp_path, PATH_MAX, 0);
\r
65 get_long_full_path_name(tmp_path, app_path);
\r
66 //AGAR_DebugLog("APPPATH=%s\n", app_path);
\r
67 if(AG_UsingGL(AGDRIVER(main_window_handle))) {
\r
75 _TCHAR tmp_path[PATH_MAX], *ptr;
\r
76 my_procname.copy(tmp_path, PATH_MAX, 0);
\r
77 get_long_full_path_name(tmp_path, app_path);
\r
78 //AGAR_DebugLog("APPPATH=%s\n", app_path);
\r
82 pVMSemaphore = SDL_CreateSemaphore(1);
\r
84 _TCHAR tmp_path[_MAX_PATH], *ptr;
\r
85 GetModuleFileName(NULL, tmp_path, _MAX_PATH);
\r
86 GetFullPathName(tmp_path, _MAX_PATH, app_path, &ptr);
\r
90 // initialize d88 file info
\r
91 memset(d88_file, 0, sizeof(d88_file));
\r
94 // load sound config
\r
95 static const int freq_table[8] = {
\r
96 2000, 4000, 8000, 11025, 22050, 44100,
\r
97 #ifdef OVERRIDE_SOUND_FREQ_48000HZ
\r
98 OVERRIDE_SOUND_FREQ_48000HZ,
\r
104 static const double late_table[5] = {0.05, 0.1, 0.2, 0.3, 0.4};
\r
106 if(!(0 <= config.sound_frequency && config.sound_frequency < 8)) {
\r
107 config.sound_frequency = 6; // default: 48KHz
\r
109 if(!(0 <= config.sound_latency && config.sound_latency < 5)) {
\r
110 config.sound_latency = 1; // default: 100msec
\r
112 sound_rate = freq_table[config.sound_frequency];
\r
113 sound_samples = (int)(sound_rate * late_table[config.sound_latency] + 0.5);
\r
115 #ifdef USE_CPU_TYPE
\r
116 cpu_type = config.cpu_type;
\r
118 #ifdef USE_SOUND_DEVICE_TYPE
\r
119 sound_device_type = config.sound_device_type;
\r
124 #ifdef USE_DEBUGGER
\r
125 initialize_debugger();
\r
127 initialize_input();
\r
128 initialize_screen();
\r
129 initialize_sound();
\r
130 initialize_media();
\r
131 initialize_printer();
\r
133 initialize_socket();
\r
135 #ifdef USE_DIRECT_SHOW
\r
136 CoInitialize(NULL);
\r
137 initialize_direct_show();
\r
139 vm->initialize_sound(sound_rate, sound_samples);
\r
141 now_suspended = false;
\r
146 #ifdef USE_DEBUGGER
\r
147 release_debugger();
\r
156 #ifdef USE_DIRECT_SHOW
\r
157 release_direct_show();
\r
158 CoInitialize(NULL);
\r
161 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
162 if(pVMSemaphore) SDL_SemWait(pVMSemaphore);
\r
166 release_debug_log();
\r
168 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
169 if(pVMSemaphore) SDL_DestroySemaphore(pVMSemaphore);
\r
173 // ----------------------------------------------------------------------------
\r
175 // ----------------------------------------------------------------------------
\r
177 int EMU::frame_interval()
\r
180 #ifdef SUPPORT_VARIABLE_TIMING
\r
181 static int prev_interval = 0;
\r
182 static double prev_fps = -1;
\r
183 double fps = vm->frame_rate();
\r
184 if(prev_fps != fps) {
\r
185 prev_interval = (int)(1024. * 1000. / fps + 0.5);
\r
188 return prev_interval;
\r
190 return (int)(1024. * 1000. / FRAMES_PER_SEC + 0.5);
\r
193 return (int)(1024. * 1000. / FRAMES_PER_SEC + 0.5);
\r
199 if(now_suspended) {
\r
200 #ifdef USE_LASER_DISC
\r
201 if(now_movie_play && !now_movie_pause) {
\r
205 now_suspended = false;
\r
207 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
208 if(pVMSemaphore) SDL_SemWait(pVMSemaphore);
\r
218 // virtual machine may be driven to fill sound buffer
\r
219 int extra_frames = 0;
\r
220 update_sound(&extra_frames);
\r
222 // drive virtual machine
\r
223 if(extra_frames == 0) {
\r
225 // printf("VM:RUN() %d\n", AG_GetTicks());
\r
228 rec_video_run_frames += extra_frames;
\r
229 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
230 if(pVMSemaphore) SDL_SemPost(pVMSemaphore);
\r
232 return extra_frames;
\r
237 // check if virtual machine should be reinitialized
\r
238 bool reinitialize = false;
\r
239 #ifdef USE_CPU_TYPE
\r
240 reinitialize |= (cpu_type != config.cpu_type);
\r
241 cpu_type = config.cpu_type;
\r
243 #ifdef USE_SOUND_DEVICE_TYPE
\r
244 reinitialize |= (sound_device_type != config.sound_device_type);
\r
245 sound_device_type = config.sound_device_type;
\r
249 if(sound_ok && sound_started) {
\r
250 #if defined(_USE_SDL) || defined(_USE_AGAR) || defined(_USE_QT)
\r
256 sound_started = false;
\r
258 // reinitialize virtual machine
\r
259 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
260 if(pVMSemaphore) SDL_SemWait(pVMSemaphore);
\r
264 vm->initialize_sound(sound_rate, sound_samples);
\r
266 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
267 if(pVMSemaphore) SDL_SemPost(pVMSemaphore);
\r
269 // restore inserted medias
\r
272 // reset virtual machine
\r
279 // restart recording
\r
280 restart_rec_sound();
\r
281 restart_rec_video();
\r
284 #ifdef USE_SPECIAL_RESET
\r
285 void EMU::special_reset()
\r
287 // reset virtual machine
\r
288 vm->special_reset();
\r
293 // restart recording
\r
294 restart_rec_sound();
\r
295 restart_rec_video();
\r
299 #ifdef USE_POWER_OFF
\r
300 void EMU::notify_power_off()
\r
302 vm->notify_power_off();
\r
306 _TCHAR* EMU::bios_path(_TCHAR* file_name)
\r
308 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
\r
309 static _TCHAR file_path[_MAX_PATH];
\r
310 strcpy(file_path, app_path);
\r
311 strcat(file_path, file_name);
\r
312 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
\r
313 AGAR_DebugLog(AGAR_LOG_INFO, "LOAD BIOS: %s\n", file_path);
\r
316 static _TCHAR file_path[_MAX_PATH];
\r
317 _stprintf(file_path, _T("%s%s"), app_path, file_name);
\r
318 printf("LOAD: %s\n", file_path);
\r
323 void EMU::suspend()
\r
325 if(!now_suspended) {
\r
326 #ifdef USE_LASER_DISC
\r
327 if(now_movie_play && !now_movie_pause) {
\r
329 now_movie_pause = false;
\r
333 now_suspended = true;
\r
337 // ----------------------------------------------------------------------------
\r
339 // ----------------------------------------------------------------------------
\r
341 void EMU::get_host_time(cur_time_t* t)
\r
343 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
\r
346 tnow = std::time(NULL);
\r
347 tm = std::localtime(&tnow);
\r
349 t->year = tm->tm_year + 1900;
\r
350 t->month = tm->tm_mon + 1;
\r
351 t->day = tm->tm_mday;
\r
352 t->day_of_week = tm->tm_wday;
\r
353 t->hour = tm->tm_hour;
\r
354 t->minute = tm->tm_min;
\r
355 t->second = tm->tm_sec;
\r
358 GetLocalTime(&sTime);
\r
360 t->year = sTime.wYear;
\r
361 t->month = sTime.wMonth;
\r
362 t->day = sTime.wDay;
\r
363 t->day_of_week = sTime.wDayOfWeek;
\r
364 t->hour = sTime.wHour;
\r
365 t->minute = sTime.wMinute;
\r
366 t->second = sTime.wSecond;
\r
370 // ----------------------------------------------------------------------------
\r
372 // ----------------------------------------------------------------------------
\r
374 void EMU::initialize_printer()
\r
376 prn_fio = new FILEIO();
\r
378 prn_strobe = false;
\r
381 void EMU::release_printer()
\r
383 close_printer_file();
\r
387 void EMU::reset_printer()
\r
389 close_printer_file();
\r
391 prn_strobe = false;
\r
394 void EMU::update_printer()
\r
396 if(prn_fio->IsOpened() && --prn_wait_frames == 0) {
\r
397 close_printer_file();
\r
401 void EMU::open_printer_file()
\r
404 get_host_time(&time);
\r
405 _stprintf(prn_file_name, _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);
\r
406 prn_fio->Fopen(bios_path(prn_file_name), FILEIO_WRITE_BINARY);
\r
409 void EMU::close_printer_file()
\r
411 if(prn_fio->IsOpened()) {
\r
412 // remove if the file size is less than 2 bytes
\r
413 bool remove = (prn_fio->Ftell() < 2);
\r
416 prn_fio->Remove(bios_path(prn_file_name));
\r
421 void EMU::printer_out(uint8 value)
\r
426 void EMU::printer_strobe(bool value)
\r
428 bool falling = (prn_strobe && !value);
\r
429 prn_strobe = value;
\r
432 if(!prn_fio->IsOpened()) {
\r
433 if(prn_data == -1) {
\r
436 open_printer_file();
\r
438 prn_fio->Fputc(prn_data);
\r
440 #ifdef SUPPORT_VARIABLE_TIMING
\r
441 prn_wait_frames = (int)(vm->frame_rate() * 10.0 + 0.5);
\r
443 prn_wait_frames = (int)(FRAMES_PER_SEC * 10.0 + 0.5);
\r
448 // ----------------------------------------------------------------------------
\r
450 // ----------------------------------------------------------------------------
\r
453 void EMU::initialize_debug_log()
\r
455 debug_log = _tfopen(_T("d:\\debug.log"), _T("w"));
\r
458 void EMU::release_debug_log()
\r
466 void EMU::out_debug_log(const _TCHAR* format, ...)
\r
470 _TCHAR buffer[1024];
\r
471 static _TCHAR prev_buffer[1024] = {0};
\r
473 va_start(ap, format);
\r
474 _vstprintf(buffer, format, ap);
\r
477 if(_tcscmp(prev_buffer, buffer) == 0) {
\r
480 _tcscpy(prev_buffer, buffer);
\r
483 _ftprintf(debug_log, _T("%s"), buffer);
\r
484 static int size = 0;
\r
485 if((size += _tcslen(buffer)) > 0x8000000) { // 128MB
\r
486 static int index = 1;
\r
487 TCHAR path[_MAX_PATH];
\r
488 _stprintf(path, _T("d:\\debug_#%d.log"), ++index);
\r
490 debug_log = _tfopen(path, _T("w"));
\r
497 void EMU::out_message(const _TCHAR* format, ...)
\r
500 va_start(ap, format);
\r
501 _vstprintf(message, format, ap);
\r
503 message_count = 4; // 4sec
\r
506 // ----------------------------------------------------------------------------
\r
508 // ----------------------------------------------------------------------------
\r
510 void EMU::initialize_media()
\r
513 memset(&cart_status, 0, sizeof(cart_status));
\r
516 memset(disk_status, 0, sizeof(disk_status));
\r
519 memset(&quickdisk_status, 0, sizeof(quickdisk_status));
\r
522 memset(&tape_status, 0, sizeof(tape_status));
\r
524 #ifdef USE_LASER_DISC
\r
525 memset(&laser_disc_status, 0, sizeof(laser_disc_status));
\r
529 #if defined(USE_FD1) || defined(USE_FD2) || defined(USE_FD3) || defined(USE_FD4) || \
\r
530 defined(USE_FD5) || defined(USE_FD6) || defined(USE_FD7) || defined(USE_FD8)
\r
533 void EMU::write_protect_fd(int drv, bool flag)
\r
535 vm->write_protect_fd(drv, flag);
\r
537 bool EMU::is_write_protected_fd(int drv)
\r
539 return vm->is_write_protect_fd(drv);
\r
543 void EMU::update_media()
\r
546 for(int drv = 0; drv < MAX_FD; drv++) {
\r
547 if(disk_status[drv].wait_count != 0 && --disk_status[drv].wait_count == 0) {
\r
548 vm->open_disk(drv, disk_status[drv].path, disk_status[drv].offset);
\r
549 out_message(_T("FD%d: %s"), drv + FD_BASE_NUMBER, disk_status[drv].path);
\r
554 for(int drv = 0; drv < MAX_QD; drv++) {
\r
555 if(quickdisk_status[drv].wait_count != 0 && --quickdisk_status[drv].wait_count == 0) {
\r
556 vm->open_quickdisk(drv, quickdisk_status[drv].path);
\r
557 out_message(_T("QD%d: %s"), drv + QD_BASE_NUMBER, quickdisk_status[drv].path);
\r
562 if(tape_status.wait_count != 0 && --tape_status.wait_count == 0) {
\r
563 if(tape_status.play) {
\r
564 vm->play_tape(tape_status.path);
\r
566 vm->rec_tape(tape_status.path);
\r
568 out_message(_T("CMT: %s"), tape_status.path);
\r
571 #ifdef USE_LASER_DISC
\r
572 if(laser_disc_status.wait_count != 0 && --laser_disc_status.wait_count == 0) {
\r
573 vm->open_laser_disc(laser_disc_status.path);
\r
574 out_message(_T("LD: %s"), laser_disc_status.path);
\r
579 void EMU::restore_media()
\r
582 for(int drv = 0; drv < MAX_CART; drv++) {
\r
583 if(cart_status[drv].path[0] != _T('\0')) {
\r
584 vm->open_cart(drv, cart_status[drv].path);
\r
589 for(int drv = 0; drv < MAX_FD; drv++) {
\r
590 if(disk_status[drv].path[0] != _T('\0')) {
\r
591 vm->open_disk(drv, disk_status[drv].path, disk_status[drv].offset);
\r
596 for(int drv = 0; drv < MAX_QD; drv++) {
\r
597 if(quickdisk_status[drv].path[0] != _T('\0')) {
\r
598 vm->open_quickdisk(drv, quickdisk_status[drv].path);
\r
603 if(tape_status.path[0] != _T('\0')) {
\r
604 if(tape_status.play) {
\r
605 vm->play_tape(tape_status.path);
\r
607 tape_status.path[0] = _T('\0');
\r
611 #ifdef USE_LASER_DISC
\r
612 if(laser_disc_status.path[0] != _T('\0')) {
\r
613 vm->open_laser_disc(laser_disc_status.path);
\r
619 void EMU::open_cart(int drv, _TCHAR* file_path)
\r
621 if(drv < MAX_CART) {
\r
622 vm->open_cart(drv, file_path);
\r
623 _tcscpy(cart_status[drv].path, file_path);
\r
624 out_message(_T("Cart%d: %s"), drv + 1, file_path);
\r
626 // restart recording
\r
627 bool s = now_rec_sound;
\r
628 bool v = now_rec_video;
\r
631 if(s) start_rec_sound();
\r
632 if(v) start_rec_video(-1);
\r
636 void EMU::close_cart(int drv)
\r
638 if(drv < MAX_CART) {
\r
639 vm->close_cart(drv);
\r
640 clear_media_status(&cart_status[drv]);
\r
641 out_message(_T("Cart%d: Ejected"), drv + 1);
\r
649 bool EMU::cart_inserted(int drv)
\r
651 if(drv < MAX_CART) {
\r
652 return vm->cart_inserted(drv);
\r
660 void EMU::open_disk(int drv, _TCHAR* file_path, int offset)
\r
663 if(vm->disk_inserted(drv)) {
\r
664 vm->close_disk(drv);
\r
666 #ifdef SUPPORT_VARIABLE_TIMING
\r
667 disk_status[drv].wait_count = (int)(vm->frame_rate() / 2);
\r
669 disk_status[drv].wait_count = (int)(FRAMES_PER_SEC / 2);
\r
671 out_message(_T("FD%d: Ejected"), drv + FD_BASE_NUMBER);
\r
672 } else if(disk_status[drv].wait_count == 0) {
\r
673 vm->open_disk(drv, file_path, offset);
\r
674 out_message(_T("FD%d: %s"), drv + FD_BASE_NUMBER, file_path);
\r
676 _tcscpy(disk_status[drv].path, file_path);
\r
677 disk_status[drv].offset = offset;
\r
681 void EMU::close_disk(int drv)
\r
684 vm->close_disk(drv);
\r
685 clear_media_status(&disk_status[drv]);
\r
686 out_message(_T("FD%d: Ejected"), drv + FD_BASE_NUMBER);
\r
690 bool EMU::disk_inserted(int drv)
\r
693 return vm->disk_inserted(drv);
\r
701 void EMU::open_quickdisk(int drv, _TCHAR* file_path)
\r
704 if(vm->quickdisk_inserted(drv)) {
\r
705 vm->close_quickdisk(drv);
\r
707 #ifdef SUPPORT_VARIABLE_TIMING
\r
708 quickdisk_status[drv].wait_count = (int)(vm->frame_rate() / 2);
\r
710 quickdisk_status[drv].wait_count = (int)(FRAMES_PER_SEC / 2);
\r
712 out_message(_T("QD%d: Ejected"), drv + QD_BASE_NUMBER);
\r
713 } else if(quickdisk_status[drv].wait_count == 0) {
\r
714 vm->open_quickdisk(drv, file_path);
\r
715 out_message(_T("QD%d: %s"), drv + QD_BASE_NUMBER, file_path);
\r
717 _tcscpy(quickdisk_status[drv].path, file_path);
\r
721 void EMU::close_quickdisk(int drv)
\r
724 vm->close_quickdisk(drv);
\r
725 clear_media_status(&quickdisk_status[drv]);
\r
726 out_message(_T("QD%d: Ejected"), drv + QD_BASE_NUMBER);
\r
730 bool EMU::quickdisk_inserted(int drv)
\r
733 return vm->quickdisk_inserted(drv);
\r
741 void EMU::play_tape(_TCHAR* file_path)
\r
743 if(vm->tape_inserted()) {
\r
746 #ifdef SUPPORT_VARIABLE_TIMING
\r
747 tape_status.wait_count = (int)(vm->frame_rate() / 2);
\r
749 tape_status.wait_count = (int)(FRAMES_PER_SEC / 2);
\r
751 out_message(_T("CMT: Ejected"));
\r
752 } else if(tape_status.wait_count == 0) {
\r
753 vm->play_tape(file_path);
\r
754 out_message(_T("CMT: %s"), file_path);
\r
756 _tcscpy(tape_status.path, file_path);
\r
757 tape_status.play = true;
\r
760 void EMU::rec_tape(_TCHAR* file_path)
\r
762 if(vm->tape_inserted()) {
\r
765 #ifdef SUPPORT_VARIABLE_TIMING
\r
766 tape_status.wait_count = (int)(vm->frame_rate() / 2);
\r
768 tape_status.wait_count = (int)(FRAMES_PER_SEC / 2);
\r
770 out_message(_T("CMT: Ejected"));
\r
771 } else if(tape_status.wait_count == 0) {
\r
772 vm->rec_tape(file_path);
\r
773 out_message(_T("CMT: %s"), file_path);
\r
775 _tcscpy(tape_status.path, file_path);
\r
776 tape_status.play = false;
\r
779 void EMU::close_tape()
\r
782 clear_media_status(&tape_status);
\r
783 out_message(_T("CMT: Ejected"));
\r
786 bool EMU::tape_inserted()
\r
788 return vm->tape_inserted();
\r
792 #ifdef USE_LASER_DISC
\r
793 void EMU::open_laser_disc(_TCHAR* file_path)
\r
795 if(vm->laser_disc_inserted()) {
\r
796 vm->close_laser_disc();
\r
798 #ifdef SUPPORT_VARIABLE_TIMING
\r
799 laser_disc_status.wait_count = (int)(vm->frame_rate() / 2);
\r
801 laser_disc_status.wait_count = (int)(FRAMES_PER_SEC / 2);
\r
803 out_message(_T("LD: Ejected"));
\r
804 } else if(laser_disc_status.wait_count == 0) {
\r
805 vm->open_laser_disc(file_path);
\r
806 out_message(_T("LD: %s"), file_path);
\r
808 _tcscpy(laser_disc_status.path, file_path);
\r
811 void EMU::close_laser_disc()
\r
813 vm->close_laser_disc();
\r
814 clear_media_status(&laser_disc_status);
\r
815 out_message(_T("LD: Ejected"));
\r
818 bool EMU::laser_disc_inserted()
\r
820 return vm->laser_disc_inserted();
\r
824 #ifdef USE_TAPE_BUTTON
\r
825 void EMU::push_play()
\r
830 void EMU::push_stop()
\r
836 #ifdef USE_BINARY_FILE1
\r
837 void EMU::load_binary(int drv, _TCHAR* file_path)
\r
839 if(drv < MAX_BINARY) {
\r
840 vm->load_binary(drv, file_path);
\r
841 out_message(_T("Load: %s"), file_path);
\r
845 void EMU::save_binary(int drv, _TCHAR* file_path)
\r
847 if(drv < MAX_BINARY) {
\r
848 vm->save_binary(drv, file_path);
\r
849 out_message(_T("Save: %s"), file_path);
\r
854 bool EMU::now_skip()
\r
856 return vm->now_skip();
\r
859 void EMU::update_config()
\r
861 vm->update_config();
\r
865 // ----------------------------------------------------------------------------
\r
867 // ----------------------------------------------------------------------------
\r
869 #define STATE_VERSION 1
\r
871 void EMU::save_state()
\r
873 _TCHAR file_name[_MAX_PATH];
\r
874 _stprintf(file_name, _T("%s.sta"), _T(CONFIG_NAME));
\r
875 save_state_tmp(bios_path(file_name));
\r
878 void EMU::load_state()
\r
880 _TCHAR file_name[_MAX_PATH];
\r
881 _stprintf(file_name, _T("%s.sta"), _T(CONFIG_NAME));
\r
882 save_state_tmp(bios_path(_T("$temp$.sta")));
\r
883 if(!load_state_tmp(bios_path(file_name))) {
\r
884 load_state_tmp(bios_path(_T("$temp$.sta")));
\r
886 DeleteFile(bios_path(_T("$temp$.sta")));
\r
889 void EMU::save_state_tmp(_TCHAR* file_path)
\r
891 FILEIO* fio = new FILEIO();
\r
892 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
893 if(pVMSemaphore) SDL_SemWait(pVMSemaphore);
\r
895 if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
\r
896 // save state file version
\r
897 fio->FputUint32(STATE_VERSION);
\r
899 save_config_state((void *)fio);
\r
900 // save inserted medias
\r
902 fio->Fwrite(&cart_status, sizeof(cart_status), 1);
\r
905 fio->Fwrite(disk_status, sizeof(disk_status), 1);
\r
906 fio->Fwrite(d88_file, sizeof(d88_file), 1);
\r
909 fio->Fwrite(&quickdisk_status, sizeof(quickdisk_status), 1);
\r
912 fio->Fwrite(&tape_status, sizeof(tape_status), 1);
\r
914 #ifdef USE_LASER_DISC
\r
915 fio->Fwrite(&laser_disc_status, sizeof(laser_disc_status), 1);
\r
918 vm->save_state(fio);
\r
919 // end of state file
\r
920 fio->FputInt32(-1);
\r
923 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
924 if(pVMSemaphore) SDL_SemPost(pVMSemaphore);
\r
929 bool EMU::load_state_tmp(_TCHAR* file_path)
\r
931 bool result = false;
\r
932 FILEIO* fio = new FILEIO();
\r
933 if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
\r
934 // check state file version
\r
935 if(fio->FgetUint32() == STATE_VERSION) {
\r
937 if(load_config_state((void *)fio)) {
\r
938 // load inserted medias
\r
940 fio->Fread(&cart_status, sizeof(cart_status), 1);
\r
943 fio->Fread(disk_status, sizeof(disk_status), 1);
\r
944 fio->Fread(d88_file, sizeof(d88_file), 1);
\r
947 fio->Fread(&quickdisk_status, sizeof(quickdisk_status), 1);
\r
950 fio->Fread(&tape_status, sizeof(tape_status), 1);
\r
952 #ifdef USE_LASER_DISC
\r
953 fio->Fread(&laser_disc_status, sizeof(laser_disc_status), 1);
\r
955 // check if virtual machine should be reinitialized
\r
956 bool reinitialize = false;
\r
957 #ifdef USE_CPU_TYPE
\r
958 reinitialize |= (cpu_type != config.cpu_type);
\r
959 cpu_type = config.cpu_type;
\r
961 #ifdef USE_SOUND_DEVICE_TYPE
\r
962 reinitialize |= (sound_device_type != config.sound_device_type);
\r
963 sound_device_type = config.sound_device_type;
\r
967 if(sound_ok && sound_started) {
\r
968 #if defined(_USE_SDL) || defined(_USE_AGAR) || defined(_USE_QT)
\r
974 sound_started = false;
\r
976 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
977 if(pVMSemaphore) SDL_SemWait(pVMSemaphore);
\r
979 // reinitialize virtual machine
\r
982 vm->initialize_sound(sound_rate, sound_samples);
\r
984 #if defined(_USE_AGAR) || (_USE_SDL) || defined(_USE_QT)
\r
985 if(pVMSemaphore) SDL_SemPost(pVMSemaphore);
\r
988 // restore inserted medias
\r
991 if(vm->load_state(fio)) {
\r
992 // check end of state
\r
993 result = (fio->FgetInt32() == -1);
\r