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: 4044
Author: andrewbroad
Date: 04/04/2004
Subject: Vertical guardians in MM versus JSW
andrewbroad wrote:
>I have done some experiments to investigate the semantic
> * The path of a vertical guardian with the same data for start-
> row, top row and bottom row, is slightly different in MM and JSW -
> and even causes them to crash into the floor in the JSW conversion
> of "Amoebatrons' Revenge" [17] and "Solar Power Generator" [18]!
> Look into this I must...
heterogeneity of vertical guardians in MM and JSW, with the
following conclusions:
<1> In MM, a vertical guardian stays at each of its two boundaries
for TWO time-frames. In JSW, it only spends ONE time-frame at each
boundary.
<2> In MM, the boundaries are slightly narrower in MM than specified
in the room-data (i.e. the actual top boundary is slightly lower
than (but sometimes equal to) the specified top boundary, and the
actual bottom boundary is slightly higher than (but never equal to)
the specified bottom boundary).
<3a> In JSW, the actual bottom boundary is equal to the specified
bottom boundary only if the distance (in pixels) between the start-
row and the bottom boundary, and between the two boundaries, are
divisible by the velocity (in pixels per time-frame). Otherwise, the
actual bottom boundary is lower than the specified bottom boundary
by r pixels, where r is the remainder of the distance divided by the
velocity. This is why the cyan VG in the JSW conversion
of "Amoebatrons' Revenge" [17] crashes into the floor.
<3b> In JSW, the actual top boundary is equal to the specified top
boundary. Even if there is a remainder r (cf. <3a>), the VG cannot
go higher than the specified top boundary. However, in this case the
VG's points along its path, including the bottom boundary, are r
pixels lower than before the VG first reaches its top boundary. This
is why the cyan VG in the JSW conversion of "Amoebatrons' Revenge"
[17] crashes into the floor on its second time down but not the
first time.
<4> The blue VG in "Solar Power Generator" [18] is actually
specified as going DOWN initially, even though it starts at its
bottom boundary! In MM, this means that it spends two time-frames
(the 0th and the 1st) in this position (during which time the floor
beneath is curiously coloured blue) before moving up. In JSW, it
oscillates between its bottom boundary and one pixel below its
bottom boundary (hence crashing into the floor).
Let's compare the codes for vertical guardians in MM and JSW:
Manic Miner (Bug-Byte edition):
36610: move VG and check for boundaries
LD A,(IY+2) ; get current row of VG (in pixels)
ADD A,(IY+4) ; add velocity (+ive for down, -ive for up) to row
CP (IY+5) ; compare row with top boundary
JR C,36631 ; if row is higher than top boundary then jump to 36631
CP (IY+6) ; compare row with bottom boundary
JR NC,36631 ; if row is lower than (or =) bottom boundary then jump
to 36631
LD (IY+2),A ; set new row (only if within boundaries)
JR 36639 ; jump to routine for drawing the VG
36631: invert velocity after passing either boundary
LD A,(IY+4) ; get velocity
NEG ; negate velocity
LD (IY+4),A ; set new velocity
36639: ...
Because the new row is only set when the boundaries are NOT passed,
the VG spends one more time-frame on that row, but with its velocity
inverted so that it will move on the next time-frame after that.
This explains why a MM VG spends two time-frames at each of its
boundaries <1>, why it cannot exceed either boundary <2>, and
why it gets away with the situation in <4>.
The use of a "higher than" comparison for the top boundary and
a "lower than or equals" comparison for the bottom boundary, is why
it can actually reach only its top boundary <2>.
Jet Set Willy:
37267: move VG and check for boundaries
LD A,(IX+3) ; get current row of VG (in pixels)
ADD A,(IX+4) ; add velocity (+ive for down, -ive for up) to row
LD (IX+3),A ; set new row (even if outside boundaries)
CP (IX+7) ; compare row with bottom boundary
JR NC,37294 ; if row is lower than (or =) bottom boundary then jump
to 37294
CP (IX+6) ; compare row with top boundary
JR Z,37288 ; if row = top boundary then jump to 37288
JR NC,37302 ; if row is lower than top boundary then jump to 37302
37288: set row to top boundary
LD A,(IX+6) ; get top boundary
LD (IX+3),A ; set new row
37294: invert velocity after passing either boundary
LD A,(IX+4) ; get velocity
NEG ; negate velocity
LD (IX+4),A ; set new velocity
37302: ...
Note here that JSW handles the top and bottom boundaries
differently. If the bottom boundary is reached or exceeded, it
simply inverts the velocity and continues - and because (unlike MM)
it sets the new row regardless of whether a boundary was exceeded on
that time-frame, a VG will appear below its bottom boundary if the
distance is not cleanly divisible by the velocity <3a>.
Whereas when the top row is reached or exceeded, it actually sets
the row to the top boundary, flattening out any remainder <3b>.
--
Dr. Andrew Broad
http://www.geocities.com/andrewbroad/
http://www.geocities.com/andrewbroad/spectrum/
http://www.geocities.com/andrewbroad/spectrum/willy/
