Jump to content
Jet Set Willy & Manic Miner Community

IRF

Contributor
  • Posts

    5,105
  • Joined

  • Last visited

Everything posted by IRF

  1. I noticed that there are several parts of the JSW code which effectively replicate the same function - namely using the table in page #82 of the code to point HL at the appropriate address for drawing various moving entities onto the pixel display and/or pixel buffer. So I have rewritten several parts of the code to allow a shared routine to be CALLed (with various entry points) which handles the table at page #82, and saves quite a few bytes (I would estimate about 30-40, all told) in the process: Entry point from
  2. Also, HL has to start off pointing at the top pixel-row of the cell in the case of a crumbly, or start off pointing at the bottom pixel-row for bashing a wall tile. Coming from 'Move Willy', HL starts off pointing at an attribute coordinate (#5Cxx or #5Dxx). Use PUSH and POP HL to preserve that address, for updating the attribute of the cell to Air once crumbling is complete. For a wall tile, use a similar approach as the 'old' crumbly tile code, in order to point HL at the bottom pixel-row: LD A,H ADD A, #1B OR #07 LD H,A For a crumbly tile, point HL at the top pixel-row by using: LD A,H ADD A, #1B AND #78 LD H,A The command in bold can be a common entry point to a shared part of the code (if the C register is used to increment or decrement H as per my previous post).
  3. How about this slight rewrite of the loop: xor a ld d,a ld b,8 loop ld e,(hl) ;the current line or d ;the line above ld (hl),d ld d,e ld a,h add a,c ld h,a djnz loop Set C=01 beforehand for regular crumbling tiles, or C=FF for bashing away at wall tiles from below(?)
  4. I've just discovered that this bug can actually be fixed using a single* POKE! POKE #92B5, #2C It replaces the INC IX at #92B4 with an INC IXL. So the 'Draw Willy' routine doesn't start looking up addresses, via the IX index, that are beyond the end of the table in page #83 of the code. Instead, when Willy is falling off the bottom of a Manic Miner cavern, the rest of his sprite is drawn at the top of the cavern (although in the first time-frame, it may not be visible if the Air INK and PAPER settings match). Because whilst the low byte of IX may be incremented from #FF to #00, the high byte of IX always retains the value #83 if only IXL is incremented. (Whereas in the original code, the incrementation of the IX register-pair means that it can proceed from #83FF to #8400.) N.B. This does not address the issue where Willy falling past the bottom of a cavern causes errant (de facto Water) cells to be created in the top two cell-rows. To resolve that, a separate fix would need to be applied to the code which writes Willy's attributes to the screen. (* For elegance, you could also replace the preceding INC IX at #92B2 with an INC IXL, but that isn't necessary to fix the bug because the IX index always holds an even value going into those two consecutive INC IX commands, and so the first of the two will never increment IX from #83FF to #8400.)
  5. IRF

    Wraparound Guardians

    Horizontal and Vertical Guardians can now wrap around both the vertical and horizontal edges of the screen - see the attached. Note that the horizontal guardians do not change Base Sprite as they wrap around (which they do in the original JSW game engine). Getting both the graphic bytes and attributes to fully behave was quite a challenge. But I got there in the end. :) P.S. In the test file (startup room = Back Door), don't be surprised if the two guardians eventually collide with each other! Horizontal and Vertical Wraparound Guardians.z80
  6. I would probably go with the apostrophe in that case, because you're referring to a person rather than an 'entity', so it seems more personal. e.g. I would refer to "Geoff Eddy's rewrite of the game engine" rather than "the Geoff Eddy rewrite of the game engine". On the other hand, I would say "There are a lot of novel features in the Geoff Mode game engine".
  7. I would either go with the apostrophe, or else say "the R. D. Foord Software version".
  8. IRF

    Wraparound Guardians

    I have managed to amend the code which moves vertical guardians, and also the guardian-drawing and sprite-drawing routines, in such a way that a guardian may safely wrap around past the top/bottom of the screen without crashing into its own 'trail of havoc' (i.e. errant pixels left on the primary screen buffer. Please see the attached. The starting room is 'On Top of the House'. There are now two flag guardians in that room, which have identical definition bytes to each other except that, for one of the flags, the upper and lower bounds have been transposed (causing it to wander up off the top of the screen and back again). I thought it was appropriate to use the flag guardians to illustrate this behaviour, as I managed to achieve this technical novelty by careful use of the F Register flags (the Zero, Carry and Parity Flags were all instrumental). I'll type up the source code when I find the time. But note that the same routine handles both guardians. Vertical Wraparound Guardians.z80
  9. The two commands at #888F and #8890 can be replaced with a BIT 1,D, and the jump at #8892 changed to a JR Z (different conditionality and a relative jump) - saves two bytes. **** In the 'Print a Sprite' routine (#9456), there is replication of certain commands (#9458-##9461 and #9463 are repeated at #9464-#946D and #9470). Placing those commands in a subroutine, and CALLing them twice (with an INC L in between, and the move to the next raster line following afterwards) would save a few bytes. **** If the toilet attributes are printed first, then the CALL to draw the toilet's pixels can be replaced with a JUMP, saving one byte as the RET at the end of the draw routine serves to return the program to the Main Loop.
  10. At #9308, if the destination of the CALL is changed to #8E99, then the three-byte command at #9304 can be removed.
  11. I think the references to 1024 in the above should read 512? (Number of attributes/cells in the playable screen.) N.B. The source post from which the above quote is taken is correct in stating that the number of graphic bytes in the playable screen is 4096.
  12. I forgot to mention that, within that more efficient rewrite, I also fixed the bug whereby Fire cells in the top cell-row can kill Willy if he drops off the bottom of the screen directly beneath them. ** By the way, my rewrite does not test the cell underneath the 'upslope' half of Willy's sprite for Earth/wall attributes. This means that Willy can still walk smoothly up a ramp in a room with matching attributes for Earth and Ramp. (Though he can't jump through such a ramp, or walk through it from the 'under-stairs' side.) In an earlier attempt, I had the check for underfoot Earth performed by a CALL to the shared subroutine discussed earlier (which checks both adjacent cells under Willy's feet). However, that had the effect of making Willy's movement jerky as he walked up/down a combined wall-ramp (moving up/down by one cell-row at a time).
  13. The subroutine which you referred to above - do you also use it when checking the two cells below Willy's feet, looking for a Fire or a Conveyor block in either or both cells? i.e. If either is true, then let Willy fall through to next row down (in the case of Fire) or move him sideways (if he's on a Conveyor). But presumably this approach does not work when checking for underfoot Crumbly cells (at least not in the same way), because in some circumstances you need to crumble both blocks simultaneously. And the same subroutine wouldn't work when checking for Air underfoot, because the conditionality is reversed and you have to have Air in BOTH cells in order for Willy to fall through.
  14. I wonder if the byte savings could be achieved in the main routine (loop set up in the latter part of #95C8) by working from the bottom upwards when considering Willy's attributes, instead of from the top downwards? Hmmm.... how about this: [EDIT: I'VE EXTENDED THE REWRITE TO INCORPORATE THE WHOLE ROUTINE] org: #95C8 LD HL, (#85D3) LD DE, #0040 ADD HL,DE [point HL down to two cell-rows below Willy] LD B, #00 [assume Willy's ramp-adjustment y-offset is zero] [or LD B, D to save one byte] LD E, L [save L, and hence HL, for later] LD A, (#85D1) OR A JR NZ, colour_Willy_code [don't adjust y-coordinate for ramp if Willy is jumping] LD A, (#80DA) AND #01 LD C, A [store ramp direction flag in C] ADD A, L LD L, A [point HL at cell underneath 'upslope' half of Willy] LD A, (#80C4) CP (HL) JR NZ, colour_Willy_code [don't adjust y-coordinate if 'upslope' half of Willy isn't standing on a ramp tile] LD A, C RLCA CPL ADD A, #02 ADD A, L LD L, A [point HL at cell underneath 'downslope' half of Willy] LD A, (#80B2) CP (HL) JR Z, colour_Willy_code [don't adjust y-coordinate; this stops Willy from sinking into a wall block as he approaches a ramp tile] LD A, (#85D2) [calculate y-offset based on ramp direction and Willy's animation frame] DEC C XOR C CPL AND #03 RLCA RLCA LD B, A [b now holds Willy's y-coordinate offset] colour_Willy_code: LD L, E [HL is once again pointing at the cell two rows below Willy's left half] LD DE, #FFE0 [this adjusts HL up a row each time it is added] LD A, (#85CF) ADD A, B [Willy's true pixel y-coordinate, adjusted for ramp if necessary, is now stored in A] LD C, A [Copied to C for the first pass through the loop that follows] EX AF, AF' [Also stored in the shadow registers for later] LD B, #03 [Three cell-rows dealt with] BIT 1,H [Test if HL is pointing below the bottom of the screen [to prevent the bug whereby Willy can be killed by remote Fire cells in the top cell-row] JR NZ, special_case_bottom_of_screen: cell_set_loop: CALL colour_a_row INC HL CALL colour_a_row DEC HL special_case_bottom_of_screen: ADD HL,DE [Move UP a cell-row] LD C, D [saves one byte compared with original - note that C doesn't have to hold the specific value #0F, it just needs at least one of Bits 0-3 set, in order to enforce white INK for Willy's top two cell-rows] DJNZ cell_set_loop EX AF, AF' [Willy's true pixel y-coordinate is restored to A] JR #963B [Note new jump destination; commands at #9637-#963A are no longer needed] [in fact, that jump could also be dispensed with if the colour_a_row subroutine is relocated to AFTER the code which draw's Willy's pixels] colour_a_row: LD A, (#80BB) CP (HL) JP Z, #90B6 LD A, C AND #0F RET Z LD A, (#80A0) CP (HL) RET NZ OR #07 LD (HL), A RET N.B. I haven't tried this out yet! EDIT: I just tested it out - I am pleased to report that it works like a charm! (Except for an initial hitch because I accidentally used an ADC command instead of an ADD!) It saves 11 bytes (potentially 13 bytes, if the subroutine is relocated and the unconditional relative jump at the end is dispensed with), and that's including an additional check for an underfoot Earth block adjacent to the base of a ramp.
  15. I was thinking - hypothetically - about whether the byte-efficient rewriting of 'Draw Willy' could be tweaked so that Fire cells still killed Willy if he was located over one whilst cell-row aligned (to stop him jumping over a head-height nasty). If the subroutine (#96E1) were simply CALLed and enacted in full six times, what would the consequences be? Willy's white INK attribute is only assigned to a particular cell if it's a background (Air) cell, and since Air cells don't themselves contain any infilled pixels, the only consequences I could think of would be that Willy could collect certain items more easily. e.g. in 'Watch Tower', he could collect the second-from-right item whilst standing on the right-hand 'parapet', rather than having to touch it during a well-placed jump close to the Fire cell upon which that item sits. And it would no longer be possible to jump over something like the Bathroom tap without collecting it. (Saving an item to collect later on could be a necessary thing to do in a room with a 'Eugene' type challenge, if collecting it too soon meant that Eugene blocked the portal before Willy could escape.) ** Having the subroutine performed six times for the purposes of checking for a nasty collision, but part of that subroutine is only enacted four times for assigning white INK when Willy is cell-aligned, requires the decision to be made in the main routine (#95C8) as to whether to assign the white INK four or six times, so we're essentially reverting back to the original code! However, placing the check for Fire cells within the subroutine (#96E1) before the check for Air cells does provide a couple of byte savings, by replacing two conditional relative jumps with conditional RETURNS.
  16. Norman, your Draw Willy rewrite code is missing a LD HL,(#85D3) at the start, to pick up Willy's attribute coordinates. (As I just found to my cost when I tried to implement it and ended up with an invisible Willy!) **** The positions from which Willy can jump over a head-height Fire cell are either 6 or 7 steps away from Willy hitting the Fire cell if he were to walk towards it (i.e. feet together frame of animation, or the next one, with one clear cell-column between him and the Fire cell). **** One other consequence of the change to your Draw Willy code is that Willy can walk up closer to the crabs buried in the sand in 'The Beach', and then jump over them without them fatally nipping his toes! (i.e. closer than he can approach the crabs with the original code in place.)
  17. Here is my understanding of the situation: Horizontal part of trajectory: It takes 8 time-frames for Willy to completely pass over (or through) a particular cell (assuming that his lateral motion is uninterrupted). Vertical part of trajectory: Without your rewrite of 'Draw Willy', he spends 7 time-frames at the apex of his jump, at a height greater than two cell-rows above the starting point of the jump. (Greater than two cell rows is the criterion to avoid being killed by a Fire cell that is two rows above the base of the jump, because of the check for Fire two rows below the top of Willy's sprite in all circumstances.) But Willy spends 9 time-frames at a height greater than or equal to two cell-rows above the starting point of the jump. (Greater than or equal to two cell rows up is the criterion to avoid collecting an item, because he only collects the item if his white attribute enters the cell in which it is located, and when he is cell-row aligned his attribute is NOT written two cell-rows below the top of his sprite.) 8 is greater than 7 but less than 9; this is why Willy can jump over an item without collecting it, but not over a Fire cell without being killed. However, with your rewrite of 'Draw Willy' in place, he can avoid being killed if he is at a height greater than or equal to two cell-rows above the platform off which he jumped, so he can clear a head-height Fire cell. *** Bassed on the above, I believe there will be two positions (frames of animation) from which Willy can start a jump and make it over a head-height Fire cell, with your rewrite in place. (Because the 9 frames spent above the danger zone provides a single frame 'margin of error' over the 8 frames it takes to pass horizontally.) If Willy attemps to jump over a head-height wall tile, from the equivalent of either of those positions, then he should clear the wall on the ascendency without his jump trajectory being affected (but he will land on the wall on the descent, either on his back heel or one animation-frame short of that). If Willy starts the jump from a closer position, then in the case of the Fire cell (with your rewrite) he will hit it and die, whereas with the wall, his horizontal motion will be blocked for at least one time-frame, causing him to move vertically upwards until he has cleared the top of the wall (but then he will still land on the far side of the wall with his back heel).
  18. Incidentally Norman, your code would also end up fixing this bug: http://skoolkid.github.io/jetsetwilly/reference/bugs.html#longDistanceNasties
  19. The sunglasses emoji was meant to say "Dec B"!
  20. The cell_set_loop could be used in conjunction with my guardian code rewrite, which draws guardian attributes across more than one medium (whilst preserving the PAPER colour of each cell through which they pass). That rewrite uses a similar principle of CALLing a subroutine four or six times (depending on whether the guardian is cell-row aligned), and I don't think that the B register is used by the guardian equivalent of the colour_me subroutine. In fact, it could yield a further efficiency, because if a DJNZ command controls the loop then there would be no need for the DEC C (or in this case DEC B ).
  21. But Fire cells effectively behave the same way as Air cells in the Move Willy routine. It's only the Draw Willy routine which means that Fire cells kill him. And if we've changed the way that Fire cells kill him (so that he has to be drawn ON a Fire cell, rather than ON OR ABOVE), then I think it will be possible to clear a head-height Fire cell. In the same way that Willy can jump over an item at head-height without collecting it.
  22. Would that code allow Willy to jump over a Fire cell at head-height? (I suspect it would.)
  23. Another potential use for the headbutt feature - if wall and nasty blocks have matching attributes, then you could have composite 'nasty walls' (Fire-Earth) which: - block Willy's progress (though without harming him) if he tries to walk through them; - kill Willy if he walks along on top of them, or jumps onto them from above; - but Willy can safely chip away at them with his head (eventually removing them entirely) if he jumps up and hits them from below! Which could give rise to some interesting layout possibilities!
  24. IRF

    Final Barrier Glitch

    That will make the whole screen turn black, won't it? If you only want to disguise Willy's feet under the portal during the decreasing air effect, then instead of having the existing commands (#9071-#9076) which overwrite the cells (addresses #58F3-#58F4) with black INK, you could print a pair of ASCII space characters over that part of the screen's pixel file (set DE=#40F3, C=02, IX=#FE00, then CALL #92BA).
  25. IRF

    Final Barrier Glitch

    I've just noticed a bug/glitch/inconsistency in the way that the 'Swordfish' routine is executed at the end of the Final Barrier. When Willy enters the portal (unless you're playing in Cheat Mode, of course), his sprite appears above the portal which displays the Swordfish icon. There is also a command which overwrites the attributes of the two cells underneath the portal, in order to disguise Willy's feet (so that he doesn't appear to be in two places at once!) However, once the points start to be ratcheted up as the remaining air supply is counted down, Willy's feet are still visible (in blue INK on black PAPER), because the pixel display for those two cells isn't wiped, only the white INK attribute. **** Incidentally, the green PAPER attribute of the cells occupied by Willy's lower half when he is drawn above the Swordfish would possibly look a bit better if cyan PAPER was used (as is the case for the upper half of his sprite at that point).
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.