Jump to content
Jet Set Willy & Manic Miner Community

Idea for a new cell type in Manic Miner


IRF

Recommended Posts

Having tested a room with a cell at head height. 

 

I find I can jump over it. So the third check is needed.

 

What is strange is the arc of willy jumping over a nasty compared to the arc of willy passing over a wall. They are nothing alike.

 

So I need to have a look at the ramp code or any other piece of code that might be relevant, and find out why the wall is stopping the arc in the manner it does. I am not concerned with the heel catch and land on a wall, but the point at which is says it is clear to move. The arcs are so dissimilar that I need to investigate the take off and clear portion. 

 

 

This is side tracking me from what I was doing...

Link to comment
Share on other sites

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).

Edited by IRF
Link to comment
Share on other sites

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.)

Edited by IRF
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Edited by IRF
Link to comment
Share on other sites

You are probably coming into the routine at 8ebc from one of the two jumps below, which presents a problem

 

8DF7  LD A,($80B2) 

8DFA  CP (HL) 

8DFB  JP Z,$8EBC  >>>> 

8DFE  INC HL 

8DFF  CP (HL) 

8E00  JP Z,$8EBC >>>

 

I have a very small subroutine to handle the above type of tile check. It occurs elsewhere. The sole purpose of the routine is to leave HL alone.

 

But a quick method of doing the same as my sub routine is

 

          original                         change to

 

8DF7  LD A,($80B2)              Ld a,($80b2)

8DFA  CP (HL)                       cp (hl)

8DFB  JP Z,$8EBC  >>>>       jr z,$8e00

8DFC

8DFD                                     inc hl 

8DFE  INC HL                        cp (hl)

8DFF  CP (HL)                      dec hl 

8E00  JP Z,$8EBC >>>          jp z,   Butt or $8ebc

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.

Edited by IRF
Link to comment
Share on other sites

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.

 

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).

Link to comment
Share on other sites

  • 3 weeks later...

I'm pleased to be able to announce that I've managed to rewrite the 'Move Willy' and 'Draw Willy' routines in the Manic Miner game engine, in order to allow Willy's sprite and attributes to wrap around the screen, both vertically and horizontally.  Whilst I was at it, I added the 'headbutt' facility for clearing wall tiles/Earth cells.

 

In the attached test tile, only the Central Cavern has had its layout affected to showcase these changes to the game engine.  But I would suggest that the changes could be exploited more widely in the 'Manic Mixup' project (currently being worked on in the Contributor Lounge).

 

EDIT: The test file is now attached to a later post in this thread.

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.