Merge branch 'master' into float_velocities

This commit is contained in:
Sezz 2022-08-13 09:45:07 +10:00
commit 79dde962fe
33 changed files with 456 additions and 1348 deletions

View file

@ -9,11 +9,15 @@ Version 1.0.1
- Fixed camera behaviour with pushable blocks. - Fixed camera behaviour with pushable blocks.
- Fixed minecart unduck on inclines. - Fixed minecart unduck on inclines.
- Fixed quadbike dismount with jump key and allow to shoot big gun with action key. - Fixed quadbike dismount with jump key and allow to shoot big gun with action key.
- Fixed static meshes having wrong colors on savegame reload.
- Fixed rollingball incorrectly killing Lara in water and in jump. - Fixed rollingball incorrectly killing Lara in water and in jump.
- Fixed resurfacing on underwater death. - Fixed resurfacing on underwater death.
- Fixed ripples not appearing on water connections higher than room bottom. - Fixed ripples not appearing on water connections higher than room bottom.
- Fixed crashes when loading image files are missing.
- Clear locusts and other swarm enemies on level reload.
- Prevent title music audio from starting in a random place. - Prevent title music audio from starting in a random place.
- Update harpoon speed on room change. - Update harpoon speed on room change.
- Enable second sky layer rendering.
- Timer.Create now lets you choose the units to display remaining time. - Timer.Create now lets you choose the units to display remaining time.
- Fatal script errors now boot you to the title (it will crash if the title itself has these errors). - Fatal script errors now boot you to the title (it will crash if the title itself has these errors).
- SetFarView has been removed, and Flow.Level.farView is now uncapped. - SetFarView has been removed, and Flow.Level.farView is now uncapped.

View file

@ -370,11 +370,12 @@ unsigned CALLBACK GameMain(void *)
TimeInit(); TimeInit();
if (g_GameFlow->IntroImagePath.empty())
throw TENScriptException("Intro image path is not set.");
// Do a fixed time title image // Do a fixed time title image
g_Renderer.RenderTitleImage(); if (g_GameFlow->IntroImagePath.empty())
TENLog("Intro image path is not set.", LogLevel::Warning);
else
g_Renderer.RenderTitleImage();
// Execute the LUA gameflow and play the game // Execute the LUA gameflow and play the game
g_GameFlow->DoFlow(); g_GameFlow->DoFlow();
@ -717,6 +718,9 @@ void CleanUp()
DisableBubbles(); DisableBubbles();
DisableDebris(); DisableDebris();
// Clear swarm enemies
ClearSwarmEnemies(nullptr);
// Clear soundtrack masks // Clear soundtrack masks
ClearSoundTrackMasks(); ClearSoundTrackMasks();
} }

View file

@ -22,6 +22,7 @@
#include "Objects/TR5/Emitter/tr5_spider_emitter.h" #include "Objects/TR5/Emitter/tr5_spider_emitter.h"
#include "Objects/TR5/Emitter/tr5_rats_emitter.h" #include "Objects/TR5/Emitter/tr5_rats_emitter.h"
#include "Objects/TR5/Object/tr5_pushableblock.h" #include "Objects/TR5/Object/tr5_pushableblock.h"
#include "Objects/Effects/tr4_locusts.h"
using std::function; using std::function;
using namespace TEN::Effects::Footprints; using namespace TEN::Effects::Footprints;
@ -85,6 +86,7 @@ void ClearSwarmEnemies(ItemInfo* item)
ClearSpiders(); ClearSpiders();
ClearRats(); ClearRats();
ClearBeetleSwarm(); ClearBeetleSwarm();
ClearLocusts();
} }
void FlashOrange(ItemInfo* item) void FlashOrange(ItemInfo* item)

View file

@ -49,7 +49,7 @@ struct FX_INFO
short fallspeed; short fallspeed;
int frameNumber; int frameNumber;
short counter; short counter;
short shade; Vector4 color;
short flag1; short flag1;
short flag2; short flag2;
}; };

View file

@ -1506,7 +1506,7 @@ void ExplodingDeath(short itemNumber, short flags)
} }
fx->objectNumber = ID_BODY_PART; fx->objectNumber = ID_BODY_PART;
fx->shade = 16912; fx->color = item->Color;
fx->flag2 = flags; fx->flag2 = flags;
fx->frameNumber = obj->meshIndex + i; fx->frameNumber = obj->meshIndex + i;
} }

View file

@ -106,39 +106,24 @@ namespace TEN::Effects::Environment
void EnvironmentController::UpdateSky(ScriptInterfaceLevel* level) void EnvironmentController::UpdateSky(ScriptInterfaceLevel* level)
{ {
if (level->GetSkyLayerEnabled(0)) for (int i = 0; i < 2; i++)
{ {
SkyPosition1 += level->GetSkyLayerSpeed(0); if (!level->GetSkyLayerEnabled(i))
if (SkyPosition1 <= SKY_POSITION_LIMIT) continue;
{
if (SkyPosition1 < 0)
SkyPosition1 += SKY_POSITION_LIMIT;
}
else
{
SkyPosition1 -= SKY_POSITION_LIMIT;
}
}
if (level->GetSkyLayerEnabled(1)) SkyCurrentPosition[i] += level->GetSkyLayerSpeed(i);
{ if (SkyCurrentPosition[i] <= SKY_POSITION_LIMIT)
SkyPosition2 += level->GetSkyLayerSpeed(1);
if (SkyPosition2 <= SKY_POSITION_LIMIT)
{ {
if (SkyPosition2 < 0) if (SkyCurrentPosition[i] < 0)
SkyPosition2 += SKY_POSITION_LIMIT; SkyCurrentPosition[i] += SKY_POSITION_LIMIT;
} }
else else
{ SkyCurrentPosition[i] -= SKY_POSITION_LIMIT;
SkyPosition2 -= SKY_POSITION_LIMIT;
}
} }
} }
void EnvironmentController::UpdateStorm(ScriptInterfaceLevel* level) void EnvironmentController::UpdateStorm(ScriptInterfaceLevel* level)
{ {
auto color = Vector4(level->GetSkyLayerColor(0).GetR() / 255.0f, level->GetSkyLayerColor(0).GetG() / 255.0f, level->GetSkyLayerColor(0).GetB() / 255.0f, 1.0f);
if (level->HasStorm()) if (level->HasStorm())
{ {
if (StormCount || StormRand) if (StormCount || StormRand)
@ -154,16 +139,26 @@ namespace TEN::Effects::Environment
StormCount = (rand() & 0x1F) + 16; StormCount = (rand() & 0x1F) + 16;
StormTimer = (rand() & 3) + 12; StormTimer = (rand() & 3) + 12;
} }
auto flashBrightness = StormSkyColor / 255.0f;
auto r = std::clamp(color.x + flashBrightness, 0.0f, 1.0f);
auto g = std::clamp(color.y + flashBrightness, 0.0f, 1.0f);
auto b = std::clamp(color.z + flashBrightness, 0.0f, 1.0f);
SkyCurrentColor = Vector4(r, g, b, color.w);
} }
else
SkyCurrentColor = color; for (int i = 0; i < 2; i++)
{
auto color = Vector4(level->GetSkyLayerColor(i).GetR() / 255.0f,
level->GetSkyLayerColor(i).GetG() / 255.0f,
level->GetSkyLayerColor(i).GetB() / 255.0f, 1.0f);
if (level->HasStorm())
{
auto flashBrightness = StormSkyColor / 255.0f;
auto r = std::clamp(color.x + flashBrightness, 0.0f, 1.0f);
auto g = std::clamp(color.y + flashBrightness, 0.0f, 1.0f);
auto b = std::clamp(color.z + flashBrightness, 0.0f, 1.0f);
SkyCurrentColor[i] = Vector4(r, g, b, color.w);
}
else
SkyCurrentColor[i] = color;
}
} }
void EnvironmentController::UpdateLightning() void EnvironmentController::UpdateLightning()

View file

@ -31,9 +31,8 @@ namespace TEN::Effects::Environment
Vector3 Wind() { return Vector3(WindX / 2.0f, 0, WindZ / 2.0f); } Vector3 Wind() { return Vector3(WindX / 2.0f, 0, WindZ / 2.0f); }
Vector3 FlashColor() { return FlashColorBase * sin(FlashProgress * PI / 2.0f); } Vector3 FlashColor() { return FlashColorBase * sin(FlashProgress * PI / 2.0f); }
Vector4 SkyColor() { return SkyCurrentColor; } Vector4 SkyColor(int index) { return SkyCurrentColor[std::clamp(index, 0, 1)]; }
short SkyLayer1Position() { return SkyPosition1; } short SkyPosition(int index) { return SkyCurrentPosition[std::clamp(index, 0, 1)]; }
short SkyLayer2Position() { return SkyPosition2; }
void Flash(int r, int g, int b, float speed); void Flash(int r, int g, int b, float speed);
void Update(); void Update();
@ -46,9 +45,8 @@ namespace TEN::Effects::Environment
std::vector<WeatherParticle> Particles; std::vector<WeatherParticle> Particles;
// Sky // Sky
Vector4 SkyCurrentColor = Vector4::Zero; Vector4 SkyCurrentColor[2] = {};
short SkyPosition1 = 0; short SkyCurrentPosition[2] = {};
short SkyPosition2 = 0;
// Wind // Wind
int WindX = 0; int WindX = 0;

View file

@ -374,7 +374,7 @@ short CreateNewEffect(short roomNum)
room->fxNumber = fxNumber; room->fxNumber = fxNumber;
fx->nextActive = NextFxActive; fx->nextActive = NextFxActive;
NextFxActive = fxNumber; NextFxActive = fxNumber;
fx->shade = GRAY555; fx->color = Vector4::One;
} }
return fxNumber; return fxNumber;

View file

