Telinc1
Weirdo Extraordinaire
- 168
- Posts
- 11
- Years
- Sofia, Bulgaria
- Seen Apr 3, 2020
Preamble
Script tiles are a really wonderful thing. They let you run scripts when the player steps on them, making them an indispensable tool for revealing your game's plot. They have one major downside, however: you have to use variables for them and that is not ideal for many cases. Say you want an event to happen once and then never happen again, e.g. Oak leading you to his lab in the beginning of FireRed. If you want to do something like that, you need to waste an entire variable of which you'll only be using two values (probably 0 and 1). Because they have a big capacity (16 bits), there's way fewer variables than there are flags. Wouldn't it be great if you could control script tiles with flags? Oh, hang on...
Prerequisites
You should know how to assemble a routine, insert it into freespace and make a pointer to it. Basic knowledge of binary is recommended. Software-wise, you need an ARM assembler (GAS) and a hex editor.
The routine
With this routine, you'll be able to use flags for script tiles without giving up support for variables.
Assemble and insert into aligned freespace:
After that, go to 0806DD9C (6DD9C in a hex editor) and type 00 48 00 47 FF FF FF 08, replacing FF FF FF 08 with the pointer to the routine + 1.
Using the routine
By default, script tiles will behave the same they did before. If you want a script tile to use a flag instead of a variable, you set the flag number's most significant bit (for the laymen, that means add 0x8000 to it) and put in the result as the variable number for the script tile. Set the variable value to 0 if you want the script to run if the flag is cleared. Set it to 1 if you want the script to run if the flag is set. Other values will make the script never run (probably, I haven't tested this scenario). That's all there is to it.
In case you're wondering, sacrificing the MSB of the variable field shouldn't affect anything, as the only safe variables (0x4000–0x40FF and 0x5000–0x51FF if you've added the variable extension routine) do not have it set, and neither do any of the safe flags (0x200–0x2FF and 0x900–0x18FF if you've added the flag extension routine), meaning that you can use all flags and variables for script tiles.
Edit: 0x8000–0x8016 is also a valid range of variables. I've never seen them used for script tiles before, seeing as they're just temporary (they hold things like LASTRESULT, PLAYERFACING, etc.). You shouldn't ever need them outside of scripts.
If this kills the game somehow, nag me about it. Credit highly appreciated, but not required.
Script tiles are a really wonderful thing. They let you run scripts when the player steps on them, making them an indispensable tool for revealing your game's plot. They have one major downside, however: you have to use variables for them and that is not ideal for many cases. Say you want an event to happen once and then never happen again, e.g. Oak leading you to his lab in the beginning of FireRed. If you want to do something like that, you need to waste an entire variable of which you'll only be using two values (probably 0 and 1). Because they have a big capacity (16 bits), there's way fewer variables than there are flags. Wouldn't it be great if you could control script tiles with flags? Oh, hang on...
Prerequisites
You should know how to assemble a routine, insert it into freespace and make a pointer to it. Basic knowledge of binary is recommended. Software-wise, you need an ARM assembler (GAS) and a hex editor.
The routine
With this routine, you'll be able to use flags for script tiles without giving up support for variables.
Assemble and insert into aligned freespace:
Code:
.text
.align 2
.thumb
.thumb_func
.global triggerflag
main:
ldrh r0, [r4, #0x6]
mov r1, #0x80
lsl r1, #0x8
tst r0, r1
bne flag
ldr r1, var_load
bl linker
lsl r0, #0x10
lsr r0, #0x10
b check
flag:
mvn r1, r1
and r0, r1
ldr r1, flag_load
bl linker
check:
ldrb r1, [r4, #0x8]
cmp r0, r1
bne skip
ldr r0, [r4, #0xC]
b execute
skip:
mov r0, #0x0
execute:
ldr r1, return
linker:
bx r1
.align 2
var_load: .word 0x0806E569
flag_load: .word 0x0806E6D1
return: .word 0x0806DDB9
After that, go to 0806DD9C (6DD9C in a hex editor) and type 00 48 00 47 FF FF FF 08, replacing FF FF FF 08 with the pointer to the routine + 1.
Using the routine
By default, script tiles will behave the same they did before. If you want a script tile to use a flag instead of a variable, you set the flag number's most significant bit (for the laymen, that means add 0x8000 to it) and put in the result as the variable number for the script tile. Set the variable value to 0 if you want the script to run if the flag is cleared. Set it to 1 if you want the script to run if the flag is set. Other values will make the script never run (probably, I haven't tested this scenario). That's all there is to it.
In case you're wondering, sacrificing the MSB of the variable field shouldn't affect anything, as the only safe variables (0x4000–0x40FF and 0x5000–0x51FF if you've added the variable extension routine) do not have it set, and neither do any of the safe flags (0x200–0x2FF and 0x900–0x18FF if you've added the flag extension routine), meaning that you can use all flags and variables for script tiles.
Edit: 0x8000–0x8016 is also a valid range of variables. I've never seen them used for script tiles before, seeing as they're just temporary (they hold things like LASTRESULT, PLAYERFACING, etc.). You shouldn't ever need them outside of scripts.
If this kills the game somehow, nag me about it. Credit highly appreciated, but not required.
Last edited: