Jump to content


Photo

Fixing the 'Ramps vs Walls' Bug


  • Please log in to reply
13 replies to this topic

#1 IRF

IRF

    Advanced Member

  • Contributor
  • 3,744 posts

Posted 22 December 2017 - 02:49 PM

http://skoolkid.gith...ml#rampsVsWalls

Some preliminary thoughts:

When Willy is walking up a ramp, add an additional check for an Earth block (and RET if one is encountered):

- When Willy is walking left, the check should be made at (x,y-1);
- When Willy is walking right, the check should be made at (x+1,y-1);

where (x,y) are the coordinates of the top-left cell occupied by Willy's sprite prior to him crossing the cell boundary.

****

When Willy is walking down a ramp, the simple solution would be to block his progress is there is an Earth block ahead of his sprite and two cell-rows below. But that doesn't seem logical. In the example seen in 'On Top of the House', I feel the most realistic solution would be for Willy to simply step onto the block at the base of the ramp. But that would require amendments to two different routines:

(1) Edit the routine at #95C8 - after the check for a ramp cell under Willy's back foot, add an additional check for an Earth block under Willy's front foot (perform an XOR 01 on the L register, load the Earth attribute to A, and then do a CP (HL) / JP Z,#95F8 - all to be inserted in between the commands at #95DC and #95DE). So if Willy is standing on a ramp cell and an Earth block simultaneously, then the 'solidity' of the Earth block will take precedence over the 'downward pull' of the ramp cell* when deciding where to draw Willy;

(2) Adjust the 'Move Willy (3)' routine so that, when Willy is about to step off a ramp cell at (x+1,y+2) / (x,y+2) [when walking left / right respectively i.e. a ramp cell in the cell underneath Willy's back foot], then make a check for an Earth block at (x,y+2) / (x+1,y+2) [i.e. in the cell underneath Willy's [i]front[/i] foot], and if there is an Earth block there, then undo the commands which adjust Willy's coordinates downwards by a row as he moves past the cell boundary. Edit: i.e. at #900A and #9078, insert the extra check, and if there is an Earth block under Willy's front foot, then set BC=00 (although C=0 should be sufficient).

****

* N.B. This shouldn't affect the ability for Willy to walk down a ramp cell through Water cells, such as occurs in 'Swimming Pool' or 'West Wing'.

Edited by IRF, 22 December 2017 - 07:17 PM.


#2 IRF

IRF

    Advanced Member

  • Contributor
  • 3,744 posts

Posted 22 December 2017 - 03:07 PM

perform an XOR 01 on the L register


Sorry, that will probably only work if Willy's attribute coordinates (WATTR) hold an even value. If they hold an odd value, then the check for Earth blocks may be misplaced to a cell beyond where Willy is standing. I'll have to rethink the logic.

EDIT: In specific terms, if the ramp slopes up to the left, then it will be detected at WATTR+#40 ; in that circumstance, the test for an Earth block needs to be at WATTR+#41.
But if the ramp slopes up to the right, then it will be detected at WATTR=#41 ; the test for an Earth block then needs to be at WATTR+#40.
Ideally, we would have a generic set of operations that will work for both ramp directions.

#3 IRF

IRF

    Advanced Member

  • Contributor
  • 3,744 posts

Posted 22 December 2017 - 03:26 PM

Ramp up to the left: Offset #DA = 0 .... Test for Earth at Underfoot Ramp coordinate +1
Ramp up to the right: Offset #DA = 1 .... Test for Earth at Underfoot Ramp coordinate -1

So we need to map 0 to 1, and 1 to -1.

