Prev: B2C5 Up: Map Next: B37F
B2EE: Find an object's sprite, and turn it the way the object faces
Used by the routines at DRAW_OBJECT and CALC_2D_INFO.
The graphic (+0) indexes GRAPHICS for the sprite. A sprite whose first byte is 0 draws nothing: the routine then drops its own return address, so its RET leaves its caller too.
Sprites are turned in place, and the width byte remembers which way round the data now is: bit 7 set while it is stored upside down, bit 6 while mirrored. Bits 7 and 6 of the object's flags (+7) say how it wants to be drawn. Where they disagree the data is turned and the sprite's bit toggled, so an object that keeps facing one way costs nothing after the first time, while two objects sharing a sprite and facing opposite ways turn it back and forth every time each is drawn.
Upside down is done by swapping whole rows end for end; mirroring by reversing the order of each row's cells and the bits of every byte, through REVERSED. Knight Lore does the same in three routines; here they are one.
Input
IX the object
Output
DE the sprite
FIND_SPRITE B2EE LD L,(IX+$00) DE = the sprite, from the graphic table
B2F1 LD H,$00
B2F3 ADD HL,HL
B2F4 LD BC,GRAPHICS
B2F7 ADD HL,BC
B2F8 LD E,(HL)
B2F9 INC HL
B2FA LD D,(HL)
B2FB LD A,(DE) A real sprite
B2FC AND A
B2FD JR NZ,FIND_SPRITE_0
B2FF INC SP None: return from the caller as well
B300 INC SP
B301 RET
FIND_SPRITE_0 B302 PUSH DE Kept
B303 LD A,(DE) The sprite's bit 7 against the object's: the same means no turning over
B304 XOR (IX+$07)
B307 AND $80
B309 JR Z,FIND_SPRITE_4
B30B LD A,(DE) Toggle the sprite's bit
B30C XOR $80
B30E LD (DE),A
B30F RLCA B = bytes a row: the width in bits 0 to 3, times two for the mask and image bytes
B310 AND $1E
B312 LD B,A
B313 INC DE C = the height in rows; DE on the data
B314 LD A,(DE)
B315 LD C,A
B316 INC DE
B317 PUSH BC HL = B * C, the data's length, plus the start: one past the end
B318 PUSH DE
B319 LD E,C
B31A LD D,$00
B31C LD H,D
B31D LD L,D
FIND_SPRITE_1 B31E ADD HL,DE
B31F DJNZ FIND_SPRITE_1
B321 POP DE
B322 POP BC
B323 ADD HL,DE
B324 EX DE,HL DE one past the end; HL one past the first row
B325 LD A,B
B326 CALL ADD_HL_A
B329 DEC DE DE on the last byte of the last row, HL on the last byte of the first
B32A DEC HL
B32B SRL C Swap rows in pairs: half the height
FIND_SPRITE_2 B32D PUSH BC Swap the two rows byte by byte, working backwards
FIND_SPRITE_3 B32E LD A,(DE)
B32F LD C,(HL)
B330 LD (HL),A
B331 LD A,C
B332 LD (DE),A
B333 DEC HL
B334 DEC DE
B335 DJNZ FIND_SPRITE_3
B337 POP BC HL on to the end of the next row down; DE is already at the end of the row before its last
B338 LD A,B
B339 CALL ADD_HL_A
B33C LD A,B
B33D CALL ADD_HL_A
B340 DEC C The next pair
B341 JR NZ,FIND_SPRITE_2
FIND_SPRITE_4 B343 POP DE The sprite's bit 6 against the object's
B344 PUSH DE
B345 LD A,(DE)
B346 XOR (IX+$07)
B349 AND $40
B34B JR Z,FIND_SPRITE_7
B34D LD A,(DE) Toggle the sprite's bit; B and C = the width in cells
B34E XOR $40
B350 LD (DE),A
B351 AND $0F
B353 LD B,A
B354 LD C,A
B355 INC DE The height into A'
B356 LD A,(DE)
B357 EX AF,AF'
B358 INC DE HL' reads and HL writes, both from the first row; B' = the page of the bit reversal table
B359 EX DE,HL
B35A PUSH HL
B35B EXX
B35C POP HL
B35D LD B,$F1
B35F EXX
FIND_SPRITE_5 B360 EXX Push a row's pairs, each byte reversed: E' the mask, D' the image
B361 LD C,(HL)
B362 LD A,(BC)
B363 LD E,A
B364 INC HL
B365 LD C,(HL)
B366 LD A,(BC)
B367 LD D,A
B368 INC HL
B369 PUSH DE
B36A EXX
B36B DJNZ FIND_SPRITE_5
B36D LD B,C Pop them back over the row: last first, so the cells come back in the reverse order
FIND_SPRITE_6 B36E POP DE
B36F LD (HL),E
B370 INC HL
B371 LD (HL),D
B372 INC HL
B373 DJNZ FIND_SPRITE_6
B375 EX AF,AF' The next row, until the height runs out
B376 DEC A
B377 JR Z,FIND_SPRITE_7
B379 EX AF,AF'
B37A LD B,C
B37B JR FIND_SPRITE_5
FIND_SPRITE_7 B37D POP DE DE = the sprite
B37E RET
Prev: B2C5 Up: Map Next: B37F