Edit: The following code is apparently fine. I figured out the problem elsewhere and it fixed it. My other question is still relevant though.
So I decided to learn how to make an action game.
In order to make physics smooth and flexible like I want them, I understand that I need to make: A fixed-point subpixel system so I can move slower than 1 pixel/frame, acceleration-based movement for both running and jumping, and variable height jumping.
I already made subpixel coordinates using one byte for the fractional part and one for the integer part of the coordinate and they work fine.
Now I'm trying to make acceleration-based movement. I started making the controller handling for rightward movement. I learned to do comparisons with signed numbers from this article.
So to move rightwards, I'm using two bytes for velocity that are added to by a two-byte acceleration value every frame that the RIGHT d-pad button is pressed. Before updating the velocity I first compare (using 16-bit signed comparison from above link) the new velocity value with the max speed value and if it's more than the max speed, I set the velocity to the max speed value, else I proceed to update velocity with the new value.
Velocity is then added to the 16-bit X-coordinate which updates the sprite position.
My code works fine as long as my max speed isn't set to $00.7F or more. As soon as my sprite comes up to this speed he will start slowing down to zero again, then accelerate again and so on as long as I hold the button. I suspect something about the comparison routine makes it think that the lower velocity byte is signed. Shouldn't the sign only be in the most significant byte so that the range becomes $80.00 to $7F.FF?
Code: Select all
;Constants: MOB_ACCEL_L = 4 ;walking/running acceleration value fractional part MOB_ACCEL_H = 0 ;walking/running acceleration value integer part MOB_MSPD_L = 128 ;maximum walking/running speed fractional part MOB_MSPD_H = 0 ;maximum walking/running speed integer part ;Variables: temp+0 temp+1 ;temporary storage p1_x+0 ;horizontal coordinate fractional part p1_x+1 ;horizontal coordinate integer part p1_vx+0 ;horizontal velocity fractional part p1_vx+1 ;horizontal velocity integer part ;Code: @right1: ;controller I input handler for RIGHT button lda con_state+0 and #CON_RIGHT beq @not_right1 lda p1_vx+1 bmi @not_right1 ;if velocity negative, not right lda p1_vx+0 clc adc #MOB_ACCEL_L ;add acceleration value to velocity, low byte sta temp+0 lda p1_vx+1 adc #MOB_ACCEL_H ;add acceleration value to velocity, high byte sta temp+1 ;store new velocity temporary for comparison lda temp+0 cmp #MOB_MSPD_L lda temp+1 sbc #MOB_MSPD_H bvc @n_xor_v_vr eor #$80 @n_xor_v_vr: ;16-bit signed comparison with max speed bmi @not_terminal_vr ;if velocity < max speed, allow acceleration lda #MOB_MSPD_L ldx #MOB_MSPD_H jmp @terminal_vr ;else, velocity = max speed @not_terminal_vr: lda temp+0 ldx temp+1 @terminal_vr: sta p1_vx+0 stx p1_vx+1 ;set velocity jmp @a1 ;exit @not_right1: ;if !RIGHT, decelerate ;...... p1_move_x: ;horizontal movement based on velocity lda p1_x+0 clc adc p1_vx+0 sta p1_x+0 ;add velocity to position to move, low byte lda p1_x+1 adc p1_vx+1 sta p1_x+1 ;add high byte plus carry
1) What's wrong with my code?
Edit: Of course soon after posting this, I found out the problem. It appears the code is fine, the problem was very simple and unrelated to this code. I guess the code can be used by others trying to do the same thing. My other question is still relevant though.
2) What is the Overflow Flag normally used for? From what I understand it indicates overflow/underflow between $7F and $80 to indicate that the value didn't fit in the signed number, much like Carry indicates that a number doesn't fit in a byte. But unlike Carry it isn't used in additions and subtractions. The only use I know of it is for signed comparisons, as a simulation of a branch always instruction and used in a special feature of the BIT instruction.
Any help is greatly appreciated!