215 lines
6.4 KiB
C
215 lines
6.4 KiB
C
#include <stddef.h>
|
|
#include <math.h>
|
|
#include <zoom/player.h>
|
|
#include <zoom/level.h>
|
|
#include <zoom/collision.h>
|
|
#include <zoom/math.h>
|
|
|
|
int input = 0;
|
|
int falling = 0;
|
|
|
|
PLAYER player = {
|
|
{0.0, 0.0, 0.0},
|
|
0.0, 0.0, 1.0,
|
|
100, 100, 0
|
|
};
|
|
|
|
float rotx = 0, roty = 0;
|
|
float rotxspeed = 0, rotyspeed = 0;
|
|
|
|
float objrot = 0;
|
|
|
|
extern LEVEL level;
|
|
|
|
void MouseInput(int x, int y) {
|
|
roty += x * 0.3;
|
|
rotx += y * 0.3;
|
|
|
|
rotxspeed = rotx * 0.02;
|
|
rotyspeed = roty * 0.02;
|
|
}
|
|
|
|
void DoInput(int delta) {
|
|
int i, wasfalling = falling;
|
|
int g;
|
|
VERTEX pos;
|
|
int room = player.room;
|
|
VECTOR move = {0.0, 0.0, 0.0};
|
|
VECTOR v = {0.0, -1.0, 0.0};
|
|
float s, c;
|
|
float f = 0.0;
|
|
VERTEX p1, p2;
|
|
VECTOR v1, v2;
|
|
MATRIX transform;
|
|
|
|
objrot += 0.01*delta;
|
|
if(objrot > 360.0) objrot -= 360.0;
|
|
|
|
if(rotx > 0) {
|
|
if(rotx < rotxspeed*delta) {player.rotx += rotx; rotx = 0;}
|
|
else {player.rotx += rotxspeed*delta; rotx -= rotxspeed*delta;}
|
|
}
|
|
else if(rotx < 0) {
|
|
if(rotx > rotxspeed*delta) {player.rotx += rotx; rotx = 0;}
|
|
else {player.rotx += rotxspeed*delta; rotx -= rotxspeed*delta;}
|
|
}
|
|
if(roty > 0) {
|
|
if(roty < rotyspeed*delta) {f = roty; roty = 0;}
|
|
else {f = rotyspeed*delta; roty -= rotyspeed*delta;}
|
|
}
|
|
else if(roty < 0) {
|
|
if(roty > rotyspeed*delta) {f = roty; roty = 0;}
|
|
else {f = rotyspeed*delta; roty -= rotyspeed*delta;}
|
|
}
|
|
|
|
if(player.rotx > 60) player.rotx = 60;
|
|
else if(player.rotx < -60) player.rotx = -60;
|
|
|
|
s = sin(f/180*M_PI);
|
|
c = cos(f/180*M_PI);
|
|
f = c*player.rotycos - s*player.rotysin;
|
|
player.rotysin = c*player.rotysin + s*player.rotycos;
|
|
player.rotycos = f;
|
|
|
|
s = player.rotysin;
|
|
c = player.rotycos;
|
|
|
|
if(!falling) {
|
|
if((input & INPUT_UP) && !(input & INPUT_DOWN)) {
|
|
if((input & INPUT_RIGHT) && !(input & INPUT_LEFT)) {
|
|
move.x = (s+c)*M_SQRT1_2;
|
|
move.z = (s-c)*M_SQRT1_2;
|
|
}
|
|
else if((input & INPUT_LEFT) && !(input & INPUT_RIGHT)) {
|
|
move.x = (s-c)*M_SQRT1_2;
|
|
move.z = (-s-c)*M_SQRT1_2;
|
|
}
|
|
else {
|
|
move.x = s;
|
|
move.z = -c;
|
|
}
|
|
}
|
|
else if((input & INPUT_DOWN) && !(input & INPUT_UP)) {
|
|
if((input & INPUT_RIGHT) && !(input & INPUT_LEFT)) {
|
|
move.x = (-s+c)*M_SQRT1_2;
|
|
move.z = (s+c)*M_SQRT1_2;
|
|
}
|
|
else if((input & INPUT_LEFT) && !(input & INPUT_RIGHT)) {
|
|
move.x = (-s-c)*M_SQRT1_2;
|
|
move.z = (-s+c)*M_SQRT1_2;
|
|
}
|
|
else {
|
|
move.x = -s;
|
|
move.z = c;
|
|
}
|
|
}
|
|
else if((input & INPUT_RIGHT) && !(input & INPUT_LEFT)) {
|
|
move.x = c;
|
|
move.z = s;
|
|
}
|
|
else if((input & INPUT_LEFT) && !(input & INPUT_RIGHT)) {
|
|
move.x = -c;
|
|
move.z = -s;
|
|
}
|
|
if(input & INPUT_OPEN) {
|
|
for(i = 0; i < level.rooms[room].nGates; i++) {
|
|
if(level.rooms[room].gateinfo[i].state != STATE_CLOSED) continue;
|
|
if(CollisionSphereTriangle(player.pos, 1.0, level.rooms[room].gates[i].triangles[0]) ||
|
|
CollisionSphereTriangle(player.pos, 1.0, level.rooms[room].gates[i].triangles[1])) {
|
|
level.rooms[room].gateinfo[i].state = STATE_OPENING;
|
|
level.rooms[room].gateinfo[i].timer = 1000;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pos = VectorAdd(player.pos, VectorMul(move, delta/150.0));
|
|
|
|
if(falling) pos.y -= delta/100.0;
|
|
|
|
for(i = 0; i < level.rooms[room].nGates; i++) {
|
|
if(CollisionSphereTriangle(pos, 0.3, level.rooms[room].gates[i].triangles[0]) ||
|
|
CollisionSphereTriangle(pos, 0.3, level.rooms[room].gates[i].triangles[1])) {
|
|
if(level.rooms[room].gateinfo[i].state == STATE_OPENED) {
|
|
if(CollisionPointTriangle(pos, level.rooms[room].gates[i].triangles[0]) ||
|
|
CollisionPointTriangle(pos, level.rooms[room].gates[i].triangles[1])) {
|
|
p1 = level.rooms[room].gates[i].point;
|
|
v1 = level.rooms[room].gates[i].triangles[0].normal;
|
|
level.rooms[room].gateinfo[i].state = STATE_CLOSED;
|
|
g = level.rooms[room].gates[i].gate;
|
|
room = level.rooms[room].gates[i].room;
|
|
p2 = level.rooms[room].gates[g].point;
|
|
v2 = VectorNeg(level.rooms[room].gates[g].triangles[0].normal);
|
|
level.rooms[room].gateinfo[g].state = STATE_OPENED;
|
|
level.rooms[room].gateinfo[g].timer = 5000;
|
|
transform = VectorMatrix(p2, v2, p1, v1);
|
|
pos = VectorMatrixMul(pos, transform);
|
|
v1.x = p1.x + c;
|
|
v1.z = p1.z + s;
|
|
v1 = VectorMatrixMul(v1, transform);
|
|
c = v1.x - p2.x;
|
|
s = v1.z - p2.z;
|
|
move = VectorSub(VectorMatrixMul(VectorAdd(move, p1), transform), p2);
|
|
break;
|
|
}
|
|
level.rooms[room].gateinfo[i].timer = 5000;
|
|
}
|
|
else pos = player.pos;
|
|
}
|
|
}
|
|
falling = 1;
|
|
for(i = 0; i < level.rooms[room].nTriangles; i++) {
|
|
if(level.rooms[room].triangles[i].type == TRIANGLE_WALL &&
|
|
CollisionMovingSphereTriangle(VectorSub(pos, VectorMul(move, delta/150.0)), 0.3, move, delta/150.0, level.rooms[room].triangles[i])) {
|
|
pos = player.pos;
|
|
if(player.room != room) {
|
|
level.rooms[room].gateinfo[g].state = STATE_CLOSED;
|
|
g = level.rooms[room].gates[g].gate;
|
|
room = player.room;
|
|
level.rooms[room].gateinfo[g].state = STATE_OPENED;
|
|
}
|
|
s = player.rotysin;
|
|
c = player.rotycos;
|
|
falling = 0;
|
|
break;
|
|
}
|
|
else if(level.rooms[room].triangles[i].type == TRIANGLE_FLOOR) {
|
|
pos.y -= 1.81;
|
|
if(CollisionPointTriangle(pos, level.rooms[room].triangles[i])) {
|
|
falling = 0;
|
|
pos.y += 1.81;
|
|
if(wasfalling && CollisionRayTriangle(pos, v, level.rooms[room].triangles[i], &f)) pos.y -= f - 1.8;
|
|
}
|
|
else pos.y += 1.81;
|
|
}
|
|
}
|
|
player.pos = pos;
|
|
player.room = room;
|
|
player.rotysin = s;
|
|
player.rotycos = c;
|
|
|
|
for(i = 0; i < level.rooms[player.room].nObjects; i++) {
|
|
pos = VectorSub(level.rooms[player.room].objects[i].pos, player.pos);
|
|
pos.y += 0.9;
|
|
switch(level.rooms[player.room].objects[i].type) {
|
|
case OBJECT_MEDIPAK100:
|
|
if((pos.x*pos.x + (pos.y*pos.y)/3 + pos.z*pos.z) < 0.36) level.rooms[player.room].objects[i].visible = 0;
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < level.rooms[player.room].nGates; i++) {
|
|
if(level.rooms[player.room].gateinfo[i].state == STATE_CLOSED) continue;
|
|
if((level.rooms[player.room].gateinfo[i].timer - delta) < 0) {
|
|
if(level.rooms[player.room].gateinfo[i].state == STATE_OPENING) {
|
|
level.rooms[player.room].gateinfo[i].state = STATE_OPENED;
|
|
level.rooms[player.room].gateinfo[i].timer = 5000;
|
|
}
|
|
else if(level.rooms[player.room].gateinfo[i].state == STATE_OPENED) {
|
|
level.rooms[player.room].gateinfo[i].state = STATE_CLOSING;
|
|
level.rooms[player.room].gateinfo[i].timer = 1000;
|
|
}
|
|
else level.rooms[player.room].gateinfo[i].state = STATE_CLOSED;
|
|
}
|
|
else level.rooms[player.room].gateinfo[i].timer -= delta;
|
|
}
|
|
}
|