|
|
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 root 20: #include "memorySnapShot.h"
21: #include "reset.h"
22: #include "screen.h"
23: #include "screenSnapShot.h"
1.1.1.8 root 24: #include "configuration.h"
1.1 root 25: #include "shortcut.h"
1.1.1.10 root 26: #include "debugui.h"
1.1 root 27: #include "sound.h"
1.1.1.10 root 28: #include "sdlgui.h"
1.1.1.13 root 29: #include "video.h"
30: #include "avi_record.h"
1.1.1.14 root 31: #include "clocks_timings.h"
1.1.1.19! root 32: #include "statusbar.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 ];
1.1.1.10 root 231:
232: if (SDLGui_SetScreen(sdlscrn))
233: return;
234:
1.1.1.17 root 235: /* Save current names for drive 1 before checking autoinsert */
236: strcpy ( FileNameB , ConfigureParams.DiskImage.szDiskFileName[ 1 ] );
237:
1.1.1.10 root 238: if (ConfigureParams.DiskImage.szDiskFileName[drive][0])
239: tmpname = ConfigureParams.DiskImage.szDiskFileName[drive];
240: else
241: tmpname = ConfigureParams.DiskImage.szDiskImageDirectory;
242:
1.1.1.12 root 243: Main_PauseEmulation(true);
1.1.1.18 root 244: selname = SDLGui_FileSelect("Floppy image:", tmpname, &zip_path, false);
1.1.1.10 root 245: if (selname)
246: {
247: if (File_Exists(selname))
1.1.1.11 root 248: Floppy_SetDiskFileName(drive, selname, zip_path);
1.1.1.10 root 249: else
250: Floppy_SetDiskFileNameNone(drive);
1.1.1.11 root 251:
1.1.1.19! root 252: free(zip_path);
1.1.1.10 root 253: free(selname);
1.1.1.11 root 254:
255: Floppy_InsertDiskIntoDrive(0);
1.1.1.17 root 256:
257: /* Check if inserting into drive 0 also changed drive 1 with autoinsert */
258: if ( ( strcmp ( FileNameB , ConfigureParams.DiskImage.szDiskFileName[ 1 ] ) != 0 )
259: || ( strcmp ( FileNameB , ConfigureParams.DiskImage.szDiskZipPath[ 1 ] ) != 0 ) )
260: Floppy_InsertDiskIntoDrive(1);
261:
1.1.1.10 root 262: }
263: Main_UnPauseEmulation();
264: }
265:
266:
267: /*-----------------------------------------------------------------------*/
268: /**
1.1.1.9 root 269: * Check to see if pressed any shortcut keys, and call handling function
270: */
1.1.1.8 root 271: void ShortCut_ActKey(void)
1.1.1.5 root 272: {
1.1.1.9 root 273: if (ShortCutKey == SHORTCUT_NONE)
274: return;
1.1.1.8 root 275:
1.1.1.9 root 276: switch (ShortCutKey)
277: {
278: case SHORTCUT_OPTIONS:
1.1.1.19! root 279: Dialog_DoProperty(); /* Show options dialog */
1.1.1.9 root 280: break;
281: case SHORTCUT_FULLSCREEN:
1.1.1.19! root 282: ShortCut_FullScreen(); /* Switch between fullscreen/windowed mode */
1.1.1.9 root 283: break;
1.1.1.13 root 284: case SHORTCUT_MOUSEGRAB:
1.1.1.19! root 285: ShortCut_MouseGrab(); /* Toggle mouse grab */
1.1.1.9 root 286: break;
287: case SHORTCUT_COLDRESET:
1.1.1.10 root 288: Main_UnPauseEmulation();
1.1.1.19! root 289: Reset_Cold(); /* Reset emulator with 'cold' (clear all) */
! 290: Statusbar_UpdateInfo(); /* Some infos can change after 'reset' */
1.1.1.9 root 291: break;
292: case SHORTCUT_WARMRESET:
1.1.1.10 root 293: Main_UnPauseEmulation();
1.1.1.19! root 294: Reset_Warm(); /* Emulator 'warm' reset */
! 295: Statusbar_UpdateInfo(); /* Some infos can change after 'reset' */
1.1.1.9 root 296: break;
297: case SHORTCUT_SCREENSHOT:
1.1.1.19! root 298: ScreenSnapShot_SaveScreen(); /* Grab screenshot */
1.1.1.9 root 299: break;
300: case SHORTCUT_BOSSKEY:
1.1.1.19! root 301: ShortCut_BossKey(); /* Boss key */
1.1.1.9 root 302: break;
1.1.1.19! root 303: case SHORTCUT_CURSOREMU: /* Toggle joystick emu on/off */
1.1.1.9 root 304: Joy_ToggleCursorEmulation();
305: break;
1.1.1.10 root 306: case SHORTCUT_FASTFORWARD:
1.1.1.19! root 307: ShortCut_FastForward(); /* Toggle Min/Max speed */
1.1.1.9 root 308: break;
309: case SHORTCUT_RECANIM:
1.1.1.19! root 310: ShortCut_RecordAnimation(); /* Record animation */
1.1.1.9 root 311: break;
312: case SHORTCUT_RECSOUND:
1.1.1.19! root 313: ShortCut_RecordSound(); /* Toggle sound recording */
1.1.1.9 root 314: break;
315: case SHORTCUT_SOUND:
1.1.1.19! root 316: ShortCut_SoundOnOff(); /* Enable/disable sound */
1.1.1.9 root 317: break;
1.1.1.12 root 318: case SHORTCUT_DEBUG:
1.1.1.19! root 319: ShortCut_Debug(); /* Invoke the Debug UI */
1.1.1.12 root 320: break;
1.1.1.10 root 321: case SHORTCUT_PAUSE:
1.1.1.19! root 322: ShortCut_Pause(); /* Invoke Pause */
1.1.1.10 root 323: break;
1.1.1.18 root 324: case SHORTCUT_JOY_0:
325: Joy_SwitchMode(0);
326: break;
327: case SHORTCUT_JOY_1:
328: Joy_SwitchMode(1);
329: break;
330: case SHORTCUT_PAD_A:
331: Joy_SwitchMode(2);
332: break;
333: case SHORTCUT_PAD_B:
334: Joy_SwitchMode(3);
335: break;
1.1.1.9 root 336: case SHORTCUT_QUIT:
1.1.1.17 root 337: Main_RequestQuit(0);
1.1.1.9 root 338: break;
339: case SHORTCUT_LOADMEM:
1.1.1.12 root 340: MemorySnapShot_Restore(ConfigureParams.Memory.szMemoryCaptureFileName, true);
1.1.1.9 root 341: break;
342: case SHORTCUT_SAVEMEM:
1.1.1.12 root 343: MemorySnapShot_Capture(ConfigureParams.Memory.szMemoryCaptureFileName, true);
1.1.1.9 root 344: break;
1.1.1.10 root 345: case SHORTCUT_INSERTDISKA:
346: ShortCut_InsertDisk(0);
347: break;
1.1.1.9 root 348: case SHORTCUT_KEYS:
349: case SHORTCUT_NONE:
350: /* ERROR: cannot happen, just make compiler happy */
351: break;
352: }
353: ShortCutKey = SHORTCUT_NONE;
354: }
355:
356:
357: /*-----------------------------------------------------------------------*/
358: /**
1.1.1.10 root 359: * Invoke shortcut identified by name. This supports only keys for
360: * functionality that cannot be invoked with command line options
1.1.1.12 root 361: * or otherwise for remote GUIs etc.
1.1.1.10 root 362: */
363: bool Shortcut_Invoke(const char *shortcut)
364: {
365: struct {
366: SHORTCUTKEYIDX id;
367: const char *name;
368: } shortcuts[] = {
1.1.1.13 root 369: { SHORTCUT_MOUSEGRAB, "mousegrab" },
1.1.1.10 root 370: { SHORTCUT_COLDRESET, "coldreset" },
371: { SHORTCUT_WARMRESET, "warmreset" },
372: { SHORTCUT_SCREENSHOT, "screenshot" },
373: { SHORTCUT_BOSSKEY, "bosskey" },
374: { SHORTCUT_RECANIM, "recanim" },
375: { SHORTCUT_RECSOUND, "recsound" },
376: { SHORTCUT_SAVEMEM, "savemem" },
377: { SHORTCUT_QUIT, "quit" },
378: { SHORTCUT_NONE, NULL }
379: };
380: int i;
381:
382: if (ShortCutKey != SHORTCUT_NONE)
383: {
384: fprintf(stderr, "Shortcut invocation failed, shortcut already active\n");
1.1.1.12 root 385: return false;
1.1.1.10 root 386: }
387: for (i = 0; shortcuts[i].name; i++)
388: {
389: if (strcmp(shortcut, shortcuts[i].name) == 0)
390: {
391: ShortCutKey = shortcuts[i].id;
392: ShortCut_ActKey();
393: ShortCutKey = SHORTCUT_NONE;
1.1.1.12 root 394: return true;
1.1.1.10 root 395: }
396: }
397: fprintf(stderr, "WARNING: unknown shortcut '%s'\n\n", shortcut);
398: fprintf(stderr, "Hatari shortcuts are:\n");
399: for (i = 0; shortcuts[i].name; i++)
400: {
401: fprintf(stderr, "- %s\n", shortcuts[i].name);
402: }
1.1.1.12 root 403: return false;
1.1.1.10 root 404: }
405:
406:
407: /*-----------------------------------------------------------------------*/
408: /**
1.1.1.9 root 409: * Check whether given key was any of the ones in given shortcut array.
410: * Return corresponding array index or SHORTCUT_NONE for no match
411: */
1.1.1.8 root 412: static SHORTCUTKEYIDX ShortCut_CheckKey(int symkey, int *keys)
413: {
1.1.1.9 root 414: SHORTCUTKEYIDX key;
1.1.1.12 root 415: for (key = SHORTCUT_OPTIONS; key < SHORTCUT_KEYS; key++)
1.1.1.9 root 416: {
417: if (symkey == keys[key])
418: return key;
419: }
420: return SHORTCUT_NONE;
1.1.1.8 root 421: }
422:
423: /*-----------------------------------------------------------------------*/
1.1.1.9 root 424: /**
425: * Check which Shortcut key is pressed/released.
426: * If press is set, store the key array index.
427: * Return zero if key didn't match to a shortcut
428: */
1.1.1.10 root 429: int ShortCut_CheckKeys(int modkey, int symkey, bool press)
1.1.1.8 root 430: {
1.1.1.9 root 431: SHORTCUTKEYIDX key;
1.1.1.8 root 432:
1.1.1.9 root 433: if (modkey & (KMOD_RALT|KMOD_LMETA|KMOD_RMETA|KMOD_MODE))
434: key = ShortCut_CheckKey(symkey, ConfigureParams.Shortcut.withModifier);
435: else
436: key = ShortCut_CheckKey(symkey, ConfigureParams.Shortcut.withoutModifier);
437:
438: if (key == SHORTCUT_NONE)
439: return 0;
440: if (press)
441: ShortCutKey = key;
442: return 1;
1.1.1.5 root 443: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.