1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-12 08:04:09 +02:00

convert tabs to spaces

This commit is contained in:
Gagiev Timur
2016-08-29 11:06:13 +03:00
parent 6af424cee8
commit 0b670a1846
13 changed files with 2599 additions and 2659 deletions

View File

@@ -4,45 +4,45 @@
#include "core.h" #include "core.h"
struct Camera { struct Camera {
float fov, znear, zfar; float fov, znear, zfar;
vec3 pos, angle, offset; vec3 pos, angle, offset;
void update() { void update() {
#ifdef FREE_CAMERA #ifdef FREE_CAMERA
vec3 dir = vec3(sinf(angle.y - PI) * cosf(-angle.x), -sinf(-angle.x), cosf(angle.y - PI) * cosf(-angle.x)); vec3 dir = vec3(sinf(angle.y - PI) * cosf(-angle.x), -sinf(-angle.x), cosf(angle.y - PI) * cosf(-angle.x));
vec3 v = vec3(0); vec3 v = vec3(0);
if (Input::down[ikW]) v = v + dir; if (Input::down[ikW]) v = v + dir;
if (Input::down[ikS]) 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[ikD]) v = v + dir.cross(vec3(0, 1, 0));
if (Input::down[ikA]) 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); pos = pos + v.normal() * (Core::deltaTime * 2048.0f);
#endif #endif
if (Input::down[ikMouseL]) { if (Input::down[ikMouseL]) {
vec2 delta = Input::mouse.pos - Input::mouse.start.L; vec2 delta = Input::mouse.pos - Input::mouse.start.L;
angle.x -= delta.y * 0.01f; angle.x -= delta.y * 0.01f;
angle.y -= delta.x * 0.01f; angle.y -= delta.x * 0.01f;
angle.x = min(max(angle.x, -PI * 0.5f + EPS), PI * 0.5f - EPS); angle.x = min(max(angle.x, -PI * 0.5f + EPS), PI * 0.5f - EPS);
Input::mouse.start.L = Input::mouse.pos; Input::mouse.start.L = Input::mouse.pos;
} }
} }
void setup() { void setup() {
Core::mView.identity(); Core::mView.identity();
Core::mView.translate(vec3(-offset.x, -offset.y, -offset.z)); Core::mView.translate(vec3(-offset.x, -offset.y, -offset.z));
Core::mView.rotateZ(-angle.z); Core::mView.rotateZ(-angle.z);
Core::mView.rotateX(-angle.x); Core::mView.rotateX(-angle.x);
Core::mView.rotateY(-angle.y); Core::mView.rotateY(-angle.y);
Core::mView.translate(vec3(-pos.x, -pos.y, -pos.z)); Core::mView.translate(vec3(-pos.x, -pos.y, -pos.z));
Core::mView.scale(vec3(-1, -1, 1)); Core::mView.scale(vec3(-1, -1, 1));
Core::mProj = mat4(fov, (float)Core::width / (float)Core::height, znear, zfar); Core::mProj = mat4(fov, (float)Core::width / (float)Core::height, znear, zfar);
Core::mViewProj = Core::mProj * Core::mView;
Core::viewPos = Core::mView.inverse().getPos(); Core::mViewProj = Core::mProj * Core::mView;
}
Core::viewPos = Core::mView.inverse().getPos();
}
}; };
#endif #endif

View File

