|
|
1.1 ! root 1: /* ! 2: Hatari ! 3: */ ! 4: ! 5: #include <time.h> ! 6: ! 7: #include <SDL.h> ! 8: ! 9: #include "main.h" ! 10: #include "configuration.h" ! 11: #include "decode.h" ! 12: #include "dialog.h" ! 13: #include "createDiscImage.h" ! 14: #include "audio.h" ! 15: #include "debug.h" ! 16: #include "joy.h" ! 17: #include "errlog.h" ! 18: #include "file.h" ! 19: #include "floppy.h" ! 20: #include "gemdos.h" ! 21: #include "ikbd.h" ! 22: #include "intercept.h" ! 23: #include "reset.h" ! 24: #include "m68000.h" ! 25: #include "memorySnapShot.h" ! 26: #include "misc.h" ! 27: #include "printer.h" ! 28: #include "rs232.h" ! 29: #include "screen.h" ! 30: #include "shortcut.h" ! 31: #include "sound.h" ! 32: #include "timer.h" ! 33: #include "tos.h" ! 34: #include "video.h" ! 35: #include "view.h" ! 36: #include "ymFormat.h" ! 37: ! 38: #include "uae-cpu/hatari-glue.h" ! 39: ! 40: ! 41: extern int quit_program; /* Declared in newcpu.c */ ! 42: ! 43: ! 44: BOOL bQuitProgram=FALSE; /* Flag to quit program cleanly */ ! 45: BOOL bUseFullscreen=FALSE; ! 46: BOOL bEmulationActive=EMULATION_ACTIVE; /* Run emulation when started (we'll be in window mouse mode!) */ ! 47: BOOL bAppActive = FALSE; ! 48: unsigned int TimerID; /* Timer ID for main window */ ! 49: char szName[] = { "Hatari" }; ! 50: char szBootDiscImage[MAX_FILENAME_LENGTH] = { "" }; ! 51: ! 52: char szWorkingDir[MAX_FILENAME_LENGTH] = { "" }; ! 53: char szCurrentDir[MAX_FILENAME_LENGTH] = { "" }; ! 54: ! 55: unsigned char STRam[16*1024*1024]; /* This is our ST Ram, includes all TOS/hardware areas for ease */ ! 56: ! 57: int STSpeedMilliSeconds[] = { /* Convert option 'nMinMaxSpeed' into milliseconds */ ! 58: 1000/50, /* MINMAXSPEED_MIN(20ms) */ ! 59: 1000/66, /* MINMAXSPEED_1(15ms) */ ! 60: 1000/100, /* MINMAXSPEED_2(10ms) */ ! 61: 1000/200, /* MINMAXSPEED_3(5ms) */ ! 62: 1, /* MINMAXSPEED_MAX(1ms) */ ! 63: }; ! 64: ! 65: ! 66: ! 67: ! 68: /*-----------------------------------------------------------------------*/ ! 69: /* ! 70: Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type) ! 71: */ ! 72: void Main_MemorySnapShot_Capture(BOOL bSave) ! 73: { ! 74: int nBytes; ! 75: ! 76: /* Save/Restore details */ ! 77: /* Only save/restore area of memory machine ie set to, eg 1Mb */ ! 78: if (bSave) { ! 79: nBytes = STRamEnd_BusErr; ! 80: MemorySnapShot_Store(&nBytes,sizeof(nBytes)); ! 81: MemorySnapShot_Store(STRam,nBytes); ! 82: } ! 83: else { ! 84: MemorySnapShot_Store(&nBytes,sizeof(nBytes)); ! 85: MemorySnapShot_Store(STRam,nBytes); ! 86: } ! 87: /* And Cart/TOS/Hardware area */ ! 88: MemorySnapShot_Store(&STRam[0xE00000],0x200000); ! 89: MemorySnapShot_Store(szBootDiscImage,sizeof(szBootDiscImage)); ! 90: MemorySnapShot_Store(szWorkingDir,sizeof(szWorkingDir)); ! 91: MemorySnapShot_Store(szCurrentDir,sizeof(szCurrentDir)); ! 92: } ! 93: ! 94: ! 95: /*-----------------------------------------------------------------------*/ ! 96: /* ! 97: Error handler ! 98: */ ! 99: void Main_SysError(char *Error,char *Title) ! 100: { ! 101: //FIXME MessageBox(hWnd,Error,Title,MB_OK | MB_ICONSTOP); ! 102: } ! 103: ! 104: /*-----------------------------------------------------------------------*/ ! 105: /* ! 106: Bring up message(handles full-screen as well as Window) ! 107: */ ! 108: int Main_Message(char *lpText, char *lpCaption/*,unsigned int uType*/) ! 109: { ! 110: int Ret=0; ! 111: ! 112: /* Are we in full-screen? */ ! 113: /*if (bInFullScreen) ! 114: Screen_ReturnFromFullScreen();*/ ! 115: ! 116: /* Show message */ ! 117: fprintf(stderr,"Message (%s):\n %s\n", lpCaption, lpText); ! 118: ! 119: return(Ret); ! 120: } ! 121: ! 122: /*-----------------------------------------------------------------------*/ ! 123: /* ! 124: Pause emulation, stop sound ! 125: */ ! 126: void Main_PauseEmulation(void) ! 127: { ! 128: bEmulationActive = EMULATION_INACTIVE; ! 129: } ! 130: ! 131: //----------------------------------------------------------------------- ! 132: /* ! 133: Start emulation ! 134: */ ! 135: void Main_UnPauseEmulation(void) ! 136: { ! 137: // SetMenu(hWnd,NULL); // Remove any menu's! ! 138: bFullScreenHold = FALSE; // Release hold ! 139: Screen_SetFullUpdate(); // Cause full screen update(to clear all) ! 140: ! 141: bEmulationActive = EMULATION_ACTIVE; ! 142: DAudio_ResetBuffer(); ! 143: } ! 144: ! 145: /* ----------------------------------------------------------------------- */ ! 146: /* ! 147: Message handler ( actually called from Video_InterruptHandler_VBL() ) ! 148: Here we process the SDL events (keyboard, mouse, ...) and map it to ! 149: Atari IKBD events. ! 150: */ ! 151: #ifndef SDL_BUTTON_LEFT /* Seems not to be defined in old SDL versions */ ! 152: #define SDL_BUTTON_LEFT 1 ! 153: #define SDL_BUTTON_MIDDLE 2 ! 154: #define SDL_BUTTON_RIGHT 3 ! 155: #endif ! 156: void Main_EventHandler() ! 157: { ! 158: SDL_Event event; ! 159: ! 160: if( SDL_PollEvent(&event) ) ! 161: switch( event.type ) ! 162: { ! 163: case SDL_QUIT: ! 164: quit_program=1; ! 165: bQuitProgram=1; ! 166: break; ! 167: case SDL_MOUSEMOTION: ! 168: View_UpdateSTMousePosition(); /* Read/Update internal mouse position */ ! 169: break; ! 170: case SDL_MOUSEBUTTONDOWN: ! 171: if( event.button.button==SDL_BUTTON_LEFT ) ! 172: View_LeftMouseButtonDown(); ! 173: else if( event.button.button==SDL_BUTTON_RIGHT ) ! 174: View_RightMouseButtonDown(); ! 175: else if( event.button.button==SDL_BUTTON_MIDDLE ) ! 176: Keyboard.LButtonDblClk = 1; /* Start double-click sequence in emulation time */ ! 177: break; ! 178: case SDL_MOUSEBUTTONUP: ! 179: if( event.button.button==SDL_BUTTON_LEFT ) ! 180: View_LeftMouseButtonUp(); ! 181: else if( event.button.button==SDL_BUTTON_RIGHT ) ! 182: View_RightMouseButtonUp(); ! 183: break; ! 184: case SDL_KEYDOWN: ! 185: View_KeyDown( event.key.keysym.sym, event.key.keysym.mod ); ! 186: break; ! 187: case SDL_KEYUP: ! 188: if(event.key.keysym.sym == SDLK_F12) { ! 189: quit_program=1; ! 190: bQuitProgram=1; ! 191: } else { ! 192: View_KeyUp( event.key.keysym.sym, event.key.keysym.mod ); ! 193: } ! 194: break; ! 195: } ! 196: } ! 197: ! 198: ! 199: /*-----------------------------------------------------------------------*/ ! 200: /* ! 201: Create an event which is times our VBL(50fps) to govern the speed of the emulator ! 202: This changes to vary emulation speed according to user settings ! 203: */ ! 204: /* FIXME */ ! 205: /* ! 206: void Main_CreateVBLEvent(void) ! 207: { ! 208: hVBLHandle = CreateEvent(NULL, // pointer to security attributes ! 209: FALSE, // flag for manual-reset event ! 210: FALSE, // flag for initial state ! 211: NULL); // pointer to event-object name ! 212: } ! 213: */ ! 214: ! 215: //----------------------------------------------------------------------- ! 216: /* ! 217: Delete VBL timer ! 218: */ ! 219: /* FIXME */ ! 220: /* ! 221: void Main_DeleteVBLEvent(void) ! 222: { ! 223: if (hVBLHandle) { ! 224: CloseHandle(hVBLHandle); ! 225: hVBLHandle = NULL; ! 226: } ! 227: } ! 228: */ ! 229: ! 230: //----------------------------------------------------------------------- ! 231: /* ! 232: Signal VBL timer event - used in 'Main_WaitVBLEvent' ! 233: */ ! 234: /* FIXME */ ! 235: /* ! 236: void Main_SetVBLEvent(void) ! 237: { ! 238: if (hVBLHandle) ! 239: SetEvent(hVBLHandle); ! 240: } ! 241: */ ! 242: ! 243: //----------------------------------------------------------------------- ! 244: /* ! 245: Wait for VBL counter to latch to next frame(called by sound callback @ 20ms, 50fps) ! 246: */ ! 247: /* FIXME */ ! 248: /* ! 249: void Main_WaitVBLEvent(void) ! 250: { ! 251: // Wait until event signalled by Sound VBL, this need to be more Windows friendly ! 252: if (hVBLHandle) { ! 253: if (WaitForSingleObject(hVBLHandle,50)==WAIT_TIMEOUT) { // Suspend thread until VBL count increases ! 254: // Something went wrong, reset, try again ! 255: Main_SetSpeedThreadTimer(ConfigureParams.Configure.nMinMaxSpeed); ! 256: } ! 257: } ! 258: } ! 259: */ ! 260: ! 261: //----------------------------------------------------------------------- ! 262: /* ! 263: Check VBL event to see if already set, and return TRUE ! 264: */ ! 265: /* FIXME */ ! 266: /* ! 267: BOOL Main_AlreadyWaitingVBLEvent(void) ! 268: { ! 269: // Test event to see if already set ! 270: if (WaitForSingleObject(hVBLHandle,0)==WAIT_TIMEOUT) ! 271: return(FALSE); ! 272: ! 273: return(TRUE); ! 274: } ! 275: */ ! 276: ! 277: //----------------------------------------------------------------------- ! 278: /* ! 279: Create sound thread to handle passing of sound on to DirectSound ! 280: */ ! 281: /* FIXME */ ! 282: /* ! 283: void Main_CreateSoundThread(void) ! 284: { ! 285: // Create thread to run every 20ms(50fps) to send emulation samples to DirectSound ! 286: hSoundTimer = timeSetEvent(20,1,Main_SoundThreadFunc,0,TIME_PERIODIC); ! 287: } ! 288: */ ! 289: ! 290: //----------------------------------------------------------------------- ! 291: /* ! 292: This thread runs at 50fps and passes sound samples to direct sound and also also ! 293: set the counter/events to govern emulation speed to match the two together. ! 294: When running at a speed other than standard ST speed the VBL event is set by 'Main_SpeedThreadFunc' ! 295: which occurs at differing speeds. ! 296: */ ! 297: /* FIXME */ ! 298: /* ! 299: void CALLBACK Main_SoundThreadFunc( UINT wTimerID, UINT msg, DWORD dwUsers, DWORD dw1, DWORD dw2 ) ! 300: { ! 301: // Advance frame counter, used to draw screen to window at 50fps ! 302: VBLCounter++; ! 303: ! 304: // Set event so waiting screen draw routine will continue ! 305: if (ConfigureParams.Configure.nMinMaxSpeed==MINMAXSPEED_MIN) { ! 306: // Do wish to skip frames? ! 307: if (ConfigureParams.Screen.Advanced.bFrameSkip) { ! 308: if (VBLCounter&1) ! 309: Main_SetVBLEvent(); // 25fps, with frame-skip ! 310: } ! 311: else ! 312: Main_SetVBLEvent(); // 50fps ! 313: } ! 314: ! 315: // And play sound through DirectSound, if enabled ! 316: if ( (ConfigureParams.Sound.bEnableSound) && bAppActive ) ! 317: Sound_PassYMSamplesToDirectSound(); ! 318: } ! 319: */ ! 320: ! 321: //----------------------------------------------------------------------- ! 322: /* ! 323: When running in non-standard ST speed this sets the VBL event to increase the ! 324: running speed of the emulator ! 325: */ ! 326: /* FIXME */ ! 327: /* ! 328: void CALLBACK Main_SpeedThreadFunc( UINT wTimerID, UINT msg, DWORD dwUsers, DWORD dw1, DWORD dw2 ) ! 329: { ! 330: // Advance screen update counter - ONLY if in max speed mode ! 331: if (ConfigureParams.Configure.nMinMaxSpeed!=MINMAXSPEED_MIN) ! 332: Main_SetVBLEvent(); ! 333: } ! 334: */ ! 335: ! 336: //----------------------------------------------------------------------- ! 337: /* ! 338: Set timer for 'Main_SpeedThreadFunc' to govern fast than ST emulation speed ! 339: When running in min/max speed this thread is ignored ! 340: */ ! 341: /* FIXME */ ! 342: /* ! 343: void Main_SetSpeedThreadTimer(int nMinMaxSpeed) ! 344: { ! 345: // Do we have an old timer? If so kill it ! 346: if (hSpeedTimer) { ! 347: timeKillEvent(hSpeedTimer); ! 348: hSpeedTimer = NULL; ! 349: } ! 350: ! 351: // Set new timer, according to MINMAXSPEED_xxxx ! 352: if ( ( (nMinMaxSpeed!=MINMAXSPEED_MIN) && nMinMaxSpeed!=MINMAXSPEED_MAX) && (!bQuitProgram) ) ! 353: hSpeedTimer = timeSetEvent(STSpeedMilliSeconds[nMinMaxSpeed],1,Main_SpeedThreadFunc,0,TIME_PERIODIC); ! 354: } ! 355: */ ! 356: ! 357: /*-----------------------------------------------------------------------*/ ! 358: /* ! 359: Check for any passed parameters ! 360: Used to disable DirectDraw, DirectSound and DirectInput for machines with problems ! 361: */ ! 362: void Main_ReadParameters(int argc, char *argv[]) ! 363: { ! 364: int i; ! 365: ! 366: /* Scan for any which we can use */ ! 367: for(i=1; i<argc; i++) ! 368: { ! 369: if (strlen(argv[i])>0) ! 370: { ! 371: if (!strcmp(argv[i],"--help") || !strcmp(argv[i],"-h")) ! 372: { ! 373: printf("Usage:\n hatari [options] [disk image name]\n" ! 374: "Where options are:\n" ! 375: " --help or -h Print this help text and exit.\n" ! 376: " --version or -v Print version number and exit.\n" ! 377: " --color or -c Start in color mode instead of mono.\n" ! 378: " --fullscreen or -f Try to use fullscreen mode.\n" ! 379: " --joystick or -j Emulate a ST joystick with the cursor keys\n" ! 380: ); ! 381: exit(0); ! 382: } ! 383: else if (!strcmp(argv[i],"--version") || !strcmp(argv[i],"-v")) ! 384: { ! 385: printf("This is %s.\n", PROG_NAME); ! 386: printf("This program is free software licensed under the GNU GPL.\n"); ! 387: exit(0); ! 388: } ! 389: else if (!strcmp(argv[i],"--color") || !strcmp(argv[i],"-c")) ! 390: { ! 391: bUseHighRes=FALSE; ! 392: } ! 393: else if (!strcmp(argv[i],"--fullscreen") || !strcmp(argv[i],"-f")) ! 394: { ! 395: bUseFullscreen=TRUE; ! 396: } ! 397: else if (!strcmp(argv[i],"--joystick") || !strcmp(argv[i],"-j")) ! 398: { ! 399: fprintf(stderr,"Joystate: %i\n",(int)ConfigureParams.Joysticks.Joy[1].bCursorEmulation); ! 400: ConfigureParams.Joysticks.Joy[1].bCursorEmulation=TRUE; ! 401: } ! 402: else ! 403: { ! 404: /* Possible passed disc image filename, ie starts with character other than '-' */ ! 405: if (argv[i][0]!='-') ! 406: strcpy(szBootDiscImage,argv[i]); ! 407: } ! 408: } ! 409: } ! 410: } ! 411: ! 412: //----------------------------------------------------------------------- ! 413: /* ! 414: Initialise emulation ! 415: */ ! 416: void Main_Init(void) ! 417: { ! 418: Misc_SeedRandom(1043618); ! 419: Printer_Init(); ! 420: RS232_Init(); ! 421: Configuration_Init(); ! 422: Timer_Init(); ! 423: File_Init(); ! 424: Screen_Init(); ! 425: Floppy_Init(); ! 426: Reset_Cold(); ! 427: GemDOS_Init(); ! 428: Intercept_Init(); ! 429: Joy_Init(); ! 430: DAudio_Init(); ! 431: Sound_Init(); ! 432: //FM Main_CreateVBLEvent(); ! 433: //FM Main_CreateSoundThread(); ! 434: ! 435: // Check passed disc image parameter, boot directly into emulator ! 436: if (strlen(szBootDiscImage)>0) { ! 437: Floppy_InsertDiscIntoDrive(0,szBootDiscImage); ! 438: //FM View_ToggleWindowsMouse(MOUSE_ST); ! 439: } ! 440: } ! 441: ! 442: //----------------------------------------------------------------------- ! 443: /* ! 444: Un-Initialise emulation ! 445: */ ! 446: void Main_UnInit(void) ! 447: { ! 448: Screen_ReturnFromFullScreen(); ! 449: //FM Main_SetSpeedThreadTimer(-1); ! 450: //FM Main_DeleteVBLEvent(); ! 451: //FM timeKillEvent(hSoundTimer); ! 452: Floppy_EjectBothDrives(); ! 453: Floppy_UnInit(); ! 454: RS232_UnInit(); ! 455: Printer_UnInit(); ! 456: // DJoy_UnInit(); ! 457: Intercept_UnInit(); ! 458: DAudio_UnInit(); ! 459: // DSurface_UnInit(); ! 460: YMFormat_FreeRecording(); ! 461: //FM View_LimitCursorToScreen(); ! 462: Screen_UnInit(); ! 463: ! 464: #ifdef USE_DEBUGGER ! 465: FreeDebugDialog(); ! 466: #endif ! 467: Configuration_UnInit(); ! 468: } ! 469: ! 470: //----------------------------------------------------------------------- ! 471: /* ! 472: Main ! 473: */ ! 474: int main(int argc, char *argv[]) ! 475: { ! 476: ! 477: /* Generate random seed */ ! 478: srand( time(NULL) ); ! 479: ! 480: /* Get working directory, if in MSDev force */ ! 481: Misc_FindWorkingDirectory(); ! 482: #ifdef FORCE_WORKING_DIR ! 483: getcwd(szWorkingDir, MAX_FILENAME_LENGTH); ! 484: #endif ! 485: ! 486: /* Create debug files */ ! 487: Debug_OpenFiles(); ! 488: ErrLog_OpenFile(); ! 489: ! 490: /* Check for any passed parameters */ ! 491: Main_ReadParameters(argc, argv); ! 492: ! 493: /* Init emulator system */ ! 494: Main_Init(); ! 495: ! 496: /* Set timing threads to govern timing and debug display */ ! 497: //FM Main_SetSpeedThreadTimer(ConfigureParams.Configure.nMinMaxSpeed); ! 498: //FM TimerID = SetTimer(hWnd,1,1000,NULL); ! 499: ! 500: #ifdef USE_DEBUGGER ! 501: /* Run our debugger */ ! 502: Debugger_Init(); ! 503: Main_UnPauseEmulation(); ! 504: /* Run messages until quit */ ! 505: for(;;) { ! 506: if (Main_ExecuteWindowsMessage()) ! 507: break; ! 508: } ! 509: #else ! 510: /* Run release emulation */ ! 511: Main_UnPauseEmulation(); ! 512: //RunIntructions(); ! 513: Init680x0(); /* Init CPU emulation */ ! 514: Start680x0(); /* Start emulation */ ! 515: #endif ! 516: ! 517: /* Un-init emulation system */ ! 518: //FM KillTimer(hWnd,TimerID); ! 519: Main_UnInit(); ! 520: ! 521: /* Close debug files */ ! 522: ErrLog_CloseFile(); ! 523: Debug_CloseFiles(); ! 524: ! 525: return(0); ! 526: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.