@ -10,12 +10,6 @@
enum GAME_OBJECT_ID : short; enum GAME_OBJECT_ID : short;
// used by fx->shade !
#define RGB555(r, g, b) ((r << 7) & 0x7C00 | (g << 2) & 0x3E0 | (b >> 3) & 0x1F)
#define WHITE555 RGB555(255, 255, 255)
#define GRAY555 RGB555(128, 128, 128)
#define BLACK555 RGB555( 0, 0, 0)
constexpr auto NO_ITEM = -1; constexpr auto NO_ITEM = -1;
constexpr auto NOT_TARGETABLE = -16384; constexpr auto NOT_TARGETABLE = -16384;
constexpr auto NUM_ITEMS = 1024; constexpr auto NUM_ITEMS = 1024;

View file

@ -178,7 +178,7 @@ short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber
fx->speed = SHARD_VELOCITY; fx->speed = SHARD_VELOCITY;
fx->frameNumber = 0; fx->frameNumber = 0;
fx->objectNumber = ID_PROJ_SHARD; fx->objectNumber = ID_PROJ_SHARD;
fx->shade = 14 * 256; fx->color = Vector4::One;
ShootAtLara(fx); ShootAtLara(fx);
} }
@ -201,7 +201,7 @@ short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
fx->speed = ROCKET_VELOCITY; fx->speed = ROCKET_VELOCITY;
fx->frameNumber = 0; fx->frameNumber = 0;
fx->objectNumber = ID_PROJ_BOMB; fx->objectNumber = ID_PROJ_BOMB;
fx->shade = 16 * 256; fx->color = Vector4::One;
ShootAtLara(fx); ShootAtLara(fx);
} }
@ -224,7 +224,7 @@ short NatlaGun(int x, int y, int z, short velocity, short yRot, short roomNumber
fx->speed = NATLA_GUN_VELOCITY; fx->speed = NATLA_GUN_VELOCITY;
fx->frameNumber = 0; fx->frameNumber = 0;
fx->objectNumber = ID_PROJ_NATLA; fx->objectNumber = ID_PROJ_NATLA;
fx->shade = 16 * 256; fx->color = Vector4::One;
ShootAtLara(fx); ShootAtLara(fx);
} }

View file

