![]() |
Routines |
Prev: 26923 | Up: Map | Next: 27016 |
Used by the routines at Handler_PlayerSprite and Handler_GhostRider.
|
||||||||||||||
DrawSpriteObject | 26924 | LD B,A | Store the sprite frame ID in B. | |||||||||||
26925 | LD A,C | Load the sprite attribute value into A. | ||||||||||||
26926 | EXX | Switch to the shadow registers. | ||||||||||||
26927 | LD HL,(30748) | HL'=*SpriteBackgroundBuffer_Pointer. | ||||||||||||
26930 | LD C,A | Load the sprite attribute value into C'. | ||||||||||||
26931 | LD A,(30747) | Load *ActiveSpriteBlocks into B'. | ||||||||||||
26934 | LD B,A | |||||||||||||
26935 | EXX | Switch back to the normal registers. | ||||||||||||
Calculate the sprite data address from the frame ID.
|
||||||||||||||
26936 | LD A,B | Load L with the frame ID multiplied by 2. | ||||||||||||
26937 | ADD A,A | |||||||||||||
26938 | LD L,A | |||||||||||||
This is quite clever, and very subtle. It's probably easier here to show examples:
The cleverness here is with the carry flag and the
ADC instruction.
When the multiplication of the frame ID passes 256 the carry flag is set and this is included when adding the graphics high byte 190. The
SUB L then removes the "frame ID * 2" part, leaving just 190 + carry flag.
|
||||||||||||||
26939 | ADC A,190 | Load H with the high byte for the graphics data: 190 + the carry flag. | ||||||||||||
26941 | SUB L | |||||||||||||
26942 | LD H,A | |||||||||||||
26943 | LD A,B | Load the original frame ID into A. | ||||||||||||
Fetch the sprite data.
|
||||||||||||||
26944 | LD C,(HL) | Fetch the sprite data address from *HL and store it in BC. | ||||||||||||
26945 | INC L | |||||||||||||
26946 | LD B,(HL) | |||||||||||||
Check the sprite "type" bit.
|
||||||||||||||
26947 | BIT 5,A | Jump to DrawLargeSprite if bit 5 of the sprite ID is set. | ||||||||||||
26949 | JP NZ,DrawLargeSprite | |||||||||||||
Process regular sprite animation frames.
|
||||||||||||||
26952 | LD A,(BC) | Fetch the sprite X offset and store it in A. | ||||||||||||
ProcessNextFrame | 26953 | INC BC | Move to the next data byte. | |||||||||||
26954 | ADD A,E | E=base X position + the sprite X offset. | ||||||||||||
26955 | LD E,A | |||||||||||||
26956 | LD A,(BC) | Fetch the sprite Y offset and store it in A. | ||||||||||||
26957 | INC BC | Move to the next data byte. | ||||||||||||
CalculatePosition | 26958 | ADD A,D | D=base Y position + the sprite Y offset. | |||||||||||
26959 | LD D,A | |||||||||||||
Check if the sprite frame is within the screen boundaries.
|
||||||||||||||
26960 | CP 16 | Jump to SkipToNextFrame if the sprites "Y" position is higher than 16. | ||||||||||||
26962 | JR NC,SkipToNextFrame | |||||||||||||
26964 | LD A,E | Jump to DrawVisibleFrame if the sprites "X" position is lower than 32. | ||||||||||||
26965 | CP 32 | |||||||||||||
26967 | JR C,DrawVisibleFrame | |||||||||||||
Skip the current frame and advance to the next frame data.
|
||||||||||||||
SkipToNextFrame | 26969 | LD HL,8 | BC=sprite data pointer+0008. | |||||||||||
26972 | ADD HL,BC | |||||||||||||
26973 | LD B,H | |||||||||||||
26974 | LD C,L | |||||||||||||
CheckNextFrame | 26975 | LD A,(BC) | Load A with the next control byte from *BC. | |||||||||||
Check for the terminator (255+1 will set the zero flag).
|
||||||||||||||
26976 | INC A | Increment the control byte by one. | ||||||||||||
26977 | LD A,1 | Set the sprite "type" flag in A to 1. | ||||||||||||
26979 | JR NZ,CalculatePosition | Jump to CalculatePosition if the terminator character wasn't detected (on line 26976). | ||||||||||||
We reached the terminator.
|
||||||||||||||
26981 | INC BC | Move to the next data byte. | ||||||||||||
Check for the sequence end marker byte.
|
||||||||||||||
26982 | LD A,(BC) | Read the sequence control byte. | ||||||||||||
26983 | CP 128 | Jump to ProcessNextFrame if the sequence control byte is not equal to 128. | ||||||||||||
26985 | JR NZ,ProcessNextFrame | |||||||||||||
26987 | JP CompleteSpriteSequence | Jump to CompleteSpriteSequence. | ||||||||||||
Draw the sprite frame to the screen.
|
||||||||||||||
DrawVisibleFrame | 26990 | LD A,D | Load the sprite Y position. | |||||||||||
26991 | ADD A,64 | Convert it to a screen buffer address. | ||||||||||||
Extract the bits which relate to the ZX Spectrum screen layout.
|
||||||||||||||
26993 | AND %01001000 | Keep only bits 3 and 6. | ||||||||||||
26995 | LD H,A | Store the result in H. | ||||||||||||
26996 | LD A,D | Reload the sprite Y position. | ||||||||||||
26997 | RRCA | Rotate A right three positions (bits 0 to 2 are now in positions 5 to 7). | ||||||||||||
26998 | RRCA | |||||||||||||
26999 | RRCA | |||||||||||||
Keep only the row bits.
|
||||||||||||||
27000 | AND %11100000 | Keep only bits 5-7. | ||||||||||||
27002 | ADD A,E | Add the sprite X position and store the result in L. | ||||||||||||
27003 | LD L,A | |||||||||||||
Draw the sprite to the screen buffer.
|
||||||||||||||
27004 | CALL DrawSprite | Call DrawSprite to draw the top of the sprite. | ||||||||||||
27007 | INC H | Move to the next screen row. | ||||||||||||
27008 | CALL DrawSprite | Call DrawSprite to draw the bottom of the sprite. | ||||||||||||
27011 | CALL ScreenBufferToAttributeBuffer | Call ScreenBufferToAttributeBuffer. | ||||||||||||
27014 | JR CheckNextFrame | Jump to CheckNextFrame. |
Prev: 26923 | Up: Map | Next: 27016 |