Hopefully this turns into a layer of a build system that occurs when the user types make
or some similar bash command that
triggers this build process before ultimately starting the Makefile process.
The idea is that firstly, we take input from the user. This is probably the most flexible part.
Somehow, we read in these ACMD scripts from the user, each associated with metadata including the category, kind, acmd type, and animation.
Example of input:
input_1:
category:
fighter
kind:
peach
animcmd_type:
game
animation:
catch
contents:
frame(1);
if (is_excute()) {
CATCH(ID=0, X=1, Y=2, Z=3)
}
wait(2);
if (is_excute()) {
GrabModule__clear_all();
}
input_2:
category:
fighter
kind:
fox
animcmd_type:
effect
animation:
attacklw4
contents:
frame(5);
if (is_excute()) {
EffectModule__req(0, 1, 2)
}
Given this data, we want to autogenerate a C++ header file (or header files, depending on how you think it would best be organized) that contains it all with the relevant information to the framework. The tranformation from the user's script contents to the C++ contents shown below in each function is handled currently by the Python script in generate_acmd/, or a port of this script to whatever language you decide to use if you want it to be a process internal to your system.
The #include
s are not extremely important as they may change depending on the structure of the framework (as we're still changing it a lot), so read
pay attention to everything else.
Example of autogenerated output:
// script_replacement.hpp
#include <switch.h>
#include <stdint.h>
#include "crc32.h"
#include "l2c_imports.hpp"
#include "acmd_wrapper.hpp"
#include "const_value_table.h"
using namespace lib;
using namespace app::sv_animcmd;
using namespace app::sv_module_access;
using namespace app::lua_bind;
u64 peach_game_catch(L2CAgent* l2c_agent, void* variadic) {
ACMD acmd(l2c_agent);
acmd.frame(1);
if (acmd.is_excute()) {
acmd.wrap(CATCH, { /*ID*/ L2CValue(0), /*X*/ L2CValue(1), /*Y*/ L2CValue(2), /*Z*/ L2CValue(3) });
}
acmd.wait(2);
if (acmd.is_excute()) {
GrabModule::clear_all(acmd.module_accessor);
}
return 0;
}
u64 fox_effect_attacklw4(L2CAgent* l2c_agent, void* variadic) {
ACMD acmd(l2c_agent);
acmd.frame(5);
if (acmd.is_excute()) {
EffectModule::req(acmd.module_accessor, 0, 1, 2);
}
return 0;
}
void replace_scripts(L2CAgent* l2c_agent, u8 category, int kind) {
if (category == BATTLE_OBJECT_CATEGORY_FIGHTER) {
if (kind == FIGHTER_KIND_PEACH) {
l2c_agent->sv_set_function_hash(&peach_game_catch, hash40("game_catch"));
}
if (kind == FIGHTER_KIND_FOX) {
l2c_agent->sv_set_function_hash(&fox_effect_attacklw4, hash40("effect_attacklw4"));
}
}
}