Skip to content

Commit

Permalink
Updated animation speed/accel data types and flyby camera trigger type.
Browse files Browse the repository at this point in the history
By finding out EXTREMELY PERVERSE data type which was used by original
programmers to store speed and accel values for animations, we have
finally fixed almost all animation speeds, and made Lara movement even
more genuine!
Also, another important discovery is an extra bitu16 field after flyby
camera trigger function operand, which contains some important flyby
properties. Along the way, taking it into account fixes wrong trigger
parsing in TR4-5.
  • Loading branch information
Lwmte committed May 23, 2015
1 parent 6c6e361 commit db18b55
Show file tree
Hide file tree
Showing 18 changed files with 151 additions and 108 deletions.
22 changes: 22 additions & 0 deletions scripts/entity/entity_functions.lua
Expand Up @@ -148,6 +148,28 @@ function venicebird_init(id) -- Venice singing birds (TR2)
prepareEntity(id);
end

function drips_init(id) -- Maria Doria drips (TR2)

setEntityTypeFlag(id, ENTITY_TYPE_GENERIC);

entity_funcs[id].onActivate = function(object_id, activator_id)
setEntityActivity(object_id, 1);
end

entity_funcs[id].onDeactivate = function(object_id, activator_id)
setEntityActivity(object_id, 0);
end

entity_funcs[id].onLoop = function(object_id)
if(tickEntity(object_id) == TICK_STOPPED) then setEntityActivity(object_id, 0) end;
if(getEntityDistance(player, object_id) < 8192.0) then
if(math.random(100000) > 99500) then playSound(329, object_id) end;
end;
end

prepareEntity(id);
end

function doorbell_init(id) -- Lara's Home doorbell (TR2)

setEntityTypeFlag(id, ENTITY_TYPE_GENERIC);
Expand Down
2 changes: 1 addition & 1 deletion scripts/entity/entity_properties.lua
Expand Up @@ -379,7 +379,7 @@ tr2_entity_tbl[209] = {coll = 0x00}; -- Dragon explosion effect (e
tr2_entity_tbl[210] = {coll = 0x00}; -- Dragon explosion effect (expanding netted bubble)
tr2_entity_tbl[211] = {coll = 0x00}; -- Dragon explosion effect (expanding solid bubble)
tr2_entity_tbl[212] = {coll = 0x00, func = "alarm_TR2"}; -- Alarm
tr2_entity_tbl[213] = {coll = 0x00, hide = 0x01}; -- Placeholder
tr2_entity_tbl[213] = {coll = 0x00, hide = 0x01, func = "drips"}; -- Dripping water
tr2_entity_tbl[214] = {coll = 0x02}; -- Tyrannosaur
tr2_entity_tbl[215] = {coll = 0x00, hide = 0x01, func = "venicebird"}; -- Singing birds
tr2_entity_tbl[216] = {coll = 0x00, hide = 0x01}; -- Placeholder
Expand Down
4 changes: 2 additions & 2 deletions scripts/trigger/trigger_functions.lua
Expand Up @@ -172,9 +172,9 @@ end

-- Plays specified flyby. Only valid in TR4-5.

function playFlyby(flyby_index)
function playFlyby(flyby_index, once)
if(getLevelVersion() < TR_IV) then return 0 end;
print("FLYBY: index = " .. flyby_index);
print("FLYBY: index = " .. flyby_index .. " once = " .. once);
end


Expand Down
46 changes: 16 additions & 30 deletions src/anim_state_control.cpp
Expand Up @@ -250,7 +250,14 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim)
* Base onfloor animations
*/
case TR_STATE_LARA_STOP:
ent->dir_flag = ENT_STAY;

// Reset directional flag only on intermediate animation!

if(ss_anim->current_animation == TR_ANIMATION_LARA_STAY_SOLID)
{
ent->dir_flag = ENT_STAY;
}

cmd->rot[0] = 0;
cmd->crouch |= low_vertical_space;
Character_Lean(ent, cmd, 0.0);
Expand Down Expand Up @@ -674,10 +681,6 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim)

