Prev: D848 Up: Map Next: D8DE
D865: Flip Sprite
Used by the routine at GetSpriteAddress.
Flips the data of a sprite in place, if its flags are not the same as the flags of the object that is going to be drawn. The width byte of a sprite has the vertical flip in bit 7 and the horizontal flip in bit 6. The sprite is flipped vertically by swapping its lines, and horizontally by reversing the bits of each byte and the order of the bytes of each line, with the table of reversed bytes.
Input
DE Address of the sprite
IX Address of the object
Output
DE Address of the sprite
Flip the sprite vertically if the object's flags say so.
FlipSprite D865 PUSH DE Stash the address of the sprite on the stack.
D866 LD A,(DE) Fetch the width of the sprite.
D867 XOR (IX+$07) Compare the vertical flip with the one of the object.
D86A AND %10000000 Keep it.
D86C JR Z,FlipSprite_Horizontal Jump to FlipSprite_Horizontal if they are the same.
D86E LD A,(DE) Fetch the width byte of the sprite.
D86F XOR %10000000 Toggle the vertical flip.
D871 LD (DE),A Store the width.
D872 RLCA Double the width, for the mask and the data.
D873 AND %00011110 Keep the doubled width and drop the flags.
D875 LD B,A Stash it in B.
D876 INC DE Point DE at the height of the sprite.
Fetch the height and stash it in C.
D877 LD A,(DE) Fetch the height.
D878 LD C,A Copy it to C.
D879 INC DE Point DE at the data.
D87A PUSH DE Stash the address of the data on the stack.
D87B LD E,B Set DE to the number of bytes in a line.
D87C LD D,$00
D87E CALL MultiplyAByDE Multiply it by the height.
D881 POP DE Restore the address of the data from the stack.
D882 ADD HL,DE Add the number of bytes of data.
D883 EX DE,HL Point DE at the end of the data, and HL at the start.
D884 LD A,B Fetch B.
D885 CALL AddAToHL Call AddAToHL.
D888 DEC DE Point DE at the last byte of the last line.
D889 DEC HL Point HL at the last byte of the first line.
D88A SRL C Halve the height to get the number of pairs of lines.
FlipSprite_Lines D88C PUSH BC Stash the number of bytes in a line and the number of pairs on the stack.
FlipSprite_Bytes D88D LD A,(DE) Fetch a byte of the last line.
D88E LD C,(HL) Fetch a byte of the first line.
D88F LD (HL),A Store the byte of the last line in the first line.
D890 LD A,C Fetch the byte of the first line.
D891 LD (DE),A Store it in the last line.
D892 DEC HL Go back a byte in the first line.
D893 DEC DE Go back a byte in the last line.
D894 DJNZ FlipSprite_Bytes Jump to FlipSprite_Bytes until the lines are swapped.
D896 POP BC Restore the number of bytes in a line and the number of pairs from the stack.
D897 LD A,B Fetch B.
D898 CALL AddAToHL Call AddAToHL.
D89B LD A,B Add it again, to go to the end of the next line.
D89C CALL AddAToHL
D89F DEC C Count down the pairs of lines.
D8A0 JR NZ,FlipSprite_Lines Jump to FlipSprite_Lines until all of the pairs are swapped.
Flip the sprite horizontally if the object's flags say so.
FlipSprite_Horizontal D8A2 POP DE Fetch the address of the sprite and keep it on the stack.
D8A3 PUSH DE
D8A4 LD A,(DE) Fetch the width of the sprite.
D8A5 XOR (IX+$07) Compare the horizontal flip with the one of the object.
D8A8 AND %01000000 Keep it.
D8AA JR Z,FlipSprite_Done Jump to FlipSprite_Done if they are the same.
D8AC LD A,(DE) Fetch the width byte of the sprite.
D8AD XOR %01000000 Toggle the horizontal flip.
D8AF LD (DE),A Store the width.
D8B0 AND %00001111 Keep the width.
D8B2 LD B,A Copy it to B.
D8B3 LD C,A Copy it to C.
D8B4 INC DE Point DE at the height of the sprite.
D8B5 LD A,(DE) Fetch the height.
D8B6 EX AF,AF' Stash it in the alternate A.
D8B7 INC DE Point DE at the data.
D8B8 EX DE,HL Point HL at the data.
D8B9 PUSH HL Stash the address of the data on the stack.
D8BA EXX Switch to the alternate registers.
D8BB POP HL Restore the address of the data from the stack.
D8BC LD B,$F1 Point BC at the table of reversed bytes.
D8BE EXX Switch back to the main registers.
Reverse the bits of each pair and store the line back in reverse order.
FlipSprite_Line D8BF EXX Switch to the alternate registers.
D8C0 LD C,(HL) Fetch the mask byte of a pair.
D8C1 LD A,(BC) Find the reversed byte.
D8C2 LD E,A Stash it in E.
D8C3 INC HL Move on.
D8C4 LD C,(HL) Fetch the data byte of the pair.
D8C5 LD A,(BC) Find the reversed byte.
D8C6 LD D,A Stash it in D.
D8C7 INC HL Move on.
D8C8 PUSH DE Stash the reversed pair on the stack.
D8C9 EXX Switch back to the main registers.
D8CA DJNZ FlipSprite_Line Jump to FlipSprite_Line until all of the pairs of the line are on the stack.
D8CC LD B,C Set the number of pairs.
FlipSprite_Store D8CD POP DE Restore a reversed pair from the stack, which comes off in the opposite order.
Store the mask byte, and move on.
D8CE LD (HL),E Store the mask byte.
D8CF INC HL Move on.
D8D0 LD (HL),D Store the data byte.
D8D1 INC HL Move on.
D8D2 DJNZ FlipSprite_Store Jump to FlipSprite_Store until the line is stored.
D8D4 EX AF,AF' Fetch the number of lines left.
D8D5 DEC A Count down the lines.
D8D6 JR Z,FlipSprite_Done Jump to FlipSprite_Done if all of the lines are done.
D8D8 EX AF,AF' Stash the number of lines left.
D8D9 LD B,C Set the number of pairs.
D8DA JR FlipSprite_Line Jump to FlipSprite_Line.
FlipSprite_Done D8DC POP DE Restore the address of the sprite from the stack.
D8DD RET Return.
View the equivalent code in;
Prev: D848 Up: Map Next: D8DE