fixed endianess issue in goat3d file reading
[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, j, num, nfaces;
38         int *idxarr;
39         float *varr, *narr, *uvarr;
40         float xform[16];
41
42         if(!(gscn = goat3d_create()) || goat3d_load(gscn, "data/track1.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(goat3d_get_node_type(node) == GOAT3D_NODE_MESH) {
52                         struct goat3d_mesh *mesh = goat3d_get_node_object(node);
53
54                         goat3d_get_node_matrix(node, xform);
55                         glPushMatrix();
56                         glMultMatrixf(xform);
57
58                         varr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX);
59                         narr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL);
60                         uvarr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD);
61
62                         glEnableClientState(GL_VERTEX_ARRAY);
63                         glVertexPointer(3, GL_FLOAT, 0, varr);
64
65                         if(narr) {
66                                 glEnableClientState(GL_NORMAL_ARRAY);
67                                 glNormalPointer(GL_FLOAT, 0, narr);
68                         }
69                         if(uvarr) {
70                                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
71                                 glTexCoordPointer(2, GL_FLOAT, 0, uvarr);
72                         }
73
74                         nfaces = goat3d_get_mesh_face_count(mesh);
75                         idxarr = goat3d_get_mesh_faces(mesh);
76                         glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, idxarr);
77
78                         glDisableClientState(GL_VERTEX_ARRAY);
79                         glDisableClientState(GL_NORMAL_ARRAY);
80                         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
81
82                         glPopMatrix();
83                 }
84         }
85         glEndList();
86
87         return 0;
88 }
89
90 static void gdestroy(void)
91 {
92         goat3d_free(gscn);
93 }
94
95 static int gstart(void)
96 {
97         return 0;
98 }
99
100 static void gstop(void)
101 {
102 }
103
104 static void gdisplay(void)
105 {
106         glMatrixMode(GL_MODELVIEW);
107         glLoadIdentity();
108         glTranslatef(0, 0, -cam_dist);
109         glRotatef(cam_phi, 1, 0, 0);
110         glRotatef(cam_theta, 0, 1, 0);
111         glTranslatef(cam_pan[0], cam_pan[1], cam_pan[2]);
112
113         glCallList(dlist);
114 }
115
116 static void greshape(int x, int y)
117 {
118 }
119
120 static void gkeyb(int key, int press)
121 {
122 }
123
124 static void gmouse(int bn, int press, int x, int y)
125 {
126 }
127
128 static void gmotion(int x, int y)
129 {
130         int dx = x - mouse_x;
131         int dy = y - mouse_y;
132
133         if(!(dx | dy)) return;
134
135         if(mouse_state[0]) {
136                 cam_theta += dx * 0.5;
137                 cam_phi += dy * 0.5;
138                 if(cam_phi < -90) cam_phi = -90;
139                 if(cam_phi > 90) cam_phi = 90;
140         }
141         if(mouse_state[1]) {
142                 float up[3], right[3];
143                 float theta = cam_theta * M_PI / 180.0f;
144                 float phi = cam_phi * M_PI / 180.0f;
145
146                 up[0] = -sin(theta) * sin(phi);
147                 up[1] = -cos(phi);
148                 up[2] = cos(theta) * sin(phi);
149                 right[0] = cos(theta);
150                 right[1] = 0;
151                 right[2] = sin(theta);
152
153                 cam_pan[0] += (right[0] * dx + up[0] * dy) * 0.01;
154                 cam_pan[1] += up[1] * dy * 0.01;
155                 cam_pan[2] += (right[2] * dx + up[2] * dy) * 0.01;
156         }
157         if(mouse_state[2]) {
158                 cam_dist += dy * 0.1;
159                 if(cam_dist < 0) cam_dist = 0;
160         }
161 }