Jump to content


Photo

'Guardian Aura' Bug Fix and miscellaneous other patches


  • Please log in to reply
64 replies to this topic

#31 IRF

IRF

    Advanced Member

  • Contributor
  • 4,163 posts

Posted 16 November 2017 - 06:51 PM

I've tweaked the layout of the two 'Multimedia Guardian' test files, and re-uploaded them to my post from last night, in order to illustrate the point that Air cells can also have their PAPER miscoloured, if they are entered from the left (or from above) by a guardian that is passing from a different medium with a different PAPER setting.



#32 Spider

Spider

    DEC (HL)

  • Administrator
  • 3,872 posts

Posted 16 November 2017 - 07:57 PM

I've tweaked the layout of the two 'Multimedia Guardian' test files, and re-uploaded them to my post from last night, in order to illustrate the point that Air cells can also have their PAPER miscoloured, if they are entered from the left (or from above) by a guardian that is passing from a different medium with a different PAPER setting.

Tis very interesting to see the 'difference' between the two. :)

 

Its almost as though (as daft as it sounds) I expected a collision somehow :D


  • IRF likes this
Changing order to chaos since 1984

#33 IRF

IRF

    Advanced Member

  • Contributor
  • 4,163 posts

Posted 17 November 2017 - 10:30 AM

Here's another bug fix, although this applies to the 'Move the guardians' routine, rather than 'Draw the guardians'.  This fixes the bug (feature?) whereby certain vertical guardians can extend beyond their lowest permitted bound (if the distance between their upper and lower bounds isn't exactly divisible by their vertical speed).

 

 

For comparison, this is the original code, courtesy of SkoolKid http://skoolkid.gith...y/asm/90C0.html

 

DD 7E 03      9193   LD A,(IX+$03)       Update the guardian's y-coordinate

DD 86 04      9196   ADD A,(IX+$04)    

DD 77 03      9199   LD (IX+$03),A       

DD BE 07     919C   CP (IX+$07)         Has the guardian reached the lowest point of its path (maximum y-coordinate)?

30 0D           919F   JR NC,$91AE       If so, jump to change its direction of movement

DD BE 06     91A1   CP (IX+$06)         Compare the new y-coordinate with the minimum value (the highest point of its path)

28 02            91A4   JR Z,$91A8          If they match, jump to change the guardian's direction of movement

30 0E            91A6   JR NC,$91B6       If the new y-coordinate is above the minimum value, jump to consider the next entity

DD 7E 06      91A8   LD A,(IX+$06)      Make sure that the guardian's y-coordinate is set to its minimum value

DD 77 03      91AB   LD (IX+$03),A      

DD 7E 04      91AE   LD A,(IX+$04)     Negate the y-coordinate increment; this changes the guardian's direction of movement

ED 44           91B1   NEG                     

DD 77 04      91B3   LD (IX+$04),A      

 

 

The above would need to be replaced with the following (which requires code consolidation to fit eight extra bytes into the available space, or else a JUMP to somewhere with the necessary free space):

 

DD 7E 03                                        LD A, (IX+$03)                       Pick up the guardian's y-coordinate

DD 86 04                                        ADD A, (IX+$04)                    Add the guardian's vertical speed; A now holds the updated y

DD BE 07                                       CP (IX+$07)                           Has the guardian reached or gone past its lower bound?

30 07                                              JR NC, change_direction       If so, jump to change its direction of movement

DD BE 06                                       CP (IX+$06)                           Compare the new coordinate with the guardian's upper bound

28 02                                              JR Z, change_direction          If they match, jump to change the guardian's direction of movement

30 16                                              JR NC, update_y                    If the guardian hasn't gone past its upper bound, jump to update y

DD 7E 04        change_direction:   LD A, (IX+$04)                       Negate the y-coordinate increment;

ED 44                                             NEG                                           this changes the guardian's

DD 77 04                                        LD (IX+$04), A                           direction of movement

DD CB 04 7E                                  BIT 7, (IX+$04)                      Is the guardian's vertical speed now negative?

