Jump to content
Jet Set Willy & Manic Miner Community

Ropes & Arrows


SymbolShift

Recommended Posts

16 hours ago, MtM said:

It always seemed fairly intuitive to me for some reason, I don't know why. Maybe that was the same reason for MS?

Think you could be right with that. Matthew Smith's game design is just as eccentric as the man himself, and to do things the normal way would be been considered boring for him. Either that, or it just made perfect sense to him, possibly due to his eccentricity. We also know that MS did not like to make things "too easy" 🙂

Edited by SymbolShift
Link to comment
Share on other sites

SymbolShift wrote:

"Anyone I know who jumps on a rope for the first time is totally baffled on how to control Willy, as the climbing direction reverses when the swing direction changes. That said, after a while, you do eventually get used to it. I have coded the above method in my game (since it's true to JSW), but I did try a simplified version (left = up, right = down, no matter what swinging direction) and it seemed way more logical."

Your suggestion doesn't seem more logical to me, because when the rope is left-of-centre, pushing the left button (to move up, in your system) would cause Willy's horizontal position on the screen to move rightwards. It would only be a more logical method, it seems to me, at times when the rope is to the right of its central position (i.e. to the right of where it would hang if it wasn't swinging). 

Perhaps the most logical set-up would be to have the up-down functions of the left-right keys toggle to having the opposite effect every time the rope passed from the left-hand side to the right-hand side of the screen, and vice versa (as opposed to toggling every time the direction of swing flipped). 

That would involve the key functionality being determined by the value of the Rope Animation Frame variable (whether it is a positive or negative number, treating the byte as a signed number so that values > than 128 are negative), instead of using the Rope Direction Flag (the highest bit of the guardian type byte in the guardian definition buffer) to determine which keys send Willy up/down the rope. 

Edited by IRF
Link to comment
Share on other sites

Further to my previous post, I've implemented my suggested alternative rope motion in the attached file.

**

Code changes: this involved firstly changing the command at #937D from a XOR (IX+$00) to a XOR (IX+$01), to pick up the 'Is the rope left- or right-of-centre?' flag, instead of the 'Is the rope swinging left- or right-wards?' flag.

But that had exactly the opposite effect of what I intended (the left key made Willy move rightwards on the rope, and vice versa), so I inserted an additional XOR #80 command to toggle the movement back to the correct way round.  (I needed to insert two additional bytes for that, so I deleted the redundant two-byte instruction at #93B1, and shuffled all the code in between.)

[There may be a simpler way of doing the above without using two consecutive XOR's, but I couldn't think of one.]

**

Now that I've dealt with the technical stuff, please have a go with the rope in the Swimming Pool in the attached file.  I think this makes most sense of all - pressing left moves Willy leftwards on the rope, regardless of its swing direction, and pressing right moves him rightwards on the rope - simples!

In the original game, if you keep a single movement key pressed as Willy swings on the rope, then he switches from climbing up to climbing down the rope (or vice versa) at the moment when the rope reaches the furthest extremity of its swing and turns round to start swinging the other way - that doesn't seem to follow simple logic (hence SymbolShift was prompted to initiate this debate in the first place!)

But in the attached, if you keep a single movement key pressed as Willy swings on the rope, then he switches from climbing up to climbing down the rope (or vice versa) at the moment when the rope passes through its vertical position, from one side of the screen to the other. i.e. as the rope changes between having a 'sloping down to the right' versus a 'sloping down to the left' gradient.  This seems to me to be a more logical distinction to make, because if you consider the horizontal component of Willy's motion, he is always moving in the direction (left or right) which corresponds with the key that you are pressing.

Thoughts?

Logical Rope Movement.z80

Edited by IRF
Link to comment
Share on other sites

This is not something new. It is the above code written differently, and it still leaves those 2 bytes alone (the relative jump to the next byte - which is redundant code at #93b1)

 

;Now that the entire rope has been drawn, deal with Willy's movement along it.
L935E    ld hl,rope_status   
               bit 7,(hl)        ;    ;   Has Willy recently jumped off the rope or dropped off the bottom of it (A>=0xF0)?
               jr z,L93xx     ;    ;   Jump if not
               inc (hl)        ;    ;     Update the rope status indicator at L85D6
               RES ropebit,(IX+rope0B) ;         ;    Signal: Willy is not on the rope
               JR next_entity_draw    ;         ;#93b3  Jump to consider the next entity

L93xx  
               BIT ropebit,(IX+rope0B) ;         ;    ropebit=0, Is Willy on the rope?
               JR Z,next_entity_draw    ;         ; #93b3      If not, jump to consider the next entity

              LD A,(willy_dir)    ;         ;       Pick up Willy's direction and movement flags from L85D0
              BIT 1,A                 ;         ;    Is Willy trying to move up or down the rope?
              JR Z,next_entity_draw    ;    ;#93b3
              cpl            ;    ;    invert the bits - only intetest is in bit [0] the direction Willy wants to move
              rrca             ;     ;    shift bit [0] > bit [7]
              xor (ix+rope01)     ;    ;      direction of swing in bit [7]
              rlca             ;     ;    from [7] to [0]
              rlca             ;     ;    from [0] to [1]

              AND #02         ;         ;    value is now 0 or 2
              DEC A            ;         ;    value is now -1 or 1
             ADD A,(HL)        ;         ;    add on the rope status
             LD (HL),A        ;       ;    and save the new value

           nop            ;     ; a bit of space saved 5 bytes
           nop
           nop
           nop
           nop


L938a:

Edited by Norman Sword
Link to comment
Share on other sites

Nice one, Norman! 

Note to self: The code changes you identified would provide a saving of six bytes if you weren't simultaneously implementing the alternative key action whilst Willy is on a rope.

i.e. If not inserting the CPL command, whilst leaving the XOR as a xor (ix+rope00)

Edited by IRF
Link to comment
Share on other sites

Norman's CPL is essentially doing the same thing as my XOR #80, in this context (CPL toggles all the bits of A, but that has no effect here since there's an AND gate shortly afterwards which isolates the bit under consideration). The other difference is that I applied the XOR #80 after XORing with the appropriate rope definition byte, whereas Norman did the CPL first. (Doesn't make a difference which order they're done in.)

And of course the CPL only requires a single byte, whereas XOR #80 takes two bytes.

Link to comment
Share on other sites

For consistancy of timing states and logic flow, it is probably better to manipulate the bits into the appropiate position.

The code I listed is manipulating bits to provide an answer, but the direct route is just as quick, but varies in timing depending on the path taken.

(as listed above) 

.
L935E   ld hl,rope_status   
              bit 7,(hl)     
              jr z,L93xx 
              inc (hl)     
              RES ropebit,(IX+rope0B)
              JR next_entity_draw

L93xx  
              BIT ropebit,(IX+rope0B) 
              JR Z,next_entity_draw  
              LD A,(willy_dir)  
              BIT 1,A
              JR Z,next_entity_draw  
              cpl                                       ; in revision this is not needed                                                         
              rrca           
              xor (ix+rope01)         
              rlca                                     ; in the revision the bit position is not shifted 
              rlca
              AND #02                           ; no need to isolate bit - a direct test is done      
              DEC A        
              ADD A,(HL)      
              LD (HL),A
              NOP 
              NOP
              NOP
              NOP
              NOP   

revised:


L935E    ld hl,rope_status   
               bit 7,(hl)      
               jr z,L93xx   
               inc (hl)       
               RES ropebit,(IX+rope0B)
               JR next_entity_draw

 L93xx  
               BIT ropebit,(IX+rope0B) 
               JR Z,next_entity_draw  
               LD A,(willy_dir)  
               BIT 1,A
               JR Z,next_entity_draw    ; 
               rrca                                 ; move bit [0] to bit [7]
               xor (ix+rope01)              ;  bit [7] 
               inc  (hl)                           ; do a +1 change on rope_status
               bit 7,a                              ; check the bit[7] status
               jr z,skip_o                       ; branch if ok  with +1 
               dec  (hl)                          ; else revise the +1 to 0
               dec  (hl)                           ; and revise again to -1

skip_o:
              NOP
              NOP
              NOP
              NOP 
              NOP
              NOP
 

 

which removes the need to CPL the byte for testing and is also one byte shorter.
 

Edited by Norman Sword
removing unwanted text >> t
Link to comment
Share on other sites

Norman's latest code makes it easy to switch between the two 'rope modes' (key function switch when rope turn round versus when rope passes through the vertical) - to revert the code as listed above back to the original setup (retaining the 6 byte saving), you only need to edit two bytes: change the offset byte of the XOR from 01 to 00, and then swap the JR Z, skip_0 to a JR NZ, skip_0

****

Random fact: when Willy jumps off or falls off the end of a rope, a counter is set that means he cannot get back onto the rope for 16 time-frames of the game. (Presumably intended to prevent him from getting unintentionally tangled back onto the rope immediately after dismounting.) But in a room in a modified game that has two ropes (even with the Adjacent Ropes patch implemented), this 'cooling off period' only lasts for 8 game 'ticks'; with four ropes in the same room it will only be four 'ticks' after dismounting before he can get back onto a rope; etc. 

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.