-
Posts
5,111 -
Joined
-
Last visited
Everything posted by IRF
-
Actually, it's kind of the other way round - the 'entry point' for a jump (the check for whether the jump key is being pressed) is in 'Move Willy (2)', and so during a jump Willy's x-coordinate is incremented first (via 'Move Willy (3)'), then we return to the Main Loop and Willy's new position is drawn, then in the next pass through the main loop we reach 'Move Willy (1)' and his y-coordinate is incremented for the first time, followed by the check for Fire cells before he is drawn again. And I think I've come up with the reason why this is the case - there isn't actually a check in the code for overhead Earth cells that stops Willy from jumping up through them. Instead, he is moved upwards by one increment and then, if either of his upper cells coincides with an Earth block, he is immediately brought back down again by the code at #8EBC (the same code that causes the 'Innocent-Looking Block' effect). Now, if Willy's sprite was drawn on the screen at the updated y-coordinate before that check took place, then when walking through a cavity that is two cell-rows high with the jump key depressed, Willy would appear to repeatedly jump up into the Earth cells above (by half a cell height) before falling back down each time. So the order of the routines, as laid out in the first paragraph above, prevents the quirky effect described in the second paragraph from being seen (although it is taking place 'behind the scenes').
-
Case in point: On two occasions I used a two-byte 'FE 00' (Compare with zero) command, whereas a single-byte 'B7' (OR A) instruction achieves the same thing!
-
I'm hoping that digesting the above helps you to get your head around the precise mechanics of the AND command, and in turn gain a deeper understanding of how your patch vectors work! Indeed, typing out the above (and 'gathering my thoughts' in the process) has given me fresh insight into how your 'alternative screen flash routine' operates. (That isn't by any chance one of the examples that sparked this query, is it?) I've come up with a variant of your 'alternative screen flash routine', which I might install into The Nightmare Room in WRN, which uses an operand for the AND command of D0. It causes two blackouts, of short but equal duration, each of which is followed by two short bursts of screen flash - as if the lights in the room are flickering back on after each blackout! It looks great, but now I can understand how it's being brought about, which is even better! AND D0 in binary is AND 1101 0000, and so values of the 'tick counter' (loaded up to the A register) of between 0 and 15 (00001111 in binary) give a zero output, meaning that the screen flash counter is assigned a fixed value for 16 passes through the Main Loop - resulting in the screen taking on a fixed colour (my choice being Black for a true blackout!) during that period. Then from A=16 (00010000) onwards, the output of the AND D0 command is non-zero, so the screen flash effect resumes (via decrementation of the screen flash counter), until the A register reaches a value of 32 (00100000), whereupon once again the AND 11010000 gate outputs zero, causing the screen colour to be fixed (on Black) once again. Then when A reaches 00110000 (48 in decimal), the second blackout stops and the screenflash resumes (until A is decremented to zero, at around 64 'ticks' - although that can be varied via the operand of the subsequent '3E' instruction), and the output of the AND 11010000 command then remains non-zero until A (determined by the tick counter) wraps back around to zero at the start of the next 256-tick cycle. So the blackout/light flashing routine lasts for about 1/4 of each cycle - perfect for disorienting Willy in the tricky Nightmare Room, without making it impossible to complete!
-
Doubling the in-game clock speed was achieved via the command 'E6 7F', or AND 01111111 (in binary), with the in-game clock being incremented every time the output of the AND command is zero. The fact that the highest (7th) bit of the operand is zero, is key to how it works. The only eight-bit binary numbers that yield an output of zero (00000000) when AND 01111111 is applied, are 00000000 and 10000000 (i.e. 0 and 128 in decimal respectively). All other numbers have at least one bit set to 1 in the 'Bit 0 to Bit 6' range, so the AND 01111111 gate passes a non-zero output. Hence the minutes are incremented every 128 ticks, instead of every 256 ticks. [incidentally, the command 'E6 FF' or AND 11111111 would essentially leave the routine unchanged, with a clock increment occurring every 256 ticks.] Had you made an analogous error to the one you're now reporting, you would have put 'E6 80', or AND 10000000, into the routine that increments the clock. I believe the effect of that would have been to increment the clock every tick (i.e. every pass through the Main Loop) for the first 128 ticks (from 00000000 ticks to 01111111 ticks - the output is always zero during this phase because the highest bit of the tick counter is zero and the AND command resets all the other bits to zero), followed by NO clock increments at all for the next 128 ticks (from 10000000 ticks to 11111111 ticks - the highest bit of the output is set to 1 so you never get an output of zero during this phase), then it would resume incrementing the clock on every tick for the next 128... So as you say, a change of just '1' in the value of the operand of the AND command, can have a dramatic effect on the impact of the AND command! EDIT: I just tried out the above and it played out exactly as I predicted! The minutes rolled by rapidly throughout the first rendition of 'Rich Man', before stopping at 9:07am (i.e. the incrementation ceased after the 128th minute). Then after another rendition of 'Rich Man' [there are two tune renditions for every 256 'ticks'], the clock resumed rapidly ticking over, before stopping again at 11:15am. (N.B. I think the reason for the extra minute which was apparently counted second time round, is that the minutes started incrementing again when the tick counter rolled over to a value of zero - whereas the tick counter had started at zero at the very beginning of the game).
-
It relates to powers of 2, not necessarily numbers that are divisible by 2. If you convert all the numbers to binary then you can see more easily how the AND command acts as a 'gate'.
-
The attached rzx demonstrates the problems with the 'Andrew Broad variant' of the Bug Fix - if Willy is underneath Earth blocks, and walking towards a head-height Earth block, if he holds the Jump key down then he can pass through the latter! It also removes his ability to stand adjacent to a head-height Earth block and jump up onto it - instead, he jumps through it (in either direction)! So I've come up with a 'hybrid' solution which resolves the above, but which retains [for moving left - and adds in the case of rightwards movement] Willy's ability to jump onto ledges underneath Earth blocks, or to quirkily jump through overhead Earth blocks. This was achieved by inserting the following checks when Willy is trying to pass left or right through a cell boundary: (1) firstly, is Willy jumping (is the Airborne Status Indicator at #85D1 set to a value of 01)? If not, check for Earth blocks at head-height (in either direction), and block his progress (or not) accordingly; (2) secondly, has Willy only just started his jump (is the Jumping Animation Counter at #85D5 reset to a value of 00)? If so, check for Earth blocks at head-height (in either direction), and block his progress (or not) accordingly; (3) in all other circumstances, the check for head-height Earth blocks is bypassed. I have implemented the above in the attached 'hybrid fix' Z80 file (the relevant code once again starts at #9700). Starting point set to The Bathroom, with the same layout as in the previous file - you will see that the original Bathroom tap in this test file is now uncollectable! I think we've cracked it this time!! (Except that there is plenty of scope for code optimisation!) New Bug Fix Andrew variant.rzx New Bug Fix Hybrid.z80
-
I remember trying that one out a while back and discovering that whilst Willy could jump up a column of Earth blocks, he could only get so far (halfway up - ironically it was on the screen 'Halfway up the East Wall' that I noticed it!) It's just occurred to me that the reason must be something to do with the fact that the playing area is drawn in two halves of eight cell-rows each.
-
EDIT: I've taken this one off to a Private Message, as it was more of a specific suggestion to Danny, as opposed to a general post for wider consumption.
-
I've implemented the 'Andrew Broad variant' of the 'Don't Mind Your Head Bug Fix', and noticed some other interesting elements of it. Before I go into detail, you might like to try out the following mini-challenge - load up the attached file, then try to collect all the Bathroom taps and exit to Top Landing (without losing any lives). New Bug Fix Andrew variant.z80
-
There are 2 spare bytes here: http://skoolkid.gith...y/asm/8C01.html 8C20 OR $10 Set bit 4 of A (for no apparent reason) The command sets (assigns a value of 1) to bit 4 of A. But then it is immediately followed at #8C22 by XOR A, which resets all the bits of A (including bit 4) to 0. So I am quite confident that those two bytes can be reused for other purposes.
-
I think the Flying Pig Sprite, like the end sequence elements, is hard-wired into the Main Loop (in the original game, at least; although I seem to recall you saying there's a game in which Willy's sprite is determined according to the value of a particular offset byte in each room - which inspired your solution for the tunes). So perhaps the Flying Pig Willy fulfills the 'patch' aspect, but not the 'vector' part? The "as perfected by Ian" is a bit wordy, but maybe a brief mention in the readme would be in order? And to continue the 'pig' theme, my assistance in this regard makes me feel better about that fact that you inadvertently ended up acting as my 'guinea pig', in implementing my initial suggestion for a patch to ensure the music is on at the start of the game. A suggestion which required you to find spare bytes, when ultimately (only a week or two later, such is the speed at which my Z80 coding skills came on!) I identified an alternative which could have actually saved* you some bytes!! (* EDIT: Although having thought about it again, I can see that this is not quite that simple, as three and two of the potential five bytes are located respectively before and after the 'Initialise Willy's Room number/coordinates' commands [the operands of which are treated by JSWED as variables, hence they can't easily be moved from their current locations].)
-
One other point in relation to this Bug Fix - my variant means that Willy is safe from hitting a Fire cell that is embedded between Earth cells above and below it; whilst Andrew Broad's variant means it is possible for Willy to hit such a Fire cell if he jumps from a certain animation-frame. (I've got Hornet's Nest in TNE particularly in mind here, given that the whole screen is a 'honeycomb' of Fire and Earth cells!)
-
This is an interesting phenomenon - if you NOP out the bytes at #8E4E and #8E55 (relative jumps associated with checks for a Fire cell underneath Willy's sprite*), then Willy can bounce off a Fire cell into a second forwards jump without being killed! It doesn't work if the second jump is vertical though! And it only occurs if his frame of animation is such that he's about to cross a cell-column boundary when his attributes (though not his on-screen sprite) become cell-row aligned. See the attached rzx recording - after a successful 'bounce' in each direction, I pressed the jump straight up key when Willy was coming in to land between the pillows, and he was killed (hence he jumps straight up at the start of his next life, because 'jump' was still depressed; after that I jumped across and let go, which of course had the same fatal consequence). (*This is how the checks are described in the SkoolKit disassembly, although in light of recent discussions I don't think it's strictly accurate to refer to the cells "below Willy's sprite" - the vertical position of his attributes and his sprite drawn on the screen are out of sync!) Fire Bounce.rzx
-
Having thought some more about this, I don't think progressing both x- and y- coordinates before checking for underfoot cells would prevent Willy from jumping through a Ramp, but it might mean that he falls straight through the Ramp, rather than getting caught on the 'inside' of it and being able to walk through... EDIT: Actually, he can do that anyway with the existing code if he starts at the bottom of the ramp. If he then turns around and jumps back though (jumping from the inside of the ramp), he doesn't jump straight through to the outside, but gets caught on the ramp - another illustration of the asymmetry of the way jumps are determined by the game engine!
-
The above also explains the asymmetry of jumping over Fire cells. If Willy jumps over a Fire cell and lands too close, he can't just turn around and perform the jump in the opposite direction, as you might expect. And if two Fire cells are placed three columns apart, he can't jump them in turn without stepping back towards the first one in order to clear the second.
-
Indeed! Or you could blame the fact that there are Earth cells overhead. So it's the culmination of a number of elements. But I'd rather fix the Left bug (thus preventing him from getting into the situation in the first place) than remove the conveyor (or the wall)!
-
One further thought - would it be worth mentioning here: "The number 15 here determines the highest segment of rope that Willy can reach (originally 12)" where 0 represents the top of the rope. i.e. the segment count is from the top downwards? Otherwise the casual reader may think that the POKES enable Willy to reach a higher part of the rope (15 being a higher number than 12)!
-
Okay, but I'm sure the reason that Willy's y-coordinate never goes below 25 at segment 15, relates back to fundamental mathematics!? Although I appreciate that it's not linear, but subject to discrete jumps of 8 pixels, so basic trigonometry is perhaps too simplistic. Still, my crude trig-based calculation yielded the same result! If the game engine were to be amended such that the swing of the rope extended further than it does, then with Willy holding onto segment 15 of the rope, he may be brought within jumping reach of the top of the screen! Because the angle of the upper part of the rope's deviation from the vertical would be greater than it is at the moment, so his y-coordinate might drop below 24 (meaning it is 'rounded down' to 16).
-
Regarding the phenomenon highlighted in bold, I've now realised that the scenario in which it occurred involved a static guardian adjacent to a ramp. And the reason for this quirky behaviour is down to the routine at 38344. There is a section of code in that routine at 38372 which calculates Willy's true pixel y-coordinate if he is on a ramp. However, that section of code is bypassed if the Airborne Status Indicator is non-zero. So if the 'Jump' key is kept depressed, the vertical position of the bottom of Willy's sprite is aligned with the top of the ramp cell on which he lands. So he appears to briefly 'bounce' a few pixels above the exact position of the ramp beneath him. And hence Willy can jump safely away from certain guardians located adjacent to a ramp (as long as the guardian's filled in pixels don't coincide with those of Willy when he is at the lowest point in his jump), whereas if 'Jump' isn't depressed, the program draws Willy at his exact vertical position (based on his precise horizontal pixel position on the ramp), which then can mean the same guardian's pixels do coincide with Willy's, and he dies! (N.B. The same trick cannot be performed with a Fire cell located adjacent to a ramp, because death by Fire cell isn't pixel-based.) The same check 'Is Willy Jumping?' in the routine at 38372 also explains why Willy can appear to 'hover' above a ramp, if he keeps the 'Jump' key depressed when he is walking up the ramp underneath an overhead Earth cell. The attached rzx recording demonstrates both of these phenomena, as well as the fact that Willy can walk up a ramp through an overhead Earth cell (as there is no check in the code for overhead Earth cells when Willy is walking up a ramp). This effectively makes walking up the ramp a one-way route, because when he tries to return back down, he is stopped by the check for Earth blocks adjacent to him! It's also worth mentioning that he can walk down a ramp through an Earth cell at the bottom of a ramp (this is not shown in the attached rzx, but you can see it in action in the original JSW, by walking down the ramp in On Top of the House!) That's because the check for Earth cells at the level (y+2) doesn't take place when he's cell-row aligned. (Otherwise he wouldn't be able to walk along Earth cell platforms; it also explains his ability to jump through Earth cells if he encounters them when he's cell-row aligned at a certain animation frame, as your MM disassembly 'Bugs' section demonstrates.) Ramp jump test.rzx
-
Richard, In the Trivia section of the JSW disassembly, the 'Ropes for Beginners' guide is very useful (i.e. how to climb up, based on the direction of the rope's swing and Willy's facing direction). I was thinking that maybe you could also include a 'Ramps for Beginners' guide, explaining how exactly Willy can jump through, rather than onto a ramp. i.e. Starting at which frame of animation allows him to jump through? Perhaps with an explanation of the mechanics of jumping through ramps? And on that subject... I'm wondering if one such unintended consequence might be to prevent Willy from being able to jump through a ramp? (I'm not sure about that though.)
-
I'm afraid that all the Writetyper code was reused for 'higher' purposes...
-
Is it something like 12/cos(?), where 12 is the value that prevents Willy jumping off the top when the rope is hanging vertically down [and is the value of the bytes in question in the original game code], and ? is the angle by which the top of the rope deviates from the vertical, at its point of maximum swing?
-
Not derailing at all! 15 (or #0F in hex) was the value that I concluded was just enough to prevent it.
-
Richard, Please see the attached, starting position is The Forgotten Abbey. I performed the manoeuvre twice - the first time, I kept 'left' depressed (walking against the flow of the conveyor) so Willy was able to escape the situation. The second time, I let go of 'left' after entering The Wine Cellar, and so Willy got stuck! In Dr Jones..., if you manoeuvre Willy to be standing three cells above the 'tusk' item, and walk left, then he gets stuck inside the elephant's head! (N.B. This is the case in the original JSW, but in the Bug Fix 2015 Edition it has been prevented by removing some of the Water cells inside the 'head', allowing Willy to drop out of that row of cells.) Stuck in wall bug.rzx
-
Have you played our JSW The Nightmare Edition? There's a static guardian (with filled-in pixels only one cell-column deep) on the far right-hand side of The Off Licence - if you can get that far!!