Annotation of previous/src/main.c, revision 1.1.1.4

1.1       root        1: /*
                      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.
                      8: */
                      9: const char Main_fileid[] = "Hatari main.c : " __DATE__ " " __TIME__;
                     10: 
                     11: #include <time.h>
1.1.1.2   root       12: #include <errno.h>
1.1       root       13: #include <SDL.h>
                     14: 
                     15: #include "main.h"
                     16: #include "configuration.h"
                     17: #include "control.h"
                     18: #include "options.h"
                     19: #include "dialog.h"
                     20: #include "ioMem.h"
1.1.1.2   root       21: #include "keymap.h"
1.1       root       22: #include "log.h"
                     23: #include "m68000.h"
                     24: #include "memorySnapShot.h"
                     25: #include "paths.h"
                     26: #include "reset.h"
1.1.1.2   root       27: #include "resolution.h"
1.1       root       28: #include "screen.h"
1.1.1.4 ! root       29: #include "scsi.h"
1.1       root       30: #include "sdlgui.h"
                     31: #include "shortcut.h"
                     32: #include "statusbar.h"
                     33: #include "nextMemory.h"
                     34: #include "str.h"
                     35: #include "video.h"
                     36: #include "avi_record.h"
                     37: #include "debugui.h"
1.1.1.2   root       38: #include "clocks_timings.h"
1.1.1.4 ! root       39: #include "file.h"
1.1.1.2   root       40: 
1.1       root       41: #include "hatari-glue.h"
                     42: 
1.1.1.2   root       43: #if HAVE_GETTIMEOFDAY
                     44: #include <sys/time.h>
                     45: #endif
1.1       root       46: 
1.1.1.4 ! root       47: int nFrameSkips;
1.1       root       48: 
                     49: bool bQuitProgram = false;                /* Flag to quit program cleanly */
                     50: 
1.1.1.2   root       51: static Uint32 nRunVBLs;                   /* Whether and how many VBLS to run before exit */
1.1       root       52: static Uint32 nFirstMilliTick;            /* Ticks when VBL counting started */
                     53: static Uint32 nVBLCount;                  /* Frame count */
                     54: 
                     55: static bool bEmulationActive = true;      /* Run emulation when started */
                     56: static bool bAccurateDelays;              /* Host system has an accurate SDL_Delay()? */
                     57: static bool bIgnoreNextMouseMotion = false;  /* Next mouse motion will be ignored (needed after SDL_WarpMouse) */
                     58: 
                     59: 
                     60: /*-----------------------------------------------------------------------*/
                     61: /**
                     62:  * Return current time as millisecond for performance measurements.
                     63:  * 
                     64:  * (On Unix only time spent by Hatari itself is counted, on other
                     65:  * platforms less accurate SDL "wall clock".)
                     66:  */
                     67: #if HAVE_SYS_TIMES_H
                     68: #include <unistd.h>
                     69: #include <sys/times.h>
                     70: static Uint32 Main_GetTicks(void)
                     71: {
                     72:        static unsigned int ticks_to_msec = 0;
                     73:        struct tms fields;
                     74:        if (!ticks_to_msec)
                     75:        {
                     76:                ticks_to_msec = sysconf(_SC_CLK_TCK);
                     77:                printf("OS clock ticks / second: %d\n", ticks_to_msec);
                     78:                /* Linux has 100Hz virtual clock so no accuracy loss there */
                     79:                ticks_to_msec = 1000UL / ticks_to_msec;
                     80:        }
                     81:        /* return milliseconds (clock ticks) spent in this process
                     82:         */
                     83:        times(&fields);
                     84:        return ticks_to_msec * fields.tms_utime;
                     85: }
                     86: #else
                     87: # warning "times() function missing, using inaccurate SDL_GetTicks() instead."
                     88: # define Main_GetTicks SDL_GetTicks
                     89: #endif
                     90: 
                     91: 
