Speed up lighting engine by 80%

Lights are also zero indexed now which I could change to being one indexed but I think this is better anyway.
I restored ambient light objects setting it every frame since it broke a mod I was working on.
Sorry if any of these changes break anything you're working on dj.
Kaze would be proud though I bet
This commit is contained in:
Agent X 2025-07-17 15:41:06 -04:00
parent de96a75ddc
commit 74115c2aac
14 changed files with 318 additions and 314 deletions

View file

@ -28,7 +28,7 @@ const Gfx bully_seg5_dl_050002E0[] = {
// 0x05000398 - 0x05000408
const Gfx bully_seg5_dl_05000398[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_DECALRGB, G_CC_DECALRGB),
gsDPSetCombineMode(G_CC_MODULATERGBA, G_CC_MODULATERGBA),
gsSPClearGeometryMode(G_LIGHTING),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),

View file

@ -3618,7 +3618,7 @@ HUD_DISPLAY_DEFAULT = HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_CO
--- | `HUD_DISPLAY_DEFAULT`
--- @type integer
LE_MAX_LIGHTS = 128
LE_MAX_LIGHTS = 256
LE_MODE_AFFECT_ALL_SHADED_AND_COLORED = 0 --- @type LEMode
LE_MODE_AFFECT_ALL_SHADED = 1 --- @type LEMode

View file

@ -2915,8 +2915,8 @@ function uv_update_scroll()
-- ...
end
--- Behavior init function for the lighting engine ambient light. Takes the first 3 behavior parameter bytes for RGB color
function bhv_ambient_light_init()
--- Behavior loop function for the lighting engine ambient light. Takes the first 3 behavior parameter bytes for RGB color
function bhv_ambient_light_update()
-- ...
end
@ -4997,6 +4997,12 @@ function lvl_set_current_level(param, levelNum)
-- ...
end
--- @return boolean
--- Gets whether the lighting engine has been enabled or not. It becomes enabled once a light is added or the ambient color is set
function le_is_enabled()
-- ...
end
--- @param mode LEMode
--- Sets the lighting engine mode to `mode`
function le_set_mode(mode)
@ -5015,9 +5021,17 @@ function le_set_tone_mapping(toneMapping)
-- ...
end
--- @return boolean
--- Gets whether the lighting engine has been enabled or not. It becomes enabled once a light is added or the ambient color is set
function le_is_enabled()
--- @param out Color
--- Outputs the lighting engine's ambient color to `out`
function le_get_ambient_color(out)
-- ...
end
--- @param r integer
--- @param g integer
--- @param b integer
--- Sets the lighting engine ambient color
function le_set_ambient_color(r, g, b)
-- ...
end
@ -5078,20 +5092,6 @@ function le_light_exists(id)
-- ...
end
--- @param out Color
--- Outputs the lighting engine's ambient color to `out`
function le_get_ambient_color(out)
-- ...
end
--- @param r integer
--- @param g integer
--- @param b integer
--- Sets the lighting engine ambient color
function le_set_ambient_color(r, g, b)
-- ...
end
--- @param id integer
--- @param out Vec3f
--- Outputs a lighting engine point light's position to `out`

View file

@ -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[] = {

View file

@ -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),
};

View file

