mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-09 14:47:02 +02:00
add simple floor collision
This commit is contained in:
228
src/controller.h
228
src/controller.h
@@ -16,6 +16,9 @@ struct Controller {
|
||||
int state; // LaraState
|
||||
int lastFrame;
|
||||
|
||||
int sc;
|
||||
bool lState;
|
||||
|
||||
Controller(TR::Level *level, int entity) : level(level), entity(entity), pos(0.0f), angle(0.0f), fTime(0.0f) {
|
||||
anim = &level->anims[0];
|
||||
lastFrame = 0;
|
||||
@@ -23,10 +26,14 @@ struct Controller {
|
||||
TR::Entity &e = level->entities[entity];
|
||||
pos = vec3(e.x, e.y, e.z);
|
||||
angle = e.rotation / 16384.0f * PI * 0.5f;
|
||||
|
||||
sc = 0;
|
||||
lState = false;
|
||||
}
|
||||
|
||||
void update() {
|
||||
float rot = 0.0f;
|
||||
|
||||
state = TR::STATE_STOP;
|
||||
if (Input::down[ikShift]) {
|
||||
if (Input::down[ikUp]) { state = TR::STATE_WALK; };
|
||||
@@ -57,10 +64,34 @@ struct Controller {
|
||||
if (Input::down[ikLeft]) { if (!Input::down[ikUp] && !Input::down[ikDown]) state = TR::STATE_TURN_LEFT; rot = -Core::deltaTime * PI; };
|
||||
if (Input::down[ikRight]) { if (!Input::down[ikUp] && !Input::down[ikDown]) state = TR::STATE_TURN_RIGHT; rot = Core::deltaTime * PI; };
|
||||
}
|
||||
|
||||
|
||||
if (Input::down[ikEnter])
|
||||
state = TR::STATE_COMPRESS;
|
||||
if (Input::down[ikEnter]) {
|
||||
if (!lState) {
|
||||
lState = true;
|
||||
// state = TR::STATE_ROLL;
|
||||
// fTime = 0;
|
||||
|
||||
// sc = (sc + 1) % level->statesCount;
|
||||
// anim = &level->anims[146];//level->ranges[ level->states[sc].rangesOffset ].nextAnimation ];
|
||||
// fTime = 0;
|
||||
// state = level->states[sc].state;
|
||||
/*
|
||||
LOG("state: %d\n", anim->state);
|
||||
for (int i = 0; i < anim->scCount; i++) {
|
||||
auto &sc = level->states[anim->scOffset + i];
|
||||
LOG("-> %d : ", (int)sc.state);
|
||||
for (int j = 0; j < sc.rangesCount; j++) {
|
||||
TR::AnimRange &range = level->ranges[sc.rangesOffset + j];
|
||||
LOG("%d ", range.nextAnimation);
|
||||
//range.
|
||||
}
|
||||
LOG("\n");
|
||||
}
|
||||
*/
|
||||
}
|
||||
} else
|
||||
lState = false;
|
||||
|
||||
fTime += Core::deltaTime;
|
||||
int fCount = anim->frameEnd - anim->frameStart + 1;
|
||||
@@ -80,12 +111,13 @@ struct Controller {
|
||||
LOG("\n");
|
||||
}
|
||||
*/
|
||||
|
||||
if (anim->state != state) {
|
||||
for (int i = 0; i < anim->scCount; i++) {
|
||||
auto &sc = level->states[anim->scOffset + i];
|
||||
if (sc.state == state) {
|
||||
for (int j = 0; j < sc.rCount; j++) {
|
||||
auto &range = level->ranges[sc.rangeOffset + j];
|
||||
for (int j = 0; j < sc.rangesCount; j++) {
|
||||
auto &range = level->ranges[sc.rangesOffset + j];
|
||||
if ( anim->frameStart + fIndex >= range.low && anim->frameStart + fIndex <= range.high) {
|
||||
int st = anim->state;
|
||||
anim = &level->anims[range.nextAnimation];
|
||||
@@ -103,26 +135,21 @@ struct Controller {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (fIndex >= fCount) {
|
||||
fIndex = anim->nextFrame;
|
||||
int id = anim->nextAnimation;
|
||||
anim = &level->anims[anim->nextAnimation];
|
||||
// LOG("nxt anim %d %f %f %d %d\n", id, anim->accel.toFloat(), anim->speed.toFloat(), anim->frameRate, anim->frameEnd - anim->frameStart + 1);
|
||||
|
||||
// LOG("from %f to %f\n", s, s + a * c / 30.0f);
|
||||
|
||||
fIndex -= anim->frameStart;
|
||||
// LOG("frame: %d\n", fIndex);
|
||||
fTime = (fIndex) / 30.0f;
|
||||
//fCount = anim->frameEnd - anim->frameStart + 1;
|
||||
//LOG("reset\n");
|
||||
}
|
||||
|
||||
if (anim->state == state) {
|
||||
angle += rot;
|
||||
}
|
||||
|
||||
float d = 0.0f;
|
||||
|
||||
int16 *ptr = &level->commands[anim->animCommand];
|
||||
|
||||
for (int i = 0; i < anim->acCount; i++) {
|
||||
@@ -154,19 +181,21 @@ struct Controller {
|
||||
|
||||
void *p = &level->soundData[c];
|
||||
|
||||
PlaySound((LPSTR)p, NULL, SND_ASYNC | SND_MEMORY);
|
||||
//PlaySound((LPSTR)p, NULL, SND_ASYNC | SND_MEMORY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x06 :
|
||||
if (fIndex != lastFrame && fIndex + anim->frameStart == ptr[0]) {
|
||||
if (ptr[1] == 0) {
|
||||
angle = angle + PI;
|
||||
}
|
||||
}
|
||||
ptr += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float d = 0.0f;
|
||||
|
||||
switch (anim->state) {
|
||||
case TR::STATE_BACK :
|
||||
case TR::STATE_BACK_JUMP :
|
||||
@@ -184,17 +213,14 @@ struct Controller {
|
||||
}
|
||||
d += angle;
|
||||
|
||||
float speed = anim->speed.toFloat() + anim->accel.toFloat() * (fTime * 30.0f);
|
||||
pos = pos + vec3(sinf(d), 0, cosf(d)) * (speed * Core::deltaTime * 30.0f);
|
||||
float speed = anim->speed.toFloat() + anim->accel.toFloat() * (fTime * 30.0f);
|
||||
|
||||
move(vec3(sinf(d), 0, cosf(d)) * (speed * Core::deltaTime * 30.0f));
|
||||
collide();
|
||||
|
||||
lastFrame = fIndex;
|
||||
|
||||
TR::Entity &e = level->entities[entity];
|
||||
|
||||
e.x = int(pos.x);
|
||||
e.y = int(pos.y);
|
||||
e.z = int(pos.z);
|
||||
e.rotation = int(angle / (PI * 0.5f) * 16384.0f);
|
||||
|
||||
updateEntity();
|
||||
|
||||
/*
|
||||
TR::Room &room = level->rooms[level->entities[entity].room];
|
||||
@@ -216,6 +242,61 @@ struct Controller {
|
||||
*/
|
||||
}
|
||||
|
||||
void checkPortals(const vec3 &oldPos, const vec3 &newPos) {
|
||||
TR::Room &room = getRoom();
|
||||
|
||||
TR::Vertex a = { (int)oldPos.x - room.info.x, (int)oldPos.y, (int)oldPos.z - room.info.z };
|
||||
TR::Vertex b = { (int)newPos.x - room.info.x, (int)newPos.y, (int)newPos.z - room.info.z };
|
||||
|
||||
for (int i = 0; i < room.portalsCount; i++) {
|
||||
TR::Vertex &n = room.portals[i].normal;
|
||||
TR::Vertex &v = room.portals[i].vertices[0];
|
||||
int d = -(v.x * n.x + v.y * n.y + v.z * n.z);
|
||||
int oldSign = sign(a.x * n.x + a.y * n.y + a.z * n.z + d);
|
||||
int newSign = sign(b.x * n.x + b.y * n.y + b.z * n.z + d);
|
||||
if (oldSign != newSign) {
|
||||
getEntity().room = room.portals[i].roomIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void move(const vec3 &speed) {
|
||||
vec3 p = pos;
|
||||
pos = pos + speed;
|
||||
|
||||
checkPortals(p, pos);
|
||||
|
||||
updateEntity();
|
||||
|
||||
TR::Room &room = getRoom();
|
||||
TR::Entity &entity = getEntity();
|
||||
|
||||
int dx, dz;
|
||||
TR::Room::Sector &s = getSector(dx, dz);
|
||||
|
||||
int d = entity.y - s.floor * 256;
|
||||
if (d >= 256 * 4) {
|
||||
pos = p;//vec3(entity.x, entity.y, entity.z);
|
||||
updateEntity();
|
||||
state = TR::STATE_STOP;
|
||||
if (d >= 256 * 4)
|
||||
anim = &level->anims[53]; // forward smash
|
||||
else
|
||||
anim = &level->anims[11]; // instant stand
|
||||
fTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void updateEntity() {
|
||||
TR::Entity &e = getEntity();
|
||||
e.x = int(pos.x);
|
||||
e.y = int(pos.y);
|
||||
e.z = int(pos.z);
|
||||
e.rotation = int(angle / (PI * 0.5f) * 16384.0f);
|
||||
}
|
||||
|
||||
bool insideRoom(const vec3 &pos, int room) {
|
||||
TR::Room &r = level->rooms[room];
|
||||
vec3 min = vec3(r.info.x, r.info.yTop, r.info.z);
|
||||
@@ -226,6 +307,103 @@ struct Controller {
|
||||
pos.z >= min.z && pos.z <= max.z;
|
||||
}
|
||||
|
||||
TR::Entity& getEntity() {
|
||||
return level->entities[entity];
|
||||
}
|
||||
|
||||
TR::Room& getRoom() {
|
||||
return level->rooms[getEntity().room];
|
||||
}
|
||||
|
||||
TR::Room::Sector& getSector(int &dx, int &dz) {
|
||||
TR::Room &room = getRoom();
|
||||
TR::Entity &entity = getEntity();
|
||||
|
||||
dx = entity.x - room.info.x;
|
||||
dz = entity.z - room.info.z;
|
||||
int sx = dx / 1024;
|
||||
int sz = dz / 1024;
|
||||
dx -= sx * 1024;
|
||||
dz -= sz * 1024;
|
||||
|
||||
return room.sectors[sx * room.zSectors + sz];
|
||||
}
|
||||
|
||||
void collide() {
|
||||
int dx, dz;
|
||||
TR::Room::Sector &s = getSector(dx, dz);
|
||||
TR::Entity &entity = getEntity();
|
||||
|
||||
float bottom = s.floor * 256;
|
||||
|
||||
float fx = dx / 1024.0f, fz = dz / 1024.0f;
|
||||
|
||||
// dx -= 512;
|
||||
// dz -= 512;
|
||||
|
||||
uint16 *d = &level->floors[s.floorIndex];
|
||||
auto cmd = *d;
|
||||
|
||||
do {
|
||||
cmd = *d;
|
||||
int func = cmd & 0x001F; // function
|
||||
int sub = (cmd & 0x7F00) >> 8; // sub function
|
||||
d++;
|
||||
|
||||
|
||||
if (func == 0x00) { // portal
|
||||
LOG("portal\n");
|
||||
// d++;
|
||||
}
|
||||
|
||||
if ((func == 0x02 || func == 0x03) && sub == 0x00) { // floor & ceiling heights
|
||||
int sx = (int)(int8)(*d & 0x00FF);
|
||||
int sz = (int)(int8)((*d & 0xFF00) >> 8);
|
||||
|
||||
if (func == 0x02) {
|
||||
if (sx > 0)
|
||||
bottom += sx * (1024 - dx) >> 2;
|
||||
else
|
||||
bottom -= sx * dx >> 2;
|
||||
|
||||
if (sz > 0)
|
||||
bottom += sz * (1024 - dz) >> 2;
|
||||
else
|
||||
bottom -= sz * dz >> 2;
|
||||
} else {
|
||||
/*
|
||||
if (sx < 0) {
|
||||
p[0].y += sx;
|
||||
p[3].y += sx;
|
||||
} else {
|
||||
p[1].y -= sx;
|
||||
p[2].y -= sx;
|
||||
}
|
||||
|
||||
if (sz > 0) {
|
||||
p[0].y -= sz;
|
||||
p[1].y -= sz;
|
||||
} else {
|
||||
p[3].y += sz;
|
||||
p[2].y += sz;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// d++;
|
||||
}
|
||||
|
||||
d++;
|
||||
|
||||
|
||||
// LOG("%d %d\n", func, sub);
|
||||
} while ((cmd & 0x8000) == 0); // end
|
||||
|
||||
pos.y = bottom;
|
||||
|
||||
entity.y = (int)pos.y;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -50,10 +50,16 @@ namespace Core {
|
||||
int width, height;
|
||||
float deltaTime;
|
||||
mat4 mView, mProj, mViewProj, mModel;
|
||||
vec3 viewPos;
|
||||
vec3 lightPos;
|
||||
vec4 lightColor;
|
||||
vec3 ambient;
|
||||
vec4 color;
|
||||
|
||||
struct {
|
||||
int dips;
|
||||
int tris;
|
||||
} stats;
|
||||
}
|
||||
|
||||
#include "texture.h"
|
||||
|
14
src/format.h
14
src/format.h
@@ -4,6 +4,12 @@
|
||||
#include "utils.h"
|
||||
|
||||
namespace TR {
|
||||
#define ENTITY_FLAG_CLEAR 0x0080
|
||||
#define ENTITY_FLAG_VISIBLE 0x0100
|
||||
#define ENTITY_FLAG_MASK 0x3E00
|
||||
|
||||
|
||||
|
||||
#define ENTITY_LARA 0
|
||||
|
||||
#define ENTITY_ENEMY_TWIN 6
|
||||
@@ -70,7 +76,7 @@ namespace TR {
|
||||
STATE_FAST_TURN_20,
|
||||
STATE_STEP_RIGHT,
|
||||
STATE_STEP_LEFT,
|
||||
STATE_ROLL_23,
|
||||
STATE_ROLL,
|
||||
STATE_SLIDE,
|
||||
STATE_BACK_JUMP,
|
||||
STATE_RIGHT_JUMP,
|
||||
@@ -101,7 +107,7 @@ namespace TR {
|
||||
STATE_NULL_51,
|
||||
STATE_SWAN_DIVE,
|
||||
STATE_FAST_DIVE,
|
||||
STATE_NULL_54,
|
||||
STATE_HANDSTAND,
|
||||
STATE_WATER_OUT,
|
||||
STATE_CLIMB_START_AND_STANDING,
|
||||
STATE_CLIMB_UP,
|
||||
@@ -288,8 +294,8 @@ namespace TR {
|
||||
|
||||
struct AnimState {
|
||||
uint16 state;
|
||||
uint16 rCount; // number of ranges
|
||||
uint16 rangeOffset; // Offset into animRanges[]
|
||||
uint16 rangesCount; // number of ranges
|
||||
uint16 rangesOffset; // Offset into animRanges[]
|
||||
};
|
||||
|
||||
struct AnimRange {
|
||||
|
72
src/game.h
72
src/game.h
@@ -5,61 +5,12 @@
|
||||
#include "format.h"
|
||||
#include "level.h"
|
||||
|
||||
struct Camera {
|
||||
float fov, znear, zfar;
|
||||
vec3 pos, angle;
|
||||
|
||||
void update() {
|
||||
vec3 dir = vec3(sinf(angle.y - PI) * cosf(-angle.x), -sinf(-angle.x), cosf(angle.y - PI) * cosf(-angle.x));
|
||||
vec3 v = vec3(0);
|
||||
|
||||
if (Input::down[ikW]) v = v + dir;
|
||||
if (Input::down[ikS]) v = v - dir;
|
||||
if (Input::down[ikD]) v = v + dir.cross(vec3(0, 1, 0));
|
||||
if (Input::down[ikA]) v = v - dir.cross(vec3(0, 1, 0));
|
||||
|
||||
pos = pos + v.normal() * (Core::deltaTime * 2048.0f);
|
||||
|
||||
if (Input::down[ikMouseL]) {
|
||||
vec2 delta = Input::mouse.pos - Input::mouse.start.L;
|
||||
angle.x -= delta.y * 0.01f;
|
||||
angle.y -= delta.x * 0.01f;
|
||||
angle.x = min(max(angle.x, -PI * 0.5f + EPS), PI * 0.5f - EPS);
|
||||
Input::mouse.start.L = Input::mouse.pos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Core::mView.identity();
|
||||
Core::mView.rotateZ(-angle.z);
|
||||
Core::mView.rotateX(-angle.x);
|
||||
Core::mView.rotateY(-angle.y);
|
||||
Core::mView.translate(vec3(-pos.x, -pos.y, -pos.z));
|
||||
|
||||
Core::mProj = mat4(fov, (float)Core::width / (float)Core::height, znear, zfar);
|
||||
|
||||
Core::mViewProj = Core::mProj * Core::mView;
|
||||
}
|
||||
};
|
||||
|
||||
namespace Game {
|
||||
Level *level;
|
||||
Camera camera;
|
||||
|
||||
void init() {
|
||||
Core::init();
|
||||
|
||||
// Stream stream("GYM.PHD");
|
||||
level = new Level("data\\LEVEL3A.PHD");
|
||||
|
||||
camera.fov = 90.0f;
|
||||
camera.znear = 0.1f * 2048.0f;
|
||||
camera.zfar = 1000.0f * 2048.0f;
|
||||
// camera.pos = vec3(-10, -2, 26);
|
||||
camera.pos = vec3(-13.25f, 0.42f, 38.06f) * 2048.0f;
|
||||
// camera.pos = vec3(-36, -1, 2);
|
||||
camera.angle = vec3(0);
|
||||
level = new Level("data\\LEVEL1.PHD");
|
||||
}
|
||||
|
||||
void free() {
|
||||
@@ -69,8 +20,6 @@ namespace Game {
|
||||
}
|
||||
|
||||
void update() {
|
||||
camera.update();
|
||||
|
||||
level->update();
|
||||
}
|
||||
|
||||
@@ -79,27 +28,8 @@ namespace Game {
|
||||
Core::setViewport(0, 0, Core::width, Core::height);
|
||||
Core::setBlending(bmAlpha);
|
||||
|
||||
camera.setup();
|
||||
level->render();
|
||||
}
|
||||
|
||||
/*
|
||||
void input(InputKey key, InputState state) {
|
||||
static vec2 mLast;
|
||||
if (state == isDown && key == ikMouseL) {
|
||||
mLast = Input::mouse.pos;
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == isMove && key == ikMouse && (Input::mouse.L.down || Input::mouse.R.down)) {
|
||||
vec2 delta = Input::mouse.pos - mLast;
|
||||
camera.angle.x -= delta.y * 0.01f;
|
||||
camera.angle.y -= delta.x * 0.01f;
|
||||
camera.angle.x = _min(_max(camera.angle.x, -PI * 0.5f + EPS), PI * 0.5f - EPS);
|
||||
mLast = Input::mouse.pos;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#endif
|
245
src/level.h
245
src/level.h
@@ -5,62 +5,12 @@
|
||||
#include "utils.h"
|
||||
#include "format.h"
|
||||
#include "controller.h"
|
||||
#include "camera.h"
|
||||
#include "debug.h"
|
||||
|
||||
const char SHADER[] = \
|
||||
"varying vec3 vLightVec;\n"\
|
||||
"varying vec2 vTexCoord;\n"\
|
||||
"varying vec4 vNormal;\n"\
|
||||
"varying vec4 vColor;\n"\
|
||||
\
|
||||
"#ifdef VERTEX\n"\
|
||||
" uniform mat4 uViewProj;\n"\
|
||||
" uniform mat4 uModel;\n"\
|
||||
" uniform vec3 uLightPos;\n"\
|
||||
\
|
||||
" attribute vec3 aCoord;\n"\
|
||||
" attribute vec2 aTexCoord;\n"\
|
||||
" attribute vec4 aNormal;\n"\
|
||||
" attribute vec4 aColor;\n"\
|
||||
\
|
||||
" void main() {\n"\
|
||||
" vec4 coord = uModel * vec4(aCoord, 1.0);\n"\
|
||||
" vLightVec = uLightPos - coord.xyz;\n"\
|
||||
" vTexCoord = aTexCoord + vec2(0.5/1024.0);\n"\
|
||||
" vNormal = vec4(mat3(uModel[0].xyz, uModel[1].xyz, uModel[2].xyz) * (aNormal.xyz * 2.0 - 1.0), aNormal.w);\n"\
|
||||
" vColor = aColor;\n"\
|
||||
" gl_Position = uViewProj * coord;\n"\
|
||||
" }\n"\
|
||||
"#else\n"\
|
||||
" uniform sampler2D sDiffuse;\n"\
|
||||
" uniform vec4 uColor;\n"\
|
||||
" uniform vec3 uAmbient;\n"\
|
||||
" uniform vec4 uLightColor;\n"\
|
||||
\
|
||||
" void main() {\n"\
|
||||
" vec4 color = texture2D(sDiffuse, vTexCoord) * vColor * uColor;\n"\
|
||||
" color.xyz = pow(color.xyz, vec3(2.2));\n"\
|
||||
" vec3 light = uLightColor.xyz * max(vNormal.w, dot(normalize(vNormal.xyz), normalize(vLightVec)));\n"\
|
||||
" light += uAmbient;\n"\
|
||||
" color.xyz *= light;\n"\
|
||||
" color.xyz = pow(color.xyz, vec3(1.0/2.2));\n"\
|
||||
" //color.xyz = normalize(vLightVec) * 0.5 + 0.5;\n"\
|
||||
" gl_FragColor = color;\n"\
|
||||
" }\n"\
|
||||
"#endif";
|
||||
|
||||
|
||||
ubyte4 packNormal(const TR::Vertex &n) {
|
||||
vec3 vn = (vec3(n.x, n.y, n.z).normal() * 0.5f + vec3(0.5f)) * 255.0f;
|
||||
ubyte4 v;
|
||||
// v.x = (int)n.x * 255 / (2 * 16300) + 127;
|
||||
// v.y = (int)n.y * 255 / (2 * 16300) + 127;
|
||||
// v.z = (int)n.z * 255 / (2 * 16300) + 127;
|
||||
v.x = (int)vn.x;
|
||||
v.y = (int)vn.y;
|
||||
v.z = (int)vn.z;
|
||||
v.w = 0;
|
||||
return v;
|
||||
}
|
||||
const char SHADER[] =
|
||||
#include "shader.glsl"
|
||||
;
|
||||
|
||||
struct Level {
|
||||
TR::Level level;
|
||||
@@ -74,6 +24,9 @@ struct Level {
|
||||
|
||||
MeshRange *rangeRooms;
|
||||
|
||||
Camera camera;
|
||||
|
||||
|
||||
int mCount;
|
||||
struct MeshInfo : MeshRange {
|
||||
int offset;
|
||||
@@ -94,6 +47,15 @@ struct Level {
|
||||
}
|
||||
|
||||
lara = new Controller(&level, entity);
|
||||
|
||||
camera.fov = 90.0f;
|
||||
camera.znear = 0.1f * 2048.0f;
|
||||
camera.zfar = 1000.0f * 2048.0f;
|
||||
camera.pos = vec3(-lara->pos.x, -lara->pos.y, lara->pos.z) + vec3(0, 1024, -512);
|
||||
// camera.pos = vec3(-10, -2, 26);
|
||||
// camera.pos = vec3(-13.25f, 0.42f, 38.06f) * 2048.0f;
|
||||
// camera.pos = vec3(-36, -1, 2);
|
||||
camera.angle = vec3(0, PI, 0);
|
||||
}
|
||||
|
||||
~Level() {
|
||||
@@ -226,8 +188,8 @@ struct Level {
|
||||
|
||||
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z };
|
||||
vertices[vCount].color = { a, a, a, 255 };
|
||||
vertices[vCount].normal = { 0, 0, 0, 255 };
|
||||
vertices[vCount].texCoord = { (tx + t.vertices[k].Xpixel) << 5, (ty + t.vertices[k].Ypixel) << 5 };
|
||||
vertices[vCount].normal = { 0, 0, 0, 0x7FFF };
|
||||
vertices[vCount].texCoord = { ((tx + t.vertices[k].Xpixel) << 5) + 16, ((ty + t.vertices[k].Ypixel) << 5) + 16};
|
||||
vCount++;
|
||||
}
|
||||
}
|
||||
@@ -254,8 +216,8 @@ struct Level {
|
||||
|
||||
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z };
|
||||
vertices[vCount].color = { a, a, a, 255 };
|
||||
vertices[vCount].normal = { 0, 0, 0, 255 };
|
||||
vertices[vCount].texCoord = { (tx + t.vertices[k].Xpixel) << 5, (ty + t.vertices[k].Ypixel) << 5 };
|
||||
vertices[vCount].normal = { 0, 0, 0, 0x7FFF };
|
||||
vertices[vCount].texCoord = { ((tx + t.vertices[k].Xpixel) << 5) + 16, ((ty + t.vertices[k].Ypixel) << 5) + 16};
|
||||
vCount++;
|
||||
}
|
||||
}
|
||||
@@ -316,14 +278,15 @@ struct Level {
|
||||
vertices[vCount].coord = { v.x, v.y, v.z };
|
||||
|
||||
if (nCount > 0) {
|
||||
vertices[vCount].normal = packNormal(normals[f.vertices[k]]);
|
||||
TR::Vertex &n = normals[f.vertices[k]];
|
||||
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
|
||||
vertices[vCount].color = { 255, 255, 255, 255 };
|
||||
} else {
|
||||
uint8 a = 255 - (lights[f.vertices[k]] >> 5);
|
||||
vertices[vCount].normal = { 0, 0, 0, 255 };
|
||||
vertices[vCount].color = { a, a, a, 255 };
|
||||
}
|
||||
vertices[vCount].texCoord = { (tx + t.vertices[k].Xpixel) << 5, (ty + t.vertices[k].Ypixel) << 5 };
|
||||
vertices[vCount].texCoord = { ((tx + t.vertices[k].Xpixel) << 5) + 16, ((ty + t.vertices[k].Ypixel) << 5) + 16};
|
||||
vCount++;
|
||||
}
|
||||
}
|
||||
@@ -351,14 +314,15 @@ struct Level {
|
||||
vertices[vCount].coord = { v.x, v.y, v.z };
|
||||
|
||||
if (nCount > 0) {
|
||||
vertices[vCount].normal = packNormal(normals[f.vertices[k]]);
|
||||
TR::Vertex &n = normals[f.vertices[k]];
|
||||
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
|
||||
vertices[vCount].color = { 255, 255, 255, 255 };
|
||||
} else {
|
||||
uint8 a = 255 - (lights[f.vertices[k]] >> 5);
|
||||
vertices[vCount].normal = { 0, 0, 0, 255 };
|
||||
vertices[vCount].color = { a, a, a, 255 };
|
||||
}
|
||||
vertices[vCount].texCoord = { (tx + t.vertices[k].Xpixel) << 5, (ty + t.vertices[k].Ypixel) << 5 };
|
||||
vertices[vCount].texCoord = { ((tx + t.vertices[k].Xpixel) << 5) + 16, ((ty + t.vertices[k].Ypixel) << 5) + 16};
|
||||
vCount++;
|
||||
}
|
||||
}
|
||||
@@ -387,7 +351,8 @@ struct Level {
|
||||
vertices[vCount].coord = { v.x, v.y, v.z };
|
||||
|
||||
if (nCount > 0) {
|
||||
vertices[vCount].normal = packNormal(normals[f.vertices[k]]);
|
||||
TR::Vertex &n = normals[f.vertices[k]];
|
||||
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
|
||||
vertices[vCount].color = { c.r, c.g, c.b, 255 };
|
||||
} else {
|
||||
uint8 a = 255 - (lights[f.vertices[k]] >> 5);
|
||||
@@ -419,7 +384,8 @@ struct Level {
|
||||
vertices[vCount].coord = { v.x, v.y, v.z };
|
||||
|
||||
if (nCount > 0) {
|
||||
vertices[vCount].normal = packNormal(normals[f.vertices[k]]);
|
||||
TR::Vertex &n = normals[f.vertices[k]];
|
||||
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
|
||||
vertices[vCount].color = { c.r, c.g, c.b, 255 };
|
||||
} else {
|
||||
uint8 a = 255 - (lights[f.vertices[k]] >> 5);
|
||||
@@ -471,12 +437,10 @@ struct Level {
|
||||
|
||||
mat4 m = Core::mModel;
|
||||
Core::mModel.translate(vec3(rMesh.x, rMesh.y, rMesh.z));
|
||||
Core::mModel.rotateY((rMesh.rotation >> 14) * 90.0f * DEG2RAD);
|
||||
// Core::mModel.rotateY((rMesh.rotation >> 14) * 90.0f * DEG2RAD);
|
||||
Core::mModel.rotateY(rMesh.rotation / 16384.0f * PI * 0.5f);
|
||||
|
||||
getLight(vec3(rMesh.x, rMesh.y, rMesh.z), index);
|
||||
shader->setParam(uAmbient, Core::ambient);
|
||||
shader->setParam(uLightPos, Core::lightPos);
|
||||
shader->setParam(uLightColor, Core::lightColor);
|
||||
|
||||
renderMesh(sMesh->mesh);
|
||||
|
||||
@@ -669,49 +633,58 @@ struct Level {
|
||||
}
|
||||
}
|
||||
|
||||
void getLight(const vec3 &pos, int room) {
|
||||
int getLightIndex(const vec3 &pos, int &room) {
|
||||
int idx = -1;
|
||||
float dist;
|
||||
for (int i = 0; i < level.rooms[room].lightsCount; i++) {
|
||||
TR::Room::Light &light = level.rooms[room].lights[i];
|
||||
float d = (pos - vec3(light.x, light.y, light.z)).length();
|
||||
if (idx == -1 || d < dist) {
|
||||
idx = i;
|
||||
dist = d;
|
||||
for (int j = 0; j < level.roomsCount; j++)
|
||||
for (int i = 0; i < level.rooms[j].lightsCount; i++) {
|
||||
TR::Room::Light &light = level.rooms[j].lights[i];
|
||||
float d = (pos - vec3(light.x, light.y, light.z)).length();
|
||||
if (idx == -1 || d < dist) {
|
||||
idx = i;
|
||||
dist = d;
|
||||
room = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
void getLight(const vec3 &pos, int roomIndex) {
|
||||
int room;
|
||||
int idx = getLightIndex(pos, room);
|
||||
if (idx > -1) {
|
||||
TR::Room::Light &light = level.rooms[room].lights[idx];
|
||||
float c = level.rooms[room].lights[idx].Intensity / 8191.0f;
|
||||
Core::lightPos = vec3(-light.x, -light.y, light.z);// * SCALE;
|
||||
Core::lightColor = vec4(c, c, c, 0.0f);
|
||||
Core::lightPos = vec3(light.x, light.y, light.z);
|
||||
Core::lightColor = vec4(c, c, c, light.fade * light.fade);
|
||||
} else {
|
||||
Core::lightPos = vec3(0.0f);
|
||||
Core::lightColor = vec4(0.0f);
|
||||
}
|
||||
Core::ambient = vec3(1.0f - level.rooms[room].ambient / 8191.0f);
|
||||
Core::ambient = vec3(1.0f - level.rooms[roomIndex].ambient / 8191.0f);
|
||||
shader->setParam(uAmbient, Core::ambient);
|
||||
shader->setParam(uLightPos, Core::lightPos);
|
||||
shader->setParam(uLightColor, Core::lightColor);
|
||||
}
|
||||
|
||||
void renderEntity(const TR::Entity &entity) {
|
||||
// if (!(entity.flags & ENTITY_FLAG_VISIBLE))
|
||||
// return;
|
||||
|
||||
mat4 m = Core::mModel;
|
||||
Core::mModel.translate(vec3(entity.x, entity.y, entity.z));
|
||||
|
||||
float c = (entity.intensity > -1) ? (1.0f - entity.intensity / (float)0x1FFF) : 1.0f;
|
||||
float l = 1.0f;
|
||||
|
||||
Core::color = vec4(c, c, c, 1.0);
|
||||
Core::color = vec4(c, c, c, 1.0);
|
||||
shader->setParam(uColor, Core::color);
|
||||
|
||||
getLight(vec3(entity.x, entity.y, entity.z), entity.room);
|
||||
|
||||
shader->setParam(uColor, Core::color);
|
||||
shader->setParam(uAmbient, Core::ambient);
|
||||
shader->setParam(uLightPos, Core::lightPos);
|
||||
shader->setParam(uLightColor, Core::lightColor);
|
||||
|
||||
|
||||
for (int i = 0; i < level.modelsCount; i++)
|
||||
if (entity.id == level.models[i].id) {
|
||||
Core::mModel.rotateY(entity.rotation / 16384.0f * PI * 0.5f);
|
||||
// Core::mModel.rotateY((entity.rotation >> 14) * 90.0f * DEG2RAD);
|
||||
renderModel(level.models[i]);
|
||||
break;
|
||||
}
|
||||
@@ -756,17 +729,17 @@ struct Level {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
Core::setBlending(bmAlpha);
|
||||
}
|
||||
|
||||
void debugFloor(const vec3 &f, const vec3 &c, int floorIndex) {
|
||||
*/
|
||||
void debugFloor(const vec3 &f, const vec3 &c, int floorIndex, bool current) {
|
||||
vec3 vf[4] = { f, f + vec3(1024, 0, 0), f + vec3(1024, 0, 1024), f + vec3(0, 0, 1024) };
|
||||
vec3 vc[4] = { c, c + vec3(1024, 0, 0), c + vec3(1024, 0, 1024), c + vec3(0, 0, 1024) };
|
||||
|
||||
auto *d = &floors[floorIndex];
|
||||
uint16 *d = &level.floors[floorIndex];
|
||||
auto cmd = *d;
|
||||
|
||||
do {
|
||||
cmd = *d;
|
||||
int func = cmd & 0x001F; // function
|
||||
int func = cmd & 0x001F; // function
|
||||
int sub = (cmd & 0x7F00) >> 8; // sub function
|
||||
d++;
|
||||
|
||||
@@ -782,7 +755,7 @@ struct Level {
|
||||
auto &p = func == 0x02 ? vf : vc;
|
||||
|
||||
if (func == 0x02) {
|
||||
|
||||
|
||||
if (sx > 0) {
|
||||
p[0].y += sx;
|
||||
p[3].y += sx;
|
||||
@@ -828,7 +801,11 @@ struct Level {
|
||||
// LOG("%d %d\n", func, sub);
|
||||
} while ((cmd & 0x8000) == 0); // end
|
||||
|
||||
glColor3f(0, 1, 0);
|
||||
if (current)
|
||||
glColor3f(1, 1, 1);
|
||||
else
|
||||
glColor3f(0, 1, 0);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int i = 0; i < 5; i++)
|
||||
glVertex3fv((GLfloat*)&vf[i % 4]);
|
||||
@@ -840,50 +817,44 @@ struct Level {
|
||||
glVertex3fv((GLfloat*)&vc[i % 4]);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void debugSectors(int index) {
|
||||
TR::Room &room = level.rooms[index];
|
||||
|
||||
void debugSectors(tr_room *room) {
|
||||
vec3 p = (Core::viewPos / SCALE - vec3(-room->info.x, 0, room->info.z)) / vec3(1024, 1, 1024);
|
||||
int px = (int)-p.x;
|
||||
int pz = (int)p.z;
|
||||
vec3 p = (lara->pos - vec3(room.info.x, 0, room.info.z)) / vec3(1024, 1, 1024);
|
||||
|
||||
for (int z = 0; z < room->zSectors; z++)
|
||||
for (int x = 0; x < room->xSectors; x++) {
|
||||
auto &s = room->sectors[x * room->zSectors + z];
|
||||
vec3 f(x * 1024 + room->info.x, s.floor * 256, z * 1024 + room->info.z);
|
||||
vec3 c(x * 1024 + room->info.x, s.ceiling * 256, z * 1024 + room->info.z);
|
||||
for (int z = 0; z < room.zSectors; z++)
|
||||
for (int x = 0; x < room.xSectors; x++) {
|
||||
auto &s = room.sectors[x * room.zSectors + z];
|
||||
vec3 f(x * 1024 + room.info.x, s.floor * 256, z * 1024 + room.info.z);
|
||||
vec3 c(x * 1024 + room.info.x, s.ceiling * 256, z * 1024 + room.info.z);
|
||||
|
||||
debugFloor(f, c, s.floorIndex);
|
||||
debugFloor(f, c, s.floorIndex, (int)p.x == x && (int)p.z == z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void debugRooms() {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
Core::setBlending(bmAdd);
|
||||
glColor3f(0, 0.25f, 0);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(-SCALE, -SCALE, SCALE);
|
||||
|
||||
for (int i = 0; i < rooms.count; i++) {
|
||||
auto &r = *rooms[i];
|
||||
for (int i = 0; i < level.roomsCount; i++) {
|
||||
TR::Room &r = level.rooms[i];
|
||||
vec3 p = vec3(r.info.x, r.info.yTop, r.info.z);
|
||||
if (isInsideRoom(Core::viewPos, rooms[i])) {
|
||||
debugSectors(rooms[i]);
|
||||
|
||||
if (i == level.entities[lara->entity].room) {// isInsideRoom(Core::viewPos, rooms[i])) {
|
||||
debugSectors(i);
|
||||
glColor3f(0, 1, 0);
|
||||
} else
|
||||
glColor3f(1, 1, 1);
|
||||
|
||||
Debug::Draw::box(Box(p, p + vec3(r.xSectors * 1024, r.info.yBottom - r.info.yTop, r.zSectors * 1024)));
|
||||
|
||||
Debug::Draw::box(p, p + vec3(r.xSectors * 1024, r.info.yBottom - r.info.yTop, r.zSectors * 1024));
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
Core::setBlending(bmAlpha);
|
||||
}
|
||||
|
||||
/*
|
||||
void debugMeshes() {
|
||||
glPushMatrix();
|
||||
glScalef(-SCALE, -SCALE, SCALE);
|
||||
@@ -893,22 +864,28 @@ struct Level {
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
*/
|
||||
void debugLights() {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
int roomIndex = level.entities[lara->entity].room;
|
||||
int lightIndex = getLightIndex(lara->pos, roomIndex);
|
||||
|
||||
glPointSize(8);
|
||||
glBegin(GL_POINTS);
|
||||
for (int i = 0; i < rooms.count; i++)
|
||||
for (int j = 0; j < rooms[i]->lights.count; j++) {
|
||||
auto &l = rooms[i]->lights[j];
|
||||
float a = l.Intensity1 / 8191.0f;
|
||||
glColor3f(a, a, a);
|
||||
glVertex3f(-l.x * SCALE, -l.y * SCALE, l.z * SCALE);
|
||||
for (int i = 0; i < level.roomsCount; i++)
|
||||
for (int j = 0; j < level.rooms[i].lightsCount; j++) {
|
||||
TR::Room::Light &l = level.rooms[i].lights[j];
|
||||
float a = l.Intensity / 8191.0f;
|
||||
vec3 p = vec3(l.x, l.y, l.z);
|
||||
vec4 color = vec4(a, a, a, 1);
|
||||
Debug::Draw::point(p, color);
|
||||
if (i == roomIndex && j == lightIndex)
|
||||
color = vec4(0, 1, 0, 1);
|
||||
Debug::Draw::sphere(p, l.fade, color);
|
||||
}
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
/*
|
||||
void debugEntity() {
|
||||
Core::setCulling(cfNone);
|
||||
Core::active.shader = NULL;
|
||||
@@ -971,6 +948,7 @@ struct Level {
|
||||
void update() {
|
||||
time += Core::deltaTime;
|
||||
lara->update();
|
||||
camera.update();
|
||||
|
||||
if (tickTextureAnimation > 0.25f) {
|
||||
tickTextureAnimation = 0.0f;
|
||||
@@ -992,6 +970,9 @@ struct Level {
|
||||
}
|
||||
|
||||
void render() {
|
||||
camera.pos = vec3(-lara->pos.x, -lara->pos.y, lara->pos.z) + vec3(0, 1024, -1024);
|
||||
camera.setup();;
|
||||
|
||||
shader->bind();
|
||||
atlas->bind(0);
|
||||
mesh->bind();
|
||||
@@ -1006,8 +987,6 @@ struct Level {
|
||||
Core::setCulling(cfFront);
|
||||
|
||||
Core::mModel.identity();
|
||||
// Core::mModel.scale(vec3(-SCALE, -SCALE, SCALE));
|
||||
Core::mModel.scale(vec3(-1, -1, 1));
|
||||
|
||||
Core::color = vec4(1.0f);
|
||||
Core::ambient = vec3(0.0f);
|
||||
@@ -1021,11 +1000,13 @@ struct Level {
|
||||
for (int i = 0; i < level.entitiesCount; i++)
|
||||
renderEntity(level.entities[i]);
|
||||
|
||||
// debugRooms();
|
||||
Debug::Draw::begin();
|
||||
debugRooms();
|
||||
// debugMeshes();
|
||||
// debugLights();
|
||||
debugLights();
|
||||
// debugPortals();
|
||||
// debugEntity();
|
||||
Debug::Draw::end();
|
||||
}
|
||||
|
||||
};
|
||||
|
@@ -8,7 +8,7 @@ typedef unsigned short Index;
|
||||
struct Vertex {
|
||||
short3 coord;
|
||||
short2 texCoord;
|
||||
ubyte4 normal;
|
||||
short4 normal;
|
||||
ubyte4 color;
|
||||
};
|
||||
|
||||
@@ -48,9 +48,12 @@ struct Mesh {
|
||||
Vertex *v = (Vertex*)(range.vStart * sizeof(Vertex));
|
||||
glVertexAttribPointer(aCoord, 3, GL_SHORT, false, sizeof(Vertex), &v->coord);
|
||||
glVertexAttribPointer(aTexCoord, 2, GL_SHORT, true, sizeof(Vertex), &v->texCoord);
|
||||
glVertexAttribPointer(aNormal, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &v->normal);
|
||||
glVertexAttribPointer(aNormal, 4, GL_SHORT, true, sizeof(Vertex), &v->normal);
|
||||
glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &v->color);
|
||||
glDrawElements(GL_TRIANGLES, range.iCount, GL_UNSIGNED_SHORT, (GLvoid*)(range.iStart * sizeof(Index)));
|
||||
|
||||
Core::stats.dips++;
|
||||
Core::stats.tris += range.iCount / 3;
|
||||
}
|
||||
};
|
||||
|
||||
|
12
src/utils.h
12
src/utils.h
@@ -43,6 +43,10 @@ struct short3 {
|
||||
int16 x, y, z;
|
||||
};
|
||||
|
||||
struct short4 {
|
||||
int16 x, y, z, w;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline const T& min(const T &a, const T &b) {
|
||||
return a < b ? a : b;
|
||||
@@ -53,6 +57,11 @@ inline const T& max(const T &a, const T &b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline const int sign(const T &x) {
|
||||
return x > 0 ? 1 : (x < 0 ? -1 : 0);
|
||||
}
|
||||
|
||||
struct vec2 {
|
||||
float x, y;
|
||||
vec2() {}
|
||||
@@ -76,9 +85,12 @@ struct vec3 {
|
||||
vec3(float x, float y, float z) : x(x), y(y), z(z) {}
|
||||
vec3(const vec2 &xy, float z = 0.0f) : x(xy.x), y(xy.y), z(z) {}
|
||||
|
||||
float& operator [] (int index) const { return ((float*)this)[index]; }
|
||||
|
||||
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); }
|
||||
|
||||
float dot(const vec3 &v) const { return x*v.x + y*v.y + z*v.z; }
|
||||
|
@@ -95,8 +95,10 @@
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\camera.h" />
|
||||
<ClInclude Include="..\controller.h" />
|
||||
<ClInclude Include="..\core.h" />
|
||||
<ClInclude Include="..\debug.h" />
|
||||
<ClInclude Include="..\game.h" />
|
||||
<ClInclude Include="..\input.h" />
|
||||
<ClInclude Include="..\level.h" />
|
||||
@@ -106,6 +108,9 @@
|
||||
<ClInclude Include="..\format.h" />
|
||||
<ClInclude Include="..\utils.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\shader.glsl" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@@ -215,13 +215,17 @@ int main() {
|
||||
lastTime = time;
|
||||
|
||||
joyUpdate();
|
||||
|
||||
Core::stats.dips = 0;
|
||||
Core::stats.tris = 0;
|
||||
|
||||
Game::update();
|
||||
Game::render();
|
||||
|
||||
SwapBuffers(hDC);
|
||||
|
||||
if (fpsTime < getTime()) {
|
||||
LOG("FPS: %d\n", fps);
|
||||
LOG("FPS: %d DIP: %d TRI: %d\n", fps, Core::stats.dips, Core::stats.tris);
|
||||
fps = 0;
|
||||
fpsTime = getTime() + 1000;
|
||||
} else
|
||||
|
Reference in New Issue
Block a user