View Single Post
  #168    
Old September 26th, 2011 (06:42 PM). Edited September 26th, 2011 by DavidJCobb.
DavidJCobb DavidJCobb is offline
RESIDENT RAAAAAAAAAAAAGEMASTER
 
Join Date: Jul 2010
Gender: Male
Nature: Lonely
Posts: 275
Here's some information that may make my previous discovery more useful.

First, a demonstration.

Next, the walking subroutine that I used in that demonstration, with comments added. Modifying this should allow for easily-controlled tile-changing-when-stepped on effects.

Spoiler:
Code:
.align 2
.thumb

SUBR_MAIN:
push {r4-r7,lr}
add sp, #-0x4
lsl r0, r0, #0x18
lsr r0, r0, #0x18
ldr r2, EXECUTION_QUEUE
add r2, r2, #0x8
lsl r1, r0, #0x2
add r1, r1, r0
lsl r1, r1, #0x3
add r5, r1, r2                     // r5 is the start of roughly 30 bytes of RAM alotted for this functionality
mov r1, #0x2
ldsh r0, [r5, r1]                  // we use this as part of a queueing system
cmp r0, #0x0                       // only happens after switching subroutines with cmda6 (the 30 bytes are cleared)
beq SUBR_INIT
cmp r0, #0x1                       // 1 means that we're listening for footsteps
beq SUBR_STEP
bgt SUBR_TILE                      // higher values mean we have a tile change queued
mov r0, #0x1
strh r0, [r5, #0x2]

SUBR_RTRN:
add sp, #0x4
pop {r4-r7}
pop {pc}

SUBR_INIT:                         // initialize our state data
mov r4, sp
add r4, r4, #0x2
mov r1, r4
ldr r3, F_GET_COORDS
bl CALL_R3
ldrh r2, [sp]
strh r2, [r5, #0x4] // we
ldrh r0, [r4]
strh r0, [r5, #0x6]
ldr r2, DEFAULT_COLOR
strh r2, [r5, #0x8]
mov r2, #0x0
strh r2, [r5, #0xC]
mov r2, #0x1
strh r2, [r5, #0x2]
b SUBR_RTRN

SUBR_STEP:                         // check if the player's taken a step
mov r4, sp
add r4, r4, #0x2
mov r1, r4
mov r0, sp
ldr r3, F_GET_COORDS
bl CALL_R3
mov r0, sp                         // compare current coords to logged coords
ldrh r2, [r0]
mov r3, #0x0
ldsh r1, [r0, r3]
mov r3, #0x4
ldsh r0, [r5, r3]
cmp r0, r1
bne SUBR_STEP_CHECK_SWITCH
mov r3, #0x0
ldsh r1, [r4, r3]
mov r3, #0x6
ldsh r0, [r5, r3]
cmp r0, r1
beq SUBR_RTRN
b SUBR_STEP_CHECK_SWITCH

SUBR_STEP_CHECK_SWITCH:
strh r2, [r5, #0x4]                // log the new coords
ldrh r0, [r4]
strh r0, [r5, #0x6]
mov r0, sp
mov r3, #0x0
ldsh r0, [r0, r3]
ldsh r1, [r4, r3]
ldr r3, F_GET_TILE                 // check if the player's standing on one of the "palette" tiles
bl CALL_R3
mov r2, #0x0
ldr r1, BLUE_SWITCH_TILE
cmp r0, r1
beq SUBR_STEP_SET_BLUE
ldr r1, RED_SWITCH_TILE
cmp r0, r1
beq SUBR_STEP_SET_RED
ldr r1, GREEN_SWITCH_TILE
cmp r0, r1
beq SUBR_STEP_SET_GREEN
ldr r1, WHITE_SWITCH_TILE
cmp r0, r1
beq SUBR_STEP_SET_WHITE
b SUBR_STEP_CHECK_CANVAS

SUBR_STEP_SET_BLUE:
ldr r2, BLUE_CANVAS_TILE
b SUBR_STEP_SET

SUBR_STEP_SET_RED:
ldr r2, RED_CANVAS_TILE
b SUBR_STEP_SET

SUBR_STEP_SET_GREEN:
ldr r2, GREEN_CANVAS_TILE
b SUBR_STEP_SET

SUBR_STEP_SET_WHITE:
ldr r2, WHITE_CANVAS_TILE
b SUBR_STEP_SET

SUBR_STEP_SET:
strh r2, [r5, #0x8]                // if so, store their selection (tile ID of color to change to)
b SUBR_RTRN

SUBR_STEP_CHECK_CANVAS:            // check if standing on a "canvas" tile
ldr r2, BLUE_CANVAS_TILE
cmp r0, r2
beq SUBR_STEP_QUEUE_CANVAS
ldr r2, RED_CANVAS_TILE
cmp r0, r2
beq SUBR_STEP_QUEUE_CANVAS
ldr r2, GREEN_CANVAS_TILE
cmp r0, r2
beq SUBR_STEP_QUEUE_CANVAS
ldr r2, WHITE_CANVAS_TILE
cmp r0, r2
beq SUBR_STEP_QUEUE_CANVAS
b SUBR_RTRN

SUBR_STEP_QUEUE_CANVAS:
mov r2, #0x4                       // if so, queue a change
strh r2, [r5, #0xC]
mov r0, #0x2
strh r0, [r5, #0x2]
ldrh r0, [sp]
strh r0, [r5, #0xE]
ldrh r0, [r4]
strh r0, [r5, #0x10]
b SUBR_RTRN

SUBR_TILE:
ldrh r0, [r5, #0xC]
cmp r0, #0x1                       // we can delay a change by a specific number of frames
bgt SUBR_TILE_DELAY
mov r1, sp
ldrh r0, [r5, #0xE]
strh r0, [r1]
mov r4, sp
add r4, r4, #0x2
ldrh r0, [r5, #0x10]
strh r0, [r4]
mov r0, #0x24                      // the "ice tile just cracked" sound
ldr r3, F_PLAY_SOUND
bl CALL_R3
mov r0, sp
mov r3, #0x0
ldsh r0, [r0, r3]
ldsh r1, [r4, r3]
ldrh r2, [r5, #0x8]
ldr r3, F_CHANGE_TILE
bl CALL_R3
mov r0, sp
mov r3, #0x0
ldsh r0, [r0, r3]
ldsh r1, [r4, r3]
ldr r3, F_REPAINT_TILE             // not entirely sure how it works, but it does update the specified tile's entries in graphical memory
bl CALL_R3
mov r0, #0x1
strh r0, [r5, #0x2]
b SUBR_RTRN

SUBR_TILE_DELAY:
sub r0, #0x1
strh r0, [r5, #0xC]
b SUBR_RTRN

CALL_R3:
bx r3
bx lr

.align 2
F_GET_COORDS:
.word 0x0805C539

F_GET_TILE:
.word 0x08058E49

F_PLAY_SOUND:
.word 0x080722CD

F_CHANGE_TILE:
.word 0x08058FA5

F_REPAINT_TILE:
.word 0x0805A8E9

EXECUTION_QUEUE:
.word 0x03005090

// Everything below here is a tile number in the major and minor tilesets
// You'd basically use the hex values that AMap shows you when you mouseover a given tile
DEFAULT_COLOR:
.word 0x000003F4

BLUE_CANVAS_TILE:
.word 0x000003EC

RED_CANVAS_TILE:
.word 0x000003ED

GREEN_CANVAS_TILE:
.word 0x000003F5

WHITE_CANVAS_TILE:
.word 0x000003F4

BLUE_SWITCH_TILE:
.word 0x000003E9

RED_SWITCH_TILE:
.word 0x000003EA

GREEN_SWITCH_TILE:
.word 0x000003EB

WHITE_SWITCH_TILE:
.word 0x000003F1


The upshot of all of this is that it is now very easy to make polished effects like a floor cracking underneath the player's feet, for example -- complete with sound effects and perhaps even other behaviors.

That alone could be used for things like unique Gym puzzles. Theoretically, that is just scratching the surface of this functionality's potential, however. Remember that it runs on every frame of animation in which the overworld is being shown and/or processed. In theory, you could do things like timing how long the player stands on a block, or tampering with the movement patterns of an NPC (this runs when you take a step, not when you finish moving, so problems waiting for movement should be few and far between).

And so this concludes my research on CmdA6.
__________________
Reply With Quote