|
|
1.1 root 1: /* 1.1.1.6 ! root 2: Hatari - main.c ! 3: ! 4: This file is distributed under the GNU Public License, version 2 or at ! 5: your option any later version. Read the file gpl.txt for details. ! 6: ! 7: Main initialization and event handling routines. 1.1 root 8: */ 1.1.1.6 ! root 9: static char rcsid[] = "Hatari $Id: main.c,v 1.31 2003/03/04 19:27:20 thothy Exp $"; 1.1 root 10: 11: #include <time.h> 1.1.1.2 root 12: #include <signal.h> 13: #include <sys/time.h> 1.1.1.5 root 14: #include <unistd.h> 1.1 root 15: 16: #include <SDL.h> 17: 18: #include "main.h" 19: #include "configuration.h" 20: #include "decode.h" 21: #include "dialog.h" 22: #include "createDiscImage.h" 23: #include "audio.h" 24: #include "debug.h" 25: #include "joy.h" 26: #include "errlog.h" 27: #include "file.h" 28: #include "floppy.h" 29: #include "gemdos.h" 1.1.1.4 root 30: #include "hdc.h" 1.1 root 31: #include "ikbd.h" 32: #include "intercept.h" 33: #include "reset.h" 1.1.1.5 root 34: #include "keymap.h" 1.1 root 35: #include "m68000.h" 36: #include "memorySnapShot.h" 37: #include "misc.h" 38: #include "printer.h" 39: #include "rs232.h" 40: #include "screen.h" 1.1.1.5 root 41: #include "sdlgui.h" 1.1 root 42: #include "shortcut.h" 43: #include "sound.h" 44: #include "tos.h" 1.1.1.5 root 45: #include "vdi.h" 1.1 root 46: #include "video.h" 47: #include "ymFormat.h" 1.1.1.2 root 48: #include "debugui.h" 1.1 root 49: 50: #include "uae-cpu/hatari-glue.h" 51: 52: 1.1.1.4 root 53: #define FORCE_WORKING_DIR /* Set default directory to cwd */ 54: 1.1 root 55: 1.1.1.6 ! root 56: SDL_TimerID hSystemTimer; /* Handle for system timer */ 1.1 root 57: 58: BOOL bQuitProgram=FALSE; /* Flag to quit program cleanly */ 59: BOOL bUseFullscreen=FALSE; 1.1.1.4 root 60: BOOL bEmulationActive=TRUE; /* Run emulation when started */ 1.1 root 61: BOOL bAppActive = FALSE; 1.1.1.2 root 62: BOOL bEnableDebug=FALSE; /* Enable debug UI? */ 1.1 root 63: char szBootDiscImage[MAX_FILENAME_LENGTH] = { "" }; 64: 65: char szWorkingDir[MAX_FILENAME_LENGTH] = { "" }; 66: char szCurrentDir[MAX_FILENAME_LENGTH] = { "" }; 67: 68: unsigned char STRam[16*1024*1024]; /* This is our ST Ram, includes all TOS/hardware areas for ease */ 69: 70: 71: 72: /*-----------------------------------------------------------------------*/ 73: /* 74: Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type) 75: */ 76: void Main_MemorySnapShot_Capture(BOOL bSave) 77: { 78: int nBytes; 79: 80: /* Save/Restore details */ 81: /* Only save/restore area of memory machine ie set to, eg 1Mb */ 82: if (bSave) { 83: nBytes = STRamEnd_BusErr; 84: MemorySnapShot_Store(&nBytes,sizeof(nBytes)); 85: MemorySnapShot_Store(STRam,nBytes); 86: } 87: else { 88: MemorySnapShot_Store(&nBytes,sizeof(nBytes)); 89: MemorySnapShot_Store(STRam,nBytes); 90: } 91: /* And Cart/TOS/Hardware area */ 92: MemorySnapShot_Store(&STRam[0xE00000],0x200000); 93: MemorySnapShot_Store(szBootDiscImage,sizeof(szBootDiscImage)); 94: MemorySnapShot_Store(szWorkingDir,sizeof(szWorkingDir)); 95: MemorySnapShot_Store(szCurrentDir,sizeof(szCurrentDir)); 96: } 97: 98: 99: /*-----------------------------------------------------------------------*/ 100: /* 101: Error handler 102: */ 103: void Main_SysError(char *Error,char *Title) 104: { 1.1.1.2 root 105: fprintf(stderr,"%s : %s\n",Title,Error); 1.1 root 106: } 107: 1.1.1.2 root 108: 1.1 root 109: /*-----------------------------------------------------------------------*/ 110: /* 111: Bring up message(handles full-screen as well as Window) 112: */ 113: int Main_Message(char *lpText, char *lpCaption/*,unsigned int uType*/) 114: { 115: int Ret=0; 116: 117: /* Show message */ 1.1.1.5 root 118: fprintf(stderr,"%s: %s\n", lpCaption, lpText); 1.1 root 119: 120: return(Ret); 121: } 122: 123: /*-----------------------------------------------------------------------*/ 124: /* 125: Pause emulation, stop sound 126: */ 127: void Main_PauseEmulation(void) 128: { 1.1.1.4 root 129: if( bEmulationActive ) 130: { 1.1.1.6 ! root 131: Audio_EnableAudio(FALSE); 1.1.1.4 root 132: bEmulationActive = FALSE; 133: } 1.1 root 134: } 135: 1.1.1.2 root 136: /*-----------------------------------------------------------------------*/ 1.1 root 137: /* 138: Start emulation 139: */ 140: void Main_UnPauseEmulation(void) 141: { 1.1.1.4 root 142: if( !bEmulationActive ) 143: { 1.1.1.6 ! root 144: Audio_EnableAudio(ConfigureParams.Sound.bEnableSound); 1.1.1.4 root 145: bFullScreenHold = FALSE; /* Release hold */ 146: Screen_SetFullUpdate(); /* Cause full screen update(to clear all) */ 1.1 root 147: 1.1.1.4 root 148: bEmulationActive = TRUE; 149: } 1.1 root 150: } 151: 152: /* ----------------------------------------------------------------------- */ 153: /* 154: Message handler ( actually called from Video_InterruptHandler_VBL() ) 155: Here we process the SDL events (keyboard, mouse, ...) and map it to 156: Atari IKBD events. 157: */ 158: #ifndef SDL_BUTTON_LEFT /* Seems not to be defined in old SDL versions */ 159: #define SDL_BUTTON_LEFT 1 160: #define SDL_BUTTON_MIDDLE 2 161: #define SDL_BUTTON_RIGHT 3 162: #endif 163: void Main_EventHandler() 164: { 1.1.1.4 root 165: SDL_Event event; 1.1 root 166: 1.1.1.4 root 167: if( SDL_PollEvent(&event) ) 168: switch( event.type ) 1.1 root 169: { 170: case SDL_QUIT: 1.1.1.4 root 171: bQuitProgram = TRUE; 1.1 root 172: break; 1.1.1.4 root 173: case SDL_MOUSEMOTION: /* Read/Update internal mouse position */ 174: KeyboardProcessor.Mouse.dx += event.motion.xrel; 175: KeyboardProcessor.Mouse.dy += event.motion.yrel; 1.1 root 176: break; 177: case SDL_MOUSEBUTTONDOWN: 178: if( event.button.button==SDL_BUTTON_LEFT ) 1.1.1.4 root 179: { 180: if(Keyboard.LButtonDblClk==0) 181: Keyboard.bLButtonDown |= BUTTON_MOUSE; /* Set button down flag */ 182: } 1.1 root 183: else if( event.button.button==SDL_BUTTON_RIGHT ) 1.1.1.4 root 184: Keyboard.bRButtonDown |= BUTTON_MOUSE; 1.1 root 185: else if( event.button.button==SDL_BUTTON_MIDDLE ) 186: Keyboard.LButtonDblClk = 1; /* Start double-click sequence in emulation time */ 187: break; 188: case SDL_MOUSEBUTTONUP: 189: if( event.button.button==SDL_BUTTON_LEFT ) 1.1.1.4 root 190: Keyboard.bLButtonDown &= ~BUTTON_MOUSE; 1.1 root 191: else if( event.button.button==SDL_BUTTON_RIGHT ) 1.1.1.4 root 192: Keyboard.bRButtonDown &= ~BUTTON_MOUSE;; 1.1 root 193: break; 194: case SDL_KEYDOWN: 1.1.1.4 root 195: Keymap_KeyDown( event.key.keysym.sym, event.key.keysym.mod ); 1.1 root 196: break; 197: case SDL_KEYUP: 1.1.1.4 root 198: Keymap_KeyUp( event.key.keysym.sym, event.key.keysym.mod ); 1.1 root 199: break; 200: } 201: } 202: 203: 1.1.1.2 root 204: /*-----------------------------------------------------------------------*/ 1.1 root 205: /* 1.1.1.6 ! root 206: This routine runs at 50fps. ! 207: It increases the VBL counter to govern emulation speed. 1.1 root 208: */ 1.1.1.6 ! root 209: static Uint32 Main_SystemTimerFunc(Uint32 interval, void *param) 1.1 root 210: { 1.1.1.2 root 211: /* Advance frame counter, used to draw screen to window at 50fps */ 1.1 root 212: VBLCounter++; 1.1.1.3 root 213: return(interval); 1.1 root 214: } 215: 1.1.1.2 root 216: 217: /*-----------------------------------------------------------------------*/ 1.1 root 218: /* 1.1.1.6 ! root 219: Create system timer to handle speed. 1.1 root 220: */ 1.1.1.6 ! root 221: static void Main_CreateSystemTimer(void) 1.1 root 222: { 1.1.1.6 ! root 223: /* Create thread to run every 20ms (50fps) */ ! 224: hSystemTimer = SDL_AddTimer(20, Main_SystemTimerFunc, NULL); 1.1 root 225: } 226: 1.1.1.6 ! root 227: 1.1.1.2 root 228: /*-----------------------------------------------------------------------*/ 1.1 root 229: /* 1.1.1.6 ! root 230: Delete system timer 1.1 root 231: */ 1.1.1.6 ! root 232: static void Main_RemoveSystemTimer(void) 1.1 root 233: { 1.1.1.6 ! root 234: SDL_RemoveTimer(hSystemTimer); 1.1 root 235: } 1.1.1.2 root 236: 237: 1.1 root 238: 239: /*-----------------------------------------------------------------------*/ 240: /* 241: Check for any passed parameters 242: */ 243: void Main_ReadParameters(int argc, char *argv[]) 244: { 1.1.1.4 root 245: int i; 1.1 root 246: 1.1.1.4 root 247: /* Scan for any which we can use */ 248: for(i=1; i<argc; i++) 1.1 root 249: { 1.1.1.4 root 250: if (strlen(argv[i])>0) 1.1 root 251: { 1.1.1.4 root 252: if (!strcmp(argv[i],"--help") || !strcmp(argv[i],"-h")) 1.1 root 253: { 1.1.1.4 root 254: printf("Usage:\n hatari [options] [disk image name]\n" 255: "Where options are:\n" 256: " --help or -h Print this help text and exit.\n" 257: " --version or -v Print version number and exit.\n" 258: " --mono or -m Start in monochrome mode instead of color.\n" 259: " --fullscreen or -f Try to use fullscreen mode.\n" 260: " --joystick or -j Emulate a ST joystick with the cursor keys.\n" 261: " --nosound Disable sound (faster!).\n" 262: " --frameskip Skip every second frame (speeds up emulation!).\n" 263: " --debug or -D Allow debug interface.\n" 264: " --harddrive <dir> Emulate an ST harddrive\n" 265: " or -d <dir> (<dir> = root directory).\n" 266: " --hdimage <imagename> Emulate an ST harddrive with an image.\n" 267: " --tos <file> Use TOS image <file>.\n" 268: " --cpulevel x Set the CPU type (x => 680x0) (TOS 2.06 only!).\n" 269: " --compatible Use a more compatible (but slower) 68000 CPU mode.\n" 1.1.1.5 root 270: " --blitter Enable blitter emulation (unstable!)\n" 271: " --vdi Use extended VDI resolution\n" 1.1.1.4 root 272: ); 273: exit(0); 1.1 root 274: } 275: else if (!strcmp(argv[i],"--version") || !strcmp(argv[i],"-v")) 276: { 1.1.1.4 root 277: printf("This is %s.\n", PROG_NAME); 278: printf("This program is free software licensed under the GNU GPL.\n"); 279: exit(0); 1.1 root 280: } 1.1.1.2 root 281: else if (!strcmp(argv[i],"--mono") || !strcmp(argv[i],"-m")) 1.1 root 282: { 1.1.1.4 root 283: bUseHighRes=TRUE; 284: ConfigureParams.Screen.bUseHighRes=TRUE; 285: STRes=PrevSTRes=ST_HIGH_RES; 1.1 root 286: } 287: else if (!strcmp(argv[i],"--fullscreen") || !strcmp(argv[i],"-f")) 288: { 1.1.1.4 root 289: bUseFullscreen=TRUE; 1.1 root 290: } 291: else if (!strcmp(argv[i],"--joystick") || !strcmp(argv[i],"-j")) 292: { 1.1.1.4 root 293: ConfigureParams.Joysticks.Joy[1].bCursorEmulation=TRUE; 1.1 root 294: } 1.1.1.4 root 295: else if ( !strcmp(argv[i],"--nosound") ) 1.1.1.2 root 296: { 1.1.1.4 root 297: bDisableSound=TRUE; 298: ConfigureParams.Sound.bEnableSound = FALSE; 1.1.1.2 root 299: } 300: else if ( !strcmp(argv[i],"--frameskip") ) 301: { 1.1.1.4 root 302: ConfigureParams.Screen.Advanced.bFrameSkip = TRUE; 1.1.1.2 root 303: } 1.1.1.4 root 304: else if (!strcmp(argv[i],"--debug") || !strcmp(argv[i],"-D")) 1.1.1.2 root 305: { 1.1.1.4 root 306: bEnableDebug=TRUE; 1.1.1.2 root 307: } 1.1.1.4 root 308: else if (!strcmp(argv[i],"--hdimage")) 1.1.1.3 root 309: { 1.1.1.4 root 310: if( argc>i+1 && strlen(argv[i+1])<=MAX_FILENAME_LENGTH ) 311: { 312: if( HDC_Init(argv[i+1]) == TRUE) 313: { 314: strcpy(ConfigureParams.HardDisc.szHardDiscImage, argv[i+1]); 315: printf("Hard drive image %s mounted.\n", argv[i+1]); 316: i++; 317: } 318: else 319: { 1.1.1.5 root 320: printf("Couldn't open file: %s, or no partitions\n", argv[i+1]); 1.1.1.4 root 321: } 322: } 323: } 324: else if (!strcmp(argv[i],"--harddrive") || !strcmp(argv[i],"-d")) 325: { 326: if( i+1<argc && strlen(argv[i+1])<=MAX_PATH ) /* both parameters exist */ 327: { 328: strcpy(ConfigureParams.HardDisc.szHardDiscDirectories[0], argv[i+1]); 329: GemDOS_InitDrives(); 330: i += 1; 331: } 1.1.1.3 root 332: } 333: else if (!strcmp(argv[i],"--tos")) 334: { 1.1.1.4 root 335: if(i+1>=argc) 336: fprintf(stderr,"Missing argument for --tos.\n"); 1.1.1.3 root 337: else 1.1.1.4 root 338: strncpy(ConfigureParams.TOSGEM.szTOSImageFileName, argv[++i], MAX_FILENAME_LENGTH); 1.1.1.3 root 339: } 340: else if (!strcmp(argv[i],"--cpulevel")) 341: { 1.1.1.4 root 342: if(i+1>=argc) 343: fprintf(stderr,"Missing argument for --cpulevel.\n"); 344: else 345: cpu_level = atoi(argv[++i]); 346: if(cpu_level<0 || cpu_level>4) 347: cpu_level = 0; 1.1.1.5 root 348: ConfigureParams.System.nCpuLevel = cpu_level; 1.1.1.3 root 349: } 350: else if (!strcmp(argv[i],"--compatible") || !strcmp(argv[i],"-d")) 351: { 1.1.1.4 root 352: cpu_compatible = TRUE; 1.1.1.5 root 353: ConfigureParams.System.bCompatibleCpu = TRUE; 354: } 355: else if (!strcmp(argv[i],"--blitter")) 356: { 357: bEnableBlitter = TRUE; 358: ConfigureParams.System.bBlitter = TRUE; 359: } 360: else if(!strcmp(argv[i], "--vdi")) 361: { 362: bUseVDIRes = ConfigureParams.TOSGEM.bUseExtGEMResolutions = TRUE; 1.1.1.3 root 363: } 1.1 root 364: else 365: { 1.1.1.4 root 366: /* Possible passed disc image filename, ie starts with character other than '-' */ 367: if (argv[i][0]!='-') 368: strcpy(szBootDiscImage,argv[i]); 1.1.1.3 root 369: else 1.1.1.4 root 370: fprintf(stderr,"Illegal parameter: %s\n",argv[i]); 1.1 root 371: } 372: } 373: } 374: } 375: 1.1.1.2 root 376: 377: /*-----------------------------------------------------------------------*/ 1.1 root 378: /* 379: Initialise emulation 380: */ 381: void Main_Init(void) 382: { 1.1.1.5 root 383: /* Init SDL's video and timer subsystem. Note: Audio and joystick subsystems 384: will be initialized later (failures there are not fatal). */ 385: if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0 ) 1.1.1.4 root 386: { 1.1.1.2 root 387: fprintf(stderr, "Could not initialize the SDL library:\n %s\n", SDL_GetError() ); 388: exit(-1); 1.1.1.4 root 389: } 1.1.1.2 root 390: 1.1 root 391: Misc_SeedRandom(1043618); 1.1.1.4 root 392: Configuration_Init(); 393: SDLGui_Init(); 1.1 root 394: Printer_Init(); 395: RS232_Init(); 396: Screen_Init(); 397: Floppy_Init(); 1.1.1.6 ! root 398: Init680x0(); /* Init CPU emulation */ ! 399: Audio_Init(); ! 400: ! 401: if(Reset_Cold()) /* Reset all systems, load TOS image */ ! 402: { ! 403: /* If loading of the TOS failed, we bring up the GUI to let the ! 404: * user choose another TOS ROM file. */ ! 405: Dialog_DoProperty(); ! 406: } ! 407: if(!bTosImageLoaded || bQuitProgram) ! 408: { ! 409: fprintf(stderr, "Failed to load TOS image!\n"); ! 410: SDL_Quit(); ! 411: exit(-2); ! 412: } ! 413: 1.1 root 414: GemDOS_Init(); 415: Intercept_Init(); 416: Joy_Init(); 417: Sound_Init(); 1.1.1.6 ! root 418: Main_CreateSystemTimer(); 1.1 root 419: 1.1.1.2 root 420: /* Check passed disc image parameter, boot directly into emulator */ 1.1.1.6 ! root 421: if(strlen(szBootDiscImage) > 0) ! 422: { 1.1 root 423: Floppy_InsertDiscIntoDrive(0,szBootDiscImage); 424: } 425: } 426: 1.1.1.6 ! root 427: 1.1.1.2 root 428: /*-----------------------------------------------------------------------*/ 1.1 root 429: /* 430: Un-Initialise emulation 431: */ 432: void Main_UnInit(void) 433: { 434: Screen_ReturnFromFullScreen(); 1.1.1.6 ! root 435: Main_RemoveSystemTimer(); 1.1 root 436: Floppy_EjectBothDrives(); 437: Floppy_UnInit(); 1.1.1.4 root 438: HDC_UnInit(); 1.1 root 439: RS232_UnInit(); 440: Printer_UnInit(); 441: Intercept_UnInit(); 1.1.1.4 root 442: GemDOS_UnInitDrives(); 1.1.1.5 root 443: if(Sound_AreWeRecording()) 444: Sound_EndRecording(); 1.1.1.2 root 445: Audio_UnInit(); 1.1 root 446: YMFormat_FreeRecording(); 1.1.1.4 root 447: SDLGui_UnInit(); 1.1 root 448: Screen_UnInit(); 449: 450: #ifdef USE_DEBUGGER 451: FreeDebugDialog(); 452: #endif 453: Configuration_UnInit(); 1.1.1.2 root 454: 455: /* SDL uninit: */ 456: SDL_Quit(); 1.1 root 457: } 458: 1.1.1.6 ! root 459: 1.1.1.2 root 460: /*-----------------------------------------------------------------------*/ 1.1 root 461: /* 462: Main 463: */ 464: int main(int argc, char *argv[]) 465: { 466: 467: /* Generate random seed */ 468: srand( time(NULL) ); 469: 470: /* Get working directory, if in MSDev force */ 1.1.1.4 root 471: Misc_FindWorkingDirectory(argv[0]); 1.1 root 472: #ifdef FORCE_WORKING_DIR 473: getcwd(szWorkingDir, MAX_FILENAME_LENGTH); 474: #endif 475: 476: /* Create debug files */ 477: Debug_OpenFiles(); 478: ErrLog_OpenFile(); 479: 1.1.1.2 root 480: /* Set default configuration values: */ 481: Configuration_SetDefault(); 482: 1.1 root 483: /* Check for any passed parameters */ 1.1.1.2 root 484: Main_ReadParameters(argc, argv); 1.1 root 485: 486: /* Init emulator system */ 487: Main_Init(); 488: 1.1.1.2 root 489: /* Switch immediately to fullscreen if user wants to */ 490: if( bUseFullscreen ) 491: Screen_EnterFullScreen(); 492: 1.1.1.4 root 493: /* Run emulation */ 1.1 root 494: Main_UnPauseEmulation(); 1.1.1.4 root 495: Start680x0(); /* Start emulation */ 1.1 root 496: 497: /* Un-init emulation system */ 498: Main_UnInit(); 499: 500: /* Close debug files */ 501: ErrLog_CloseFile(); 502: Debug_CloseFiles(); 503: 504: return(0); 505: } 1.1.1.3 root 506: 507: 508: 509:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.