|
|
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.