@ -102,6 +102,46 @@ Save::Position FromPHD(PHD_3DPOS const& src)
}; };
} }
Save::Vector3 FromVector3(Vector3 vec)
{
return Save::Vector3(vec.x, vec.y, vec.z);
}
Save::Vector3 FromVector3(Vector3Int vec)
{
return Save::Vector3(vec.x, vec.y, vec.z);
}
Save::Vector3 FromVector3(Vector3Shrt vec)
{
return Save::Vector3(vec.x, vec.y, vec.z);
}
Save::Vector4 FromVector4(Vector4 vec)
{
return Save::Vector4(vec.x, vec.y, vec.z, vec.w);
}
Vector3Shrt ToVector3Shrt(const Save::Vector3* vec)
{
return Vector3Shrt(short(vec->x()), short(vec->y()), short(vec->z()));
}
Vector3Int ToVector3Int(const Save::Vector3* vec)
{
return Vector3Int(int(vec->x()), int(vec->y()), int(vec->z()));
}
Vector3 ToVector3(const Save::Vector3* vec)
{
return Vector3(vec->x(), vec->y(), vec->z());
}
Vector4 ToVector4(const Save::Vector4* vec)
{
return Vector4(vec->x(), vec->y(), vec->z(), vec->w());
}
bool SaveGame::Save(int slot) bool SaveGame::Save(int slot)
{ {
auto fileName = std::string(SAVEGAME_PATH) + "savegame." + std::to_string(slot); auto fileName = std::string(SAVEGAME_PATH) + "savegame." + std::to_string(slot);
@ -196,17 +236,6 @@ bool SaveGame::Save(int slot)
wet.push_back(Lara.Wet[i] == 1); wet.push_back(Lara.Wet[i] == 1);
auto wetOffset = fbb.CreateVector(wet); auto wetOffset = fbb.CreateVector(wet);
Save::Vector3 nextCornerPos = Save::Vector3(Lara.NextCornerPos.Position.x, Lara.NextCornerPos.Position.y, Lara.NextCornerPos.Position.z);
Save::Vector3 nextCornerRot = Save::Vector3(Lara.NextCornerPos.Orientation.x, Lara.NextCornerPos.Orientation.y, Lara.NextCornerPos.Orientation.z);
Save::Vector3 leftArmRotation = Save::Vector3(Lara.LeftArm.Orientation.x, Lara.LeftArm.Orientation.y, Lara.LeftArm.Orientation.z);
Save::Vector3 rightArmRotation = Save::Vector3(Lara.RightArm.Orientation.x, Lara.RightArm.Orientation.y, Lara.RightArm.Orientation.z);
Save::Vector3 extraHeadRot = Save::Vector3(Lara.ExtraHeadRot.x, Lara.ExtraHeadRot.y, Lara.ExtraHeadRot.z);
Save::Vector3 extraTorsoRot = Save::Vector3(Lara.ExtraTorsoRot.x, Lara.ExtraTorsoRot.y, Lara.ExtraTorsoRot.z);
Save::Vector3 extraVelocity = Save::Vector3(Lara.ExtraVelocity.x, Lara.ExtraVelocity.y, Lara.ExtraVelocity.z);
Save::Vector3 waterCurrentPull = Save::Vector3(Lara.WaterCurrentPull.x, Lara.WaterCurrentPull.y, Lara.WaterCurrentPull.z);
std::vector<int> laraTargetAngles{}; std::vector<int> laraTargetAngles{};
laraTargetAngles.push_back(Lara.TargetArmOrient.y); laraTargetAngles.push_back(Lara.TargetArmOrient.y);
laraTargetAngles.push_back(Lara.TargetArmOrient.x); laraTargetAngles.push_back(Lara.TargetArmOrient.x);
@ -230,7 +259,7 @@ bool SaveGame::Save(int slot)
leftArm.add_frame_base(Lara.LeftArm.FrameBase); leftArm.add_frame_base(Lara.LeftArm.FrameBase);
leftArm.add_frame_number(Lara.LeftArm.FrameNumber); leftArm.add_frame_number(Lara.LeftArm.FrameNumber);
leftArm.add_locked(Lara.LeftArm.Locked); leftArm.add_locked(Lara.LeftArm.Locked);
leftArm.add_rotation(&leftArmRotation); leftArm.add_rotation(&FromVector3(Lara.LeftArm.Orientation));
auto leftArmOffset = leftArm.Finish(); auto leftArmOffset = leftArm.Finish();
Save::ArmInfoBuilder rightArm{ fbb }; Save::ArmInfoBuilder rightArm{ fbb };
@ -240,7 +269,7 @@ bool SaveGame::Save(int slot)
rightArm.add_frame_base(Lara.RightArm.FrameBase); rightArm.add_frame_base(Lara.RightArm.FrameBase);
rightArm.add_frame_number(Lara.RightArm.FrameNumber); rightArm.add_frame_number(Lara.RightArm.FrameNumber);
rightArm.add_locked(Lara.RightArm.Locked); rightArm.add_locked(Lara.RightArm.Locked);
rightArm.add_rotation(&rightArmRotation); rightArm.add_rotation(&FromVector3(Lara.RightArm.Orientation));
auto rightArmOffset = rightArm.Finish(); auto rightArmOffset = rightArm.Finish();
Save::FlareDataBuilder flare{ fbb }; Save::FlareDataBuilder flare{ fbb };
@ -397,12 +426,11 @@ bool SaveGame::Save(int slot)
lara.add_burn_blue(Lara.BurnBlue); lara.add_burn_blue(Lara.BurnBlue);
lara.add_burn_smoke(Lara.BurnSmoke); lara.add_burn_smoke(Lara.BurnSmoke);
lara.add_control(controlOffset); lara.add_control(controlOffset);
lara.add_next_corner_position(&nextCornerPos); lara.add_next_corner_pose(&FromPHD(Lara.NextCornerPos));
lara.add_next_corner_rotation(&nextCornerRot);
lara.add_extra_anim(Lara.ExtraAnim); lara.add_extra_anim(Lara.ExtraAnim);
lara.add_extra_head_rot(&extraHeadRot); lara.add_extra_head_rot(&FromVector3(Lara.ExtraHeadRot));
lara.add_extra_torso_rot(&extraTorsoRot); lara.add_extra_torso_rot(&FromVector3(Lara.ExtraTorsoRot));
lara.add_extra_velocity(&extraVelocity); lara.add_extra_velocity(&FromVector3(Lara.ExtraVelocity));
lara.add_flare(flareOffset); lara.add_flare(flareOffset);
lara.add_highest_location(Lara.HighestLocation); lara.add_highest_location(Lara.HighestLocation);
lara.add_hit_direction(Lara.HitDirection); lara.add_hit_direction(Lara.HitDirection);
@ -424,7 +452,7 @@ bool SaveGame::Save(int slot)
lara.add_torch(torchOffset); lara.add_torch(torchOffset);
lara.add_vehicle(Lara.Vehicle); lara.add_vehicle(Lara.Vehicle);
lara.add_water_current_active(Lara.WaterCurrentActive); lara.add_water_current_active(Lara.WaterCurrentActive);
lara.add_water_current_pull(&waterCurrentPull); lara.add_water_current_pull(&FromVector3(Lara.WaterCurrentPull));
lara.add_water_surface_dist(Lara.WaterSurfaceDist); lara.add_water_surface_dist(Lara.WaterSurfaceDist);
lara.add_weapons(carriedWeaponsOffset); lara.add_weapons(carriedWeaponsOffset);
lara.add_wet(wetOffset); lara.add_wet(wetOffset);
@ -563,13 +591,7 @@ bool SaveGame::Save(int slot)
kayakBuilder.add_front_vertical_velocity(kayak->FrontVerticalVelocity); kayakBuilder.add_front_vertical_velocity(kayak->FrontVerticalVelocity);
kayakBuilder.add_left_right_count(kayak->LeftRightPaddleCount); kayakBuilder.add_left_right_count(kayak->LeftRightPaddleCount);
kayakBuilder.add_left_vertical_velocity(kayak->LeftVerticalVelocity); kayakBuilder.add_left_vertical_velocity(kayak->LeftVerticalVelocity);
kayakBuilder.add_old_pos(&Save::Position( kayakBuilder.add_old_pos(&FromPHD(kayak->OldPose));
kayak->OldPose.Position.x,
kayak->OldPose.Position.y,
kayak->OldPose.Position.z,
kayak->OldPose.Orientation.x,
kayak->OldPose.Orientation.y,
kayak->OldPose.Orientation.z));
kayakBuilder.add_right_vertical_velocity(kayak->RightVerticalVelocity); kayakBuilder.add_right_vertical_velocity(kayak->RightVerticalVelocity);
kayakBuilder.add_true_water(kayak->TrueWater); kayakBuilder.add_true_water(kayak->TrueWater);
kayakBuilder.add_turn(kayak->Turn); kayakBuilder.add_turn(kayak->Turn);
@ -592,20 +614,6 @@ bool SaveGame::Save(int slot)
intOffset = ib.Finish(); intOffset = ib.Finish();
} }
Save::Position position = Save::Position(
(int32_t)itemToSerialize.Pose.Position.x,
(int32_t)itemToSerialize.Pose.Position.y,
(int32_t)itemToSerialize.Pose.Position.z,
(int32_t)itemToSerialize.Pose.Orientation.x,
(int32_t)itemToSerialize.Pose.Orientation.y,
(int32_t)itemToSerialize.Pose.Orientation.z);
Save::Vector4 color = Save::Vector4(
itemToSerialize.Color.x,
itemToSerialize.Color.y,
itemToSerialize.Color.z,
itemToSerialize.Color.w);
Save::ItemBuilder serializedItem{ fbb }; Save::ItemBuilder serializedItem{ fbb };
serializedItem.add_next_item(itemToSerialize.NextItem); serializedItem.add_next_item(itemToSerialize.NextItem);
@ -624,12 +632,12 @@ bool SaveGame::Save(int slot)
serializedItem.add_item_flags(itemFlagsOffset); serializedItem.add_item_flags(itemFlagsOffset);
serializedItem.add_mesh_bits(itemToSerialize.MeshBits); serializedItem.add_mesh_bits(itemToSerialize.MeshBits);
serializedItem.add_object_id(itemToSerialize.ObjectNumber); serializedItem.add_object_id(itemToSerialize.ObjectNumber);
serializedItem.add_position(&position); serializedItem.add_pose(&FromPHD(itemToSerialize.Pose));
serializedItem.add_required_state(itemToSerialize.Animation.RequiredState); serializedItem.add_required_state(itemToSerialize.Animation.RequiredState);
serializedItem.add_room_number(itemToSerialize.RoomNumber); serializedItem.add_room_number(itemToSerialize.RoomNumber);
serializedItem.add_velocity(itemToSerialize.Animation.Velocity.z); serializedItem.add_velocity(itemToSerialize.Animation.Velocity.z);
serializedItem.add_timer(itemToSerialize.Timer); serializedItem.add_timer(itemToSerialize.Timer);
serializedItem.add_color(&color); serializedItem.add_color(&FromVector4(itemToSerialize.Color));
serializedItem.add_touch_bits(itemToSerialize.TouchBits); serializedItem.add_touch_bits(itemToSerialize.TouchBits);
serializedItem.add_trigger_flags(itemToSerialize.TriggerFlags); serializedItem.add_trigger_flags(itemToSerialize.TriggerFlags);
serializedItem.add_triggered((itemToSerialize.Flags & (TRIGGERED | CODE_BITS | ONESHOT)) != 0); serializedItem.add_triggered((itemToSerialize.Flags & (TRIGGERED | CODE_BITS | ONESHOT)) != 0);
@ -700,9 +708,8 @@ bool SaveGame::Save(int slot)
for (auto& effectToSerialize : EffectList) for (auto& effectToSerialize : EffectList)
{ {
Save::FXInfoBuilder serializedEffect{ fbb }; Save::FXInfoBuilder serializedEffect{ fbb };
auto savedPos = FromPHD(effectToSerialize.pos);
serializedEffect.add_pos(&savedPos); serializedEffect.add_pose(&FromPHD(effectToSerialize.pos));
serializedEffect.add_room_number(effectToSerialize.roomNumber); serializedEffect.add_room_number(effectToSerialize.roomNumber);
serializedEffect.add_object_number(effectToSerialize.objectNumber); serializedEffect.add_object_number(effectToSerialize.objectNumber);
serializedEffect.add_next_fx(effectToSerialize.nextFx); serializedEffect.add_next_fx(effectToSerialize.nextFx);
@ -711,7 +718,7 @@ bool SaveGame::Save(int slot)
serializedEffect.add_fall_speed(effectToSerialize.fallspeed); serializedEffect.add_fall_speed(effectToSerialize.fallspeed);
serializedEffect.add_frame_number(effectToSerialize.frameNumber); serializedEffect.add_frame_number(effectToSerialize.frameNumber);
serializedEffect.add_counter(effectToSerialize.counter); serializedEffect.add_counter(effectToSerialize.counter);
serializedEffect.add_shade(effectToSerialize.shade); serializedEffect.add_color(&FromVector4(effectToSerialize.color));
serializedEffect.add_flag1(effectToSerialize.flag1); serializedEffect.add_flag1(effectToSerialize.flag1);
serializedEffect.add_flag2(effectToSerialize.flag2); serializedEffect.add_flag2(effectToSerialize.flag2);
@ -808,18 +815,8 @@ bool SaveGame::Save(int slot)
{ {
Save::StaticMeshInfoBuilder staticMesh{ fbb }; Save::StaticMeshInfoBuilder staticMesh{ fbb };
staticMesh.add_position(&Save::Vector3(room->mesh[j].pos.Position.x, staticMesh.add_pose(&FromPHD(room->mesh[j].pos));
room->mesh[j].pos.Position.y, staticMesh.add_color(&FromVector4(room->mesh[j].color));
room->mesh[j].pos.Position.z));
staticMesh.add_rotation(&Save::Vector3(room->mesh[j].pos.Orientation.x,
room->mesh[j].pos.Orientation.y,
room->mesh[j].pos.Orientation.z));
staticMesh.add_color(&Save::Vector4(room->mesh[j].color.x,
room->mesh[j].color.y,
room->mesh[j].color.z,
room->mesh[j].color.w));
staticMesh.add_flags(room->mesh[j].flags); staticMesh.add_flags(room->mesh[j].flags);
staticMesh.add_hit_points(room->mesh[j].HitPoints); staticMesh.add_hit_points(room->mesh[j].HitPoints);
@ -837,18 +834,9 @@ bool SaveGame::Save(int slot)
volumeState.add_room_number(i); volumeState.add_room_number(i);
volumeState.add_number(j); volumeState.add_number(j);
volumeState.add_position(&Save::Vector3(volume.Position.x, volumeState.add_position(&FromVector3(volume.Position));
volume.Position.y, volumeState.add_rotation(&FromVector4(volume.Rotation));
volume.Position.z)); volumeState.add_scale(&FromVector3(volume.Scale));
volumeState.add_rotation(&Save::Vector4(volume.Rotation.x,
volume.Rotation.y,
volume.Rotation.z,
volume.Rotation.w));
volumeState.add_scale(&Save::Vector3(volume.Scale.x,
volume.Scale.y,
volume.Scale.z));
int triggerer = -1; int triggerer = -1;
if (std::holds_alternative<short>(volume.Triggerer)) if (std::holds_alternative<short>(volume.Triggerer))
@ -916,86 +904,66 @@ bool SaveGame::Save(int slot)
} }
auto particleOffset = fbb.CreateVector(particles); auto particleOffset = fbb.CreateVector(particles);
// Particle enemies // Swarm enemies
std::vector<flatbuffers::Offset<Save::BatInfo>> bats; std::vector<flatbuffers::Offset<Save::SwarmObjectInfo>> bats;
for (int i = 0; i < NUM_BATS; i++) for (int i = 0; i < NUM_BATS; i++)
{ {
auto* bat = &Bats[i]; auto* bat = &Bats[i];
Save::BatInfoBuilder batInfo{ fbb }; Save::SwarmObjectInfoBuilder batInfo{ fbb };
batInfo.add_counter(bat->Counter); batInfo.add_flags(bat->Counter);
batInfo.add_on(bat->On); batInfo.add_on(bat->On);
batInfo.add_room_number(bat->RoomNumber); batInfo.add_room_number(bat->RoomNumber);
batInfo.add_x(bat->Pose.Position.x); batInfo.add_pose(&FromPHD(bat->Pose));
batInfo.add_y(bat->Pose.Position.y);
batInfo.add_z(bat->Pose.Position.z);
batInfo.add_x_rot(bat->Pose.Orientation.x);
batInfo.add_y_rot(bat->Pose.Orientation.y);
batInfo.add_z_rot(bat->Pose.Orientation.z);
bats.push_back(batInfo.Finish()); bats.push_back(batInfo.Finish());
} }
auto batsOffset = fbb.CreateVector(bats); auto batsOffset = fbb.CreateVector(bats);
std::vector<flatbuffers::Offset<Save::SpiderInfo>> spiders; std::vector<flatbuffers::Offset<Save::SwarmObjectInfo>> spiders;
for (int i = 0; i < NUM_SPIDERS; i++) for (int i = 0; i < NUM_SPIDERS; i++)
{ {
auto* spider = &Spiders[i]; auto* spider = &Spiders[i];
Save::SpiderInfoBuilder spiderInfo{ fbb }; Save::SwarmObjectInfoBuilder spiderInfo{ fbb };
spiderInfo.add_flags(spider->Flags); spiderInfo.add_flags(spider->Flags);
spiderInfo.add_on(spider->On); spiderInfo.add_on(spider->On);
spiderInfo.add_room_number(spider->RoomNumber); spiderInfo.add_room_number(spider->RoomNumber);
spiderInfo.add_x(spider->Pose.Position.x); spiderInfo.add_pose(&FromPHD(spider->Pose));
spiderInfo.add_y(spider->Pose.Position.y);
spiderInfo.add_z(spider->Pose.Position.z);
spiderInfo.add_x_rot(spider->Pose.Orientation.x);
spiderInfo.add_y_rot(spider->Pose.Orientation.y);
spiderInfo.add_z_rot(spider->Pose.Orientation.z);
spiders.push_back(spiderInfo.Finish()); spiders.push_back(spiderInfo.Finish());
} }
auto spidersOffset = fbb.CreateVector(spiders); auto spidersOffset = fbb.CreateVector(spiders);
std::vector<flatbuffers::Offset<Save::RatInfo>> rats; std::vector<flatbuffers::Offset<Save::SwarmObjectInfo>> rats;
for (int i = 0; i < NUM_RATS; i++) for (int i = 0; i < NUM_RATS; i++)
{ {
auto* rat = &Rats[i]; auto* rat = &Rats[i];
Save::RatInfoBuilder ratInfo{ fbb }; Save::SwarmObjectInfoBuilder ratInfo{ fbb };
ratInfo.add_flags(rat->Flags); ratInfo.add_flags(rat->Flags);
ratInfo.add_on(rat->On); ratInfo.add_on(rat->On);
ratInfo.add_room_number(rat->RoomNumber); ratInfo.add_room_number(rat->RoomNumber);
ratInfo.add_x(rat->Pose.Position.x); ratInfo.add_pose(&FromPHD(rat->Pose));
ratInfo.add_y(rat->Pose.Position.y);
ratInfo.add_z(rat->Pose.Position.z);
ratInfo.add_x_rot(rat->Pose.Orientation.x);
ratInfo.add_y_rot(rat->Pose.Orientation.y);
ratInfo.add_z_rot(rat->Pose.Orientation.z);
rats.push_back(ratInfo.Finish()); rats.push_back(ratInfo.Finish());
} }
auto ratsOffset = fbb.CreateVector(rats); auto ratsOffset = fbb.CreateVector(rats);
std::vector<flatbuffers::Offset<Save::ScarabInfo>> scarabs; std::vector<flatbuffers::Offset<Save::SwarmObjectInfo>> scarabs;
for (int i = 0; i < NUM_BATS; i++) for (int i = 0; i < NUM_BATS; i++)
{ {
auto* beetle = &BeetleSwarm[i]; auto* beetle = &BeetleSwarm[i];
Save::ScarabInfoBuilder scarabInfo{ fbb }; Save::SwarmObjectInfoBuilder scarabInfo{ fbb };
scarabInfo.add_flags(beetle->Flags); scarabInfo.add_flags(beetle->Flags);
scarabInfo.add_on(beetle->On); scarabInfo.add_on(beetle->On);
scarabInfo.add_room_number(beetle->RoomNumber); scarabInfo.add_room_number(beetle->RoomNumber);
scarabInfo.add_x(beetle->Pose.Position.x); scarabInfo.add_pose(&FromPHD(beetle->Pose));
scarabInfo.add_y(beetle->Pose.Position.y);
scarabInfo.add_z(beetle->Pose.Position.z);
scarabInfo.add_x_rot(beetle->Pose.Orientation.x);
scarabInfo.add_y_rot(beetle->Pose.Orientation.y);
scarabInfo.add_z_rot(beetle->Pose.Orientation.z);
scarabs.push_back(scarabInfo.Finish()); scarabs.push_back(scarabInfo.Finish());
} }
@ -1012,42 +980,27 @@ bool SaveGame::Save(int slot)
std::vector<const Save::Vector3*> segments; std::vector<const Save::Vector3*> segments;
for (int i = 0; i < ROPE_SEGMENTS; i++) for (int i = 0; i < ROPE_SEGMENTS; i++)
segments.push_back(&Save::Vector3( segments.push_back(&FromVector3(rope->segment[i]));
rope->segment[i].x,
rope->segment[i].y,
rope->segment[i].z));
auto segmentsOffset = fbb.CreateVector(segments); auto segmentsOffset = fbb.CreateVector(segments);
std::vector<const Save::Vector3*> velocities; std::vector<const Save::Vector3*> velocities;
for (int i = 0; i < ROPE_SEGMENTS; i++) for (int i = 0; i < ROPE_SEGMENTS; i++)
velocities.push_back(&Save::Vector3( velocities.push_back(&FromVector3(rope->velocity[i]));
rope->velocity[i].x,
rope->velocity[i].y,
rope->velocity[i].z));
auto velocitiesOffset = fbb.CreateVector(velocities); auto velocitiesOffset = fbb.CreateVector(velocities);
std::vector<const Save::Vector3*> normalisedSegments; std::vector<const Save::Vector3*> normalisedSegments;
for (int i = 0; i < ROPE_SEGMENTS; i++) for (int i = 0; i < ROPE_SEGMENTS; i++)
normalisedSegments.push_back(&Save::Vector3( normalisedSegments.push_back(&FromVector3(rope->normalisedSegment[i]));
rope->normalisedSegment[i].x,
rope->normalisedSegment[i].y,
rope->normalisedSegment[i].z));
auto normalisedSegmentsOffset = fbb.CreateVector(normalisedSegments); auto normalisedSegmentsOffset = fbb.CreateVector(normalisedSegments);
std::vector<const Save::Vector3*> meshSegments; std::vector<const Save::Vector3*> meshSegments;
for (int i = 0; i < ROPE_SEGMENTS; i++) for (int i = 0; i < ROPE_SEGMENTS; i++)
meshSegments.push_back(&Save::Vector3( meshSegments.push_back(&FromVector3(rope->meshSegment[i]));
rope->meshSegment[i].x,
rope->meshSegment[i].y,
rope->meshSegment[i].z));
auto meshSegmentsOffset = fbb.CreateVector(meshSegments); auto meshSegmentsOffset = fbb.CreateVector(meshSegments);
std::vector<const Save::Vector3*> coords; std::vector<const Save::Vector3*> coords;
for (int i = 0; i < ROPE_SEGMENTS; i++) for (int i = 0; i < ROPE_SEGMENTS; i++)
coords.push_back(&Save::Vector3( coords.push_back(&FromVector3(rope->coords[i]));
rope->coords[i].x,
rope->coords[i].y,
rope->coords[i].z));
auto coordsOffset = fbb.CreateVector(coords); auto coordsOffset = fbb.CreateVector(coords);
Save::RopeBuilder ropeInfo{ fbb }; Save::RopeBuilder ropeInfo{ fbb };
@ -1058,36 +1011,21 @@ bool SaveGame::Save(int slot)
ropeInfo.add_normalised_segments(normalisedSegmentsOffset); ropeInfo.add_normalised_segments(normalisedSegmentsOffset);
ropeInfo.add_coords(coordsOffset); ropeInfo.add_coords(coordsOffset);
ropeInfo.add_coiled(rope->coiled); ropeInfo.add_coiled(rope->coiled);
ropeInfo.add_position(&Save::Vector3( ropeInfo.add_position(&FromVector3(rope->position));
rope->position.x,
rope->position.y,
rope->position.z));
ropeInfo.add_segment_length(rope->segmentLength); ropeInfo.add_segment_length(rope->segmentLength);
ropeOffset = ropeInfo.Finish(); ropeOffset = ropeInfo.Finish();
Save::PendulumBuilder pendulumInfo{ fbb }; Save::PendulumBuilder pendulumInfo{ fbb };
pendulumInfo.add_node(CurrentPendulum.node); pendulumInfo.add_node(CurrentPendulum.node);
pendulumInfo.add_position(&Save::Vector3( pendulumInfo.add_position(&FromVector3(CurrentPendulum.position));
CurrentPendulum.position.x, pendulumInfo.add_velocity(&FromVector3(CurrentPendulum.velocity));
CurrentPendulum.position.y,
CurrentPendulum.position.z));
pendulumInfo.add_velocity(&Save::Vector3(
CurrentPendulum.velocity.x,
CurrentPendulum.velocity.y,
CurrentPendulum.velocity.z));
pendulumOffset = pendulumInfo.Finish(); pendulumOffset = pendulumInfo.Finish();
Save::PendulumBuilder alternatePendulumInfo{ fbb }; Save::PendulumBuilder alternatePendulumInfo{ fbb };
alternatePendulumInfo.add_node(AlternatePendulum.node); alternatePendulumInfo.add_node(AlternatePendulum.node);
alternatePendulumInfo.add_position(&Save::Vector3( alternatePendulumInfo.add_position(&FromVector3(AlternatePendulum.position));
AlternatePendulum.position.x, alternatePendulumInfo.add_velocity(&FromVector3(AlternatePendulum.velocity));
AlternatePendulum.position.y,
AlternatePendulum.position.z));
alternatePendulumInfo.add_velocity(&Save::Vector3(
AlternatePendulum.velocity.x,
AlternatePendulum.velocity.y,
AlternatePendulum.velocity.z));
alternatePendulumOffset = alternatePendulumInfo.Finish(); alternatePendulumOffset = alternatePendulumInfo.Finish();
} }
@ -1298,18 +1236,8 @@ bool SaveGame::Load(int slot)
auto room = &g_Level.Rooms[staticMesh->room_number()]; auto room = &g_Level.Rooms[staticMesh->room_number()];
int number = staticMesh->number(); int number = staticMesh->number();
room->mesh[number].pos.Position = Vector3Int(staticMesh->position()->x(), room->mesh[number].pos = ToPHD(staticMesh->pose());
staticMesh->position()->y(), room->mesh[number].color = ToVector4(staticMesh->color());
staticMesh->position()->z());
room->mesh[number].pos.Orientation = Vector3Shrt(short(staticMesh->rotation()->x()),
short(staticMesh->rotation()->y()),
short(staticMesh->rotation()->z()));
room->mesh[number].color = Vector4(staticMesh->color()->x(),
staticMesh->color()->y(),
staticMesh->color()->z(),
staticMesh->color()->w());
room->mesh[number].flags = staticMesh->flags(); room->mesh[number].flags = staticMesh->flags();
room->mesh[number].HitPoints = staticMesh->hit_points(); room->mesh[number].HitPoints = staticMesh->hit_points();
@ -1330,18 +1258,9 @@ bool SaveGame::Load(int slot)
auto room = &g_Level.Rooms[volume->room_number()]; auto room = &g_Level.Rooms[volume->room_number()];
int number = volume->number(); int number = volume->number();
room->triggerVolumes[number].Position = Vector3(volume->position()->x(), room->triggerVolumes[number].Position = ToVector3(volume->position());
volume->position()->y(), room->triggerVolumes[number].Rotation = ToVector4(volume->rotation());
volume->position()->z()); room->triggerVolumes[number].Scale = ToVector3(volume->scale());
room->triggerVolumes[number].Rotation = Vector4(volume->rotation()->x(),
volume->rotation()->y(),
volume->rotation()->z(),
volume->rotation()->w());
room->triggerVolumes[number].Scale = Vector3(volume->scale()->x(),
volume->scale()->y(),
volume->scale()->z());
int triggerer = volume->triggerer(); int triggerer = volume->triggerer();
if (triggerer >= 0) if (triggerer >= 0)
@ -1410,13 +1329,7 @@ bool SaveGame::Load(int slot)
g_GameScriptEntities->TryAddColliding(i); g_GameScriptEntities->TryAddColliding(i);
item->Pose.Position.x = savedItem->position()->x_pos(); item->Pose = ToPHD(savedItem->pose());
item->Pose.Position.y = savedItem->position()->y_pos();
item->Pose.Position.z = savedItem->position()->z_pos();
item->Pose.Orientation.x = savedItem->position()->x_rot();
item->Pose.Orientation.y = savedItem->position()->y_rot();
item->Pose.Orientation.z = savedItem->position()->z_rot();
item->RoomNumber = savedItem->room_number(); item->RoomNumber = savedItem->room_number();
item->Animation.Velocity.z = savedItem->velocity(); item->Animation.Velocity.z = savedItem->velocity();
@ -1454,10 +1367,7 @@ bool SaveGame::Load(int slot)
item->Flags = savedItem->flags(); item->Flags = savedItem->flags();
// Color // Color
item->Color = Vector4(savedItem->color()->x(), item->Color = ToVector4(savedItem->color());
savedItem->color()->y(),
savedItem->color()->z(),
savedItem->color()->w());
// Carried item // Carried item
item->CarriedItem = savedItem->carried_item(); item->CarriedItem = savedItem->carried_item();
@ -1591,12 +1501,7 @@ bool SaveGame::Load(int slot)
kayak->FrontVerticalVelocity = savedKayak->front_vertical_velocity(); kayak->FrontVerticalVelocity = savedKayak->front_vertical_velocity();
kayak->LeftRightPaddleCount = savedKayak->left_right_count(); kayak->LeftRightPaddleCount = savedKayak->left_right_count();
kayak->LeftVerticalVelocity = savedKayak->left_vertical_velocity(); kayak->LeftVerticalVelocity = savedKayak->left_vertical_velocity();
kayak->OldPose.Position.x = savedKayak->old_pos()->x_pos(); kayak->OldPose = ToPHD(savedKayak->old_pos());
kayak->OldPose.Position.y = savedKayak->old_pos()->y_pos();
kayak->OldPose.Position.z = savedKayak->old_pos()->z_pos();
kayak->OldPose.Orientation.x = savedKayak->old_pos()->x_rot();
kayak->OldPose.Orientation.y = savedKayak->old_pos()->y_rot();
kayak->OldPose.Orientation.z = savedKayak->old_pos()->z_rot();
kayak->RightVerticalVelocity = savedKayak->right_vertical_velocity(); kayak->RightVerticalVelocity = savedKayak->right_vertical_velocity();
kayak->TrueWater = savedKayak->true_water(); kayak->TrueWater = savedKayak->true_water();
kayak->Turn = savedKayak->turn(); kayak->Turn = savedKayak->turn();
@ -1669,14 +1574,9 @@ bool SaveGame::Load(int slot)
auto* bat = &Bats[i]; auto* bat = &Bats[i];
bat->On = batInfo->on(); bat->On = batInfo->on();
bat->Counter = batInfo->counter(); bat->Counter = batInfo->flags();
bat->RoomNumber = batInfo->room_number(); bat->RoomNumber = batInfo->room_number();
bat->Pose.Position.x = batInfo->x(); bat->Pose = ToPHD(batInfo->pose());
bat->Pose.Position.y = batInfo->y();
bat->Pose.Position.z = batInfo->z();
bat->Pose.Orientation.x = batInfo->x_rot();
bat->Pose.Orientation.y = batInfo->y_rot();
bat->Pose.Orientation.z = batInfo->z_rot();
} }
for (int i = 0; i < s->rats()->size(); i++) for (int i = 0; i < s->rats()->size(); i++)
@ -1687,12 +1587,7 @@ bool SaveGame::Load(int slot)
rat->On = ratInfo->on(); rat->On = ratInfo->on();
rat->Flags = ratInfo->flags(); rat->Flags = ratInfo->flags();
rat->RoomNumber = ratInfo->room_number(); rat->RoomNumber = ratInfo->room_number();
rat->Pose.Position.x = ratInfo->x(); rat->Pose = ToPHD(ratInfo->pose());
rat->Pose.Position.y = ratInfo->y();
rat->Pose.Position.z = ratInfo->z();
rat->Pose.Orientation.x = ratInfo->x_rot();
rat->Pose.Orientation.y = ratInfo->y_rot();
rat->Pose.Orientation.z = ratInfo->z_rot();
} }
for (int i = 0; i < s->spiders()->size(); i++) for (int i = 0; i < s->spiders()->size(); i++)
@ -1703,28 +1598,18 @@ bool SaveGame::Load(int slot)
spider->On = spiderInfo->on(); spider->On = spiderInfo->on();
spider->Flags = spiderInfo->flags(); spider->Flags = spiderInfo->flags();
spider->RoomNumber = spiderInfo->room_number(); spider->RoomNumber = spiderInfo->room_number();
spider->Pose.Position.x = spiderInfo->x(); spider->Pose = ToPHD(spiderInfo->pose());
spider->Pose.Position.y = spiderInfo->y();
spider->Pose.Position.z = spiderInfo->z();
spider->Pose.Orientation.x = spiderInfo->x_rot();
spider->Pose.Orientation.y = spiderInfo->y_rot();
spider->Pose.Orientation.z = spiderInfo->z_rot();
} }
for (int i = 0; i < s->scarabs()->size(); i++) for (int i = 0; i < s->scarabs()->size(); i++)
{ {
auto beetleInfo = s->scarabs()->Get(i); auto beetleInfo = s->scarabs()->Get(i);
auto* Beetle = &BeetleSwarm[i]; auto* beetle = &BeetleSwarm[i];
Beetle->On = beetleInfo->on(); beetle->On = beetleInfo->on();
Beetle->Flags = beetleInfo->flags(); beetle->Flags = beetleInfo->flags();
Beetle->RoomNumber = beetleInfo->room_number(); beetle->RoomNumber = beetleInfo->room_number();
Beetle->Pose.Position.x = beetleInfo->x(); beetle->Pose = ToPHD(beetleInfo->pose());
Beetle->Pose.Position.y = beetleInfo->y();
Beetle->Pose.Position.z = beetleInfo->z();
Beetle->Pose.Orientation.x = beetleInfo->x_rot();
Beetle->Pose.Orientation.y = beetleInfo->y_rot();
Beetle->Pose.Orientation.z = beetleInfo->z_rot();
} }
NextFxFree = s->next_fx_free(); NextFxFree = s->next_fx_free();
@ -1734,7 +1619,7 @@ bool SaveGame::Load(int slot)
{ {
auto& fx = EffectList[i]; auto& fx = EffectList[i];
auto fx_saved = s->fxinfos()->Get(i); auto fx_saved = s->fxinfos()->Get(i);
fx.pos = ToPHD(fx_saved->pos()); fx.pos = ToPHD(fx_saved->pose());
fx.roomNumber = fx_saved->room_number(); fx.roomNumber = fx_saved->room_number();
fx.objectNumber = fx_saved->object_number(); fx.objectNumber = fx_saved->object_number();
fx.nextFx = fx_saved->next_fx(); fx.nextFx = fx_saved->next_fx();
@ -1743,7 +1628,7 @@ bool SaveGame::Load(int slot)
fx.fallspeed = fx_saved->fall_speed(); fx.fallspeed = fx_saved->fall_speed();
fx.frameNumber = fx_saved->frame_number(); fx.frameNumber = fx_saved->frame_number();
fx.counter = fx_saved->counter(); fx.counter = fx_saved->counter();
fx.shade = fx_saved->shade(); fx.color = ToVector4(fx_saved->color());
fx.flag1 = fx_saved->flag1(); fx.flag1 = fx_saved->flag1();
fx.flag2 = fx_saved->flag2(); fx.flag2 = fx_saved->flag2();
} }
@ -1901,18 +1786,10 @@ bool SaveGame::Load(int slot)
Lara.LeftArm.FrameBase = s->lara()->left_arm()->frame_base(); Lara.LeftArm.FrameBase = s->lara()->left_arm()->frame_base();
Lara.LeftArm.FrameNumber = s->lara()->left_arm()->frame_number(); Lara.LeftArm.FrameNumber = s->lara()->left_arm()->frame_number();
Lara.LeftArm.Locked = s->lara()->left_arm()->locked(); Lara.LeftArm.Locked = s->lara()->left_arm()->locked();
Lara.LeftArm.Orientation.x = s->lara()->left_arm()->rotation()->x(); Lara.LeftArm.Orientation = ToVector3Shrt(s->lara()->left_arm()->rotation());
Lara.LeftArm.Orientation.y = s->lara()->left_arm()->rotation()->y();
Lara.LeftArm.Orientation.z = s->lara()->left_arm()->rotation()->z();
Lara.Location = s->lara()->location(); Lara.Location = s->lara()->location();
Lara.LocationPad = s->lara()->location_pad(); Lara.LocationPad = s->lara()->location_pad();
Lara.NextCornerPos = PHD_3DPOS( Lara.NextCornerPos = ToPHD(s->lara()->next_corner_pose());
s->lara()->next_corner_position()->x(),
s->lara()->next_corner_position()->y(),
s->lara()->next_corner_position()->z(),
s->lara()->next_corner_rotation()->x(),
s->lara()->next_corner_rotation()->y(),
s->lara()->next_corner_rotation()->z());
Lara.PoisonPotency = s->lara()->poison_potency(); Lara.PoisonPotency = s->lara()->poison_potency();
Lara.ProjectedFloorHeight = s->lara()->projected_floor_height(); Lara.ProjectedFloorHeight = s->lara()->projected_floor_height();
Lara.RightArm.AnimNumber = s->lara()->right_arm()->anim_number(); Lara.RightArm.AnimNumber = s->lara()->right_arm()->anim_number();
@ -1921,9 +1798,7 @@ bool SaveGame::Load(int slot)
Lara.RightArm.FrameBase = s->lara()->right_arm()->frame_base(); Lara.RightArm.FrameBase = s->lara()->right_arm()->frame_base();
Lara.RightArm.FrameNumber = s->lara()->right_arm()->frame_number(); Lara.RightArm.FrameNumber = s->lara()->right_arm()->frame_number();
Lara.RightArm.Locked = s->lara()->right_arm()->locked(); Lara.RightArm.Locked = s->lara()->right_arm()->locked();
Lara.RightArm.Orientation.x = s->lara()->right_arm()->rotation()->x(); Lara.RightArm.Orientation = ToVector3Shrt(s->lara()->right_arm()->rotation());
Lara.RightArm.Orientation.y = s->lara()->right_arm()->rotation()->y();
Lara.RightArm.Orientation.z = s->lara()->right_arm()->rotation()->z();
Lara.Torch.IsLit = s->lara()->torch()->is_lit(); Lara.Torch.IsLit = s->lara()->torch()->is_lit();
Lara.Torch.State = (TorchState)s->lara()->torch()->state(); Lara.Torch.State = (TorchState)s->lara()->torch()->state();
Lara.Control.Rope.Segment = s->lara()->control()->rope()->segment(); Lara.Control.Rope.Segment = s->lara()->control()->rope()->segment();
@ -2001,61 +1876,25 @@ bool SaveGame::Load(int slot)
for (int i = 0; i < ROPE_SEGMENTS; i++) for (int i = 0; i < ROPE_SEGMENTS; i++)
{ {
rope->segment[i] = Vector3Int( rope->segment[i] = ToVector3Int(s->rope()->segments()->Get(i));
s->rope()->segments()->Get(i)->x(), rope->normalisedSegment[i] = ToVector3Int(s->rope()->normalised_segments()->Get(i));
s->rope()->segments()->Get(i)->y(), rope->meshSegment[i] = ToVector3Int(s->rope()->mesh_segments()->Get(i));
s->rope()->segments()->Get(i)->z()); rope->coords[i] = ToVector3Int(s->rope()->coords()->Get(i));
rope->velocity[i] = ToVector3Int(s->rope()->velocities()->Get(i));
rope->normalisedSegment[i] = Vector3Int(
s->rope()->normalised_segments()->Get(i)->x(),
s->rope()->normalised_segments()->Get(i)->y(),
s->rope()->normalised_segments()->Get(i)->z());
rope->meshSegment[i] = Vector3Int(
s->rope()->mesh_segments()->Get(i)->x(),
s->rope()->mesh_segments()->Get(i)->y(),
s->rope()->mesh_segments()->Get(i)->z());
rope->coords[i] = Vector3Int(
s->rope()->coords()->Get(i)->x(),
s->rope()->coords()->Get(i)->y(),
s->rope()->coords()->Get(i)->z());
rope->velocity[i] = Vector3Int(
s->rope()->velocities()->Get(i)->x(),
s->rope()->velocities()->Get(i)->y(),
s->rope()->velocities()->Get(i)->z());
} }
rope->coiled = s->rope()->coiled(); rope->coiled = s->rope()->coiled();
rope->active = s->rope()->active(); rope->active = s->rope()->active();
rope->position = Vector3Int(
s->rope()->position()->x(),
s->rope()->position()->y(),
s->rope()->position()->z());
CurrentPendulum.position = Vector3Int( rope->position = ToVector3Int(s->rope()->position());
s->pendulum()->position()->x(), CurrentPendulum.position = ToVector3Int(s->pendulum()->position());
s->pendulum()->position()->y(), CurrentPendulum.velocity = ToVector3Int(s->pendulum()->velocity());
s->pendulum()->position()->z());
CurrentPendulum.velocity = Vector3Int(
s->pendulum()->velocity()->x(),
s->pendulum()->velocity()->y(),
s->pendulum()->velocity()->z());
CurrentPendulum.node = s->pendulum()->node(); CurrentPendulum.node = s->pendulum()->node();
CurrentPendulum.rope = rope; CurrentPendulum.rope = rope;
AlternatePendulum.position = Vector3Int( AlternatePendulum.position = ToVector3Int(s->alternate_pendulum()->position());
s->alternate_pendulum()->position()->x(), AlternatePendulum.velocity = ToVector3Int(s->alternate_pendulum()->velocity());
s->alternate_pendulum()->position()->y(),
s->alternate_pendulum()->position()->z());
AlternatePendulum.velocity = Vector3Int(
s->alternate_pendulum()->velocity()->x(),
s->alternate_pendulum()->velocity()->y(),
s->alternate_pendulum()->velocity()->z());
AlternatePendulum.node = s->alternate_pendulum()->node(); AlternatePendulum.node = s->alternate_pendulum()->node();
AlternatePendulum.rope = rope; AlternatePendulum.rope = rope;

