17 #define kPollEveryNFrames 2 //Poll input only every this many frames
21 #define kPollOssoEveryNFrames 10 //Poll dbus only every this many frames
24 #define TRACE printf("trace: %s:%s\n", __FILE__, __func__);
25 #define DIE(format, ...) do { \
26 fprintf(stderr, "Died at %s:%d: ", __FILE__, __LINE__ ); \
27 fprintf(stderr, format "\n", ## __VA_ARGS__); \
31 void S9xMessage(int type, int number, const char * message)
33 printf("%s\n", message);
36 void S9xAutoSaveSRAM()
38 Memory.SaveSRAM(S9xGetFilename(FILE_SRAM));
43 if (!Memory.Init () || !S9xInitAPU())
44 DIE("Memory or APU failed");
48 S9xSetSoundMute (TRUE);
50 // TODO: PAL/NTSC something better than this
51 Settings.PAL = Settings.ForcePAL;
53 Settings.FrameTime = Settings.PAL?Settings.FrameTimePAL:Settings.FrameTimeNTSC;
54 Memory.ROMFramesPerSecond = Settings.PAL?50:60;
56 IPPU.RenderThisFrame = TRUE;
61 const char * file = S9xGetFilename(FILE_ROM);
63 printf("ROM: %s\n", file);
65 if (!Memory.LoadROM(file))
66 DIE("Loading ROM failed");
68 file = S9xGetFilename(FILE_SRAM);
69 printf("SRAM: %s\n", file);
70 Memory.LoadSRAM(file);
73 static void resumeGame()
75 if (!Config.snapshotLoad) return;
77 const char * file = S9xGetFilename(FILE_FREEZE);
78 int result = S9xUnfreezeGame(file);
80 printf("Unfreeze: %s", file);
84 FILE* fp = fopen(file, "rb");
86 if (Config.snapshotSave) {
87 puts(", but the file exists, so I'm not going to overwrite it");
88 Config.snapshotSave = false;
94 puts(" (file does not exist)");
101 static void pauseGame()
103 if (!Config.snapshotSave) return;
105 const char * file = S9xGetFilename(FILE_FREEZE);
106 int result = S9xFreezeGame(file);
108 printf("Freeze: %s", file);
111 Config.snapshotSave = false; // Serves as a flag to Hgw
118 /* This comes nearly straight from snes9x */
119 /** Calculates framerate, enables frame skip if to low, sleeps if too high, etc. */
120 static void frameSync() {
121 Uint32 now = SDL_GetTicks();
123 if (Settings.TurboMode)
125 // In Turbo mode, just skip as many frames as desired, but don't sleep.
126 if(Settings.SkipFrames == AUTO_FRAMERATE ||
127 ++IPPU.FrameSkip >= Settings.SkipFrames)
130 IPPU.SkippedFrames = 0;
131 IPPU.RenderThisFrame = TRUE;
135 ++IPPU.SkippedFrames;
136 IPPU.RenderThisFrame = FALSE;
139 // Take care of framerate display
140 if (Settings.DisplayFrameRate) {
141 static Uint32 last = 0;
142 // Update framecounter every second
143 if (now > last && (now - last > 1000)) {
144 IPPU.DisplayedRenderedFrameCount =
145 IPPU.RenderedFramesCount;
146 IPPU.RenderedFramesCount = 0;
151 static Uint32 next1 = 0;
153 // If there is no known "next" frame, initialize it now
158 // If we're on AUTO_FRAMERATE, we'll display frames always
159 // only if there's excess time.
160 // Otherwise we'll display around 1 frame every 10.
161 unsigned limit = Settings.SkipFrames == AUTO_FRAMERATE
162 ? (next1 < now ? 10 : 1)
163 : Settings.SkipFrames;
165 IPPU.RenderThisFrame = ++IPPU.SkippedFrames >= limit;
166 if (IPPU.RenderThisFrame) {
167 IPPU.SkippedFrames = 0;
169 // If we were behind the schedule, check how much it is
172 unsigned long lag = now - next1;
175 // More than a half-second behind means probably
176 // pause. The next line prevents the magic
177 // fast-forward effect.
183 // If we're now ahead of time, sleep a while
186 SDL_Delay(next1 - now);
187 // SDL will take care if a signal arrives, restarting sleep.
190 // Calculate the timestamp of the next frame.
191 next1 += Settings.FrameTime;
193 // Take care of framerate display
194 if (Settings.DisplayFrameRate) {
195 // Update every theoretical 60 frames
196 if (IPPU.FrameCount % Memory.ROMFramesPerSecond == 0) {
197 IPPU.DisplayedRenderedFrameCount =
198 IPPU.RenderedFramesCount;
199 IPPU.RenderedFramesCount = 0;
205 /** Wraps s9xProcessEvents, taking care of kPollEveryNFrames */
206 static inline void pollEvents() {
207 static int frames = 0;
209 if (++frames > kPollEveryNFrames) {
210 S9xProcessEvents(false);
216 /** Wraps OssoPollEvents, taking care of kPollOssoEveryNFrames */
217 static inline void pollOssoEvents() {
218 static int frames = 0;
220 if (!OssoOk()) return;
222 if (++frames > kPollOssoEveryNFrames) {
229 int main(int argc, char ** argv) {
232 DIE("SDL_Init: %s", SDL_GetError());
236 OssoInit(); // Hildon-games-wrapper initialization.
238 S9xLoadConfig(argc, argv); // Load config files and parse cmd line.
240 OssoConfig(); // Apply specific hildon-games config.
243 // S9x initialization
244 S9xInitDisplay(argc, argv);
245 S9xInitAudioOutput();
246 S9xInitInputDevices();
250 // Load rom and related files: state, unfreeze if needed
254 // Late initialization
255 sprintf(String, "DrNokSnes - %s", Memory.ROMName);
257 S9xHacksLoadFile(Config.hacksFile);
258 if (!S9xGraphicsInit())
259 DIE("S9xGraphicsInit failed");
260 S9xAudioOutputEnable(true);
263 frameSync(); // May block, or set frameskip to true.
264 S9xMainLoop(); // Does CPU things, renders if needed.
269 } while (!Config.quitting);
272 S9xAudioOutputEnable(false);
273 S9xDeinitInputDevices();
274 S9xDeinitAudioOutput();
278 Memory.SaveSRAM(S9xGetFilename(FILE_SRAM));
281 // Late deinitialization
294 void S9xDoAction(unsigned char action)
296 if (action & kActionQuit)
297 Config.quitting = true;
299 if (action & kActionToggleFullscreen) {
300 S9xVideoToggleFullscreen();
303 if (action & kActionQuickLoad1) {
304 const char * file = S9xGetQuickSaveFilename(1);
305 int result = S9xUnfreezeGame(file);
306 S9xSetInfoString("Load slot %u: %s", 1,
307 (result ? "done" : "failed"));
310 if (action & kActionQuickSave1) {
311 const char * file = S9xGetQuickSaveFilename(1);
312 int result = S9xFreezeGame(file);
313 S9xSetInfoString("Save slot %u: %s", 1,
314 (result ? "done" : "failed"));
317 if (action & kActionQuickLoad2) {
318 const char * file = S9xGetQuickSaveFilename(2);
319 int result = S9xUnfreezeGame(file);
320 S9xSetInfoString("Load slot %u: %s", 2,
321 (result ? "done" : "failed"));
324 if (action & kActionQuickSave2) {
325 const char * file = S9xGetQuickSaveFilename(2);
326 int result = S9xFreezeGame(file);
327 S9xSetInfoString("Save slot %u: %s", 2,
328 (result ? "done" : "failed"));