new level test
[deeprace] / src / scr_game.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <GL/gl.h>
5 #include "miniglut.h"
6 #include "game.h"
7 #include "util.h"
8 #include "goat3d.h"
9
10 static int ginit(void);
11 static void gdestroy(void);
12 static int gstart(void);
13 static void gstop(void);
14 static void gdisplay(void);
15 static void greshape(int x, int y);
16 static void gkeyb(int key, int press);
17 static void gmouse(int bn, int press, int x, int y);
18 static void gmotion(int x, int y);
19
20 struct game_screen scr_game = {
21         "game",
22         ginit, gdestroy,
23         gstart, gstop,
24         gdisplay, greshape,
25         gkeyb, gmouse, gmotion
26 };
27
28 static float cam_theta, cam_phi = 20, cam_dist = 10;
29 static float cam_pan[3];
30
31 static struct goat3d *gscn;
32 static int dlist;
33
34
35 static int ginit(void)
36 {
37         int i, num, nfaces;
38         int *idxarr;
39         float *varr, *narr, *uvarr;
40         float xform[16];
41
42         if(!(gscn = goat3d_create()) || goat3d_load(gscn, "data/level1.g3d")) {
43                 return -1;
44         }
45
46         dlist = glGenLists(1);
47         glNewList(dlist, GL_COMPILE);
48         num = goat3d_get_node_count(gscn);
49         for(i=0; i<num; i++) {
50                 struct goat3d_node *node = goat3d_get_node(gscn, i);
51                 if(match_prefix(goat3d_get_node_name(node), "portal_")) {
52                         continue;
53                 }
54                 if(goat3d_get_node_type(node) == GOAT3D_NODE_MESH) {
55                         struct goat3d_mesh *mesh = goat3d_get_node_object(node);
56
57                         goat3d_get_node_matrix(node, xform);
58                         glPushMatrix();
59                         glMultMatrixf(xform);
60
61                         varr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX);
62                         narr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL);
63                         uvarr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD);
64
65                         glEnableClientState(GL_VERTEX_ARRAY);
66                         glVertexPointer(3, GL_FLOAT, 0, varr);
67
68                         if(narr) {
69                                 glEnableClientState(GL_NORMAL_ARRAY);
70                                 glNormalPointer(GL_FLOAT, 0, narr);
71                         }
72                         if(uvarr) {
73                                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
74                                 glTexCoordPointer(2, GL_FLOAT, 0, uvarr);
75                         }
76
77                         nfaces = goat3d_get_mesh_face_count(mesh);
78                         idxarr = goat3d_get_mesh_faces(mesh);
79                         glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, idxarr);
80
81                         glDisableClientState(GL_VERTEX_ARRAY);
82                         glDisableClientState(GL_NORMAL_ARRAY);
83                         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
84
85                         glPopMatrix();
86                 }
87         }
88         glEndList();
89
90         return 0;
91 }
92
93 static void gdestroy(void)
94 {
95         goat3d_free(gscn);
96 }
97
98 static int gstart(void)
99 {
100         return 0;
101 }
102
103 static void gstop(void)
104 {
105 }
106
107 static void gdisplay(void)
108 {
109         glMatrixMode(GL_MODELVIEW);
110         glLoadIdentity();
111         glTranslatef(0, 0, -cam_dist);
112         glRotatef(cam_phi, 1, 0, 0);
113         glRotatef(cam_theta, 0, 1, 0);
114         glTranslatef(cam_pan[0], cam_pan[1], cam_pan[2]);
115
116         glCallList(dlist);
117 }
118
119 static void greshape(int x, int y)
120 {
121 }
122
123 static void gkeyb(int key, int press)
124 {
125 }
126
127 static void gmouse(int bn, int press, int x, int y)
128 {
129 }
130
131 static void gmotion(int x, int y)
132 {
133         int dx = x - mouse_x;
134         int dy = y - mouse_y;
135
136         if(!(dx | dy)) return;
137
138         if(mouse_state[0]) {
139                 cam_theta += dx * 0.5;
140                 cam_phi += dy * 0.5;
141                 if(cam_phi < -90) cam_phi = -90;
142                 if(cam_phi > 90) cam_phi = 90;
143         }
144         if(mouse_state[1]) {
145                 float up[3], right[3];
146                 float theta = cam_theta * M_PI / 180.0f;
147                 float phi = cam_phi * M_PI / 180.0f;
148
149                 up[0] = -sin(theta) * sin(phi);
150                 up[1] = -cos(phi);
151                 up[2] = cos(theta) * sin(phi);
152                 right[0] = cos(theta);
153                 right[1] = 0;
154                 right[2] = sin(theta);
155
156                 cam_pan[0] += (right[0] * dx + up[0] * dy) * 0.01;
157                 cam_pan[1] += up[1] * dy * 0.01;
158                 cam_pan[2] += (right[2] * dx + up[2] * dy) * 0.01;
159         }
160         if(mouse_state[2]) {
161                 cam_dist += dy * 0.1;
162                 if(cam_dist < 0) cam_dist = 0;
163         }
164 }