Page 1 of 3

D-Pad emulation

Posted: Sun Apr 12, 2009 10:26 pm
by Celius
I'm working on a game, and I just realized that if both up and down are pressed, really bad things will happen. However, after using FCEUXD and holding both up and down, I noticed nothing happened. Then I discovered that it seemed to not acknowledge either button if both were pressed. Is this how it is on all emulators? And is this just because of how the NES D-Pad plastic arrows are designed, or is there another reason circuitry-related that both up and down (or left and right) cannot be pressed at the same time?

Posted: Sun Apr 12, 2009 10:47 pm
by Drag
The way the dpad is physically constructed, there's no physical way to press up+down, nor left+right, short of snapping the dpad in half, or pressing the actual contacts.

There's no actual circuitry to prevent up+down and left+right though.

Emulators would prevent it because those of us (like me) who use the keyboard for emulators find it very very easy to accidentally hit both directions at the same time without meaning to, when changing from one to the other.

Posted: Sun Apr 12, 2009 11:10 pm
by Dwedit
There's an option to enable and disable UP+DOWN or LEFT+RIGHT in Fceux. Many TASs require pressing the illegal button combination to play through the game faster.

Posted: Sun Apr 12, 2009 11:11 pm
by Celius
Thanks; that's what I thought.

I was just wondering if I would be safe assuming that an up+down combination would never come from $4016. I think I am, pretty much. Though I guess it's not that hard to prevent with software, I guess. Just check if up is pressed. If so, do up-pressed logic, and skip to check if left or right is pressed. If up isn't pressed, check if down is pressed. So that way it will always do one or the other.

EDIT:
Dwedit wrote:There's an option to enable and disable UP+DOWN or LEFT+RIGHT in Fceux. Many TASs require pressing the illegal button combination to play through the game faster.
TASs?

Posted: Sun Apr 12, 2009 11:28 pm
by Dwedit
Tool Assisted Speedrun

Posted: Mon Apr 13, 2009 12:05 am
by AWal
If one of your NES control pads is worn enough and you don't mind (near)blisering your thumb, Mario in the first SMB can do a pretty mean moon walk if you squish the center of the D-Pad, causing that to happen.

Posted: Mon Apr 13, 2009 1:09 am
by Bregalad
In fact pressing Up+Down or Left+Right causes some interesting effects in some games.
In castlevania, this allowed one to use items while crouching. In gradius, it makes the spaceship not moving, but the options does and regroup where the spaceship. In batteltoads something really weird can happen. In my game, this make the player walk without moving (I didn't make it on purpose, it just happened to have this effect).

So I'd say you must consider that combination as impossible, but if that happens, it'd be nice if your programm didn't crash or anything real bad wouldn't happen.

Posted: Mon Apr 13, 2009 1:47 am
by koitsu
Bottom line: don't worry about it. And why emulator authors added that option is beyond me -- I'd love to punch them in the balls.

Posted: Mon Apr 13, 2009 4:50 am
by tepples
koitsu wrote:And why emulator authors added that option is beyond me -- I'd love to punch them in the balls.
Because they're emulating the piece of plastic in the Control Pad.

Posted: Mon Apr 13, 2009 5:15 am
by Xkeeper
koitsu wrote:Bottom line: don't worry about it. And why emulator authors added that option is beyond me -- I'd love to punch them in the balls.
Yes, because it's not like this kind of thing can happen on an actual NES (see the post about worn out pads).


Jesus Christ you assholes are uptight over this shit.

Oh btw if you want to test up+down / left+right in your game or whatever, just lock the "input" byte you store to have both bits set.

Posted: Mon Apr 13, 2009 7:12 am
by blargg
Just wanted to note that since all the buttons are latched simultaneously by the shift register, there's virtually no way a normal controller can register conflicting directions. If they weren't all latched simultaneously, the player changing from down to up could theoretically occur between when you read one bit and when you read another, allowing both to read as set.

Posted: Mon Apr 13, 2009 10:17 am
by Celius
Xkeeper wrote:Jesus Christ you assholes are uptight over this shit.
Who is an asshole? And who's uptight about what?

Just to be safe, I'm going to code it assuming all buttons can be pressed at once. I won't really take extra time assuming this, as it can be easily prevented by doing this:

if up = pressed
do stuff
go to +
else
end if

if down = pressed
do stuff
else
end if

+

if left = pressed
do stuff
go to +
else
end if

if right = pressed
do stuff
else
end if

+

It's really quite simple, I guess. If opposite directions are pressed, just pick one of the directions and say the other isn't pressed so your program won't crash. And users pressing two opposite directions at once should know that they shouldn't do that, so anything like one direction dominating over the other won't be so weird to have.

Oh, but then you could do this trick:

if Left AND Right = 1
do nothing
else
end if

if Left = Pressed
...

So that you would effectively have left and right cancel each other out. This would be better to do.

Posted: Mon Apr 13, 2009 10:53 am
by Bregalad
Yeah having one direction take over another or having both cancelling is definitely the way to go (do it the more compact way possible without adding code to handle this). You just don't want your programm to crash if up+down or left+right are pressed, so that this enable people to play your game with some emulators or unlicenced controllers without having it crashing.

Remember, computer science is like math, the more complicated the route you take is, the most likely it's the wrong one.

BTW pressing up+down+B is the only way to use a subweapon while crouching in Castlevania. And the knife/boomerang thrown IS lower than normal, apparently the developper just didn't think that up+down wasn't possible. Altough this only works for Castlevania 1, not Castlevania 3.

Posted: Mon Apr 13, 2009 11:03 am
by Jon
you could exclusive-OR(aka XOR) the up/down and left/right bits together so that they cancel one another out when they are both pressed.

When you read in the data a bit at a time, you could pad the Up/Down and Left/Right bits with an extra 0 as you shift it into a temp variable. Using these extra 0s as space for shift and EOR.

A = 0 0 U D 0 L R 0

Then store it in a temp variable. next you shift it right and EOR it with the temp variable.

Code: Select all

  0 0 U D 0 L R 0
^ 0 0 0 U D 0 L R
--------------------
  0 0 U p D L q R  
Now you can use p instead of U or D, depending on which has priority.
And q instead of L or R, again depending on which has priority.

Clear as mud? (warning: i didn't bother trying this idea out before posting it)

Posted: Mon Apr 13, 2009 11:14 am
by blargg
The "best" algorithm was posted a while back. In summary, if both directions on an axis are pressed, only the one most recently pressed is reported as down. This way if you're using a keyboard and currently pressing left, then press right before you release left, the right press will register immediately, rather than causing it to appear that neither was pressed until left is released.