D-Pad emulation

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
D-Pad emulation
by on (#45537)
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?

by on (#45538)
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.

by on (#45539)
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.

by on (#45540)
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?

by on (#45542)
Tool Assisted Speedrun

by on (#45544)
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.

by on (#45546)
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.

by on (#45548)
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.

by on (#45552)
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.

by on (#45554)
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.

by on (#45557)
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.

by on (#45562)
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.

by on (#45567)
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.

by on (#45569)
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:
  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)

by on (#45570)
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.

by on (#45572)
I guess it's fine if they cancel each other out. I just implemented this. But Blargg, registering which one was most recently pressed sounds definitely like the best way to go. But I've got to confess, at the moment I'm too lazy to implement that. I'm assuming left and right won't be pressed too often simultaneously. And plus, even though my game is action-based, it won't require lightning fast reflexes and very precise timing, so it's not that big of a deal. Thanks for everyone's help!

by on (#45585)
Celius wrote:
I guess it's fine if they cancel each other out. I just implemented this. But Blargg, registering which one was most recently pressed sounds definitely like the best way to go. But I've got to confess, at the moment I'm too lazy to implement that. I'm assuming left and right won't be pressed too often simultaneously. And plus, even though my game is action-based, it won't require lightning fast reflexes and very precise timing, so it's not that big of a deal. Thanks for everyone's help!


My recommendation: focus on the game first then optimize your code for those things after. Why would it be an issue during the developing phase?

my 2 cent.

by on (#45587)
Some games have more than "interesting" behaviour if conflicting directions are pressed. Commando crashes if left and right are pressed simultaneously.

by on (#45589)
baisoku wrote:
Some games have more than "interesting" behaviour if conflicting directions are pressed. Commando crashes if left and right are pressed simultaneously.


simple. before doing anything with the directions in the game logic just have left-right instantly kill you, and up-down make your invisible (not invincible). then TAS people can't scam your game.

by on (#45592)
Banshaku wrote:
My recommendation: focus on the game first then optimize your code for those things after. Why would it be an issue during the developing phase?


I like to get as much out of the way as possible before realizing my project is a hopeless mess and having to start over like I have so many times before. And in the earlier stages of development, I think it's best to make sure it doesn't crash.

Banshaku wrote:
my 2 cent.


I'm sorry, I really don't mean to be nit picky (I don't like to be nit picky), but I notice you write this after nearly every post. It's almost like signing each post with "-<your name>" all the time. It's not really annoying or anything, I just think by this point we know what you're posting is your 2 cents, and you could save yourself the trouble of typing it all the time. If you feel you need to, go ahead, but it's just my 2 cents :) .

by on (#45595)
Celius wrote:
I like to get as much out of the way as possible before realizing my project is a hopeless mess and having to start over like I have so many times before. And in the earlier stages of development, I think it's best to make sure it doesn't crash.


It always depends on much your joystick input routine have an impact on your game. From my point of view, you are just reading a state of an input device that will be stored in a buffer somewhere. this buffer will be used after in another routine. Those 2 routines are not tied together and should be independent.

To optimize later the the way the buffer is read to avoid pressing button should have no impact on your current development cycle unless they are deeply coupled in some way. This is why I said that it shouldn't be an issue. Those are the kind of details that always delay the development cycle of a program because we think they could be important and annoys us but often they are not.

Celius wrote:
I'm sorry, I really don't mean to be nit picky (I don't like to be nit picky), but I notice you write this after nearly every post. It's almost like signing each post with "-<your name>" all the time. It's not really annoying or anything, I just think by this point we know what you're posting is your 2 cents, and you could save yourself the trouble of typing it all the time. If you feel you need to, go ahead, but it's just my 2 cents :) .


It just happens that I wrote it to a few message recently but I don't write it to all of them. I don't like signatures and it was not the intend. I always write it for some specific messages only.

If it so irritating then I will try to avoid using it compulsively. my 2 .. argggg :P

by on (#45596)
I actually don't worry about what can and cannot be pressed on a hardware level, I just assume everything can. I don't get any bugs because my logic/physics does not collapse if opposing directions are pressed. If left and right are pressed at the same time, my engine will just take both forces into account, and the character will most likely just stand there, no problem. If it was walking in one direction and the opposite key was pressed (while the other remained pressed), the character would just slow down because of the opposing force and eventually stop.

I didn't have to deal with up and down yet (because I haven't used up), but I'd probably handle it using states, favoring the current state. If the character was looking down and the player pressed up, I'd look into the request of looking up, but wouldn't allow it since the character was currently looking down (as I wouldn't for many other states, such as jumping, getting hurt, etc). Same thing if it was looking up, I'd deny a look down until it stopped looking up.

I really feel that this problem is best resolved at the game logic level. If you filter keys at the hardware level (the emulator does it for you or you do it on your joypad reading routine) you loose the power to prioritize keypresses on a case-by-case basis. blargg's solution is interesting, but what if for some reason during a specific portion of my game I need to prioritize the key that was pressed first (as opposed to the most recent)?

Just out of curiosity, I just checked how Sonic 1 and 2 handle the looking up/down thing. It just prioritizes looking up, which I think is wrong. I know that some NES games have bugs when opposing directions are pressed, and I see this as sloppy coding, right along with visible scrolling artifacts and other "pearls" present in so called "professional" games.

by on (#45603)
blargg wrote:
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.

All it takes is a low quality pad or a pad that does not work correctly and suddenly it is indeed very possible.

Oh wait, nothing ever goes wrong with consoles or their hardware. Silly me.


Celius wrote:
Xkeeper wrote:
Jesus Christ you assholes are uptight over this shit.


Who is an asshole? And who's uptight about what?

hint: the person I quoted right before saying that.

by on (#45604)
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.


That's a bit extreme. I can name a few titles with spots that will lock the game in an infinite loop if you press up+down or left+right at the same time. Since it's difficult to do it with a real D-pad anyway, it's a good option to have when using a keyboard for input. I'd even say it's best to block the combinations by default.

That said, since the hardware technically allows it, it's best to put the input filtering code on the UI side, and not in the core register polling routines.

by on (#45606)
I never understood how tool asisted stuff could make the hero make super jumps or being teleported. Dodes some game have this kind of behavior when up+down or left+right are pressed ?

To kill tool assisted stuff you could show directly the ending whenever up+down or left+right are pressed, so that people will think "that's unfair" and will watch real speedruns instead.

by on (#45617)
I originally added this filter to my emulator after spending a long time chasing a bug in the Battletoads snake pit levels. Pressing left+right causes your character to float upwards, and not go back down when you release them. Since that game has such tricky timing and delays enabling rendering, I spent the longest time looking for timing bugs.

by on (#45618)
Bregalad wrote:
I never understood how tool asisted stuff could make the hero make super jumps or being teleported. Dodes some game have this kind of behavior when up+down or left+right are pressed ?

I think they use all sorts of bugs from the games, not just up+down/left+right. I guess that teleports are often the result of collision detection issues (like when a character gets stuck into a wall and is ejected from it, either to the other side or to the top), or coordinate system issues (unusual coordinates are misinterpreted and the characters shows up somewhere else). High jumps, I believe, are the result of jumping again at the exact frame where the engine is not certain if the character is on the ground or not. In some games (SMB is one of them, I think) you can jump when pressed against a wall if the character is vertically aligned with a wall block that is perceived as floor.

by on (#45621)
- Short answer: programming bugs.
- Well, Battletoads gameplay is ruined during vertical stages if you press down+up. In Zelda 2, Link can slide almost instantly with left+right.

- As quick note, when someone says "up+down", it can be "hold up THEN press down" as example. ;)

by on (#45648)
Bregalad wrote:
I never understood how tool asisted stuff could make the hero make super jumps or being teleported. Dodes some game have this kind of behavior when up+down or left+right are pressed ?

To kill tool assisted stuff you could show directly the ending whenever up+down or left+right are pressed, so that people will think "that's unfair" and will watch real speedruns instead.


That really won't kill tool-assisted speedruns (why would you want to, anyway?).

There are several games with extreme game-breaking glitches (Link's Awakening is one of them, both original and DX versions). That is why there's a TAS of the full game.


I never got the reason for all the hate over TASes. I, for one, enjoy both; TASes are meant to be a demonstration of perfection, speedruns are a demonstration of skills. They're not at odds with each other, and you would do yourself well to understand that.



As for left+right/up+down bugs, surprisingly few games actually have ones that are anything beyond "low" in severity. SMB1's, for example, just makes you moonwalk.

by on (#45658)
Jon wrote:
simple. before doing anything with the directions in the game logic just have left-right instantly kill you, and up-down make your invisible (not invincible). then TAS people can't scam your game.


All Killing the character would do is make the TAS player not press left+right. They'll still TAS the game, and you'll have accomplished nothing. Making the character invisible would not stop a dedicated TAS player, who would simply find his position in RAM. As a matter of fact, it would give a TAS player a reason to TAS your game, as going through an entire game invisible would make a SPECTACULAR TAS to watch. All these two things would do is seriously confuse a player with a broken down NES controller, or an emulator that doesn't filter up+down or left+right. Not to mention that programming the game to handle the case so nothing weird happens is a much better solution anyway.

As for making up+down display a game's ending, the TAS player could simply... not press up+down?

Xkeeper: I don't understand TAS hate either. TAS are always clearly labeled, so they don't compete with regular speedruns. I don't think people understand the knowledge that goes into making some of the better ones. You have to know SO much about the game to get a really good one. There's a lot more to them than just playing a game frame by frame, or pressing "illegal button combinations". Especially some of the better RPG ones that manipulate "luck" by watching locations in RAM.

by on (#45686)
Yep, a TAS is similar to a Hollywood movie: use whatever tools you can to get the on-screen effect you want. That means re-taking scenes many times when the actors mess up or whatever, using computers and stop-motion filming to get really intricate sequences, etc. One difference is that a TAS may not do anything beyond what can be done by sending the game a sequence of button presses as a controller could generate, otherwise it really is just a movie rather than an intricate puzzle.

by on (#45687)
It's not really that I have hatred for TAS speedrun, but I find it really annoying when I'm looking for an actual speedrun to find only "WOOW MY GOD XXX GAME IN ONLY 27 SEC" to find a movie of the hero teleporting to the last boss room, defeting it with heavy cheating and see the ending. This is not a speedrun.

Altough there is good tool asisted speedruns, like I remember one who did Castlevania : Circle of the moon in slightly more than 20 minutes which was awesome it was very weird and turned into a skeleton to kill all bosses in one hit.

So while some TAS sucks, some others can be great. With regular speedruns you are sure that they are fair and even more impressive. But tool asisted stuff can be more fun at times.

Also it is wrong to say that tool assisted speedruns are always clearly labeled at such. I have seen many speedruns on Youtube that were not labeled as tool assisted, but that seems to have been done with other cheats than just savestates.

by on (#45703)
TAS videos surely use reverse emulation. ^_^;;

by on (#45712)
Bregalad wrote:
Altough there is good tool asisted speedruns, like I remember one who did Castlevania : Circle of the moon in slightly more than 20 minutes which was awesome it was very weird and turned into a skeleton to kill all bosses in one hit.


That was the most disappointing speedrun, tool-assisted or no, that I've ever seen. (For me to enjoy it, it is important that they not cheat luck too much -- killing every single boss via possibly multiple critical bones made it completely implausible that someone might have done that. OTOH, the Metroid speedrun where they kill enemies frame-perfect to get the desired loot was psychologically ok.)

by on (#47676)
Kasumi wrote:
Xkeeper: I don't understand TAS hate either. TAS are always clearly labeled, so they don't compete with regular speedruns. I don't think people understand the knowledge that goes into making some of the better ones. ...

I don't hate TAS, I just don't wouldn't want to make it easier than necessary (as if someone would bother to speedrun anything I've written, let alone even play it twice). Part of the fun of a TAS (I assume) is the challenge.