Jump to content

Norman Sword

Member Since 08 Mar 2017
Offline Last Active Jan 14 2018 12:32 AM

#8511 Free space and code optimisation in "JSW"

Posted by Norman Sword on 14 January 2018 - 12:31 AM

The terminology that I used was "Mid Sprite bounce". Indicating a bounce in the mid part of its path. NOTE I keep on using Mid and not Middle.  


Mid has a multitude of definitions  Its preposition definition is      --- in the course of ---



You define a bounce point in the course of the sprite path.  

#8501 Free space and code optimisation in "JSW"

Posted by Norman Sword on 12 January 2018 - 07:55 PM

Yes an increment of IX.


The code must also copy the y position.....Which it can do when setting the arrows phase in room set up..

(different from what I have at present... So I will change my own code) 



If a pair of arrows are defined and they are facing each other and cross on the screen. Then one needs setting as even and the other odd. (x position)


Erroneous spelling noted. The assembler code is 540k of ASCII  text. It has become difficult to read and bits and pieces get missed.  

  • IRF likes this

#8496 Free space and code optimisation in "JSW"

Posted by Norman Sword on 12 January 2018 - 05:43 PM

The seven empty slots. Which because of the code that double up arrows, gives fourteen arrows in that room. Of note it only uses ONE guardian definition, the others are defined by the position. E.g. the code below is all it takes in the room set up.


But first a quick run down of my thoughts...


bit 0 gives the arrow bug

but just taking the first 16 values and removing that bug leaves values 00,02,04,06,08,10,12,14


we also have a feature/bug that stops the code working on the extremes of chars, so values of 00 or 14, should also be avoided.
leaving 02,04,06,08,10,12 = 6 values from the first 16.  or for the full screen playing area 16*6 values. 96 values from 256 in total.


I fail to see why this is used. If the arrow had been confined to a fixed position within the char. Then only four bits are needed to define an arrow.
The other four bits could be used for any multitude of applications.


At present an arrow is defined by a fixed guardian. If a JSW2 style volley is wanted then each arrow would need its own guardian slot/definition.


By juggling those four bits a shift can/could be introduced into the fixed timing phase of the arrow. (done at room set up)
This then permits one guardian to be defined as having up to 16 sub classes, just by allowing a phase change on just the one guardian definition.


patched into the room set up, after testing for an arrow type guardian. With no attempt at reducing the code size.


ld a,(iy+arrow_y)
ld b,a
and 15
add a,a
add a,a

add a,(iy+arrow_x)
ld (iy+arrow_x),a
ld a,b
and $f0
add a,8  ;middle of char
ld (iy+arrow_y),a

#8493 Free space and code optimisation in "JSW"

Posted by Norman Sword on 12 January 2018 - 05:01 PM

Re arrows:-


The arrows, my first play with them introduced a second arrow into the same guardian slot.


Mentioning wasted bits I decided to implement something I had thought about concerning the arrows.


This file shows what the wasted bits can do. Only demonstrated in the bathroom. 


This arrow demo, is tagged onto a file that keeps on being added to. (it needs deleting)



Attached Files

#8485 Free space and code optimisation in "JSW"

Posted by Norman Sword on 11 January 2018 - 11:22 AM

I amended the routine the handles depression into a block for ramps. It was not listed because it was another problem, separate from the ramp code.


Plus my version can not be used because it uses subroutines and the routine itself is another subroutine. I would have needed to rewrite it.

  • IRF likes this

#8482 Free space and code optimisation in "JSW"

Posted by Norman Sword on 10 January 2018 - 03:01 PM

;very little difference to the other version.
;but this has
;1) the addition of cell blocking to stop up and down movement via stairs into blocks
;2) changes in logic for jumping.
;3) removal of some data from the data table

; some of the data tables entries can be calculated by code. But the overhead of the code is bigger than the data table entry

;e.g  entry for (ix+ramp_final_adjust)= (ix+ramp_where_1)-(ix+ramp_step)

;set variables for these offsets
ramp_step                    equ 0*2
ramp_where_1             equ 1*2
ramp_where_2             equ 2*2
ramp_adjust                 equ 3*2
ramp_final_adjust        equ 4*2
ramp_animation_reset equ 5*2

