Prev: 46907 Up: Map Next: 48142
47900: 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 8 three-column-wide sprites (e.g. Percy, large hazards), then up to 8 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 47900 LD IX,56000 Point IX at Percy_X_Position.
47904 LD A,(24510) Jump to Draw_3Wide_Sprites if *Lives_Backup is zero.
47907 OR A
47908 JR Z,Draw_3Wide_Sprites
47910 LD HL,63488 Clear 703 bytes of the sprite overlay buffer from OverlayBuffer onwards.
47913 LD DE,63489
47916 LD (HL),L
47917 LD BC,703
47920 LDIR
47922 RET Return.
Main sprite drawing loop: draw up to 8 three-column-wide sprites.
Draw_3Wide_Sprites 47923 LD IX,56000 Point IX at Percy_X_Position.
47927 LD A,255 Write a terminator byte (255) to *OverlayBuffer_End.
47929 LD (64192),A
47932 LD B,8 Set the sprite counter to 8 in B.
Draw_3Wide_Loop 47934 PUSH BC Stash the sprite counter on the stack.
47935 LD A,(IX+1) Clamp the Y position: if *IX+1 is not less than 161 write 160 to *IX+1.
47938 CP 161
47940 JR C,Draw_3Wide_TestActive
47942 LD (IX+1),160
Draw_3Wide_TestActive 47946 LD A,(IX+3) Jump to Sprite_Inactive_Delay if the sprite is inactive (*IX+3 which is frame ID is zero).
47949 OR A
47950 JP Z,Sprite_Inactive_Delay
47953 CALL CalculateScreenBufferAddress Call CalculateScreenBufferAddress.
47956 PUSH HL Stash the screen buffer address on the stack.
47957 CALL Draw_3Wide_Sprite_Column Call Draw_3Wide_Sprite_Column.
47960 POP HL Restore the screen buffer address from the stack.
47961 CALL ApplySpriteAttributes3Wide Call ApplySpriteAttributes3Wide.
This entry point is used by the routine at Sprite_Inactive_Delay.
Advance_To_Next_Sprite 47964 INC IX Advance IX to the next sprite entry (each entry is 4 bytes).
47966 INC IX
47968 INC IX
47970 INC IX
47972 POP BC Restore the sprite counter from the stack.
47973 DJNZ Draw_3Wide_Loop Decrease the sprite counter and loop back to Draw_3Wide_Loop until all 8 three-wide sprites are processed.
Draw up to 8 two-column-wide sprites.
Draw_2Wide_Sprites 47975 LD B,8 Set the sprite counter to 8 in B.
Draw_2Wide_Loop 47977 PUSH BC Stash the sprite counter on the stack.
47978 LD A,(IX+1) Clamp the Y position: if *IX+1 is not less than 169 write 168 to *IX+1.
47981 CP 169
47983 JR C,Draw_Sprites_0
47985 LD (IX+1),168
Draw_Sprites_0 47989 LD A,(IX+3) Jump to Advance_To_Next_2Wide if the sprite is inactive (*IX+3 is zero).
47992 OR A
47993 JR Z,Advance_To_Next_2Wide
47995 CALL CalculateScreenBufferAddress Call CalculateScreenBufferAddress.
47998 PUSH HL Stash the screen buffer address on the stack.
47999 CALL Draw_2Wide_Sprite_Column Call Draw_2Wide_Sprite_Column.
48002 POP HL Restore the screen buffer address from the stack.
48003 CALL ApplySpriteAttributes2Wide Call ApplySpriteAttributes2Wide.
Advance_To_Next_2Wide 48006 INC IX Advance IX to the next sprite entry (each entry is 4 bytes).
48008 INC IX
48010 INC IX
48012 INC IX
48014 POP BC Restore the sprite counter from the stack.
48015 DJNZ Draw_2Wide_Loop Decrease the sprite counter and loop back to Draw_2Wide_Loop until all 8 two-wide sprites are processed.
Back up current sprite positions for the next frame's erase pass.
48017 LD HL,56000 Copy 64 bytes from Percy_X_Position to Backup_Percy.
48020 LD DE,56064
48023 LD BC,64
48026 LDIR
Scan the collision overlay buffer and merge sprite pixels onto the background. Each non-zero, non-255 byte in the buffer is a countdown; when it reaches zero the sprite pixel data is composited with the scenery.
48028 LD HL,63487 Set HL to 63487 (one byte before the overlay buffer).
48031 XOR A Set A to 0.
Collision_Scan_Loop 48032 INC HL Increment HL and jump back to Collision_Scan_Loop if *HL is zero (skip empty cells).
48033 OR (HL)
48034 JP Z,Collision_Scan_Loop
48037 CP 255 Return if the terminator (255) is found indicating the end of the buffer.
48039 RET Z
48040 DEC (HL) Decrease the countdown at *HL.
48041 CP 2 Jump to Merge_Sprite_Column if the value was 2 (skip background restore).
48043 JP Z,Merge_Sprite_Column
Restore the background pixel at this position from the scenery buffer.
48046 PUSH HL Stash the overlay buffer pointer on the stack.
48047 LD A,H Calculate the scenery source address in DE by subtracting 32 from the high byte of HL.
48048 SUB 32
48050 LD D,A
48051 LD E,L Copy the low byte across.
48052 LD A,H Calculate the screen destination address in HL by subtracting 160 from the high byte.
48053 SUB 160
48055 LD H,A
48056 LD A,(DE) Copy the scenery byte from *DE to the screen buffer at *HL.
48057 LD (HL),A
48058 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 8 pixel rows.
Merge_Sprite_Column 48059 PUSH HL Stash the overlay buffer pointer on the stack.
48060 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.
48061 AND %00000011
48063 RLCA
48064 RLCA
48065 RLCA
48066 OR %11000000 Set bits 6-7.
48068 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.
48069 LD B,H
48070 LD D,H
48071 SET 5,B
48073 RES 7,D
48075 LD C,L Copy the low byte to C and E.
48076 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.
48077 LD A,(BC) Row 1: merge sprite with background, write to screen, clear sprite.
48078 OR (HL)
48079 LD (DE),A
48080 XOR A
48081 LD (BC),A
48082 INC B Row 2: advance all row pointers and merge.
48083 INC D
48084 INC H
48085 LD A,(BC)
48086 OR (HL)
48087 LD (DE),A
48088 XOR A
48089 LD (BC),A
48090 INC B Row 3: advance all row pointers and merge.
48091 INC D
48092 INC H
48093 LD A,(BC)
48094 OR (HL)
48095 LD (DE),A
48096 XOR A
48097 LD (BC),A
48098 INC B Row 4: advance all row pointers and merge.
48099 INC D
48100 INC H
48101 LD A,(BC)
48102 OR (HL)
48103 LD (DE),A
48104 XOR A
48105 LD (BC),A
48106 INC B Row 5: advance all row pointers and merge.
48107 INC D
48108 INC H
48109 LD A,(BC)
48110 OR (HL)
48111 LD (DE),A
48112 XOR A
48113 LD (BC),A
48114 INC B Row 6: advance all row pointers and merge.
48115 INC D
48116 INC H
48117 LD A,(BC)
48118 OR (HL)
48119 LD (DE),A
48120 XOR A
48121 LD (BC),A
48122 INC D
48123 INC H Row 7: advance all row pointers and merge.
48124 INC B
48125 LD A,(BC)
48126 OR (HL)
48127 LD (DE),A
48128 XOR A
48129 LD (BC),A Row 8: advance all row pointers, merge and clear sprite.
48130 INC B
48131 INC H
48132 INC D
48133 LD A,(BC)
48134 OR (HL)
48135 LD (DE),A
48136 XOR A
48137 LD (BC),A
48138 POP HL Restore the overlay buffer pointer from the stack.
48139 JP Collision_Scan_Loop Jump back to Collision_Scan_Loop to continue scanning.
Prev: 46907 Up: Map Next: 48142