Prev: D157 Up: Map Next: D1EB
D174: Turn a sprite's stored data the way its object faces
Used by the routine at FLIP_SPRITE.
Reached by a jump from FLIP_SPRITE, so its RET goes back to FLIP_SPRITE's caller. 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 (HFLIP_SPRITE_DATA) by reversing the order of each row's cells and the bits of every byte, through MIRROR_TABLE. The row swap halves the height: a sprite one row high would make that 0 and the loop run 256 times. The only such sprite is graphic 5, the border's sides, which is mirrored but never turned upside down (BORDER_DATA). As Knight Lore's vflip_sprite_data and hflip_sprite_data.
Input
DE the sprite's width byte
IX the object
Output
DE the sprite's width byte
VFLIP_SPRITE_DATA D174 PUSH DE Kept
D175 LD A,(DE) The sprite's bit 7 against the object's: the same means no turning over
D176 XOR (IX+$07)
D179 AND $80
D17B JR Z,HFLIP_SPRITE_DATA
D17D LD A,(DE) Toggle the sprite's bit
D17E XOR $80
D180 LD (DE),A
D181 RLCA B = bytes a row: the width times two, for the mask and image bytes
D182 AND $7E
D184 LD B,A
D185 INC DE C = the height in rows; DE on the data
D186 LD A,(DE)
D187 LD C,A
D188 INC DE
D189 PUSH DE HL = B * C, the data's length, plus the start: one past the end
D18A LD E,B
D18B LD D,$00
D18D CALL HL_EQUALS_DE_X_A
D190 POP DE
D191 ADD HL,DE
D192 EX DE,HL
D193 LD A,B DE one past the end; HL one past the first row
D194 CALL ADD_HL_A
D197 DEC DE DE on the last byte of the last row, HL on the last byte of the first
D198 DEC HL
D199 SRL C Swap rows in pairs: half the height
VFLIP_ROW_PAIR D19B PUSH BC Kept
VFLIP_SPRITE_LINE_PAIR D19C LD A,(DE) Swap the two rows byte by byte, working backwards
D19D LD C,(HL)
D19E LD (HL),A
D19F LD A,C
D1A0 LD (DE),A
D1A1 DEC HL
D1A2 DEC DE
D1A3 DJNZ VFLIP_SPRITE_LINE_PAIR
D1A5 POP BC HL on to the end of the next row down; DE is already at the end of the row before its last
D1A6 LD A,B
D1A7 SLA A
D1A9 CALL ADD_HL_A
D1AC DEC C The next pair
D1AD JR NZ,VFLIP_ROW_PAIR
HFLIP_SPRITE_DATA D1AF POP DE The sprite's bit 6 against the object's
D1B0 PUSH DE
D1B1 LD A,(DE)
D1B2 XOR (IX+$07)
D1B5 AND $40
D1B7 JR Z,FLIP_DONE
D1B9 LD A,(DE) Toggle the sprite's bit; B and C = the width in cells
D1BA XOR $40
D1BC LD (DE),A
D1BD AND $0F
D1BF LD B,A
D1C0 LD C,A
D1C1 INC DE The height into A'
D1C2 LD A,(DE)
D1C3 EX AF,AF'
D1C4 INC DE HL' reads and HL writes, both from the first row; B' = the page of the bit reversal table
D1C5 EX DE,HL
D1C6 PUSH HL
D1C7 EXX
D1C8 POP HL
D1C9 LD B,$F1
D1CB EXX
HFLIP_READ_ROW D1CC EXX Push a row's pairs, each byte reversed: E' the mask, D' the image
D1CD LD C,(HL)
D1CE LD A,(BC)
D1CF LD E,A
D1D0 INC HL
D1D1 LD C,(HL)
D1D2 LD A,(BC)
D1D3 LD D,A
D1D4 INC HL
D1D5 PUSH DE
D1D6 EXX
D1D7 DJNZ HFLIP_READ_ROW
D1D9 LD B,C The width again, for the writing
HFLIP_WRITE_ROW D1DA POP DE Pop them back over the row: last first, so the cells come back in the reverse order
D1DB LD (HL),E
D1DC INC HL
D1DD LD (HL),D
D1DE INC HL
D1DF DJNZ HFLIP_WRITE_ROW
D1E1 EX AF,AF' The next row, until the height runs out
D1E2 DEC A
D1E3 JR Z,FLIP_DONE
D1E5 EX AF,AF'
D1E6 LD B,C
D1E7 JR HFLIP_READ_ROW
FLIP_DONE D1E9 POP DE DE = the sprite
D1EA RET
Prev: D157 Up: Map Next: D1EB