View file

@ -15,7 +15,7 @@ namespace TEN::Entities::TR4
{ {
LOCUST_INFO Locusts[MAX_LOCUSTS]; LOCUST_INFO Locusts[MAX_LOCUSTS];
int CreateLocust(void) int CreateLocust()
{ {
for (int i = 0; i < MAX_LOCUSTS; i++) for (int i = 0; i < MAX_LOCUSTS; i++)
{ {
@ -112,7 +112,7 @@ namespace TEN::Entities::TR4
} }
} }
void UpdateLocusts(void) void UpdateLocusts()
{ {
for (int i = 0; i < MAX_LOCUSTS; i++) for (int i = 0; i < MAX_LOCUSTS; i++)
{ {
@ -208,7 +208,13 @@ namespace TEN::Entities::TR4
} }
} }
void DrawLocust(void) void ClearLocusts()
{
for (int i = 0; i < MAX_LOCUSTS; i++)
Locusts[i].on = false;
}
void DrawLocust()
{ {
// TODO: no render for the locusts ! // TODO: no render for the locusts !
} }

View file

@ -15,17 +15,19 @@ struct LOCUST_INFO
BYTE counter; BYTE counter;
}; };
namespace TEN::Entities::TR4 { namespace TEN::Entities::TR4
{
constexpr auto MAX_LOCUSTS = 64; constexpr auto MAX_LOCUSTS = 64;
constexpr auto LOCUST_LARA_DAMAGE = 3; constexpr auto LOCUST_LARA_DAMAGE = 3;
constexpr auto LOCUST_ENTITY_DAMAGE = 1; constexpr auto LOCUST_ENTITY_DAMAGE = 1;
extern LOCUST_INFO Locusts[MAX_LOCUSTS]; extern LOCUST_INFO Locusts[MAX_LOCUSTS];
extern int CreateLocust(void); extern int CreateLocust();
extern void SpawnLocust(ItemInfo* item); extern void SpawnLocust(ItemInfo* item);
extern void InitialiseLocust(short itemNumber); extern void InitialiseLocust(short itemNumber);
extern void LocustControl(short itemNumber); extern void LocustControl(short itemNumber);
extern void UpdateLocusts(void); extern void UpdateLocusts();
extern void DrawLocust(void); extern void ClearLocusts();
extern void DrawLocust();
} }

