Hi members of Cemetech my name is Mike.(But you can refer to me by my screen name) I recently had to migrate from UnitedTI after the shut-down.
Recently, I've been working on a Physics engine and I feel fairly proud of myself before getting to this point. I've got most of the physics parts done(at least I think I do) but came to a complete stop once I got to collision detection.
Now I wanted to ask about debugging my code. I didn't see any rules against simply posting my code. In any case, if it is against the rules, or this is the wrong place for this topic
I apologize.
My Physics routine has two point/vectors stored in memory. The current position of the object and the previous position of the object represent like this
Code:
Nothing to fancy
The Physics routine first puts the current position in the previous postion and then modifies the current position based on forces and velocity. It then finds the slope of these two points and simply used that slope to see if there is a collision.
Here's the actual code to detect collisions not the physic part.
Code:
I dont think there a problem with the main but I think there a problem with the called routines xslope and yslope
here is the called routine called xslope
Code:
And here is the called routine yslope
Code:
I'm not sure exactly what the error is. I am open to suggestion or even complete a completely different algorithm, even an already written routine. Any help is appreciated.
Recently, I've been working on a Physics engine and I feel fairly proud of myself before getting to this point. I've got most of the physics parts done(at least I think I do) but came to a complete stop once I got to collision detection.
Now I wanted to ask about debugging my code. I didn't see any rules against simply posting my code. In any case, if it is against the rules, or this is the wrong place for this topic
I apologize.
My Physics routine has two point/vectors stored in memory. The current position of the object and the previous position of the object represent like this
Code:
XPOS:
.db 0
YPOS:
.db 0
PREV_XPOS:
.db 0
PREV_YPOS:
.db 0
Nothing to fancy
The Physics routine first puts the current position in the previous postion and then modifies the current position based on forces and velocity. It then finds the slope of these two points and simply used that slope to see if there is a collision.
Here's the actual code to detect collisions not the physic part.
Code:
;Main Loop
SlopeLoop:
call xslope
jr c,Yonly
call yslope
jr c,Xonly
cp l
ret c
ret z
push af
ld a,e
cp h
jr c,Done
jr z,Done
pop af
jr SlopeLoop
Xonly:
call xslope
push af
ld a,e
cp h
jr c,Done
jr z,Done
pop af
jr Xonly
Yonly:
call yslope
push af
cp l
jr c,Done
jr z,Done
pop af
jr Yonly
Done:
pop af
ret
I dont think there a problem with the main but I think there a problem with the called routines xslope and yslope
here is the called routine called xslope
Code:
xslope:
;Checks to see if there is an x collision on the x-slope
; if there is the carry flag is set otherwise reset
;INPUTS:
; SLOPE:
; b = y
; c = x
; e = PREV_XPOS
; a = PREV_YPOS
;
; h = XPOS
; l = YPOS
; ix= tilemap address
;OUPUTS:
; Complicated
; technically through pushing and poping all the registers
; are preserved the only expection being e
; e represent the prev_xpos and is incremented "c" times.
; IF e equals a tile that is not clear, then it will stop
; incrementing, set XPOS to e and Velocity X component to zero, and set the
; carry flag. the carry will be reset if e is increamented "c" times.
; Preservation:
; This routine need to called but it destoried the registers that it needs
; and registers other routines needs while running. To get around this problem
; all values are pushed before being used, poped and then updated(only e) after use
push bc
ld b,c
DoXslope:
push af
push bc
push de
push hl
push ix
call FindTile ;Finds a tile based on a=y and e=x ix=tilemap
;Destories All
call CheckClearTile ;if tile is clear, carry is reset, otherwise set
jr c,SkipIncX
pop ix ;If this part runs, then it represents that somewhere
pop hl ;between the previous xpos and the current one there
pop de ;is an object and this object is located at e in the
pop bc ;x direction.
pop af
rl b ;This checks to see if e needs to be inc or dec
jr c,DEC_E1 ;based on wheather b is positive or negitive
;respectively
rr b
inc e
jr SetXPOS
DEC_E1:
rr b
dec e
SetXPOS:
ld a,e ;Simply this code runs only if a collision has happened
ld (XPOS),a ;So the XPOS is set to e, which represents an x coordinate
;where the collision occured
xor a ;Since it hit something the velocity is set equal
ld (Velocity),a ;to zero
pop bc
scf ;carry is set sense we hit something
ret
SkipIncX:
pop ix
pop hl
pop de ;restores everything
pop bc
pop af
rl b
jr c,DEC_E ;modifies e based on b
rr b
inc e
inc b ;inc and jumps if b != 0
jr z,DoXslope
jr xSlopeDone ;if b = 0 then no collision occured
DEC_E:
rr b
dec e
djnz DoXslope
xSlopeDone:
pop bc
scf ;reset carry flag sense there was not a collision
ccf
ret
And here is the called routine yslope
Code:
yslope:
;Checks to see if there is an x collision on the x-slope
; if there is the carry flag is set otherwise reset
;INPUTS:
; SLOPE:
; b = y
; c = x
; e = PREV_XPOS
; a = PREV_YPOS
;
; h = XPOS
; l = YPOS
; ix= tilemap address
;OUPUTS:
; Complicated
; technically through pushing and poping all the registers
; are preserved the only expection being a
; a represent the prev_ypos and is incremented "b" times.
; IF a equals a tile that is not clear, then it will stop
; incrementing, set YPOS to a and Velocity Y component to zero, and set the
; carry flag. the carry will be reset if is increamented "b" times.
; Preservation:
; This routine need to called but it destoried the registers that it needs
; and registers other routines needs while running. To get around this problem
; all values are pushed before being used, poped and then updated (only a) after use
push bc
DoYslope:
push af
push bc
push de
push hl
push ix
call FindTile
call CheckClearTile ;if tile is clear, carry is reset, otherwise set
jr c,SkipIncY
;------------------------------------------------------------------------
;************************************************************************
;------------------------------------------------------------------------
pop ix ;If this part runs, then it represents that somewhere
pop hl ;between the previous ypos and the current one there
pop de ;is an object and this object is located at a in the
pop bc ;y direction.
pop af
rl b ;determines if a needs to be inc or dec
jr c,DEC_A1 ;by wheather b is positive or negitive respectivly
rr b
inc a
jr SetYPOS
DEC_A1:
rr b
dec a
SetYPOS:
push af ;a is saved so when the routine exits it will
ld (YPOS),a ;be the same. a is set up as the current ypos
xor a ;the y velocity is set to zero sense there was
ld (Velocity+1),a ;a collision in the y direction
pop af
pop bc
scf ;carry flag is set sense there was a collision
ret
;----------------------------------------------------------------------
;**********************************************************************
;----------------------------------------------------------------------
SkipIncY:
pop ix
pop hl
pop de ;restores the registers
pop bc
pop af
rl b ;checks to see if a should be inc or dec based on
jr c,DEC_A ;wheater b is positive or negitive respectively
rr b
inc a
inc b ;inc and jump if b is not zero
jr z,DoYslope
jr ySlopeDone
DEC_A:
rr b
dec a
djnz DoYslope
ySlopeDone:
pop bc
scf ;since no collision occured, reset carry flag
ccf
ret
I'm not sure exactly what the error is. I am open to suggestion or even complete a completely different algorithm, even an already written routine. Any help is appreciated.