19 #define kPollEveryNFrames 5 //Poll input only every this many frames
20 #define kPollOssoEveryNFrames 10 //Poll dbus only every this many frames
22 #define TRACE printf("trace: %s:%s\n", __FILE__, __func__);
23 #define DIE(format, ...) do { \
24 fprintf(stderr, "Died at %s:%d: ", __FILE__, __LINE__ ); \
25 fprintf(stderr, format "\n", ## __VA_ARGS__); \
29 void S9xMessage(int type, int number, const char * message)
31 printf("%s\n", message);
34 void S9xAutoSaveSRAM()
36 Memory.SaveSRAM(S9xGetFilename(FILE_SRAM));
41 if (!Memory.Init () || !S9xInitAPU())
42 DIE("Memory or APU failed");
46 S9xSetSoundMute (TRUE);
48 // TODO: PAL/NTSC something better than this
49 Settings.PAL = Settings.ForcePAL;
51 Settings.FrameTime = Settings.PAL?Settings.FrameTimePAL:Settings.FrameTimeNTSC;
52 Memory.ROMFramesPerSecond = Settings.PAL?50:60;
54 IPPU.RenderThisFrame = TRUE;
59 const char * file = S9xGetFilename(FILE_ROM);
61 printf("ROM: %s\n", file);
63 if (!Memory.LoadROM(file))
64 DIE("Loading ROM failed");
66 file = S9xGetFilename(FILE_SRAM);
67 printf("SRAM: %s\n", file);
68 Memory.LoadSRAM(file);
71 static void resumeGame()
73 if (!Config.snapshotLoad) return;
75 const char * file = S9xGetFilename(FILE_FREEZE);
76 int result = S9xUnfreezeGame(file);
78 printf("Unfreeze: %s", file);
82 FILE* fp = fopen(file, "rb");
84 if (Config.snapshotSave) {
85 puts(", but the file exists, so I'm not going to overwrite it");
86 Config.snapshotSave = false;
92 puts(" (file does not exist)");
99 static void pauseGame()
101 if (!Config.snapshotSave) return;
103 const char * file = S9xGetFilename(FILE_FREEZE);
104 int result = S9xFreezeGame(file);
106 printf("Freeze: %s", file);
109 Config.snapshotSave = false; // Serves as a flag to Hgw
116 /* This comes nearly straight from snes9x */
117 static void frameSync() {
118 if (Settings.TurboMode)
120 if(Settings.SkipFrames == AUTO_FRAMERATE ||
121 ++IPPU.FrameSkip >= Settings.SkipFrames)
124 IPPU.SkippedFrames = 0;
125 IPPU.RenderThisFrame = TRUE;
129 ++IPPU.SkippedFrames;
130 IPPU.RenderThisFrame = FALSE;
134 static Uint32 next1 = 0;
135 Uint32 now = SDL_GetTicks();
137 // If there is no known "next" frame, initialize it now
142 // If we're on AUTO_FRAMERATE, we'll display frames always
143 // only if there's excess time.
144 // Otherwise we'll display around 1 frame every 10.
145 unsigned limit = Settings.SkipFrames == AUTO_FRAMERATE
146 ? (next1 < now ? 10 : 1)
147 : Settings.SkipFrames;
149 IPPU.RenderThisFrame = ++IPPU.SkippedFrames >= limit;
150 if (IPPU.RenderThisFrame) {
151 IPPU.SkippedFrames = 0;
153 // If we were behind the schedule, check how much it is
156 unsigned long lag = now - next1;
159 // More than a half-second behind means probably
160 // pause. The next line prevents the magic
161 // fast-forward effect.
167 // If we're now ahead of time, sleep a while
170 SDL_Delay(next1 - now);
171 // SDL will take care if a signal arrives, restarting sleep.
174 // Calculate the timestamp of the next frame.
175 next1 += Settings.FrameTime;
179 /** Wraps s9xProcessEvents, taking care of kPollEveryNFrames */
180 static inline void pollEvents() {
181 static int frames = 0;
183 if (++frames > kPollEveryNFrames) {
184 S9xProcessEvents(false);
190 /** Wraps OssoPollEvents, taking care of kPollOssoEveryNFrames */
191 static inline void pollOssoEvents() {
192 static int frames = 0;
194 if (!OssoOk()) return;
196 if (++frames > kPollOssoEveryNFrames) {
203 int main(int argc, char ** argv) {
206 DIE("SDL_Init: %s", SDL_GetError());
210 OssoInit(); // Hildon-games-wrapper initialization.
212 S9xLoadConfig(argc, argv); // Load config files and parse cmd line.
214 OssoConfig(); // Apply specific hildon-games config.
217 // S9x initialization
218 S9xInitDisplay(argc, argv);
219 S9xInitAudioOutput();
220 S9xInitInputDevices();
224 // Load rom and related files: state, unfreeze if needed
228 // Late initialization
229 sprintf(String, "DrNokSnes - %s", Memory.ROMName);
231 S9xHacksLoadFile(Config.hacksFile);
232 if (!S9xGraphicsInit())
233 DIE("S9xGraphicsInit failed");
234 S9xAudioOutputEnable(true);
237 frameSync(); // May block, or set frameskip to true.
238 S9xMainLoop(); // Does CPU things, renders if needed.
243 } while (!Config.quitting);
246 S9xAudioOutputEnable(false);
247 S9xDeinitInputDevices();
248 S9xDeinitAudioOutput();
252 Memory.SaveSRAM(S9xGetFilename(FILE_SRAM));
255 // Late deinitialization
268 void S9xDoAction(unsigned char action)
270 if (action & kActionQuit)
271 Config.quitting = true;
273 if (action & kActionToggleFullscreen) {
274 S9xVideoToggleFullscreen();
277 if (action & kActionQuickLoad1) {
278 const char * file = S9xGetQuickSaveFilename(1);
279 int result = S9xUnfreezeGame(file);
280 S9xSetInfoString("Load slot %u: %s", 1,
281 (result ? "done" : "failed"));
284 if (action & kActionQuickSave1) {
285 const char * file = S9xGetQuickSaveFilename(1);
286 int result = S9xFreezeGame(file);
287 S9xSetInfoString("Save slot %u: %s", 1,
288 (result ? "done" : "failed"));
291 if (action & kActionQuickLoad2) {
292 const char * file = S9xGetQuickSaveFilename(2);
293 int result = S9xUnfreezeGame(file);
294 S9xSetInfoString("Load slot %u: %s", 2,
295 (result ? "done" : "failed"));
298 if (action & kActionQuickSave2) {
299 const char * file = S9xGetQuickSaveFilename(2);
300 int result = S9xFreezeGame(file);
301 S9xSetInfoString("Save slot %u: %s", 2,
302 (result ? "done" : "failed"));