@ -11942,13 +11942,13 @@ Behavior loop function for UV texture scrolling
<br />
## [bhv_ambient_light_init](#bhv_ambient_light_init)
## [bhv_ambient_light_update](#bhv_ambient_light_update)
### Description
Behavior init function for the lighting engine ambient light. Takes the first 3 behavior parameter bytes for RGB color
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
@ -11957,7 +11957,7 @@ Behavior init 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:](#)

View file

@ -6633,6 +6633,27 @@ Sets the level number and handles the act select screen. `param` is used for ove
<br />
## [le_is_enabled](#le_is_enabled)
### Description
Gets whether the lighting engine has been enabled or not. It becomes enabled once a light is added or the ambient color is set
### Lua Example
`local booleanValue = le_is_enabled()`
### Parameters
- None
### Returns
- `boolean`
### C Prototype
`bool le_is_enabled(void);`
[:arrow_up_small:](#)
<br />
## [le_set_mode](#le_set_mode)
### Description
@ -6700,22 +6721,49 @@ Sets the lighting engine's tone mapping mode to `toneMapping`
<br />
## [le_is_enabled](#le_is_enabled)
## [le_get_ambient_color](#le_get_ambient_color)
### Description
Gets whether the lighting engine has been enabled or not. It becomes enabled once a light is added or the ambient color is set
Outputs the lighting engine's ambient color to `out`
### Lua Example
`local booleanValue = le_is_enabled()`
`le_get_ambient_color(out)`
### Parameters
- None
| Field | Type |
| ----- | ---- |
| out | [Color](structs.md#Color) |
### Returns
- `boolean`
- None
### C Prototype
`bool le_is_enabled(void);`
`void le_get_ambient_color(OUT Color out);`
[:arrow_up_small:](#)
<br />
## [le_set_ambient_color](#le_set_ambient_color)
### Description
Sets the lighting engine ambient color
### Lua Example
`le_set_ambient_color(r, g, b)`
### Parameters
| Field | Type |
| ----- | ---- |
| r | `integer` |
| g | `integer` |
| b | `integer` |
### Returns
- None
### C Prototype
`void le_set_ambient_color(u8 r, u8 g, u8 b);`
[:arrow_up_small:](#)
@ -6820,7 +6868,7 @@ Adds a lighting engine point light at `x`, `y`, `z` with color `r`, `g`, `b` and
- `integer`
### C Prototype
`s32 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity);`
`s16 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity);`
[:arrow_up_small:](#)
@ -6843,7 +6891,7 @@ Removes a lighting engine point light corresponding to `id`
- None
### C Prototype
`void le_remove_light(s32 id);`
`void le_remove_light(s16 id);`
[:arrow_up_small:](#)
@ -6864,7 +6912,7 @@ Gets the total number of lights currently loaded in the lighting engine
- `integer`
### C Prototype
`s32 le_get_light_count(void);`
`s16 le_get_light_count(void);`
[:arrow_up_small:](#)
@ -6887,55 +6935,7 @@ Checks if a lighting engine point light corresponding to `id` exists
- `boolean`
### C Prototype
`bool le_light_exists(s32 id);`
[:arrow_up_small:](#)
<br />
## [le_get_ambient_color](#le_get_ambient_color)
### Description
Outputs the lighting engine's ambient color to `out`
### Lua Example
`le_get_ambient_color(out)`
### Parameters
| Field | Type |
| ----- | ---- |
| out | [Color](structs.md#Color) |
### Returns
- None
### C Prototype
`void le_get_ambient_color(OUT Color out);`
[:arrow_up_small:](#)
<br />
## [le_set_ambient_color](#le_set_ambient_color)
### Description
Sets the lighting engine ambient color
### Lua Example
`le_set_ambient_color(r, g, b)`
### Parameters
| Field | Type |
| ----- | ---- |
| r | `integer` |
| g | `integer` |
| b | `integer` |
### Returns
- None
### C Prototype
`void le_set_ambient_color(u8 r, u8 g, u8 b);`
`bool le_light_exists(s16 id);`
[:arrow_up_small:](#)
@ -6959,7 +6959,7 @@ Outputs a lighting engine point light's position to `out`
- None
### C Prototype
`void le_get_light_pos(s32 id, OUT Vec3f out);`
`void le_get_light_pos(s16 id, OUT Vec3f out);`
[:arrow_up_small:](#)
@ -6985,7 +6985,7 @@ Sets a lighting engine point light's position to `x`, `y`, `z`
- None
### C Prototype
`void le_set_light_pos(s32 id, f32 x, f32 y, f32 z);`
`void le_set_light_pos(s16 id, f32 x, f32 y, f32 z);`
[:arrow_up_small:](#)
@ -7009,7 +7009,7 @@ Outputs a lighting engine point light's color to `out`
- None
### C Prototype
`void le_get_light_color(s32 id, OUT Color out);`
`void le_get_light_color(s16 id, OUT Color out);`
[:arrow_up_small:](#)
@ -7035,7 +7035,7 @@ Sets a lighting engine point light's color to `r`, `g`, `b`
- None
### C Prototype
`void le_set_light_color(s32 id, u8 r, u8 g, u8 b);`
`void le_set_light_color(s16 id, u8 r, u8 g, u8 b);`
[:arrow_up_small:](#)
@ -7058,7 +7058,7 @@ Gets a lighting engine point light's `radius`
- `number`
### C Prototype
`f32 le_get_light_radius(s32 id);`
`f32 le_get_light_radius(s16 id);`
[:arrow_up_small:](#)
@ -7082,7 +7082,7 @@ Sets a lighting engine point light's `radius`
- None
### C Prototype
`void le_set_light_radius(s32 id, f32 radius);`
`void le_set_light_radius(s16 id, f32 radius);`
[:arrow_up_small:](#)
@ -7105,7 +7105,7 @@ Gets a lighting engine point light's `intensity`
- `number`
### C Prototype
`f32 le_get_light_intensity(s32 id);`
`f32 le_get_light_intensity(s16 id);`
[:arrow_up_small:](#)
@ -7129,7 +7129,7 @@ Sets a lighting engine point light's `intensity`
- None
### C Prototype
`void le_set_light_intensity(s32 id, f32 intensity);`
`void le_set_light_intensity(s16 id, f32 intensity);`
[:arrow_up_small:](#)
@ -7152,7 +7152,7 @@ Gets whether a lighting engine point light will use a surface's normals to deter
- `boolean`
### C Prototype
`bool le_get_light_use_surface_normals(s32 id);`
`bool le_get_light_use_surface_normals(s16 id);`
[:arrow_up_small:](#)
@ -7176,7 +7176,7 @@ Sets whether a lighting engine point light will use a surface's normals to deter
- None
### C Prototype
`void le_set_light_use_surface_normals(s32 id, bool useSurfaceNormals);`
`void le_set_light_use_surface_normals(s16 id, bool useSurfaceNormals);`
[:arrow_up_small:](#)

View file

@ -605,7 +605,7 @@
- [bhv_yoshi_loop](functions-2.md#bhv_yoshi_loop)
- [bhv_volcano_trap_loop](functions-2.md#bhv_volcano_trap_loop)
- [uv_update_scroll](functions-2.md#uv_update_scroll)
- [bhv_ambient_light_init](functions-2.md#bhv_ambient_light_init)
- [bhv_ambient_light_update](functions-2.md#bhv_ambient_light_update)
- [bhv_point_light_init](functions-2.md#bhv_point_light_init)
- [bhv_point_light_loop](functions-2.md#bhv_point_light_loop)
- [spawn_default_star](functions-2.md#spawn_default_star)
@ -962,10 +962,12 @@
<br />
- lighting_engine.h
- [le_is_enabled](functions-3.md#le_is_enabled)
- [le_set_mode](functions-3.md#le_set_mode)
- [le_get_mode](functions-3.md#le_get_mode)
- [le_set_tone_mapping](functions-3.md#le_set_tone_mapping)
- [le_is_enabled](functions-3.md#le_is_enabled)
- [le_get_ambient_color](functions-3.md#le_get_ambient_color)
- [le_set_ambient_color](functions-3.md#le_set_ambient_color)
- [le_calculate_lighting_color](functions-3.md#le_calculate_lighting_color)
- [le_calculate_lighting_color_with_normal](functions-3.md#le_calculate_lighting_color_with_normal)
- [le_calculate_lighting_dir](functions-3.md#le_calculate_lighting_dir)
@ -973,8 +975,6 @@
- [le_remove_light](functions-3.md#le_remove_light)
- [le_get_light_count](functions-3.md#le_get_light_count)
- [le_light_exists](functions-3.md#le_light_exists)
- [le_get_ambient_color](functions-3.md#le_get_ambient_color)
- [le_set_ambient_color](functions-3.md#le_set_ambient_color)
- [le_get_light_pos](functions-3.md#le_get_light_pos)
- [le_set_light_pos](functions-3.md#le_set_light_pos)
- [le_get_light_color](functions-3.md#le_get_light_color)

View file

@ -1,12 +1,22 @@
#include "lighting_engine.h"
#include "math_util.h"
#include "surface_collision.h"
#include "pc/debuglog.h"
#include "data/dynos_cmap.cpp.h"
struct LELight
{
f32 posX;
f32 posY;
f32 posZ;
u8 colorR;
u8 colorG;
u8 colorB;
f32 radius;
f32 intensity;
bool added;
bool useSurfaceNormals;
};
Color gLEAmbientColor = { 127, 127, 127 };
static void* sLights = NULL;
static s32 sLightID = 0;
static struct LELight sLights[LE_MAX_LIGHTS] = { 0 };
static enum LEMode sMode = LE_MODE_AFFECT_ALL_SHADED_AND_COLORED;
static enum LEToneMapping sToneMapping = LE_TONE_MAPPING_WEIGHTED;
static bool sEnabled = false;
@ -42,6 +52,15 @@ void le_set_tone_mapping(enum LEToneMapping toneMapping) {
sToneMapping = toneMapping;
}
void le_get_ambient_color(OUT Color out) {
color_copy(out, gLEAmbientColor);
}
void le_set_ambient_color(u8 r, u8 g, u8 b) {
color_set(gLEAmbientColor, r, g, b);
sEnabled = true;
}
static inline void le_tone_map_total_weighted(Color out, Color inAmbient, Vec3f inColor, float weight) {
out[0] = clamp((inAmbient[0] + inColor[0]) / weight, 0, 255);
out[1] = clamp((inAmbient[1] + inColor[1]) / weight, 0, 255);
@ -120,15 +139,16 @@ static inline void le_calculate_light_contribution(struct LELight* light, Vec3f
}
void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, Color out) {
if (sLights == NULL) { return; }
// clear color
Vec3f color = { 0 };
// accumulate lighting
f32 weight = 1.0f;
for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) {
le_calculate_light_contribution(light, pos, NULL, 1, color, &weight);
for (s16 i = 0; i < LE_MAX_LIGHTS; i++) {
struct LELight* light = &sLights[i];
if (!light->added) { continue; }
le_calculate_light_contribution(light, pos, NULL, 1.0f, color, &weight);
}
// tone map and output
@ -141,14 +161,15 @@ void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, Color out) {
}
void le_calculate_lighting_color(Vec3f pos, Color out, f32 lightIntensityScalar) {
if (sLights == NULL) { return; }
// clear color
Vec3f color = { 0 };
// accumulate lighting
f32 weight = 1.0f;
for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) {
for (s16 i = 0; i < LE_MAX_LIGHTS; i++) {
struct LELight* light = &sLights[i];
if (!light->added) { continue; }
le_calculate_light_contribution(light, pos, NULL, lightIntensityScalar, color, &weight);
}
@ -157,8 +178,6 @@ void le_calculate_lighting_color(Vec3f pos, Color out, f32 lightIntensityScalar)
}
void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, Color out, f32 lightIntensityScalar) {
if (sLights == NULL) { return; }
// normalize normal
if (normal) { vec3f_normalize(normal); }
@ -167,7 +186,10 @@ void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, Color out,
// accumulate lighting
f32 weight = 1.0f;
for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) {
for (s16 i = 0; i < LE_MAX_LIGHTS; i++) {
struct LELight* light = &sLights[i];
if (!light->added) { continue; }
le_calculate_light_contribution(light, pos, normal, lightIntensityScalar, color, &weight);
}
@ -176,11 +198,13 @@ void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, Color out,
}
void le_calculate_lighting_dir(Vec3f pos, Vec3f out) {
if (sLights == NULL) { return; }
Vec3f lightingDir = { 0, 0, 0 };
s32 count = 1;
for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) {
s16 count = 1;
for (s16 i = 0; i < LE_MAX_LIGHTS; i++) {
struct LELight* light = &sLights[i];
if (!light->added) { continue; }
f32 diffX = light->posX - pos[0];
f32 diffY = light->posY - pos[1];
f32 diffZ = light->posZ - pos[2];
@ -209,159 +233,150 @@ void le_calculate_lighting_dir(Vec3f pos, Vec3f out) {
vec3f_normalize(out);
}
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;
s16 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity) {
struct LELight* newLight = NULL;
s16 lightID = -1;
for (s16 i = 0; i < LE_MAX_LIGHTS; i++) {
struct LELight* light = &sLights[i];
if (!light->added) {
newLight = light;
lightID = i;
break;
}
}
if (newLight == NULL) { return -1; }
newLight->posX = x;
newLight->posY = y;
newLight->posZ = z;
newLight->colorR = r;
newLight->colorG = g;
newLight->colorB = b;
newLight->radius = radius;
newLight->intensity = intensity;
newLight->added = true;
newLight->useSurfaceNormals = true;
sEnabled = true;
return lightID;
}
void le_remove_light(s16 id) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return; }
memset(&sLights[id], 0, sizeof(struct LELight));
}
s16 le_get_light_count(void) {
s16 count = 0;
for (s16 i = 0; i < LE_MAX_LIGHTS; i++) {
if (sLights[i].added) { count++; }
}
struct LELight* light = calloc(1, sizeof(struct LELight));
light->posX = x;
light->posY = y;
light->posZ = z;
light->colorR = r;
light->colorG = g;
light->colorB = b;
light->radius = radius;
light->intensity = intensity;
light->useSurfaceNormals = true;
hmap_put(sLights, ++sLightID, light);
sEnabled = true;
return sLightID;
return count;
}
void le_remove_light(s32 id) {
if (sLights == NULL || id <= 0) { return; }
free(hmap_get(sLights, id));
hmap_del(sLights, id);
bool le_light_exists(s16 id) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return false; }
return sLights[id].added;
}
s32 le_get_light_count(void) {
if (sLights == NULL) { return 0; }
return hmap_len(sLights);
}
void le_get_light_pos(s16 id, OUT Vec3f out) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return; }
bool le_light_exists(s32 id) {
if (sLights == NULL || id <= 0) { return false; }
return hmap_get(sLights, id) != NULL;
}
void le_get_ambient_color(OUT Color out) {
color_copy(out, gLEAmbientColor);
}
void le_set_ambient_color(u8 r, u8 g, u8 b) {
color_set(gLEAmbientColor, r, g, b);
sEnabled = true;
}
void le_get_light_pos(s32 id, OUT Vec3f out) {
if (sLights == NULL || id <= 0) { return; }
struct LELight* light = hmap_get(sLights, id);
if (light == NULL) { return; }
struct LELight* light = &sLights[id];
if (!light->added) { return; }
vec3f_set(out, light->posX, light->posY, light->posZ);
}
void le_set_light_pos(s32 id, f32 x, f32 y, f32 z) {
if (sLights == NULL || id <= 0) { return; }
void le_set_light_pos(s16 id, f32 x, f32 y, f32 z) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return; }
struct LELight* light = hmap_get(sLights, id);
if (light == NULL) { return; }
struct LELight* light = &sLights[id];
if (!light->added) { return; }
light->posX = x;
light->posY = y;
light->posZ = z;
}
void le_get_light_color(s32 id, OUT Color out) {
if (sLights == NULL || id <= 0) { return; }
void le_get_light_color(s16 id, OUT Color out) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return; }
struct LELight* light = hmap_get(sLights, id);
if (light == NULL) { return; }
struct LELight* light = &sLights[id];
if (!light->added) { return; }
color_set(out, light->colorR, light->colorG, light->colorB);
}
void le_set_light_color(s32 id, u8 r, u8 g, u8 b) {
if (sLights == NULL || id <= 0) { return; }
void le_set_light_color(s16 id, u8 r, u8 g, u8 b) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return; }
struct LELight* light = hmap_get(sLights, id);
if (light == NULL) { return; }
struct LELight* light = &sLights[id];
if (!light->added) { return; }
light->colorR = r;
light->colorG = g;
light->colorB = b;
}
f32 le_get_light_radius(s32 id) {
if (sLights == NULL || id <= 0) { return 0.0f; }
f32 le_get_light_radius(s16 id) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return 0.0f; }
struct LELight* light = hmap_get(sLights, id);
if (light == NULL) { return 0.0f; }
struct LELight* light = &sLights[id];
if (!light->added) { return 0.0f; }
return light->radius;
}
void le_set_light_radius(s32 id, f32 radius) {
if (sLights == NULL || id <= 0) { return; }
void le_set_light_radius(s16 id, f32 radius) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return; }
struct LELight* light = hmap_get(sLights, id);
if (light == NULL) { return; }
struct LELight* light = &sLights[id];
if (!light->added) { return; }
light->radius = radius;
}
f32 le_get_light_intensity(s32 id) {
if (sLights == NULL || id <= 0) { return 0.0f; }
f32 le_get_light_intensity(s16 id) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return 0.0f; }
struct LELight* light = hmap_get(sLights, id);
if (light == NULL) { return 0.0f; }
struct LELight* light = &sLights[id];
if (!light->added) { return 0.0f; }
return light->intensity;
}
void le_set_light_intensity(s32 id, f32 intensity) {
if (sLights == NULL || id <= 0) { return; }
void le_set_light_intensity(s16 id, f32 intensity) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return; }
struct LELight* light = hmap_get(sLights, id);
if (light == NULL) { return; }
struct LELight* light = &sLights[id];
if (!light->added) { return; }
light->intensity = intensity;
}
bool le_get_light_use_surface_normals(s32 id) {
if (sLights == NULL || id <= 0) { return false; }
bool le_get_light_use_surface_normals(s16 id) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return false; }
struct LELight* light = hmap_get(sLights, id);
if (light == NULL) { return false; }
struct LELight* light = &sLights[id];
if (!light->added) { return false; }
return light->useSurfaceNormals;
}
void le_set_light_use_surface_normals(s32 id, bool useSurfaceNormals) {
if (sLights == NULL || id <= 0) { return; }
void le_set_light_use_surface_normals(s16 id, bool useSurfaceNormals) {
if (id < 0 || id >= LE_MAX_LIGHTS) { return; }
struct LELight* light = hmap_get(sLights, id);
if (light == NULL) { return; }
struct LELight* light = &sLights[id];
if (!light->added) { return; }
light->useSurfaceNormals = useSurfaceNormals;
}
void le_clear(void) {
if (sLights == NULL) { return; }
memset(&sLights, 0, sizeof(struct LELight) * LE_MAX_LIGHTS);
for (struct LELight* light = hmap_begin(sLights); light != NULL; light = hmap_next(sLights)) {
free(light);
}
hmap_clear(sLights);
sLightID = 0;
gLEAmbientColor[0] = 127;
gLEAmbientColor[1] = 127;
gLEAmbientColor[2] = 127;
}
void le_shutdown(void) {
if (sLights == NULL) { return; }
sEnabled = false;
sMode = LE_MODE_AFFECT_ALL_SHADED_AND_COLORED;
sToneMapping = LE_TONE_MAPPING_WEIGHTED;
le_clear();
hmap_destroy(sLights);
sLights = NULL;
}

View file

@ -3,20 +3,7 @@
#include "types.h"
#define LE_MAX_LIGHTS 128
struct LELight
{
f32 posX;
f32 posY;
f32 posZ;
u8 colorR;
u8 colorG;
u8 colorB;
f32 radius;
f32 intensity;
bool useSurfaceNormals;
};
#define LE_MAX_LIGHTS 256
enum LEMode {
LE_MODE_AFFECT_ALL_SHADED_AND_COLORED,
@ -33,14 +20,18 @@ enum LEToneMapping {
extern Color gLEAmbientColor;
/* |description|Gets whether the lighting engine has been enabled or not. It becomes enabled once a light is added or the ambient color is set|descriptionEnd|*/
bool le_is_enabled(void);
/* |description|Sets the lighting engine mode to `mode`|descriptionEnd|*/
void le_set_mode(enum LEMode mode);
/* |description|Gets the lighting engine mode|descriptionEnd|*/
enum LEMode le_get_mode(void);
/* |description|Sets the lighting engine's tone mapping mode to `toneMapping`|descriptionEnd|*/
void le_set_tone_mapping(enum LEToneMapping toneMapping);
/* |description|Gets whether the lighting engine has been enabled or not. It becomes enabled once a light is added or the ambient color is set|descriptionEnd|*/
bool le_is_enabled(void);
/* |description|Outputs the lighting engine's ambient color to `out`|descriptionEnd| */
void le_get_ambient_color(OUT Color out);
/* |description|Sets the lighting engine ambient color|descriptionEnd| */
void le_set_ambient_color(u8 r, u8 g, u8 b);
void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, OUT Color out);
/* |description|Calculates the lighting with `lightIntensityScalar` at a position and outputs the color in `out`|descriptionEnd|*/
@ -50,37 +41,33 @@ void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, OUT Color
/* |description|Calculates the lighting direction from a position and outputs the result in `out`|descriptionEnd| */
void le_calculate_lighting_dir(Vec3f pos, OUT Vec3f out);
/* |description|Adds a lighting engine point light at `x`, `y`, `z` with color `r`, `g`, `b` and `radius` with `intensity`|descriptionEnd| */
s32 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity);
s16 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(s32 id);
void le_remove_light(s16 id);
/* |description|Gets the total number of lights currently loaded in the lighting engine|descriptionEnd| */
s32 le_get_light_count(void);
s16 le_get_light_count(void);
/* |description|Checks if a lighting engine point light corresponding to `id` exists|descriptionEnd| */
bool le_light_exists(s32 id);
/* |description|Outputs the lighting engine's ambient color to `out`|descriptionEnd| */
void le_get_ambient_color(OUT Color out);
/* |description|Sets the lighting engine ambient color|descriptionEnd| */
void le_set_ambient_color(u8 r, u8 g, u8 b);
bool le_light_exists(s16 id);
/* |description|Outputs a lighting engine point light's position to `out`|descriptionEnd| */
void le_get_light_pos(s32 id, OUT Vec3f out);
void le_get_light_pos(s16 id, OUT Vec3f out);
/* |description|Sets a lighting engine point light's position to `x`, `y`, `z`|descriptionEnd| */
void le_set_light_pos(s32 id, f32 x, f32 y, f32 z);
void le_set_light_pos(s16 id, f32 x, f32 y, f32 z);
/* |description|Outputs a lighting engine point light's color to `out`|descriptionEnd| */
void le_get_light_color(s32 id, OUT Color out);
void le_get_light_color(s16 id, OUT Color out);
/* |description|Sets a lighting engine point light's color to `r`, `g`, `b`|descriptionEnd| */
void le_set_light_color(s32 id, u8 r, u8 g, u8 b);
void le_set_light_color(s16 id, u8 r, u8 g, u8 b);
/* |description|Gets a lighting engine point light's `radius`|descriptionEnd| */
f32 le_get_light_radius(s32 id);
f32 le_get_light_radius(s16 id);
/* |description|Sets a lighting engine point light's `radius`|descriptionEnd| */
void le_set_light_radius(s32 id, f32 radius);
void le_set_light_radius(s16 id, f32 radius);
/* |description|Gets a lighting engine point light's `intensity`|descriptionEnd| */
f32 le_get_light_intensity(s32 id);
f32 le_get_light_intensity(s16 id);
/* |description|Sets a lighting engine point light's `intensity`|descriptionEnd| */
void le_set_light_intensity(s32 id, f32 intensity);
void le_set_light_intensity(s16 id, f32 intensity);
/* |description|Gets whether a lighting engine point light will use a surface's normals to determine its brightness with `useSurfaceNormals`|descriptionEnd| */
bool le_get_light_use_surface_normals(s32 id);
bool le_get_light_use_surface_normals(s16 id);
/* |description|Sets whether a lighting engine point light will use a surface's normals to determine its brightness with `useSurfaceNormals`|descriptionEnd| */
void le_set_light_use_surface_normals(s32 id, bool useSurfaceNormals);
void le_set_light_use_surface_normals(s16 id, bool useSurfaceNormals);
void le_clear(void);
void le_shutdown(void);

View file

@ -1145,8 +1145,8 @@ 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|Behavior init function for the lighting engine ambient light. Takes the first 3 behavior parameter bytes for RGB color|descriptionEnd| */
void bhv_ambient_light_init(void);
/* |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_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| */

View file

@ -1,4 +1,4 @@
void bhv_ambient_light_init(void) {
void bhv_ambient_light_update(void) {
le_set_ambient_color(
(o->oBehParams >> 24) & 0xFF,
(o->oBehParams >> 16) & 0xFF,

View file

@ -1784,7 +1784,7 @@ char gSmluaConstants[] = ""
"HUD_DISPLAY_FLAG_EMPHASIZE_POWER=0x8000\n"
"HUD_DISPLAY_NONE=0x0000\n"
"HUD_DISPLAY_DEFAULT=HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_CAMERA | HUD_DISPLAY_FLAG_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020\n"
"LE_MAX_LIGHTS=128\n"
"LE_MAX_LIGHTS=256\n"
"LE_MODE_AFFECT_ALL_SHADED_AND_COLORED=0\n"
"LE_MODE_AFFECT_ALL_SHADED=1\n"
"LE_MODE_AFFECT_ONLY_GEOMETRY_MODE=2\n"

View file

@ -9678,18 +9678,18 @@ int smlua_func_uv_update_scroll(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;
}
@ -15460,6 +15460,21 @@ int smlua_func_lvl_set_current_level(lua_State* L) {
// lighting_engine.h //
///////////////////////
int smlua_func_le_is_enabled(UNUSED lua_State* L) {
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", "le_is_enabled", 0, top);
return 0;
}
lua_pushboolean(L, le_is_enabled());
return 1;
}
int smlua_func_le_set_mode(lua_State* L) {
if (L == NULL) { return 0; }
@ -15509,17 +15524,44 @@ int smlua_func_le_set_tone_mapping(lua_State* L) {
return 1;
}
int smlua_func_le_is_enabled(UNUSED lua_State* L) {
int smlua_func_le_get_ambient_color(lua_State* L) {
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", "le_is_enabled", 0, top);
if (top != 1) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "le_get_ambient_color", 1, top);
return 0;
}
lua_pushboolean(L, le_is_enabled());
Color out;
smlua_get_color(out, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_get_ambient_color"); return 0; }
le_get_ambient_color(out);
smlua_push_color(out, 1);
return 1;
}
int smlua_func_le_set_ambient_color(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 3) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "le_set_ambient_color", 3, top);
return 0;
}
u8 r = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_ambient_color"); return 0; }
u8 g = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "le_set_ambient_color"); return 0; }
u8 b = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "le_set_ambient_color"); return 0; }
le_set_ambient_color(r, g, b);
return 1;
}
@ -15647,7 +15689,7 @@ int smlua_func_le_remove_light(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_remove_light"); return 0; }
le_remove_light(id);
@ -15679,7 +15721,7 @@ int smlua_func_le_light_exists(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_light_exists"); return 0; }
lua_pushboolean(L, le_light_exists(id));
@ -15687,48 +15729,6 @@ int smlua_func_le_light_exists(lua_State* L) {
return 1;
}
int smlua_func_le_get_ambient_color(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 1) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "le_get_ambient_color", 1, top);
return 0;
}
Color out;
smlua_get_color(out, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_get_ambient_color"); return 0; }
le_get_ambient_color(out);
smlua_push_color(out, 1);
return 1;
}
int smlua_func_le_set_ambient_color(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 3) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "le_set_ambient_color", 3, top);
return 0;
}
u8 r = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_ambient_color"); return 0; }
u8 g = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "le_set_ambient_color"); return 0; }
u8 b = smlua_to_integer(L, 3);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "le_set_ambient_color"); return 0; }
le_set_ambient_color(r, g, b);
return 1;
}
int smlua_func_le_get_light_pos(lua_State* L) {
if (L == NULL) { return 0; }
@ -15738,7 +15738,7 @@ int smlua_func_le_get_light_pos(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_get_light_pos"); return 0; }
Vec3f out;
@ -15761,7 +15761,7 @@ int smlua_func_le_set_light_pos(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_light_pos"); return 0; }
f32 x = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "le_set_light_pos"); return 0; }
@ -15784,7 +15784,7 @@ int smlua_func_le_get_light_color(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_get_light_color"); return 0; }
Color out;
@ -15807,7 +15807,7 @@ int smlua_func_le_set_light_color(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_light_color"); return 0; }
u8 r = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "le_set_light_color"); return 0; }
@ -15830,7 +15830,7 @@ int smlua_func_le_get_light_radius(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_get_light_radius"); return 0; }
lua_pushnumber(L, le_get_light_radius(id));
@ -15847,7 +15847,7 @@ int smlua_func_le_set_light_radius(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_light_radius"); return 0; }
f32 radius = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "le_set_light_radius"); return 0; }
@ -15866,7 +15866,7 @@ int smlua_func_le_get_light_intensity(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_get_light_intensity"); return 0; }
lua_pushnumber(L, le_get_light_intensity(id));
@ -15883,7 +15883,7 @@ int smlua_func_le_set_light_intensity(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_light_intensity"); return 0; }
f32 intensity = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "le_set_light_intensity"); return 0; }
@ -15902,7 +15902,7 @@ int smlua_func_le_get_light_use_surface_normals(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_get_light_use_surface_normals"); return 0; }
lua_pushboolean(L, le_get_light_use_surface_normals(id));
@ -15919,7 +15919,7 @@ int smlua_func_le_set_light_use_surface_normals(lua_State* L) {
return 0;
}
s32 id = smlua_to_integer(L, 1);
s16 id = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_light_use_surface_normals"); return 0; }
bool useSurfaceNormals = smlua_to_boolean(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "le_set_light_use_surface_normals"); return 0; }
@ -36888,7 +36888,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "bhv_yoshi_loop", smlua_func_bhv_yoshi_loop);
smlua_bind_function(L, "bhv_volcano_trap_loop", smlua_func_bhv_volcano_trap_loop);
smlua_bind_function(L, "uv_update_scroll", smlua_func_uv_update_scroll);
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_point_light_init", smlua_func_bhv_point_light_init);
smlua_bind_function(L, "bhv_point_light_loop", smlua_func_bhv_point_light_loop);
//smlua_bind_function(L, "geo_move_mario_part_from_parent", smlua_func_geo_move_mario_part_from_parent); <--- UNIMPLEMENTED
@ -37219,10 +37219,12 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "lvl_set_current_level", smlua_func_lvl_set_current_level);
// lighting_engine.h
smlua_bind_function(L, "le_is_enabled", smlua_func_le_is_enabled);
smlua_bind_function(L, "le_set_mode", smlua_func_le_set_mode);
smlua_bind_function(L, "le_get_mode", smlua_func_le_get_mode);
smlua_bind_function(L, "le_set_tone_mapping", smlua_func_le_set_tone_mapping);
smlua_bind_function(L, "le_is_enabled", smlua_func_le_is_enabled);
smlua_bind_function(L, "le_get_ambient_color", smlua_func_le_get_ambient_color);
smlua_bind_function(L, "le_set_ambient_color", smlua_func_le_set_ambient_color);
smlua_bind_function(L, "le_calculate_lighting_color", smlua_func_le_calculate_lighting_color);
smlua_bind_function(L, "le_calculate_lighting_color_with_normal", smlua_func_le_calculate_lighting_color_with_normal);
smlua_bind_function(L, "le_calculate_lighting_dir", smlua_func_le_calculate_lighting_dir);
@ -37230,8 +37232,6 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "le_remove_light", smlua_func_le_remove_light);
smlua_bind_function(L, "le_get_light_count", smlua_func_le_get_light_count);
smlua_bind_function(L, "le_light_exists", smlua_func_le_light_exists);
smlua_bind_function(L, "le_get_ambient_color", smlua_func_le_get_ambient_color);
smlua_bind_function(L, "le_set_ambient_color", smlua_func_le_set_ambient_color);
smlua_bind_function(L, "le_get_light_pos", smlua_func_le_get_light_pos);
smlua_bind_function(L, "le_set_light_pos", smlua_func_le_set_light_pos);
smlua_bind_function(L, "le_get_light_color", smlua_func_le_get_light_color);