case TR_STATE_LARA_RUN_BACK:
ent->dir_flag = ENT_MOVE_BACKWARD;
if(ss_anim->current_animation == TR_ANIMATION_LARA_RUN_BACK_BEGIN)
{
ent->current_speed = 16.0; ///@FIXME: magick!
}

if(ent->move_type == MOVE_FREE_FALLING)
{
Expand Down Expand Up @@ -1069,8 +1072,7 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim)

if(ent->character->height_info.quicksand)
{
ent->current_speed = 8.0;
Entity_UpdateCurrentSpeed(ent, 0);
ent->current_speed *= 0.5;
}

if(cmd->move[0] == 1)
Expand Down Expand Up @@ -1142,17 +1144,16 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim)

case TR_STATE_LARA_WALK_BACK:
cmd->rot[0] *= 0.4;
vec3_mul_scalar(global_offset, ent->transform + 4, -WALK_BACK_OFFSET);
global_offset[2] += ent->bf.bb_max[2];
i = Character_CheckNextStep(ent, global_offset, &next_fc);
//ent->dir_flag = ENT_MOVE_BACKWARD;
ent->dir_flag = ENT_MOVE_BACKWARD;

if(ent->character->height_info.quicksand)
{
ent->current_speed = 4.0;
Entity_UpdateCurrentSpeed(ent, 0);
ent->current_speed *= 0.5;
}


vec3_mul_scalar(global_offset, ent->transform + 4, -WALK_BACK_OFFSET);
global_offset[2] += ent->bf.bb_max[2];
i = Character_CheckNextStep(ent, global_offset, &next_fc);
if(ent->move_type == MOVE_FREE_FALLING)
{
Entity_SetAnimation(ent, TR_ANIMATION_LARA_START_FREE_FALL, 0);
Expand Down Expand Up @@ -1961,7 +1962,6 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim)
case TR_STATE_LARA_LADDER_LEFT:
//ent->character->complex_collision = 0x01;
ent->dir_flag = ENT_MOVE_LEFT;
ent->current_speed = 5.0;
if((cmd->action == 0) || (ent->character->climb.wall_hit == 0))
{
ss_anim->next_state = TR_STATE_LARA_HANG;
Expand All @@ -1975,7 +1975,6 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim)
case TR_STATE_LARA_LADDER_RIGHT:
//ent->character->complex_collision = 0x01;
ent->dir_flag = ENT_MOVE_RIGHT;
ent->current_speed = 5.0;
if((cmd->action == 0) || (ent->character->climb.wall_hit == 0))
{
ss_anim->next_state = TR_STATE_LARA_HANG;
Expand Down Expand Up @@ -2040,7 +2039,6 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim)
break;

case TR_STATE_LARA_SHIMMY_LEFT:
ent->current_speed = 5.0;
cmd->rot[0] = 0.0;
ent->dir_flag = ENT_MOVE_LEFT;
if(cmd->action == 0)
Expand Down Expand Up @@ -2100,7 +2098,6 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim)
break;

case TR_STATE_LARA_SHIMMY_RIGHT:
ent->current_speed = 5.0;
cmd->rot[0] = 0.0;
ent->dir_flag = ENT_MOVE_RIGHT;
if(cmd->action == 0)
Expand Down Expand Up @@ -2823,7 +2820,7 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim)
break;

case TR_STATE_LARA_CRAWL_BACK:
ent->dir_flag = ENT_MOVE_BACKWARD;
ent->dir_flag = ENT_MOVE_FORWARD; // Absurd? No, Core Design.
ent->character->no_fix_body_parts = BODY_PART_HANDS_2 | BODY_PART_HANDS_3 | BODY_PART_LEGS_3;
cmd->rot[0] = cmd->rot[0] * 0.5;
vec3_mul_scalar(move, ent->transform + 4, -PENETRATION_TEST_OFFSET);
Expand All @@ -2843,17 +2840,6 @@ int State_Control_Lara(struct entity_s *ent, struct ss_animation_s *ss_anim)
ent->dir_flag = ENT_STAY;
Entity_SetAnimation(ent, TR_ANIMATION_LARA_CRAWL_IDLE, 0);
}
else
{
if(ss_anim->current_animation == TR_ANIMATION_LARA_CRAWL_BACKWARD)
{
ent->current_speed = 16.0; ///@FIXME: magick!
}
else
{
ent->current_speed = 6.0;
}
}
break;