20 05                                              JR NZ, reached_bottom         If so, the guardian must have reached its lower bound, so jump

DD 7E 06        reached_top           LD A, (IX+$06)                        Otherwise, the guardian has reached its upper bound, so

18 03                                              JP update_y                             make sure that the guardian's y-coordinate is set to its minimum value

DD 7E 07        reached_bottom     LD A, (IX+$07)                        Make sure that the guardians' y-coordinate is set to its maximum value

DD 77 03         update_y                LD (IX+$03), A                        Update the guardian's y-coordinate


Edited by IRF, 17 November 2017 - 10:37 AM.


#34 Norman Sword

Norman Sword

    Advanced Member

  • Member
  • PipPipPip
  • 196 posts

Posted 17 November 2017 - 01:57 PM

Wrote this months ago, seems to be of the same theme. I had no problems fitting code into the available space.

 

:your code can be rewritten to fit into the available space. 

 

My old solution.

 

; We are dealing with a vertical guardian.
L917F
           push ix
           pop hl
           ld a,(hl)
           xor 8
           ld (hl),a
           and $18
           jr z,vert_phase
           ld a,(hl)
           add a,$20
           ld (hl),a
vert_phase:
          inc hl
          inc hl
          inc hl
          ld a,(hl) ;   y
          inc hl
          add a,(hl) ;delta y
          ld d,(ix+7) ;max y
          cp d                            ;reached or exceeded max
          jr NC,reverse_delta    ;reverse and save y as max y
          ld D,(IX+$06)               ;min Y
          cp D                            ;reached or exceeded min
          jr Z,reverse_delta       ;save MIN as position
          jr C,reverse_delta       ;save MIN as position
          ld D,A                         ;save as calculated
          jr save_y

 

reverse_delta:
          ld a,(hl) ;reverse delta y
          neg
         ld (hl),a
save_y:
         dec hl
         ld (hl),d   ;new ypos

 

        jr next_entity ;$93b3

 

; around nine bytes of unused space here

 

 

 

code from $93b3

; this label/position is referenced from all other guardian movements, 

next_entity:
        LD DE,$0008
        ADD IX,DE ;Point IX at the first byte of the next entity's buffer
        JP L90C4  ;Jump back to deal with any more guardians


Edited by Norman Sword, 17 November 2017 - 01:59 PM.


#35 IRF

IRF

    Advanced Member

  • Contributor
  • 4,163 posts

Posted 17 November 2017 - 02:31 PM

Thanks Norman.

You could use a similar PUSH IX / POP HL trick for all the 'Move the guardians' elements (ropes and horizontal guardians as well), couldn't you? Since H and L aren't used at all within that routine (and nor is there a CALL to a subroutine that does use H or L).

EDIT: In fact, if that is the case, then couldn't the PUSH IX / POP HL be placed near the very start of the 'Move the Guardians' routine - after #90C0 but before #90C4 (with #91BB jumping back to include this 'variable swap') - so that it only has to be done once, rather than at the start of each branch of the routine (for ropes, horizontal and vertical guardians)?

Edited by IRF, 10 January 2018 - 08:21 AM.


#36 IRF

IRF

    Advanced Member

  • Contributor
  • 4,163 posts

Posted 06 January 2018 - 07:45 PM

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


The above does technically save three bytes. However, they are left adjacent to the single unused byte within the main 'Draw the Guardians' routine, which isn't a very useful place.

But I think I've come up with a way to shorten the 'out of situ' part of the patch, which would yield a couple of spare bytes in a more usable location.

(If it works!)

Edited by IRF, 06 January 2018 - 07:46 PM.


#37 IRF

IRF

    Advanced Member

  • Contributor
  • 4,163 posts

Posted 31 January 2018 - 12:31 PM

But I think I've come up with a way to shorten the 'out of situ' part of the patch, which would yield a couple of spare bytes in a more usable location.


