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

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

unix.superglobalmegacorp.com

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