![]() |
Routines |
| Prev: B2C5 | Up: Map | Next: B37F |
|
Used by the routines at DrawObject and CalculateSpriteSize.
Makes sure that the sprite of an object faces the way the object does. The sprite data holds its own state in the top two bits of its first byte: bit 7 says that it is upside down and bit 6 that it is mirrored. If either differs from the flags of the object (bits 7 and 6 of its flag byte) the sprite data is flipped to match, in place.
A sprite is held as rows of pairs of bytes, one pair per 08 pixels, with the mask byte first. Its bottom row comes first. Flipping it upside down swaps the rows over; mirroring it reverses the bits of each byte and the order of the bytes in each row.
If the type of the object has no sprite, the routine returns to the caller of its caller.
|
||||||||||||
|
Find the address of the sprite.
|
||||||||||||
| GetSpriteAddress | B2EE | LD L,(IX+$00) | Fetch the sprite number. | |||||||||
| B2F1 | LD H,$00 | Set H to 00. | ||||||||||
| B2F3 | ADD HL,HL | Double HL. | ||||||||||
|
Find the entry for the type in the sprite table, SpriteTable.
|
||||||||||||
| B2F4 | LD BC,$6DD7 | Point BC at SpriteTable. | ||||||||||
| B2F7 | ADD HL,BC | Add BC to HL. | ||||||||||
| B2F8 | LD E,(HL) | Fetch the address of the sprite. | ||||||||||
| B2F9 | INC HL | |||||||||||
| B2FA | LD D,(HL) | |||||||||||
| B2FB | LD A,(DE) | Jump to GetSpriteAddress_Vertical if the sprite exists, which is when its first byte is not zero. | ||||||||||
| B2FC | AND A | |||||||||||
| B2FD | JR NZ,GetSpriteAddress_Vertical | |||||||||||
| B2FF | INC SP | Otherwise discard the return address of the caller... | ||||||||||
| B300 | INC SP | |||||||||||
| B301 | RET | ...and return to the caller of the caller. | ||||||||||
|
Flip the sprite upside down if its state differs from that of the object.
|
||||||||||||
| GetSpriteAddress_Vertical | B302 | PUSH DE | Stash the address of the sprite on the stack. | |||||||||
| B303 | LD A,(DE) | Compare the first byte of the sprite with the flags of the object. | ||||||||||
| B304 | XOR (IX+$07) | |||||||||||
| B307 | AND %10000000 | Keep only bit 7. | ||||||||||
| B309 | JR Z,GetSpriteAddress_Horizontal | Jump to GetSpriteAddress_Horizontal if they are the same. | ||||||||||
| B30B | LD A,(DE) | Toggle bit 7 of the sprite state. | ||||||||||
| B30C | XOR $80 | |||||||||||
| B30E | LD (DE),A | |||||||||||
| B30F | RLCA | Rotate the width up by one bit, to double it. | ||||||||||
| B310 | AND %00011110 | Keep the doubled width, which is the number of bytes in a row. | ||||||||||
| B312 | LD B,A | Set B to the row length. | ||||||||||
| B313 | INC DE | Move on to the height. | ||||||||||
| B314 | LD A,(DE) | Fetch the height of the sprite in C. | ||||||||||
| B315 | LD C,A | |||||||||||
| B316 | INC DE | Move on to the first row. | ||||||||||
| B317 | PUSH BC | Stash the row length and the height, and the address of the data, on the stack. | ||||||||||
| B318 | PUSH DE | |||||||||||
| B319 | LD E,C | Set DE to the height and clear HL. | ||||||||||
| B31A | LD D,$00 | |||||||||||
| B31C | LD H,D | |||||||||||
| B31D | LD L,D | |||||||||||
| GetSpriteAddress_Multiply | B31E | ADD HL,DE | Multiply the height by the row length, to get the size of the data. | |||||||||
| B31F | DJNZ GetSpriteAddress_Multiply | |||||||||||
| B321 | POP DE | Restore the address of the data and the row length from the stack. | ||||||||||
| B322 | POP BC | |||||||||||
| B323 | ADD HL,DE | Add the address of the data to get the address of the end of it. | ||||||||||
| B324 | EX DE,HL | Put the end of the sprite data against its start. | ||||||||||
| B325 | LD A,B | Call AddAToHL to add the row length to HL, which then points to the end of the first row. | ||||||||||
| B326 | CALL AddAToHL | |||||||||||
| B329 | DEC DE | Line up the last byte of the last row with that of the first row. | ||||||||||
| B32A | DEC HL | |||||||||||
| B32B | SRL C | Halve the height to get the number of pairs of rows to swap. | ||||||||||
| GetSpriteAddress_SwapRows | B32D | PUSH BC | Stash the counters on the stack. | |||||||||
| GetSpriteAddress_SwapByte | B32E | LD A,(DE) | Swap a byte of the lower row with a byte of the upper row. | |||||||||
| B32F | LD C,(HL) | |||||||||||
| B330 | LD (HL),A | |||||||||||
| B331 | LD A,C | |||||||||||
| B332 | LD (DE),A | |||||||||||
| B333 | DEC HL | Move both pointers back to the previous byte. | ||||||||||
| B334 | DEC DE | |||||||||||
| B335 | DJNZ GetSpriteAddress_SwapByte | Decrease the byte counter and loop until the rows have been swapped. | ||||||||||
| B337 | POP BC | Restore the counters from the stack. | ||||||||||
|
Move on to the next pair of rows: the upper pointer on to the end of the next row, while the lower pointer is already at the end of the row below.
|
||||||||||||
| B338 | LD A,B | Call AddAToHL to add the row length to HL. | ||||||||||
| B339 | CALL AddAToHL | |||||||||||
| B33C | LD A,B | Call AddAToHL to add the row length to HL again. | ||||||||||
| B33D | CALL AddAToHL | |||||||||||
| B340 | DEC C | Count down the row pairs and jump to GetSpriteAddress_SwapRows until they are swapped. | ||||||||||
| B341 | JR NZ,GetSpriteAddress_SwapRows | |||||||||||
|
Mirror the sprite if its state differs from that of the object.
|
||||||||||||
| GetSpriteAddress_Horizontal | B343 | POP DE | Restore the address of the sprite from the stack. | |||||||||
| B344 | PUSH DE | Stash the address of the sprite on the stack again. | ||||||||||
| B345 | LD A,(DE) | Compare the first byte of the sprite with the flags of the object. | ||||||||||
| B346 | XOR (IX+$07) | |||||||||||
| B349 | AND %01000000 | Keep only bit 6. | ||||||||||
| B34B | JR Z,GetSpriteAddress_Done | Jump to GetSpriteAddress_Done if they are the same. | ||||||||||
| B34D | LD A,(DE) | Toggle bit 6 of the sprite state. | ||||||||||
| B34E | XOR $40 | |||||||||||
| B350 | LD (DE),A | |||||||||||
| B351 | AND %00001111 | Keep only the width. | ||||||||||
| B353 | LD B,A | Set B and C to the width in byte columns. | ||||||||||
| B354 | LD C,A | |||||||||||
| B355 | INC DE | Move on to the height. | ||||||||||
| B356 | LD A,(DE) | Fetch the height. | ||||||||||
| B357 | EX AF,AF' | Keep the height as the row counter. | ||||||||||
| B358 | INC DE | Move on to the first row. | ||||||||||
| B359 | EX DE,HL | Start at the first row of the sprite. | ||||||||||
| B35A | PUSH HL | Stash the address of the first row on the stack. | ||||||||||
| B35B | EXX | Switch to the shadow registers. | ||||||||||
| B35C | POP HL | Restore it into HL' from the stack to read the data with. | ||||||||||
| B35D | LD B,$F1 | Use the table of reversed bytes, whose page is F1. | ||||||||||
| B35F | EXX | Switch back to the main registers. | ||||||||||
|
Read a row, reversing the bits of each byte, and stack each pair of bytes.
|
||||||||||||
| GetSpriteAddress_ReadRow | B360 | EXX | Switch to the shadow registers. | |||||||||
| B361 | LD C,(HL) | Look up the mask byte in the table of reversed bytes, and keep the result in the low byte of DE'. | ||||||||||
| B362 | LD A,(BC) | |||||||||||
| B363 | LD E,A | |||||||||||
| B364 | INC HL | Move on to the pixel byte. | ||||||||||
| B365 | LD C,(HL) | Do the same with the pixel byte, keeping the result in the high byte of DE'. | ||||||||||
| B366 | LD A,(BC) | |||||||||||
| B367 | LD D,A | |||||||||||
| B368 | INC HL | Move on to the next pair. | ||||||||||
| B369 | PUSH DE | Stash the reversed pair on the stack. | ||||||||||
| B36A | EXX | Switch back to the main registers. | ||||||||||
| B36B | DJNZ GetSpriteAddress_ReadRow | Decrease the column counter and loop until the row has been read. | ||||||||||
| B36D | LD B,C | Restore the column counter. | ||||||||||
|
Write the pairs back in the opposite order.
|
||||||||||||
| GetSpriteAddress_WriteRow | B36E | POP DE | Take a pair from the stack. | |||||||||
| B36F | LD (HL),E | Write the mask byte. | ||||||||||
| B370 | INC HL | Move on. | ||||||||||
| B371 | LD (HL),D | Write the pixel byte. | ||||||||||
| B372 | INC HL | Move on. | ||||||||||
| B373 | DJNZ GetSpriteAddress_WriteRow | Decrease the column counter and loop until the row has been written. | ||||||||||
| B375 | EX AF,AF' | Swap in the row counter. | ||||||||||
| B376 | DEC A | Jump to GetSpriteAddress_Done once the last row has been mirrored. | ||||||||||
| B377 | JR Z,GetSpriteAddress_Done | |||||||||||
| B379 | EX AF,AF' | Stash the row counter again. | ||||||||||
| B37A | LD B,C | Restore the column counter. | ||||||||||
| B37B | JR GetSpriteAddress_ReadRow | Jump to GetSpriteAddress_ReadRow to do the next row. | ||||||||||
| GetSpriteAddress_Done | B37D | POP DE | Restore the address of the sprite from the stack. | |||||||||
| B37E | RET | Return. | ||||||||||
|
View the equivalent code in;
|
||||||||||||
| Prev: B2C5 | Up: Map | Next: B37F |