Jump to content
Jet Set Willy & Manic Miner Community

IRF

Contributor
  • Posts

    5,105
  • Joined

  • Last visited

Everything posted by IRF

  1. I have taken the liberty of editing the title of this topic from 'The AND instruction' [as it was when started by jetsetdanny] to 'The AND, OR and XOR instructions', to reflect more inclusively the discussions of the use of those instructions in the thread as a whole. This is a good place to mention a cunning use of the OR command - namely something which Norman Sword came up with, to fix the bug in the original Manic Miner game engine whereby crumbling cells can sometimes leave ghosts. The original MM engine clears the bottom pixel-row of a crumbly cell when Willy stands on it, then shifts all the pixel-rows above down by one pixel-row, and then checks the bottom pixel-row - and if it is empty, the program considers that cell to be cleared and replaces the crumbly colour-attribute with the air cell attribute for the current cavern. The problem with that approach is if you have a crumbly cell pixel pattern with a clear (inkless) pixel-row halfway down the cell, with some infilled pixels in the pixel-rows above that blank row - then the program is fooled into turning the crumbly cell to air prematurely, leaving a 'ghost' of the uncleared pixels in the top part of the (now air) cell. Norman Sword rewrote the crumbling cell routine (as discussed elsewhere), so that all eight pixel-rows of a crumbly cell are OR'd together whenever Willy stands on the cell. After clearing the Accumulator (A register), a loop is set up to apply the OR command to all eight bytes representing the bitmaps for each pixel-row of the crumbly cell. (i.e. pixel-row 1 OR pixel-row 2 OR row 3 OR row 4 OR row 5 OR row 6 OR row 7 OR row 8). If a single pixel is infilled in any one of those pixel-rows, then the Zero flag will not be set at the end of the loop. Only if all eight crumbly rows are clear (all eight bytes which are OR'd together hold the value 00) will the Z flag be set - with the outcome that the crumbly cell gets changed to air [by changing the cell's attribute]. In Manic Mixup, I adapted Norman's code, based on the OR command, to be used both in underfoot crumbly cells, and also whenever Willy uses his hard hat to headbutt away an overhead earth block (which causes the pixel-rows to be cleared in the opposite direction i.e. the rows are shifted from the bottom upwards).
  2. The typo MtM referred to appeared in the scrolling message on the title screen. (Now corrected though.)
  3. It was possible (in the most recent build you uploaded, in Trainer mode) to 'disappear' off the top of the Central Cavern by jumping up off the top of one of the spiky bush nasties on the top platform. When you go past the top of a cavern in the original Manic Miner game engine [in a modified game because none of the original cavern layouts allow it], Willy's head temporarily appears at the bottom of the screen, and furthermore the attempt to draw Willy 'out of bounds' also causes corruption of the game file itself. I presume that your rewrite of the game engine has eliminated such issues though?
  4. You mean hitting his head on the red and yellow (stripy) block? As MtM has pointed out, you just need to walk on a bit further leftwards before jumping. From your comments, I believe you must have assumed that the white square-shaped blocks act like JSW64-style Trap cells (i.e. if you step on one you fall through, even if you are also standing on a solid block with the other half of Willy's sprite). Whereas in fact, they just seem to behave like Air cells with a pixel pattern (so you only actually fall through if Willy's sprite is spanning two of the white square-shaped blocks). ** Something else which I've just noticed in 'Manic Panic' is that the Fire cells (e.g. the spiky 'poisonous pansy' bushes) are solid, such that Willy can stand/walk/jump on them without falling through - although it saps the air supply if you attempt to do that. In contrast, in the standard MM/JSW game engine, if you hack the engine to turn off the fatal outcome whenever Willy comes into contact with a Fire cell, then he will fall through Fire cells as if they are Air - with the added quirky behaviour that, even if the other half of his sprite is atop a solid block, he will still fall through both the Fire cell and the adjacent solid block. (In fact, that is how John Elliott created Trap cells in JSW64 - they are just non-lethal Fire cells.)
  5. Nice music*, and the long scrolly message is intriguing. (*There are a few bum notes in 'Fur Elise' though.) P.S. This latest file works in Torinak, unlike the previous builds. :)
  6. This is the bug that you're talking about; it only affects the Solar beam cavern: https://skoolkid.github.io/manicminer/reference/bugs.html#nineLivesInTheLight
  7. These files don't seem to work on the online emulator 'QAOP' which I tend to use. I managed to get them working okay on SPIN though.
  8. I did download the file last week and played all the introductory screens and up until the end of the Central Cavern, but didn't get chance to post yet due to 'real life' work pressures. Anyway, what I saw was excellent, and I'm intrigued by the one cavern in the first post's screenshots which I didn't manage to reach yet - the kind of Spiral Staircase affair. Thanks for posting this project, NS, and for the detailed description of the collision logic as well. I have a question: I notice that not all of the master pixel buffer is copied to the working pixel buffer during each pass through the main loop - instead, only those elements of the screen that have had their pixels changed since the previous pass are updated. I presume this is primarily to speed up the game. My question is: could the same logic not be applied to the attributes (admittedly for a more marginal improvement in speed)? i.e. Instead of copying all of the master attribute buffer to the working attribute buffer during each loop-pass, just update those parts of the screen where Willy or a guardian's attributes have changed things since the previous pass?
  9. I'd forgotten about The Final Barrier, it's actually a good example of what I was talking about. Some of the cells in the upper half of the cavern are drawn using data that is supposed to represent Willy's start position, movement flags, fall counter, etc for the top seven pixel-rows, and the conveyor direction byte for the bottom pixel-row of the cell. In other cases, the Cell Graphics Bug causes 'classic' corruption of cells in the upper half of The Final Barrier - like you see in several rooms in JSW - where the defined attribute value inadvertently matches with a graphical byte value (one of the defined cell bitmaps). But of course, none of this is ever seen in The Final Barrier - it happens 'behind the scenes' in the pixel-buffer, but is then overwritten by the graphic from the title screen before gameplay commences. I don't think the search will ever go beyond the address #8068 that immediately follows on after the end of the cell graphics table, where HL is left pointing if the CPIR loop comes to an end without a match. So there's no danger of a scan through the whole of memory (unless a patch has been applied that is based on an unbounded search, as per Skoolkid's or J.G.Harston's methods). But I agree that it would be good to reduce the length of the CPIR loop by 9 (i.e. reduce the value assigned to BC by 09, prior to the CPIR being executed), so that the 'default' graphic for a 'none of the above' cell type can be defined and controlled, rather than the program picking up unassociated data for the purpose. That would also have the benefit that you would be able to have different coloured switches within a single Kong cavern. (The switch graphic definition uses the last slot in the table of cell graphics, and collision-detection between Willy and a switch isn't attribute-based.)
  10. Incidentally, you can see the effect of a bounded search in action in Manic Miner (albeit that the data picked up falls beyond the intended range of the bounded search, if you insert* an attribute value into a cavern layout which doesn't match with any of the attribute or graphical bytes in the cavern's cell definitions. (*e.g. Manually via the Hex Editor, not in JSWED's GUI.) What happens is that when the CPIR loop comes to an end having failed to find a match after searching through the range of addresses #8020-#8067, HL is left pointing at the next address in the cavern buffer: #8068. The next eight bytes - #8068-#806E (various parameters which define Willy's state upon entry to the cavern) and #806F (which defines the conveyor direction for the cavern) are then interpreted as graphical bytes to draw the pixel pattern of the errant cell.
  11. Sorry yes, not a search in the sense of looking for a matching value. I was picking up the terminology introduced by Zub about unbounded vs bounded searches, and trying to make the point that your method (like his) will only use data from within a fixed, intended range.
  12. For reference, Norman Sword's fix for the CGB (as part of a more fundamental rewrite/optimisation of the Room Expansion routine) is listed here: http://jswmm.co.uk/topic/496-source-code-for-jsw/?p=11166 It involves a bounded search. (P.S. My tablet attempted to autocorrect that to "a bouncer search", which sounds like a plotline from Neighbours during the 1980's.)
  13. Also J.G.Harston's 'JSW Extensions' page was updated in 2017, which seems to be when he added the CGB fix. So Stuart (Zub)'s fix on this forum seems to have been the first to be 'published' (unless you count Skoolkid's Github entry, prior to it being transposed to a disassembly update).
  14. IRF

    Portal Change Idea

    Can't do that in Manic Miner. If you try to jump over the portal when traversing at the lower level, then Willy doesn't land on the far side, but drops into the portal, and you have to jump back out again. (But with your modification, he would die before he got the chance to jump back out!) You could perform such a jump in JSW, but only when jumping from right to left, not vice versa.
  15. IRF

    Portal Change Idea

    I think the check for whether Willy has entered a portal comes before the test for a standonable (or jumpoffable) platform underneath Willy. Otherwise, Willy wouldn't be able to survive falling into the portal in Return of Kong...
  16. For 'compare and contrast' purposes, Dr Broad's original versions of the JSW->MM and MM->JSW conversions are available within this Zip folder: https://jswcentral.org/download/02-jsw48/a/oth/party_willy.zip
  17. Further to the above, I've made a short recording (see attached) to demonstrate a 'proper toilet run' incorporating The Nightmare Room. Look at his little trotters go! As it turned out, no use of the 'P' key bug to pause* Willy in order to avoid guardians was actually necessary - though it was a close-run thing with the red Maria! That's just as well, because in the test file that I previously prepared to demonstrate the alternative toilet run - upon which I based the recording - I had 'fixed' the 'P' key bug so it no longer functions to pause the toilet run. (Incidentally, I also fixed the 'jagged finger' visual flaw identified by Norman Sword, since it was particularly prominent during the toilet dash what with the sprite moving so fast.) In the recording I also started off the toilet run in The Banyan Tree, to extend the run as much as possible, and as an added bonus I hit the Jump and Right keys just before applying the POKE to commence the sequence, so that it starts off with a nice 'Superjump' over the yellow saw guardian. B) (* 'P' for 'Pause'? Hmmm..... maybe it was a feature not a bug all along!?) Proper Toilet Run through Nightmare Room.rzx
  18. UPDATE: It's just occurred to me that if you were to implement the above, and then instigate the toilet run in The Nightmare Room, the pig sprite would run with its little legs without flapping its wings! If you load up the 'Proper Toilet Run' test file which I attached four posts above this one, start the game & navigate to The Nightmare Room (preferably the left-hand side of that room to see the effect in full), and then apply Mickey's POKE 34271,2 then you can see what I mean. From that position, you should be able to complete the game too (possibly with some judicious use of the 'P' key to dodge the Nightmare Room guardians), as once you leave that room and revert back to the Willy sprite, there's just a straight run up the full length of the ramp in First Landing and on to The Bathroom!
  19. P.S. If you wanted a pure tone of #40, then you would need to use a pair of pitch values #40 and #20. (I don't think it would matter in which order the two values are stored in the data, as long as one is half the value of t'other.) In terms of Andrew's original JSW->MM conversion, the upshot is that the pure tone version of 'Moonlight Sonata' plays the lower pitched half of each note (as if the doubling of pitch that you get in the JSW engine was applied immediately, instead of halfway through each note). Rather than only playing the higher pitched half of each note (which is what you get if you just NOP out the RL E command from #96BC in the JSW game engine).
  20. Explanation for the above: say you had a set of three pitch values for a MM title tune note of #32 [the duration], #40 and #80 [pair of pitch values]. Those values are assigned to the C, D and E registers respectively. The inner note playing loop decrements D and E once for each pass through the loop, and when either of those reaches zero then an XOR #18 command is executed - meaning that the speaker state will be toggled at the start of the next pass through the inner loop - before D or E is reset back to its original value for this note. (The inner loop is controlled by the B register, which is set to #00 at the start, and that effectively means #100 iterations since B is decremented to #FF before a check for a zero value is made. The outer loop decrements C to repeat all of the above C times, meaning that the duration of the note is C x #100 iterations of the inner loop [#3200 iterations in the above example].) But if you have two pitch values which are exactly separated by a factor of 2, as in the above example, then the following happens: On the #40th iteration of the inner loop, D has reached zero so an XOR #18 activates the speaker. On the #80th iteration of the inner loop, D and E both reach zero so XOR #18 is executed twice; those operations cancel each other out*, so the speaker is not activated. On the #C0th iteration, D has reached zero again so XOR #18 activates the speaker. On the #100th iteration, D and E both reach zero so XOR #18 is executed twice; those operations cancel each other out, so the speaker is not activated. B has now reached zero which brings an end to the inner loop for now. Then C is decremented and the whole of the above is repeated, until C reaches zero, bringing the outer loop to an end. (Then there is a check for whether the ENTER key is being pressed to start the game - if not, then the next note will be played [next set of three note definition bytes will be considered].) If you look at the above pattern, you can see that - except for in the very first instance shortly after the start of the loop - the speaker diaphragm is only actually activated once every #80 passes through the inner loop. So the note that is played has a pitch of #80, corresponding to the lower of the two pitches represented by the note data (i.e. the numerically higher of the two pitch values, since a smaller number yields a higher pitch and vice versa). (* Applying XOR #18 to the A register, and then applying another XOR #18 to A, is effectively the same as applying XOR #00, which has no effect on the value in A.)
  21. Of course, the time-consuming bit would be working out all the datapoints for the table...
  22. If there was space in memory for it, then the following code could be adapted for the purpose. (It's something which I came up with for Daniel Gromann's recent 48K conversion of Fabian Alvarez Lopez's 128K JSW game 'Madam Blavskja's Carnival Macabre'.)
  23. Norman, am I right in thinking that the piano keys on the title screen now light up 'correctly'? i.e. they accurately represent the notes which are being played at the time, so that if you were to reproduce the visual pattern on a real piano then you would end up playing the tune faithfully? And assuming that is the case, then I have a follow-up query: are the appropriate attribute addresses on the screen worked out in your rewritten version of the title-tune routine, using a logarithmic calculation method (as opposed to the linear method in the original MM, which leads to incorrect keys being highlighted)? Or alternatively, does your rewritten routine use a look-up table to determine which piano keys (i.e. which attribute addresses on the screen) to highlight, based on what note (i.e. which pitch value) is being played?
×
×
  • Create New...

Important Information

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