![]() |
Routines |
| Prev: B3B6 | Up: Map | Next: B44F |
|
Used by the routine at ResolveObjectOrder.
Draws the sprite of an object into the buffer, using whatever of the room has already been drawn as the background. An object of type 01 is only a marker that something has to be erased, so it is removed instead of being drawn.
The sprite data is for whole bytes. If the screen x co-ordinate of the object is not a multiple of eight, the sprite is shifted to the right by the difference as it is drawn, which makes it one byte wider. Sprites are at most five bytes wide.
The drawing is done by two pieces of code that are set up for the width of the sprite. Each is made of a run of identical units, one for each byte column, and a jump into the run, which is patched with a displacement, starts it at the first unit that is needed. The stack pointer is made to point at the sprite data, so that each pair of bytes can be fetched with a POP.
Each pair is a mask byte followed by a pixel byte. The bits of the buffer that are under the mask are cleared and then the pixel byte is merged in.
|
||||||||
|
An object of type 01 only marks an area to be erased, so it is freed and not drawn.
|
||||||||
| DrawObject | B3D3 | LD A,(IX+$00) | Jump to DrawObject_Project if the type of the object is not 01. | |||||
| B3D6 | CP $01 | |||||||
| B3D8 | JR NZ,DrawObject_Project | |||||||
| B3DA | LD (IX+$00),$00 | Set the type of the object to 00, which frees it. | ||||||
| B3DE | RET | Return. | ||||||
|
Work out where on the screen the sprite goes and fetch the sprite, flipped to the right way round.
|
||||||||
| DrawObject_Project | B3DF | RES 4,(IX+$07) | Clear the flag that says the object needs drawing. | |||||
| B3E3 | CALL CalculatePixelCoordinates | Call CalculatePixelCoordinates to work out the screen position of the object. | ||||||
| B3E6 | RET NC | Return if the object is above the top of the screen. | ||||||
|
This entry point is used by the routines at DisplayObjectsCarried, PrintTableSprite, PrintSprites and DrawLives.
|
||||||||
| DrawObject_Sprite | B3E7 | CALL GetSpriteAddress | Call GetSpriteAddress to flip the sprite if needed and get its address in DE. | |||||
|
Set up the drawing code for a sprite that has to be shifted.
|
||||||||
| B3EA | LD A,(IX+$1A) | Fetch the screen x co-ordinate of the object. | ||||||
| B3ED | AND %00000111 | Keep the number of bits to shift by. | ||||||
| B3EF | JR Z,DrawObject_Aligned | Jump to DrawObject_Aligned if there is no shift. | ||||||
| B3F1 | RLCA | Double it. | ||||||
| B3F2 | AND %00001110 | Keep the number as an even number of pages. | ||||||
| B3F4 | OR %11110000 | Add the page of the first shift table, F0. | ||||||
| B3F6 | LD H,A | Set H to the page of the table for this shift. | ||||||
|
The sprite is a byte wider when it is shifted. Set that width in the object.
|
||||||||
| B3F7 | LD A,(DE) | Fetch the first byte of the sprite, which holds its width, and move on to the height. | ||||||
| B3F8 | INC DE | |||||||
| B3F9 | AND %00000111 | Keep only the width. | ||||||
| B3FB | INC A | Add one for the extra byte. | ||||||
| B3FC | LD B,A | Stash the width in B. | ||||||
| B3FD | LD (IX+$18),A | Write it to the object. | ||||||
|
Work out the displacement that jumps into the shifted code at the first unit that is needed. A unit is 10 bytes long, and the last of them ends at B4CD.
|
||||||||
| B400 | DEC A | Subtract one to get the width of the sprite. | ||||||
| B401 | AND %00000111 | Keep the width (which is at most five). | ||||||
| B403 | ADD A,A | Multiply it by sixteen, the size of a unit. | ||||||
| B404 | ADD A,A | |||||||
| B405 | ADD A,A | |||||||
| B406 | ADD A,A | |||||||
| B407 | NEG | Negate it. | ||||||
| B409 | ADD A,$50 | Add 50, the distance from the displacement to the end of the units. | ||||||
| DrawObject_SetOffset | B40B | LD ($B47C),A | Write it into the jump that starts the drawing, at B47C. | |||||
|
Work out the amount to add to the buffer address to get from the end of a row of the sprite to the start of the next.
|
||||||||
| B40E | LD A,B | Fetch the width, and invert it. | ||||||
| B40F | CPL | |||||||
| B410 | ADD A,$22 | Add 22, which makes the amount 21 less the width. | ||||||
| B412 | LD ($B4D0),A | Write it to the code that finishes a row, at B4D0. | ||||||
|
Fetch the height of the sprite, and cut it down if the sprite sticks out above the top of the screen.
|
||||||||
| B415 | LD A,(DE) | Fetch the height and move on to the data. | ||||||
| B416 | INC DE | |||||||
| B417 | LD (IX+$19),A | Write the height to the object. | ||||||
| B41A | ADD A,(IX+$1B) | Add the bottom of the sprite to get the top of the sprite. | ||||||
| B41D | SUB $C0 | Subtract C0 to see how far it sticks out of the screen. | ||||||
| B41F | JR C,DrawObject_SetAddress | Jump to DrawObject_SetAddress if it does not. | ||||||
| B421 | NEG | Negate the amount. | ||||||
| B423 | ADD A,(IX+$19) | Subtract it from the height, and write that to the object. | ||||||
| B426 | LD (IX+$19),A | |||||||
|
Find where in the buffer the sprite starts and set the stack pointer to the data.
|
||||||||
| DrawObject_SetAddress | B429 | LD C,(IX+$1A) | Set BC to the pixel co-ordinates of the sprite. | |||||
| B42C | LD B,(IX+$1B) | |||||||
| B42F | CALL CalculateBufferAddress | Call CalculateBufferAddress to get the address in the buffer in BC. | ||||||
| B432 | LD ($A717),SP | Save the stack pointer in SavedStackPointer. | ||||||
| B436 | EX DE,HL | Point the stack pointer at the sprite data. | ||||||
| B437 | LD SP,HL | |||||||
| B438 | EX DE,HL | |||||||
| B439 | LD A,(IX+$19) | Fetch the number of rows to draw. | ||||||
| B43C | JR DrawLines | Jump to DrawLines to start drawing. | ||||||
|
Set up the drawing code for a sprite that is not shifted. Each unit of it is 08 bytes long, and the last of them ends at DrawLines_FinishRow.
|
||||||||
| DrawObject_Aligned | B43E | LD A,(DE) | Fetch the first byte of the sprite, which holds its width, and move on to the height. | |||||
| B43F | INC DE | |||||||
| B440 | AND %00001111 | Keep only the width. | ||||||
| B442 | LD (IX+$18),A | Write the width to the object. | ||||||
| B445 | LD B,A | Stash the width in B. | ||||||
| B446 | ADD A,A | Multiply it by eight, the size of a unit. | ||||||
| B447 | ADD A,A | |||||||
| B448 | ADD A,A | |||||||
| B449 | NEG | Negate it. | ||||||
| B44B | SUB $06 | Subtract 06, which makes the jump end at the last unit. | ||||||
| B44D | JR DrawObject_SetOffset | Jump to DrawObject_SetOffset to write the displacement and carry on. | ||||||
|
View the equivalent code in;
|
||||||||
| Prev: B3B6 | Up: Map | Next: B44F |