Nuke '^M' from includes
[attac-man.git] / game.c
blob1f31464c96cbed0814d7bd8e94b5217899427da3
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"
56 #include "level-0.h"
57 //#include "level-classic.h"
58 //#include "level-demo.h"
59 //#include "level-1.h"
61 struct game *game_new(int game_type)
63 struct game *ret;
65 ret = (struct game *)malloc(sizeof(struct game));
66 ret->game_type = game_type;
67 ret->current_level = -1;
68 ret->n_players = 0;
69 ret->players = NULL;
70 ret->n_ghosts = 0;
71 ret->ghosts = NULL;
72 ret->n_shots = 0;
73 ret->bombs = NULL;
74 ret->n_bombs = 0;
75 ret->shots = NULL;
76 ret->map = NULL;
77 ret->demo_camera = NULL;
79 return ret;
82 void game_free(struct game *game)
84 if(game->players)
85 free(game->players);
86 if(game->ghosts)
87 free(game->ghosts);
88 if(game->map)
89 map_free(game->map);
91 free(game);
94 void game_run(struct game *game)
96 int last_update, ticks;
97 int frames;
98 int c;
100 input_reset();
102 last_update = ticks = SDL_GetTicks();
104 game_start(game);
106 for(c = 0; c < game->n_players; c++)
108 render_reset_camera(game->players[c].camera);
109 game_reset_camera(game, c);
112 frames = 0;
114 audio_play_music("sfx/tranzy.ogg");
116 for(;;)
118 int diff;
120 input_update();
122 if(input_kstate(SDLK_ESCAPE))
124 audio_fade_music(500);
125 SDL_Delay(500);
126 return;
129 diff = SDL_GetTicks() - last_update;
130 game_update(game, (float)diff / 1000);
131 last_update = SDL_GetTicks();
133 render_start_frame();
135 for(c = 0; c < game->n_players; c++)
137 render_setup(game, c);
139 map_render_opaque_objects(game);
140 game_draw_opaque_objects(game, c);
141 map_render_translucent_objects(game, c);
142 game_draw_translucent_objects(game, c);
143 game_draw_player_lives(game, c, (float)diff / 1000);
147 if(game->n_players == 1)
148 render_draw_logo();
151 render_finish_frame();
152 frames++;
154 if(SDL_GetTicks() - ticks >= 1000)
156 printf("%d FPS\n", frames);
157 ticks = SDL_GetTicks();
158 frames = 0;
161 if(game_count_dots(game) == 0)
163 game_do_victory_loop(game);
164 return;
167 if(game->players[0].lives == 0)
169 game_do_defeat_loop(game);
170 return;
173 SDL_Delay(0);
177 void game_draw_player_lives(struct game *game, int player_no, float delta)
179 GLfloat light0_position[] = { 0.0, 1.0, 0.0, 1.0 };
180 GLfloat light0_direction[] = { 0.0, 0.5, 1.5 };
181 GLfloat inactive_color[] = { 0.5, 0.5, 0.5, 1.0 };
183 int c;
184 struct player *p;
185 static float frame = 0.0;
187 struct viewport *vp;
189 vp = screen_get_viewport(player_no);
190 p = &game->players[player_no];
191 frame += delta * ANIM_FPS;
193 for(c = 0; c < p->lives; c++)
195 glMatrixMode(GL_MODELVIEW);
196 glLoadIdentity();
197 glMatrixMode(GL_PROJECTION);
198 glLoadIdentity();
200 glViewport(0 + 70 * vp->width / 800 * c, 0,
201 150 * vp->width / 800, 150 * vp->width / 800);
203 glViewport(0 + 70 * vp->width / 800 * c, vp->ll_y,
204 150 * vp->width / 800, 150 * vp->width / 800);
206 glFrustum(-1.0, 1.0,
207 -1.0, 1.0, 1.5, 3.0);
208 gluLookAt(0.0, 0.0, 0.0,
209 0.0, 0.0, 1.0,
210 0.0, 1.0, 0.0);
212 glShadeModel(GL_SMOOTH);
213 glEnable(GL_COLOR_MATERIAL);
214 glDisable(GL_BLEND);
215 glDisable(GL_TEXTURE_2D);
216 glEnable(GL_DEPTH_TEST);
217 glDepthMask(GL_TRUE);
219 glEnable(GL_LIGHTING);
220 glEnable(GL_LIGHT0);
221 glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
222 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0_direction);
224 glClear(GL_DEPTH_BUFFER_BIT);
225 glMatrixMode(GL_MODELVIEW);
226 glTranslatef(0.0, 0.0, 2.1);
228 glRotatef(180.0, 0.0, 1.0, 0.0);
229 glRotatef(180.0, 0.0, 0.0, 1.0);
230 glRotatef(-75.0, 0.0, 1.0, 0.0);
232 if(c == p->lives - 1)
233 switch(p->state)
235 case PLAYER_STATE_MOVING:
236 case PLAYER_STATE_STOPPED:
237 render_dlist(&p->model_moving[(int)frame % p->frames_moving], p->color);
238 break;
240 case PLAYER_STATE_DEAD:
241 render_dlist(&p->model_dying[(int)p->current_frame % p->frames_dying], p->color);
242 break;
244 else
245 render_dlist(&p->model_stopped[0], inactive_color);
249 #if 1
250 /* XXX - this is for player 0 only */
251 void game_do_victory_loop(struct game *game)
253 int last_update;
254 struct image_rgba32 *level_complete;
255 int tx_level_complete;
256 struct viewport *vp;
258 audio_fade_music(500);
259 SDL_Delay(500);
261 level_complete = gfx_get("gfx/level-complete.tga");
262 gfx_alpha_from_key("gfx/level-complete.tga", 0, 0, 0);
263 tx_level_complete = gfx_upload_texture("gfx/level-complete.tga");
265 audio_play_music("sfx/hiscore.ogg");
267 game->players[0].camera->type = CAMERA_TYPE_DEMO;
269 last_update = SDL_GetTicks();
271 game->players[0].state = PLAYER_STATE_WON;
272 game->players[0].current_frame = 0.0;
273 vp = screen_get_viewport(0);
275 for(;;)
277 SDL_Event ev;
278 int diff, c;
279 float delta;
281 while(SDL_PollEvent(&ev))
283 if(ev.type == SDL_QUIT)
285 SDL_Quit();
286 exit(0);
289 if((ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE) ||
290 (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_SPACE))
292 audio_fade_music(500);
293 SDL_Delay(500);
294 return;
298 diff = SDL_GetTicks() - last_update;
299 last_update = SDL_GetTicks();
300 delta = (float)diff / 1000.0;
302 for(c = 0; c < game->n_players; c++)
303 game->players[c].current_frame += delta * ANIM_FPS;
305 for(c = 0; c < game->n_ghosts; c++)
306 game->ghosts[c].current_frame += delta * ANIM_FPS;
308 game_update_camera(game, 0, delta);
309 render_point_camera(game->players[0].camera,
310 game->players[0].position[X],
311 game->players[0].position[Y],
312 game->players[0].position[Z]);
314 render_start_frame();
316 render_setup(game, 0);
317 map_render_opaque_objects(game);
318 game_draw_opaque_objects(game, 0);
319 map_render_translucent_objects(game, 0);
320 game_draw_translucent_objects(game, 0);
322 /* render_draw_logo();*/
324 render_setup_2d(vp);
326 if(level_complete->width > vp->width)
327 render_draw_scaled_image("gfx/level-complete.tga",
328 0, 0,
329 vp->width,
330 level_complete->height * vp->height / vp->width);
331 else
332 render_draw_scaled_image("gfx/level-complete.tga",
333 (vp->width - level_complete->width) / 2, 0,
334 (vp->width + level_complete->width) / 2,
335 level_complete->height);
337 render_finish_frame();
341 /* XXX - player 0 only */
342 void game_do_defeat_loop(struct game *game)
344 int last_update;
345 struct image_rgba32 *game_over;
346 int tx_game_over;
347 struct viewport *vp;
349 audio_fade_music(500);
350 SDL_Delay(500);
352 game_over = gfx_get("gfx/game-over.tga");
353 gfx_alpha_from_key("gfx/game-over.tga", 0, 0, 0);
354 tx_game_over = gfx_upload_texture("gfx/game-over.tga");
356 audio_play_music("sfx/gameover.ogg");
358 game->players[0].camera->type = CAMERA_TYPE_DEMO;
360 last_update = SDL_GetTicks();
361 vp = screen_get_viewport(0);
363 for(;;)
365 int diff, c;
366 float delta;
368 input_update();
370 if(input_kstate(SDLK_ESCAPE))
372 input_kclear(SDLK_ESCAPE);
373 audio_fade_music(500);
374 SDL_Delay(500);
375 return;
378 diff = SDL_GetTicks() - last_update;
379 last_update = SDL_GetTicks();
380 delta = (float)diff / 1000.0;
382 for(c = 0; c < n_players; c++)
383 players[c].current_frame += delta * ANIM_FPS;
385 for(c = 0; c < game->n_ghosts; c++)
386 game->ghosts[c].current_frame += delta * ANIM_FPS;
388 game_update_camera(game, 0, delta);
389 render_point_camera(game->players[0].camera,
390 game->players[0].position[X],
391 game->players[0].position[Y],
392 game->players[0].position[Z]);
394 render_start_frame();
396 render_setup(game, 0);
397 map_render_opaque_objects(game);
398 game_draw_opaque_objects(game, 0);
399 map_render_translucent_objects(game, 0);
400 game_draw_translucent_objects(game, 0);
402 /* render_draw_logo();*/
404 render_setup_2d(vp);
406 if(game_over->width > vp->width)
407 render_draw_scaled_image("gfx/game-over.tga",
408 0, 0,
409 vp->width,
410 game_over->height * vp->height / vp->width);
411 else
412 render_draw_scaled_image("gfx/game-over.tga",
413 (vp->width - game_over->width) / 2, 0,
414 (vp->width + game_over->width) / 2,
415 game_over->height);
416 render_finish_frame();
419 #else
420 void game_do_victory_loop(struct game *game)
424 void game_do_defeat_loop(struct game *game)
427 #endif
429 void game_reset(struct game *game)
431 player_reset(game);
432 glDisable(GL_LIGHT1);
435 int game_count_dots(struct game *game)
437 struct map *map;
438 int x, y, ret;
440 map = game->map;
441 ret = 0;
443 for(x = 0; x < map->width; x++)
444 for(y = 0; y < map->height; y++)
445 if(MAP(map, x, y).content == MAP_CONTENT_FOOD &&
446 MAP(map, x, y).c_data.food.status == FOOD_STATUS_ACTIVE)
447 ret++;
449 return ret;
452 void game_teleport_player(struct game *game, int player)
454 struct player *p;
455 struct map *map;
456 int x, y;
457 int dx, dy;
459 p = &game->players[player];
460 map = game->map;
462 x = (int)p->position[X];
463 y = (int)p->position[Z];
465 if(MAP(map, x, y).content != MAP_CONTENT_TELEPORT)
466 return;
468 if(MAP_TELEPORT(map, x, y).direction != p->direction)
469 return;
471 dx = MAP_TELEPORT(map, x, y).dest_x;
472 dy = MAP_TELEPORT(map, x, y).dest_y;
474 p->position[X] = (float)dx + 0.5;
475 p->position[Z] = (float)dy + 0.5;
478 void game_start(struct game *game)
480 struct map *map;
481 int c, cx, cy;
483 /* distribuir os jogadores pelos spawn points */
484 c = 0;
485 map = game->map;
487 for(cx = 0; cx < map->width; cx++)
488 for(cy = 0; cy < map->height; cy++)
489 if(c < game->n_players &&
490 MAP(map, cx, cy).flags & MAP_FLAG_PACMAN_START_POSITION)
492 /* spawn */
493 game->players[c].position[X] = (float)cx + 0.5;
494 game->players[c].position[Z] = (float)cy + 0.5;
496 game->players[c].start_position[X] = (float)cx + 0.5;
497 game->players[c].start_position[Y] = game->players[c].position[Y];
498 game->players[c].start_position[Z] = (float)cy + 0.5;
500 c++;
502 if(c == game->n_players)
503 break;
508 if(c != game->n_players)
510 printf("game_start: tanta gente (%d)!\n", game->n_players);
511 SDL_Quit();
512 exit(1);
515 ghost_reset_all(game);
518 void game_reset_camera(struct game *game, int player_no)
520 struct camera *cam;
521 struct player *player;
523 if(player_no == -1)
525 player = NULL;
526 cam = game->demo_camera;
527 } else {
528 player = &game->players[player_no];
529 cam = player->camera;
532 switch(cam->type)
534 case CAMERA_TYPE_FIXED_CHASE:
535 break;
537 case CAMERA_TYPE_LOOSE_CHASE:
538 render_reset_camera(cam);
539 render_move_camera(cam,
540 player->position[X],
541 -3.5,
542 player->position[Z] - 3.5);
543 break;
545 case CAMERA_TYPE_LOOSE_TRAIL:
546 render_reset_camera(cam);
547 render_move_camera(cam,
548 0.0, CAMERA_LOOSE_TRAIL_Y_OFFSET, CAMERA_LOOSE_TRAIL_Z_OFFSET);
549 render_point_camera(cam,
550 player->position[X],
551 player->position[Y],
552 player->position[Z]);
554 break;
556 case CAMERA_TYPE_DEMO:
557 render_reset_camera(cam);
558 render_move_camera(cam, game->map->width / 2 + 0.5, CAMERA_DEMO_HEIGHT, 0.0);
559 render_point_camera(cam, game->map->width / 2 + 0.5, 0.0, game->map->height / 2 + 0.5);
560 break;
562 case CAMERA_TYPE_TOMB_RAIDER:
563 render_reset_camera(cam);
564 render_move_camera(cam,
565 0.0, CAMERA_TOMB_RAIDER_Y_OFFSET, -CAMERA_TOMB_RAIDER_OFFSET);
566 render_point_camera(cam,
567 player->position[X],
568 player->position[Y],
569 player->position[Z]);
571 break;
573 case CAMERA_TYPE_FREE:
574 break;
578 void game_update_camera(struct game *game, int player_no, float delta)
580 static int state = 0;
581 struct camera *cam;
582 struct player *player;
584 if(player_no == -1)
586 /* magic value: demo camera */
587 player = NULL;
588 cam = game->demo_camera;
589 } else {
590 player = &game->players[player_no];
591 cam = player->camera;
594 if(input_kstate(SDLK_c))
596 cam->type = (cam->type + 1) % CAMERA_NUM_TYPES;
597 input_kclear(SDLK_c);
598 // game_reset_camera(game, player_no);
601 switch(cam->type)
603 float v1[3], v2[3], vr[3], dist, d2;
605 case CAMERA_TYPE_FIXED_CHASE:
606 render_reset_camera(cam);
607 render_move_camera(cam,
608 player->position[X],
609 -3.5,
610 player->position[Z] - 2.5);
611 render_point_camera(cam,
612 player->position[X],
613 player->position[Y],
614 player->position[Z]);
616 break;
618 case CAMERA_TYPE_LOOSE_CHASE:
619 render_point_camera(cam,
620 player->position[X],
621 player->position[Y],
622 player->position[Z]);
624 v1[X] = player->position[X];
625 v1[Y] = cam->pos[Y];
626 v1[Z] = player->position[Z];
628 math_sub_vec3(v1, v1, cam->pos);
630 if(state)
632 if(math_norm_vec3(v1) > CAMERA_LOOSE_CHASE_LOW_THRESHOLD)
634 math_len_vec3(v1, v1, delta * CAMERA_LOOSE_CHASE_SPEED);
635 math_add_vec3(v1, cam->pos, v1);
636 render_move_camera(cam, v1[X], v1[Y], v1[Z]);
637 } else
638 state = 0;
639 } else
640 if(math_norm_vec3(v1) > CAMERA_LOOSE_CHASE_HIGH_THRESHOLD)
641 state = 1;
643 break;
645 case CAMERA_TYPE_LOOSE_TRAIL:
646 v1[X] = cam->dir[X];
647 v1[Y] = cam->dir[Y];
648 v1[Z] = cam->dir[Z];
650 render_point_camera(cam,
651 player->position[X],
652 player->position[Y],
653 player->position[Z]);
656 v2[X] = cam->dir[X];
657 v2[Y] = cam->dir[Y];
658 v2[Z] = cam->dir[Z];
660 math_sub_vec3(vr, v2, v1);
661 dist = math_norm_vec3(vr);
662 if(dist > CAMERA_LOOSE_TRAIL_ROTATE_SPEED * delta || state)
664 state = 1;
666 math_len_vec3(vr, vr,
667 CAMERA_LOOSE_TRAIL_ROTATE_SPEED * delta * sin(dist));
668 math_add_vec3(v1, v1, vr);
669 render_point_camera(cam, v1[X], v1[Y], v1[Z]);
671 math_sub_vec3(vr, player->position, cam->pos);
672 if(dist * math_norm_vec3(vr) < 0.06)
673 state = 0;
676 /* xx */
677 v1[X] = player->position[X];
678 v1[Y] = 0.0;
679 v1[Z] = 0.0;
681 v2[X] = cam->pos[X];
682 v2[Y] = 0.0;
683 v2[Z] = 0.0;
685 math_sub_vec3(vr, v2, v1);
687 dist = math_norm_vec3(vr);
688 math_len_vec3(vr, vr,
689 MAX(-delta * player->speed * dist * 0.7,
690 -CAMERA_LOOSE_TRAIL_SPEED * delta));
692 d2 = math_norm_vec3(vr);
693 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
695 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
697 /* yy */
698 v1[X] = 0.0;
699 v1[Y] = CAMERA_LOOSE_TRAIL_Y_OFFSET;
700 v1[Z] = 0.0;
702 v2[X] = 0.0;
703 v2[Y] = cam->pos[Y];
704 v2[Z] = 0.0;
706 math_sub_vec3(vr, v2, v1);
708 dist = math_norm_vec3(vr);
709 math_len_vec3(vr, vr,
710 MAX(-delta * player->speed * dist * 0.7,
711 -CAMERA_LOOSE_TRAIL_SPEED * delta));
713 d2 = math_norm_vec3(vr);
714 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
716 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
719 /* zz */
720 v1[X] = 0.0;
721 v1[Y] = 0.0;
722 v1[Z] = player->position[Z] + CAMERA_LOOSE_TRAIL_Z_OFFSET;
724 v2[X] = 0.0;
725 v2[Y] = 0.0;
726 v2[Z] = cam->pos[Z];
728 math_sub_vec3(vr, v2, v1);
730 dist = math_norm_vec3(vr);
731 math_len_vec3(vr, vr,
732 MAX(-delta * player->speed * dist * 0.9,
733 -CAMERA_LOOSE_TRAIL_SPEED * delta));
735 d2 = math_norm_vec3(vr);
736 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
738 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
740 break;
742 case CAMERA_TYPE_DEMO:
743 v1[X] = game->map->width / 2 + 0.5;
744 v1[Y] = 0.0;
745 v1[Z] = game->map->height / 2 + 0.5;
747 v2[X] = 0.0;
748 v2[Y] = 1.0;
749 v2[Z] = 0.0;
751 math_sub_vec3(vr, cam->pos, v1);
752 math_rotate_vec3(vr, vr, v2, CAMERA_DEMO_ROTATE_SPEED * delta);
753 math_add_vec3(cam->pos, v1, vr);
755 render_point_camera(cam,
756 game->map->width / 2 + 0.5, 0.0,
757 game->map->height / 2 + 0.5);
758 break;
760 case CAMERA_TYPE_TOMB_RAIDER:
761 v1[X] = cam->dir[X];
762 v1[Y] = cam->dir[Y];
763 v1[Z] = cam->dir[Z];
765 render_point_camera(cam,
766 player->position[X],
767 player->position[Y],
768 player->position[Z]);
771 v2[X] = cam->dir[X];
772 v2[Y] = cam->dir[Y];
773 v2[Z] = cam->dir[Z];
775 math_sub_vec3(vr, v2, v1);
776 dist = math_norm_vec3(vr);
777 if(dist > CAMERA_TOMB_RAIDER_ROTATE_SPEED * delta || state)
779 state = 1;
781 math_len_vec3(vr, vr,
782 CAMERA_TOMB_RAIDER_ROTATE_SPEED * delta * sin(dist));
783 math_add_vec3(v1, v1, vr);
784 render_point_camera(cam, v1[X], v1[Y], v1[Z]);
786 math_sub_vec3(vr, player->position, cam->pos);
787 if(dist * math_norm_vec3(vr) < 0.6)
788 state = 0;
791 /* xx */
792 switch(player->direction)
794 case DIRECTION_UP:
795 case DIRECTION_DOWN:
796 v1[X] = player->position[X];
797 break;
799 case DIRECTION_LEFT:
800 v1[X] = player->position[X] + CAMERA_TOMB_RAIDER_OFFSET;
801 break;
803 case DIRECTION_RIGHT:
804 v1[X] = player->position[X] - CAMERA_TOMB_RAIDER_OFFSET;
805 break;
807 v1[Y] = 0.0;
808 v1[Z] = 0.0;
810 v2[X] = cam->pos[X];
811 v2[Y] = 0.0;
812 v2[Z] = 0.0;
814 math_sub_vec3(vr, v2, v1);
816 dist = math_norm_vec3(vr);
817 math_len_vec3(vr, vr,
818 MAX(-delta * player->speed * dist * 0.7,
819 -CAMERA_TOMB_RAIDER_SPEED * delta));
821 d2 = math_norm_vec3(vr);
822 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
824 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
826 /* yy */
827 v1[X] = 0.0;
828 v1[Y] = CAMERA_TOMB_RAIDER_Y_OFFSET;
829 v1[Z] = 0.0;
831 v2[X] = 0.0;
832 v2[Y] = cam->pos[Y];
833 v2[Z] = 0.0;
835 math_sub_vec3(vr, v2, v1);
837 dist = math_norm_vec3(vr);
838 math_len_vec3(vr, vr,
839 MAX(-delta * player->speed * dist * 0.7,
840 -CAMERA_TOMB_RAIDER_SPEED * delta));
842 d2 = math_norm_vec3(vr);
843 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
845 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
847 /* zz */
848 v1[X] = 0.0;
849 v1[Y] = 0.0;
850 switch(player->direction)
852 case DIRECTION_UP:
853 v1[Z] = player->position[Z] - CAMERA_TOMB_RAIDER_OFFSET;
854 break;
856 case DIRECTION_DOWN:
857 v1[Z] = player->position[Z] + CAMERA_TOMB_RAIDER_OFFSET;
858 break;
860 case DIRECTION_LEFT:
861 case DIRECTION_RIGHT:
862 v1[Z] = player->position[Z];
863 break;
866 v2[X] = 0.0;
867 v2[Y] = 0.0;
868 v2[Z] = cam->pos[Z];
870 math_sub_vec3(vr, v2, v1);
872 dist = math_norm_vec3(vr);
873 math_len_vec3(vr, vr,
874 MAX(-delta * player->speed * dist * 0.9,
875 -CAMERA_TOMB_RAIDER_SPEED * delta));
877 d2 = math_norm_vec3(vr);
878 math_len_vec3(vr, vr, MAX(d2, d2 * (dist * 0.07) * (dist * 0.07)));
880 render_translate_camera(cam, vr[X], vr[Y], vr[Z]);
882 break;
884 case CAMERA_TYPE_FREE:
885 if(input_kstate(SDLK_w))
886 /* move forward */
887 render_advance_camera(cam, 0.0, 0.0, 0.1);
889 if(input_kstate(SDLK_s))
890 /* move backward */
891 render_advance_camera(cam, 0.0, 0.0, -0.1);
893 if(input_kstate(SDLK_a))
894 /* move left */
895 render_advance_camera(cam, -0.1, 0.0, 0.0);
897 if(input_kstate(SDLK_d))
898 /* move right */
899 render_advance_camera(cam, 0.1, 0.0, 0.0);
901 if(input_kstate(SDLK_r))
902 /* move up */
903 render_advance_camera(cam, 0.0, -0.1, 0.0);
905 if(input_kstate(SDLK_f))
906 /* move down */
907 render_advance_camera(cam, 0.0, 0.1, 0.0);
909 if(input_kstate(SDLK_q))
910 /* roll Cwise */
911 render_camera_roll(cam, 1.0);
913 if(input_kstate(SDLK_e))
914 /* roll CCwise */
915 render_camera_roll(cam, -1.0);
917 if(input_kstate(SDLK_z))
918 /* rotate Cwise */
919 render_camera_yaw(cam, 1.0);
921 if(input_kstate(SDLK_x))
922 /* rotate CCwise */
923 render_camera_yaw(cam, -1.0);
925 if(input_kstate(SDLK_t))
926 /* pitch up */
927 render_camera_pitch(cam, -1.0);
929 if(input_kstate(SDLK_g))
930 /* pitch down */
931 render_camera_pitch(cam, 1.0);
933 break;
938 actualiza o estado do jogo
940 void game_update(struct game *game, float delta)
942 int c;
944 map_update(game->map, delta);
946 for(c = 0; c < game->n_players; c++)
948 player_update(game, c, delta);
949 game_update_camera(game, c, delta);
952 for(c = 0; c < game->n_ghosts; c++)
953 ghost_update(game, c, delta);
955 for(c = 0; c < game->n_shots; c++)
956 shot_update(game, c, delta);
958 for(c = 0; c < game->n_bombs; c++)
959 bomb_update(game, c, delta);
961 if(game->demo_camera)
962 game_update_camera(game, -1, delta);
965 void game_draw_opaque_objects(struct game *game, int player_no)
967 int c;
969 for(c = 0; c < game->n_ghosts; c++)
970 ghost_render(game, &game->ghosts[c]);
972 for(c = 0; c < game->n_players; c++)
973 player_render(&game->players[c]);
975 for(c = 0; c < game->n_shots; c++)
976 shot_render_opaque(game, c);
978 for(c = 0; c < game->n_bombs; c++)
979 bomb_render_opaque(game, c);
982 void game_draw_translucent_objects(struct game *game, int player_no)
984 int c;
986 for(c = 0; c < game->n_shots; c++)
987 shot_render_translucent(game, player_no, c);
989 for(c = 0; c < game->n_bombs; c++)
990 bomb_render_translucent(game, player_no, c);