View file

@ -97,7 +97,7 @@ namespace TEN::Entities::TR3
fx->pos.Orientation.z = 0; fx->pos.Orientation.z = 0;
fx->objectNumber = ID_TONY_BOSS_FLAME; fx->objectNumber = ID_TONY_BOSS_FLAME;
fx->speed = flame.speed; fx->speed = flame.speed;
fx->shade = 0; fx->color = Vector4::Zero;
fx->flag1 = flame.type; fx->flag1 = flame.type;
fx->flag2 = (GetRandomControl() & 3) + 1; fx->flag2 = (GetRandomControl() & 3) + 1;

View file

@ -130,7 +130,7 @@ namespace TEN::Entities::TR4
fx->fallspeed = -(GetRandomControl() / 1024); fx->fallspeed = -(GetRandomControl() / 1024);
fx->frameNumber = Objects[103].meshIndex; fx->frameNumber = Objects[103].meshIndex;
fx->objectNumber = ID_BODY_PART; fx->objectNumber = ID_BODY_PART;
fx->shade = 0x4210; fx->color = Vector4::One;
fx->flag2 = 0x601; fx->flag2 = 0x601;
auto* spark = GetFreeParticle(); auto* spark = GetFreeParticle();

View file

@ -107,7 +107,7 @@ static void ImpThrowStones(ItemInfo* item)
fx->fallspeed = 0; fx->fallspeed = 0;
fxNumber = Objects[ID_IMP_ROCK].meshIndex + (GetRandomControl() & 7); fxNumber = Objects[ID_IMP_ROCK].meshIndex + (GetRandomControl() & 7);
fx->objectNumber = ID_IMP_ROCK; fx->objectNumber = ID_IMP_ROCK;
fx->shade = 16912; fx->color = Vector4::One;
fx->counter = 0; fx->counter = 0;
fx->frameNumber = fxNumber; fx->frameNumber = fxNumber;
fx->flag1 = 2; fx->flag1 = 2;

