From 0ee8d5f81eb207cee368f296348462fb6438ca82 Mon Sep 17 00:00:00 2001 From: Agent X <44549182+AgentXLP@users.noreply.github.com> Date: Fri, 28 Mar 2025 23:06:48 -0400 Subject: [PATCH] Fix/optimize/improve lighting engine --- autogen/lua_definitions/functions.lua | 27 +++++- autogen/lua_definitions/manual.lua | 4 +- autogen/lua_definitions/structs.lua | 1 + data/behavior_data.c | 4 +- data/dynos_mgr_builtin.cpp | 2 +- docs/lua/functions-2.md | 63 ++++++++++++- docs/lua/functions-3.md | 4 +- docs/lua/functions.md | 4 +- docs/lua/structs.md | 1 + include/object_fields.h | 3 +- src/engine/lighting_engine.c | 129 ++++++++++++++++++-------- src/engine/lighting_engine.h | 12 ++- src/game/behavior_actions.h | 6 +- src/game/behaviors/light.inc.c | 36 ++++++- src/pc/gfx/gfx_pc.c | 1 - src/pc/lua/smlua_cobject_autogen.c | 3 +- src/pc/lua/smlua_functions_autogen.c | 66 ++++++++++++- 17 files changed, 301 insertions(+), 65 deletions(-) diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 06794286b..54f4d5e4c 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -120,7 +120,7 @@ function bhv_alpha_boo_key_loop() end --- Behavior loop function for the lighting engine ambient light. Takes the first 3 behavior parameter bytes for RGB color -function bhv_ambient_light_init() +function bhv_ambient_light_update() -- ... end @@ -2841,6 +2841,18 @@ function play_penguin_walking_sound(walk) -- ... end +--- @param x number +--- @param y number +--- @param z number +--- @param r integer +--- @param g integer +--- @param b integer +--- @return Object +--- Spawns a lighting engine point light +function spawn_ambient_light(x, y, z, r, g, b) + -- ... +end + --- @param x number --- @param y number --- @param z number @@ -2872,6 +2884,19 @@ function spawn_no_exit_star(x, y, z) -- ... end +--- @param x number +--- @param y number +--- @param z number +--- @param r integer +--- @param g integer +--- @param b integer +--- @param radius number +--- @return Object +--- Spawns a lighting engine ambient light +function spawn_point_light(x, y, z, r, g, b, radius) + -- ... +end + --- @param x number --- @param y number --- @param z number diff --git a/autogen/lua_definitions/manual.lua b/autogen/lua_definitions/manual.lua index da6186217..65bef6f64 100644 --- a/autogen/lua_definitions/manual.lua +++ b/autogen/lua_definitions/manual.lua @@ -356,12 +356,12 @@ function texture_override_reset(textureName) -- ... end ---- @class bhvData +--- @class BehaviorData --- @field behavior BehaviorId --- @field behaviorArg integer --- @param levelNum LevelNum | integer ---- @param func fun(areaIndex:number, bhvData:bhvData, macroBhvIds:BehaviorId[], macroBhvArgs:integer[]) +--- @param func fun(areaIndex:number, bhvData:BehaviorData, macroBhvIds:BehaviorId[], macroBhvArgs:integer[]) --- When `func` is called, arguments are filled depending on the level command: --- - `AREA` command: only `areaIndex` is filled. It's a number --- - `OBJECT` command: only `bhvData` is filled. `bhvData` is a table with nine fields: 'behavior', 'behaviorArg', 'model', 'posX', 'posY', 'posZ', 'pitch', 'yaw' and 'roll' diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index 143ff8670..481cd2a00 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -1709,6 +1709,7 @@ --- @field public oKoopaTurningAwayFromWall integer --- @field public oKoopaUnshelledTimeUntilTurn integer --- @field public oLightID integer +--- @field public oLightRadius number --- @field public oLllRotatingHexFlameUnkF4 number --- @field public oLllRotatingHexFlameUnkF8 number --- @field public oLllRotatingHexFlameUnkFC number diff --git a/data/behavior_data.c b/data/behavior_data.c index 335b10187..f691d3c11 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -6440,7 +6440,9 @@ const BehaviorScript editor_Scroll_Texture[] = { const BehaviorScript bhvAmbientLight[] = { BEGIN(OBJ_LIST_DEFAULT), ID(id_bhvAmbientLight), - CALL_NATIVE(bhv_ambient_light_init), + BEGIN_LOOP(), + CALL_NATIVE(bhv_ambient_light_update), + END_LOOP(), }; const BehaviorScript bhvPointLight[] = { diff --git a/data/dynos_mgr_builtin.cpp b/data/dynos_mgr_builtin.cpp index de1ca0de5..d222411a3 100644 --- a/data/dynos_mgr_builtin.cpp +++ b/data/dynos_mgr_builtin.cpp @@ -2030,7 +2030,7 @@ static const void* sDynosBuiltinFuncs[] = { define_builtin(spawn_star_number), define_builtin(bhv_ferris_wheel_platform_init), define_builtin(geo_mario_cap_display_list), - define_builtin(bhv_ambient_light_init), + define_builtin(bhv_ambient_light_update), define_builtin(bhv_point_light_init), define_builtin(bhv_point_light_loop), }; diff --git a/docs/lua/functions-2.md b/docs/lua/functions-2.md index 4381b0942..fa6ffb4b3 100644 --- a/docs/lua/functions-2.md +++ b/docs/lua/functions-2.md @@ -436,13 +436,13 @@ Behavior loop function for alpha boo key
-## [bhv_ambient_light_init](#bhv_ambient_light_init) +## [bhv_ambient_light_update](#bhv_ambient_light_update) ### Description Behavior loop function for the lighting engine ambient light. Takes the first 3 behavior parameter bytes for RGB color ### Lua Example -`bhv_ambient_light_init()` +`bhv_ambient_light_update()` ### Parameters - None @@ -451,7 +451,7 @@ Behavior loop function for the lighting engine ambient light. Takes the first 3 - None ### C Prototype -`void bhv_ambient_light_init(void);` +`void bhv_ambient_light_update(void);` [:arrow_up_small:](#) @@ -11818,6 +11818,34 @@ Plays the penguin walking sound
+## [spawn_ambient_light](#spawn_ambient_light) + +### Description +Spawns a lighting engine point light + +### Lua Example +`local ObjectValue = spawn_ambient_light(x, y, z, r, g, b)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x | `number` | +| y | `number` | +| z | `number` | +| r | `integer` | +| g | `integer` | +| b | `integer` | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object* spawn_ambient_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b);` + +[:arrow_up_small:](#) + +
+ ## [spawn_default_star](#spawn_default_star) ### Description @@ -11914,6 +11942,35 @@ Spawns a Star that won't make Mario exit the level with an ID corresponding to t
+## [spawn_point_light](#spawn_point_light) + +### Description +Spawns a lighting engine ambient light + +### Lua Example +`local ObjectValue = spawn_point_light(x, y, z, r, g, b, radius)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x | `number` | +| y | `number` | +| z | `number` | +| r | `integer` | +| g | `integer` | +| b | `integer` | +| radius | `number` | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object* spawn_point_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius);` + +[:arrow_up_small:](#) + +
+ ## [spawn_red_coin_cutscene_star](#spawn_red_coin_cutscene_star) ### Description diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index 4c5b339f6..31ce79ac4 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -6273,7 +6273,7 @@ Adds a lighting engine point light at `x`, `y`, `z` with color `r`, `g`, `b` and - `integer` ### C Prototype -`s16 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity);` +`s32 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity);` [:arrow_up_small:](#) @@ -6343,7 +6343,7 @@ Gets the total number of lights currently loaded in the lighting engine - `integer` ### C Prototype -`s16 le_get_light_count(void);` +`s32 le_get_light_count(void);` [:arrow_up_small:](#) diff --git a/docs/lua/functions.md b/docs/lua/functions.md index b80ee43c1..bd3bf4392 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -59,7 +59,7 @@ - [bhv_activated_back_and_forth_platform_init](functions-2.md#bhv_activated_back_and_forth_platform_init) - [bhv_activated_back_and_forth_platform_update](functions-2.md#bhv_activated_back_and_forth_platform_update) - [bhv_alpha_boo_key_loop](functions-2.md#bhv_alpha_boo_key_loop) - - [bhv_ambient_light_init](functions-2.md#bhv_ambient_light_init) + - [bhv_ambient_light_update](functions-2.md#bhv_ambient_light_update) - [bhv_ambient_sounds_init](functions-2.md#bhv_ambient_sounds_init) - [bhv_animated_texture_loop](functions-2.md#bhv_animated_texture_loop) - [bhv_animates_on_floor_switch_press_init](functions-2.md#bhv_animates_on_floor_switch_press_init) @@ -600,10 +600,12 @@ - [mario_moving_fast_enough_to_make_piranha_plant_bite](functions-2.md#mario_moving_fast_enough_to_make_piranha_plant_bite) - [obj_set_secondary_camera_focus](functions-2.md#obj_set_secondary_camera_focus) - [play_penguin_walking_sound](functions-2.md#play_penguin_walking_sound) + - [spawn_ambient_light](functions-2.md#spawn_ambient_light) - [spawn_default_star](functions-2.md#spawn_default_star) - [spawn_mist_from_global](functions-2.md#spawn_mist_from_global) - [spawn_mist_particles_variable](functions-2.md#spawn_mist_particles_variable) - [spawn_no_exit_star](functions-2.md#spawn_no_exit_star) + - [spawn_point_light](functions-2.md#spawn_point_light) - [spawn_red_coin_cutscene_star](functions-2.md#spawn_red_coin_cutscene_star) - [spawn_star_number](functions-2.md#spawn_star_number) - [spawn_triangle_break_particles](functions-2.md#spawn_triangle_break_particles) diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 9af8a2141..8bb810723 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -2762,6 +2762,7 @@ | oYoshiTargetYaw | `integer` | | | oBreakableWallForce | `integer` | | | oLightID | `integer` | | +| oLightRadius | `number` | | [:arrow_up_small:](#) diff --git a/include/object_fields.h b/include/object_fields.h index d96906ea3..e9ba6e21b 100644 --- a/include/object_fields.h +++ b/include/object_fields.h @@ -1167,6 +1167,7 @@ #define /*0x104*/ oBreakableWallForce OBJECT_FIELD_S32(0x1F) /* Point Light */ -#define /*0x104*/ oLightID OBJECT_FIELD_S32(0x1F) +#define /*0x0F4*/ oLightID OBJECT_FIELD_S32(0x1B) +#define /*0x0F8*/ oLightRadius OBJECT_FIELD_F32(0x1C) #endif // OBJECT_FIELDS_H diff --git a/src/engine/lighting_engine.c b/src/engine/lighting_engine.c index a8b6b3c60..b27839df5 100644 --- a/src/engine/lighting_engine.c +++ b/src/engine/lighting_engine.c @@ -2,11 +2,15 @@ #include "math_util.h" #include "surface_collision.h" #include "pc/lua/utils/smlua_math_utils.h" +#include "pc/debuglog.h" #include "data/dynos_cmap.cpp.h" +#define LE_MAX_LIGHTS 256 +#define LE_TOTAL_WEIGHTED_LIGHTING + static Color sAmbientColor; static void* sLights = NULL; -static s16 sLightID = -1; +static s32 sLightID = 0; static inline void color_set(Color color, u8 r, u8 g, u8 b) { color[0] = r; @@ -17,84 +21,115 @@ static inline void color_set(Color color, u8 r, u8 g, u8 b) { void le_calculate_vertex_lighting(Vtx_t* v, Color out) { if (sLights == NULL) { return; } +#ifdef LE_TOTAL_WEIGHTED_LIGHTING + f32 r = v->cn[0] * (sAmbientColor[0] / 255.0f); + f32 g = v->cn[1] * (sAmbientColor[1] / 255.0f); + f32 b = v->cn[2] * (sAmbientColor[2] / 255.0f); +#else f32 r = 0; f32 g = 0; f32 b = 0; +#endif + f32 weight = 1.0f; for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) { - f32 dist = vec3f_dist(light->pos, v->ob); - if (dist > light->radius) { continue; } - dist = 1 - minf(dist / light->radius, 1); + f32 diffX = light->posX - v->ob[0]; + f32 diffY = light->posY - v->ob[1]; + f32 diffZ = light->posZ - v->ob[2]; + f32 dist = (diffX * diffX) + (diffY * diffY) + (diffZ * diffZ); + f32 radius = light->radius * light->radius; + if (dist > radius) { continue; } - r += light->color[0] * dist * light->intensity; - g += light->color[1] * dist * light->intensity; - b += light->color[2] * dist * light->intensity; + f32 brightness = (1 - (dist / radius)) * light->intensity; + r += light->colorR * brightness; + g += light->colorG * brightness; + b += light->colorB * brightness; + weight += brightness; } - out[0] = min((v->cn[0] * (sAmbientColor[0] / 255.0f)) + r, 255); - out[1] = min((v->cn[1] * (sAmbientColor[1] / 255.0f)) + g, 255); - out[2] = min((v->cn[2] * (sAmbientColor[2] / 255.0f)) + b, 255); +#ifdef LE_TOTAL_WEIGHTED_LIGHTING + out[0] = min(r / weight, 255); + out[1] = min(g / weight, 255); + out[2] = min(b / weight, 255); +#else + out[0] = min((v->cn[0] * (sAmbientColor[0] / 255.0f)) + (r / weight), 255); + out[1] = min((v->cn[1] * (sAmbientColor[1] / 255.0f)) + (g / weight), 255); + out[2] = min((v->cn[2] * (sAmbientColor[2] / 255.0f)) + (b / weight), 255); +#endif } void le_calculate_lighting_color(Vec3f pos, Color out, f32 lightIntensityScalar) { if (sLights == NULL) { return; } - f32 r = 0; - f32 g = 0; - f32 b = 0; + f32 r = sAmbientColor[0]; + f32 g = sAmbientColor[1]; + f32 b = sAmbientColor[2]; for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) { - f32 dist = vec3f_dist(light->pos, pos); - if (dist > light->radius) { continue; } - dist = 1 - minf(dist / light->radius, 1); + f32 diffX = light->posX - pos[0]; + f32 diffY = light->posY - pos[1]; + f32 diffZ = light->posZ - pos[2]; + f32 dist = (diffX * diffX) + (diffY * diffY) + (diffZ * diffZ); + f32 radius = light->radius * light->radius; + if (dist > radius) { continue; } - r += light->color[0] * dist * light->intensity * lightIntensityScalar; - g += light->color[1] * dist * light->intensity * lightIntensityScalar; - b += light->color[2] * dist * light->intensity * lightIntensityScalar; + f32 brightness = (1 - (dist / radius)) * light->intensity * lightIntensityScalar; + r += light->colorR * brightness; + g += light->colorG * brightness; + b += light->colorB * brightness; } - out[0] = min(sAmbientColor[0] + r, 255); - out[1] = min(sAmbientColor[1] + g, 255); - out[2] = min(sAmbientColor[2] + b, 255); + out[0] = min(r, 255); + out[1] = min(g, 255); + out[2] = min(b, 255); } void le_calculate_lighting_dir(Vec3f pos, Vec3f out) { if (sLights == NULL) { return; } Vec3f lightingDir = { 0, 0, 0 }; - s16 count = 0; + s16 count = 1; for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) { - f32 dist = vec3f_dist(light->pos, pos); - if (dist > light->radius) { continue; } - dist = 1 - minf(dist / light->radius, 1); + f32 diffX = light->posX - pos[0]; + f32 diffY = light->posY - pos[1]; + f32 diffZ = light->posZ - pos[2]; + f32 dist = (diffX * diffX) + (diffY * diffY) + (diffZ * diffZ); + f32 radius = light->radius * light->radius; + if (dist > radius) { continue; } Vec3f dir = { - pos[0] - light->pos[0], - pos[1] - light->pos[1], - pos[2] - light->pos[2], + pos[0] - light->posX, + pos[1] - light->posY, + pos[2] - light->posZ, }; vec3f_normalize(dir); - lightingDir[0] += dir[0] * dist * light->intensity; - lightingDir[1] += dir[1] * dist * light->intensity; - lightingDir[2] += dir[2] * dist * light->intensity; + f32 intensity = (1 - (dist / radius)) * light->intensity; + lightingDir[0] += dir[0] * intensity; + lightingDir[1] += dir[1] * intensity; + lightingDir[2] += dir[2] * intensity; count++; } - count++; // additional increment out[0] = lightingDir[0] / (f32)(count); out[1] = lightingDir[1] / (f32)(count); out[2] = lightingDir[2] / (f32)(count); vec3f_normalize(out); } -s16 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity) { +s32 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity) { if (sLights == NULL) { sLights = hmap_create(true); + } else if (hmap_len(sLights) >= LE_MAX_LIGHTS) { + return 0; } struct LELight* light = calloc(1, sizeof(struct LELight)); - vec3f_set(light->pos, x, y, z); - color_set(light->color, r, g, b); + light->posX = x; + light->posY = y; + light->posZ = z; + light->colorR = r; + light->colorG = g; + light->colorB = b; light->radius = radius; light->intensity = intensity; hmap_put(sLights, ++sLightID, light); @@ -102,11 +137,13 @@ s16 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensit } void le_remove_light(s16 id) { + if (sLights == NULL || id <= 0) { return; } + free(hmap_get(sLights, id)); hmap_del(sLights, id); } -s16 le_get_light_count(void) { +s32 le_get_light_count(void) { if (sLights == NULL) { return 0; } return hmap_len(sLights); } @@ -116,24 +153,36 @@ void le_set_ambient_color(u8 r, u8 g, u8 b) { } void le_set_light_pos(s16 id, f32 x, f32 y, f32 z) { + if (sLights == NULL || id <= 0) { return; } + struct LELight* light = hmap_get(sLights, id); if (light == NULL) { return; } - vec3f_set(light->pos, x, y, z); + light->posX = x; + light->posY = y; + light->posZ = z; } void le_set_light_color(s16 id, u8 r, u8 g, u8 b) { + if (sLights == NULL || id <= 0) { return; } + struct LELight* light = hmap_get(sLights, id); if (light == NULL) { return; } - color_set(light->color, r, g, b); + light->colorR = r; + light->colorG = g; + light->colorB = b; } void le_set_light_radius(s16 id, f32 radius) { + if (sLights == NULL || id <= 0) { return; } + struct LELight* light = hmap_get(sLights, id); if (light == NULL) { return; } light->radius = radius; } void le_set_light_intensity(s16 id, f32 intensity) { + if (sLights == NULL || id <= 0) { return; } + struct LELight* light = hmap_get(sLights, id); if (light == NULL) { return; } light->intensity = intensity; @@ -146,7 +195,7 @@ void le_clear(void) { free(light); } hmap_clear(sLights); - sLightID = -1; + sLightID = 0; sAmbientColor[0] = 0; sAmbientColor[1] = 0; sAmbientColor[2] = 0; diff --git a/src/engine/lighting_engine.h b/src/engine/lighting_engine.h index 3feb3cf33..5708722df 100644 --- a/src/engine/lighting_engine.h +++ b/src/engine/lighting_engine.h @@ -5,8 +5,12 @@ struct LELight { - Vec3f pos; - Color color; + f32 posX; + f32 posY; + f32 posZ; + u8 colorR; + u8 colorG; + u8 colorB; f32 radius; f32 intensity; }; @@ -17,11 +21,11 @@ void le_calculate_lighting_color(Vec3f pos, Color out, f32 lightIntensityScalar) /* |description|Calculates the lighting direction from a position and outputs the result in `out`|descriptionEnd| */ void le_calculate_lighting_dir(Vec3f pos, Vec3f out); /* |description|Adds a lighting engine point light at `x`, `y`, `z` with color `r`, `g`, `b` and `radius` with `intensity`|descriptionEnd| */ -s16 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity); +s32 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity); /* |description|Removes a lighting engine point light corresponding to `id`|descriptionEnd| */ void le_remove_light(s16 id); /* |description|Gets the total number of lights currently loaded in the lighting engine|descriptionEnd| */ -s16 le_get_light_count(void); +s32 le_get_light_count(void); /* |description|Sets the lighting engine ambient color|descriptionEnd| */ void le_set_ambient_color(u8 r, u8 g, u8 b); /* |description|Sets a lighting engine point light's position to `x`, `y`, `z`|descriptionEnd| */ diff --git a/src/game/behavior_actions.h b/src/game/behavior_actions.h index a19889ae1..968da5949 100644 --- a/src/game/behavior_actions.h +++ b/src/game/behavior_actions.h @@ -1147,8 +1147,12 @@ void bhv_yoshi_loop(void); void bhv_volcano_trap_loop(void); /* |description|Behavior loop function for UV texture scrolling|descriptionEnd| */ void uv_update_scroll(void); +/* |description|Spawns a lighting engine point light|descriptionEnd| */ +struct Object* spawn_ambient_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b); +/* |description|Spawns a lighting engine ambient light|descriptionEnd| */ +struct Object* spawn_point_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius); /* |description|Behavior loop function for the lighting engine ambient light. Takes the first 3 behavior parameter bytes for RGB color|descriptionEnd| */ -void bhv_ambient_light_init(void); +void bhv_ambient_light_update(void); /* |description|Behavior init function for the lighting engine point light. Takes the first 3 behavior parameter bytes for RGB color and the last for radius|descriptionEnd| */ void bhv_point_light_init(void); /* |description|Behavior loop function for the lighting engine point light|descriptionEnd| */ diff --git a/src/game/behaviors/light.inc.c b/src/game/behaviors/light.inc.c index 7d5ebbe30..cb8dfcf19 100644 --- a/src/game/behaviors/light.inc.c +++ b/src/game/behaviors/light.inc.c @@ -1,4 +1,25 @@ -void bhv_ambient_light_init(void) { +struct Object* spawn_ambient_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b) { + struct Object* obj = spawn_object(NULL, MODEL_NONE, bhvAmbientLight); + + obj->oPosX = x; + obj->oPosY = y; + obj->oPosZ = z; + obj->oBehParams = (r << 24) | (g << 16) | (b << 8) | (0x00); + return obj; +} + +struct Object* spawn_point_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius) { + struct Object* obj = spawn_object(NULL, MODEL_NONE, bhvPointLight); + + obj->oPosX = x; + obj->oPosY = y; + obj->oPosZ = z; + obj->oBehParams = (r << 24) | (g << 16) | (b << 8) | (0x00); + obj->oLightRadius = radius; + return obj; +} + +void bhv_ambient_light_update(void) { le_set_ambient_color( (o->oBehParams >> 24) & 0xFF, (o->oBehParams >> 16) & 0xFF, @@ -8,13 +29,21 @@ void bhv_ambient_light_init(void) { void bhv_point_light_init(void) { + // assign oLightRadius + f32 radius = (o->oBehParams & 0xFF) * 10.0f; + if (o->oLightRadius != 0.0f) { + radius = o->oLightRadius; + } else if (radius != 0) { + o->oLightRadius = radius; + } + o->oLightID = le_add_light( // position o->oPosX, o->oPosY, o->oPosZ, // color (o->oBehParams >> 24) & 0xFF, (o->oBehParams >> 16) & 0xFF, (o->oBehParams >> 8) & 0xFF, // radius - (o->oBehParams & 0xFF) * 10.0f, + radius, // intensity (2 by default) 2.0f ); @@ -31,5 +60,8 @@ void bhv_point_light_loop(void) { obj_copy_pos(o, o->parentObj); } + // update these values every frame le_set_light_pos(o->oLightID, o->oPosX, o->oPosY, o->oPosZ); + le_set_light_color(o->oLightID, (o->oBehParams >> 24) & 0xFF, (o->oBehParams >> 16) & 0xFF, (o->oBehParams >> 8) & 0xFF); + le_set_light_radius(o->oLightID, o->oLightRadius); } diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index b2ecf41ae..449fad7cd 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -877,7 +877,6 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons d->color.g = color[1]; d->color.b = color[2]; } - } else { if (!(rsp.geometry_mode & G_LIGHT_MAP_EXT) && luaVertexColor) { d->color.r = v->cn[0] * vertexColorCached[0]; diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 9e55d95b6..b1e5d88ef 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -1616,7 +1616,7 @@ static struct LuaObjectField sNetworkPlayerFields[LUA_NETWORK_PLAYER_FIELD_COUNT { "type", LVT_U8, offsetof(struct NetworkPlayer, type), true, LOT_NONE, 1, sizeof(u8) }, }; -#define LUA_OBJECT_FIELD_COUNT 761 +#define LUA_OBJECT_FIELD_COUNT 762 static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = { { "activeFlags", LVT_S16, offsetof(struct Object, activeFlags), false, LOT_NONE, 1, sizeof(s16) }, { "allowRemoteInteractions", LVT_U8, offsetof(struct Object, allowRemoteInteractions), false, LOT_NONE, 1, sizeof(u8) }, @@ -2022,6 +2022,7 @@ static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = { { "oKoopaTurningAwayFromWall", LVT_S32, offsetof(struct Object, oKoopaTurningAwayFromWall), false, LOT_NONE, 1, sizeof(s32) }, { "oKoopaUnshelledTimeUntilTurn", LVT_S32, offsetof(struct Object, oKoopaUnshelledTimeUntilTurn), false, LOT_NONE, 1, sizeof(s32) }, { "oLightID", LVT_S32, offsetof(struct Object, oLightID), false, LOT_NONE, 1, sizeof(s32) }, + { "oLightRadius", LVT_F32, offsetof(struct Object, oLightRadius), false, LOT_NONE, 1, sizeof(f32) }, { "oLllRotatingHexFlameUnkF4", LVT_F32, offsetof(struct Object, oLllRotatingHexFlameUnkF4), false, LOT_NONE, 1, sizeof(f32) }, { "oLllRotatingHexFlameUnkF8", LVT_F32, offsetof(struct Object, oLllRotatingHexFlameUnkF8), false, LOT_NONE, 1, sizeof(f32) }, { "oLllRotatingHexFlameUnkFC", LVT_F32, offsetof(struct Object, oLllRotatingHexFlameUnkFC), false, LOT_NONE, 1, sizeof(f32) }, diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index ec19820b2..edbe878be 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -565,18 +565,18 @@ int smlua_func_bhv_alpha_boo_key_loop(UNUSED lua_State* L) { return 1; } -int smlua_func_bhv_ambient_light_init(UNUSED lua_State* L) { +int smlua_func_bhv_ambient_light_update(UNUSED lua_State* L) { if (!gCurrentObject) { return 0; } if (L == NULL) { return 0; } int top = lua_gettop(L); if (top != 0) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "bhv_ambient_light_init", 0, top); + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "bhv_ambient_light_update", 0, top); return 0; } - bhv_ambient_light_init(); + bhv_ambient_light_update(); return 1; } @@ -9465,6 +9465,33 @@ int smlua_func_play_penguin_walking_sound(lua_State* L) { return 1; } +int smlua_func_spawn_ambient_light(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 6) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "spawn_ambient_light", 6, top); + return 0; + } + + f32 x = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "spawn_ambient_light"); return 0; } + f32 y = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "spawn_ambient_light"); return 0; } + f32 z = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "spawn_ambient_light"); return 0; } + u8 r = smlua_to_integer(L, 4); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "spawn_ambient_light"); return 0; } + u8 g = smlua_to_integer(L, 5); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "spawn_ambient_light"); return 0; } + u8 b = smlua_to_integer(L, 6); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 6, "spawn_ambient_light"); return 0; } + + smlua_push_object(L, LOT_OBJECT, spawn_ambient_light(x, y, z, r, g, b), NULL); + + return 1; +} + int smlua_func_spawn_default_star(lua_State* L) { if (L == NULL) { return 0; } @@ -9543,6 +9570,35 @@ int smlua_func_spawn_no_exit_star(lua_State* L) { return 1; } +int smlua_func_spawn_point_light(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 7) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "spawn_point_light", 7, top); + return 0; + } + + f32 x = smlua_to_number(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "spawn_point_light"); return 0; } + f32 y = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "spawn_point_light"); return 0; } + f32 z = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "spawn_point_light"); return 0; } + u8 r = smlua_to_integer(L, 4); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "spawn_point_light"); return 0; } + u8 g = smlua_to_integer(L, 5); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "spawn_point_light"); return 0; } + u8 b = smlua_to_integer(L, 6); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 6, "spawn_point_light"); return 0; } + f32 radius = smlua_to_number(L, 7); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 7, "spawn_point_light"); return 0; } + + smlua_push_object(L, LOT_OBJECT, spawn_point_light(x, y, z, r, g, b, radius), NULL); + + return 1; +} + int smlua_func_spawn_red_coin_cutscene_star(lua_State* L) { if (L == NULL) { return 0; } @@ -33155,7 +33211,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "bhv_activated_back_and_forth_platform_init", smlua_func_bhv_activated_back_and_forth_platform_init); smlua_bind_function(L, "bhv_activated_back_and_forth_platform_update", smlua_func_bhv_activated_back_and_forth_platform_update); smlua_bind_function(L, "bhv_alpha_boo_key_loop", smlua_func_bhv_alpha_boo_key_loop); - smlua_bind_function(L, "bhv_ambient_light_init", smlua_func_bhv_ambient_light_init); + smlua_bind_function(L, "bhv_ambient_light_update", smlua_func_bhv_ambient_light_update); smlua_bind_function(L, "bhv_ambient_sounds_init", smlua_func_bhv_ambient_sounds_init); smlua_bind_function(L, "bhv_animated_texture_loop", smlua_func_bhv_animated_texture_loop); smlua_bind_function(L, "bhv_animates_on_floor_switch_press_init", smlua_func_bhv_animates_on_floor_switch_press_init); @@ -33707,10 +33763,12 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "mario_moving_fast_enough_to_make_piranha_plant_bite", smlua_func_mario_moving_fast_enough_to_make_piranha_plant_bite); smlua_bind_function(L, "obj_set_secondary_camera_focus", smlua_func_obj_set_secondary_camera_focus); smlua_bind_function(L, "play_penguin_walking_sound", smlua_func_play_penguin_walking_sound); + smlua_bind_function(L, "spawn_ambient_light", smlua_func_spawn_ambient_light); smlua_bind_function(L, "spawn_default_star", smlua_func_spawn_default_star); smlua_bind_function(L, "spawn_mist_from_global", smlua_func_spawn_mist_from_global); smlua_bind_function(L, "spawn_mist_particles_variable", smlua_func_spawn_mist_particles_variable); smlua_bind_function(L, "spawn_no_exit_star", smlua_func_spawn_no_exit_star); + smlua_bind_function(L, "spawn_point_light", smlua_func_spawn_point_light); smlua_bind_function(L, "spawn_red_coin_cutscene_star", smlua_func_spawn_red_coin_cutscene_star); smlua_bind_function(L, "spawn_star_number", smlua_func_spawn_star_number); smlua_bind_function(L, "spawn_triangle_break_particles", smlua_func_spawn_triangle_break_particles);