;left data followed by right data
  DB -1,    1      ;0 STEP TO NEXT animation FRAME - replaces inc or dec
  DB $1f, $22   ;1 POSITION OF RAMP 1 - ramp walk up
  DB $41, $40  ;2 POSITION OF RAMP 2 - ramp walk down
  DB -1,     2     ;3 DIRECTION TO ADJUST HL - where to check vertically
  db $20, $21   ;4 FINAL ADJUST - final adjust of willy to his new moved to position
  DB 3,     0      ;5 ANIMATION RESET for next frame

; ;8FBC: Move Willy (3)
; Used by the routines at 8DD3 and 8ED4. This routine moves Willy
; left or right as necessary.
RAMP_LOGIC                     ;L8FBC
    LD A,(ROPE_STATUS)   ;L85D6;rope status indicator
    DEC A                             ;Is Willy on a rope?
    RET P                             ;Return if so (Willy's movement along a rope is handled at 935E)

    LD A,(L85D0)                 ;L85D0;Willy's direction and movement flags
    BIT 1,A                           ;Is Willy moving?
    RET Z                             ;Return if not
;not on a rope, but moving
    ld ix,left_data
    AND $01                        ;Is Willy facing left?
    JR nz,set_left                 ;go if so 1=LEFT, 0=RIGHT
    inc ix                              ;else move IX to right data
    ld c,a                              ;save direction facing
    LD  HL,(WILLY_ATT)    ;L85D3; Willy's attribute buffer coordinates
; is the animation still within the same ATT squares
    ld de,WILLY_ANM

    ld a,(de)                        ;(WILLY_ANM);L85D2 ;Willy's animation frame at 85D2  
    add a,(ix+ramp_step)    ;-1 OR +1 step to next animation
;if it was 0 then and now -1
;or if it was 3 then now 4    ; in both cases bit 2 is set
    BIT 2,A                          ;check limits
    JR NZ,RAMP_CHK         ;L8FDC ;move Willy's across a cell boundary
;if here still contained within the same animation (att) square, but different phase of animation
    LD (DE),A                     ;WILLY_ANM


; Willy now needs to move left or right and move into new attribyte squares
; this movement also needs to handle the stairs and check for their presence
; three final outcomes for bc
;                                            going up   bc=-32
;                                            going down    bc=+32
;                                            no ramp/blocked  bc=0
    push hl                             ;save for later

; all de increments are positive so preload D
    ld d,0
; if jumping ignore ramp checks
    LD  A,(AIRBORNE)                   ;L85D1
    OR A                                        ;Is Willy jumping?
    JR  NZ,null_offset                     ;Jump if so
;not jumping so check for stairs
    ld a,(RAMP_DIR)                     ;L80da ;either 0 or 1
; in the original JSW this value is 0 or 1 (my versions use other bits. so get rid the extra bits)
    and 1                                       ;get rid of the other bits
; this condition swaps on left and right movement
    cp c                                         ;set the condition for where to check
;assume going up ramp
    ld bc,-32
    ld e,(ix+ramp_where_1)
    jr nz,ramp_decided
; if here going down
    ld bc,+32
    ld e,(ix+ramp_where_2)
    add hl,de                                ; add offset to find ramp/stair square
    ld a,(RAMP)                           ;L80C4
    sub (hl)                                  ; is a ramp here ?
;if ramp not found then no offset needed
    jr nz,null_offset
;on a ramp is it going down?
    or b                                         ;the direction, taken from BC=+32/-32,  "A" must have been 0
    jr nz,found_                            ;branch if going up
;going down so locate the possible blocking tile
    LD A,L
    ADD A,(ix+ramp_step)             ;step across to possible wall
    LD L,A
;is the wall blocking descent
    ld a,(WALL)                            ;L80B2
    cp (hl)
    jr nz,found_
;a wall is blocking going down ramp- so remove ramp offset - and walk horizontally along  ramp/wall

; come here for no offset-or no ramp action
    ld b,d                                       ;
    ld c,d                                       ;bc=0, no ramp so no offset/shift
    pop hl                                      ;retrieve  WILLY_ATT

    add hl,bc                                 ; add the possible ramp displacement
    ld a,(WALL)
    LD B,A                                     ;
    ld e,(ix+ramp_adjust)              ;d is still 0
    ld a,l
   and 31
   add a,e                                    ; move across
;if negative (-1) then
    jp m,GO_ROOM_LEFT           ;L948A
; if 32, then also off screen
    bit 5,a
    jp nz,GO_ROOM_RIGHT         ;L949E
    ld a,l                                        ; restore full x position (which has part y position embeded)
    add a,e
    ld l,a                                        ;still on screen
    bit 1,h
    jr nz,ignore_this
; additional check if moving up a ramp; which checks out of line for willies head
;c can be -32 +32 or 0
    bit  7,c
    jr z,hor_or_dwn
;going up find the tile to check
    ld e,a
    sub (ix+ramp_step)                ; the direction we are moving
    ld l,a                                       ;hl adjusted to head tile
    ld a,b                                      ; the wall tile value
    cp (hl)                                     ;wall tile?
    ret z                                        ;return path is blocked
;adjust back
    ld l,e
; move vertically and check the squares
; after the initial add hl,bc and possible head check
; this checks downwards in a line


;change logic if jumping downward, willies head can pass through wall block
    call jump_fix                                ;z=moving down
    ld a,b
    jr z,ignore_this                            ;zero indicates logic change-- ignore this tile
    cp (hl)                              ;head  ;wall tile?
    ret z                                            ;return path is blocked
; resume checking vertically down
    ld e,$20                                      ;D is still 0
    ADD HL,DE                                 ;move hl down one row
;                                                      ;(y+0)  if Willy is on or about to up a ramp
;                                                      ;(y+1) if just walking or
;                                                      ;(y+2) if Willy is walking down a ramp
    CP (HL)                            ;foot    ;wall tile?
    RET Z                                         ;Return path is blocked
    LD A,(WILLY_Y)                         ;L85CF; y-coordinate (Y)
; bc held the ramp shift (b has been re-used but c is still the ramp shift)
    SRA C                                         ; halve the value from
                                                        ;c 32>16
                                                        ;c  0>0
                                                        ;c-32>-16  to get ramp y-shift
    ADD A,C                                      ; y-position + ramp y shift
    LD C,A                                         ; save in C
; this addition is changing logic depending on movement (jumping)
call jump_fix                                     ;z=moving down
; if jumping downward  this square MUST be checked
    jr z,force_this
; otherwise check if willy occupies 3 squares
    ld a,c
    AND $0F   ;
    JR Z,ONLY_TWO                         ;Jump if not
    LD A,b                                          ;ATT wall tile
    ADD HL,DE                                  ;point hil at the cell one lower
; Addendum for the bottom of the screen... Jumping downward and cell aligned can process of the screen
; it is easier to capture/stop problems before they happen
    BIT 1,H
    JR NZ,offscreen
;                                                       ;(y+1)  if Willy is on or about to up a ramp
;                                                       ;(y+2) if just walking or
;                                                       ;(y+3) if Willy is walking down a ramp
    CP (HL)                        ;beneath ;Is there a wall tile down there?

    RET Z                                          ;return path is blocked
   OR A   ;
   SBC HL,DE                                     ; move back to feet position

;if here then Willy has been allowed to move up or down a ramp- walked along or jumped into a new attribute square.
; so save all the new parameters 
    OR A
    ld e,(ix+ramp_final_adjust)
    SBC  HL,DE                                  ; back to final head position (free to move here)
    LD  (WILLY_ATT),HL                    ;L85D3;Save Willy's new attribute buffer coordinates

    LD A,(IX+ramp_animation_reset)  ; the animation frame
    LD  (WILLY_ANM),A                      ;L85D2

    LD  A,C                                         ;Willy's new pixel y-coordinate
    LD  (WILLY_Y),A ;L85CF

    ld a,(JUMP)                                   ;L85d5
    sub 12
    ret c
    ld a,(AIRBORNE)
    dec a

#8478 Free space and code optimisation in "JSW"

Posted by Norman Sword on 10 January 2018 - 11:07 AM

Nice piece of code.


My only editing of the original code was to stop the type of guardian being changed whenever the original horizontal code was called. This was because my homing sprite called the horizontal movement whenever it wanted to move horizontally. The original code changed the guardian type.


It is noted that the guardian type in your code is not modified.




For clarity on your code it would benefit from a few additions regarding the usage of bit 7 (direction). This bit is being toggled in several places, with no mention as to why.  e.g.


          XOR #80        ;restore direction (bit 7)  which was inverted


         XOR #E0         ; invert direction (bit 7) and invert animation bits (6 and 5)


and finally for clarity , an explanation of what the carry bit is being used for.


; the direction bit (bit 7 = #80) must be taken into account
;animation right adding #20      #80, #a0, #c0, #e0    carry clear with each addition but not  #eo+#20  = #00
;                left   adding #e0       #60, #40, #20, #00   carry set with each addition but not      #00+#eo  = #eo



#8455 Undocumented Quirky Features of JSW2

Posted by Norman Sword on 07 January 2018 - 02:53 PM

This is also probably the bug the lets Willy move into the floor/wall tile when jumping right into the wall gap (next to the priest) in the "First Landing" . Again the check for beneath his feet incorrectly checks the tiles beneath his feet and not the tiles his feet are about to land on.

Like so many other parts of the code, other checks can/could prevent this.

#8454 Undocumented Quirky Features of JSW2

Posted by Norman Sword on 07 January 2018 - 02:42 PM

What Logic dictates and what actually happens.



The black squares represent wall tiles

Left block diagram: part 1: willy occupies the red squares and is trying to move upward and left. All checks to the left indicate that the two blues squares are free but the lower square contains a wall (black square). movement left is blocked. Movement vertically is free. So willy moves upward.



Middle block diagram: Part 2: willy at this point is cell aligned and still moving upward and left. The orange squares are checked and found to be free. Willy is moved left and upward into the squares.


The arc of his flight moves onward till we arrive at picture 3

Right block diagram: Part 3: willy is cell aligned and wants to move left and downward. The question here is are the cells/squares in green free to move into. The answer being yes. Willy should be moved across the cell boundary into the green squares.


But in part 3 JSW has a specific check, that affects the outcome:-
Willy is falling and the code (listed) below checks for what is beneath his feet. Even though at this point willy will not actually enter both of the squares that are checked below his feet. Willy is moving diagonally downward, and he moves both vertically and horizontally across cell boundaries. The check below does not move horizontally across the cell boundary and checks directly beneath Willies feet. (this is a bug)


*** Note the problem is due to incorrect horizontal cell checking.


This incorrect cell check, stops the jump and Willy lands on the wall.


The complete Jet Set Willy RAM disassembly 20171113
© 1984 Software Projects Ltd. © 2017 Richard Dymond.
Created using SkoolKit 6.1.
If we get here, then Willy is standing on the floor or a ramp, or he's falling, or his jumping animation counter is 13 (at which point Willy is on his way down and is exactly two cell-heights above where he started the jump) or 16 (at which point Willy is on his way down and is exactly one cell-height above where he started the jump).

8E36 LD A,($85CF)      Pick up Willy's pixel y-coordinate from 85CF

8E39 AND $0E              Is Willy either on a ramp, or occupying only four cells?
8E3B JR NZ,$8E62       Jump if not
8E3D LD HL,($85D3)    Pick up Willy's attribute buffer coordinates from 85D3
8E40 LD DE,$0040       Point HL at the left-hand cell below Willy's sprite
8E44 BIT 1,H                Is this location below the floor of the current room?
8E46 JP NZ,$94D2       If so, move Willy into the room below
8E49 LD A,($80BB)      Pick up the attribute byte of the nasty tile for the current room from 80BB
8E4C CP (HL)               Does the left-hand cell below Willy's sprite contain a nasty?
8E4D JR Z,$8E62         Jump if so
8E4F INC HL                 Point HL at the right-hand cell below Willy's sprite
8E50 LD A,($80BB)      Pick up the attribute byte of the nasty tile for the current room from 80BB (again, redundantly)
8E53 CP (HL)               Does the right-hand cell below Willy's sprite contain a nasty?
8E54 JR Z,$8E62         Jump if so
8E56 LD A,($80A0)      Pick up the attribute byte of the background tile for the current room from 80A0

8E59 CP (HL)               Set the zero flag if the right-hand cell below Willy's sprite is empty

8E5A DEC HL               Point HL at the left-hand cell below Willy's sprite

8E5B JP NZ,$8ED4      >> Jump if the right-hand cell below Willy's sprite is not empty
8E5E CP (HL)               Is the left-hand cell below Willy's sprite empty?
8E5F JP NZ,$8ED4      >> Jump if not
8E62 LD A,($85D1)     Pick up the airborne status indicator from 85D1
8E65 CP $01               Is Willy jumping?
8E67 JP Z,$8FBC        Jump if so

The above logic flaw is why he lands on a wall, that his parabolic arc should have permitted him to cross.

Note also that this flaw extends into the checks for nasties (which kill). And results in Willies inability to jump nasties at head height.



. 2nd diagram might improve clarity. (willy outline is not indicative of animation frame)

Attached Thumbnails

  • willy tiles1.jpg
  • block3.jpg

#8433 Free space and code optimisation in "JSW"

Posted by Norman Sword on 04 January 2018 - 07:45 PM

The room jump routines -- about 40 bytes shorter


ROOM_L                EQU $80E9
ROOM_R               EQU $80EA
ROOM_U               EQU $80EB
ROOM_D               EQU $80EC

WILLY_Y                EQU $85CF
AIRBORNE             EQU $85D1
;ANIMATION           EQU $85D2
WILLY_ATT           EQU $85D3
WILLY_ATT_H       EQU $85D4
NEW_ROOM          EQU $8912

GO_ROOM_LEFT:              ;L948A
    LD BC,$FE1E        ;;; OR    LD BC $E01E



    LD A,(HL)   

    LD A,(HL)
    AND B
    OR C
    LD (HL),A                        ;L85D3 
    POP HL   ;
    JP NEW_ROOM              ;L8912


GO_ROOM_RIGHT:           ;L949E
    LD BC,$E000


GO_ROOM_UP:                 ;L94B0

    LD BC,$1FA0

    LD DE,$D05D

    XOR A

    LD A,E
    LD A,D
    LD (WILLY_Y),A


GO_ROOM_DOWN           ;L94D2
    LD BC,$1F00


    LD DE,$005C  


    CP $0B

    LD A,$02



Slight edit to set up variables in a more consistent manner.

#8379 Remake of Manic Miner- Both bug byte and S.P. versions

Posted by Norman Sword on 30 December 2017 - 11:43 PM

The visual differences between the  bug byte version and Software projects version in room data


The changed data consists of around 240 bytes changed. in 12 separate groups. Ranging from a single byte to a group of 127.


Some of the data that changes may or may not be visual. But the program stores the around 480 bytes and swaps the 240 over on each playing.


This is on top of the 2*256 bytes for the scrolling message. So Nearly 1k stored for the changes.


The room data was left intact, and in the same format. I did consider adding a few more versions and the compressing the lot. 

Attached Thumbnails


#8361 Remake of Manic Miner- Both bug byte and S.P. versions

Posted by Norman Sword on 28 December 2017 - 08:48 PM

Posted elsewhere on this forum, just moving into the download category as well.

This version of Manic Miner contains both the Software projects version of the game alongside the Bug byte version.


Each time the game is played it will swap versions.


I have edited and revised a lot of the routines. The game should play the same way as the original game. A lot of the changes would need you to be aware of the originals exact format to enable comparisons.


Cheat is enabled (bug-byte password)


differences that I can remember


1) demo cycle stops and redisplayed the title screen and replays the title music

2) added a credits screen

3) added explosions on credit screen

4) added intermission screen

5) change scroll to pixel scroll and not character scroll

6) will moves with a sprite mask

7) explosion on death

8) willies death stump scrolls onto the screen

9) score scrolls to high score

10) reason given for demise

11) sound effects on solar ray

12) collection sound

13)  cheat modes rebuild platforms

14) cheat mode immunity

15) cheat mode move by a single key, and not multi combinations of keys

16) cheat mode plays with all sprites active

17) game swaps between two versions- Bug Byte and software Projects

18) other sound effects

19) less sprite flicker

20) game runs faster

21) multiple icon displays

22) bar graph on title screen

23) Animated version icon on title screen

24) keyboard layout on title screen fixed

24a) title screen. missing pixel on car replaced

25) new screen scrolls

26) easter egg on Credit screen

27) easter egg on Pause

28) skylab landing sound effect

29) skylab does not colour in platforms




standard movement keys e.g. "q" to "p" for left to right

"z" to "m" jump"

"a" to "g" pause

"h to "enter" music on/off


The "1" key changes the method of movement.



In cheat mode. the boot will still be displayed

various icons are active and indicate options selected

The "9" key rebuilds platforms

the "3" key activates platform rebuild option (tool kit)

the "4" key activates immortality (medical kit)

