aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNebuleon Fumika2012-12-21 03:50:10 -0500
committerNebuleon Fumika2012-12-21 03:50:10 -0500
commita0d0c5e7a5bdc396b4c370a750273b6e3b963bb0 (patch)
tree6bc433422db602b974a01dffbfc5ce5d84afc578
parent3972512b2a5c25236ea3ba586621dba6e5b56361 (diff)
downloadsnes9x2005-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--Makefile2
-rw-r--r--source/cpuexec.cpp14
-rw-r--r--source/nds/ds2_main.c52
-rw-r--r--source/nds/entry.cpp10
-rw-r--r--source/nds/gui.c1
-rw-r--r--source/ppu.cpp35
-rw-r--r--source/ppu.h3
7 files changed, 84 insertions, 33 deletions
diff --git a/Makefile b/Makefile
index 255cf39..605d727 100644
--- a/Makefile
+++ b/Makefile
@@ -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];