case TR_STATE_LARA_CRAWL_TURN_LEFT:
Expand Down
10 changes: 5 additions & 5 deletions src/character_controller.cpp
Expand Up @@ -1576,24 +1576,24 @@ int Character_MoveOnFloor(struct entity_s *ent)
{
ent->character->resp.slide = CHARACTER_SLIDE_FRONT;
ent->angles[0] = ang + 180.0;
// front forward sly down
// front forward slide down
}
else
{
ent->character->resp.slide = CHARACTER_SLIDE_BACK;
ent->angles[0] = ang;
// back forward sly down
// back forward slide down
}
Entity_UpdateRotation(ent);
ent->character->resp.vertical_collide |= 0x01;
}
else // no slide - free to walk
else // no slide - free to walk
{
t = ent->current_speed * ent->character->speed_mult;
t = (t < 0.0)?(0.0):(t); /// stick or feature: that is a serious question!
ent->character->resp.vertical_collide |= 0x01;
ent->angles[0] += ent->character->cmd.rot[0];
Entity_UpdateRotation(ent); // apply rotations

Entity_UpdateRotation(ent); // apply rotations

if(ent->dir_flag & ENT_MOVE_FORWARD)
{
Expand Down
5 changes: 3 additions & 2 deletions src/character_controller.h
Expand Up @@ -159,8 +159,8 @@ enum CharParameters

#define PARAM_ABSOLUTE_MAX (-1)

#define LARA_PARAM_HEALTH_MAX (1000.0) // 30 secs of air
#define LARA_PARAM_AIR_MAX (1800.0) // 30 secs of air
#define LARA_PARAM_HEALTH_MAX (1000.0) // 1000 HP
#define LARA_PARAM_AIR_MAX (3600.0) // 60 secs of air
#define LARA_PARAM_STAMINA_MAX (120.0) // 4 secs of sprint
#define LARA_PARAM_WARMTH_MAX (240.0) // 8 secs of freeze

Expand Down Expand Up @@ -280,6 +280,7 @@ typedef struct character_s
struct entity_s *ent; // actor entity
struct character_command_s cmd; // character control commands
struct character_response_s resp; // character response info (collides, slide, next steps, drops, e.t.c.)

struct inventory_node_s *inventory;
struct character_param_s parameters;
struct character_stats_s statistics;
Expand Down
2 changes: 1 addition & 1 deletion src/engine.cpp
Expand Up @@ -245,7 +245,7 @@ void Engine_BTInit()
bt_engine_dynamicsWorld->setInternalTickCallback(Engine_InternalTickCallback);
bt_engine_dynamicsWorld->setGravity(btVector3(0, 0, -4500.0));

debugDrawer.setDebugMode(btIDebugDraw::DBG_DrawWireframe);
debugDrawer.setDebugMode(btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawConstraints);
bt_engine_dynamicsWorld->setDebugDrawer(&debugDrawer);
//bt_engine_dynamicsWorld->getPairCache()->setInternalGhostPairCallback(bt_engine_filterCallback);
}
Expand Down
7 changes: 5 additions & 2 deletions src/engine.h
Expand Up @@ -16,12 +16,15 @@
#define OBJECT_STATIC_MESH (0x0001)
#define OBJECT_ROOM_BASE (0x0002)
#define OBJECT_ENTITY (0x0003)
#define OBJECT_BULLET_MISC (0x0004)
#define OBJECT_HAIR (0x0004)
#define OBJECT_BULLET_MISC (0x7FFF)

#define COLLISION_MASK_NONE (0x0000)
#define COLLISION_MASK_ALL (0xFFFF)

#define COLLISION_GROUP_ALL (0xFFFF)
#define COLLISION_GROUP_STATIC (0x0001) // room mesh, statics
#define COLLISION_GROUP_CINEMATIC (0x0002) // doors, blocks, static animated entityes
#define COLLISION_GROUP_KINEMATIC (0x0002) // doors, blocks, static animated entityes
#define COLLISION_GROUP_CHARACTERS (0x0004) // Lara, enemies, friends, creatures
#define COLLISION_GROUP_BULLETS (0x0008) // bullets, rockets, grenades, arrows...
#define COLLISION_GROUP_DYNAMICS (0x0010) // test balls, warious
Expand Down
39 changes: 28 additions & 11 deletions src/entity.cpp
Expand Up @@ -250,13 +250,16 @@ void BT_GenEntityRigidBody(entity_p ent)
{
ent->bt_body[i] = NULL;
cshape = BT_CSfromMesh(ent->bf.animations.model->mesh_tree[i].mesh_base, true, true, ent->self->collide_flag, false);
cshape->calculateLocalInertia(0.0, localInertia);

if(cshape)
{
Mat4_Mat4_mul(tr, ent->transform, ent->bf.bone_tags[i].full_transform);
startTransform.setFromOpenGLMatrix(tr);
btDefaultMotionState* motionState = new btDefaultMotionState(startTransform);
ent->bt_body[i] = new btRigidBody(0.0, motionState, cshape, localInertia);
bt_engine_dynamicsWorld->addRigidBody(ent->bt_body[i], COLLISION_GROUP_CINEMATIC, COLLISION_MASK_ALL);
ent->bt_body[i]->setCollisionFlags(ent->bt_body[i]->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
bt_engine_dynamicsWorld->addRigidBody(ent->bt_body[i], COLLISION_GROUP_KINEMATIC, COLLISION_MASK_ALL);
ent->bt_body[i]->setUserPointer(ent->self);
}
}
Expand Down Expand Up @@ -977,7 +980,7 @@ void Entity_SetAnimation(entity_p entity, int animation, int frame, int another_

entity->bf.animations.last_state = anim->state_id;
entity->bf.animations.next_state = anim->state_id;
entity->current_speed = anim->speed;
entity->current_speed = anim->speed_x;
entity->bf.animations.current_animation = animation;
entity->bf.animations.current_frame = frame;
entity->bf.animations.next_animation = animation;
Expand Down Expand Up @@ -1213,7 +1216,6 @@ int Entity_Frame(entity_p entity, btScalar time)
ret = 0x01;
Entity_DoAnimCommands(entity, &entity->bf.animations, ret);
Entity_DoAnimMove(entity);
entity->bf.animations.current_frame = frame;
}

af = entity->bf.animations.model->animations + entity->bf.animations.current_animation;
Expand All @@ -1225,14 +1227,29 @@ int Entity_Frame(entity_p entity, btScalar time)
entity->bf.animations.lerp = (entity->smooth_anim)?(dt / entity->bf.animations.period):(0.0);
Entity_GetNextFrame(&entity->bf, entity->bf.animations.period, stc, &entity->bf.animations.next_frame, &entity->bf.animations.next_animation, ss_anim->anim_flags);

Character_DoWeaponFrame(entity, time);
/*
* Update acceleration
*/
if(entity->character)
{
entity->current_speed += time * entity->character->speed_mult * (btScalar)af->accel_hi;
// Update acceleration.
// With variable framerate, we don't know when we'll reach final
// frame for sure, so we use native frame number check to increase acceleration.

if((entity->character) && (ss_anim->current_frame != frame))
{

// NB!!! For Lara, we update ONLY X-axis speed/accel.

if(af->accel_x == 0)
{
entity->current_speed = af->speed_x;
}
else
{
entity->current_speed += af->accel_x;
}
}

entity->bf.animations.current_frame = frame;


Character_DoWeaponFrame(entity, time);

Entity_UpdateCurrentBoneFrame(&entity->bf, entity->transform);
if(entity->bf.animations.onFrame != NULL)
Expand Down Expand Up @@ -1726,4 +1743,4 @@ void Character_DoWeaponFrame(struct entity_s *entity, btScalar time)
Entity_DoAnimCommands(entity, ss_anim, 0);
}
}
}
}
16 changes: 8 additions & 8 deletions src/game.cpp
Expand Up @@ -752,13 +752,12 @@ void Game_UpdateCharacters()
}
}


