console: Format tabs semi-intelligently
[attac-man.git] / game.c
blob03c21803d0f0e361485b7c8789f39fd67e4ea7c4
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"
46 #include "score.h"
48 #include "player.h"
49 #include "ghost.h"
51 #include "render_map.h"
52 #include "render_ghost.h"
53 #include "render_player.h"
54 #include "render_shot.h"
55 #include "render_bomb.h"
56 #include "oglconsole.h"
58 #include "level-0.h"
59 //#include "level-classic.h"
60 //#include "level-demo.h"
61 //#include "level-1.h"
63 struct game *game_new(int game_type)
65 struct game *ret;
67 ret = (struct game *)malloc(sizeof(struct game));
68 ret->game_type = game_type;
69 ret->current_level = -1;
70 ret->n_players = 0;
71 ret->players = NULL;
72 ret->n_ghosts = 0;
73 ret->ghosts = NULL;
74 ret->n_shots = 0;
75 ret->bombs = NULL;
76 ret->n_bombs = 0;
77 ret->shots = NULL;
78 ret->map = NULL;
79 ret->demo_camera = NULL;
81 return ret;
84 void game_free(struct game *game)
86 if(game->players)
87 free(game->players);
88 if(game->ghosts)
89 free(game->ghosts);
90 if(game->map)
91 map_free(game->map);
93 free(game);
96 void game_run(struct game *game)
98 struct viewport *vp = screen_get_viewport(0);
99 int last_update, ticks;
100 int frames;
101 int c;
102 score_lock_t lock;
104 input_reset();
106 last_update = ticks = SDL_GetTicks();
108 game_start(game);
110 for(c = 0; c < game->n_players; c++)
112 render_reset_camera(game->players[c].camera);
113 game_reset_camera(game, c);
116 frames = 0;
118 audio_play_music("sfx/tranzy.ogg");
120 for(;;)
122 int diff;
124 input_update();
126 if(input_kstate(SDLK_ESCAPE))
128 audio_fade_music(500);
129 SDL_Delay(500);
130 return;
133 diff = SDL_GetTicks() - last_update;
134 game_update(game, (float)diff / 1000);
135 last_update = SDL_GetTicks();
137 render_start_frame();
139 for(c = 0; c < game->n_players; c++)
141 render_setup(game, c);
143 map_render_opaque_objects(game);
144 game_draw_opaque_objects(game, c);
145 map_render_translucent_objects(game, c);
146 game_draw_translucent_objects(game, c);
147 game_draw_player_lives(game, c, (float)diff / 1000);
151 if(game->n_players == 1)
152 render_draw_logo();
155 render_setup_2d(vp);
156 render_finish_frame();
157 frames++;
159 if(SDL_GetTicks() - ticks >= 1000)
161 printf("%d FPS\n", frames);
162 ticks = SDL_GetTicks();
163 frames = 0;
166 if (game_count_dots(game) == 0 || game->players[0].lives == 0) {
168 con_printf("Final Score: %d\n", game->players[0].score);
169 lock = lock_scores();
170 if (lock >= 0) {
171 if (high_score(game->players[0].score)) {
172 add_high_score("xxx",
173 game->players[0].score);
174 rewrite_score_file();
176 unlock_scores(lock);
178 if (game_count_dots(game) == 0)
179 game_do_victory_loop(game);
180 else
181 game_do_defeat_loop(game);
182 return;
185 SDL_Delay(0);
189 void game_draw_player_lives(struct game *game, int player_no, float delta)
191 GLfloat light0_position[] = { 0.0, 1.0, 0.0, 1.0 };
192 GLfloat light0_direction[] = { 0.0, 0.5, 1.5 };
193 GLfloat inactive_color[] = { 0.5, 0.5, 0.5, 1.0 };
195 int c;
196 struct player *p;
197 static float frame = 0.0;
199 struct viewport *vp;
201 vp = screen_get_viewport(player_no);
202 p = &game->players[player_no];
203 frame += delta * ANIM_FPS;
205 for(c = 0; c < p->lives; c++)
207 glMatrixMode(GL_MODELVIEW);
208 glLoadIdentity();
209 glMatrixMode(GL_PROJECTION);
210 glLoadIdentity();
212 glViewport(0 + 70 * vp->width / 800 * c, 0,
213 150 * vp->width / 800, 150 * vp->width / 800);
215 glViewport(0 + 70 * vp->width / 800 * c, vp->ll_y,
216 150 * vp->width / 800, 150 * vp->width / 800);
218 glFrustum(-1.0, 1.0,
219 -1.0, 1.0, 1.5, 3.0);
220 gluLookAt(0.0, 0.0, 0.0,
221 0.0, 0.0, 1.0,
222 0.0, 1.0, 0.0);
224 glShadeModel(GL_SMOOTH);
225 glEnable(GL_COLOR_MATERIAL);
226 glDisable(GL_BLEND);
227 glDisable(GL_TEXTURE_2D);
228 glEnable(GL_DEPTH_TEST);
229 glDepthMask(GL_TRUE);
231 glEnable(GL_LIGHTING);
232 glEnable(GL_LIGHT0);
233 glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
234 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0_direction);
236 glClear(GL_DEPTH_BUFFER_BIT);
237 glMatrixMode(GL_MODELVIEW);
238 glTranslatef(0.0, 0.0, 2.1);
240 glRotatef(180.0, 0.0, 1.0, 0.0);
241 glRotatef(180.0, 0.0, 0.0, 1.0);
242 glRotatef(-75.0, 0.0, 1.0, 0.0);
244 if(c == p->lives - 1)
245 switch(p->state)
247 case PLAYER_STATE_MOVING:
248 case PLAYER_STATE_STOPPED:
249 render_dlist(&p->model_moving[(int)frame % p->frames_moving], p->color);
250 break;
252 case PLAYER_STATE_DEAD:
253 render_dlist(&p->model_dying[(int)p->current_frame % p->frames_dying], p->color);
254 break;
256 else
257 render_dlist(&p->model_stopped[0], inactive_color);
261 #if 1
262 /* XXX - this is for player 0 only */
263 void game_do_victory_loop(struct game *game)
265 int last_update;
266 struct image_rgba32 *level_complete;
267 int tx_level_complete;
268 struct viewport *vp;
270 audio_fade_music(500);
271 SDL_Delay(500);
273 level_complete = gfx_get("gfx/level-complete.tga");
274 gfx_alpha_from_key("gfx/level-complete.tga", 0, 0, 0);
275 tx_level_complete = gfx_upload_texture("gfx/level-complete.tga");
277 audio_play_music("sfx/hiscore.ogg");
279 game->players[0].camera->type = CAMERA_TYPE_DEMO;
281 last_update = SDL_GetTicks();
283 game->players[0].state = PLAYER_STATE_WON;
284 game->players[0].current_frame = 0.0;
285 vp = screen_get_viewport(0);
287 for(;;)
289 SDL_Event ev;
290 int diff, c;
291 float delta;
293 while(SDL_PollEvent(&ev))
295 if (OGLCONSOLE_SDLEvent(&ev) != 0)
296 continue;
298 if(ev.type == SDL_QUIT)
300 SDL_Quit();
301 exit(0);
304 if((ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE) ||
305 (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_SPACE))
307 audio_fade_music(500);
308 SDL_Delay(500);
309 return;
313 diff = SDL_GetTicks() - last_update;
314 last_update = SDL_GetTicks();
315 delta = (float)diff / 1000.0;
317 for(c = 0; c < game->n_players; c++)
318 game->players[c].current_frame += delta * ANIM_FPS;
320 for(c = 0; c < game->n_ghosts; c++)
321 game->ghosts[c].current_frame += delta * ANIM_FPS;
323 game_update_camera(game, 0, delta);
324 render_point_camera(game->players[0].camera,
325 game->players[0].position[X],
326 game->players[0].position[Y],
327 game->players[0].position[Z]);
329 render_start_frame();
331 render_setup(game, 0);
332 map_render_opaque_objects(game);
333 game_draw_opaque_objects(game, 0);
334 map_render_translucent_objects(game, 0);
335 game_draw_translucent_objects(game, 0);
337 /* render_draw_logo();*/
339 render_setup_2d(vp);
341 if(level_complete->width > vp->width)
342 render_draw_scaled_image("gfx/level-complete.tga",
343 0, 0,
344 vp->width,
345 level_complete->height * vp->height / vp->width);
346 else
347 render_draw_scaled_image("gfx/level-complete.tga",
348 (vp->width - level_complete->width) / 2, 0,
349 (vp->width + level_complete->width) / 2,
350 level_complete->height);
352 render_finish_frame();
356 /* XXX - player 0 only */
357 void game_do_defeat_loop(struct game *game)
359 int last_update;
360 struct image_rgba32 *game_over;
361 int tx_game_over;
362 struct viewport *vp;
364 audio_fade_music(500);
365 SDL_Delay(500);
367 game_over = gfx_get("gfx/game-over.tga");
368 gfx_alpha_from_key("gfx/game-over.tga", 0, 0, 0);
369 tx_game_over = gfx_upload_texture("gfx/game-over.tga");
371 audio_play_music("sfx/gameover.ogg");
373 game->players[0].camera->type = CAMERA_TYPE_DEMO;
375 last_update = SDL_GetTicks();
376 vp = screen_get_viewport(0);
378 for(;;)
380 int diff, c;
381 float delta;
383 input_update();
385 if(input_kstate(SDLK_ESCAPE))
387 input_kclear(SDLK_ESCAPE);
388 audio_fade_music(500);
389 SDL_Delay(500);
390 return;
393 diff = SDL_GetTicks() - last_update;
394 last_update = SDL_GetTicks();
395 delta = (float)diff / 1000.0;
397 for(c = 0; c < n_players; c++)
398 players[c].current_frame += delta * ANIM_FPS;
400 for(c = 0; c < game->n_ghosts; c++)
401 game->ghosts[c].current_frame += delta * ANIM_FPS;
403 game_update_camera(game, 0, delta);
404 render_point_camera(game->players[0].camera,
405 game->players[0].position[X],
406 game->players[0].position[Y],
407 game->players[0].position[Z]);
409 render_start_frame();
411 render_setup(game, 0);
412 map_render_opaque_objects(game);
413 game_draw_opaque_objects(game, 0);
414 map_render_translucent_objects(game, 0);
415 game_draw_translucent_objects(game, 0);
417 /* render_draw_logo();*/
419 render_setup_2d(vp);
421 if(game_over->width > vp->width)
422 render_draw_scaled_image("gfx/game-over.tga",
423 0, 0,
424 vp->width,
425 game_over->height * vp->height / vp->width);
426 else
427 render_draw_scaled_image("gfx/game-over.tga",
428 (vp->width - game_over->width) / 2, 0,
429 (vp->width + game_over->width) / 2,
430 game_over->height);
431 render_finish_frame();
434 #else
435 void game_do_victory_loop(struct game *game)
439 void game_do_defeat_loop(struct game *game)
442 #endif
444 void game_reset(struct game *game)
446 player_reset(game);
447 glDisable(GL_LIGHT1);
450 int game_count_dots(struct game *game)
452 struct map *map;
453 int x, y, ret;
455 map = game->map;
456 ret = 0;
458 for(x = 0; x < map->width; x++)
459 for(y = 0; y < map->height; y++)
460 if(MAP(map, x, y).content == MAP_CONTENT_FOOD &&
461 MAP(map, x, y).c_data.food.status == FOOD_STATUS_ACTIVE)
462 ret++;
464 return ret;
467 void game_teleport_player(struct game *game, int player)
469 struct player *p;
470 struct map *map;
471 int x, y;
472 int dx, dy;
474 p = &game->players[player];
475 map = game->map;
477 x = (int)p->position[X];
478 y = (int)p->position[Z];
480 if(MAP(map, x, y).content != MAP_CONTENT_TELEPORT)
481 return;
483 if(MAP_TELEPORT(map, x, y).direction != p->direction)
484 return;
486 dx = MAP_TELEPORT(map, x, y).dest_x;
487 dy = MAP_TELEPORT(map, x, y).dest_y;
489 p->position[X] = (float)dx + 0.5;
490 p->position[Z] = (float)dy + 0.5;
493 void game_start(struct game *game)
495 struct map *map;
496 int c, cx, cy;
498 /* distribuir os jogadores pelos spawn points */
499 c = 0;
500 map = game->map;
502 for(cx = 0; cx < map->width; cx++)
503 for(cy = 0; cy < map->height; cy++)
504 if(c < game->n_players &&
505 MAP(map, cx, cy).flags & MAP_FLAG_PACMAN_START_POSITION)
507 /* spawn */
508 game->players[c].position[X] = (float)cx + 0.5;
509 game->players[c].position[Z] = (float)cy + 0.5;
511 game->players[c].start_position[X] = (float)cx + 0.5;
512 game->players[c].start_position[Y] = game->players[c].position[Y];
513 game->players[c].start_position[Z] = (float)cy + 0.5;
515 c++;
517 if(c == game->n_players)
518 break;
523 if(c != game->n_players)
525 printf("game_start: tanta gente (%d)!\n", game->n_players);
526 SDL_Quit();
527 exit(1);
530 ghost_reset_all(game);
533 void game_reset_camera(struct game *game, int player_no)
535 struct camera *cam;
536 struct player *player;
538 if(player_no == -1)
540 player = NULL;
541 cam = game->demo_camera;
542 } else {
543 player = &game->players[player_no];
544 cam = player->camera;
547 switch(cam->type)
549 case CAMERA_TYPE_FIXED_CHASE:
550 break;
552 case CAMERA_TYPE_LOOSE_CHASE:
553 render_reset_camera(cam);
554 render_move_camera(cam,
555 player->position[X],
556 -3.5,
557 player->position[Z] - 3.5);
558 break;
560 case CAMERA_TYPE_LOOSE_TRAIL:
561 render_reset_camera(cam);
562 render_move_camera(cam,
563 0.0, CAMERA_LOOSE_TRAIL_Y_OFFSET, CAMERA_LOOSE_TRAIL_Z_OFFSET);
564 render_point_camera(cam,
565 player->position[X],
566 player->position[Y],
567 player->position[Z]);
569 break;
571 case CAMERA_TYPE_DEMO:
572 render_reset_camera(cam);
573 render_move_camera(cam, game->map->width / 2 + 0.5, CAMERA_DEMO_HEIGHT, 0.0);
574 render_point_camera(cam, game->map->width / 2 + 0.5, 0.0, game->map->height / 2 + 0.5);
575 break;
577 case CAMERA_TYPE_TOMB_RAIDER:
578 render_reset_camera(cam);
579 render_move_camera(cam,
580 0.0, CAMERA_TOMB_RAIDER_Y_OFFSET, -CAMERA_TOMB_RAIDER_OFFSET);
581 render_point_camera(cam,
582 player->position[X],
583 player->position[Y],
584 player->position[Z]);
586 break;
588 case CAMERA_TYPE_FREE:
589 break;
593 void game_update_camera(struct game *game, int player_no, float delta)
595 static int state = 0;
596 struct camera *cam;
597 struct player *player;
599 if(player_no == -1)
601 /* magic value: demo camera */
602 player = NULL;
603 cam = game->demo_camera;
604 } else {
605 player = &game->players[player_no];
606 cam = player->camera;
609 if(input_kstate(SDLK_c))
611 cam->type = (cam->type + 1) % CAMERA_NUM_TYPES;
612 input_kclear(SDLK_c);
613 // game_reset_camera(game, player_no);
616 switch(cam->type)
618 float v1[3], v2[3], vr[3], dist, d2;
620 case CAMERA_TYPE_FIXED_CHASE:
621 render_reset_camera(cam);
622 render_move_camera(cam,
623 player->position[X],
624 -3.5,
625 player->position[Z] - 2.5);
626 render_point_camera(cam,
627 player->position[X],
628 player->position[Y],
629 player->position[Z]);
631 break;
633 case CAMERA_TYPE_LOOSE_CHASE:
634 render_point_camera(cam,
635 player->position[X],
636 player->position[Y],
637 player->position[Z]);
639 v1[X] = player->position[X];
640 v1[Y] = cam->pos[Y];
641 v1[Z] = player->position[Z];
643 math_sub_vec3(v1, v1, cam->pos);
645 if(state)
647 if(math_norm_vec3(v1) > CAMERA_LOOSE_CHASE_LOW_THRESHOLD)
649 math_len_vec3(v1, v1, delta * CAMERA_LOOSE_CHASE_SPEED);
650 math_add_vec3(v1, cam->pos, v1);
651 render_move_camera(cam, v1[X], v1[Y], v1[Z]);
652 } else
653 state = 0;
654 } else
655 if(math_norm_vec3(v1) > CAMERA_LOOSE_CHASE_HIGH_THRESHOLD)
656 state = 1;
658 break;
660 case CAMERA_TYPE_LOOSE_TRAIL:
661 v1[X] = cam->dir[X];
662 v1[Y] = cam->dir[Y];
663 v1[Z] = cam->dir[Z];
665 render_point_camera(cam,
666 player->position[X],
667 player->position[Y],
668 player->position[Z]);
671 v2[X] = cam->dir[X];
672 v2[Y] = cam->dir[Y];
673 v2[Z] = cam->dir[Z];
675 math_sub_vec3(vr, v2, v1);
676 dist = math_norm_vec3(vr);
677 if(dist > CAMERA_LOOSE_TRAIL_ROTATE_SPEED * delta || state)
679 state = 1;
681 math_len_vec3(vr, vr,
682 CAMERA_LOOSE_TRAIL_ROTATE_SPEED * delta * sin(dist));
683 math_add_vec3(v1, v1, vr);
684 render_point_camera(cam, v1[X], v1[Y], v1[Z]);
686 math_sub_vec3(vr, player->position, cam->pos);
687 if(dist * math_norm_vec3(vr) < 0.06)
688 state = 0;
691 /* xx */
692 v1[X] = player->position[X];
693 v1[Y] = 0.0;
694 v1[Z] = 0.0;
696 v2[X] = cam->pos[X];
697 v2[Y] = 0.0;
698 v2[Z] = 0.0;
700 math_sub_vec3(vr, v2, v1);
702 dist = math_norm_vec3(vr);
703 math_len_vec3(vr, vr,
704 MAX(-delta * player->speed * dist * 0.7,
705 -CAMERA_LOOSE_TRAIL_SPEED * delta));
707 d2 = math_norm_vec3(vr);
708 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
710 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
712 /* yy */
713 v1[X] = 0.0;
714 v1[Y] = CAMERA_LOOSE_TRAIL_Y_OFFSET;
715 v1[Z] = 0.0;
717 v2[X] = 0.0;
718 v2[Y] = cam->pos[Y];
719 v2[Z] = 0.0;
721 math_sub_vec3(vr, v2, v1);
723 dist = math_norm_vec3(vr);
724 math_len_vec3(vr, vr,
725 MAX(-delta * player->speed * dist * 0.7,
726 -CAMERA_LOOSE_TRAIL_SPEED * delta));
728 d2 = math_norm_vec3(vr);
729 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
731 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
734 /* zz */
735 v1[X] = 0.0;
736 v1[Y] = 0.0;
737 v1[Z] = player->position[Z] + CAMERA_LOOSE_TRAIL_Z_OFFSET;
739 v2[X] = 0.0;
740 v2[Y] = 0.0;
741 v2[Z] = cam->pos[Z];
743 math_sub_vec3(vr, v2, v1);
745 dist = math_norm_vec3(vr);
746 math_len_vec3(vr, vr,
747 MAX(-delta * player->speed * dist * 0.9,
748 -CAMERA_LOOSE_TRAIL_SPEED * delta));
750 d2 = math_norm_vec3(vr);
751 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
753 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
755 break;
757 case CAMERA_TYPE_DEMO:
758 v1[X] = game->map->width / 2 + 0.5;
759 v1[Y] = 0.0;
760 v1[Z] = game->map->height / 2 + 0.5;
762 v2[X] = 0.0;
763 v2[Y] = 1.0;
764 v2[Z] = 0.0;
766 math_sub_vec3(vr, cam->pos, v1);
767 math_rotate_vec3(vr, vr, v2, CAMERA_DEMO_ROTATE_SPEED * delta);
768 math_add_vec3(cam->pos, v1, vr);
770 render_point_camera(cam,
771 game->map->width / 2 + 0.5, 0.0,
772 game->map->height / 2 + 0.5);
773 break;
775 case CAMERA_TYPE_TOMB_RAIDER:
776 v1[X] = cam->dir[X];
777 v1[Y] = cam->dir[Y];
778 v1[Z] = cam->dir[Z];
780 render_point_camera(cam,
781 player->position[X],
782 player->position[Y],
783 player->position[Z]);
786 v2[X] = cam->dir[X];
787 v2[Y] = cam->dir[Y];
788 v2[Z] = cam->dir[Z];
790 math_sub_vec3(vr, v2, v1);
791 dist = math_norm_vec3(vr);
792 if(dist > CAMERA_TOMB_RAIDER_ROTATE_SPEED * delta || state)
794 state = 1;
796 math_len_vec3(vr, vr,
797 CAMERA_TOMB_RAIDER_ROTATE_SPEED * delta * sin(dist));
798 math_add_vec3(v1, v1, vr);
799 render_point_camera(cam, v1[X], v1[Y], v1[Z]);
801 math_sub_vec3(vr, player->position, cam->pos);
802 if(dist * math_norm_vec3(vr) < 0.6)
803 state = 0;
806 /* xx */
807 switch(player->direction)
809 case DIRECTION_UP:
810 case DIRECTION_DOWN:
811 v1[X] = player->position[X];
812 break;
814 case DIRECTION_LEFT:
815 v1[X] = player->position[X] + CAMERA_TOMB_RAIDER_OFFSET;
816 break;
818 case DIRECTION_RIGHT:
819 v1[X] = player->position[X] - CAMERA_TOMB_RAIDER_OFFSET;
820 break;
822 v1[Y] = 0.0;
823 v1[Z] = 0.0;
825 v2[X] = cam->pos[X];
826 v2[Y] = 0.0;
827 v2[Z] = 0.0;
829 math_sub_vec3(vr, v2, v1);
831 dist = math_norm_vec3(vr);
832 math_len_vec3(vr, vr,
833 MAX(-delta * player->speed * dist * 0.7,
834 -CAMERA_TOMB_RAIDER_SPEED * delta));
836 d2 = math_norm_vec3(vr);
837 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
839 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
841 /* yy */
842 v1[X] = 0.0;
843 v1[Y] = CAMERA_TOMB_RAIDER_Y_OFFSET;
844 v1[Z] = 0.0;
846 v2[X] = 0.0;
847 v2[Y] = cam->pos[Y];
848 v2[Z] = 0.0;
850 math_sub_vec3(vr, v2, v1);
852 dist = math_norm_vec3(vr);
853 math_len_vec3(vr, vr,
854 MAX(-delta * player->speed * dist * 0.7,
855 -CAMERA_TOMB_RAIDER_SPEED * delta));
857 d2 = math_norm_vec3(vr);
858 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
860 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
862 /* zz */
863 v1[X] = 0.0;
864 v1[Y] = 0.0;
865 switch(player->direction)
867 case DIRECTION_UP:
868 v1[Z] = player->position[Z] - CAMERA_TOMB_RAIDER_OFFSET;
869 break;
871 case DIRECTION_DOWN:
872 v1[Z] = player->position[Z] + CAMERA_TOMB_RAIDER_OFFSET;
873 break;
875 case DIRECTION_LEFT:
876 case DIRECTION_RIGHT:
877 v1[Z] = player->position[Z];
878 break;
881 v2[X] = 0.0;
882 v2[Y] = 0.0;
883 v2[Z] = cam->pos[Z];
885 math_sub_vec3(vr, v2, v1);
887 dist = math_norm_vec3(vr);
888 math_len_vec3(vr, vr,
889 MAX(-delta * player->speed * dist * 0.9,
890 -CAMERA_TOMB_RAIDER_SPEED * delta));
892 d2 = math_norm_vec3(vr);
893 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
895 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
897 break;
899 case CAMERA_TYPE_FREE:
900 if(input_kstate(SDLK_w))
901 /* move forward */
902 render_advance_camera(cam, 0.0, 0.0, 0.1);
904 if(input_kstate(SDLK_s))
905 /* move backward */
906 render_advance_camera(cam, 0.0, 0.0, -0.1);
908 if(input_kstate(SDLK_a))
909 /* move left */
910 render_advance_camera(cam, -0.1, 0.0, 0.0);
912 if(input_kstate(SDLK_d))
913 /* move right */
914 render_advance_camera(cam, 0.1, 0.0, 0.0);
916 if(input_kstate(SDLK_r))
917 /* move up */
918 render_advance_camera(cam, 0.0, -0.1, 0.0);
920 if(input_kstate(SDLK_f))
921 /* move down */
922 render_advance_camera(cam, 0.0, 0.1, 0.0);
924 if(input_kstate(SDLK_q))
925 /* roll Cwise */
926 render_camera_roll(cam, 1.0);
928 if(input_kstate(SDLK_e))
929 /* roll CCwise */
930 render_camera_roll(cam, -1.0);
932 if(input_kstate(SDLK_z))
933 /* rotate Cwise */
934 render_camera_yaw(cam, 1.0);
936 if(input_kstate(SDLK_x))
937 /* rotate CCwise */
938 render_camera_yaw(cam, -1.0);
940 if(input_kstate(SDLK_t))
941 /* pitch up */
942 render_camera_pitch(cam, -1.0);
944 if(input_kstate(SDLK_g))
945 /* pitch down */
946 render_camera_pitch(cam, 1.0);
948 break;
953 actualiza o estado do jogo
955 void game_update(struct game *game, float delta)
957 int c;
959 map_update(game->map, delta);
961 for(c = 0; c < game->n_players; c++)
963 player_update(game, c, delta);
964 game_update_camera(game, c, delta);
967 for(c = 0; c < game->n_ghosts; c++)
968 ghost_update(game, c, delta);
970 for(c = 0; c < game->n_shots; c++)
971 shot_update(game, c, delta);
973 for(c = 0; c < game->n_bombs; c++)
974 bomb_update(game, c, delta);
976 if(game->demo_camera)
977 game_update_camera(game, -1, delta);
980 void game_draw_opaque_objects(struct game *game, int player_no)
982 int c;
984 for(c = 0; c < game->n_ghosts; c++)
985 ghost_render(game, &game->ghosts[c]);
987 for(c = 0; c < game->n_players; c++)
988 player_render(&game->players[c]);
990 for(c = 0; c < game->n_shots; c++)
991 shot_render_opaque(game, c);
993 for(c = 0; c < game->n_bombs; c++)
994 bomb_render_opaque(game, c);
997 void game_draw_translucent_objects(struct game *game, int player_no)
999 int c;
1001 for(c = 0; c < game->n_shots; c++)
1002 shot_render_translucent(game, player_no, c);
1004 for(c = 0; c < game->n_bombs; c++)
1005 bomb_render_translucent(game, player_no, c);