mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
844 lines
32 KiB
C
844 lines
32 KiB
C
#include "smlua.h"
|
|
#include "smlua_cobject.h"
|
|
|
|
#include "game/level_update.h"
|
|
#include "game/area.h"
|
|
#include "game/mario.h"
|
|
#include "game/mario_step.h"
|
|
#include "game/mario_actions_stationary.h"
|
|
#include "audio/external.h"
|
|
#include "object_fields.h"
|
|
#include "engine/math_util.h"
|
|
#include "engine/level_script.h"
|
|
#include "pc/djui/djui_hud_utils.h"
|
|
#include "include/level_misc_macros.h"
|
|
#include "include/macro_presets.h"
|
|
#include "utils/smlua_anim_utils.h"
|
|
|
|
bool smlua_functions_valid_param_count(lua_State* L, int expected) {
|
|
int top = lua_gettop(L);
|
|
if (top != expected) {
|
|
LOG_LUA_LINE("Improper param count: Expected %u, Received %u", expected, top);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool smlua_functions_valid_param_range(lua_State* L, int min, int max) {
|
|
int top = lua_gettop(L);
|
|
if (top < min || top > max) {
|
|
LOG_LUA_LINE("Improper param count: Expected (%u - %u), Received %u", min, max, top);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//////////
|
|
// misc //
|
|
//////////
|
|
|
|
int smlua_func_sins(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
|
|
|
s16 x = smlua_to_number(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
|
|
lua_pushnumber(L, sins(x));
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_coss(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
|
|
|
s16 x = smlua_to_number(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
|
|
lua_pushnumber(L, coss(x));
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_atan2s(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
|
|
|
f32 y = smlua_to_number(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
f32 x = smlua_to_number(L, 2);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
|
|
|
lua_pushinteger(L, atan2s(y, x));
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_init_mario_after_warp(lua_State* L) {
|
|
if (network_player_connected_count() >= 2) {
|
|
LOG_LUA_LINE("This function can only be used in single-player");
|
|
return 0;
|
|
}
|
|
|
|
if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
|
|
|
|
extern void init_mario_after_warp(void);
|
|
init_mario_after_warp();
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_initiate_warp(lua_State* L) {
|
|
if(!smlua_functions_valid_param_count(L, 4)) { return 0; }
|
|
|
|
s16 destLevel = smlua_to_number(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
s16 destArea = smlua_to_number(L, 2);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
|
s16 destWarpNode = smlua_to_number(L, 3);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
|
s32 arg3 = smlua_to_number(L, 4);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; }
|
|
|
|
extern void initiate_warp(s16 destLevel, s16 destArea, s16 destWarpNode, s32 arg3);
|
|
initiate_warp(destLevel, destArea, destWarpNode, arg3);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_reset_level(lua_State* L) {
|
|
if (network_player_connected_count() >= 2) {
|
|
LOG_LUA_LINE("This function can only be used in single-player");
|
|
return 0;
|
|
}
|
|
|
|
if(!smlua_functions_valid_param_count(L, 0)) { return 0; }
|
|
|
|
gChangeLevel = gCurrLevelNum;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_network_init_object(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 3)) { return 0; }
|
|
|
|
struct Object* obj = smlua_to_cobject(L, 1, LOT_OBJECT);
|
|
if (!gSmLuaConvertSuccess || obj == NULL) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
|
|
bool standardSync = smlua_to_boolean(L, 2);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
|
|
|
if (lua_type(L, 3) != LUA_TNIL && lua_type(L, 3) != LUA_TTABLE) {
|
|
LOG_LUA_LINE("network_init_object() called with an invalid type for param 3: %u", lua_type(L, 3));
|
|
return 0;
|
|
}
|
|
|
|
struct SyncObject* so = sync_object_init(obj, standardSync ? 4000.0f : SYNC_DISTANCE_ONLY_EVENTS);
|
|
if (so == NULL) {
|
|
LOG_LUA_LINE("Failed to allocate sync object.");
|
|
return 0;
|
|
}
|
|
|
|
if (lua_type(L, 3) == LUA_TTABLE) {
|
|
lua_pushnil(L); // first key
|
|
|
|
while (lua_next(L, 3) != 0) {
|
|
// uses 'key' (at index -2) and 'value' (at index -1)
|
|
if (lua_type(L, -1) != LUA_TSTRING) {
|
|
LOG_LUA_LINE("Invalid type passed to network_init_object(): %u", lua_type(L, -1));
|
|
lua_pop(L, 1); // pop value
|
|
continue;
|
|
}
|
|
const char* fieldIdentifier = smlua_to_string(L, -1);
|
|
if (!gSmLuaConvertSuccess) {
|
|
LOG_LUA_LINE("Invalid field passed to network_init_object()");
|
|
lua_pop(L, 1); // pop value
|
|
continue;
|
|
}
|
|
|
|
struct LuaObjectField* data = smlua_get_object_field(LOT_OBJECT, fieldIdentifier);
|
|
if (data == NULL) {
|
|
data = smlua_get_custom_field(L, LOT_OBJECT, lua_gettop(L));
|
|
}
|
|
|
|
u8 lvtSize = 0;
|
|
if ((data->valueType == LVT_U32) || (data->valueType == LVT_S32) || (data->valueType == LVT_F32)) { lvtSize = 32; }
|
|
if ((data->valueType == LVT_U16) || (data->valueType == LVT_S16)) { lvtSize = 16; }
|
|
if ((data->valueType == LVT_U8) || (data->valueType == LVT_S8)) { lvtSize = 8; }
|
|
|
|
if (data == NULL || lvtSize == 0) {
|
|
LOG_LUA_LINE("Invalid field passed to network_init_object(): %s", fieldIdentifier);
|
|
lua_pop(L, 1); // pop value
|
|
continue;
|
|
}
|
|
|
|
u8* field = ((u8*)(intptr_t)obj) + data->valueOffset;
|
|
sync_object_init_field_with_size(obj, field, lvtSize);
|
|
|
|
lua_pop(L, 1); // pop value
|
|
}
|
|
lua_pop(L, 1); // pop key
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_network_send_object(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
|
|
|
struct Object* obj = smlua_to_cobject(L, 1, LOT_OBJECT);
|
|
if (!gSmLuaConvertSuccess || obj == NULL) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
|
|
bool reliable = smlua_to_boolean(L, 2);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
|
|
|
struct SyncObject* so = sync_object_get(obj->oSyncID);
|
|
if (!so || so->o != obj) {
|
|
LOG_LUA_LINE("Failed to retrieve sync object.");
|
|
return 0;
|
|
}
|
|
|
|
network_send_object_reliability(obj, reliable);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_network_send(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
|
network_send_lua_custom(true);
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_network_send_to(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 3)) { return 0; }
|
|
network_send_lua_custom(false);
|
|
return 1;
|
|
}
|
|
|
|
//////////////
|
|
// Textures //
|
|
//////////////
|
|
|
|
int smlua_func_get_texture_info(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
|
|
|
if (lua_type(L, -1) != LUA_TSTRING) {
|
|
LOG_LUA_LINE("Invalid type passed to get_texture_info(): %u", lua_type(L, -1));
|
|
lua_pop(L, 1); // pop value
|
|
return 0;
|
|
}
|
|
|
|
struct TextureInfo texInfo = { 0 };
|
|
const char* textureName = smlua_to_string(L, -1);
|
|
if (!dynos_texture_get(textureName, &texInfo)) {
|
|
LOG_LUA_LINE("Could not find texture info for '%s'", textureName);
|
|
return 0;
|
|
}
|
|
|
|
lua_newtable(L);
|
|
|
|
lua_pushstring(L, "texture");
|
|
smlua_push_pointer(L, LVT_U8_P, texInfo.texture);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "bitSize");
|
|
lua_pushinteger(L, texInfo.bitSize);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "width");
|
|
lua_pushinteger(L, texInfo.width);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "height");
|
|
lua_pushinteger(L, texInfo.height);
|
|
lua_settable(L, -3);
|
|
|
|
lua_pushstring(L, "name");
|
|
lua_pushstring(L, texInfo.name);
|
|
lua_settable(L, -3);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_djui_hud_render_texture(lua_State* L) {
|
|
if(!smlua_functions_valid_param_count(L, 5)) { return 0; }
|
|
|
|
struct TextureInfo tmpTexInfo = { 0 };
|
|
struct TextureInfo* texInfo = &tmpTexInfo;
|
|
|
|
if (smlua_is_cobject(L, 1, LOT_TEXTUREINFO)) {
|
|
texInfo = (struct TextureInfo*)smlua_to_cobject(L, 1, LOT_TEXTUREINFO);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
} else {
|
|
int top = lua_gettop(L);
|
|
lua_pushvalue(L, 1);
|
|
|
|
lua_pushstring(L, "texture");
|
|
lua_gettable(L, top+1);
|
|
tmpTexInfo.texture = smlua_to_cpointer(L, lua_gettop(L), LVT_U8_P);
|
|
lua_pop(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'texture' field"); return 0; }
|
|
|
|
tmpTexInfo.bitSize = smlua_get_integer_field(top+1, "bitSize");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'bitSize' field"); return 0; }
|
|
|
|
tmpTexInfo.width = smlua_get_integer_field(top+1, "width");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'width' field"); return 0; }
|
|
|
|
tmpTexInfo.height = smlua_get_integer_field(top+1, "height");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'height' field"); return 0; }
|
|
|
|
tmpTexInfo.name = smlua_get_string_field(top+1, "name");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'name' field"); return 0; }
|
|
|
|
lua_settop(L, top);
|
|
}
|
|
|
|
f32 x = smlua_to_number(L, 2);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
|
f32 y = smlua_to_number(L, 3);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
|
f32 scaleW = smlua_to_number(L, 4);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; }
|
|
f32 scaleH = smlua_to_number(L, 5);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 5"); return 0; }
|
|
|
|
djui_hud_render_texture_raw(texInfo->texture, texInfo->bitSize, texInfo->width, texInfo->height, x, y, scaleW, scaleH);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_djui_hud_render_texture_tile(lua_State* L) {
|
|
if(!smlua_functions_valid_param_count(L, 9)) { return 0; }
|
|
|
|
struct TextureInfo tmpTexInfo = { 0 };
|
|
struct TextureInfo* texInfo = &tmpTexInfo;
|
|
|
|
if (smlua_is_cobject(L, 1, LOT_TEXTUREINFO)) {
|
|
texInfo = (struct TextureInfo*)smlua_to_cobject(L, 1, LOT_TEXTUREINFO);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
} else {
|
|
int top = lua_gettop(L);
|
|
lua_pushvalue(L, 1);
|
|
|
|
lua_pushstring(L, "texture");
|
|
lua_gettable(L, top+1);
|
|
tmpTexInfo.texture = smlua_to_cpointer(L, lua_gettop(L), LVT_U8_P);
|
|
lua_pop(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'texture' field"); return 0; }
|
|
|
|
tmpTexInfo.bitSize = smlua_get_integer_field(top+1, "bitSize");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'bitSize' field"); return 0; }
|
|
|
|
tmpTexInfo.width = smlua_get_integer_field(top+1, "width");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'width' field"); return 0; }
|
|
|
|
tmpTexInfo.height = smlua_get_integer_field(top+1, "height");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'height' field"); return 0; }
|
|
|
|
tmpTexInfo.name = smlua_get_string_field(top+1, "name");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'name' field"); return 0; }
|
|
|
|
lua_settop(L, top);
|
|
}
|
|
|
|
f32 x = smlua_to_number(L, 2);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
|
f32 y = smlua_to_number(L, 3);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
|
f32 scaleW = smlua_to_number(L, 4);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; }
|
|
f32 scaleH = smlua_to_number(L, 5);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 5"); return 0; }
|
|
f32 tileX = smlua_to_number(L, 6);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 6"); return 0; }
|
|
f32 tileY = smlua_to_number(L, 7);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 7"); return 0; }
|
|
f32 tileW = smlua_to_number(L, 8);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 8"); return 0; }
|
|
f32 tileH = smlua_to_number(L, 9);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 9"); return 0; }
|
|
|
|
djui_hud_render_texture_tile_raw(texInfo->texture, texInfo->bitSize, texInfo->width, texInfo->height, x, y, scaleW, scaleH, tileX, tileY, tileW, tileH);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_djui_hud_render_texture_interpolated(lua_State* L) {
|
|
if(!smlua_functions_valid_param_count(L, 9)) { return 0; }
|
|
|
|
struct TextureInfo tmpTexInfo = { 0 };
|
|
struct TextureInfo* texInfo = &tmpTexInfo;
|
|
|
|
if (smlua_is_cobject(L, 1, LOT_TEXTUREINFO)) {
|
|
texInfo = (struct TextureInfo*)smlua_to_cobject(L, 1, LOT_TEXTUREINFO);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
} else {
|
|
int top = lua_gettop(L);
|
|
lua_pushvalue(L, 1);
|
|
|
|
lua_pushstring(L, "texture");
|
|
lua_gettable(L, top+1);
|
|
tmpTexInfo.texture = smlua_to_cpointer(L, lua_gettop(L), LVT_U8_P);
|
|
lua_pop(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'texture' field"); return 0; }
|
|
|
|
tmpTexInfo.bitSize = smlua_get_integer_field(top+1, "bitSize");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'bitSize' field"); return 0; }
|
|
|
|
tmpTexInfo.width = smlua_get_integer_field(top+1, "width");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'width' field"); return 0; }
|
|
|
|
tmpTexInfo.height = smlua_get_integer_field(top+1, "height");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'height' field"); return 0; }
|
|
|
|
tmpTexInfo.name = smlua_get_string_field(top+1, "name");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'name' field"); return 0; }
|
|
|
|
lua_settop(L, top);
|
|
}
|
|
|
|
f32 prevX = smlua_to_number(L, 2);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
|
f32 prevY = smlua_to_number(L, 3);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
|
f32 prevScaleW = smlua_to_number(L, 4);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; }
|
|
f32 prevScaleH = smlua_to_number(L, 5);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 5"); return 0; }
|
|
f32 x = smlua_to_number(L, 6);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 6"); return 0; }
|
|
f32 y = smlua_to_number(L, 7);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 7"); return 0; }
|
|
f32 scaleW = smlua_to_number(L, 8);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 8"); return 0; }
|
|
f32 scaleH = smlua_to_number(L, 9);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 9"); return 0; }
|
|
|
|
djui_hud_render_texture_interpolated(texInfo, prevX, prevY, prevScaleW, prevScaleH, x, y, scaleW, scaleH);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_djui_hud_render_texture_tile_interpolated(lua_State* L) {
|
|
if(!smlua_functions_valid_param_count(L, 13)) { return 0; }
|
|
|
|
struct TextureInfo tmpTexInfo = { 0 };
|
|
struct TextureInfo* texInfo = &tmpTexInfo;
|
|
|
|
if (smlua_is_cobject(L, 1, LOT_TEXTUREINFO)) {
|
|
texInfo = (struct TextureInfo*)smlua_to_cobject(L, 1, LOT_TEXTUREINFO);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
} else {
|
|
int top = lua_gettop(L);
|
|
lua_pushvalue(L, 1);
|
|
|
|
lua_pushstring(L, "texture");
|
|
lua_gettable(L, top+1);
|
|
tmpTexInfo.texture = smlua_to_cpointer(L, lua_gettop(L), LVT_U8_P);
|
|
lua_pop(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'texture' field"); return 0; }
|
|
|
|
tmpTexInfo.bitSize = smlua_get_integer_field(top+1, "bitSize");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'bitSize' field"); return 0; }
|
|
|
|
tmpTexInfo.width = smlua_get_integer_field(top+1, "width");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'width' field"); return 0; }
|
|
|
|
tmpTexInfo.height = smlua_get_integer_field(top+1, "height");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'height' field"); return 0; }
|
|
|
|
tmpTexInfo.name = smlua_get_string_field(top+1, "name");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'name' field"); return 0; }
|
|
|
|
lua_settop(L, top);
|
|
}
|
|
|
|
f32 prevX = smlua_to_number(L, 2);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
|
f32 prevY = smlua_to_number(L, 3);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; }
|
|
f32 prevScaleW = smlua_to_number(L, 4);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; }
|
|
f32 prevScaleH = smlua_to_number(L, 5);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 5"); return 0; }
|
|
f32 x = smlua_to_number(L, 6);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 6"); return 0; }
|
|
f32 y = smlua_to_number(L, 7);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 7"); return 0; }
|
|
f32 scaleW = smlua_to_number(L, 8);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 8"); return 0; }
|
|
f32 scaleH = smlua_to_number(L, 9);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 9"); return 0; }
|
|
f32 tileX = smlua_to_number(L, 10);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 10"); return 0; }
|
|
f32 tileY = smlua_to_number(L, 11);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 11"); return 0; }
|
|
f32 tileW = smlua_to_number(L, 12);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 12"); return 0; }
|
|
f32 tileH = smlua_to_number(L, 13);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 13"); return 0; }
|
|
|
|
djui_hud_render_texture_tile_interpolated(texInfo, prevX, prevY, prevScaleW, prevScaleH, x, y, scaleW, scaleH, tileX, tileY, tileW, tileH);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_texture_override_set(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
|
|
|
const char* textureName = smlua_to_string(L, 1);
|
|
|
|
struct TextureInfo tmpOverrideTexInfo = { 0 };
|
|
struct TextureInfo* overrideTexInfo = &tmpOverrideTexInfo;
|
|
|
|
if (smlua_is_cobject(L, 2, LOT_TEXTUREINFO)) {
|
|
overrideTexInfo = (struct TextureInfo*)smlua_to_cobject(L, 2, LOT_TEXTUREINFO);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
|
} else {
|
|
int top = lua_gettop(L);
|
|
lua_pushvalue(L, 2);
|
|
|
|
lua_pushstring(L, "texture");
|
|
lua_gettable(L, top+1);
|
|
tmpOverrideTexInfo.texture = smlua_to_cpointer(L, lua_gettop(L), LVT_U8_P);
|
|
lua_pop(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2's 'texture' field"); return 0; }
|
|
|
|
tmpOverrideTexInfo.bitSize = smlua_get_integer_field(top+1, "bitSize");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2's 'bitSize' field"); return 0; }
|
|
|
|
tmpOverrideTexInfo.width = smlua_get_integer_field(top+1, "width");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2's 'width' field"); return 0; }
|
|
|
|
tmpOverrideTexInfo.height = smlua_get_integer_field(top+1, "height");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2's 'height' field"); return 0; }
|
|
|
|
tmpOverrideTexInfo.name = smlua_get_string_field(top+1, "name");
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2's 'name' field"); return 0; }
|
|
|
|
lua_settop(L, top);
|
|
}
|
|
|
|
dynos_texture_override_set(textureName, overrideTexInfo);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int smlua_func_texture_override_reset(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 1)) { return 0; }
|
|
|
|
const char* textureName = smlua_to_string(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
|
|
dynos_texture_override_reset(textureName);
|
|
|
|
return 1;
|
|
}
|
|
|
|
////////////////////////////////
|
|
// level script preprocessing //
|
|
////////////////////////////////
|
|
|
|
struct LuaLevelScriptParse {
|
|
int reference;
|
|
struct Mod* mod;
|
|
};
|
|
|
|
struct LuaLevelScriptParse sLevelScriptParse = { 0 };
|
|
|
|
s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
|
|
u32 areaIndex, bhvId, bhvArgs;
|
|
u32 *pAreaIndex = NULL, *pBhvId = NULL, *pBhvArgs = NULL;
|
|
MacroObject *pMacroData = NULL;
|
|
|
|
// Gather arguments
|
|
switch (type) {
|
|
|
|
// AREA
|
|
case 0x1F: {
|
|
areaIndex = (u8) dynos_level_cmd_get(cmd, 2);
|
|
pAreaIndex = &areaIndex;
|
|
} break;
|
|
|
|
// OBJECT_WITH_ACTS
|
|
case 0x24: {
|
|
const BehaviorScript *bhv = (const BehaviorScript *) dynos_level_cmd_get(cmd, 20);
|
|
if (bhv) {
|
|
bhvId = (u32) get_id_from_behavior(bhv);
|
|
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16);
|
|
pBhvId = &bhvId;
|
|
pBhvArgs = &bhvArgs;
|
|
}
|
|
} break;
|
|
|
|
// OBJECT_WITH_ACTS_EXT
|
|
case 0x3F: {
|
|
if (gLevelScriptModIndex != -1) {
|
|
const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 20));
|
|
if (bhvStr) {
|
|
gSmLuaConvertSuccess = true;
|
|
bhvId = (u32) smlua_get_integer_mod_variable(gLevelScriptModIndex, bhvStr);
|
|
if (!gSmLuaConvertSuccess) {
|
|
gSmLuaConvertSuccess = true;
|
|
bhvId = (u32) smlua_get_any_integer_mod_variable(bhvStr);
|
|
}
|
|
if (gSmLuaConvertSuccess) {
|
|
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16);
|
|
pBhvId = &bhvId;
|
|
pBhvArgs = &bhvArgs;
|
|
}
|
|
}
|
|
}
|
|
} break;
|
|
|
|
// OBJECT_WITH_ACTS_EXT2
|
|
case 0x40: {
|
|
if (gLevelScriptModIndex != -1) {
|
|
const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 24));
|
|
if (bhvStr) {
|
|
gSmLuaConvertSuccess = true;
|
|
bhvId = (u32) smlua_get_integer_mod_variable(gLevelScriptModIndex, bhvStr);
|
|
if (!gSmLuaConvertSuccess) {
|
|
gSmLuaConvertSuccess = true;
|
|
bhvId = (u32) smlua_get_any_integer_mod_variable(bhvStr);
|
|
}
|
|
if (gSmLuaConvertSuccess) {
|
|
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16);
|
|
pBhvId = &bhvId;
|
|
pBhvArgs = &bhvArgs;
|
|
}
|
|
}
|
|
}
|
|
} break;
|
|
|
|
// MACRO_OBJECTS
|
|
case 0x39: {
|
|
pMacroData = (MacroObject *) dynos_level_cmd_get(cmd, 4);
|
|
} break;
|
|
|
|
// None of the above
|
|
default: return 0;
|
|
}
|
|
|
|
// Retrieve Lua state
|
|
lua_State* L = gLuaState;
|
|
if (L == NULL) { return 0; }
|
|
struct LuaLevelScriptParse* preprocess = &sLevelScriptParse;
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, preprocess->reference);
|
|
|
|
// Push 'areaIndex'
|
|
if (pAreaIndex) {
|
|
lua_pushinteger(L, *pAreaIndex);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
|
|
// Push 'bhvData'
|
|
if (pBhvId && pBhvArgs) {
|
|
lua_newtable(L);
|
|
lua_pushstring(L, "behavior");
|
|
lua_pushinteger(L, *pBhvId);
|
|
lua_settable(L, -3);
|
|
lua_pushstring(L, "behaviorArg");
|
|
lua_pushinteger(L, *pBhvArgs);
|
|
lua_settable(L, -3);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
|
|
// Push 'macroBhvIds' and 'macroBhvArgs'
|
|
if (pMacroData) {
|
|
lua_newtable(L);
|
|
s32 macroBhvIdsIdx = lua_gettop(gLuaState);
|
|
lua_newtable(L);
|
|
s32 macroBhvArgsIdx = lua_gettop(gLuaState);
|
|
for (s32 i = 0; *pMacroData != MACRO_OBJECT_END(); pMacroData += 5, i++) {
|
|
s32 presetId = (s32) ((pMacroData[0] & 0x1FF) - 0x1F);
|
|
s32 presetParams = MacroObjectPresets[presetId].param;
|
|
s32 objParams = (pMacroData[4] & 0xFF00) | (presetParams & 0x00FF);
|
|
s32 bhvParams = ((objParams & 0x00FF) << 16) | (objParams & 0xFF00);
|
|
lua_pushinteger(L, i);
|
|
lua_pushinteger(L, get_id_from_behavior(MacroObjectPresets[presetId].behavior));
|
|
lua_settable(L, macroBhvIdsIdx);
|
|
lua_pushinteger(L, i);
|
|
lua_pushinteger(L, bhvParams);
|
|
lua_settable(L, macroBhvArgsIdx);
|
|
}
|
|
} else {
|
|
lua_pushnil(L);
|
|
lua_pushnil(L);
|
|
}
|
|
|
|
// call the callback
|
|
if (0 != smlua_call_hook(L, 4, 0, 0, preprocess->mod)) {
|
|
LOG_LUA("Failed to call the callback behaviors: %u", type);
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void smlua_func_level_script_parse(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 2)) { return; }
|
|
|
|
lua_Integer levelNum = smlua_to_integer(L, 1);
|
|
if (!gSmLuaConvertSuccess) {
|
|
LOG_LUA_LINE("Invalid level script name");
|
|
return;
|
|
}
|
|
|
|
struct LuaLevelScriptParse* preprocess = &sLevelScriptParse;
|
|
preprocess->reference = LUA_NOREF;
|
|
|
|
lua_pushvalue(L, 2);
|
|
int ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
|
if (ref == -1) {
|
|
LOG_LUA_LINE("Level Script Parse: %lld tried to parse using undefined function", levelNum);
|
|
return;
|
|
}
|
|
|
|
preprocess->reference = ref;
|
|
preprocess->mod = gLuaActiveMod;
|
|
|
|
void *script = dynos_level_get_script(levelNum);
|
|
if (script == NULL) {
|
|
LOG_LUA("Failed to find script: %lld", levelNum);
|
|
return;
|
|
}
|
|
s32 modIndex = dynos_level_get_mod_index(levelNum);
|
|
|
|
// Back up current values
|
|
LevelScript *currLevelScript = gLevelScriptActive;
|
|
s32 currModIndex = gLevelScriptModIndex;
|
|
|
|
// Parse script
|
|
gLevelScriptActive = (LevelScript *) script;
|
|
gLevelScriptModIndex = modIndex;
|
|
dynos_level_parse_script(script, smlua_func_level_script_parse_callback);
|
|
|
|
// Restore current values
|
|
gLevelScriptActive = currLevelScript;
|
|
gLevelScriptModIndex = currModIndex;
|
|
}
|
|
|
|
///////////////////////
|
|
// custom animations //
|
|
///////////////////////
|
|
|
|
static u16 *smlua_to_u16_list(lua_State* L, int index, u32* length) {
|
|
|
|
// Get number of values
|
|
*length = lua_rawlen(L, index);
|
|
if (!*length) { LOG_LUA("smlua_to_u16_list: Table must not be empty"); return NULL; }
|
|
u16 *values = calloc(*length, sizeof(u16));
|
|
|
|
// Retrieve values
|
|
lua_pushnil(L);
|
|
s32 top = lua_gettop(L);
|
|
while (lua_next(L, index) != 0) {
|
|
int indexKey = lua_gettop(L) - 1;
|
|
int indexValue = lua_gettop(L) - 0;
|
|
|
|
s32 key = smlua_to_integer(L, indexKey);
|
|
if (!gSmLuaConvertSuccess) {
|
|
LOG_LUA("smlua_to_u16_list: Failed to convert table key");
|
|
free(values);
|
|
return 0;
|
|
}
|
|
|
|
u16 value = smlua_to_integer(L, indexValue);
|
|
if (!gSmLuaConvertSuccess) {
|
|
LOG_LUA("smlua_to_u16_list: Failed to convert table value");
|
|
free(values);
|
|
return 0;
|
|
}
|
|
|
|
values[key - 1] = value;
|
|
lua_settop(L, top);
|
|
}
|
|
lua_settop(L, top);
|
|
return values;
|
|
}
|
|
|
|
int smlua_func_smlua_anim_util_register_animation(lua_State* L) {
|
|
if (!smlua_functions_valid_param_count(L, 8)) { return 0; }
|
|
|
|
const char *name = smlua_to_string(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("%s: Failed to convert parameter '%s'", "smlua_anim_util_register_animation", "name"); return 0; }
|
|
|
|
s16 flags = smlua_to_integer(L, 2);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("%s: Failed to convert parameter '%s'", "smlua_anim_util_register_animation", "flags"); return 0; }
|
|
|
|
s16 animYTransDivisor = smlua_to_integer(L, 3);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("%s: Failed to convert parameter '%s'", "smlua_anim_util_register_animation", "animYTransDivisor"); return 0; }
|
|
|
|
s16 startFrame = smlua_to_integer(L, 4);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("%s: Failed to convert parameter '%s'", "smlua_anim_util_register_animation", "startFrame"); return 0; }
|
|
|
|
s16 loopStart = smlua_to_integer(L, 5);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("%s: Failed to convert parameter '%s'", "smlua_anim_util_register_animation", "loopStart"); return 0; }
|
|
|
|
s16 loopEnd = smlua_to_integer(L, 6);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("%s: Failed to convert parameter '%s'", "smlua_anim_util_register_animation", "loopEnd"); return 0; }
|
|
|
|
u32 valuesLength = 0;
|
|
u16 *values = (u16 *) smlua_to_u16_list(L, 7, &valuesLength);
|
|
if (!values) { LOG_LUA("%s: Failed to convert parameter '%s'", "smlua_anim_util_register_animation", "values"); return 0; }
|
|
|
|
u32 indexLength = 0;
|
|
u16 *index = (u16 *) smlua_to_u16_list(L, 8, &indexLength);
|
|
if (!index) { LOG_LUA("%s: Failed to convert parameter '%s'", "smlua_anim_util_register_animation", "index"); free(values); return 0; }
|
|
|
|
smlua_anim_util_register_animation(name, flags, animYTransDivisor, startFrame, loopStart, loopEnd, values, valuesLength, index, indexLength);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/////////////
|
|
// console //
|
|
/////////////
|
|
|
|
int smlua_func_log_to_console(lua_State* L) {
|
|
if (!smlua_functions_valid_param_range(L, 1, 2)) { return 0; }
|
|
|
|
int paramCount = lua_gettop(L);
|
|
|
|
const char* message = smlua_to_string(L, 1);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; }
|
|
|
|
enum ConsoleMessageLevel level = CONSOLE_MESSAGE_INFO;
|
|
if (paramCount >= 2) {
|
|
level = smlua_to_integer(L, 2);
|
|
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; }
|
|
}
|
|
|
|
djui_console_message_create(message, level);
|
|
|
|
return 1;
|
|
}
|
|
|
|
//////////
|
|
// bind //
|
|
//////////
|
|
|
|
void smlua_bind_functions(void) {
|
|
lua_State* L = gLuaState;
|
|
|
|
// misc
|
|
smlua_bind_function(L, "sins", smlua_func_sins);
|
|
smlua_bind_function(L, "coss", smlua_func_coss);
|
|
smlua_bind_function(L, "atan2s", smlua_func_atan2s);
|
|
smlua_bind_function(L, "init_mario_after_warp", smlua_func_init_mario_after_warp);
|
|
smlua_bind_function(L, "initiate_warp", smlua_func_initiate_warp);
|
|
smlua_bind_function(L, "network_init_object", smlua_func_network_init_object);
|
|
smlua_bind_function(L, "network_send_object", smlua_func_network_send_object);
|
|
smlua_bind_function(L, "reset_level", smlua_func_reset_level);
|
|
smlua_bind_function(L, "network_send", smlua_func_network_send);
|
|
smlua_bind_function(L, "network_send_to", smlua_func_network_send_to);
|
|
smlua_bind_function(L, "get_texture_info", smlua_func_get_texture_info);
|
|
smlua_bind_function(L, "djui_hud_render_texture", smlua_func_djui_hud_render_texture);
|
|
smlua_bind_function(L, "djui_hud_render_texture_tile", smlua_func_djui_hud_render_texture_tile);
|
|
smlua_bind_function(L, "djui_hud_render_texture_interpolated", smlua_func_djui_hud_render_texture_interpolated);
|
|
smlua_bind_function(L, "djui_hud_render_texture_tile_interpolated", smlua_func_djui_hud_render_texture_tile_interpolated);
|
|
smlua_bind_function(L, "texture_override_set", smlua_func_texture_override_set);
|
|
smlua_bind_function(L, "texture_override_reset", smlua_func_texture_override_reset);
|
|
smlua_bind_function(L, "level_script_parse", smlua_func_level_script_parse);
|
|
smlua_bind_function(L, "smlua_anim_util_register_animation", smlua_func_smlua_anim_util_register_animation);
|
|
smlua_bind_function(L, "log_to_console", smlua_func_log_to_console);
|
|
}
|