252 lines
7.2 KiB
C
252 lines
7.2 KiB
C
#include <stddef.h>
|
|
#include <math.h>
|
|
#include <zoom/player.h>
|
|
#include <zoom/level.h>
|
|
#include <zoom/light.h>
|
|
#include <neofx/collision.h>
|
|
#include <neofx/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;
|
|
extern int nLights;
|
|
extern LIGHT *lights;
|
|
|
|
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].walls[0].triangle) ||
|
|
CollisionSphereTriangle(player.pos, 1.0, level->rooms[room].gates[i].walls[1].triangle)) {
|
|
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].walls[0].triangle) ||
|
|
CollisionSphereTriangle(pos, 0.3, level->rooms[room].gates[i].walls[1].triangle)) {
|
|
if(level->rooms[room].gateinfo[i].state == STATE_OPENED) {
|
|
if(CollisionPointTriangle(pos, level->rooms[room].gates[i].walls[0].triangle) ||
|
|
CollisionPointTriangle(pos, level->rooms[room].gates[i].walls[1].triangle)) {
|
|
p1 = level->rooms[room].gates[i].point;
|
|
v1 = level->rooms[room].gates[i].walls[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].walls[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].nWalls; i++) {
|
|
if(/*level->rooms[room].walls[i].type == TRIANGLE_WALL &&*/
|
|
CollisionMovingSphereTriangle(VectorSub(pos, VectorMul(move, delta/150.0)), 0.3, move, delta/150.0, level->rooms[room].walls[i].triangle)) {
|
|
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].walls[i].type == TRIANGLE_FLOOR) {
|
|
pos.y -= 1.81;
|
|
if(CollisionPointTriangle(pos, level->rooms[room].walls[i].triangle)) {
|
|
falling = 0;
|
|
pos.y += 1.81;
|
|
if(wasfalling && CollisionRayTriangle(pos, v, level->rooms[room].walls[i].triangle, &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].nThings; i++) {
|
|
pos = VectorSub(level->rooms[player.room].things[i].pos, player.pos);
|
|
pos.y += 0.9;
|
|
switch(level->rooms[player.room].things[i].type) {
|
|
case THING_MEDIPAK100:
|
|
if((pos.x*pos.x + (pos.y*pos.y)/3 + pos.z*pos.z) < 0.36) level->rooms[player.room].things[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;
|
|
}*/
|
|
|
|
static int lightpos = 0;
|
|
|
|
lightpos += delta;
|
|
lightpos %= 24000;
|
|
|
|
if(lightpos < 12000) i = lightpos;
|
|
else i = 24000 - lightpos;
|
|
|
|
if(i == 0) {
|
|
lights[0].pos.x = 0.0;
|
|
lights[0].pos.y = 0.0;
|
|
lights[0].pos.z = 0.0;
|
|
}
|
|
else if(i < 4000) {
|
|
lights[0].pos.x = 0.0;
|
|
lights[0].pos.y = 0.0;
|
|
lights[0].pos.z = -i * 0.001;
|
|
}
|
|
else if(i < 8000) {
|
|
lights[0].pos.x = (i-4000) * 0.001;
|
|
lights[0].pos.y = 0.0;
|
|
lights[0].pos.z = -4.0;
|
|
}
|
|
else if(i < 12000) {
|
|
lights[0].pos.x = 4.0;
|
|
lights[0].pos.y = 0.0;
|
|
lights[0].pos.z = -4.0 - (i-8000) * 0.001;
|
|
}
|
|
else {
|
|
lights[0].pos.x = 4.0;
|
|
lights[0].pos.y = 0.0;
|
|
lights[0].pos.z = -8.0;
|
|
}
|
|
}
|