@@ -6,456 +6,455 @@
#define GRAVITY 7.0f #define GRAVITY 7.0f
struct Controller { struct Controller {
TR::Level *level; TR::Level *level;
int entity; int entity;
TR::Animation *anim; TR::Animation *anim;
float fTime; float fTime;
vec3 pos, velocity; vec3 pos, velocity;
float angle; float angle;
int state; // target state int state; // target state
int lastFrame; int lastFrame;
int sc; int sc;
bool lState; bool lState;
bool onGround; bool onGround;
Controller(TR::Level *level, int entity) : level(level), entity(entity), pos(0.0f), velocity(0.0f), angle(0.0f), fTime(0.0f) { Controller(TR::Level *level, int entity) : level(level), entity(entity), pos(0.0f), velocity(0.0f), angle(0.0f), fTime(0.0f) {
anim = &level->anims[getModel().animation]; anim = &level->anims[getModel().animation];
lastFrame = 0; lastFrame = 0;
TR::Entity &e = level->entities[entity]; TR::Entity &e = level->entities[entity];
pos = vec3(e.x, e.y, e.z); pos = vec3(e.x, e.y, e.z);
angle = e.rotation / 16384.0f * PI * 0.5f; angle = e.rotation / 16384.0f * PI * 0.5f;
sc = 0; sc = 0;
lState = false; lState = false;
state = TR::STATE_STOP; state = TR::STATE_STOP;
} }
void update() { void update() {
float rot = 0.0f; float rot = 0.0f;
enum { LEFT = 1, RIGHT = 2, FORTH = 4, BACK = 8, JUMP = 16, WALK = 32, ACTION = 64, WEAPON = 128, ROLL = 256, GROUND = 512, WATER = 1024, DEATH = 2048,
PULL = 4096, PICKUP = 8192, SWITCH_ON = 16 * 1024, SWITCH_OFF = 32 * 1024, KEY = 64 * 1024, PUZZLE = 128 * 1024, HANG = 256 * 1024, FALL = 512 * 1024, COMPRESS = 1024 * 1024};
int mask = 0;
if (Input::down[ikW] || Input::joy.L.y < 0) mask |= FORTH; enum { LEFT = 1, RIGHT = 2, FORTH = 4, BACK = 8,
if (Input::down[ikS] || Input::joy.L.y > 0) mask |= BACK; JUMP = 16, WALK = 32, ACTION = 64, WEAPON = 128, ROLL = 256,
if (Input::down[ikA] || Input::joy.L.x < 0) mask |= LEFT; GROUND = 512, WATER = 1024, DEATH = 2048,
if (Input::down[ikD] || Input::joy.L.x > 0) mask |= RIGHT; PULL = 4096, PICKUP = 8192, SWITCH_ON = 16 * 1024, SWITCH_OFF = 32 * 1024, KEY = 64 * 1024, PUZZLE = 128 * 1024, HANG = 256 * 1024, FALL = 512 * 1024, COMPRESS = 1024 * 1024};
if (Input::down[ikSpace] || Input::down[ikJoyX]) mask |= JUMP; int mask = 0;
if (Input::down[ikShift] || Input::down[ikJoyLT]) mask |= WALK;
if (Input::down[ikE] || /*Input::down[ikMouseL] ||*/ Input::down[ikJoyA]) mask |= ACTION; if (Input::down[ikW] || Input::joy.L.y < 0) mask |= FORTH;
if (Input::down[ikQ] || Input::down[ikMouseR] || Input::down[ikJoyY]) mask |= WEAPON; if (Input::down[ikS] || Input::joy.L.y > 0) mask |= BACK;
if (onGround) mask |= GROUND; if (Input::down[ikA] || Input::joy.L.x < 0) mask |= LEFT;
if (getRoom().flags & 1) mask |= WATER; if (Input::down[ikD] || Input::joy.L.x > 0) mask |= RIGHT;
if (velocity.y > 2048) mask |= FALL; if (Input::down[ikSpace] || Input::down[ikJoyX]) mask |= JUMP;
if (anim->state == TR::STATE_COMPRESS) mask |= COMPRESS; if (Input::down[ikShift] || Input::down[ikJoyLT]) mask |= WALK;
if (Input::down[ikE] || /*Input::down[ikMouseL] ||*/ Input::down[ikJoyA]) mask |= ACTION;
if (Input::down[ikQ] || Input::down[ikMouseR] || Input::down[ikJoyY]) mask |= WEAPON;
if (onGround) mask |= GROUND;
if (getRoom().flags & 1) mask |= WATER;
if (velocity.y > 2048) mask |= FALL;
if (anim->state == TR::STATE_COMPRESS) mask |= COMPRESS;
int origMask = mask;
if (origMask & (FORTH | BACK))
mask &= ~(LEFT | RIGHT);
int stateMask[TR::STATE_MAX];
for (int i = 0; i < TR::STATE_MAX; i++)
stateMask[i] = -1;
stateMask[TR::STATE_WALK] = GROUND | FORTH | WALK;
stateMask[TR::STATE_RUN] = GROUND | FORTH;
stateMask[TR::STATE_STOP] = GROUND;
stateMask[TR::STATE_FORWARD_JUMP] = GROUND | JUMP | FORTH;
// stateMask[TR::STATE_FAST_TURN] = 0;
stateMask[TR::STATE_FAST_BACK] = GROUND | BACK;
stateMask[TR::STATE_TURN_RIGHT] = GROUND | RIGHT;
stateMask[TR::STATE_TURN_LEFT] = GROUND | LEFT;
stateMask[TR::STATE_DEATH] = DEATH;
stateMask[TR::STATE_FAST_FALL] = FALL;
stateMask[TR::STATE_HANG] = HANG | ACTION;
stateMask[TR::STATE_REACH] = ACTION;
// stateMask[TR::STATE_SPLAT]
// stateMask[TR::STATE_TREAD]
// stateMask[TR::STATE_FAST_TURN_14]
stateMask[TR::STATE_COMPRESS] = GROUND | JUMP;
stateMask[TR::STATE_BACK] = GROUND | WALK | BACK;
stateMask[TR::STATE_SWIM] = WATER | FORTH;
// stateMask[TR::STATE_GLIDE]
// stateMask[TR::STATE_NULL_19]
// stateMask[TR::STATE_FAST_TURN_20]
stateMask[TR::STATE_FAST_TURN_20] = GROUND | LEFT | RIGHT;
stateMask[TR::STATE_STEP_RIGHT] = GROUND | WALK | RIGHT;
stateMask[TR::STATE_STEP_LEFT] = GROUND | WALK | LEFT;
stateMask[TR::STATE_ROLL] = GROUND | ROLL;
// stateMask[TR::STATE_SLIDE]
stateMask[TR::STATE_BACK_JUMP] = GROUND | COMPRESS | BACK;
stateMask[TR::STATE_RIGHT_JUMP] = GROUND | COMPRESS | RIGHT;
stateMask[TR::STATE_LEFT_JUMP] = GROUND | COMPRESS | LEFT;
stateMask[TR::STATE_UP_JUMP] = GROUND | COMPRESS;
stateMask[TR::STATE_DIVE] = WATER;
stateMask[TR::STATE_PUSH_PULL_READY] = GROUND | ACTION | PULL;
stateMask[TR::STATE_PICK_UP] = GROUND | ACTION | PICKUP;
stateMask[TR::STATE_SWITCH_ON] = GROUND | ACTION | SWITCH_ON;
stateMask[TR::STATE_SWITCH_OFF] = GROUND | ACTION | SWITCH_OFF;
stateMask[TR::STATE_USE_KEY] = GROUND | ACTION | KEY;
stateMask[TR::STATE_USE_PUZZLE] = GROUND | ACTION | PUZZLE;
stateMask[TR::STATE_SWAN_DIVE] = JUMP | WALK | FORTH;
int origMask = mask; fTime += Core::deltaTime;
if (origMask & (FORTH | BACK)) int fCount = anim->frameEnd - anim->frameStart + 1;
mask &= ~(LEFT | RIGHT); int fIndex = int(fTime * 30.0f);
state = -1;
int maxMask = 0;
if (stateMask[anim->state] != mask)
for (int i = 0; i < anim->scCount; i++) {
TR::AnimState &sc = level->states[anim->scOffset + i];
if (sc.state >= TR::STATE_MAX || stateMask[sc.state] == -1)
LOG("unknown state %d\n", sc.state);
else
if (stateMask[sc.state] > maxMask && ((stateMask[sc.state] & mask) == stateMask[sc.state])) {
maxMask = stateMask[sc.state];
state = anim->scOffset + i;
}
}
int stateMask[TR::STATE_MAX]; if (state > -1 && anim->state != level->states[state].state) {
for (int i = 0; i < TR::STATE_MAX; i++) TR::AnimState &sc = level->states[state];
stateMask[i] = -1; for (int j = 0; j < sc.rangesCount; j++) {
TR::AnimRange &range = level->ranges[sc.rangesOffset + j];
stateMask[TR::STATE_WALK] = GROUND | FORTH | WALK; if ( anim->frameStart + fIndex >= range.low && anim->frameStart + fIndex <= range.high) {
stateMask[TR::STATE_RUN] = GROUND | FORTH; int st = anim->state;
stateMask[TR::STATE_STOP] = GROUND; anim = &level->anims[range.nextAnimation];
stateMask[TR::STATE_FORWARD_JUMP] = GROUND | JUMP | FORTH; fIndex = range.nextFrame - anim->frameStart;
// stateMask[TR::STATE_FAST_TURN] = 0; fCount = anim->frameEnd - anim->frameStart + 1;
stateMask[TR::STATE_FAST_BACK] = GROUND | BACK; fTime = fIndex / 30.0f;
stateMask[TR::STATE_TURN_RIGHT] = GROUND | RIGHT; break;
stateMask[TR::STATE_TURN_LEFT] = GROUND | LEFT; }
stateMask[TR::STATE_DEATH] = DEATH; }
stateMask[TR::STATE_FAST_FALL] = FALL; }
stateMask[TR::STATE_HANG] = HANG | ACTION;
stateMask[TR::STATE_REACH] = ACTION;
// stateMask[TR::STATE_SPLAT]
// stateMask[TR::STATE_TREAD]
// stateMask[TR::STATE_FAST_TURN_14]
stateMask[TR::STATE_COMPRESS] = GROUND | JUMP;
stateMask[TR::STATE_BACK] = GROUND | WALK | BACK;
stateMask[TR::STATE_SWIM] = WATER | FORTH;
// stateMask[TR::STATE_GLIDE]
// stateMask[TR::STATE_NULL_19]
// stateMask[TR::STATE_FAST_TURN_20]
stateMask[TR::STATE_FAST_TURN_20] = GROUND | LEFT | RIGHT;
stateMask[TR::STATE_STEP_RIGHT] = GROUND | WALK | RIGHT;
stateMask[TR::STATE_STEP_LEFT] = GROUND | WALK | LEFT;
stateMask[TR::STATE_ROLL] = GROUND | ROLL;
// stateMask[TR::STATE_SLIDE]
stateMask[TR::STATE_BACK_JUMP] = GROUND | COMPRESS | BACK;
stateMask[TR::STATE_RIGHT_JUMP] = GROUND | COMPRESS | RIGHT;
stateMask[TR::STATE_LEFT_JUMP] = GROUND | COMPRESS | LEFT;
stateMask[TR::STATE_UP_JUMP] = GROUND | COMPRESS;
stateMask[TR::STATE_DIVE] = WATER;
stateMask[TR::STATE_PUSH_PULL_READY] = GROUND | ACTION | PULL;
stateMask[TR::STATE_PICK_UP] = GROUND | ACTION | PICKUP;
stateMask[TR::STATE_SWITCH_ON] = GROUND | ACTION | SWITCH_ON;
stateMask[TR::STATE_SWITCH_OFF] = GROUND | ACTION | SWITCH_OFF;
stateMask[TR::STATE_USE_KEY] = GROUND | ACTION | KEY;
stateMask[TR::STATE_USE_PUZZLE] = GROUND | ACTION | PUZZLE;
stateMask[TR::STATE_SWAN_DIVE] = JUMP | WALK | FORTH;
fTime += Core::deltaTime;
int fCount = anim->frameEnd - anim->frameStart + 1;
int fIndex = int(fTime * 30.0f);
state = -1;
int maxMask = 0;
if (stateMask[anim->state] != mask)
for (int i = 0; i < anim->scCount; i++) {
TR::AnimState &sc = level->states[anim->scOffset + i];
if (sc.state >= TR::STATE_MAX || stateMask[sc.state] == -1)
LOG("unknown state %d\n", sc.state);
else
if (stateMask[sc.state] > maxMask && ((stateMask[sc.state] & mask) == stateMask[sc.state])) {
maxMask = stateMask[sc.state];
state = anim->scOffset + i;
}
}
if (state > -1 && anim->state != level->states[state].state) {
TR::AnimState &sc = level->states[state];
for (int j = 0; j < sc.rangesCount; j++) {
TR::AnimRange &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];
fIndex = range.nextFrame - anim->frameStart;
fCount = anim->frameEnd - anim->frameStart + 1;
fTime = fIndex / 30.0f;
break;
}
}
}
#ifdef _DEBUG #ifdef _DEBUG
if (Input::down[ikEnter]) { if (Input::down[ikEnter]) {
if (!lState) { if (!lState) {
lState = true; lState = true;
// state = TR::STATE_ROLL; // state = TR::STATE_ROLL;
// fTime = 0; // fTime = 0;
// sc = (sc + 1) % level->statesCount; // sc = (sc + 1) % level->statesCount;
// anim = &level->anims[146];//level->ranges[ level->states[sc].rangesOffset ].nextAnimation ]; // anim = &level->anims[146];//level->ranges[ level->states[sc].rangesOffset ].nextAnimation ];
// fTime = 0; // fTime = 0;
// state = level->states[sc].state; // state = level->states[sc].state;
LOG("state: %d\n", anim->state); LOG("state: %d\n", anim->state);
for (int i = 0; i < anim->scCount; i++) { for (int i = 0; i < anim->scCount; i++) {
auto &sc = level->states[anim->scOffset + i]; auto &sc = level->states[anim->scOffset + i];
LOG("-> %d : ", (int)sc.state); LOG("-> %d : ", (int)sc.state);
for (int j = 0; j < sc.rangesCount; j++) { for (int j = 0; j < sc.rangesCount; j++) {
TR::AnimRange &range = level->ranges[sc.rangesOffset + j]; TR::AnimRange &range = level->ranges[sc.rangesOffset + j];
LOG("%d ", range.nextAnimation); LOG("%d ", range.nextAnimation);
//range. //range.
} }
LOG("\n"); LOG("\n");
} }
} }
} else } else
lState = false; lState = false;
#endif #endif
if (anim->state == TR::STATE_RUN || if (anim->state == TR::STATE_RUN ||
anim->state == TR::STATE_FAST_BACK || anim->state == TR::STATE_FAST_BACK ||
anim->state == TR::STATE_WALK || anim->state == TR::STATE_WALK ||
anim->state == TR::STATE_BACK || anim->state == TR::STATE_BACK ||
anim->state == TR::STATE_TURN_LEFT || anim->state == TR::STATE_TURN_LEFT ||
anim->state == TR::STATE_TURN_RIGHT) { anim->state == TR::STATE_TURN_RIGHT) {
if (origMask & LEFT) angle -= Core::deltaTime * PI; if (origMask & LEFT) angle -= Core::deltaTime * PI;
if (origMask & RIGHT) angle += Core::deltaTime * PI; if (origMask & RIGHT) angle += Core::deltaTime * PI;
} }
float d = 0.0f; float d = 0.0f;
switch (anim->state) { switch (anim->state) {
case TR::STATE_BACK : case TR::STATE_BACK :
case TR::STATE_BACK_JUMP : case TR::STATE_BACK_JUMP :
case TR::STATE_FAST_BACK : case TR::STATE_FAST_BACK :
d = PI; d = PI;
break; break;
case TR::STATE_STEP_LEFT : case TR::STATE_STEP_LEFT :
case TR::STATE_LEFT_JUMP : case TR::STATE_LEFT_JUMP :
d = -PI * 0.5f; d = -PI * 0.5f;
break; break;
case TR::STATE_STEP_RIGHT : case TR::STATE_STEP_RIGHT :
case TR::STATE_RIGHT_JUMP : case TR::STATE_RIGHT_JUMP :
d = PI * 0.5f; d = PI * 0.5f;
break; break;
} }
d += angle; d += angle;
bool endFrame = fIndex >= fCount; bool endFrame = fIndex >= fCount;
int16 *ptr = &level->commands[anim->animCommand]; int16 *ptr = &level->commands[anim->animCommand];
for (int i = 0; i < anim->acCount; i++) { for (int i = 0; i < anim->acCount; i++) {
switch (*ptr++) { switch (*ptr++) {
case 0x01 : { // cmd position case 0x01 : { // cmd position
int16 sx = *ptr++; int16 sx = *ptr++;
int16 sy = *ptr++; int16 sy = *ptr++;
int16 sz = *ptr++; int16 sz = *ptr++;
LOG("move: %d %d\n", (int)sx, (int)sy, (int)sz); LOG("move: %d %d\n", (int)sx, (int)sy, (int)sz);
break; break;
} }
case 0x02 : { // cmd jump speed case 0x02 : { // cmd jump speed
int16 sy = *ptr++; int16 sy = *ptr++;
int16 sz = *ptr++; int16 sz = *ptr++;
if (endFrame) { if (endFrame) {
LOG("jump: %d %d\n", (int)sy, (int)sz); LOG("jump: %d %d\n", (int)sy, (int)sz);
velocity.x = sinf(d) * sz; velocity.x = sinf(d) * sz;
velocity.y = sy; velocity.y = sy;
velocity.z = cosf(d) * sz; velocity.z = cosf(d) * sz;
onGround = false; onGround = false;
} }
break; break;
} }
case 0x03 : // empty hands case 0x03 : // empty hands
break; break;
case 0x04 : // kill case 0x04 : // kill
break; break;
case 0x05 : { // play sound case 0x05 : { // play sound
int frame = (*ptr++); int frame = (*ptr++);
int id = (*ptr++) & 0x3FFF; int id = (*ptr++) & 0x3FFF;
if (fIndex == frame - anim->frameStart && fIndex != lastFrame) { if (fIndex == frame - anim->frameStart && fIndex != lastFrame) {
auto a = level->soundsMap[id]; auto a = level->soundsMap[id];
auto b = level->soundsInfo[a].index; auto b = level->soundsInfo[a].index;
auto c = level->soundOffsets[b]; auto c = level->soundOffsets[b];
void *p = &level->soundData[c]; void *p = &level->soundData[c];
PlaySound((LPSTR)p, NULL, SND_ASYNC | SND_MEMORY); PlaySound((LPSTR)p, NULL, SND_ASYNC | SND_MEMORY);
} }
break; break;
} }
case 0x06 : case 0x06 :
if (fIndex != lastFrame && fIndex + anim->frameStart == ptr[0]) { if (fIndex != lastFrame && fIndex + anim->frameStart == ptr[0]) {
if (ptr[1] == 0) { if (ptr[1] == 0) {
angle = angle + PI; angle = angle + PI;
} }
} }
ptr += 2; ptr += 2;
break; break;
} }
} }
float dt = Core::deltaTime * 30.0f; float dt = Core::deltaTime * 30.0f;
if (onGround) { if (onGround) {
float speed = anim->speed.toFloat() + anim->accel.toFloat() * (fTime * 30.0f); float speed = anim->speed.toFloat() + anim->accel.toFloat() * (fTime * 30.0f);
velocity.x = sinf(d) * speed; velocity.x = sinf(d) * speed;
velocity.z = cosf(d) * speed; velocity.z = cosf(d) * speed;
} }
velocity.y += GRAVITY * dt; velocity.y += GRAVITY * dt;
if (endFrame) { if (endFrame) {
fIndex = anim->nextFrame; fIndex = anim->nextFrame;
int id = anim->nextAnimation; int id = anim->nextAnimation;
anim = &level->anims[anim->nextAnimation]; anim = &level->anims[anim->nextAnimation];
fIndex -= anim->frameStart; fIndex -= anim->frameStart;
fTime = fIndex / 30.0f; fTime = fIndex / 30.0f;
fCount = anim->frameEnd - anim->frameStart + 1; fCount = anim->frameEnd - anim->frameStart + 1;
} }
move(velocity * dt); move(velocity * dt);
collide(); collide();
lastFrame = fIndex; lastFrame = fIndex;
} }
void move(const vec3 &offset) { void move(const vec3 &offset) {
vec3 p = pos; vec3 p = pos;
pos = pos + offset; pos = pos + offset;
updateEntity(); updateEntity();
TR::Room &room = getRoom(); TR::Room &room = getRoom();
TR::Entity &entity = getEntity(); TR::Entity &entity = getEntity();
int dx, dz; int dx, dz;
TR::Room::Sector &s = getSector(dx, dz); TR::Room::Sector &s = getSector(dx, dz);
int d = entity.y - s.floor * 256; int d = entity.y - s.floor * 256;
if (d >= 256 * 4) { if (d >= 256 * 4) {
pos.x = p.x;//vec3(entity.x, entity.y, entity.z); pos.x = p.x;//vec3(entity.x, entity.y, entity.z);
pos.z = p.z; pos.z = p.z;
updateEntity(); updateEntity();
if (d >= 256 * 4) if (d >= 256 * 4)
anim = &level->anims[53]; // forward smash anim = &level->anims[53]; // forward smash
else else
anim = &level->anims[11]; // instant stand anim = &level->anims[11]; // instant stand
state = anim->state; state = anim->state;
fTime = 0; fTime = 0;
} }
} }
void updateEntity() { void updateEntity() {
TR::Entity &e = getEntity(); TR::Entity &e = getEntity();
e.x = int(pos.x); e.x = int(pos.x);
e.y = int(pos.y); e.y = int(pos.y);
e.z = int(pos.z); e.z = int(pos.z);
e.rotation = int(angle / (PI * 0.5f) * 16384.0f); e.rotation = int(angle / (PI * 0.5f) * 16384.0f);
} }
bool insideRoom(const vec3 &pos, int room) { bool insideRoom(const vec3 &pos, int room) {
TR::Room &r = level->rooms[room]; TR::Room &r = level->rooms[room];
vec3 min = vec3(r.info.x, r.info.yTop, r.info.z); vec3 min = vec3(r.info.x, r.info.yTop, r.info.z);
vec3 max = min + vec3(r.xSectors * 1024, r.info.yBottom - r.info.yTop, r.zSectors * 1024); vec3 max = min + vec3(r.xSectors * 1024, r.info.yBottom - r.info.yTop, r.zSectors * 1024);
return pos.x >= min.x && pos.x <= max.x && return pos.x >= min.x && pos.x <= max.x &&
pos.y >= min.y && pos.y <= max.y && pos.y >= min.y && pos.y <= max.y &&
pos.z >= min.z && pos.z <= max.z; pos.z >= min.z && pos.z <= max.z;
} }
TR::Entity& getEntity() { TR::Entity& getEntity() {
return level->entities[entity]; return level->entities[entity];
} }
TR::Model& getModel() { TR::Model& getModel() {
TR::Entity &entity = getEntity(); TR::Entity &entity = getEntity();
for (int i = 0; i < level->modelsCount; i++) for (int i = 0; i < level->modelsCount; i++)
if (entity.id == level->models[i].id) if (entity.id == level->models[i].id)
return level->models[i]; return level->models[i];
} }
TR::Room& getRoom() { TR::Room& getRoom() {
return level->rooms[getEntity().room]; return level->rooms[getEntity().room];
} }
TR::Room::Sector& getSector(int &dx, int &dz) { TR::Room::Sector& getSector(int &dx, int &dz) {
TR::Room &room = getRoom(); TR::Room &room = getRoom();
TR::Entity &entity = getEntity(); TR::Entity &entity = getEntity();
dx = entity.x - room.info.x; dx = entity.x - room.info.x;
dz = entity.z - room.info.z; dz = entity.z - room.info.z;
int sx = dx / 1024; int sx = dx / 1024;
int sz = dz / 1024; int sz = dz / 1024;
dx -= sx * 1024; dx -= sx * 1024;
dz -= sz * 1024; dz -= sz * 1024;
return room.sectors[sx * room.zSectors + sz]; return room.sectors[sx * room.zSectors + sz];
} }
void collide() { void collide() {
int dx, dz; int dx, dz;
TR::Room::Sector &s = getSector(dx, dz); TR::Room::Sector &s = getSector(dx, dz);
TR::Entity &entity = getEntity(); TR::Entity &entity = getEntity();
float bottom = s.floor * 256;
float fx = dx / 1024.0f, fz = dz / 1024.0f; float bottom = s.floor * 256;
// dx -= 512; float fx = dx / 1024.0f, fz = dz / 1024.0f;
// dz -= 512;
uint16 cmd, *d = &level->floors[s.floorIndex]; // dx -= 512;
// dz -= 512;
if (s.floorIndex) uint16 cmd, *d = &level->floors[s.floorIndex];
do {
cmd = *d++;
int func = cmd & 0x00FF; // function
int sub = (cmd & 0x7F00) >> 8; // sub function
switch (func) { if (s.floorIndex)
case 1 : do {
entity.room = *d++; cmd = *d++;
break; int func = cmd & 0x00FF; // function
case 2 : int sub = (cmd & 0x7F00) >> 8; // sub function
case 3 : {
int8 sx = (int8)(*d & 0x00FF);
int8 sz = (int8)((*d & 0xFF00) >> 8);
if (func == 2) { switch (func) {
if (sx > 0) case 1 :
bottom += (int)sx * (1024 - dx) >> 2; entity.room = *d++;
else break;
bottom -= (int)sx * dx >> 2; case 2 :
case 3 : {
if (sz > 0) int8 sx = (int8)(*d & 0x00FF);
bottom += (int)sz * (1024 - dz) >> 2; int8 sz = (int8)((*d & 0xFF00) >> 8);
else
bottom -= (int)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) { if (func == 2) {
p[0].y -= sz; if (sx > 0)
p[1].y -= sz; bottom += (int)sx * (1024 - dx) >> 2;
} else { else
p[3].y += sz; bottom -= (int)sx * dx >> 2;
p[2].y += sz;
}
*/
}
d++;
break;
}
case 4 : {
/*
//*d++; // trigger setup
if (sub == 0x00) LOG("trigger\n");
if (sub == 0x01) LOG("pad\n");
if (sub == 0x02) LOG("switch\n");
if (sub == 0x03) LOG("key\n");
if (sub == 0x04) LOG("pickup\n");
if (sub == 0x05) LOG("heavy-trigger\n");
if (sub == 0x06) LOG("anti-pad\n");
if (sub == 0x07) LOG("combat\n");
if (sub == 0x08) LOG("dummy\n");
if (sub == 0x09) LOG("anti-trigger\n");
*/
uint16 act;
do {
act = *d++; // trigger action
} while (!(act & 0x8000));
break;
}
default :
LOG("unknown func: %d\n", func);
}
} while (!(cmd & 0x8000)); if (sz > 0)
bottom += (int)sz * (1024 - dz) >> 2;
else
bottom -= (int)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++;
break;
}
case 4 : {
/*
//*d++; // trigger setup
if (sub == 0x00) LOG("trigger\n");
if (sub == 0x01) LOG("pad\n");
if (sub == 0x02) LOG("switch\n");
if (sub == 0x03) LOG("key\n");
if (sub == 0x04) LOG("pickup\n");
if (sub == 0x05) LOG("heavy-trigger\n");
if (sub == 0x06) LOG("anti-pad\n");
if (sub == 0x07) LOG("combat\n");
if (sub == 0x08) LOG("dummy\n");
if (sub == 0x09) LOG("anti-trigger\n");
*/
uint16 act;
do {
act = *d++; // trigger action
} while (!(act & 0x8000));
break;
}
default :
LOG("unknown func: %d\n", func);
}
} while (!(cmd & 0x8000));
onGround = pos.y > bottom; onGround = pos.y > bottom;
if (onGround) { if (onGround) {
onGround = true; onGround = true;
if (s.roomBelow != 255) { if (s.roomBelow != 255) {
entity.room = s.roomBelow; entity.room = s.roomBelow;
onGround = false; onGround = false;
return; return;
} }
pos.y = bottom; pos.y = bottom;
velocity.y = 0.0f; velocity.y = 0.0f;
} }
entity.y = (int)pos.y; entity.y = (int)pos.y;
} }
}; };

