Add missing ConsoleFont.c (bitmap font for console)
[attac-man.git] / game.c
blobcdce5cb847549df61ddd1a4240e13847635f6353
1 /*
2 Pacman Arena
3 Copyright (C) 2003 Nuno Subtil
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 static const char cvsid[] =
21 "$Id: game.c,v 1.71 2003/11/30 17:43:55 nsubtil Exp $";
23 #ifdef _WIN32
24 #include <windows.h>
25 #endif
27 #include <GL/gl.h>
28 #include <GL/glu.h>
29 #include <SDL.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
34 #include "object.h"
35 #include "audio.h"
36 #include "m_math.h"
37 #include "gfx.h"
38 #include "game.h"
39 #include "map.h"
40 #include "screen.h"
41 #include "render.h"
42 #include "shot.h"
43 #include "bomb.h"
44 #include "particle.h"
45 #include "input.h"
47 #include "player.h"
48 #include "ghost.h"
50 #include "render_map.h"
51 #include "render_ghost.h"
52 #include "render_player.h"
53 #include "render_shot.h"
54 #include "render_bomb.h"
55 #include "oglconsole.h"
57 #include "level-0.h"
58 //#include "level-classic.h"
59 //#include "level-demo.h"
60 //#include "level-1.h"
62 struct game *game_new(int game_type)
64 struct game *ret;
66 ret = (struct game *)malloc(sizeof(struct game));
67 ret->game_type = game_type;
68 ret->current_level = -1;
69 ret->n_players = 0;
70 ret->players = NULL;
71 ret->n_ghosts = 0;
72 ret->ghosts = NULL;
73 ret->n_shots = 0;
74 ret->bombs = NULL;
75 ret->n_bombs = 0;
76 ret->shots = NULL;
77 ret->map = NULL;
78 ret->demo_camera = NULL;
80 return ret;
83 void game_free(struct game *game)
85 if(game->players)
86 free(game->players);
87 if(game->ghosts)
88 free(game->ghosts);
89 if(game->map)
90 map_free(game->map);
92 free(game);
95 void game_run(struct game *game)
97 struct viewport *vp = screen_get_viewport(0);
98 int last_update, ticks;
99 int frames;
100 int c;
102 input_reset();
104 last_update = ticks = SDL_GetTicks();
106 game_start(game);
108 for(c = 0; c < game->n_players; c++)
110 render_reset_camera(game->players[c].camera);
111 game_reset_camera(game, c);
114 frames = 0;
116 audio_play_music("sfx/tranzy.ogg");
118 for(;;)
120 int diff;
122 input_update();
124 if(input_kstate(SDLK_ESCAPE))
126 audio_fade_music(500);
127 SDL_Delay(500);
128 return;
131 diff = SDL_GetTicks() - last_update;
132 game_update(game, (float)diff / 1000);
133 last_update = SDL_GetTicks();
135 render_start_frame();
137 for(c = 0; c < game->n_players; c++)
139 render_setup(game, c);
141 map_render_opaque_objects(game);
142 game_draw_opaque_objects(game, c);
143 map_render_translucent_objects(game, c);
144 game_draw_translucent_objects(game, c);
145 game_draw_player_lives(game, c, (float)diff / 1000);
149 if(game->n_players == 1)
150 render_draw_logo();
153 render_setup_2d(vp);
154 render_finish_frame();
155 frames++;
157 if(SDL_GetTicks() - ticks >= 1000)
159 printf("%d FPS\n", frames);
160 ticks = SDL_GetTicks();
161 frames = 0;
164 if(game_count_dots(game) == 0)
166 con_printf("Final Score: %d\n", game->players[0].score);
167 game_do_victory_loop(game);
168 return;
171 if(game->players[0].lives == 0)
173 con_printf("Final Score: %d\n", game->players[0].score);
174 game_do_defeat_loop(game);
175 return;
178 SDL_Delay(0);
182 void game_draw_player_lives(struct game *game, int player_no, float delta)
184 GLfloat light0_position[] = { 0.0, 1.0, 0.0, 1.0 };
185 GLfloat light0_direction[] = { 0.0, 0.5, 1.5 };
186 GLfloat inactive_color[] = { 0.5, 0.5, 0.5, 1.0 };
188 int c;
189 struct player *p;
190 static float frame = 0.0;
192 struct viewport *vp;
194 vp = screen_get_viewport(player_no);
195 p = &game->players[player_no];
196 frame += delta * ANIM_FPS;
198 for(c = 0; c < p->lives; c++)
200 glMatrixMode(GL_MODELVIEW);
201 glLoadIdentity();
202 glMatrixMode(GL_PROJECTION);
203 glLoadIdentity();
205 glViewport(0 + 70 * vp->width / 800 * c, 0,
206 150 * vp->width / 800, 150 * vp->width / 800);
208 glViewport(0 + 70 * vp->width / 800 * c, vp->ll_y,
209 150 * vp->width / 800, 150 * vp->width / 800);
211 glFrustum(-1.0, 1.0,
212 -1.0, 1.0, 1.5, 3.0);
213 gluLookAt(0.0, 0.0, 0.0,
214 0.0, 0.0, 1.0,
215 0.0, 1.0, 0.0);
217 glShadeModel(GL_SMOOTH);
218 glEnable(GL_COLOR_MATERIAL);
219 glDisable(GL_BLEND);
220 glDisable(GL_TEXTURE_2D);
221 glEnable(GL_DEPTH_TEST);
222 glDepthMask(GL_TRUE);
224 glEnable(GL_LIGHTING);
225 glEnable(GL_LIGHT0);
226 glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
227 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0_direction);
229 glClear(GL_DEPTH_BUFFER_BIT);
230 glMatrixMode(GL_MODELVIEW);
231 glTranslatef(0.0, 0.0, 2.1);
233 glRotatef(180.0, 0.0, 1.0, 0.0);
234 glRotatef(180.0, 0.0, 0.0, 1.0);
235 glRotatef(-75.0, 0.0, 1.0, 0.0);
237 if(c == p->lives - 1)
238 switch(p->state)
240 case PLAYER_STATE_MOVING:
241 case PLAYER_STATE_STOPPED:
242 render_dlist(&p->model_moving[(int)frame % p->frames_moving], p->color);
243 break;
245 case PLAYER_STATE_DEAD:
246 render_dlist(&p->model_dying[(int)p->current_frame % p->frames_dying], p->color);
247 break;
249 else
250 render_dlist(&p->model_stopped[0], inactive_color);
254 #if 1
255 /* XXX - this is for player 0 only */
256 void game_do_victory_loop(struct game *game)
258 int last_update;
259 struct image_rgba32 *level_complete;
260 int tx_level_complete;
261 struct viewport *vp;
263 audio_fade_music(500);
264 SDL_Delay(500);
266 level_complete = gfx_get("gfx/level-complete.tga");
267 gfx_alpha_from_key("gfx/level-complete.tga", 0, 0, 0);
268 tx_level_complete = gfx_upload_texture("gfx/level-complete.tga");
270 audio_play_music("sfx/hiscore.ogg");
272 game->players[0].camera->type = CAMERA_TYPE_DEMO;
274 last_update = SDL_GetTicks();
276 game->players[0].state = PLAYER_STATE_WON;
277 game->players[0].current_frame = 0.0;
278 vp = screen_get_viewport(0);
280 for(;;)
282 SDL_Event ev;
283 int diff, c;
284 float delta;
286 while(SDL_PollEvent(&ev))
288 if (OGLCONSOLE_SDLEvent(&ev) != 0)
289 continue;
291 if(ev.type == SDL_QUIT)
293 SDL_Quit();
294 exit(0);
297 if((ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE) ||
298 (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_SPACE))
300 audio_fade_music(500);
301 SDL_Delay(500);
302 return;
306 diff = SDL_GetTicks() - last_update;
307 last_update = SDL_GetTicks();
308 delta = (float)diff / 1000.0;
310 for(c = 0; c < game->n_players; c++)
311 game->players[c].current_frame += delta * ANIM_FPS;
313 for(c = 0; c < game->n_ghosts; c++)
314 game->ghosts[c].current_frame += delta * ANIM_FPS;
316 game_update_camera(game, 0, delta);
317 render_point_camera(game->players[0].camera,
318 game->players[0].position[X],
319 game->players[0].position[Y],
320 game->players[0].position[Z]);
322 render_start_frame();
324 render_setup(game, 0);
325 map_render_opaque_objects(game);
326 game_draw_opaque_objects(game, 0);
327 map_render_translucent_objects(game, 0);
328 game_draw_translucent_objects(game, 0);
330 /* render_draw_logo();*/
332 render_setup_2d(vp);
334 if(level_complete->width > vp->width)
335 render_draw_scaled_image("gfx/level-complete.tga",
336 0, 0,
337 vp->width,
338 level_complete->height * vp->height / vp->width);
339 else
340 render_draw_scaled_image("gfx/level-complete.tga",
341 (vp->width - level_complete->width) / 2, 0,
342 (vp->width + level_complete->width) / 2,
343 level_complete->height);
345 render_finish_frame();
349 /* XXX - player 0 only */
350 void game_do_defeat_loop(struct game *game)
352 int last_update;
353 struct image_rgba32 *game_over;
354 int tx_game_over;
355 struct viewport *vp;
357 audio_fade_music(500);
358 SDL_Delay(500);
360 game_over = gfx_get("gfx/game-over.tga");
361 gfx_alpha_from_key("gfx/game-over.tga", 0, 0, 0);
362 tx_game_over = gfx_upload_texture("gfx/game-over.tga");
364 audio_play_music("sfx/gameover.ogg");
366 game->players[0].camera->type = CAMERA_TYPE_DEMO;
368 last_update = SDL_GetTicks();
369 vp = screen_get_viewport(0);
371 for(;;)
373 int diff, c;
374 float delta;
376 input_update();
378 if(input_kstate(SDLK_ESCAPE))
380 input_kclear(SDLK_ESCAPE);
381 audio_fade_music(500);
382 SDL_Delay(500);
383 return;
386 diff = SDL_GetTicks() - last_update;
387 last_update = SDL_GetTicks();
388 delta = (float)diff / 1000.0;
390 for(c = 0; c < n_players; c++)
391 players[c].current_frame += delta * ANIM_FPS;
393 for(c = 0; c < game->n_ghosts; c++)
394 game->ghosts[c].current_frame += delta * ANIM_FPS;
396 game_update_camera(game, 0, delta);
397 render_point_camera(game->players[0].camera,
398 game->players[0].position[X],
399 game->players[0].position[Y],
400 game->players[0].position[Z]);
402 render_start_frame();
404 render_setup(game, 0);
405 map_render_opaque_objects(game);
406 game_draw_opaque_objects(game, 0);
407 map_render_translucent_objects(game, 0);
408 game_draw_translucent_objects(game, 0);
410 /* render_draw_logo();*/
412 render_setup_2d(vp);
414 if(game_over->width > vp->width)
415 render_draw_scaled_image("gfx/game-over.tga",
416 0, 0,
417 vp->width,
418 game_over->height * vp->height / vp->width);
419 else
420 render_draw_scaled_image("gfx/game-over.tga",
421 (vp->width - game_over->width) / 2, 0,
422 (vp->width + game_over->width) / 2,
423 game_over->height);
424 render_finish_frame();
427 #else
428 void game_do_victory_loop(struct game *game)
432 void game_do_defeat_loop(struct game *game)
435 #endif
437 void game_reset(struct game *game)
439 player_reset(game);
440 glDisable(GL_LIGHT1);
443 int game_count_dots(struct game *game)
445 struct map *map;
446 int x, y, ret;
448 map = game->map;
449 ret = 0;
451 for(x = 0; x < map->width; x++)
452 for(y = 0; y < map->height; y++)
453 if(MAP(map, x, y).content == MAP_CONTENT_FOOD &&
454 MAP(map, x, y).c_data.food.status == FOOD_STATUS_ACTIVE)
455 ret++;
457 return ret;
460 void game_teleport_player(struct game *game, int player)
462 struct player *p;
463 struct map *map;
464 int x, y;
465 int dx, dy;
467 p = &game->players[player];
468 map = game->map;
470 x = (int)p->position[X];
471 y = (int)p->position[Z];
473 if(MAP(map, x, y).content != MAP_CONTENT_TELEPORT)
474 return;
476 if(MAP_TELEPORT(map, x, y).direction != p->direction)
477 return;
479 dx = MAP_TELEPORT(map, x, y).dest_x;
480 dy = MAP_TELEPORT(map, x, y).dest_y;
482 p->position[X] = (float)dx + 0.5;
483 p->position[Z] = (float)dy + 0.5;
486 void game_start(struct game *game)
488 struct map *map;
489 int c, cx, cy;
491 /* distribuir os jogadores pelos spawn points */
492 c = 0;
493 map = game->map;
495 for(cx = 0; cx < map->width; cx++)
496 for(cy = 0; cy < map->height; cy++)
497 if(c < game->n_players &&
498 MAP(map, cx, cy).flags & MAP_FLAG_PACMAN_START_POSITION)
500 /* spawn */
501 game->players[c].position[X] = (float)cx + 0.5;
502 game->players[c].position[Z] = (float)cy + 0.5;
504 game->players[c].start_position[X] = (float)cx + 0.5;
505 game->players[c].start_position[Y] = game->players[c].position[Y];
506 game->players[c].start_position[Z] = (float)cy + 0.5;
508 c++;
510 if(c == game->n_players)
511 break;
516 if(c != game->n_players)
518 printf("game_start: tanta gente (%d)!\n", game->n_players);
519 SDL_Quit();
520 exit(1);
523 ghost_reset_all(game);
526 void game_reset_camera(struct game *game, int player_no)
528 struct camera *cam;
529 struct player *player;
531 if(player_no == -1)
533 player = NULL;
534 cam = game->demo_camera;
535 } else {
536 player = &game->players[player_no];
537 cam = player->camera;
540 switch(cam->type)
542 case CAMERA_TYPE_FIXED_CHASE:
543 break;
545 case CAMERA_TYPE_LOOSE_CHASE:
546 render_reset_camera(cam);
547 render_move_camera(cam,
548 player->position[X],
549 -3.5,
550 player->position[Z] - 3.5);
551 break;
553 case CAMERA_TYPE_LOOSE_TRAIL:
554 render_reset_camera(cam);
555 render_move_camera(cam,
556 0.0, CAMERA_LOOSE_TRAIL_Y_OFFSET, CAMERA_LOOSE_TRAIL_Z_OFFSET);
557 render_point_camera(cam,
558 player->position[X],
559 player->position[Y],
560 player->position[Z]);
562 break;
564 case CAMERA_TYPE_DEMO:
565 render_reset_camera(cam);
566 render_move_camera(cam, game->map->width / 2 + 0.5, CAMERA_DEMO_HEIGHT, 0.0);
567 render_point_camera(cam, game->map->width / 2 + 0.5, 0.0, game->map->height / 2 + 0.5);
568 break;
570 case CAMERA_TYPE_TOMB_RAIDER:
571 render_reset_camera(cam);
572 render_move_camera(cam,
573 0.0, CAMERA_TOMB_RAIDER_Y_OFFSET, -CAMERA_TOMB_RAIDER_OFFSET);
574 render_point_camera(cam,
575 player->position[X],
576 player->position[Y],
577 player->position[Z]);
579 break;
581 case CAMERA_TYPE_FREE:
582 break;
586 void game_update_camera(struct game *game, int player_no, float delta)
588 static int state = 0;
589 struct camera *cam;
590 struct player *player;
592 if(player_no == -1)
594 /* magic value: demo camera */
595 player = NULL;
596 cam = game->demo_camera;
597 } else {
598 player = &game->players[player_no];
599 cam = player->camera;
602 if(input_kstate(SDLK_c))
604 cam->type = (cam->type + 1) % CAMERA_NUM_TYPES;
605 input_kclear(SDLK_c);
606 // game_reset_camera(game, player_no);
609 switch(cam->type)
611 float v1[3], v2[3], vr[3], dist, d2;
613 case CAMERA_TYPE_FIXED_CHASE:
614 render_reset_camera(cam);
615 render_move_camera(cam,
616 player->position[X],
617 -3.5,
618 player->position[Z] - 2.5);
619 render_point_camera(cam,
620 player->position[X],
621 player->position[Y],
622 player->position[Z]);
624 break;
626 case CAMERA_TYPE_LOOSE_CHASE:
627 render_point_camera(cam,
628 player->position[X],
629 player->position[Y],
630 player->position[Z]);
632 v1[X] = player->position[X];
633 v1[Y] = cam->pos[Y];
634 v1[Z] = player->position[Z];
636 math_sub_vec3(v1, v1, cam->pos);
638 if(state)
640 if(math_norm_vec3(v1) > CAMERA_LOOSE_CHASE_LOW_THRESHOLD)
642 math_len_vec3(v1, v1, delta * CAMERA_LOOSE_CHASE_SPEED);
643 math_add_vec3(v1, cam->pos, v1);
644 render_move_camera(cam, v1[X], v1[Y], v1[Z]);
645 } else
646 state = 0;
647 } else
648 if(math_norm_vec3(v1) > CAMERA_LOOSE_CHASE_HIGH_THRESHOLD)
649 state = 1;
651 break;
653 case CAMERA_TYPE_LOOSE_TRAIL:
654 v1[X] = cam->dir[X];
655 v1[Y] = cam->dir[Y];
656 v1[Z] = cam->dir[Z];
658 render_point_camera(cam,
659 player->position[X],
660 player->position[Y],
661 player->position[Z]);
664 v2[X] = cam->dir[X];
665 v2[Y] = cam->dir[Y];
666 v2[Z] = cam->dir[Z];
668 math_sub_vec3(vr, v2, v1);
669 dist = math_norm_vec3(vr);
670 if(dist > CAMERA_LOOSE_TRAIL_ROTATE_SPEED * delta || state)
672 state = 1;
674 math_len_vec3(vr, vr,
675 CAMERA_LOOSE_TRAIL_ROTATE_SPEED * delta * sin(dist));
676 math_add_vec3(v1, v1, vr);
677 render_point_camera(cam, v1[X], v1[Y], v1[Z]);
679 math_sub_vec3(vr, player->position, cam->pos);
680 if(dist * math_norm_vec3(vr) < 0.06)
681 state = 0;
684 /* xx */
685 v1[X] = player->position[X];
686 v1[Y] = 0.0;
687 v1[Z] = 0.0;
689 v2[X] = cam->pos[X];
690 v2[Y] = 0.0;
691 v2[Z] = 0.0;
693 math_sub_vec3(vr, v2, v1);
695 dist = math_norm_vec3(vr);
696 math_len_vec3(vr, vr,
697 MAX(-delta * player->speed * dist * 0.7,
698 -CAMERA_LOOSE_TRAIL_SPEED * delta));
700 d2 = math_norm_vec3(vr);
701 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
703 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
705 /* yy */
706 v1[X] = 0.0;
707 v1[Y] = CAMERA_LOOSE_TRAIL_Y_OFFSET;
708 v1[Z] = 0.0;
710 v2[X] = 0.0;
711 v2[Y] = cam->pos[Y];
712 v2[Z] = 0.0;
714 math_sub_vec3(vr, v2, v1);
716 dist = math_norm_vec3(vr);
717 math_len_vec3(vr, vr,
718 MAX(-delta * player->speed * dist * 0.7,
719 -CAMERA_LOOSE_TRAIL_SPEED * delta));
721 d2 = math_norm_vec3(vr);
722 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
724 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
727 /* zz */
728 v1[X] = 0.0;
729 v1[Y] = 0.0;
730 v1[Z] = player->position[Z] + CAMERA_LOOSE_TRAIL_Z_OFFSET;
732 v2[X] = 0.0;
733 v2[Y] = 0.0;
734 v2[Z] = cam->pos[Z];
736 math_sub_vec3(vr, v2, v1);
738 dist = math_norm_vec3(vr);
739 math_len_vec3(vr, vr,
740 MAX(-delta * player->speed * dist * 0.9,
741 -CAMERA_LOOSE_TRAIL_SPEED * delta));
743 d2 = math_norm_vec3(vr);
744 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
746 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
748 break;
750 case CAMERA_TYPE_DEMO:
751 v1[X] = game->map->width / 2 + 0.5;
752 v1[Y] = 0.0;
753 v1[Z] = game->map->height / 2 + 0.5;
755 v2[X] = 0.0;
756 v2[Y] = 1.0;
757 v2[Z] = 0.0;
759 math_sub_vec3(vr, cam->pos, v1);
760 math_rotate_vec3(vr, vr, v2, CAMERA_DEMO_ROTATE_SPEED * delta);
761 math_add_vec3(cam->pos, v1, vr);
763 render_point_camera(cam,
764 game->map->width / 2 + 0.5, 0.0,
765 game->map->height / 2 + 0.5);
766 break;
768 case CAMERA_TYPE_TOMB_RAIDER:
769 v1[X] = cam->dir[X];
770 v1[Y] = cam->dir[Y];
771 v1[Z] = cam->dir[Z];
773 render_point_camera(cam,
774 player->position[X],
775 player->position[Y],
776 player->position[Z]);
779 v2[X] = cam->dir[X];
780 v2[Y] = cam->dir[Y];
781 v2[Z] = cam->dir[Z];
783 math_sub_vec3(vr, v2, v1);
784 dist = math_norm_vec3(vr);
785 if(dist > CAMERA_TOMB_RAIDER_ROTATE_SPEED * delta || state)
787 state = 1;
789 math_len_vec3(vr, vr,
790 CAMERA_TOMB_RAIDER_ROTATE_SPEED * delta * sin(dist));
791 math_add_vec3(v1, v1, vr);
792 render_point_camera(cam, v1[X], v1[Y], v1[Z]);
794 math_sub_vec3(vr, player->position, cam->pos);
795 if(dist * math_norm_vec3(vr) < 0.6)
796 state = 0;
799 /* xx */
800 switch(player->direction)
802 case DIRECTION_UP:
803 case DIRECTION_DOWN:
804 v1[X] = player->position[X];
805 break;
807 case DIRECTION_LEFT:
808 v1[X] = player->position[X] + CAMERA_TOMB_RAIDER_OFFSET;
809 break;
811 case DIRECTION_RIGHT:
812 v1[X] = player->position[X] - CAMERA_TOMB_RAIDER_OFFSET;
813 break;
815 v1[Y] = 0.0;
816 v1[Z] = 0.0;
818 v2[X] = cam->pos[X];
819 v2[Y] = 0.0;
820 v2[Z] = 0.0;
822 math_sub_vec3(vr, v2, v1);
824 dist = math_norm_vec3(vr);
825 math_len_vec3(vr, vr,
826 MAX(-delta * player->speed * dist * 0.7,
827 -CAMERA_TOMB_RAIDER_SPEED * delta));
829 d2 = math_norm_vec3(vr);
830 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
832 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
834 /* yy */
835 v1[X] = 0.0;
836 v1[Y] = CAMERA_TOMB_RAIDER_Y_OFFSET;
837 v1[Z] = 0.0;
839 v2[X] = 0.0;
840 v2[Y] = cam->pos[Y];
841 v2[Z] = 0.0;
843 math_sub_vec3(vr, v2, v1);
845 dist = math_norm_vec3(vr);
846 math_len_vec3(vr, vr,
847 MAX(-delta * player->speed * dist * 0.7,
848 -CAMERA_TOMB_RAIDER_SPEED * delta));
850 d2 = math_norm_vec3(vr);
851 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
853 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
855 /* zz */
856 v1[X] = 0.0;
857 v1[Y] = 0.0;
858 switch(player->direction)
860 case DIRECTION_UP:
861 v1[Z] = player->position[Z] - CAMERA_TOMB_RAIDER_OFFSET;
862 break;
864 case DIRECTION_DOWN:
865 v1[Z] = player->position[Z] + CAMERA_TOMB_RAIDER_OFFSET;
866 break;
868 case DIRECTION_LEFT:
869 case DIRECTION_RIGHT:
870 v1[Z] = player->position[Z];
871 break;
874 v2[X] = 0.0;
875 v2[Y] = 0.0;
876 v2[Z] = cam->pos[Z];
878 math_sub_vec3(vr, v2, v1);
880 dist = math_norm_vec3(vr);
881 math_len_vec3(vr, vr,
882 MAX(-delta * player->speed * dist * 0.9,
883 -CAMERA_TOMB_RAIDER_SPEED * delta));
885 d2 = math_norm_vec3(vr);
886 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
888 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
890 break;
892 case CAMERA_TYPE_FREE:
893 if(input_kstate(SDLK_w))
894 /* move forward */
895 render_advance_camera(cam, 0.0, 0.0, 0.1);
897 if(input_kstate(SDLK_s))
898 /* move backward */
899 render_advance_camera(cam, 0.0, 0.0, -0.1);
901 if(input_kstate(SDLK_a))
902 /* move left */
903 render_advance_camera(cam, -0.1, 0.0, 0.0);
905 if(input_kstate(SDLK_d))
906 /* move right */
907 render_advance_camera(cam, 0.1, 0.0, 0.0);
909 if(input_kstate(SDLK_r))
910 /* move up */
911 render_advance_camera(cam, 0.0, -0.1, 0.0);
913 if(input_kstate(SDLK_f))
914 /* move down */
915 render_advance_camera(cam, 0.0, 0.1, 0.0);
917 if(input_kstate(SDLK_q))
918 /* roll Cwise */
919 render_camera_roll(cam, 1.0);
921 if(input_kstate(SDLK_e))
922 /* roll CCwise */
923 render_camera_roll(cam, -1.0);
925 if(input_kstate(SDLK_z))
926 /* rotate Cwise */
927 render_camera_yaw(cam, 1.0);
929 if(input_kstate(SDLK_x))
930 /* rotate CCwise */
931 render_camera_yaw(cam, -1.0);
933 if(input_kstate(SDLK_t))
934 /* pitch up */
935 render_camera_pitch(cam, -1.0);
937 if(input_kstate(SDLK_g))
938 /* pitch down */
939 render_camera_pitch(cam, 1.0);
941 break;
946 actualiza o estado do jogo
948 void game_update(struct game *game, float delta)
950 int c;
952 map_update(game->map, delta);
954 for(c = 0; c < game->n_players; c++)
956 player_update(game, c, delta);
957 game_update_camera(game, c, delta);
960 for(c = 0; c < game->n_ghosts; c++)
961 ghost_update(game, c, delta);
963 for(c = 0; c < game->n_shots; c++)
964 shot_update(game, c, delta);
966 for(c = 0; c < game->n_bombs; c++)
967 bomb_update(game, c, delta);
969 if(game->demo_camera)
970 game_update_camera(game, -1, delta);
973 void game_draw_opaque_objects(struct game *game, int player_no)
975 int c;
977 for(c = 0; c < game->n_ghosts; c++)
978 ghost_render(game, &game->ghosts[c]);
980 for(c = 0; c < game->n_players; c++)
981 player_render(&game->players[c]);
983 for(c = 0; c < game->n_shots; c++)
984 shot_render_opaque(game, c);
986 for(c = 0; c < game->n_bombs; c++)
987 bomb_render_opaque(game, c);
990 void game_draw_translucent_objects(struct game *game, int player_no)
992 int c;
994 for(c = 0; c < game->n_shots; c++)
995 shot_render_translucent(game, player_no, c);
997 for(c = 0; c < game->n_bombs; c++)
998 bomb_render_translucent(game, player_no, c);