Jump to content
Jet Set Willy & Manic Miner Community

IRF

Contributor
  • Posts

    5,105
  • Joined

  • Last visited

Everything posted by IRF

  1. Yes, since I wrote my post last night I was playing around in one of your earlier test files, and I noted that the 'sinking into the wall' didn't occur as Willy walked along the top of the 'parapet' wall block towards the bottom of the ramp in 'On top of the house', so I assumed you must have also altered the 'Draw Willy' code in some way (not necessarily in the same way that I suggested above).
  2. I have compiled various bits of code to try and achieve the same thing (in relation to the movement along ramps in the vicinity of wall tiles), but I haven't yet had a chance to sit down and put it all together into a working test file. It will be interesting to see if it achieves the same thing as your code (assuming mine works!) EDIT: Having now studied Norman's code, it seems to be addressing the same issues. However, I also had a notion to amend the routine at #95C8. Otherwise when Willy walks down a ramp and steps onto an adjacent wall/Earth block ( a la 'On top of the house'), and he's in a position where his front foot is on the wall but his back foot is still on the ramp, then his sprite will be drawn progressively 'sunken down' into the wall as his animation-frame progresses within the same pair of cell-columns - until he transcends the next cell-column boundary and moves beyond the influence of the ramp tile (at which point his sprite will appear to suddenly 'spring back up' onto the top of the wall tile, because the downwards vertical displacement normally caused by the ramp has been cancelled out in this case). Therefore, I would propose to edit the start of the routine at #95C8 as follows (new elements in bold, relocated elements in italics): LD HL, (#85D3) ; Willy's attribute coordinates LD B, #00 ; default vertical offset (in case Willy is not on a ramp) LD A, (#85D1) ; might as well place this earlier - if Willy is jumping then no need to test for underfoot ramp cell OR A JR NZ, vert_offset_dealt_with LD A, (#80DA) ; Ramp direction byte AND #01 LD C, A ADD A, #40 LD E, A LD D, B ; incidental one-byte efficiency here, compared with original code ADD HL, DE LD A, (#80C4) ; ramp attribute byte CP (HL). ; Is Willy's 'up-slope' foot on a ramp cell? JR NZ, vert_offset_dealt_with. ; If not, keep B=0 OR A SBC HL, DE. ; restore Willy's attribute coordnates in HL LD A,C ; A now holds either 0 or 1 XOR #01 ADD A, #40 XOR #41 ; I think this will do the same as the two operations struck-through above, but in one two-byte operation? ; (given the limited possible input values of A) LD E,A ; D already holds 00 ADD HL,DE LD A, (#80B2) ; Earth/wall attribute byte CP (HL). ;Is Willy's 'down-slope' foot on an Earth/wall block? JR Z, vert_offset_dealt_with. ; If so, keep B=0 That then leads into the code originally at #95E4, which calculates the vertical offset when Willy is standing on a ramp. #95F8 is the jump destination labelled as vert_offset_dealt_with in the above.
  3. I ran out of time last night. I intend to provide more commentary when I have the time (particularly in relation to the need to complement the Carry Flag), but I think you've grasped the gist of it. I've also come up with a further optimisation which negates the need to take the Carry Flag into account in that way (and saves another four bytes), by replacing the JR C with a JP PO (responding to the Overflow Flag, with the conditionality the same for both left- and right-moving guardians). However, it's a bit of a fiddle as it involves swapping the half-pages of each bidirectional sprite (otherwise they walk backwards!), amongst other changes. It is possible to do it whilst preserving all the original behaviour though.
  4. I am pleased to report that I've managed to achieve the above (my suggestion in bold). The following code will handle horizontal guardians moving both leftwards and rightwards, and it saves 21 bytes compared with Matthew's original code: Starting at #9133: PUSH IX ; copy the address of Byte 0 of the guardian definition POP HL ; to the HL register-pair LD DE,#E0FF ; parameters for a LD B A,(IX+$06) ; guardian moving left BIT 7,(HL) JR Z, left LD DE,#2001 ; parameters for a LD B A,(IX+$07) ; guardian moving right left: LD B,A LD A,(HL) ADD A,D ; increment animation-frame of guardian BIT 7,(HL) ; sets the Zero Flag for a left-moving guardian LD (HL),A ; update guardian definition Byte 0 with correct animation-frame JR Z,carry_okay CCF ; Complement the Carry Flag for a right-moving guardian carry_okay: JR C,#91B6 ; not time to update the guardian's x-coordinate; proceed to Move the next guardian XOR #80 LD (HL),A ; time to update the guardian's x-coordinate, so reset the animation-frame to the first one for the next cell-column LD A,(IX+$02) ; guardian definition byte 2 LD C,A ; temporarily save in the C register AND #1F ; extract guardian's current x-coordinate CP B ; has the guardian reached the extremity of its range in the current direction of travel? JR Z,turn_around ; if so, jump to reverse its direction of travel LD A,C ; retrieve guardian definition byte 2 ADD A,E ; adjust x-coordinate LD (IX+$02),A ; and save JR #91B6 ; proceed to Move the next guardian turn_around: LD A,(HL) ; we're not updating the x-coordinate after all, XOR #E0 ; instead we are switching to consider the other set of four animation-frames LD (HL),A ; [assuming it's an eight-frame bidirectional sprite; if not, then filtering out of unwanted frames is done at the 'Draw the guardians' stage] JR #91B6 ; proceed to Move the next guardian [#916A to #917E is now free; this may be sufficient to implement Norman Sword's 'mid-sprite bounce' - that's my next area for investigation...]
  5. I don't think it would make a difference. It's only one Air block in each row - you need two consecutive Air for Willy to fall through.
  6. The following idea only saves a single byte, but I consider it to be a most satisfactory arrangement: - Replace the 'INC HL' at #96C6 with a 'DEC HL'; - Take all the notes of the Title Screen tune, reverse their order, and insert them into the range of spare addresses starting at #8141, such that the last note of the tune occupies the address #8141; - Edit the operand of the LD HL, $0000 command at #88A8, to point at the new position of the first byte of the Title Screen tune (the first note now occupying the highest used address in page #81 of the code). The Guardian Buffer Terminator Byte (value #FF) at #8140 now serves a dual purpose, as it also serves to terminate the Title Screen tune! N.B. Under this arrangement, the Title Screen tune now has a maximum length of 191 bytes (not including the Terminator Byte), because page #82 of the code is used as the Screen Buffer Address look-up table).
  7. POKE #F4DB,#E1 - this moves the ramp in 'Back Stairway' one cell to the left. As Willy walks down it, you might think he is about to move diagonally downwards to the room below and to the left (i.e. 'Tool Shed'). But in fact, he moves back up again as he crosses the horizontal edge of the room, ending up on the conveyor in 'Back Door'.
  8. Yes, the ability to land on the head-height wall - when he should jump right over it - and the way that Willy can fall through solid blocks - if he jumps from a certain position - are 'two sides of the same coin', as I see it.
  9. I have created four screenshots (attached) to illustrate one of the differences between the jump mechanics in the JSW1 and JSW2 game engines. Willy is making a jump over a head-height pillar of Earth blocks in 'Tree Top'. He starts his jump from the position shown in the screenshot named 'Tree Top Jump 1'. In 'Tree Top Jump 2', Willy is on the descent and is exactly one vertical increment above the top of the upper solid block. With the original JSW1 game engine, the screenshot 'Tree Top Jump 3a' shows what happens in the next time-frame - Willy lands on the top of the tree trunk, one frame of animation short of going over the edge. With the JSW2 game engine (or in this case, the JSW1 engine hacked to behave like JSW2), the screenshot entitled 'Tree Top Jump 3b' shows the 'alternative reality' behaviour - in the next time-frame after the second screenshot was captured, Willy has been moved along by an increment vertically downwards but also one increment horizontally [in this case leftwards]. Therefore he overshoots the top of the tree trunk, and in subsequent time-frames (not shown in the attached), he proceeds with the descent part of his parabolic jump trajectory, dropping down on the far side of the solid blocks. This explains why Willy gets 'stuck in the hole' in the JSW2 'Bathroom' test file that I uploaded earlier in this thread.
  10. The above does technically save three bytes. However, they are left adjacent to the single unused byte within the main 'Draw the Guardians' routine, which isn't a very useful place. But I think I've come up with a way to shorten the 'out of situ' part of the patch, which would yield a couple of spare bytes in a more usable location. (If it works!)
  11. Just to expand on my point about 'consistent logic', when Willy is moving into a vertically adjacent room, the AND B filters the bits which represent Willy's unchanged horizontal position, then the OR C sets the appropriate bits for his new vertical position. So for 'Exit Up', BC=$1FA0. For 'Exit Down', BC=$1F00.
  12. Given that the AND now comes before the OR, it's possibly more elegant, logical and consistent to use LD BC, $E01E when moving into the room to the left. i.e. For both 'Exit Left' and 'Exit Right' (for which BC=$E000), pass the bits which represent Willy's (unchanged) vertical position through the AND B gate, and then set the bits which determine his (new) horizontal position via the OR C gate. Although it makes no difference to the final outcome. And of course, it's another excellent bit of optimisation that you've come up with!
  13. I've played around with this now - in JSW2, in addition to Willy not being able to fall as far* after hitting his head on an overhead Earth block during a jump, he also progresses forwards by one animation-frame during the first two time-frames of descent, but then he stops moving horizontally for the rest of his descent. Whereas in JSW1, his horizontal momentum is completely curtailed when he bangs his head on an overhead Earth block. (*He can only drop to a level that is three cell-rows lower than the apex of his jump without being killed, which is less than the four rows through which he can safely drop if he has head clearance. In JSW1, hitting his head on Earth actually allows him to fall a greater distance than he could if he made the same jump with head clearance.)
  14. Move Willy into the room to the left: #9493 OR #1F #9495 AND #FE can be replaced (I think?) with: OR #1E Move Willy into the room above: #94BD LD (#85D3),A #94C0 LD A, #5D #94C2 LD (#85D4),A replace with: LD L,A LD H, #5D LD (#85D3),HL Move Willy into the room below: #94ED LD (#85D3),A #94F0 LD A, #5C #94F2 LD (#85D4),A replace with: LD L,A LD H, #5C LD (#85D3),HL **** Some other savings can be made across the four 'move to another room' routines, by sharing a common ending (POP HL/JP #8912) via relative jumps. Also, rearrange the various components of 'Move up' and 'Move down' so that the LD (#85CF), A and LD (#85D3), HL commands are shared by those two routines. I think all of the above should cumulatively save about 18 bytes?
  15. This is the only thing that I could find, courtesy of John Elliott: https://www.seasip.info/Jsw/jsw2room.html
  16. Sorry Andy, was the above comment in relation to the conveyor behaviour (at the left-hand of the conveyor) in JSW2? I appreciate I've been discussing several different phenomena at once, so it's difficult to keep track! (P.S. The reference to "that platform" didn't help with my confusion - I presume you're referring to Amstrad as the platform as in hardware, rather than a platform as in standonable room cell!? :-p)
  17. Last few for now: - In JSW2, in a room with a narrow passage along a conveyor with Earth blocks located two rows above Willy's head, you can't perform the trick of pressing the Jump and [opposite sideways movement key to the direction of the conveyor] simultaneously, and then keeping the 'opposite L/R' key depressed, to bring Willy to a halt on the conveyor (as you can do in 'Tree Root', or in the Final Barrier in MM) - Willy's progress along the conveyor can be slowed down, but not stopped; - Conversely, in JSW2 Willy can progress 'upstream' along a conveyor in a similar scenario (with Earth blocks two rows above the conveyor) by jumping up onto the conveyor - in JSW1, Willy would bump his head on the overhead Earth block, and this would reset his Movement Flag, preventing him from proceeding up the conveyor. [Looking at Andrew Broad's list of quirky features for JSW2, hitting an overhead Earth block during a jump also alters Willy's Airborne Status Indicator in a different way as well, meaning that he can't fall as far afterwards as he can in JSW1 - although I haven't explored this behaviour yet.)
  18. There's something strange and asymmetrical about JSW2 conveyor behaviour. Try starting up the game (with Willy at the left of the bath, facing right) and keep the jump key depressed, without pressing any sideways movement keys. Willy jumps straight up, then turns around and proceeds leftwards by one increment at a time, in between a series of vertical jumps - rather than being sent into a leftwards jump by the action of the bath (which is a left-conveyor), as occurs in JSW1. But if you start off with Willy in the middle of the bath, and try to perform vertical jumps, then he is sent jumping leftwards as you would expect. And if you perform a similar (mirror imaged) set of jumps at the right-hand end of the 'ballroom table' (i.e. the right-conveyor in 'Ballroom West'), then Willy is sent into a rightwards jump (which is more in line with JSW1 conveyor behaviour). **** A more well-documented difference between JSW1 and JSW2 is that, in the latter game engine, Willy can safely jump over a head-height Fire cell (provided he starts the jump from precisely the right position). Completing the room 'The Garden' wouldn't be possible without this, although it does provide Willy with a 'short-cut' out from the upper Ballroom platforms without having to climb up the East Wall (by jumping over the spider at the top-right of 'To the Kitchens...Main Stairway'). I would speculate that this manoeuvre is possible because the routine which draws Willy's attributes (and checks if he has collided with, or stood upon, Fire cells) doesn't make a check for underfoot Fire if Willy is jumping (or at least, if he is on the ascent part of a jump)?
  19. I've just spotted a couple of changes to the layouts of classic rooms in JSW2: - In 'The Bow', the Water platform with the 'ship's wheel' item at the end of it, has been extended by one cell - this was presumably done to overcome the difference in the jumping behaviour when Willy is up against the adjacent Earth pillar (which extends two cells higher than the Water platform); just as in 'Banyan Tree' or The Bathroom in my earlier test file, Willy cannot jump up and land on top of the Earth pillar unless he steps far enough back from it (hence the need to extend the 'ships wheel' supporting platform); - In 'Under the Drive', one of the platforms to the left of (and two cell-rows higher than) the end of the conveyor has been moved leftwards by one cell-column - without that change, the difference in the sequence of the 'Move Willy' routine presumably meant that Willy would have missed that platform at the end of the sequence of three consecutive jumps after entering from 'Tree Root'. **** This doesn't involve a layout change between JSW1 and JSW2, but there is a change in Willy's behaviour - when Willy walks down the flagpole in 'On top of the house', in JSW1 he passes through the wall/Earth block at the base, and then emerges out the other side of that block and carries on his way (until the next wall blocks him from walking any further). But when performing the same manoeuvre in JSW2, he once again walks into the first wall block, but he is then prevented from proceeding any further unless he jumps out of that wall block.
  20. Sorry, in my previous response I thought you were considering a 'turn around and jump' scenario in 'Priest's Hole'. In the situation your screenshot depicts, the 'safe' way to do it is to ensure that Willy is positioned two steps away from falling off the platform (i.e. two steps if he were to walk forwards), and then perform the jump/hold jump/press left sequence of keypresses. **** There seems to be another quirk at play. If you stand somewhere on a solid floor (with no overhead obstacles), press Left+Jump simultaneously, and see how many horizontal increments Willy has moved on by when he lands at the end of the jump, it is one more increment than if you do a vertical jump first and then hold down Left+Jump whilst he is still airborne. I wonder if, in the single time-frame when Willy lands, he is responsive to horizontal keypresses but not to the jump keys? That could explain the difference in behaviour for both of the above scenarios. I don't suppose there's a disassembly of the JSW2 game engine available anywhere, is there?
  21. I believe that there may be differences in some of the entries in the left-right movement table (the equivalent of the table at #8421 in JSW1) in the JSW2 game engine, which have the result that if Willy is facing rightwards and you press left (or vice versa), then he doesn't just turn around but his animation-frame is also incremented at the same time. This allows him to jump leftwards and then rightwards in quick succession (whereas in JSW1 if you try to do that, he will turn around upon landing but do a vertical jump before performing the jump back the way he came from). One way to get around this effect in the 'Priest's Hole' scenario is to have Willy standing on the edge of the platform facing away from the direction he is about to jump, and then press the 'opposite left-right' key and Jump key simultaneously. Then he will turn around and jump without falling off his precarious perch! **** However, this 'turn around and move at the same time' effect doesn't explain what is going on in my 'JSW2 New Quirky Feature' test file. If you move Willy into the bottom-right corner, facing right, then press Left+Jump simultaneously (so that he turns around but starts the jump from as far right a position as possible), then he still jumps all the way over the pillar and falls down into the hole on the other side. Conversely, in the test file based on the JSW1 game engine, you can walk Willy all the way up to the two-high Earth block pillar (facing it and touching it), and then jump up onto it without him falling down into the hole on the far side - he lands on top of the pillar, one animation-frame short of falling past it. **** During my earlier experimentation, playing around with the jumping routine in JSW1, I managed to recreate the behaviour seen in JSW2, in my 'Jump Code rewrite' test file (http://jswmm.co.uk/topic/185-free-space-and-code-optimisation-in-jsw/page-20?do=findComment&comment=8311). In fact, I came up with that test file, and discovered the 'different' jumping outcomes, before I spotted the similar behaviour manifesting itself in JSW2. I believe that the difference in the JSW2 jumping behaviour may arise because in each time-frame of a jump, the check for a solid underfoot platform (to curtail the descent phase of a jump) takes place before Willy's y-coordinate is incremented downwards.* Whereas in the JSW1 game engine, he is moved downwards during a jump before the check for underfoot behaviour takes place. That, I believe, is the fundamental reason why Willy can jump into supposedly solid blocks. So really, it is the JSW1 jumping that is the illogical and quirky behaviour - Willy shouldn't be able to jump up onto a two-block high wall (such as you get in 'Banyan Tree') unless he takes several steps back from it before taking the jump. I'll try to create a few frame-by-frame screenshots later to illustrate exactly why that is the case. (*EDIT: Either that, or both vertical AND horizontal incrementations of Willy are performed in JSW2 before a check for underfoot platforms is made - actually, that might explain why Willy is able to jump into the slots in 'Wine Cellar' without his head entering an Earth block on the way down.)
  22. Furthermore, I've just discovered an even stranger quirk in the previously-uploaded 'JSW2 New Quirky Feature' test file. Start up the game, then immediately press Right+Jump simultaneously and keep them depressed - Willy lands on the original Bathroom tap, and eventually the new tap item if you keep those keys depressed, without collecting them!!
  23. I am not aware of any previous discussion of this quirky feature of Jet Set Willy 2 - it isn't mentioned in Andrew Broad's fairly comprehensive list of quirky features. If you open up the attached 'JSW2 New Quirky Feature' test file, and try to collect the new Bathroom tap, you'll find that Willy gets stuck, with no hope of escape! But in the other attached file, 'JSW2 New Quirky Feature not in original JSW', which has the exact same layout changes implemented to The Bathroom, Willy can collect the new item behind the newly-inserted walls, and get back out again. Curious! The subtly different behaviour could form the basis of a frustrating trap in a modified game based on the JSW2 game engine! (Not with an item at the bottom of the hole, though, as that would render the game uncompletable without loss of a life.) N.B. It might be prudent to have an occasional arrow come along at head-height, to put Willy out of his misery if he gets stuck! JSW2 New Quirky Feature.z80 JSW2 New Quirky Feature not in original JSW.z80
×
×
  • Create New...

Important Information

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