View File

@@ -10,56 +10,56 @@
#include "input.h" #include "input.h"
#ifdef WIN32 #ifdef WIN32
#if defined(_MSC_VER) // Visual Studio #if defined(_MSC_VER) // Visual Studio
#define GetProcOGL(x) *(void**)&x=(void*)wglGetProcAddress(#x); #define GetProcOGL(x) *(void**)&x=(void*)wglGetProcAddress(#x);
#else // GCC #else // GCC
#define GetProcOGL(x) x=(typeof(x))wglGetProcAddress(#x); #define GetProcOGL(x) x=(typeof(x))wglGetProcAddress(#x);
#endif #endif
// Texture // Texture
PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLACTIVETEXTUREPROC glActiveTexture;
// Shader // Shader
PFNGLCREATEPROGRAMPROC glCreateProgram; PFNGLCREATEPROGRAMPROC glCreateProgram;
PFNGLDELETEPROGRAMPROC glDeleteProgram; PFNGLDELETEPROGRAMPROC glDeleteProgram;
PFNGLLINKPROGRAMPROC glLinkProgram; PFNGLLINKPROGRAMPROC glLinkProgram;
PFNGLUSEPROGRAMPROC glUseProgram; PFNGLUSEPROGRAMPROC glUseProgram;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
PFNGLCREATESHADERPROC glCreateShader; PFNGLCREATESHADERPROC glCreateShader;
PFNGLDELETESHADERPROC glDeleteShader; PFNGLDELETESHADERPROC glDeleteShader;
PFNGLSHADERSOURCEPROC glShaderSource; PFNGLSHADERSOURCEPROC glShaderSource;
PFNGLATTACHSHADERPROC glAttachShader; PFNGLATTACHSHADERPROC glAttachShader;
PFNGLCOMPILESHADERPROC glCompileShader; PFNGLCOMPILESHADERPROC glCompileShader;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
PFNGLUNIFORM1IVPROC glUniform1iv; PFNGLUNIFORM1IVPROC glUniform1iv;
PFNGLUNIFORM3FVPROC glUniform3fv; PFNGLUNIFORM3FVPROC glUniform3fv;
PFNGLUNIFORM4FVPROC glUniform4fv; PFNGLUNIFORM4FVPROC glUniform4fv;
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
// Mesh // Mesh
PFNGLGENBUFFERSARBPROC glGenBuffers; PFNGLGENBUFFERSARBPROC glGenBuffers;
PFNGLDELETEBUFFERSARBPROC glDeleteBuffers; PFNGLDELETEBUFFERSARBPROC glDeleteBuffers;
PFNGLBINDBUFFERARBPROC glBindBuffer; PFNGLBINDBUFFERARBPROC glBindBuffer;
PFNGLBUFFERDATAARBPROC glBufferData; PFNGLBUFFERDATAARBPROC glBufferData;
#endif #endif
namespace Core { namespace Core {
int width, height; int width, height;
float deltaTime; float deltaTime;
mat4 mView, mProj, mViewProj, mModel; mat4 mView, mProj, mViewProj, mModel;
vec3 viewPos; vec3 viewPos;
vec3 lightPos; vec3 lightPos;
vec4 lightColor; vec4 lightColor;
vec3 ambient; vec3 ambient;
vec4 color; vec4 color;
struct { struct {
int dips; int dips;
int tris; int tris;
} stats; } stats;
} }
#include "texture.h" #include "texture.h"
@@ -71,87 +71,87 @@ enum BlendMode { bmNone, bmAlpha, bmAdd, bmMultiply, bmScreen };
namespace Core { namespace Core {
void init() { void init() {
GetProcOGL(glActiveTexture); GetProcOGL(glActiveTexture);
GetProcOGL(glCreateProgram); GetProcOGL(glCreateProgram);
GetProcOGL(glDeleteProgram); GetProcOGL(glDeleteProgram);
GetProcOGL(glLinkProgram); GetProcOGL(glLinkProgram);
GetProcOGL(glUseProgram); GetProcOGL(glUseProgram);
GetProcOGL(glGetProgramInfoLog); GetProcOGL(glGetProgramInfoLog);
GetProcOGL(glCreateShader); GetProcOGL(glCreateShader);
GetProcOGL(glDeleteShader); GetProcOGL(glDeleteShader);
GetProcOGL(glShaderSource); GetProcOGL(glShaderSource);
GetProcOGL(glAttachShader); GetProcOGL(glAttachShader);
GetProcOGL(glCompileShader); GetProcOGL(glCompileShader);
GetProcOGL(glGetShaderInfoLog); GetProcOGL(glGetShaderInfoLog);
GetProcOGL(glGetUniformLocation); GetProcOGL(glGetUniformLocation);
GetProcOGL(glUniform1iv); GetProcOGL(glUniform1iv);
GetProcOGL(glUniform3fv); GetProcOGL(glUniform3fv);
GetProcOGL(glUniform4fv); GetProcOGL(glUniform4fv);
GetProcOGL(glUniformMatrix4fv); GetProcOGL(glUniformMatrix4fv);
GetProcOGL(glBindAttribLocation); GetProcOGL(glBindAttribLocation);
GetProcOGL(glEnableVertexAttribArray); GetProcOGL(glEnableVertexAttribArray);
GetProcOGL(glDisableVertexAttribArray); GetProcOGL(glDisableVertexAttribArray);
GetProcOGL(glVertexAttribPointer); GetProcOGL(glVertexAttribPointer);
GetProcOGL(glGenBuffers); GetProcOGL(glGenBuffers);
GetProcOGL(glDeleteBuffers); GetProcOGL(glDeleteBuffers);
GetProcOGL(glBindBuffer); GetProcOGL(glBindBuffer);
GetProcOGL(glBufferData); GetProcOGL(glBufferData);
} }
void free() { void free() {
// //
} }
void clear(const vec4 &color) { void clear(const vec4 &color) {
glClearColor(color.x, color.y, color.z, color.w); glClearColor(color.x, color.y, color.z, color.w);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
void setViewport(int x, int y, int width, int height) { void setViewport(int x, int y, int width, int height) {
glViewport(x, y, width, height); glViewport(x, y, width, height);
} }
void setCulling(CullMode mode) { void setCulling(CullMode mode) {
switch (mode) { switch (mode) {
case cfNone : case cfNone :
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
case cfBack : case cfBack :
glCullFace(GL_BACK); glCullFace(GL_BACK);
break; break;
case cfFront : case cfFront :
glCullFace(GL_FRONT); glCullFace(GL_FRONT);
break; break;
} }
if (mode != bmNone) if (mode != bmNone)
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
} }
void setBlending(BlendMode mode) { void setBlending(BlendMode mode) {
switch (mode) { switch (mode) {
case bmNone : case bmNone :
glDisable(GL_BLEND); glDisable(GL_BLEND);
break; break;
case bmAlpha : case bmAlpha :
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break; break;
case bmAdd : case bmAdd :
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
break; break;
case bmMultiply : case bmMultiply :
glBlendFunc(GL_DST_COLOR, GL_ZERO); glBlendFunc(GL_DST_COLOR, GL_ZERO);
break; break;
case bmScreen : case bmScreen :
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
break; break;
} }
if (mode != bmNone) if (mode != bmNone)
glEnable(GL_BLEND); glEnable(GL_BLEND);
} }
} }
#endif #endif

View File

@@ -5,109 +5,109 @@
namespace Debug { namespace Debug {
namespace Draw { namespace Draw {
void begin() { void begin() {
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadMatrixf((GLfloat*)&Core::mProj); glLoadMatrixf((GLfloat*)&Core::mProj);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
glLoadMatrixf((GLfloat*)&Core::mView); glLoadMatrixf((GLfloat*)&Core::mView);
glLineWidth(3); glLineWidth(3);
glPointSize(32); glPointSize(32);
glUseProgram(0); glUseProgram(0);
} }
void end() { void end() {
// //
} }
void box(const vec3 &min, const vec3 &max) { void box(const vec3 &min, const vec3 &max) {
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex3f(min.x, min.y, min.z); glVertex3f(min.x, min.y, min.z);
glVertex3f(max.x, min.y, min.z); glVertex3f(max.x, min.y, min.z);
glVertex3f(min.x, max.y, min.z); glVertex3f(min.x, max.y, min.z);
glVertex3f(max.x, max.y, min.z); glVertex3f(max.x, max.y, min.z);
glVertex3f(min.x, min.y, max.z); glVertex3f(min.x, min.y, max.z);
glVertex3f(max.x, min.y, max.z); glVertex3f(max.x, min.y, max.z);
glVertex3f(min.x, max.y, max.z); glVertex3f(min.x, max.y, max.z);
glVertex3f(max.x, max.y, max.z); glVertex3f(max.x, max.y, max.z);
glVertex3f(min.x, min.y, min.z); glVertex3f(min.x, min.y, min.z);
glVertex3f(min.x, min.y, max.z); glVertex3f(min.x, min.y, max.z);
glVertex3f(min.x, max.y, min.z); glVertex3f(min.x, max.y, min.z);
glVertex3f(min.x, max.y, max.z); glVertex3f(min.x, max.y, max.z);
glVertex3f(max.x, min.y, min.z); glVertex3f(max.x, min.y, min.z);
glVertex3f(max.x, min.y, max.z); glVertex3f(max.x, min.y, max.z);
glVertex3f(max.x, max.y, min.z); glVertex3f(max.x, max.y, min.z);
glVertex3f(max.x, max.y, max.z); glVertex3f(max.x, max.y, max.z);
glVertex3f(min.x, min.y, min.z); glVertex3f(min.x, min.y, min.z);
glVertex3f(min.x, max.y, min.z); glVertex3f(min.x, max.y, min.z);
glVertex3f(max.x, min.y, min.z); glVertex3f(max.x, min.y, min.z);
glVertex3f(max.x, max.y, min.z); glVertex3f(max.x, max.y, min.z);
glVertex3f(min.x, min.y, min.z); glVertex3f(min.x, min.y, min.z);
glVertex3f(min.x, max.y, min.z); glVertex3f(min.x, max.y, min.z);
glVertex3f(max.x, min.y, max.z); glVertex3f(max.x, min.y, max.z);
glVertex3f(max.x, max.y, max.z); glVertex3f(max.x, max.y, max.z);
glVertex3f(min.x, min.y, max.z); glVertex3f(min.x, min.y, max.z);
glVertex3f(min.x, max.y, max.z); glVertex3f(min.x, max.y, max.z);
glEnd(); glEnd();
} }
void sphere(const vec3 &center, const float radius, const vec4 &color) { void sphere(const vec3 &center, const float radius, const vec4 &color) {
const float k = PI * 2.0f / 18.0f; const float k = PI * 2.0f / 18.0f;
glColor4fv((GLfloat*)&color); glColor4fv((GLfloat*)&color);
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
for (int i = 0; i < 19; i++) { for (int i = 0; i < 19; i++) {
vec3 p = vec3(sinf(i * k), cosf(i * k), 0.0f) * radius; vec3 p = vec3(sinf(i * k), cosf(i * k), 0.0f) * radius;
glVertex3f(p[j] + center.x, p[(j + 1) % 3] + center.y, p[(j + 2) % 3] + center.z); glVertex3f(p[j] + center.x, p[(j + 1) % 3] + center.y, p[(j + 2) % 3] + center.z);
} }
glEnd(); glEnd();
} }
} }
void mesh(vec3 *vertices, Index *indices, int iCount) { void mesh(vec3 *vertices, Index *indices, int iCount) {
glBegin(GL_LINES); glBegin(GL_LINES);
for (int i = 0; i < iCount; i += 3) { for (int i = 0; i < iCount; i += 3) {
vec3 &a = vertices[indices[i + 0]]; vec3 &a = vertices[indices[i + 0]];
vec3 &b = vertices[indices[i + 1]]; vec3 &b = vertices[indices[i + 1]];
vec3 &c = vertices[indices[i + 2]]; vec3 &c = vertices[indices[i + 2]];
glVertex3fv((GLfloat*)&a); glVertex3fv((GLfloat*)&a);
glVertex3fv((GLfloat*)&b); glVertex3fv((GLfloat*)&b);
glVertex3fv((GLfloat*)&b); glVertex3fv((GLfloat*)&b);
glVertex3fv((GLfloat*)&c); glVertex3fv((GLfloat*)&c);
glVertex3fv((GLfloat*)&c); glVertex3fv((GLfloat*)&c);
glVertex3fv((GLfloat*)&a); glVertex3fv((GLfloat*)&a);
} }
glEnd(); glEnd();
} }
void axes(float size) { void axes(float size) {
glBegin(GL_LINES); glBegin(GL_LINES);
glColor3f(1, 0, 0); glVertex3f(0, 0, 0); glVertex3f(size, 0, 0); glColor3f(1, 0, 0); glVertex3f(0, 0, 0); glVertex3f(size, 0, 0);
glColor3f(0, 1, 0); glVertex3f(0, 0, 0); glVertex3f( 0, size, 0); glColor3f(0, 1, 0); glVertex3f(0, 0, 0); glVertex3f( 0, size, 0);
glColor3f(0, 0, 1); glVertex3f(0, 0, 0); glVertex3f( 0, 0, size); glColor3f(0, 0, 1); glVertex3f(0, 0, 0); glVertex3f( 0, 0, size);
glEnd(); glEnd();
} }
void point(const vec3 &p, const vec4 &color) { void point(const vec3 &p, const vec4 &color) {
glColor4fv((GLfloat*)&color); glColor4fv((GLfloat*)&color);
glBegin(GL_POINTS); glBegin(GL_POINTS);
glVertex3fv((GLfloat*)&p); glVertex3fv((GLfloat*)&p);
glEnd(); glEnd();
} }
} }
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -8,30 +8,30 @@
#include "level.h" #include "level.h"
namespace Game { namespace Game {
Level *level; Level *level;
void init() { void init() {
Core::init(); Core::init();
level = new Level("data\\GYM.PHD"); level = new Level("data\\GYM.PHD");
} }
void free() { void free() {
delete level; delete level;
Core::free(); Core::free();
} }
void update() { void update() {
level->update(); level->update();
} }
void render() { void render() {
Core::clear(vec4(0.0f)); Core::clear(vec4(0.0f));
Core::setViewport(0, 0, Core::width, Core::height); Core::setViewport(0, 0, Core::width, Core::height);
Core::setBlending(bmAlpha); Core::setBlending(bmAlpha);
level->render(); level->render();
} }
} }
#endif #endif

View File

@@ -3,81 +3,81 @@
#include "utils.h" #include "utils.h"
enum InputKey { ikNone, enum InputKey { ikNone,
// keyboard // keyboard
ikLeft, ikRight, ikUp, ikDown, ikSpace, ikEnter, ikEscape, ikShift, ikCtrl, ikAlt, ikLeft, ikRight, ikUp, ikDown, ikSpace, ikEnter, ikEscape, ikShift, ikCtrl, ikAlt,
ik0, ik1, ik2, ik3, ik4, ik5, ik6, ik7, ik8, ik9, ik0, ik1, ik2, ik3, ik4, ik5, ik6, ik7, ik8, ik9,
ikA, ikB, ikC, ikD, ikE, ikF, ikG, ikH, ikI, ikJ, ikK, ikL, ikM, ikA, ikB, ikC, ikD, ikE, ikF, ikG, ikH, ikI, ikJ, ikK, ikL, ikM,
ikN, ikO, ikP, ikQ, ikR, ikS, ikT, ikU, ikV, ikW, ikX, ikY, ikZ, ikN, ikO, ikP, ikQ, ikR, ikS, ikT, ikU, ikV, ikW, ikX, ikY, ikZ,
// mouse // mouse
ikMouseL, ikMouseR, ikMouseM, ikMouseL, ikMouseR, ikMouseM,
// touch // touch
ikTouchA, ikTouchB, ikTouchA, ikTouchB,
// gamepad // gamepad
ikJoyA, ikJoyB, ikJoyX, ikJoyY, ikJoyLB, ikJoyRB, ikJoyL, ikJoyR, ikJoySelect, ikJoyStart, ikJoyLT, ikJoyRT, ikJoyDP, ikJoyA, ikJoyB, ikJoyX, ikJoyY, ikJoyLB, ikJoyRB, ikJoyL, ikJoyR, ikJoySelect, ikJoyStart, ikJoyLT, ikJoyRT, ikJoyDP,
ikMAX }; ikMAX };
namespace Input { namespace Input {
bool down[ikMAX]; bool down[ikMAX];
struct { struct {
vec2 pos; vec2 pos;
struct { struct {
vec2 L, R, M; vec2 L, R, M;
} start; } start;
} mouse; } mouse;
struct { struct {
vec2 L, R; vec2 L, R;
float LT, RT, DP; float LT, RT, DP;
} joy; } joy;
struct { struct {
vec2 A, B; vec2 A, B;
struct { struct {
vec2 A, B; vec2 A, B;
} start; } start;
} touch; } touch;
void reset() { void reset() {
memset(down, 0, sizeof(down)); memset(down, 0, sizeof(down));
memset(&mouse, 0, sizeof(mouse)); memset(&mouse, 0, sizeof(mouse));
memset(&joy, 0, sizeof(joy)); memset(&joy, 0, sizeof(joy));
memset(&touch, 0, sizeof(touch)); memset(&touch, 0, sizeof(touch));
} }
void setDown(InputKey key, bool value) { void setDown(InputKey key, bool value) {
if (down[key] == value) if (down[key] == value)
return; return;
if (value)
switch (key) {
case ikMouseL : mouse.start.L = mouse.pos; break;
case ikMouseR : mouse.start.R = mouse.pos; break;
case ikMouseM : mouse.start.M = mouse.pos; break;
case ikTouchA : touch.start.A = touch.A; break;
case ikTouchB : touch.start.B = touch.B; break;
}
down[key] = value; if (value)
} switch (key) {
case ikMouseL : mouse.start.L = mouse.pos; break;
case ikMouseR : mouse.start.R = mouse.pos; break;
case ikMouseM : mouse.start.M = mouse.pos; break;
case ikTouchA : touch.start.A = touch.A; break;
case ikTouchB : touch.start.B = touch.B; break;
}
void setPos(InputKey key, const vec2 &pos) { down[key] = value;
switch (key) { }
case ikMouseL :
case ikMouseR : void setPos(InputKey key, const vec2 &pos) {
case ikMouseM : mouse.pos = pos; break; switch (key) {
case ikJoyL : joy.L = pos; break; case ikMouseL :
case ikJoyR : joy.R = pos; break; case ikMouseR :
case ikJoyLT : joy.LT = pos.x; break; case ikMouseM : mouse.pos = pos; break;
case ikJoyRT : joy.RT = pos.x; break; case ikJoyL : joy.L = pos; break;
case ikJoyDP : joy.DP = pos.x; break; case ikJoyR : joy.R = pos; break;
case ikTouchA : touch.A = pos; break; case ikJoyLT : joy.LT = pos.x; break;
case ikTouchB : touch.B = pos; break; case ikJoyRT : joy.RT = pos.x; break;
} case ikJoyDP : joy.DP = pos.x; break;
} case ikTouchA : touch.A = pos; break;
case ikTouchB : touch.B = pos; break;
}
}
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -6,55 +6,55 @@
typedef unsigned short Index; typedef unsigned short Index;
struct Vertex { struct Vertex {
short3 coord; short3 coord;
short2 texCoord; short2 texCoord;
short4 normal; short4 normal;
ubyte4 color; ubyte4 color;
}; };
struct MeshRange { struct MeshRange {
int iStart; int iStart;
int iCount; int iCount;
int vStart; int vStart;
}; };
struct Mesh { struct Mesh {
GLuint ID[2]; GLuint ID[2];
int iCount; int iCount;
int vCount; int vCount;
Mesh(Index *indices, int iCount, Vertex *vertices, int vCount) : iCount(iCount), vCount(vCount) { Mesh(Index *indices, int iCount, Vertex *vertices, int vCount) : iCount(iCount), vCount(vCount) {
glGenBuffers(2, ID); glGenBuffers(2, ID);
bind(); bind();
glBufferData(GL_ELEMENT_ARRAY_BUFFER, iCount * sizeof(Index), indices, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, iCount * sizeof(Index), indices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, vCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, vCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
} }
virtual ~Mesh() { virtual ~Mesh() {
glDeleteBuffers(2, ID); glDeleteBuffers(2, ID);
} }
void bind() { void bind() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ID[0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ID[0]);
glBindBuffer(GL_ARRAY_BUFFER, ID[1]); glBindBuffer(GL_ARRAY_BUFFER, ID[1]);
glEnableVertexAttribArray(aCoord); glEnableVertexAttribArray(aCoord);
glEnableVertexAttribArray(aTexCoord); glEnableVertexAttribArray(aTexCoord);
glEnableVertexAttribArray(aNormal); glEnableVertexAttribArray(aNormal);
glEnableVertexAttribArray(aColor); glEnableVertexAttribArray(aColor);
} }
void render(const MeshRange &range) { void render(const MeshRange &range) {
Vertex *v = (Vertex*)(range.vStart * sizeof(Vertex)); Vertex *v = (Vertex*)(range.vStart * sizeof(Vertex));
glVertexAttribPointer(aCoord, 3, GL_SHORT, false, sizeof(Vertex), &v->coord); glVertexAttribPointer(aCoord, 3, GL_SHORT, false, sizeof(Vertex), &v->coord);
glVertexAttribPointer(aTexCoord, 2, GL_SHORT, true, sizeof(Vertex), &v->texCoord); glVertexAttribPointer(aTexCoord, 2, GL_SHORT, true, sizeof(Vertex), &v->texCoord);
glVertexAttribPointer(aNormal, 4, GL_SHORT, 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); glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &v->color);
glDrawElements(GL_TRIANGLES, range.iCount, GL_UNSIGNED_SHORT, (GLvoid*)(range.iStart * sizeof(Index))); glDrawElements(GL_TRIANGLES, range.iCount, GL_UNSIGNED_SHORT, (GLvoid*)(range.iStart * sizeof(Index)));
Core::stats.dips++; Core::stats.dips++;
Core::stats.tris += range.iCount / 3; Core::stats.tris += range.iCount / 3;
} }
}; };
#endif #endif

View File

@@ -3,80 +3,80 @@
#include "core.h" #include "core.h"
enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX }; enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX };
enum SamplerType { sDiffuse, sMAX }; enum SamplerType { sDiffuse, sMAX };
enum UniformType { uViewProj, uModel, uColor, uAmbient, uLightPos, uLightColor, uMAX }; enum UniformType { uViewProj, uModel, uColor, uAmbient, uLightPos, uLightColor, uMAX };
const char *AttribName[aMAX] = { "aCoord", "aTexCoord", "aNormal", "aColor" }; const char *AttribName[aMAX] = { "aCoord", "aTexCoord", "aNormal", "aColor" };
const char *SamplerName[sMAX] = { "sDiffuse" }; const char *SamplerName[sMAX] = { "sDiffuse" };
const char *UniformName[uMAX] = { "uViewProj", "uModel", "uColor", "uAmbient", "uLightPos", "uLightColor" }; const char *UniformName[uMAX] = { "uViewProj", "uModel", "uColor", "uAmbient", "uLightPos", "uLightColor" };
struct Shader { struct Shader {
GLuint ID; GLuint ID;
GLint uID[uMAX]; GLint uID[uMAX];
Shader(const char *text) { Shader(const char *text) {
#define GLSL_DEFINE "#version 110\n" #define GLSL_DEFINE "#version 110\n"
const int type[2] = { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER }; const int type[2] = { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER };
const char *code[2][2] = { const char *code[2][2] = {
{ GLSL_DEFINE "#define VERTEX\n", text }, { GLSL_DEFINE "#define VERTEX\n", text },
{ GLSL_DEFINE "#define FRAGMENT\n", text } { GLSL_DEFINE "#define FRAGMENT\n", text }
}; };
GLchar info[256]; GLchar info[256];
ID = glCreateProgram(); ID = glCreateProgram();
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
GLuint obj = glCreateShader(type[i]); GLuint obj = glCreateShader(type[i]);
glShaderSource(obj, 2, code[i], NULL); glShaderSource(obj, 2, code[i], NULL);
glCompileShader(obj); glCompileShader(obj);
glGetShaderInfoLog(obj, sizeof(info), NULL, info);
if (info[0]) LOG("! shader: %s\n", info);
glAttachShader(ID, obj); glGetShaderInfoLog(obj, sizeof(info), NULL, info);
glDeleteShader(obj); if (info[0]) LOG("! shader: %s\n", info);
}
for (int at = 0; at < aMAX; at++) glAttachShader(ID, obj);
glBindAttribLocation(ID, at, AttribName[at]); glDeleteShader(obj);
}
glLinkProgram(ID); for (int at = 0; at < aMAX; at++)
glBindAttribLocation(ID, at, AttribName[at]);
glGetProgramInfoLog(ID, sizeof(info), NULL, info); glLinkProgram(ID);
if (info[0]) LOG("! program: %s\n", info);
bind(); glGetProgramInfoLog(ID, sizeof(info), NULL, info);
for (int st = 0; st < sMAX; st++) if (info[0]) LOG("! program: %s\n", info);
glUniform1iv(glGetUniformLocation(ID, (GLchar*)SamplerName[st]), 1, &st);
for (int ut = 0; ut < uMAX; ut++)
uID[ut] = glGetUniformLocation(ID, (GLchar*)UniformName[ut]);
}
virtual ~Shader() {
glDeleteProgram(ID);
}
void bind() { bind();
glUseProgram(ID); for (int st = 0; st < sMAX; st++)
} glUniform1iv(glGetUniformLocation(ID, (GLchar*)SamplerName[st]), 1, &st);
void setParam(UniformType uType, const vec3 &value, int count = 1) { for (int ut = 0; ut < uMAX; ut++)
if (uID[uType] != -1) uID[ut] = glGetUniformLocation(ID, (GLchar*)UniformName[ut]);
glUniform3fv(uID[uType], count, (GLfloat*)&value); }
}
void setParam(UniformType uType, const vec4 &value, int count = 1) { virtual ~Shader() {
if (uID[uType] != -1) glDeleteProgram(ID);
glUniform4fv(uID[uType], count, (GLfloat*)&value); }
}
void setParam(UniformType uType, const mat4 &value, int count = 1) { void bind() {
if (uID[uType] != -1) glUseProgram(ID);
glUniformMatrix4fv(uID[uType], count, false, (GLfloat*)&value); }
}
void setParam(UniformType uType, const vec3 &value, int count = 1) {
if (uID[uType] != -1)
glUniform3fv(uID[uType], count, (GLfloat*)&value);
}
void setParam(UniformType uType, const vec4 &value, int count = 1) {
if (uID[uType] != -1)
glUniform4fv(uID[uType], count, (GLfloat*)&value);
}
void setParam(UniformType uType, const mat4 &value, int count = 1) {
if (uID[uType] != -1)
glUniformMatrix4fv(uID[uType], count, false, (GLfloat*)&value);
}
}; };
#endif #endif

