diff options
Diffstat (limited to 'source/nds/entry.cpp')
-rw-r--r-- | source/nds/entry.cpp | 620 |
1 files changed, 386 insertions, 234 deletions
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; |