← B9D2 Process every active on-screen object Map BA8B → Blit an object's sprite shifted N pixels, over three columns
B9FC: Draw one object's sprite into the back buffer
Draws one object's 16×16 sprite into the back buffer with an OR-blit. It then stamps the dirty counter of every cell it covered.
Input
IX the object's sprite record
draw_object B9FC CALL object_backbuf_addr Turn the object's position into a screen address.
B9FF OR A object_backbuf_addr left the sprite's sub-cell horizontal pixel offset in A. Non-zero means the sprite is not byte-aligned – take the shifted-blit path; zero falls through to the byte-aligned blit.
BA00 JP NZ,draw_object_shifted
BA03 PUSH BC
BA04 LD (draw_sp_save),SP Save SP, then point it at the sprite data so each POP reads a 16-pixel row.
BA08 LD H,(IX+$07)
BA0B LD L,(IX+$06)
BA0E LD SP,HL
BA0F LD A,$10 Sixteen rows to draw
draw_object_row BA11 EX AF,AF' Park the row counter in the alternate accumulator – the blit below needs A itself.
BA12 POP HL Read the next two sprite bytes (one row).
BA13 LD A,(BC) OR-blit the row's two halves into the back buffer – sprites overlay.
BA14 OR H
BA15 LD (BC),A
BA16 INC C
BA17 LD A,(BC)
BA18 OR L
BA19 LD (BC),A
BA1A DEC C
BA1B INC B Step down one pixel row, and carry across the character and third boundaries.
BA1C LD A,B
BA1D AND $07
BA1F JR NZ,draw_object_next_row
BA21 LD A,C
BA22 AND $E0
BA24 CP $E0
BA26 JR Z,draw_object_third_cross
BA28 LD A,B
BA29 SUB $08
BA2B LD B,A
BA2C LD A,C
BA2D ADD A,$20
BA2F LD C,A
BA30 JP draw_object_next_row
draw_object_third_cross BA33 LD A,C The row crossed a screen third: wrap the low byte and step into the next third.
BA34 SUB $E0
BA36 LD C,A
draw_object_next_row BA37 EX AF,AF' Loop until all 16 rows are drawn.
BA38 DEC A
BA39 JR NZ,draw_object_row
BA3B LD SP,(draw_sp_save) Restore SP, then stamp the covered cells' dirty counters. A cell-aligned sprite covers two columns on each of two rows.
BA3F POP HL
BA40 LD C,H
BA41 LD A,H
BA42 AND $18
BA44 RRCA
BA45 RRCA
BA46 RRCA
BA47 ADD A,WORKBUF_FB/$100
BA49 LD H,A
BA4A LD A,C
BA4B AND $07
BA4D JP NZ,draw_object_stamp_lower
BA50 LD (HL),$02
BA52 INC L
BA53 LD (HL),$02
BA55 CALL advance_buffer_row
BA58 LD (HL),$02
BA5A DEC L
BA5B LD (HL),$02
BA5D RET
draw_object_stamp_lower BA5E LD (HL),$02 A sprite that straddles a row boundary also stamps the dirty counter of the lower row of cells.
BA60 INC L
BA61 LD (HL),$02
BA63 CALL advance_buffer_row
BA66 LD (HL),$02
BA68 DEC L
BA69 LD (HL),$02
BA6B CALL advance_buffer_row
BA6E LD (HL),$02
BA70 INC L
BA71 LD (HL),$02
draw_object_aligned_done BA73 RET
draw_object_shifted BA74 ADD A,A A sprite whose X is not cell-aligned takes the shifted path. Twice the pixel shift becomes the offset byte of the jump that enters the shift staircase.
BA75 LD (draw_shifted_dispatch+$0001),A
BA78 PUSH BC
BA79 LD (draw_sp_save),SP
BA7D LD H,(IX+$07)
BA80 LD L,(IX+$06)
BA83 LD SP,HL
BA84 LD A,$10
draw_shifted_row BA86 EX AF,AF' Top of the shifted path's per-row loop, re-entered from the row-loop test for every row after the first. Park the row counter and take the row's two sprite bytes; the staircase needs A clear.
BA87 POP HL
BA88 XOR A
draw_shifted_dispatch BA89 JR draw_shifted_dispatch
← B9D2 Process every active on-screen object Map BA8B → Blit an object's sprite shifted N pixels, over three columns
Fork me on GitHub