__inline btScalar Game_Tick(btScalar *game_logic_time)
{
int t;
t = *game_logic_time / GAME_LOGIC_REFRESH_INTERVAL;
*game_logic_time -= (btScalar)t * GAME_LOGIC_REFRESH_INTERVAL;
return *game_logic_time;
int t = *game_logic_time / GAME_LOGIC_REFRESH_INTERVAL;
btScalar dt = (btScalar)t * GAME_LOGIC_REFRESH_INTERVAL;
*game_logic_time -= dt;
return dt;
}


Expand Down Expand Up @@ -801,14 +800,14 @@ void Game_Frame(btScalar time)
return;
}


// We're going to update main logic with a fixed step.
// This allows to conserve CPU resources and keep everything in sync!

if(game_logic_time >= GAME_LOGIC_REFRESH_INTERVAL)
{
int32_t t = game_logic_time / GAME_LOGIC_REFRESH_INTERVAL;
btScalar dt = (btScalar)t * GAME_LOGIC_REFRESH_INTERVAL;
game_logic_time -= dt;
btScalar dt = Game_Tick(&game_logic_time);

bt_engine_dynamicsWorld->stepSimulation(dt, 8);
lua_DoTasks(engine_lua, dt);
Game_UpdateAI();
Expand All @@ -822,6 +821,7 @@ void Game_Frame(btScalar time)

if(is_entitytree) Game_LoopEntities(engine_world.entity_tree->root);
}


