Prev: 46006 Up: Map Next: 46159
46035: Draw Object
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 1 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.
Input
IX Object record
An object of type 1 only marks an area to be erased, so it is freed and not drawn.
DrawObject 46035 LD A,(IX+0) Jump to DrawObject_Project if the type of the object is not 1.
46038 CP 1
46040 JR NZ,DrawObject_Project
46042 LD (IX+0),0 Set the type of the object to 0, which frees it.
46046 RET Return.
Work out where on the screen the sprite goes and fetch the sprite, flipped to the right way round.
DrawObject_Project 46047 RES 4,(IX+7) Clear the flag that says the object needs drawing.
46051 CALL CalculatePixelCoordinates Call CalculatePixelCoordinates to work out the screen position of the object.
46054 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 46055 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.
46058 LD A,(IX+26) Fetch the screen x co-ordinate of the object.
46061 AND %00000111 Keep the number of bits to shift by.
46063 JR Z,DrawObject_Aligned Jump to DrawObject_Aligned if there is no shift.
46065 RLCA Double it.
46066 AND %00001110 Keep the number as an even number of pages.
46068 OR %11110000 Add the page of the first shift table, 240.
46070 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.
46071 LD A,(DE) Fetch the first byte of the sprite, which holds its width, and move on to the height.
46072 INC DE
46073 AND %00000111 Keep only the width.
46075 INC A Add one for the extra byte.
46076 LD B,A Stash the width in B.
46077 LD (IX+24),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 16 bytes long, and the last of them ends at 46285.
46080 DEC A Subtract one to get the width of the sprite.
46081 AND %00000111 Keep the width (which is at most five).
46083 ADD A,A Multiply it by sixteen, the size of a unit.
46084 ADD A,A
46085 ADD A,A
46086 ADD A,A
46087 NEG Negate it.
46089 ADD A,80 Add 80, the distance from the displacement to the end of the units.
DrawObject_SetOffset 46091 LD (46204),A Write it into the jump that starts the drawing, at 46204.
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.
46094 LD A,B Fetch the width, and invert it.
46095 CPL
46096 ADD A,34 Add 34, which makes the amount 33 less the width.
46098 LD (46288),A Write it to the code that finishes a row, at 46288.
Fetch the height of the sprite, and cut it down if the sprite sticks out above the top of the screen.
46101 LD A,(DE) Fetch the height and move on to the data.
46102 INC DE
46103 LD (IX+25),A Write the height to the object.
46106 ADD A,(IX+27) Add the bottom of the sprite to get the top of the sprite.
46109 SUB 192 Subtract 192 to see how far it sticks out of the screen.
46111 JR C,DrawObject_SetAddress Jump to DrawObject_SetAddress if it does not.
46113 NEG Negate the amount.
46115 ADD A,(IX+25) Subtract it from the height, and write that to the object.
46118 LD (IX+25),A
Find where in the buffer the sprite starts and set the stack pointer to the data.
DrawObject_SetAddress 46121 LD C,(IX+26) Set BC to the pixel co-ordinates of the sprite.
46124 LD B,(IX+27)
46127 CALL CalculateBufferAddress Call CalculateBufferAddress to get the address in the buffer in BC.
46130 LD (42775),SP Save the stack pointer in SavedStackPointer.
46134 EX DE,HL Point the stack pointer at the sprite data.
46135 LD SP,HL
46136 EX DE,HL
46137 LD A,(IX+25) Fetch the number of rows to draw.
46140 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 8 bytes long, and the last of them ends at DrawLines_FinishRow.
DrawObject_Aligned 46142 LD A,(DE) Fetch the first byte of the sprite, which holds its width, and move on to the height.
46143 INC DE
46144 AND %00001111 Keep only the width.
46146 LD (IX+24),A Write the width to the object.
46149 LD B,A Stash the width in B.
46150 ADD A,A Multiply it by eight, the size of a unit.
46151 ADD A,A
46152 ADD A,A
46153 NEG Negate it.
46155 SUB 6 Subtract 6, which makes the jump end at the last unit.
46157 JR DrawObject_SetOffset Jump to DrawObject_SetOffset to write the displacement and carry on.
View the equivalent code in;
Prev: 46006 Up: Map Next: 46159