forked from pret/pokeemerald
-
Notifications
You must be signed in to change notification settings - Fork 0
callnativevar
tustin2121 edited this page Aug 26, 2022
·
1 revision
https://discord.com/channels/442462691542695948/442465020291317760/981321994383548456
6:23 PM] MGriffin: Dropping this here in case anybody is as mad as me, extending specialvar to take up to four u16 arguments that are resolved as variables and passed through to the underlying function:
--- a/asm/macros/event.inc
+++ b/asm/macros/event.inc
- .macro specialvar output:req, function:req
+ .macro specialvar output:req, function:req, inputs:vararg
.byte 0x26
.2byte \output
.2byte SPECIAL_\function
+ _byte_count \inputs
+ .2byte \inputs
+ .endm
+
+ .macro _byte_count args:vararg
+ .ifb \args
+ .byte 0
+ .else
+ __byte_count 1, \args
+ .endif
+ .endm
+
+ .macro __byte_count n:req, _:req, args:vararg
+ .ifb \args
+ .byte \n
+ .else
+ __byte_count \n+1, \args
+ .endif
.endm
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
bool8 ScrCmd_specialvar(struct ScriptContext *ctx)
{
u16 *var = GetVarPointer(ScriptReadHalfword(ctx));
-
- *var = gSpecials[ScriptReadHalfword(ctx)]();
+ u16 (*special)(u16, u16, u16, u16) = (void *)gSpecials[ScriptReadHalfword(ctx)];
+ u8 count = ScriptReadByte(ctx);
+ u16 arg0, arg1, arg2, arg3;
+ if (count >= 1) arg0 = VarGet(ScriptReadHalfword(ctx));
+ if (count >= 2) arg1 = VarGet(ScriptReadHalfword(ctx));
+ if (count >= 3) arg2 = VarGet(ScriptReadHalfword(ctx));
+ if (count >= 4) arg3 = VarGet(ScriptReadHalfword(ctx));
+ *var = special(arg0, arg1, arg2, arg3);
return FALSE;
}Used like so:
--- a/data/specials.inc
+++ b/data/specials.inc
@@ -239,3 +239,4 @@ gSpecials:: @ 81DBA64
+ def_special AddVars
--- a/src/field_specials.c
+++ b/src/field_specials.c
+u16 AddVars(u16 a, u16 b)
+{
+ return a + b;
+}
--- a/data/maps/???/scripts.inc
+++ b/data/maps/???/scripts.inc
+ specialvar VAR_RESULT, AddVars, VAR_0x8000, VAR_0x8001(Not that I think AddVars is a very sensible example)
Very confusing results if your argument counts are mismatched.