Prev: 59078 Up: Map Next: 59116
59080: Rotate Player Cursor Attributes
Used by the routine at 63581.
This is a pretty confusing routine, it's used for rotating the attribute values of the players cursor. These are stored in a table at CursorAttributes.
The reason why this is complicated is simply down to how the data is stored... Rather than hold the attribute bytes sequentially, they're held as: top row x 4 bytes, left side x 1 byte, right side x 1 byte, left side x 1 byte, right side x 1 byte and lastly, the bottom row x 4 bytes.
This makes them a lot easier to draw, as the whole thing can then be drawn left-to-right one row at a time (see Draw_Cursor).
Hopefully the rotation problem is clear already, this isn't a matter of just moving every byte along one position - in order to rotate, a look up table is used to track the positions at Table_CursorAttributePositions.
This table should also hopefully make things clearer:
Address Before After 1 Pass After 2 Passes Position
Attribute Byte Attribute Byte Attribute Byte
59055 9 118 54 Top byte 1 (left)
59056 73 9 118 Top byte 2
59057 18 73 9 Top byte 3
59058 82 18 73 Top byte 4 (right)
59059 118 54 109 Middle top byte 1 (left)
59060 27 82 18 Middle top byte 2 (right)
59061 54 109 45 Middle bottom byte 1 (left)
59062 91 27 82 Middle bottom byte 2 (right)
59063 109 45 100 Bottom byte 1 (left)
59064 45 100 36 Bottom byte 2
59065 100 36 91 Bottom byte 3
59066 36 91 27 Bottom byte 4 (right)
On the top row, it's very simple to shift each byte one position to the right but when you reach the end of that row, the subsequent address isn't just next in the sequence. Instead, it's "Middle top byte 2 (right)" as shown in the table which is two positions after "Top byte 4 (right)". Likewise, the next position for the middle section is again, two positions after this one and the bottom row moves in the opposite direction entirely in order to achieve the circular motion!
This creates a wonderful effect as shown here:
moving-game-cursor-animation
PlayerCursor_AttributesRotator 59080 LD HL,59055 Set HL to point to CursorAttributes.
59083 LD IX,59067 Set IX to point to Table_CursorAttributePositions which is the rotation order table.
59087 LD DE,0 Initialise DE to 0000.
59090 LD B,11 Set a counter in B for 11 attribute byte positions.
Grab the first attribute byte value and store it in C for the last part...
59092 LD C,(HL) Fetch the first byte from the cursor attributes pointer and store it in C.
This is a loop which rotates the attributes 11 times, each time moving an attribute from the position specified in the table to the current position.
PlayerCursor_AttributesRotator_Loop 59093 PUSH HL Stash the current position in CursorAttributes on the stack.
59094 LD E,(IX+0) Fetch the current position in the rotation order and store it in E.
59097 INC IX Move to the next entry in rotation table.
59099 LD HL,59055 Add CursorAttributes with DE and store the result in HL.
59102 ADD HL,DE
59103 LD A,(HL) Fetch a byte from the calculated attribute byte pointer and store it in A.
59104 LD (59078),HL Store the calculated attribute byte pointer at *TempAttributeStore.
59107 POP HL Restore the cursor attributes pointer from the stack.
59108 LD (HL),A Write the byte to the cursor attributes pointer.
59109 LD HL,(59078) Restore the calculated attribute byte pointer at *TempAttributeStore back to HL.
59112 DJNZ PlayerCursor_AttributesRotator_Loop Decrease the attribute byte counter by one and loop back to PlayerCursor_AttributesRotator_Loop until the attribute byte counter is zero.
Write the first attribute byte value we stored in C to the second position in the attributes table.
59114 LD (HL),C Write the stored attribute byte in C to *HL.
59115 RET Return.
Prev: 59078 Up: Map Next: 59116