Jump to content
Jet Set Willy & Manic Miner Community

IRF

Contributor
  • Posts

    5,105
  • Joined

  • Last visited

Everything posted by IRF

  1. In light of the above, I'm not sure my notion of an 'Item-Collection Patch Vector' quite fits in with the definitions? I suppose it's a modification of the concept: rather than each item definition holding a unique two-byte address where the Item-Collection Patch is stored, the exact nature of the special effect associated with the collection of each item is hard-wired to the item number [effectively; although it's actually determined by the item's position in the Item Table at #A4xx-#A5xx, which amounts to the same thing]. In that sense, it's more similar to the checks of the current room number in original JSW, which are the way in which the special effects in The Nightmare Room, The Bathroom and the Master Bedroom are implemented.
  2. Have you tried it? I don't think Willy will be able to jump up and land on the single-cell platform in 'Under the Roof' (the one attached to the left-hand side of the 'trunk')? That single-cell platform is one row too high up, and Willy's Airborne Status Indicator is reset when he jumps up from one room to the next one above, so I believe that he will briefly appear in the bottom-left of 'Under the Roof' but will just fall straight back down again... Figs, since it's a Banyan Tree. B)
  3. I've implemented the principle successfully, in several instances, in 'Mini'. :)
  4. I wonder whether we've been getting the terminology correct here? Having given some thought to the matter, I now believe that: - The 'Patch Vector Subroutine' is the four-byte subroutine that is CALLed from the Main Loop (or from the Room Setup Routine), which picks up a two-byte address stored within each room's data, and jumps to it; - 'Patch Vector' is the term for the jump destination address, stored across two spare offset bytes within the room data for each room (i.e. the Patch Vector refers to the coordinates where the Patch for that room is located); - A 'Patch' is a subroutine, located at the address that is pointed at by the 'Patch Vector' for the current room; the Patch is CALLed up from the Main Loop (or from the Room Setup Routine) via the 'Patch Vector Subroutine'. So for a game in which the Main Loop contains a CALL to the Patch Vector Subroutine, all rooms have one Patch Vector (no more, no less), although a room may feature more than one Patch if several are 'daisy-chained' together before a RETurn command is encountered during flow of execution. In such a game, if a room's Patch Vector points directly at a RETurn command, then it would be the case that that room doesn't have a Patch, but it does have a Patch Vector. ****** Following the above definitions, one would say that each room in the SE of 'Willy's New Mansion' has exactly one Patch Vector, and one or more patches. ****** Another example: in the recently-released 'Jet Set Mini', there is a CALL to a Patch Vector Subroutine from both the Main Loop and the Room Setup Routine. Every room therefore has precisely two Patch Vectors - a Room Setup Patch Vector and a Main Loop Patch Vector. However, some rooms don't actually feature any Patches at all (both Patch Vectors point straight at a RET command); some rooms contain a Main Loop Patch but no Room Setup Patch (or vice versa); some rooms feature both a Room Setup Patch and a Main Loop Patch; and some rooms contain more than one Room Setup Patch and/or more than one Main Loop Patch. Furthermore, some Patches may be shared by more than one room (where the Patch Vectors for both of those rooms point at the same address), or a Patch might be partially shared by more than one room (if two Patch Vectors point at different entry points into the same Patch). Finally, some Patches in 'Jet Set Mini' make use of existing subroutines within the original JSW code (e.g. by setting appropriate values for the register-pairs and then CALLing up the 'Print a sprite' subroutine at #9456). Where such a feature forms the only or final element of a room's Patch, then JUMPing to the subroutine instead of CALLing it means that there is no need to insert a RETurn command at the end of the Patch; the RET at the end of the existing subroutine will do the job of returning the flow of execution back to the Main Loop (or to the Room Setup Routine).
  5. Based on my recent observations, JSWII items cycle through five colours - blue, red, green, cyan and white.
  6. View File Jet Set Mixup 'Jet Set Mixup' is a redesign of Matthew Smith's classic ZX Spectrum 48K game 'Jet Set Willy'. It can be played on a real Spectrum, on the Sinclair ZX Spectrum Vega/Vega+ or on a computer, game console or another device using a ZX Spectrum emulator. The layout of 'Jet Set Mixup' is almost identical to that of 'Jet Set Willy', but most of the original guardians have gone on holiday, and have been replaced on duty by sprites from 'Manic Miner' and 'Jet Set Willy II'. Furthermore, the player is offered a choice of sprites with which they can play the game. We hope you enjoy this 'mixup'! Submitter IRF Submitted 07/21/2017 Category JSWMM Releases  
  7. View File Jet Set Mini "Willy has fallen on hard times. After living the high life for several years, he had frittered away his mining fortune, and found himself struggling with the upkeep of his sprawling mansion. So he had no choice but to downsize to a more modest pile. Things settled down for a while, but then he made the mistake of inviting a few of his old friends over to his new gaff for a housewarming party: 'Just a few quiet drinks, nothing major...' The morning after the night before, Willy wakes up in the bath with a throbbing hangover, to observe a disturbingly familiar scene. His house is trashed, all his friends have deserted him, an assortment of dangerous denizens have taken up residence - and his tyrannical housekeeper Maria won't let him go to bed until he's tidied up the place..." *********************************** 'Jet Set Mini' is a redesign of Matthew Smith's classic ZX Spectrum 48K game 'Jet Set Willy'. It can be played on a real Spectrum, on the Sinclair ZX Spectrum Vega/Vega+ or on a computer, games console or another device using a ZX Spectrum emulator. Willy's new abode in 'Jet Set Mini' is rather scaled down in comparison with his original mansion. But size isn't everything! Much of the code which was freed up by paring back the layout has been recycled, in order to insert a whole host of special effects into the game! Many of these changes are implemented via tools known in the trade as 'Patch Vectors', which are called up on a room-specific basis. There are also a number of generic modifications and enhancements to the game engine. However, the essence of this 8-bit, 48K game will be very familiar to connoisseurs of 'Jet Set Willy'. We hope it gives you 'no small measure of pleasure'! Submitter IRF Submitted 07/21/2017 Category JSWMM Releases  
  8. 333 downloads

    'Jet Set Mixup' is a redesign of Matthew Smith's classic ZX Spectrum 48K game 'Jet Set Willy'. It can be played on a real Spectrum, on the Sinclair ZX Spectrum Vega/Vega+ or on a computer, game console or another device using a ZX Spectrum emulator. The layout of 'Jet Set Mixup' is almost identical to that of 'Jet Set Willy', but most of the original guardians have gone on holiday, and have been replaced on duty by sprites from 'Manic Miner' and 'Jet Set Willy II'. Furthermore, the player is offered a choice of sprites with which they can play the game. We hope you enjoy this 'mixup'!
  9. 389 downloads

    "Willy has fallen on hard times. After living the high life for several years, he had frittered away his mining fortune, and found himself struggling with the upkeep of his sprawling mansion. So he had no choice but to downsize to a more modest pile. Things settled down for a while, but then he made the mistake of inviting a few of his old friends over to his new gaff for a housewarming party: 'Just a few quiet drinks, nothing major...' The morning after the night before, Willy wakes up in the bath with a throbbing hangover, to observe a disturbingly familiar scene. His house is trashed, all his friends have deserted him, an assortment of dangerous denizens have taken up residence - and his tyrannical housekeeper Maria won't let him go to bed until he's tidied up the place..." *********************************** 'Jet Set Mini' is a redesign of Matthew Smith's classic ZX Spectrum 48K game 'Jet Set Willy'. It can be played on a real Spectrum, on the Sinclair ZX Spectrum Vega/Vega+ or on a computer, games console or another device using a ZX Spectrum emulator. Willy's new abode in 'Jet Set Mini' is rather scaled down in comparison with his original mansion. But size isn't everything! Much of the code which was freed up by paring back the layout has been recycled, in order to insert a whole host of special effects into the game! Many of these changes are implemented via tools known in the trade as 'Patch Vectors', which are called up on a room-specific basis. There are also a number of generic modifications and enhancements to the game engine. However, the essence of this 8-bit, 48K game will be very familiar to connoisseurs of 'Jet Set Willy'. We hope it gives you 'no small measure of pleasure'!
  10. IRF

    Being a coder...

    Just back from pub - LOL!!!!
  11. IRF

    Moving the room data

    Norman Sword, you have reappeared here at a fortuitous moment! We are about to release a game called 'Jet Set Mini' (possibly later today, or tomorrow), which includes a fairly comprehensive readme file. This is an excerpt from the readme, which relates to a contribution that you made on jswmm.co.uk If you would care to have a quick read and pass comment, then we can take any such comments on board prior to the game's release. There is also an individual credit for you, see below. (We can change it if you would prefer to be credited as Derrick P. Rowson - if indeed you are he?)
  12. IRF

    Too many lives scenario

    Try the method I suggested, your new subroutine would only need to be six bytes I think. ;) Alternative sprite - have you tried replacing the value of #8726, from the default '82' to '81'. That should work, although the sprites picked up in some caverns might look a bit odd. :o
  13. IRF

    Too many lives scenario

    That should of course read "AND #07 would work instead"! (Original post corrected.)
  14. IRF

    Too many lives scenario

    You could insert an AND #0F just before the LD B, A at #8717. That way, no more than fifteen remaining lives would be displayed. You'd need to check whether that leaves room for the 'Cheat Mode' Boot sprite - I think it would, but if not, then using an AND #07 would work instead. ****** Either way, it would require two more bytes to be inserted near the start of the Main Loop, which is quite a tight part of the code. The simplest way I can think of to do that (with minimal code-shuffling) would be to replace the three-byte command at #8711 with a CALL to a subroutine located elsewhere (e.g. the spare addresses that are filled with source code remnants). Then at the remote location, insert the following six bytes: AND #0F (to bring A within the range 00-0F) LD HL, #50A0 (to replace the command which was displaced from #8711( RET
  15. IRF

    Useful Links

    Ignore the part in bold in my previous post - the code counts seven digits, via the E register, so it won't wrap around into an eighth digit! :blush: However, I was quite correct in my assertion that time won't run out when the clock reaches 0000000 - having just tried running a Geoff Mode game in SPIN until that point, it just starts again at 9999999! Geoff admits in the 'Time Counter' section of his 'Guide to Geoff Mode' webpage that: This no longer shows a time, but a 7-digit number which counts down from 9999999. This dates from the earliest days of Geoff Mode, and I can no longer remember why I did it. What he doesn't admit, though, is that the Time Counter is seemingly completely pointless! :D
  16. IRF

    Useful Links

    One other observation with respect to the Geoff Mode game engine - I don't think that anything will actually happen if the time counter (which counts down from 9999999) were ever to reach 0000000!? i.e. I can't see any evidence in the code that the game comes to an end, although the number of items collected up to that point might start to be decremented!?
  17. IRF

    Moving the air bar

    You would also need to change the value of #86D0 from #20 to #40 (that's to print the word 'AIR' in the right character-row).
  18. IRF

    Moving the air bar

    Did you apply the fix for the sound effect, when Willy clears a cavern? And I should emphasise: you'd have to change the value of the appropriate Offset Byte in the data for all twenty caverns, not just for Central Cavern.
  19. IRF

    Moving the air bar

    It isn't the #52 at #86D6 which you need to change. That just determines the height of the air supply pixel-rows within the chosen character-row. I think you would need to do the following: At #86DA: replace the #24 with #44 At #86DC: replace the #25 with #45 At #86E2: replace the #24 with #44 At #8A4C: replace the #24 with #44 Then in each individual cavern definition, add #20 to the relevant Offset Byte (#xBC, where x = 2,6,A or E). e.g. For the Central Cavern, edit #B2BC to replace the value #3F with #5F. ****** Warning: That might do odd things to the sound effect when the remaining air supply is counted down after Willy has completed a cavern! If you wanted to preserve the sound effect, then I suspect you would have to insert a SUB A, #20 immediately before the CPL instruction at #90D1. Fortunately, I have just identified two inefficiencies in the vicinity of that part of Matthew's code, which would free up the necessary two bytes to allow you to insert the SUB A, #20 with minimal code-shuffling: - At #90D4, there is a two-byte RLC A command which could be replaced with a single-byte RLCA; - At #90D7, there is a two-byte LD A, #00 command which could be replaced with a single-byte XOR A. (Don't forget to adjust the operand of the relative jump at #90E6 accordingly.) ****** Er, good luck!!!
  20. IRF

    Useful Links

    Having now investigated this, I am extremely pleased to report that I was correct, both in my diagnosis that there is a problem (a bug in the Geoff Mode game engine), and with my prescribed solution (which fixes the bug with a single POKE)!
  21. IRF

    Useful Links

    A few more errors/inefficiencies in the Geoff Mode disassembly (for my own future reference, if nothing else): https://web.archive.org/web/20030701143111/http://www.cix.co.uk/~morven/jsw/geoff_dis.html The opcodes in bold text above are erroneous, it should read 'C3 BC 8D'. Actually, it could read 'C3 92 8B', and jump to an identical bit of code which sits at the end of another subroutine (see below). Also, the RET command at #916C above is superfluous, as the preceding jump goes to code which ends in a RET back to the Main Loop. As I mentioned above, the minor sprite patch in italics is superfluous if the jump from #9169 is directed to #8B92 (see bold highlight below). The 'necessary context' which Geoff referred to above, is to distinguish between the 'NW-SE' and 'NE-SW' types of diagonal guardians. Contrary to the Geoff Mode documentation, Bit 4 of Byte 1 of a diagonal guardian's Definition Bytes is not flipped when non-wraparound guardians change direction. The references to various types of diagonal guardian in the above is messy. "double dy" in italics above should refer to a type 3 diagonal guardian, for example. The subroutine at #8DB1 should be introduced as 'Used for diagonal and wraparound sprites': The Geoff Mode documentation implies that, as in Matthew Mode, Bit 7 of Guardian Definition Byte 0 keeps track of the current direction of horizontal (and diagonal) guardians. However, I'm not sure that it does in Geoff Mode. The direction of horizontal guardians is tracked via Byte 4 (which is a signed byte and determines the velocity) - as is the case for vertical guardians in both game engines. At #9193-#919C, both Byte 4 and Bit 7 of Byte 0 are toggled - via a NEG command and an XOR #80 gate respectively - but I believe that the latter bit of code (i.e. #9199-#919C, in italics below) may be superfluous: EDIT: Actually, whilst Bit 7 of Byte 0 isn't used to keep track of horizontal guardians in the 'Move the Guardians' routine, it is used by the 'Draw the guardians' routine, in order to determine which set of sprite-frames to use for bidirectional sprites. No errors here, but I thought it would be worth emphasising a particular difference between Geoff and Matthew Modes, which Geoff doesn't explicitly mention in his notes. Namely that vertical guardians cycle forwards through their sprite-frames as they descend the screen, but backwards through their sprite-frames as they ascend: In contrast, Matthew Mode vertical guardians always cycle forwards through their sprite-frames, regardless of the status of their vertical trajectory. (So, to give a real example, the foliage on the Plant Pots in 'Jet Set Mini' are always growing outwards, before suddenly being 'pruned back' and starting again; if they were present in a Geoff Mode game, then the leaves would reverse direction and start 'shrinking' as the guardian started to move up the screen.) ****** Finally, I have a sneaking suspicion, from studying the code, that if a type 2 wraparound diagonal guardian (i.e. one that traverses at 14 degrees from the horizontal) has an odd number of increments defined in Byte 7, then it might fall 'out of phase' by one vertical increment, each time it wraps around. That could cause the guardian to 'stray from the path' - potentially leading to problems like the guardian colliding with elements of a room's layout. I have yet experimented to test this out, but if I am right, then it might be easily resolved by swapping the RET Z at #8B7D for a RET NZ. i.e. so that type 2 diagonal guardians are only vertically adjusted when the counter at Byte 6 holds an even value (instead of only being vertically adjusted for odd values of Byte 6, as is currently the case in the Geoff Mode game engine).
  22. Hi Mickey, Have you finalised this project? If not, there are (arguably) a couple of Water cells missing underneath the ramps in 'West Wing Roof' (at ground floor level, below and to the right of the ramp) and 'Back Stairway' (one of the water cells of the second platform from the bottom, again directly below the ramp). In the latter case, the contrast is quite striking with the way in which the ramp interacts with the bottom platform, and the other two platforms higher up the screen. If you did want to 'restore' them in your 'AMI' project, but can't see what I mean, then I'll try and do a couple of screenshots to illustrate where I'm talking about. :)
  23. I've just come to realise why a certain aspect of the MM/JSW code is the way it is. The convention when copying data from one place to another is to use HL (or the indexed equivalents, IX or IY) to point at the data that you're copying, and DE as the addresses to which the values are copied. (DE presumably signifying 'DEstination'?) That's how LDIR loops operate, and also how the 'Print a message' and 'Print a single character' routines work. But in the case of the 'Draw a sprite' routine at #9456, it is the other way round - DE points at the sprite graphic data, whilst the address to which to draw each byte, in turn, is defined via HL. The reason for this is that the test for pixel collisions uses an AND (HL) instruction. Furthermore, if no collision occurs, then the process of merging the sprite being drawn with the existing background graphic is done via an OR (HL) instruction. There are no such equivalent Z80 commands involving the DE register-pair. i.e. there are no AND (DE) or OR (DE) commands in the Z80 instruction set. So that is why the DE and HL register-pairs are used in the way that they are by the 'Draw a sprite' routine.
  24. The three byte command at #959A is unnecessary; if the program arrives there, then A already holds the number of the current room from #8420, having been assigned it by the identical command at #9534.
  25. Geoff Mode's 'Move the guardians' routine actually takes the above approach further, in order to update the animation frame of a guardian, and the x-coordinate of horizontal/diagonal guardians. In these circumstances, part of a guardian definition byte needs to be updated without altering the rest of the byte. That's easy for a single flag - just toggle the relevant bit (e.g. Bit 7 of Byte 0 which specifies the direction - use XOR 80). However, when a variable uses more than a single bit, it gets more complicated. One example would be the two bits that determine a guardian's current frame of animation, which sits within the same definition byte (Byte 0) as the guardian type (lowest bits) as well as its direction flag. Another example is a guardian's x-coordinate, which shares a definition byte (Byte 2) with the Base sprite. The more familiar approach (to me at least) is to: - load the byte that you're updating into the A register, - do an AND for the bits you don't want to alter, - save the output into another variable such as C, - load the value you want for the bits you do want to update to A, - do an OR C to merge the two elements, - and then reload the output of that back into the definition byte. Geoff used the sequence XOR - AND - XOR, which I think is more efficient(?), to update only the parts of a byte that need updating, and leave the rest of the byte unchanged. The operand of both XOR commands being the guardian definition byte under consideration, whilst the operand of the AND command selects only the bits that you want to update. e.g. to update a guardian's x-coordinate, he uses: [A register holds the new value of the guardian's x-coordinate, in Bits 0-4; whilst Bits 5-7 are initially blank] XOR (IX+$02) AND #1F for updating Bits 0-4 XOR (IX+$02) [Then load A back into (IX+$02)] The end result is that the x-coordinate of the guardian is updated, but its Base Sprite is unaltered.
×
×
  • Create New...

Important Information

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