Moonwalk

Franco92

New member
I think i found a little bug.
In order to find it you have to walk left and release the left button,
if you press quickly the right button and release it immediately, your character will continue to move left with the "Idle Right" animation.

The same bug occurs on the vertical axis (as written above but by pressing Up, Down and releasing the latter) in this case it will move up with the "Idle Down" animation.

:)
 

RadJunk

Administrator
Staff member
I suppose it is possible, but sounds more likely that your inputs are set up incorrectly?
 

RadJunk

Administrator
Staff member
Hard to tech, because I can't reproduce it.

If you attach a screenshot of your input editor, I can have a look.
 

Franco92

New member
Sure:
31949535_1418916764881620_5028858094558380032_n.jpg
 

RadJunk

Administrator
Staff member
Thanks! And correct, I don't see anything wrong there.

It's strange, because I can't seem to reproduce the problem
 

Rob Burrito

New member
i had a gliding/skating issue which would turn into other errors when other directions were pressed. try removing all your direction scripts in the input editor and reloading them assigned to of course the correct directions, and also making sure the release is all set with the right form of press/hold/release.
 

Franco92

New member
TheNew8bitHeroes said:
Thanks! And correct, I don't see anything wrong there.

It's strange, because I can't seem to reproduce the problem

You must be very fast by pressing the keys.
I also encountered another problem:
If you press a directional key and immediately after releasing it, press the opposite direction, the character will walk "on spot" until the last key is released.
Can a video with input on the display help you to find the problem?

Rob Burrito said:
i had a gliding/skating issue which would turn into other errors when other directions were pressed. try removing all your direction scripts in the input editor and reloading them assigned to of course the correct directions, and also making sure the release is all set with the right form of press/hold/release.

I have already tried this without solving the problem
 

RadJunk

Administrator
Staff member
If I can make a hypothesis? It's not "really fast" change of input, it's actually simultaneous input (which would be impossible on an actual controller, which is what we're testing on and the intended deliverable...better input reads could always be written to handle better for simultaneous reads on a computer keyboard). This is just a guess. If he's walking "on spot" (animating, but not moving) it means his state is 1, but his movement byte is 0 in the horizontal direction. This is fairly common with the current movement scripts if you're thumbing in with a keyboard, especially. The "moonwalk" thing is another matter, though.
 

Franco92

New member
I use a keyboard, so your hypothesis is plausible.
Anyway, I attach a demostrative video, maybe it can be useful :)

giphy.gif
 

Kasumi

New member
I played a NES Maker ROM from a discord that lets you walk double speed with left+right. (Press right, press left, release right.) Sure, I'll totally beat the dead horse! Just filter it in software! Then you'll always be sure the reason for any odd movement isn't that.

If you're worried about the once per frame cycle hit, you can speed up the current joypad read routine with a ring buffer and a few other changes. (Which I recommend doing even if you don't filter left+right. It's fewer bytes, and faster, even if not much faster.)
Code:
GamePadCheck:
	;strobe the gamepad
	LDA #$01
	STA $4016
	LDA #$00
	STA $4016
	
	LDA #$80
	sta gamepad;Why? For seven rors, the carry will be clear.
	;For the eighth ror, the carry will be set, which means you've done
	;all eight buttons. No need for X. Also, you can ror the variable directly
	;to avoid the PHA and PLA. PHA, ROR A, PLA is 9 cycles. 
	;ROR zero page is 5. You save 4 cycles per loop.
	;Then you save the dex due to the ring buffer for another 2 cycles per loop
	;Then 3 cycles because no need to store to gamepad at the end.
	;The result is already there due to roring it there directly.
	;51 cycles saved
ReadControllerBytesLoop:
	LDA $4016
	AND #%00000011
	CMP #%00000001
	ROR gamepad
	BCC ReadControllerBytesLoop
	
	RTS
And to add to the above, here it is filtered:
Code:
GamePadCheck:
	;strobe the gamepad
	LDA #$01
	STA $4016
	LDA #$00
	STA $4016
	
	LDA #$80
	sta gamepad;Why? For seven rors, the carry will be clear.
	;For the eighth ror, the carry will be set, which means you've done
	;all eight buttons. No need for X. Also, you can ror the variable directly
	;to avoid the PHA and PLA. PHA, ROR A, PLA is 9 cycles. 
	;ROR zero page is 5. You save 4 cycles per loop.
	;Then you save the dex due to the ring buffer for another 2 cycles per loop
	;Then 3 cycles because no need to store to gamepad.
	;The result is already there due to roring it there directly.
	;51 cycles saved
ReadControllerBytesLoop:
	LDA $4016
	AND #%00000011
	CMP #%00000001
	ROR gamepad
	BCC ReadControllerBytesLoop
	
	lda gamepad
	and #%11000000;Isolate left+right
	cmp #%11000000;If both are not pressed, don't filter
	bne ReadControllerNoFilterLeftRight
	;If here, both left and right are pressed
	eor gamepad;Since you've guaranteed both bits are set, this eor will clear them
	sta gamepad
ReadControllerNoFilterLeftRight:
	lda gamepad
	and #%00110000;Isolate up+down
	cmp #%00110000;If both are not pressed, don't filter
	bne ReadControllerNoFilterUpDown
	;If here, both up and down are pressed
	eor gamepad;Since you've guaranteed both bits are set, this eor will clear them
	sta gamepad
ReadControllerNoFilterUpDown:
	RTS
30 cycles added if you're pressing ALL FOUR D-PAD DIRECTIONS AT ONCE.
20 cycles if you're not pressing anything simultaneously.