1.1.1.2   root       92: //#undef HAVE_GETTIMEOFDAY
                     93: //#undef HAVE_NANOSLEEP
                     94: 
                     95: /*-----------------------------------------------------------------------*/
                     96: /**
                     97:  * Return a time counter in micro seconds.
                     98:  * If gettimeofday is available, we use it directly, else we convert the
                     99:  * return of SDL_GetTicks in micro sec.
                    100:  */
                    101: 
                    102: static Sint64  Time_GetTicks ( void )
                    103: {
                    104:         Sint64         ticks_micro;
                    105: 
                    106: #if HAVE_GETTIMEOFDAY
                    107:         struct timeval now;
                    108:         gettimeofday ( &now , NULL );
                    109:         ticks_micro = (Sint64)now.tv_sec * 1000000 + now.tv_usec;
                    110: #else
                    111:        ticks_micro = (Sint64)SDL_GetTicks() * 1000;            /* milli sec -> micro sec */
                    112: #endif
                    113: 
                    114:        return ticks_micro;
                    115: }
                    116: 
                    117: 
                    118: /*-----------------------------------------------------------------------*/
                    119: /**
                    120:  * Sleep for a given number of micro seconds.
                    121:  * If nanosleep is available, we use it directly, else we use SDL_Delay
                    122:  * (which is portable, but less accurate as is uses milli-seconds)
                    123:  */
                    124: 
                    125: static void    Time_Delay ( Sint64 ticks_micro )
                    126: {
                    127: #if HAVE_NANOSLEEP
                    128:        struct timespec ts;
                    129:        int             ret;
                    130:        ts.tv_sec = ticks_micro / 1000000;
                    131:        ts.tv_nsec = (ticks_micro % 1000000) * 1000;    /* micro sec -> nano sec */
                    132:        /* wait until all the delay is elapsed, including possible interruptions by signals */
                    133:        do
                    134:        {
                    135:                 errno = 0;
                    136:                 ret = nanosleep(&ts, &ts);
                    137:        } while ( ret && ( errno == EINTR ) );          /* keep on sleeping if we were interrupted */
                    138: #else
                    139:        SDL_Delay ( (Uint32)(ticks_micro / 1000) ) ;    /* micro sec -> milli sec */
                    140: #endif
                    141: }
                    142: 
                    143: 
