X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=platform%2Fsdl.cpp;h=1558c6af7ad95d255a24711548e6d43ae5cc31d4;hb=2af26f8a9741caf38e67844501d3921c3a0e90f4;hp=b3477489e478f6bf018838394d3da26573267f29;hpb=a195aac8c156d1ddd532a8905cf5e0ad0557e289;p=drnoksnes diff --git a/platform/sdl.cpp b/platform/sdl.cpp index b347748..1558c6a 100644 --- a/platform/sdl.cpp +++ b/platform/sdl.cpp @@ -6,13 +6,18 @@ #include "platform.h" #include "snes9x.h" +#include "cpuexec.h" #include "gfx.h" +#include "ppu.h" #include "display.h" #include "memmap.h" #include "soundux.h" #include "hacks.h" +#include "snapshot.h" +#include "osso.h" -#define kPollEveryNFrames 4 //Poll input only every this many frames +#define kPollEveryNFrames 5 //Poll input only every this many frames +#define kPollOssoEveryNFrames 10 //Poll dbus only every this many frames #define TRACE printf("trace: %s:%s\n", __FILE__, __func__); #define DIE(format, ...) do { \ @@ -26,14 +31,9 @@ void S9xMessage(int type, int number, const char * message) printf("%s\n", message); } -void S9xLoadSDD1Data() -{TRACE - Settings.SDD1Pack=FALSE; -} - void S9xAutoSaveSRAM() { - Memory.SaveSRAM(S9xGetFilename(".srm")); + Memory.SaveSRAM(S9xGetFilename(FILE_SRAM)); } static void S9xInit() @@ -56,23 +56,65 @@ static void S9xInit() static void loadRom() { - const char * file = S9xGetFilename(".smc"); + const char * file = S9xGetFilename(FILE_ROM); printf("ROM: %s\n", file); if (!Memory.LoadROM(file)) DIE("Loading ROM failed"); - file = S9xGetFilename(".srm"); + file = S9xGetFilename(FILE_SRAM); printf("SRAM: %s\n", file); Memory.LoadSRAM(file); } +static void resumeGame() +{ + if (!Config.snapshotLoad) return; + + const char * file = S9xGetFilename(FILE_FREEZE); + int result = S9xUnfreezeGame(file); + + printf("Unfreeze: %s", file); + + if (!result) { + printf(" failed"); + FILE* fp = fopen(file, "rb"); + if (fp) { + if (Config.snapshotSave) { + puts(", but the file exists, so I'm not going to overwrite it"); + Config.snapshotSave = false; + } else { + puts(" (bad file?)"); + } + fclose(fp); + } else { + puts(" (file does not exist)"); + } + } else { + puts(" ok"); + } +} + +static void pauseGame() +{ + if (!Config.snapshotSave) return; + + const char * file = S9xGetFilename(FILE_FREEZE); + int result = S9xFreezeGame(file); + + printf("Freeze: %s", file); + + if (!result) { + Config.snapshotSave = false; // Serves as a flag to Hgw + puts(" failed"); + } else { + puts(" ok"); + } +} + /* This comes nearly straight from snes9x */ static void frameSync() { - static struct timeval next1 = {0, 0}; - struct timeval now; - if (Settings.TurboMode) { if(Settings.SkipFrames == AUTO_FRAMERATE || @@ -88,77 +130,50 @@ static void frameSync() { IPPU.RenderThisFrame = FALSE; } return; + } else { + static Uint32 next1 = 0; + Uint32 now = SDL_GetTicks(); + + // If there is no known "next" frame, initialize it now + if (next1 == 0) { + next1 = now + 1; + } + + // If we're on AUTO_FRAMERATE, we'll display frames always + // only if there's excess time. + // Otherwise we'll display around 1 frame every 10. + unsigned limit = Settings.SkipFrames == AUTO_FRAMERATE + ? (next1 < now ? 10 : 1) + : Settings.SkipFrames; + + IPPU.RenderThisFrame = ++IPPU.SkippedFrames >= limit; + if (IPPU.RenderThisFrame) { + IPPU.SkippedFrames = 0; + } else { + // If we were behind the schedule, check how much it is + if (next1 < now) + { + unsigned long lag = now - next1; + if (lag >= 500) + { + // More than a half-second behind means probably + // pause. The next line prevents the magic + // fast-forward effect. + next1 = now; + } + } + } + + // If we're now ahead of time, sleep a while + if (next1 > now) + { + SDL_Delay(next1 - now); + // SDL will take care if a signal arrives, restarting sleep. + } + + // Calculate the timestamp of the next frame. + next1 += Settings.FrameTime; } - - /* Normal mode */ - - while (gettimeofday(&now, 0) < 0); - - /* If there is no known "next" frame, initialize it now */ - if (next1.tv_sec == 0) { next1 = now; ++next1.tv_usec; } - - /* If we're on AUTO_FRAMERATE, we'll display frames always - * only if there's excess time. - * Otherwise we'll display the defined amount of frames. - */ - unsigned limit = Settings.SkipFrames == AUTO_FRAMERATE - ? (timercmp(&next1, &now, <) ? 10 : 1) - : Settings.SkipFrames; - - IPPU.RenderThisFrame = ++IPPU.SkippedFrames >= limit; - if(IPPU.RenderThisFrame) - { - IPPU.SkippedFrames = 0; - } - else - { - /* If we were behind the schedule, check how much it is */ - if(timercmp(&next1, &now, <)) - { - unsigned lag = - (now.tv_sec - next1.tv_sec) * 1000000 - + now.tv_usec - next1.tv_usec; - if(lag >= 500000) - { - /* More than a half-second behind means probably - * pause. The next line prevents the magic - * fast-forward effect. - */ - next1 = now; - } - } - } - - /* Delay until we're completed this frame */ - - /* Can't use setitimer because the sound code already could - * be using it. We don't actually need it either. - */ - - while(timercmp(&next1, &now, >)) - { - /* If we're ahead of time, sleep a while */ - unsigned timeleft = - (next1.tv_sec - now.tv_sec) * 1000000 - + next1.tv_usec - now.tv_usec; - - usleep(timeleft); - - // XXX : CHECK_SOUND(); S9xProcessEvents(FALSE); - - while (gettimeofday(&now, 0) < 0); - /* Continue with a while-loop because usleep() - * could be interrupted by a signal - */ - } - - /* Calculate the timestamp of the next frame. */ - next1.tv_usec += Settings.FrameTime; - if (next1.tv_usec >= 1000000) - { - next1.tv_sec += next1.tv_usec / 1000000; - next1.tv_usec %= 1000000; - } } /** Wraps s9xProcessEvents, taking care of kPollEveryNFrames */ @@ -166,33 +181,54 @@ static inline void pollEvents() { static int frames = 0; if (++frames > kPollEveryNFrames) { - S9xProcessEvents(FALSE); + S9xProcessEvents(false); + frames = 0; + } +} + +#if CONF_GUI +/** Wraps OssoPollEvents, taking care of kPollOssoEveryNFrames */ +static inline void pollOssoEvents() { + static int frames = 0; + + if (!OssoOk()) return; + + if (++frames > kPollOssoEveryNFrames) { + OssoPollEvents(); frames = 0; } } +#endif -int main(int argc, const char ** argv) { +int main(int argc, char ** argv) { // Initialise SDL if (SDL_Init(0) < 0) DIE("SDL_Init: %s", SDL_GetError()); - + // Configure snes9x - S9xLoadConfig(argc, argv); - +#if CONF_GUI + OssoInit(); // Hildon-games-wrapper initialization. +#endif + S9xLoadConfig(argc, argv); // Load config files and parse cmd line. +#if CONF_GUI + OssoConfig(); // Apply specific hildon-games config. +#endif + // S9x initialization S9xInitDisplay(argc, argv); S9xInitAudioOutput(); S9xInitInputDevices(); S9xInit(); S9xReset(); - - // Load rom and related files: state + + // Load rom and related files: state, unfreeze if needed loadRom(); - + resumeGame(); + // Late initialization sprintf(String, "DrNokSnes - %s", Memory.ROMName); S9xSetTitle(String); - S9xHacksLoadFile(Config.hacksFile[0] ? Config.hacksFile : 0); + S9xHacksLoadFile(Config.hacksFile); if (!S9xGraphicsInit()) DIE("S9xGraphicsInit failed"); S9xAudioOutputEnable(true); @@ -201,19 +237,28 @@ int main(int argc, const char ** argv) { frameSync(); // May block, or set frameskip to true. S9xMainLoop(); // Does CPU things, renders if needed. pollEvents(); +#if CONF_GUI + pollOssoEvents(); +#endif } while (!Config.quitting); // Deinitialization S9xAudioOutputEnable(false); + S9xDeinitInputDevices(); S9xDeinitAudioOutput(); S9xDeinitDisplay(); // Save state - Memory.SaveSRAM(S9xGetFilename(".srm")); + Memory.SaveSRAM(S9xGetFilename(FILE_SRAM)); + pauseGame(); // Late deinitialization S9xGraphicsDeinit(); Memory.Deinit(); + S9xUnloadConfig(); +#if CONF_GUI + OssoDeinit(); +#endif SDL_Quit(); @@ -224,8 +269,37 @@ void S9xDoAction(unsigned char action) { if (action & kActionQuit) Config.quitting = true; - - if (action & kActionToggleFullscreen) + + if (action & kActionToggleFullscreen) { S9xVideoToggleFullscreen(); + } + + if (action & kActionQuickLoad1) { + const char * file = S9xGetQuickSaveFilename(1); + int result = S9xUnfreezeGame(file); + S9xSetInfoString("Load slot %u: %s", 1, + (result ? "done" : "failed")); + } + + if (action & kActionQuickSave1) { + const char * file = S9xGetQuickSaveFilename(1); + int result = S9xFreezeGame(file); + S9xSetInfoString("Save slot %u: %s", 1, + (result ? "done" : "failed")); + } + + if (action & kActionQuickLoad2) { + const char * file = S9xGetQuickSaveFilename(2); + int result = S9xUnfreezeGame(file); + S9xSetInfoString("Load slot %u: %s", 2, + (result ? "done" : "failed")); + } + + if (action & kActionQuickSave2) { + const char * file = S9xGetQuickSaveFilename(2); + int result = S9xFreezeGame(file); + S9xSetInfoString("Save slot %u: %s", 2, + (result ? "done" : "failed")); + } }