Jump to content
Jet Set Willy & Manic Miner Community

Useful Links


IRF

Recommended Posts

Another comment from Geoff's JSW webpage:
 
https://web.archive.org/web/20030818082654/http://www.cix.co.uk:80/~morven/jsw/geoffmode.html
 

NOTE: Strange and rather annoying effects have been noticed with some pathological ropes. I don't remember if this was due to a bug in the code or weird interactions with other data.

 
I think this must refer to a rope where the lowest three Bits of the guardian definition Byte 0 are set to 111 (07), rather than the usual 011 (03):
 

[bits 0-2 of Byte 0 of a guardian's definition] specifies the type of the guardian, as follows:

  • 000: not used
  • 001: horizontal guardian, non-wraparound
  • 010: vertical guardian, non-wraparound
  • 011: rope
  • 100: arrow
  • 101: horizontal guardian, wraparound
  • 110: vertical guardian, wraparound
  • 111: rope
Edited by IRF
Link to comment
Share on other sites

  • 4 weeks later...

A few more errors/inefficiencies in the Geoff Mode disassembly (for my own future reference, if nothing else):

 

https://web.archive.org/web/20030701143111/http://www.cix.co.uk/~morven/jsw/geoff_dis.html

 

 


9166 CDB18D   CALL #8DB1       ; get A = -A x B
9169 DD8603   JP   #8DBC       ; adjust and store y
916C C9       RET

 

The opcodes in bold text above are erroneous, it should read 'C3 BC 8D'.  Actually, it could read 'C3 92 8B', and jump to an identical bit of code which sits at the end of another subroutine (see below).

 

Also, the RET command at #916C above is superfluous, as the preceding jump goes to code which ends in a RET back to the Main Loop.

 

 


; minor sprite patch

8DBC DD8603   ADD  (IX+#03)    ; add current y
8DBF DD7703   LD   (IX+#03), A ; and store new y
8DC2 C9       RET 

 

As I mentioned above, the minor sprite patch in italics is superfluous if the jump from #9169 is directed to #8B92 (see bold highlight below).

 

 


; update y-coordinate of diagonal guardians @@@

8B73 0E02     LD   C, #02      ; amount to change y-coordinate by
8B75 FE10     CP   #10         ; if diag type is 2,
8B77 2007     JR   NZ, #8B80
8B79 DDCB0646 BIT  0, (IX+#06) ; y is updated every other tick
8B7D C8       RET  Z
8B7E 1806     JR   #8B86
8B80 FE08     CP   #08         ; if diag type is 1
8B82 2802     JR   Z, #8B86
8B84 0E04     LD   C, #04      ; double dy
8B86 79       LD   A, C
8B87 CDB18D   CALL #8DB1       ; get A = -A x B
8B8A DDCB0166 BIT  4, (IX+#01) ; negate A if necessary
8B8E 2002     JR   NZ, #8B92   ; I can't remember what "necessary" is
8B90 ED44     NEG              ; in this context!
8B92 DD8603   ADD  (IX+#03)    ; work out new y
8B95 DD7703   LD   (IX+#03), A ; and store it
8B98 C9       RET

 

The 'necessary context' which Geoff referred to above, is to distinguish between the 'NW-SE' and 'NE-SW' types of diagonal guardians.  Contrary to the Geoff Mode documentation, Bit 4 of Byte 1 of a diagonal guardian's Definition Bytes is not flipped when non-wraparound guardians change direction.

 

The references to various types of diagonal guardian in the above is messy.  "double dy" in italics above should refer to a type 3 diagonal guardian, for example.

 

The subroutine at #8DB1 should be introduced as 'Used for diagonal and wraparound sprites':

 


; A = - A x B. Used for diagonal sprites. @@@

8DB1 C5       PUSH BC
8DB2 48       LD   C, B
8DB3 47       LD   B, A
8DB4 AF       XOR  A
8DB5 81       ADD  C
8DB6 10FD     DJNZ  #8DB5
8DB8 ED44     NEG
8DBA C1       POP  BC
8DBB C9       RET

 

 

The Geoff Mode documentation implies that, as in Matthew Mode, Bit 7 of Guardian Definition Byte 0 keeps track of the current direction of horizontal (and diagonal) guardians.  However, I'm not sure that it does in Geoff Mode.  The direction of horizontal guardians is tracked via Byte 4 (which is a signed byte and determines the velocity) - as is the case for vertical guardians in both game engines.

 

At #9193-#919C, both Byte 4 and Bit 7 of Byte 0 are toggled - via a NEG command and an XOR #80 gate respectively - but I believe that the latter bit of code (i.e. #9199-#919C, in italics below) may be superfluous:  EDIT: Actually, whilst Bit 7 of Byte 0 isn't used to keep track of horizontal guardians in the 'Move the Guardians' routine, it is used by the 'Draw the guardians' routine, in order to determine which set of sprite-frames to use for bidirectional sprites.

 


9193 78       LD   A, B
9194 ED44     NEG
9196 DD7704   LD   (IX+#04), A ; x = x - v * length
9199 7E       LD   A, (HL)
919A EE80     XOR  #80
919C 77       LD   (HL), A     ; change direction

 

 

No errors here, but I thought it would be worth emphasising a particular difference between Geoff and Matthew Modes, which Geoff doesn't explicitly mention in his notes.  Namely that vertical guardians cycle forwards through their sprite-frames as they descend the screen, but backwards through their sprite-frames as they ascend:

 


 

9146 CB78     BIT  7, B
9148 2804     JR   Z, #914E
914A D620     SUB  #20
914C 1802     JR   #9150
914E C620     ADD  #20
9150 77       LD   (HL), A     ; change sprite image

 

In contrast, Matthew Mode vertical guardians always cycle forwards through their sprite-frames, regardless of the status of their vertical trajectory.  (So, to give a real example, the foliage on the Plant Pots in 'Jet Set Mini' are always growing outwards, before suddenly being 'pruned back' and starting again; if they were present in a Geoff Mode game, then the leaves would reverse direction and start 'shrinking' as the guardian started to move up the screen.)

 

 

******

 

Finally, I have a sneaking suspicion, from studying the code, that if a type 2 wraparound diagonal guardian (i.e. one that traverses at 14 degrees from the horizontal) has an odd number of increments defined in Byte 7, then it might fall 'out of phase' by one vertical increment, each time it wraps around.  That could cause the guardian to 'stray from the path' - potentially leading to problems like the guardian colliding with elements of a room's layout.

 

I have yet experimented to test this out, but if I am right, then it might be easily resolved by swapping the RET Z at #8B7D for a RET NZ.  i.e. so that type 2 diagonal guardians are only vertically adjusted when the counter at Byte 6 holds an even value (instead of only being vertically adjusted for odd values of Byte 6, as is currently the case in the Geoff Mode game engine).

Edited by IRF
Link to comment
Share on other sites

Finally, I have a sneaking suspicion, from studying the code, that if a type 2 wraparound diagonal guardian (i.e. one that traverses at 14 degrees from the horizontal) has an odd number of increments defined in Byte 7, then it might fall 'out of phase' by one vertical increment, each time it wraps around.  That could cause the guardian to 'stray from the path' - potentially leading to problems like the guardian colliding with elements of a room's layout.

 

I have yet experimented to test this out, but if I am right, then it might be easily resolved by swapping the RET Z at #8B7D for a RET NZ.  i.e. so that type 2 diagonal guardians are only vertically adjusted when the counter at Byte 6 holds an even value (instead of only being vertically adjusted for odd values of Byte 6, as is currently the case in the Geoff Mode game engine).

 

Having now investigated this, I am extremely pleased to report that I was correct, both in my diagnosis that there is a problem (a bug in the Geoff Mode game engine), and with my prescribed solution (which fixes the bug with a single POKE)!

Link to comment
Share on other sites

One other observation with respect to the Geoff Mode game engine - I don't think that anything will actually happen if the time counter (which counts down from 9999999) were ever to reach 0000000!?

 

i.e. I can't see any evidence in the code that the game comes to an end, although the number of items collected up to that point might start to be decremented!?

Edited by IRF
Link to comment
Share on other sites

One other observation with respect to the Geoff Mode game engine - I don't think that anything will actually happen if the time counter (which counts down from 9999999) were ever to reach 0000000!?

 

i.e. I can't see any evidence in the code that the game comes to an end, although the number of items collected up to that point might start to be decremented!?

I've not looked at how that counter was done. I'm assuming that they used the extra space digits that were not 'printed' for this. Although I'd expect once it reached 0 it may drop to display a " / " , as a "0" is chr$ 48 / chr$ #30 and the "/" being 47 / #2F :unsure:

 

I'm basing this simply on some 'accident's I had when erm 'adjusting' the clock digits a while back to do other things. I'd expect there is no check for the far left digit in his code ? In which case the DEC will simply drop the "0" down one character to "/" , all being well (or not!)

 

EDIT... Pic ?

 

chrs_nums.gif

Edited by Spider
Link to comment
Share on other sites

One other observation with respect to the Geoff Mode game engine - I don't think that anything will actually happen if the time counter (which counts down from 9999999) were ever to reach 0000000!?

 

i.e. I can't see any evidence in the code that the game comes to an end, although the number of items collected up to that point might start to be decremented!?

 

 

Ignore the part in bold in my previous post - the code counts seven digits, via the E register, so it won't wrap around into an eighth digit!  :blush:

 

However, I was quite correct in my assertion that time won't run out when the clock reaches 0000000 - having just tried running a Geoff Mode game in SPIN until that point, it just starts again at 9999999!

 

Geoff admits in the 'Time Counter' section of his 'Guide to Geoff Mode' webpage that:

 

This no longer shows a time, but a 7-digit number which counts down from 9999999. This dates from the earliest days of Geoff Mode, and I can no longer remember why I did it.

 

What he doesn't admit, though, is that the Time Counter is seemingly completely pointless!  :D

Edited by IRF
Link to comment
Share on other sites

  • 2 months later...

A good example of the use of a lookup table in a Patch Vector can be found in the first part of Geoff' Eddys patch for Room 11 ('Under Your Spell') in 'ZX Willy the Bug Slayer':

https://web.archive.org/web/20080511161939/http://www.cix.co.uk/~morven/jsw/patches.html

I later adapted Geoff's method for the PV in the 'Master Bedroom' in 'Jet Set Mini'.

Edited by IRF
Link to comment
Share on other sites

  • 3 weeks later...

http://www.seasip.info/Jsw/jswdiffs.html

 

I thought it would be a useful resource to provide the source code for the guardian expansion code in the JSW128 game engine.  John Elliott's otherwise excellent document (link above) only does half a job in relation to this!

 

Here's the bit that John does provide:

 

 


;(v0.00HL2) Code to support multiple guardian tables.
;
    ;48k                            ;128k
    ORG    8930h            ORG    8930h
    LD    H,14h                LD    H,0
    ADD    HL,HL            CALL    CC4B6    ;Find table addr.
    ADD    HL,HL
    ADD    HL,HL

 

And here's the missing part (using the same notation, for consistency):

 

;128k

ORG     C4B6h

ADD HL, HL

ADD HL, HL

ADD HL, HL

LD BC, (W80DF)

ADD HL, BC

RET

Edited by IRF
Link to comment
Share on other sites

  • 11 months later...

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.