Both of which fit in under the 51 cycles saved. (But yes, it's more bytes, then.)
 

RadJunk

Administrator
Staff member
Sure - keep in mind though, ALL the routines here you see are really placeholders. They're the "vanilla". These are exactly the sort of thing we want to show people WHERE to add to the code, and how to do it to end up with the same output bytes, and then hopefully have a big repository of these sorts of codes for people to plug in to do exactly what they want to do :)
 

RadJunk

Administrator
Staff member
Two things. 1, that's super weird. I can't replicate that over here. I've tried. It must be a same frame type thing...it's the only thing I can figure.

2...please tell me you're using awesome walking arrow dude in a game! haha
 

Mihoshi20

Member
Franco92 said:
I use a keyboard, so your hypothesis is plausible.
Anyway, I attach a demostrative video, maybe it can be useful :)

giphy.gif

I love this little arrow guy. He needs his own game. Reminds me a lot of like an enemy you'd see in Earthbound.
 

Franco92

New member
Kasumi said:
I played a NES Maker ROM from a discord that lets you walk double speed with left+right. (Press right, press left, release right.) Sure, I'll totally beat the dead horse! Just filter it in software! Then you'll always be sure the reason for any odd movement isn't that.

If you're worried about the once per frame cycle hit, you can speed up the current joypad read routine with a ring buffer and a few other changes. (Which I recommend doing even if you don't filter left+right. It's fewer bytes, and faster, even if not much faster.)

I tried the key combination (right, left, release right) but no speed increase happens.
thanks anyway for the tip!
I tried your codes but the moonwalk persists, maybe it can depend on the fact that I'm testing the game with a keyboard?

TheNew8bitHeroes said:
Two things. 1, that's super weird. I can't replicate that over here. I've tried. It must be a same frame type thing...it's the only thing I can figure.
2...please tell me you're using awesome walking arrow dude in a game! haha

Very strange, I use two frames for "Idle" and four for "walk".
haha sure maybe it will appear as an NPC or a monster ;)

Mihoshi20 said:
I love this little arrow guy. He needs his own game. Reminds me a lot of like an enemy you'd see in Earthbound.

haha Thank you!
 

RadJunk

Administrator
Staff member
Kasumi - maybe I'll use a filter check system while demonstrating the (forthcoming) general code selection interface, which is similar to the Input, but a bit different (and considered an advanced function, generally), where the user can determine the physics code, the collision code, etc. I'll be doing that when showing off platforming mechanics anyway, so...maybe I'll show you you could build a few versions of input and pull the one you want into the code.

Not sure if that's ready for Memorial day, or slight behind.
 

Kasumi

New member
Franco92: Out of curiosity where did you put the code? It's meant as an engine change, not a modified user script.
TheNew8bitHeroes: Why demonstrate it at all? There's no reason to put this on the user to do. You can just put it in the engine! GameEngineData/Routines/System/GamePadCheck.asm

It is significantly more rare that a user would want left+right precisely because of the d-pad thing you mention, but this would prevent your keyboard users from having problems. If you really want it as an option, the user that should have to change it should be the wants who want left+right rather than those who don't. While I'm at it, one more change to save a byte:
Code:
GamePadCheck:
	;strobe the gamepad
	LDA #$01
	STA $4016
	lsr;This is the change. A one then a zero is needed, 1 shifted right is zero.
	STA $4016
	
	LDA #$80
	sta gamepad;Why? For seven rors, the carry will be clear.
	;For the eighth ror, the carry will be set, which means you've done
	;all eight buttons. No need for X. Also, you can ror the variable directly
	;to avoid the PHA and PLA. PHA, ROR A, PLA is 9 cycles. 
	;ROR zero page is 5. You save 4 cycles per loop.
	;Then you save the dex due to the ring buffer for another 2 cycles per loop
	;Then 3 cycles because no need to store to gamepad.
	;The result is already there due to roring it there directly.
	;51 cycles saved
ReadControllerBytesLoop:
	LDA $4016
	AND #%00000011
	CMP #%00000001
	ROR gamepad
	BCC ReadControllerBytesLoop
	
	lda gamepad
	and #%11000000;Isolate left+right
	cmp #%11000000;If both are not pressed, don't filter
	bne ReadControllerNoFilterLeftRight
	;If here, both left and right are pressed
	eor gamepad;Since you've guaranteed both bits are set, this eor will clear them
	sta gamepad
ReadControllerNoFilterLeftRight:
	lda gamepad
	and #%00110000;Isolate up+down
	cmp #%00110000;If both are not pressed, don't filter
	bne ReadControllerNoFilterUpDown
	;If here, both up and down are pressed
	eor gamepad;Since you've guaranteed both bits are set, this eor will clear them
	sta gamepad
ReadControllerNoFilterUpDown:
	RTS
 

RadJunk

Administrator
Staff member
The main reason is to keep the base vanilla for all sorts of things we can't account for, and for super easy reading. But moreso, why leave it to add - because it's a demonstrable point where a user might want to do something different, not even defined in the code you shared. Since you're right, it would make a good update, having THEM look at how to implement an update and walking it through might give them some more ASM confidence. :)
 

Franco92

New member
Sorry kasumi, my english is very bad I misunderstood!
NESmaker\GameEngineData\Routines\System\GamePadCheck
I put everything back as it was before :p
 

RadJunk

Administrator
Staff member
FYI - Kasumi...I did add this filter as a default in the controller check. In combination, in future tutorials, I'm going to use "dpad held" rather then pressed to start motion. This should prevent moonwalking and make movement a little more refined.

Thanks for the thought, and you're right. This wasn't a big enough difference to warrant being the 'change out scripts' thing. You rock, sir.
 
Top Bottom