Jump to content
Jet Set Willy & Manic Miner Community

Norman Sword

Contributor
  • Posts

    596
  • Joined

  • Last visited

Everything posted by Norman Sword

  1. Code at $8ebc change to original 8EBC call Butt LD A,($85CF) 8EBF ld a,($85CF) ADD A,$10 8EC0 8EC1 AND $F0 8EC2 ADD A $10 8EC3 LD ($85CF),A 8EC4 AND $F0 8EC5 8EC6 call $8E99 CALL $8E9C see the routine below 8EC9 LD A,$02 8ECB LD ($85D1),A 8ECE LD HL,$85D0 8ED1 RES 1,(HL) 8ED3 RET ; the call to this routine is moved to the point that "a" is saved 8E94 LD A,($85CF) 8E97 ADD A,$08 8E99 LD ($85CF),A ; moved to call here 8E9C AND $F0 ;<<<<<<<< original call point 8E9E LD L,A 8E9F XOR A 8EA0 RL L 8EA2 ADC A,$5C 8EA4 LD H,A 8EA5 LD A,($85D3) 8EA8 AND $1F 8EAA OR L 8EAB LD L,A 8EAC LD ($85D3),HL 8EAF RET ; a very vague Butt routine Butt: test if code is wanted, e.g. jump direction, headbutt flag return if not wanted else call Butt2 inc hl ;all calls here return with hl intatct Butt2 code to check where hl is pointing return is not wall tile act on the headbutt If tile graphics not cleared then return clear TILE from Master Attrib ret ;========================================================================================== Teaser: The border bits are very wasteful. The bits 0-1-2 are the border colour and the rest of the byte is wasted. So I use 1 bit for setting the Butt to on or off. That still leaves 4 bits With the room fixed to 256 bytes in size,. Conveyors and ramps use Ramp_dir 1 byte Ramp_position 2 bytes Ramp_length 1 byte Conveyor_dir 1 byte Conveyor_position 2 bytes Conveyor_length 1 byte That is eight bytes to define these two actions - It is possible on variable room size (as I now have) to delete a lot of the fixed room data. The bytes that store the conveyor and ramp direction are now also stored in the border colour byte. In fact I have deleted all the ramp data and all the conveyor data from the room data. e.g. these eight bytes are reduced to the top two bits in the border flag... - It uses a big chunk of code to restore these bytes but the code is part of a bigger piece of code. And the ramp/conveyor specific code (the bit dealing with replacing the data, deleted from the room) is no where near 100 bytes Simple maths will show you why it is worth the effort of removing unwanted data. Those 8 bytes are repeated 128 times, if using the old room storage method.( in a 128 room game) So the data contained would use 128*8 bytes of memory ( 1024 ) verses the 100 bytes of code The above is an over simplification.
  2. Yes it is #8ebc. The code is crumbly floor in reverse. The majority of my code is concerned with checking that the wall tile can be deleted. I have now added a room specific flag. One of the unused border bits (bit 4) in my case. So rooms have head butting as an option via the border flag.(For now) This means only the one room left. And since that is in the original 60 rooms, it should be edited back to the original layout, and have the head butt option removed. Tested out the full 128 room version. I have it up and running and can now wander around 128 rooms in a 48k Spectrum Don't expect any major changes, from other versions... I am testing other things, and I have never tested this to see how far you can get. 128 room.tap
  3. The wall tile disappearing is the result yet again of the ramp/stair code. So I used part of that code to stop downward detection and deletion of the tiles. The updated file is with the first file. E.g. Two posts ago.
  4. Test this to see if you like the concept. Yes it my mega edited, must delete, what a mess piece of code. 120 room, bullets,and now headbutting I have stopped the ability to head butt out of the top of the room. So the top row of wall tiles can not be headbutted away. Removed the downward movement butt-ability.... That's the second file. Added a blocking ability. This stops a wall being removed if over another type of tile. That's version 3 The Top Landing is the only room that I have edited to show this. (feature is in every room, but they are not edited) IRF HEAD BUTT.tap IRF 2 HEAD BUTT.tap IRF 3 head butt.tap
  5. Do you need a new cell type? Most of the lower, and the bottom row is impossible to head butt. If head butting from the room below they would reset anyway, after each room change. The lazy option is to just enable in certain rooms the ability to head butt a wall tile from underneath. Would have been handy in the forgotten abbey, when the wall tile was accidentally left unchanged and made the room impossible. If the only tile that can be head butted is a wall tile, and only from below, should be easy enough to design rooms to allow for that fact. A vertical wall that is inaccessible from below, still acts as a vertical wall, and is impossible to penetrate by head butting. Very easy to do,,,, I have a version running now.
  6. A flurry of posts whilst I sat with the above text in the editor.
  7. I have no problems with the code as listed here I changed the ld a,(hl) (twice) ; ;----------------- CODE by IRF ------------------------- ; ; ; Pre_search: LD A,(#A3FF) ;offset for first key LD L,A LD H,#A4 ;base of key list . full address now in HL filter_loop: LD A,(#8420) ;current room XOR (HL) ; xor comparison AND #3f ; does it match after removing key position page and collection flag. Bits 6 and bit 7 JR Z,match_found INC L ;move to next key JR NZ,filter_loop ;keep going through list ; ; If we get here, then we have been through all the item table entries, and there are no items (collected or uncollected) to consider in this room: ; LD A,#C9 ;disable item drawing by overwriting code with a "ret" Pre_exit: LD (#93D1),A ; disable/set the Item-drawing routine whilst Willy is in this room RET ;finished ; match_found: LD A,L ; get the position in the list LD (#93D2),A ; and store offset .value used to initiate the item-drawing loop in this room find_last_item: INC L ; wrap around is not a problem LD A,(#8420) ; the current room XOR (HL) ; comparison match AND #3F ;does it match after removing key position page and collection flag. Bits 6 and bit 7 JR Z,find_last_item ; If we get here, then HL is pointing at the first item for the next room: LD A,L ; get the position in the list LD (#9452),A ; and store this offset. value used to terminate the item-drawing loop in this room ; Now restore the first byte of the Item-drawing routine: LD A,#21 ;enable item drawing by replacing the LD HL,xxxx opcode jr Pre_exit
  8. In the context that I have just written this and it is not tested. ; As defined in Manic Miner ; HL Address of the crumbling floor tile 35770 LD C,L 35771 LD A,H 35772 ADD A,27 35774 OR 7 35776 LD B,A 35777 DEC B 35778 LD A,(BC) 35779 INC B 35780 LD (BC),A 35781 DEC B 35782 LD A,B 35783 AND 7 35785 JR NZ,35777 35787 XOR A 35788 LD (BC),A 35789 LD A,B 35790 ADD A,7 35792 LD B,A 35793 LD A,(BC) 35794 OR A 35795 RET NZ ; ignoring the above, no help to me ; ; this code moves the tile in hl down by one line ; xor a ld d,a ld b,8 loop ld e,(hl) ;the current line or d ;the line above ld (hl),d ld d,e inc h djnz loop ; ; a=the accumalative value of the bits drawn ; or a ;if a value exists then the floor is still collapsing This permits a one pixel line to be moved down the screen
  9. Definitely a lot easier to write code and not edit a fixed piece of code. Trying to write source code with proportionally spaced font is a challenge. The presentation leaves a lot to be desired. Then every time I do a cut and paste I am presented with a file that has most of the blank lines deleted. Hence the multitude of lines with a full stop , semi colon or some other marker. This is my attempt at trying to force inclusion of blank lines..... I do wonder also why the internet has decided that tabs need replacing with a space (or even nothing). If I press tab, as I write this the cursor will disappear and I have no more typing output, until I click with the mouse on the screen. Is the input designed to remove the archaic tabs at source, and is it trying to educate me in the new world order. NO TABS ALLOWED.
  10. Revert (partialy) back to the original with the erroneous LD A,L . . Using original source and I am listing what is needed (up to edit 2(now edit 3.5)) to extend the keys to enable 128 rooms. This is done without wasting a full 256 bytes of data, and uses very little to accomplish this. . This method gets around the key reset at game start up (no code change). It also has no need to calculate the total keys (the value is as before) . AT NEW ROOM set up ; ;use $A3ff for the lower key OFFSET e.g this value is the numbers of keys in total. as before . ; use $A3fe for the upper key, this value holds the start of keys for rooms 64 upward . ; storage of keys is laid out as follows : ;from the value of ($a3ff) up to ($a3fe) the lower room keys ; from the value in ($a3fe) up to $ff the keys for rooms 64 to 128 . new code to implement change ld bc,($a3fe) ; ; c=upper key pointer ; Changed from what I originally wrote ; b=lower key pointer ; LD A,(ROOM_NUMBER) AND 64 ;UPPER OR LOWER SET JR z,lower_set ld b,c ;set b=upper key offset ld c,0 ;set limit=0 to stop search lower_set: ld a,b ;this is the start of search ld ($93d2),a ;set the new base for search ld a,c ld ($9452),a ; set the upper limit of search ; ;The above sets up the key collect routine ; ;------------------------------------- modification to the key collect routine address old code replace with 93D1 ld h,#A4 ld hl,#A4ff << LS of hl modified 93d2 93d3 ld a,($A3ff) 93d4 nop 93d5 nop 93d6 ld l,a nop << remove this as well (ironic that the LD a,L was ommited at the end and ommited for deletion at the beginning) . . 93E0 JR NZ,$9452 JR NZ,$944F <<< THREE BYTES EARLIER . 942E JR $9452 JR $944F << THREE BYTES EARLIER . 943E lD A,(HL) LD A,D ; 943F RLCA RLCA 9440 RLCA RLCA 9441 RLCA RLCA 9442 RLCA AND #08 9443 AND #8 9444 ADD A, #60 9445 ADD A,#60 9446 LD D,A 9447 LD D,A PUSH HL 9448 PUSH HL LD HL, #80E1 9449 LD HL,#80E1 944A 944B CALL #9699 ;call address is 2 bytes earlier 944C LD B,#8 944D 944E CALL #969B POP HL ;new branch to here 944F INC L 9450 LD A,L 9451 POP HL CP #00 ; old branch to here 9452 INC L 9453 JR NZ,93D7 JR NZ, #93D7 ;UNCHANGED 9454 9456 RET RET ;UNCHANGED ;-------------------------------- keys are stored in this fashion START OFFSET IN $A3FF OFFSET IN $A3FE THE 255TH ENTRY OFFSET 0 v v v 0,0,0,0,0,0.....,0,0,0,0,L,L,L,L,L.....,L,L,L,L,L,L,L,L,L,L,L,H,H,H,H ......,H,H,H,H,H,H,H . WHERE L IS THE DATA FOR ROOMS 0 TO 63 (THE LOW ROOMS) . AND H IS THE DATA FOR ROOM 64 TO 127 (THE HIGH ROOMS)
  11. :this is the above post rewritten to fix the missed LD A,L ;I could not find a space for the missed instruction so a redesign . Extending the rooms up to 128. I wrote a couple of posts back of a method to extend the key tables to have over 64 rooms. I was vague because I do not use the original source layout. So I have had a look at the original source and I am listing what is needed to extend the keys to enable 128 rooms. This is done without wasting a full 256 bytes of data, and uses very little to accomplish this. This method gets around the key reset at game start up (no code change). It also has no need to calculate the total keys (the value is as before) AT NEW ROOM set up ; use $A3ff for the lower key OFFSET e.g this value is the numbers of keys in total. as before . ; use $A3fe for the upper key, this value holds the start of keys for rooms 64 upward . ; storage of keys is laid out as follows : from the value of ($a3ff) up to ($a3fe) the lower room keys ; from the value in ($a3fe) up to $ff the keys for rooms 64 to 128 . new code to implement change . ld bc,($a3fe) . ;c=upper key pointer ; Changed from what I originally wrote ; b=lower key pointer . LD A,(ROOM_NUMBER) AND 64 ;UPPER OR LOWER SET JR z,lower_set ld b,c ;set c=upper key offset ld c,0 ;set limit=0 to stop search lower_set: or $40 ld (93dc),a ; the room number searched for with bit 6 set ld a,b ;this is the start of search ld ($93d2),a ;set the new base for search ld a,c ld ($93d6),a ; set the upper limit of search . The above sets up the key collect routine ;------------------------------------- modification to the key collect routine address old code replace with 93d1 ld h,$a4 ld hl,a4ff ; this is the start offset 93d2 93d3 ld a,($a3ff) NEW LOOP HERE 93d4 ld a,l 93d5 cp $ff ;this value is the exit offset 93d6 ld l,a OLD LOOP HERE 93d7 ld c,(hl) ret z 93d8 res 7,c ld c,(hl) 93d9 res 7,c 93da ld a,($8240) 93db ld a,$ff ;this is the room number with bit 6 set 93dc 93dd or $40 nop 93de nop ; the final branch of this routine changed to . 9453 jr 93d7 jr 93d4 ;change the loop address ; ;-------------------------------- keys are stored in this fashion START OFFSET IN $A3FF OFFSET IN $A3FE THE 255TH ENTRY OFFSET 0 v v v 0,0,0,0,0,0.....,0,0,0,0,L,L,L,L,L.....,L,L,L,L,L,L,L,L,L,L,L,H,H,H,H ......,H,H,H,H,H,H,H . WHERE L IS THE DATA FOR ROOMS 0 TO 63 (THE LOW ROOMS) . AND H IS THE DATA FOR ROOM 64 TO 127 (THE HIGH ROOMS) . . . Not checked for difference in amount of changes. Removed most of the changes for the lower half of the key routine. The above will only permit 255 keys and not the full 256
  12. Probably, I changed so much as I was writing it. I swapped a lot of the registers around and a lot of the upper/lower references. I was changing the code as I wrote it. I will re read and edit.
  13. Extending the rooms up to 128. I wrote a couple of posts back of a method to extend the key tables to have over 64 rooms. I was vague because I do not use the original source layout. So I have had a look at the original source and I am listing what is needed to extend the keys to enable 128 rooms. This is done without wasting a full 256 bytes of data, and uses very little to accomplish this. This method gets around the key reset at game start up (no code change). It also has no need to calculate the total keys (the value is as before) AT NEW ROOM set up ; use $A3ff for the lower key OFFSET e.g this value is the numbers of keys in total. as before . ; use $A3fe for the upper key, this value holds the start of keys for rooms 64 upward . ; storage of keys is laid out as follows : from the value of ($a3ff) up to ($a3fe) the lower room keys ; from the value in ($a3fe) up to $ff the keys for rooms 64 to 128 new code to implement change ld bc,($a3fe) ; c=upper key pointer ; Changed from what I originally wrote ; b=lower key pointer LD A,(ROOM_NUMBER) AND 64 ;UPPER OR LOWER SET JR z,lower_set ld b,c ;set c=upper key offset ld c,0 ;set limit=0 to stop search lower_set: ld a,b ;this is the start of search ld ($93d4),a ;set the new base for search ld a,c ld ($9452),a ; set the upper limit of search The above sets up the key collect routine ;------------------------------------- modification to the key collect routine address old code replace with 93d3 ld a,($A3ff) ld a,0 <<value modified . nop . 93E0 JR NZ,$9452 JR NZ,$9450 <<< TWO BYTES EARLIER . 942E JR $9452 JR $9450 << TWO BYTES EARLIER . 944c ld b,8 call $9699 ;two bytes earlier 944e call $969b 944f pop hl 9450 inc l 9451 POP HL CP 00 <<value modified 9452 INC L 9453 JR NZ,$93D7 JR NZ,$93D7 << unchanged ;-------------------------------- keys are stored in this fashion START OFFSET IN $A3FF OFFSET IN $A3FE THE 255TH ENTRY OFFSET 0 v v v 0,0,0,0,0,0.....,0,0,0,0,L,L,L,L,L.....,L,L,L,L,L,L,L,L,L,L,L,H,H,H,H ......,H,H,H,H,H,H,H . WHERE L IS THE DATA FOR ROOMS 0 TO 63 (THE LOW ROOMS) . AND H IS THE DATA FOR ROOM 64 TO 127 (THE HIGH ROOMS)
  14. Decided to test concept. One hour later I had an up and running 120 room version. Both completely independent and both can be remapped. No enthusiasm for doing so. Both sets or rooms are free to cross to the other at any point. This is a full 120 room version. I can not think of any layout restrictions.
  15. 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.
  16. 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. JSW ALTERED 1.tap
  17. I have added a note to the top of what I wrote, concerning the SET 7,L opcode.
  18. Rough figures... ;**************************************** ADDENDUM **************************************** I originally used the terminology of REM'd out for the SET 7,L in the code. This is only possible in an assembly listing and is not possible with situations such as this. The nearest equivalent would be inserting NOP,NOP. However this makes a slight change in how the text is handled. The stream of text going through the print routine could have any value, and might be over 127 With that in mind, it would make a far better change to use RES 7,L as the alternative to SET 7,L ******************************************* . .From listing of JET SET WILLY Numbers in HEX . 9691 LD H,$07 9693 LD L,A 9694 SET 7,L ;could delete NOP'd >>> use RES 7,L 9696 ADD HL,HL ;*2 9697 ADD HL,HL ;*4 9698 ADD HL,HL ;*8 9699 LD B,$08 . Changing the opcode at #9691-- the LD H,07 setting H to = 0 1 2 3 4 5 6 7 etc muliplied *8 0000/0800/1000/1800/2000/2800/3000/3800 up to f800 setting bit 7 of L and multiplying by 8 gives an offset of 400h . so by combining we can have offsets of 0000/0400/0800/0c00/1000/1400 up to Fc00 . by setting either we have #20 addresses we can use. anything below #8000 is taken by buffers/screen/rom Giving usable addresses such as (in hex) h= 10 11 12 13 14 15 16 17 8000,8800,9000,9800,a000,a800,b000,b800 with RES 7,L REM'ed out 8400,8c00,9400,9c00,a400,ac00,b400,bc00 with SET 7,L left in h= 18 19 1a 1b 1c 1d 1e 1f c000,c800,d000,d800,e000,e800,f000,f800 with RES 7,L REM'ed out c400,cc00,d400,dc00,e400,ec00,f400,fc00 with SET 7,L left in ;---------------------------------------------------------------------------------------------------------------------------- The font needs to be stored at these addresses (data from above adjusted for font position) e.g.+#100 h= 10 11 12 13 14 15 16 17 8100,8900,9100,9900,a100,a900,b100,b900 with RES 7,L REM'ed out 8500,8d00,9500,9d00,a500,ad00,b500,bd00 with SET 7,L left in h= 18 19 1a 1b 1c 1d 1e 1f c100,c900,d100,d900,e100,e900,f100,f900 with RES 7,L REM'ed out c500,cd00,d500,dd00,e500,ed00,f500,fd00 with SET 7,L left in ;----------------------------------------------------------------------------------------------------------------------------- Plenty of memory addresses to play with (back to decimal) I would assume you would use a short font, e.g. just ASCII 32 up to ASCII 127 or less I see no point in ASCII above 128 or below 32 The stored font then needs to sit 32*8 above the base page (listed above) e.g. +256 with a font size less than 800 bytes Stored font is (128-32)*8=768
  19. The terminology that I used was "Mid Sprite bounce". Indicating a bounce in the mid part of its path. NOTE I keep on using Mid and not Middle. Mid has a multitude of definitions Its preposition definition is --- in the course of --- You define a bounce point in the course of the sprite path.
  20. Yes an increment of IX. The code must also copy the y position.....Which it can do when setting the arrows phase in room set up.. (different from what I have at present... So I will change my own code) If a pair of arrows are defined and they are facing each other and cross on the screen. Then one needs setting as even and the other odd. (x position) Erroneous spelling noted. The assembler code is 540k of ASCII text. It has become difficult to read and bits and pieces get missed.
  21. The seven empty slots. Which because of the code that double up arrows, gives fourteen arrows in that room. Of note it only uses ONE guardian definition, the others are defined by the position. E.g. the code below is all it takes in the room set up. But first a quick run down of my thoughts... bit 0 gives the arrow bug . but just taking the first 16 values and removing that bug leaves values 00,02,04,06,08,10,12,14 . we also have a feature/bug that stops the code working on the extremes of chars, so values of 00 or 14, should also be avoided. leaving 02,04,06,08,10,12 = 6 values from the first 16. or for the full screen playing area 16*6 values. 96 values from 256 in total. . I fail to see why this is used. If the arrow had been confined to a fixed position within the char. Then only four bits are needed to define an arrow. The other four bits could be used for any multitude of applications. . At present an arrow is defined by a fixed guardian. If a JSW2 style volley is wanted then each arrow would need its own guardian slot/definition. . By juggling those four bits a shift can/could be introduced into the fixed timing phase of the arrow. (done at room set up) This then permits one guardian to be defined as having up to 16 sub classes, just by allowing a phase change on just the one guardian definition. . patched into the room set up, after testing for an arrow type guardian. With no attempt at reducing the code size. ld a,(iy+arrow_y) ld b,a and 15 add a,a add a,a add a,(iy+arrow_x) ld (iy+arrow_x),a ld a,b and $f0 add a,8 ;middle of char ld (iy+arrow_y),a
  22. Re arrows:- The arrows, my first play with them introduced a second arrow into the same guardian slot. Mentioning wasted bits I decided to implement something I had thought about concerning the arrows. This file shows what the wasted bits can do. Only demonstrated in the bathroom. This arrow demo, is tagged onto a file that keeps on being added to. (it needs deleting) mega volly.tap.tap
  23. I amended the routine the handles depression into a block for ramps. It was not listed because it was another problem, separate from the ramp code. Plus my version can not be used because it uses subroutines and the routine itself is another subroutine. I would have needed to rewrite it.
  24. ;very little difference to the other version. ; ;but this has ;1) the addition of cell blocking to stop up and down movement via stairs into blocks ;2) changes in logic for jumping. ;3) removal of some data from the data table ; ; some of the data tables entries can be calculated by code. But the overhead of the code is bigger than the data table entry ;e.g entry for (ix+ramp_final_adjust)= (ix+ramp_where_1)-(ix+ramp_step) ; ;set variables for these offsets ramp_step equ 0*2 ramp_where_1 equ 1*2 ramp_where_2 equ 2*2 ramp_adjust equ 3*2 ramp_final_adjust equ 4*2 ramp_animation_reset equ 5*2 ; ;left data followed by right data left_data DB -1, 1 ;0 STEP TO NEXT animation FRAME - replaces inc or dec DB $1f, $22 ;1 POSITION OF RAMP 1 - ramp walk up DB $41, $40 ;2 POSITION OF RAMP 2 - ramp walk down DB -1, 2 ;3 DIRECTION TO ADJUST HL - where to check vertically db $20, $21 ;4 FINAL ADJUST - final adjust of willy to his new moved to position DB 3, 0 ;5 ANIMATION RESET for next frame ;----------------------------------- ; ;8FBC: Move Willy (3) ; Used by the routines at 8DD3 and 8ED4. This routine moves Willy ; left or right as necessary. RAMP_LOGIC ;L8FBC LD A,(ROPE_STATUS) ;L85D6;rope status indicator DEC A ;Is Willy on a rope? RET P ;Return if so (Willy's movement along a rope is handled at 935E) LD A,(L85D0) ;L85D0;Willy's direction and movement flags BIT 1,A ;Is Willy moving? RET Z ;Return if not ;not on a rope, but moving ld ix,left_data AND $01 ;Is Willy facing left? JR nz,set_left ;go if so 1=LEFT, 0=RIGHT inc ix ;else move IX to right data set_left: ld c,a ;save direction facing LD HL,(WILLY_ATT) ;L85D3; Willy's attribute buffer coordinates ; is the animation still within the same ATT squares ld de,WILLY_ANM ld a,(de) ;(WILLY_ANM);L85D2 ;Willy's animation frame at 85D2 add a,(ix+ramp_step) ;-1 OR +1 step to next animation ;if it was 0 then and now -1 ;or if it was 3 then now 4 ; in both cases bit 2 is set BIT 2,A ;check limits JR NZ,RAMP_CHK ;L8FDC ;move Willy's across a cell boundary ;if here still contained within the same animation (att) square, but different phase of animation LD (DE),A ;WILLY_ANM RET ; Willy now needs to move left or right and move into new attribyte squares ; this movement also needs to handle the stairs and check for their presence RAMP_CHK: ; three final outcomes for bc ; going up bc=-32 ; going down bc=+32 ; no ramp/blocked bc=0 push hl ;save for later ; all de increments are positive so preload D ld d,0 ; if jumping ignore ramp checks LD A,(AIRBORNE) ;L85D1 OR A ;Is Willy jumping? JR NZ,null_offset ;Jump if so ;not jumping so check for stairs ld a,(RAMP_DIR) ;L80da ;either 0 or 1 ; in the original JSW this value is 0 or 1 (my versions use other bits. so get rid the extra bits) and 1 ;get rid of the other bits ; this condition swaps on left and right movement cp c ;set the condition for where to check ;assume going up ramp ld bc,-32 ld e,(ix+ramp_where_1) jr nz,ramp_decided ; if here going down ld bc,+32 ld e,(ix+ramp_where_2) ramp_decided: add hl,de ; add offset to find ramp/stair square ld a,(RAMP) ;L80C4 sub (hl) ; is a ramp here ? ;if ramp not found then no offset needed jr nz,null_offset ;on a ramp is it going down? or b ;the direction, taken from BC=+32/-32, "A" must have been 0 jr nz,found_ ;branch if going up ;going down so locate the possible blocking tile LD A,L ADD A,(ix+ramp_step) ;step across to possible wall LD L,A ;is the wall blocking descent ld a,(WALL) ;L80B2 cp (hl) jr nz,found_ ;a wall is blocking going down ramp- so remove ramp offset - and walk horizontally along ramp/wall : : ; come here for no offset-or no ramp action null_offset: ld b,d ; ld c,d ;bc=0, no ramp so no offset/shift found_: pop hl ;retrieve WILLY_ATT add hl,bc ; add the possible ramp displacement ld a,(WALL) LD B,A ; ld e,(ix+ramp_adjust) ;d is still 0 ld a,l and 31 add a,e ; move across ;if negative (-1) then jp m,GO_ROOM_LEFT ;L948A ; if 32, then also off screen bit 5,a jp nz,GO_ROOM_RIGHT ;L949E ld a,l ; restore full x position (which has part y position embeded) add a,e ld l,a ;still on screen bit 1,h jr nz,ignore_this ; additional check if moving up a ramp; which checks out of line for willies head ;c can be -32 +32 or 0 bit 7,c jr z,hor_or_dwn ;going up find the tile to check ld e,a sub (ix+ramp_step) ; the direction we are moving ld l,a ;hl adjusted to head tile ld a,b ; the wall tile value cp (hl) ;wall tile? ret z ;return path is blocked ;adjust back ld l,e hor_or_dwn: ; move vertically and check the squares ; after the initial add hl,bc and possible head check ; this checks downwards in a line ; ;change logic if jumping downward, willies head can pass through wall block call jump_fix ;z=moving down ld a,b jr z,ignore_this ;zero indicates logic change-- ignore this tile cp (hl) ;head ;wall tile? ret z ;return path is blocked ; resume checking vertically down ignore_this: ld e,$20 ;D is still 0 ADD HL,DE ;move hl down one row ; ;(y+0) if Willy is on or about to up a ramp ; ;(y+1) if just walking or ; ;(y+2) if Willy is walking down a ramp CP (HL) ;foot ;wall tile? RET Z ;Return path is blocked LD A,(WILLY_Y) ;L85CF; y-coordinate (Y) ; bc held the ramp shift (b has been re-used but c is still the ramp shift) SRA C ; halve the value from ;c 32>16 ;c 0>0 ;c-32>-16 to get ramp y-shift ADD A,C ; y-position + ramp y shift LD C,A ; save in C ; this addition is changing logic depending on movement (jumping) call jump_fix ;z=moving down ; if jumping downward this square MUST be checked jr z,force_this ; otherwise check if willy occupies 3 squares ld a,c AND $0F ; JR Z,ONLY_TWO ;Jump if not force_this: LD A,b ;ATT wall tile ADD HL,DE ;point hil at the cell one lower ; Addendum for the bottom of the screen... Jumping downward and cell aligned can process of the screen ; it is easier to capture/stop problems before they happen BIT 1,H JR NZ,offscreen ; ;(y+1) if Willy is on or about to up a ramp ; ;(y+2) if just walking or ; ;(y+3) if Willy is walking down a ramp CP (HL) ;beneath ;Is there a wall tile down there? RET Z ;return path is blocked offscreen: OR A ; SBC HL,DE ; move back to feet position ;if here then Willy has been allowed to move up or down a ramp- walked along or jumped into a new attribute square. ; so save all the new parameters ONLY_TWO OR A ld e,(ix+ramp_final_adjust) SBC HL,DE ; back to final head position (free to move here) LD (WILLY_ATT),HL ;L85D3;Save Willy's new attribute buffer coordinates LD A,(IX+ramp_animation_reset) ; the animation frame LD (WILLY_ANM),A ;L85D2 LD A,C ;Willy's new pixel y-coordinate LD (WILLY_Y),A ;L85CF RET ;----------------------------------------- jump_fix: ld a,(JUMP) ;L85d5 sub 12 ret c ld a,(AIRBORNE) dec a ret
  25. Nice piece of code. My only editing of the original code was to stop the type of guardian being changed whenever the original horizontal code was called. This was because my homing sprite called the horizontal movement whenever it wanted to move horizontally. The original code changed the guardian type. It is noted that the guardian type in your code is not modified. For clarity on your code it would benefit from a few additions regarding the usage of bit 7 (direction). This bit is being toggled in several places, with no mention as to why. e.g. XOR #80 ;restore direction (bit 7) which was inverted XOR #E0 ; invert direction (bit 7) and invert animation bits (6 and 5) and finally for clarity , an explanation of what the carry bit is being used for. ; the direction bit (bit 7 = #80) must be taken into account ;animation right adding #20 #80, #a0, #c0, #e0 carry clear with each addition but not #eo+#20 = #00 ; left adding #e0 #60, #40, #20, #00 carry set with each addition but not #00+#eo = #eo
×
×
  • Create New...

Important Information

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