add structs/macros for matching map data

This commit is contained in:
Alex Bates 2020-10-20 04:08:28 +01:00
parent dd72dfcd1f
commit 23f8d8ee35
No known key found for this signature in database
GPG Key ID: 5E11C2DB78877706
13 changed files with 380 additions and 212 deletions

View File

@ -5,6 +5,7 @@
#include "ultra64.h"
#include "types.h"
#include "si.h"
#include "enums.h"
struct ScriptInstance;
@ -27,6 +28,13 @@ typedef struct Vec3s {
/* 0x04 */ s16 z;
} Vec3s; // size = 0x06
typedef struct Vec4f {
/* 0x00 */ f32 x;
/* 0x04 */ f32 y;
/* 0x08 */ f32 z;
/* 0x0C */ f32 yaw;
} Vec4f; // size = 0x10
typedef struct Matrix4f {
/* 0x00 */ f32 mtx[4][4];
} Matrix4f; // size = 0x40
@ -106,7 +114,6 @@ typedef struct Npc {
/* 0x0AA */ u8 renderMode;
/* 0x0AB */ char unk_AB[661];
} Npc; // size = 0x340
typedef struct PlayerData {
/* 0x000 */ s8 bootsLevel;
/* 0x001 */ s8 hammerLevel;
@ -172,7 +179,6 @@ typedef struct PlayerData {
/* 0x33C */ s16 smashGameRecord;
/* 0x33E */ char unk_33E[2];
} PlayerData; // size = 0x340
typedef union {
struct {
/* 0x0 */ s16 genericFlagIndex;
@ -180,7 +186,6 @@ typedef union {
} bytes;
s32 flags;
} TriggerFlags;
typedef struct Trigger {
/* 0x00 */ TriggerFlags flags;
/* 0x04 */ s32 params1;
@ -195,68 +200,6 @@ typedef struct Trigger {
/* 0x31 */ char unk_31[3];
/* 0x34 */ s32 runningScriptID;
} Trigger; // size = 0x38
typedef struct Enemy {
/* 0x00 */ s32 flags;
/* 0x04 */ u8 encounterIndex;
/* 0x05 */ s8 encountered;
/* 0x06 */ u8 scriptGroup; /* scripts launched for this npc controller will be assigned this group */
/* 0x07 */ s8 unk_07;
/* 0x08 */ s16 npcID;
/* 0x0A */ s16 spawnPos[3];
/* 0x10 */ Vec3s unk_10;
/* 0x16 */ char unk_16[2];
/* 0x18 */ struct StaticNpcSettings* npcSettings;
/* 0x1C */ Bytecode* initBytecode;
/* 0x20 */ Bytecode* interactBytecode;
/* 0x24 */ Bytecode* aiBytecode;
/* 0x28 */ Bytecode* hitBytecode;
/* 0x2C */ Bytecode* auxBytecode;
/* 0x30 */ Bytecode* defeatBytecode;
/* 0x34 */ struct ScriptInstance* initScript;
/* 0x38 */ struct ScriptInstance* interactScript;
/* 0x3C */ struct ScriptInstance* aiScript;
/* 0x40 */ struct ScriptInstance* hitScript;
/* 0x44 */ struct ScriptInstance* auxScript;
/* 0x48 */ struct ScriptInstance* defeatScript;
/* 0x4C */ s32 initScriptID;
/* 0x50 */ s32 interactScriptID;
/* 0x54 */ s32 aiScriptID;
/* 0x58 */ s32 hitScriptID;
/* 0x5C */ s32 auxScriptID;
/* 0x60 */ s32 defeatScriptID;
/* 0x64 */ char unk_64[8];
/* 0x6C */ s32 varTable[16];
/* 0xAC */ char unk_AC[9];
/* 0xB5 */ s8 unk_B5;
/* 0xB6 */ char unk_B6[2];
/* 0xB8 */ s32 unkSettings24;
/* 0xBC */ char unk_BC[8];
/* 0xC4 */ s32 unk_C4;
/* 0xC8 */ s32 unk_C8;
/* 0xCC */ s32* animList;
/* 0xD0 */ UNK_PTR territoryData;
/* 0xD4 */ s16* dropTables;
/* 0xD8 */ u32 tattleString;
/* 0xDC */ char unk_DC[20];
} Enemy; // size = 0xF0
typedef struct StaticNpcSettings {
/* 0x00 */ char unk_00[4];
/* 0x04 */ s16 height;
/* 0x06 */ s16 radius;
/* 0x08 */ UNK_PTR otherAI;
/* 0x0C */ Bytecode* interactScript;
/* 0x10 */ Bytecode* aiScript;
/* 0x14 */ Bytecode* hitScript;
/* 0x18 */ Bytecode* auxScript;
/* 0x1C */ Bytecode* defeatScript;
/* 0x20 */ s32 flags;
/* 0x24 */ char unk_24[4];
/* 0x28 */ s16 level;
/* 0x2A */ s16 unkFlags;
} StaticNpcSettings; // size = 0x2C
typedef struct ScriptInstance {
/* 0x000 */ u8 state;
/* 0x001 */ u8 currentArgc;
@ -347,27 +290,6 @@ typedef struct MusicPlayer {
/* 0x18 */ char unk_18[24];
} MusicPlayer; // size = 0x30
typedef struct StaticNpc {
/* 0x000 */ s32 ID;
/* 0x004 */ struct StaticNpcSettings* npcSettings;
/* 0x008 */ s32 spawnPos[3];
/* 0x014 */ s32 flags;
/* 0x018 */ Bytecode* initScript;
/* 0x01C */ char unk_1C[8];
/* 0x024 */ s32 spawnYaw;
/* 0x028 */ s16 itemDrops[25];
/* 0x05A */ s16 heartDrops[32];
/* 0x09A */ s16 flowerDrops[32];
/* 0x0DA */ s16 minCoinBonus;
/* 0x0DC */ s16 maxCoinBonus;
/* 0x0DE */ char unk_DE[2];
/* 0x0E0 */ s32 movementData[48];
/* 0x1A0 */ s32 animations[16];
/* 0x1E0 */ char unk_1E0[8];
/* 0x1E8 */ UNK_PTR extraAnimations;
/* 0x1EC */ s32 tattle;
} StaticNpc; // size = 0x1F0
typedef struct MenuIcon {
/* 0x00 */ u32 flags;
/* 0x04 */ u32* readPos;
@ -438,7 +360,6 @@ typedef struct UiStatus {
/* 0x68 */ s32 iconIndex13;
/* 0x6C */ s8 unk_6C[4];
} UiStatus; // size = 0x70
typedef struct Collider {
/* 0x00 */ s32 flags;
/* 0x04 */ s16 nextSibling;
@ -1547,29 +1468,4 @@ typedef struct SaveData {
/* 0x1304 */ char unk_1304[0x7C];
} SaveData; // size = 0x1380
typedef struct MapHeader {
/* 0x00 */ char unk_00[0x10];
/* 0x10 */ Bytecode* mainScript;
/* 0x14 */ f32* entryList;
/* 0x18 */ s32 entryCount;
/* 0x1C */ char unk_1C[0x1C];
/* 0x38 */ s32 background; // 0x80200000 if there is one, 0 otherwise
/* 0x3C */ UNK_FUN_PTR(tattle); // or string id
} MapHeader; // size = 0x40
typedef struct NpcAISettings {
/* 0x00 */ f32 moveSpeed;
/* 0x04 */ s32 moveTime;
/* 0x08 */ s32 waitTime;
/* 0x0C */ f32 alertRadius;
/* 0x10 */ f32 unk_10;
/* 0x14 */ s32 unk_14;
/* 0x18 */ f32 chaseSpeed;
/* 0x1C */ s32 unk_1C; // chase turn step?
/* 0x20 */ s32 unk_20;
/* 0x24 */ f32 chaseRadius;
/* 0x28 */ f32 unk_28;
/* 0x2C */ s32 unk_2C; // bool
} NpcAISettings; // size = 0x30
#endif

View File

@ -554,7 +554,7 @@ typedef UNK_TYPE Cam;
#define Cam_TATTLE 0x00000002
#define Cam_CAM3 0x00000003
typedef UNK_TYPE ItemId;
typedef s16 ItemId;
#define ItemId_JUMP 0x00000001
#define ItemId_SPIN_JUMP 0x00000002
#define ItemId_TORNADO_JUMP 0x00000003

View File

@ -87,8 +87,6 @@ Npc* get_npc_unsafe(NpcId npcId);
Npc* resolve_npc(ScriptInstance* script, NpcId npcIdOrPtr);
void set_npc_yaw(Npc* npcPtr, f32 angle);
Enemy* get_enemy(NpcId npcId);
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by);
f32 dist3D(f32 ax, f32 ay, f32 az, f32 bx, f32 by, f32 bz);
void add_vec2D_polar(f32* x, f32* y, f32 r, f32 theta);

View File

@ -45,4 +45,7 @@
#define SQ(x) (x*x)
// Fixed-point short literal
#define F16(f) (s16)(f * 327.67f)
#endif

197
include/map.h Normal file
View File

@ -0,0 +1,197 @@
#ifndef _MAP_H_
#define _MAP_H_
#include "common_structs.h"
#include "enums.h"
#include "script_api/map.h"
// TODO: consider moving Npc here
#define ENTRY_COUNT(entryList) (sizeof(entryList) / sizeof(Vec4f))
typedef Vec4f EntryList[];
typedef struct MapHeader {
/* 0x00 */ char unk_00[0x10];
/* 0x10 */ Bytecode* main;
/* 0x14 */ EntryList* entryList;
/* 0x18 */ s32 entryCount;
/* 0x1C */ char unk_1C[0x1C];
/* 0x38 */ s32 background; // 0x80200000 if there is one, 0 otherwise
/* 0x3C */ UNK_FUN_PTR(tattle); // or string id
} MapHeader; // size = 0x40
typedef struct NpcAISettings {
/* 0x00 */ f32 moveSpeed;
/* 0x04 */ s32 moveTime;
/* 0x08 */ s32 waitTime;
/* 0x0C */ f32 alertRadius;
/* 0x10 */ f32 unk_10;
/* 0x14 */ s32 unk_14;
/* 0x18 */ f32 chaseSpeed;
/* 0x1C */ s32 unk_1C; // chase turn step?
/* 0x20 */ s32 unk_20;
/* 0x24 */ f32 chaseRadius;
/* 0x28 */ f32 unk_28;
/* 0x2C */ s32 unk_2C; // bool
} NpcAISettings; // size = 0x30
typedef struct StaticNpcSettings {
/* 0x00 */ char unk_00[4];
/* 0x04 */ s16 height;
/* 0x06 */ s16 radius;
/* 0x08 */ UNK_PTR otherAI;
/* 0x0C */ Bytecode* interactScript;
/* 0x10 */ Bytecode* aiScript;
/* 0x14 */ Bytecode* hitScript;
/* 0x18 */ Bytecode* auxScript;
/* 0x1C */ Bytecode* defeatScript;
/* 0x20 */ s32 flags;
/* 0x24 */ char unk_24[4];
/* 0x28 */ s16 level;
/* 0x2A */ s16 unk_2A;
} StaticNpcSettings; // size = 0x2C
typedef struct ItemDrop {
/* 0x00 */ ItemId item;
/* 0x02 */ s16 weight;
/* 0x04 */ s16 unk_08;
} ItemDrop; // size = 0x06
typedef struct StatDrop {
// NOTE: these %s are F16
/* 0x00 */ s16 hpCutoff; // % of max HP/FP
/* 0x02 */ s16 generalChance; // %
/* 0x04 */ s16 attempts;
/* 0x06 */ s16 chancePerAttempt; // %
} StatDrop; // size = 0x08
#define NO_DROPS { F16(100), F16(0), 0, F16(0) }
#define STANDARD_HEART_DROPS(attempts) { \
{ F16(20), F16(70), attempts, F16(50) }, \
{ F16(30), F16(60), attempts, F16(50) }, \
{ F16(50), F16(50), attempts, F16(40) }, \
{ F16(80), F16(40), attempts, F16(40) }, \
{ F16(100), F16(30), attempts, F16(30) }, \
}
#define GENEROUS_HEART_DROPS(attempts) { \
{ F16(20), F16(80), attempts, F16(50) } \
{ F16(30), F16(70), attempts, F16(50) } \
{ F16(50), F16(60), attempts, F16(40) } \
{ F16(80), F16(50), attempts, F16(40) } \
{ F16(100), F16(40), attempts, F16(30) }, \
}
#define GENEROUS_WHEN_LOW_HEART_DROPS(attempts) { \
{ F16(20), F16(80), attempts, F16(60) }, \
{ F16(30), F16(70), attempts, F16(50) }, \
{ F16(50), F16(60), attempts, F16(50) }, \
{ F16(80), F16(50), attempts, F16(40) }, \
{ F16(100), F16(30), attempts, F16(30) }, \
}
#define STANDARD_FLOWER_DROPS(attempts) { \
{ F16(20), F16(50), attempts, F16(40) }, \
{ F16(30), F16(40), attempts, F16(40) }, \
{ F16(50), F16(40), attempts, F16(40) }, \
{ F16(80), F16(40), attempts, F16(40) }, \
{ F16(100), F16(30), attempts, F16(40) }, \
}
#define GENEROUS_WHEN_LOW_FLOWER_DROPS(attempts) { \
{ F16(20), F16(70), attempts, F16(50) }, \
{ F16(30), F16(60), attempts, F16(50) }, \
{ F16(50), F16(50), attempts, F16(40) }, \
{ F16(80), F16(40), attempts, F16(40) }, \
{ F16(100), F16(30), attempts, F16(40) }, \
}
#define REDUCED_FLOWER_DROPS(attempts) { \
{ F16(20), F16(40), attempts, F16(40) }, \
{ F16(30), F16(40), attempts, F16(40) }, \
{ F16(50), F16(40), attempts, F16(40) }, \
{ F16(80), F16(40), attempts, F16(40) }, \
{ F16(100), F16(30), attempts, F16(40) }, \
}
#define ANIMATION(sprite, palette, anim) (sprite << 16) + (palette << 8) + anim
typedef struct StaticNPC {
/* 0x000 */ NpcId id;
/* 0x004 */ StaticNpcSettings* settings;
/* 0x008 */ Vec3f pos;
/* 0x014 */ s32 flags;
/* 0x018 */ Bytecode* init;
/* 0x01C */ char unk_1C[8];
/* 0x024 */ s32 yaw;
/* 0x028 */ s8 dropFlags;
/* 0x029 */ s8 itemDropChance; // %
/* 0x02A */ ItemDrop itemDrops[8];
/* 0x05A */ StatDrop heartDrops[8];
/* 0x09A */ StatDrop flowerDrops[8];
/* 0x0DA */ s16 minCoinBonus;
/* 0x0DC */ s16 maxCoinBonus;
/* 0x0DE */ char unk_DE[2];
/* 0x0E0 */ s32 movement[48];
/* 0x1A0 */ s32 animations[16];
/* 0x1E0 */ char unk_1E0[8];
/* 0x1E8 */ UNK_PTR extraAnimations;
/* 0x1EC */ s32 tattle;
} StaticNpc; // size = 0x1F0
typedef struct Enemy {
/* 0x00 */ s32 flags;
/* 0x04 */ u8 encounterIndex;
/* 0x05 */ s8 encountered;
/* 0x06 */ u8 scriptGroup; /* scripts launched for this npc controller will be assigned this group */
/* 0x07 */ s8 unk_07;
/* 0x08 */ s16 npcID;
/* 0x0A */ s16 spawnPos[3];
/* 0x10 */ Vec3s unk_10;
/* 0x16 */ char unk_16[2];
/* 0x18 */ struct StaticNpcSettings* npcSettings;
/* 0x1C */ Bytecode* initBytecode;
/* 0x20 */ Bytecode* interactBytecode;
/* 0x24 */ Bytecode* aiBytecode;
/* 0x28 */ Bytecode* hitBytecode;
/* 0x2C */ Bytecode* auxBytecode;
/* 0x30 */ Bytecode* defeatBytecode;
/* 0x34 */ struct ScriptInstance* initScript;
/* 0x38 */ struct ScriptInstance* interactScript;
/* 0x3C */ struct ScriptInstance* aiScript;
/* 0x40 */ struct ScriptInstance* hitScript;
/* 0x44 */ struct ScriptInstance* auxScript;
/* 0x48 */ struct ScriptInstance* defeatScript;
/* 0x4C */ s32 initScriptID;
/* 0x50 */ s32 interactScriptID;
/* 0x54 */ s32 aiScriptID;
/* 0x58 */ s32 hitScriptID;
/* 0x5C */ s32 auxScriptID;
/* 0x60 */ s32 defeatScriptID;
/* 0x64 */ char unk_64[8];
/* 0x6C */ s32 varTable[16];
/* 0xAC */ char unk_AC[9];
/* 0xB5 */ s8 unk_B5;
/* 0xB6 */ char unk_B6[2];
/* 0xB8 */ s32 unkSettings24;
/* 0xBC */ char unk_BC[8];
/* 0xC4 */ s32 unk_C4;
/* 0xC8 */ s32 unk_C8;
/* 0xCC */ s32* animList;
/* 0xD0 */ UNK_PTR territoryData;
/* 0xD4 */ s16* dropTables;
/* 0xD8 */ u32 tattleString;
/* 0xDC */ char unk_DC[20];
} Enemy; // size = 0xF0
typedef struct {
/* 0x00 */ s32 npcCount;
/* 0x04 */ StaticNpc* npcs;
/* 0x08 */ s32 battleID;
} NpcGroupList[]; // size = 0x0C
Enemy* get_enemy(NpcId npcId);
#endif