The "9" key held plus Tapping "1" will move to a previous screen. If on room 1 then it will go to room 20 

The "9" key held plus tapping "2" will move to the next screen. If on room 20 then it will go to room 1


Bug byte cheat is 6031769



Icons displayed are from right to left



Alternate movement

Music on

Cheat invoked

medical kit

tool kit

Attached Thumbnails

  • post-125-0-49909500-1504709479.png
  • full icons.png
  • credit 2.png

Attached Files

#8349 Fixing the 'Ramps vs Walls' Bug

Posted by Norman Sword on 24 December 2017 - 05:56 PM

Just a note on the file I posted:


What is happening?

In the original JSW, the code for jumping and moving up and down ramps, are set in one overall routine that detects wall blocks and stops movement.

Within the code of the original, was two sets of movement code that treated the movement going left and the movement going right differently.


Moving left.

The code for moving left omitted a check for head height blocks. This permits willies head to pass through blocks moving left. This also permits willies head to pass through blocks at head height when jumping. Another routine at #8df7 detects the passage through the block at head height and immediately pushes willy downward to cell align him into/onto the block below. In most cases this works well if willy is going upwards on a jump. If willy is going downwards on a jumping arc, then the code at #8df7 will appear to move willy suddenly downward. This is the characteristic jerk as willy hits a wall and slides down it into a gap.