View file

@ -74,7 +74,7 @@ static void RomanStatueHitEffect(ItemInfo* item, Vector3Int* pos, int joint)
fx->speed = 1; fx->speed = 1;
fx->fallspeed = 0; fx->fallspeed = 0;
fx->objectNumber = ID_BODY_PART; fx->objectNumber = ID_BODY_PART;
fx->shade = 16912; fx->color = Vector4::One;
fx->flag2 = 9729; fx->flag2 = 9729;
fx->frameNumber = Objects[ID_BUBBLES].meshIndex + (GetRandomControl() & 7); fx->frameNumber = Objects[ID_BUBBLES].meshIndex + (GetRandomControl() & 7);
fx->counter = 0; fx->counter = 0;

View file

@ -129,6 +129,8 @@ namespace TEN::Renderer
int RoomNumber; int RoomNumber;
Vector3 Position; Vector3 Position;
Matrix World; Matrix World;
Vector4 Color;
Vector4 AmbientLight;
RendererMesh* Mesh; RendererMesh* Mesh;
std::vector<RendererLight*> LightsToDraw; std::vector<RendererLight*> LightsToDraw;
}; };

View file

@ -147,6 +147,9 @@ namespace TEN::Renderer
totalIndices += bucket.numQuads * 6 + bucket.numTriangles * 3; totalIndices += bucket.numQuads * 6 + bucket.numTriangles * 3;
} }
if (!totalVertices || !totalIndices)
throw std::exception("Level has no textured room geometry.");
roomsVertices.resize(totalVertices); roomsVertices.resize(totalVertices);
roomsIndices.resize(totalIndices); roomsIndices.resize(totalIndices);