View File

@ -4,6 +4,8 @@
#include "common_structs.h"
#include "si.h"
typedef Bytecode Script[];
ApiStatus FadeBackgroundToBlack(ScriptInstance* script, s32 isInitialCall);
ApiStatus UnfadeBackgroundFromBlack(ScriptInstance* script, s32 isInitialCall);
ApiStatus GetCamLookAtObjVector(ScriptInstance* script, s32 isInitialCall);

View File

@ -43,8 +43,8 @@ typedef s32 ApiStatus;
#define SI_END_LOOP() SI_CMD(0x06)
#define SI_BREAK_LOOP() SI_CMD(0x07)
#define SI_WAIT_FRAMES(i) SI_CMD(0x08, 1, i)
#define SI_WAIT_SECS(i) SI_CMD(0x09, 1, i)
#define SI_WAIT_FRAMES(i) SI_CMD(0x08, i)
#define SI_WAIT_SECS(i) SI_CMD(0x09, i)
#define SI_IF_EQ(a, b) SI_CMD(0x0A, a, b)
#define SI_IF_NE(a, b) SI_CMD(0x0B, a, b)
@ -54,8 +54,8 @@ typedef s32 ApiStatus;
#define SI_IF_GE(a, b) SI_CMD(0x0F, a, b)
#define SI_IF_BITS_ON(a, b) SI_CMD(0x10, a, b)
#define SI_IF_BITS_OFF(a, b) SI_CMD(0x11, a, b)
#define SI_ELSE() SI_CMD(0x12, 0)
#define SI_END_IF() SI_CMD(0x13, 0)
#define SI_ELSE() SI_CMD(0x12)
#define SI_END_IF() SI_CMD(0x13)
#define SI_SWITCH(a) SI_CMD(0x14, a)
#define SI_SWITCH_CONST(a) SI_CMD(0x15, a) // Does not get_variable
@ -139,11 +139,11 @@ typedef s32 ApiStatus;
#define SI_END_CHILD_THREAD() SI_CMD(0x59)
#define GEN_EXIT_WALK_SCRIPT(name, walkDistance, exitIdx, map, entryIdx) \
Bytecode name[] = { \
Script name = { \
SI_GROUP(0x1B), \
SI_CALL(&UseExitHeading, walkDistance, exitIdx), \
SI_EXEC(&ExitWalk), \
SI_CALL(&GotoMap, map, entryIdx), \
SI_CALL(UseExitHeading, walkDistance, exitIdx), \
SI_EXEC(ExitWalk), \
SI_CALL(GotoMap, map, entryIdx), \
SI_WAIT_FRAMES(100), \
SI_RETURN(), \
SI_END(), \

View File

@ -1,4 +1,5 @@
#include "common.h"
#include "map.h"
void NOP_npc_callback(void) {
}

View File

@ -1,4 +1,5 @@
#include "common.h"
#include "map.h"
ApiStatus SetEncounterStatusFlags(ScriptInstance* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
@ -501,7 +502,7 @@ ApiStatus func_80045838(ScriptInstance* script, s32 isInitialCall) {
}
ApiStatus func_800458CC(ScriptInstance* script, s32 isInitialCall) {
set_variable(script, *script->ptrReadPos, script->ownerActorID->npcSettings->unkFlags & 8);
set_variable(script, *script->ptrReadPos, script->ownerActorID->npcSettings->unk_2A & 8);
return ApiStatus_DONE2;
}

View File

@ -1,35 +1,28 @@
#include "common.h"
#include "script_api/map.h"
#include "kmr_12.h"
Bytecode kmr_12_play_music[];
ApiStatus get_goomba_ref(ScriptInstance* script, s32 isInitialCall);
GEN_EXIT_WALK_SCRIPT(exit_west, 60, 0, 0x80240AB0 /*"kmr_07"*/, 1);
GEN_EXIT_WALK_SCRIPT(exit_east, 60, 1, 0x80240AB8 /*"kmr_11"*/, 0);
Bytecode make_entities[];
Bytecode read_sign[];
GEN_EXIT_WALK_SCRIPT(exit_west, 60, 0, "kmr_07", 1);
GEN_EXIT_WALK_SCRIPT(exit_east, 60, 1, "kmr_11", 0);
Bytecode bind_exits[] = {
SI_BIND(&exit_west, TriggerFlag_FLOOR_ABOVE, 0 /* deili1 */, NULL),
SI_BIND(&exit_east, TriggerFlag_FLOOR_ABOVE, 3 /* deili2 */, NULL),
Script bind_exits = {
SI_BIND(exit_west, TriggerFlag_FLOOR_ABOVE, 0 /* deili1 */, NULL),
SI_BIND(exit_east, TriggerFlag_FLOOR_ABOVE, 3 /* deili2 */, NULL),
SI_RETURN(),
SI_END(),
};
Bytecode kmr_12_main[] = {
Script kmr_12_main = {
SI_SET(SI_SAVE_VAR(425), 31),
SI_CALL(&SetSpriteShading, -1),
SI_CALL(&SetCamPerspective, 0, 3, 25, 16, 4096),
SI_CALL(&SetCamBGColor, 0, 0, 0, 0),
SI_CALL(&SetCamEnabled, 0, 1),
SI_CALL(&MakeNpcs, 0, 0x802409A8),
SI_EXEC_WAIT(&make_entities),
SI_EXEC(&kmr_12_play_music),
SI_CALL(SetSpriteShading, -1),
SI_CALL(SetCamPerspective, 0, 3, 25, 16, 4096),
SI_CALL(SetCamBGColor, 0, 0, 0, 0),
SI_CALL(SetCamEnabled, 0, 1),
SI_CALL(MakeNpcs, 0, npc_groups),
SI_EXEC_WAIT(make_entities),
SI_EXEC(kmr_12_play_music),
SI_SET(SI_VAR(0), bind_exits),
SI_EXEC(&EnterWalk),
SI_EXEC(EnterWalk),
SI_WAIT_FRAMES(1),
SI_BIND(read_sign, TriggerFlag_WALL_INTERACT, 10, NULL),
SI_BIND(read_west_sign, TriggerFlag_WALL_INTERACT, 10, NULL),
SI_RETURN(),
SI_END(),
};
@ -49,110 +42,180 @@ NpcAISettings goomba_ai_settings = {
TRUE
};
Bytecode goomba_ai[] = {
SI_CALL(&DoBasicAI, &goomba_ai_settings),
Script goomba_ai = {
SI_CALL(DoBasicAI, &goomba_ai_settings),
SI_RETURN(),
SI_END(),
};
StaticNpcSettings goomba_npc_settings = {
.radius = 20,
.height = 23,
.height = 20,
.radius = 23,
.aiScript = &goomba_ai,
.hitScript = (Bytecode*)0x80077F70,
.defeatScript = (Bytecode*)0x8007809C,
.level = 5,
};
Bytecode read_sign[] = { // *INDENT-OFF*
// *INDENT-OFF*
Script read_west_sign = {
SI_GROUP(0),
// "Eat a Mushroom to regain your energy!"
SI_SUSPEND_GROUP(1),
SI_CALL(&DisablePlayerInput, TRUE),
SI_CALL(&ShowMessageAtScreenPos, 0x1D0167, 160, 40),
SI_CALL(DisablePlayerInput, TRUE),
SI_CALL(ShowMessageAtScreenPos, 0x1D0167, 160, 40),
SI_RESUME_GROUP(1),
SI_SET(SI_FLAG(0), FALSE),
SI_CALL(&get_goomba_ref),
SI_CALL(get_goomba_ref),
SI_IF_NE(SI_VAR(0), FALSE),
SI_CALL(&GetNpcVar, 0, 0, SI_VAR(0)),
SI_CALL(GetNpcVar, NpcId_GOOMBA, 0, SI_VAR(0)),
SI_IF_EQ(SI_VAR(0), FALSE),
// Trigger Goomba to peel off
SI_CALL(&SetNpcVar, 0, 0, TRUE),
SI_CALL(SetNpcVar, NpcId_GOOMBA, 0, TRUE),
SI_SET(SI_FLAG(0), TRUE),
SI_WAIT_FRAMES(10),
SI_END_IF(),
SI_END_IF(),
SI_CALL(&DisablePlayerInput, FALSE),
SI_CALL(DisablePlayerInput, FALSE),
SI_IF_EQ(SI_FLAG(0), TRUE),
SI_UNBIND_ME(),
SI_END_IF(),
SI_END(),
SI_RETURN(), // Whoops!
}; // *INDENT-ON*
};
Bytecode goomba_idle[] = { // *INDENT-OFF*
Script goomba_idle = {
SI_WAIT_FRAMES(1),
SI_CALL(&SetSelfVar, 0, FALSE),
SI_CALL(&SetNpcAnimation, NpcId_SELF, 0x26000D),
SI_CALL(&EnableNpcShadow, NpcId_SELF, 0),
SI_CALL(&SetSelfEnemyFlagBits, 32, 1),
SI_CALL(SetSelfVar, 0, FALSE),
SI_CALL(SetNpcAnimation, NpcId_SELF, 0x26000D),
SI_CALL(EnableNpcShadow, NpcId_SELF, 0),
SI_CALL(SetSelfEnemyFlagBits, 32, 1),
// Wait until read_sign sets NPC var 0
SI_LABEL(0),
SI_CALL(&GetSelfVar, 0, SI_VAR(0)),
SI_CALL(GetSelfVar, 0, SI_VAR(0)),
SI_WAIT_FRAMES(1),
SI_IF_EQ(SI_VAR(0), TRUE),
SI_IF_EQ(SI_VAR(0), FALSE),
SI_GOTO(0),
SI_END_IF(),
// Peel and jump off the sign
SI_CALL(&SetNpcFlagBits, NpcId_SELF, 0x240000, 1),
SI_CALL(SetNpcFlagBits, NpcId_SELF, 0x240000, 1),
SI_WAIT_FRAMES(3),
SI_SET_F(SI_VAR(0), SI_FIXED(0.0f)),
SI_LOOP(9),
SI_ADD_F(SI_VAR(0), SI_FIXED(10.0f)),
SI_CALL(&SetNpcRotation, NpcId_SELF, 0, SI_VAR(0), 0),
SI_CALL(SetNpcRotation, NpcId_SELF, 0, SI_VAR(0), 0),
SI_WAIT_FRAMES(1),
SI_END_LOOP(),
SI_CALL(&SetNpcAnimation, NpcId_SELF, 0x260000),
SI_CALL(SetNpcAnimation, NpcId_SELF, 0x260000),
SI_LOOP(9),
SI_ADD_F(SI_VAR(0), SI_FIXED(10.0f)),
SI_CALL(&SetNpcRotation, NpcId_SELF, 0, SI_VAR(0), 0),
SI_CALL(SetNpcRotation, NpcId_SELF, 0, SI_VAR(0), 0),
SI_WAIT_FRAMES(1),
SI_END_LOOP(),
SI_CALL(&SetNpcAnimation, NpcId_SELF, 0x260007),
SI_CALL(SetNpcAnimation, NpcId_SELF, 0x260007),
SI_WAIT_FRAMES(20),
SI_CALL(&SetNpcAnimation, NpcId_SELF, 0x260001),
SI_CALL(&PlaySoundAtNpc, NpcId_SELF, 248, 0),
SI_CALL(&func_802CFE2C, NpcId_SELF, 8192),
SI_CALL(&func_802CFD30, NpcId_SELF, 5, 6, 1, 1, 0),
SI_CALL(SetNpcAnimation, NpcId_SELF, 0x260001),
SI_CALL(PlaySoundAtNpc, NpcId_SELF, 248, 0),
SI_CALL(func_802CFE2C, NpcId_SELF, 8192),
SI_CALL(func_802CFD30, NpcId_SELF, 5, 6, 1, 1, 0),
SI_WAIT_FRAMES(12),
SI_WAIT_FRAMES(5),
SI_CALL(&PlaySoundAtNpc, NpcId_SELF, 812, 0),
SI_CALL(&EnableNpcShadow, NpcId_SELF, 1),
SI_CALL(&SetNpcJumpscale, NpcId_SELF, SI_FIXED(0.6005859375f)),
SI_CALL(&NpcJump0, NpcId_SELF, 0xFFFFFFDD, 0, 30, 23),
SI_CALL(&func_802CFD30, NpcId_SELF, 0, 0, 0, 0, 0),
SI_CALL(&InterpNpcYaw, NpcId_SELF, 90, 0),
SI_CALL(&SetNpcFlagBits, NpcId_SELF, 0x240000, 0),
SI_CALL(&SetSelfEnemyFlagBits, 32, 0),
SI_CALL(&SetSelfEnemyFlagBits, 0x40000000, 1),
SI_CALL(PlaySoundAtNpc, NpcId_SELF, 812, 0),
SI_CALL(EnableNpcShadow, NpcId_SELF, 1),
SI_CALL(SetNpcJumpscale, NpcId_SELF, SI_FIXED(0.6005859375f)),
SI_CALL(NpcJump0, NpcId_SELF, 0xFFFFFFDD, 0, 30, 23),
SI_CALL(func_802CFD30, NpcId_SELF, 0, 0, 0, 0, 0),
SI_CALL(InterpNpcYaw, NpcId_SELF, 90, 0),
SI_CALL(SetNpcFlagBits, NpcId_SELF, 0x240000, 0),
SI_CALL(SetSelfEnemyFlagBits, 32, 0),
SI_CALL(SetSelfEnemyFlagBits, 0x40000000, 1),
// We're done jumping off; the player can read the sign again
SI_BIND(read_sign, TriggerFlag_WALL_INTERACT, 10, NULL),
SI_BIND(read_west_sign, TriggerFlag_WALL_INTERACT, 10, NULL),
// Behave like a normal enemy from now on
SI_CALL(&BindNpcAI, NpcId_SELF, &goomba_ai),
SI_CALL(BindNpcAI, NpcId_SELF, &goomba_ai),
SI_RETURN(),
SI_END(),
}; // *INDENT-ON*
Bytecode goomba_init[] = {
SI_CALL(&BindNpcIdle, NpcId_SELF, &goomba_idle),
SI_RETURN(),
SI_END(),
};
// *INDENT-ON*
Script goomba_init = {
SI_CALL(BindNpcIdle, NpcId_SELF, &goomba_idle),
SI_RETURN(),
SI_END(),
};
StaticNpc goomba_npc = {
.id = NpcId_GOOMBA,
.settings = &goomba_npc_settings,
.pos = { -33.0f, 30.0f, -25.0f },
.flags = 0x00000C00,
.init = goomba_init,
.yaw = 90,
.dropFlags = 0x80,
.itemDropChance = 5,
.itemDrops = { { ItemId_MUSHROOM, 10 } },
.heartDrops = GENEROUS_WHEN_LOW_HEART_DROPS(2),
.flowerDrops = GENEROUS_WHEN_LOW_FLOWER_DROPS(2),
.movement = { 0xFFFFFFDF, 0x0, 0x1E, 0x28, 0x14, 0xFFFF8001, 0x1, 0xC8, 0x0, 0x0, 0x190, 0x3C, 0x1, 0x1 },
.animations = {
ANIMATION(SpriteId_GOOMBA, 0, 1),
ANIMATION(SpriteId_GOOMBA, 0, 2),
ANIMATION(SpriteId_GOOMBA, 0, 3),
ANIMATION(SpriteId_GOOMBA, 0, 3),
ANIMATION(SpriteId_GOOMBA, 0, 1),
ANIMATION(SpriteId_GOOMBA, 0, 1),
ANIMATION(SpriteId_GOOMBA, 0, 5),
ANIMATION(SpriteId_GOOMBA, 0, 5),
ANIMATION(SpriteId_GOOMBA, 0, 3),
ANIMATION(SpriteId_GOOMBA, 0, 3),
ANIMATION(SpriteId_GOOMBA, 0, 3),
ANIMATION(SpriteId_GOOMBA, 0, 3),
ANIMATION(SpriteId_GOOMBA, 0, 3),
ANIMATION(SpriteId_GOOMBA, 0, 3),
ANIMATION(SpriteId_GOOMBA, 0, 3),
ANIMATION(SpriteId_GOOMBA, 0, 3),
},
};
NpcGroupList npc_groups = {
{ sizeof(goomba_npc) / sizeof(StaticNpc), &goomba_npc, 0x00010003 },
{ 0, 0, 0 },
};
// *INDENT-OFF*
Script read_east_sign = {
SI_CALL(0x800441F0, SI_VAR(0)),
SI_IF_EQ(SI_VAR(0), 1),
SI_RETURN(),
SI_END_IF(),
SI_GROUP(0),
// "Goomba King's Fortress Ahead"
SI_CALL(0x802D5830, 1),
SI_CALL(DisablePlayerInput, 1),
SI_CALL(ShowMessageAtScreenPos, 0x1D0168, 160, 40),
SI_CALL(DisablePlayerInput, 0),
SI_CALL(0x802D5830, 0),
SI_RETURN(),
SI_END(),
};
Script make_entities = {
SI_CALL(MakeEntity, 0x802EAFDC, 436, 0, -42, 0, 0x80000000),
SI_CALL(AssignScript, read_east_sign),
SI_RETURN(),
SI_END(),
};
// *INDENT-ON*

View File

@ -1,27 +1,25 @@
#include "common.h"
#include "script_api/map.h"
#include "kmr_12.h"
Bytecode kmr_12_main[];
f32 entryList[][4] = {
EntryList entryList = {
{ -126.0f, 0.0f, 12.0f, 90.0f }, // west, towards Red/Blue Goomba miniboss room
{ 471.0f, 0.0f, 12.0f, 270.0f }, // east, towards Goomba King's Fortress
};
MapHeader header = {
.mainScript = &kmr_12_main,
.main = kmr_12_main,
.entryList = entryList,
.entryCount = ENTRY_COUNT(entryList),
.background = 0x80200000,
.tattle = 0x00190040,
};
Bytecode kmr_12_play_music[] = {
SI_CALL(&SetMusicTrack, 0, Song_PLEASANT_PATH, 0, 8),
Script kmr_12_play_music = {
SI_CALL(SetMusicTrack, 0, Song_PLEASANT_PATH, 0, 8),
SI_RETURN(),
SI_END(),
};
ApiStatus get_goomba_ref(ScriptInstance* script, s32 isInitialCall) {
script->varTable[0] = get_enemy_safe(0);
script->varTable[0] = get_enemy_safe(NpcId_GOOMBA);
return ApiStatus_DONE2;
}

View File

@ -0,0 +1,12 @@
#include "common.h"
#include "map.h"
#define NpcId_GOOMBA 0
Script kmr_12_main;
Script kmr_12_play_music;
Script make_entities;
Script read_west_sign;
NpcGroupList npc_groups;
ApiStatus get_goomba_ref(ScriptInstance* script, s32 isInitialCall);

View File

@ -35,7 +35,7 @@ def star_rod_lib():
if kind == "api":
print(f"ApiStatus {name}(ScriptInstance* script, s32 isInitialCall);")
elif kind == "scr":
print(f"extern Bytecode {name}[];")
print(f"extern Script {name};")
"""
except:
pass
@ -43,14 +43,9 @@ def star_rod_lib():
return _star_rod_lib
def addr_ref(addr):
func_name = star_rod_lib().get(addr)
if func_name:
func_name = "&" + func_name
else:
func_name = f"0x{addr:08X}"
return func_name
return star_rod_lib().get(addr, f"0x{addr:08X}")
def disassemble(bytes, indent = 0):
def disassemble(bytes, indent = 0, script_name = "script"):
out = ""
prefix = ""
@ -121,10 +116,12 @@ def disassemble(bytes, indent = 0):
indent -= 1
if indent_used:
prefix_line("Bytecode script[] = { // *INDENT-OFF*")
write_line("}; // *INDENT-ON*")
prefix_line("// *INDENT-OFF*")
prefix_line(f"Script {script_name} = {{")
write_line("};")
write_line("// *INDENT-ON*")
else:
prefix_line("Bytecode script[] = {")
prefix_line(f"Script {script_name} = {{")
write_line("};")
return prefix + out