Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 766 lines (667 sloc) 16.009 kb
c1c057a @pbrook Initial 3D rendering.
authored
1 /* OpenGL 2.0 setup and rendering code.
2 Copyright (C) 2011 Paul Brook
3 This code is licenced under the GNU GPL v3 */
4 #include "chuckie.h"
5
e434ad0 @pbrook Add spinny demo mode.
authored
6 #include <math.h>
c1c057a @pbrook Initial 3D rendering.
authored
7 #include <SDL.h>
8 #define GL_GLEXT_PROTOTYPES
9
10 #include "raster.h"
11 #include "model.h"
12
e434ad0 @pbrook Add spinny demo mode.
authored
13 #define DEPTH 1280.0f
c1c057a @pbrook Initial 3D rendering.
authored
14
15 static int fullscreen = 0;
16 static int scale = 2;
d420051 @pbrook Add legacy fixed-function rendering path.
authored
17 static int shaders = 1;
e2530ac @pbrook Improve rotation controls.
authored
18 extern int projection_mode;
e434ad0 @pbrook Add spinny demo mode.
authored
19
20 extern float rotate_x;
21 extern float rotate_y;
c1c057a @pbrook Initial 3D rendering.
authored
22
23 raster_hooks *raster = NULL;
24
25 static SDL_Surface *sdlscreen;
26
27 void die(const char *msg, ...)
28 {
29 va_list va;
30 va_start(va, msg);
31 fprintf(stderr, "Error: ");
32 vfprintf(stderr, msg, va);
33 va_end(va);
34 exit(1);
35 }
36
37 static Uint32 do_timer(Uint32 interval, void *param)
38 {
39 SDL_Event event;
40 event.type = SDL_USEREVENT;
41 SDL_PushEvent(&event);
42 return interval;
43 }
44
45 static const GLchar *vertex_code = " \
46 #version 110 \n\
47 attribute vec3 position; \n\
48 uniform mat4 proj; \n\
49 void main() \n\
50 { \n\
8a9b475 @pbrook Optimize shaders. Animate models.
authored
51 gl_Position = proj * vec4(position, 1.0); \n\
c1c057a @pbrook Initial 3D rendering.
authored
52 } \n\
53 ";
54
55 static const GLchar *fragment_code = " \
56 #version 110 \n\
57 uniform vec3 color; \n\
58 void main() \n\
59 { \n\
60 gl_FragColor = vec4(color, 1.0f); \n\
61 } \n\
62 ";
63
64 GLuint vertex_shader;
65 GLuint fragment_shader;
66 GLuint program;
67 GLuint attr_position;
68 GLuint param_color;
69 GLuint param_world;
70 GLuint param_proj;
71
72 static void show_info_log(GLuint object, PFNGLGETSHADERIVPROC glGet__iv,
73 PFNGLGETSHADERINFOLOGPROC glGet__InfoLog)
74 {
75 GLint log_length;
76 char *log;
77
78 glGet__iv(object, GL_INFO_LOG_LENGTH, &log_length);
79 log = malloc(log_length);
80 glGet__InfoLog(object, log_length, NULL, log);
81 fprintf(stderr, "%s", log);
82 free(log);
83 }
84
85 static GLuint make_shader(GLenum type, const GLchar *src)
86 {
87 GLuint shader;
88 GLint shader_ok;
89
90 shader = glCreateShader(type);
91 glShaderSource(shader, 1, &src, NULL);
92 glCompileShader(shader);
93 glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
94 if (!shader_ok) {
95 fprintf(stderr, "Failed to compile shader:\n");
96 show_info_log(shader, glGetShaderiv, glGetShaderInfoLog);
97 glDeleteShader(shader);
98 exit(1);
99 }
100 return shader;
101 }
102
103 typedef struct {
104 struct {
105 GLfloat r[4];
106 } c[4];
107 } matrix;
108
109 static void m_identity(matrix *m)
110 {
111 int i, j;
112 for (i = 0; i < 4; i++)
113 for (j = 0; j < 4; j++)
114 m->c[i].r[j] = (i == j) ? 1.0f : 0.0f;
115 }
116
117 static void m_translate(matrix *m, GLfloat x, GLfloat y, GLfloat z)
118 {
119 m->c[3].r[0] += x;
120 m->c[3].r[1] += y;
121 m->c[3].r[2] += z;
122 }
123
124 static void m_scale(matrix *m, GLfloat x, GLfloat y, GLfloat z)
125 {
126 int i;
127
128 for (i = 0; i < 4; i++) {
129 m->c[i].r[0] *= x;
130 m->c[i].r[1] *= y;
131 m->c[i].r[2] *= z;
132 }
133 }
134
e434ad0 @pbrook Add spinny demo mode.
authored
135 static void m_rotate_x(matrix *m, GLfloat a)
c1c057a @pbrook Initial 3D rendering.
authored
136 {
137 memset(m, 0, sizeof(*m));
e434ad0 @pbrook Add spinny demo mode.
authored
138 m->c[0].r[0] = 1.0f;
139 m->c[2].r[1] = sin(a);
140 m->c[1].r[1] = cos(a);
141 m->c[2].r[2] = cos(a);
142 m->c[1].r[2] = -sin(a);
143 m->c[3].r[3] = 1.0f;
144 }
145
146 static void m_rotate_y(matrix *m, GLfloat a)
147 {
148 memset(m, 0, sizeof(*m));
149 m->c[0].r[0] = cos(a);
150 m->c[2].r[0] = -sin(a);
151 m->c[1].r[1] = 1.0f;
152 m->c[0].r[2] = sin(a);
153 m->c[2].r[2] = cos(a);
c1c057a @pbrook Initial 3D rendering.
authored
154 m->c[3].r[3] = 1.0f;
e434ad0 @pbrook Add spinny demo mode.
authored
155 }
156
157 static void m_rotate_z(matrix *m, GLfloat a)
158 {
159 memset(m, 0, sizeof(*m));
160 m->c[0].r[0] = cos(a);
161 m->c[1].r[0] = sin(a);
162 m->c[2].r[2] = 1.0f;
163 m->c[0].r[1] = -sin(a);
164 m->c[1].r[1] = cos(a);
165 m->c[3].r[3] = 1.0f;
166 }
167
168 static void m_project(matrix *m, GLfloat w, GLfloat h)
169 {
170 GLfloat n, f;
171 memset(m, 0, sizeof(*m));
e2530ac @pbrook Improve rotation controls.
authored
172 if (projection_mode == 0) {
e434ad0 @pbrook Add spinny demo mode.
authored
173 n = -160;
174 f = 160;
175 m->c[0].r[0] = 1 / w;
176 m->c[1].r[1] = 1 / h;
177 m->c[2].r[2] = 2.0f / (f - n);
178 m->c[3].r[2] = -(f + n) / (f - n);
179 m->c[3].r[3] = 1.0f;
180 } else{
181 n = DEPTH - 160;
182 f = DEPTH + 160;
183 m->c[0].r[0] = n / w;
184 m->c[1].r[1] = n / h;
185 m->c[2].r[2] = (f + n) / (f - n);
186 m->c[2].r[3] = 1.0f;
187 m->c[3].r[2] = -2.0f * f * n / (f - n);
188 }
c1c057a @pbrook Initial 3D rendering.
authored
189 }
190
191 static matrix modelworld;
192 static matrix eye;
193 static matrix projection;
194
195 #if 0
196 typedef struct {
197 } *gltex;
198
199 static gltex gltex_wall;
200 static gltex gltex_ladder;
201 static gltex gltex_egg;
202 static gltex gltex_grain;
203 static gltex gltex_lift;
204
205 static gltex gltex_duck[10];
206 static gltex gltex_big_duck_l1;
207 static gltex gltex_big_duck_l2;
208 static gltex gltex_big_duck_r1;
209 static gltex gltex_big_duck_r2;
210 static gltex gltex_cage_open;
211 static gltex gltex_cage_closed;
212
213 static gltex gltex_player_r[4];
214 static gltex gltex_player_l[4];
215 static gltex gltex_player_up[4];
216
217 static gltex gltex_score;
218 static gltex gltex_blank;
219 static gltex gltex_player;
220 static gltex gltex_level;
221 static gltex gltex_bonus;
222 static gltex gltex_time;
223 static gltex gltex_hat;
224 static gltex gltex_digit[10];
225 #endif
226
227 static GLuint make_buffer(GLenum target, const void *buffer_data,
228 GLsizei buffer_size) {
229 GLuint buffer;
230
231 glGenBuffers(1, &buffer);
232 glBindBuffer(target, buffer);
233 glBufferData(target, buffer_size, buffer_data, GL_STATIC_DRAW);
234 return buffer;
235 }
236
237 static void LoadModel(sprite_model *s)
238 {
239 s->vec_vbo = make_buffer(GL_ARRAY_BUFFER, s->vec,
240 sizeof(GLfloat) * s->vec_count * 3);
241 s->ind_vbo = make_buffer(GL_ARRAY_BUFFER, s->ind,
242 sizeof(GLushort) * s->ind_count);
243 }
244 static void LoadTextures(void)
245 {
246 LoadModel(&model_farmer);
247 LoadModel(&model_duck);
248 LoadModel(&model_ladder);
249 LoadModel(&model_wall);
250 LoadModel(&model_egg);
251 LoadModel(&model_grain);
92c2c71 @pbrook Add 3D lift models.
authored
252 LoadModel(&model_lift);
c1c057a @pbrook Initial 3D rendering.
authored
253 }
254
255 /* A = B * C */
256 static void m_mul(matrix *a, matrix *b, matrix *c)
257 {
258 int i;
259 int j;
260 int k;
261 GLfloat v;
262
263 for (i = 0; i < 4; i++) {
264 for (j = 0; j < 4; j++) {
265 v = 0.0f;
266 for (k = 0; k < 4; k++)
267 v += b->c[k].r[j] * c->c[i].r[k];
268 a->c[i].r[j] = v;
269 }
270 }
271 }
272
273 /* Transform from model to world coordinates. */
274 static void m_swizzle(matrix *m, int x, int y, int rot)
275 {
e434ad0 @pbrook Add spinny demo mode.
authored
276 matrix w;
277 matrix r;
278 matrix tmp;
279
280 memset(&w, 0, sizeof(w));
281
c1c057a @pbrook Initial 3D rendering.
authored
282 switch (rot) {
283 default:
e434ad0 @pbrook Add spinny demo mode.
authored
284 w.c[0].r[0] = 2.0f;
285 w.c[1].r[2] = 2.0f;
c1c057a @pbrook Initial 3D rendering.
authored
286 break;
287 case 1:
e434ad0 @pbrook Add spinny demo mode.
authored
288 w.c[1].r[0] = -2.0f;
289 w.c[0].r[2] = 2.0f;
c1c057a @pbrook Initial 3D rendering.
authored
290 break;
291 case 2:
e434ad0 @pbrook Add spinny demo mode.
authored
292 w.c[0].r[0] = -2.0f;
293 w.c[1].r[2] = -2.0f;
c1c057a @pbrook Initial 3D rendering.
authored
294 break;
295 case 3:
e434ad0 @pbrook Add spinny demo mode.
authored
296 w.c[1].r[0] = 2.0f;
297 w.c[0].r[2] = -2.0f;
c1c057a @pbrook Initial 3D rendering.
authored
298 break;
299 }
e434ad0 @pbrook Add spinny demo mode.
authored
300 w.c[2].r[1] = 2.0f;
301 w.c[3].r[3] = 1.0f;
302
303 w.c[3].r[0] = x * 2 - 160;
304 w.c[3].r[1] = y - 120;
305 m_rotate_y(&r, rotate_x);
306 m_mul(&tmp, &r, &w);
307 m_rotate_x(&r, rotate_y);
308 m_mul(m, &r, &tmp);
e2530ac @pbrook Improve rotation controls.
authored
309 if (projection_mode) {
e434ad0 @pbrook Add spinny demo mode.
authored
310 m->c[3].r[2] += DEPTH;
311 }
c1c057a @pbrook Initial 3D rendering.
authored
312 }
313
8a9b475 @pbrook Optimize shaders. Animate models.
authored
314 static float sprite_angle1;
ac30f1e @pbrook Improve animation.
authored
315 static float sprite_angle2;
d3c8d14 @pbrook Improve animation. Add blender source objects.
authored
316 static float sprite_mov1;
8a9b475 @pbrook Optimize shaders. Animate models.
authored
317
c1c057a @pbrook Initial 3D rendering.
authored
318 static void RenderGroup(object_group *g)
319 {
320 matrix prev = eye;
321 matrix mat;
8a9b475 @pbrook Optimize shaders. Animate models.
authored
322 matrix final;
c1c057a @pbrook Initial 3D rendering.
authored
323 object_group *child;
324
8a9b475 @pbrook Optimize shaders. Animate models.
authored
325 switch (g->mod) {
326 case 'L':
327 m_rotate_x(&mat, sprite_angle1);
d3c8d14 @pbrook Improve animation. Add blender source objects.
authored
328 m_translate(&mat, 0, 0, sprite_mov1);
8a9b475 @pbrook Optimize shaders. Animate models.
authored
329 break;
330 case 'R':
331 m_rotate_x(&mat, -sprite_angle1);
d3c8d14 @pbrook Improve animation. Add blender source objects.
authored
332 m_translate(&mat, 0, 0, -sprite_mov1);
8a9b475 @pbrook Optimize shaders. Animate models.
authored
333 break;
ac30f1e @pbrook Improve animation.
authored
334 case 'B':
335 m_rotate_x(&mat, sprite_angle2 / 2.0f);
336 break;
337 case 'N':
338 case 'l':
339 m_rotate_x(&mat, sprite_angle2);
340 break;
341 case 'r':
342 m_rotate_x(&mat, -sprite_angle2);
343 break;
d3c8d14 @pbrook Improve animation. Add blender source objects.
authored
344 case 'H':
345 m_rotate_x(&mat, -sprite_angle2 / 2.0f);
346 break;
8a9b475 @pbrook Optimize shaders. Animate models.
authored
347 case 'U':
348 m_rotate_x(&mat, fabsf(sprite_angle1) / 2.0f);
349 break;
350 case 'D':
351 m_rotate_x(&mat, -fabsf(sprite_angle1) / 2.0f);
352 break;
353 default:
354 m_identity(&mat);
355 break;
356 }
357
ac30f1e @pbrook Improve animation.
authored
358 m_translate(&mat, g->translate[0], g->translate[1], g->translate[2]);
8a9b475 @pbrook Optimize shaders. Animate models.
authored
359 m_mul(&eye, &prev, &mat);
360
c1c057a @pbrook Initial 3D rendering.
authored
361
362 for (child = g->child; child; child = child->next) {
363 RenderGroup(child);
364 }
365
366 if (g->ind_count) {
367 m_mul(&mat, &modelworld, &eye);
8a9b475 @pbrook Optimize shaders. Animate models.
authored
368 m_mul(&final, &projection, &mat);
d420051 @pbrook Add legacy fixed-function rendering path.
authored
369 if (shaders) {
370 glUniform3f(param_color, g->color[0], g->color[1], g->color[2]);
8a9b475 @pbrook Optimize shaders. Animate models.
authored
371 glUniformMatrix4fv(param_proj, 1, GL_FALSE, &final.c[0].r[0]);
d420051 @pbrook Add legacy fixed-function rendering path.
authored
372 } else {
8a9b475 @pbrook Optimize shaders. Animate models.
authored
373 glLoadMatrixf(&final.c[0].r[0]);
d420051 @pbrook Add legacy fixed-function rendering path.
authored
374 glColor3f(g->color[0], g->color[1], g->color[2]);
375 }
c1c057a @pbrook Initial 3D rendering.
authored
376 glDrawElements(GL_TRIANGLES, g->ind_count, GL_UNSIGNED_SHORT,
d420051 @pbrook Add legacy fixed-function rendering path.
authored
377 (void *)(sizeof(GLushort) * g->ind_start));
c1c057a @pbrook Initial 3D rendering.
authored
378 }
379 eye = prev;
380 }
381
382 static void RenderSprite(sprite_model *s, int x, int y, int rot)
383 {
384 glBindBuffer(GL_ARRAY_BUFFER, s->vec_vbo);
d420051 @pbrook Add legacy fixed-function rendering path.
authored
385 if (shaders) {
386 glUniformMatrix4fv(param_proj, 1, GL_FALSE, &projection.c[0].r[0]);
387 glVertexAttribPointer(attr_position, 3, GL_FLOAT, GL_FALSE,
388 sizeof(GLfloat) * 3, (void *)0);
389 glEnableVertexAttribArray(attr_position);
390 } else {
391 glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 3, (void *)0);
392 glEnableClientState(GL_VERTEX_ARRAY);
393 }
c1c057a @pbrook Initial 3D rendering.
authored
394 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->ind_vbo);
395 m_identity(&eye);
396 m_swizzle(&modelworld, x, y, rot);
397 RenderGroup(s->group);
d420051 @pbrook Add legacy fixed-function rendering path.
authored
398 if (shaders) {
399 glDisableVertexAttribArray(attr_position);
400 }
c1c057a @pbrook Initial 3D rendering.
authored
401 }
402
403 #if 0
404 static void RenderDigit(int x, int y, int n)
405 {
406 RenderSprite(gltex_digit[n], x, y);
407 }
408
409 static void AddSceneSprite(gltex t, GLfloat x, GLfloat y)
410 {
411 RenderSprite(t, x, y);
412 }
413
414 static void RenderPlayerHUD(int player)
415 {
416 int x = player * 0x22 + 0x1b;
417 int n;
418
419 for (n = 0; n < 6; n++) {
420 RenderDigit(x + 1 + n * 5, 0xef,
421 all_player_data[player].score[n + 2]);
422 }
423
424 n = all_player_data[player].lives;
425 if (n > 8)
426 n = 8;
427 while (n--) {
428 RenderSprite(gltex_hat, x, 0xe7);
429 x += 4;
430 }
431 }
432
433 static int item_pos[32];
434 static int item_count;
435 #endif
436
437 void RenderBackground(void)
438 {
439 }
440
441 #if 0
442 static void RenderScene(void)
443 {
444 int player;
445 int x;
446 int y;
447 int n;
448 int type;
449 gltex tex;
450
451 AddSceneSprite(gltex_score, 0, 0xf0);
452 for (player = 0; player < num_players; player++) {
453 x = player * 0x22 + 0x1b;
454 AddSceneSprite(gltex_blank, x, 0xf0);
455 }
456
457 y = 0xe3;
458 AddSceneSprite(gltex_player, 0, y + 1);
459 AddSceneSprite(gltex_digit[current_player + 1], 0x1b, y);
460
461 AddSceneSprite(gltex_level, 0x24, y + 1);
462 n = current_level + 1;
463 AddSceneSprite(gltex_digit[n % 10], 0x45, y);
464 n /= 10;
465 AddSceneSprite(gltex_digit[n % 10], 0x40, y);
466 if (n > 10)
467 AddSceneSprite(gltex_digit[n / 10], 0x3b, y);
468
469 AddSceneSprite(gltex_bonus, 0x4e, y + 1);
470 AddSceneSprite(gltex_digit[0], 0x75, y);
471 AddSceneSprite(gltex_time, 0x7e, y + 1);
472
473 item_count = 0;
474 for (x = 0; x < 20; x++) {
475 for (y = 0; y < 25; y++) {
476 type = levelmap[y * 20 + x];
477 if (type & TILE_LADDER) {
478 tex = gltex_ladder;
479 } else if (type & TILE_WALL) {
480 tex = gltex_wall;
481 } else if (type & (TILE_EGG | TILE_GRAIN)) {
482 item_pos[item_count++] = y * 20 + x;
483 continue;
484 } else {
485 continue;
486 }
487 AddSceneSprite(tex, x << 3, (y << 3) | 7);
488 }
489 }
490
491 if (have_big_duck) {
492 tex = gltex_cage_open;
493 } else {
494 tex = gltex_cage_closed;
495 }
496 AddSceneSprite(tex, 0, 0xdc);
497 }
498 #endif
499
500 void RenderFrame(void)
501 {
502 int x;
503 int y;
504 int n;
505 int type;
506 int rot;
507 sprite_model *model;
508
e2530ac @pbrook Improve rotation controls.
authored
509 switch (projection_mode) {
510 case 1:
e434ad0 @pbrook Add spinny demo mode.
authored
511 rotate_x -= 0.05;
512 rotate_y += 0.005;
e2530ac @pbrook Improve rotation controls.
authored
513 break;
514 case 0:
e434ad0 @pbrook Add spinny demo mode.
authored
515 rotate_x = 0;
516 rotate_y = 0;
e2530ac @pbrook Improve rotation controls.
authored
517 break;
518 default:
519 break;
e434ad0 @pbrook Add spinny demo mode.
authored
520 }
521
c7e656b @pbrook Add frameskip.
authored
522 if (skip_frame) {
523 return;
524 }
e434ad0 @pbrook Add spinny demo mode.
authored
525 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
526
527 m_project(&projection, 160, 120);
c1c057a @pbrook Initial 3D rendering.
authored
528
d420051 @pbrook Add legacy fixed-function rendering path.
authored
529 if (shaders) {
530 glUseProgram(program);
531 }
c1c057a @pbrook Initial 3D rendering.
authored
532
533 /* Egg/Grain. */
534 for (x = 0; x < 20; x++) {
535 for (y = 0; y < 25; y++) {
536 type = levelmap[y * 20 + x];
537 if (type & TILE_LADDER) {
538 model = &model_ladder;
539 } else if (type & TILE_WALL) {
540 model = &model_wall;
541 } else if (type & TILE_EGG) {
542 model = &model_egg;
543 } else if (type & TILE_GRAIN) {
544 model = &model_grain;
545 } else {
546 continue;
547 }
548 RenderSprite(model, (x << 3) + 4, (y << 3) + 7, 0);
549 }
550 }
551
552 /* Player. */
553 if (player_face == 0) {
554 rot = 2;
555 n = (player_y >> 1) & 3;
556 } else {
557 if (player_face < 0)
558 rot = 3;
559 else
560 rot = 1;
561 n = (player_x >> 1) & 3;
562 }
563 if (player_mode != PLAYER_CLIMB) {
564 if (move_x == 0)
565 n = 0;
566 } else {
567 if (move_y == 0)
568 n = 0;
569 }
8a9b475 @pbrook Optimize shaders. Animate models.
authored
570 if (n == 1) {
571 sprite_angle1 = M_PI / 4;
572 } else if (n == 3) {
573 sprite_angle1 = -M_PI / 4;
574 } else {
575 sprite_angle1 = 0.0f;
576 }
ac30f1e @pbrook Improve animation.
authored
577 if (rot == 2) {
578 sprite_angle2 = (M_PI / 2) - sprite_angle1;
d3c8d14 @pbrook Improve animation. Add blender source objects.
authored
579 sprite_mov1 = sprite_angle1 * (2.0f / M_PI);
580 sprite_angle1 = 0.0f;
ac30f1e @pbrook Improve animation.
authored
581 } else {
582 sprite_angle2 = -sprite_angle1;
d3c8d14 @pbrook Improve animation. Add blender source objects.
authored
583 sprite_mov1 = 0.0f;
ac30f1e @pbrook Improve animation.
authored
584 }
8a9b475 @pbrook Optimize shaders. Animate models.
authored
585
c1c057a @pbrook Initial 3D rendering.
authored
586 RenderSprite(&model_farmer, player_x + 4, player_y - 8, rot);
587
588 /* Ducks. */
589 for (n = 0; n < num_ducks; n++) {
590 int dir = duck[n].dir;
591 x = duck[n].x;
592 if (dir == DIR_R) {
593 rot = 1;
594 } else if (dir == DIR_L) {
595 rot = 3;
596 } else {
597 rot = 2;
598 }
d3c8d14 @pbrook Improve animation. Add blender source objects.
authored
599 sprite_mov1 = 0.0f;
c1c057a @pbrook Initial 3D rendering.
authored
600 switch (duck[n].mode) {
601 case DUCK_BORED:
8a9b475 @pbrook Optimize shaders. Animate models.
authored
602 sprite_angle1 = 0.0f;
ac30f1e @pbrook Improve animation.
authored
603 sprite_angle2 = 0.0f;
8a9b475 @pbrook Optimize shaders. Animate models.
authored
604 break;
c1c057a @pbrook Initial 3D rendering.
authored
605 case DUCK_STEP:
d3c8d14 @pbrook Improve animation. Add blender source objects.
authored
606 if (rot == 2) {
607 sprite_mov1 = 1.0f;
608 }
8a9b475 @pbrook Optimize shaders. Animate models.
authored
609 sprite_angle1 = M_PI / 4;
610 if ((duck[n].x ^ duck[n].y) & 8) {
611 sprite_angle1 = -sprite_angle1;
d3c8d14 @pbrook Improve animation. Add blender source objects.
authored
612 sprite_mov1 = -sprite_mov1;
8a9b475 @pbrook Optimize shaders. Animate models.
authored
613 }
ac30f1e @pbrook Improve animation.
authored
614 sprite_angle2 = 0.0f;
615 break;
616 case DUCK_EAT2:
617 case DUCK_EAT4:
618 sprite_angle1 = 0.0f;
619 sprite_angle2 = -M_PI / 4;
c1c057a @pbrook Initial 3D rendering.
authored
620 break;
ac30f1e @pbrook Improve animation.
authored
621 case DUCK_EAT3:
8a9b475 @pbrook Optimize shaders. Animate models.
authored
622 sprite_angle1 = 0.0f;
ac30f1e @pbrook Improve animation.
authored
623 sprite_angle2 = -M_PI / 2;
c1c057a @pbrook Initial 3D rendering.
authored
624 break;
ac30f1e @pbrook Improve animation.
authored
625 default:
626 abort();
c1c057a @pbrook Initial 3D rendering.
authored
627 }
628 RenderSprite(&model_duck, x + 4, duck[n].y - 12, rot);
629 }
630
92c2c71 @pbrook Add 3D lift models.
authored
631 /* Lift. */
632 if (have_lift) {
633 for (n = 0; n < 2; n++) {
634 RenderSprite(&model_lift, lift_x + 8, lift_y[n] + 4, 0);
635 }
636 }
637
c1c057a @pbrook Initial 3D rendering.
authored
638 #if 0
639 RenderScene();
640
641 /* HUD */
642 for (n = 0; n < num_players; n++) {
643 RenderPlayerHUD(n);
644 }
645
646 y = 0xe3;
647
648 RenderDigit(0x66, y, bonus[0]);
649 RenderDigit(0x6b, y, bonus[1]);
650 RenderDigit(0x70, y, bonus[2]);
651
652 RenderDigit(0x91, y, timer_ticks[0]);
653 RenderDigit(0x96, y, timer_ticks[1]);
654 RenderDigit(0x9b, y, timer_ticks[2]);
655
656
657 /* Big duck. */
658 if (big_duck_dir) {
659 tex = big_duck_frame ? gltex_big_duck_l2 : gltex_big_duck_l1;
660 } else {
661 tex = big_duck_frame ? gltex_big_duck_r2 : gltex_big_duck_r1;
662 }
663 RenderSprite(tex, big_duck_x, big_duck_y);
664 #endif
665
666 SDL_GL_SwapBuffers();
667 if (glGetError() != GL_NO_ERROR) {
668 die("Error rendering frame\n");
669 }
670 }
671
672 static void parse_args(int argc, const char *argv[])
673 {
674 const char *p;
675 int i;
676
677 for (i = 1; i < argc; i++) {
678 p = argv[i];
679 if (*p == '-')
680 p++;
681 if (*p >= '1' && *p <= '9')
682 scale = *p - '0';
683 else if (*p == 'f')
684 fullscreen = 1;
d420051 @pbrook Add legacy fixed-function rendering path.
authored
685 else if (*p == 's')
686 shaders = 0;
c1c057a @pbrook Initial 3D rendering.
authored
687 else if (*p == 'h') {
d420051 @pbrook Add legacy fixed-function rendering path.
authored
688 printf("Usage: chuckie -123456789fs\n");
c1c057a @pbrook Initial 3D rendering.
authored
689 exit(0);
690 }
691 }
692 }
693
694 static void InitGL(void)
695 {
696 GLint program_ok;
697
e434ad0 @pbrook Add spinny demo mode.
authored
698 glEnable(GL_DEPTH_TEST);
c1c057a @pbrook Initial 3D rendering.
authored
699 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
700 glEnable(GL_BLEND);
701 glClearColor(0, 0, 0, 0);
d420051 @pbrook Add legacy fixed-function rendering path.
authored
702 glEnable(GL_CULL_FACE);
c1c057a @pbrook Initial 3D rendering.
authored
703 LoadTextures();
704
d420051 @pbrook Add legacy fixed-function rendering path.
authored
705 if (shaders) {
706 vertex_shader = make_shader(GL_VERTEX_SHADER, vertex_code);
707 fragment_shader = make_shader(GL_FRAGMENT_SHADER, fragment_code);
708
709 program = glCreateProgram();
710 glAttachShader(program, vertex_shader);
711 glAttachShader(program, fragment_shader);
712 glLinkProgram(program);
713 glGetProgramiv(program, GL_LINK_STATUS, &program_ok);
714 if (!program_ok) {
715 fprintf(stderr, "Failed to link shader program:\n");
716 show_info_log(program, glGetProgramiv, glGetProgramInfoLog);
717 glDeleteProgram(program);
718 exit(1);
719 }
720 attr_position = glGetAttribLocation(program, "position");
721 param_color = glGetUniformLocation(program, "color");
722 param_proj = glGetUniformLocation(program, "proj");
c1c057a @pbrook Initial 3D rendering.
authored
723 }
724
725 glViewport(0, 0, scale * 320, scale * 240);
726 if (glGetError() != GL_NO_ERROR) {
727 die("Error initializing OpenGL\n");
728 }
729 }
730
731 int main(int argc, const char *argv[])
732 {
733 parse_args (argc, argv);
734 int flags;
735
736 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) {
737 die("SDL_Init: %s\n", SDL_GetError());
738 }
739
740 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
741 flags = SDL_OPENGL;
742 if (fullscreen)
743 flags |= SDL_FULLSCREEN;
744
745 sdlscreen = SDL_SetVideoMode(scale * 320, scale * 240, 32, flags);
746 if (!sdlscreen) {
747 SDL_Quit();
748 fprintf(stderr, "SDL_SetVideoMode failed\n");
749 return 0;
750 }
751
752 SDL_ShowCursor(SDL_DISABLE);
753
754 init_sound();
755
390be52 @pbrook Joystick support.
authored
756 init_input();
757
c1c057a @pbrook Initial 3D rendering.
authored
758 InitGL();
759
760 SDL_AddTimer(30, do_timer, NULL);
761
762 run_game();
763
764 return 0;
765 }
Something went wrong with that request. Please try again.