test input
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 1 Apr 2023 02:50:10 +0000 (05:50 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 1 Apr 2023 02:50:10 +0000 (05:50 +0300)
src/game.c
src/input.c [new file with mode: 0644]
src/input.h [new file with mode: 0644]
src/scr_game.c

index 7b33ee2..e11543f 100644 (file)
@@ -3,6 +3,7 @@
 #include <GL/gl.h>
 #include <GL/glu.h>
 #include "game.h"
+#include "input.h"
 
 int mouse_x, mouse_y, mouse_state[3];
 int win_width, win_height;
@@ -40,6 +41,8 @@ int game_init(void)
                game_chscr(&scr_game);  /* TODO: scr_menu */
        }
 
+       init_input();
+
        glClearColor(0.1, 0.1, 0.1, 1);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_CULL_FACE);
diff --git a/src/input.c b/src/input.c
new file mode 100644 (file)
index 0000000..3e57f7e
--- /dev/null
@@ -0,0 +1,23 @@
+#include <string.h>
+#include "input.h"
+
+static const struct input_map def_inpmap[MAX_INPUTS] = {
+       {INP_FWD, 'w', -1},
+       {INP_BACK, 's', -1},
+       {INP_LEFT, 'a', -1},
+       {INP_RIGHT, 'd', -1},
+       {INP_FIRE, ' ', 0},
+       {INP_LROLL, 'q', -1},
+       {INP_RROLL, 'e', -1}
+};
+
+struct input_map inpmap[MAX_INPUTS];
+
+unsigned int inpstate;
+
+
+void init_input(void)
+{
+       memcpy(inpmap, def_inpmap, sizeof inpmap);
+       inpstate = 0;
+}
diff --git a/src/input.h b/src/input.h
new file mode 100644 (file)
index 0000000..a969d8e
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef INPUT_H_
+#define INPUT_H_
+
+/* game input actions */
+enum {
+       INP_FWD,
+       INP_BACK,
+       INP_LEFT,
+       INP_RIGHT,
+       INP_FIRE,
+       INP_LROLL,
+       INP_RROLL,
+
+       MAX_INPUTS
+};
+
+#define INP_FWD_BIT            (1 << INP_FWD)
+#define INP_BACK_BIT   (1 << INP_BACK)
+#define INP_LEFT_BIT   (1 << INP_LEFT)
+#define INP_RIGHT_BIT  (1 << INP_RIGHT)
+#define INP_FIRE_BIT   (1 << INP_FIRE)
+#define INP_LROLL_BIT  (1 << INP_LROLL)
+#define INP_RROLL_BIT  (1 << INP_RROLL)
+
+#define INP_MOVE_BITS  \
+       (INP_FWD_BIT | INP_BACK_BIT | INP_LEFT_BIT | INP_RIGHT_BIT)
+
+struct input_map {
+       int inp, key, mbn;
+};
+extern struct input_map inpmap[MAX_INPUTS];
+
+extern unsigned int inpstate;
+
+void init_input(void);
+
+#endif /* INPUT_H_ */
index d91e765..98f5d76 100644 (file)
@@ -6,6 +6,8 @@
 #include "game.h"
 #include "util.h"
 #include "goat3d.h"
+#include "input.h"
+#include "cgmath/cgmath.h"
 
 static int ginit(void);
 static void gdestroy(void);
@@ -17,6 +19,10 @@ static void gkeyb(int key, int press);
 static void gmouse(int bn, int press, int x, int y);
 static void gmotion(int x, int y);
 
