Resource centre for ZX Spectrum games
      using Manic Miner and Jet Set Willy game engines

 

Archive of the

Manic Miner & Jet Set Willy Yahoo! Group

messages

 

 

 

Message: 5485

Author: andrewbroad

Date: 11/02/2006

Subject: Re: Andrew's ideas for implementing lifts in JSW

 

john_elliott_uk wrote:

>
>> I'm also attacking the problem from the other direction - by
>> reverse-engineering the JSW64:MM variant known as "m.z80", which
>> contains a thing like a lift
> [...]
>> This code corresponds, to a large extent, with the "Experimental
>> lift support" in dmm64.zsm of JSW64:Dragon.
>
> I'd have thought the code in dmm64.zsm would have been more useful,
> being commented and all.

I understand it much better now that I have annotated it myself,
using the following sources to understand it:
* the annotated code in dmm64.zsm;
* my annotated printout of your annotated disassembly of JSW48;
* applying SPECSAISIE Disassemble to m.z80 (especially where JSW64
differs from JSW48, i.e. interpreting guardian-types at 91C2);
* the table of op-codes to mnemonics in Part 27 of the ZX Spectrum +2
manual (because the code is self-modifying!);
* Arsen Torbarina's JSW Tech Page (for the guardian-class format).

And so, my annotated disassembly of the lift-code in m.z80:

9945: jp 93B3 _____; next guardian (draw it)
;
;
; * liftmove *
;
9948: call 9193 ___; do vertical movement with no animation
994B: jp 91B6 _____; next guardian (move it)
;
;
; * liftdraw *
;
994E: call 9974 ___; draw guardian
9951: jr z,996C ___; no collision = not on lift
9953: ld a,(85CF) _; get Willy's Y-coordinate
9956: ld c,(ix+3) _; get lift's Y-coordinate
9959: cp c
995A: jr nc,996C __; if Willy is below top of the lift then JR 996C

995C: ld a,(ix+3) _; get lift's Y-coordinate (in pixels*2)
995F: sub 1E ______; subtract 30 (i.e. 15 pixels above)
9961: ld (85CF),a _; set Willy's Y-coordinate to that
9964: ld hl,6818 __; 18 = op-code for JR
9967: ld (8E6A),hl ; self-modify 8E6A: JR +68 (i.e. JR 8ED4: walking)
996A: jr 9945 _____; next guardian

996C: ld hl,D021 __; 21 = op-code for LD HL,nn
996F: ld (8E6A),hl ; self-modify 8E6A: revert to LD HL,85D0
9972: jr 9945 _____; next guardian
;
;
; * draw guardian & detect collision *
;
9974: ld a,C9 _____;
9976: ld (922E),a _; self-modify 922E: RET (replaces CALL 9456)
9979: call 91D6 ___; call the code that draws VGs and detects collis.
997C: push de
997D: push hl
997E: call 9456 ___; actually draw lift - returns NZ if collision
9981: pop hl
9982: pop de
9983: jr z,998B ___; if no collision then JR 998B
9985: ld c,0 ______; disable collision-detection
9987: call 9456 ___; redraw lift (i.e. draw whole sprite this time!)
998A: inc a _______; useless instruction
998B: ld a,CD _____; CD = op-code for CALL nn
998D: ld (922E),a _; self-modify 922E: CALL 9456
9990: ret

The problem with this code is that it relies on guardian collision-
detection (which is pixel-based) to detect that Willy is standing on
the lift, which has the following drawbacks:
1. if Willy stands on the right edge of the lift and turns left, he
falls through because there's no pixel-collision;
2. Willy keeps falling down as the lift goes down.

I don't think guardian collision-detection should come into it at
all. Detecting that Willy is on the lift should be purely position-
based (I see code for this in dmm64.zsm but not m.z80). Back to the
drawing-board I go...

--
Dr. Andrew Broad
http://geocities.com/andrewbroad/
http://geocities.com/andrewbroad/spectrum/
http://geocities.com/andrewbroad/spectrum/willy/

 

 

arrowleft
arrowright