Since deployed units aren’t stored in linear order (e.g. the “Other” Units are stored after “Enemy” Units though their deployment numbers are before (0x40’s, vs 0x80’s)). This is also the method the game uses to get the nth deployed character.
FE7 - 0x08B92EB0
FE8 - 0x0859A5D0
The nth pointer is a pointer to the nth deployed unit. Note that since the deployment table is 1-aligned, the 0th pointer is 0x00000000. So instead, keep a loop counter and load the nth pointer.
loop through
(0x00-0x3F) for players
(0x40-0x7F) for other
(0x80-0xBF) for enemies
(0xC0-0xC5) for 4th-player.
Also, I think the slots in game are 0x48-aligned, so it should be safe to just loop through the strict ram location.
But this is still the technically safer and/or better way, so just advocating it!
Well, I mean that the enemy faction will be hit if you keep looping through 0x48 increments from the player units. But it seems a bit more fickle/easy to break. So yeah, I’d go with this method.
I stopped the 00 termination because dead characters get their character pointer wipes, so if a character in the middle of your data dies, . . . Your loop is broken.
It’s more secure to loop through a constant 0x3F slots.
Copy-paste code for looking through deployed units for one with character ID given in r0.
.thumb
.org 0x0
push {r4, r14}
mov r0, #0xFF @Character to look for
ldr r1, Unit_Pointers
mov r4, #0x0
look_for_unit__asdfgh: @Name mangling for copy-pasta-bility
lsl r2, r4, #0x2
ldr r3, [r1, r2]
cmp r3, #0x0 @Is the slot valid?
beq loop__asdfgh @Nope
ldr r2, [r3] @is there a character here?
cmp r2, #0x0
beq loop__asdfgh @Nope
ldrb r2, [r2, #0x4] @Character number
cmp r0, r2 @Is it the character we are looking for?
beq Perform_Action__asdfgh
loop__asdfgh:
add r4, #0x1
cmp r4, #0x3F @Have we checked 0x3F units?
bgt end @The unit we were looking for is not deployed.
b look_for_unit__asdfgh
Perform_Action__asdfgh:
mov r0, r3
@r0 = &Unit with the id of initial r0.
end:
@things might have to be done here, such as making it return false or something like that.
pop {r4}
pop {r1}
bx r1
.align
Unit_Pointers:
.long 0x08B92EB0
Edit: Something I use for assembly conditionals more is something like:
returnFalse:
mov r0, #0x0
end:
pop {r4}
pop {r1}
bx r1
and instead of the branch to end in the 0x3F player unit check, I’d branch to returnFalse.
I always just looped through the WRAM and ignored NULL characters while still iterating the full 0x3E times (I think it’s actually 0x3E)
I mean, those references you’re talking about are in the ROM. You are basically just calculating them on the fly without any sacrifice to speed or memory usage. They certainly aren’t going to change
but then you have the same situation where you already know where
what
is this for looping through the entire cast of units regardless of allegiance with a single loop? I guess that would be a good reason to bother with the pointers but then like
why would you be doing that to begin with
I would sooner have my 3 loops (read: 3 loops of one loop) and allow for some customization based on allegiance (odds are I would want it)
yeah too late
your choices are do what I say or replace FEditor from scratch
There are also pointers for that. Also, this way you don’t need to keep around a 0x48 for adding to. Also, robustness. And readability (just comment @gets the nth deployed unit).