/** * Change given Hatari options * Return false if parsing failed, true otherwise */ static bool Change_Options(int argc, const char *argv[]) { bool bOK; CNF_PARAMS current; Main_PauseEmulation(false); /* get configuration changes */ current = ConfigureParams; ConfigureParams.Screen.bFullScreen = bInFullScreen; bOK = Opt_ParseParameters(argc, argv); /* Check if reset is required and ask user if he really wants to continue */ if (bOK && Change_DoNeedReset(¤t, &ConfigureParams) && current.Log.nAlertDlgLogLevel > LOG_FATAL) { bOK = DlgAlert_Query("The emulated system must be " "reset to apply these changes. " "Apply changes now and reset " "the emulator?"); } /* Copy details to configuration */ if (bOK) { if (!Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, false)) { ConfigureParams = current; DlgAlert_Notice("Return to old parameters..."); Reset_Cold(); } } else { ConfigureParams = current; } Main_UnPauseEmulation(); return bOK; }
/** * Shorcut to debug interface */ static void ShortCut_Debug(void) { int running; /* Call the debugger */ running = Main_PauseEmulation(true); DebugUI(); if (running) Main_UnPauseEmulation(); }
/** * Shortcut to 'Boss' key, ie minmize Window and switch to another application */ static void ShortCut_BossKey(void) { /* If we are in full-screen, then return to a window */ Screen_ReturnFromFullScreen(); if (bGrabMouse) { SDL_SetRelativeMouseMode(SDL_FALSE); SDL_SetWindowGrab(sdlWindow, SDL_FALSE); bGrabMouse = false; } Main_PauseEmulation(true); /* Minimize Window and give up processing to next one! */ fprintf(stderr,"FIXME: minimize window!\n"); }
/** * Open Property sheet Options dialog. * * We keep all our configuration details in a structure called * 'ConfigureParams'. When we open our dialog we make a backup * of this structure. When the user finally clicks on 'OK', * we can compare and makes the necessary changes. * * Return true if user chooses OK, or false if cancel! */ bool Dialog_DoProperty(void) { bool bOKDialog; /* Did user 'OK' dialog? */ bool bForceReset; bool bLoadedSnapshot; CNF_PARAMS current; Main_PauseEmulation(true); bForceReset = false; /* Copy details (this is so can restore if 'Cancel' dialog) */ current = ConfigureParams; ConfigureParams.Screen.bFullScreen = bInFullScreen; bOKDialog = Dialog_MainDlg(&bForceReset, &bLoadedSnapshot); /* If a memory snapshot has been loaded, no further changes are required */ if (bLoadedSnapshot) { Main_UnPauseEmulation(); return true; } /* Check if reset is required and ask user if he really wants to continue then */ if (bOKDialog && !bForceReset && Change_DoNeedReset(¤t, &ConfigureParams) && ConfigureParams.Log.nAlertDlgLogLevel > LOG_FATAL) { bOKDialog = DlgAlert_Query("The emulated system must be " "reset to apply these changes. " "Apply changes now and reset " "the emulator?"); } /* Copy details to configuration */ if (bOKDialog) { Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, bForceReset); } else { ConfigureParams = current; } Main_UnPauseEmulation(); if (bQuitProgram) Main_RequestQuit(); return bOKDialog; }
/** * Shortcut to 'Boss' key, ie minmize Window and switch to another application */ static void ShortCut_BossKey(void) { /* If we are in full-screen, then return to a window */ Screen_ReturnFromFullScreen(); if (bGrabMouse) { SDL_WM_GrabInput(SDL_GRAB_OFF); bGrabMouse = false; } Main_PauseEmulation(true); /* Minimize Window and give up processing to next one! */ #if WITH_SDL2 SDL_MinimizeWindow(sdlWindow); #else SDL_WM_IconifyWindow(); #endif }
/** * Shorcut to load a disk image */ static void ShortCut_InsertDisk(int drive) { char *selname, *zip_path = NULL; const char *tmpname; char FileNameB[ FILENAME_MAX ]; char ZipPathB[ FILENAME_MAX ]; if (SDLGui_SetScreen(sdlscrn)) return; /* Save current names for drive 1 before checking autoinsert */ strcpy ( FileNameB , ConfigureParams.DiskImage.szDiskFileName[ 1 ] ); strcpy ( ZipPathB , ConfigureParams.DiskImage.szDiskZipPath[ 1 ] ); if (ConfigureParams.DiskImage.szDiskFileName[drive][0]) tmpname = ConfigureParams.DiskImage.szDiskFileName[drive]; else tmpname = ConfigureParams.DiskImage.szDiskImageDirectory; Main_PauseEmulation(true); selname = SDLGui_FileSelect("Floppy image:", tmpname, &zip_path, false); if (selname) { if (File_Exists(selname)) Floppy_SetDiskFileName(drive, selname, zip_path); else Floppy_SetDiskFileNameNone(drive); if (zip_path) free(zip_path); free(selname); Floppy_InsertDiskIntoDrive(0); /* Check if inserting into drive 0 also changed drive 1 with autoinsert */ if ( ( strcmp ( FileNameB , ConfigureParams.DiskImage.szDiskFileName[ 1 ] ) != 0 ) || ( strcmp ( FileNameB , ConfigureParams.DiskImage.szDiskZipPath[ 1 ] ) != 0 ) ) Floppy_InsertDiskIntoDrive(1); } Main_UnPauseEmulation(); }
/** * Return from Full screen mode back to a window */ void Screen_ReturnFromFullScreen(void) { bool bWasRunning; if (bInFullScreen) { /* Hold things... */ bWasRunning = Main_PauseEmulation(false); bInFullScreen = false; if (Screen_UseHostScreen()) { // HostScreen_toggleFullScreen(); } else { SDL_SetWindowFullscreen(sdlWindow, 0); //Screen_SetResolution(); } SDL_Delay(20); /* To give monitor time to switch resolution */ if (bWasRunning) { /* And off we go... */ Main_UnPauseEmulation(); } else { Screen_Refresh(); } if (!bGrabMouse) { /* Un-grab mouse pointer in windowed mode */ SDL_SetRelativeMouseMode(SDL_FALSE); SDL_SetWindowGrab(sdlWindow, SDL_FALSE); } } }
/** * Enter Full screen mode */ void Screen_EnterFullScreen(void) { bool bWasRunning; if (!bInFullScreen) { /* Hold things... */ bWasRunning = Main_PauseEmulation(false); bInFullScreen = true; if (Screen_UseHostScreen()) { // HostScreen_toggleFullScreen(); } else { SDL_SetWindowFullscreen(sdlWindow, SDL_WINDOW_FULLSCREEN_DESKTOP); //Screen_SetResolution(); //Screen_ClearScreen(); /* Black out screen bitmap as will be invalid when return */ } SDL_Delay(20); /* To give monitor time to change to new resolution */ if (bWasRunning) { /* And off we go... */ Main_UnPauseEmulation(); } else { Screen_Refresh(); } SDL_SetRelativeMouseMode(SDL_TRUE); SDL_SetWindowGrab(sdlWindow, SDL_TRUE); } }
/** * Shorcut to pausing */ static void ShortCut_Pause(void) { if (!Main_UnPauseEmulation()) Main_PauseEmulation(true); }
/** * This function waits on each emulated VBL to synchronize the real time * with the emulated ST. * Unfortunately SDL_Delay and other sleep functions like usleep or nanosleep * are very inaccurate on some systems like Linux 2.4 or Mac OS X (they can only * wait for a multiple of 10ms due to the scheduler on these systems), so we have * to "busy wait" there to get an accurate timing. * All times are expressed as micro seconds, to avoid too much rounding error. */ void Main_WaitOnVbl(void) { Sint64 CurrentTicks; static Sint64 DestTicks = 0; Sint64 FrameDuration_micro; Sint64 nDelay; nVBLCount++; if (nRunVBLs && nVBLCount >= nRunVBLs) { /* show VBLs/s */ Main_PauseEmulation(true); exit(0); } // FrameDuration_micro = (Sint64) ( 1000000.0 / nScreenRefreshRate + 0.5 ); /* round to closest integer */ FrameDuration_micro = ClocksTimings_GetVBLDuration_micro ( ConfigureParams.System.nMachineType , 68 ); // FrameDuration_micro = 1000000/50; CurrentTicks = Time_GetTicks(); if ( DestTicks == 0 ) /* first call, init DestTicks */ { DestTicks = CurrentTicks + FrameDuration_micro; } nDelay = DestTicks - CurrentTicks; /* Do not wait if we are in fast forward mode or if we are totally out of sync */ if (ConfigureParams.System.bFastForward == true || nDelay < -4*FrameDuration_micro || nDelay > 50*FrameDuration_micro) { if (ConfigureParams.System.bFastForward == true) { if (!nFirstMilliTick) nFirstMilliTick = Main_GetTicks(); } if (nFrameSkips < ConfigureParams.Screen.nFrameSkips) { nFrameSkips += 1; Log_Printf(LOG_DEBUG, "Increased frameskip to %d\n", nFrameSkips); } /* Only update DestTicks for next VBL */ DestTicks = CurrentTicks + FrameDuration_micro; return; } /* If automatic frameskip is enabled and delay's more than twice * the effect of single frameskip, decrease frameskip */ if (nFrameSkips > 0 && ConfigureParams.Screen.nFrameSkips >= AUTO_FRAMESKIP_LIMIT && 2*nDelay > FrameDuration_micro/nFrameSkips) { nFrameSkips -= 1; Log_Printf(LOG_DEBUG, "Decreased frameskip to %d\n", nFrameSkips); } if (bAccurateDelays) { /* Accurate sleeping is possible -> use SDL_Delay to free the CPU */ if (nDelay > 1000) Time_Delay(nDelay - 1000); } else { /* No accurate SDL_Delay -> only wait if more than 5ms to go... */ if (nDelay > 5000) Time_Delay(nDelay<10000 ? nDelay-1000 : 9000); } /* Now busy-wait for the right tick: */ while (nDelay > 0) { CurrentTicks = Time_GetTicks(); nDelay = DestTicks - CurrentTicks; /* If the delay is still bigger than one frame, somebody * played tricks with the system clock and we have to abort */ if (nDelay > FrameDuration_micro) break; } //printf ( "tick %lld\n" , CurrentTicks ); /* Update DestTicks for next VBL */ DestTicks += FrameDuration_micro; }