17 #define kPollEveryNFrames 5 //Poll input only every this many frames
18 #define kPollHgwEveryNFrames 10 //Poll dbus only every this many frames
20 #define TRACE printf("trace: %s:%s\n", __FILE__, __func__);
21 #define DIE(format, ...) do { \
22 fprintf(stderr, "Died at %s:%d: ", __FILE__, __LINE__ ); \
23 fprintf(stderr, format "\n", ## __VA_ARGS__); \
27 void S9xMessage(int type, int number, const char * message)
29 printf("%s\n", message);
32 void S9xLoadSDD1Data()
34 Settings.SDD1Pack=FALSE;
37 void S9xAutoSaveSRAM()
39 Memory.SaveSRAM(S9xGetFilename(FILE_SRAM));
44 if (!Memory.Init () || !S9xInitAPU())
45 DIE("Memory or APU failed");
49 S9xSetSoundMute (TRUE);
51 // TODO: PAL/NTSC something better than this
52 Settings.PAL = Settings.ForcePAL;
54 Settings.FrameTime = Settings.PAL?Settings.FrameTimePAL:Settings.FrameTimeNTSC;
55 Memory.ROMFramesPerSecond = Settings.PAL?50:60;
57 IPPU.RenderThisFrame = TRUE;
62 const char * file = S9xGetFilename(FILE_ROM);
64 printf("ROM: %s\n", file);
66 if (!Memory.LoadROM(file))
67 DIE("Loading ROM failed");
69 file = S9xGetFilename(FILE_SRAM);
70 printf("SRAM: %s\n", file);
71 Memory.LoadSRAM(file);
74 static void resumeGame()
76 if (!Config.snapshotLoad) return;
78 const char * file = S9xGetFilename(FILE_FREEZE);
79 int result = S9xUnfreezeGame(file);
81 printf("Unfreeze: %s", file);
85 FILE* fp = fopen(file, "rb");
87 if (Config.snapshotSave) {
88 puts(", but the file exists, so I'm not going to overwrite it");
89 Config.snapshotSave = false;
95 puts(" (file does not exist)");
102 static void pauseGame()
104 if (!Config.snapshotSave) return;
106 const char * file = S9xGetFilename(FILE_FREEZE);
107 int result = S9xFreezeGame(file);
109 printf("Freeze: %s", file);
112 Config.snapshotSave = false; // Serves as a flag to Hgw
119 /* This comes nearly straight from snes9x */
120 static void frameSync() {
121 if (Settings.TurboMode)
123 if(Settings.SkipFrames == AUTO_FRAMERATE ||
124 ++IPPU.FrameSkip >= Settings.SkipFrames)
127 IPPU.SkippedFrames = 0;
128 IPPU.RenderThisFrame = TRUE;
132 ++IPPU.SkippedFrames;
133 IPPU.RenderThisFrame = FALSE;
137 static Uint32 next1 = 0;
138 Uint32 now = SDL_GetTicks();
140 // If there is no known "next" frame, initialize it now
145 // If we're on AUTO_FRAMERATE, we'll display frames always
146 // only if there's excess time.
147 // Otherwise we'll display around 1 frame every 10.
148 unsigned limit = Settings.SkipFrames == AUTO_FRAMERATE
149 ? (next1 < now ? 10 : 1)
150 : Settings.SkipFrames;
152 IPPU.RenderThisFrame = ++IPPU.SkippedFrames >= limit;
153 if (IPPU.RenderThisFrame) {
154 IPPU.SkippedFrames = 0;
156 // If we were behind the schedule, check how much it is
159 unsigned long lag = now - next1;
162 // More than a half-second behind means probably
163 // pause. The next line prevents the magic
164 // fast-forward effect.
170 // If we're now ahead of time, sleep a while
173 SDL_Delay(next1 - now);
174 // SDL will take care if a signal arrives, restarting sleep.
177 // Calculate the timestamp of the next frame.
178 next1 += Settings.FrameTime;
182 /** Wraps s9xProcessEvents, taking care of kPollEveryNFrames */
183 static inline void pollEvents() {
184 static int frames = 0;
186 if (++frames > kPollEveryNFrames) {
187 S9xProcessEvents(FALSE);
192 /** Wraps HgwPollEvents, taking care of kPollHgwEveryNFrames */
193 static inline void pollHgwEvents() {
194 static int frames = 0;
196 if (!hgwLaunched) return;
198 if (++frames > kPollHgwEveryNFrames) {
204 int main(int argc, const char ** argv) {
207 DIE("SDL_Init: %s", SDL_GetError());
210 HgwInit(); // Hildon-games-wrapper initialization.
211 S9xLoadConfig(argc, argv); // Load config files and parse cmd line.
212 HgwConfig(); // Apply specific hildon-games config.
214 // S9x initialization
215 S9xInitDisplay(argc, argv);
216 S9xInitAudioOutput();
217 S9xInitInputDevices();
221 // Load rom and related files: state, unfreeze if needed
225 // Late initialization
226 sprintf(String, "DrNokSnes - %s", Memory.ROMName);
228 S9xHacksLoadFile(Config.hacksFile);
229 if (!S9xGraphicsInit())
230 DIE("S9xGraphicsInit failed");
231 S9xAudioOutputEnable(true);
234 frameSync(); // May block, or set frameskip to true.
235 S9xMainLoop(); // Does CPU things, renders if needed.
238 } while (!Config.quitting);
241 S9xAudioOutputEnable(false);
242 S9xDeinitInputDevices();
243 S9xDeinitAudioOutput();
247 Memory.SaveSRAM(S9xGetFilename(FILE_SRAM));
250 // Late deinitialization
261 void S9xDoAction(unsigned char action)
263 if (action & kActionQuit)
264 Config.quitting = true;
266 if (action & kActionToggleFullscreen) {
267 S9xVideoToggleFullscreen();
268 S9xInputFullscreenChanged();