View file

@ -2224,27 +2224,28 @@ namespace TEN::Renderer
SetBlendMode(BLENDMODE_ADDITIVE); SetBlendMode(BLENDMODE_ADDITIVE);
for (int i = 0; i < 2; i++) for (int s = 0; s < 2; s++)
{ for (int i = 0; i < 2; i++)
auto weather = TEN::Effects::Environment::Weather; {
auto weather = TEN::Effects::Environment::Weather;
Matrix translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyLayer1Position() - i * 9728.0f, Matrix translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyPosition(s) - i * 9728.0f,
Camera.pos.y - 1536.0f, Camera.pos.z); Camera.pos.y - 1536.0f, Camera.pos.z);
Matrix world = rotation * translation; Matrix world = rotation * translation;
m_stStatic.World = (rotation * translation); m_stStatic.World = (rotation * translation);
m_stStatic.Color = weather.SkyColor(); m_stStatic.Color = weather.SkyColor(s);
m_stStatic.AmbientLight = Vector4::One; m_stStatic.AmbientLight = Vector4::One;
m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_STATIC; m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_STATIC;
m_cbStatic.updateData(m_stStatic, m_context.Get()); m_cbStatic.updateData(m_stStatic, m_context.Get());
BindConstantBufferVS(CB_STATIC, m_cbStatic.get()); BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
BindConstantBufferPS(CB_STATIC, m_cbStatic.get()); BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
m_primitiveBatch->Begin(); m_primitiveBatch->Begin();
m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]); m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]);
m_primitiveBatch->End(); m_primitiveBatch->End();
} }
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0); m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
// Draw horizon // Draw horizon

View file

@ -1036,8 +1036,8 @@ namespace TEN::Renderer
RendererRoom const& room = m_rooms[effect->RoomNumber]; RendererRoom const& room = m_rooms[effect->RoomNumber];
m_stStatic.World = effect->World; m_stStatic.World = effect->World;
m_stStatic.Color = Vector4::One; m_stStatic.Color = effect->Color;
m_stStatic.AmbientLight = room.AmbientLight; m_stStatic.AmbientLight = effect->AmbientLight;
m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_DYNAMIC; m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
m_cbStatic.updateData(m_stStatic, m_context.Get()); m_cbStatic.updateData(m_stStatic, m_context.Get());
BindConstantBufferVS(CB_STATIC, m_cbStatic.get()); BindConstantBufferVS(CB_STATIC, m_cbStatic.get());

View file

@ -1,17 +1,18 @@
#include "framework.h" #include "framework.h"
#include "Renderer/Renderer11.h" #include "Renderer/Renderer11.h"
#include "Specific/configuration.h"
#include "Game/savegame.h" #include "Game/savegame.h"
#include "Game/health.h" #include "Game/health.h"
#include "Game/animation.h" #include "Game/animation.h"
#include "Game/gui.h" #include "Game/gui.h"
#include "Game/Lara/lara.h" #include "Game/Lara/lara.h"
#include "Game/control/control.h"
#include "Game/control/volume.h"
#include "Scripting/Internal/TEN/Flow//Level/FlowLevel.h"
#include "Specific/configuration.h"
#include "Specific/level.h" #include "Specific/level.h"
#include "Specific/setup.h" #include "Specific/setup.h"
#include "Game/control/control.h" #include "Specific/trutils.h"
#include "Scripting/Internal/TEN/Flow//Level/FlowLevel.h"
#include "Specific/winmain.h" #include "Specific/winmain.h"
#include "Game/control/volume.h"
using namespace TEN::Input; using namespace TEN::Input;
@ -631,36 +632,31 @@ namespace TEN::Renderer
void Renderer11::RenderTitleImage() void Renderer11::RenderTitleImage()
{ {
wchar_t introFileChars[255];
std::mbstowcs(introFileChars, g_GameFlow->IntroImagePath.c_str(), 255);
std::wstring titleStringFileName(introFileChars);
Texture2D texture; Texture2D texture;
SetTextureOrDefault(texture, titleStringFileName); SetTextureOrDefault(texture, TEN::Utils::FromChar(g_GameFlow->IntroImagePath.c_str()));
float currentFade = 0; if (!texture.Texture)
while (currentFade <= 1.0f) return;
{
DrawFullScreenImage(texture.ShaderResourceView.Get(), currentFade, m_backBufferRTV, m_depthStencilView);
Synchronize();
currentFade += FADE_FACTOR;
m_swapChain->Present(0, 0);
}
for (int i = 0; i < 20; i++) int timeout = 20;
float currentFade = FADE_FACTOR;
while (timeout || currentFade > 0.0f)
{ {
DrawFullScreenImage(texture.ShaderResourceView.Get(), 1.0f, m_backBufferRTV, m_depthStencilView); if (timeout)
{
if (currentFade < 1.0f)
currentFade = std::clamp(currentFade += FADE_FACTOR, 0.0f, 1.0f);
else
timeout--;
}
else
currentFade = std::clamp(currentFade -= FADE_FACTOR, 0.0f, 1.0f);
DrawFullScreenImage(texture.ShaderResourceView.Get(), Smoothstep(currentFade), m_backBufferRTV, m_depthStencilView);
Synchronize(); Synchronize();
m_swapChain->Present(0, 0); m_swapChain->Present(0, 0);
} m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
currentFade = 1.0f;
while (currentFade >= 0.0f)
{
DrawFullScreenImage(texture.ShaderResourceView.Get(), currentFade, m_backBufferRTV, m_depthStencilView);
Synchronize();
currentFade -= FADE_FACTOR;
m_swapChain->Present(0, 0);
} }
} }
@ -824,12 +820,12 @@ namespace TEN::Renderer
void Renderer11::RenderLoadingScreen(float percentage) void Renderer11::RenderLoadingScreen(float percentage)
{ {
// Set basic render states
SetBlendMode(BLENDMODE_OPAQUE);
SetCullMode(CULL_MODE_CCW);
do do
{ {
// Set basic render states
SetBlendMode(BLENDMODE_OPAQUE);
SetCullMode(CULL_MODE_CCW);
// Clear screen // Clear screen
m_context->ClearRenderTargetView(m_backBufferRTV, Colors::Black); m_context->ClearRenderTargetView(m_backBufferRTV, Colors::Black);
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
@ -840,12 +836,13 @@ namespace TEN::Renderer
ResetScissor(); ResetScissor();
// Draw the full screen background // Draw the full screen background
DrawFullScreenQuad( if (loadingScreenTexture.Texture)
loadingScreenTexture.ShaderResourceView.Get(), DrawFullScreenQuad(
Vector3(ScreenFadeCurrent, ScreenFadeCurrent, ScreenFadeCurrent)); loadingScreenTexture.ShaderResourceView.Get(),
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); Vector3(ScreenFadeCurrent, ScreenFadeCurrent, ScreenFadeCurrent));
DrawLoadingBar(percentage); if (ScreenFadeCurrent && percentage > 0.0f && percentage < 100.0f)
DrawLoadingBar(percentage);
m_swapChain->Present(0, 0); m_swapChain->Present(0, 0);
m_context->ClearState(); m_context->ClearState();

View file

@ -724,6 +724,8 @@ namespace TEN::Renderer
newEffect->ObjectNumber = fx->objectNumber; newEffect->ObjectNumber = fx->objectNumber;
newEffect->RoomNumber = fx->roomNumber; newEffect->RoomNumber = fx->roomNumber;
newEffect->Position = fx->pos.Position.ToVector3(); newEffect->Position = fx->pos.Position.ToVector3();
newEffect->AmbientLight = room.AmbientLight;
newEffect->Color = fx->color;
newEffect->World = rotation * translation; newEffect->World = rotation * translation;
newEffect->Mesh = GetMesh(obj->nmeshes ? obj->meshIndex : fx->frameNumber); newEffect->Mesh = GetMesh(obj->nmeshes ? obj->meshIndex : fx->frameNumber);

View file

@ -26,7 +26,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0 FILEVERSION 1,0,1,0
PRODUCTVERSION 1,5,2,0 PRODUCTVERSION 1,5,2,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
@ -43,7 +43,7 @@ BEGIN
BLOCK "000904b0" BLOCK "000904b0"
BEGIN BEGIN
VALUE "CompanyName", "TRLE Dev Community" VALUE "CompanyName", "TRLE Dev Community"
VALUE "FileVersion", "1.0.0.0" VALUE "FileVersion", "1.0.1.0"
VALUE "InternalName", "TombEngine.exe" VALUE "InternalName", "TombEngine.exe"
VALUE "LegalCopyright", "Copyright (C) 2022" VALUE "LegalCopyright", "Copyright (C) 2022"
VALUE "OriginalFilename", "TombEngine.exe" VALUE "OriginalFilename", "TombEngine.exe"

View file

@ -373,7 +373,7 @@ void EnumerateLegacyTracks()
} }
else else
{ {
TENLog("Folder \"" + dir.string() + "\" does not exist. ", LogLevel::Error, LogConfig::All); TENLog("Folder \"" + dir.string() + "\" does not exist. ", LogLevel::Warning, LogConfig::All);
} }
} }

View file

