aboutsummaryrefslogtreecommitdiff
path: root/source/nds
diff options
context:
space:
mode:
Diffstat (limited to 'source/nds')
-rw-r--r--source/nds/dma_adj.c26
-rw-r--r--source/nds/dma_adj.h29
-rw-r--r--source/nds/ds2_main.c5
-rw-r--r--source/nds/ds2sound.h21
-rw-r--r--source/nds/entry.cpp620
-rw-r--r--source/nds/entry.h4
-rw-r--r--source/nds/gui.c704
-rw-r--r--source/nds/gui.h22
-rw-r--r--source/nds/message.h37
9 files changed, 893 insertions, 575 deletions
diff --git a/source/nds/dma_adj.c b/source/nds/dma_adj.c
new file mode 100644
index 0000000..8b6f9ad
--- /dev/null
+++ b/source/nds/dma_adj.c
@@ -0,0 +1,26 @@
+#include "ds2_malloc.h"
+#include "dma_adj.h"
+
+#ifdef DS2_DMA
+
+struct SPointerAdjustments PtrAdj;
+
+void* AlignedMalloc (unsigned int Size, unsigned int Alignment, unsigned int* Adjustment)
+{
+ if (Alignment == 0) Alignment = 1;
+
+ unsigned char* result = (unsigned char*) malloc(Size + Alignment);
+ if (!result) {
+ return result;
+ } else {
+ *Adjustment = Alignment - ((unsigned int) result & (Alignment - 1));
+ return (void*) (result + *Adjustment);
+ }
+}
+
+void AlignedFree (void* Memory, unsigned int Adjustment)
+{
+ free((void*) ((unsigned char*) Memory - Adjustment));
+}
+
+#endif // DS2_DMA
diff --git a/source/nds/dma_adj.h b/source/nds/dma_adj.h
new file mode 100644
index 0000000..3852f09
--- /dev/null
+++ b/source/nds/dma_adj.h
@@ -0,0 +1,29 @@
+#ifndef _DMA_ADJ_H_
+#define _DMA_ADJ_H_
+
+#ifdef DS2_DMA
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct SPointerAdjustments {
+ /* These are used by the DSTWO-NDS side code. */
+ unsigned int GFXScreen;
+
+ /* These are used by Snes9x. */
+ unsigned int ROM;
+};
+
+extern struct SPointerAdjustments PtrAdj;
+
+extern void* AlignedMalloc (unsigned int Size, unsigned int Alignment, unsigned int* Adjustment);
+extern void AlignedFree (void* Memory, unsigned int Adjustment);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DS2_DMA
+
+#endif // !_DMA_ADJ_H_
diff --git a/source/nds/ds2_main.c b/source/nds/ds2_main.c
index f9b29d5..af81df3 100644
--- a/source/nds/ds2_main.c
+++ b/source/nds/ds2_main.c
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "port.h"
+
#include <stdio.h>
#include "console.h"
#include "fs_api.h"
@@ -25,6 +27,7 @@
#include "ds2_timer.h"
#include "ds2_malloc.h"
#include "ds2sound.h"
+#include "gui.h"
#define BLACK_COLOR RGB15(0, 0, 0)
#define WHITE_COLOR RGB15(31, 31, 31)
@@ -47,7 +50,7 @@ void ddump_mem(unsigned char* addr, unsigned int len)
void ds2_main(void)
{
int err;
- ds2_setCPUclocklevel(13);
+ HighFrequencyCPU();
//Initial video and audio and other input and output
err = ds2io_initb(DS2_BUFFER_SIZE, SND_SAMPLE_RATE, 0, 0);
if(err) goto _failure;
diff --git a/source/nds/ds2sound.h b/source/nds/ds2sound.h
index f51a6e1..8c0e2bf 100644
--- a/source/nds/ds2sound.h
+++ b/source/nds/ds2sound.h
@@ -1,21 +1,24 @@
// The sound buffer sizes used on the DS2's side, for each value of
// Settings.SoundPlaybackRate.
+// * Don't buffer too much, otherwise audio is delayed from video.
+// * Don't go below one frame (20 milliseconds).
+// * Buffer sizes must be multiples of 128.
#define DS2_BUFFER_SIZE_4 512 /* tested working */
-#define DS2_BUFFER_SIZE_5 1024 /* like the SNES! tested working, but slow */
-#define DS2_BUFFER_SIZE_6 1024 /* tested working, slow because of upsampling */
-#define DS2_BUFFER_SIZE_7 1024 /* tested working, slow because of upsampling */
+#define DS2_BUFFER_SIZE_5 640 /* like the SNES! tested working */
+#define DS2_BUFFER_SIZE_6 896 /* tested working */
+#define DS2_BUFFER_SIZE_7 1024 /* tested working */
// The sampling rate for the sound, in Hz, for each value of
// Settings.SoundPlaybackRate.
#define SND_SAMPLE_RATE_1 8000
#define SND_SAMPLE_RATE_2 11025
#define SND_SAMPLE_RATE_3 16000
-#define SND_SAMPLE_RATE_4 22050
-#define SND_SAMPLE_RATE_5 32000
+#define SND_SAMPLE_RATE_4 22050 /* NDSSFC 1.06 - CATSFC 1.28 used this one */
+#define SND_SAMPLE_RATE_5 32000 /* like the SNES! */
#define SND_SAMPLE_RATE_6 44100
-#define SND_SAMPLE_RATE_7 48000
+#define SND_SAMPLE_RATE_7 48000 /* CATSFC 1.25 made using this one possible */
// Settings in use. The number should match in all three settings.
-#define DS2_BUFFER_SIZE DS2_BUFFER_SIZE_4
-#define SND_SAMPLE_RATE SND_SAMPLE_RATE_4
-#define SNES9X_SRATE_ID 4
+#define DS2_BUFFER_SIZE DS2_BUFFER_SIZE_5
+#define SND_SAMPLE_RATE SND_SAMPLE_RATE_5
+#define SNES9X_SRATE_ID 5
diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp
index 702442e..c4cc389 100644
--- a/source/nds/entry.cpp
+++ b/source/nds/entry.cpp
@@ -23,6 +23,11 @@
#include "entry.h"
#include "ds2sound.h"
+#ifdef DS2_DMA
+#include "ds2_dma.h"
+#include "dma_adj.h"
+#endif
+
void S9xProcessSound (unsigned int);
char *rom_filename = NULL;
@@ -58,7 +63,11 @@ void S9xExtraUsage ()
*/
void S9xDeinitDisplay (void)
{
+#ifdef DS2_DMA
+ if(GFX.Screen) AlignedFree(GFX.Screen, PtrAdj.GFXScreen);
+#else
if(GFX.Screen) free(GFX.Screen);
+#endif
if(GFX.SubScreen) free(GFX.SubScreen);
if(GFX.ZBuffer) free(GFX.ZBuffer);
if(GFX.SubZBuffer) free(GFX.SubZBuffer);
@@ -69,7 +78,11 @@ void S9xInitDisplay (int, char **)
int h = IMAGE_HEIGHT;
GFX.Pitch = IMAGE_WIDTH * 2;
+#ifdef DS2_DMA
+ GFX.Screen = (unsigned char*) AlignedMalloc (GFX.Pitch * h, 32, &PtrAdj.GFXScreen);
+#else
GFX.Screen = (unsigned char*) malloc (GFX.Pitch * h);
+#endif
GFX.SubScreen = (unsigned char*) malloc (GFX.Pitch * h);
GFX.ZBuffer = (unsigned char*) malloc ((GFX.Pitch >> 1) * h);
GFX.SubZBuffer =(unsigned char*) malloc ((GFX.Pitch >> 1) * h);
@@ -86,7 +99,7 @@ void S9xParseDisplayArg (char **argv, int &ind, int)
void S9xExit ()
{
- ds2_setCPUclocklevel(13); // Crank it up to exit quickly
+ HighFrequencyCPU(); // Crank it up to exit quickly
if(Settings.SPC7110)
(*CleanUp7110)();
@@ -130,17 +143,38 @@ bool8 S9xDeinitUpdate (int Width, int Height, bool8 /*sixteen_bit*/)
{
//Up
case 1:
+#ifdef DS2_DMA
+ __dcache_writeback_all();
+ ds2_DMAcopy_32Byte(1 /* channel: graphics */, up_screen_addr, GFX.Screen + 256 * 32 * 2, 256 * 192 * 2);
+ ds2_DMA_wait(1);
+ ds2_DMA_stop(1);
+#else
memcpy(up_screen_addr, GFX.Screen+256*32*2, 256*192*2);
+#endif
break;
//Down
case 2:
+#ifdef DS2_DMA
+ __dcache_writeback_all();
+ ds2_DMAcopy_32Byte(1 /* channel: graphics */, up_screen_addr, GFX.Screen, 256 * 192 * 2);
+ ds2_DMA_wait(1);
+ ds2_DMA_stop(1);
+#else
memcpy(up_screen_addr, GFX.Screen, 256*192*2);
+#endif
break;
//Both
case 3:
+#ifdef DS2_DMA
+ __dcache_writeback_all();
+ ds2_DMAcopy_32Byte(1 /* channel: graphics */, up_screen_addr, GFX.Screen + 256 * 16 * 2, 256 * 192 * 2);
+ ds2_DMA_wait(1);
+ ds2_DMA_stop(1);
+#else
memcpy(up_screen_addr, GFX.Screen+256*16*2, 256*192*2);
+#endif
break;
case 4:
@@ -150,14 +184,23 @@ bool8 S9xDeinitUpdate (int Width, int Height, bool8 /*sixteen_bit*/)
default:
{
- unsigned char *src, *dst;
- unsigned int m;
+#ifdef DS2_DMA
+ __dcache_writeback_all();
+#endif
+ register unsigned char *src, *dst;
+ register unsigned int m;
src = GFX.Screen;
dst = (unsigned char*)up_screen_addr;
for(m = 0; m < 32; m++)
{
+#ifdef DS2_DMA
+ ds2_DMAcopy_32Byte(1 /* channel: graphics */, dst, src, 256 * 6 * 2);
+ ds2_DMA_wait(1);
+ ds2_DMA_stop(1);
+#else
memcpy(dst, src, 256*6*2);
+#endif
dst += 256*6*2;
src += 256*7*2;
}
@@ -350,6 +393,18 @@ void game_set_frameskip()
Settings.SkipFrames = game_config.frameskip_value - 1 /* 1 -> 0 and so on */;
}
}
+
+void game_set_fluidity()
+{
+ if( game_config.SoundSync == 1)
+ {
+ Settings.SoundSync = TRUE;
+ }
+ else
+ {
+ Settings.SoundSync = FALSE;
+ }
+}
void init_sfc_setting(void)
{
@@ -370,6 +425,7 @@ void init_sfc_setting(void)
//sound settings
Settings.APUEnabled = Settings.NextAPUEnabled = TRUE;
Settings.FixFrequency = 1;
+
S9xSetEightBitConsoleSound (TRUE);
@@ -403,7 +459,7 @@ void init_sfc_setting(void)
#endif
Settings.ApplyCheats = TRUE;
Settings.TurboMode = FALSE;
- Settings.TurboSkipFrames = 40;
+ Settings.TurboSkipFrames = 10;
Settings.StretchScreenshots = 1;
Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX;
@@ -444,7 +500,7 @@ void game_restart(void)
S9xReset ();
}
-int load_gamepak(char* file)
+int load_gamepak(const char* file)
{
CPU.Flags = 0;
// mdelay(50); // Delete this delay
@@ -540,6 +596,7 @@ int sfc_main (int argc, char **argv)
#endif
Settings.Paused = 1;
+ bool8 FirstInvocation = TRUE;
while (1)
{
@@ -564,7 +621,8 @@ int sfc_main (int argc, char **argv)
unsigned short screen[256*192];
copy_screen((void*)screen, up_screen_addr, 0, 0, 256, 192);
- menu(screen);
+ menu(screen, FirstInvocation);
+ FirstInvocation = FALSE;
game_disableAudio();
Settings.Paused = 0;
}
@@ -582,7 +640,6 @@ int sfc_main (int argc, char **argv)
static unsigned int sync_last= 0;
static unsigned int sync_next = 0;
-static unsigned int auto_equivalent_skip = 0;
static unsigned int skip_rate= 0;
@@ -590,6 +647,7 @@ void S9xSyncSpeed ()
{
uint32 syncnow;
int32 syncdif;
+ unsigned int LastAutoCPUFrequency = AutoCPUFrequency;
#if 0
if (Settings.SoundSync == 2)
@@ -601,12 +659,14 @@ void S9xSyncSpeed ()
#endif
syncnow = getSysTime();
- if (game_fast_forward || temporary_fast_forward /* hotkey is held */)
+ bool8 FastForward = game_fast_forward || temporary_fast_forward /* hotkey is held */;
+
+ if (FastForward)
{
sync_last = syncnow;
sync_next = syncnow;
- if(++skip_rate < 10)
+ if(++skip_rate < Settings.TurboSkipFrames)
IPPU.RenderThisFrame = false;
else
{
@@ -614,110 +674,132 @@ void S9xSyncSpeed ()
IPPU.RenderThisFrame = true;
}
}
- else if (Settings.SkipFrames == AUTO_FRAMERATE /* && !game_fast_forward && !temporary_fast_forward */)
+ else
{
- // frame_time is in getSysTime units: 42.667 microseconds.
- int32 frame_time = Settings.PAL ? 468 /* = 20.0 ms */ : 391 /* = 16.67 ms */;
- if (sync_last > syncnow) // Overflow occurred! (every 50 hrs)
+ // Manual or automatic frame skipping, no fast-forward.
+ if (Settings.SkipFrames == AUTO_FRAMERATE)
{
- // Render this frame regardless, set the
- // sync_next, and get the hell out.
- IPPU.RenderThisFrame = TRUE;
+ // frame_time is in getSysTime units: 42.667 microseconds.
+ int32 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;
- 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 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(skip_rate < 2 /* did not skip 2 frames yet */)
{
- if(syncdif >= -11719 /* not more than 500.0 ms late */)
+ // Skip a minimum of 2 frames between rendered frames.
+ // This prevents the DSTwo-DS link from being too busy
+ // to return button statuses.
+ ++skip_rate;
+ IPPU.RenderThisFrame = FALSE;
+ 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)
{
- IPPU.RenderThisFrame = FALSE;
- sync_next += frame_time;
+ 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;
+ }
}
else
- { //lag more than 0.5s, maybe paused
+ {
+ skip_rate = 0;
IPPU.RenderThisFrame = TRUE;
sync_next = syncnow + frame_time;
}
}
- else
+ else // Early
{
skip_rate = 0;
+ if (syncdif > 0)
+ {
+ do {
+ S9xProcessSound (0);
+#ifdef ACCUMULATE_JOYPAD
+/*
+ * This call allows NDSSFC to synchronise the DS controller more often.
+ * If porting a later version of Snes9x into NDSSFC, it is essential to
+ * preserve it.
+ */
+ NDSSFCAccumulateJoypad ();
+#endif
+ syncdif = sync_next - getSysTime();
+ } while (syncdif > 0);
+ }
+
IPPU.RenderThisFrame = TRUE;
- sync_next = syncnow + frame_time;
+ sync_next += 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(++framenum >= 60)
+ 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) */
{
- syncdif = syncnow - sync_last;
+ // 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;
- framenum = 0;
- //printf("T %d %d\n", syncdif*42667/1000, realframe);
- realframe = 0;
- }
+ if (++skip_rate > Settings.SkipFrames)
+ {
+ skip_rate = 0;
+ IPPU.RenderThisFrame = TRUE;
+ // Are we early?
+ syncdif = sync_next - syncnow;
+ if (syncdif > 0)
+ {
+ do {
+ S9xProcessSound (0);
+#ifdef ACCUMULATE_JOYPAD
+/*
+ * This call allows NDSSFC to synchronise the DS controller more often.
+ * If porting a later version of Snes9x into NDSSFC, it is essential to
+ * preserve it.
+ */
+ NDSSFCAccumulateJoypad ();
#endif
- }
- else /* if (Settings.SkipFrames != AUTO_FRAMERATE && !game_fast_forward && !temporary_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)
+ syncdif = sync_next - getSysTime();
+ } while (syncdif > 0);
+ // After that little delay, what time is it?
+ syncnow = getSysTime();
+ }
+ sync_next = syncnow + frame_time * (Settings.SkipFrames + 1);
+ }
+ else
{
- 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();
+ IPPU.RenderThisFrame = FALSE;
}
- sync_next = syncnow + frame_time * (Settings.SkipFrames + 1);
- }
- else
- {
- IPPU.RenderThisFrame = FALSE;
}
}
@@ -901,150 +983,189 @@ void S9xGenerateSound ()
}
}
-void S9xProcessSound (unsigned int)
-{
- unsigned short *audiobuff;
+#define SOUND_EMISSION_INTERVAL ((unsigned int) ((((unsigned long long) DS2_BUFFER_SIZE * 1000000) / SND_SAMPLE_RATE) * 3 / 128))
+#define TRUE_SOUND_EMISSION_INTERVAL ((((double) DS2_BUFFER_SIZE * 1000000) / SND_SAMPLE_RATE) * 3 / 128)
+#define SOUND_EMISSION_INTERVAL_ERROR ((int) ((TRUE_SOUND_EMISSION_INTERVAL - SOUND_EMISSION_INTERVAL) * FIXED_POINT))
+static unsigned int LastSoundEmissionTime = 0;
- if (so.mute_sound || !game_enable_audio)
- return;
+/*
+ * Accumulated error in the sound emission time. The unit is as follows:
+ * FIXED_POINT = 42.667 microseconds.
+ * As the error goes past FIXED_POINT, the new target for sound emission
+ * becomes 42.667 microseconds LATER. This helps with sound buffer overruns,
+ * correctly dealing with the fact that 42.667 microseconds does not fit
+ * an integer number of times in 1/32000 second (or whatever sampling rate).
+ */
+static unsigned int SoundEmissionTimeError = 0;
- if(ds2_checkAudiobuff() > 4)
+void S9xProcessSound (unsigned int)
+{
+ if (!game_enable_audio)
return;
- /* Number of samples to generate now */
- int sample_count;
- sample_count = so.buffer_size;
-#ifndef FOREVER_16_BIT_SOUND
- if (so.sixteen_bit)
+ unsigned int Now = getSysTime();
+ if (Now - LastSoundEmissionTime >= SOUND_EMISSION_INTERVAL)
{
-#endif
- /* to prevent running out of buffer space,
- * create less samples
- */
- sample_count >>= 1;
-#ifndef FOREVER_16_BIT_SOUND
- }
-#endif
+ if(ds2_checkAudiobuff() > AUDIO_BUFFER_COUNT - 1)
+ {
+ LastSoundEmissionTime++;
+ return;
+ }
- audiobuff = (unsigned short*)ds2_getAudiobuff();
- if(NULL == audiobuff) //There are audio queue in sending or wait to send
- {
- return;
- }
+ unsigned short *audiobuff;
- /* If we need more audio samples */
- if (so.samples_mixed_so_far < sample_count)
- {
- /* Where to put the samples to */
+ if (Now - LastSoundEmissionTime >= 11719 /* 500 milliseconds */)
+ {
+ LastSoundEmissionTime = Now;
+ // We were probably paused. Restart sending sound,
+ // synchronising from now.
+ }
+ else
+ {
+ LastSoundEmissionTime += SOUND_EMISSION_INTERVAL;
+ SoundEmissionTimeError += SOUND_EMISSION_INTERVAL_ERROR;
+ if (SoundEmissionTimeError >= FIXED_POINT)
+ {
+ LastSoundEmissionTime += SoundEmissionTimeError >> FIXED_POINT_SHIFT;
+ SoundEmissionTimeError &= FIXED_POINT_REMAINDER;
+ }
+ }
+ /* Number of samples to generate now */
+ int sample_count = so.buffer_size;
#ifndef FOREVER_16_BIT_SOUND
- unsigned byte_offset = (so.play_position +
- (so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far)) & SOUND_BUFFER_SIZE_MASK;
-#else
- unsigned byte_offset = (so.play_position +
- (so.samples_mixed_so_far << 1)) & SOUND_BUFFER_SIZE_MASK;
+ if (so.sixteen_bit)
+ {
+#endif
+ /* to prevent running out of buffer space,
+ * create less samples
+ */
+ sample_count >>= 1;
+#ifndef FOREVER_16_BIT_SOUND
+ }
#endif
- //printf ("%d:", sample_count - so.samples_mixed_so_far); fflush (stdout);
- if (Settings.SoundSync == 2)
+ audiobuff = (unsigned short*)ds2_getAudiobuff();
+ while (audiobuff == NULL) //There are audio queue in sending or wait to send
{
- /*memset (Buf + (byte_offset & SOUND_BUFFER_SIZE_MASK), 0,
- sample_count - so.samples_mixed_so_far);*/
+#ifdef ACCUMULATE_JOYPAD
+ NDSSFCAccumulateJoypad ();
+#endif
+ audiobuff = (unsigned short*)ds2_getAudiobuff();
}
- else
+
+ /* If we need more audio samples */
+ if (so.samples_mixed_so_far < sample_count)
{
- /* Mix the missing samples */
+ /* Where to put the samples to */
#ifndef FOREVER_16_BIT_SOUND
- int bytes_so_far = so.sixteen_bit ? (so.samples_mixed_so_far << 1) :
- so.samples_mixed_so_far;
+ unsigned byte_offset = (so.play_position +
+ (so.sixteen_bit ? (so.samples_mixed_so_far << 1) : so.samples_mixed_so_far)) & SOUND_BUFFER_SIZE_MASK;
#else
- int bytes_so_far = so.samples_mixed_so_far << 1;
+ unsigned byte_offset = (so.play_position +
+ (so.samples_mixed_so_far << 1)) & SOUND_BUFFER_SIZE_MASK;
#endif
- uint32 samples_to_write = sample_count - so.samples_mixed_so_far;
- do
+ if (Settings.SoundSync == 2)
{
- int bytes_this_run = samples_to_write;
+ /*memset (Buf + (byte_offset & SOUND_BUFFER_SIZE_MASK), 0,
+ sample_count - so.samples_mixed_so_far);*/
+ }
+ else
+ {
+ /* Mix the missing samples */
#ifndef FOREVER_16_BIT_SOUND
- if (so.sixteen_bit)
+ int bytes_so_far = so.sixteen_bit ? (so.samples_mixed_so_far << 1) :
+ so.samples_mixed_so_far;
+#else
+ int bytes_so_far = so.samples_mixed_so_far << 1;
#endif
- bytes_this_run <<= 1;
- if (byte_offset + bytes_this_run > SOUND_BUFFER_SIZE)
+ uint32 samples_to_write = sample_count - so.samples_mixed_so_far;
+ do
{
- bytes_this_run = SOUND_BUFFER_SIZE - byte_offset;
- }
+ int bytes_this_run = samples_to_write;
+#ifndef FOREVER_16_BIT_SOUND
+ if (so.sixteen_bit)
+#endif
+ bytes_this_run <<= 1;
- if (bytes_so_far + bytes_this_run > so.buffer_size)
- {
- bytes_this_run = so.buffer_size - bytes_so_far;
- if (bytes_this_run == 0)
- break;
- }
+ if (byte_offset + bytes_this_run > SOUND_BUFFER_SIZE)
+ {
+ bytes_this_run = SOUND_BUFFER_SIZE - byte_offset;
+ }
- int samples_this_run = bytes_this_run;
+ if (bytes_so_far + bytes_this_run > so.buffer_size)
+ {
+ bytes_this_run = so.buffer_size - bytes_so_far;
+ if (bytes_this_run == 0)
+ break;
+ }
+
+ int samples_this_run = bytes_this_run;
#ifndef FOREVER_16_BIT_SOUND
- if (so.sixteen_bit)
+ if (so.sixteen_bit)
#endif
- samples_this_run >>= 1;
+ samples_this_run >>= 1;
- S9xMixSamples (Buf + byte_offset, samples_this_run);
- so.samples_mixed_so_far += samples_this_run;
- samples_to_write -= samples_this_run;
+ S9xMixSamples (Buf + byte_offset, samples_this_run);
+ so.samples_mixed_so_far += samples_this_run;
+ samples_to_write -= samples_this_run;
#ifndef FOREVER_16_BIT_SOUND
- bytes_so_far += so.sixteen_bit ? (samples_this_run << 1) :
- samples_this_run;
+ bytes_so_far += so.sixteen_bit ? (samples_this_run << 1) :
+ samples_this_run;
#else
- bytes_so_far += samples_this_run << 1;
+ bytes_so_far += samples_this_run << 1;
#endif
- byte_offset = (byte_offset + bytes_this_run) & SOUND_BUFFER_SIZE_MASK;
- } while (samples_to_write > 0);
+ byte_offset = (byte_offset + bytes_this_run) & SOUND_BUFFER_SIZE_MASK;
+ } while (samples_to_write > 0);
+ }
}
- }
-// if (!so.mute_sound)
- {
- unsigned bytes_to_write = sample_count;
+ // if (!so.mute_sound)
+ {
+ unsigned bytes_to_write = sample_count;
#ifndef FOREVER_16_BIT_SOUND
- if(so.sixteen_bit)
+ if(so.sixteen_bit)
#endif
- bytes_to_write <<= 1;
+ bytes_to_write <<= 1;
- unsigned byte_offset = so.play_position;
- so.play_position = (so.play_position + bytes_to_write) & SOUND_BUFFER_SIZE_MASK; /* wrap to beginning */
+ unsigned byte_offset = so.play_position;
+ so.play_position = (so.play_position + bytes_to_write) & SOUND_BUFFER_SIZE_MASK; /* wrap to beginning */
- unsigned short *dst_pt = audiobuff;
- unsigned short *dst_pt1 = dst_pt + DS2_BUFFER_SIZE;
+ unsigned short *dst_pt = audiobuff;
+ unsigned short *dst_pt1 = dst_pt + DS2_BUFFER_SIZE;
- /* Feed the samples to the soundcard until nothing is left */
- for(;;)
- {
- int I = bytes_to_write;
- if (byte_offset + I > SOUND_BUFFER_SIZE)
+ /* Feed the samples to the soundcard until nothing is left */
+ for(;;)
{
- I = SOUND_BUFFER_SIZE - byte_offset;
- }
- if(I == 0) break;
+ int I = bytes_to_write;
+ if (byte_offset + I > SOUND_BUFFER_SIZE)
+ {
+ I = SOUND_BUFFER_SIZE - byte_offset;
+ }
+ if(I == 0) break;
-// memcpy(dst_pt, (char *) Buf + byte_offset, I);
-// dst_pt += I;
+ // memcpy(dst_pt, (char *) Buf + byte_offset, I);
+ // dst_pt += I;
- unsigned short *src_pt= (unsigned short*)(Buf + byte_offset);
- for(int m= 0; m < I/4; m++)
- {
- *dst_pt++= *src_pt++;//(*src_pt++) <<1;
- *dst_pt1++= *src_pt++;//(*src_pt++) <<1;
+ unsigned short *src_pt= (unsigned short*)(Buf + byte_offset);
+ for(int m= 0; m < I/4; m++)
+ {
+ *dst_pt++= *src_pt++;//(*src_pt++) <<1;
+ *dst_pt1++= *src_pt++;//(*src_pt++) <<1;
+ }
+
+ bytes_to_write -= I;
+ byte_offset = (byte_offset + I) & SOUND_BUFFER_SIZE_MASK; /* wrap */
}
- bytes_to_write -= I;
- byte_offset = (byte_offset + I) & SOUND_BUFFER_SIZE_MASK; /* wrap */
- }
+ ds2_updateAudio();
- ds2_updateAudio();
+ /* All data sent. */
+ }
- /* All data sent. */
+ so.samples_mixed_so_far -= sample_count;
}
-
- so.samples_mixed_so_far -= sample_count;
}
/*
@@ -1066,68 +1187,99 @@ const unsigned int keymap[12] = {
static bool8 SoundToggleWasHeld = FALSE;
-unsigned int S9xReadJoypad (int which1)
-{
- struct key_buf inputdata;
+#ifdef ACCUMULATE_JOYPAD
+// These are kept as DS key bitfields until it's time to send them to Snes9x.
+static uint32 PreviousControls = 0x00000000;
+static uint32 ControlsPressed = 0x00000000;
+static uint32 ControlsReleased = 0x00000000;
+void NDSSFCAccumulateJoypad ()
+{
+ struct key_buf inputdata;
ds2_getrawInput(&inputdata);
- if (inputdata.key & KEY_LID)
+ ControlsPressed |= inputdata.key & ~PreviousControls;
+ ControlsReleased |= PreviousControls & ~inputdata.key;
+}
+#endif // ACCUMULATE_JOYPAD
+
+uint32 S9xReadJoypad (int which1)
+{
+ if(which1 < 1)
{
- ds2_setCPUclocklevel(0);
- ds2_setSupend();
- do {
+ uint32 Controls;
+#ifdef ACCUMULATE_JOYPAD
+ Controls = (PreviousControls | ControlsPressed) & ~ControlsReleased;
+ PreviousControls = Controls;
+ ControlsPressed = ControlsReleased = 0x00000000;
+#else
+ {
+ struct key_buf inputdata;
ds2_getrawInput(&inputdata);
- mdelay(1);
- } while (inputdata.key & KEY_LID);
- ds2_wakeup();
- set_cpu_clock(clock_speed_number);
- }
- u32 HotkeyReturnToMenu = game_config.HotkeyReturnToMenu != 0 ? game_config.HotkeyReturnToMenu : emu_config.HotkeyReturnToMenu;
- u32 HotkeyTemporaryFastForward = game_config.HotkeyTemporaryFastForward != 0 ? game_config.HotkeyTemporaryFastForward : emu_config.HotkeyTemporaryFastForward;
- u32 HotkeyToggleSound = game_config.HotkeyToggleSound != 0 ? game_config.HotkeyToggleSound : emu_config.HotkeyToggleSound;
+ Controls = inputdata.key;
+ }
+#endif
- if(inputdata.key & KEY_TOUCH ||
- (HotkeyReturnToMenu && ((inputdata.key & HotkeyReturnToMenu) == HotkeyReturnToMenu))
- ) //Active menu
- Settings.Paused = 1;
+ if (Controls & KEY_LID)
+ {
+ LowFrequencyCPU();
+ ds2_setSupend();
+ struct key_buf inputdata;
+ do {
+ ds2_getrawInput(&inputdata);
+ mdelay(1);
+ } while (inputdata.key & KEY_LID);
+ ds2_wakeup();
+ // Before starting to emulate again, turn off the lower
+ // screen's backlight.
+ mdelay(100); // needed to avoid ds2_setBacklight crashing
+ ds2_setBacklight(2);
+ GameFrequencyCPU();
+ }
- temporary_fast_forward =
- (HotkeyTemporaryFastForward && ((inputdata.key & HotkeyTemporaryFastForward) == HotkeyTemporaryFastForward))
- ;
+ u32 HotkeyReturnToMenu = game_config.HotkeyReturnToMenu != 0 ? game_config.HotkeyReturnToMenu : emu_config.HotkeyReturnToMenu;
+ u32 HotkeyTemporaryFastForward = game_config.HotkeyTemporaryFastForward != 0 ? game_config.HotkeyTemporaryFastForward : emu_config.HotkeyTemporaryFastForward;
+ u32 HotkeyToggleSound = game_config.HotkeyToggleSound != 0 ? game_config.HotkeyToggleSound : emu_config.HotkeyToggleSound;
- bool8 SoundToggleIsHeld =
- (HotkeyToggleSound && ((inputdata.key & HotkeyToggleSound) == HotkeyToggleSound))
- ;
+ if(Controls & KEY_TOUCH ||
+ (HotkeyReturnToMenu && ((Controls & HotkeyReturnToMenu) == HotkeyReturnToMenu))
+ ) //Active menu
+ Settings.Paused = 1;
- if (SoundToggleIsHeld && !SoundToggleWasHeld)
- {
- game_enable_audio = !game_enable_audio;
- game_disableAudio();
- }
+ temporary_fast_forward =
+ (HotkeyTemporaryFastForward && ((Controls & HotkeyTemporaryFastForward) == HotkeyTemporaryFastForward))
+ ;
- SoundToggleWasHeld = SoundToggleIsHeld;
+ bool8 SoundToggleIsHeld =
+ (HotkeyToggleSound && ((Controls & HotkeyToggleSound) == HotkeyToggleSound))
+ ;
- if(which1 < 1)
- {
- unsigned int key;
+ if (SoundToggleIsHeld && !SoundToggleWasHeld)
+ {
+ game_enable_audio = !game_enable_audio;
+ game_disableAudio();
+ }
+
+ SoundToggleWasHeld = SoundToggleIsHeld;
+
+ uint32 key = 0x80000000; // Required by Snes9x
// DS -> SNES
- key = (inputdata.key & KEY_A ) << 7; // 0x0001 -> 0x0080
- key |= (inputdata.key & KEY_B ) << 14; // 0x0002 -> 0x8000
- key |= (inputdata.key & KEY_SELECT) << 11; // 0x0004 -> 0x2000
- key |= (inputdata.key & KEY_START ) << 9; // 0x0008 -> 0x1000
- key |= (inputdata.key & KEY_UP ) << 5; // 0x0040 -> 0x0800
+ key |= (Controls & KEY_A ) << 7; // 0x0001 -> 0x0080
+ key |= (Controls & KEY_B ) << 14; // 0x0002 -> 0x8000
+ key |= (Controls & KEY_SELECT) << 11; // 0x0004 -> 0x2000
+ key |= (Controls & KEY_START ) << 9; // 0x0008 -> 0x1000
+ key |= (Controls & KEY_UP ) << 5; // 0x0040 -> 0x0800
// 0x0010 -> 0x0100; 0x0020 -> 0x0200
// 0x0030 -> 0x0300
- key |= (inputdata.key & (KEY_RIGHT | KEY_LEFT)) << 4;
+ key |= (Controls & (KEY_RIGHT | KEY_LEFT)) << 4;
// 0x0100 -> 0x0010; 0x0200 -> 0x0020; 0x0400 -> 0x0040
// 0x0700 -> 0x0070
- key |= (inputdata.key & (KEY_R | KEY_L | KEY_X)) >> 4;
+ key |= (Controls & (KEY_R | KEY_L | KEY_X)) >> 4;
// 0x0080 -> 0x0400; 0x0800 -> 0x4000
// 0x0880 -> 0x4400
- key |= (inputdata.key & (KEY_DOWN | KEY_Y)) << 3;
+ key |= (Controls & (KEY_DOWN | KEY_Y)) << 3;
/*
for(i= 0; i < 12; i++) //remap key
{
@@ -1135,7 +1287,7 @@ unsigned int S9xReadJoypad (int which1)
}
*/
- return (key | 0x80000000);
+ return key;
}
else
return 0;
diff --git a/source/nds/entry.h b/source/nds/entry.h
index a6bd350..0728768 100644
--- a/source/nds/entry.h
+++ b/source/nds/entry.h
@@ -7,7 +7,9 @@ extern "C" {
void game_restart(void);
- int load_gamepak(char* file);
+ int load_gamepak(const char* file);
+
+ extern unsigned int AutoCPUFrequency;
#ifdef __cplusplus
}
#endif
diff --git a/source/nds/gui.c b/source/nds/gui.c
index 09e01ac..4299db2 100644
--- a/source/nds/gui.c
+++ b/source/nds/gui.c
@@ -45,23 +45,27 @@ char rom_path[MAX_PATH];
char gamepak_name[MAX_PATH];
char gcheat_filename[MAX_PATH];
+//program arguments
+char argv[2][MAX_PATH];
+
// If adding a language, make sure you update the size of the array in
// message.h too.
-char *lang[3] =
- {
+char *lang[4] =
+ {
"English", // 0
"简体中文", // 1
- "Français", // 2
+ "Français", // 2
+ "Deutsch", // 3
};
-char *language_options[] = { (char *) &lang[0], (char *) &lang[1], (char *) &lang[2] };
+char *language_options[] = { (char *) &lang[0], (char *) &lang[1], (char *) &lang[2], (char *) &lang[3] };
/******************************************************************************
* Macro definition
******************************************************************************/
#define SUBMENU_ROW_NUM 6
-#define NDSSFC_VERSION "1.23"
+#define NDSSFC_VERSION "1.28"
#define SAVE_STATE_SLOT_NUM 16
@@ -289,7 +293,6 @@ u32 game_enable_audio = 1;
/******************************************************************************
******************************************************************************/
static u32 menu_cheat_page = 0;
-u32 clock_speed_number = 5;
u32 gamepad_config_menu;
/******************************************************************************
@@ -324,6 +327,21 @@ gui_action_type get_gui_input(void)
key = getKey();
+ if (key & KEY_LID)
+ {
+ ds2_setSupend();
+ struct key_buf inputdata;
+ do {
+ ds2_getrawInput(&inputdata);
+ mdelay(1);
+ } while (inputdata.key & KEY_LID);
+ ds2_wakeup();
+ // In the menu, the lower screen's backlight needs to be on,
+ // and it is on right away after resuming from suspend.
+ // mdelay(100); // needed to avoid ds2_setBacklight crashing
+ // ds2_setBacklight(3);
+ }
+
switch(key)
{
case KEY_UP:
@@ -420,53 +438,52 @@ void change_ext(char *src, char *buffer, char *extension)
--------------------------------------------------------*/
static int sort_function(const void *dest_str_ptr, const void *src_str_ptr)
{
- char *dest_str = *((char **)dest_str_ptr);
- char *src_str = *((char **)src_str_ptr);
+ char *dest_str = ((char *)dest_str_ptr);
+ char *src_str = ((char *)src_str_ptr);
// For files and directories, . and .. sort first.
- if(src_str[0] == '.')
+ if(src_str[0] == '.' && dest_str[0] != '.')
return 1;
- if(dest_str[0] == '.')
+ if(dest_str[0] == '.' && src_str[0] != '.')
return -1;
return strcasecmp(dest_str, src_str);
}
-static int my_array_partion(void *array, int left, int right)
+static int my_array_partion(void **array, int left, int right)
{
- unsigned int pivot= *((unsigned int*)array + left);
-
- while(left < right)
- {
- while(sort_function((void*)((unsigned int*)array+left), (void*)((unsigned int *)array+right)) < 0) {
- right--;
- }
-
- if(right== left) break;
- *((unsigned int*)array + left) = *((unsigned int*)array + right);
- *((unsigned int*)array + right) = pivot;
-
- if(left < right)
- {
- left++;
- if(right== left) break;
- }
-
- while(sort_function((void*)((unsigned int*)array+right), (void*)((unsigned int *)array+left)) > 0) {
- left++;
- }
+ // Choose a pivot, left <= pivot <= right
+ unsigned int pivotIndex = left + (right - left) / 2;
+
+ // Move pivot value to the end
+ void *temp = array[pivotIndex];
+ array[pivotIndex] = array[right];
+ array[right] = temp;
+
+ // Move values that sort before the pivot value to before the new
+ // pivot's location
+ unsigned int storeIndex = left, i;
+ for (i = left; i <= right - 1; i++)
+ {
+ if (sort_function(array[i], array[right]) < 0)
+ {
+ temp = array[i];
+ array[i] = array[storeIndex];
+ array[storeIndex] = temp;
+ storeIndex++;
+ }
+ }
- if(left== right) break;
- *((unsigned int*)array + right) = *((unsigned int*)array + left);
- *((unsigned int*)array + left) = pivot;
- right--;
- }
+ // Move the pivot value to its correct location
+ temp = array[storeIndex];
+ array[storeIndex] = array[right];
+ array[right] = temp;
- return left;
+ return storeIndex;
}
-static void my_qsort(void *array, int left, int right)
+static void my_qsort(void **array, int left, int right)
{
if(left < right)
{
@@ -558,7 +575,7 @@ static int manage_filelist_info(struct FILE_LIST_INFO *filelist_infop, int flag)
int i;
void *pt;
- //Increase all
+ //Increase all
if(flag & 0x1)
{
i = NAME_MEM_SIZE;
@@ -733,9 +750,9 @@ static int load_file_list(struct FILE_LIST_INFO *filelist_infop)
#if 0
my_qsort((void *)file_list, 0, num_files-1);
#else //to support ".." directory, but take it as file
- my_qsort((void *)file_list, 1, num_files-1);
+ my_qsort((void **)file_list, 1, num_files-1);
#endif
- my_qsort((void *)dir_list, 0, num_dirs-1);
+ my_qsort((void **)dir_list, 0, num_dirs-1);
return 0;
}
@@ -820,6 +837,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name)
{
case CURSOR_TOUCH:
ds2_getrawInput(&inputdata);
+ wait_Allkey_release(0);
// ___ 33 This screen has 6 possible rows. Touches
// ___ 60 above or below these are ignored.
// . . . (+27)
@@ -985,6 +1003,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name)
break;
case CURSOR_SELECT:
+ wait_Allkey_release(0);
//file selected
if(selected_item_on_list + 1 <= num_files)
{
@@ -1024,6 +1043,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name)
case CURSOR_BACK:
{
+ wait_Allkey_release(0);
char *ext_pos;
strcpy(filelist_info.current_path, default_dir_name);
@@ -1041,6 +1061,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name)
}
case CURSOR_EXIT:
+ wait_Allkey_release(0);
return_value = -1;
repeat = 0;
break;
@@ -1082,7 +1103,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name)
//Path
if(-1 == redraw) {
draw_hscroll_over(0);
- draw_hscroll_init(down_screen_addr, 49, 10, 170, COLOR_TRANS,
+ draw_hscroll_init(down_screen_addr, 49, 10, 170, COLOR_TRANS,
COLOR_WHITE, default_dir_name);
path_scroll = 0x8000; //first scroll left
}
@@ -1129,7 +1150,7 @@ s32 load_file(char **wildcards, char *result, char *default_dir_name)
pt = file_list[m];
}
- draw_hscroll_init(down_screen_addr, 41, 40 + k*27, 185,
+ draw_hscroll_init(down_screen_addr, 41, 40 + k*27, 185,
COLOR_TRANS, color, pt);
}
@@ -1260,7 +1281,7 @@ u32 play_screen_snapshot(void)
if(draw_yesno_dialog(DOWN_SCREEN, 115, msg[MSG_GENERAL_CONFIRM_WITH_A], msg[MSG_GENERAL_CANCEL_WITH_B]))
return 1;
- else
+ else
return 0;
}
@@ -1365,7 +1386,7 @@ u32 play_screen_snapshot(void)
time1= time0;
}
break;
-
+
case CURSOR_DOWN:
if(!pause)
{
@@ -1373,21 +1394,21 @@ u32 play_screen_snapshot(void)
time1= time0;
}
break;
-
+
case CURSOR_LEFT:
time1 = ticks;
if(i > 1) i -= 2;
else if(i == 1) i= file_num -1;
else i= file_num -2;
break;
-
+
case CURSOR_RIGHT:
time1 = ticks;
break;
-
+
case CURSOR_SELECT:
if(!pause)
- {
+ {
time1 = -1;
pause= 1;
}
@@ -1395,15 +1416,15 @@ u32 play_screen_snapshot(void)
{
time1 = ticks;
pause= 0;
- }
+ }
break;
-
- case CURSOR_BACK:
+
+ case CURSOR_BACK:
if(screenp) free((void*)screenp);
//deconstruct filelist_info struct
manage_filelist_info(&filelist_info, -1);
repeat = 0;
- break;
+ break;
default: gui_action= CURSOR_NONE;
break;
@@ -1443,7 +1464,7 @@ int search_dir(char *directory, char* directory_path)
//while((current_file = readdir(current_dir)) != NULL)
while((current_file = readdir_ex(current_dir, &st)) != NULL)
{
- //Is directory
+ //Is directory
if(S_ISDIR(st.st_mode))
{
if(strcmp(".", current_file->d_name) || strcmp("..", current_file->d_name))
@@ -1622,7 +1643,7 @@ int save_state(char* file, void* screen)
n = ftell(fp);
ds2_getTime(&time);
- sprintf(str, "%02d-%02d %02d:%02d:%02d",
+ sprintf(str, "%02d-%02d %02d:%02d:%02d",
time.month, time.day, time.hours, time.minutes, time.seconds);
PRINT_STRING_BG(screen, str, COLOR_WHITE, COLOR_BLACK, 0, 0);
@@ -1637,12 +1658,22 @@ int save_state(char* file, void* screen)
return 0;
}
-void set_cpu_clock(u32 num)
+void LowFrequencyCPU()
{
- u32 clock_speed_table[6] = {6, 9, 10, 11, 12, 13}; //240, 300, 336, 360, 384, 394
+ ds2_setCPUclocklevel(0); // 60 MHz
+}
- if(num <= 5)
- ds2_setCPUclocklevel(clock_speed_table[num]);
+void HighFrequencyCPU()
+{
+ ds2_setCPUclocklevel(13); // 396 MHz
+}
+
+void GameFrequencyCPU()
+{
+ u32 clock_speed_table[6] = {6, 9, 10, 11, 12, 13}; //240, 300, 336, 360, 384, 396
+
+ if(game_config.clock_speed_number <= 5)
+ ds2_setCPUclocklevel(clock_speed_table[game_config.clock_speed_number]);
}
void savefast_int(void)
@@ -1668,7 +1699,7 @@ unsigned int frame_interval;
/*--------------------------------------------------------
Main Menu
--------------------------------------------------------*/
-u32 menu(u16 *screen)
+u32 menu(u16 *screen, bool8 FirstInvocation)
{
gui_action_type gui_action;
u32 i;
@@ -1684,7 +1715,7 @@ u32 menu(u16 *screen)
MENU_TYPE *current_menu = NULL;
MENU_OPTION_TYPE *current_option = NULL;
MENU_OPTION_TYPE *display_option = NULL;
-
+
u32 current_option_num;
// u32 parent_option_num;
u32 string_select;
@@ -1692,6 +1723,9 @@ u32 menu(u16 *screen)
u16 *bg_screenp;
u32 bg_screenp_color;
+ GAME_CONFIG PreviousGameConfig; // Compared with current settings to
+ EMU_CONFIG PreviousEmuConfig; // determine if they need to be saved
+
auto void choose_menu();
auto void menu_return();
auto void menu_exit();
@@ -1732,7 +1766,9 @@ u32 menu(u16 *screen)
auto void latest_game_menu_end();
auto void language_set();
auto void game_fastforward();
+#ifdef ENABLE_FREE_SPACE
auto void show_card_space();
+#endif
auto void savestate_selitem(u32 sel, u32 y_pos);
auto void game_state_menu_passive();
auto void gamestate_delette_menu_passive();
@@ -1747,131 +1783,94 @@ u32 menu(u16 *screen)
void menu_exit()
{
- ds2_setCPUclocklevel(13); // Crank it up, leave quickly
- if(gamepak_name[0] != 0)
- {
- game_config.clock_speed_number = clock_speed_number;
-
- reorder_latest_file();
+ HighFrequencyCPU(); // Crank it up, leave quickly
+ if(gamepak_name[0] != 0)
+ {
S9xAutoSaveSRAM ();
- save_game_config_file();
}
- save_emu_config_file();
quit();
}
- void menu_load()
+ void SaveConfigsIfNeeded()
{
- char *file_ext[] = { ".smc", ".sfc", ".zip", NULL };
-
- if(gamepak_name[0] != 0)
- {
- S9xAutoSaveSRAM ();
+ if (memcmp(&PreviousGameConfig, &game_config, sizeof(GAME_CONFIG)) != 0)
save_game_config_file();
- }
+ if (memcmp(&PreviousEmuConfig, &emu_config, sizeof(EMU_CONFIG)) != 0)
+ save_emu_config_file();
+ }
- if(load_file(file_ext, tmp_filename, g_default_rom_dir) != -1)
- {
- strcpy(line_buffer, g_default_rom_dir);
- strcat(line_buffer, "/");
- strcat(line_buffer, tmp_filename);
+ void PreserveConfigs()
+ {
+ memcpy(&PreviousGameConfig, &game_config, sizeof(GAME_CONFIG));
+ memcpy(&PreviousEmuConfig, &emu_config, sizeof(EMU_CONFIG));
+ }
- draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
- draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_PROGRESS_LOADING_GAME]);
- ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD);
+ int LoadGameAndItsData(char *filename){
+ if (gamepak_name[0] != '\0') {
+ S9xAutoSaveSRAM();
+ }
- ds2_setCPUclocklevel(13);
- int load_result = load_gamepak(line_buffer);
- ds2_setCPUclocklevel(0);
- if(load_result == -1)
- {
- first_load = 1;
- gamepak_name[0] = '\0';
- return;
- }
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_PROGRESS_LOADING_GAME]);
+ ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD);
- strcpy(gamepak_name, tmp_filename);
- first_load = 0;
- load_game_config_file();
-// time_period_action();
+ HighFrequencyCPU();
+ int load_result = load_gamepak(filename);
+ LowFrequencyCPU();
- return_value = 1;
- repeat = 0;
+ if(load_result == -1)
+ {
+ first_load = 1;
+ gamepak_name[0] = '\0';
+ return 0;
+ }
- reorder_latest_file();
- get_savestate_filelist();
+ char tempPath[MAX_PATH];
+ strcpy(tempPath, filename);
- game_fast_forward= 0;
- }
- else
- {
- choose_menu(current_menu);
- }
- }
-
- bool Get_Args(char *file, char **filebuf)
- {
- FILE* dat = fat_fopen(file, "rb");
- if(dat)
- {
- int i = 0;
- while(!fat_feof (dat))
- {
- fat_fgets(filebuf[i], 512, dat);
- int len = strlen(filebuf[i]);
- if(filebuf[i][len - 1] == '\n')
- filebuf[i][len - 1] = '\0';
- i++;
- }
-
- fat_fclose(dat);
- fat_remove(file);
- return i;
- }
- return 0;
- }
+ //update folders and names for settings/config uses
+ char *dirEnd = strrchr(tempPath, '/');
+ //make sure a valid path was provided
+ if(!dirEnd)
+ return 0;
- int CheckLoad_Arg()
- {
- char args[2][512];
- char *argarray[2];
-
- argarray[0] = args[0];
- argarray[1] = args[1];
-
- if(!Get_Args("/plgargs.dat", argarray))
- return 0;
-
- fat_remove("plgargs.dat");
-
- draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
- draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_PROGRESS_LOADING_GAME]);
- ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD);
+ //copy file name as gamepak_name
+ strcpy(gamepak_name, dirEnd+1);
+ //then strip filename from directory path and set it
+ *dirEnd = '\0';
+ strcpy(g_default_rom_dir, tempPath);
- ds2_setCPUclocklevel(13);
- int load_result = load_gamepak(args[1]);
- ds2_setCPUclocklevel(0);
+ first_load = 0;
+ load_game_config_file();
+ PreserveConfigs(); // Make the emulator not save what we've JUST read
+ // but it will save the emulator configuration below for latest files
- if(load_result == -1)
- {
- first_load = 1;
- gamepak_name[0] = '\0';
- return 0;
- }
+ return_value = 1;
+ repeat = 0;
- strcpy(gamepak_name, args[1]);
- first_load = 0;
- load_game_config_file();
+ reorder_latest_file();
+ get_savestate_filelist();
- return_value = 1;
- repeat = 0;
+ game_fast_forward= 0;
+ return 1;
+ }
- reorder_latest_file();
- get_savestate_filelist();
+ void menu_load()
+ {
+ char *file_ext[] = { ".smc", ".sfc", ".zip", NULL };
+
+ if(load_file(file_ext, tmp_filename, g_default_rom_dir) != -1)
+ {
+ strcpy(line_buffer, g_default_rom_dir);
+ strcat(line_buffer, "/");
+ strcat(line_buffer, tmp_filename);
- game_fast_forward= 0;
- return 1;
-
+ LoadGameAndItsData(line_buffer);
+ }
+ else
+ {
+ choose_menu(current_menu);
+ }
}
void menu_restart()
@@ -2060,9 +2059,9 @@ u32 menu(u16 *screen)
draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_PROGRESS_SAVED_STATE_CREATING]);
ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD);
- ds2_setCPUclocklevel(13);
+ HighFrequencyCPU();
int flag = save_state(tmp_filename, (void*)screen);
- ds2_setCPUclocklevel(0);
+ LowFrequencyCPU();
//clear message
draw_message(down_screen_addr, NULL, 28, 31, 227, 96, 0);
if(flag < 0)
@@ -2076,17 +2075,13 @@ u32 menu(u16 *screen)
ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD);
- //save game config
- reorder_latest_file();
- save_game_config_file();
-
SavedStateCacheInvalidate ();
mdelay(500); // let the progress message linger
}
}
}
-
+
void menu_load_state()
{
if(!first_load)
@@ -2126,12 +2121,12 @@ u32 menu(u16 *screen)
//right
if(gui_action == CURSOR_SELECT)
{
- draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
draw_string_vcenter(up_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_PROGRESS_SAVED_STATE_LOADING]);
- ds2_setCPUclocklevel(13);
+ HighFrequencyCPU();
int flag = load_state(tmp_filename);
- ds2_setCPUclocklevel(0);
+ LowFrequencyCPU();
if(0 == flag)
{
return_value = 1;
@@ -2146,9 +2141,9 @@ u32 menu(u16 *screen)
}
else //load screen snapshot
{
- ds2_setCPUclocklevel(13);
+ HighFrequencyCPU();
load_game_stat_snapshot(tmp_filename);
- ds2_setCPUclocklevel(0);
+ LowFrequencyCPU();
}
}
else
@@ -2210,7 +2205,7 @@ u32 menu(u16 *screen)
}
else if(current_option_num == 2) //delette single
{
- draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
+ draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
if(SavedStateFileExists(delette_savestate_num))
{
@@ -2278,7 +2273,7 @@ u32 menu(u16 *screen)
{
m= current_menu->screen_focus -1;
draw_hscroll_over(m+1);
- draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
+ draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[current_option_num].display_string);
}
else
@@ -2288,7 +2283,7 @@ u32 menu(u16 *screen)
m= current_menu->focus_option - current_menu->screen_focus+2;
for(n= 0; n < SUBMENU_ROW_NUM-1; n++)
- draw_hscroll_init(down_screen_addr, 23, 40 + n*27, 200,
+ draw_hscroll_init(down_screen_addr, 23, 40 + n*27, 200,
COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[m+n].display_string);
}
}
@@ -2296,7 +2291,7 @@ u32 menu(u16 *screen)
if(current_option_num == 0)
{
draw_hscroll_over(0);
- draw_hscroll_init(down_screen_addr, 50, 9, 180,
+ draw_hscroll_init(down_screen_addr, 50, 9, 180,
COLOR_TRANS, COLOR_ACTIVE_ITEM, *dynamic_cheat_options[0].display_string);
}
@@ -2309,7 +2304,7 @@ u32 menu(u16 *screen)
if(m >= SUBMENU_ROW_NUM) m -= 1;
draw_hscroll_over(m+1);
- draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
+ draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
COLOR_TRANS, COLOR_ACTIVE_ITEM, *dynamic_cheat_options[current_option_num].display_string);
}
@@ -2323,7 +2318,7 @@ u32 menu(u16 *screen)
{
m = current_menu->screen_focus -1;
draw_hscroll_over(m+1);
- draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
+ draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[current_option_num].display_string);
}
else
@@ -2338,7 +2333,7 @@ u32 menu(u16 *screen)
if(k > SUBMENU_ROW_NUM) k = SUBMENU_ROW_NUM;
for(n= 1; n < k; n++)
- draw_hscroll_init(down_screen_addr, 23, 40 + n*27, 200,
+ draw_hscroll_init(down_screen_addr, 23, 40 + n*27, 200,
COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[m+n].display_string);
}
}
@@ -2350,7 +2345,7 @@ u32 menu(u16 *screen)
if(current_option_num == 0)
{
draw_hscroll_over(0);
- draw_hscroll_init(down_screen_addr, 50, 9, 180,
+ draw_hscroll_init(down_screen_addr, 50, 9, 180,
COLOR_TRANS, COLOR_ACTIVE_ITEM, *dynamic_cheat_options[0].display_string);
}
}
@@ -2365,7 +2360,7 @@ u32 menu(u16 *screen)
m = current_menu->screen_focus -1;
draw_hscroll_over(m+1);
- draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
+ draw_hscroll_init(down_screen_addr, 23, 40 + m*27, 200,
COLOR_TRANS, COLOR_ACTIVE_ITEM, *dynamic_cheat_options[current_option_num].display_string);
}
break;
@@ -2641,7 +2636,7 @@ u32 menu(u16 *screen)
mm = *(display_option->current_option);
sprintf(line_buffer, *(display_option->display_string), str[mm]);
-
+
PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, 27,
38 + (display_option-> line_number)*32);
}
@@ -2718,22 +2713,9 @@ u32 menu(u16 *screen)
{
if(gui_action == CURSOR_LEFT || gui_action == CURSOR_RIGHT)
{
- ds2_setCPUclocklevel(13); // crank it up
- if(bg_screenp != NULL)
- {
- bg_screenp_color = COLOR16(43, 11, 11);
- memcpy(bg_screenp, down_screen_addr, 256*192*2);
- }
- else
- bg_screenp_color = COLOR_BG;
+ HighFrequencyCPU(); // crank it up
- draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, bg_screenp_color);
- draw_string_vcenter(down_screen_addr, 36, 75, 190, COLOR_MSSG, msg[MSG_CHANGE_LANGUAGE]);
- draw_string_vcenter(down_screen_addr, 36, 95, 190, COLOR_MSSG, msg[MSG_CHANGE_LANGUAGE_WAITING]);
- ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD);
-
- load_language_msg(LANGUAGE_PACK, emu_config.language);
- // gui_change_icon(emu_config.language); // uncomment if images change per language [Neb]
+ load_language_msg(LANGUAGE_PACK, emu_config.language);
if(first_load)
{
@@ -2742,12 +2724,11 @@ u32 menu(u16 *screen)
ds2_flipScreen(UP_SCREEN, 1);
}
- save_emu_config_file();
- ds2_setCPUclocklevel(0); // and back down
- wait_Allkey_release(0);
+ LowFrequencyCPU(); // and back down
}
}
+#ifdef ENABLE_FREE_SPACE
unsigned int freespace;
void show_card_space ()
{
@@ -2791,6 +2772,7 @@ u32 menu(u16 *screen)
PRINT_STRING_BG(down_screen_addr, line_buffer, COLOR_INACTIVE_ITEM, COLOR_TRANS, 147,
40 + (display_option->line_number)*27);
}
+#endif
char *screen_ratio_options[] = { (char*)&msg[MSG_VIDEO_ASPECT_RATIO_0],
(char*)&msg[MSG_VIDEO_ASPECT_RATIO_1],
@@ -2800,6 +2782,10 @@ u32 menu(u16 *screen)
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 *cpu_frequency_options[] = { (char*)&msg[MSG_OPTIONS_CPU_FREQUENCY_0], (char*)&msg[MSG_OPTIONS_CPU_FREQUENCY_1], (char*)&msg[MSG_OPTIONS_CPU_FREQUENCY_2], (char*)&msg[MSG_OPTIONS_CPU_FREQUENCY_3], (char*)&msg[MSG_OPTIONS_CPU_FREQUENCY_4], (char*)&msg[MSG_OPTIONS_CPU_FREQUENCY_5] };
+
+ char *fluidity_options[] = { (char*)&msg[MSG_VIDEO_AUDIO_FLUIDITY_PREFER_VIDEO], (char*)&msg[MSG_VIDEO_AUDIO_FLUIDITY_PREFER_AUDIO] };
+
char *on_off_options[] = { (char*)&msg[MSG_GENERAL_OFF], (char*)&msg[MSG_GENERAL_ON] };
char *sound_seletion[] = { (char*)&msg[MSG_AUDIO_MUTED], (char*)&msg[MSG_AUDIO_ENABLED] };
@@ -2815,17 +2801,20 @@ u32 menu(u16 *screen)
{
/* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_MAIN_MENU_VIDEO_AUDIO], NULL, 0),
- /* 01 */ STRING_SELECTION_OPTION(NULL, NULL, &msg[FMT_VIDEO_ASPECT_RATIO], screen_ratio_options,
+ /* 01 */ STRING_SELECTION_OPTION(NULL, NULL, &msg[FMT_VIDEO_ASPECT_RATIO], screen_ratio_options,
&game_config.graphic, 5, NULL, PASSIVE_TYPE, 1),
- /* 02 */ STRING_SELECTION_OPTION(game_fastforward, NULL, &msg[FMT_VIDEO_FAST_FORWARD], on_off_options,
+ /* 02 */ STRING_SELECTION_OPTION(game_fastforward, NULL, &msg[FMT_VIDEO_FAST_FORWARD], on_off_options,
&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),
-
- /* 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)
+
+ /* 04 */ STRING_SELECTION_OPTION(game_set_fluidity, NULL, &msg[FMT_VIDEO_AUDIO_FLUIDITY_PREFERENCE], fluidity_options,
+ &game_config.SoundSync, 2, NULL, ACTION_TYPE, 4),
+
+ /* 05 */ 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, 5)
};
MAKE_MENU(graphics, NULL, NULL, NULL, NULL, 0, 0);
@@ -2854,10 +2843,12 @@ u32 menu(u16 *screen)
{
/* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_MAIN_MENU_SAVED_STATES], NULL, 0),
- /* 01 */ NUMERIC_SELECTION_ACTION_OPTION(menu_save_state, NULL, &msg[FMT_SAVED_STATE_CREATE], &savestate_index, SAVE_STATE_SLOT_NUM, NULL, 1),
+ // savestate_index is still a signed int
+ /* 01 */ NUMERIC_SELECTION_ACTION_OPTION(menu_save_state, NULL, &msg[FMT_SAVED_STATE_CREATE], (u32*) &savestate_index, SAVE_STATE_SLOT_NUM, NULL, 1),
+ // savestate_index is still a signed int
/* 02 */ NUMERIC_SELECTION_ACTION_OPTION(menu_load_state, NULL,
- &msg[FMT_SAVED_STATE_LOAD], &savestate_index, SAVE_STATE_SLOT_NUM, NULL, 2),
+ &msg[FMT_SAVED_STATE_LOAD], (u32*) &savestate_index, SAVE_STATE_SLOT_NUM, NULL, 2),
/* 03 */ SUBMENU_OPTION(&gamestate_delette_menu, &msg[MSG_SAVED_STATE_DELETE_GENERAL], NULL, 5),
};
@@ -2871,9 +2862,9 @@ u32 menu(u16 *screen)
{
/* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_MAIN_MENU_CHEATS], NULL,0),
- /* 01 */ CHEAT_OPTION(cheat_option_action, cheat_option_passive,
+ /* 01 */ CHEAT_OPTION(cheat_option_action, cheat_option_passive,
((CHEATS_PER_PAGE * menu_cheat_page) + 0), 1),
- /* 02 */ CHEAT_OPTION(cheat_option_action, cheat_option_passive,
+ /* 02 */ CHEAT_OPTION(cheat_option_action, cheat_option_passive,
((CHEATS_PER_PAGE * menu_cheat_page) + 1), 2),
/* 03 */ CHEAT_OPTION(cheat_option_action, cheat_option_passive,
((CHEATS_PER_PAGE * menu_cheat_page) + 2), 3),
@@ -2940,7 +2931,7 @@ u32 menu(u16 *screen)
/*--------------------------------------------------------
Tools
--------------------------------------------------------*/
- MENU_OPTION_TYPE tools_options[] =
+ MENU_OPTION_TYPE tools_options[] =
{
/* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_MAIN_MENU_TOOLS], NULL, 0),
@@ -2952,10 +2943,10 @@ u32 menu(u16 *screen)
// /* 02 */ SUBMENU_OPTION(&tools_keyremap_menu, &msg[MSG_SUB_MENU_31], NULL, 2),
-// /* 03 */ STRING_SELECTION_OPTION(time_backward_action, NULL, &msg[MSG_SUB_MENU_302], on_off_options,
+// /* 03 */ STRING_SELECTION_OPTION(time_backward_action, NULL, &msg[MSG_SUB_MENU_302], on_off_options,
// &game_config.backward, 2, NULL, ACTION_TYPE, 3),
-// /* 04 */ NUMERIC_SELECTION_ACTION_OPTION(time_period_action, time_period_passive, &msg[MSG_SUB_MENU_32],
+// /* 04 */ NUMERIC_SELECTION_ACTION_OPTION(time_period_action, time_period_passive, &msg[MSG_SUB_MENU_32],
// &game_config.backward_time, 6, NULL, 4)
};
@@ -2969,18 +2960,33 @@ u32 menu(u16 *screen)
{
/* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_MAIN_MENU_OPTIONS], NULL, 0),
- //CPU speed
- /* 01 */ NUMERIC_SELECTION_OPTION(NULL, &msg[FMT_OPTIONS_CPU_FREQUENCY], &clock_speed_number, 6, NULL, 1),
+ //CPU speed (string: shows MHz)
+ /* 01 */ STRING_SELECTION_OPTION(NULL, NULL, &msg[FMT_OPTIONS_CPU_FREQUENCY], cpu_frequency_options,
+ &game_config.clock_speed_number, 6, NULL, PASSIVE_TYPE, 1),
/* 02 */ STRING_SELECTION_OPTION(language_set, NULL, &msg[FMT_OPTIONS_LANGUAGE], language_options,
&emu_config.language, sizeof(language_options) / sizeof(language_options[0]) /* number of possible languages */, NULL, ACTION_TYPE, 2),
+#ifdef ENABLE_FREE_SPACE
/* 03 */ STRING_SELECTION_OPTION(NULL, show_card_space, &msg[MSG_OPTIONS_CARD_CAPACITY], NULL,
&desert, 2, NULL, PASSIVE_TYPE | HIDEN_TYPE, 3),
+#endif
- /* 04 */ ACTION_OPTION(load_default_setting, NULL, &msg[MSG_OPTIONS_RESET], NULL, 4),
+ /* 04 */ ACTION_OPTION(load_default_setting, NULL, &msg[MSG_OPTIONS_RESET], NULL,
+#ifdef ENABLE_FREE_SPACE
+ 4
+#else
+ 3
+#endif
+ ),
- /* 05 */ ACTION_OPTION(check_gbaemu_version, NULL, &msg[MSG_OPTIONS_VERSION], NULL, 5),
+ /* 05 */ ACTION_OPTION(check_gbaemu_version, NULL, &msg[MSG_OPTIONS_VERSION], NULL,
+#ifdef ENABLE_FREE_SPACE
+ 5
+#else
+ 4
+#endif
+ ),
};
MAKE_MENU(others, others_menu_init, NULL, NULL, NULL, 1, 1);
@@ -2989,7 +2995,7 @@ u32 menu(u16 *screen)
Load_game
--------------------------------------------------------*/
MENU_TYPE latest_game_menu;
-
+
MENU_OPTION_TYPE load_game_options[] =
{
/* 00 */ SUBMENU_OPTION(NULL, &msg[MSG_LOAD_GAME_MENU_TITLE], NULL, 0),
@@ -3120,7 +3126,7 @@ u32 menu(u16 *screen)
show_icon(down_screen_addr, &ICON_MSEL, 173, 131);
}
else {
- show_icon(down_screen_addr, &ICON_NEXIT, 187, 75);
+ show_icon(down_screen_addr, &ICON_NEXIT, 187, 75);
show_icon(down_screen_addr, &ICON_MNSEL, 173, 131);
}
draw_string_vcenter(down_screen_addr, 175, 131, 75, COLOR_WHITE, line_buffer);
@@ -3315,7 +3321,7 @@ u32 menu(u16 *screen)
{
ext_pos= strrchr(emu_config.latest_file[k], '/');
if(ext_pos != NULL)
- draw_hscroll_init(down_screen_addr, 26, 40 + k*27, 200,
+ draw_hscroll_init(down_screen_addr, 26, 40 + k*27, 200,
COLOR_TRANS, COLOR_INACTIVE_ITEM, ext_pos+1);
else
break;
@@ -3373,7 +3379,7 @@ u32 menu(u16 *screen)
void latest_game_menu_end()
{
u32 k;
-
+
for(k= 0; k < 5; k++)
{
if(emu_config.latest_file[k][0] != '\0')
@@ -3393,12 +3399,12 @@ u32 menu(u16 *screen)
{
draw_hscroll_over(current_option_num-1);
ext_pos= strrchr(emu_config.latest_file[current_option_num-1], '/');
- draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
+ draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
COLOR_TRANS, COLOR_INACTIVE_ITEM, ext_pos+1);
}
current_option_num += 1;
- if(current_option_num >= latest_game_menu.num_options)
+ if(current_option_num >= latest_game_menu.num_options)
current_option_num = 0;
current_option = current_menu->options + current_option_num;
@@ -3407,7 +3413,7 @@ u32 menu(u16 *screen)
{
draw_hscroll_over(current_option_num-1);
ext_pos= strrchr(emu_config.latest_file[current_option_num-1], '/');
- draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
+ draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
COLOR_TRANS, COLOR_ACTIVE_ITEM, ext_pos+1);
}
@@ -3419,7 +3425,7 @@ u32 menu(u16 *screen)
{
draw_hscroll_over(current_option_num-1);
ext_pos= strrchr(emu_config.latest_file[current_option_num-1], '/');
- draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
+ draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
COLOR_TRANS, COLOR_INACTIVE_ITEM, ext_pos+1);
}
@@ -3432,7 +3438,7 @@ u32 menu(u16 *screen)
{
draw_hscroll_over(current_option_num-1);
ext_pos= strrchr(emu_config.latest_file[current_option_num-1], '/');
- draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
+ draw_hscroll_init(down_screen_addr, 26, 40 + (current_option_num-1)*27, 200,
COLOR_TRANS, COLOR_ACTIVE_ITEM, ext_pos+1);
}
@@ -3455,16 +3461,6 @@ u32 menu(u16 *screen)
{
char *ext_pos;
- draw_message(down_screen_addr, bg_screenp, 28, 31, 227, 165, 0);
- draw_string_vcenter(down_screen_addr, 36, 100, 190, COLOR_MSSG, msg[MSG_PROGRESS_LOADING_GAME]);
- ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD);
-
- if(gamepak_name[0] != 0)
- {
- S9xAutoSaveSRAM ();
- save_game_config_file();
- }
-
if(bg_screenp != NULL) {
bg_screenp_color = COLOR16(43, 11, 11);
}
@@ -3478,42 +3474,19 @@ u32 menu(u16 *screen)
ext_pos = emu_config.latest_file[current_option_num -1];
- ds2_setCPUclocklevel(13);
- int load_result = load_gamepak(ext_pos);
- ds2_setCPUclocklevel(0);
-
- if(load_result == -1) {
- first_load = 1;
- return;
- }
-
- strcpy(g_default_rom_dir, ext_pos);
- ext_pos = strrchr(g_default_rom_dir, '/');
- *ext_pos= '\0';
- strcpy(gamepak_name, ext_pos+1);
-
-
- load_game_config_file();
-// time_period_action();
-
- reorder_latest_file();
- get_savestate_filelist();
- game_fast_forward= 0;
+ LoadGameAndItsData(ext_pos);
get_newest_savestate(tmp_filename);
if(tmp_filename[0] != '\0')
{
load_state(tmp_filename);
}
-
- return_value = 1;
- repeat = 0;
}
void game_fastforward()
{
}
-
+
void reload_cheats_page()
@@ -3527,11 +3500,13 @@ u32 menu(u16 *screen)
void others_menu_init()
{
+#ifdef ENABLE_FREE_SPACE
unsigned int total, used;
//get card space info
freespace = 0;
fat_getDiskSpaceInfo("fat:", &total, &used, &freespace);
+#endif
}
void choose_menu(MENU_TYPE *new_menu)
@@ -3542,23 +3517,28 @@ u32 menu(u16 *screen)
if(NULL != current_menu) {
if(current_menu->end_function)
current_menu->end_function();
+ SaveConfigsIfNeeded();
}
current_menu = new_menu;
current_option_num= current_menu -> focus_option;
current_option = new_menu->options + current_option_num;
+ PreserveConfigs();
if(current_menu->init_function)
current_menu->init_function();
}
//----------------------------------------------------------------------------//
// Menu Start
- ds2_setCPUclocklevel(0);
- mdelay(100); // to prevent ds2_setBacklight() from crashing
- ds2_setBacklight(3);
-
-
- wait_Allkey_release(0);
+ LowFrequencyCPU();
+ if (!FirstInvocation)
+ { // assume that the backlight is already at 3 when the emulator starts
+ mdelay(100); // to prevent ds2_setBacklight() from crashing
+ ds2_setBacklight(3);
+ // also allow the user to press A for New Game right away
+ wait_Allkey_release(0);
+ }
+
bg_screenp= (u16*)malloc(256*192*2);
repeat = 1;
@@ -3566,7 +3546,8 @@ u32 menu(u16 *screen)
if(gamepak_name[0] == 0)
{
first_load = 1;
- if(CheckLoad_Arg())
+ //try auto loading games passed through argv first
+ if(strlen(argv[1]) > 0 && LoadGameAndItsData(argv[1]))
repeat = 0;
else
{
@@ -3589,7 +3570,7 @@ u32 menu(u16 *screen)
choose_menu(&main_menu);
// Menu loop
-
+
while(repeat)
{
display_option = current_menu->options;
@@ -3638,7 +3619,7 @@ u32 menu(u16 *screen)
focus_option = line_num;
}
current_menu -> focus_option = focus_option;
-
+
i = focus_option - screen_focus;
display_option += i +1;
@@ -3684,7 +3665,7 @@ u32 menu(u16 *screen)
color= COLOR_ACTIVE_ITEM;
else
color= COLOR_INACTIVE_ITEM;
-
+
PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, 23, 40 + i*27);
}
}
@@ -3697,6 +3678,7 @@ u32 menu(u16 *screen)
{
case CURSOR_TOUCH:
ds2_getrawInput(&inputdata);
+ wait_Allkey_release(0);
/* Back button at the top of every menu but the main one */
if(current_menu != &main_menu && inputdata.x > 231 && inputdata.y <= 25)
{
@@ -3714,7 +3696,7 @@ u32 menu(u16 *screen)
current_option_num = (inputdata.y / 80) * 3 + (inputdata.x / 86);
current_option = current_menu->options + current_option_num;
-
+
if(current_option -> option_type & HIDEN_TYPE)
break;
else if(current_option->option_type & ACTION_TYPE)
@@ -3723,11 +3705,10 @@ u32 menu(u16 *screen)
choose_menu(current_option->sub_menu);
}
/* This is the majority case, covering all menus except save states, screen shots, and game loading */
- else if(current_menu != (main_menu.options + 1)->sub_menu
+ else if(current_menu != (main_menu.options + 1)->sub_menu
&& current_menu != ((main_menu.options +1)->sub_menu->options + 3)->sub_menu
- && current_menu != (main_menu.options +3)->sub_menu
+ && current_menu != (main_menu.options +3)->sub_menu
&& current_menu != ((main_menu.options +3)->sub_menu->options + 1)->sub_menu
- && current_menu != ((main_menu.options +3)->sub_menu->options + 2)->sub_menu
&& current_menu != (main_menu.options +6)->sub_menu
&& current_menu != ((main_menu.options +6)->sub_menu->options + 2)->sub_menu)
{
@@ -3794,9 +3775,9 @@ u32 menu(u16 *screen)
next_option_num = 3;
else
break;
-
+
struct _MENU_OPTION_TYPE *next_option = current_menu->options + next_option_num;
-
+
if(next_option_num == 1 /* write */ || next_option_num == 2 /* read */)
{
u32 current_option_val = *(next_option->current_option);
@@ -3841,7 +3822,7 @@ u32 menu(u16 *screen)
}
break;
}
-
+
gui_action = CURSOR_SELECT;
if(next_option -> option_type & HIDEN_TYPE)
break;
@@ -3868,9 +3849,9 @@ u32 menu(u16 *screen)
next_option_num = 2;
else
break;
-
+
struct _MENU_OPTION_TYPE *next_option = current_menu->options + next_option_num;
-
+
if(next_option_num == 2)
{
u32 current_option_val = *(next_option->current_option);
@@ -3908,7 +3889,7 @@ u32 menu(u16 *screen)
}
break;
}
-
+
gui_action = CURSOR_SELECT;
if(next_option -> option_type & HIDEN_TYPE)
break;
@@ -4032,16 +4013,19 @@ u32 menu(u16 *screen)
break;
case CURSOR_EXIT:
+ wait_Allkey_release(0);
break;
case CURSOR_SELECT:
+ wait_Allkey_release(0);
if(current_option->option_type & ACTION_TYPE)
current_option->action_function();
else if(current_option->option_type & SUBMENU_TYPE)
choose_menu(current_option->sub_menu);
break;
- case CURSOR_BACK:
+ case CURSOR_BACK:
+ wait_Allkey_release(0);
if(current_menu != &main_menu)
choose_menu(current_menu->options->sub_menu);
else
@@ -4057,20 +4041,11 @@ u32 menu(u16 *screen)
if (current_menu && current_menu->end_function)
current_menu->end_function();
+ SaveConfigsIfNeeded();
destroy_dynamic_cheats();
if(bg_screenp != NULL) free((void*)bg_screenp);
-
- if(gamepak_name[0] != 0)
- {
- game_config.clock_speed_number = clock_speed_number;
- reorder_latest_file();
- S9xAutoSaveSRAM ();
- save_game_config_file();
- }
- save_emu_config_file();
-
ds2_clearScreen(DOWN_SCREEN, 0);
ds2_flipScreen(DOWN_SCREEN, DOWN_SCREEN_UPDATE_METHOD);
copy_screen(up_screen_addr, (void*) screen, 0, 0, 256, 192);
@@ -4080,7 +4055,7 @@ u32 menu(u16 *screen)
mdelay(100); // to prevent ds2_setBacklight() from crashing
ds2_setBacklight(2);
- set_cpu_clock(clock_speed_number);
+ GameFrequencyCPU();
return return_value;
}
@@ -4132,6 +4107,10 @@ int load_language_msg(char *filename, u32 language)
strcpy(start, "STARTFRENCH");
strcpy(end, "ENDFRENCH");
break;
+ case GERMAN:
+ strcpy(start, "STARTGERMAN");
+ strcpy(end, "ENDGERMAN");
+ break;
}
u32 cmplen = strlen(start);
@@ -4175,7 +4154,61 @@ int load_language_msg(char *filename, u32 language)
break;
len= strlen(pt);
- memcpy(dst, pt, len);
+ // memcpy(dst, pt, len);
+
+ // Replace key definitions (*letter) with Pictochat icons
+ // while copying.
+ unsigned int curChar;
+ for (curChar = 0; curChar < len; curChar++)
+ {
+ if (pt[curChar] == '*')
+ {
+ switch (pt[curChar + 1])
+ {
+ case 'A':
+ memcpy(&dst[curChar], HOTKEY_A_DISPLAY, 2);
+ curChar++;
+ break;
+ case 'B':
+ memcpy(&dst[curChar], HOTKEY_B_DISPLAY, 2);
+ curChar++;
+ break;
+ case 'X':
+ memcpy(&dst[curChar], HOTKEY_X_DISPLAY, 2);
+ curChar++;
+ break;
+ case 'Y':
+ memcpy(&dst[curChar], HOTKEY_Y_DISPLAY, 2);
+ curChar++;
+ break;
+ case 'L':
+ memcpy(&dst[curChar], HOTKEY_L_DISPLAY, 2);
+ curChar++;
+ break;
+ case 'R':
+ memcpy(&dst[curChar], HOTKEY_R_DISPLAY, 2);
+ curChar++;
+ break;
+ case 'S':
+ memcpy(&dst[curChar], HOTKEY_START_DISPLAY, 2);
+ curChar++;
+ break;
+ case 's':
+ memcpy(&dst[curChar], HOTKEY_SELECT_DISPLAY, 2);
+ curChar++;
+ break;
+ case '\0':
+ dst[curChar] = pt[curChar];
+ break;
+ default:
+ memcpy(&dst[curChar], &pt[curChar], 2);
+ curChar++;
+ break;
+ }
+ }
+ else
+ dst[curChar] = pt[curChar];
+ }
dst += len;
//at a line return, when "\n" paded, this message not end
@@ -4198,7 +4231,7 @@ int load_language_msg(char *filename, u32 language)
else//a message end
{
if(*(dst-2) == 0x0D)
- dst -= 1;
+ dst -= 1;
*(dst-1) = '\0';
msg[++loop] = dst;
}
@@ -4235,9 +4268,9 @@ u32 load_font()
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.frameskip_value = 0; // Automatic frame skipping
+ game_config.SoundSync = 0; // Prefer fluid images by default
game_config.backward = 0; //time backward disable
game_config.backward_time = 2; //time backward granularity 1s
@@ -4290,8 +4323,8 @@ void load_game_config_file(void)
{
fread(&game_config, 1, sizeof(GAME_CONFIG), fp);
- 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 */);
+ game_set_frameskip();
+ game_set_fluidity();
}
fclose(fp);
@@ -4322,6 +4355,10 @@ int load_emu_config_file(void)
fclose(fp);
return 0;
}
+ else
+ {
+ fclose(fp);
+ }
}
//have no confiure file, set default
@@ -4342,7 +4379,7 @@ int save_game_config_file(void)
sprintf(game_config_filename, "%s/%s", DEFAULT_CFG_DIR, gamepak_name);
pt = strrchr(game_config_filename, '.');
- if(NULL == pt)
+ if(NULL == pt)
return -1;
*pt = '\0';
@@ -4418,7 +4455,7 @@ void reorder_latest_file(void)
else
break;
}
-
+
strcpy(emu_config.latest_file[i-1], full_file);
}
return ;
@@ -4584,7 +4621,7 @@ void get_newest_savestate(char *name_buffer)
get_savestate_filename(latest_save, name_buffer);
}
-static void get_timestamp_string(char *buffer, u16 msg_id, u16 year, u16 mon,
+static void get_timestamp_string(char *buffer, u16 msg_id, u16 year, u16 mon,
u16 day, u16 wday, u16 hour, u16 min, u16 sec, u32 msec)
{
char *weekday_strings[] =
@@ -4592,7 +4629,7 @@ static void get_timestamp_string(char *buffer, u16 msg_id, u16 year, u16 mon,
"SUN", "MON", "TUE", "WED", "TUR", "FRI", "SAT"
};
- sprintf(buffer, "%s %02d/%02d/%04d %02d:%02d:%02d", weekday_strings[wday],
+ sprintf(buffer, "%s %02d/%02d/%04d %02d:%02d:%02d", weekday_strings[wday],
day, mon, year, hour, min, sec);
}
@@ -4617,7 +4654,7 @@ static u32 save_ss_bmp(u16 *image)
change_ext(gamepak_name, ss_filename, "_");
ds2_getTime(&current_time);
- sprintf(save_ss_path, "%s/%s%02d%02d%02d%02d%02d.bmp", DEFAULT_SS_DIR, ss_filename,
+ sprintf(save_ss_path, "%s/%s%02d%02d%02d%02d%02d.bmp", DEFAULT_SS_DIR, ss_filename,
current_time.month, current_time.day, current_time.hours, current_time.minutes, current_time.seconds);
for(y = 0; y < 192; y++)
@@ -4652,7 +4689,7 @@ void quit(void)
__asm__ __volatile__("or %0, $0, $ra"
: "=r" (reg_ra)
:);
-
+
dbg_printf("return address= %08x\n", reg_ra);
*/
@@ -4678,11 +4715,44 @@ u32 file_length(FILE* file)
/*
* GUI Initialize
*/
+static bool Get_Args(char *file, char **filebuf){
+ FILE* dat = fat_fopen(file, "rb");
+ if(dat){
+ int i = 0;
+ while(!fat_feof (dat)){
+ fat_fgets(filebuf[i], 512, dat);
+ int len = strlen(filebuf[i]);
+ if(filebuf[i][len - 1] == '\n')
+ filebuf[i][len - 1] = '\0';
+ i++;
+ }
+
+ fat_fclose(dat);
+ fat_remove(file);
+ return i;
+ }
+ return 0;
+}
+
+int CheckLoad_Arg(){
+ argv[0][0] = '\0'; // Initialise the first byte to be a NULL in case
+ argv[1][0] = '\0'; // there are no arguments to avoid uninit. memory
+ char *argarray[2];
+ argarray[0] = argv[0];
+ argarray[1] = argv[1];
+
+ if(!Get_Args("/plgargs.dat", argarray))
+ return 0;
+
+ fat_remove("plgargs.dat");
+ return 1;
+}
+
void gui_init(u32 lang_id)
{
int flag;
- ds2_setCPUclocklevel(13); // Crank it up. When the menu starts, -> 0.
+ HighFrequencyCPU(); // Crank it up. When the menu starts, -> 0.
// Start with no saved state existing, as no game is loaded yet.
int i;
@@ -4695,7 +4765,17 @@ void gui_init(u32 lang_id)
//Find the "CATSFC" system directory
DIR *current_dir;
- strcpy(main_path, "fat:/CATSFC");
+ if(CheckLoad_Arg()){
+ //copy new folder location
+ strcpy(main_path, "fat:");
+ strcat(main_path, argv[0]);
+ //strip off the binary name
+ char *endStr = strrchr(main_path, '/');
+ *endStr = '\0';
+ }
+ else
+ strcpy(main_path, "fat:/CATSFC");
+
current_dir = opendir(main_path);
if(current_dir)
closedir(current_dir);
diff --git a/source/nds/gui.h b/source/nds/gui.h
index 87c14e4..290a927 100644
--- a/source/nds/gui.h
+++ b/source/nds/gui.h
@@ -59,7 +59,20 @@ struct _GAME_CONFIG
u32 HotkeyReturnToMenu;
u32 HotkeyTemporaryFastForward;
u32 HotkeyToggleSound;
- u32 Reserved2[45];
+ u32 SoundSync;
+ /*
+ * PreviouslyUsed_20130206_1 was for a second meaning of
+ * frameskip_value that is now dropped.
+ * THIS VALUE IS NOT GUARANTEED TO BE RESERVED AND SET TO 0.
+ */
+ u32 PreviouslyUsed_20130206_1;
+ /*
+ * PreviouslyUsed_20130206_2 was for a second meaning of
+ * clock_speed_number that is now dropped.
+ * THIS VALUE IS NOT GUARANTEED TO BE RESERVED AND SET TO 0.
+ */
+ u32 PreviouslyUsed_20130206_2;
+ u32 Reserved2[42];
};
typedef enum
@@ -124,10 +137,13 @@ extern GAME_CONFIG game_config;
/******************************************************************************
******************************************************************************/
extern void gui_init(u32 lang_id);
-extern u32 menu(u16 *original_screen);
+extern u32 menu(u16 *original_screen, bool8 FirstInvocation);
extern void game_disableAudio();
extern void game_set_frameskip();
-extern void set_cpu_clock(u32 num);
+extern void game_set_fluidity();
+extern void LowFrequencyCPU();
+extern void HighFrequencyCPU();
+extern void GameFrequencyCPU();
extern int load_language_msg(char *filename, u32 language);
#ifdef __cplusplus
diff --git a/source/nds/message.h b/source/nds/message.h
index 0aff8d9..538bc3b 100644
--- a/source/nds/message.h
+++ b/source/nds/message.h
@@ -31,6 +31,9 @@ enum MSG
MSG_MAIN_MENU_TOOLS,
MSG_MAIN_MENU_OPTIONS,
MSG_MAIN_MENU_EXIT,
+ FMT_VIDEO_AUDIO_FLUIDITY_PREFERENCE,
+ MSG_VIDEO_AUDIO_FLUIDITY_PREFER_VIDEO,
+ MSG_VIDEO_AUDIO_FLUIDITY_PREFER_AUDIO,
FMT_VIDEO_ASPECT_RATIO,
FMT_VIDEO_FAST_FORWARD,
FMT_VIDEO_FRAME_SKIPPING,
@@ -41,21 +44,27 @@ enum MSG
FMT_CHEAT_PAGE,
MSG_CHEAT_LOAD_FROM_FILE,
MSG_TOOLS_SCREENSHOT_GENERAL,
- MSG_TOOLS_GLOBAL_HOTKEY_GENERAL, // currently unused
- MSG_TOOLS_GAME_HOTKEY_GENERAL, // currently unused
+ MSG_TOOLS_GLOBAL_HOTKEY_GENERAL,
+ MSG_TOOLS_GAME_HOTKEY_GENERAL,
FMT_OPTIONS_LANGUAGE,
FMT_OPTIONS_CPU_FREQUENCY,
- MSG_OPTIONS_CARD_CAPACITY,
+ MSG_OPTIONS_CPU_FREQUENCY_0,
+ MSG_OPTIONS_CPU_FREQUENCY_1,
+ MSG_OPTIONS_CPU_FREQUENCY_2,
+ MSG_OPTIONS_CPU_FREQUENCY_3,
+ MSG_OPTIONS_CPU_FREQUENCY_4,
+ MSG_OPTIONS_CPU_FREQUENCY_5,
+ MSG_OPTIONS_CARD_CAPACITY /* unused if !defined(ENABLE_FREE_SPACE) */,
MSG_OPTIONS_RESET,
MSG_OPTIONS_VERSION,
MSG_SCREENSHOT_CREATE,
MSG_SCREENSHOT_BROWSE,
- MSG_HOTKEY_MAIN_MENU, // currently unused
- MSG_HOTKEY_TEMPORARY_FAST_FORWARD, // currently unused
- MSG_HOTKEY_SOUND_TOGGLE, // currently unused
- MSG_PROGRESS_HOTKEY_WAITING_FOR_KEYS, // currently unused
- MSG_HOTKEY_DELETE_WITH_A, // currently unused
- MSG_HOTKEY_CANCEL_WITH_B, // currently unused
+ MSG_HOTKEY_MAIN_MENU,
+ MSG_HOTKEY_TEMPORARY_FAST_FORWARD,
+ MSG_HOTKEY_SOUND_TOGGLE,
+ MSG_PROGRESS_HOTKEY_WAITING_FOR_KEYS,
+ MSG_HOTKEY_DELETE_WITH_A,
+ MSG_HOTKEY_CANCEL_WITH_B,
MSG_LOAD_GAME_RECENTLY_PLAYED,
MSG_LOAD_GAME_FROM_CARD,
MSG_LOAD_GAME_MENU_TITLE,
@@ -112,9 +121,6 @@ enum MSG
MSG_PROGRESS_SCREENSHOT_CREATION_SUCCEEDED,
MSG_PROGRESS_SCREENSHOT_CREATION_FAILED,
- MSG_CHANGE_LANGUAGE,
- MSG_CHANGE_LANGUAGE_WAITING,
-
MSG_NO_SLIDE,
MSG_PLAYING_SLIDE,
MSG_PAUSE_SLIDE,
@@ -139,13 +145,14 @@ enum MSG
enum LANGUAGE {
ENGLISH,
CHINESE_SIMPLIFIED,
- FRENCH
+ FRENCH,
+ GERMAN
};
-extern char* lang[3]; // Allocated in gui.c, needs to match the languages ^
+extern char* lang[4]; // Allocated in gui.c, needs to match the languages ^
char *msg[MSG_END+1];
-char msg_data[16 * 1024];
+char msg_data[32 * 1024];
#endif //__MESSAGE_H__