Prev: 26923 Up: Map Next: 27016
26924: Draw Sprite Object
Used by the routines at Handler_PlayerSprite and Handler_GhostRider.
Input
A Sprite frame ID
C Sprite colour
DE Sprite screen position
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:
Input Value Output in HL
13 48666
18 48676
135 48910
199 49038
From a quick glance, the following code looks pretty straight-forward, just a little strange: H=(frame ID * 2) + 190 - (frame ID * 2).
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