@ -1043,30 +1043,25 @@ unsigned int _stdcall LoadLevel(void* data)
{ {
const int levelIndex = reinterpret_cast<int>(data); const int levelIndex = reinterpret_cast<int>(data);
char filename[80];
ScriptInterfaceLevel* level = g_GameFlow->GetLevel(levelIndex); ScriptInterfaceLevel* level = g_GameFlow->GetLevel(levelIndex);
strcpy_s(filename, level->FileName.c_str());
TENLog("Loading level file: " + std::string(filename), LogLevel::Info); TENLog("Loading level file: " + level->FileName, LogLevel::Info);
LevelDataPtr = nullptr; LevelDataPtr = nullptr;
FILE* filePtr = nullptr; FILE* filePtr = nullptr;
char* dataPtr = nullptr; char* dataPtr = nullptr;
wchar_t loadscreenFileName[80]; g_Renderer.SetLoadingScreen(TEN::Utils::FromChar(level->LoadScreenFileName.c_str()));
std::mbstowcs(loadscreenFileName, level->LoadScreenFileName.c_str(), 80);
std::wstring loadScreenFile = std::wstring(loadscreenFileName);
g_Renderer.SetLoadingScreen(loadScreenFile);
SetScreenFadeIn(FADE_SCREEN_SPEED); SetScreenFadeIn(FADE_SCREEN_SPEED);
g_Renderer.UpdateProgress(0); g_Renderer.UpdateProgress(0);
try try
{ {
filePtr = FileOpen(filename); filePtr = FileOpen(level->FileName.c_str());
if (!filePtr) if (!filePtr)
throw std::exception((std::string("Unable to read level file: ") + filename).c_str()); throw std::exception((std::string("Unable to read level file: ") + level->FileName).c_str());
char header[4]; char header[4];
unsigned char version[4]; unsigned char version[4];

View file

@ -559,9 +559,9 @@ struct Position::Traits {
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3 FLATBUFFERS_FINAL_CLASS { FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3 FLATBUFFERS_FINAL_CLASS {
private: private:
int32_t x_; float x_;
int32_t y_; float y_;
int32_t z_; float z_;
public: public:
struct Traits; struct Traits;
@ -570,18 +570,18 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3 FLATBUFFERS_FINAL_CLASS {
y_(0), y_(0),
z_(0) { z_(0) {
} }
Vector3(int32_t _x, int32_t _y, int32_t _z) Vector3(float _x, float _y, float _z)
: x_(flatbuffers::EndianScalar(_x)), : x_(flatbuffers::EndianScalar(_x)),
y_(flatbuffers::EndianScalar(_y)), y_(flatbuffers::EndianScalar(_y)),
z_(flatbuffers::EndianScalar(_z)) { z_(flatbuffers::EndianScalar(_z)) {
} }
int32_t x() const { float x() const {
return flatbuffers::EndianScalar(x_); return flatbuffers::EndianScalar(x_);
} }
int32_t y() const { float y() const {
return flatbuffers::EndianScalar(y_); return flatbuffers::EndianScalar(y_);
} }
int32_t z() const { float z() const {
return flatbuffers::EndianScalar(z_); return flatbuffers::EndianScalar(z_);
} }
}; };
@ -593,10 +593,10 @@ struct Vector3::Traits {
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector4 FLATBUFFERS_FINAL_CLASS { FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector4 FLATBUFFERS_FINAL_CLASS {
private: private:
int32_t x_; float x_;
int32_t y_; float y_;
int32_t z_; float z_;
int32_t w_; float w_;
public: public:
struct Traits; struct Traits;
@ -606,22 +606,22 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector4 FLATBUFFERS_FINAL_CLASS {
z_(0), z_(0),
w_(0) { w_(0) {
} }
Vector4(int32_t _x, int32_t _y, int32_t _z, int32_t _w) Vector4(float _x, float _y, float _z, float _w)
: x_(flatbuffers::EndianScalar(_x)), : x_(flatbuffers::EndianScalar(_x)),
y_(flatbuffers::EndianScalar(_y)), y_(flatbuffers::EndianScalar(_y)),
z_(flatbuffers::EndianScalar(_z)), z_(flatbuffers::EndianScalar(_z)),
w_(flatbuffers::EndianScalar(_w)) { w_(flatbuffers::EndianScalar(_w)) {
} }
int32_t x() const { float x() const {
return flatbuffers::EndianScalar(x_); return flatbuffers::EndianScalar(x_);
} }
int32_t y() const { float y() const {
return flatbuffers::EndianScalar(y_); return flatbuffers::EndianScalar(y_);
} }
int32_t z() const { float z() const {
return flatbuffers::EndianScalar(z_); return flatbuffers::EndianScalar(z_);
} }
int32_t w() const { float w() const {
return flatbuffers::EndianScalar(w_); return flatbuffers::EndianScalar(w_);
} }
}; };

View file

@ -186,16 +186,16 @@ table ShortArray {
} }
struct Vector3 { struct Vector3 {
x: int32; x: float;
y: int32; y: float;
z: int32; z: float;
} }
struct Vector4 { struct Vector4 {
x: int32; x: float;
y: int32; y: float;
z: int32; z: float;
w: int32; w: float;
} }
union ItemData { union ItemData {

View file

@ -27,7 +27,7 @@ table Item {
carried_item: int32; carried_item: int32;
after_death: int32; after_death: int32;
item_flags: [int32]; item_flags: [int32];
position: Position; pose: Position;
next_item: int32; next_item: int32;
next_item_active: int32; next_item_active: int32;
triggered: bool; triggered: bool;
@ -48,7 +48,7 @@ table Item {
} }
table FXInfo { table FXInfo {
pos : Position; pose : Position;
room_number: int32; room_number: int32;
object_number: int32; object_number: int32;
next_fx: int32; next_fx: int32;
@ -57,7 +57,7 @@ table FXInfo {
fall_speed: int32; fall_speed: int32;
frame_number: int32; frame_number: int32;
counter : int32; counter : int32;
shade: int32; color: Vector4;
flag1: int32; flag1: int32;
flag2: int32; flag2: int32;
} }
@ -248,8 +248,7 @@ table Lara {
target_facing_angle: int32; target_facing_angle: int32;
water_surface_dist: int32; water_surface_dist: int32;
interacted_item: int32; interacted_item: int32;
next_corner_position: Vector3; next_corner_pose: Position;
next_corner_rotation: Vector3;
burn_type: int32; burn_type: int32;
burn_count: uint32; burn_count: uint32;
burn: bool; burn: bool;
@ -277,8 +276,7 @@ table Sink {
table StaticMeshInfo { table StaticMeshInfo {
number: int32; number: int32;
room_number: int32; room_number: int32;
position: Vector3; pose: Position;
rotation: Vector3;
color: Vector4; color: Vector4;
hit_points: int32; hit_points: int32;
flags: int32; flags: int32;
@ -324,54 +322,13 @@ table ParticleInfo {
node_number: int32; node_number: int32;
} }
table RatInfo { table SwarmObjectInfo {
on: bool; on: bool;
x: int32; pose: Position;
y: int32;
z: int32;
x_rot: int32;
y_rot: int32;
z_rot: int32;
room_number: int32; room_number: int32;
flags: int32; flags: int32;
} }
table SpiderInfo {
on: bool;
x: int32;
y: int32;
z: int32;
x_rot: int32;
y_rot: int32;
z_rot: int32;
room_number: int32;
flags: int32;
}
table ScarabInfo {
on: bool;
x: int32;
y: int32;
z: int32;
x_rot: int32;
y_rot: int32;
z_rot: int32;
room_number: int32;
flags: int32;
}
table BatInfo {
on: bool;
x: int32;
y: int32;
z: int32;
x_rot: int32;
y_rot: int32;
z_rot: int32;
room_number: int32;
counter: int32;
}
table Rope { table Rope {
segments: [Vector3]; segments: [Vector3];
velocities: [Vector3]; velocities: [Vector3];
@ -481,10 +438,10 @@ table SaveGame {
static_meshes: [StaticMeshInfo]; static_meshes: [StaticMeshInfo];
flyby_cameras: [FlyByCamera]; flyby_cameras: [FlyByCamera];
particles: [ParticleInfo]; particles: [ParticleInfo];
rats: [RatInfo]; rats: [SwarmObjectInfo];
spiders: [SpiderInfo]; spiders: [SwarmObjectInfo];
scarabs: [ScarabInfo]; scarabs: [SwarmObjectInfo];
bats: [BatInfo]; bats: [SwarmObjectInfo];
flip_maps: [int32]; flip_maps: [int32];
flip_stats: [int32]; flip_stats: [int32];
flip_effect: int32; flip_effect: int32;

View file

@ -1,8 +1,7 @@
#include "framework.h" #include "framework.h"
#include "Specific/trmath.h" #include "Specific/trmath.h"
#include <cmath>
#include "Specific/prng.h" #include "Specific/prng.h"
#include <cmath>
using namespace TEN::Math::Random; using namespace TEN::Math::Random;

View file

@ -11,12 +11,19 @@ namespace TEN::Utils
return source; return source;
} }
std::string FromWchar(wchar_t* source) std::string FromWchar(const wchar_t* source)
{ {
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter; std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
return converter.to_bytes(std::wstring(source)); return converter.to_bytes(std::wstring(source));
} }
std::wstring FromChar(const char* source)
{
wchar_t buffer[UCHAR_MAX];
std::mbstowcs(buffer, source, UCHAR_MAX);
return std::wstring(buffer);
}
std::vector<std::string> SplitString(const std::string& source) std::vector<std::string> SplitString(const std::string& source)
{ {
std::vector<std::string> strings; std::vector<std::string> strings;

View file

@ -4,7 +4,8 @@
namespace TEN::Utils namespace TEN::Utils
{ {
std::string ToLower(std::string source); std::string ToLower(std::string source);
std::string FromWchar(wchar_t* source); std::string FromWchar(const wchar_t* source);
std::wstring FromChar(const char* source);
std::vector<std::string> SplitString(const std::string& source); std::vector<std::string> SplitString(const std::string& source);
std::vector<unsigned short> GetProductOrFileVersion(bool productVersion); std::vector<unsigned short> GetProductOrFileVersion(bool productVersion);