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
|
|
||
|
|
||
| Previous in thread |
|
Message: 6556
Author: andrewbroad
Date: 10/07/2009
Subject: Re: Harmless guardians / Patch to kill guardians
I have just cited Message 5816 in a post about Willy being able to kill guardians at
http://www.worldofspectrum.org/forums/showthread.php?t=24988
My idea is to replace the code that kills Willy when a guardian collides with him with some code to remove that guardian-instance from the current-room buffer (to make it disappear instantly), and from the primary room-record (to make it disappear permanently).
I don't fancy writing a MM/JSW game in which the player can kill guardians, because it kind of ruins the point of designing intricate, challenging MM/JSW rooms. But it would be cool to see it just as a variant of the original Jet Set Willy.
What would also be cool would be to see a Spectrum-conversion (or even a PC-remake) of _Horace in the Mystic Woods_ <http://www.worldofspectrum.org/forums/showthread.php?t=24818>: having just watched a video of the game on YouTube, it looks very Manic-Minerish, but you build up speed as you run (à la Super Mario Bros), and the faster you're running, the higher you can jump.
I wish I could write more about my MM/JSW plans now that Wimbledon is over, but I'm not sure what to do next on the MM/JSW front. I might start work on H***** or start/resume another MM/JSW-editing project (as per the previews on my website), or perhaps this is a year to finally make serious inroads in my backlog of playing the MM/JSW games that were released since 2000. :o
--
Dr. Andrew Broad
http://tinyurl.com/andrewbroad-mmjsw
[Message 5816]
I wrote:
--------------------------------------
Method A: The quick and dirty solution
--------------------------------------The nastiest way to have harmless guardians in Jet Set Willy is...
POKE 37050,58 (Hex 90BA: 3A)
...which modifies the following code...
#90B8: LD A,#FF
#90BA: LD (#85D1),A ; set 'airborne' status to 'dead' (#FF)...as follows:
#90BA: LD A,(#85D1) ; get 'airborne' status
Guardians still collide (and are only drawn down to the point of
collision), Fire-cells don't kill you, and if you fall too far, you
just disappear and have to reset the game.-------------------------------------------
Method B: Modify the sprite-drawing routine
-------------------------------------------The following two POKEs, which must be used together, ...
POKE 37982,0 (Hex 945E: 00)
POKE 37994,0 (Hex 946A: 00)...modify the sprite-drawing subroutine at #9456 to ignore
collisions. This subroutine has the following preconditions...* C == 1 if collision is to be enabled, 0 if disabled;
* DE == address of sprite to draw;
* HL == address to draw it to....and the following postconditions...
* Zero-flag == set (Z) if no collision occurred - the whole sprite
was drawn;
* Zero-flag == reset (NZ) if a collision occurred - the sprite was
drawn only down to the point of collision.#9456: LD B,#10 ;;;; 16 pixel-rows to draw
#9458: BIT 0,C ;;;;; (loop starts at #9458) test Bit 0 of C-register
#945A: LD A,(DE) ;;; get pixel-row from sprite's left cell-column
#945B: JR Z,#9461 ;; skip collision-detection if Bit 0 of C is 0
#945D: AND (HL) ;;;; if any pixels collide
#945E: RET NZ ;;;;;; then return with Zero-flag reset (collision!)
#945F: LD A,(DE) ;;; get pixel-row from sprite's left cell-column
#9460: OR (HL) ;;;;; merge sprite's pixels with what's already there
#9461: LD (HL),A ;;; draw pixel-row (left cell-column)
#9462: INC L ;;;;;;; move right by one cell-column
#9463: INC DE ;;;;;; point to next pixel-row in sprite's right column
#9464: BIT 0,C ;;;;; ditto re. sprite's right cell-column...
#9466: LD A,(DE)
#9467: JR Z,#946D
#9469: AND (HL) ;;;; if any pixels collide
#946A: RET NZ ;;;;;; then return with Zero-flag reset (collision!)
#946B: LD A,(DE)
#946C: OR (HL)
#946D: LD (HL),A
#946E: DEC L ;;;;;;; move left by one cell-column
#946F: INC H ;;;;;;; move down by one cell-row
#9470: INC DE ;;;;;; point to next pixel-row in sprite's left column
another>
#9486: DJNZ #9458 ;; repeat until whole sprite drawn
#9488: XOR A ;;;;;;; A:= 0 and set Zero-flag (Z)
#9489: RET ;;;;;;;;; return with Zero-flag set (no collision)The above two POKEs replace the RET NZ instructions with NOPs, so
if a collision does occur, it is ignored and the whole sprite is
drawn. This means that if Willy walks into a guardian, their pixels
are merged together.Note that this subroutine is called not only for guardians, but
also for Maria (but not the toilet), Willy's extra lives, the
objects on the Game Over screen, and the colour-code routine.
So the above two POKEs allow Willy to walk through Maria as well as
guardians.-------------------------------------------------------
Method C: Modify calls to the sprite-drawing subroutine
-------------------------------------------------------For guardians and Maria, the above subroutine is called with C == 1
to enable collision-detection.So, to disable collision-detection for guardians, we can call it
with C == 0 by using the following POKE...POKE 37392,0 (Hex 9210: 00)
...which modifies the following code...
#920F: LD C,1 ;;;;;;;; enable collision-detection
#9211: LD A,(IX+1) ;;; A:= animation-mask
#9214: AND (IX+0) ;;;; bitwise-AND it with the current frame-number
#9217: OR (IX+2) ;;;;; bitwise-OR that with the start-sprite
#921A: AND %11100000 ; extract frame-number to be drawn
#921C: LD E,A ;;;;;;;; this forms the low byte of the sprite-address
#921D: LD D,(IX+5) ;;; D:= sprite-page (high byte of sprite-address)
#9220: LD H,#82 ;;;;;; lookup-table at #8200: position -> address
#9222: LD L,(IX+3) ;;; L:= guardian's row (in pixels*2)
#9225: LD A,(IX+2) ;;; A:= start-sprite | cell-column
#9228: AND %00011111 ; extract cell-column
#922A: OR (HL) ;;;;;;; table lookup: (row, column) -> low byte
#922B: INC HL ;;;;;;;; point to next byte in table
#922C: LD H,(HL) ;;;;; table lookup: (row, column) -> high byte
#922D: LD L,A ;;;;;;;; {HL == address to draw sprite}
#922E: CALL #9456 ;;;; call sprite-drawing subroutine...as follows:
#920F: LD C,0 ;;;;;;;; disable collision-detection
This differs from Method B in that:
(a) it's only one POKE;
(b) it doesn't disable collision-detection for Maria (that can be
done by POKE 38242,0 (Hex 9562: 00));(c) each guardian-sprite overwrites everything in its 16x16-pixel
square, rather than merging its pixels with what's there already.
This means that each guardian is like a moving portal; thus
stationary guardians can be combined with teleporters to simulate
portals (which are permanently open, regardless of any items in the
room).