Moving right

This code blocks the movement of willies head through a wall tile. The result is that willy can not jump into slots cut out of walls in the same manner. Because willies body and head do not enter in a wall tile, willy will slide down walls at a normal speed, until his feet land on something. 



The slight difference in the movement is why the game has cut outs in vertical walls only in left jumped to walls. The same style cut out that exist in right cut out walls normally have a platform below the cut out, on which willy can land. It also is the reason for the jerk jumping left in certain circumstances that are not replicated going right.



Various fixs can be applied and each fix might cure one or other problem.

1) stop willies head passing through a block.
This fix will stop the jumps into cut outs.


2) allow willies head to pass through a block going right.
This fix will enable jumps left and right into cut outs. But willy will pass through so many blocks it just looks wrong.


3) rewrite the lot.
This introduces so many new variables, that anything can happen. My thoughts on that are GOOD LUCK.


The demo program posted above changes its set of rules depending on what is happening.
1) If willy is walking up or down a ramp then it will check for willies head/body/above head(going up)/below head (going down).
When jumping the rules are changed. When jumping upward it checks above his head, his head and also his body. If not cell aligned it will check the third cell (lower body/under foot)
2) When jumping downward  it ignores the head check and checks for his body and if free to move also checks the cell below his body (under foot). This double check for body and lower body/under foot is needed to ensure that willy is actually passing into a gap in which he can fit. (two cells high)
If the two cells are free then the code permits willies head to pass through a wall block. The code at #8df7 will detect the passage through a wall block and immediately pull willy downwards into the gap. This is what happens in the original game. The only difference in this demo is that it now happens going left or right, but willies head is blocked from passing into wall blocks when walking, walking on ramps, or even jumping upward.


