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