LD A,(#80DA)

RLCA
00 -> 00 01 -> 02

CPL
00 -> FF=-01 02 -> FD=-03

ADD A, #02
-01 -> 01 -03 -> -01

LD E,A

There may be a more efficient, clever trick that utilises the Carry Flag?

EDIT: Maybe need to adjust D as well? 0->0, 1->-1

LD A,(#80DA)

NEG

LD D,A

Then ADD HL,DE

FURTHER EDIT: It's actually more efficient just to do:

LD A, (#80DA)
AND #01
LD C,A - insert into original code after #95D0

....

 

OR A

SBC HL,DE
LD A,C
XOR #01
ADD A, #40
LD E,A
[D already holds 00]
ADD HL,DE

LD A,(Earth)

CP(HL)

JR Z, #95F8  [original JSW address, probably now changed]


Edited by IRF, 10 January 2018 - 11:54 PM.


#4 IRF

IRF

    Advanced Member

  • Contributor
  • 3,744 posts

Posted 22 December 2017 - 03:35 PM

This shouldn't affect the ability for Willy to walk down a ramp cell through Water cells, such as occurs in 'Swimming Pool' or 'West Wing'.


Sorry, the latter example should have read 'West Wing Roof'!

#5 IRF

IRF

    Advanced Member

  • Contributor
  • 3,744 posts

Posted 22 December 2017 - 11:38 PM

Another couple of thoughts: the check for an overhead Earth block should also test whether Willy is in the top two rows before carrying out a test for a blocking Earth cell above him. Also, the test for an underfoot Earth block ahead of Willy should be done after the edge-of-room test (otherwise Earth blocks that are horizontally at the opposite end of the current room could have an inappropriate influence on his progression). EDIT: Actually, thinking about it, that latter point isn't important - when Willy walks off the edge of a room, the vertical displacement isn't applied anyway, even if he is on a ramp (hence the ramps in adjacent rooms don't line up when you view a master plan of the whole house e.g. see Orangery/West Wing Roof).

The two additional checks for Earth/wall cells have different outcomes anyway (in the former case, Willy's diagonal movement is blocked; in the latter case, his diagonal movement is converted into sideways movement).

****

Anyway, I'll try and put all of this into practice when I get a chance; ideally I will be able to build upon Norman Sword's work in making a generic 'sideways movement' routine, covering both left and right movements simultaneously. :)


Edited by IRF, 23 December 2017 - 11:44 PM.


#6 IRF

IRF

    Advanced Member

  • Contributor
  • 3,744 posts

Posted 23 December 2017 - 09:43 AM

ld a,(RAMP)
sub (HL)
jr z,found_ ;if ramp is here keep bc=shift
;ramp not found so no offset needed
as_is:
ld b,d
ld c,d ;bc=0 no ramp so no offset/shift
found_:

 

Slight rewrite to detect 'On Top of the House'-type Earth/wall block:

 

UPDATE: Edited to update the D register when Willy is moving left and about to step onto a wall tile (so that the ADD HL,DE instruction points HL at the correct room cell):

 

ld a,(RAMP)
cp (HL)
jr nz,as_is ;if ramp is here keep bc=shift

LD A,C
CP #20
JR NZ found_ ;Willy is going up the ramp, so no need to check if he's about to step onto a wall

LD A, (ix+ramp_condition) ;reuse existing variable...

DEC A                                   ;decrement...

LD D,A                                  ;and load into D, to give correct values for both left and right movement

LD E,(ix+ramp_animation) ;reuse existing variable, which happens to hold the correct values for both left and right movement

ADD HL,DE
LD A, (wall)
CP (HL)
JR NZ, found_ ;no wall under Willy's front foot, so he proceeds down the ramp as normal


;ramp not found, or it was but an adjacent wall block 'over-ruled' it, so no offset needed
as_is:
LD BC, #0000 ;bc=0 no ramp so no offset/shift
found_:


Edited by IRF, 24 December 2017 - 12:37 AM.


#7 IRF

IRF

    Advanced Member

  • Contributor
  • 3,744 posts

Posted 23 December 2017 - 10:11 AM

; the initial adjust is for ramps. e.g. up/down or level
ADD HL,BC ;Point HL at the cell at
; ;(y-1) Willy is on or about to go up a ramp
; ;(y+0) just walking
; ;(y+1) Willy is walking down a ramp
ld a,(WALL)
;in theory this position could be off the top of the screen
bit 1,h
jr nz,ignore_head_check
cp (hl) ;head
ret z ;return if path is blocked
ignore_head_check:

 

Slight rewrite to detect overhead blocking wall cell:

 

ADD HL,BC
ld a,(WALL)
;in theory this position could be off the top of the screen
bit 1,h
jr nz,ignore_head_check

 

;the next wall test only occurs if Willy is walking up a ramp (i.e. if B is -01)
INC B

JR NZ, ignore_other_head_check   ; the Zero Flag will be set only if Willy is walking up a ramp

 

LD B,A ; save wall attribute in B

 

;Adjust HL to find overhead wall
LD A,L
SUB A,(IX+ramp_animation) ;this variable can be reused
LD L,A

LD A,B
CP(HL)
RET Z

;Adjust HL back again
LD A,L
ADD A,(IX+ramp_animation) ;and reused again
LD L,A

 

LD A,B

 

ignore_other_head_check:

cp (hl) ;head  ;this is the original head-height wall check

ret z ;return if path is blocked

ignore_head_check:

 

******

 

UPDATE: Here is an alternative, slightly more efficient rewrite of this part of the routine:

 

ADD HL,BC
ld a,(WALL)
;in theory this position could be off the top of the screen
bit 1,h
jr nz,ignore_head_check

 

;the next wall test only occurs if Willy is walking up a ramp (i.e. if B is -01)
INC B

JR NZ, ignore_other_head_check   ; the Zero Flag will be set only if Willy is walking UP a ramp

 

LD B,L ;retain old coordinates in HL

 

;Adjust HL to find overhead wall
LD A,L
SUB A,(IX+ramp_animation) ;this variable can be reused
LD L,A

LD A,(WALL)
CP(HL)
RET Z

;Adjust HL back again
LD L,B

 

ignore_other_head_check:

cp (hl) ;head  ;this is the original head-height wall check

ret z ;return if path is blocked

ignore_head_check:


Edited by IRF, 24 December 2017 - 12:36 AM.


#8 IRF

IRF

    Advanced Member

  • Contributor
  • 3,744 posts

Posted 23 December 2017 - 10:15 AM

I think I've covered all the constituent parts now; I just need to cobble it all together into a test file and see if it works! However, that will have to wait till after Christmas (and probably into the New Year).

Edited by IRF, 23 December 2017 - 10:15 AM.


#9 Norman Sword

Norman Sword

    Advanced Member

  • Member
  • PipPipPip
  • 125 posts

Posted 23 December 2017 - 06:17 PM

Meanwhile :- something I wrote last week. ------ Which is an extension of my test files Not meant to be complete or working game.

 

 

Just a test extension of matt's logic. Which also had tile blocking incorporated. 

 

 

 

The very jerky jumps, means the jumps happen a lot quicker than the nice smooth arcs of what the jumps should have been.

 

 

 

 

Since the source code for this contains so many obsolete routines. It will probably be soon deleted/purged.

 

Attached Files



#10 IRF

IRF

    Advanced Member

  • Contributor
  • 3,744 posts

Posted 23 December 2017 - 07:00 PM

Thanks for the Christmas present, Norman Sword!


Edited by IRF, 23 December 2017 - 11:34 PM.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users