Prev: B73B Up: Map Next: BC0E
BB1C: Draw Sprites and Merge Collision Map
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.
Input
IX Percy sprite data pointer
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