#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 "hgw.h"
#define kPollEveryNFrames 5 //Poll input only every this many frames
-#define kPollHgwEveryNFrames 10 //Poll dbus 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 { \
printf("%s\n", message);
}
-void S9xLoadSDD1Data()
-{TRACE
- Settings.SDD1Pack=FALSE;
-}
-
void S9xAutoSaveSRAM()
{
Memory.SaveSRAM(S9xGetFilename(FILE_SRAM));
}
/* 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)
{
++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 */
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);
// 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);
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();
S9xGraphicsDeinit();
Memory.Deinit();
S9xUnloadConfig();
- HgwDeinit();
+#if CONF_GUI
+ OssoDeinit();
+#endif
SDL_Quit();
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"));
+ }
}