Prev: D331 Up: Map Next: D446
D368: Determine Maroc's sprite graphic position, height and direction
Used by the routine at D331.
Set Maroc's facing direction depending on keys pressed, and set his height (above his shadow) based on his speed
Maroc in a stationary position Maroc moving and hovering
Prepare Maroc's sprite - direction, height and movement
Set attributes and reset movement if needed
D368 CALL $E220 Set attribute colours for Maroc
D36B LD A,($EAAA) Get generic game counter/timer
D36E INC A Increment
D36F LD ($EAAA),A ...and re-store
D372 AND $02 Check bit 1 - this will be set every other frame
D374 JR Z,$D37E
D376 LD A,$00
D378 LD ($EAAB),A If not set (i.e. every other game frame), set vertical & horizontal movement velocity to 0
D37B LD ($EAAC),A By only resetting it every other frame, this has the effect of continuing Maroc's forward movement very briefly when he enters a new room (through a door), before stopping
Identify Maroc's current X/Y pixel co-ordinates (including offsets):
D37E LD A,$00 High overflow/precision byte for graphic horizontal screen position - reset just in case
D380 LD ($EAD4),A
D383 LD HL,($EAC2) Get Maroc's sprite frame graphic address pointer (table at 97C3)
D386 LD ($EACD),HL Copy to graphics address buffer
D389 LD A,($EAC0) Maroc's horizontal (X-axis) screen position (4-pixel/half-character steps)
D38C RLA x 2
D38D RLA x 4 - screen position is now in pixels
D38E AND $FC Filter out any unwanted bits 0 & 1 caused by the RLA
D390 LD ($EAD3),A Store horizontal pixel position in graphics data buffer
D393 LD A,($ECA1) Maroc's height offset as he moves (above his shadow) in pixels
D396 LD D,A
D397 LD A,($EAC1) Maroc's vertical (Y-axis) screen position
D39A LD ($EAD2),A Copy to graphics buffer
D39D SUB D Subtract Maroc's height offset (changes depending on how fast he's moving)
D39E LD D,A Store back in D register
Convert Maroc's horizontal and vertical speeds to positive numbers if needed:
D39F LD A,($EB04) Maroc's horizontal movement speed/rate
D3A2 CP $80 If bit 7 is set, Maroc's moving right
D3A4 JR C,$D3A8 ...So if there's a carry, it means bit 7 isn't set (Maroc's moving left)
D3A6 NEG If Maroc's moving right, change his speed to a positive value (i.e. reset bit 7) ready for the next calculations
D3A8 LD C,A Store horizontal speed in C register
D3A9 LD A,($EB05) Maroc's vartical movement speed/rate
D3AC CP $80 If bit 7 is set, Maroc's moving down
D3AE JR C,$D3B2 ...So if there's a carry, it means bit 7 isn't set (Maroc's moving up)
D3B0 NEG If Maroc's moving up, change his speed to a positive value (i.e. reset bit 7) ready for the next calculations
Get Maroc's speed, and adjust his height above his shadow (pixel offset) accordingly.
First, get the greater of either his horizontal or vertical speed:
D3B2 CP C Check vertical speed (A register) vs horizontal speed (C register)
D3B3 JR NC,$D3B6 If no carry, vertical speed >= horizontal speed
D3B5 LD A,C Otherwise, pick horizontal speed
Calculate Maroc's new height pixel offset based on his current speed:
D3B6 RRA
D3B7 RRA Divide by 4. e.g. if Maroc is at 32 (max speed) the offset will be 8
D3B8 AND $1F ...and filter out any unwanted bits (bits 5-7)
D3BA LD C,A
D3BB LD A,$07 7 (pixels) is the base value (if Maroc isn't moving)
D3BD SUB C Subtract the offset (offset is now between -1 and +7 pixels)
D3BE LD ($ECA1),A ...and store the new offset.
D3C1 ADD A,D Add the new offset to Maroc's vertical (Y-axis) pixel position
D3C2 LD ($EAC1),A ...and store.
Identify Maroc's left/right movement
D3C5 LD A,($EAFD) Get left/right direction key press flag
D3C8 CP $00 If it's 0, neither right/left is being pressed
D3CA JR Z,$D3E7
D3CC CP $80 Left or right direction controls are being pressed so check bit 7 to determine which one.
D3CE JR C,$D3FA Carry = right control key used
D3D0 LD A,($EAFE) No carry = left control key used. Get up/down direction key press flag
D3D3 CP $00 If it's 0, neither up/down is being pressed
D3D5 JR Z,$D3DF
D3D7 CP $80 Up or down direction controls are being pressed so check bit 7 to determine which one.
D3D9 JR C,$D3E3 Carry = up control key used
LEFT and DOWN controls pressed
D3DB LD A,$20
D3DD JR $D40F
LEFT control pressed, no up/down controls pressed.
D3DF LD A,$40
D3E1 JR $D40F
LEFT and UP controls pressed
D3E3 LD A,$60
D3E5 JR $D40F
Neither left or right controls pressed. Check up/down controls.
D3E7 LD A,($EAFE) Get up/down direction key press flag
D3EA CP $00 If it's 0, neither up/down (or left/right) is being pressed - skip out of routine
D3EC JR Z,$D426
D3EE CP $80 Up or down direction controls are being pressed so check bit 7 to determine which one
D3F0 JR NC,$D3F6 No carry = down control key used
UP control pressed, no left/right controls pressed
D3F2 LD A,$80
D3F4 JR $D40F
DOWN control pressed, no left/right controls pressed
D3F6 LD A,$00
D3F8 JR $D40F
Right control pressed - check up/down options
D3FA LD A,($EAFE) Right control pressed. Get up/down direction key press flag
D3FD CP $00 If it's 0, neither up/down is being pressed
D3FF JR Z,$D409
D401 CP $80 Up or down direction controls are being pressed so check bit 7 to determine which one
D403 JR C,$D40D Carry = up control key used
RIGHT and DOWN controls pressed
D405 LD A,$E0
D407 JR $D40F
RIGHT control pressed, no up/down controls pressed
D409 LD A,$C0
D40B JR $D40F
RIGHT and UP controls pressed
D40D LD A,$A0
Determine Maroc's direction - part 2
Control key presses have now been evaluated, and the A register contains a value based on these.
Direction Contents of the A register
DOWN 0
DOWN and LEFT 32
LEFT 64
UP and LEFT 96
UP 128
UP and RIGHT 160
RIGHT 192
DOWN and RIGHT 224
Each additional 32 increment indicates a clockwise rotation of the sprite. As Maroc moves, he smoothly rotates towards the new position using these increments, rather than the sprite suddenly switching to a new direction.
D40F LD B,A Store above value in B register
D410 LD A,($EB03) Get Maroc's current facing direction
D413 LD C,A Store in C register
D414 LD A,B Get the new direction based on the previously evaluated keys pressed
D415 SUB C ...and subtract the existing direction
D416 JR Z,$D426 If the result is 0, Maroc is already facing in the right direction - nothing to change
D418 CP $80 Check bit 7 to see if the result is positive or negative, i.e. whether Maroc needs to rotate clockwise or anti-clockwise.
D41A JR NC,$D420
D41C LD A,$20 If it's positive, set the increment amount to 32 - Maroc is rotating CLOCKWISE
D41E JR $D422
D420 LD A,$E0 If it's negative, set the increment amount to -32 - Maroc is rotating ANTI-CLOCKWISE
D422 ADD A,C Add this offset to the existing position
D423 LD ($EB03),A ...and store.
Get the graphic address offset corresponding to this new rotational position.
D426 LD A,($EB03) Get Maroc's new rotational position (see values in table at D40F)
D429 RRA Divide by 16
D42A RRA
D42B RRA
D42C RRA
D42D AND $0E Filter out any other bits set by the RRA instructions
The A register value is now even and in the range of 0-14. This is the address pointer offset for Maroc's sprite frame (starting at 97C3).
D42F LD E,A Store in E register
D430 LD C,$00 Reset C register (will act as a flag to indicate if anything has changed with Maroc's sprite)
D432 LD A,($EC9F) Get the current address pointer offset
D435 CP E Compare with the newly calculated one
D436 JR Z,$D446 If it's the same, there's nothing to change, so skip out of this routine
D438 INC C Increment the (flag) C register (this indicates that there's been a change to Maroc's sprite graphic)
D439 LD A,E Get the newly calculated graphics offset address value
D43A LD ($EC9F),A ...and store
D43D LD D,$00 The graphics address offset will be in DE, the high byte of the offset isn't needed so reset it
D43F LD HL,($EB6A) Address pointer to graphics at 97C3
D442 ADD HL,DE Add the offset for Maroc's new graphics frame
D443 LD ($EAC2),HL ...and store.
Prev: D331 Up: Map Next: D446