From 4843e4e87a323c1d42b5e981d01df3a29fcb1157 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Fri, 19 Jun 2026 08:31:26 +0900 Subject: [PATCH] SealEngine: add light parameter storage and HLL bindings SealEngine manages a 41-float light parameter set (serialized as .lit file) for tone mapping, hemisphere lighting, and light scattering. This adds the storage and HLL plumbing, without wiring values into shaders. - A DIRECTIONAL_LIGHT instance owns a parameter set, filled by loading a .lit file (RE_instance_load). - SealEngine.StoreInstanceLightParam() reflects that presets into the plugin's master buffer, which is used by the renderer. - SealEngine.LoadInstanceLightParam() copies the master back into an instance, and Reset()/Set()/Get() operate directly on the master. --- include/reign.h | 27 +++++++++++++++++++ src/3d/3d_internal.h | 3 +++ src/3d/parser.c | 60 +++++++++++++++++++++++++++++++++++++++++++ src/3d/reign.c | 22 ++++++++++++++++ src/hll/ReignEngine.c | 56 ++++++++++++++++++++++++++++++++++------ 5 files changed, 160 insertions(+), 8 deletions(-) diff --git a/include/reign.h b/include/reign.h index ea06a57..c5acbe8 100644 --- a/include/reign.h +++ b/include/reign.h @@ -19,6 +19,7 @@ #define RE_NR_BACK_CGS 16 #define RE_NR_INSTANCE_TARGETS 2 +#define RE_NR_LIGHT_PARAMS 41 // .lit parameter count #include @@ -57,6 +58,29 @@ enum RE_fog_type { RE_FOG_LIGHT_SCATTERING = 2, }; +// Indices into light_params. Vector entries name their first component. +enum seal_light_param { + SEAL_LP_TONEMAP_EXPOSURE_BIAS = 0, + SEAL_LP_TONEMAP_WHITE_POINT = 1, + SEAL_LP_TONEMAP_A = 2, + SEAL_LP_TONEMAP_B = 3, + SEAL_LP_TONEMAP_C = 4, + SEAL_LP_TONEMAP_D = 5, + SEAL_LP_TONEMAP_E = 6, + SEAL_LP_TONEMAP_F = 7, + SEAL_LP_HEMI_VEC = 8, // x,y,z + SEAL_LP_HEMI_SKY_COLOR = 11, // r,g,b + SEAL_LP_HEMI_MID_COLOR = 14, // r,g,b + SEAL_LP_HEMI_GROUND_COLOR = 17, // r,g,b + SEAL_LP_LS_BETA_R = 20, + SEAL_LP_LS_BETA_M = 21, + SEAL_LP_LS_G = 22, + SEAL_LP_LS_DISTANCE = 23, + SEAL_LP_LS_LIGHT_VEC = 24, // x,y,z + SEAL_LP_LS_LIGHT_COLOR = 27, // r,g,b + SEAL_LP_LS_SUN_COLOR = 30, // r,g,b +}; + enum RE_draw_type { RE_DRAW_TYPE_NORMAL = 0, RE_DRAW_TYPE_ADDITIVE = 1, @@ -158,6 +182,7 @@ struct RE_plugin { // SealEngine int mag_speed; + float light_params[RE_NR_LIGHT_PARAMS]; }; struct RE_instance { @@ -197,6 +222,7 @@ struct RE_instance { // Lights vec3 vec; vec3 globe_diffuse; + float *light_params; // Private bool local_transform_needs_update; @@ -244,6 +270,7 @@ bool RE_instance_optimize_path_line(struct RE_instance *instance); bool RE_instance_calc_path_finder_intersect_eye_vec(struct RE_instance *instance, int mouse_x, int mouse_y, vec3 out); bool RE_plugin_transform_pos_to_view_pos(struct RE_plugin *plugin, float x, float y, float z, int *view_x, int *view_y); bool RE_plugin_get_camera_z_vector(struct RE_plugin *plugin, vec3 out); +void RE_plugin_reset_light_param(struct RE_plugin *plugin); int RE_motion_get_state(struct motion *motion); bool RE_motion_set_state(struct motion *motion, int state); diff --git a/src/3d/3d_internal.h b/src/3d/3d_internal.h index 8c755d2..f857520 100644 --- a/src/3d/3d_internal.h +++ b/src/3d/3d_internal.h @@ -790,6 +790,9 @@ struct amt_material *amt_find_material(struct amt *amt, const char *name); void opr_load(uint8_t *data, size_t size, struct pol *pol); void txa_load(uint8_t *data, size_t size, struct mot *mot); +void lit_reset(float *out); +bool lit_parse(uint8_t *data, size_t size, float *out); + // mpr.c struct mpr_float_key { int frame; float v; }; diff --git a/src/3d/parser.c b/src/3d/parser.c index a82af73..9f18552 100644 --- a/src/3d/parser.c +++ b/src/3d/parser.c @@ -687,3 +687,63 @@ void txa_load(uint8_t *data, size_t size, struct mot *mot) mot->nr_texture_indices = count; mot->texture_indices = indices; } + +void lit_reset(float *out) +{ + static const float lit_param_defaults[RE_NR_LIGHT_PARAMS] = { + [SEAL_LP_TONEMAP_EXPOSURE_BIAS] = 1.0f, + [SEAL_LP_TONEMAP_WHITE_POINT] = 1.0f, + [SEAL_LP_TONEMAP_A] = 0.22f, + [SEAL_LP_TONEMAP_B] = 0.30f, + [SEAL_LP_TONEMAP_C] = 0.10f, + [SEAL_LP_TONEMAP_D] = 0.20f, + [SEAL_LP_TONEMAP_E] = 0.01f, + [SEAL_LP_TONEMAP_F] = 0.30f, + [SEAL_LP_HEMI_VEC + 0] = -1.0f, + [SEAL_LP_HEMI_VEC + 1] = -1.0f, + [SEAL_LP_HEMI_VEC + 2] = 1.0f, + [SEAL_LP_HEMI_SKY_COLOR + 0] = 1.2f, + [SEAL_LP_HEMI_SKY_COLOR + 1] = 1.2f, + [SEAL_LP_HEMI_SKY_COLOR + 2] = 1.2f, + [SEAL_LP_HEMI_MID_COLOR + 0] = 0.5f, + [SEAL_LP_HEMI_MID_COLOR + 1] = 0.5f, + [SEAL_LP_HEMI_MID_COLOR + 2] = 0.5f, + [SEAL_LP_HEMI_GROUND_COLOR + 0] = 0.3f, + [SEAL_LP_HEMI_GROUND_COLOR + 1] = 0.3f, + [SEAL_LP_HEMI_GROUND_COLOR + 2] = 0.3f, + [SEAL_LP_LS_BETA_R] = 0.25f, + [SEAL_LP_LS_BETA_M] = 1.25f, + [SEAL_LP_LS_G] = 0.05f, + [SEAL_LP_LS_DISTANCE] = 140.0f, + [SEAL_LP_LS_LIGHT_VEC + 0] = -1.0f, + [SEAL_LP_LS_LIGHT_VEC + 1] = -1.0f, + [SEAL_LP_LS_LIGHT_VEC + 2] = 1.0f, + [SEAL_LP_LS_LIGHT_COLOR + 0] = 1.0f, + [SEAL_LP_LS_LIGHT_COLOR + 1] = 1.0f, + [SEAL_LP_LS_LIGHT_COLOR + 2] = 1.0f, + [SEAL_LP_LS_SUN_COLOR + 0] = 0.5f, + [SEAL_LP_LS_SUN_COLOR + 1] = 0.5f, + [SEAL_LP_LS_SUN_COLOR + 2] = 0.5f, + }; + memcpy(out, lit_param_defaults, sizeof(lit_param_defaults)); +} + +bool lit_parse(uint8_t *data, size_t size, float *out) +{ + if (size != 8 + RE_NR_LIGHT_PARAMS * 4 || memcmp(data, "LITP", 4) != 0) { + WARNING("invalid .lit file"); + return false; + } + struct buffer r; + buffer_init(&r, data, size); + buffer_skip(&r, 4); // "LITP" + int32_t version = buffer_read_int32(&r); + if (version != 0) { + WARNING("unsupported .lit version %d", version); + return false; + } + lit_reset(out); + for (int i = 0; i < RE_NR_LIGHT_PARAMS; i++) + out[i] = buffer_read_float(&r); + return true; +} diff --git a/src/3d/reign.c b/src/3d/reign.c index c249637..1e47f90 100644 --- a/src/3d/reign.c +++ b/src/3d/reign.c @@ -23,6 +23,7 @@ #include "system4.h" #include "system4/aar.h" +#include "system4/archive.h" #include "system4/cg.h" #include "system4/hashtable.h" #include "system4/string.h" @@ -98,6 +99,7 @@ static void unload_instance(struct RE_instance *instance) static void free_instance(struct RE_instance *instance) { unload_instance(instance); + free(instance->light_params); xfree_aligned(instance); } @@ -249,6 +251,7 @@ struct RE_plugin *RE_plugin_new(enum RE_plugin_version version) plugin->fog_near = 1.0; plugin->fog_far = 10.0; glm_vec3_one(plugin->fog_color); + lit_reset(plugin->light_params); return plugin; } @@ -431,6 +434,10 @@ bool RE_instance_set_type(struct RE_instance *instance, int type) instance->motion->instance = instance; break; case RE_ITYPE_DIRECTIONAL_LIGHT: + if (re_plugin_version >= RE_SEAL_PLUGIN) { + instance->light_params = xmalloc(RE_NR_LIGHT_PARAMS * sizeof(float)); + lit_reset(instance->light_params); + } break; case RE_ITYPE_SPECULAR_LIGHT: break; @@ -526,6 +533,16 @@ bool RE_instance_load(struct RE_instance *instance, const char *name) } } return true; + case RE_ITYPE_DIRECTIONAL_LIGHT: + if (re_plugin_version >= RE_SEAL_PLUGIN) { + struct archive_data *dfile = archive_get_by_name(instance->plugin->aar, name); + if (!dfile) + return false; + bool ok = lit_parse(dfile->data, dfile->size, instance->light_params); + archive_free_data(dfile); + return ok; + } + return false; default: WARNING("Invalid instance type %d", instance->type); return false; @@ -786,6 +803,11 @@ bool RE_plugin_get_camera_z_vector(struct RE_plugin *plugin, vec3 out) return true; } +void RE_plugin_reset_light_param(struct RE_plugin *plugin) +{ + lit_reset(plugin->light_params); +} + void RE_instance_update_local_transform(struct RE_instance *inst) { vec3 euler = { diff --git a/src/hll/ReignEngine.c b/src/hll/ReignEngine.c index c501453..808aaf4 100644 --- a/src/hll/ReignEngine.c +++ b/src/hll/ReignEngine.c @@ -16,6 +16,7 @@ #include #include +#include #include "system4.h" #include "system4/aar.h" @@ -2449,8 +2450,25 @@ static bool SealEngine_IsExistInstanceMotion(int plugin, int instance, struct st //bool SealEngine_AddLineList(int PluginNumber, int InstanceNumber, float X0, float Y0, float Z0, int Color0, float X1, float Y1, float Z1, int Color1); HLL_WARN_UNIMPLEMENTED(false, bool, SealEngine, SetInstanceCircleShadowRadius, int PluginNumber, int InstanceNumber, float CircleShadowRadius); //float SealEngine_GetInstanceCircleShadowRadius(int PluginNumber, int InstanceNumber); -//bool SealEngine_LoadInstanceLightParam(int PluginNumber, int InstanceNumber); -HLL_WARN_UNIMPLEMENTED(false, bool, SealEngine, StoreInstanceLightParam, int PluginNumber, int InstanceNumber); +static bool SealEngine_LoadInstanceLightParam(int plugin, int instance) +{ + struct RE_plugin *rp = get_plugin(plugin); + struct RE_instance *ri = get_instance(plugin, instance); + if (!rp || !ri || !ri->light_params) + return false; + memcpy(ri->light_params, rp->light_params, RE_NR_LIGHT_PARAMS * sizeof(float)); + return true; +} + +static bool SealEngine_StoreInstanceLightParam(int plugin, int instance) +{ + struct RE_plugin *rp = get_plugin(plugin); + struct RE_instance *ri = get_instance(plugin, instance); + if (!rp || !ri || !ri->light_params) + return false; + memcpy(rp->light_params, ri->light_params, RE_NR_LIGHT_PARAMS * sizeof(float)); + return true; +} static bool SealEngine_SetInstanceUseMagSpeed(int plugin, int instance, bool use_mag_speed) { struct RE_instance *ri = get_instance(plugin, instance); @@ -2517,9 +2535,31 @@ static bool SealEngine_TransformPosToViewPos(int PluginNumber, float x, float y, return RE_plugin_transform_pos_to_view_pos(get_plugin(PluginNumber), x, y, -z, view_x, view_y); } -HLL_WARN_UNIMPLEMENTED(false, bool, SealEngine, ResetLightParam, int PluginNumber); -//bool SealEngine_SetLightParam(int PluginNumber, int Type, float Value); -//float SealEngine_GetLightParam(int PluginNumber, int Type); +static bool SealEngine_ResetLightParam(int plugin) +{ + struct RE_plugin *rp = get_plugin(plugin); + if (!rp) + return false; + RE_plugin_reset_light_param(rp); + return true; +} + +static bool SealEngine_SetLightParam(int plugin, int type, float value) +{ + struct RE_plugin *rp = get_plugin(plugin); + if (!rp || (unsigned)type >= RE_NR_LIGHT_PARAMS) + return false; + rp->light_params[type] = value; + return true; +} + +static float SealEngine_GetLightParam(int plugin, int type) +{ + struct RE_plugin *rp = get_plugin(plugin); + if (!rp || (unsigned)type >= RE_NR_LIGHT_PARAMS) + return 0.0f; + return rp->light_params[type]; +} HLL_QUIET_UNIMPLEMENTED(false, bool, SealEngine, IsThreadLoadingMode, int PluginNumber); //bool SealEngine_ClearCache(int PluginNumber); //bool SealEngine_GetHistogram(int PluginNumber, struct page **HistogramList); @@ -2582,7 +2622,7 @@ HLL_QUIET_UNIMPLEMENTED(false, bool, SealEngine, IsThreadLoadingMode, int Plugin HLL_TODO_EXPORT(AddLineList, SealEngine_AddLineList), \ HLL_EXPORT(SetInstanceCircleShadowRadius, SealEngine_SetInstanceCircleShadowRadius), \ HLL_TODO_EXPORT(GetInstanceCircleShadowRadius, SealEngine_GetInstanceCircleShadowRadius), \ - HLL_TODO_EXPORT(LoadInstanceLightParam, SealEngine_LoadInstanceLightParam), \ + HLL_EXPORT(LoadInstanceLightParam, SealEngine_LoadInstanceLightParam), \ HLL_EXPORT(StoreInstanceLightParam, SealEngine_StoreInstanceLightParam), \ HLL_EXPORT(SetInstanceUseMagSpeed, SealEngine_SetInstanceUseMagSpeed), \ HLL_EXPORT(IsInstanceUseMagSpeed, SealEngine_IsInstanceUseMagSpeed), \ @@ -2623,8 +2663,8 @@ HLL_QUIET_UNIMPLEMENTED(false, bool, SealEngine, IsThreadLoadingMode, int Plugin HLL_TODO_EXPORT(GetOptimizedPathLine, SealEngine_GetOptimizedPathLine), \ HLL_EXPORT(TransformPosToViewPos, SealEngine_TransformPosToViewPos), \ HLL_EXPORT(ResetLightParam, SealEngine_ResetLightParam), \ - HLL_TODO_EXPORT(SetLightParam, SealEngine_SetLightParam), \ - HLL_TODO_EXPORT(GetLightParam, SealEngine_GetLightParam), \ + HLL_EXPORT(SetLightParam, SealEngine_SetLightParam), \ + HLL_EXPORT(GetLightParam, SealEngine_GetLightParam), \ HLL_EXPORT(IsThreadLoadingMode, SealEngine_IsThreadLoadingMode), \ HLL_TODO_EXPORT(ClearCache, SealEngine_ClearCache), \ HLL_TODO_EXPORT(GetHistogram, SealEngine_GetHistogram)