Jump to content
Jet Set Willy & Manic Miner Community

Norman Sword

Contributor
  • Posts

    596
  • Joined

  • Last visited

Posts posted by Norman Sword

  1. Jumping arc of travel.

    It is noticable that when Willy does his sumersault jump, that one frame after the rotation part of the sumersault. Seems to be out of sync. This gives the visual feedback of pausing animation and moving horizontal mid jump. Crude picture to try and explain better. (moving from left to right) 
     

    mid jump pause.jpg

  2. An ommision from the above.

    The CPC does not have a version of JET SET WILLY2. It has a version that is identical but is called JET SET WILLY - the  final frontier.  

    Yet the cpc also contains a version called simply JET SET WILLY. Which might seem confusing, but in a way it does make sense to have the two versions.

    Whilst converting  the game from the CPC to the Zx spectrum, I was asked was it possible to reduce the game (on the cpc) back to the original with a mere 60 rooms, eg delete 70+ rooms and leave just the 60 . I answerd it was not a big task, to reduce the size down to less than half. But did question "for what purpose?". The answer was simply to enable the game to be part of they "sold a million" compilation tapes, and strictly speaking the version I had written was not the original jet set willy, it had been more than doubled in size.  Plus the smaller (a mere 60 rooms) version was not going to be sold as a stand alone product. But only on a compilation tape, which meant that both versions could still be sold on the cpc.

    Version 1) JET SET WILLY - the final frontier-- 130+ rooms - written first and sold first on the cpc
    Version2) JET SET WILLY a mere 60 rooms - sold only on a compilation tape/disc with they SOLD A MILLION compilation. (Beach head, Sabre Wulf,Jet Set Willy, Daley Thompsom-DECATHLON)

    The reduction down to the mere 60 rooms of the original was not that difficult. It was just a case of deleting most of the data. I added a high score table to give immediate feedback to the player that it was a different version. But their are visual changes on the title screen as well. (see picture)667241153_highligh.thumb.jpg.61868d6a11fd93b0eb1fd78b392aba5b.jpg1182503609_JSWcass.thumb.jpg.e889a39bbb8fc5c4a41e07516745fd51.jpg

    And before anyone says that the tail on the title screen looks like a two. It was just a copy of the squiggle on the graffiti. Which on reflection when doing JSW2, I decided to remove.





     

    They Sold a Million_1.jpg

  3. If only bright was used, then usage was technical. However I do not like the Mud versions of the bright colours. Given a choice I tend to use bright. 

    Basic background on JSW on the CPC 464.

    When tasked with writing the CPC464 version of JSW, I started with the knowledge that Manic Miner on the CPC managed to use all the memory available. So JSW has triple the amount of rooms and that was why I decided to compress everything I could think of. 

    The final version called "JSW the final frontier" was supposed to be just my version of JSW on the cpc. It was never intended to be a new version. In fact most things were toned down to stop it diverging too much from the original.

    When I was asked if it could be rewritten back on the spectrum, I tentatively said "probably yes". I knew it would not be an easy task. The reason behind the apprehension was because the way the cpc was doing collision detection was based on colour, but was also being drawn directly on the cpc's screen. The spectrum would need to do things differently, and somewhere along the line I would be forced to introduce a copy screen. 

    The cpc version used translation colour bytes for the rooms. Most code was an adaptation of the cpc code. The compacted code needed to be even more compacted due to needing to save 4k when moving from the cpc game onto the zx spectrum. All screen draws on the cpc are done on the viewed screen. To stop flicker the drawing on the zx spectrum is done on a copy screen. (that takes a minimum of 4k) In essence if space was available anywhere then it was used. Most of the games running variable data is stored on the screen for the zx spectrum version 


    The cpc version on Manic Miner with written On a Tandy Model 4 - with floopy discs
    The Cpc version of "Jet Set Willy the final frontier was written on a Tandy Model 4- with floopy discs
    The cpc version of "Jet Set Willy" was written on a Tandy Model 4 - with floppy discs
    The spectrum version of "Jet Set Willy 2" the final frontier was written on a Tandy Model 4 - with a 20 meg hard drive

    The Tandy was running Newdos 80 (disc operating system). The assembler was EDAS by misosys.

    Download from Tandy to CPC was done using a z80 dart.
    Download from Tandy to zx spectrum was done using a parallel interface - using my own direct download software - taking the Tandy's loading structure as it basis. Which allowed direct disc to memory transfer. Which was nothing like Matthews fixed memory transfer. Where source and destination occupied the same address.

    I will elaborate on the transfer. In Matthews case to transfer from the Tandy to the spectrum.  Data is loaded into the Tandy's memory. That data is transferred byte for byte from a location on the Tandy to the same location on the spectrum. - this lead to bugs.

    My method interrogated the Tandy's disc loading system, and transfers the disc contents from the Tandy to the address it was assembled at. This meant a re-org of the assembled program, would also be transferred to the new org. No data (apart from one sector) is loaded from the Tandy's disc, when transferring code.


    Matthews method also introduced the loss of four rooms into JSW. What Matthew had not realised, was  that the upper memory of the Tandy was dedicated/allocated just for the Hard disc operating system. The hard disc was bought after development of Manic Miner. So the very upper memory on the Tandy was and could be used, whilst he was writing Manic Miner. That same memory was occupied when it came to develop Jet Set Willy. Simply because he had bought himself that 5 meg hard drive.  (I am surprised he did not notice) The upper memory rooms ended up being corrupted and those rooms, were eventually deleted. The upper memory of JSW still contains the TANDy hard drive code, (instead of room data) 

     

    The biggest problem (apart from disc size) was the source code needed to be continually stripped of comments and meaningful labels. After a while you get used to seeing what look like meaningless labels. So a label like "main_control_loop"  (which can not be written - max eight letters), gets shortened to "MCL". and slowly you get multiple versions such as MCLx,MCLp  When I first saw the assembly listing again, a few years ago, it was strange to read a label such as "IAOAL"  and immediately say to myself  "I am on a lift"  It was if I had written the label a few moments before I had read it. Yet the time gap was nearly 30 years.

     

  4. 1 hour ago, MtM said:

    If I do go I will take some pics and put them up here. I could do with a t shirt with Miner Willy on it really for id purposes.

     

    Anyone got a good working link and recommendation as to where I could get one please? Preferably in the UK

    but if it has to ship then okay!

     

     

    E-bay seems to have been cleared out - due to previous legal threats

    however 

    https://www.redbubble.com/shop/manic+miner+t-shirts 

    seems to supply whatever you want. - This is not an endorsement by me - I have never used this company.

     

     

    screenshot 2022-07-28 121905_1.jpg

    screenshot 2022-07-28 121835_1.jpg

    screenshot 2022-07-28 122100_1.jpg

    screenshot 2022-07-28 121950_1.jpg

    screenshot 2022-07-28 121807_1.jpg

    screenshot 2022-07-28 122021_1.jpg

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

  6. 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:

  7. JSW and MM - walking on a conveyor.

     

    Part 2:-


    Your past, influences your future

    Jsw and MM on the zx spectrum both use a lookup table for translating joystick/ keyboard actions into a new key press action.

    The predefined actions for every combination of key press is contained in those lookup tables. With some responses being the supposed quirks in game play.

    One action that might not be recognised is the response to an action when two horizontal actions are asked for. Normally the player only asks for a response for moving in one direction. Which is how most of the game is played. The player presses a direction key and Willy responds by moving in that direction. But suppose Willy is asked to walk both left and right at the same time? The action for that situation is contained in the keyboard translation / response table, and that action is to respond only on the previous key pressed, and ignore the new key.

    To see what this means walk to the right of the bathroom and press the key to move left. Whilst holding down left and walking left, press the right key. The movement lookup table will ignore the new key being introduced into his movement and Willy will continue walking left. Whilst walking left no matter how long or short the right key is pressed, its actions will be ignored, until the left key is released.

    Jumping and falling introduce more variables, but walking and holding a key down will continue on that walk until the key is released. Willy can of course walk over a conveyor whilst holding down the key. The conveyor will press the direction key for the conveyor, and the game engine via the lookup table will ignore any change in horizontal movement.

    Back to jumping onto conveyors. The most important point about the movement lookup table is that new horizontal actions are defined by the old actions. hence "Your past, influences your future" . The actions that a conveyor has is defined by the actions undertaken to arrive on the conveyor. If your previous action had a horizontal movement as a component of its action and that action is still being requested, then the movement table will oblige and continue with that horizontal movement.

    Which is why I tried to explain the consequence of falling onto a conveyor. Because when the horizontal movement of Willy is stopped (previous action) the new action (the conveyor) tries to takes over the  horizontal movement of  Willy.  (see stopped on a conveyor :- at the end)

    In the situations of Willy landing with a horizontal movement component still being his last horizontal movement action. If requested to continue with the horizontal movement. (e.g. you are still pressing the key) then the conveyor action will be ignored.
     

    Stopped on a conveyor.
    The movement action table also explains why you can stop on a conveyor.  If your previous horizontal action was no movement (e.g. a fall) then a request to move in the opposite direction of the conveyor. Will upon landing on that conveyor, result in no movement. This situation is a request to move horizontally both left and right, from a previous null horizontal movement.. That request is translated as a new null horizontal movement reponse.  These actions are all defined in the movement lookup table. 
     

  8. JSW and MM - walking on a conveyor.


    Part 1:-


    When Willy is jumping he can have a forward movement component for the arc of travel.. Which is basically an automatic key press in the direction he is jumping.

    When the arc of the jump is finished,  and he starts falling, the code kills his movement key and willy no longer has a horizontal movement component for his actions.

    This means at the point of landing on a conveyor from any fall, (note I say fall- and not jump) Willy can NOT have a horizontal movement component and this coupled with the automatic key press supplied by the conveyor results in the actions as seen.

    All other instances of landing on a conveyor that is level or above the start point have the horizontal component still intact from the start of the jump, and this is transfered to the point of landing. Nothing strange or convoluted in this coding of action.

  9.  

    Taking the actual code used to control Willy on the rope . It took me all of 1 second to change the logic.

    This original is deliberate and very logical in the manor of control. Walking up a stair you press against the stair, to move down a rope you press against the rope. Which to me is reverse logic, but still a consistant logic.

    To modify to play as you mentioned is the lazy way of coding the movement and not the other way around. Note the ease of modification

    Part of the rope swing


        LD A,(willy_dir)    ; #9375    ;#85D0  Pick up Willy's direction and movement flags from #85D0
        BIT 1,A         ; #9378    ;    Is Willy moving up or down the rope?
        JR Z,next_entity_draw    ; #937A    ;#93b3  If not, jump to consider the next entity

    ;CHANGE CODE FROM
    ;    RRCA            ; #937C    ;    XOR Willy's direction bit (0=facing right, 1=facing left) with the rope's direction bit
    ;;                ;;    ;    (0=swinging right to left, 1=swinging left to right)

    ;    XOR (IX+rope00)     ; #937D    ;
    ;    RLCA            ; #9380    ;
    ;    RLCA            ; #9381    ;    Now A=1 if Willy is facing the same direction as the rope is swinging (he will move down the rope),
    ;;                ;;    ;    or -1 otherwise (he will move up the rope)

    ; CHANGE CODE TO 
        RLCA           ; #937C
        NOP            ; #937D
        NOP            ; #937E
        NOP            ; #937F
        NOP            ; #9380
        NOP            ; #9381

     

    ;>> back to the normal logic

       AND #02         ; 9382    ;
        DEC A            ; 9384    ;

     

    included is a file with the rope swinging in such a way. 

     

     

    NOTE this file is so close to the original --- it might still have the attic bug --- I can not remember.

     

    Addendum:-  easier is to just  zero out #937c, #937d, #937e, #937f, #9380.  -- five 0(zero) pokes.

    jsw rope swing.tap

  10. Correction on the misinformation about automatic room switching: JSW can switch rooms at around 4 frames per second. The graphics will appear on the screen. long enough, for the room to be recognised. Additionally you will be able to follow what willy does.

    This means the minimum time MUST be around 15 seconds, and that time is to just flash through 60 rooms. That time however does not allow much leeway for moving around the rooms. 
     

  11. The rope is very simple in operation. Matthews code does its best to obscure that simplicity.

    The rope data has offsets for x and y. - the data below is padded out to 256 bytes
     

    rope_table_X:
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H01,&H01,&H01,&H01,&H01,&H01,&H01,&H01
    DATA &H01,&H01,&H01,&H01,&H02,&H02,&H02,&H02
    DATA &H02,&H02,&H02,&H02,&H02,&H02,&H02,&H02
    DATA &H02,&H02,&H02,&H02,&H02,&H02,&H02,&H02
    DATA &H02,&H02,&H01,&H02,&H02,&H01,&H01,&H02
    DATA &H01,&H01,&H02,&H02,&H03,&H02,&H03,&H02
    DATA &H03,&H03,&H03,&H03,&H03,&H03

    ;==================

    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00


    ' y-coordinate shift
    rope_table_Y:
    DATA &H06,&H06,&H06,&H06,&H06,&H06,&H06,&H06
    DATA &H06,&H06,&H06,&H06,&H06,&H06,&H06,&H06
    DATA &H06,&H06,&H06,&H06,&H06,&H06,&H06,&H06
    DATA &H06,&H06,&H06,&H06,&H06,&H06,&H06,&H06
    DATA &H06,&H06,&H06,&H06,&H06,&H06,&H06,&H06
    DATA &H06,&H06,&H06,&H06,&H06,&H06,&H06,&H06
    DATA &H04,&H06,&H06,&H04,&H06,&H04,&H06,&H04
    DATA &H06,&H04,&H04,&H04,&H06,&H04,&H04,&H04
    DATA &H04,&H04,&H04,&H04,&H04,&H04,&H04,&H04
    DATA &H04,&H04,&H04,&H04,&H04,&H04,&H04,&H04
    DATA &H04,&H04,&H04,&H04,&H04,&H04

    ;===========

    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
    DATA &H00,&H00

    simple logic for animation

    A pointer is set as an offset into the data (as above)

    The pointer has two other variables - side and step

    The step is added to the offset.
     

    if the offset is now 0 then reverse the step and reverse the side - simply negate the side and step.

    if the offset is maximum the reverse the step- Simply negate the step

    The above is the core logic for animation

    --------------------------

    To draw- start x=128; start y=0:
    loop
    draw point x,y
    Take the offset into the above data - find the x entry - delta x-  and if side is 1 add delta x to x ; if side is -1 deduct delta x from x
    Take the offset into the above data : find the y entry and add to the y

    add 1 to the offset

    loop for the length of the rope

    the above will need adjustments, with the size of steps and length of rope etc =but will draw the rope.

     

     


     

  12. Assuming you can draw the rope. Starting at the top we count the pixels drawn for the rope draw.  

    If Not attached to the rope. Each cell drawn is tested for collision. if collision then willy is attached to the rope at that point. 

    If attached to the rope. The cell that is assigned as the collision point (as above) is used as the x,y position to draw Willy - (slight shift adjustment needed in zx spectrum code)

    To move on the rope the point of collision is moved up or down the rope 

    To detach from the rope. A timer is set and Willy is cell aligned and exits from the rope.

  13. In zx spectrum JSw and JSW2 and JSW2+. When Willy is walking along he is always aligned to a character cell. When Willy is above a ramp/stair he is still aligned to a character cell, but is drawn with a displacement. When Willy appears to walk diagonally up or down a stair. He actually walks in steps of one char up and down the stairs. It is the displacement code the makes him appear to walk diagonally.

  14. I will again state. It is possible to run Manic miner and return to basic. On returning to basic it will still be possible to poke the game and again enter MM ( and if needed keep on repeating the loop of running the game and returning to basic). All the basic that was in memory before running MM will still be there. Because certain members on here do not have the skill needed to do this does not preclude others from doing so. (e.g. I can if I wanted, do the modifications needed. But I have no intention of doing so. ) in the 30+ years since MM was written I have had no need to do so, and I still have no need to do so. 


     

  15. A side track. The design of Nomen luni focuses on the crashed plane. Yet for some reason Matthew part obscured the design by flashing un needed graphics. So the next version of this screen I do, will be changed to this (picture below) which assigns nasty graphics to the un wanted flashing graphics on the right, and thus removes the flashing from those graphics. Which then forces the plane to take centre stage. 

    New room layout small.jpg

  16. The room exists as a void room. The room is drawn with no graphics no sprites and all exits are set to go to the "off licence".


    The code checks (in cheat)  for rooms 47/61/62 and 63 if found then the cheat code is ignored.

    If in playing the room 47/61/62 or 63 was entered, you would land either on the floor across the room at mid point or across the bottom. Nothing would be visible. On walking across the room you would enter the "off licence".

    So yes the room exists. But would be very difficult to edit by virtue of the data size being set to the smallest possible size.

    Looking at the data with a hex editor will not show much. The data and its structure are comparable to JSW2 in its layout. While JSW2 keeps all the rooms in continuous blocks of data . The room layouts all being together and the (sprite movement data ,the tile colours, the graphics and room name) being in another block. In ManicJetSetWilly the room graphics and the tile colours etc are mixed with no real indication of where one starts or finishes.  In JSW2 the room names can be seen alongside the appropiate room data. Giving an easy to see reference point.

    In ManicJetSetWilly the data for room names and the room data are vastly seperated and room data just flows from one rooms data set to the next for the room data.  

     

×
×
  • Create New...

Important Information

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