I forgot to mention that I implemented the above (successfully) in 'Jet Set 40-40'. If I recall correctly, the out-of-situ part of the patch is located at #93BB-CB, just before the short Easter egg message 'ANDYF' in the code. (And in fact, reworking the Guardian Aura Patch enabled me to fit a five-character message into that location.)

#38 Norman Sword

Norman Sword

    Advanced Member

  • Member
  • PipPipPip
  • 196 posts

Posted 01 February 2018 - 06:50 PM

Re Gaurdians aura

 

This version has a playable "Swimming pool" 

 

This is another edit of my "delete me now" file.

 

Only Rooms of interest (reference by the normal room names)

 

Swimming Pool    Guardian aura/colouring

The Chapel         homing sprite

The Bathroom     arrow volley

 

A lot of other rooms have had minor changes  

 

This is a bigger edit of the last file I uploaded. This might look like a normal JSW file but it contains 120 rooms, with each of the normal 60 rooms, having a fully definable clone room. This version could be remapped to be a playable 120+ room game.

 

The game is set to swap between each version of rooms. 

 

 

Attached Files



#39 IRF

IRF

    Advanced Member

  • Contributor
  • 4,163 posts

Posted 01 February 2018 - 07:08 PM

Nice one Norman.

 

The 'aura' fix is highlighted well by the 'printing press' guardian in the room 'Mondrain', because of that guardian's 'transparency'.

 

The yellow 'bat' guardian also illustrates the fact that when guardians are passing through cells with a non-black PAPER setting, the BRIGHTness settings of the guardians are inherited from the cells through which they pass - rather than the other way round, as was the case in the original JSW.

 

****

 

I'm guessing that the decision as to which variant of each room to display, at a given moment in time, is based on whether the 'tick' counter (#85CB in the original game) has an odd or even value (i.e. status of Bit 7 of that variable) at the point when Willy enters the room.


Edited by IRF, 01 February 2018 - 08:31 PM.


#40 Norman Sword

Norman Sword

    Advanced Member

  • Member
  • PipPipPip
  • 196 posts

Posted 02 February 2018 - 07:54 PM

Ramblings:- concerning the last part demo program.
.
     I got bored with the standard 64 room limit, plus the fixed memory restrictions, so decided to change how the rooms where stored.
.
Change 1) Leave the room data alone (e.g. the tile definitions, sprite definitions, room names) but split the room shapes off from this data and compress. I ended up with 60 room data pages and 2 sets of 60 room shapes. This edit has for every room shape, a shadow room shape. It was in the file before last, that I uploaded. Which was why some room shapes changed.
.
Change 2) I decided to then compress the room data. Not an extensive compression, but enough data was removed so in this version I had 2 sets of room data, and 2 sets of room shapes. This was 60 rooms, and 60 rooms shadowed. The change from one set of rooms to the other permitted new sprite definitions and new tile definitions and new room names. It was effectively a 120 room game with no attempt at changing the alternate room layout. The two sets of rooms still contained a common overall layout and a common set of room keys.
.
Sidetrack
Norman sword Key storage
.
     It is easy to compress the room data, and therefore easy to increase the room count upwards. The simplest method is to ditch the constrictive usage of page boundary data and move to indexed data with variable size. This permits every room to be whatever size it requires. The room exits use a full byte so it is easy to have room numbers greater than sixty three. We can have room numbers up to two hundred and fifty five. But we do not have the memory to store that many, so a realistic figure of one hundred and twenty seven is possible.
.
     The rooms can easily be drawn and stored. The biggest challenge lies in the storage of the keys. Matthew implemented a six bit storage limit into the room numbers stored in the two pages of stored data for the keys. Some attempts have extended this table by adding a new page of data. (256 bytes) When only 32 bytes where needed. What was missed was the simplicity of just using a one bit variable that indicates upper or lower sets. Rooms naught to sixty three are stored in the key list exactly as of present, occupying the upper half of the key page. Any room that is over sixty three, uses the lower half of the table. Its value "AND'ed" with sixty 63 and uses the same data space, but is confined to the lower half.
