Prev: B7A4 Up: Map Next: B8DD
B7CE: Update Extra Record
Used by the routine at UpdateExtraRecords.
Builds the extra record for an entity, and fills the temporary entity at TemporaryEntity so that SetEntitySize can measure its sprite. Field 1F chooses the size class: below 17 is class 0, below 25 is class 1, and any higher value is class 2. A size index of zero or FF leaves the record unset.
Bit 6 of the flags in field 1E selects the higher frame. The frame written for the temporary entity is the class when the bit is clear, and the class plus three when it is set. The same bit is copied into bit 7 of byte 0C of the extra record. Purpose of the flag beyond that choice is not yet known. The instructions at UpdateExtraRecord_Unused would step the shape bits of the height and then start a burst, but they are not reached: the class is only 0, 1 or 2, so the jump at UpdateExtraRecord_HigherFrame is always taken. The saved zero flag then makes the height adjustment subtract field 1F rather than add the z extent.
The adjusted x coordinate is the entity's x plus half of field 0B its x extent, and the adjusted y coordinate is the entity's y plus half of field 0C its y extent. Both are reduced by a margin taken from the class. The z coordinate is the entity's z less field 1F or 0100 when that would leave the high byte zero. Bytes 02 and 03 of the extra record receive the adjusted x, bytes 04 and 05 the adjusted y, and bytes 06 and 07 the adjusted z. Byte 0B holds the width in bits 0-3 and the frame in bits 4-7. Byte 0C holds the height in bits 0-5.
Input
IX The entity
IY The extra record
Output
A Zero if the record was set up, otherwise non-zero
Leave the record unset when the size index is zero or FF.
UpdateExtraRecord B7CE LD A,(IX+$1F) Fetch the size index.
B7D1 AND A Jump to UpdateExtraRecord_Start if the size index is not zero.
B7D2 JR NZ,UpdateExtraRecord_Start
UpdateExtraRecord_Return B7D4 OR %00000001 Report that the record was not set up.
B7D6 RET Return.
UpdateExtraRecord_Start B7D7 INC A Advance the size index.
B7D8 JR Z,UpdateExtraRecord_Return Leave the record unset if the size index was FF.
B7DA LD D,$00 Take class 0.
B7DC CP $18 Use class 0 when the size index is below 17.
B7DE JR C,UpdateExtraRecord_Class
B7E0 INC D Take the next class.
B7E1 CP $26 Use class 1 when the size index is below 25.
B7E3 JR C,UpdateExtraRecord_Class
B7E5 INC D Take class 2.
Remember a clear zero flag, so the height adjustment later subtracts the size index. Then choose the higher frame when bit 6 of the flags is set.
UpdateExtraRecord_Class B7E6 XOR A Clear the alternate flags.
B7E7 EX AF,AF' Save the alternate flags.
B7E8 LD A,D Take the class as the frame.
B7E9 BIT 6,(IX+$1E) Jump to UpdateExtraRecord_Position to keep this frame if bit 6 is clear.
B7ED JR Z,UpdateExtraRecord_Position
B7EF LD A,(IX+$1F) Fetch the size index again.
B7F2 CP $05 Compare the size index with 05. The result is not used.
B7F4 LD A,D Take the class again.
B7F5 INC A Advance to the higher frame.
UpdateExtraRecord_HigherFrame B7F6 JR NC,UpdateExtraRecord_Size Use the higher frame. This jump is always taken.
These instructions are not reached. They would cycle bits 6-7 of the height, play the medium buzz the first time, and start a burst when the cycle wraps, clearing bit 6 of the flags.
UpdateExtraRecord_Unused B7F8 EX AF,AF' Restore the alternate flags.
B7F9 LD A,(IX+$17) Fetch the height byte.
B7FC AND %11000000 Keep the shape bits of the height.
B7FE JR NZ,UpdateExtraRecord_Frame Step the shape if it has already started.
B800 SET 6,(IX+$17) Set the first shape bit of the height.
B804 CALL PlayMediumBuzz Play the medium buzz.
B807 JR UpdateExtraRecord_Shape Join the shape calculation.
UpdateExtraRecord_Frame B809 LD A,($A2DD) Fetch the frame counter.
B80C AND %00000011 Act on every fourth frame.
B80E JR NZ,UpdateExtraRecord_Shape Leave the shape as it is on the other frames.
B810 LD A,(IX+$17) Fetch the height byte.
B813 ADD A,$40 Step the shape bits.
B815 JR NC,UpdateExtraRecord_Store Store the new shape if it has not wrapped.
B817 CALL StartBurst Start a burst.
B81A RES 6,(IX+$1E) Clear bit 6 of the flags.
B81E RES 7,(IX+$17) Clear the upper shape bit of the height.
B822 RES 6,(IX+$17) Clear the lower shape bit of the height.
B826 JR UpdateExtraRecord_Return Leave the record unset.
UpdateExtraRecord_Store B828 LD (IX+$17),A Store the stepped height byte.
UpdateExtraRecord_Shape B82B LD A,(IX+$17) Fetch the height byte.
B82E RLCA Move the shape bits down.
B82F RLCA
B830 NEG Make the shape number negative.
B832 AND %00000011 Keep the two shape bits.
UpdateExtraRecord_Size B834 ADD A,$02 Move up by two frames from the shape, or from the higher frame.
B836 LD D,$02 Use a fixed margin for the higher frame.
Write the frame, then the x extent of the temporary entity, which is four times the complement of the class margin.
UpdateExtraRecord_Position B838 LD ($B7A5),A Store the frame in the temporary entity.
B83B LD A,D Take the class, or the fixed margin of the higher frame.
B83C ADD A,$FC Subtract four.
B83E CPL Complement the margin.
B83F ADD A,A Double the margin.
B840 LD D,A Keep the doubled margin.
B841 ADD A,A Double it again.
B842 LD ($B7AF),A Store the x extent of the temporary entity.
Move the x coordinate by half of the x extent, less the margin.
B845 LD H,(IX+$02) Fetch the high byte of the x coordinate.
B848 LD L,(IX+$03) Fetch the low byte of the x coordinate.
B84B LD A,(IX+$0B) Fetch the x extent.
B84E SRL A Halve the x extent.
B850 DEC A Reduce it by one.
B851 SUB D Subtract the margin.
B852 LD C,A Keep the adjustment.
B853 LD B,$00 Take a positive adjustment.
B855 JR NC,UpdateExtraRecord_AddX Keep the positive adjustment.
B857 LD B,$FF Take a negative adjustment.
UpdateExtraRecord_AddX B859 ADD HL,BC Add the adjustment to the x coordinate.
B85A LD A,L Swap the bytes of the x coordinate.
B85B LD L,H
B85C LD H,A
B85D LD ($B7A6),HL Store the adjusted x coordinate in the temporary entity.
B860 LD (IY+$02),L Store the high byte of the adjusted x coordinate in the extra record.
B863 LD (IY+$03),H Store the low byte of the adjusted x coordinate in the extra record.
Move the y coordinate by half of the y extent, less the same margin.
B866 LD H,(IX+$05) Fetch the high byte of the y coordinate.
B869 LD L,(IX+$06) Fetch the low byte of the y coordinate.
B86C LD A,(IX+$0C) Fetch the y extent.
B86F SRL A Halve the y extent.
B871 DEC A Reduce it by one.
B872 SUB D Subtract the margin.
B873 LD B,$00 Take a positive adjustment.
B875 JR NC,UpdateExtraRecord_AddY Keep the positive adjustment.
B877 LD B,$FF Take a negative adjustment.
UpdateExtraRecord_AddY B879 ADD HL,BC Add the adjustment to the y coordinate.
B87A LD A,L Swap the bytes of the y coordinate.
B87B LD L,H
B87C LD H,A
B87D LD ($B7A9),HL Store the adjusted y coordinate in the temporary entity.
B880 LD (IY+$04),L Store the high byte of the adjusted y coordinate in the extra record.
B883 LD (IY+$05),H Store the low byte of the adjusted y coordinate in the extra record.
Lower the z coordinate by the size index. The saved zero flag makes this the path that is taken. The other path would add the z extent.
B886 LD H,(IX+$08) Fetch the top byte of the z coordinate.
B889 LD L,(IX+$09) Fetch the middle byte of the z coordinate.
B88C LD D,$00 Clear the high byte of the subtraction.
B88E EX AF,AF' Restore the saved zero flag.
B88F JR Z,UpdateExtraRecord_Height Subtract the size index. This jump is always taken.
B891 LD E,(IX+$0D) Fetch the z extent.
B894 ADD HL,DE Add the z extent. This path is not taken.
B895 JR UpdateExtraRecord_Finish Join the stored height.
UpdateExtraRecord_Height B897 LD E,(IX+$1F) Fetch the size index.
B89A XOR A Clear the carry.
B89B SBC HL,DE Subtract the size index from the z coordinate.
B89D OR H Test the high byte of the result.
B89E JR NZ,UpdateExtraRecord_Finish Keep the result when the high byte is not zero.
B8A0 LD HL,$0100 Use a height of 0100 when the result is zero.
UpdateExtraRecord_Finish B8A3 LD (IY+$06),H Store the high byte of the adjusted z coordinate in the extra record.
B8A6 LD (IY+$07),L Store the low byte of the adjusted z coordinate in the extra record.
B8A9 LD A,L Swap the bytes of the z coordinate.
B8AA LD L,H
B8AB LD H,A
B8AC LD ($B7AC),HL Store the adjusted z coordinate in the temporary entity.
B8AF LD IX,$B7A4 Use the temporary entity.
B8B3 LD (IX+$17),$00 Clear the height byte of the temporary entity.
B8B7 CALL SetEntitySize Measure the sprite.
B8BA LD A,(IX+$01) Fetch the frame of the temporary entity.
B8BD ADD A,A Move the frame into the high nibble.
B8BE ADD A,A
B8BF ADD A,A
B8C0 ADD A,A
B8C1 LD B,A
B8C2 LD A,(IX+$16) Fetch the width of the temporary entity.
B8C5 AND %00001111 Keep the width.
B8C7 OR B Combine the frame with the width.
B8C8 LD (IY+$0B),A Store the frame and the width in the extra record.
B8CB LD A,(IX+$17) Fetch the height of the temporary entity.
B8CE AND %00111111 Keep the height.
B8D0 LD B,A Keep the height aside.
B8D1 LD A,(IX+$1E) Fetch the flags.
B8D4 ADD A,A Move bit 6 of the flags up to bit 7.
B8D5 AND %10000000 Keep that bit.
B8D7 OR B Combine it with the height.
B8D8 LD (IY+$0C),A Store the height in the extra record.
B8DB XOR A Report that the record was set up.
B8DC RET Return.
Prev: B7A4 Up: Map Next: B8DD