+static void set_light_dir(int idx, float x, float y, float z);
+static void set_light_color(int idx, float r, float g, float b, float s);
+
+
 struct game_screen scr_game = {
        "game",
        ginit, gdestroy,
@@ -25,8 +31,8 @@ struct game_screen scr_game = {
        gkeyb, gmouse, gmotion
 };
 
-static float cam_theta, cam_phi = 20, cam_dist = 10;
-static float cam_pan[3];
+static float cam_theta, cam_phi = 20, cam_dist;
+static cgm_vec3 cam_pan;
 
 static struct goat3d *gscn;
 static int dlist;
@@ -97,6 +103,16 @@ static void gdestroy(void)
 
 static int gstart(void)
 {
+       float amb[] = {0.25, 0.25, 0.25, 1};
+
+       glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
+
+       set_light_color(0, 1, 1, 1, 0.8);
+       glEnable(GL_LIGHT0);
+       set_light_color(1, 1, 0.6, 0.5, 0.2);
+       glEnable(GL_LIGHT1);
+       set_light_color(2, 0.5, 0.6, 1, 0.3);
+       glEnable(GL_LIGHT2);
        return 0;
 }
 
@@ -104,14 +120,68 @@ static void gstop(void)
 {
 }
 
+#define TSTEP  (1.0f / 30.0f)
+
+static void gupdate(void)
+{
+       if(inpstate & INP_MOVE_BITS) {
+               cgm_vec3 fwd, right;
+               float theta = cam_theta * M_PI / 180.0f;
+               float phi = cam_phi * M_PI / 180.0f;
+
+               float dx = 0, dy = 0;
+
+               fwd.x = -sin(theta) * cos(phi);
+               fwd.y = sin(phi);
+               fwd.z = cos(theta) * cos(phi);
+               right.x = cos(theta);
+               right.y = 0;
+               right.z = sin(theta);
+
+               if(inpstate & INP_FWD_BIT) {
+                       dy += 0.1;
+               }
+               if(inpstate & INP_BACK_BIT) {
+                       dy -= 0.1;
+               }
+               if(inpstate & INP_RIGHT_BIT) {
+                       dx -= 0.1;
+               }
+               if(inpstate & INP_LEFT_BIT) {
+                       dx += 0.1;
+               }
+
+               cam_pan.x += right.x * dx + fwd.x * dy;
+               cam_pan.y += fwd.y * dy;
+               cam_pan.z += right.z * dx + fwd.z * dy;
+       }
+}
+
 static void gdisplay(void)
 {
+       static long prev_msec;
+       static float tm_acc;
+       long msec;
+
+       msec = glutGet(GLUT_ELAPSED_TIME);
+       tm_acc += (float)(msec - prev_msec) / 1000.0f;
+       prev_msec = msec;
+
+       while(tm_acc >= TSTEP) {
+               gupdate();
+               tm_acc -= TSTEP;
+       }
+
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0, 0, -cam_dist);
        glRotatef(cam_phi, 1, 0, 0);
        glRotatef(cam_theta, 0, 1, 0);
-       glTranslatef(cam_pan[0], cam_pan[1], cam_pan[2]);
+       glTranslatef(cam_pan.x, cam_pan.y, cam_pan.z);
+
+       set_light_dir(0, -1, 1, 5);
+       set_light_dir(1, 5, 0, 3);
+       set_light_dir(2, -0.5, -2, -3);
 
        glCallList(dlist);
 }
@@ -122,6 +192,18 @@ static void greshape(int x, int y)
 
 static void gkeyb(int key, int press)
 {
+       int i;
+
+       for(i=0; i<MAX_INPUTS; i++) {
+               if(inpmap[i].key == key) {
+                       if(press) {
+                               inpstate |= 1 << inpmap[i].inp;
+                       } else {
+                               inpstate &= ~(1 << inpmap[i].inp);
+                       }
+                       break;
+               }
+       }
 }
 
 static void gmouse(int bn, int press, int x, int y)
@@ -141,6 +223,7 @@ static void gmotion(int x, int y)
                if(cam_phi < -90) cam_phi = -90;
                if(cam_phi > 90) cam_phi = 90;
        }
+       /*
        if(mouse_state[1]) {
                float up[3], right[3];
                float theta = cam_theta * M_PI / 180.0f;
@@ -157,8 +240,31 @@ static void gmotion(int x, int y)
                cam_pan[1] += up[1] * dy * 0.01;
                cam_pan[2] += (right[2] * dx + up[2] * dy) * 0.01;
        }
+       */
        if(mouse_state[2]) {
                cam_dist += dy * 0.1;
                if(cam_dist < 0) cam_dist = 0;
        }
 }
+
+static void set_light_dir(int idx, float x, float y, float z)
+{
+       float pos[4];
+       pos[0] = x;
+       pos[1] = y;
+       pos[2] = z;
+       pos[3] = 0;
+       glLightfv(GL_LIGHT0 + idx, GL_POSITION, pos);
+}
+
+static void set_light_color(int idx, float r, float g, float b, float s)
+{
+       float color[4];
+       color[0] = r * s;
+       color[1] = g * s;
+       color[2] = b * s;
+       color[3] = 1;
+       glLightfv(GL_LIGHT0 + idx, GL_DIFFUSE, color);
+       glLightfv(GL_LIGHT0 + idx, GL_SPECULAR, color);
+}
+