View File

@@ -4,27 +4,27 @@
#include "core.h" #include "core.h"
struct Texture { struct Texture {
GLuint ID; GLuint ID;
int width, height; int width, height;
Texture(int width, int height, int format, void *data) : width(width), height(height) { Texture(int width, int height, int format, void *data) : width(width), height(height) {
glGenTextures(1, &ID); glGenTextures(1, &ID);
bind(0); bind(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
} }
virtual ~Texture() { virtual ~Texture() {
glDeleteTextures(1, &ID); glDeleteTextures(1, &ID);
} }
void bind(int sampler) { void bind(int sampler) {
glActiveTexture(GL_TEXTURE0 + sampler); glActiveTexture(GL_TEXTURE0 + sampler);
glBindTexture(GL_TEXTURE_2D, ID); glBindTexture(GL_TEXTURE_2D, ID);
} }
}; };
#endif #endif

View File

@@ -131,23 +131,23 @@ struct quat {
w = cosf(angle); w = cosf(angle);
} }
quat quat::operator - () const { quat operator - () const {
return quat(-x, -y, -z, -w); return quat(-x, -y, -z, -w);
} }
quat quat::operator + (const quat &q) const { quat operator + (const quat &q) const {
return quat(x + q.x, y + q.y, z + q.z, w + q.w); return quat(x + q.x, y + q.y, z + q.z, w + q.w);
} }
quat quat::operator - (const quat &q) const { quat operator - (const quat &q) const {
return quat(x - q.x, y - q.y, z - q.z, w - q.w); return quat(x - q.x, y - q.y, z - q.z, w - q.w);
} }
quat quat::operator * (const float s) const { quat operator * (const float s) const {
return quat(x * s, y * s, z * s, w * s); return quat(x * s, y * s, z * s, w * s);
} }
quat quat::operator * (const quat &q) const { quat operator * (const quat &q) const {
return quat(w * q.x + x * q.w + y * q.z - z * q.y, return quat(w * q.x + x * q.w + y * q.z - z * q.y,
w * q.y + y * q.w + z * q.x - x * q.z, w * q.y + y * q.w + z * q.x - x * q.z,
w * q.z + z * q.w + x * q.y - y * q.x, w * q.z + z * q.w + x * q.y - y * q.x,
@@ -166,19 +166,19 @@ struct quat {
return sqrtf(length2()); return sqrtf(length2());
} }
void quat::normalize() { void normalize() {
*this = normal(); *this = normal();
} }
quat quat::normal() const { quat normal() const {
return *this * (1.0f / length()); return *this * (1.0f / length());
} }
quat quat::conjugate() const { quat conjugate() const {
return quat(-x, -y, -z, w); return quat(-x, -y, -z, w);
} }
quat quat::inverse() const { quat inverse() const {
return conjugate() * (1.0f / length2()); return conjugate() * (1.0f / length2());
} }
@@ -382,7 +382,7 @@ struct mat4 {
return r; return r;
} }
quat mat4::getRot() const { quat getRot() const {
float t, s; float t, s;
t = 1.0f + e00 + e11 + e22; t = 1.0f + e00 + e11 + e22;
if (t > EPS) { if (t > EPS) {
@@ -402,7 +402,7 @@ struct mat4 {
} }
} }
void mat4::setRot(const quat &rot) { void setRot(const quat &rot) {
float sx = rot.x * rot.x, float sx = rot.x * rot.x,
sy = rot.y * rot.y, sy = rot.y * rot.y,
sz = rot.z * rot.z, sz = rot.z * rot.z,
@@ -430,11 +430,11 @@ struct mat4 {
e12 = (t1 - t2) * inv; e12 = (t1 - t2) * inv;
} }
vec3 mat4::getPos() const { vec3 getPos() const {
return offset.xyz; return offset.xyz;
} }
void mat4::setPos(const vec3 &pos) { void setPos(const vec3 &pos) {
offset.xyz = pos; offset.xyz = pos;
} }
}; };

View File

@@ -1,246 +1,246 @@
#ifdef _DEBUG #ifdef _DEBUG
#include "crtdbg.h" #include "crtdbg.h"
#endif #endif
#include "game.h" #include "game.h"
DWORD getTime() { DWORD getTime() {
#ifdef DEBUG #ifdef DEBUG
LARGE_INTEGER Freq, Count; LARGE_INTEGER Freq, Count;
QueryPerformanceFrequency(&Freq); QueryPerformanceFrequency(&Freq);
QueryPerformanceCounter(&Count); QueryPerformanceCounter(&Count);
return (DWORD)(Count.QuadPart * 1000L / Freq.QuadPart); return (DWORD)(Count.QuadPart * 1000L / Freq.QuadPart);
#else #else
timeBeginPeriod(0); timeBeginPeriod(0);
return timeGetTime(); return timeGetTime();
#endif #endif
} }
InputKey keyToInputKey(int code) { InputKey keyToInputKey(int code) {
int codes[] = { int codes[] = {
VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_SPACE, VK_RETURN, VK_ESCAPE, VK_SHIFT, VK_CONTROL, VK_MENU, VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_SPACE, VK_RETURN, VK_ESCAPE, VK_SHIFT, VK_CONTROL, VK_MENU,
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
}; };
for (int i = 0; i < sizeof(codes) / sizeof(codes[0]); i++) for (int i = 0; i < sizeof(codes) / sizeof(codes[0]); i++)
if (codes[i] == code) if (codes[i] == code)
return (InputKey)(ikLeft + i); return (InputKey)(ikLeft + i);
return ikNone; return ikNone;
} }
InputKey mouseToInputKey(int msg) { InputKey mouseToInputKey(int msg) {
return (msg >= WM_LBUTTONDOWN || msg <= WM_LBUTTONDBLCLK) ? ikMouseL : return (msg >= WM_LBUTTONDOWN || msg <= WM_LBUTTONDBLCLK) ? ikMouseL :
(msg >= WM_RBUTTONDOWN || msg <= WM_RBUTTONDBLCLK) ? ikMouseR : ikMouseM; (msg >= WM_RBUTTONDOWN || msg <= WM_RBUTTONDBLCLK) ? ikMouseR : ikMouseM;
} }
#define JOY_DEAD_ZONE_STICK 0.3f #define JOY_DEAD_ZONE_STICK 0.3f
#define JOY_DEAD_ZONE_TRIGGER 0.01f #define JOY_DEAD_ZONE_TRIGGER 0.01f
bool joyReady; bool joyReady;
void joyInit() { void joyInit() {
JOYINFOEX info; JOYINFOEX info;
info.dwSize = sizeof(info); info.dwSize = sizeof(info);
info.dwFlags = JOY_RETURNALL; info.dwFlags = JOY_RETURNALL;
joyReady = joyGetPosEx(0, &info) == JOYERR_NOERROR; joyReady = joyGetPosEx(0, &info) == JOYERR_NOERROR;
} }
void joyFree() { void joyFree() {
joyReady = false; joyReady = false;
memset(&Input::joy, 0, sizeof(Input::joy)); memset(&Input::joy, 0, sizeof(Input::joy));
for (int ik = ikJoyA; ik <= ikJoyDP; ik++) for (int ik = ikJoyA; ik <= ikJoyDP; ik++)
Input::down[ik] = false; Input::down[ik] = false;
} }
float joyAxis(int x, int xMin, int xMax) { float joyAxis(int x, int xMin, int xMax) {
return ((x - xMin) / (float)(xMax - xMin)) * 2.0f - 1.0f; return ((x - xMin) / (float)(xMax - xMin)) * 2.0f - 1.0f;
} }
vec2 joyDir(float ax, float ay) { vec2 joyDir(float ax, float ay) {
vec2 dir = vec2(ax, ay); vec2 dir = vec2(ax, ay);
float dist = min(1.0f, dir.length()); float dist = min(1.0f, dir.length());
if (dist < JOY_DEAD_ZONE_STICK) dist = 0; if (dist < JOY_DEAD_ZONE_STICK) dist = 0;
return dir.normal() * dist; return dir.normal() * dist;
} }
void joyUpdate() { void joyUpdate() {
if (!joyReady) return; if (!joyReady) return;
JOYINFOEX info; JOYINFOEX info;
info.dwSize = sizeof(info); info.dwSize = sizeof(info);
info.dwFlags = JOY_RETURNALL; info.dwFlags = JOY_RETURNALL;
if (joyGetPosEx(0, &info) == JOYERR_NOERROR) { if (joyGetPosEx(0, &info) == JOYERR_NOERROR) {
JOYCAPS caps; JOYCAPS caps;
joyGetDevCaps(0, &caps, sizeof(caps)); joyGetDevCaps(0, &caps, sizeof(caps));
Input::setPos(ikJoyL, joyDir(joyAxis(info.dwXpos, caps.wXmin, caps.wXmax), Input::setPos(ikJoyL, joyDir(joyAxis(info.dwXpos, caps.wXmin, caps.wXmax),
joyAxis(info.dwYpos, caps.wYmin, caps.wYmax))); joyAxis(info.dwYpos, caps.wYmin, caps.wYmax)));
if ((caps.wCaps & JOYCAPS_HASR) && (caps.wCaps & JOYCAPS_HASU)) if ((caps.wCaps & JOYCAPS_HASR) && (caps.wCaps & JOYCAPS_HASU))
Input::setPos(ikJoyR, joyDir(joyAxis(info.dwUpos, caps.wUmin, caps.wUmax), Input::setPos(ikJoyR, joyDir(joyAxis(info.dwUpos, caps.wUmin, caps.wUmax),
joyAxis(info.dwRpos, caps.wRmin, caps.wRmax))); joyAxis(info.dwRpos, caps.wRmin, caps.wRmax)));
if (caps.wCaps & JOYCAPS_HASZ) { if (caps.wCaps & JOYCAPS_HASZ) {
float z = joyAxis(info.dwZpos, caps.wZmin, caps.wZmax); float z = joyAxis(info.dwZpos, caps.wZmin, caps.wZmax);
if (fabsf(z) > JOY_DEAD_ZONE_TRIGGER) if (fabsf(z) > JOY_DEAD_ZONE_TRIGGER)
Input::setPos(z > 0.0f ? ikJoyLT : ikJoyRT, vec2(fabsf(z), 0.0f)); Input::setPos(z > 0.0f ? ikJoyLT : ikJoyRT, vec2(fabsf(z), 0.0f));
} }
if (caps.wCaps & JOYCAPS_HASPOV && info.dwPOV != JOY_POVCENTERED)
Input::setPos(ikJoyDP, vec2((float)(1 + info.dwPOV / 4500), 0));
for (int i = 0; i < 10; i++) if (caps.wCaps & JOYCAPS_HASPOV && info.dwPOV != JOY_POVCENTERED)
Input::setDown((InputKey)(ikJoyA + i), (info.dwButtons & (1 << i)) > 0); Input::setPos(ikJoyDP, vec2((float)(1 + info.dwPOV / 4500), 0));
} else
joyFree(); for (int i = 0; i < 10; i++)
Input::setDown((InputKey)(ikJoyA + i), (info.dwButtons & (1 << i)) > 0);
} else
joyFree();
} }
static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) { switch (msg) {
case WM_ACTIVATE : case WM_ACTIVATE :
Input::reset(); Input::reset();
break; break;
// keyboard // keyboard
case WM_KEYDOWN : case WM_KEYDOWN :
case WM_KEYUP : case WM_KEYUP :
case WM_SYSKEYDOWN : case WM_SYSKEYDOWN :
case WM_SYSKEYUP : case WM_SYSKEYUP :
Input::setDown(keyToInputKey(wParam), msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN); Input::setDown(keyToInputKey(wParam), msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
break; break;
// mouse // mouse
case WM_LBUTTONDOWN : case WM_LBUTTONDOWN :
case WM_LBUTTONUP : case WM_LBUTTONUP :
case WM_LBUTTONDBLCLK : case WM_LBUTTONDBLCLK :
case WM_RBUTTONDOWN : case WM_RBUTTONDOWN :
case WM_RBUTTONUP : case WM_RBUTTONUP :
case WM_RBUTTONDBLCLK : case WM_RBUTTONDBLCLK :
case WM_MBUTTONDOWN : case WM_MBUTTONDOWN :
case WM_MBUTTONUP : case WM_MBUTTONUP :
case WM_MBUTTONDBLCLK : { case WM_MBUTTONDBLCLK : {
InputKey key = mouseToInputKey(msg); InputKey key = mouseToInputKey(msg);
Input::setPos(key, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam))); Input::setPos(key, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam)));
bool down = msg != WM_LBUTTONUP && msg != WM_RBUTTONUP && msg != WM_MBUTTONUP; bool down = msg != WM_LBUTTONUP && msg != WM_RBUTTONUP && msg != WM_MBUTTONUP;
Input::setDown(key, down); Input::setDown(key, down);
if (down) if (down)
SetCapture(hWnd); SetCapture(hWnd);
else else
ReleaseCapture(); ReleaseCapture();
break; break;
} }
case WM_MOUSEMOVE : case WM_MOUSEMOVE :
Input::setPos(ikMouseL, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam))); Input::setPos(ikMouseL, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam)));
break; break;
// gamepad // gamepad
case WM_DEVICECHANGE : case WM_DEVICECHANGE :
joyInit(); joyInit();
return 1; return 1;
// touch // touch
// ... // ...
case WM_SIZE : case WM_SIZE :
Core::width = LOWORD(lParam); Core::width = LOWORD(lParam);
Core::height = HIWORD(lParam); Core::height = HIWORD(lParam);
break; break;
case WM_DESTROY : case WM_DESTROY :
PostQuitMessage(0); PostQuitMessage(0);
break; break;
default : default :
return DefWindowProc(hWnd, msg, wParam, lParam); return DefWindowProc(hWnd, msg, wParam, lParam);
} }
return 0; return 0;
} }
HGLRC initGL(HDC hDC) { HGLRC initGL(HDC hDC) {
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd)); memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd); pfd.nSize = sizeof(pfd);
pfd.nVersion = 1; pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.cColorBits = 32; pfd.cColorBits = 32;
pfd.cDepthBits = 24; pfd.cDepthBits = 24;
int format = ChoosePixelFormat(hDC, &pfd); int format = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, format, &pfd); SetPixelFormat(hDC, format, &pfd);
HGLRC hRC = wglCreateContext(hDC); HGLRC hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC); wglMakeCurrent(hDC, hRC);
return hRC; return hRC;
} }
void freeGL(HGLRC hRC) { void freeGL(HGLRC hRC) {
wglMakeCurrent(0, 0); wglMakeCurrent(0, 0);
wglDeleteContext(hRC); wglDeleteContext(hRC);
} }
int main() { int main() {
#ifdef _DEBUG #ifdef _DEBUG
_CrtMemState _ms; _CrtMemState _ms;
_CrtMemCheckpoint(&_ms); _CrtMemCheckpoint(&_ms);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
#endif #endif
RECT r = { 0, 0, 1280, 720 }; RECT r = { 0, 0, 1280, 720 };
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false); AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false);
HWND hWnd = CreateWindow("static", "OpenLara", WS_OVERLAPPEDWINDOW, 0, 0, r.right - r.left, r.bottom - r.top, 0, 0, 0, 0); HWND hWnd = CreateWindow("static", "OpenLara", WS_OVERLAPPEDWINDOW, 0, 0, r.right - r.left, r.bottom - r.top, 0, 0, 0, 0);
joyInit(); joyInit();
HDC hDC = GetDC(hWnd); HDC hDC = GetDC(hWnd);
HGLRC hRC = initGL(hDC); HGLRC hRC = initGL(hDC);
Game::init(); Game::init();
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&WndProc); SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&WndProc);
ShowWindow(hWnd, SW_SHOWDEFAULT); ShowWindow(hWnd, SW_SHOWDEFAULT);
DWORD time, lastTime = getTime(); DWORD time, lastTime = getTime();
MSG msg;
msg.message = WM_PAINT;
DWORD fps = 0, fpsTime = getTime() + 1000;
while (msg.message != WM_QUIT) MSG msg;
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { msg.message = WM_PAINT;
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
time = getTime();
if (time <= lastTime)
continue;
Core::deltaTime = (time - lastTime) * 0.001f;
lastTime = time;
joyUpdate(); DWORD fps = 0, fpsTime = getTime() + 1000;
Core::stats.dips = 0; while (msg.message != WM_QUIT)
Core::stats.tris = 0; if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
time = getTime();
if (time <= lastTime)
continue;
Game::update(); Core::deltaTime = (time - lastTime) * 0.001f;
Game::render(); lastTime = time;
SwapBuffers(hDC); joyUpdate();
if (fpsTime < getTime()) { Core::stats.dips = 0;
LOG("FPS: %d DIP: %d TRI: %d\n", fps, Core::stats.dips, Core::stats.tris); Core::stats.tris = 0;
fps = 0;
fpsTime = getTime() + 1000;
} else
fps++;
}
Game::free();
freeGL(hRC);
ReleaseDC(hWnd, hDC);
DestroyWindow(hWnd); Game::update();
Game::render();
SwapBuffers(hDC);
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++;
}
Game::free();
freeGL(hRC);
ReleaseDC(hWnd, hDC);
DestroyWindow(hWnd);
#ifdef _DEBUG #ifdef _DEBUG
_CrtMemDumpAllObjectsSince(&_ms); _CrtMemDumpAllObjectsSince(&_ms);
system("pause"); system("pause");
#endif #endif
return 0; return 0;
} }