![]() |
Routines |
| Prev: E32C | Up: Map | Next: E3D6 |
|
Used by the routine at DRAW_SPRITE.
The graphic (+0) indexes GRAPHICS for the sprite. A sprite is a width byte -- bits 0-3 the width in bytes, bit 7 set while its data is stored upside down, bit 6 while it is stored mirrored -- a height byte, and then a mask byte and an image byte for each byte of each row, the bottom row first. Bits 7 and 6 of the object's flags (+7) say how it wants to be drawn. Where they differ from the sprite's, the data is turned in place 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 swaps whole rows end for end, the first with the last, working inwards. Mirroring (MIRROR_SPRITE_DATA, also entered by MIRROR_SPRITE) reverses the order of each row's mask and image pairs and the bits of every byte, through REVERSE_TABLE: a row's pairs are read, reversed, onto the stack and popped back in the opposite order.
Nothing in the game sets bit 7 of a record's flags. Every write to that byte was read: the records are cleared or copied from templates that hold 0 there; the rest set or clear bits 0, 1 and 5, set bit 6 from the view or the facing, take bits 6 and 7 from a table whose four bytes have bit 7 clear (FACING_LOOKS), or copy another record's flags. So the upside-down half, and the multiply it uses (HL_EQUALS_DE_X_A), never run -- which the build's sessions agree with -- and every sprite's bit 7 stays clear. Knight Lore's objects do turn upside down; Pentagram's routine is the same as this one, and Alien 8's nearly so.
|
||||||||||||
| TURN_SPRITE | E353 | LD A,(IX+$00) | DE = the sprite, kept on the stack | |||||||||
| E356 | LD BC,GRAPHICS | |||||||||||
| E359 | CALL TABLE_WORD | |||||||||||
| E35C | EX DE,HL | |||||||||||
| E35D | PUSH DE | |||||||||||
| E35E | LD A,(DE) | Stored the way up the object wants? | ||||||||||
| E35F | XOR (IX+$07) | |||||||||||
| E362 | AND $80 | |||||||||||
| E364 | JR Z,TURN_SPRITE_2 | |||||||||||
| E366 | LD A,(DE) | No (it never happens): toggle the sprite's upside-down bit | ||||||||||
| E367 | XOR $80 | |||||||||||
| E369 | LD (DE),A | |||||||||||
| E36A | RLCA | B = the bytes in a row, twice the width | ||||||||||
| E36B | AND $1E | |||||||||||
| E36D | LD B,A | |||||||||||
| E36E | INC DE | C = the height; DE on to the data | ||||||||||
| E36F | LD A,(DE) | |||||||||||
| E370 | LD C,A | |||||||||||
| E371 | INC DE | |||||||||||
| E372 | PUSH DE | |||||||||||
| E373 | LD E,B | DE = the end of the data: the height times a row's bytes on from its start | ||||||||||
| E374 | LD D,$00 | |||||||||||
| E376 | CALL HL_EQUALS_DE_X_A | |||||||||||
| E379 | POP DE | |||||||||||
| E37A | ADD HL,DE | |||||||||||
| E37B | EX DE,HL | |||||||||||
| E37C | LD A,B | HL = the last byte of the first row, DE the last byte of the last; C = half the height, the pairs of rows to swap | ||||||||||
| E37D | CALL ADD_HL_A | |||||||||||
| E380 | DEC DE | |||||||||||
| E381 | DEC HL | |||||||||||
| E382 | SRL C | |||||||||||
| TURN_SPRITE_0 | E384 | PUSH BC | Swap a row with its partner, byte for byte from their ends | |||||||||
| TURN_SPRITE_1 | E385 | LD A,(DE) | ||||||||||
| E386 | LD C,(HL) | |||||||||||
| E387 | LD (HL),A | |||||||||||
| E388 | LD A,C | |||||||||||
| E389 | LD (DE),A | |||||||||||
| E38A | DEC HL | |||||||||||
| E38B | DEC DE | |||||||||||
| E38C | DJNZ TURN_SPRITE_1 | |||||||||||
| E38E | POP BC | HL on to the end of the next row up; DE is already at the end of the row below its last | ||||||||||
| E38F | LD A,B | |||||||||||
| E390 | CALL ADD_HL_A | |||||||||||
| E393 | LD A,B | |||||||||||
| E394 | CALL ADD_HL_A | |||||||||||
| E397 | DEC C | Until the middle | ||||||||||
| E398 | JR NZ,TURN_SPRITE_0 | |||||||||||
| TURN_SPRITE_2 | E39A | POP DE | Stored mirrored or not as the object wants? | |||||||||
| E39B | PUSH DE | |||||||||||
| E39C | LD A,(DE) | |||||||||||
| E39D | XOR (IX+$07) | |||||||||||
| E3A0 | AND $40 | |||||||||||
| E3A2 | JR Z,TURN_SPRITE_5 | |||||||||||
|
This entry point is used by the routine at MIRROR_SPRITE.
|
||||||||||||
| MIRROR_SPRITE_DATA | E3A4 | LD A,(DE) | No, or entered here (MIRROR_SPRITE_DATA): toggle the sprite's mirrored bit; B and C = the width | |||||||||
| E3A5 | XOR $40 | |||||||||||
| E3A7 | LD (DE),A | |||||||||||
| E3A8 | AND $0F | |||||||||||
| E3AA | LD B,A | |||||||||||
| E3AB | LD C,A | |||||||||||
| E3AC | INC DE | A' = the height; HL at the data, and HL' too, with B' the page of REVERSE_TABLE | ||||||||||
| E3AD | LD A,(DE) | |||||||||||
| E3AE | EX AF,AF' | |||||||||||
| E3AF | INC DE | |||||||||||
| E3B0 | EX DE,HL | |||||||||||
| E3B1 | PUSH HL | |||||||||||
| E3B2 | EXX | |||||||||||
| E3B3 | POP HL | |||||||||||
| E3B4 | LD B,$F9 | |||||||||||
| E3B6 | EXX | |||||||||||
| TURN_SPRITE_3 | E3B7 | EXX | Read a row's pairs onto the stack, each byte's bits reversed | |||||||||
| E3B8 | LD C,(HL) | |||||||||||
| E3B9 | LD A,(BC) | |||||||||||
| E3BA | LD E,A | |||||||||||
| E3BB | INC HL | |||||||||||
| E3BC | LD C,(HL) | |||||||||||
| E3BD | LD A,(BC) | |||||||||||
| E3BE | LD D,A | |||||||||||
| E3BF | INC HL | |||||||||||
| E3C0 | PUSH DE | |||||||||||
| E3C1 | EXX | |||||||||||
| E3C2 | DJNZ TURN_SPRITE_3 | |||||||||||
| E3C4 | LD B,C | Pop them back over the same row, the last pair first | ||||||||||
| TURN_SPRITE_4 | E3C5 | POP DE | ||||||||||
| E3C6 | LD (HL),E | |||||||||||
| E3C7 | INC HL | |||||||||||
| E3C8 | LD (HL),D | |||||||||||
| E3C9 | INC HL | |||||||||||
| E3CA | DJNZ TURN_SPRITE_4 | |||||||||||
| E3CC | EX AF,AF' | The next row, until the height is done | ||||||||||
| E3CD | DEC A | |||||||||||
| E3CE | JR Z,TURN_SPRITE_5 | |||||||||||
| E3D0 | EX AF,AF' | |||||||||||
| E3D1 | LD B,C | |||||||||||
| E3D2 | JR TURN_SPRITE_3 | |||||||||||
| TURN_SPRITE_5 | E3D4 | POP DE | Return the sprite in DE | |||||||||
| E3D5 | RET | |||||||||||
| Prev: E32C | Up: Map | Next: E3D6 |