.
     I use the term "the lower half" when in reality I am storing one set of key data from offset 255 downwards, and the other set of data from offset 0 and storing upwards. As long as the two sets of data do not overlap. Then the two sets of data can happily exists in the same data space.
.
The changes needed to some of the other routines are minimal. (broad outlook on changes, no detail)
:- The reset the keys to uncollected, changed to reset the full page, as opposed to just the top part.
:- the number of items uncollected is the top page value - the bottom page value 
:- The key collection routine can be modified to search upwards or downwards depending on the value of the room number. e.g the key flag
:- The drawing of new rooms from the value obtained from room data, sets which set of keys needs to be searched. Rooms 0-63 search upper key list, rooms 64 to 127 search lower key list. e.g set a one bit key flag. Which is used by the key collect and draw routine

 

     I do not check the key list in a similar fashion to the original. On room expansion I generate a new key list for the current room. This is the key list used to check for collected items and also to animate the keys. The method I use to generate this new key list is similar to the method outlined above. For the lower rooms I search the top of the key list, for rooms above 64 I search the bottom of the list.
.
     This limits the total key count to 256, but other versions have this restriction. It took me around two hours to implement this data change and also implement the usage of both sets of data.
.
     Having implemented the above change for the keys with each block of 60 rooms having its own tile/sprite definitions/room name, its own room shape and now its own key storage area. It is now possible to implement the next change. (not implemented).
.
Change 3) The logic added for the shadow routines can be removed. One set of rooms no longer needs to have any reference to the other set of rooms. Both sets of rooms are now free in every aspect. And we can map out a 128 room game
I have about 99.9% of the above written, but at present no urge to implement change 3. (which is mainly deleting routines)

     At present I am editing the version with 120 rooms, but each set is an overlay of the other set. This restricts room layout to enable free switching between the two sets. The designing and editing is still done by using the standard 64 room version. What my program does is incorporate the data from two games, and merge them together.

.

BASIC
     As I said above I compressed the rooms because I was reaching the fixed limit of memory that I had available. I was experiencing graphics being overwritten. So I wrote a routine in BASIC to compress the room graphics and output the data in assembler form. I would have liked to say this routine was simple to write. And perhaps it was, the BASIC is a few lines short of 1000 lines and took a week to write. (not in one go)

.

The BASIC file was edited along these lines

.

     The basic takes a game file and from it extracts the game data, in the Format that is similar to the Matthew room data layout below.
     This was changed to extract the room data (the shape of the room) into another file after doing a RUN LINE COMPRESSION on the file.
     This was then changed to have macro's that allowed both versions to be used by the assembler in one file.
     This was again changed to enable vertical and horizontal RUN LINE COMPRESSION for the assembler file.
     Another change enabled the stairs and conveyors to be incorporated into the VERTICAL RUN LINE COMPRESSION.
     Yet another change saw the output of the keys data in a separate file
     Yet another change saw the program output the data from two files at the same time. The original data and the shadow data
     Another change and the file was compressing and deleting the unwanted room graphics/exits/room name/unused sprites etc.
     Then the final change was the merging of both sets of key data into a single key data file.

.

     I am always amazed at how fast modern PC's can do this amount of processing and output. The time between the start and finish of the extraction process is measured in fractions of one second. Yet the output is measured in around 110k of source code data

.

Whilst I was changing the data, I needed to change lots of parts of the assembler source file in parallel. And I was amazed when I wrote the final leap into having all of the data compressed that it worked first time.
.
.
.
example of the size of the data for the room shape.
.
As stored by Matthew for The Off Licence
; reduced from the uncompressed 512 bytes used in Manic Miner

; this is two bit run line coding

;128 bytes,#80

