aboutsummaryrefslogtreecommitdiff
path: root/source/nds
diff options
context:
space:
mode:
Diffstat (limited to 'source/nds')
-rw-r--r--source/nds/entry.cpp195
-rw-r--r--source/nds/gui.c21
-rw-r--r--source/nds/gui.h62
-rw-r--r--source/nds/message.h17
4 files changed, 222 insertions, 73 deletions
diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp
index 5573f47..58adf49 100644
--- a/source/nds/entry.cpp
+++ b/source/nds/entry.cpp
@@ -343,6 +343,18 @@ void game_disableAudio()
S9xSetSoundMute (TRUE);
}
}
+
+void game_set_frameskip()
+{
+ if( game_config.frameskip_value == 0)
+ {
+ Settings.SkipFrames = AUTO_FRAMERATE;
+ }
+ else
+ {
+ Settings.SkipFrames = game_config.frameskip_value - 1 /* 1 -> 0 and so on */;
+ }
+}
void init_sfc_setting(void)
{
@@ -368,7 +380,6 @@ void init_sfc_setting(void)
Settings.ShutdownMaster = TRUE;
Settings.FrameTimePAL = 20000;
Settings.FrameTimeNTSC = 16667;
- Settings.FrameTime = Settings.FrameTimeNTSC;
Settings.DisableSampleCaching = FALSE;
Settings.DisableMasterVolume = FALSE;
Settings.Mouse = TRUE;
@@ -449,10 +460,12 @@ int load_gamepak(char* file)
game_disableAudio();
CPU.Flags = 0;
- S9xReset ();
// mdelay(50); // Delete this delay
if (!Memory.LoadROM (file))
return -1;
+ S9xReset ();
+
+ Settings.FrameTime = (Settings.PAL ? Settings.FrameTimePAL : Settings.FrameTimeNTSC);
Memory.LoadSRAM (S9xGetFilename (".srm"));
// mdelay(50); // Delete this delay
@@ -611,41 +624,18 @@ int sfc_main (int argc, char **argv)
return (0);
}
+static unsigned int sync_last= 0;
+static unsigned int sync_next = 0;
+static unsigned int framenum = 0;
+
+extern "C" u32 game_fast_forward;
+
+static unsigned int skip_rate= 0;
+
void S9xSyncSpeed ()
{
-#if 0
-#ifdef _NETPLAY_SUPPORT
- if (Settings.NetPlay)
- {
- // XXX: Send joypad position update to server
- // XXX: Wait for heart beat from server
- S9xNetPlaySendJoypadUpdate (joypads [0]);
- if (!S9xNetPlayCheckForHeartBeat ())
- {
- do
- {
- CHECK_SOUND ();
-// S9xProcessEvents (FALSE);
- } while (!S9xNetPlayCheckForHeartBeat ());
- IPPU.RenderThisFrame = TRUE;
- IPPU.SkippedFrames = 0;
- }
- else
- {
- if (IPPU.SkippedFrames < 10)
- {
- IPPU.SkippedFrames++;
- IPPU.RenderThisFrame = FALSE;
- }
- else
- {
- IPPU.RenderThisFrame = TRUE;
- IPPU.SkippedFrames = 0;
- }
- }
- }
- else
-#endif
+ uint32 syncnow;
+ int32 syncdif;
#if 0
if (Settings.SoundSync == 2)
@@ -655,30 +645,135 @@ void S9xSyncSpeed ()
return;
}
#endif
+ syncnow = getSysTime();
+
+ if (game_fast_forward)
+ {
+ sync_last = syncnow;
+ sync_next = syncnow;
+ if(++skip_rate < 10)
+ IPPU.RenderThisFrame = false;
+ else
+ {
+ skip_rate = 0;
+ IPPU.RenderThisFrame = true;
+ }
+ }
+ else if (Settings.SkipFrames == AUTO_FRAMERATE /* && !game_fast_forward */)
+ {
+ // frame_time is in getSysTime units: 42.667 microseconds.
+ uint32 frame_time = Settings.PAL ? 468 /* = 20.0 ms */ : 391 /* = 16.67 ms */;
+ if (sync_last > syncnow) // Overflow occurred! (every 50 hrs)
+ {
+ // Render this frame regardless, set the
+ // sync_next, and get the hell out.
+ IPPU.RenderThisFrame = TRUE;
+ sync_last = syncnow;
+ sync_next = syncnow + frame_time;
+ return;
+ }
+ sync_last = syncnow;
+ // If this is positive, we have syncdif*42.66 microseconds to
+ // spare.
+ // If this is negative, we're late by syncdif*42.66
+ // microseconds.
+ syncdif = sync_next - syncnow;
+ if (syncdif < 0 && syncdif >= -(frame_time / 2))
+ {
+ // We're late, but by less than half a frame. Draw it
+ // anyway. If the next frame is too late, it'll be
+ // skipped.
+ skip_rate = 0;
+ IPPU.RenderThisFrame = true;
+ sync_next += frame_time;
+ }
+ else if(syncdif < 0)
+ {
+ /*
+ * If we're consistently late, delay up to 8 frames.
+ *
+ * That really helps with certain games, such as
+ * Super Mario RPG and Yoshi's Island.
+ */
+ if(++skip_rate < 10)
+ {
+ if(syncdif >= -11719 /* not more than 500.0 ms late */)
+ {
+ IPPU.RenderThisFrame = FALSE;
+ sync_next += frame_time;
+ }
+ else
+ { //lag more than 0.5s, maybe paused
+ IPPU.RenderThisFrame = TRUE;
+ sync_next = syncnow + frame_time;
+ framenum = 0;
+ }
+ }
+ else
+ {
+ skip_rate = 0;
+ IPPU.RenderThisFrame = TRUE;
+ sync_next = syncnow + frame_time;
+ }
+ }
+ else // Early
+ {
+ skip_rate = 0;
+ ds2_setCPUclocklevel(0);
+ if (syncdif > 0)
+ udelay(syncdif * 128 / 3 /* times 42 + 2/3 microseconds */);
+ set_cpu_clock(clock_speed_number);
+ S9xProcessSound (0);
+
+ IPPU.RenderThisFrame = TRUE;
+ sync_next += frame_time;
+ }
#if 0
- if (Settings.TurboMode)
- {
- if(++IPPU.FrameSkip >= Settings.TurboSkipFrames)
- {
- IPPU.FrameSkip = 0;
- IPPU.SkippedFrames = 0;
- IPPU.RenderThisFrame = TRUE;
- }
- else
- {
- ++IPPU.SkippedFrames;
- IPPU.RenderThisFrame = FALSE;
- }
- return;
- }
+ if(++framenum >= 60)
+ {
+ syncdif = syncnow - sync_last;
+ sync_last = syncnow;
+ framenum = 0;
+ //printf("T %d %d\n", syncdif*42667/1000, realframe);
+ realframe = 0;
+ }
#endif
+ }
+ else /* if (Settings.SkipFrames != AUTO_FRAMERATE && !game_fast_forward) */
+ {
+ // frame_time is in getSysTime units: 42.667 microseconds.
+ uint32 frame_time = Settings.PAL ? 468 /* = 20.0 ms */ : 391 /* = 16.67 ms */;
+ sync_last = syncnow;
+ if (++skip_rate > Settings.SkipFrames)
+ {
+ skip_rate = 0;
+ IPPU.RenderThisFrame = TRUE;
+ // Are we early?
+ syncdif = sync_next - syncnow;
+ if (syncdif > 0)
+ {
+ ds2_setCPUclocklevel(0);
+ udelay(syncdif * 128 / 3 /* times 42 + 2/3 microseconds */);
+ set_cpu_clock(clock_speed_number);
+ S9xProcessSound (0);
+ // After that little delay, what time is it?
+ syncnow = getSysTime();
+ }
+ sync_next = syncnow + frame_time * Settings.SkipFrames;
+ }
+ else
+ {
+ IPPU.RenderThisFrame = FALSE;
+ }
+ }
#ifdef __sgi
/* BS: saves on CPU usage */
sginap(1);
#endif
+#if 0
/* Check events */
static struct timeval next1 = {0, 0};
diff --git a/source/nds/gui.c b/source/nds/gui.c
index 4ebb224..d198166 100644
--- a/source/nds/gui.c
+++ b/source/nds/gui.c
@@ -17,8 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "snes9x.h"
-
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
@@ -78,7 +78,7 @@ GAME_CONFIG game_config;
//save state file map
char savestate_map[SAVE_STATE_SLOT_NUM];
-static unsigned int savestate_index;
+static u32 savestate_index;
#define MAKE_MENU(name, init_function, passive_function, key_function, end_function, \
focus_option, screen_focus) \
@@ -2776,7 +2776,7 @@ u32 menu(u16 *screen)
(char*)&msg[MSG_VIDEO_ASPECT_RATIO_3],
(char*)&msg[MSG_VIDEO_ASPECT_RATIO_4]};
- char *frameskip_options[] = { (char*)&msg[MSG_FRAMESKIP_0], (char*)&msg[MSG_FRAMESKIP_1] };
+ char *frameskip_options[] = { (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_AUTOMATIC], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_0], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_1], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_2], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_3], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_4], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_5], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_6], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_7], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_8], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_9], (char*)&msg[MSG_VIDEO_FRAME_SKIPPING_10] };
char *on_off_options[] = { (char*)&msg[MSG_GENERAL_OFF], (char*)&msg[MSG_GENERAL_ON] };
@@ -2800,7 +2800,10 @@ u32 menu(u16 *screen)
&game_fast_forward, 2, NULL, ACTION_TYPE, 2),
/* 03 */ STRING_SELECTION_OPTION(game_disableAudio, NULL, &msg[FMT_AUDIO_SOUND], sound_seletion,
- &game_enable_audio, 2, NULL, ACTION_TYPE, 3)
+ &game_enable_audio, 2, NULL, ACTION_TYPE, 3),
+
+ /* 04 */ STRING_SELECTION_OPTION(game_set_frameskip, NULL, &msg[FMT_VIDEO_FRAME_SKIPPING], frameskip_options,
+ &game_config.frameskip_value, 12 /* auto (0) and 0..10 (1..11) make 12 option values */, NULL, ACTION_TYPE, 4)
};
MAKE_MENU(graphics, NULL, NULL, NULL, NULL, 0, 0);
@@ -4004,9 +4007,7 @@ void init_game_config(void)
game_config.clock_speed_number = 5; // 396 MHz by default
clock_speed_number = 5;
game_config.graphic = 3; // By default, have a good-looking aspect ratio
-
- game_config.gamepad_config_menu = BUTTON_ID_TOUCH;
- memcpy(game_config.gamepad_config_map, gamepad_config_map_init, sizeof(gamepad_config_map_init));
+ game_config.frameskip_value = 0; // Automatic frame skipping
game_config.backward = 0; //time backward disable
game_config.backward_time = 2; //time backward granularity 1s
@@ -4063,9 +4064,8 @@ void load_game_config_file(void)
{
fread(&game_config, 1, sizeof(GAME_CONFIG), fp);
- memcpy(gamepad_config_map, game_config.gamepad_config_map, sizeof(game_config.gamepad_config_map));
- gamepad_config_menu = game_config.gamepad_config_menu;
clock_speed_number = game_config.clock_speed_number;
+ Settings.SkipFrames = (game_config.frameskip_value == 0 ? AUTO_FRAMERATE : game_config.frameskip_value - 1 /* 1 -> 0 and so on */);
}
fclose(fp);
@@ -4113,9 +4113,6 @@ int save_game_config_file(void)
if(gamepak_name[0] == 0) return -1;
- memcpy(game_config.gamepad_config_map, gamepad_config_map, sizeof(game_config.gamepad_config_map));
- game_config.gamepad_config_menu = gamepad_config_menu;
-
sprintf(game_config_filename, "%s/%s", DEFAULT_CFG_DIR, gamepak_name);
pt = strrchr(game_config_filename, '.');
if(NULL == pt)
diff --git a/source/nds/gui.h b/source/nds/gui.h
index 5a40979..ec0dd1a 100644
--- a/source/nds/gui.h
+++ b/source/nds/gui.h
@@ -44,16 +44,63 @@ struct _EMU_CONFIG
struct _GAME_CONFIG
{
- u32 clock_speed_number;
- u32 frameskip_type;
+ u32 clock_speed_number;
+ u32 Reserved0;
u32 frameskip_value;
- u32 graphic;
- u32 enable_audio;
- u32 gamepad_config_menu;
+ u32 graphic;
+ u32 enable_audio;
+ u32 Reserved1;
u32 backward;
u32 backward_time;
- u32 reserve[32];
- u32 gamepad_config_map[MAX_GAMEPAD_MAP];
+ u32 Reserved2;
+ u32 Reserved3;
+ u32 Reserved4;
+ u32 Reserved5;
+ u32 Reserved6;
+ u32 Reserved7;
+ u32 Reserved8;
+ u32 Reserved9;
+ u32 Reserved10;
+ u32 Reserved11;
+ u32 Reserved12;
+ u32 Reserved13;
+ u32 Reserved14;
+ u32 Reserved15;
+ u32 Reserved16;
+ u32 Reserved17;
+ u32 Reserved18;
+ u32 Reserved19;
+ u32 Reserved20;
+ u32 Reserved21;
+ u32 Reserved22;
+ u32 Reserved23;
+ u32 Reserved24;
+ u32 Reserved25;
+ u32 Reserved26;
+ u32 Reserved27;
+ u32 Reserved28;
+ u32 Reserved29;
+ u32 Reserved30;
+ u32 Reserved31;
+ u32 Reserved32;
+
+ u32 Reserved33;
+ u32 Reserved34;
+ u32 Reserved35;
+ u32 Reserved36;
+ u32 Reserved37;
+ u32 Reserved38;
+ u32 Reserved39;
+ u32 Reserved40;
+ u32 Reserved41;
+ u32 Reserved42;
+ u32 Reserved43;
+ u32 Reserved44;
+ u32 Reserved45;
+ u32 Reserved46;
+ u32 Reserved47;
+ u32 Reserved48;
+ u32 Reserved49;
};
typedef enum
@@ -118,6 +165,7 @@ extern GAME_CONFIG game_config;
extern void gui_init(u32 lang_id);
extern u32 menu(u16 *original_screen);
extern void game_disableAudio();
+extern void game_set_frameskip();
extern void set_cpu_clock(u32 num);
#ifdef __cplusplus
diff --git a/source/nds/message.h b/source/nds/message.h
index ee89acd..09332bc 100644
--- a/source/nds/message.h
+++ b/source/nds/message.h
@@ -30,8 +30,7 @@ enum MSG
MSG_MAIN_MENU_EXIT,
FMT_VIDEO_ASPECT_RATIO,
FMT_VIDEO_FAST_FORWARD,
- FMT_VIDEO_FRAME_SKIP_AUTOMATIC,
- FMT_VIDEO_FRAME_SKIP_MANUAL,
+ FMT_VIDEO_FRAME_SKIPPING,
FMT_AUDIO_SOUND,
MSG_SAVED_STATE_CREATE,
FMT_SAVED_STATE_LOAD,
@@ -56,8 +55,18 @@ enum MSG
MSG_VIDEO_ASPECT_RATIO_3,
MSG_VIDEO_ASPECT_RATIO_4,
- MSG_FRAMESKIP_0, // currently unused
- MSG_FRAMESKIP_1, // currently unused
+ MSG_VIDEO_FRAME_SKIPPING_AUTOMATIC,
+ MSG_VIDEO_FRAME_SKIPPING_0,
+ MSG_VIDEO_FRAME_SKIPPING_1,
+ MSG_VIDEO_FRAME_SKIPPING_2,
+ MSG_VIDEO_FRAME_SKIPPING_3,
+ MSG_VIDEO_FRAME_SKIPPING_4,
+ MSG_VIDEO_FRAME_SKIPPING_5,
+ MSG_VIDEO_FRAME_SKIPPING_6,
+ MSG_VIDEO_FRAME_SKIPPING_7,
+ MSG_VIDEO_FRAME_SKIPPING_8,
+ MSG_VIDEO_FRAME_SKIPPING_9,
+ MSG_VIDEO_FRAME_SKIPPING_10,
MSG_GENERAL_OFF,
MSG_GENERAL_ON,