Any modification will invariably introduce new problems. Simply because the original game appears to have been constructed around the non symmetry of code. Some of these problems are very easy to fix others are waiting to come to light.



Most of the labels I have in this area have been moved/change/deleted . I have had to use an unchanged version, to find the address I am referencing. 


Over head wall check, that push's willy downward , as written by 


The complete Jet Set Willy RAM disassembly 2017 11 13
© 1984 Software Projects Ltd. © 2017 Richard Dymond.
Created using SkoolKit 6.1.



Adjust Willy's attribute buffer location at 85D3 depending on his pixel y-coordinate
8DF7 LD A,($80B2)      Pick up the attribute byte of the wall tile for the current room from 80B2
8DFA CP (HL)               Is the top-left cell of Willy's sprite overlapping a wall tile?
8DFB JP Z,$8EBC        Jump if so
8DFE INC HL                Point HL at the top-right cell occupied by Willy's sprite
8DFF CP (HL)              Is the top-right cell of Willy's sprite overlapping a wall tile?
8E00 JP Z,$8EBC        Jump if so


The code at $8ebc will adjust his position


The top-left or top-right cell of Willy's sprite is overlapping a wall tile.
8EBC LD A,($85CF)     Adjust Willy's pixel y-coordinate at 85CF so that the top row of cells of his sprite is just below the wall tile
8EBF ADD A,$10
8EC1 AND $F0
8EC3 LD ($85CF),A
8EC6 CALL $8E9C      Adjust Willy's attribute buffer location at 85D3 to account for this new pixel y-coordinate
8EC9 LD A,$02           Set the airborne status indicator at 85D1 to 0x02: Willy has started falling
8ECB LD ($85D1),A
8ECE LD HL,$85D0    Reset bit 1 at 85D0: Willy is not moving left or right
8ED1 RES 1,(HL)