1.1       root      144: /*-----------------------------------------------------------------------*/
                    145: /**
                    146:  * Pause emulation, stop sound.  'visualize' should be set true,
                    147:  * unless unpause will be called immediately afterwards.
                    148:  * 
                    149:  * @return true if paused now, false if was already paused
                    150:  */
                    151: bool Main_PauseEmulation(bool visualize)
                    152: {
                    153:        if ( !bEmulationActive )
                    154:                return false;
                    155: 
1.1.1.2   root      156: //     Audio_EnableAudio(false);
1.1       root      157:        bEmulationActive = false;
                    158:        if (visualize)
                    159:        {
                    160:                if (nFirstMilliTick)
                    161:                {
                    162:                        int interval = Main_GetTicks() - nFirstMilliTick;
                    163:                        static float previous;
                    164:                        float current;
                    165: 
                    166:                        current = (1000.0 * nVBLCount) / interval;
                    167:                        printf("SPEED: %.1f VBL/s (%d/%.1fs), diff=%.1f%%\n",
                    168:                               current, nVBLCount, interval/1000.0,
1.1.1.2   root      169:                               previous>0.0 ? 100*(current-previous)/previous : 0.0);
1.1       root      170:                        nVBLCount = nFirstMilliTick = 0;
                    171:                        previous = current;
                    172:                }
                    173:                
                    174:                Statusbar_AddMessage("Emulation paused", 100);
                    175:                /* make sure msg gets shown */
                    176:                Statusbar_Update(sdlscrn);
                    177: 
                    178:                if (bGrabMouse && !bInFullScreen)
                    179:                        /* Un-grab mouse pointer in windowed mode */
                    180:                        SDL_WM_GrabInput(SDL_GRAB_OFF);
                    181:        }
                    182:        return true;
                    183: }
                    184: 
                    185: /*-----------------------------------------------------------------------*/
                    186: /**
                    187:  * Start/continue emulation
                    188:  * 
                    189:  * @return true if continued, false if was already running
                    190:  */
                    191: bool Main_UnPauseEmulation(void)
                    192: {
                    193:        if ( bEmulationActive )
                    194:                return false;
                    195: 
1.1.1.2   root      196: //     Sound_BufferIndexNeedReset = true;
                    197: //     Audio_EnableAudio(ConfigureParams.Sound.bEnableSound);
1.1       root      198:        bEmulationActive = true;
                    199: 
                    200:        /* Cause full screen update (to clear all) */
                    201:        Screen_SetFullUpdate();
                    202: 
                    203:        if (bGrabMouse)
                    204:                /* Grab mouse pointer again */
                    205:                SDL_WM_GrabInput(SDL_GRAB_ON);
                    206:        return true;
                    207: }
                    208: 
                    209: /*-----------------------------------------------------------------------*/
                    210: /**
                    211:  * Optionally ask user whether to quit and set bQuitProgram accordingly
                    212:  */
                    213: void Main_RequestQuit(void)
                    214: {
                    215:        if (ConfigureParams.Memory.bAutoSave)
                    216:        {
                    217:                bQuitProgram = true;
                    218:                MemorySnapShot_Capture(ConfigureParams.Memory.szAutoSaveFileName, false);
                    219:        }
                    220:        else if (ConfigureParams.Log.bConfirmQuit)
                    221:        {
                    222:                bQuitProgram = false;   /* if set true, dialog exits */
                    223:                bQuitProgram = DlgAlert_Query("All unsaved data will be lost.\nDo you really want to quit?");
                    224:        }
                    225:        else
                    226:        {
                    227:                bQuitProgram = true;
                    228:        }
                    229: 
                    230:        if (bQuitProgram)
                    231:        {
                    232:                /* Assure that CPU core shuts down */
                    233:                M68000_SetSpecial(SPCFLAG_BRK);
                    234:        }
                    235: }
                    236: 
                    237: /*-----------------------------------------------------------------------*/
                    238: /**
1.1.1.2   root      239:  * Set how many VBLs Hatari should run, from the moment this function
                    240:  * is called.
                    241:  */
                    242: void Main_SetRunVBLs(Uint32 vbls)
                    243: {
                    244:        fprintf(stderr, "Exit after %d VBLs.\n", vbls);
                    245:        nRunVBLs = vbls;
                    246:        nVBLCount = 0;
                    247: }
                    248: 
                    249: /*-----------------------------------------------------------------------*/
                    250: /**
1.1       root      251:  * This function waits on each emulated VBL to synchronize the real time
                    252:  * with the emulated ST.
                    253:  * Unfortunately SDL_Delay and other sleep functions like usleep or nanosleep
                    254:  * are very inaccurate on some systems like Linux 2.4 or Mac OS X (they can only
                    255:  * wait for a multiple of 10ms due to the scheduler on these systems), so we have
                    256:  * to "busy wait" there to get an accurate timing.
1.1.1.2   root      257:  * All times are expressed as micro seconds, to avoid too much rounding error.
1.1       root      258:  */
                    259: void Main_WaitOnVbl(void)
                    260: {
1.1.1.2   root      261:        Sint64 CurrentTicks;
                    262:        static Sint64 DestTicks = 0;
                    263:        Sint64 FrameDuration_micro;
                    264:        Sint64 nDelay;
1.1       root      265: 
                    266:        nVBLCount++;
                    267:        if (nRunVBLs && nVBLCount >= nRunVBLs)
                    268:        {
                    269:                /* show VBLs/s */
                    270:                Main_PauseEmulation(true);
                    271:                exit(0);
                    272:        }
                    273: 
1.1.1.2   root      274: //     FrameDuration_micro = (Sint64) ( 1000000.0 / nScreenRefreshRate + 0.5 );        /* round to closest integer */
1.1.1.4 ! root      275:        FrameDuration_micro = ClocksTimings_GetVBLDuration_micro ( ConfigureParams.System.nMachineType , 68 );
        !           276: //      FrameDuration_micro = 1000000/50;
1.1.1.2   root      277:        CurrentTicks = Time_GetTicks();
                    278: 
                    279:        if ( DestTicks == 0 )                                   /* first call, init DestTicks */
                    280:                DestTicks = CurrentTicks + FrameDuration_micro;
                    281: 
                    282:        nDelay = DestTicks - CurrentTicks;
1.1       root      283: 
                    284:        /* Do not wait if we are in fast forward mode or if we are totally out of sync */
                    285:        if (ConfigureParams.System.bFastForward == true
1.1.1.2   root      286:                || nDelay < -4*FrameDuration_micro)
1.1       root      287:        {
                    288:                if (ConfigureParams.System.bFastForward == true)
                    289:                {
                    290:                        if (!nFirstMilliTick)
                    291:                                nFirstMilliTick = Main_GetTicks();
                    292:                }
1.1.1.4 ! root      293:                if (nFrameSkips < ConfigureParams.Screen.nFrameSkips)
        !           294:                {
        !           295:                        nFrameSkips += 1;
        !           296:                        Log_Printf(LOG_DEBUG, "Increased frameskip to %d\n", nFrameSkips);
        !           297:                }
1.1.1.2   root      298:                /* Only update DestTicks for next VBL */
                    299:                DestTicks = CurrentTicks + FrameDuration_micro;
1.1       root      300:                return;
                    301:        }
                    302:        /* If automatic frameskip is enabled and delay's more than twice
                    303:         * the effect of single frameskip, decrease frameskip
                    304:         */
1.1.1.4 ! root      305:        if (nFrameSkips > 0
        !           306:            && ConfigureParams.Screen.nFrameSkips >= AUTO_FRAMESKIP_LIMIT
        !           307:            && 2*nDelay > FrameDuration_micro/nFrameSkips)
        !           308:        {
        !           309:                nFrameSkips -= 1;
        !           310:                Log_Printf(LOG_DEBUG, "Decreased frameskip to %d\n", nFrameSkips);
        !           311:        }
1.1       root      312: 
                    313:        if (bAccurateDelays)
                    314:        {
                    315:                /* Accurate sleeping is possible -> use SDL_Delay to free the CPU */
1.1.1.2   root      316:                if (nDelay > 1000)
                    317:                        Time_Delay(nDelay - 1000);
1.1       root      318:        }
                    319:        else
                    320:        {
                    321:                /* No accurate SDL_Delay -> only wait if more than 5ms to go... */
1.1.1.2   root      322:                if (nDelay > 5000)
                    323:                        Time_Delay(nDelay<10000 ? nDelay-1000 : 9000);
1.1       root      324:        }
                    325: 
                    326:        /* Now busy-wait for the right tick: */
                    327:        while (nDelay > 0)
                    328:        {
1.1.1.2   root      329:                CurrentTicks = Time_GetTicks();
                    330:                nDelay = DestTicks - CurrentTicks;
1.1       root      331:        }
                    332: 
1.1.1.2   root      333: //printf ( "tick %lld\n" , CurrentTicks );
                    334:        /* Update DestTicks for next VBL */
                    335:        DestTicks += FrameDuration_micro;
1.1       root      336: }
                    337: 
                    338: 
                    339: /*-----------------------------------------------------------------------*/
                    340: /**
                    341:  * Since SDL_Delay and friends are very inaccurate on some systems, we have
                    342:  * to check if we can rely on this delay function.
                    343:  */
                    344: static void Main_CheckForAccurateDelays(void)
                    345: {
                    346:        int nStartTicks, nEndTicks;
                    347: 
                    348:        /* Force a task switch now, so we have a longer timeslice afterwards */
                    349:        SDL_Delay(10);
                    350: 
                    351:        nStartTicks = SDL_GetTicks();
                    352:        SDL_Delay(1);
                    353:        nEndTicks = SDL_GetTicks();
                    354: 
                    355:        /* If the delay took longer than 10ms, we are on an inaccurate system! */
                    356:        bAccurateDelays = ((nEndTicks - nStartTicks) < 9);
                    357: 
                    358:        if (bAccurateDelays)
                    359:                Log_Printf(LOG_WARN, "Host system has accurate delays. (%d)\n", nEndTicks - nStartTicks);
                    360:        else
                    361:                Log_Printf(LOG_WARN, "Host system does not have accurate delays. (%d)\n", nEndTicks - nStartTicks);
                    362: }
                    363: 
                    364: 
                    365: /* ----------------------------------------------------------------------- */
                    366: /**
                    367:  * Set mouse pointer to new coordinates and set flag to ignore the mouse event
                    368:  * that is generated by SDL_WarpMouse().
                    369:  */
                    370: void Main_WarpMouse(int x, int y)
                    371: {
                    372:        SDL_WarpMouse(x, y);                  /* Set mouse pointer to new position */
                    373:        bIgnoreNextMouseMotion = true;        /* Ignore mouse motion event from SDL_WarpMouse */
                    374: }
                    375: 
                    376: 
                    377: /* ----------------------------------------------------------------------- */
                    378: /**
                    379:  * Handle mouse motion event.
                    380:  */
                    381: static void Main_HandleMouseMotion(SDL_Event *pEvent)
                    382: {
                    383:        int dx, dy;
                    384:        static int ax = 0, ay = 0;
                    385: 
                    386:        /* Ignore motion when position has changed right after a reset or TOS
                    387:         * (especially version 4.04) might get confused and play key clicks */
1.1.1.4 ! root      388:        if (bIgnoreNextMouseMotion )
1.1       root      389:        {
                    390:                bIgnoreNextMouseMotion = false;
                    391:                return;
                    392:        }
                    393: 
                    394:        dx = pEvent->motion.xrel;
                    395:        dy = pEvent->motion.yrel;
                    396: 
                    397:        /* In zoomed low res mode, we divide dx and dy by the zoom factor so that
                    398:         * the ST mouse cursor stays in sync with the host mouse. However, we have
                    399:         * to take care of lowest bit of dx and dy which will get lost when
                    400:         * dividing. So we store these bits in ax and ay and add them to dx and dy
                    401:         * the next time. */
                    402:        if (nScreenZoomX != 1)
                    403:        {
                    404:                dx += ax;
                    405:                ax = dx % nScreenZoomX;
                    406:                dx /= nScreenZoomX;
                    407:        }
                    408:        if (nScreenZoomY != 1)
                    409:        {
                    410:                dy += ay;
                    411:                ay = dy % nScreenZoomY;
                    412:                dy /= nScreenZoomY;
                    413:        }
                    414: 
1.1.1.2   root      415: //     KeyboardProcessor.Mouse.dx += dx;
                    416: //     KeyboardProcessor.Mouse.dy += dy;
1.1       root      417: }
                    418: 
                    419: 
                    420: /* ----------------------------------------------------------------------- */
                    421: /**
                    422:  * SDL message handler.
                    423:  * Here we process the SDL events (keyboard, mouse, ...) and map it to
                    424:  * Atari IKBD events.
                    425:  */
                    426: void Main_EventHandler(void)
                    427: {
                    428:        bool bContinueProcessing;
                    429:        SDL_Event event;
                    430:        int events;
                    431:        int remotepause;
                    432: 
                    433:        do
                    434:        {
                    435:                bContinueProcessing = false;
                    436: 
                    437:                /* check remote process control */
                    438:                remotepause = Control_CheckUpdates();
                    439: 
                    440:                if ( bEmulationActive || remotepause )
                    441:                {
                    442:                        events = SDL_PollEvent(&event);
                    443:                }
                    444:                else
                    445:                {
                    446:                        ShortCut_ActKey();
                    447:                        /* last (shortcut) event activated emulation? */
                    448:                        if ( bEmulationActive )
                    449:                                break;
                    450:                        events = SDL_WaitEvent(&event);
                    451:                }
                    452:                if (!events)
                    453:                {
                    454:                        /* no events -> if emulation is active or
                    455:                         * user is quitting -> return from function.
                    456:                         */
                    457:                        continue;
                    458:                }
                    459:                switch (event.type)
                    460:                {
                    461: 
                    462:                 case SDL_QUIT:
                    463:                        Main_RequestQuit();
                    464:                        break;
                    465:                        
                    466:                 case SDL_MOUSEMOTION:               /* Read/Update internal mouse position */
                    467:                        Main_HandleMouseMotion(&event);
                    468:                        bContinueProcessing = true;
                    469:                        break;
                    470: 
                    471:                 case SDL_MOUSEBUTTONDOWN:
                    472:                        if (event.button.button == SDL_BUTTON_LEFT)
                    473:                        {
1.1.1.2   root      474: //                             if (Keyboard.LButtonDblClk == 0)
                    475: //                                     Keyboard.bLButtonDown |= BUTTON_MOUSE;  /* Set button down flag */
1.1       root      476:                        }
                    477:                        else if (event.button.button == SDL_BUTTON_RIGHT)
                    478:                        {
1.1.1.2   root      479: //                             Keyboard.bRButtonDown |= BUTTON_MOUSE;
1.1       root      480:                        }
                    481:                        else if (event.button.button == SDL_BUTTON_MIDDLE)
                    482:                        {
1.1.1.2   root      483:                                /* Start double-click sequence in emulation time */
                    484: //                             Keyboard.LButtonDblClk = 1;
1.1       root      485:                        }
                    486:                        else if (event.button.button == SDL_BUTTON_WHEELDOWN)
                    487:                        {
1.1.1.2   root      488:                                /* Simulate pressing the "cursor down" key */
                    489: //                             IKBD_PressSTKey(0x50, true);
1.1       root      490:                        }
                    491:                        else if (event.button.button == SDL_BUTTON_WHEELUP)
                    492:                        {
1.1.1.2   root      493:                                /* Simulate pressing the "cursor up" key */
                    494: //                             IKBD_PressSTKey(0x48, true);
1.1       root      495:                        }
                    496:                        break;
                    497: 
                    498:                 case SDL_MOUSEBUTTONUP:
                    499:                        if (event.button.button == SDL_BUTTON_LEFT)
                    500:                        {
1.1.1.2   root      501: //                             Keyboard.bLButtonDown &= ~BUTTON_MOUSE;
1.1       root      502:                        }
                    503:                        else if (event.button.button == SDL_BUTTON_RIGHT)
                    504:                        {
1.1.1.2   root      505: //                             Keyboard.bRButtonDown &= ~BUTTON_MOUSE;
1.1       root      506:                        }
                    507:                        else if (event.button.button == SDL_BUTTON_WHEELDOWN)
                    508:                        {
1.1.1.2   root      509:                                /* Simulate releasing the "cursor down" key */
                    510: //                             IKBD_PressSTKey(0x50, false);
1.1       root      511:                        }
                    512:                        else if (event.button.button == SDL_BUTTON_WHEELUP)
                    513:                        {
1.1.1.2   root      514:                                /* Simulate releasing the "cursor up" key */
                    515: //                             IKBD_PressSTKey(0x48, false);
1.1       root      516:                        }
                    517:                        break;
                    518: 
                    519:                 case SDL_KEYDOWN:
1.1.1.3   root      520: //          fprintf(stderr, "keydwn\n");
                    521: //                     Keymap_KeyDown(&event.key.keysym);
                    522:             KeyTranslator(&event.key.keysym);
1.1       root      523:                        break;
                    524: 
                    525:                 case SDL_KEYUP:
1.1.1.3   root      526: //                     Keymap_KeyUp(&event.key.keysym);
                    527:             KeyRelease(&event.key.keysym);
1.1       root      528:                        break;
                    529: 
                    530:                default:
                    531:                        /* don't let unknown events delay event processing */
                    532:                        bContinueProcessing = true;
                    533:                        break;
                    534:                }
                    535:        } while (bContinueProcessing || !(bEmulationActive || bQuitProgram));
                    536: }
                    537: 
                    538: 
                    539: /*-----------------------------------------------------------------------*/
                    540: /**
1.1.1.2   root      541:  * Set Hatari window title. Use NULL for default
                    542:  */
                    543: void Main_SetTitle(const char *title)
                    544: {
                    545:        if (title)
1.1.1.4 ! root      546:                SDL_WM_SetCaption(title, "Previous");
1.1.1.2   root      547:        else
1.1.1.4 ! root      548:                SDL_WM_SetCaption(PROG_NAME, "Previous");
1.1.1.2   root      549: }
                    550: 
                    551: /*-----------------------------------------------------------------------*/
                    552: /**
1.1       root      553:  * Initialise emulation
                    554:  */
                    555: static void Main_Init(void)
                    556: {
                    557:        /* Open debug log file */
                    558:        if (!Log_Init())
                    559:        {
                    560:                fprintf(stderr, "Logging/tracing initialization failed\n");
                    561:                exit(-1);
                    562:        }
                    563:        Log_Printf(LOG_INFO, PROG_NAME ", compiled on:  " __DATE__ ", " __TIME__ "\n");
                    564: 
                    565:        /* Init SDL's video subsystem. Note: Audio and joystick subsystems
                    566:           will be initialized later (failures there are not fatal). */
                    567:        if (SDL_Init(SDL_INIT_VIDEO | Opt_GetNoParachuteFlag()) < 0)
                    568:        {
                    569:                fprintf(stderr, "Could not initialize the SDL library:\n %s\n", SDL_GetError() );
                    570:                exit(-1);
                    571:        }
1.1.1.2   root      572:        ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
                    573:        Resolution_Init();
1.1       root      574:        SDLGui_Init();
                    575:        Screen_Init();
1.1.1.2   root      576:        Main_SetTitle(NULL);
                    577: //     HostScreen_Init();
                    578: //     DSP_Init();
                    579: //     Floppy_Init();
1.1       root      580:        M68000_Init();                /* Init CPU emulation */
1.1.1.2   root      581: //     Audio_Init();
                    582: //     DmaSnd_Init();
1.1.1.3   root      583:        Keymap_Init();
1.1.1.2   root      584: 
1.1.1.4 ! root      585: 
1.1.1.2   root      586:     /* call menu at startup */
1.1.1.4 ! root      587:     if (!File_Exists(sConfigFileName) || ConfigureParams.ConfigDialog.bShowConfigDialogAtStartup)
        !           588:         Dialog_DoProperty();
        !           589:     else
        !           590:         Dialog_CheckFiles();
        !           591:     
1.1.1.2   root      592:     if (bQuitProgram)
1.1.1.4 ! root      593:     {
        !           594:         SDL_Quit();
        !           595:         exit(-2);
        !           596:     }
        !           597:     
        !           598:     
        !           599: //    const char *err_msg;
        !           600: //    
        !           601: //    while ((err_msg=Reset_Cold())!=NULL)
        !           602: //    {
        !           603: //        DlgMissing_Rom();
        !           604: //        if (bQuitProgram) {
        !           605: //            Main_RequestQuit();
        !           606: //            break;
        !           607: //        }
        !           608: //    }
        !           609: 
        !           610:     Reset_Cold();
        !           611:     
        !           612: //    if (bQuitProgram) {
        !           613: //        SDL_Quit();
        !           614: //        exit(-2);
        !           615: //    }
1.1       root      616:        IoMem_Init();
                    617:        
                    618:        /* done as last, needs CPU & DSP running... */
                    619:        DebugUI_Init();
                    620: }
                    621: 
                    622: 
                    623: /*-----------------------------------------------------------------------*/
                    624: /**
                    625:  * Un-Initialise emulation
                    626:  */
                    627: static void Main_UnInit(void)
                    628: {
                    629:        Screen_ReturnFromFullScreen();
1.1.1.4 ! root      630:        SCSI_Uninit();
1.1       root      631:        IoMem_UnInit();
                    632:        SDLGui_UnInit();
                    633:        Screen_UnInit();
                    634:        Exit680x0();
                    635: 
                    636:        /* SDL uninit: */
                    637:        SDL_Quit();
                    638: 
                    639:        /* Close debug log file */
                    640:        Log_UnInit();
                    641: }
                    642: 
                    643: 
                    644: /*-----------------------------------------------------------------------*/
                    645: /**
                    646:  * Load initial configuration file(s)
                    647:  */
                    648: static void Main_LoadInitialConfig(void)
                    649: {
                    650:        char *psGlobalConfig;
                    651: 
                    652:        psGlobalConfig = malloc(FILENAME_MAX);
                    653:        if (psGlobalConfig)
                    654:        {
                    655: #if defined(__AMIGAOS4__)
                    656:                strncpy(psGlobalConfig, CONFDIR"previous.cfg", FILENAME_MAX);
                    657: #else
                    658:                snprintf(psGlobalConfig, FILENAME_MAX, CONFDIR"%cprevious.cfg", PATHSEP);
                    659: #endif
                    660:                /* Try to load the global configuration file */
                    661:                Configuration_Load(psGlobalConfig);
                    662: 
                    663:                free(psGlobalConfig);
                    664:        }
                    665: 
                    666:        /* Now try the users configuration file */
                    667:        Configuration_Load(NULL);
                    668: }
                    669: 
                    670: /*-----------------------------------------------------------------------*/
                    671: /**
                    672:  * Set TOS etc information and initial help message
                    673:  */
                    674: static void Main_StatusbarSetup(void)
                    675: {
                    676:        const char *name = NULL;
                    677:        SDLKey key;
                    678: 
                    679:        key = ConfigureParams.Shortcut.withoutModifier[SHORTCUT_OPTIONS];
                    680:        if (!key)
                    681:                key = ConfigureParams.Shortcut.withModifier[SHORTCUT_OPTIONS];
                    682:        if (key)
                    683:                name = SDL_GetKeyName(key);
                    684:        if (name)
                    685:        {
                    686:                char message[24], *keyname;
                    687: #ifdef _MUDFLAP
                    688:                __mf_register(name, 32, __MF_TYPE_GUESS, "SDL keyname");
                    689: #endif
                    690:                keyname = Str_ToUpper(strdup(name));
                    691:                snprintf(message, sizeof(message), "Press %s for Options", keyname);
                    692:                free(keyname);
                    693: 
                    694:                Statusbar_AddMessage(message, 6000);
                    695:        }
                    696:        /* update information loaded by Main_Init() */
                    697:        Statusbar_UpdateInfo();
                    698: }
                    699: 
                    700: /*-----------------------------------------------------------------------*/
                    701: /**
                    702:  * Main
                    703:  * 
                    704:  * Note: 'argv' cannot be declared const, MinGW would then fail to link.
                    705:  */
                    706: int main(int argc, char *argv[])
                    707: {
                    708:        /* Generate random seed */
                    709:        srand(time(NULL));
                    710: 
                    711:        /* Initialize directory strings */
                    712:        Paths_Init(argv[0]);
                    713: 
                    714:        /* Set default configuration values: */
                    715:        Configuration_SetDefault();
                    716: 
                    717:        /* Now load the values from the configuration file */
                    718:        Main_LoadInitialConfig();
                    719: 
                    720:        /* Check for any passed parameters */
1.1.1.2   root      721:        if (!Opt_ParseParameters(argc, (const char * const *)argv))
1.1       root      722:        {
                    723:                return 1;
                    724:        }
                    725:        /* monitor type option might require "reset" -> true */
                    726:        Configuration_Apply(true);
                    727: 
                    728: #ifdef WIN32
                    729:        Win_OpenCon();
                    730: #endif
                    731: 
                    732:        /* Needed on maemo but useful also with normal X11 window managers
                    733:         * for window grouping when you have multiple Hatari SDL windows open
                    734:         */
                    735: #if HAVE_SETENV
                    736:        setenv("SDL_VIDEO_X11_WMCLASS", "previous", 1);
                    737: #endif
                    738: 
                    739:        /* Init emulator system */
                    740:        Main_Init();
                    741: 
                    742:        /* Set initial Statusbar information */
                    743:        Main_StatusbarSetup();
                    744:        
                    745:        /* Check if SDL_Delay is accurate */
                    746:        Main_CheckForAccurateDelays();
                    747: 
                    748: 
                    749:        /* Run emulation */
                    750:        Main_UnPauseEmulation();
                    751:        M68000_Start();                 /* Start emulation */
                    752: 
1.1.1.4 ! root      753: 
1.1       root      754:        /* Un-init emulation system */
                    755:        Main_UnInit();
                    756: 
                    757:        return 0;
                    758: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.