Export FEbuilderGBA patch to a Buildfile

Hi everybody, I’m here to ask some very important questions for the progress of my project (I use the Buildfile)
While transferring my work to a buildfile, I got stuck with a couple of problems, in practice I found myself unable to execute some commands during the creation of the events, due to the lack of some ASM codes, which are not present for the buildfile, but which instead are for FEbuilderGBA, or at least I think, and from some of my questions about discord, unfortunately I have not received any information about this, but rightly so, I was also advised to extract the patches of FEbuilderGBA, and put them in my Buildfile, and in the end this works, and coming to the actual problem, if some of these I managed to make work thanks to the help of the guys who helped me on Discord, others instead, trying and trying again I could not…I found myself particularly unable to get the codes that added new definitions and commands to the events to work, because, even if I entered the code, while building the event through the buildfile, I would not know how to define the command:

  1. EVENTSCRIPT_give_exp 20191015: this Febuilder code allows you to donate experience points to a unit via events, i managed to install it, but i don’t know how to define the appropriate event to make it work:

    #ifdef FE8

    #include “EAstdlib.event”
    #include “Extensions/Hack Installation.txt”

    ALIGN 4
    give_exp_Install:
    #incbin “give_exp.dmp” //HINT=ASM
    POIN event_proc_bin

    ALIGN 4
    event_proc_bin:
    //#incbin “event_fe8j.bin” //HINT=PROCS
    #incbin “event_fe8u.bin” //HINT=PROCS

    #else
    ERROR This version of Selection Quotes is for FE8!
    #endif

  2. EVENTSCRIPT_COND_GetStatus: The other code, on the other hand, allows you to change the status of a unit, or to assign it a status such as “Sleep” or “Silence” always trough events, Unfortunately, I was unable to install this, due to the madhouse inside the folder, and I am completely blocked

Now, from what I know, both of these events are going to modify the part of the RAM that handles the information of a unit, is there another way, or function in the buildfile that allows the modification trough game events?

  1. My third dilemma would be to use the escape command functions remade from 7743 for FEbuilderGBA, as far as I know, I need to install three FEbuilder patches: EscapeMenu, EVENTSCRIPT_COND_ESCAPEMAP and EVENTSCRIPT_SimpleEscape_20200305 in order to use these functions, thanks to the help of 7743 I managed to install the first patch correctly, but to be able to use it I need to install the other two as well, in particular the third, from here I don’t know how to install them and then how to define a new command for the event assembler to be used in my events

Now, I hope I’m not the only fool, trying to use the Buildfile along with some Builder patches that weren’t originally written for the Buildfile, you can export them and insert them in the buildfile, I managed some simpler things, I would like to do it with these too

I hope someone can help me, I am really blocked from continuing my project and I apologize for the bad English,

Let me preface this by saying that I am an febuilder user and I have a limited understanding of buildfiles. Take what I say with a grain of salt. I am trying to explain the concepts that I hardly understand, and there are probably better ways to do things.

Usually hacks will ORG to freespace. Only rarely they’ll be written inline, so most of the time when you see ORG to an address, it is just to hook a vanilla function to add their own stuff.
eg.

PUSH
ORG 0x1AACC // Hook in MapAddInRange 
callHack_r4(CalcFogDR)
POP

Then when all of that’s over, we install our hacks to freespace.

ALIGN 4
CalcFogDR:
#incbin "asm/CalcFogDR.dmp"
Hacky method 1

When I install this via febuilder, it spits out a .sym file for me, showing where each function has gone into my ROM.

CheckDangerRadius=$14C2814 //starting point
SetAllDangerRadius2=$14C28E8
CalcFogDR=$14C2A84
//etc.

For me, I just create an event that runs each asmc.

Or as EA, my event looks like this:
image

Now you could do the same thing with buildfiles by using fixed addresses. I am certain this isn’t how you’re supposed to, but this is a possible way.

