16 #define kPollEveryNFrames 5 //Poll input only every this many frames
17 #define kPollHgwEveryNFrames 10 //Poll osso only every this many frames
19 #define TRACE printf("trace: %s:%s\n", __FILE__, __func__);
20 #define DIE(format, ...) do { \
21 fprintf(stderr, "Died at %s:%d: ", __FILE__, __LINE__ ); \
22 fprintf(stderr, format "\n", ## __VA_ARGS__); \
26 void S9xMessage(int type, int number, const char * message)
28 printf("%s\n", message);
31 void S9xLoadSDD1Data()
33 Settings.SDD1Pack=FALSE;
36 void S9xAutoSaveSRAM()
38 Memory.SaveSRAM(S9xGetFilename(".srm"));
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(".smc");
63 printf("ROM: %s\n", file);
65 if (!Memory.LoadROM(file))
66 DIE("Loading ROM failed");
68 file = S9xGetFilename(".srm");
69 printf("SRAM: %s\n", file);
70 Memory.LoadSRAM(file);
73 /* This comes nearly straight from snes9x */
74 static void frameSync() {
75 static struct timeval next1 = {0, 0};
78 if (Settings.TurboMode)
80 if(Settings.SkipFrames == AUTO_FRAMERATE ||
81 ++IPPU.FrameSkip >= Settings.SkipFrames)
84 IPPU.SkippedFrames = 0;
85 IPPU.RenderThisFrame = TRUE;
90 IPPU.RenderThisFrame = FALSE;
97 while (gettimeofday(&now, 0) < 0);
99 /* If there is no known "next" frame, initialize it now */
100 if (next1.tv_sec == 0) { next1 = now; ++next1.tv_usec; }
102 /* If we're on AUTO_FRAMERATE, we'll display frames always
103 * only if there's excess time.
104 * Otherwise we'll display the defined amount of frames.
106 unsigned limit = Settings.SkipFrames == AUTO_FRAMERATE
107 ? (timercmp(&next1, &now, <) ? 10 : 1)
108 : Settings.SkipFrames;
110 IPPU.RenderThisFrame = ++IPPU.SkippedFrames >= limit;
111 if(IPPU.RenderThisFrame)
113 IPPU.SkippedFrames = 0;
117 /* If we were behind the schedule, check how much it is */
118 if(timercmp(&next1, &now, <))
121 (now.tv_sec - next1.tv_sec) * 1000000
122 + now.tv_usec - next1.tv_usec;
125 /* More than a half-second behind means probably
126 * pause. The next line prevents the magic
127 * fast-forward effect.
134 /* Delay until we're completed this frame */
136 /* Can't use setitimer because the sound code already could
137 * be using it. We don't actually need it either.
140 while(timercmp(&next1, &now, >))
142 /* If we're ahead of time, sleep a while */
144 (next1.tv_sec - now.tv_sec) * 1000000
145 + next1.tv_usec - now.tv_usec;
149 // XXX : CHECK_SOUND(); S9xProcessEvents(FALSE);
151 while (gettimeofday(&now, 0) < 0);
152 /* Continue with a while-loop because usleep()
153 * could be interrupted by a signal
157 /* Calculate the timestamp of the next frame. */
158 next1.tv_usec += Settings.FrameTime;
159 if (next1.tv_usec >= 1000000)
161 next1.tv_sec += next1.tv_usec / 1000000;
162 next1.tv_usec %= 1000000;
166 /** Wraps s9xProcessEvents, taking care of kPollEveryNFrames */
167 static inline void pollEvents() {
168 static int frames = 0;
170 if (++frames > kPollEveryNFrames) {
171 S9xProcessEvents(FALSE);
176 /** Wraps HgwPollEvents, taking care of kPollHgwEveryNFrames */
177 static inline void pollHgwEvents() {
178 static int frames = 0;
180 if (!hgwLaunched) return;
182 if (++frames > kPollHgwEveryNFrames) {
188 int main(int argc, const char ** argv) {
191 DIE("SDL_Init: %s", SDL_GetError());
194 HgwInit(); // Hildon-games-wrapper initialization.
195 S9xLoadConfig(argc, argv); // Load config files and parse cmd line.
196 HgwConfig(); // Apply specific hildon-games config.
198 // S9x initialization
199 S9xInitDisplay(argc, argv);
200 S9xInitAudioOutput();
201 S9xInitInputDevices();
205 // Load rom and related files: state
208 // Late initialization
209 sprintf(String, "DrNokSnes - %s", Memory.ROMName);
211 S9xHacksLoadFile(Config.hacksFile[0] ? Config.hacksFile : 0);
212 if (!S9xGraphicsInit())
213 DIE("S9xGraphicsInit failed");
214 S9xAudioOutputEnable(true);
217 frameSync(); // May block, or set frameskip to true.
218 S9xMainLoop(); // Does CPU things, renders if needed.
221 } while (!Config.quitting);
224 S9xAudioOutputEnable(false);
225 S9xDeinitAudioOutput();
229 Memory.SaveSRAM(S9xGetFilename(".srm"));
231 // Late deinitialization
241 void S9xDoAction(unsigned char action)
243 if (action & kActionQuit)
244 Config.quitting = true;
246 if (action & kActionToggleFullscreen)
247 S9xVideoToggleFullscreen();