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: 7050
Author: ian.rushforth
Date: 13/02/2017
Subject: Re: wraparound / mm
I wrote:
> I've just noticed that Andrew Broad came up with a different fix for this in his game Manic Miner: Neighbours > - Allana Truman.
> I would say that my fix is much simpler than Andrew's, although mine is somewhat less elegant.
Allow me to explain. First, here is a recap as to the nub of the problem which arises - in the words of Andrew Broad (from his TECHNICA.TXT for Manic Miner: Neighbours - Allana Truman):
"The problem when Willy is falling off the bottom of the screen is that IX >= 33792 [#8400], which is pointing off the end of the lookup-table, into the first few instructions of Manic Miner! So it tries to interpret the codes for these instructions as though they were entries in the lookup table, thus generating all kinds of erroneous addresses to poke to! Some of these addresses happen to be in the screen-layout of Room 7."
The basis of my solution was to spot that most of the addresses which get POKED to when Willy falls off the bottom of the screen [or, for that matter, jumps off the top] have a High Byte which is less than #40. Therefore they lie within the range of the ROM and are immune to such POKING.
The basis of my solution was to spot that most of the addresses which get POKED to when Willy falls off the bottom of the screen [or, for that matter, jumps off the top] have a High Byte which is less than #40. Therefore they lie within the range of the ROM and are immune to such POKING.
However, the jump instruction at #8404 is problematic. The operand of that jump is #85CC, the Low Byte of which (#CC) is interpreted as the High Byte of an entry in the look-up table. (That is why the cavern 'Miner Willy Meets the Kong Beast' - the layout data for which occupies the range #CCxx - gets corrupted.)
My POKES simply redirect the problematic jump instruction at #8404, shifting that jump to occupy the conveniently-located spare bytes at #841C-#841E.
The reason that this works is because, by editing the original jump at #8404, so that it is JP #841E, the Low Byte of the operand of that jump is now #1E. If that is interpreted as the High Byte of an out-of-range entry in the look-up table at #8300-#83FF, then the program will (harmlessly) attempt to overwrite the ROM at #1Exx.
And the new location for the jump to #85CC, being at #841C, is in practical terms beyond the reach of any possible overshooting of the end of the look-up table when Willy's sprite is transcending the bottom of the screen.
**
P.S. I should qualify the above: in theory, Willy's sprite could be drawn starting in the bottom pixel-row of character-row 15 (i.e. at y=127), which would mean that the next fifteen pixel-rows of his sprite would wrap beyond the bottom of the screen. So theoretically, up to 30 (15x2) bytes beyond the natural end of the look-up table could be interpreted as addresses to which to POKE Willy's graphic bytes. That would take you up to #841D.
[Indeed, if you POKE Willy's y-coordinate with a value of 127 - #FE in hex since the value stored at #8068 is actually twice Willy's pixel y-coordinate - then the corruption of 'Miner Willy Meets the Kong Beast' will recur if Willy falls off the bottom of the cavern. Which, incidentally, he will do repeatedly since he is out-of-sync with the platforms and therefore can't land on them!]
However, in practice, there is no way in which Willy would get into such a position during the course of the game. The closest he could get is if he jumped off off the top of the screen from a height of four cell-rows below. In the time-frame immediately after he has disappeared off the top, Willy has a y-coordinate of 126, and so two pixel-rows are drawn at the bottom of the screen, whilst fourteen pixel-rows have extended beyond the bottom. In those circumstances, the 28 (14x2) bytes from #8400-#841C are interpreted as look-up addresses, with no permanent* impact on the game code.
[In my first attempt to implement this fix, I shifted the 'Jump to #85CC' command to #841C-1E, since there are actually four spare bytes at that location and I initially chose the first three for this purpose. However, that caused corruption of some of the graphic bytes of the Toilet guardian in the cavern 'Eugene's Lair' (which occupies the range #C000-#C3FF). The jump command itself, 'C3', was being interpreted as the High Byte for the POKE address, whilst the Low Byte derived from the ASCII code of the letter 'R' in the message 'AIR' (which is stored at #841B).]
**
* Apart from a couple of trivial exceptions: - There is a temporary, instantaneous glitch, caused by the the letters 'A' and 'I' of 'AIR's ASCII codes being interpreted as a look-up address - but this only occurs at the level of the Screen Display File at #4941, and so it is immediately overwritten in the next time-frame. (Not noticeable at all if it coincides with an Air cell in a cavern where the Air's INK and PAPER settings are identical.) - Also, the command at #8401, which establishes the stack address for the game [#9CFE and earlier addresses], can also cause a relatively harmless, and barely noticeable, overwriting of the first character of the Scrolling Message (at #9D00). For that to happen, Willy's x-coordinate must hold an odd value at the moment when he is transcending the bottom of the screen (the exact address to be over-written with a graphic byte from the left half of Willy's sprite is OR'd with Willy's x-coordinate, and then the next byte along is over-written with a graphic byte from Willy's right half).
And the new location for the jump to #85CC, being at #841C, is in practical terms beyond the reach of any possible overshooting of the end of the look-up table when Willy's sprite is transcending the bottom of the screen.
**
P.S. I should qualify the above: in theory, Willy's sprite could be drawn starting in the bottom pixel-row of character-row 15 (i.e. at y=127), which would mean that the next fifteen pixel-rows of his sprite would wrap beyond the bottom of the screen. So theoretically, up to 30 (15x2) bytes beyond the natural end of the look-up table could be interpreted as addresses to which to POKE Willy's graphic bytes. That would take you up to #841D.
[Indeed, if you POKE Willy's y-coordinate with a value of 127 - #FE in hex since the value stored at #8068 is actually twice Willy's pixel y-coordinate - then the corruption of 'Miner Willy Meets the Kong Beast' will recur if Willy falls off the bottom of the cavern. Which, incidentally, he will do repeatedly since he is out-of-sync with the platforms and therefore can't land on them!]
However, in practice, there is no way in which Willy would get into such a position during the course of the game. The closest he could get is if he jumped off off the top of the screen from a height of four cell-rows below. In the time-frame immediately after he has disappeared off the top, Willy has a y-coordinate of 126, and so two pixel-rows are drawn at the bottom of the screen, whilst fourteen pixel-rows have extended beyond the bottom. In those circumstances, the 28 (14x2) bytes from #8400-#841C are interpreted as look-up addresses, with no permanent* impact on the game code.
[In my first attempt to implement this fix, I shifted the 'Jump to #85CC' command to #841C-1E, since there are actually four spare bytes at that location and I initially chose the first three for this purpose. However, that caused corruption of some of the graphic bytes of the Toilet guardian in the cavern 'Eugene's Lair' (which occupies the range #C000-#C3FF). The jump command itself, 'C3', was being interpreted as the High Byte for the POKE address, whilst the Low Byte derived from the ASCII code of the letter 'R' in the message 'AIR' (which is stored at #841B).]
**
* Apart from a couple of trivial exceptions: - There is a temporary, instantaneous glitch, caused by the the letters 'A' and 'I' of 'AIR's ASCII codes being interpreted as a look-up address - but this only occurs at the level of the Screen Display File at #4941, and so it is immediately overwritten in the next time-frame. (Not noticeable at all if it coincides with an Air cell in a cavern where the Air's INK and PAPER settings are identical.) - Also, the command at #8401, which establishes the stack address for the game [#9CFE and earlier addresses], can also cause a relatively harmless, and barely noticeable, overwriting of the first character of the Scrolling Message (at #9D00). For that to happen, Willy's x-coordinate must hold an odd value at the moment when he is transcending the bottom of the screen (the exact address to be over-written with a graphic byte from the left half of Willy's sprite is OR'd with Willy's x-coordinate, and then the next byte along is over-written with a graphic byte from Willy's right half).