#8332 Fixing the 'Ramps vs Walls' Bug

Posted by Norman Sword on 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

#8297 Free space and code optimisation in "JSW"

Posted by Norman Sword on 17 December 2017 - 02:50 PM

A viewpoint (which might change) based on code written today.




The previous code and several other bits that modify the path that willy can take still have problems. I wrote a routine that shows in real time what tiles are being checked by this program. (allowing frame by frame analysis). What this routine showed was, that the checking has flaws in its design.


The original routine was not symmetrical, and it was the non symmetry that allowed for jumping into gaps in walls. (In jsw all the gaps are accessed by jumping left) If symmetry is introduced then those gap jumps become impossible. But the other problems become more noticeable.


Passing through a wall


In the code that checks for ramps and also checks for blocking the move left and right, was a check for reducing the three cell check to only two, when willy was cell aligned. The primary reason was when willy walks along a platform, the third cell was below his feet. Since he was walking along the top of the cells, they could not block his path. Hence the third cell check is removed for that reason. (otherwise willy can not walk along a wall)


However when willy is jumping the third cell is crucial for deciding if willy can move.







In the text diagram above willy occupies the four squares with "0" in them, in this case willy is jumping right and is on his way down. The two squares with "a" and "b" are clear. Since willy in this thought experiment  is now cell aligned. The present routine has decided that "e" can be ignored. This then permits willy to move diagonally downward to the right to now occupy the cell "e".  This is why the jump right on the "FIRST LANDING" passes through a square and lands inside the floor when jumping the gap on the lower floor.


If I add a check for falling into the routine that checks for wall blocking when moving. The purpose of which is solely to force the third cell check when falling. Then this particular problem disappears.


However it still permits passing though a wall block in "on top of the house" when walking down a stair (because those blocks are NOT checked by the stair check routine)




The third cell check stops one problem. But Symmetry causes a problem when jumping into gaps.


Again looking at the text diagram, the cell "g" was not tested moving  left, and that permitted walking through cells at head height. The cell "a" was tested when walking right. It is the lack of cell testing that permits jumping into wall gaps, when jumping left.  The symmetrical code I posted will not permit jumping into two cell wide gaps in specific conditions because of the extra check.


The jump left in "ball room east" into the gap above the red barrel can no longer be done.  The reason is because the checking now stop movement into wall tiles. The gap was only two cells wide only when cell aligned. This does not happen when jumping from a horizontal position (which is level with the gap), because the forward motion has ceased at the exact point that the cells are aligned.


From my viewpoint the non symmetry was deliberate, and in looking at the way the code is written, it is possible the change in logic from left and right was a quirk that was exploited


I however prefer these anomalies to be written out of the code. Whatever it does one way should be the same the other way.


Back to the cell checking.. Introducing a specific check for jumping (downward) to force a third square check, stops the movement into wall cells on jumping downward. It also appears that stopping the check for willies head when jumping and moving downward either left or right. Re-enables the passage into gaps. Removing the check for willies head (cell "g" or cell "a") but forcing the check for the third tile, means that willy can move into a two cell wide gap. In practical terms this is similar to permitting passage through the corner of a wall cell on his way down, only if the two cells below are not occupied by a wall. This Matthew style FIX permits a one frame movement into the gap. 


I have not had a good look at the code to implement these changes, in a manner that I am happy with. I have however added two additional pieces of code to implement these changes, which seem to do as I want. Which is symmetry in movement.


1) checking head height cell and blocking willy from moving through them ... *NOTE 1 

2) ability to still jump into gaps

3) stop passage into wall cells


*Note 1 The upper Platform in "the Forgotten Abbey" if left as a wall will block Willy walking of the conveyor underneath it.