1
/*************************************************************************
4
Copyright (c) 2004, Mika Halttunen
6
This software is provided 'as-is', without any express or implied
7
warranty. In no event will the authors be held liable for any damages
8
arising from the use of this software.
10
Permission is granted to anyone to use this software for any purpose,
11
including commercial applications, and to alter it and redistribute
12
it freely, subject to the following restrictions:
14
1. The origin of this software must not be misrepresented; you must
15
not claim that you wrote the original software. If you use this
16
software in a product, an acknowledgment in the product documentation
17
would be appreciated but is not required.
19
2. Altered source versions must be plainly marked as such, and must
20
not be misrepresented as being the original software.
22
3. This notice may not be removed or altered from any source
26
Mika Halttunen <lsoft@mbnet.fi>
28
*************************************************************************/
32
#include "SDL_opengl.h"
33
#include "SDL_image.h"
46
#include "screenshot.h"
50
#include "special_power.h"
51
#include "soundmusic.h"
57
#include "select_special.h"
61
// Background texture list
62
int bgrounds[NUM_BGROUNDS];
66
// Are we fading? (0 == no, 1 == fade in, 2 == fade out)
72
static float light_ambient[] = { 0.75f, 0.75f, 0.75f, 1.0f };
73
static float light_diffuse1[] = { 1.0f, 1.0f, 1.0f, 1.0f };
74
static float light_diffuse2[] = { 0.5f, 0.5f, 0.5f, 1.0f };
75
//static float light_diffuse2[] = { 0.3f, 0.8f, 1.0f, 1.0f };
76
static float light_position1[] = { MAP_W*0.5f, 6.0f, MAP_H*0.75f, 1.0f };
77
static float light_position2[] = { -MAP_W*0.5f, 2.0f, MAP_H*0.25f, 1.0f };
80
// Array containing currently pressed keys
86
// Are we playing a two player game?
91
extern int killed_5_diamonds;
94
// Confirm the ESC press
95
static bool confirm_esc;
102
// Load background textures
103
void load_bgrounds() {
104
// Prepare the background list
105
for(int f=0; f<NUM_BGROUNDS; f++)
109
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1);
110
glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
112
glLightfv(GL_LIGHT2, GL_DIFFUSE, light_diffuse2);
113
glLightfv(GL_LIGHT2, GL_POSITION, light_position2);
115
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_ambient);
121
//glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
122
glClear(GL_DEPTH_BUFFER_BIT);
124
// Set up the viewport (either perspective or ortho)
125
glMatrixMode(GL_PROJECTION);
127
if(!config.perspective_mode)
128
glOrtho(-11.0f, 11.0f, -8.0f, 8.0f, -50.0f, 50.0f);
130
gluPerspective(30.0f, 1.333333f, 1, 100);
131
glTranslatef(0,0,-32);
134
// Draw the background
135
glMatrixMode(GL_MODELVIEW);
137
BIND_TEXTURE(cur_bground);
138
glDepthMask(GL_FALSE);
140
glBegin(GL_TRIANGLE_STRIP);
141
if(!config.perspective_mode) {
142
glTexCoord2f(1,1); glVertex3f(11.0f, 8.0f, -2);
143
glTexCoord2f(0,1); glVertex3f(-11.0f, 8.0f, -2);
144
glTexCoord2f(1,0); glVertex3f(11.0f, -8.0f, -2);
145
glTexCoord2f(0,0); glVertex3f(-11.0f, -8.0f, -2);
148
glTexCoord2f(1,1); glVertex3f(12.2f, 9.1f, -2);
149
glTexCoord2f(0,1); glVertex3f(-12.2f, 9.1f, -2);
150
glTexCoord2f(1,0); glVertex3f(12.2f, -9.1f, -2);
151
glTexCoord2f(0,0); glVertex3f(-12.2f, -9.1f, -2);
154
glDepthMask(GL_TRUE);
156
// Rotate to the isometric view
157
glRotatef(30.0f, 1.0f, 0,0);
158
glRotatef(-45.0f, 0, 1.0f, 0.0f);
160
// Center the map around the origin
161
glTranslatef(-MAP_W * 0.5f, 0, -MAP_H * 0.5f);
167
// Enable alpha blending for sprites
169
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
175
// Enable alpha testing
176
glEnable(GL_ALPHA_TEST);
186
// Draw the potato men
192
// Disable alpha blending
193
glDisable(GL_ALPHA_TEST);
200
// Draw the teleports
204
// Draw the particles
210
// Draw the special powers
211
draw_special_power();
213
// Draw the player icons when in two player mode
217
// Begin font drawing
220
// Draw the FPS amount
221
if(config.show_fps && !icon_menu.visible) {
223
glprintf_center(font1, 0, 0, 9, -25, "FPS: %02.1f", fps);
226
// Draw the kill count
229
sprintf(str, "%4d", kill_count);
230
glprint_num(2.0f, 3.0f - 1.2f*icon_menu.pos, -10, str);
232
// Draw the remaining seconds
233
sprintf(str, "%2d", num_seconds_left);
234
glColor3f(1, 0.8f, 0.4f);
235
set_font_scale(0.25f, 0.3f);
236
glprint_num(4.7f, 2.6f - 1.2f*icon_menu.pos, -10, str);
243
// Draw the special power selection menu
244
draw_special_selection();
246
// Draw the ESC confirmation
250
glColor4f(0,0,0, 0.45f);
251
glBegin(GL_TRIANGLE_STRIP);
252
glVertex3f(4, 3, -2);
253
glVertex3f(-4, 3, -2);
255
glVertex3f(-4,-3,-2);
259
set_font_scale(0.4f, 0.6f);
260
glprintf_center(font1, 0, 0, 2.0f, -13, "ARE YOU SURE YOU WANT TO EXIT?");
261
glprintf_center(font1, 0, 0, 1.1f, -13, "Press ESC to exit, or ENTER to resume.");
266
if(fade_amount != 0.0f) {
269
glColor4f(0,0,0,fade_amount);
270
glBegin(GL_TRIANGLE_STRIP);
271
glVertex3f(4, 3, -2);
272
glVertex3f(-4, 3, -2);
274
glVertex3f(-4,-3,-2);
281
// Flush and swap the buffers
283
SDL_GL_SwapBuffers();
288
// Return true if we're going to quit
289
bool handle_event(SDL_Event &event) {
292
case SDL_QUIT: // Quit
296
// Update the 'key' array
297
key[event.key.keysym.sym] = 1;
301
// Update the 'key' array
302
key[event.key.keysym.sym] = 0;
311
void start_game(bool two_pls) {
313
memset(key, 0, sizeof(key));
322
two_players = two_pls;
337
// Set up the main loop
341
Uint32 fps_counter = 0;
342
int frames_drawn = 0;
344
prev_ticks = SDL_GetTicks();
345
Uint32 confirm_time = 0;
346
bool main_loop_done = false;
347
bool f12_down = false;
348
bool key_return_down = false;
349
bool key_esc_down = false;
350
bool finished = false;
354
while(!main_loop_done) {
357
while(SDL_PollEvent(&event)) {
358
main_loop_done = handle_event(event);
362
while(timer_count > 0 && !game_paused) {
367
fade_amount -= 0.01f;
368
if(fade_amount <= 0.0f) {
373
else if(fading == 2) {
375
fade_amount += 0.01f;
376
if(fade_amount >= 1.0f) {
379
main_loop_done = true;
386
if(key[SDLK_ESCAPE] && !fading) {
387
if(key_esc_down == false) {
391
// Keep track of the time, so we can restore it
392
confirm_time = SDL_GetTicks();
402
key_esc_down = false;
406
if(key[SDLK_RETURN]) {
407
if(key_return_down == false) {
408
key_return_down = true;
410
if(!killed_5_diamonds)
411
level_time += (SDL_GetTicks() - confirm_time);
415
key_return_down = false;
421
if(f12_down == false) {
431
// Handle the level pause
432
if(level_pause == LEVEL_PAUSE_BEGIN) {
433
if(key[SDLK_RETURN] || key[config.key_shoot[0]] || key[config.key_shoot[1]]) {
434
if(!key_return_down) {
435
// Start timing the level change
436
start_level_timing();
438
key_return_down = true;
440
// A little hack to prevent players firing their bombs accidentally,
441
// if they press their Shoot button to start the level.
447
key_return_down = false;
451
if(!icon_menu.visible && level_pause != LEVEL_PAUSE_BEGIN && !finished) {
452
// Change to the next level if enough time has passed
453
// (we don't call this when the Killed-5 diamonds are visible, because
454
// it advances the time, and we don't want that to happen.)
455
if(!killed_5_diamonds || level_pause == LEVEL_PAUSE_END) {
456
if(!change_level()) {
457
// We've finished all the levels.
469
// Update the special powers
470
update_special_power();
487
// Handle the special power selection menu
489
do_special_selection();
493
// Advance the fps_counter
494
if(config.show_fps) {
495
Uint32 ticks_now = SDL_GetTicks();
496
Uint32 diff = ticks_now - prev_ticks;
498
prev_ticks = ticks_now;
500
if(fps_counter >= 1000) {
501
fps = (float)frames_drawn / (float)(fps_counter/1000.0f);
524
// Check if we get to the hiscore list
525
HISCORE_LIST &list = (two_players) ? hiscore_2 : hiscore_1;
526
int place = list.add_name("null", kill_count);
528
// Get the name and save the list
529
list.input_name(place);
531
list.save(get_hiscore_location(2,true));
533
list.save(get_hiscore_location(1,true));