49152 DEFB 0,0,0,0,0,0,0,0  ;Room shape
49160 DEFB 0,0,0,0,0,0,0,0
49168 DEFB 0,0,0,0,0,0,0,0
49176 DEFB 0,0,0,170,170,170,170,170
49184 DEFB 0,0,0,128,0,0,0,2
49192 DEFB 0,0,0,128,0,0,0,2
49200 DEFB 0,0,0,140,0,0,0,2
49208 DEFB 0,0,0,128,0,0,0,2
49216 DEFB 0,0,0,128,0,0,0,2
49224 DEFB 0,0,0,128,0,0,0,2
49232 DEFB 0,0,0,128,0,0,0,2
49240 DEFB 0,0,0,170,0,0,2,170
49248 DEFB 0,0,0,0,0,0,0,2
49256 DEFB 0,0,0,0,0,0,0,2
49264 DEFB 0,0,0,0,0,0,0,2
49272 DEFB 85,85,85,85,85,85,85,85
.
What it is possible to compress to. (variable size)
.
Data as stored by me for the same room. The Off Licence
;this is vertical and horizontal run line coding
;26 bytes, #1a

102 bytes smaller

db #25,#DF,#2D,#5F,#2D,#4C,#97,#33
db #67,#D7,#1E,#3F,#2B,#93,#3F,#0D
db #C0,#3F,#3F,#1C,#83,#0A,#84,#3F
db #1F,#5F
  
  
; Matthews storage of the basic room data
; 128 bytes #80

49280 DEFM "         The Off Licence        " ;Room name
49312 DEFB 0,0,0,0,0,0,0,0,0 ;Background
49321 DEFB 68,255,222,108,136,18,64,4,0 ;Floor
49330 DEFB 22,34,255,136,255,34,255,136,255 ;Wall
49339 DEFB 5,248,136,158,189,189,158,136,248 ;Nasty
49348 DEFB 7,3,0,12,0,48,0,192,0 ;Ramp
49357 DEFB 67,51,255,51,0,255,0,170,0 ;Conveyor
49366 DEFB 0 ;Direction
49367 DEFW 24371 ;pos
49369 DEFB 12 ;Length
49370 DEFB 1 ;Direction
49371 DEFW 24535 ;pos
49373 DEFB 4 ;Length
49374 DEFB 5 ;Border
49375 DEFB 0,160 ;Unused
49377 DEFB 24,24,60,126,98,98,98,126 ;Item
49385 DEFB 1 ;left
49386 DEFB 0 ;right
49387 DEFB 0 ;above
49388 DEFB 0 ;below

49389 DEFB 0,0,0 ;unused

49392 DEFB 10,138 ;guard 1
49394 DEFB 12,29 ;guard 2
49396 DEFB 44,39 ;guard 3
49398 DEFB 255,0 ;Terminator
49400 DEFB 0,0
49402 DEFB 0,0
49404 DEFB 0,0
49406 DEFB 0,0

.

all that is needed. variable size
;82 bytes (this might be an edited version of the above)

;46 bytes smaller

.

db #09,"The Off Licenc",+"e"+#80
db #00 ; back
db #44,#FF,#DE,#6C,#88,#12,#40,#04,#00 ; floor
db #16,#22,#FF,#88,#FF,#22,#FF,#88,#FF ; wall
db #05,#F8,#88,#9E,#BD,#BD,#9E,#88,#F8 ; nasty
db #07,#03,#00,#0C,#00,#30,#00,#C0,#00 ; ramp
db #43,#33,#FF,#33,#00,#FF,#00,#AA,#00 ; convey
db #45,#18,#18,#3C,#7E,#62,#62,#62,#7E ; (conv/ramp/border)/item
db #01,#00,#00,#00; Paths
db #0A,#8A; guard 1
db #0C,#1D; guard 2
db #2C,#27; guard 3
db #FF; Terminator 
        

Matthew per room                 256 bytes
; this room compressed 26+82=    108 bytes + 4 for pointers
;                        144 bytes smaller

 

 

query on terminology. The middle sprite in Mondrain, is used extensively in conjunction with the  Monks. The shape and format of the sprite is typical of medieval parchment  scrolls.  

Attached Thumbnails

  • SCROLL.jpg

Edited by Norman Sword, 02 February 2018 - 08:44 PM.





1 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users


    Bing (1)