IRF Posted November 12, 2017 Report Share Posted November 12, 2017 I have now tried out the alternative end to the 'Lose a life' routine, and removed the code in 'Room setup' which wipes the bottom screen-third. Another option I'm considering is, instead of just erasing the expired lives, print over them with a bespoke 16x16 graphic indicating their demise. The code which animates the remaining lives wouldn't touch such graphics, I believe. As per the above, instead of the expired lives being overwritten by a blank sprite (32 contiguous zeroes), I have printed a modified version of the Barrel sprite in their place. (With the three 'X's being replaced by the letters 'RIP'!) I have also tweaked the 'Draw the remaining lives' routine so that the consecutive lives appear in different animation-frames - like in Geoff Mode, but I have gone further than he did so that the adjacent lives are updated at different times as well. It all works fine. :) Spider 1 Quote Link to comment Share on other sites More sharing options...
jetsetdanny Posted November 14, 2017 Author Report Share Posted November 14, 2017 Well done! :) It's interesting to follow this discussion, even though I am only a passive observer. IRF 1 Quote Link to comment Share on other sites More sharing options...
IRF Posted November 17, 2017 Report Share Posted November 17, 2017 (edited) I have now tried out the alternative end to the 'Lose a life' routine, and removed the code in 'Room setup' which wipes the bottom screen-third. As per the above, instead of the expired lives being overwritten by a blank sprite (32 contiguous zeroes), I have printed a modified version of the Barrel sprite in their place. (With the three 'X's being replaced by the letters 'RIP'!) I have also tweaked the 'Draw the remaining lives' routine so that the consecutive lives appear in different animation-frames - like in Geoff Mode, but I have gone further than he did so that the adjacent lives are updated at different times as well. It all works fine. :) Further to the above, I've also noticed that if you apply the Infinite Lives POKE, the RIP sprite briefly appears when Willy is killed - overprinting the right-hand dancing Willy in the 'Remaining Lives' bar - but then the rightmost dancing Willy is restored (replacing the RIP sprite) when the game resumes! Edited November 17, 2017 by IRF Spider 1 Quote Link to comment Share on other sites More sharing options...
IRF Posted November 30, 2017 Report Share Posted November 30, 2017 (edited) If the following two commands (five bytes) are added at the start of the subroutine at #9584: LD HL, #85D2 SET 0, (HL) then the eleven bytes at #8A00-#8A0A can be removed from the Main Loop entirely. **** To achieve the above: - The four bytes at #9580-83 can be replaced by a relative jump to the code that is currently at #9596 (but that will need to be adjusted to take account of the next step); that saves two bytes; - The three-byte command at #959A is redundant, and can be removed (remember to adjust the length of the relative jump which takes you to that entry point, from #9539). Edited March 11, 2018 by IRF jetsetdanny and Spider 2 Quote Link to comment Share on other sites More sharing options...
IRF Posted December 7, 2017 Report Share Posted December 7, 2017 (edited) A few efficiencies can be found around the IN commands that take signals from the keyboard.Wherever there is a LD BC,#0000 followed by an IN A,(C) - this can be replaced with a LD A,#00 [the value that was previously being loaded up to B] followed by an IN A,(#FE).Also, in places where a routine responds to any keypress from one or more entire half-rows of keys*, you can replace this sequence:AND #1FCP #1Fwhich leaves the Zero flag reset if and only if one of the appropriate keys is pressed, with this:OR #E0CPL [Note that the CPL command leaves the Zero Flag unchanged, even if the Accumulator ends up with a value of #00.] INC A [This replaced the CPL command, which didn't work. INC A will set the Zero flag if and only if the previous value of A was #FF i.e. all bits set, because no keys in the relevant half-row are being pressed.] which has the same effect on the Zero flag, but requires one less byte.(*Such as pausing/unpausing the game, toggling the music on/off, or pressing a Jump key other than '0'. It wouldn't work when specific keys out of a half-row are being tested, such as Left-Right movement or the SHIFT+SPACE abandon-the-game key combo. Note that this won't work if the situation requires the precise value in A - as determined by the particular key in the half-row that was pressed - to be used for other purposes.) Edited January 10, 2019 by IRF Spider and jetsetdanny 2 Quote Link to comment Share on other sites More sharing options...
Norman Sword Posted December 8, 2017 Report Share Posted December 8, 2017 (edited) Space saving The code from $8aab to $8ac6 8AAB LD BC,$FEFE Read keys SHIFT-Z-X-C-V8AAE IN A,©8AB0 LD E,A Save the result in E8AB1 LD B,$7F Read keys B-N-M-SS-SPACE8AB3 IN A,©8AB5 OR E Combine the results8AB6 AND $01 Are SHIFT and SPACE being pressed?8AB8 JP Z,$87CA If so, quit the game 8ABB LD A,($85E0) Increment the inactivity timer at 85E08ABE INC A8ABF LD ($85E0),A8AC2 JR Z,$8AD1 Jump if the inactivity timer is now 0 (no keys have been pressed for a while)8AC4 LD B,$FD Read keys A-S-D-F-G The code from 8AAB to 8ac6 can be replaced by CALL $1F54 JP NC,$87CA LD HL,$85E0 INC (HL) JR Z,$8AD1; c has not been set up yet, so the next instruction sets c LD BC,$FDFE ; ; ;in all the versions of Manic miner or JSW I have posted, I tend to not use BC for the ports Tendency is ld a,port_? ;port_? is assigned to the row or even multiple row of keys that will be read in a,($fe) The code I actually use is defined in a MACRO, so I will type and see Read_Port port_a+port_k ; this sets up and scans both keyboard rows. e.g. row a-s-d-f-g and row h-j-k-l-enter The reason I do this is to ensure the port is fully assigned when addressed.It also frees the BC register pair Edited December 8, 2017 by Norman Sword jetsetdanny, Spider and IRF 3 Quote Link to comment Share on other sites More sharing options...
IRF Posted December 8, 2017 Report Share Posted December 8, 2017 Thanks Norman. I suppose there might be other functions where Matthew's code replicates something that is already available in the ROM? Quote Link to comment Share on other sites More sharing options...
IRF Posted December 12, 2017 Report Share Posted December 12, 2017 JG Harston provides a patch to check for wall tiles at head-height in both directions: http://mdfs.net/Software/JSW/JGH/Docs/Patch.htm#wall The patch is made to fit into the available space by using some code efficiencies: Original code: Changed to: 9035 22 D3 85 LD (POSITION),HL 9035 3A B2 80 LD A,(WALL) 9038 78 LD A,B 9038 BE CP (HL) 9039 32 CF 85 LD (YPOSN),A 9039 C8 RET Z 903C 3E 03 LD A,&03 903A 22 D3 85 LD (POSITION),HL 903E 32 D2 85 LD (FRAME),A 903D 3E 03 LD A,&03 9041 C9 RET 903F C3 AE 90 JP &90AE This approach (of using common code at the end of the parts of the 'Move Willy (3)' routine which deal with Willy moving left and moving right) can be taken further, to save a few more bytes: Original code: Changed to: 9035 22 D3 85 LD (POSITION),HL 9035 3A B2 80 LD A,(WALL) 9038 78 LD A,B 9038 BE CP (HL) 9039 32 CF 85 LD (YPOSN),A 9039 C8 RET Z 903C 3E 03 LD A,&03 903A 3E 03 LD A,&03 903E 32 D2 85 LD (FRAME),A 903C C3 AB 90 JP &90AB 9041 C9 RET 903F 00 00 00 Three spare bytes 90AA 22 D3 85 LD (POSITION),HL 90AA AF XOR A 90AD AF XOR A 90AB 22 D3 85 LD (POSITION),HL jetsetdanny 1 Quote Link to comment Share on other sites More sharing options...
Norman Sword Posted December 12, 2017 Report Share Posted December 12, 2017 (edited) I decided to ditch the whole of Matthews code for dealing with ramps. That is the code from $8fbc to $90b5 =$105= 259decimal In essence the code repeats for left and right. I wanted it to be exactly symmetrical, with no deviation in how it handles left or right. So the code I use handles both directions by having one routine, which has variables passed to it. The testing is the same in both directions and it is around 187 bytes in length or around 72 bytes shorter than Matthews version. The code in the post below has been edited to move the subroutine to inline code. This has reduced its size by 7 bytes. So length is now around 180 bytes or around 79 bytes shorter than Mattthews version. Edited December 13, 2017 by Norman Sword jetsetdanny and IRF 2 Quote Link to comment Share on other sites More sharing options...
Norman Sword Posted December 13, 2017 Report Share Posted December 13, 2017 (edited) slight edit to change a comment, which was from code that no longer exists. The comment confused what was happening when testing for extremes of movement left and right. This code has been edited repeatedly to arrive at what is seen Comments are sometimes the remains of multiple copies, and pastes If I am aware of a misplaced comment, I will delete it or edit it. ;set variables for these offsetsramp_frame equ 0ramp_animation equ 1*2ramp_where_1 equ 2*2ramp_where_2 equ 3*2ramp_condition equ 4*2ramp_adjust equ 5*2ramp_exit_screen equ 6*2ramp_final_adjust equ 7*2ramp_animation_reset equ 8*2 ;left data followed by right dataleft_data db 0, 3 ;0 VALUE TO JUMP FRAME - limit of animation movement at same position DB -1, 1 ;1 STEP TO NEXT animation FRAME - replaces inc or dec DB $1f, $22 ;2 POSITION OF RAMP 1 - ramp walk up DB $41, $40 ;3 POSITION OF RAMP 2 - ramp walk down DB 0, 1 ;4 CONDITION FOR RAMP DIRECTION - decision to check for up or down DB -1, 2 ;5 DIRECTION TO ADJUST HL - where to check vertically DB 31, 0 ;6 CONDITION TO TEST FOR NEW ROOM (limit of travel) DB 0, -1 ;7 STEP BACK - adjust of hl after vert check DB 3, 0 ;8 ANIMATION RESET for next frame;----------------------------------- .L8FBC: LD A,(ROPE_STATUS) ;L85D6 DEC A BIT 7,A RET Z LD A,(L85D0) BIT 1,A RET Z ; Willy now needs to move left or right; this movement needs to handle the stairs and check for their presence; decide if moving left or right ld ix,left_data AND $01 JR nz,skippp inc ix ;switch to right dataskippp:; Willy is moving LD HL,(WILLY_ATT) ;L85D3 LD DE,WILLY_ANM ;L85D2 LD A,(DE) cp (ix+ramp_frame) JR Z,RAMP_CHK add a,(ix+ramp_animation) LD (de),a ;L85D2 RET RAMP_CHK:; all de increments are positive so preload D ld d,0 LD A,(AIRBORNE) ;L85D1 OR A JR NZ,as_is ; three outcomes going up bc=-32; going down bc=+32; no ramp bc=0 ld bc,-32 ld e,(ix+ramp_where_1) ld a,(RAMP_DIR) ;either 0 or 1 and 1 ;get rid of other bits cp (ix+ramp_condition) ; the sign test; this condition swaps on left and right jr z,down_ ld bc,+32 ld e,(ix+ramp_where_2)down_: add hl,de ; add offset to find ramp/stair square ld a,(RAMP) sub (HL) jr z,found_ ;if ramp is here keep bc=shift;ramp not found so no offset neededas_is: ld b,d ld c,d ;bc=0 no ramp so no offset/shift found_: ld hl,(WILLY_ATT) ; this test is for extremes of position when moving left or right LD A,L ;left edge =0 right edge=30 ADD A,(IX+ramp_adjust) ;move in the direction left or right LD L,A ;left edge =-1 right edge=32 AND 31 ;left edge=31 right edge=0 ; if value is zero then move right ld de,GO_ROOM_LEFT jr nz,exit_other_way ld de,GO_ROOM_RIGHTexit_other_way: CP (IX+ramp_exit_screen) ; have we moved to the extremes? JR NZ,same_room;we have moved far enough to enter a new room ex de,hl jp (hl) ;now check a vertical line for walls blocking pathsame_room: ; just move vertically and check the squares; this code only checks for WALL's nothing else; after the initial add hl,bc this checks downwards in a line ; the initial adjust is for ramps. e.g. up/down or level ADD HL,BC ;Point HL at the cell at; ;(y-1) Willy is on or about to go up a ramp; ;(y+0) just walking; ;(y+1) Willy is walking down a ramp ld a,(WALL);in theory this position could be off the top of the screen bit 1,h jr nz,ignore_head_check cp (hl) ;head ret z ;return if path is blockedignore_head_check:; now check vertically down LD DE,$0020 ADD HL,DE ;point hil at the cell one lower; ;(y+0) Willy is on or about to go up a ramp; ;(y+1) just walking; ;(y+2) if Willy is walking down a ramp CP (HL) ;foot RET Z LD B,A LD A,(WILLY_Y) ;L85CF SRA C ADD A,C LD C,A AND $0F ;jumping JR Z,ONLY_TWO LD A,b ADD HL,DE ; check- maybe needlessly- but check anyway. BIT 1,H JR NZ,OFFSCREEN; ;(y+1) Willy is on or about to go up a ramp; ;(y+2) just walking; ;(y+3) Willy is walking down a ramp CP (HL) ;beneath? RET ZOFFSCREEN: OR A SBC HL,DE ; move back to feet; final adjust back to HL=head positionONLY_TWO: OR A SBC HL,DE ; back to head position (free to move here) ;Adjust HL back LD A,L ADD A,(IX+ramp_final_adjust) LD L,A LD A,(IX+ramp_animation_reset) ; the animation frame :save state: LD (WILLY_ANM),A ;L85D2 LD (WILLY_ATT),HL ;L85D3 LD A,C LD (WILLY_Y),A ;L85CF RET Edited December 14, 2017 by Norman Sword IRF and jetsetdanny 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.