If I ORG 94C2814 the address as where I wanted to install DangerRadius to, it should then place each function to a subsequent address based on the size of them. This should yield identical results to using febuilder’s “insert EA” function.

image

When doing this via febuilder it can generate a .sym file for you, giving you fixed addresses to use in your buildfile for each ASMC you want to call. Or running no$gba through febuilder also generates a .sym for you of the various functions I think.

Now this is definitely not a good way to do things if you’re using a buildfile, so I’m going to try and reference LoA now. In the prologue events, it has this:

BeginningScene:
ASMC SetDifficulty|1 // For now, force difficulty to Normal.

So indeed, he’s installed an ASMC somewhere called SetDifficulty. And if we look in ASM/SetDifficulty, we find this:

.thumb

.equ gChapterData, 0x0202BCF0

.global SetDifficulty
.type SetDifficulty, %function
SetDifficulty: @ Force difficulty to normal.
ldr r0, =gChapterData
ldrb r1, [ r0, #0x14 ] @ Contains difficulty.
mov r2, #0x40
bic r1, r2 @ Clear the difficulty bit.
strb r1, [ r0, #0x14 ]
bx lr

And of course the installer of it all, which includes the SetDifficulty command.
#include "SetDifficulty/SetDifficulty.lyn.event"

So that seems to be how you’d want to define your ASMCs I think.

Hacky installation method 2

After building your ROM, open with febuilder and install your patch. Now go to Advanced Menu -> Export with EA -> Export Undo Buffer.
image

It will export an EA file looking something like this:

//Patches AddEvent: Set Unit Status (PatchForm) AddEvent: Set Unit Status2020-11-23 10:57:10 AM
ORG $B88570
BYTE  $30 $B5 $84 $6B $20 $78 $0F $21 $08 $40 $01 $28 $05 $D0 $0B $28 $08 $D0 $0F $28 $03 $D0 $A0 $78 $05 $E0 $34 $48 $03 $E0 $34 $48 $00 $68 $03 $E0 $33 $48 $34 $4B $9E $46 $00 $F8 $00 $28 $5A $D0 $32 $4A $92 $68 $E3 $78 $00 $2B $1A $D0 $04 $2B $18 $D0 $0C $2B $16 $D0 $01 $2B $28 $D0 $05 $2B $2F $D0 $47 $2B $12 $DD $50 $2B $12 $D0 $51 $2B $12 $D0 $52 $2B $12 $D0 $53 $2B $12 $D0 $54 $2B $12 $D0 $55 $2B $12 $D0 $56 $2B $12 $D0 $57 $2B $12 $D0 $3A $E0 $C2 $50 $2F $E0 $C2 $54 $2D $E0 $1A $23 $26 $E0 $1A $23 $24 $E0 $1D $23 $22 $E0 $1D $23 $20 $E0 $30 $23 $1E $E0 $30 $23 $1C $E0 $31 $23 $1A $E0 $31 $23 $18 $E0 $05 $1C $10 $1C $18 $4B $9E $46 $00 $F8 $00 $28 $1F $D0 $28 $60 $14 $E0 $05 $1C $10 $1C $15 $4B $9E $46 $00 $F8 $00 $28 $16 $D0 $68 $60 $0B $E0 $C5 $5C $0F $21 $0D $40 $12 $01 $15 $43 $C5 $54 $04 $E0 $C5 $5C $F0 $21 $0D $40 $15 $43 $C5 $54 $0C $4B $9E $46 $00 $F8 $0C $4B $9E $46 $00 $F8 $0B $4B $9E $46 $00 $F8 $00 $20 $30 $BD $00 $00 $FF $FF $FF $FF $50 $4E $00 $03 $FE $FF $FF $FF $50 $BC $00 $08 $B8 $04 $00 $03 $30 $94 $01 $08 $44 $94 $01 $08 $F4 $A1 $01 $08 $A0 $71 $02 $08 $3C $9C $01 $08;
//Patches AddEvent: Get Unit Status (PatchForm) AddEvent: Get Unit Status2020-11-23 10:57:11 AM
ORG $B88694
BYTE  $10 $B5 $84 $6B $20 $78 $0F $21 $08 $40 $01 $28 $05 $D0 $0B $28 $08 $D0 $0F $28 $03 $D0 $A0 $78 $05 $E0 $28 $48 $03 $E0 $28 $48 $00 $68 $03 $E0 $27 $48 $28 $4B $9E $46 $00 $F8 $00 $28 $43 $D0 $E3 $78 $00 $2B $1A $D0 $04 $2B $18 $D0 $0C $2B $16 $D0 $01 $2B $28 $D0 $05 $2B $2B $D0 $47 $2B $12 $DD $50 $2B $12 $D0 $51 $2B $12 $D0 $52 $2B $12 $D0 $53 $2B $12 $D0 $54 $2B $12 $D0 $55 $2B $12 $D0 $56 $2B $12 $D0 $57 $2B $12 $D0 $25 $E0 $C0 $58 $21 $E0 $C0 $5C $1F $E0 $1A $23 $1A $E0 $1A $23 $18 $E0 $1D $23 $16 $E0 $1D $23 $14 $E0 $30 $23 $12 $E0 $30 $23 $10 $E0 $31 $23 $0E $E0 $31 $23 $0C $E0 $00 $68 $00 $28 $0E $D0 $00 $79 $0A $E0 $40 $68 $00 $28 $09 $D0 $00 $79 $05 $E0 $C0 $5C $00 $09 $02 $E0 $C0 $5C $0F $22 $10 $40 $05 $4A $10 $63 $10 $BD $00 $00 $FF $FF $FF $FF $50 $4E $00 $03 $FE $FF $FF $FF $50 $BC $00 $08 $B8 $04 $00 $03;

It will install the ASMC to a fixed address I believe which you could call just as febuilder does. This is rather poor form, but works. As long as you #include the generated EA file at the end of your buildfile, it should be identical to as if you built the rom and then made these edits via febuilder all in a row. (Please note that if you decide to no longer #include one of them, febuilder could write to the same FreeSpace the next time you do this. You could easily prevent this, but just be aware of it.)

In the long term I would heavily recommend against doing very much in this way with your buildfile. But as a temporary measure, it would function and allow you to focus your efforts on other aspects if you are feeling overwhelmed by this problem. If you always call the same event with your fixed address ASMC, then it is easy to change the ASMC of that one event to be the name for it instead at a later date.

Good luck with it all!

3 Likes

First of all, thank you again Vesly for helping me out, I have read both methods, and as a matter of principle I want things done well before moving on, also because to publish my damn project I am basically just missing this! and I have already postponed this problem for a while, so I decided to fix it once and for all, therefore, I will try to follow the first method, at this point I also thank Snakey1’s guiding spirit
Being a bit dumb, I will try to follow the procedure step by step, with your support if possible
Starting with the simplest case, assign experience to a unit:

#ifdef _FE8_

#include "EAstdlib.event"
#include "Extensions/Hack Installation.txt"


ALIGN 4
give_exp_Install:
#incbin "give_exp.dmp" //HINT=ASM
POIN event_proc_bin


ALIGN 4
event_proc_bin:
//#incbin "event_fe8j.bin" //HINT=PROCS
#incbin "event_fe8u.bin" //HINT=PROCS

#else
    ERROR This version of Selection Quotes is for FE8!
#endif

This is the installation code, from my research, I know it doesn’t rely on any Vanilla game code;
The first problem arises from here, in the example you gave me, it is only one function to be recalled, while for me there are two!
in the Snakey Buildfile example, I think it is better to take into consideration not so much the ASM code, but rather the installation method, and the function call, or at least I think

ALIGN 4

PUSH

ORG CURRENTOFFSET+$1;SetDifficulty:

POP

SHORT $4802 $7D01 $2240 $4391 $7501 $4770
BYTE $F0 $BC $2 $2

The code was installed using Lyn, already this basic worries me, because I have never used Lyn, and perhaps I wonder if to solve my problems I should not use this method, which seems to me very different from how I tried to install the patch, and how it does also FEbuilderGBA, I really don’t know, I could also be saying absurd bullshit, so I really say it with the greatest sincerity to correct me if I’m wrong to think about the solution

Assuming that everything works, I should in practice call the aforementioned function in the Buildfile, right?
with these:

ASMC: give_exp_Install|*unitsId*|*exp value* 

here it is, right now I don’t know if it will work, but the fact that FEbuilderGBA installs two different code in this case: give_exp_Install and event_proc_bin, which one should I call? or both? in what order?
I don’t know, maybe they are stupid questions or I am just wrong from the start?

If I’m not talking bullshit now, I remember 7743 recommend me to translating FEbuilderGBA’s EventScript into command for event assembler, taking the point of reference just the original FEbuilder file, in this case this here:

NAME=ユニットに経験値を与える 20191015 (イベント命令)
NAME.en=Add Event: Give the unit experience points 20191015
NAME.zh=事件指令为人物提供经验值 20191015 (Add Event)

TYPE=EA
TAG=#ENGINE

INFO=ユニットに任意の経験値を与えます。
INFO.en=Give arbitrary experience value to the unit.
INFO.zh=们给人物提供任意经验值。

//既に適応されたかどうか
PATCHED_IF:$FGREP4 give_exp.dmp=0x70 0xB5 0x05 0x1C

EA=give_exp_Install.event

EVENTSCRIPT:1.en=400DXXYY{$L1:give_exp.dmp}	Give the unit experience points[XX:UNIT:Unit][YY:DECIMAL:add exp]	{UNIT}
EVENTSCRIPT:2.en=410D00YY{$L1:give_exp.dmp}	Give experience value of SVAL1 Unit.[YY:DECIMAL:add exp](LOW)
EVENTSCRIPT:3.en=4B0D00YY{$L1:give_exp.dmp}	Give experience value to Unit of SVALB coordinates.[YY:DECIMAL:add exp](LOW)
EVENTSCRIPT:4.en=40050B00ZZZZWWWW4B0D00YY{$L1:give_exp.dmp}	coordinate[ZZ:MAPX:X][WW:MAPY:Y]Give the Unit of coordinates an experience value.[YY:DECIMAL:add exp]	{UNIT}
EVENTSCRIPT:5.en=4F0D00YY{$L1:give_exp.dmp}	Give experience value to the Unit currently being operated.[YY:DECIMAL:add exp]	{UNIT}

in particular these eventscripts which are the last lines of the block, i think they refer to other commands+something else, it could help me? Or am I going astray?

I found something interesting by looking in the Pikmin buildfile (JpHack):Pik’s ASMC event
I think he must transcribe some of FEbuilder’s EventScripts as he did and I believe it is also the way that 7743 had recommended me

After a while, I did it!
Prova

Basically I followed the logic that Pikmin used in JpHack to insert some FEbuilderGBA event codes, from here I was able to decipher the order of the Builder EventScripts meaning, in the case that I have examined, the code that allows to get experience points, the Builder code was the following:

EVENTSCRIPT:1.en=400DXXYY{$L1:give_exp.dmp}	Give the unit experience points[XX:UNIT:Unit][YY:DECIMAL:add exp]	{UNIT}

I redefined the command in Event Assembler like this:

#define GiveEXP(UNITID, EXP) “BYTE 0x40 0x0D UNITID EXP ; POIN give_exp_Install|1;”

so, in any event I just need to do this to:
GiveEXP(0x01,0x64)
and does what it does in the gif that posted

I hope that the buildfile masters can confirm the correctness of this reasoning:

40  -> 0x40
0D -> 0x0D
XX -> UNITID
YY -> EXP (value)
{$L1:give_exp.dmp} -> POIN give_exp_Install|1;
callable with: GiveEXP(UNITID, EXP) "..."

which forms the code I put above in full

Now, I’m happy with my little win, but I wonder, if I wanted to do the same reasoning but for the unit in use? what should i put, what should i go to change? finished with this first problem I will try to solve the other one as well

it looks like the convention is based on the vanilla commands, I think. For example, 212E0000 is the binary code for CheckActive, so 7743 made the patches related to that start with 212E0000 as well.

400D is the assembler function, so many things will use that.
Pikmin also has one that uses coordinates:
#define SilentGiveItem(xcoord,ycoord,itemid) "SVAL 0xB Coords(xcoord,ycoord); BYTE 0x4B 0x0D 0x0 itemid ; POIN SilentGiveItemASMC|1"

I think that if you use the vanilla getter of unit, it allows you to do FFFF active, FFFE sB coords, and FFFD s2 unit. But it seems that for set status, 7743 did not use that, instead making it a separate command for active, coords, and unit.

You might want to call it 4F0D for active unit. But I am not really sure.

If you do figure them all out, I would be curious to see them. Good luck. Sorry I cannot be more of a help.

2 Likes

Don’t worry Vesly, you have been of great help, you have given me a great track to be able to perform, as soon as I have time I want to see how to rewrite all the functions, as soon as I discover other things, I’ll be happy to show them!

1 Like

I did a couple of tests, and i think i managed to create all three commands in the exp patch, in format for the event assembler:


the related FEbuilder’s Event Script:

EVENTSCRIPT:5.en=4F0D00YY{$L1:give_exp.dmp}	Give experience value to the Unit currently being operated.[YY:DECIMAL:add exp]	{UNIT}
EVENTSCRIPT:4.en=40050B00ZZZZWWWW4B0D00YY{$L1:give_exp.dmp}	coordinate[ZZ:MAPX:X][WW:MAPY:Y]Give the Unit of coordinates an experience value.[YY:DECIMAL:add exp]	{UNIT}

rewritten through the logic used before:

#define GiveEXPcurrentUnit(EXP) "BYTE 0x4F 0x0D 0x00 EXP ; POIN give_exp_Install|1;"
#define GiveEXP(xcoord, ycoord, EXP) "SVAL 0xB Coords(xcoord,ycoord); BYTE 0x4B 0x0D 0x0 EXP ; POIN give_exp_Install|1"

As you can see, I just put getting coordinates like pikmin did in his code
I’m telling the truth, I’m not really sure, I think it’s a base game feature that allows you to do this? I don’t know, because this FEbuilder event script reads it twice, once like this, and another time in a different way … but both are equivalent in the end, the effect is always the same … it should be investigated, or hope that someone who has worked on this part knows the two differences … also because FEbuilder reads them in the same way
anyway I did a couple of tests and they work … apart from that there is a strange bug that for two seconds the sprite of the unit disappears … but I saw that it also does it in a clean ROM, modified directly by Builder, so I don’t think I’m the one who did something wrong

Moving on to the second problem, now I know that I can solve it in the same way, only that I have a bit of doubts about how to install everything since the unit status patch folder really includes a lot of different things…
I think I’ll have to do some blind tests, however the event scripts that I will have to rewrite are these:

|EVENTSCRIPT:1.en=40050200VVVVVVVV400DXXYY{$L1:set_status_param.dmp}|Set [XX:UNIT:Unit]'s [YY:RAM_UNIT_PARAM:Status] to [VV:RAM_UNIT_VALUE:NewValue]|{UNITPERSOLNAL}|
|EVENTSCRIPT:2.en=40050200VVVVVVVV410D00YY{$L1:set_status_param.dmp}|Set SVAL1 Unit's [YY:RAM_UNIT_PARAM:Status] to [VV:RAM_UNIT_VALUE:NewValue](LOW)|{UNITPERSOLNAL}|
|EVENTSCRIPT:3.en=40050200VVVVVVVV4B0D00YY{$L1:set_status_param.dmp}|Set SVALB unit's [YY:RAM_UNIT_PARAM:Status] to [VV:RAM_UNIT_VALUE:NewValue](LOW)|{UNITPERSOLNAL}|
|EVENTSCRIPT:4.en=40050200VVVVVVVV40050B00ZZZZWWWW4B0D00YY{$L1:set_status_param.dmp}|Set coordinate[ZZ:MAPX:X][WW:MAPY:Y] unit's [YY:RAM_UNIT_PARAM:Status] to [VV:RAM_UNIT_VALUE:NewValue]|{UNITPERSOLNAL}|
|EVENTSCRIPT:5.en=40050200VVVVVVVV4F0D00YY{$L1:set_status_param.dmp}|Current Unit's [YY:RAM_UNIT_PARAM:Status] to [VV:RAM_UNIT_VALUE:NewValue]|{UNITPERSOLNAL}|
|EVENTSCRIPT:6.en=400DXXYY{$L1:set_status_param.dmp}|Set [XX:UNIT:Unit]'s [YY:RAM_UNIT_PARAM:Status] to SVAL2(LOW)|{UNITPERSOLNAL}|
|EVENTSCRIPT:7.en=400DXXYY{$L1:get_status_param.dmp}40050200VVVVVVVV2006C202400DXXYY{$L1:set_status_param.dmp}|Add [XX:UNIT:Unit]'s [YY:RAM_UNIT_PARAM:Status] By [VV::Increase value]|{UNITPERSOLNAL}|
|EVENTSCRIPT:8.en=400DXXYY{$L1:get_status_param.dmp}40050200VVVVVVVV2106C202400DXXYY{$L1:set_status_param.dmp}|Sub [XX:UNIT:Unit]'s [YY:RAM_UNIT_PARAM:Status] By [VV::Decrease value]|{UNITPERSOLNAL}|
|EVENTSCRIPT:9.en=40050B00ZZZZWWWW4B0D00YY{$L1:get_status_param.dmp}40050200VVVVVVVV2006C2024B0D00YY{$L1:set_status_param.dmp}|Add coordinate[ZZ:MAPX:X][WW:MAPY:Y] unit's [YY:RAM_UNIT_PARAM:Status] By [VV::Increase value]|{UNITPERSOLNAL}|
|EVENTSCRIPT:A.en=40050B00ZZZZWWWW4B0D00YY{$L1:get_status_param.dmp}40050200VVVVVVVV2106C2024B0D00YY{$L1:set_status_param.dmp}|Sub coordinate[ZZ:MAPX:X][WW:MAPY:Y] unit's [YY:RAM_UNIT_PARAM:Status] By [VV::Decrease value]|{UNITPERSOLNAL}|
|EVENTSCRIPT:B.en=4F0D00YY{$L1:get_status_param.dmp}40050200VVVVVVVV2006C2024F0D00YY{$L1:set_status_param.dmp}|Add Current Unit's [YY:RAM_UNIT_PARAM:Status] By [VV::Increase value]|{UNITPERSOLNAL}|
|EVENTSCRIPT:C.en=4F0D00YY{$L1:get_status_param.dmp}40050200VVVVVVVV2106C2024F0D00YY{$L1:set_status_param.dmp}|Sub Current Unit's [YY:RAM_UNIT_PARAM:Status] By [VV::Decrease value]|{UNITPERSOLNAL}|

This will really take some time, this patch seems to be linked to others as well, Vesly ((anyone who reads and wants to help out, I mean “you” to be friendlier)
do you know how this patch is connected? is it also based on other patches? or does it enter all these commands by itself? my doubt comes from here because it is inside a bigger folder called “UNIT status” and it really includes many other things: