mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-17 18:36:43 +02:00
#15 core stats refactoring; gamepad analog fix for web; shadow matrix crop (test)
This commit is contained in:
@@ -254,6 +254,10 @@ struct Camera : Controller {
|
||||
updateListener();
|
||||
}
|
||||
|
||||
mat4 getProjMatrix() {
|
||||
return mat4(fov, (float)Core::width / (float)Core::height, znear, zfar);
|
||||
}
|
||||
|
||||
virtual void setup(bool calcMatrices) {
|
||||
if (calcMatrices) {
|
||||
if (reflectPlane) {
|
||||
@@ -263,7 +267,7 @@ struct Camera : Controller {
|
||||
Core::mViewInv = mViewInv;
|
||||
|
||||
Core::mView = Core::mViewInv.inverse();
|
||||
Core::mProj = mat4(fov, (float)Core::width / (float)Core::height, znear, zfar);
|
||||
Core::mProj = getProjMatrix();
|
||||
|
||||
// TODO: camera shake
|
||||
// TODO: temporal anti-aliasing
|
||||
|
@@ -541,7 +541,7 @@ struct Controller {
|
||||
|
||||
entity.flags.rendered = true;
|
||||
|
||||
if (Core::frameIndex != frameIndex)
|
||||
if (Core::stats.frame != frameIndex)
|
||||
animation.getJoints(matrix, -1, true, joints);
|
||||
|
||||
if (layers) {
|
||||
@@ -563,7 +563,7 @@ struct Controller {
|
||||
mesh->renderModel(entity.modelIndex - 1);
|
||||
}
|
||||
|
||||
frameIndex = Core::frameIndex;
|
||||
frameIndex = Core::stats.frame;
|
||||
|
||||
// blob shadow // TODO: fake AO
|
||||
if (!Core::settings.shadows && Core::pass == Core::passCompose && TR::castShadow(entity.type)) {
|
||||
|
33
src/core.h
33
src/core.h
@@ -186,9 +186,10 @@ struct Texture;
|
||||
enum CullMode { cfNone, cfBack, cfFront };
|
||||
enum BlendMode { bmNone, bmAlpha, bmAdd, bmMultiply, bmScreen };
|
||||
|
||||
extern int getTime();
|
||||
|
||||
namespace Core {
|
||||
int width, height;
|
||||
int frameIndex;
|
||||
float deltaTime;
|
||||
mat4 mView, mProj, mViewProj, mViewInv, mLightProj;
|
||||
Basis basis;
|
||||
@@ -221,9 +222,24 @@ namespace Core {
|
||||
CullMode cullMode;
|
||||
} active;
|
||||
|
||||
struct {
|
||||
int dips;
|
||||
int tris;
|
||||
struct Stats {
|
||||
int dips, tris, frame, fps, fpsTime;
|
||||
|
||||
Stats() : frame(0), fps(0), fpsTime(0) {}
|
||||
|
||||
void start() {
|
||||
dips = tris = 0;
|
||||
}
|
||||
|
||||
void stop() {
|
||||
if (fpsTime < getTime()) {
|
||||
LOG("FPS: %d DIP: %d TRI: %d\n", fps, dips, tris);
|
||||
fps = frame;
|
||||
frame = 0;
|
||||
fpsTime = getTime() + 1000;
|
||||
} else
|
||||
frame++;
|
||||
}
|
||||
} stats;
|
||||
|
||||
struct {
|
||||
@@ -360,8 +376,6 @@ namespace Core {
|
||||
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
lightColor[i] = vec4(0, 0, 0, 1);
|
||||
|
||||
frameIndex = 0;
|
||||
|
||||
uint32 data = 0x00000000;
|
||||
blackTex = new Texture(1, 1, Texture::RGBA, false, &data, false);
|
||||
@@ -532,13 +546,18 @@ namespace Core {
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, x, y, width, height);
|
||||
}
|
||||
|
||||
void resetStates() {
|
||||
void beginFrame() {
|
||||
memset(&active, 0, sizeof(active));
|
||||
setDepthTest(true);
|
||||
active.blendMode = bmAlpha;
|
||||
active.cullMode = cfNone;
|
||||
setCulling(cfFront);
|
||||
setBlending(bmNone);
|
||||
Core::stats.start();
|
||||
}
|
||||
|
||||
void endFrame() {
|
||||
Core::stats.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -60,8 +60,9 @@ namespace Game {
|
||||
}
|
||||
|
||||
void render() {
|
||||
Core::beginFrame();
|
||||
level->render();
|
||||
Core::frameIndex++;
|
||||
Core::endFrame();
|
||||
}
|
||||
}
|
||||
|
||||
|
197
src/lara.h
197
src/lara.h
@@ -54,7 +54,7 @@ struct Lara : Character {
|
||||
ANIM_STAND_RIGHT = 3,
|
||||
|
||||
ANIM_STAND = 11,
|
||||
|
||||
|
||||
ANIM_CLIMB_JUMP = 26,
|
||||
|
||||
ANIM_HANG_FALL = 28,
|
||||
@@ -159,7 +159,7 @@ struct Lara : Character {
|
||||
STATE_HANDSTAND,
|
||||
STATE_WATER_OUT,
|
||||
STATE_MAX };
|
||||
|
||||
|
||||
enum : int {
|
||||
BODY_HIP = 0x0001,
|
||||
BODY_LEG_L1 = 0x0002,
|
||||
@@ -209,7 +209,7 @@ struct Lara : Character {
|
||||
} arms[2];
|
||||
|
||||
ActionCommand actionList[MAX_TRIGGER_ACTIONS];
|
||||
|
||||
|
||||
Inventory inventory;
|
||||
int lastPickUp;
|
||||
int viewTarget;
|
||||
@@ -272,10 +272,10 @@ struct Lara : Character {
|
||||
float DAMPING = 1.5f;
|
||||
|
||||
if (lara->getRoom().flags.water) {
|
||||
ACCEL *= -0.5f;
|
||||
ACCEL *= -0.5f;
|
||||
DAMPING = 4.0f;
|
||||
}
|
||||
|
||||
|
||||
DAMPING = 1.0f / (1.0f + DAMPING * TIMESTEP); // Pade approximation
|
||||
|
||||
for (int i = 1; i < jointsCount; i++) {
|
||||
@@ -340,7 +340,7 @@ struct Lara : Character {
|
||||
a.pos -= dir;
|
||||
b.pos += dir;
|
||||
} else
|
||||
b.pos += dir * (d * 1.0f);
|
||||
b.pos += dir * (d * 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ struct Lara : Character {
|
||||
integrate(); // Verlet integration step
|
||||
collide(); // check collision with Lara's mesh
|
||||
for (int i = 0; i < jointsCount; i++) // solve connections (springs)
|
||||
solve();
|
||||
solve();
|
||||
|
||||
vec3 headDir = getBasis().rot * vec3(0.0f, 0.0f, -1.0f);
|
||||
|
||||
@@ -357,13 +357,13 @@ struct Lara : Character {
|
||||
vec3 d = (joints[i + 1].pos - joints[i].pos).normal();
|
||||
vec3 r = d.cross(headDir).normal();
|
||||
vec3 u = d.cross(r).normal();
|
||||
|
||||
|
||||
mat4 m;
|
||||
m.up = vec4(u, 0.0f);
|
||||
m.dir = vec4(d, 0.0f);
|
||||
m.right = vec4(r, 0.0f);
|
||||
m.offset = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
|
||||
basis[i].identity();
|
||||
basis[i].translate(joints[i].pos);
|
||||
basis[i].rotate(m.getRot());
|
||||
@@ -374,11 +374,11 @@ struct Lara : Character {
|
||||
Core::active.shader->setParam(uBasis, basis[0], jointsCount);
|
||||
mesh->renderModel(lara->level->extra.braid);
|
||||
}
|
||||
|
||||
|
||||
} *braid;
|
||||
|
||||
Lara(IGame *game, int entity, bool home) : Character(game, entity, 1000), home(home), wpnCurrent(Weapon::EMPTY), wpnNext(Weapon::EMPTY), chestOffset(pos), viewTarget(-1), braid(NULL) {
|
||||
|
||||
|
||||
if (getEntity().type == TR::Entity::LARA) {
|
||||
if (getRoom().flags.water)
|
||||
animation.setAnim(ANIM_UNDERWATER);
|
||||
@@ -408,7 +408,7 @@ struct Lara : Character {
|
||||
if (level->extra.braid > -1)
|
||||
braid = new Braid(this, vec3(-4.0f, 24.0f, -48.0f));
|
||||
|
||||
#ifdef _DEBUG
|
||||
#ifdef _DEBUG
|
||||
//reset(14, vec3(40448, 3584, 60928), PI * 0.5f, true); // gym (pool)
|
||||
|
||||
//reset(14, vec3(20215, 6656, 52942), PI); // level 1 (bridge)
|
||||
@@ -443,7 +443,7 @@ struct Lara : Character {
|
||||
}
|
||||
updateEntity();
|
||||
}
|
||||
|
||||
|
||||
void wpnSet(Weapon::Type wType) {
|
||||
wpnCurrent = wType;
|
||||
wpnState = Weapon::IS_FIRING;
|
||||
@@ -463,9 +463,9 @@ struct Lara : Character {
|
||||
|
||||
arm.anim = wAnim;
|
||||
|
||||
if (wAnimDir > 0.0f)
|
||||
if (wAnimDir > 0.0f)
|
||||
arm.animation.time = wAnimTime;
|
||||
else
|
||||
else
|
||||
if (wAnimDir < 0.0f)
|
||||
arm.animation.time = arm.animation.timeMax + wAnimTime;
|
||||
arm.animation.updateInfo();
|
||||
@@ -490,7 +490,7 @@ struct Lara : Character {
|
||||
int mask = 0;
|
||||
switch (wpnCurrent) {
|
||||
case Weapon::EMPTY : break;
|
||||
case Weapon::PISTOLS :
|
||||
case Weapon::PISTOLS :
|
||||
case Weapon::MAGNUMS :
|
||||
case Weapon::UZIS :
|
||||
switch (wState) {
|
||||
@@ -518,7 +518,7 @@ struct Lara : Character {
|
||||
// 2 - shotgun (hands, chest)
|
||||
// 3 - angry (head)
|
||||
|
||||
// swap weapon parts
|
||||
// swap weapon parts
|
||||
if (wpnCurrent != Weapon::SHOTGUN) {
|
||||
meshSwap(1, level->extra.weapons[wpnCurrent], mask);
|
||||
// have a shotgun in inventory place it on the back if another weapon is in use
|
||||
@@ -529,7 +529,7 @@ struct Lara : Character {
|
||||
|
||||
// mesh swap to angry Lara's head while firing (from uzis model)
|
||||
meshSwap(3, level->extra.weapons[Weapon::UZIS], (wState == Weapon::IS_FIRING) ? BODY_HEAD : 0);
|
||||
|
||||
|
||||
wpnState = wState;
|
||||
}
|
||||
|
||||
@@ -538,7 +538,7 @@ struct Lara : Character {
|
||||
}
|
||||
|
||||
bool canLookAt() {
|
||||
return (stand == STAND_GROUND || stand == STAND_SLIDE)
|
||||
return (stand == STAND_GROUND || stand == STAND_SLIDE)
|
||||
&& state != STATE_REACH
|
||||
&& state != STATE_PUSH_BLOCK
|
||||
&& state != STATE_PULL_BLOCK
|
||||
@@ -551,7 +551,7 @@ struct Lara : Character {
|
||||
&& emptyHands()
|
||||
&& animation.index != ANIM_CLIMB_3
|
||||
&& animation.index != ANIM_CLIMB_2
|
||||
&& state != STATE_DEATH
|
||||
&& state != STATE_DEATH
|
||||
&& state != STATE_HANG
|
||||
&& state != STATE_REACH
|
||||
&& state != STATE_TREAD
|
||||
@@ -595,7 +595,7 @@ struct Lara : Character {
|
||||
wpnSetAnim(arms[0], wpnState, Weapon::Anim::PREPARE, 0.0f, 1.0f);
|
||||
wpnSetAnim(arms[1], wpnState, Weapon::Anim::PREPARE, 0.0f, 1.0f);
|
||||
} else
|
||||
wpnSetAnim(arms[0], wpnState, Weapon::Anim::UNHOLSTER, 0.0f, 1.0f);
|
||||
wpnSetAnim(arms[0], wpnState, Weapon::Anim::UNHOLSTER, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -621,7 +621,7 @@ struct Lara : Character {
|
||||
case Weapon::Anim::PREPARE : ASSERT(false); break; // rifle has no prepare animation
|
||||
case Weapon::Anim::UNHOLSTER : return 1;
|
||||
case Weapon::Anim::HOLSTER : return 3;
|
||||
case Weapon::Anim::HOLD :
|
||||
case Weapon::Anim::HOLD :
|
||||
case Weapon::Anim::AIM : return 0;
|
||||
case Weapon::Anim::FIRE : return 2;
|
||||
default : ;
|
||||
@@ -631,7 +631,7 @@ struct Lara : Character {
|
||||
case Weapon::Anim::PREPARE : return 1;
|
||||
case Weapon::Anim::UNHOLSTER : return 2;
|
||||
case Weapon::Anim::HOLSTER : ASSERT(false); break; // pistols has no holster animation (it's reversed unholster)
|
||||
case Weapon::Anim::HOLD :
|
||||
case Weapon::Anim::HOLD :
|
||||
case Weapon::Anim::AIM : return 0;
|
||||
case Weapon::Anim::FIRE : return 3;
|
||||
default : ;
|
||||
@@ -663,7 +663,7 @@ struct Lara : Character {
|
||||
wpnSetAnim(arms[i], Weapon::IS_ARMED, Weapon::Anim::AIM, 0.0f, -1.0f, target == -1);
|
||||
}
|
||||
// shotgun reload sound
|
||||
if (wpnCurrent == Weapon::SHOTGUN) {
|
||||
if (wpnCurrent == Weapon::SHOTGUN) {
|
||||
if (anim.frameIndex == 10)
|
||||
playSound(TR::SND_SHOTGUN_RELOAD, pos, Sound::Flags::PAN);
|
||||
}
|
||||
@@ -681,12 +681,12 @@ struct Lara : Character {
|
||||
|
||||
void doShot(bool rightHand, bool leftHand) {
|
||||
int count = wpnCurrent == Weapon::SHOTGUN ? 6 : 2;
|
||||
|
||||
|
||||
float nearDist = 32.0f * 1024.0f;
|
||||
vec3 nearPos;
|
||||
bool hasShot = false;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
int armIndex;
|
||||
if (wpnCurrent == Weapon::SHOTGUN) {
|
||||
if (!rightHand) continue;
|
||||
@@ -696,7 +696,7 @@ struct Lara : Character {
|
||||
armIndex = i;
|
||||
}
|
||||
Arm *arm = &arms[armIndex];
|
||||
|
||||
|
||||
arm->shotTimer = 0.0f;
|
||||
hasShot = true;
|
||||
|
||||
@@ -786,12 +786,12 @@ struct Lara : Character {
|
||||
float intensity = clamp((0.1f - arms[i].shotTimer) * 20.0f, 0.0f, 1.0f);
|
||||
Core::lightColor[1 + i] = FLASH_LIGHT_COLOR * vec4(intensity, intensity, intensity, sqrtf(intensity));
|
||||
}
|
||||
|
||||
|
||||
if (isRifle)
|
||||
animateShotgun();
|
||||
else
|
||||
animatePistols();
|
||||
|
||||
|
||||
wpnFire(); // make a shot
|
||||
}
|
||||
}
|
||||
@@ -800,7 +800,7 @@ struct Lara : Character {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
Arm &arm = arms[i];
|
||||
|
||||
if (!arm.animation.isEnded) continue;
|
||||
if (!arm.animation.isEnded) continue;
|
||||
|
||||
if (arm.animation.dir >= 0.0f)
|
||||
switch (arm.anim) {
|
||||
@@ -815,7 +815,7 @@ struct Lara : Character {
|
||||
break;
|
||||
default : ;
|
||||
};
|
||||
|
||||
|
||||
if (arm.animation.dir < 0.0f)
|
||||
switch (arm.anim) {
|
||||
case Weapon::Anim::PREPARE : wpnSetAnim(arm, Weapon::IS_HIDDEN, Weapon::Anim::NONE, 0.0f, 1.0f, false); break;
|
||||
@@ -842,7 +842,7 @@ struct Lara : Character {
|
||||
break;
|
||||
default : ;
|
||||
}
|
||||
} else
|
||||
} else
|
||||
if (arm.animation.frameIndex != arm.animation.framePrev) {
|
||||
float delta = arm.animation.time / arm.animation.timeMax;
|
||||
switch (arm.anim) {
|
||||
@@ -857,11 +857,11 @@ struct Lara : Character {
|
||||
}
|
||||
|
||||
void updateOverrides() {
|
||||
// head & chest
|
||||
// head & chest
|
||||
animation.overrideMask |= BODY_CHEST | BODY_HEAD;
|
||||
|
||||
animation.overrides[ 7] = animation.getJointRot( 7);
|
||||
animation.overrides[14] = animation.getJointRot(14);
|
||||
animation.overrides[14] = animation.getJointRot(14);
|
||||
|
||||
/* TODO: shotgun full body animation
|
||||
if (wpnCurrent == Weapon::SHOTGUN) {
|
||||
@@ -889,14 +889,14 @@ struct Lara : Character {
|
||||
|
||||
|
||||
lookAt(viewTarget);
|
||||
|
||||
|
||||
if (wpnCurrent == Weapon::SHOTGUN)
|
||||
aimShotgun();
|
||||
else
|
||||
aimPistols();
|
||||
}
|
||||
|
||||
void lookAt(int target) { // TODO: character lookAt
|
||||
void lookAt(int target) { // TODO: character lookAt
|
||||
float speed = 8.0f * Core::deltaTime;
|
||||
quat rot;
|
||||
|
||||
@@ -904,7 +904,7 @@ struct Lara : Character {
|
||||
// chest
|
||||
if (can && aim(target, 7, vec4(-PI * 0.4f, PI * 0.4f, -PI * 0.9f, PI * 0.9f), rot))
|
||||
rotChest = rotChest.slerp(quat(0, 0, 0, 1).slerp(rot, 0.5f), speed);
|
||||
else
|
||||
else
|
||||
rotChest = rotChest.slerp(quat(0, 0, 0, 1), speed);
|
||||
animation.overrides[7] = rotChest * animation.overrides[7];
|
||||
|
||||
@@ -1010,7 +1010,7 @@ struct Lara : Character {
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual void cmdEmpty() {
|
||||
wpnHide();
|
||||
}
|
||||
@@ -1034,7 +1034,7 @@ struct Lara : Character {
|
||||
switch (fx) {
|
||||
case TR::EFFECT_FLIP_MAP : break; // TODO
|
||||
case TR::EFFECT_LARA_HANDSFREE : break;//meshSwap(1, level->extra.weapons[wpnCurrent], BODY_LEG_L1 | BODY_LEG_R1); break;
|
||||
case TR::EFFECT_DRAW_RIGHTGUN :
|
||||
case TR::EFFECT_DRAW_RIGHTGUN :
|
||||
case TR::EFFECT_DRAW_LEFTGUN : drawGun(fx == TR::EFFECT_DRAW_RIGHTGUN); break;
|
||||
default : LOG("unknown effect command %d (anim %d)\n", fx, animation.index);
|
||||
}
|
||||
@@ -1094,7 +1094,7 @@ struct Lara : Character {
|
||||
pos -= getDir() * 256.0f;
|
||||
pos.y -= 256;
|
||||
}
|
||||
updateEntity();
|
||||
updateEntity();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1109,8 +1109,8 @@ struct Lara : Character {
|
||||
bool useItem(TR::Entity::Type item, TR::Entity::Type slot) {
|
||||
if (item == TR::Entity::NONE) {
|
||||
switch (slot) {
|
||||
case TR::Entity::HOLE_KEY : item = TR::Entity::KEY_1; break; // TODO: 1-4
|
||||
case TR::Entity::HOLE_PUZZLE : item = TR::Entity::PUZZLE_1; break;
|
||||
case TR::Entity::HOLE_KEY : item = TR::Entity::KEY_1; break; // TODO: 1-4
|
||||
case TR::Entity::HOLE_PUZZLE : item = TR::Entity::PUZZLE_1; break;
|
||||
default : return false;
|
||||
}
|
||||
}
|
||||
@@ -1269,13 +1269,13 @@ struct Lara : Character {
|
||||
if (stand == STAND_SLIDE || (stand == STAND_AIR && velocity.y > 0) || stand == STAND_GROUND) {
|
||||
if (e.y + 8 >= info.floor && (abs(info.slantX) > 2 || abs(info.slantZ) > 2)) {
|
||||
if (stand == STAND_AIR)
|
||||
playSound(TR::SND_LANDING, pos, Sound::Flags::PAN);
|
||||
playSound(TR::SND_LANDING, pos, Sound::Flags::PAN);
|
||||
pos.y = float(info.floor);
|
||||
updateEntity();
|
||||
|
||||
if (stand == STAND_GROUND || stand == STAND_AIR)
|
||||
slideStart();
|
||||
|
||||
|
||||
return STAND_SLIDE;
|
||||
}
|
||||
}
|
||||
@@ -1314,7 +1314,7 @@ struct Lara : Character {
|
||||
vec3 p = vec3(pos.x, bounds.min.y, pos.z);
|
||||
|
||||
Collision c = Collision(level, getRoomIndex(), p, getDir() * 32.0f, vec3(0.0f), LARA_RADIUS, angleExt, 0, 0, 0, 0);
|
||||
|
||||
|
||||
if (c.side != Collision::FRONT)
|
||||
return state;
|
||||
|
||||
@@ -1343,7 +1343,7 @@ struct Lara : Character {
|
||||
if (input & ACTION) return STATE_REACH;
|
||||
if ((input & (FORTH | WALK)) == (FORTH | WALK)) return STATE_SWAN_DIVE;
|
||||
}
|
||||
} else
|
||||
} else
|
||||
if (state != STATE_SWAN_DIVE && state != STATE_REACH && state != STATE_FALL && state != STATE_UP_JUMP && state != STATE_BACK_JUMP && state != STATE_LEFT_JUMP && state != STATE_RIGHT_JUMP)
|
||||
return animation.setAnim(ANIM_FALL);
|
||||
|
||||
@@ -1373,7 +1373,7 @@ struct Lara : Character {
|
||||
|
||||
for (int i = 0; i < level->entitiesCount; i++) {
|
||||
TR::Entity &e = level->entities[i];
|
||||
|
||||
|
||||
int q = entityQuadrant(e);
|
||||
int dx = abs(int(pos.x) - e.x);
|
||||
int dz = abs(int(pos.z) - e.z);
|
||||
@@ -1394,10 +1394,10 @@ struct Lara : Character {
|
||||
if ((input & ACTION) && emptyHands() && doPickUp())
|
||||
return STATE_PICK_UP;
|
||||
|
||||
if ((input & (FORTH | ACTION)) == (FORTH | ACTION) && (animation.index == ANIM_STAND || animation.index == ANIM_STAND_NORMAL) && emptyHands() && collision.side == Collision::FRONT) { // TODO: get rid of animation.index
|
||||
if ((input & (FORTH | ACTION)) == (FORTH | ACTION) && (animation.index == ANIM_STAND || animation.index == ANIM_STAND_NORMAL) && emptyHands() && collision.side == Collision::FRONT) { // TODO: get rid of animation.index
|
||||
int floor = collision.info[Collision::FRONT].floor;
|
||||
int h = (int)pos.y - floor;
|
||||
|
||||
|
||||
int aIndex = animation.index;
|
||||
if (h <= 2 * 256 + 128) {
|
||||
aIndex = ANIM_CLIMB_2;
|
||||
@@ -1406,7 +1406,7 @@ struct Lara : Character {
|
||||
aIndex = ANIM_CLIMB_3;
|
||||
pos.y = floor + 768.0f;
|
||||
} else if (h <= 7 * 256 + 128)
|
||||
aIndex = ANIM_CLIMB_JUMP;
|
||||
aIndex = ANIM_CLIMB_JUMP;
|
||||
|
||||
if (aIndex != animation.index) {
|
||||
alignToWall(-LARA_RADIUS);
|
||||
@@ -1429,29 +1429,29 @@ struct Lara : Character {
|
||||
}
|
||||
|
||||
// jump button is pressed
|
||||
if (input & JUMP) {
|
||||
if (input & JUMP) {
|
||||
if ((input & FORTH) && state == STATE_FORWARD_JUMP)
|
||||
return STATE_RUN;
|
||||
if (state == STATE_RUN)
|
||||
return STATE_FORWARD_JUMP;
|
||||
if (animation.index == ANIM_SLIDE_BACK) // TODO: animation index? %)
|
||||
return STATE_SLIDE_BACK;
|
||||
return STATE_SLIDE_BACK;
|
||||
return STATE_COMPRESS;
|
||||
}
|
||||
|
||||
|
||||
// walk button is pressed
|
||||
if (input & WALK) {
|
||||
if (input & WALK) {
|
||||
if (input & FORTH) return STATE_WALK;
|
||||
if (input & BACK) return STATE_BACK;
|
||||
if (input & LEFT) return STATE_STEP_LEFT;
|
||||
if (input & RIGHT) return STATE_STEP_RIGHT;
|
||||
return STATE_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
if ((input & ACTION) && emptyHands()) {
|
||||
if (state == STATE_PUSH_PULL_READY && (input & (FORTH | BACK))) {
|
||||
int pushState = (input & FORTH) ? STATE_PUSH_BLOCK : STATE_PULL_BLOCK;
|
||||
Block *block = getBlock();
|
||||
Block *block = getBlock();
|
||||
if (animation.canSetState(pushState) && block->doMove((input & FORTH) != 0)) {
|
||||
alignToWall(-LARA_RADIUS);
|
||||
return pushState;
|
||||
@@ -1519,7 +1519,7 @@ struct Lara : Character {
|
||||
vec3 p = pos + getDir() * (LARA_RADIUS + 2.0f);
|
||||
level->getFloorInfo(getRoomIndex(), (int)p.x, (int)p.y, (int)p.z, info);
|
||||
if (info.floor - info.ceiling >= LARA_HEIGHT)
|
||||
return (input & WALK) ? STATE_HANDSTAND : STATE_HANG_UP;
|
||||
return (input & WALK) ? STATE_HANDSTAND : STATE_HANG_UP;
|
||||
}
|
||||
return STATE_HANG;
|
||||
}
|
||||
@@ -1535,16 +1535,16 @@ struct Lara : Character {
|
||||
angle.x = -45.0f * DEG2RAD;
|
||||
return animation.setAnim(ANIM_WATER_FALL); // TODO: wronng animation
|
||||
}
|
||||
|
||||
|
||||
if (state == STATE_SWAN_DIVE) {
|
||||
angle.x = -PI * 0.5f;
|
||||
game->waterDrop(pos, 128.0f, 0.2f);
|
||||
Sprite::add(game, TR::Entity::WATER_SPLASH, getRoomIndex(), (int)pos.x, (int)pos.y, (int)pos.z);
|
||||
return STATE_DIVE;
|
||||
}
|
||||
|
||||
|
||||
if (input & JUMP) return STATE_SWIM;
|
||||
|
||||
|
||||
if (state == STATE_GLIDE && speed < LARA_SWIM_SPEED * 2.0f / 3.0f)
|
||||
return STATE_TREAD;
|
||||
|
||||
@@ -1552,7 +1552,7 @@ struct Lara : Character {
|
||||
}
|
||||
|
||||
virtual int getStateOnwater() {
|
||||
angle.x = 0.0f;
|
||||
angle.x = 0.0f;
|
||||
|
||||
if (state == STATE_WATER_OUT) return state;
|
||||
|
||||
@@ -1571,7 +1571,7 @@ struct Lara : Character {
|
||||
}
|
||||
|
||||
if (input & FORTH) {
|
||||
if (input & JUMP) {
|
||||
if (input & JUMP) {
|
||||
angle.x = -PI * 0.25f;
|
||||
game->waterDrop(pos, 256.0f, 0.2f);
|
||||
return animation.setAnim(ANIM_TO_UNDERWATER);
|
||||
@@ -1584,11 +1584,11 @@ struct Lara : Character {
|
||||
|
||||
return STATE_SURF_SWIM;
|
||||
}
|
||||
|
||||
|
||||
if (input & BACK) return STATE_SURF_BACK;
|
||||
if (input & WALK) {
|
||||
if (input & LEFT) return STATE_SURF_LEFT;
|
||||
if (input & RIGHT) return STATE_SURF_RIGHT;
|
||||
if (input & RIGHT) return STATE_SURF_RIGHT;
|
||||
}
|
||||
return STATE_SURF_TREAD;
|
||||
}
|
||||
@@ -1636,32 +1636,33 @@ struct Lara : Character {
|
||||
if (Input::down[ikE] || Input::down[ikCtrl] || Input::down[ikJoyA]) input |= ACTION;
|
||||
if (Input::down[ikQ] || Input::down[ikAlt] || Input::down[ikJoyY]) input |= WEAPON;
|
||||
|
||||
// analog control
|
||||
rotFactor = vec2(1.0f);
|
||||
// analog control
|
||||
rotFactor = vec2(1.0f);
|
||||
|
||||
if (Input::down[ikJoyL]) input = FORTH | BACK;
|
||||
if (Input::down[ikJoyL]) input = FORTH | BACK;
|
||||
|
||||
if ((state == STATE_STOP || stand == STATE_SURF_TREAD) && fabsf(Input::joy.L.x) < 0.5f && fabsf(Input::joy.L.y) < 0.5f)
|
||||
return input;
|
||||
if ((state == STATE_STOP || state == STATE_SURF_TREAD || state == STATE_HANG) && fabsf(Input::joy.L.x) < 0.5f && fabsf(Input::joy.L.y) < 0.5f)
|
||||
return input;
|
||||
|
||||
bool moving = state == STATE_RUN || state == STATE_WALK || state == STATE_BACK || state == STATE_FAST_BACK || state == STATE_SURF_SWIM || state == STATE_SURF_BACK;
|
||||
|
||||
if (!moving)
|
||||
if (fabsf(Input::joy.L.x) < fabsf(Input::joy.L.y))
|
||||
Input::joy.L.x = 0.0f;
|
||||
else
|
||||
Input::joy.L.y = 0.0f;
|
||||
if (!moving) {
|
||||
if (fabsf(Input::joy.L.x) < fabsf(Input::joy.L.y))
|
||||
Input::joy.L.x = 0.0f;
|
||||
else
|
||||
Input::joy.L.y = 0.0f;
|
||||
}
|
||||
|
||||
if (Input::joy.L.x != 0.0f) {
|
||||
input |= (Input::joy.L.x < 0.0f) ? LEFT : RIGHT;
|
||||
if (moving || stand == STAND_UNDERWATER || stand == STAND_ONWATER)
|
||||
rotFactor.y = min(fabsf(Input::joy.L.x) / 0.75f, 1.0f);
|
||||
}
|
||||
if (Input::joy.L.x != 0.0f) {
|
||||
input |= (Input::joy.L.x < 0.0f) ? LEFT : RIGHT;
|
||||
if (moving || stand == STAND_UNDERWATER || stand == STAND_ONWATER)
|
||||
rotFactor.y = min(fabsf(Input::joy.L.x) / 0.75f, 1.0f);
|
||||
}
|
||||
|
||||
if (Input::joy.L.y != 0.0f) {
|
||||
input |= (Input::joy.L.y < 0.0f) ? FORTH : BACK;
|
||||
if (stand == STAND_UNDERWATER)
|
||||
rotFactor.x = min(fabsf(Input::joy.L.y) / 0.75f, 1.0f);
|
||||
if (Input::joy.L.y != 0.0f) {
|
||||
input |= (Input::joy.L.y < 0.0f) ? FORTH : BACK;
|
||||
if (stand == STAND_UNDERWATER)
|
||||
rotFactor.x = min(fabsf(Input::joy.L.y) / 0.75f, 1.0f);
|
||||
}
|
||||
|
||||
return input;
|
||||
@@ -1672,7 +1673,7 @@ struct Lara : Character {
|
||||
case STATE_PICK_UP : {
|
||||
TR::Entity &item = level->entities[lastPickUp];
|
||||
if (!item.flags.invisible) {
|
||||
int pickupFrame = stand == STAND_GROUND ? PICKUP_FRAME_GROUND : PICKUP_FRAME_UNDERWATER;
|
||||
int pickupFrame = stand == STAND_GROUND ? PICKUP_FRAME_GROUND : PICKUP_FRAME_UNDERWATER;
|
||||
if (animation.isFrameActive(pickupFrame)) {
|
||||
item.flags.invisible = true;
|
||||
inventory.add(item.type, 1);
|
||||
@@ -1716,10 +1717,10 @@ struct Lara : Character {
|
||||
else if (state == STATE_FAST_BACK)
|
||||
w *= TURN_FAST_BACK;
|
||||
else if (state == STATE_TURN_LEFT || state == STATE_TURN_RIGHT || state == STATE_WALK)
|
||||
w *= TURN_NORMAL;
|
||||
w *= TURN_NORMAL;
|
||||
else if (state == STATE_FORWARD_JUMP || state == STATE_BACK)
|
||||
w *= TURN_SLOW;
|
||||
else
|
||||
else
|
||||
w = 0.0f;
|
||||
|
||||
if (w != 0.0f)
|
||||
@@ -1736,7 +1737,7 @@ struct Lara : Character {
|
||||
case STATE_BACK_JUMP :
|
||||
case STATE_FAST_BACK :
|
||||
case STATE_SLIDE_BACK :
|
||||
case STATE_ROLL_1 :
|
||||
case STATE_ROLL_1 :
|
||||
angleExt += PI;
|
||||
break;
|
||||
case STATE_LEFT_JUMP :
|
||||
@@ -1766,7 +1767,7 @@ struct Lara : Character {
|
||||
case STATE_SURF_SWIM :
|
||||
case STATE_SURF_BACK :
|
||||
case STATE_SURF_LEFT :
|
||||
case STATE_SURF_RIGHT :
|
||||
case STATE_SURF_RIGHT :
|
||||
speed = min(speed + 30.0f * LARA_WATER_ACCEL * Core::deltaTime, LARA_SURF_SPEED);
|
||||
break;
|
||||
default :
|
||||
@@ -1817,7 +1818,7 @@ struct Lara : Character {
|
||||
|
||||
if (velocity.length() >= 1.0f)
|
||||
move();
|
||||
|
||||
|
||||
if (getEntity().type != TR::Entity::LARA) {
|
||||
TR::Entity &e = getEntity();
|
||||
vec3 &p = getPos();
|
||||
@@ -1827,9 +1828,9 @@ struct Lara : Character {
|
||||
checkRoom();
|
||||
updateEntity();
|
||||
}
|
||||
|
||||
|
||||
if (braid)
|
||||
braid->update();
|
||||
braid->update();
|
||||
}
|
||||
|
||||
virtual vec3& getPos() {
|
||||
@@ -1839,7 +1840,7 @@ struct Lara : Character {
|
||||
void move() {
|
||||
//TR::Entity &e = getEntity();
|
||||
//TR::Level::FloorInfo info;
|
||||
|
||||
|
||||
//float f, c;
|
||||
//bool canPassGap = true;
|
||||
/*
|
||||
@@ -1899,7 +1900,7 @@ struct Lara : Character {
|
||||
}
|
||||
|
||||
if (stand == STAND_HANG && collision.side != Collision::FRONT) {
|
||||
offset.x = offset.z = 0.0f;
|
||||
offset.x = offset.z = 0.0f;
|
||||
minHeight = LARA_HANG_OFFSET;
|
||||
maxDescent = 0xFFFFFF;
|
||||
maxAscent = -LARA_HANG_OFFSET;
|
||||
@@ -1932,10 +1933,10 @@ struct Lara : Character {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check entities in the room
|
||||
if (canPassGap)
|
||||
for (int i = 0; i < level->entitiesCount; i++)
|
||||
for (int i = 0; i < level->entitiesCount; i++)
|
||||
if (i != entity && level->entities[i].room == e.room && level->entities[i].controller) {
|
||||
Box mBox = ((Controller*)level->entities[i].controller)->getBoundingBox();
|
||||
if (eBox.intersect(mBox)) {
|
||||
@@ -1951,7 +1952,7 @@ struct Lara : Character {
|
||||
if (state == STATE_WALK) rightStart = 13;
|
||||
if (state == STATE_BACK) rightStart = 28;
|
||||
bool isLeftFoot = animation.frameIndex < rightStart || animation.frameIndex > (rightStart + animation.framesCount / 2);
|
||||
|
||||
|
||||
|
||||
if (stand == STAND_UNDERWATER) {
|
||||
if (collision.side == Collision::TOP)
|
||||
@@ -1963,7 +1964,7 @@ struct Lara : Character {
|
||||
if (stand == STAND_AIR && collision.side == Collision::TOP && velocity.y < 0.0f)
|
||||
velocity.y = 30.0f;
|
||||
|
||||
if (collision.side == Collision::FRONT) {
|
||||
if (collision.side == Collision::FRONT) {
|
||||
int floor = collision.info[Collision::FRONT].floor;
|
||||
|
||||
// hit the wall
|
||||
@@ -1997,7 +1998,7 @@ struct Lara : Character {
|
||||
pos.y = opos.y;
|
||||
break;
|
||||
default : ;// no smash animation
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stand == STAND_GROUND) {
|
||||
int floor = collision.info[Collision::NONE].floor;
|
||||
|
67
src/level.h
67
src/level.h
@@ -330,7 +330,7 @@ struct Level : IGame {
|
||||
}
|
||||
|
||||
void initReflections() {
|
||||
Core::resetStates();
|
||||
Core::beginFrame();
|
||||
for (int i = 0; i < level.entitiesBaseCount; i++) {
|
||||
TR::Entity &e = level.entities[i];
|
||||
if (e.type == TR::Entity::CRYSTAL) {
|
||||
@@ -338,6 +338,7 @@ struct Level : IGame {
|
||||
renderEnvironment(c->getRoomIndex(), c->pos - vec3(0, 512, 0), &c->environment);
|
||||
}
|
||||
}
|
||||
Core::endFrame();
|
||||
}
|
||||
|
||||
void setRoomParams(int roomIndex, Shader::Type type, float diffuse, float ambient, float specular, float alpha, bool alphaTest = false) {
|
||||
@@ -523,7 +524,7 @@ struct Level : IGame {
|
||||
vec3 pos = controller->getPos();
|
||||
if (Core::settings.ambient) {
|
||||
AmbientCache::Cube cube;
|
||||
if (Core::frameIndex != controller->frameIndex) {
|
||||
if (Core::stats.frame != controller->frameIndex) {
|
||||
ambientCache->getAmbient(entity.room, pos, cube);
|
||||
if (cube.status == AmbientCache::Cube::READY)
|
||||
memcpy(controller->ambient, cube.colors, sizeof(cube.colors)); // store last calculated ambient into controller
|
||||
@@ -642,6 +643,29 @@ struct Level : IGame {
|
||||
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
|
||||
}
|
||||
|
||||
|
||||
mat4 calcCromMatrix(const mat4 &lightViewProj, const Box *boxes, int count) {
|
||||
mat4 cameraViewProjInv = (mat4(camera->fov, float(Core::width) / Core::height, 512.0f, 4096.0f) * camera->mViewInv.inverse()).inverse();
|
||||
Box frustumBox = Box(vec3(-1.0f), vec3(1.0f)) * cameraViewProjInv;
|
||||
|
||||
Box casterBox(vec3(+INF), vec3(-INF));
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
casterBox += boxes[i] * lightViewProj;
|
||||
|
||||
casterBox -= frustumBox * lightViewProj;
|
||||
|
||||
vec3 scale = vec3(2.0f, 2.0f, 1.0f) / casterBox.size();
|
||||
vec3 center = casterBox.center();
|
||||
vec3 offset = vec3(center.x, center.y, casterBox.min.z) * scale;
|
||||
|
||||
return mat4(scale.x, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, scale.y, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, scale.z, 0.0f,
|
||||
-offset.x, -offset.y, -offset.z, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
bool setupLightCamera() {
|
||||
vec3 pos = lara->getPos();
|
||||
|
||||
@@ -654,12 +678,32 @@ struct Level : IGame {
|
||||
vec3 shadowLightPos = vec3(float(light.x), float(light.y), float(light.z));
|
||||
Core::mViewInv = mat4(shadowLightPos, pos - vec3(0, 256, 0), vec3(0, -1, 0));
|
||||
Core::mView = Core::mViewInv.inverse();
|
||||
Core::mProj = mat4(120, 1.0f, camera->znear, camera->zfar);
|
||||
Core::mProj = mat4(120.0f, 1.0f, camera->znear, camera->zfar);
|
||||
|
||||
mat4 bias;
|
||||
bias.identity();
|
||||
bias.e03 = bias.e13 = bias.e23 = bias.e00 = bias.e11 = bias.e22 = 0.5f;
|
||||
Core::mLightProj = bias * Core::mProj * Core::mView;
|
||||
/*
|
||||
Box boxes[32];
|
||||
int bCount = 0;
|
||||
|
||||
float rq = light.radius * light.radius;
|
||||
for (int i = 0; i < level.entitiesCount; i++) {
|
||||
TR::Entity &e = level.entities[i];
|
||||
Controller *controller = (Controller*)e.controller;
|
||||
if (controller && TR::castShadow(e.type) && rq > (shadowLightPos - controller->pos).length2())
|
||||
boxes[bCount++] = controller->getBoundingBox();
|
||||
}
|
||||
*/
|
||||
/*
|
||||
vec3 shadowBox(1024.0f, 0.0f, 1024.0f);
|
||||
boxes[0] = lara->getBoundingBox();
|
||||
boxes[0] += Box(lara->pos - shadowBox, lara->pos + shadowBox);
|
||||
bCount++;
|
||||
Core::mProj = calcCromMatrix(Core::mProj * Core::mView, &boxes[0], bCount) * Core::mProj;
|
||||
*/
|
||||
|
||||
Core::mLightProj = bias * (Core::mProj * Core::mView);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -672,7 +716,8 @@ struct Level : IGame {
|
||||
bool colorShadow = shadow->format == Texture::Format::RGBA ? true : false;
|
||||
if (colorShadow)
|
||||
Core::setClearColor(vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
Core::setTarget(shadow, true);
|
||||
Core::setTarget(shadow);
|
||||
Core::clear(true, true);
|
||||
Core::setCulling(cfBack);
|
||||
renderScene(roomIndex);
|
||||
Core::invalidateTarget(!colorShadow, colorShadow);
|
||||
@@ -686,7 +731,6 @@ struct Level : IGame {
|
||||
params->clipHeight = NO_CLIP_PLANE;
|
||||
params->clipSign = 1.0f;
|
||||
params->waterHeight = params->clipHeight;
|
||||
Core::resetStates();
|
||||
|
||||
if (ambientCache)
|
||||
ambientCache->precessQueue();
|
||||
@@ -695,7 +739,8 @@ struct Level : IGame {
|
||||
if (shadow)
|
||||
renderShadows(lara->getRoomIndex());
|
||||
|
||||
Core::setTarget(NULL, true);
|
||||
Core::setTarget(NULL);
|
||||
Core::clear(true, true);
|
||||
Core::setViewport(0, 0, Core::width, Core::height);
|
||||
|
||||
if (waterCache)
|
||||
@@ -789,10 +834,10 @@ struct Level : IGame {
|
||||
glLoadIdentity();
|
||||
glOrtho(0, Core::width, 0, Core::height, 0, 1);
|
||||
|
||||
if (waterCache->count)
|
||||
waterCache->refract->bind(sDiffuse);
|
||||
else
|
||||
atlas->bind(sDiffuse);
|
||||
// if (waterCache->count)
|
||||
// waterCache->refract->bind(sDiffuse);
|
||||
// else
|
||||
shadow->bind(sDiffuse);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
@@ -33,7 +33,7 @@ void sndInit() {
|
||||
.rate = 44100,
|
||||
.channels = 2
|
||||
};
|
||||
|
||||
|
||||
static const pa_buffer_attr attr = {
|
||||
.maxlength = SND_DATA_SIZE * 2,
|
||||
.tlength = 0xFFFFFFFF,
|
||||
@@ -44,20 +44,20 @@ void sndInit() {
|
||||
|
||||
pthread_mutex_init(&sndMutex, NULL);
|
||||
|
||||
int error;
|
||||
int error;
|
||||
if (!(sndOut = pa_simple_new(NULL, WND_TITLE, PA_STREAM_PLAYBACK, NULL, "game", &spec, NULL, &attr, &error))) {
|
||||
LOG("pa_simple_new() failed: %s\n", pa_strerror(error));
|
||||
sndData = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
sndData = new Sound::Frame[SND_DATA_SIZE / SND_FRAME_SIZE];
|
||||
pthread_create(&sndThread, NULL, sndFill, NULL);
|
||||
|
||||
sndData = new Sound::Frame[SND_DATA_SIZE / SND_FRAME_SIZE];
|
||||
pthread_create(&sndThread, NULL, sndFill, NULL);
|
||||
}
|
||||
|
||||
void sndFree() {
|
||||
if (sndOut) {
|
||||
pthread_cancel(sndThread);
|
||||
pthread_cancel(sndThread);
|
||||
pthread_mutex_lock(&sndMutex);
|
||||
// pa_simple_flush(sndOut, NULL);
|
||||
// pa_simple_free(sndOut);
|
||||
@@ -102,7 +102,7 @@ void WndProc(const XEvent &e) {
|
||||
Core::width = e.xconfigure.width;
|
||||
Core::height = e.xconfigure.height;
|
||||
break;
|
||||
case KeyPress :
|
||||
case KeyPress :
|
||||
case KeyRelease :
|
||||
if (e.type == KeyPress && (e.xkey.state & Mod1Mask) && e.xkey.keycode == 36) {
|
||||
// TODO: windowed <-> fullscreen switch
|
||||
@@ -120,10 +120,15 @@ void WndProc(const XEvent &e) {
|
||||
case MotionNotify :
|
||||
Input::setPos(ikMouseL, vec2((float)e.xmotion.x, (float)e.xmotion.y));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char Stream::cacheDir[255];
|
||||
char Stream::contentDir[255];
|
||||
|
||||
int main() {
|
||||
Stream::contentDir[0] = Stream::cacheDir[0] = 0;
|
||||
|
||||
static int XGLAttr[] = {
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
@@ -142,8 +147,8 @@ int main() {
|
||||
ButtonMotionMask | PointerMotionMask;
|
||||
|
||||
Window wnd = XCreateWindow(dpy, RootWindow(dpy, vis->screen),
|
||||
0, 0, 1280, 720, 0,
|
||||
vis->depth, InputOutput, vis->visual,
|
||||
0, 0, 1280, 720, 0,
|
||||
vis->depth, InputOutput, vis->visual,
|
||||
CWColormap | CWBorderPixel | CWEventMask, &attr);
|
||||
XStoreName(dpy, wnd, WND_TITLE);
|
||||
|
||||
@@ -156,9 +161,9 @@ int main() {
|
||||
|
||||
sndInit();
|
||||
Game::init();
|
||||
|
||||
int lastTime = getTime(), fpsTime = lastTime + 1000, fps = 0;
|
||||
|
||||
|
||||
int lastTime = getTime();
|
||||
|
||||
while (1) {
|
||||
if (XPending(dpy)) {
|
||||
XEvent event;
|
||||
@@ -181,20 +186,11 @@ int main() {
|
||||
pthread_mutex_unlock(&sndMutex);
|
||||
lastTime = time;
|
||||
|
||||
Core::stats.dips = 0;
|
||||
Core::stats.tris = 0;
|
||||
Game::render();
|
||||
glXSwapBuffers(dpy, wnd);
|
||||
|
||||
if (fpsTime < getTime()) {
|
||||
LOG("FPS: %d DIP: %d TRI: %d\n", fps, Core::stats.dips, Core::stats.tris);
|
||||
fps = 0;
|
||||
fpsTime = getTime() + 1000;
|
||||
} else
|
||||
fps++;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
sndFree();
|
||||
Game::free();
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "game.h"
|
||||
|
||||
int lastTime, fpsTime, fps;
|
||||
int lastTime;
|
||||
EGLDisplay display;
|
||||
EGLSurface surface;
|
||||
EGLContext context;
|
||||
@@ -23,7 +23,7 @@ extern "C" {
|
||||
}
|
||||
|
||||
InputKey joyToInputKey(int code) {
|
||||
static const int codes[] = { 0, 1, 2, 3, 4, 5, 10, 11, 8, 9, 6, 7 };
|
||||
static const int codes[] = { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 6, 7 };
|
||||
|
||||
for (int i = 0; i < sizeof(codes) / sizeof(codes[0]); i++)
|
||||
if (codes[i] == code)
|
||||
@@ -63,9 +63,13 @@ void joyUpdate() {
|
||||
int count = emscripten_get_num_gamepads();
|
||||
if (count <= 0)
|
||||
return;
|
||||
|
||||
|
||||
EmscriptenGamepadEvent state;
|
||||
if (emscripten_get_gamepad_status(0, &state) != EMSCRIPTEN_RESULT_SUCCESS)
|
||||
for (int i = 0; i < count; i++)
|
||||
if (emscripten_get_gamepad_status(i, &state) == EMSCRIPTEN_RESULT_SUCCESS && state.numButtons >= 12)
|
||||
break;
|
||||
|
||||
if (state.numButtons < 12)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < max(state.numButtons, 12); i++) {
|
||||
@@ -101,17 +105,8 @@ void main_loop() {
|
||||
}
|
||||
lastTime = time;
|
||||
|
||||
Core::stats.dips = 0;
|
||||
Core::stats.tris = 0;
|
||||
Game::render();
|
||||
eglSwapBuffers(display, surface);
|
||||
|
||||
if (fpsTime < getTime()) {
|
||||
LOG("FPS: %d DIP: %d TRI: %d\n", fps, Core::stats.dips, Core::stats.tris);
|
||||
fps = 0;
|
||||
fpsTime = getTime() + 1000;
|
||||
} else
|
||||
fps++;
|
||||
}
|
||||
|
||||
bool initGL() {
|
||||
@@ -291,8 +286,6 @@ int main() {
|
||||
resize();
|
||||
|
||||
lastTime = getTime();
|
||||
fpsTime = lastTime + 1000;
|
||||
fps = 0;
|
||||
|
||||
emscripten_set_main_loop(main_loop, 0, true);
|
||||
|
||||
|
@@ -13,15 +13,15 @@
|
||||
|
||||
#include "game.h"
|
||||
|
||||
DWORD getTime() {
|
||||
int getTime() {
|
||||
#ifdef DEBUG
|
||||
LARGE_INTEGER Freq, Count;
|
||||
QueryPerformanceFrequency(&Freq);
|
||||
QueryPerformanceCounter(&Count);
|
||||
return (DWORD)(Count.QuadPart * 1000L / Freq.QuadPart);
|
||||
return int(Count.QuadPart * 1000L / Freq.QuadPart);
|
||||
#else
|
||||
timeBeginPeriod(0);
|
||||
return timeGetTime();
|
||||
return int(timeGetTime());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -232,8 +232,8 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
|
||||
break;
|
||||
case WM_KEYDOWN :
|
||||
case WM_KEYUP :
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
case WM_SYSKEYDOWN :
|
||||
case WM_SYSKEYUP :
|
||||
if (msg == WM_SYSKEYDOWN && wParam == VK_RETURN) { // switch to fullscreen or window
|
||||
static WINDOWPLACEMENT pLast;
|
||||
DWORD style = GetWindowLong(hWnd, GWL_STYLE);
|
||||
@@ -262,6 +262,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
|
||||
case WM_MBUTTONDOWN :
|
||||
case WM_MBUTTONUP :
|
||||
case WM_MBUTTONDBLCLK : {
|
||||
if ((GetMessageExtraInfo() & 0xFFFFFF00) == 0xFF515700) break;
|
||||
InputKey key = mouseToInputKey(msg);
|
||||
Input::setPos(key, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam)));
|
||||
bool down = msg != WM_LBUTTONUP && msg != WM_RBUTTONUP && msg != WM_MBUTTONUP;
|
||||
@@ -273,6 +274,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEMOVE :
|
||||
if ((GetMessageExtraInfo() & 0xFFFFFF00) == 0xFF515700) break;
|
||||
Input::setPos(ikMouseL, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam)));
|
||||
break;
|
||||
// joystick
|
||||
@@ -355,7 +357,7 @@ int main(int argc, char** argv) {
|
||||
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&WndProc);
|
||||
ShowWindow(hWnd, SW_SHOWDEFAULT);
|
||||
|
||||
DWORD lastTime = getTime(), fpsTime = lastTime + 1000, fps = 0;
|
||||
DWORD lastTime = getTime();
|
||||
MSG msg;
|
||||
|
||||
do {
|
||||
@@ -379,20 +381,11 @@ int main(int argc, char** argv) {
|
||||
LeaveCriticalSection(&sndCS);
|
||||
lastTime = time;
|
||||
|
||||
Core::stats.dips = 0;
|
||||
Core::stats.tris = 0;
|
||||
Game::render();
|
||||
SwapBuffers(hDC);
|
||||
#ifdef _DEBUG
|
||||
Sleep(20);
|
||||
#endif
|
||||
|
||||
if (fpsTime < getTime()) {
|
||||
LOG("FPS: %d DIP: %d TRI: %d\n", fps, Core::stats.dips, Core::stats.tris);
|
||||
fps = 0;
|
||||
fpsTime = getTime() + 1000;
|
||||
} else
|
||||
fps++;
|
||||
}
|
||||
} while (msg.message != WM_QUIT);
|
||||
|
||||
|
@@ -204,26 +204,28 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SHADOW_TEXEL (1.5 / 1024.0)
|
||||
|
||||
float getShadow(vec4 lightProj) {
|
||||
vec3 p = lightProj.xyz / lightProj.w;
|
||||
|
||||
float rShadow = 0.0;
|
||||
rShadow += SHADOW(p + (vec3(-0.94201624, -0.39906216, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.94558609, -0.76890725, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.09418410, -0.92938870, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.34495938, 0.29387760, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.91588581, 0.45771432, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.81544232, -0.87912464, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.38277543, 0.27676845, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.97484398, 0.75648379, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.44323325, -0.97511554, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.53742981, -0.47373420, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.26496911, -0.41893023, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.79197514, 0.19090188, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.24188840, 0.99706507, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.81409955, 0.91437590, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.19984126, 0.78641367, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.14383161, -0.14100790, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.94201624, -0.39906216, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.94558609, -0.76890725, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.09418410, -0.92938870, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.34495938, 0.29387760, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.91588581, 0.45771432, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.81544232, -0.87912464, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.38277543, 0.27676845, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.97484398, 0.75648379, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.44323325, -0.97511554, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.53742981, -0.47373420, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.26496911, -0.41893023, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.79197514, 0.19090188, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.24188840, 0.99706507, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.81409955, 0.91437590, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.19984126, 0.78641367, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.14383161, -0.14100790, 0.0) * SHADOW_TEXEL));
|
||||
|
||||
rShadow /= 16.0;
|
||||
|
||||
|
78
src/utils.h
78
src/utils.h
@@ -143,16 +143,20 @@ struct vec2 {
|
||||
vec2& operator += (const vec2 &v) { x += v.x; y += v.y; return *this; }
|
||||
vec2& operator -= (const vec2 &v) { x -= v.x; y -= v.y; return *this; }
|
||||
vec2& operator *= (const vec2 &v) { x *= v.x; y *= v.y; return *this; }
|
||||
vec2& operator /= (const vec2 &v) { x /= v.x; y /= v.y; return *this; }
|
||||
vec2& operator += (float s) { x += s; y += s; return *this; }
|
||||
vec2& operator -= (float s) { x -= s; y -= s; return *this; }
|
||||
vec2& operator *= (float s) { x *= s; y *= s; return *this; }
|
||||
vec2& operator /= (float s) { x /= s; y /= s; return *this; }
|
||||
|
||||
vec2 operator + (const vec2 &v) const { return vec2(x + v.x, y + v.y); }
|
||||
vec2 operator - (const vec2 &v) const { return vec2(x - v.x, y - v.y); }
|
||||
vec2 operator * (const vec2 &v) const { return vec2(x * v.x, y * v.y); }
|
||||
vec2 operator / (const vec2 &v) const { return vec2(x / v.x, y / v.y); }
|
||||
vec2 operator + (float s) const { return vec2(x + s, y + s ); }
|
||||
vec2 operator - (float s) const { return vec2(x - s, y - s ); }
|
||||
vec2 operator * (float s) const { return vec2(x * s, y * s ); }
|
||||
vec2 operator / (float s) const { return vec2(x / s, y / s ); }
|
||||
|
||||
float dot(const vec2 &v) const { return x * v.x + y * v.y; }
|
||||
float cross(const vec2 &v) const { return x * v.y - y * v.x; }
|
||||
@@ -164,7 +168,11 @@ struct vec2 {
|
||||
};
|
||||
|
||||
struct vec3 {
|
||||
float x, y, z;
|
||||
union {
|
||||
struct { vec2 xy; };
|
||||
struct { float x, y, z; };
|
||||
};
|
||||
|
||||
vec3() {}
|
||||
vec3(float s) : x(s), y(s), z(s) {}
|
||||
vec3(float x, float y, float z) : x(x), y(y), z(z) {}
|
||||
@@ -182,16 +190,20 @@ struct vec3 {
|
||||
vec3& operator += (const vec3 &v) { x += v.x; y += v.y; z += v.z; return *this; }
|
||||
vec3& operator -= (const vec3 &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
|
||||
vec3& operator *= (const vec3 &v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
|
||||
vec3& operator /= (const vec3 &v) { x /= v.x; y /= v.y; z /= v.z; return *this; }
|
||||
vec3& operator += (float s) { x += s; y += s; z += s; return *this; }
|
||||
vec3& operator -= (float s) { x -= s; y -= s; z -= s; return *this; }
|
||||
vec3& operator *= (float s) { x *= s; y *= s; z *= s; return *this; }
|
||||
vec3& operator /= (float s) { x /= s; y /= s; z /= s; return *this; }
|
||||
|
||||
vec3 operator + (const vec3 &v) const { return vec3(x + v.x, y + v.y, z + v.z); }
|
||||
vec3 operator - (const vec3 &v) const { return vec3(x - v.x, y - v.y, z - v.z); }
|
||||
vec3 operator * (const vec3 &v) const { return vec3(x * v.x, y * v.y, z * v.z); }
|
||||
vec3 operator / (const vec3 &v) const { return vec3(x / v.x, y / v.y, z / v.z); }
|
||||
vec3 operator + (float s) const { return vec3(x + s, y + s, z + s); }
|
||||
vec3 operator - (float s) const { return vec3(x - s, y - s, z - s); }
|
||||
vec3 operator * (float s) const { return vec3(x * s, y * s, z * s); }
|
||||
vec3 operator / (float s) const { return vec3(x / s, y / s, z / s); }
|
||||
|
||||
float dot(const vec3 &v) const { return x * v.x + y * v.y + z * v.z; }
|
||||
vec3 cross(const vec3 &v) const { return vec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); }
|
||||
@@ -219,6 +231,7 @@ struct vec3 {
|
||||
|
||||
struct vec4 {
|
||||
union {
|
||||
struct { vec2 xy; };
|
||||
struct { vec3 xyz; };
|
||||
struct { float x, y, z, w; };
|
||||
};
|
||||
@@ -356,6 +369,15 @@ struct mat4 {
|
||||
|
||||
mat4() {}
|
||||
|
||||
mat4(float e00, float e10, float e20, float e30,
|
||||
float e01, float e11, float e21, float e31,
|
||||
float e02, float e12, float e22, float e32,
|
||||
float e03, float e13, float e23, float e33) :
|
||||
e00(e00), e10(e10), e20(e20), e30(e30),
|
||||
e01(e01), e11(e11), e21(e21), e31(e31),
|
||||
e02(e02), e12(e12), e22(e22), e32(e32),
|
||||
e03(e03), e13(e13), e23(e23), e33(e33) {}
|
||||
|
||||
mat4(const quat &rot, const vec3 &pos) {
|
||||
setRot(rot);
|
||||
setPos(pos);
|
||||
@@ -683,6 +705,60 @@ struct Box {
|
||||
Box() {}
|
||||
Box(const vec3 &min, const vec3 &max) : min(min), max(max) {}
|
||||
|
||||
vec3 operator [] (int index) const {
|
||||
ASSERT(index >= 0 && index <= 7);
|
||||
switch (index) {
|
||||
case 0 : return min;
|
||||
case 1 : return max;
|
||||
case 2 : return vec3(min.x, max.y, max.z);
|
||||
case 3 : return vec3(max.x, min.y, max.z);
|
||||
case 4 : return vec3(min.x, min.y, max.z);
|
||||
case 5 : return vec3(max.x, max.y, min.z);
|
||||
case 6 : return vec3(min.x, max.y, min.z);
|
||||
case 7 : return vec3(max.x, min.y, min.z);
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
Box& operator += (const Box &box) {
|
||||
min.x = ::min(min.x, box.min.x);
|
||||
min.y = ::min(min.y, box.min.y);
|
||||
min.z = ::min(min.z, box.min.z);
|
||||
max.x = ::max(max.x, box.max.x);
|
||||
max.y = ::max(max.y, box.max.y);
|
||||
max.z = ::max(max.z, box.max.z);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Box& operator += (const vec3 &v) {
|
||||
min.x = ::min(min.x, v.x);
|
||||
min.y = ::min(min.y, v.y);
|
||||
min.z = ::min(min.z, v.z);
|
||||
max.x = ::max(max.x, v.x);
|
||||
max.y = ::max(max.y, v.y);
|
||||
max.z = ::max(max.z, v.z);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Box& operator -= (const Box &box) {
|
||||
min.x = ::max(min.x, box.min.x);
|
||||
min.y = ::max(min.y, box.min.y);
|
||||
min.z = ::max(min.z, box.min.z);
|
||||
max.x = ::min(max.x, box.max.x);
|
||||
max.y = ::min(max.y, box.max.y);
|
||||
max.z = ::min(max.z, box.max.z);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Box operator * (const mat4 &m) const {
|
||||
Box res(vec3(+INF), vec3(-INF));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
vec4 v = m * vec4((*this)[i], 1.0f);
|
||||
res += v.xyz /= v.w;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
vec3 center() const {
|
||||
return (min + max) * 0.5f;
|
||||
}
|
||||
|
Reference in New Issue
Block a user