// This must be called EVERY frame to max out smoothness.
// Includes animations, camera movement, and so on.
Expand Down
2 changes: 1 addition & 1 deletion src/main_SDL.cpp
Expand Up @@ -182,7 +182,7 @@ void SkeletalModelTestDraw()
Gui_OutTextXY(screen_info.w-632, 120, "sprite ID = %d; mesh ID = %d", bsprite->id, mesh);
Gui_OutTextXY(screen_info.w-632, 96, "model ID = %d, anim = %d of %d, rate = %d, frame = %d of %d", smodel->id, anim, smodel->animation_count, smodel->animations[anim].original_frame_rate, frame, smodel->animations[anim].frames_count);
Gui_OutTextXY(screen_info.w-632, 72, "next anim = %d, next frame = %d, num_state_changes = %d", (af->next_anim)?(af->next_anim->id):-1, af->next_frame, af->state_change_count);
Gui_OutTextXY(screen_info.w-632, 48, "v1 = %d, v2 = %d, al1 = %d, ah1 = %d, al2 = %d, ah2 = %d", af->speed, af->speed2, af->accel_lo, af->accel_hi, af->accel_lo2, af->accel_hi2);
Gui_OutTextXY(screen_info.w-632, 48, "vx = %f, vy = %f, ax = %f, ay = %f", af->speed_x, af->speed_y, af->accel_x, af->accel_y);
Gui_OutTextXY(screen_info.w-632, 24, "bb_min(%d, %d, %d), bb_max(%d, %d, %d)", (int)bframe->bb_min[0], (int)bframe->bb_min[1], (int)bframe->bb_min[2], (int)bframe->bb_max[0], (int)bframe->bb_max[1], (int)bframe->bb_max[2]);
Gui_OutTextXY(screen_info.w-632, 4, "x0 = %d, y0 = %d, z0 = %d", (int)bframe->pos[0], (int)bframe->pos[1], (int)bframe->pos[2]);

Expand Down

0 comments on commit db18b55

Please sign in to comment.