This repository has been archived on 2025-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
neofx-libzoom/player.c
neoraider a5aa4b54e2 libzoom: XML level loader implemented.
zoom: Converted old test level to XML.
2007-05-14 17:38:01 +00:00

252 lines
7.1 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;
}
}