From bf5c3a323233a78e45994aa68186ed0269816610 Mon Sep 17 00:00:00 2001 From: XProger Date: Tue, 11 Oct 2016 03:51:38 +0300 Subject: [PATCH] #3 draft of hang/reach animation, add animation effect command types --- src/controller.h | 36 +++++++--------- src/format.h | 55 +++++++++++++++++++++--- src/lara.h | 106 +++++++++++++++++++++++++++-------------------- 3 files changed, 128 insertions(+), 69 deletions(-) diff --git a/src/controller.h b/src/controller.h index f7cc395..d5e9d2c 100644 --- a/src/controller.h +++ b/src/controller.h @@ -103,7 +103,7 @@ struct Controller { TR::Animation &anim = level->anims[animIndex]; animTime = frame == -1 ? 0.0f : ((frame - anim.frameStart) / 30.0f); ASSERT(anim.frameStart <= anim.frameEnd); - animPrevFrame = -1; + animPrevFrame = int(animTime * 30.0f) - 1; return state = anim.state; } @@ -345,9 +345,9 @@ struct Controller { return vec3((float)sx, (float)sy, (float)sz); break; } - case TR::ANIM_CMD_SPEED : // cmd jump speed - case TR::ANIM_CMD_SOUND : // play sound - case TR::ANIM_CMD_SPECIAL : // special commands + case TR::ANIM_CMD_SPEED : // cmd jump speed + case TR::ANIM_CMD_SOUND : // play sound + case TR::ANIM_CMD_EFFECT : // special commands ptr += 2; break; } @@ -394,28 +394,24 @@ struct Controller { break; case TR::ANIM_CMD_KILL : // kill break; - case TR::ANIM_CMD_SOUND : { // play sound + case TR::ANIM_CMD_SOUND : // play sound + case TR::ANIM_CMD_EFFECT : { // special commands int frame = (*ptr++); int id = (*ptr++) & 0x3FFF; int idx = frame - anim->frameStart; - if (idx > animPrevFrame && idx <= frameIndex) - playSound(id); + if (idx > animPrevFrame && idx <= frameIndex) { + if (cmd == TR::ANIM_CMD_EFFECT) { + switch (id) { + case TR::EFFECT_ROTATE_180 : angle.y = angle.y + PI; break; + case TR::EFFECT_LARA_BUBBLES : playSound(TR::SND_BUBBLE); break; + default : LOG("unknown special cmd %d (anim %d)\n", id, animIndex); + } + } else + playSound(id); + } break; } - case TR::ANIM_CMD_SPECIAL : // special commands - if (frameIndex != animPrevFrame && frameIndex + anim->frameStart == ptr[0]) { - switch (ptr[1]) { - case TR::ANIM_CMD_SPECIAL_FLIP : angle.y = angle.y + PI; break; - case TR::ANIM_CMD_SPECIAL_BUBBLE : playSound(TR::SND_BUBBLE); break; - case TR::ANIM_CMD_SPECIAL_CTRL : LOG("water out ?\n"); break; - default : LOG("unknown special cmd %d\n", (int)ptr[1]); - } - } - ptr += 2; - break; - default : - LOG("unknown animation command %d\n", cmd); } } } diff --git a/src/format.h b/src/format.h index 2aa3284..0925a73 100644 --- a/src/format.h +++ b/src/format.h @@ -22,14 +22,59 @@ namespace TR { ANIM_CMD_EMPTY , ANIM_CMD_KILL , ANIM_CMD_SOUND , - ANIM_CMD_SPECIAL , + ANIM_CMD_EFFECT , }; + // https://dl.dropboxusercontent.com/u/62482708/Secret/TR4%26TR5%20PSX%20Stuff.zip enum { - ANIM_CMD_SPECIAL_FLIP = 0, - ANIM_CMD_SPECIAL_BUBBLE = 3, - ANIM_CMD_SPECIAL_CTRL = 12, - }; + EFFECT_ROTATE_180 , + EFFECT_FLOOR_SHAKE , + EFFECT_LARA_NORMAL , + EFFECT_LARA_BUBBLES , + EFFECT_FINISH_LEVEL , + EFFECT_ACTIVATE_CAMERA , + EFFECT_ACTIVATE_KEY , + EFFECT_RUBBLEFX , + EFFECT_CROWBAR , + EFFECT_CURTAINFX , + EFFECT_SETCHANGEFX , + EFFECT_EXPLOSION_FX , + EFFECT_LARA_HANDSFREE , + EFFECT_FLIP_MAP , + EFFECT_DRAW_RIGHTGUN , + EFFECT_DRAW_LEFTGUN , + EFFECT_SHOOT_RIGHTGUN , + EFFECT_SHOOT_LEFTGUN , + EFFECT_MESH_SWAP1 , + EFFECT_MESH_SWAP2 , + EFFECT_MESH_SWAP3 , + EFFECT_INV_ON , + EFFECT_INV_OFF , + EFFECT_DYN_ON , + EFFECT_DYN_OFF , + EFFECT_STATUEFX , + EFFECT_RESET_HAIR , + EFFECT_BOILERFX , + EFFECT_SETFOG , + EFFECT_GHOSTTRAP , + EFFECT_LARALOCATION , + EFFECT_CLEARSCARABS , + EFFECT_FOOTPRINT_FX , + EFFECT_FLIP_MAP0 , + EFFECT_FLIP_MAP1 , + EFFECT_FLIP_MAP2 , + EFFECT_FLIP_MAP3 , + EFFECT_FLIP_MAP4 , + EFFECT_FLIP_MAP5 , + EFFECT_FLIP_MAP6 , + EFFECT_FLIP_MAP7 , + EFFECT_FLIP_MAP8 , + EFFECT_FLIP_MAP9 , + EFFECT_POURSWAP1 , + EFFECT_POURSWAP2 , + EFFECT_LARALOCATIONPAD , + EFFECT_KILLACTIVEBADDIES, + }; enum { SND_NO = 2, diff --git a/src/lara.h b/src/lara.h index 0026516..e7c5abf 100644 --- a/src/lara.h +++ b/src/lara.h @@ -29,6 +29,8 @@ struct Lara : Controller { ANIM_CLIMB_JUMP = 26, + ANIM_HANG_UP = 29, + ANIM_FALL = 34, ANIM_SMASH_JUMP = 32, @@ -48,6 +50,11 @@ struct Lara : Controller { ANIM_BACK_DESCEND_RIGHT = 62, ANIM_SLIDE_FORTH = 70, + + ANIM_HANG_FORTH = 96, + + ANIM_STAND_NORMAL = 103, + ANIM_SLIDE_BACK = 105, ANIM_WATER_FALL = 112, @@ -82,7 +89,7 @@ struct Lara : Controller { STATE_BACK, STATE_SWIM, STATE_GLIDE, - STATE_HANG_JUMP, + STATE_HANG_UP, STATE_FAST_TURN, STATE_STEP_RIGHT, STATE_STEP_LEFT, @@ -305,30 +312,13 @@ struct Lara : Controller { break; } - return vec3(0.0f, h, 0.0f); - -/* - - - return offset; - */ - /* - switch (stand) { - case Controller::STAND_AIR : - case Controller::STAND_GROUND : - case Controller::STAND_SLIDE : - case Controller::STAND_HANG : - offset.y = 768.0f; - break; - case Controller::STAND_UNDERWATER : - case Controller::STAND_ONWATER : - offset.y = 256.0f; - break; - }*/ } virtual Stand getStand() { + if (stand == STAND_HANG && (mask & ACTION)) + return stand; + if (stand == STAND_ONWATER && state != STATE_DIVE && state != STATE_STOP) return stand; @@ -349,7 +339,7 @@ struct Lara : Controller { int extra = stand != STAND_AIR ? 256 : 0; - if (info.roomBelow == 0xFF && e.y + extra >= info.floor) + if (stand != STAND_HANG && info.roomBelow == 0xFF && e.y + extra >= info.floor) return STAND_GROUND; return STAND_AIR; @@ -364,6 +354,21 @@ struct Lara : Controller { virtual int getStateAir() { angle.x = 0.0f; + if ((state == STATE_REACH || state == STATE_UP_JUMP) && (mask & ACTION)) { + vec3 p = pos + getDir() * 128.0f; + TR::Level::FloorInfo info; + level->getFloorInfo(getRoomIndex(), (int)p.x, (int)p.z, info); + + if (abs(info.floor - (p.y - 768.0f + 64.0f)) < 32) { + turnToWall(); + pos = pos - getDir() * 128.0f; // TODO: collision wall offset + pos.y = info.floor + 768.0f - 64.0f; + stand = STAND_HANG; + updateEntity(); + return setAnimation(state == STATE_HANG ? ANIM_HANG_UP : ANIM_HANG_FORTH); + } + } + if (state == STATE_FORWARD_JUMP) { if (mask & ACTION) return STATE_REACH; if ((mask & (FORTH | WALK)) == (FORTH | WALK)) return STATE_SWAN_DIVE; @@ -423,17 +428,27 @@ struct Lara : Controller { return STATE_STOP; } - if ( (mask & (FORTH | ACTION)) == (FORTH | ACTION) ) { + if ( (mask & (FORTH | ACTION)) == (FORTH | ACTION) && (animIndex == ANIM_STAND || animIndex == ANIM_STAND_NORMAL) ) { vec3 p = pos + getDir() * 64.0f; TR::Level::FloorInfo info; level->getFloorInfo(getRoomIndex(), (int)p.x, (int)p.z, info); int h = (int)pos.y - info.floor; - if (h >= 2 * 256 - 16 && h <= 2 * 256 + 16 && animIndex != ANIM_CLIMB_2) - return setAnimation(ANIM_CLIMB_2); - if (h >= 3 * 256 - 16 && h <= 3 * 256 + 16 && animIndex != ANIM_CLIMB_3) - return setAnimation(ANIM_CLIMB_3); - if (h >= 4 * 256 - 16 && h <= 7 * 256 + 16 && state != STATE_HANG_JUMP) - return setAnimation(ANIM_CLIMB_JUMP); + + int aIndex = animIndex; + if (h < 2 * 256 - 16) + ; // do nothing + else if (h <= 2 * 256 + 16) + aIndex = ANIM_CLIMB_2; + else if (h <= 3 * 256 + 16) + aIndex = ANIM_CLIMB_3; + else if (h <= 7 * 256 + 16) + aIndex = ANIM_CLIMB_JUMP; + + if (aIndex != animIndex) { + turnToWall(); + updateEntity(); + return setAnimation(aIndex); + } } // only dpad buttons pressed @@ -483,7 +498,10 @@ struct Lara : Controller { } virtual int getStateHang() { - return Controller::getStateHang(); + if (mask & LEFT) return STATE_HANG_LEFT; + if (mask & RIGHT) return STATE_HANG_RIGHT; + if (mask & FORTH) return (mask & WALK) ? STATE_HANDSTAND : STATE_HANG_UP; + return STATE_HANG; } virtual int getStateUnderwater() { @@ -532,10 +550,13 @@ struct Lara : Controller { } virtual int getStateDefault() { - if (state == STATE_DIVE) return state; - if (stand == STAND_ONWATER) return STATE_SURF_TREAD; - if (stand == STAND_UNDERWATER) return STATE_TREAD; - if (stand == STAND_GROUND) return STATE_STOP; + if (state == STATE_DIVE) return state; + switch (stand) { + case STAND_GROUND : return STATE_STOP; + case STAND_HANG : return STATE_HANG; + case STAND_ONWATER : return STATE_SURF_TREAD; + case STAND_UNDERWATER : return STATE_TREAD; + } return STATE_FALL; } @@ -646,11 +667,13 @@ struct Lara : Controller { case STATE_LEFT_JUMP : case STATE_STEP_LEFT : case STATE_SURF_LEFT : + case STATE_HANG_LEFT : angleExt -= PI * 0.5f; break; case STATE_RIGHT_JUMP : case STATE_STEP_RIGHT : case STATE_SURF_RIGHT : + case STATE_HANG_RIGHT : angleExt += PI * 0.5f; break; } @@ -776,20 +799,15 @@ struct Lara : Controller { velocity.y = 0.0f; } else { velocity.x = velocity.z = 0.0f; - pos.y = p.y; + pos.y = p.y + offset.y; updateEntity(); } break; case STAND_GROUND : - if (state != STATE_UP_JUMP) { // early stage of up jump - if (delta <= -256 * 4 && state == STATE_RUN) - setAnimation(left ? ANIM_SMASH_RUN_LEFT : ANIM_SMASH_RUN_RIGHT); - else - setAnimation(ANIM_STAND); - } else { - pos.y = p.y; - updateEntity(); - } + if (delta <= -256 * 4 && state == STATE_RUN) + setAnimation(left ? ANIM_SMASH_RUN_LEFT : ANIM_SMASH_RUN_RIGHT); + else + setAnimation(ANIM_STAND); velocity.x = velocity.z = 0.0f; break; default : ;// no smash animation