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 $";
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"
57 //#include "level-classic.h"
58 //#include "level-demo.h"
59 //#include "level-1.h"
61 struct game
*game_new(int game_type
)
65 ret
= (struct game
*)malloc(sizeof(struct game
));
66 ret
->game_type
= game_type
;
67 ret
->current_level
= -1;
77 ret
->demo_camera
= NULL
;
82 void game_free(struct game
*game
)
94 void game_run(struct game
*game
)
96 int last_update
, ticks
;
102 last_update
= ticks
= SDL_GetTicks();
106 for(c
= 0; c
< game
->n_players
; c
++)
108 render_reset_camera(game
->players
[c
].camera
);
109 game_reset_camera(game
, c
);
114 audio_play_music("sfx/tranzy.ogg");
122 if(input_kstate(SDLK_ESCAPE
))
124 audio_fade_music(500);
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)
151 render_finish_frame();
154 if(SDL_GetTicks() - ticks
>= 1000)
156 printf("%d FPS\n", frames
);
157 ticks
= SDL_GetTicks();
161 if(game_count_dots(game
) == 0)
163 game_do_victory_loop(game
);
167 if(game
->players
[0].lives
== 0)
169 game_do_defeat_loop(game
);
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 };
185 static float frame
= 0.0;
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
);
197 glMatrixMode(GL_PROJECTION
);
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);
207 -1.0, 1.0, 1.5, 3.0);
208 gluLookAt(0.0, 0.0, 0.0,
212 glShadeModel(GL_SMOOTH
);
213 glEnable(GL_COLOR_MATERIAL
);
215 glDisable(GL_TEXTURE_2D
);
216 glEnable(GL_DEPTH_TEST
);
217 glDepthMask(GL_TRUE
);
219 glEnable(GL_LIGHTING
);
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)
235 case PLAYER_STATE_MOVING
:
236 case PLAYER_STATE_STOPPED
:
237 render_dlist(&p
->model_moving
[(int)frame
% p
->frames_moving
], p
->color
);
240 case PLAYER_STATE_DEAD
:
241 render_dlist(&p
->model_dying
[(int)p
->current_frame
% p
->frames_dying
], p
->color
);
245 render_dlist(&p
->model_stopped
[0], inactive_color
);
250 /* XXX - this is for player 0 only */
251 void game_do_victory_loop(struct game
*game
)
254 struct image_rgba32
*level_complete
;
255 int tx_level_complete
;
258 audio_fade_music(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);
281 while(SDL_PollEvent(&ev
))
283 if(ev
.type
== SDL_QUIT
)
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);
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();*/
326 if(level_complete
->width
> vp
->width
)
327 render_draw_scaled_image("gfx/level-complete.tga",
330 level_complete
->height
* vp
->height
/ vp
->width
);
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
)
345 struct image_rgba32
*game_over
;
349 audio_fade_music(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);
370 if(input_kstate(SDLK_ESCAPE
))
372 input_kclear(SDLK_ESCAPE
);
373 audio_fade_music(500);
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();*/
406 if(game_over
->width
> vp
->width
)
407 render_draw_scaled_image("gfx/game-over.tga",
410 game_over
->height
* vp
->height
/ vp
->width
);
412 render_draw_scaled_image("gfx/game-over.tga",
413 (vp
->width
- game_over
->width
) / 2, 0,
414 (vp
->width
+ game_over
->width
) / 2,
416 render_finish_frame();
420 void game_do_victory_loop(struct game
*game
)
424 void game_do_defeat_loop(struct game
*game
)
429 void game_reset(struct game
*game
)
432 glDisable(GL_LIGHT1
);
435 int game_count_dots(struct game
*game
)
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
)
452 void game_teleport_player(struct game
*game
, int player
)
459 p
= &game
->players
[player
];
462 x
= (int)p
->position
[X
];
463 y
= (int)p
->position
[Z
];
465 if(MAP(map
, x
, y
).content
!= MAP_CONTENT_TELEPORT
)
468 if(MAP_TELEPORT(map
, x
, y
).direction
!= p
->direction
)
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
)
483 /* distribuir os jogadores pelos spawn points */
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
)
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;
502 if(c
== game
->n_players
)
508 if(c
!= game
->n_players
)
510 printf("game_start: tanta gente (%d)!\n", game
->n_players
);
515 ghost_reset_all(game
);
518 void game_reset_camera(struct game
*game
, int player_no
)
521 struct player
*player
;
526 cam
= game
->demo_camera
;
528 player
= &game
->players
[player_no
];
529 cam
= player
->camera
;
534 case CAMERA_TYPE_FIXED_CHASE
:
537 case CAMERA_TYPE_LOOSE_CHASE
:
538 render_reset_camera(cam
);
539 render_move_camera(cam
,
542 player
->position
[Z
] - 3.5);
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
,
552 player
->position
[Z
]);
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);
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
,
569 player
->position
[Z
]);
573 case CAMERA_TYPE_FREE
:
578 void game_update_camera(struct game
*game
, int player_no
, float delta
)
580 static int state
= 0;
582 struct player
*player
;
586 /* magic value: demo camera */
588 cam
= game
->demo_camera
;
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);
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
,
610 player
->position
[Z
] - 2.5);
611 render_point_camera(cam
,
614 player
->position
[Z
]);
618 case CAMERA_TYPE_LOOSE_CHASE
:
619 render_point_camera(cam
,
622 player
->position
[Z
]);
624 v1
[X
] = player
->position
[X
];
626 v1
[Z
] = player
->position
[Z
];
628 math_sub_vec3(v1
, v1
, cam
->pos
);
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
]);
640 if(math_norm_vec3(v1
) > CAMERA_LOOSE_CHASE_HIGH_THRESHOLD
)
645 case CAMERA_TYPE_LOOSE_TRAIL
:
650 render_point_camera(cam
,
653 player
->position
[Z
]);
660 math_sub_vec3(vr
, v2
, v1
);
661 dist
= math_norm_vec3(vr
);
662 if(dist
> CAMERA_LOOSE_TRAIL_ROTATE_SPEED
* delta
|| state
)
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)
677 v1
[X
] = player
->position
[X
];
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
]);
699 v1
[Y
] = CAMERA_LOOSE_TRAIL_Y_OFFSET
;
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
]);
722 v1
[Z
] = player
->position
[Z
] + CAMERA_LOOSE_TRAIL_Z_OFFSET
;
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
]);
742 case CAMERA_TYPE_DEMO
:
743 v1
[X
] = game
->map
->width
/ 2 + 0.5;
745 v1
[Z
] = game
->map
->height
/ 2 + 0.5;
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);
760 case CAMERA_TYPE_TOMB_RAIDER
:
765 render_point_camera(cam
,
768 player
->position
[Z
]);
775 math_sub_vec3(vr
, v2
, v1
);
776 dist
= math_norm_vec3(vr
);
777 if(dist
> CAMERA_TOMB_RAIDER_ROTATE_SPEED
* delta
|| state
)
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)
792 switch(player
->direction
)
796 v1
[X
] = player
->position
[X
];
800 v1
[X
] = player
->position
[X
] + CAMERA_TOMB_RAIDER_OFFSET
;
803 case DIRECTION_RIGHT
:
804 v1
[X
] = player
->position
[X
] - CAMERA_TOMB_RAIDER_OFFSET
;
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
]);
828 v1
[Y
] = CAMERA_TOMB_RAIDER_Y_OFFSET
;
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
]);
850 switch(player
->direction
)
853 v1
[Z
] = player
->position
[Z
] - CAMERA_TOMB_RAIDER_OFFSET
;
857 v1
[Z
] = player
->position
[Z
] + CAMERA_TOMB_RAIDER_OFFSET
;
861 case DIRECTION_RIGHT
:
862 v1
[Z
] = player
->position
[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
]);
884 case CAMERA_TYPE_FREE
:
885 if(input_kstate(SDLK_w
))
887 render_advance_camera(cam
, 0.0, 0.0, 0.1);
889 if(input_kstate(SDLK_s
))
891 render_advance_camera(cam
, 0.0, 0.0, -0.1);
893 if(input_kstate(SDLK_a
))
895 render_advance_camera(cam
, -0.1, 0.0, 0.0);
897 if(input_kstate(SDLK_d
))
899 render_advance_camera(cam
, 0.1, 0.0, 0.0);
901 if(input_kstate(SDLK_r
))
903 render_advance_camera(cam
, 0.0, -0.1, 0.0);
905 if(input_kstate(SDLK_f
))
907 render_advance_camera(cam
, 0.0, 0.1, 0.0);
909 if(input_kstate(SDLK_q
))
911 render_camera_roll(cam
, 1.0);
913 if(input_kstate(SDLK_e
))
915 render_camera_roll(cam
, -1.0);
917 if(input_kstate(SDLK_z
))
919 render_camera_yaw(cam
, 1.0);
921 if(input_kstate(SDLK_x
))
923 render_camera_yaw(cam
, -1.0);
925 if(input_kstate(SDLK_t
))
927 render_camera_pitch(cam
, -1.0);
929 if(input_kstate(SDLK_g
))
931 render_camera_pitch(cam
, 1.0);
938 actualiza o estado do jogo
940 void game_update(struct game
*game
, float delta
)
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
)
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
)
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
);