summaryrefslogtreecommitdiffstats
path: root/player.c
diff options
context:
space:
mode:
Diffstat (limited to 'player.c')
-rw-r--r--player.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/player.c b/player.c
new file mode 100644
index 0000000..f8195c0
--- /dev/null
+++ b/player.c
@@ -0,0 +1,215 @@
+#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;
+ }
+}