diff --git a/src/libtrx/game/level/common.c b/src/libtrx/game/level/common.c index 9df504a37..0edc1bb2d 100644 --- a/src/libtrx/game/level/common.c +++ b/src/libtrx/game/level/common.c @@ -144,11 +144,11 @@ void Level_ReadRoomMesh(const int32_t room_num, VFILE *const file) for (int32_t i = 0; i < room->mesh.num_vertices; i++) { ROOM_VERTEX *const vertex = &room->mesh.vertices[i]; M_ReadVertex(&vertex->pos, file); + vertex->light_base = VFile_ReadS16(file); #if TR_VERSION == 1 - vertex->shade = VFile_ReadU16(file); vertex->flags = 0; + vertex->light_adder = vertex->light_base; #elif TR_VERSION == 2 - vertex->light_base = VFile_ReadS16(file); vertex->light_table_value = VFile_ReadU8(file); vertex->flags = VFile_ReadU8(file); vertex->light_adder = VFile_ReadS16(file); diff --git a/src/libtrx/game/output.c b/src/libtrx/game/output.c new file mode 100644 index 000000000..507a41f4b --- /dev/null +++ b/src/libtrx/game/output.c @@ -0,0 +1,295 @@ +#include "game/output.h" + +#include "game/const.h" +#include "game/matrix.h" +#include "utils.h" + +#define MAX_DYNAMIC_LIGHTS 10 + +typedef struct { + XYZ_32 pos; + int32_t shade; +} COMMON_LIGHT; + +static int32_t m_DynamicLightCount = 0; +static LIGHT m_DynamicLights[MAX_DYNAMIC_LIGHTS] = {}; + +static void M_CalculateBrightestLight( + XYZ_32 pos, const ROOM *room, COMMON_LIGHT *brightest_light); +static int32_t M_CalculateDynamicLight( + XYZ_32 pos, COMMON_LIGHT *brightest_light); + +static void M_CalculateBrightestLight( + const XYZ_32 pos, const ROOM *const room, + COMMON_LIGHT *const brightest_light) +{ +#if TR_VERSION == 2 + if (room->light_mode != RLM_NORMAL) { + const int32_t light_shade = Output_GetRoomLightShade(room->light_mode); + for (int32_t i = 0; i < room->num_lights; i++) { + const LIGHT *const light = &room->lights[i]; + const int32_t dx = pos.x - light->pos.x; + const int32_t dy = pos.y - light->pos.y; + const int32_t dz = pos.z - light->pos.z; + + const int32_t falloff_1 = SQUARE(light->falloff.value_1) >> 12; + const int32_t falloff_2 = SQUARE(light->falloff.value_2) >> 12; + const int32_t dist = (SQUARE(dx) + SQUARE(dy) + SQUARE(dz)) >> 12; + + const int32_t shade_1 = + falloff_1 * light->shade.value_1 / (falloff_1 + dist); + const int32_t shade_2 = + falloff_2 * light->shade.value_2 / (falloff_2 + dist); + const int32_t shade = + shade_1 + (shade_2 - shade_1) * light_shade / (WIBBLE_SIZE - 1); + + if (shade > brightest_light->shade) { + brightest_light->shade = shade; + brightest_light->pos = light->pos; + } + } + return; + } +#endif + + const int32_t ambient = TR_VERSION == 1 ? (0x1FFF - room->ambient) : 0; + for (int32_t i = 0; i < room->num_lights; i++) { + const LIGHT *const light = &room->lights[i]; + const int32_t dx = pos.x - light->pos.x; + const int32_t dy = pos.y - light->pos.y; + const int32_t dz = pos.z - light->pos.z; + const int32_t falloff = SQUARE(light->falloff.value_1) >> 12; + const int32_t dist = (SQUARE(dx) + SQUARE(dy) + SQUARE(dz)) >> 12; + const int32_t shade = + ambient + (falloff * light->shade.value_1 / (falloff + dist)); + if (shade > brightest_light->shade) { + brightest_light->shade = shade; + brightest_light->pos = light->pos; + } + } +} + +static int32_t M_CalculateDynamicLight( + const XYZ_32 pos, COMMON_LIGHT *const brightest_light) +{ + int32_t adder = 0; + for (int32_t i = 0; i < m_DynamicLightCount; i++) { + const LIGHT *const light = &m_DynamicLights[i]; + const int32_t dx = pos.x - light->pos.x; + const int32_t dy = pos.y - light->pos.y; + const int32_t dz = pos.z - light->pos.z; + const int32_t radius = 1 << light->falloff.value_1; + if (dx < -radius || dx > radius || dy < -radius || dy > radius + || dz < -radius || dz > radius) { + continue; + } + + const int32_t dist = SQUARE(dx) + SQUARE(dy) + SQUARE(dz); + if (dist > SQUARE(radius)) { + continue; + } + + const int32_t shade = (1 << light->shade.value_1) + - (dist >> (2 * light->falloff.value_1 - light->shade.value_1)); + if (shade > brightest_light->shade) { + brightest_light->shade = shade; + brightest_light->pos = light->pos; + } + adder += shade; + } + + return adder; +} + +void Output_CalculateLight(const XYZ_32 pos, const int16_t room_num) +{ + const ROOM *const room = Room_Get(room_num); + COMMON_LIGHT brightest_light = {}; + + M_CalculateBrightestLight(pos, room, &brightest_light); + int32_t adder = brightest_light.shade; + int32_t dynamic_adder = M_CalculateDynamicLight(pos, &brightest_light); + + adder = (adder + dynamic_adder) / 2; + if (TR_VERSION == 1 && (room->num_lights > 0 || dynamic_adder > 0)) { + adder += (0x1FFF - room->ambient) / 2; + } + + // TODO: use m_LsAdder and m_LsDivider once ported + int32_t global_adder; + int32_t global_divider; + if (adder == 0) { + global_adder = room->ambient; + global_divider = 0; + } else { +#if TR_VERSION == 1 + global_adder = 0x1FFF - adder; + global_divider = + (1 << (W2V_SHIFT + 12)) / (brightest_light.shade - adder); +#else + global_adder = room->ambient - adder; + global_divider = (1 << (W2V_SHIFT + 12)) / adder; +#endif + int16_t angles[2]; + Math_GetVectorAngles( + pos.x - brightest_light.pos.x, pos.y - brightest_light.pos.y, + pos.z - brightest_light.pos.z, angles); + Output_RotateLight(angles[1], angles[0]); + } + + const int32_t depth = g_MatrixPtr->_23 >> W2V_SHIFT; + global_adder += Output_CalcFogShade(depth); + CLAMPG(global_adder, 0x1FFF); + + Output_SetLightAdder(global_adder); + Output_SetLightDivider(global_divider); +} + +void Output_CalculateStaticLight(const int16_t adder) +{ + // TODO: use m_LsAdder + int32_t global_adder = adder - 0x1000; + const int32_t depth = g_MatrixPtr->_23 >> W2V_SHIFT; + global_adder += Output_CalcFogShade(depth); + CLAMPG(global_adder, 0x1FFF); + Output_SetLightAdder(global_adder); +} + +void Output_CalculateStaticMeshLight( + const XYZ_32 pos, const SHADE shade, const ROOM *const room) +{ + int32_t adder = shade.value_1; + if (TR_VERSION == 2 && room->light_mode != RLM_NORMAL) { + const int32_t room_shade = Output_GetRoomLightShade(room->light_mode); + adder += + (shade.value_2 - shade.value_1) * room_shade / (WIBBLE_SIZE - 1); + } + + for (int32_t i = 0; i < m_DynamicLightCount; i++) { + const LIGHT *const light = &m_DynamicLights[i]; + const int32_t dx = pos.x - light->pos.x; + const int32_t dy = pos.y - light->pos.y; + const int32_t dz = pos.z - light->pos.z; + const int32_t radius = 1 << light->falloff.value_1; + if (dx < -radius || dx > radius || dy < -radius || dy > radius + || dz < -radius || dz > radius) { + continue; + } + + const int32_t dist = SQUARE(dx) + SQUARE(dy) + SQUARE(dz); + if (dist > SQUARE(radius)) { + continue; + } + + const int32_t shade = (1 << light->shade.value_1) + - (dist >> (2 * light->falloff.value_1 - light->shade.value_1)); + adder -= shade; + if (adder < 0) { + break; + } + } + + Output_CalculateStaticLight(adder); +} + +void Output_CalculateObjectLighting( + const ITEM *const item, const BOUNDS_16 *const bounds) +{ + if (item->shade.value_1 >= 0) { + Output_CalculateStaticMeshLight( + item->pos, item->shade, Room_Get(item->room_num)); + return; + } + + Matrix_PushUnit(); + + Matrix_TranslateSet(0, 0, 0); + Matrix_Rot16(item->rot); + Matrix_TranslateRel32((XYZ_32) { + .x = (bounds->min.x + bounds->max.x) / 2, + .y = (bounds->max.y + bounds->min.y) / 2, + .z = (bounds->max.z + bounds->min.z) / 2, + }); + const XYZ_32 pos = { + .x = item->pos.x + (g_MatrixPtr->_03 >> W2V_SHIFT), + .y = item->pos.y + (g_MatrixPtr->_13 >> W2V_SHIFT), + .z = item->pos.z + (g_MatrixPtr->_23 >> W2V_SHIFT), + }; + Matrix_Pop(); + + Output_CalculateLight(pos, item->room_num); +} + +void Output_LightRoom(ROOM *const room) +{ + if (TR_VERSION == 2 && room->light_mode != RLM_NORMAL) { + Output_LightRoomVertices(room); + } else if (room->flags & RF_DYNAMIC_LIT) { + for (int32_t i = 0; i < room->mesh.num_vertices; i++) { + ROOM_VERTEX *const vtx = &room->mesh.vertices[i]; + vtx->light_adder = vtx->light_base; + } + room->flags &= ~RF_DYNAMIC_LIT; + } + + const int32_t x_min = WALL_L; + const int32_t z_min = WALL_L; + const int32_t x_max = (room->size.x - 1) * WALL_L; + const int32_t z_max = (room->size.z - 1) * WALL_L; + + for (int32_t i = 0; i < m_DynamicLightCount; i++) { + const LIGHT *const light = &m_DynamicLights[i]; + const int32_t x = light->pos.x - room->pos.x; + const int32_t y = light->pos.y; + const int32_t z = light->pos.z - room->pos.z; + const int32_t radius = 1 << light->falloff.value_1; + if (x - radius > x_max || z - radius > z_max || x + radius < x_min + || z + radius < z_min) { + continue; + } + + room->flags |= RF_DYNAMIC_LIT; + + for (int32_t j = 0; j < room->mesh.num_vertices; j++) { + ROOM_VERTEX *const v = &room->mesh.vertices[j]; + if (v->light_adder == 0) { + continue; + } + + const int32_t dx = v->pos.x - x; + const int32_t dy = v->pos.y - y; + const int32_t dz = v->pos.z - z; + if (dx < -radius || dx > radius || dy < -radius || dy > radius + || dz < -radius || dz > radius) { + continue; + } + + const int32_t dist = SQUARE(dx) + SQUARE(dy) + SQUARE(dz); + if (dist > SQUARE(radius)) { + continue; + } + + const int32_t shade = (1 << light->shade.value_1) + - (dist >> (2 * light->falloff.value_1 - light->shade.value_1)); + v->light_adder -= shade; + CLAMPL(v->light_adder, 0); + } + } +} + +void Output_ResetDynamicLights(void) +{ + m_DynamicLightCount = 0; +} + +void Output_AddDynamicLight( + const XYZ_32 pos, const int32_t intensity, const int32_t falloff) +{ + const int32_t idx = + m_DynamicLightCount < MAX_DYNAMIC_LIGHTS ? m_DynamicLightCount++ : 0; + + LIGHT *const light = &m_DynamicLights[idx]; + light->pos = pos; + light->shade.value_1 = intensity; + light->falloff.value_1 = falloff; +} diff --git a/src/libtrx/include/libtrx/game/items/types.h b/src/libtrx/include/libtrx/game/items/types.h index ccf4650c5..a6d5e81a2 100644 --- a/src/libtrx/include/libtrx/game/items/types.h +++ b/src/libtrx/include/libtrx/game/items/types.h @@ -2,6 +2,7 @@ #include "../math.h" #include "../objects/ids.h" +#include "../output/types.h" #include "./enum.h" #if TR_VERSION == 1 @@ -41,15 +42,13 @@ typedef struct { int16_t timer; uint16_t flags; + SHADE shade; #if TR_VERSION == 1 - int16_t shade; void *data; void *priv; CARRIED_ITEM *carried_item; bool enable_shadow; #elif TR_VERSION == 2 - int16_t shade_1; - int16_t shade_2; int16_t carried_item; void *data; #endif diff --git a/src/libtrx/include/libtrx/game/output.h b/src/libtrx/include/libtrx/game/output.h index 1d61544b8..6d0bbe225 100644 --- a/src/libtrx/include/libtrx/game/output.h +++ b/src/libtrx/include/libtrx/game/output.h @@ -3,6 +3,7 @@ #include "./output/const.h" #include "./output/types.h" #include "./output/vars.h" +#include "./rooms.h" #include @@ -29,3 +30,17 @@ extern void Output_SetupAboveWater(bool is_underwater); extern void Output_RotateLight(int16_t pitch, int16_t yaw); extern void Output_SetLightAdder(int32_t adder); extern void Output_SetLightDivider(int32_t divider); + +// Temporary +extern int32_t Output_CalcFogShade(int32_t depth); +extern int32_t Output_GetRoomLightShade(ROOM_LIGHT_MODE mode); +extern void Output_LightRoomVertices(const ROOM *room); + +void Output_CalculateLight(XYZ_32 pos, int16_t room_num); +void Output_CalculateStaticLight(int16_t adder); +void Output_CalculateStaticMeshLight(XYZ_32 pos, SHADE shade, const ROOM *room); +void Output_CalculateObjectLighting(const ITEM *item, const BOUNDS_16 *bounds); +void Output_LightRoom(ROOM *room); + +void Output_ResetDynamicLights(void); +void Output_AddDynamicLight(XYZ_32 pos, int32_t intensity, int32_t falloff); diff --git a/src/libtrx/include/libtrx/game/output/const.h b/src/libtrx/include/libtrx/game/output/const.h index 8db1db48b..2eda64ed2 100644 --- a/src/libtrx/include/libtrx/game/output/const.h +++ b/src/libtrx/include/libtrx/game/output/const.h @@ -7,3 +7,5 @@ #define MAX_OBJECT_TEXTURES 2048 #define MAX_SPRITE_TEXTURES 512 #endif + +#define WIBBLE_SIZE 32 diff --git a/src/libtrx/include/libtrx/game/output/types.h b/src/libtrx/include/libtrx/game/output/types.h index 9a6eaab67..c22a5fefd 100644 --- a/src/libtrx/include/libtrx/game/output/types.h +++ b/src/libtrx/include/libtrx/game/output/types.h @@ -2,6 +2,16 @@ #include +typedef struct { + int16_t value_1; + int16_t value_2; +} SHADE; + +typedef struct { + int32_t value_1; + int32_t value_2; +} FALLOFF; + typedef struct { uint16_t u; uint16_t v; diff --git a/src/libtrx/include/libtrx/game/rooms/enum.h b/src/libtrx/include/libtrx/game/rooms/enum.h index f3986aef7..d7c620c8c 100644 --- a/src/libtrx/include/libtrx/game/rooms/enum.h +++ b/src/libtrx/include/libtrx/game/rooms/enum.h @@ -8,6 +8,14 @@ typedef enum { RF_INSIDE = 0x40, } ROOM_FLAG; +typedef enum { + RLM_NORMAL = 0, + RLM_FLICKER = 1, + RLM_GLOW = 2, + RLM_SUNSET = 3, + RLM_NUMBER_OF = 4, +} ROOM_LIGHT_MODE; + typedef enum { FT_FLOOR = 0, FT_DOOR = 1, diff --git a/src/libtrx/include/libtrx/game/rooms/types.h b/src/libtrx/include/libtrx/game/rooms/types.h index f8a2dcc49..a3554a452 100644 --- a/src/libtrx/include/libtrx/game/rooms/types.h +++ b/src/libtrx/include/libtrx/game/rooms/types.h @@ -58,27 +58,19 @@ typedef struct { typedef struct { XYZ_32 pos; -#if TR_VERSION == 1 - int16_t intensity; - int32_t falloff; -#elif TR_VERSION == 2 - int16_t intensity_1; - int16_t intensity_2; - int32_t falloff_1; - int32_t falloff_2; -#endif + SHADE shade; + FALLOFF falloff; } LIGHT; typedef struct { XYZ_16 pos; + int16_t light_base; + int16_t light_adder; #if TR_VERSION == 1 uint16_t flags; - uint16_t shade; #elif TR_VERSION == 2 - int16_t light_base; uint8_t light_table_value; uint8_t flags; - int16_t light_adder; #endif } ROOM_VERTEX; @@ -103,12 +95,7 @@ typedef struct { struct { int16_t y; } rot; -#if TR_VERSION == 1 - uint16_t shade; -#elif TR_VERSION == 2 - int16_t shade_1; - int16_t shade_2; -#endif + SHADE shade; int16_t static_num; } STATIC_MESH; @@ -125,13 +112,8 @@ typedef struct { int16_t z; int16_t x; } size; -#if TR_VERSION == 1 int16_t ambient; -#else - int16_t ambient_1; - int16_t ambient_2; - int16_t light_mode; -#endif + ROOM_LIGHT_MODE light_mode; int16_t num_lights; int16_t num_static_meshes; int16_t bound_left; diff --git a/src/libtrx/meson.build b/src/libtrx/meson.build index 73b69b1ee..9153b0043 100644 --- a/src/libtrx/meson.build +++ b/src/libtrx/meson.build @@ -131,6 +131,7 @@ sources = [ 'game/objects/common.c', 'game/objects/names.c', 'game/objects/vars.c', + 'game/output.c', 'game/phase/executor.c', 'game/phase/phase_cutscene.c', 'game/phase/phase_demo.c', diff --git a/src/tr1/game/effects.c b/src/tr1/game/effects.c index b44ccf1ac..7b0e633e4 100644 --- a/src/tr1/game/effects.c +++ b/src/tr1/game/effects.c @@ -161,8 +161,7 @@ void Effect_Draw(const int16_t effect_num) Object_DrawMesh(object->mesh_idx, -1, false); } else { Output_CalculateLight( - effect->interp.result.pos.x, effect->interp.result.pos.y, - effect->interp.result.pos.z, effect->room_num); + effect->interp.result.pos, effect->room_num); Object_DrawMesh(effect->frame_num, -1, false); } } diff --git a/src/tr1/game/inject.c b/src/tr1/game/inject.c index 54e586ea2..211d10ad8 100644 --- a/src/tr1/game/inject.c +++ b/src/tr1/game/inject.c @@ -1131,7 +1131,7 @@ static void M_TriggeredItem(INJECTION *injection, LEVEL_INFO *level_info) item->pos.y = VFile_ReadS32(fp); item->pos.z = VFile_ReadS32(fp); item->rot.y = VFile_ReadS16(fp); - item->shade = VFile_ReadS16(fp); + item->shade.value_1 = VFile_ReadS16(fp); item->flags = VFile_ReadU16(fp); level_info->item_count++; @@ -1256,8 +1256,9 @@ static void M_AlterRoomVertex(const INJECTION *const injection) vertex->pos.x += x_change; vertex->pos.y += y_change; vertex->pos.z += z_change; - vertex->shade += shade_change; - CLAMPG(vertex->shade, MAX_LIGHTING); + vertex->light_base += shade_change; + CLAMPG(vertex->light_base, MAX_LIGHTING); + vertex->light_adder = vertex->light_base; } static void M_RotateRoomFace(const INJECTION *const injection) @@ -1362,7 +1363,8 @@ static void M_AddRoomVertex(const INJECTION *const injection) ROOM *const room = Room_Get(target_room); ROOM_VERTEX *const vertex = &room->mesh.vertices[room->mesh.num_vertices]; vertex->pos = pos; - vertex->shade = shade; + vertex->light_base = shade; + vertex->light_adder = shade; room->mesh.num_vertices++; } diff --git a/src/tr1/game/items.c b/src/tr1/game/items.c index 26d79ffda..e9d684a07 100644 --- a/src/tr1/game/items.c +++ b/src/tr1/game/items.c @@ -292,7 +292,7 @@ int16_t Item_Spawn(const ITEM *const item, const GAME_OBJECT_ID object_id) spawn->rot = item->rot; Item_Initialise(spawn_num); spawn->status = IS_INACTIVE; - spawn->shade = HIGH_LIGHT; + spawn->shade.value_1 = HIGH_LIGHT; } return spawn_num; } diff --git a/src/tr1/game/level.c b/src/tr1/game/level.c index 127a5f869..db0091585 100644 --- a/src/tr1/game/level.c +++ b/src/tr1/game/level.c @@ -206,6 +206,7 @@ static void M_LoadRooms(VFILE *file) // Room lights r->ambient = VFile_ReadS16(file); + r->light_mode = RLM_NORMAL; r->num_lights = VFile_ReadS16(file); if (!r->num_lights) { r->lights = NULL; @@ -217,8 +218,8 @@ static void M_LoadRooms(VFILE *file) light->pos.x = VFile_ReadS32(file); light->pos.y = VFile_ReadS32(file); light->pos.z = VFile_ReadS32(file); - light->intensity = VFile_ReadS16(file); - light->falloff = VFile_ReadS32(file); + light->shade.value_1 = VFile_ReadS16(file); + light->falloff.value_1 = VFile_ReadS32(file); } } @@ -236,7 +237,7 @@ static void M_LoadRooms(VFILE *file) mesh->pos.y = VFile_ReadS32(file); mesh->pos.z = VFile_ReadS32(file); mesh->rot.y = VFile_ReadS16(file); - mesh->shade = VFile_ReadU16(file); + mesh->shade.value_1 = VFile_ReadU16(file); mesh->static_num = VFile_ReadS16(file); } } @@ -550,7 +551,7 @@ static void M_LoadItems(VFILE *file) item->pos.y = VFile_ReadS32(file); item->pos.z = VFile_ReadS32(file); item->rot.y = VFile_ReadS16(file); - item->shade = VFile_ReadS16(file); + item->shade.value_1 = VFile_ReadS16(file); item->flags = VFile_ReadU16(file); if (item->object_id < 0 || item->object_id >= O_NUMBER_OF) { diff --git a/src/tr1/game/objects/common.c b/src/tr1/game/objects/common.c index 088171120..cc5b88fb1 100644 --- a/src/tr1/game/objects/common.c +++ b/src/tr1/game/objects/common.c @@ -91,7 +91,8 @@ void Object_DrawSpriteItem(ITEM *item) Output_DrawSprite( item->interp.result.pos.x, item->interp.result.pos.y, item->interp.result.pos.z, - g_Objects[item->object_id].mesh_idx - item->frame_num, item->shade); + g_Objects[item->object_id].mesh_idx - item->frame_num, + item->shade.value_1); } void Object_DrawPickupItem(ITEM *item) @@ -197,8 +198,7 @@ void Object_DrawPickupItem(ITEM *item) item->interp.result.pos.x, offset, item->interp.result.pos.z); Matrix_Rot16(item->interp.result.rot); - Output_CalculateLight( - item->pos.x, item->pos.y, item->pos.z, item->room_num); + Output_CalculateLight(item->pos, item->room_num); frame = object->frame_base; int32_t clip = Output_GetObjectBounds(&frame->bounds); diff --git a/src/tr1/game/objects/creatures/pod.c b/src/tr1/game/objects/creatures/pod.c index 341293a95..24f37b040 100644 --- a/src/tr1/game/objects/creatures/pod.c +++ b/src/tr1/game/objects/creatures/pod.c @@ -60,7 +60,7 @@ void Pod_Initialise(int16_t item_num) bug->pos.z = item->pos.z; bug->rot.y = item->rot.y; bug->flags = IF_INVISIBLE; - bug->shade = -1; + bug->shade.value_1 = -1; Item_Initialise(bug_item_num); diff --git a/src/tr1/game/objects/creatures/statue.c b/src/tr1/game/objects/creatures/statue.c index 218e33be3..244813f20 100644 --- a/src/tr1/game/objects/creatures/statue.c +++ b/src/tr1/game/objects/creatures/statue.c @@ -41,7 +41,7 @@ void Statue_Initialise(int16_t item_num) centaur->pos.y = item->pos.y; centaur->pos.z = item->pos.z; centaur->flags = IF_INVISIBLE; - centaur->shade = -1; + centaur->shade.value_1 = -1; Item_Initialise(centaur_item_num); diff --git a/src/tr1/game/objects/traps/dart_emitter.c b/src/tr1/game/objects/traps/dart_emitter.c index 4ddc7aab0..172403dab 100644 --- a/src/tr1/game/objects/traps/dart_emitter.c +++ b/src/tr1/game/objects/traps/dart_emitter.c @@ -36,7 +36,7 @@ void DartEmitter_Control(int16_t item_num) ITEM *dart = &g_Items[dart_item_num]; dart->object_id = O_DART; dart->room_num = item->room_num; - dart->shade = -1; + dart->shade.value_1 = -1; dart->rot.y = item->rot.y; dart->pos.y = item->pos.y - WALL_L / 2; diff --git a/src/tr1/game/objects/traps/thors_hammer_handle.c b/src/tr1/game/objects/traps/thors_hammer_handle.c index d2eb94154..478dddb1e 100644 --- a/src/tr1/game/objects/traps/thors_hammer_handle.c +++ b/src/tr1/game/objects/traps/thors_hammer_handle.c @@ -35,7 +35,7 @@ void ThorsHammerHandle_Initialise(int16_t item_num) head_item->room_num = hand_item->room_num; head_item->pos = hand_item->pos; head_item->rot = hand_item->rot; - head_item->shade = hand_item->shade; + head_item->shade.value_1 = hand_item->shade.value_1; Item_Initialise(head_item_num); hand_item->data = head_item; g_LevelItemCount++; diff --git a/src/tr1/game/output.c b/src/tr1/game/output.c index 9d48a9ba1..56e6b5daa 100644 --- a/src/tr1/game/output.c +++ b/src/tr1/game/output.c @@ -90,7 +90,6 @@ static bool M_CalcVerticeEnvMap(const OBJECT_MESH *mesh); static void M_CalcSkyboxLight(const OBJECT_MESH *mesh); static void M_CalcRoomVertices(const ROOM_MESH *mesh); static void M_CalcRoomVerticesWibble(const ROOM_MESH *mesh); -static int32_t M_CalcFogShade(int32_t depth); static void M_CalcWibbleTable(void); static void M_DrawFlatFace3s(const FACE3 *const faces, const int32_t count) @@ -365,7 +364,7 @@ static bool M_CalcVerticeEnvMap(const OBJECT_MESH *mesh) m_VBuf[i].g = 0x1000; const int32_t depth = g_MatrixPtr->_23 >> W2V_SHIFT; - m_VBuf[i].g += M_CalcFogShade(depth); + m_VBuf[i].g += Output_CalcFogShade(depth); // reflection can be darker but not brighter CLAMP(m_VBuf[i].g, 0x1000, 0x1FFF); @@ -434,7 +433,7 @@ static void M_CalcRoomVertices(const ROOM_MESH *const mesh) vbuf->xv = xv; vbuf->yv = yv; vbuf->zv = zv; - vbuf->g = vertex->shade & MAX_LIGHTING; + vbuf->g = vertex->light_adder; if (zv < Output_GetNearZ()) { vbuf->clip = (int16_t)0x8000; @@ -447,7 +446,7 @@ static void M_CalcRoomVertices(const ROOM_MESH *const mesh) clip_flags |= 16; } } else if (depth) { - vbuf->g += M_CalcFogShade(depth); + vbuf->g += Output_CalcFogShade(depth); if (!m_IsWaterEffect) { CLAMPG(vbuf->g, MAX_LIGHTING); } @@ -518,21 +517,6 @@ static void M_CalcRoomVerticesWibble(const ROOM_MESH *const mesh) } } -static int32_t M_CalcFogShade(int32_t depth) -{ - int32_t fog_begin = Output_GetDrawDistFade(); - int32_t fog_end = Output_GetDrawDistMax(); - - if (depth < fog_begin) { - return 0; - } - if (depth >= fog_end) { - return 0x1FFF; - } - - return (depth - fog_begin) * 0x1FFF / (fog_end - fog_begin); -} - static void M_CalcWibbleTable(void) { for (int i = 0; i < WIBBLE_SIZE; i++) { @@ -630,93 +614,6 @@ void Output_ClearDepthBuffer(void) S_Output_ClearDepthBuffer(); } -void Output_CalculateLight(int32_t x, int32_t y, int32_t z, int16_t room_num) -{ - ROOM *r = &g_RoomInfo[room_num]; - - if (r->num_lights == 0) { - m_LsAdder = r->ambient; - m_LsDivider = 0; - } else { - int32_t ambient = 0x1FFF - r->ambient; - int32_t brightest = 0; - - XYZ_32 ls = { - .x = 0, - .y = 0, - .z = 0, - }; - for (int i = 0; i < r->num_lights; i++) { - LIGHT *light = &r->lights[i]; - XYZ_32 lc = { - .x = x - light->pos.x, - .y = y - light->pos.y, - .z = z - light->pos.z, - }; - - int32_t distance = - (SQUARE(lc.x) + SQUARE(lc.y) + SQUARE(lc.z)) >> 12; - int32_t falloff = SQUARE(light->falloff) >> 12; - int32_t shade = - ambient + (light->intensity * falloff) / (distance + falloff); - - if (shade > brightest) { - brightest = shade; - ls = lc; - } - } - - m_LsAdder = (ambient + brightest) / 2; - if (brightest == ambient) { - m_LsDivider = 0; - } else { - m_LsDivider = (1 << (W2V_SHIFT + 12)) / (brightest - m_LsAdder); - } - m_LsAdder = 0x1FFF - m_LsAdder; - - PHD_ANGLE angles[2]; - Math_GetVectorAngles(ls.x, ls.y, ls.z, angles); - Output_RotateLight(angles[1], angles[0]); - } - - int32_t distance = g_MatrixPtr->_23 >> W2V_SHIFT; - m_LsAdder += M_CalcFogShade(distance); - CLAMPG(m_LsAdder, 0x1FFF); -} - -void Output_CalculateStaticLight(int16_t adder) -{ - m_LsAdder = adder - 16 * 256; - int32_t distance = g_MatrixPtr->_23 >> W2V_SHIFT; - m_LsAdder += M_CalcFogShade(distance); - CLAMPG(m_LsAdder, 0x1FFF); -} - -void Output_CalculateObjectLighting( - const ITEM *const item, const BOUNDS_16 *const bounds) -{ - if (item->shade >= 0) { - Output_CalculateStaticLight(item->shade); - return; - } - - Matrix_PushUnit(); - Matrix_Rot16(item->rot); - Matrix_TranslateRel32((XYZ_32) { - .x = (bounds->min.x + bounds->max.x) / 2, - .y = (bounds->min.y + bounds->max.y) / 2, - .z = (bounds->min.z + bounds->max.z) / 2, - }); - const XYZ_32 offset = { - .x = item->pos.x + (g_MatrixPtr->_03 >> W2V_SHIFT), - .y = item->pos.y + (g_MatrixPtr->_13 >> W2V_SHIFT), - .z = item->pos.z + (g_MatrixPtr->_23 >> W2V_SHIFT), - }; - Matrix_Pop(); - - Output_CalculateLight(offset.x, offset.y, offset.z, item->room_num); -} - void Output_DrawObjectMesh(const OBJECT_MESH *const mesh, const int32_t clip) { if (!M_CalcObjectVertices(mesh->vertices, mesh->num_vertices)) { @@ -956,7 +853,7 @@ void Output_DrawSprite( if (x1 >= Viewport_GetMinX() && y1 >= Viewport_GetMinY() && x0 <= Viewport_GetMaxX() && y0 <= Viewport_GetMaxY()) { int32_t depth = zv >> W2V_SHIFT; - shade += M_CalcFogShade(depth); + shade += Output_CalcFogShade(depth); CLAMPG(shade, 0x1FFF); S_Output_DrawSprite(x0, y0, x1, y1, zv, sprnum, shade); } @@ -1082,7 +979,7 @@ void Output_DrawSpriteRel( if (x1 >= Viewport_GetMinX() && y1 >= Viewport_GetMinY() && x0 <= Viewport_GetMaxX() && y0 <= Viewport_GetMaxY()) { int32_t depth = zv >> W2V_SHIFT; - shade += M_CalcFogShade(depth); + shade += Output_CalcFogShade(depth); CLAMPG(shade, 0x1FFF); S_Output_DrawSprite(x0, y0, x1, y1, zv, sprnum, shade); } @@ -1405,3 +1302,31 @@ RGB_888 Output_GetPaletteColor(uint16_t idx) } return m_ColorPalette[idx]; } + +int32_t Output_CalcFogShade(const int32_t depth) +{ + int32_t fog_begin = Output_GetDrawDistFade(); + int32_t fog_end = Output_GetDrawDistMax(); + + if (depth < fog_begin) { + return 0; + } + if (depth >= fog_end) { + return 0x1FFF; + } + + return (depth - fog_begin) * 0x1FFF / (fog_end - fog_begin); +} + +int32_t Output_GetRoomLightShade(const ROOM_LIGHT_MODE mode) +{ + // TODO: remove + ASSERT_FAIL(); + return 0; +} + +void Output_LightRoomVertices(const ROOM *room) +{ + // TODO: remove + ASSERT_FAIL(); +} diff --git a/src/tr1/game/output.h b/src/tr1/game/output.h index 73a9b52af..77657694d 100644 --- a/src/tr1/game/output.h +++ b/src/tr1/game/output.h @@ -33,10 +33,6 @@ void Output_EndScene(void); void Output_DrawBlack(void); void Output_ClearDepthBuffer(void); -void Output_CalculateLight(int32_t x, int32_t y, int32_t z, int16_t room_num); -void Output_CalculateStaticLight(int16_t adder); -void Output_CalculateObjectLighting(const ITEM *item, const BOUNDS_16 *bounds); - void Output_DrawObjectMesh(const OBJECT_MESH *mesh, int32_t clip); void Output_DrawObjectMesh_I(const OBJECT_MESH *mesh, int32_t clip); diff --git a/src/tr1/game/room_draw.c b/src/tr1/game/room_draw.c index e869bca26..96651b15f 100644 --- a/src/tr1/game/room_draw.c +++ b/src/tr1/game/room_draw.c @@ -304,7 +304,7 @@ void Room_DrawSingleRoom(int16_t room_num) Matrix_RotY(mesh->rot.y); int32_t clip = Output_GetObjectBounds(&info->draw_bounds); if (clip != 0) { - Output_CalculateStaticLight(mesh->shade); + Output_CalculateStaticLight(mesh->shade.value_1); Object_DrawMesh(info->mesh_idx, clip, false); } Matrix_Pop(); diff --git a/src/tr1/global/const.h b/src/tr1/global/const.h index 91f699a5e..4b2de47df 100644 --- a/src/tr1/global/const.h +++ b/src/tr1/global/const.h @@ -98,7 +98,6 @@ #define NO_BAD_POS (-NO_HEIGHT) #define NO_BAD_NEG NO_HEIGHT #define BAD_JUMP_CEILING ((STEP_L * 3) / 4) // = 192 -#define WIBBLE_SIZE 32 #define MAX_WIBBLE 2 #define MAX_SHADE 0x300 #define MAX_LIGHTING 0x1FFF diff --git a/src/tr2/decomp/decomp.c b/src/tr2/decomp/decomp.c index de1148676..24841c155 100644 --- a/src/tr2/decomp/decomp.c +++ b/src/tr2/decomp/decomp.c @@ -101,7 +101,7 @@ void CutscenePlayer_Control(const int16_t item_num) pos.y = 0; pos.z = 0; Collide_GetJointAbsPosition(item, &pos, 0); - Output_AddDynamicLight(pos.x, pos.y, pos.z, 12, 11); + Output_AddDynamicLight(pos, 12, 11); } Item_Animate(item); diff --git a/src/tr2/decomp/flares.c b/src/tr2/decomp/flares.c index 39e5f61d0..e1b56e14c 100644 --- a/src/tr2/decomp/flares.c +++ b/src/tr2/decomp/flares.c @@ -81,30 +81,32 @@ int32_t Flare_DoLight(const XYZ_32 *const pos, const int32_t flare_age) } const int32_t random = Random_GetDraw(); - const int32_t x = pos->x + (random & 0xF); - const int32_t y = pos->y; - const int32_t z = pos->z; + const XYZ_32 light_pos = { + .x = pos->x + (random & 0xF), + .y = pos->y, + .z = pos->z, + }; if (flare_age < FLARE_YOUNG_AGE) { const int32_t intensity = FLARE_INTENSITY * (flare_age - FLARE_YOUNG_AGE) / (2 * FLARE_YOUNG_AGE) + FLARE_INTENSITY; - Output_AddDynamicLight(x, y, z, intensity, FLARE_FALL_OFF); + Output_AddDynamicLight(light_pos, intensity, FLARE_FALL_OFF); return true; } if (flare_age < FLARE_OLD_AGE) { - Output_AddDynamicLight(x, y, z, FLARE_INTENSITY, FLARE_FALL_OFF); + Output_AddDynamicLight(light_pos, FLARE_INTENSITY, FLARE_FALL_OFF); return true; } if (random > 0x2000) { Output_AddDynamicLight( - x, y, z, FLARE_INTENSITY - (random & 3), FLARE_FALL_OFF); + light_pos, FLARE_INTENSITY - (random & 3), FLARE_FALL_OFF); return true; } - Output_AddDynamicLight(x, y, z, FLARE_INTENSITY, FLARE_FALL_OFF / 2); + Output_AddDynamicLight(light_pos, FLARE_INTENSITY, FLARE_FALL_OFF / 2); return false; } @@ -196,7 +198,7 @@ void Flare_Create(const bool thrown) item->rot.z = 0; item->rot.x = 0; - item->shade_1 = -1; + item->shade.value_1 = -1; if (thrown) { item->speed = g_LaraItem->speed + 50; diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 53c772f9b..635bfc6d0 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -304,8 +304,7 @@ void Skidoo_DoSnowEffect(const ITEM *const skidoo) g_MatrixPtr->_23 = 0; - Output_CalculateLight( - effect->pos.x, effect->pos.y, effect->pos.z, effect->room_num); + Output_CalculateLight(effect->pos, effect->room_num); effect->shade = g_LsAdder - 512; CLAMPL(effect->shade, 0); } @@ -780,10 +779,12 @@ void Skidoo_Guns(void) const int32_t cy = Math_Cos(g_LaraItem->rot.y); const int32_t sy = Math_Sin(g_LaraItem->rot.y); - const int32_t x = g_LaraItem->pos.x + (sy >> 4); - const int32_t z = g_LaraItem->pos.z + (cy >> 4); - const int32_t y = g_LaraItem->pos.y - 512; - Output_AddDynamicLight(x, y, z, 12, 11); + const XYZ_32 pos = { + .x = g_LaraItem->pos.x + (sy >> 4), + .z = g_LaraItem->pos.z + (cy >> 4), + .y = g_LaraItem->pos.y - 512, + }; + Output_AddDynamicLight(pos, 12, 11); ITEM *const skidoo = Item_Get(g_Lara.skidoo); Creature_Effect(skidoo, &g_Skidoo_LeftGun, Spawn_GunShot); diff --git a/src/tr2/game/cutscene.c b/src/tr2/game/cutscene.c index ccc9629cb..d30e02d79 100644 --- a/src/tr2/game/cutscene.c +++ b/src/tr2/game/cutscene.c @@ -77,7 +77,7 @@ GAME_FLOW_COMMAND Cutscene_Control(void) } } - g_DynamicLightCount = 0; + Output_ResetDynamicLights(); Item_Control(); Effect_Control(); diff --git a/src/tr2/game/game.c b/src/tr2/game/game.c index 2c005f12e..854932866 100644 --- a/src/tr2/game/game.c +++ b/src/tr2/game/game.c @@ -150,7 +150,7 @@ GAME_FLOW_COMMAND Game_Control(const bool demo_mode) } } - g_DynamicLightCount = 0; + Output_ResetDynamicLights(); Item_Control(); Effect_Control(); diff --git a/src/tr2/game/gun/gun_pistols.c b/src/tr2/game/gun/gun_pistols.c index 9ef2b65d4..000885f5b 100644 --- a/src/tr2/game/gun/gun_pistols.c +++ b/src/tr2/game/gun/gun_pistols.c @@ -206,10 +206,12 @@ void Gun_Pistols_Control(const LARA_GUN_TYPE weapon_type) if (g_Lara.left_arm.flash_gun || g_Lara.right_arm.flash_gun) { const int32_t c = Math_Cos(g_LaraItem->rot.y); const int32_t s = Math_Sin(g_LaraItem->rot.y); - const int32_t x = g_LaraItem->pos.x + (s >> (W2V_SHIFT - 10)); - const int32_t y = g_LaraItem->pos.y - WALL_L / 2; - const int32_t z = g_LaraItem->pos.z + (c >> (W2V_SHIFT - 10)); - Output_AddDynamicLight(x, y, z, 12, 11); + const XYZ_32 pos = { + .x = g_LaraItem->pos.x + (s >> (W2V_SHIFT - 10)), + .y = g_LaraItem->pos.y - WALL_L / 2, + .z = g_LaraItem->pos.z + (c >> (W2V_SHIFT - 10)), + }; + Output_AddDynamicLight(pos, 12, 11); } } diff --git a/src/tr2/game/gun/gun_rifle.c b/src/tr2/game/gun/gun_rifle.c index 3c4bb90e2..f6b48142b 100644 --- a/src/tr2/game/gun/gun_rifle.c +++ b/src/tr2/game/gun/gun_rifle.c @@ -98,10 +98,12 @@ void Gun_Rifle_Control(const LARA_GUN_TYPE weapon_type) && (weapon_type == LGT_SHOTGUN || weapon_type == LGT_M16)) { const int32_t c = Math_Cos(g_LaraItem->rot.y); const int32_t s = Math_Sin(g_LaraItem->rot.y); - const int32_t x = g_LaraItem->pos.x + (s >> (W2V_SHIFT - 10)); - const int32_t y = g_LaraItem->pos.y - WALL_L / 2; - const int32_t z = g_LaraItem->pos.z + (c >> (W2V_SHIFT - 10)); - Output_AddDynamicLight(x, y, z, 12, 11); + const XYZ_32 pos = { + .x = g_LaraItem->pos.x + (s >> (W2V_SHIFT - 10)), + .y = g_LaraItem->pos.y - WALL_L / 2, + .z = g_LaraItem->pos.z + (c >> (W2V_SHIFT - 10)), + }; + Output_AddDynamicLight(pos, 12, 11); } } diff --git a/src/tr2/game/items.c b/src/tr2/game/items.c index d021de06a..f4ff987c0 100644 --- a/src/tr2/game/items.c +++ b/src/tr2/game/items.c @@ -574,8 +574,7 @@ int32_t Item_Explode( ITEM *const item = &g_Items[item_num]; const OBJECT *const object = &g_Objects[item->object_id]; - Output_CalculateLight( - item->pos.x, item->pos.y, item->pos.z, item->room_num); + Output_CalculateLight(item->pos, item->room_num); const ANIM_FRAME *const best_frame = Item_GetBestFrame(item); diff --git a/src/tr2/game/level.c b/src/tr2/game/level.c index 9dad026be..0464417f0 100644 --- a/src/tr2/game/level.c +++ b/src/tr2/game/level.c @@ -135,8 +135,8 @@ static void M_LoadRooms(VFILE *const file) sector->ceiling.height = VFile_ReadS8(file) * STEP_L; } - r->ambient_1 = VFile_ReadS16(file); - r->ambient_2 = VFile_ReadS16(file); + r->ambient = VFile_ReadS16(file); + VFile_Skip(file, sizeof(int16_t)); // Unused second ambient r->light_mode = VFile_ReadS16(file); r->num_lights = VFile_ReadS16(file); @@ -150,10 +150,10 @@ static void M_LoadRooms(VFILE *const file) light->pos.x = VFile_ReadS32(file); light->pos.y = VFile_ReadS32(file); light->pos.z = VFile_ReadS32(file); - light->intensity_1 = VFile_ReadS16(file); - light->intensity_2 = VFile_ReadS16(file); - light->falloff_1 = VFile_ReadS32(file); - light->falloff_2 = VFile_ReadS32(file); + light->shade.value_1 = VFile_ReadS16(file); + light->shade.value_2 = VFile_ReadS16(file); + light->falloff.value_1 = VFile_ReadS32(file); + light->falloff.value_2 = VFile_ReadS32(file); } } @@ -170,8 +170,8 @@ static void M_LoadRooms(VFILE *const file) mesh->pos.y = VFile_ReadS32(file); mesh->pos.z = VFile_ReadS32(file); mesh->rot.y = VFile_ReadS16(file); - mesh->shade_1 = VFile_ReadS16(file); - mesh->shade_2 = VFile_ReadS16(file); + mesh->shade.value_1 = VFile_ReadS16(file); + mesh->shade.value_2 = VFile_ReadS16(file); mesh->static_num = VFile_ReadS16(file); } } @@ -371,8 +371,8 @@ static void M_LoadItems(VFILE *const file) item->pos.y = VFile_ReadS32(file); item->pos.z = VFile_ReadS32(file); item->rot.y = VFile_ReadS16(file); - item->shade_1 = VFile_ReadS16(file); - item->shade_2 = VFile_ReadS16(file); + item->shade.value_1 = VFile_ReadS16(file); + item->shade.value_2 = VFile_ReadS16(file); item->flags = VFile_ReadS16(file); if (item->object_id < 0 || item->object_id >= O_NUMBER_OF) { Shell_ExitSystemFmt( diff --git a/src/tr2/game/objects/common.c b/src/tr2/game/objects/common.c index 33de2089f..0064be687 100644 --- a/src/tr2/game/objects/common.c +++ b/src/tr2/game/objects/common.c @@ -149,8 +149,7 @@ void Object_DrawUnclippedItem(const ITEM *const item) void Object_DrawSpriteItem(const ITEM *const item) { Output_CalculateStaticMeshLight( - item->pos.x, item->pos.y, item->pos.z, item->shade_1, item->shade_2, - Room_Get(item->room_num)); + item->pos, item->shade, Room_Get(item->room_num)); const OBJECT *const obj = Object_GetObject(item->object_id); diff --git a/src/tr2/game/objects/creatures/bartoli.c b/src/tr2/game/objects/creatures/bartoli.c index 8ae1ff8f1..9550633bf 100644 --- a/src/tr2/game/objects/creatures/bartoli.c +++ b/src/tr2/game/objects/creatures/bartoli.c @@ -30,7 +30,7 @@ static void M_CreateBoom( sphere_item->pos.y = origin_item->pos.y + 256; sphere_item->pos.z = origin_item->pos.z; sphere_item->room_num = origin_item->room_num; - sphere_item->shade_1 = -1; + sphere_item->shade.value_1 = -1; Item_Initialise(item_num); Item_AddActive(item_num); sphere_item->status = IS_ACTIVE; @@ -96,7 +96,7 @@ void Bartoli_Initialise(const int16_t item_num) item_dragon_back->rot.y = item->rot.y; item_dragon_back->room_num = item->room_num; item_dragon_back->flags = IF_INVISIBLE; - item_dragon_back->shade_1 = -1; + item_dragon_back->shade.value_1 = -1; Item_Initialise(item_dragon_back_num); item_dragon_back->mesh_bits = 0x1FFFFF; @@ -108,7 +108,7 @@ void Bartoli_Initialise(const int16_t item_num) item_dragon_front->rot.y = item->rot.y; item_dragon_front->room_num = item->room_num; item_dragon_front->flags = IF_INVISIBLE; - item_dragon_front->shade_1 = -1; + item_dragon_front->shade.value_1 = -1; Item_Initialise(item_dragon_front_num); item_dragon_back->data = (void *)(intptr_t)item_dragon_front_num; diff --git a/src/tr2/game/objects/creatures/dragon.c b/src/tr2/game/objects/creatures/dragon.c index edb55fc0f..3bf193efa 100644 --- a/src/tr2/game/objects/creatures/dragon.c +++ b/src/tr2/game/objects/creatures/dragon.c @@ -230,7 +230,7 @@ void Dragon_Bones(const int16_t item_num) bone_back->rot.y = dragon_item->rot.y; bone_back->rot.z = 0; bone_back->room_num = dragon_item->room_num; - bone_back->shade_1 = -1; + bone_back->shade.value_1 = -1; Item_Initialise(bone_back_item_num); ITEM *const bone_front = Item_Get(bone_front_item_num); @@ -242,7 +242,7 @@ void Dragon_Bones(const int16_t item_num) bone_front->rot.y = dragon_item->rot.y; bone_front->rot.z = 0; bone_front->room_num = dragon_item->room_num; - bone_front->shade_1 = -1; + bone_front->shade.value_1 = -1; Item_Initialise(bone_front_item_num); bone_front->mesh_bits = ~0xC00000u; } @@ -285,9 +285,7 @@ void Dragon_Control(const int16_t item_num) if (creature->flags > -20) { // clang-format off Output_AddDynamicLight( - dragon_front_item->pos.x, - dragon_front_item->pos.y, - dragon_front_item->pos.z, + dragon_front_item->pos, ((4 * Random_GetDraw()) >> 15) + 12 + creature->flags / 2, ((4 * Random_GetDraw()) >> 15) + 10 + creature->flags / 2); // clang-format on diff --git a/src/tr2/game/objects/creatures/skidoo_driver.c b/src/tr2/game/objects/creatures/skidoo_driver.c index 8f14ae6fb..256da43eb 100644 --- a/src/tr2/game/objects/creatures/skidoo_driver.c +++ b/src/tr2/game/objects/creatures/skidoo_driver.c @@ -197,7 +197,7 @@ void SkidooDriver_Initialise(const int16_t item_num) skidoo->rot.y = skidoo_driver->rot.y; skidoo->room_num = skidoo_driver->room_num; skidoo->flags = IF_ONE_SHOT; - skidoo->shade_1 = -1; + skidoo->shade.value_1 = -1; Item_Initialise(skidoo_item_num); skidoo_driver->data = (void *)(intptr_t)skidoo_item_num; diff --git a/src/tr2/game/objects/effects/explosion.c b/src/tr2/game/objects/effects/explosion.c index 2a502578b..9215799b2 100644 --- a/src/tr2/game/objects/effects/explosion.c +++ b/src/tr2/game/objects/effects/explosion.c @@ -14,14 +14,12 @@ void Explosion_Control(const int16_t effect_num) effect->frame_num--; effect->counter = 0; if (effect->frame_num > obj->mesh_count) { - Output_AddDynamicLight( - effect->pos.x, effect->pos.y, effect->pos.z, 13, 11); + Output_AddDynamicLight(effect->pos, 13, 11); } else { Effect_Kill(effect_num); } } else { - Output_AddDynamicLight( - effect->pos.x, effect->pos.y, effect->pos.z, 12, 10); + Output_AddDynamicLight(effect->pos, 12, 10); } } diff --git a/src/tr2/game/objects/effects/gun_flash.c b/src/tr2/game/objects/effects/gun_flash.c index 9fe9e5a6c..f1c9d9205 100644 --- a/src/tr2/game/objects/effects/gun_flash.c +++ b/src/tr2/game/objects/effects/gun_flash.c @@ -16,7 +16,7 @@ void GunFlash_Control(const int16_t effect_num) } effect->rot.z = Random_GetControl(); - Output_AddDynamicLight(effect->pos.x, effect->pos.y, effect->pos.z, 12, 11); + Output_AddDynamicLight(effect->pos, 12, 11); } void GunFlash_Setup(void) diff --git a/src/tr2/game/objects/effects/missile_common.c b/src/tr2/game/objects/effects/missile_common.c index 5d331f62f..ba9f007a7 100644 --- a/src/tr2/game/objects/effects/missile_common.c +++ b/src/tr2/game/objects/effects/missile_common.c @@ -47,8 +47,7 @@ void Missile_Control(const int16_t effect_num) effect->counter = 6; Sound_Effect(SFX_CIRCLE_BLADE_HIT, &effect->pos, SPM_NORMAL); } else if (effect->object_id == O_MISSILE_FLAME) { - Output_AddDynamicLight( - effect->pos.x, effect->pos.y, effect->pos.z, 14, 11); + Output_AddDynamicLight(effect->pos, 14, 11); Effect_Kill(effect_num); } return; @@ -84,8 +83,7 @@ void Missile_Control(const int16_t effect_num) Spawn_Bubble(&effect->pos, effect->room_num); } else if (effect->object_id == O_MISSILE_FLAME) { if (!effect->counter--) { - Output_AddDynamicLight( - effect->pos.x, effect->pos.y, effect->pos.z, 14, 11); + Output_AddDynamicLight(effect->pos, 14, 11); Sound_Effect(SFX_DRAGON_FIRE, &effect->pos, SPM_NORMAL); Effect_Kill(effect_num); } diff --git a/src/tr2/game/objects/general/alarm_sound.c b/src/tr2/game/objects/general/alarm_sound.c index c8691c28b..26626cf6b 100644 --- a/src/tr2/game/objects/general/alarm_sound.c +++ b/src/tr2/game/objects/general/alarm_sound.c @@ -15,7 +15,7 @@ void AlarmSound_Control(int16_t item_num) int32_t counter = (int32_t)(intptr_t)item->data; counter++; if (counter > 6) { - Output_AddDynamicLight(item->pos.x, item->pos.y, item->pos.z, 12, 11); + Output_AddDynamicLight(item->pos, 12, 11); if (counter > 12) { counter = 0; } diff --git a/src/tr2/game/objects/general/detonator.c b/src/tr2/game/objects/general/detonator.c index dad659b65..9a294e392 100644 --- a/src/tr2/game/objects/general/detonator.c +++ b/src/tr2/game/objects/general/detonator.c @@ -79,7 +79,7 @@ void Detonator_Control(const int16_t item_num) Item_Animate(item); if (Item_TestFrameRange(item, EXPLOSION_START_FRAME, EXPLOSION_END_FRAME)) { - Output_AddDynamicLight(item->pos.x, item->pos.y, item->pos.z, 13, 11); + Output_AddDynamicLight(item->pos, 13, 11); } if (Item_TestFrameEqual(item, EXPLOSION_ACTION_FRAME)) { diff --git a/src/tr2/game/objects/general/general.c b/src/tr2/game/objects/general/general.c index 8951ffd48..2f7194e1e 100644 --- a/src/tr2/game/objects/general/general.c +++ b/src/tr2/game/objects/general/general.c @@ -32,7 +32,7 @@ void General_Control(const int16_t item_num) XYZ_32 pos = { .x = 3000, .y = 720, .z = 0 }; Collide_GetJointAbsPosition(item, &pos, 0); - Output_AddDynamicLight(pos.x, pos.y, pos.z, 14, 11); + Output_AddDynamicLight(pos, 14, 11); if (item->status == IS_DEACTIVATED) { Item_RemoveActive(item_num); diff --git a/src/tr2/game/objects/general/pickup.c b/src/tr2/game/objects/general/pickup.c index 7cb853642..84be07349 100644 --- a/src/tr2/game/objects/general/pickup.c +++ b/src/tr2/game/objects/general/pickup.c @@ -267,8 +267,7 @@ void Pickup_Draw(const ITEM *const item) Matrix_TranslateAbs(item->pos.x, offset, item->pos.z); Matrix_Rot16(item->rot); - Output_CalculateLight( - item->pos.x, item->pos.y, item->pos.z, item->room_num); + Output_CalculateLight(item->pos, item->room_num); const int32_t clip = Output_GetObjectBounds(&bounds); if (clip) { diff --git a/src/tr2/game/objects/general/waterfall.c b/src/tr2/game/objects/general/waterfall.c index 42acbc09c..2585f3a4f 100644 --- a/src/tr2/game/objects/general/waterfall.c +++ b/src/tr2/game/objects/general/waterfall.c @@ -25,8 +25,7 @@ void Waterfall_Control(const int16_t item_num) return; } - Output_CalculateLight( - item->pos.x, item->pos.y, item->pos.z, item->room_num); + Output_CalculateLight(item->pos, item->room_num); Sound_Effect(SFX_WATERFALL_LOOP, &item->pos, SPM_NORMAL); const int16_t effect_num = Effect_Create(item->room_num); diff --git a/src/tr2/game/objects/traps/dart_emitter.c b/src/tr2/game/objects/traps/dart_emitter.c index e9e47bc1b..5a2bd17a3 100644 --- a/src/tr2/game/objects/traps/dart_emitter.c +++ b/src/tr2/game/objects/traps/dart_emitter.c @@ -25,7 +25,7 @@ static void M_CreateDart(ITEM *const item) ITEM *const dart_item = Item_Get(dart_item_num); dart_item->object_id = O_DART; dart_item->room_num = item->room_num; - dart_item->shade_1 = -1; + dart_item->shade.value_1 = -1; dart_item->rot.y = item->rot.y; dart_item->pos.y = item->pos.y - 512; diff --git a/src/tr2/game/objects/vehicles/boat.c b/src/tr2/game/objects/vehicles/boat.c index 2b870ddf6..4f19d4224 100644 --- a/src/tr2/game/objects/vehicles/boat.c +++ b/src/tr2/game/objects/vehicles/boat.c @@ -288,8 +288,7 @@ void Boat_DoShift(const int32_t boat_num) void Boat_DoWakeEffect(const ITEM *const boat) { g_MatrixPtr->_23 = 0; - Output_CalculateLight( - boat->pos.x, boat->pos.y, boat->pos.z, boat->room_num); + Output_CalculateLight(boat->pos, boat->room_num); const int16_t frame = (Random_GetDraw() * g_Objects[O_WATER_SPRITE].mesh_count) >> 15; diff --git a/src/tr2/game/output.c b/src/tr2/game/output.c index 037cf0cdf..af4e18d6a 100644 --- a/src/tr2/game/output.c +++ b/src/tr2/game/output.c @@ -16,15 +16,12 @@ #include static int32_t m_TickComp = 0; -static int32_t m_RoomLightShades[4] = {}; +static int32_t m_RoomLightShades[RLM_NUMBER_OF] = {}; static ROOM_LIGHT_TABLE m_RoomLightTables[WIBBLE_SIZE] = {}; -static LIGHT m_DynamicLights[MAX_DYNAMIC_LIGHTS] = {}; static float m_WibbleTable[32]; static int16_t m_ShadesTable[32]; static int32_t m_RandomTable[32]; -static int32_t M_CalcFogShade(int32_t depth); - static void M_CalcRoomVertices(const ROOM_MESH *mesh, int32_t far_clip); static void M_CalcRoomVerticesWibble(const ROOM_MESH *mesh); static void M_DrawRoomSprites(const ROOM_MESH *mesh); @@ -37,17 +34,6 @@ static bool M_CalcObjectVertices(const XYZ_16 *vertices, int16_t count); static void M_CalcVerticeLight(const OBJECT_MESH *mesh); static void M_CalcSkyboxLight(const OBJECT_MESH *mesh); -static int32_t M_CalcFogShade(const int32_t depth) -{ - if (depth > FOG_START) { - return depth - FOG_START; - } - if (depth > FOG_END) { - return 0x1FFF; - } - return 0; -} - static void M_InsertBar( const int32_t l, const int32_t t, const int32_t w, const int32_t h, const int32_t percent, const COLOR_NAME bar_color_main, @@ -897,239 +883,6 @@ int32_t Output_GetObjectBounds(const BOUNDS_16 *const bounds) return 1; } -void Output_CalculateLight( - const int32_t x, const int32_t y, const int32_t z, const int16_t room_num) -{ - const ROOM *const r = &g_Rooms[room_num]; - - int32_t brightest_shade = 0; - XYZ_32 brightest_pos = {}; - - if (r->light_mode != 0) { - const int32_t light_shade = m_RoomLightShades[r->light_mode]; - for (int32_t i = 0; i < r->num_lights; i++) { - const LIGHT *const light = &r->lights[i]; - const int32_t dx = x - light->pos.x; - const int32_t dy = y - light->pos.y; - const int32_t dz = z - light->pos.z; - - const int32_t falloff_1 = SQUARE(light->falloff_1) >> 12; - const int32_t falloff_2 = SQUARE(light->falloff_2) >> 12; - const int32_t dist = (SQUARE(dx) + SQUARE(dy) + SQUARE(dz)) >> 12; - - const int32_t shade_1 = - falloff_1 * light->intensity_1 / (falloff_1 + dist); - const int32_t shade_2 = - falloff_2 * light->intensity_2 / (falloff_2 + dist); - const int32_t shade = - shade_1 + (shade_2 - shade_1) * light_shade / (WIBBLE_SIZE - 1); - - if (shade > brightest_shade) { - brightest_shade = shade; - brightest_pos = light->pos; - } - } - } else { - for (int32_t i = 0; i < r->num_lights; i++) { - const LIGHT *const light = &r->lights[i]; - const int32_t dx = x - light->pos.x; - const int32_t dy = y - light->pos.y; - const int32_t dz = z - light->pos.z; - const int32_t falloff_1 = - (light->falloff_1 * light->falloff_1) >> 12; - const int32_t dist = (SQUARE(dx) + SQUARE(dy) + SQUARE(dz)) >> 12; - const int32_t shade = - falloff_1 * light->intensity_1 / (falloff_1 + dist); - if (shade > brightest_shade) { - brightest_shade = shade; - brightest_pos = light->pos; - } - } - } - - int32_t adder = brightest_shade; - for (int32_t i = 0; i < g_DynamicLightCount; i++) { - const LIGHT *const light = &m_DynamicLights[i]; - const int32_t dx = x - light->pos.x; - const int32_t dy = y - light->pos.y; - const int32_t dz = z - light->pos.z; - const int32_t radius = 1 << light->falloff_1; - if (dx < -radius || dx > radius || dy < -radius || dy > radius - || dz < -radius || dz > radius) { - continue; - } - - const int32_t dist = SQUARE(dx) + SQUARE(dy) + SQUARE(dz); - if (dist > SQUARE(radius)) { - continue; - } - - const int32_t shade = (1 << light->intensity_1) - - (dist >> (2 * light->falloff_1 - light->intensity_1)); - if (shade > brightest_shade) { - brightest_shade = shade; - brightest_pos = light->pos; - } - adder += shade; - } - - adder /= 2; - if (adder != 0) { - g_LsAdder = r->ambient_1 - adder; - g_LsDivider = (1 << (W2V_SHIFT + 12)) / adder; - int16_t angles[2]; - Math_GetVectorAngles( - x - brightest_pos.x, y - brightest_pos.y, z - brightest_pos.z, - angles); - Output_RotateLight(angles[1], angles[0]); - } else { - g_LsAdder = r->ambient_1; - g_LsDivider = 0; - } - - const int32_t depth = g_MatrixPtr->_23 >> W2V_SHIFT; - g_LsAdder += M_CalcFogShade(depth); - CLAMPG(g_LsAdder, 0x1FFF); -} - -void Output_CalculateStaticLight(const int16_t adder) -{ - g_LsAdder = adder - 0x1000; - const int32_t depth = g_MatrixPtr->_23 >> W2V_SHIFT; - g_LsAdder += M_CalcFogShade(depth); - CLAMPG(g_LsAdder, 0x1FFF); -} - -void Output_CalculateStaticMeshLight( - const int32_t x, const int32_t y, const int32_t z, const int32_t shade_1, - const int32_t shade_2, const ROOM *const room) -{ - int32_t adder = shade_1; - if (room->light_mode != 0) { - adder += (shade_2 - shade_1) * m_RoomLightShades[room->light_mode] - / (WIBBLE_SIZE - 1); - } - - for (int32_t i = 0; i < g_DynamicLightCount; i++) { - const LIGHT *const light = &m_DynamicLights[i]; - const int32_t dx = x - light->pos.x; - const int32_t dy = y - light->pos.y; - const int32_t dz = z - light->pos.z; - const int32_t radius = 1 << light->falloff_1; - if (dx < -radius || dx > radius || dy < -radius || dy > radius - || dz < -radius || dz > radius) { - continue; - } - - const int32_t dist = SQUARE(dx) + SQUARE(dy) + SQUARE(dz); - if (dist > SQUARE(radius)) { - continue; - } - - const int32_t shade = (1 << light->intensity_1) - - (dist >> (2 * light->falloff_1 - light->intensity_1)); - adder -= shade; - if (adder < 0) { - break; - } - } - - Output_CalculateStaticLight(adder); -} - -void Output_CalculateObjectLighting( - const ITEM *const item, const BOUNDS_16 *const bounds) -{ - if (item->shade_1 >= 0) { - Output_CalculateStaticMeshLight( - item->pos.x, item->pos.y, item->pos.z, item->shade_1, item->shade_2, - &g_Rooms[item->room_num]); - return; - } - - Matrix_PushUnit(); - - Matrix_TranslateSet(0, 0, 0); - Matrix_Rot16(item->rot); - Matrix_TranslateRel32((XYZ_32) { - .x = (bounds->min.x + bounds->max.x) / 2, - .y = (bounds->max.y + bounds->min.y) / 2, - .z = (bounds->max.z + bounds->min.z) / 2, - }); - const XYZ_32 pos = { - .x = item->pos.x + (g_MatrixPtr->_03 >> W2V_SHIFT), - .y = item->pos.y + (g_MatrixPtr->_13 >> W2V_SHIFT), - .z = item->pos.z + (g_MatrixPtr->_23 >> W2V_SHIFT), - }; - Matrix_Pop(); - - Output_CalculateLight(pos.x, pos.y, pos.z, item->room_num); -} - -void Output_LightRoom(ROOM *const room) -{ - if (room->light_mode != 0) { - const ROOM_LIGHT_TABLE *const light_table = - &m_RoomLightTables[m_RoomLightShades[room->light_mode]]; - for (int32_t i = 0; i < room->mesh.num_vertices; i++) { - ROOM_VERTEX *const vtx = &room->mesh.vertices[i]; - const int32_t wibble = - light_table->table[vtx->light_table_value % WIBBLE_SIZE]; - vtx->light_adder = vtx->light_base + wibble; - } - } else if (room->flags & RF_DYNAMIC_LIT) { - for (int32_t i = 0; i < room->mesh.num_vertices; i++) { - ROOM_VERTEX *const vtx = &room->mesh.vertices[i]; - vtx->light_adder = vtx->light_base; - } - room->flags &= ~RF_DYNAMIC_LIT; - } - - const int32_t x_min = WALL_L; - const int32_t z_min = WALL_L; - const int32_t x_max = (room->size.x - 1) * WALL_L; - const int32_t z_max = (room->size.z - 1) * WALL_L; - - for (int32_t i = 0; i < g_DynamicLightCount; i++) { - const LIGHT *const light = &m_DynamicLights[i]; - const int32_t x = light->pos.x - room->pos.x; - const int32_t y = light->pos.y; - const int32_t z = light->pos.z - room->pos.z; - const int32_t radius = 1 << light->falloff_1; - if (x - radius > x_max || z - radius > z_max || x + radius < x_min - || z + radius < z_min) { - continue; - } - - room->flags |= RF_DYNAMIC_LIT; - - for (int32_t j = 0; j < room->mesh.num_vertices; j++) { - ROOM_VERTEX *const v = &room->mesh.vertices[j]; - if (v->light_adder == 0) { - continue; - } - - const int32_t dx = v->pos.x - x; - const int32_t dy = v->pos.y - y; - const int32_t dz = v->pos.z - z; - if (dx < -radius || dx > radius || dy < -radius || dy > radius - || dz < -radius || dz > radius) { - continue; - } - - const int32_t dist = SQUARE(dx) + SQUARE(dy) + SQUARE(dz); - if (dist > SQUARE(radius)) { - continue; - } - - const int32_t shade = (1 << light->intensity_1) - - (dist >> (2 * light->falloff_1 - light->intensity_1)); - v->light_adder -= shade; - CLAMPL(v->light_adder, 0); - } - } -} - void Output_SetupBelowWater(const bool is_underwater) { Render_SetWet(is_underwater); @@ -1148,36 +901,21 @@ void Output_SetupAboveWater(const bool is_underwater) void Output_AnimateTextures(const int32_t ticks) { g_WibbleOffset = (g_WibbleOffset + (ticks / TICKS_PER_FRAME)) % WIBBLE_SIZE; - m_RoomLightShades[1] = Random_GetDraw() % WIBBLE_SIZE; - m_RoomLightShades[2] = (WIBBLE_SIZE - 1) + m_RoomLightShades[RLM_FLICKER] = Random_GetDraw() % WIBBLE_SIZE; + m_RoomLightShades[RLM_GLOW] = (WIBBLE_SIZE - 1) * (Math_Sin((g_WibbleOffset * DEG_360) / WIBBLE_SIZE) + 0x4000) >> 15; if (g_GF_SunsetEnabled) { g_SunsetTimer += ticks; CLAMPG(g_SunsetTimer, SUNSET_TIMEOUT); - m_RoomLightShades[3] = + m_RoomLightShades[RLM_SUNSET] = g_SunsetTimer * (WIBBLE_SIZE - 1) / SUNSET_TIMEOUT; } Output_DoAnimateTextures(ticks); } -void Output_AddDynamicLight( - const int32_t x, const int32_t y, const int32_t z, const int32_t intensity, - const int32_t falloff) -{ - const int32_t idx = - g_DynamicLightCount < MAX_DYNAMIC_LIGHTS ? g_DynamicLightCount++ : 0; - - LIGHT *const light = &m_DynamicLights[idx]; - light->pos.x = x; - light->pos.y = y; - light->pos.z = z; - light->intensity_1 = intensity; - light->falloff_1 = falloff; -} - void Output_SetLightAdder(const int32_t adder) { g_LsAdder = adder; @@ -1187,3 +925,31 @@ void Output_SetLightDivider(const int32_t divider) { g_LsDivider = divider; } + +int32_t Output_CalcFogShade(const int32_t depth) +{ + if (depth > FOG_START) { + return depth - FOG_START; + } + if (depth > FOG_END) { + return 0x1FFF; + } + return 0; +} + +int32_t Output_GetRoomLightShade(const ROOM_LIGHT_MODE mode) +{ + return m_RoomLightShades[mode]; +} + +void Output_LightRoomVertices(const ROOM *const room) +{ + const ROOM_LIGHT_TABLE *const light_table = + &m_RoomLightTables[m_RoomLightShades[room->light_mode]]; + for (int32_t i = 0; i < room->mesh.num_vertices; i++) { + ROOM_VERTEX *const vtx = &room->mesh.vertices[i]; + const int32_t wibble = + light_table->table[vtx->light_table_value % WIBBLE_SIZE]; + vtx->light_adder = vtx->light_base + wibble; + } +} diff --git a/src/tr2/game/output.h b/src/tr2/game/output.h index 84db5940f..17376ce6f 100644 --- a/src/tr2/game/output.h +++ b/src/tr2/game/output.h @@ -80,16 +80,6 @@ void Output_InsertShadow( void Output_CalculateWibbleTable(void); int32_t Output_GetObjectBounds(const BOUNDS_16 *bounds); -void Output_CalculateLight(int32_t x, int32_t y, int32_t z, int16_t room_num); -void Output_CalculateStaticLight(int16_t adder); -void Output_CalculateStaticMeshLight( - int32_t x, int32_t y, int32_t z, int32_t shade_1, int32_t shade_2, - const ROOM *room); -void Output_CalculateObjectLighting(const ITEM *item, const BOUNDS_16 *bounds); -void Output_LightRoom(ROOM *room); void Output_SetupBelowWater(bool is_underwater); void Output_SetupAboveWater(bool is_underwater); void Output_AnimateTextures(int32_t ticks); - -void Output_AddDynamicLight( - int32_t x, int32_t y, int32_t z, int32_t intensity, int32_t falloff); diff --git a/src/tr2/game/room_draw.c b/src/tr2/game/room_draw.c index 4b04ea6fa..c2f5ec91a 100644 --- a/src/tr2/game/room_draw.c +++ b/src/tr2/game/room_draw.c @@ -432,9 +432,7 @@ void Room_DrawSingleRoomObjects(const int16_t room_num) Matrix_RotY(mesh->rot.y); const int16_t clip = Output_GetObjectBounds(&static_obj->draw_bounds); if (clip != 0) { - Output_CalculateStaticMeshLight( - mesh->pos.x, mesh->pos.y, mesh->pos.z, mesh->shade_1, - mesh->shade_2, r); + Output_CalculateStaticMeshLight(mesh->pos, mesh->shade, r); Object_DrawMesh(static_obj->mesh_idx, clip, false); } Matrix_Pop(); diff --git a/src/tr2/game/spawn.c b/src/tr2/game/spawn.c index c745d6f7b..72df266e9 100644 --- a/src/tr2/game/spawn.c +++ b/src/tr2/game/spawn.c @@ -69,9 +69,7 @@ void Spawn_MysticLight(const int16_t item_num) // clang-format off Output_AddDynamicLight( - item->pos.x, - item->pos.y, - item->pos.z, + item->pos, ((4 * Random_GetDraw()) >> 15) + 12, ((4 * Random_GetDraw()) >> 15) + 10); // clang-format on diff --git a/src/tr2/global/const.h b/src/tr2/global/const.h index 0a21ed933..51851fd05 100644 --- a/src/tr2/global/const.h +++ b/src/tr2/global/const.h @@ -11,7 +11,6 @@ #define BAD_JUMP_CEILING ((STEP_L * 3) / 4) // = 192 #define STEPUP_HEIGHT ((STEP_L * 3) / 2) // = 384 #define SLOPE_DIF 60 -#define WIBBLE_SIZE 32 #define MAX_WIBBLE 2 #define MAX_SHADE 0x300 #define LIGHT_MAP_SIZE 32 @@ -37,7 +36,6 @@ #define MAX_BOUND_ROOMS 128 #define MAX_ITEMS 256 #define MAX_EFFECTS 100 -#define MAX_DYNAMIC_LIGHTS 10 #define MAX_LEVELS 24 #define MAX_LEVEL_NAME_SIZE 50 // TODO: get rid of this limit #define MAX_DEMO_FILES MAX_LEVELS diff --git a/src/tr2/global/vars.c b/src/tr2/global/vars.c index 0a77aa404..13b195b41 100644 --- a/src/tr2/global/vars.c +++ b/src/tr2/global/vars.c @@ -107,7 +107,6 @@ int16_t *g_FlyZone[2] = {}; int16_t *g_GroundZone[4][2] = {}; uint16_t *g_Overlap = NULL; CREATURE *g_BaddieSlots = NULL; -int32_t g_DynamicLightCount; STATIC_OBJECT_3D g_StaticObjects3D[MAX_STATIC_OBJECTS]; STATIC_OBJECT_2D g_StaticObjects2D[MAX_STATIC_OBJECTS]; diff --git a/src/tr2/global/vars.h b/src/tr2/global/vars.h index b280c5ac2..a65c1af36 100644 --- a/src/tr2/global/vars.h +++ b/src/tr2/global/vars.h @@ -104,7 +104,6 @@ extern int16_t *g_FlyZone[2]; extern int16_t *g_GroundZone[][2]; extern uint16_t *g_Overlap; extern CREATURE *g_BaddieSlots; -extern int32_t g_DynamicLightCount; extern STATIC_OBJECT_3D g_StaticObjects3D[MAX_STATIC_OBJECTS]; extern STATIC_OBJECT_2D g_StaticObjects2D[MAX_STATIC_OBJECTS]; extern OBJECT_VECTOR *g_SoundEffects;