Annotation of previous_trunk/src/main.c, revision 1.1

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>
        !            12: #include <errno.h>
        !            13: #include <signal.h>
        !            14: 
        !            15: #include "main.h"
        !            16: #include "configuration.h"
        !            17: #include "dialog.h"
        !            18: #include "ioMem.h"
        !            19: #include "keymap.h"
        !            20: #include "log.h"
        !            21: #include "m68000.h"
        !            22: #include "paths.h"
        !            23: #include "reset.h"
        !            24: #include "screen.h"
        !            25: #include "sdlgui.h"
        !            26: #include "shortcut.h"
        !            27: #include "snd.h"
        !            28: #include "statusbar.h"
        !            29: #include "nextMemory.h"
        !            30: #include "str.h"
        !            31: #include "video.h"
        !            32: #include "audio.h"
        !            33: #include "debugui.h"
        !            34: #include "file.h"
        !            35: #include "dsp.h"
        !            36: #include "host.h"
        !            37: #include "dimension.hpp"
        !            38: 
        !            39: #include "hatari-glue.h"
        !            40: #include "NextBus.hpp"
        !            41: 
        !            42: #if HAVE_GETTIMEOFDAY
        !            43: #include <sys/time.h>
        !            44: #endif
        !            45: 
        !            46: int nFrameSkips;
        !            47: 
        !            48: bool bQuitProgram = false;                /* Flag to quit program cleanly */
        !            49: 
        !            50: static bool bEmulationActive = true;      /* Run emulation when started */
        !            51: static bool bAccurateDelays;              /* Host system has an accurate SDL_Delay()? */
        !            52: static bool bIgnoreNextMouseMotion = false;  /* Next mouse motion will be ignored (needed after SDL_WarpMouse) */
        !            53: 
        !            54: volatile int mainPauseEmulation;
        !            55: 
        !            56: typedef const char* (*report_func)(double realTime, double hostTime);
        !            57: 
        !            58: typedef struct {
        !            59:     const char*       label;
        !            60:     const report_func report;
        !            61: } report_t;
        !            62: 
        !            63: static double lastRT;
        !            64: static Uint64 lastCycles;
        !            65: static double speedFactor;
        !            66: static char   speedMsg[32];
        !            67: 
        !            68: static void Main_Speed(double realTime, double hostTime) {
        !            69:     double dRT = realTime - lastRT;
        !            70:     speedFactor = nCyclesMainCounter - lastCycles;
        !            71:     speedFactor /= ConfigureParams.System.nCpuFreq;
        !            72:     speedFactor /= 1000 * 1000;
        !            73:     speedFactor /= dRT;
        !            74:     lastRT     = realTime;
        !            75:     lastCycles = nCyclesMainCounter;
        !            76: }
        !            77: 
        !            78: void Main_SpeedReset(void) {
        !            79:     double realTime, hostTime;
        !            80:     host_time(&realTime, &hostTime);
        !            81:     lastRT     = realTime;
        !            82:     lastCycles = nCyclesMainCounter;
        !            83:     
        !            84:     Log_Printf(LOG_WARN, "Realtime mode %s.\n", ConfigureParams.System.bRealtime ? "enabled" : "disabled");
        !            85: }
        !            86: 
        !            87: const char* Main_SpeedMsg() {
        !            88:     speedMsg[0] = 0;
        !            89:     if(speedFactor > 0) {
        !            90:         if(ConfigureParams.System.bRealtime) {
        !            91:             sprintf(speedMsg, "%dMHz/", (int)(ConfigureParams.System.nCpuFreq * speedFactor + 0.5));
        !            92:         } else {
        !            93:             if ((speedFactor < 0.9) || (speedFactor > 1.1))
        !            94:                 sprintf(speedMsg, "%.1fx%dMHz/", speedFactor, ConfigureParams.System.nCpuFreq);
        !            95:             else
        !            96:                 sprintf(speedMsg, "%dMHz/",                   ConfigureParams.System.nCpuFreq);
        !            97:         }
        !            98:     }
        !            99:     return speedMsg;
        !           100: }
        !           101: 
        !           102: #if ENABLE_TESTING
        !           103: static const report_t reports[] = {
        !           104:     {"ND",    nd_reports},
        !           105:     {"Host",  host_report},
        !           106: };
        !           107: #endif
        !           108: 
        !           109: /*-----------------------------------------------------------------------*/
        !           110: /**
        !           111:  * Pause emulation, stop sound.  'visualize' should be set true,
        !           112:  * unless unpause will be called immediately afterwards.
        !           113:  * 
        !           114:  * @return true if paused now, false if was already paused
        !           115:  */
        !           116: bool Main_PauseEmulation(bool visualize) {
        !           117:        if ( !bEmulationActive )
        !           118:                return false;
        !           119: 
        !           120:        bEmulationActive = false;
        !           121:     host_pause_time(!(bEmulationActive));
        !           122:     Screen_Pause(true);
        !           123:     Sound_Pause(true);
        !           124:     NextBus_Pause(true);
        !           125:     
        !           126:        if (visualize) {
        !           127:                Statusbar_AddMessage("Emulation paused", 100);
        !           128:                /* make sure msg gets shown */
        !           129:                Statusbar_Update(sdlscrn);
        !           130: 
        !           131:                if (bGrabMouse && !bInFullScreen) {
        !           132:                        /* Un-grab mouse pointer in windowed mode */
        !           133:                        SDL_SetRelativeMouseMode(SDL_FALSE);
        !           134:             SDL_SetWindowGrab(sdlWindow, SDL_FALSE);
        !           135:         }
        !           136:        }
        !           137:        return true;
        !           138: }
        !           139: 
        !           140: /*-----------------------------------------------------------------------*/
        !           141: /**
        !           142:  * Start/continue emulation
        !           143:  * 
        !           144:  * @return true if continued, false if was already running
        !           145:  */
        !           146: bool Main_UnPauseEmulation(void) {
        !           147:        if ( bEmulationActive )
        !           148:                return false;
        !           149: 
        !           150:        bEmulationActive = true;
        !           151:     host_pause_time(!(bEmulationActive));
        !           152:     Screen_Pause(false);
        !           153:     Sound_Pause(false);
        !           154:     NextBus_Pause(false);
        !           155: 
        !           156:        if (bGrabMouse) {
        !           157:                /* Grab mouse pointer again */
        !           158:                SDL_SetRelativeMouseMode(SDL_TRUE);
        !           159:         SDL_SetWindowGrab(sdlWindow, SDL_TRUE);
        !           160:     }
        !           161:        return true;
        !           162: }
        !           163: 
        !           164: /*-----------------------------------------------------------------------*/
        !           165: /**
        !           166:  * Optionally ask user whether to quit and set bQuitProgram accordingly
        !           167:  */
        !           168: void Main_RequestQuit(void) {
        !           169:     if (ConfigureParams.Log.bConfirmQuit) {
        !           170:                bQuitProgram = false;   /* if set true, dialog exits */
        !           171:                bQuitProgram = DlgAlert_Query("All unsaved data will be lost.\nDo you really want to quit?");
        !           172:        }
        !           173:        else {
        !           174:                bQuitProgram = true;
        !           175:        }
        !           176: 
        !           177:        if (bQuitProgram) {
        !           178:                /* Assure that CPU core shuts down */
        !           179:                M68000_SetSpecial(SPCFLAG_BRK);
        !           180:        }
        !           181: }
        !           182: 
        !           183: /*-----------------------------------------------------------------------*/
        !           184: /**
        !           185:  * Since SDL_Delay and friends are very inaccurate on some systems, we have
        !           186:  * to check if we can rely on this delay function.
        !           187:  */
        !           188: static void Main_CheckForAccurateDelays(void) {
        !           189:        int nStartTicks, nEndTicks;
        !           190: 
        !           191:        /* Force a task switch now, so we have a longer timeslice afterwards */
        !           192:        SDL_Delay(10);
        !           193: 
        !           194:        nStartTicks = SDL_GetTicks();
        !           195:        SDL_Delay(1);
        !           196:        nEndTicks = SDL_GetTicks();
        !           197: 
        !           198:        /* If the delay took longer than 10ms, we are on an inaccurate system! */
        !           199:        bAccurateDelays = ((nEndTicks - nStartTicks) < 9);
        !           200: 
        !           201:        if (bAccurateDelays)
        !           202:                Log_Printf(LOG_WARN, "Host system has accurate delays. (%d)\n", nEndTicks - nStartTicks);
        !           203:        else
        !           204:                Log_Printf(LOG_WARN, "Host system does not have accurate delays. (%d)\n", nEndTicks - nStartTicks);
        !           205: }
        !           206: 
        !           207: 
        !           208: /* ----------------------------------------------------------------------- */
        !           209: /**
        !           210:  * Set mouse pointer to new coordinates and set flag to ignore the mouse event
        !           211:  * that is generated by SDL_WarpMouse().
        !           212:  */
        !           213: void Main_WarpMouse(int x, int y) {
        !           214:     SDL_WarpMouseInWindow(sdlWindow, x, y); /* Set mouse pointer to new position */
        !           215:        bIgnoreNextMouseMotion = true;          /* Ignore mouse motion event from SDL_WarpMouse */
        !           216: }
        !           217: 
        !           218: 
        !           219: /* ----------------------------------------------------------------------- */
        !           220: /**
        !           221:  * Handle mouse motion event.
        !           222:  */
        !           223: SDL_Event mymouse[100];
        !           224: static void Main_HandleMouseMotion(SDL_Event *pEvent) {
        !           225:        int dx, dy;
        !           226:        int i,nb;
        !           227: 
        !           228:        dx = pEvent->motion.xrel;
        !           229:        dy = pEvent->motion.yrel;
        !           230: 
        !           231:        /* get all mouse event to clean the queue and sum them */
        !           232:        nb=SDL_PeepEvents(&mymouse[0], 100, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION);
        !           233: 
        !           234:        for (i=0;i<nb;i++) {
        !           235:         dx += mymouse[i].motion.xrel;
        !           236:         dy += mymouse[i].motion.yrel;
        !           237:        }
        !           238: 
        !           239:        if (bGrabMouse) {
        !           240:        Keymap_MouseMove(dx,dy,ConfigureParams.Mouse.fLinSpeedLocked,ConfigureParams.Mouse.fExpSpeedLocked);
        !           241:        } else {
        !           242:        Keymap_MouseMove(dx,dy,ConfigureParams.Mouse.fLinSpeedNormal,ConfigureParams.Mouse.fLinSpeedNormal);
        !           243:        }
        !           244: }
        !           245: 
        !           246: static int statusBarUpdate;
        !           247: 
        !           248: /* ----------------------------------------------------------------------- */
        !           249: /**
        !           250:  * SDL message handler.
        !           251:  * Here we process the SDL events (keyboard, mouse, ...)
        !           252:  */
        !           253: void Main_EventHandler(void) {
        !           254:     bool bContinueProcessing;
        !           255:     SDL_Event event;
        !           256:     int events;
        !           257:     
        !           258:     if(++statusBarUpdate > 400) {
        !           259:         double vt;
        !           260:         double rt;
        !           261:         host_time(&rt, &vt);
        !           262: #if ENABLE_TESTING
        !           263:         fprintf(stderr, "[reports]");
        !           264:         for(int i = 0; i < sizeof(reports)/sizeof(report_t); i++) {
        !           265:             const char* msg = reports[i].report(rt, vt);
        !           266:             if(msg[0]) fprintf(stderr, " %s:%s", reports[i].label, msg);
        !           267:         }
        !           268:         fprintf(stderr, "\n");
        !           269: #else
        !           270:         Main_Speed(rt, vt);
        !           271: #endif
        !           272:         Statusbar_UpdateInfo();
        !           273:         statusBarUpdate = 0;
        !           274:     }
        !           275:     
        !           276:     do {
        !           277:         bContinueProcessing = false;
        !           278:         
        !           279:         /* check remote process control from different thread (e.g. i860) */
        !           280:         switch(mainPauseEmulation) {
        !           281:             case PAUSE_EMULATION:
        !           282:                 mainPauseEmulation = PAUSE_NONE;
        !           283:                 Main_PauseEmulation(true);
        !           284:                 break;
        !           285:             case UNPAUSE_EMULATION:
        !           286:                 mainPauseEmulation = PAUSE_NONE;
        !           287:                 Main_UnPauseEmulation();
        !           288:                 break;
        !           289:         }
        !           290:         
        !           291:         if (bEmulationActive) {
        !           292:             double time_offset = host_real_time_offset() * 1000;
        !           293:             if(time_offset > 10)
        !           294:                 events = SDL_WaitEventTimeout(&event, time_offset);
        !           295:             else
        !           296:                 events = SDL_PollEvent(&event);
        !           297:         }
        !           298:         else {
        !           299:             ShortCut_ActKey();
        !           300:             /* last (shortcut) event activated emulation? */
        !           301:             if ( bEmulationActive )
        !           302:                 break;
        !           303:             events = SDL_WaitEvent(&event);
        !           304:         }
        !           305:         if (!events) {
        !           306:             /* no events -> if emulation is active or
        !           307:              * user is quitting -> return from function.
        !           308:              */
        !           309:             continue;
        !           310:         }
        !           311:         switch (event.type) {
        !           312:             case SDL_WINDOWEVENT:
        !           313:                 if(event.window.event == SDL_WINDOWEVENT_CLOSE) {
        !           314:                     SDL_WaitEventTimeout(&event, 100); // grab SDL_Quit if pending
        !           315:                     Main_RequestQuit();
        !           316:                 }
        !           317:                 continue;
        !           318: 
        !           319:             case SDL_QUIT:
        !           320:                 Main_RequestQuit();
        !           321:                 break;
        !           322:                 
        !           323:             case SDL_MOUSEMOTION:               /* Read/Update internal mouse position */
        !           324:                 Main_HandleMouseMotion(&event);
        !           325:                 bContinueProcessing = false;
        !           326:                 break;
        !           327:                 
        !           328:             case SDL_MOUSEBUTTONDOWN:
        !           329:                 if (event.button.button == SDL_BUTTON_LEFT) {
        !           330:                     if (ConfigureParams.Mouse.bEnableAutoGrab && !bGrabMouse) {
        !           331:                         bGrabMouse = true;        /* Toggle flag */
        !           332:                         
        !           333:                         /* If we are in windowed mode, toggle the mouse cursor mode now: */
        !           334:                         if (!bInFullScreen)
        !           335:                         {
        !           336:                             SDL_SetRelativeMouseMode(SDL_TRUE);
        !           337:                             SDL_SetWindowGrab(sdlWindow, SDL_TRUE);
        !           338:                             Main_SetTitle(MOUSE_LOCK_MSG);
        !           339:                         }
        !           340:                     }
        !           341:                     
        !           342:                     Keymap_MouseDown(true);
        !           343:                 }
        !           344:                 else if (event.button.button == SDL_BUTTON_RIGHT)
        !           345:                 {
        !           346:                     Keymap_MouseDown(false);
        !           347:                 }
        !           348:                 break;
        !           349:                 
        !           350:             case SDL_MOUSEBUTTONUP:
        !           351:                 if (event.button.button == SDL_BUTTON_LEFT) {
        !           352:                     Keymap_MouseUp(true);
        !           353:                 }
        !           354:                 else if (event.button.button == SDL_BUTTON_RIGHT)
        !           355:                 {
        !           356:                     Keymap_MouseUp(false);
        !           357:                 }
        !           358:                 break;
        !           359:                 
        !           360:             case SDL_MOUSEWHEEL:
        !           361:                 Keymap_MouseWheel(&event.wheel);
        !           362:                 break;
        !           363:                 
        !           364:             case SDL_KEYDOWN:
        !           365:                 if (event.key.repeat)
        !           366:                     break;
        !           367:                 
        !           368:                 Keymap_KeyDown(&event.key.keysym);
        !           369:                 break;
        !           370:                 
        !           371:             case SDL_KEYUP:
        !           372:                 Keymap_KeyUp(&event.key.keysym);
        !           373:                 break;
        !           374:                 
        !           375:                 
        !           376:             default:
        !           377:                 /* don't let unknown events delay event processing */
        !           378:                 bContinueProcessing = true;
        !           379:                 break;
        !           380:         }
        !           381:     } while (bContinueProcessing || !(bEmulationActive || bQuitProgram));
        !           382: }
        !           383: 
        !           384: 
        !           385: void Main_EventHandlerInterrupt() {
        !           386:     CycInt_AcknowledgeInterrupt();
        !           387:     Main_EventHandler();
        !           388:     CycInt_AddRelativeInterruptUs((1000*1000)/200, 0, INTERRUPT_EVENT_LOOP); // poll events with 200 Hz
        !           389: }
        !           390: 
        !           391: /*-----------------------------------------------------------------------*/
        !           392: /**
        !           393:  * Set Hatari window title. Use NULL for default
        !           394:  */
        !           395: void Main_SetTitle(const char *title) {
        !           396:     if (title)
        !           397:         SDL_SetWindowTitle(sdlWindow, title);
        !           398:     else
        !           399:         SDL_SetWindowTitle(sdlWindow, PROG_NAME);
        !           400: }
        !           401: 
        !           402: /*-----------------------------------------------------------------------*/
        !           403: /**
        !           404:  * Initialise emulation
        !           405:  */
        !           406: static void Main_Init(void) {
        !           407:        /* Open debug log file */
        !           408:        if (!Log_Init()) {
        !           409:                fprintf(stderr, "Logging/tracing initialization failed\n");
        !           410:                exit(-1);
        !           411:        }
        !           412:        Log_Printf(LOG_INFO, PROG_NAME ", compiled on:  " __DATE__ ", " __TIME__ "\n");
        !           413: 
        !           414:        /* Init SDL's video subsystem. Note: Audio and joystick subsystems
        !           415:           will be initialized later (failures there are not fatal). */
        !           416:        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
        !           417:        {
        !           418:                fprintf(stderr, "Could not initialize the SDL library:\n %s\n", SDL_GetError() );
        !           419:                exit(-1);
        !           420:        }
        !           421:        SDLGui_Init();
        !           422:        Screen_Init();
        !           423:        Main_SetTitle(NULL);
        !           424:        DSP_Init();
        !           425:        M68000_Init();                /* Init CPU emulation */
        !           426:        Keymap_Init();
        !           427: 
        !           428:     /* call menu at startup */
        !           429:     if (!File_Exists(sConfigFileName) || ConfigureParams.ConfigDialog.bShowConfigDialogAtStartup) {
        !           430:         Dialog_DoProperty();
        !           431:         if (bQuitProgram) {
        !           432:             SDL_Quit();
        !           433:             exit(-2);
        !           434:         }
        !           435:     }
        !           436: 
        !           437:     Dialog_CheckFiles();
        !           438:     
        !           439:     if (bQuitProgram) {
        !           440:         SDL_Quit();
        !           441:         exit(-2);
        !           442:     }
        !           443:     
        !           444:     Reset_Cold();
        !           445:     
        !           446:        IoMem_Init();
        !           447:        
        !           448:     /* Start EventHandler */
        !           449:     CycInt_AddRelativeInterruptUs(500*1000, 0, INTERRUPT_EVENT_LOOP);
        !           450:     
        !           451:        /* done as last, needs CPU & DSP running... */
        !           452:        DebugUI_Init();
        !           453: }
        !           454: 
        !           455: 
        !           456: /*-----------------------------------------------------------------------*/
        !           457: /**
        !           458:  * Un-Initialise emulation
        !           459:  */
        !           460: static void Main_UnInit(void) {
        !           461:        Screen_ReturnFromFullScreen();
        !           462:        IoMem_UnInit();
        !           463:        SDLGui_UnInit();
        !           464:        Screen_UnInit();
        !           465:        Exit680x0();
        !           466: 
        !           467:        /* SDL uninit: */
        !           468:        SDL_Quit();
        !           469: 
        !           470:        /* Close debug log file */
        !           471:        Log_UnInit();
        !           472: }
        !           473: 
        !           474: 
        !           475: /*-----------------------------------------------------------------------*/
        !           476: /**
        !           477:  * Load initial configuration file(s)
        !           478:  */
        !           479: static void Main_LoadInitialConfig(void) {
        !           480:        char *psGlobalConfig;
        !           481: 
        !           482:        psGlobalConfig = malloc(FILENAME_MAX);
        !           483:        if (psGlobalConfig)
        !           484:        {
        !           485: #if defined(__AMIGAOS4__)
        !           486:                strncpy(psGlobalConfig, CONFDIR"previous.cfg", FILENAME_MAX);
        !           487: #else
        !           488:                snprintf(psGlobalConfig, FILENAME_MAX, CONFDIR"%cprevious.cfg", PATHSEP);
        !           489: #endif
        !           490:                /* Try to load the global configuration file */
        !           491:                Configuration_Load(psGlobalConfig);
        !           492: 
        !           493:                free(psGlobalConfig);
        !           494:        }
        !           495: 
        !           496:        /* Now try the users configuration file */
        !           497:        Configuration_Load(NULL);
        !           498: }
        !           499: 
        !           500: /*-----------------------------------------------------------------------*/
        !           501: /**
        !           502:  * Set TOS etc information and initial help message
        !           503:  */
        !           504: static void Main_StatusbarSetup(void) {
        !           505:        const char *name = NULL;
        !           506:        SDL_Keycode key;
        !           507: 
        !           508:        key = ConfigureParams.Shortcut.withoutModifier[SHORTCUT_OPTIONS];
        !           509:        if (!key)
        !           510:                key = ConfigureParams.Shortcut.withModifier[SHORTCUT_OPTIONS];
        !           511:        if (key)
        !           512:                name = SDL_GetKeyName(key);
        !           513:        if (name)
        !           514:        {
        !           515:                char message[24], *keyname;
        !           516: #ifdef _MUDFLAP
        !           517:                __mf_register(name, 32, __MF_TYPE_GUESS, "SDL keyname");
        !           518: #endif
        !           519:                keyname = Str_ToUpper(strdup(name));
        !           520:                snprintf(message, sizeof(message), "Press %s for Options", keyname);
        !           521:                free(keyname);
        !           522: 
        !           523:                Statusbar_AddMessage(message, 6000);
        !           524:        }
        !           525:        /* update information loaded by Main_Init() */
        !           526:        Statusbar_UpdateInfo();
        !           527: }
        !           528: 
        !           529: #ifdef WIN32
        !           530:        extern void Win_OpenCon(void);
        !           531: #endif
        !           532: 
        !           533: /*-----------------------------------------------------------------------*/
        !           534: /**
        !           535:  * Set signal handlers to catch signals
        !           536:  */
        !           537: static void Main_SetSignalHandlers(void) {
        !           538: #ifndef _WIN32
        !           539:     signal(SIGPIPE, SIG_IGN);
        !           540: #endif
        !           541:     signal(SIGFPE, SIG_IGN);
        !           542: }
        !           543: 
        !           544: 
        !           545: /*-----------------------------------------------------------------------*/
        !           546: /**
        !           547:  * Main
        !           548:  * 
        !           549:  * Note: 'argv' cannot be declared const, MinGW would then fail to link.
        !           550:  */
        !           551: int main(int argc, char *argv[]) {
        !           552:        /* Generate random seed */
        !           553:        srand(time(NULL));
        !           554:     
        !           555:     /* Set signal handlers */
        !           556:     Main_SetSignalHandlers();
        !           557: 
        !           558:        /* Initialize directory strings */
        !           559:        Paths_Init(argv[0]);
        !           560: 
        !           561:        /* Set default configuration values: */
        !           562:        Configuration_SetDefault();
        !           563: 
        !           564:        /* Now load the values from the configuration file */
        !           565:        Main_LoadInitialConfig();
        !           566:     
        !           567: #if 0 /* FIXME: This sometimes causes exits when starting from application bundles */
        !           568:        /* Check for any passed parameters */
        !           569:        if (!Opt_ParseParameters(argc, (const char * const *)argv))
        !           570:        {
        !           571:                return 1;
        !           572:        }
        !           573: #endif
        !           574:        /* monitor type option might require "reset" -> true */
        !           575:        Configuration_Apply(true);
        !           576: 
        !           577: #ifdef WIN32
        !           578:        Win_OpenCon();
        !           579: #endif
        !           580: 
        !           581:        /* Needed on maemo but useful also with normal X11 window managers
        !           582:         * for window grouping when you have multiple Hatari SDL windows open
        !           583:         */
        !           584: #if HAVE_SETENV
        !           585:        setenv("SDL_VIDEO_X11_WMCLASS", "previous", 1);
        !           586: #endif
        !           587: 
        !           588:        /* Init emulator system */
        !           589:        Main_Init();
        !           590: 
        !           591:        /* Set initial Statusbar information */
        !           592:        Main_StatusbarSetup();
        !           593:        
        !           594:        /* Check if SDL_Delay is accurate */
        !           595:        Main_CheckForAccurateDelays();
        !           596: 
        !           597: 
        !           598:        /* Run emulation */
        !           599:        Main_UnPauseEmulation();
        !           600:        M68000_Start();                 /* Start emulation */
        !           601: 
        !           602: 
        !           603:        /* Un-init emulation system */
        !           604:        Main_UnInit();
        !           605: 
        !           606:        return 0;
        !           607: }

unix.superglobalmegacorp.com

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