X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=platform%2Fsdl.cpp;h=c9d641ce98440fa34877202577ca324ec97cf748;hb=9902256814785f0b3f08d336a98c481c296ac7e5;hp=73a22bc729f1b1adf8dedafaa1c64ab3acb6c8d5;hpb=24f52d4c0f5f0402b9ae2fd7be1d350901472568;p=drnoksnes diff --git a/platform/sdl.cpp b/platform/sdl.cpp index 73a22bc..c9d641c 100644 --- a/platform/sdl.cpp +++ b/platform/sdl.cpp @@ -6,15 +6,20 @@ #include "platform.h" #include "snes9x.h" +#include "cpuexec.h" #include "gfx.h" -#include "display.h" +#include "ppu.h" #include "memmap.h" #include "soundux.h" #include "hacks.h" -#include "hgw.h" +#include "snapshot.h" #define kPollEveryNFrames 5 //Poll input only every this many frames -#define kPollHgwEveryNFrames 10 //Poll osso only every this many frames + +#if CONF_GUI +#include "osso.h" +#define kPollOssoEveryNFrames 10 //Poll dbus only every this many frames +#endif #define TRACE printf("trace: %s:%s\n", __FILE__, __func__); #define DIE(format, ...) do { \ @@ -28,14 +33,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() @@ -58,25 +58,71 @@ 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 */ +/** Calculates framerate, enables frame skip if to low, sleeps if too high, etc. */ static void frameSync() { - static struct timeval next1 = {0, 0}; - struct timeval now; - + Uint32 now = SDL_GetTicks(); + if (Settings.TurboMode) { + // In Turbo mode, just skip as many frames as desired, but don't sleep. if(Settings.SkipFrames == AUTO_FRAMERATE || ++IPPU.FrameSkip >= Settings.SkipFrames) { @@ -89,78 +135,71 @@ static void frameSync() { ++IPPU.SkippedFrames; IPPU.RenderThisFrame = FALSE; } - return; + + // Take care of framerate display + if (Settings.DisplayFrameRate) { + static Uint32 last = 0; + // Update framecounter every second + if (now > last && (now - last > 1000)) { + IPPU.DisplayedRenderedFrameCount = + IPPU.RenderedFramesCount; + IPPU.RenderedFramesCount = 0; + last = now; + } + } + } else { + static Uint32 next1 = 0; + + // 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; + + // Take care of framerate display + if (Settings.DisplayFrameRate) { + // Update every theoretical 60 frames + if (IPPU.FrameCount % Memory.ROMFramesPerSecond == 0) { + IPPU.DisplayedRenderedFrameCount = + IPPU.RenderedFramesCount; + IPPU.RenderedFramesCount = 0; + } + } } - - /* 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 */ @@ -168,47 +207,54 @@ static inline void pollEvents() { static int frames = 0; if (++frames > kPollEveryNFrames) { - S9xProcessEvents(FALSE); + S9xProcessEvents(false); frames = 0; } } -/** Wraps HgwPollEvents, taking care of kPollHgwEveryNFrames */ -static inline void pollHgwEvents() { +#if CONF_GUI +/** Wraps OssoPollEvents, taking care of kPollOssoEveryNFrames */ +static inline void pollOssoEvents() { static int frames = 0; - if (!hgwLaunched) return; + if (!OssoOk()) return; - if (++frames > kPollHgwEveryNFrames) { - HgwPollEvents(); + 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 - HgwInit(); // Hildon-games-wrapper initialization. +#if CONF_GUI + OssoInit(); // Hildon-games-wrapper initialization. +#endif S9xLoadConfig(argc, argv); // Load config files and parse cmd line. - HgwConfig(); // Apply specific hildon-games config. - +#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); @@ -217,21 +263,28 @@ int main(int argc, const char ** argv) { frameSync(); // May block, or set frameskip to true. S9xMainLoop(); // Does CPU things, renders if needed. pollEvents(); - pollHgwEvents(); +#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(); - HgwDeinit(); + S9xUnloadConfig(); +#if CONF_GUI + OssoDeinit(); +#endif SDL_Quit(); @@ -242,8 +295,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")); + } }