diff options
author | Nebuleon Fumika | 2012-12-21 03:50:10 -0500 |
---|---|---|
committer | Nebuleon Fumika | 2012-12-21 03:50:10 -0500 |
commit | a0d0c5e7a5bdc396b4c370a750273b6e3b963bb0 (patch) | |
tree | 6bc433422db602b974a01dffbfc5ce5d84afc578 | |
parent | 3972512b2a5c25236ea3ba586621dba6e5b56361 (diff) | |
download | snes9x2005-a0d0c5e7a5bdc396b4c370a750273b6e3b963bb0.tar.gz snes9x2005-a0d0c5e7a5bdc396b4c370a750273b6e3b963bb0.tar.bz2 snes9x2005-a0d0c5e7a5bdc396b4c370a750273b6e3b963bb0.zip |
Eliminate the latency of button press recognition, which was bad enough to lose keys entirely sometimes, and could otherwise delay a button press or release by 200 ms.
This was the entire reason I created the fork, and I finally did it! It syncs the controls every scanline of a frame, which costs about 60,000 MIPS instructions per frame to deal with. Luckily, the processor runs at 396 MHz, which means the cost of checking the controls is 1% of the CPU's power.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | source/cpuexec.cpp | 14 | ||||
-rw-r--r-- | source/nds/ds2_main.c | 52 | ||||
-rw-r--r-- | source/nds/entry.cpp | 10 | ||||
-rw-r--r-- | source/nds/gui.c | 1 | ||||
-rw-r--r-- | source/ppu.cpp | 35 | ||||
-rw-r--r-- | source/ppu.h | 3 |
7 files changed, 84 insertions, 33 deletions
@@ -71,7 +71,7 @@ CFLAGS := -mips32 -Os -mno-abicalls -fno-pic -fno-builtin \ DEFS := -DSPC700_C -DEXECUTE_SUPERFX_PER_LINE -DSDD1_DECOMP \
-DVAR_CYCLES -DCPU_SHUTDOWN -DSPC700_SHUTDOWN \
-DNO_INLINE_SET_GET -DNOASM -DHAVE_MKSTEMP '-DACCEPT_SIZE_T=size_t' \
- -DUNZIP_SUPPORT -DNO_OPEN_BUS
+ -DUNZIP_SUPPORT -DNO_OPEN_BUS -DSYNC_JOYPAD_AT_HBLANK
.PHONY: clean makedirs
.SUFFIXES: .elf .dat .plg
diff --git a/source/cpuexec.cpp b/source/cpuexec.cpp index 21b1574..5fb79e5 100644 --- a/source/cpuexec.cpp +++ b/source/cpuexec.cpp @@ -105,6 +105,10 @@ #include "sa1.h" #include "spc7110.h" +#ifdef SYNC_JOYPAD_AT_HBLANK +#include "display.h" +#endif + extern void S9xProcessSound (unsigned int); void S9xMainLoop (void) @@ -226,6 +230,16 @@ void S9xDoHBlankProcessing () switch (CPU.WhichEvent) { case HBLANK_START_EVENT: +#ifdef SYNC_JOYPAD_AT_HBLANK + // Re-get the controls every hblank. A resolution algorithm in + // ppu.cpp will determine with greater accuracy whether a key was + // pressed or released during the frame. + uint32 i; + for (i = 0; i < 5; i++) + { + IPPU.JoypadsAtHBlanks [i][CPU.V_Counter] = S9xReadJoypad (i); + } +#endif if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight) IPPU.HDMA = S9xDoHDMA (IPPU.HDMA); diff --git a/source/nds/ds2_main.c b/source/nds/ds2_main.c index 710215b..2d73313 100644 --- a/source/nds/ds2_main.c +++ b/source/nds/ds2_main.c @@ -15,19 +15,19 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */
-
-#include <stdio.h>
-#include "console.h"
-#include "fs_api.h"
+ */ + +#include <stdio.h> +#include "console.h" +#include "fs_api.h" #include "ds2io.h" #include "ds2_timer.h" #include "ds2_malloc.h" -
-#define BLACK_COLOR RGB15(0, 0, 0)
-#define WHITE_COLOR RGB15(31, 31, 31)
-
-extern int sfc_main (int argc, char **argv);
+ +#define BLACK_COLOR RGB15(0, 0, 0) +#define WHITE_COLOR RGB15(31, 31, 31) + +extern int sfc_main (int argc, char **argv); #if 0 void ddump_mem(unsigned char* addr, unsigned int len) @@ -42,24 +42,22 @@ void ddump_mem(unsigned char* addr, unsigned int len) } #endif +void ds2_main(void) +{ + int err; +ds2_setCPUclocklevel(13); + //Initial video and audio and other input and output + err = ds2io_initb(512, 22050, 0, 0); + if(err) goto _failure; -
-void ds2_main(void)
-{
- int err;
-ds2_setCPUclocklevel(13);
- //Initial video and audio and other input and output
- err = ds2io_initb(512, 22050, 0, 0);
- if(err) goto _failure;
+ //Initial file system + err = fat_init(); + if(err) goto _failure; - //Initial file system
- err = fat_init();
- if(err) goto _failure;
+ //go to user main funtion + sfc_main (0, 0); - //go to user main funtion
- sfc_main (0, 0);
-
_failure: - ds2_plug_exit();
-}
-
+ ds2_plug_exit(); +} + diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index 24c0e03..467461b 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -90,6 +90,7 @@ void S9xParseDisplayArg (char **argv, int &ind, int) void S9xExit () { + ds2_setCPUclocklevel(13); // Crank it up to exit quickly if(Settings.SPC7110) (*CleanUp7110)(); @@ -382,15 +383,15 @@ void init_sfc_setting(void) Settings.SixteenBit = TRUE; Settings.SupportHiRes = FALSE; - Settings.NetPlay = FALSE; - Settings.ServerName [0] = 0; Settings.ThreadSound = FALSE; Settings.SoundSync = TRUE; Settings.AutoSaveDelay = 0; #ifdef _NETPLAY_SUPPORT + Settings.NetPlay = FALSE; + Settings.ServerName [0] = 0; Settings.Port = NP_DEFAULT_PORT; #endif - Settings.ApplyCheats =FALSE; + Settings.ApplyCheats = FALSE; Settings.TurboMode = FALSE; Settings.TurboSkipFrames = 40; Settings.StretchScreenshots = 1; @@ -1009,7 +1010,8 @@ unsigned int S9xReadJoypad (int which1) key |= (inputdata.key & (1<<i)) ? keymap[i] : 0; } - return (key | 0x80000000); + // return (key | 0x80000000); + return key; // ??? [Neb] } else return 0; diff --git a/source/nds/gui.c b/source/nds/gui.c index bf85b67..4a04efc 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -1714,6 +1714,7 @@ 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; diff --git a/source/ppu.cpp b/source/ppu.cpp index 8ba7a5f..e0c6e24 100644 --- a/source/ppu.cpp +++ b/source/ppu.cpp @@ -3202,12 +3202,45 @@ void S9xUpdateJustifiers() void S9xUpdateJoypads () { - int i; + uint32 i; +#ifdef SYNC_JOYPAD_AT_HBLANK + uint32 j, k, KeyValue; + bool8 StartedPressed; + + // For each joypad + for (i = 0; i < 5; i++) + { + IPPU.Joypads [i] = 0; + // Sync each key + for (k = 1; k != 0x80000000; k <<= 1) + { + KeyValue = IPPU.JoypadsAtHBlanks[i][0] & k; + StartedPressed = KeyValue != 0; + // from each line. + // If, initially, the key is NOT pressed, one line of it being + // pressed means that the key MUST be pressed. + // Otherwise, the key MUST be pressed if it doesn't start as such. + for (j = 1; j < (Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER); j++) + { + if ((StartedPressed) && ((IPPU.JoypadsAtHBlanks[i][j] & k) == 0)) { + KeyValue = 0; + break; + } + else if ((!StartedPressed) && ((IPPU.JoypadsAtHBlanks[i][j] & k) != 0)) { + KeyValue = k; + break; + } + } + IPPU.Joypads [i] |= KeyValue; + } + } +#else for (i = 0; i < 5; i++) { IPPU.Joypads [i] = S9xReadJoypad (i); } +#endif // S9xMovieUpdate(); diff --git a/source/ppu.h b/source/ppu.h index 6daf473..065ad5f 100644 --- a/source/ppu.h +++ b/source/ppu.h @@ -151,6 +151,9 @@ struct InternalPPU { int CurrentLine; int Controller; uint32 Joypads[5]; +#ifdef SYNC_JOYPAD_AT_HBLANK + uint32 JoypadsAtHBlanks[5][SNES_MAX_PAL_VCOUNTER]; +#endif uint32 SuperScope; uint32 Mouse[2]; int PrevMouseX[2]; |