Skip to content

Instantly share code, notes, and snippets.

@jugeeya
Last active May 29, 2019 22:41
Show Gist options
  • Save jugeeya/c2dc27879bf2706d1c854da4f726eca4 to your computer and use it in GitHub Desktop.
Save jugeeya/c2dc27879bf2706d1c854da4f726eca4 to your computer and use it in GitHub Desktop.
ACMD code-mod-framework build system

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 #includes 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"));
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment