Jump to content
Jet Set Willy & Manic Miner Community

'Guardian Aura' Bug Fix and miscellaneous other patches


IRF

Recommended Posts

Here is a patch for the bug that is seen in Jet Set Willy in non-Black rooms, if a Guardian is present that has a different Brightness setting to the Air cells in that room. e.g. The Flying Pig in Emergency Generator.

 

The following 'new' code should be added - I suggest you locate it between #96f4 and #970b:

 

7e e6 38 c2 f2 91 dd 7e 01 e6 0f c6 38 e6 47 4f 7e e6 38 a9 4f c3 fd 91

 

Then the existing code at #91ee to #91fc should be edited as follows (this is based on the suggested starting address for the new code listed above):

 

c3 f4 96 00 dd 7e 01 e6 07 4f 7e e6 78 a9 4f 00

 

[bold and strikethrough text in the above represents Danny's previous suggested improvement]

 

Looking again at the above, there are two bytes which are common to both chunks of code, and located at the substantive end of each ('A9 4F').  So perhaps the new code could be two bytes shorter, jumping back to resume working through the main 'Draw the guardians' routine at the 'A9' command, instead of at the '71' LD (HL), C instruction (at #91FD)?

 

The more efficient code would go as follows:

 

'New' code at #96F4 to #9709 [or wherever]:

 

7e e6 38 c2 f2 91 dd 7e 01 e6 0f c6 38 e6 47 4f 7e e6 38 c3 fb 91

 

Existing code at #91ee to #91fa edited as follows (the address in italics can be changed accordingly to point at the above 'new' code; the spare NOPped out byte is in bold):

 

c3 f4 96 00 dd 7e 01 e6 07 4f 7e e6 78

 

That is then followed by the re-entry point from the 'new' code, at #91fb:

 

a9 4f ... etc

 

[Of course, if the additional code could be consolidated to sit inside the main loop, or somewhere within 128 bytes of the source routine, then two of the absolute jumps could be replaced with relative jumps, and one of the absolute jumps could perhaps be done away with altogether, providing a further saving of up to five bytes.  But the routine is in quite a 'tight' part of the code.]

Edited by IRF
Link to comment
Share on other sites

  • 3 weeks later...

Update: Not only does the above optimisation work fine (saving two bytes), there is also another three-byte optimisation to be found.

 

Currently, the 'new' section of code (called from the main 'Draw the Guardians' routine) is as follows:

 

7e e6 38 c2 f2 91 dd 7e 01 e6 0f c6 38 e6 47 4f 7e e6 38 c3 fb 91

 

It can be shortened to this:

 

7e e6 38 c2 f2 91 4f dd 7e 01 e6 0f c6 38 e6 47 c3 fb 91

 

You can see that the '4f' instruction (LD C, A) has been moved back in the code, and two commands (of total length three bytes) '7e e6 38' have been removed.  Those two commands:

 

LD A, (HL)

AND #38

 

assign the Paper colour of the guardian's background cells to Bits 3-5 of A.  But that had already been achieved by the first three bytes in the new code, so by copying that across to the C register, before the Ink colour and Brightness of the guardian are attributed to the A register, the same thing is achieved more efficiently.

 

Instead of doing the calculation XOR [Guardian Ink/Brightness], the code would then be doing [Guardian Ink/Brightness] XOR .

 

Which is the same thing, as the XOR command is a commutative function i.e. A XOR B = B XOR A.

Edited by IRF
Link to comment
Share on other sites

  • 1 month later...

I should point out that the above patch doesn't resolve the issue which can occur, if you have a guardian that moves between mediums of different Paper colour.  If a guardian does that, then the 'Draw the guardians' routine selects the Paper colour of the top-left cell that is occupied by the guardian in a given time-frame, along with its own Ink colour, and uses that attribute for all of the cells that the guardian occupies (i.e. a 2x2 square or a 2x3 rectangle).  Because of this, if a guardian moves up/down or left/right past a boundary between two mediums, then the guardian's background can change colour.  [Of course, it also changes the Ink colour of any filled-in pixels that fall within its 2x2 or 2x3 'zone of influence'.]

 

To see what I mean, try inserting a Vertical Guardian in The Swimming Pool, such that as it moves it dips in and out of the (Inkless) Water cells.

 

This is in stark contrast to the routine that draws Willy's sprite and colour attributes, in which the 4 (or 6) cells that his sprite occupies are considered in turn - each cell retains its Paper colour (and also its Ink colour unless it is an Air cell).

 

Again, The Swimming Pool provides the best example - as Willy descends down the Ramp into the Water cells, his Ink and Paper colours make a smooth transition.

Link to comment
Share on other sites

  • 5 months later...

I thought I should consolidate all of my proposed changes that fix this bug into one post, for easier reference:

 

#91EE to #91FA edited as follows:

 

C3 Yy Xx 00 DD 7E 01 E6 07 4F 7E E6 78

 

where #XxYy is a suitable address where there are 19 spare contiguous bytes.

 

Then at #XxYy:

 

7E E6 38 C2 F2 91 4F DD 7E 01 E6 0F C6 38 E6 47 C3 FB 91

Link to comment
Share on other sites

  • 9 months later...

I think another three bytes could be saved in this patch, by sharing the LD A, (IX+$01) command across both parts of the code.

 

(This relies on the fact that neither the LD C, A command, nor the LD A, (IX+$01) , affect the Zero Flag.  Therefore both of those can be placed after the AND #38 command - which does determine the status of Z - but prior to the JUMP back to #91F2.  Then the LD A, (IX+$01) command in the main 'Draw the Guardians' loop - at #91F2 - can be removed.)

Link to comment
Share on other sites

  • 4 weeks later...

I should point out that the above patch doesn't resolve the issue which can occur, if you have a guardian that moves between mediums of different Paper colour. If a guardian does that, then the 'Draw the guardians' routine selects the Paper colour of the top-left cell that is occupied by the guardian in a given time-frame, along with its own Ink colour, and uses that attribute for all of the cells that the guardian occupies (i.e. a 2x2 square or a 2x3 rectangle). Because of this, if a guardian moves up/down or left/right past a boundary between two mediums, then the guardian's background can change colour. [Of course, it also changes the Ink colour of any filled-in pixels that fall within its 2x2 or 2x3 'zone of influence'.]

 

To see what I mean, try inserting a Vertical Guardian in The Swimming Pool, such that as it moves it dips in and out of the (Inkless) Water cells.

 

This is in stark contrast to the routine that draws Willy's sprite and colour attributes, in which the 4 (or 6) cells that his sprite occupies are considered in turn - each cell retains its Paper colour (and also its Ink colour unless it is an Air cell).

 

Again, The Swimming Pool provides the best example - as Willy descends down the Ramp into the Water cells, his Ink and Paper colours make a smooth transition.

 

Thinking some more about the above, it could be resolved by taking the same approach to distributing the attributes for guardians, as the code which sets Willy's attributes in the secondary attribute buffer. i.e. put the code at #91EE-#91FD (modified to fix the Guardian Aura Bug) into a subroutine, which is then CALLed four or six times (each CALL would replace one of the existing LD (HL),C commands in the code that follows, up to #920E).

 

Of course, the fix is only necessary if you have guardians moving between different mediums, which would both probably need to be INKless in order to prevent a pixel collision between the guardian and the non-Air blocks. In the original game, the Swimming Pool is the only place that I can think of where this would be possible (since the Water cells in that room contain no infilled pixels).

Link to comment
Share on other sites

Et voila!

In the attached 'Multimedia Guardian Test' file, the start room is set to the Swimming Pool. There are several vertical guardians (two BRIGHT and two non-BRIGHT) which dip in and out of the Water. The horizontal Monk guardian has turned into King Canute and is "holding back the tide" in the middle of the pool!

The bottom row of the pool is comprised of INKless Fire cells, with the same cyan PAPER setting as the Water cells, but with BRIGHT On for the Fire and BRIGHT Off for the Water. The black Air cells have BRIGHTness switched to On.

The 'Draw the guardians' routine now CALLS a subroutine, located at #9718, up to six times for each guardian that it draws.

You can see that the guardians retain their original BRIGHTness setting when they are in the black background (Air) cells, but they assume the BRIGHTness setting of their host cells if the PAPER setting of the cells isn't black. You can also observe that the guardians are no longer drawn with a fixed PAPER colour for all of the cells that they occupy (based on the PAPER setting of their top-left cell).

EDIT: I've also attached a file called 'Multimedia Guardian Without Fix', which illustrates the original problem when guardians (vertical or horizontal) move between different media of differing PAPER settings.

Multimedia Guardian Test.z80

Multimedia Guardian Without Fix.z80

Edited by IRF
Link to comment
Share on other sites

That's great, I appreciate the 'before' file too so you get an exact copy to see the same sprites 'in action'

 

I was thinking the other day but I've not tried to look into it, the effects of either ink (or paper!) 8 or 9.

 

8 being 'transparent' = 'no change' and 9 being 'contrast' so its set to either black or white depending on what the other cell type aka ink or paper is set at.

 

9 might be more sensible if it works that is as its contrast, but IDK if its likely to work "outside Basic" I've never tried that I can recall. :unsure: :)

Link to comment
Share on other sites

That's great, I appreciate the 'before' file too so you get an exact copy to see the same sprites 'in action'

 

You can see the bug in action in Andrew Broad's game 'JSW64:MM: James Bond'. That project would certainly benefit from the bug fix I've come up with, if Andrew ever gets round to developing the game further.

 

Andrew had to pack a lot into every room (a whole James Bond movie's plot is represented by each room!), so the layouts are quite dense. As a result, there are a number of guardians which move through non-Air room elements, causing the PAPER colour of certain cells to be temporarily discoloured. Sometimes non-Air cells assume the PAPER colour of the Air cells; at other points in the guardian's trajectory, it is the Air cells which temporarily take on an anomalous PAPER colour.

 

(Actually, the latter is something that my test file doesn't demonstrate [EDIT: It does now!], because the top-left cell of a guardian determines the PAPER setting of the rest of the guardian's surroundings, and in the test file the Air cells are all either above or to the left of the Water cells. So the Air PAPER colour always happens to takes precedence. I might rearrange the layout slightly, putting the 'parting of the Waters' more centrally, in order to display the full range of buggy behaviour - i.e. as the horizontal guardian passes through a column of Air cells sandwiched between two columns of Water cells, the PAPER behind the guardian will change TWICE.)

Edited by IRF
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

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