|
|
1.1 root 1: /*
1.1.1.5 root 2: Hatari - shortcut.c
3:
1.1.1.16 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6:
7: Shortcut keys
8: */
1.1.1.12 root 9: const char ShortCut_fileid[] = "Hatari shortcut.c : " __DATE__ " " __TIME__;
1.1 root 10:
1.1.1.2 root 11: #include <SDL.h>
12:
1.1 root 13: #include "main.h"
14: #include "dialog.h"
15: #include "audio.h"
1.1.1.10 root 16: #include "file.h"
17: #include "floppy.h"
1.1 root 18: #include "joy.h"
1.1.1.18! root 19: #include "keymap.h"
1.1.1.5 root 20: #include "m68000.h"
1.1 root 21: #include "memorySnapShot.h"
22: #include "reset.h"
23: #include "screen.h"
24: #include "screenSnapShot.h"
1.1.1.8 root 25: #include "configuration.h"
1.1 root 26: #include "shortcut.h"
1.1.1.10 root 27: #include "debugui.h"
1.1 root 28: #include "sound.h"
1.1.1.10 root 29: #include "sdlgui.h"
1.1.1.13 root 30: #include "video.h"
31: #include "avi_record.h"
1.1.1.14 root 32: #include "clocks_timings.h"
1.1.1.2 root 33:
1.1.1.8 root 34: static SHORTCUTKEYIDX ShortCutKey = SHORTCUT_NONE; /* current shortcut key */
1.1 root 35:
1.1.1.4 root 36:
1.1.1.2 root 37: /*-----------------------------------------------------------------------*/
1.1.1.9 root 38: /**
39: * Shortcut to toggle full-screen
40: */
1.1.1.5 root 41: static void ShortCut_FullScreen(void)
1.1 root 42: {
1.1.1.9 root 43: if (!bInFullScreen)
44: {
45: Screen_EnterFullScreen();
46: }
47: else
48: {
49: Screen_ReturnFromFullScreen();
50: }
1.1 root 51: }
52:
1.1.1.4 root 53:
54: /*-----------------------------------------------------------------------*/
1.1.1.9 root 55: /**
1.1.1.13 root 56: * Shortcut to toggle mouse grabbing mode
1.1.1.9 root 57: */
1.1.1.13 root 58: static void ShortCut_MouseGrab(void)
1.1 root 59: {
1.1.1.9 root 60: bGrabMouse = !bGrabMouse; /* Toggle flag */
1.1 root 61:
1.1.1.9 root 62: /* If we are in windowed mode, toggle the mouse cursor mode now: */
63: if (!bInFullScreen)
64: {
65: if (bGrabMouse)
66: {
67: SDL_WM_GrabInput(SDL_GRAB_ON);
68: }
69: else
70: {
71: SDL_WM_GrabInput(SDL_GRAB_OFF);
72: }
73: }
1.1 root 74: }
75:
1.1.1.4 root 76:
1.1.1.5 root 77: /*-----------------------------------------------------------------------*/
1.1.1.9 root 78: /**
79: * Shortcut to toggle YM/WAV sound recording
80: */
1.1.1.5 root 81: static void ShortCut_RecordSound(void)
1.1 root 82: {
1.1.1.9 root 83: /* Is working? */
84: if (bSoundWorking)
85: {
86: /* Are we currently recording? If so stop */
87: if (Sound_AreWeRecording())
88: {
89: /* Stop, and save */
90: Sound_EndRecording();
91: }
92: else
93: {
94: /* Begin recording */
95: Sound_BeginRecording(ConfigureParams.Sound.szYMCaptureFileName);
96: }
97: }
1.1 root 98: }
99:
1.1.1.5 root 100:
101: /*-----------------------------------------------------------------------*/
1.1.1.9 root 102: /**
103: * Shortcut to toggle screen animation recording
104: */
1.1.1.5 root 105: static void ShortCut_RecordAnimation(void)
1.1 root 106: {
1.1.1.9 root 107: /* Are we currently recording? If so stop */
1.1.1.13 root 108: if (Avi_AreWeRecording())
1.1.1.9 root 109: {
110: /* Stop */
1.1.1.13 root 111: Avi_StopRecording();
1.1.1.9 root 112: }
113: else
114: {
115: /* Start animation */
1.1.1.14 root 116: Avi_StartRecording ( ConfigureParams.Video.AviRecordFile , ConfigureParams.Screen.bCrop ,
117: ConfigureParams.Video.AviRecordFps == 0 ?
118: ClocksTimings_GetVBLPerSec ( ConfigureParams.System.nMachineType , nScreenRefreshRate ) :
119: (Uint32)ConfigureParams.Video.AviRecordFps << CLOCKS_TIMINGS_SHIFT_VBL ,
120: 1 << CLOCKS_TIMINGS_SHIFT_VBL ,
121: ConfigureParams.Video.AviRecordVcodec );
1.1.1.9 root 122: }
1.1 root 123: }
124:
1.1.1.4 root 125:
126: /*-----------------------------------------------------------------------*/
1.1.1.9 root 127: /**
128: * Shortcut to sound on/off
129: */
1.1.1.5 root 130: static void ShortCut_SoundOnOff(void)
1.1 root 131: {
1.1.1.9 root 132: /* Toggle sound on/off */
1.1.1.12 root 133: ConfigureParams.Sound.bEnableSound ^= true;
1.1.1.9 root 134:
135: /* And start/stop if need to */
136: if (!ConfigureParams.Sound.bEnableSound)
137: {
138: if (Sound_AreWeRecording())
139: Sound_EndRecording();
140: Audio_UnInit();
141: }
142: else
143: {
144: Audio_Init();
145: }
1.1 root 146: }
147:
1.1.1.5 root 148:
149: /*-----------------------------------------------------------------------*/
1.1.1.9 root 150: /**
1.1.1.10 root 151: * Shortcut to fast forward
1.1.1.9 root 152: */
1.1.1.10 root 153: static void ShortCut_FastForward(void)
1.1 root 154: {
1.1.1.9 root 155: /* If already on max speed, switch back to normal */
1.1.1.12 root 156: if (ConfigureParams.System.bFastForward == true)
1.1.1.9 root 157: {
158: /* Restore */
1.1.1.12 root 159: ConfigureParams.System.bFastForward = false;
1.1.1.9 root 160:
161: /* Reset the sound emulation variables: */
1.1.1.14 root 162: Sound_BufferIndexNeedReset = true;
1.1.1.9 root 163: }
164: else
165: {
166: /* Set maximum speed */
1.1.1.12 root 167: ConfigureParams.System.bFastForward = true;
1.1.1.9 root 168: }
1.1 root 169: }
170:
1.1.1.5 root 171:
172: /*-----------------------------------------------------------------------*/
1.1.1.9 root 173: /**
174: * Shortcut to 'Boss' key, ie minmize Window and switch to another application
175: */
1.1.1.5 root 176: static void ShortCut_BossKey(void)
1.1 root 177: {
1.1.1.9 root 178: /* If we are in full-screen, then return to a window */
179: Screen_ReturnFromFullScreen();
1.1.1.5 root 180:
1.1.1.9 root 181: if (bGrabMouse)
182: {
183: SDL_WM_GrabInput(SDL_GRAB_OFF);
1.1.1.12 root 184: bGrabMouse = false;
1.1.1.9 root 185: }
1.1.1.12 root 186: Main_PauseEmulation(true);
1.1.1.5 root 187:
1.1.1.9 root 188: /* Minimize Window and give up processing to next one! */
1.1.1.18! root 189: #if WITH_SDL2
! 190: SDL_MinimizeWindow(sdlWindow);
! 191: #else
1.1.1.9 root 192: SDL_WM_IconifyWindow();
1.1.1.18! root 193: #endif
1.1 root 194: }
195:
1.1.1.4 root 196:
197: /*-----------------------------------------------------------------------*/
1.1.1.9 root 198: /**
1.1.1.12 root 199: * Shorcut to debug interface
1.1.1.10 root 200: */
1.1.1.12 root 201: static void ShortCut_Debug(void)
1.1.1.10 root 202: {
1.1.1.12 root 203: int running;
1.1.1.10 root 204:
1.1.1.12 root 205: /* Call the debugger */
206: running = Main_PauseEmulation(true);
1.1.1.15 root 207: DebugUI(REASON_USER);
1.1.1.12 root 208: if (running)
209: Main_UnPauseEmulation();
1.1.1.10 root 210: }
211:
212:
1.1.1.12 root 213: /*-----------------------------------------------------------------------*/
214: /**
215: * Shorcut to pausing
216: */
217: static void ShortCut_Pause(void)
218: {
219: if (!Main_UnPauseEmulation())
220: Main_PauseEmulation(true);
221: }
222:
1.1.1.10 root 223: /**
224: * Shorcut to load a disk image
225: */
226: static void ShortCut_InsertDisk(int drive)
227: {
228: char *selname, *zip_path = NULL;
229: const char *tmpname;
1.1.1.17 root 230: char FileNameB[ FILENAME_MAX ];
231: char ZipPathB[ FILENAME_MAX ];
1.1.1.10 root 232:
233: if (SDLGui_SetScreen(sdlscrn))
234: return;
235:
1.1.1.17 root 236: /* Save current names for drive 1 before checking autoinsert */
237: strcpy ( FileNameB , ConfigureParams.DiskImage.szDiskFileName[ 1 ] );
238: strcpy ( ZipPathB , ConfigureParams.DiskImage.szDiskZipPath[ 1 ] );
239:
1.1.1.10 root 240: if (ConfigureParams.DiskImage.szDiskFileName[drive][0])
241: tmpname = ConfigureParams.DiskImage.szDiskFileName[drive];
242: else
243: tmpname = ConfigureParams.DiskImage.szDiskImageDirectory;
244:
1.1.1.12 root 245: Main_PauseEmulation(true);
1.1.1.18! root 246: selname = SDLGui_FileSelect("Floppy image:", tmpname, &zip_path, false);
1.1.1.10 root 247: if (selname)
248: {
249: if (File_Exists(selname))
1.1.1.11 root 250: Floppy_SetDiskFileName(drive, selname, zip_path);
1.1.1.10 root 251: else
252: Floppy_SetDiskFileNameNone(drive);
1.1.1.11 root 253:
254: if (zip_path)
255: free(zip_path);
1.1.1.10 root 256: free(selname);
1.1.1.11 root 257:
258: Floppy_InsertDiskIntoDrive(0);
1.1.1.17 root 259:
260: /* Check if inserting into drive 0 also changed drive 1 with autoinsert */
261: if ( ( strcmp ( FileNameB , ConfigureParams.DiskImage.szDiskFileName[ 1 ] ) != 0 )
262: || ( strcmp ( FileNameB , ConfigureParams.DiskImage.szDiskZipPath[ 1 ] ) != 0 ) )
263: Floppy_InsertDiskIntoDrive(1);
264:
1.1.1.10 root 265: }
266: Main_UnPauseEmulation();
267: }
268:
269:
270: /*-----------------------------------------------------------------------*/
271: /**
1.1.1.9 root 272: * Check to see if pressed any shortcut keys, and call handling function
273: */
1.1.1.8 root 274: void ShortCut_ActKey(void)
1.1.1.5 root 275: {
1.1.1.9 root 276: if (ShortCutKey == SHORTCUT_NONE)
277: return;
1.1.1.8 root 278:
1.1.1.9 root 279: switch (ShortCutKey)
280: {
281: case SHORTCUT_OPTIONS:
282: Dialog_DoProperty(); /* Show options dialog */
283: break;
284: case SHORTCUT_FULLSCREEN:
285: ShortCut_FullScreen(); /* Switch between fullscreen/windowed mode */
286: break;
1.1.1.13 root 287: case SHORTCUT_MOUSEGRAB:
288: ShortCut_MouseGrab(); /* Toggle mouse grab */
1.1.1.9 root 289: break;
290: case SHORTCUT_COLDRESET:
1.1.1.10 root 291: Main_UnPauseEmulation();
1.1.1.9 root 292: Reset_Cold(); /* Reset emulator with 'cold' (clear all) */
293: break;
294: case SHORTCUT_WARMRESET:
1.1.1.10 root 295: Main_UnPauseEmulation();
1.1.1.9 root 296: Reset_Warm(); /* Emulator 'warm' reset */
297: break;
298: case SHORTCUT_SCREENSHOT:
299: ScreenSnapShot_SaveScreen(); /* Grab screenshot */
300: break;
301: case SHORTCUT_BOSSKEY:
302: ShortCut_BossKey(); /* Boss key */
303: break;
304: case SHORTCUT_CURSOREMU: /* Toggle joystick emu on/off */
305: Joy_ToggleCursorEmulation();
306: break;
1.1.1.10 root 307: case SHORTCUT_FASTFORWARD:
308: ShortCut_FastForward(); /* Toggle Min/Max speed */
1.1.1.9 root 309: break;
310: case SHORTCUT_RECANIM:
311: ShortCut_RecordAnimation(); /* Record animation */
312: break;
313: case SHORTCUT_RECSOUND:
314: ShortCut_RecordSound(); /* Toggle sound recording */
315: break;
316: case SHORTCUT_SOUND:
317: ShortCut_SoundOnOff(); /* Enable/disable sound */
318: break;
1.1.1.12 root 319: case SHORTCUT_DEBUG:
320: ShortCut_Debug(); /* Invoke the Debug UI */
321: break;
1.1.1.10 root 322: case SHORTCUT_PAUSE:
1.1.1.12 root 323: ShortCut_Pause(); /* Invoke Pause */
1.1.1.10 root 324: break;
1.1.1.18! root 325: case SHORTCUT_JOY_0:
! 326: Joy_SwitchMode(0);
! 327: break;
! 328: case SHORTCUT_JOY_1:
! 329: Joy_SwitchMode(1);
! 330: break;
! 331: case SHORTCUT_PAD_A:
! 332: Joy_SwitchMode(2);
! 333: break;
! 334: case SHORTCUT_PAD_B:
! 335: Joy_SwitchMode(3);
! 336: break;
1.1.1.9 root 337: case SHORTCUT_QUIT:
1.1.1.17 root 338: Main_RequestQuit(0);
1.1.1.9 root 339: break;
340: case SHORTCUT_LOADMEM:
1.1.1.12 root 341: MemorySnapShot_Restore(ConfigureParams.Memory.szMemoryCaptureFileName, true);
1.1.1.9 root 342: break;
343: case SHORTCUT_SAVEMEM:
1.1.1.12 root 344: MemorySnapShot_Capture(ConfigureParams.Memory.szMemoryCaptureFileName, true);
1.1.1.9 root 345: break;
1.1.1.10 root 346: case SHORTCUT_INSERTDISKA:
347: ShortCut_InsertDisk(0);
348: break;
1.1.1.9 root 349: case SHORTCUT_KEYS:
350: case SHORTCUT_NONE:
351: /* ERROR: cannot happen, just make compiler happy */
352: break;
353: }
354: ShortCutKey = SHORTCUT_NONE;
355: }
356:
357:
358: /*-----------------------------------------------------------------------*/
359: /**
1.1.1.10 root 360: * Invoke shortcut identified by name. This supports only keys for
361: * functionality that cannot be invoked with command line options
1.1.1.12 root 362: * or otherwise for remote GUIs etc.
1.1.1.10 root 363: */
364: bool Shortcut_Invoke(const char *shortcut)
365: {
366: struct {
367: SHORTCUTKEYIDX id;
368: const char *name;
369: } shortcuts[] = {
1.1.1.13 root 370: { SHORTCUT_MOUSEGRAB, "mousegrab" },
1.1.1.10 root 371: { SHORTCUT_COLDRESET, "coldreset" },
372: { SHORTCUT_WARMRESET, "warmreset" },
373: { SHORTCUT_SCREENSHOT, "screenshot" },
374: { SHORTCUT_BOSSKEY, "bosskey" },
375: { SHORTCUT_RECANIM, "recanim" },
376: { SHORTCUT_RECSOUND, "recsound" },
377: { SHORTCUT_SAVEMEM, "savemem" },
378: { SHORTCUT_QUIT, "quit" },
379: { SHORTCUT_NONE, NULL }
380: };
381: int i;
382:
383: if (ShortCutKey != SHORTCUT_NONE)
384: {
385: fprintf(stderr, "Shortcut invocation failed, shortcut already active\n");
1.1.1.12 root 386: return false;
1.1.1.10 root 387: }
388: for (i = 0; shortcuts[i].name; i++)
389: {
390: if (strcmp(shortcut, shortcuts[i].name) == 0)
391: {
392: ShortCutKey = shortcuts[i].id;
393: ShortCut_ActKey();
394: ShortCutKey = SHORTCUT_NONE;
1.1.1.12 root 395: return true;
1.1.1.10 root 396: }
397: }
398: fprintf(stderr, "WARNING: unknown shortcut '%s'\n\n", shortcut);
399: fprintf(stderr, "Hatari shortcuts are:\n");
400: for (i = 0; shortcuts[i].name; i++)
401: {
402: fprintf(stderr, "- %s\n", shortcuts[i].name);
403: }
1.1.1.12 root 404: return false;
1.1.1.10 root 405: }
406:
407:
408: /*-----------------------------------------------------------------------*/
409: /**
1.1.1.9 root 410: * Check whether given key was any of the ones in given shortcut array.
411: * Return corresponding array index or SHORTCUT_NONE for no match
412: */
1.1.1.8 root 413: static SHORTCUTKEYIDX ShortCut_CheckKey(int symkey, int *keys)
414: {
1.1.1.9 root 415: SHORTCUTKEYIDX key;
1.1.1.12 root 416: for (key = SHORTCUT_OPTIONS; key < SHORTCUT_KEYS; key++)
1.1.1.9 root 417: {
418: if (symkey == keys[key])
419: return key;
420: }
421: return SHORTCUT_NONE;
1.1.1.8 root 422: }
423:
424: /*-----------------------------------------------------------------------*/
1.1.1.9 root 425: /**
426: * Check which Shortcut key is pressed/released.
427: * If press is set, store the key array index.
428: * Return zero if key didn't match to a shortcut
429: */
1.1.1.10 root 430: int ShortCut_CheckKeys(int modkey, int symkey, bool press)
1.1.1.8 root 431: {
1.1.1.9 root 432: SHORTCUTKEYIDX key;
1.1.1.8 root 433:
1.1.1.9 root 434: if (modkey & (KMOD_RALT|KMOD_LMETA|KMOD_RMETA|KMOD_MODE))
435: key = ShortCut_CheckKey(symkey, ConfigureParams.Shortcut.withModifier);
436: else
437: key = ShortCut_CheckKey(symkey, ConfigureParams.Shortcut.withoutModifier);
438:
439: if (key == SHORTCUT_NONE)
440: return 0;
441: if (press)
442: ShortCutKey = key;
443: return 1;
1.1.1.5 root 444: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.