![]() |
Routines |
| Prev: B73B | Up: Map | Next: BC0E |
|
Used by the routine at Run_Game_Frame.
Draws all active sprites (Percy, hazards, etc.) to the screen buffer and then merges the collision map with the background scenery. First draws up to 08 three-column-wide sprites (e.g. Percy, large hazards), then up to 08 two-column-wide sprites (e.g. smaller objects). After drawing, the sprite positions are backed up and the collision map is scanned to composite sprite pixels onto the background.
|
||||||||
|
Check if lives backup is non-zero; if so, clear the sprite overlay buffer and return early (used during life-lost sequence).
|
||||||||
| Draw_Sprites | BB1C | LD IX,$DAC0 | Point IX at Percy_X_Position. | |||||
| BB20 | LD A,($5FBE) | Jump to Draw_3Wide_Sprites if *Lives_Backup is zero. | ||||||
| BB23 | OR A | |||||||
| BB24 | JR Z,Draw_3Wide_Sprites | |||||||
| BB26 | LD HL,$F800 | Clear 02BF bytes of the sprite overlay buffer from OverlayBuffer onwards. | ||||||
| BB29 | LD DE,$F801 | |||||||
| BB2C | LD (HL),L | |||||||
| BB2D | LD BC,$02BF | |||||||
| BB30 | LDIR | |||||||
| BB32 | RET | Return. | ||||||
|
Main sprite drawing loop: draw up to 08 three-column-wide sprites.
|
||||||||
| Draw_3Wide_Sprites | BB33 | LD IX,$DAC0 | Point IX at Percy_X_Position. | |||||
| BB37 | LD A,$FF | Write a terminator byte (FF) to *OverlayBuffer_End. | ||||||
| BB39 | LD ($FAC0),A | |||||||
| BB3C | LD B,$08 | Set the sprite counter to 08 in B. | ||||||
| Draw_3Wide_Loop | BB3E | PUSH BC | Stash the sprite counter on the stack. | |||||
| BB3F | LD A,(IX+$01) | Clamp the Y position: if *IX+01 is not less than A1 write A0 to *IX+01. | ||||||
| BB42 | CP $A1 | |||||||
| BB44 | JR C,Draw_3Wide_TestActive | |||||||
| BB46 | LD (IX+$01),$A0 | |||||||
| Draw_3Wide_TestActive | BB4A | LD A,(IX+$03) | Jump to Sprite_Inactive_Delay if the sprite is inactive (*IX+03 which is frame ID is zero). | |||||
| BB4D | OR A | |||||||
| BB4E | JP Z,Sprite_Inactive_Delay | |||||||
| BB51 | CALL CalculateScreenBufferAddress | Call CalculateScreenBufferAddress. | ||||||
| BB54 | PUSH HL | Stash the screen buffer address on the stack. | ||||||
| BB55 | CALL Draw_3Wide_Sprite_Column | Call Draw_3Wide_Sprite_Column. | ||||||
| BB58 | POP HL | Restore the screen buffer address from the stack. | ||||||
| BB59 | CALL ApplySpriteAttributes3Wide | Call ApplySpriteAttributes3Wide. | ||||||
|
This entry point is used by the routine at Sprite_Inactive_Delay.
|
||||||||
| Advance_To_Next_Sprite | BB5C | INC IX | Advance IX to the next sprite entry (each entry is 04 bytes). | |||||
| BB5E | INC IX | |||||||
| BB60 | INC IX | |||||||
| BB62 | INC IX | |||||||
| BB64 | POP BC | Restore the sprite counter from the stack. | ||||||
| BB65 | DJNZ Draw_3Wide_Loop | Decrease the sprite counter and loop back to Draw_3Wide_Loop until all 08 three-wide sprites are processed. | ||||||
|
Draw up to 08 two-column-wide sprites.
|
||||||||
| Draw_2Wide_Sprites | BB67 | LD B,$08 | Set the sprite counter to 08 in B. | |||||
| Draw_2Wide_Loop | BB69 | PUSH BC | Stash the sprite counter on the stack. | |||||
| BB6A | LD A,(IX+$01) | Clamp the Y position: if *IX+01 is not less than A9 write A8 to *IX+01. | ||||||
| BB6D | CP $A9 | |||||||
| BB6F | JR C,Draw_Sprites_0 | |||||||
| BB71 | LD (IX+$01),$A8 | |||||||
| Draw_Sprites_0 | BB75 | LD A,(IX+$03) | Jump to Advance_To_Next_2Wide if the sprite is inactive (*IX+03 is zero). | |||||
| BB78 | OR A | |||||||
| BB79 | JR Z,Advance_To_Next_2Wide | |||||||
| BB7B | CALL CalculateScreenBufferAddress | Call CalculateScreenBufferAddress. | ||||||
| BB7E | PUSH HL | Stash the screen buffer address on the stack. | ||||||
| BB7F | CALL Draw_2Wide_Sprite_Column | Call Draw_2Wide_Sprite_Column. | ||||||
| BB82 | POP HL | Restore the screen buffer address from the stack. | ||||||
| BB83 | CALL ApplySpriteAttributes2Wide | Call ApplySpriteAttributes2Wide. | ||||||
| Advance_To_Next_2Wide | BB86 | INC IX | Advance IX to the next sprite entry (each entry is 04 bytes). | |||||
| BB88 | INC IX | |||||||
| BB8A | INC IX | |||||||
| BB8C | INC IX | |||||||
| BB8E | POP BC | Restore the sprite counter from the stack. | ||||||
| BB8F | DJNZ Draw_2Wide_Loop | Decrease the sprite counter and loop back to Draw_2Wide_Loop until all 08 two-wide sprites are processed. | ||||||
|
Back up current sprite positions for the next frame's erase pass.
|
||||||||
| BB91 | LD HL,$DAC0 | Copy 40 bytes from Percy_X_Position to Backup_Percy. | ||||||
| BB94 | LD DE,$DB00 | |||||||
| BB97 | LD BC,$0040 | |||||||
| BB9A | LDIR | |||||||
|
Scan the collision overlay buffer and merge sprite pixels onto the background. Each non-zero, non-FF byte in the buffer is a countdown; when it reaches zero the sprite pixel data is composited with the scenery.
|
||||||||
| BB9C | LD HL,$F7FF | Set HL to F7FF (one byte before the overlay buffer). | ||||||
| BB9F | XOR A | Set A to 00. | ||||||
| Collision_Scan_Loop | BBA0 | INC HL | Increment HL and jump back to Collision_Scan_Loop if *HL is zero (skip empty cells). | |||||
| BBA1 | OR (HL) | |||||||
| BBA2 | JP Z,Collision_Scan_Loop | |||||||
| BBA5 | CP $FF | Return if the terminator (FF) is found indicating the end of the buffer. | ||||||
| BBA7 | RET Z | |||||||
| BBA8 | DEC (HL) | Decrease the countdown at *HL. | ||||||
| BBA9 | CP $02 | Jump to Merge_Sprite_Column if the value was 02 (skip background restore). | ||||||
| BBAB | JP Z,Merge_Sprite_Column | |||||||
|
Restore the background pixel at this position from the scenery buffer.
|
||||||||
| BBAE | PUSH HL | Stash the overlay buffer pointer on the stack. | ||||||
| BBAF | LD A,H | Calculate the scenery source address in DE by subtracting 20 from the high byte of HL. | ||||||
| BBB0 | SUB $20 | |||||||
| BBB2 | LD D,A | |||||||
| BBB3 | LD E,L | Copy the low byte across. | ||||||
| BBB4 | LD A,H | Calculate the screen destination address in HL by subtracting A0 from the high byte. | ||||||
| BBB5 | SUB $A0 | |||||||
| BBB7 | LD H,A | |||||||
| BBB8 | LD A,(DE) | Copy the scenery byte from *DE to the screen buffer at *HL. | ||||||
| BBB9 | LD (HL),A | |||||||
| BBBA | POP HL | Restore the overlay buffer pointer from the stack. | ||||||
|
Merge the sprite column pixels with the background. Derives the sprite buffer, background and screen buffer addresses from the overlay buffer pointer, then ORs sprite data onto the background for 08 pixel rows.
|
||||||||
| Merge_Sprite_Column | BBBB | PUSH HL | Stash the overlay buffer pointer on the stack. | |||||
| BBBC | LD A,H | Derive the attribute row from the overlay buffer address: mask the low two bits of the high byte, rotate left three times and set bits 6-7 to form the base screen buffer address high byte. | ||||||
| BBBD | AND %00000011 | |||||||
| BBBF | RLCA | |||||||
| BBC0 | RLCA | |||||||
| BBC1 | RLCA | |||||||
| BBC2 | OR %11000000 | Set bits 6-7. | ||||||
| BBC4 | LD H,A | Set H, B (sprite source) and D (screen destination) to this base. Set bit 5 of B for the sprite buffer and reset bit 7 of D for the screen buffer. | ||||||
| BBC5 | LD B,H | |||||||
| BBC6 | LD D,H | |||||||
| BBC7 | SET 5,B | |||||||
| BBC9 | RES 7,D | |||||||
| BBCB | LD C,L | Copy the low byte to C and E. | ||||||
| BBCC | LD E,L | |||||||
|
Merge eight pixel rows: OR the sprite data from *BC onto the background at *HL, write the result to the screen buffer at *DE, then clear the sprite source byte.
|
||||||||
| BBCD | LD A,(BC) | Row 1: merge sprite with background, write to screen, clear sprite. | ||||||
| BBCE | OR (HL) | |||||||
| BBCF | LD (DE),A | |||||||
| BBD0 | XOR A | |||||||
| BBD1 | LD (BC),A | |||||||
| BBD2 | INC B | Row 2: advance all row pointers and merge. | ||||||
| BBD3 | INC D | |||||||
| BBD4 | INC H | |||||||
| BBD5 | LD A,(BC) | |||||||
| BBD6 | OR (HL) | |||||||
| BBD7 | LD (DE),A | |||||||
| BBD8 | XOR A | |||||||
| BBD9 | LD (BC),A | |||||||
| BBDA | INC B | Row 3: advance all row pointers and merge. | ||||||
| BBDB | INC D | |||||||
| BBDC | INC H | |||||||
| BBDD | LD A,(BC) | |||||||
| BBDE | OR (HL) | |||||||
| BBDF | LD (DE),A | |||||||
| BBE0 | XOR A | |||||||
| BBE1 | LD (BC),A | |||||||
| BBE2 | INC B | Row 4: advance all row pointers and merge. | ||||||
| BBE3 | INC D | |||||||
| BBE4 | INC H | |||||||
| BBE5 | LD A,(BC) | |||||||
| BBE6 | OR (HL) | |||||||
| BBE7 | LD (DE),A | |||||||
| BBE8 | XOR A | |||||||
| BBE9 | LD (BC),A | |||||||
| BBEA | INC B | Row 5: advance all row pointers and merge. | ||||||
| BBEB | INC D | |||||||
| BBEC | INC H | |||||||
| BBED | LD A,(BC) | |||||||
| BBEE | OR (HL) | |||||||
| BBEF | LD (DE),A | |||||||
| BBF0 | XOR A | |||||||
| BBF1 | LD (BC),A | |||||||
| BBF2 | INC B | Row 6: advance all row pointers and merge. | ||||||
| BBF3 | INC D | |||||||
| BBF4 | INC H | |||||||
| BBF5 | LD A,(BC) | |||||||
| BBF6 | OR (HL) | |||||||
| BBF7 | LD (DE),A | |||||||
| BBF8 | XOR A | |||||||
| BBF9 | LD (BC),A | |||||||
| BBFA | INC D | |||||||
| BBFB | INC H | Row 7: advance all row pointers and merge. | ||||||
| BBFC | INC B | |||||||
| BBFD | LD A,(BC) | |||||||
| BBFE | OR (HL) | |||||||
| BBFF | LD (DE),A | |||||||
| BC00 | XOR A | |||||||
| BC01 | LD (BC),A | Row 8: advance all row pointers, merge and clear sprite. | ||||||
| BC02 | INC B | |||||||
| BC03 | INC H | |||||||
| BC04 | INC D | |||||||
| BC05 | LD A,(BC) | |||||||
| BC06 | OR (HL) | |||||||
| BC07 | LD (DE),A | |||||||
| BC08 | XOR A | |||||||
| BC09 | LD (BC),A | |||||||
| BC0A | POP HL | Restore the overlay buffer pointer from the stack. | ||||||
| BC0B | JP Collision_Scan_Loop | Jump back to Collision_Scan_Loop to continue scanning. | ||||||
| Prev: B73B | Up: Map | Next: BC0E |