X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fgameloop.cpp;h=4a8d7f29928885e886b921d433e857763049b045;hb=34145c1911171da557faac38278c1ba56bb5e201;hp=58f959302ebfe94bc5a9bed4fd151964b6aac8fd;hpb=f938830d155595143b587891216e236e24d22fe8;p=supertux.git diff --git a/src/gameloop.cpp b/src/gameloop.cpp index 58f959302..4a8d7f299 100644 --- a/src/gameloop.cpp +++ b/src/gameloop.cpp @@ -8,18 +8,19 @@ http://www.newbreedsoftware.com/supertux/ April 11, 2000 - March 15, 2004 - */ +*/ #include #include +#include #include #include #include +#include #include #include #ifndef WIN32 -#include #include #include #endif @@ -38,11 +39,13 @@ #include "level.h" #include "scene.h" #include "collision.h" +#include "tile.h" +#include "particlesystem.h" /* extern variables */ st_level current_level; -int game_started = NO; +int game_started = false; /* Local variables: */ @@ -51,7 +54,6 @@ static texture_type img_cloud[2][4]; static SDL_Event event; static SDLKey key; static char level_subset[100]; -static char str[60]; static float fps_fps; static int st_gl_mode; static unsigned int last_update_time; @@ -68,22 +70,20 @@ void drawstatus(void); void drawendscreen(void); void drawresultscreen(void); -#define JOYSTICK_DEAD_ZONE 4096 - void levelintro(void) { + char str[60]; /* Level Intro: */ - clearscreen(0, 0, 0); sprintf(str, "LEVEL %d", level); - text_drawf(&blue_text, str, 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&blue_text, str, 0, 200, A_HMIDDLE, A_TOP, 1); sprintf(str, "%s", current_level.name.c_str()); - text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1); sprintf(str, "TUX x %d", tux.lives); - text_drawf(&white_text, str, 0, 256, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&white_text, str, 0, 256, A_HMIDDLE, A_TOP, 1); flipscreen(); @@ -100,22 +100,28 @@ void start_timers(void) void activate_bad_guys(void) { - int x,y; - - /* Activate bad guys: */ - - for (y = 0; y < 15; y++) + for (std::vector::iterator i = current_level.badguy_data.begin(); + i != current_level.badguy_data.end(); + ++i) { - for (x = 0; x < current_level.width; x++) - { - if (current_level.tiles[y][x] >= '0' && current_level.tiles[y][x] <= '9') - { - add_bad_guy(x * 32, y * 32, current_level.tiles[y][x] - '0'); - current_level.tiles[y][x] = '.'; - } - } + add_bad_guy(i->x, i->y, i->kind); } +} +void activate_particle_systems(void) +{ + if(current_level.particle_system == "clouds") + { + particle_systems.push_back(new CloudParticleSystem); + } + else if(current_level.particle_system == "snow") + { + particle_systems.push_back(new SnowParticleSystem); + } + else if(current_level.particle_system != "") + { + st_abort("unknown particle system specified in level", ""); + } } /* --- GAME EVENT! --- */ @@ -136,7 +142,7 @@ void game_event(void) if(show_menu) menu_event(&event.key.keysym); - if(player_key_event(&tux,key,DOWN)) + if(tux.key_event(key,DOWN)) break; switch(key) @@ -148,13 +154,13 @@ void game_event(void) quit = 1; else if(show_menu) { - menu_set_current(&game_menu); + Menu::set_current(game_menu); show_menu = 0; st_pause_ticks_stop(); } else { - menu_set_current(&game_menu); + Menu::set_current(game_menu); show_menu = 1; st_pause_ticks_start(); } @@ -167,7 +173,7 @@ void game_event(void) case SDL_KEYUP: /* A keyrelease! */ key = event.key.keysym.sym; - if(player_key_event(&tux,key,UP)) + if(tux.key_event(key, UP)) break; switch(key) @@ -188,7 +194,7 @@ void game_event(void) } break; case SDLK_TAB: - if(debug_mode == YES) + if(debug_mode) { tux.size = !tux.size; if(tux.size == BIG) @@ -200,67 +206,74 @@ void game_event(void) } break; case SDLK_END: - if(debug_mode == YES) + if(debug_mode) distros += 50; break; case SDLK_SPACE: - if(debug_mode == YES) + if(debug_mode) next_level = 1; break; case SDLK_DELETE: - if(debug_mode == YES) + if(debug_mode) tux.got_coffee = 1; break; case SDLK_INSERT: - if(debug_mode == YES) + if(debug_mode) timer_start(&tux.invincible_timer,TUX_INVINCIBLE_TIME); break; case SDLK_l: - if(debug_mode == YES) + if(debug_mode) --tux.lives; break; case SDLK_s: - if(debug_mode == YES) + if(debug_mode) score += 1000; case SDLK_f: - if(debug_fps == YES) - debug_fps = NO; - else - debug_fps = YES; - break; + if(debug_fps) + debug_fps = false; + else + debug_fps = true; + break; default: break; } break; -#ifdef JOY_YES case SDL_JOYAXISMOTION: switch(event.jaxis.axis) { case JOY_X: if (event.jaxis.value < -JOYSTICK_DEAD_ZONE) - tux.input.left = DOWN; + { + tux.input.left = DOWN; + tux.input.right = UP; + } else if (event.jaxis.value > JOYSTICK_DEAD_ZONE) - tux.input.left = UP; - - if (event.jaxis.value > JOYSTICK_DEAD_ZONE) - tux.input.right = DOWN; - else if (event.jaxis.value < -JOYSTICK_DEAD_ZONE) - tux.input.right = UP; + { + tux.input.left = UP; + tux.input.right = DOWN; + } + else + { + tux.input.left = DOWN; + tux.input.right = DOWN; + } break; case JOY_Y: if (event.jaxis.value > JOYSTICK_DEAD_ZONE) tux.input.down = DOWN; else if (event.jaxis.value < -JOYSTICK_DEAD_ZONE) tux.input.down = UP; + else + tux.input.down = UP; /* Handle joystick for the menu */ if(show_menu) { if(tux.input.down == DOWN) - menuaction = MN_DOWN; + menuaction = MENU_ACTION_DOWN; else - menuaction = MN_UP; + menuaction = MENU_ACTION_UP; } break; default: @@ -280,24 +293,22 @@ void game_event(void) tux.input.fire = UP; if(show_menu) - menuaction = MN_HIT; + menuaction = MENU_ACTION_HIT; break; -#endif default: break; } /* switch */ } /* while */ - } /* --- GAME ACTION! --- */ int game_action(void) { - int i; + unsigned int i; /* (tux_dying || next_level) */ if (tux.dying || next_level) @@ -325,11 +336,11 @@ int game_action(void) arrays_free(); return(0); } - player_level_begin(&tux); + tux.level_begin(); } else { - player_dying(&tux); + tux.is_dying(); /* No more lives!? */ @@ -354,7 +365,7 @@ int game_action(void) /* Either way, (re-)load the (next) level... */ - player_level_begin(&tux); + tux.level_begin(); set_defaults(); level_free(¤t_level); @@ -372,6 +383,7 @@ int game_action(void) arrays_free(); arrays_init(); activate_bad_guys(); + activate_particle_systems(); level_free_gfx(); level_load_gfx(¤t_level); level_free_song(); @@ -383,19 +395,17 @@ int game_action(void) play_current_music(); } - player_action(&tux); + tux.action(); /* Handle bouncy distros: */ - - for (i = 0; i < num_bouncy_distros; i++) + for (i = 0; i < bouncy_distros.size(); i++) { bouncy_distro_action(&bouncy_distros[i]); } /* Handle broken bricks: */ - - for (i = 0; i < num_broken_bricks; i++) + for (i = 0; i < broken_bricks.size(); i++) { broken_brick_action(&broken_bricks[i]); } @@ -403,7 +413,7 @@ int game_action(void) /* Handle distro counting: */ - if (counting_distros == YES) + if (counting_distros) { distro_counter--; @@ -414,7 +424,7 @@ int game_action(void) /* Handle bouncy bricks: */ - for (i = 0; i < num_bouncy_bricks; i++) + for (i = 0; i < bouncy_bricks.size(); i++) { bouncy_brick_action(&bouncy_bricks[i]); } @@ -422,7 +432,7 @@ int game_action(void) /* Handle floating scores: */ - for (i = 0; i < num_floating_scores; i++) + for (i = 0; i < floating_scores.size(); i++) { floating_score_action(&floating_scores[i]); } @@ -430,14 +440,14 @@ int game_action(void) /* Handle bullets: */ - for (i = 0; i < num_bullets; ++i) + for (i = 0; i < bullets.size(); ++i) { bullet_action(&bullets[i]); } /* Handle upgrades: */ - for (i = 0; i < num_upgrades; i++) + for (i = 0; i < upgrades.size(); i++) { upgrade_action(&upgrades[i]); } @@ -445,9 +455,16 @@ int game_action(void) /* Handle bad guys: */ - for (i = 0; i < num_bad_guys; i++) + for (i = 0; i < bad_guys.size(); i++) { - badguy_action(&bad_guys[i]); + bad_guys[i].action(); + } + + /* update particle systems */ + std::vector::iterator p; + for(p = particle_systems.begin(); p != particle_systems.end(); ++p) + { + (*p)->simulate(frame_ratio); } /* Handle all possible collisions. */ @@ -460,22 +477,21 @@ int game_action(void) void game_draw(void) { - int x, y, i, s; +int y,x; /* Draw screen: */ - - if (tux.dying && (frame % 4) == 0) + if (tux.dying && (global_frame_counter % 4) == 0) clearscreen(255, 255, 255); else if(timer_check(&super_bkgd_timer)) - texture_draw(&img_super_bkgd, 0, 0, NO_UPDATE); + texture_draw(&img_super_bkgd, 0, 0); else { /* Draw the real background */ if(current_level.bkgd_image[0] != '\0') { - s = (int)scroll_x / 30; - texture_draw_part(&img_bkgd,s,0,0,0,img_bkgd.w - s, img_bkgd.h, NO_UPDATE); - texture_draw_part(&img_bkgd,0,0,screen->w - s ,0,s,img_bkgd.h, NO_UPDATE); + int s = (int)scroll_x / 30; + texture_draw_part(&img_bkgd,s,0,0,0,img_bkgd.w - s, img_bkgd.h); + texture_draw_part(&img_bkgd,0,0,screen->w - s ,0,s,img_bkgd.h); } else { @@ -483,97 +499,95 @@ void game_draw(void) } } + /* Draw particle systems (background) */ + std::vector::iterator p; + for(p = particle_systems.begin(); p != particle_systems.end(); ++p) + { + (*p)->draw(scroll_x, 0, 0); + } + /* Draw background: */ for (y = 0; y < 15; ++y) { for (x = 0; x < 21; ++x) { - drawshape(x * 32 - ((int)scroll_x % 32), y * 32, - current_level.tiles[(int)y][(int)x + (int)(scroll_x / 32)]); + drawshape(32*x - fmodf(scroll_x, 32), y * 32, + current_level.bg_tiles[(int)y][(int)x + (int)(scroll_x / 32)]); } } + /* Draw interactive tiles: */ - /* (Bouncy bricks): */ - - for (i = 0; i < num_bouncy_bricks; ++i) - { - bouncy_brick_draw(&bouncy_bricks[i]); - } - - - /* (Bad guys): */ - - for (i = 0; i < num_bad_guys; ++i) + for (y = 0; y < 15; ++y) { - badguy_draw(&bad_guys[i]); + for (x = 0; x < 21; ++x) + { + drawshape(32*x - fmodf(scroll_x, 32), y * 32, + current_level.ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]); + } } - /* (Tux): */ + /* (Bouncy bricks): */ - player_draw(&tux); + for (unsigned int i = 0; i < bouncy_bricks.size(); ++i) + bouncy_brick_draw(&bouncy_bricks[i]); - /* (Bullets): */ + for (unsigned int i = 0; i < bad_guys.size(); ++i) + bad_guys[i].draw(); - for (i = 0; i < num_bullets; ++i) - { - bullet_draw(&bullets[i]); - } - - /* (Floating scores): */ + tux.draw(); - for (i = 0; i < num_floating_scores; ++i) - { - floating_score_draw(&floating_scores[i]); - } + for (unsigned int i = 0; i < bullets.size(); ++i) + bullet_draw(&bullets[i]); + for (unsigned int i = 0; i < floating_scores.size(); ++i) + floating_score_draw(&floating_scores[i]); - /* (Upgrades): */ + for (unsigned int i = 0; i < upgrades.size(); ++i) + upgrade_draw(&upgrades[i]); - for (i = 0; i < num_upgrades; ++i) - { - upgrade_draw(&upgrades[i]); - } + for (unsigned int i = 0; i < bouncy_distros.size(); ++i) + bouncy_distro_draw(&bouncy_distros[i]); + for (unsigned int i = 0; i < broken_bricks.size(); ++i) + broken_brick_draw(&broken_bricks[i]); - /* (Bouncy distros): */ + /* Draw foreground: */ - for (i = 0; i < num_bouncy_distros; ++i) + for (y = 0; y < 15; ++y) { - bouncy_distro_draw(&bouncy_distros[i]); + for (x = 0; x < 21; ++x) + { + drawshape(32*x - fmodf(scroll_x, 32), y * 32, + current_level.fg_tiles[(int)y][(int)x + (int)(scroll_x / 32)]); + } } - - /* (Broken bricks): */ - - for (i = 0; i < num_broken_bricks; ++i) + /* Draw particle systems (foreground) */ + for(p = particle_systems.begin(); p != particle_systems.end(); ++p) { - broken_brick_draw(&broken_bricks[i]); + (*p)->draw(scroll_x, 0, 1); } drawstatus(); - if(game_pause) { - x = screen->h / 20; - for(i = 0; i < x; ++i) + int x = screen->h / 20; + for(int i = 0; i < x; ++i) { fillrect(i % 2 ? (pause_menu_frame * i)%screen->w : -((pause_menu_frame * i)%screen->w) ,(i*20+pause_menu_frame)%screen->h,screen->w,10,20,20,20, rand() % 20 + 1); } fillrect(0,0,screen->w,screen->h,rand() % 50, rand() % 50, rand() % 50, 128); - text_drawf(&blue_text, "PAUSE - Press 'P' To Play", 0, 230, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&blue_text, "PAUSE - Press 'P' To Play", 0, 230, A_HMIDDLE, A_TOP, 1); } if(show_menu) menu_process_current(); /* (Update it all!) */ - updatescreen(); - - } /* --- GAME LOOP! --- */ @@ -582,10 +596,10 @@ int gameloop(const char * subset, int levelnb, int mode) { int fps_cnt, jump, done; timer_type fps_timer, frame_timer; - timer_init(&fps_timer, YES); - timer_init(&frame_timer, YES); + timer_init(&fps_timer, true); + timer_init(&frame_timer, true); - game_started = YES; + game_started = true; st_gl_mode = mode; level = levelnb; @@ -609,9 +623,10 @@ int gameloop(const char * subset, int levelnb, int mode) level_load_gfx(¤t_level); activate_bad_guys(); + activate_particle_systems(); level_load_song(¤t_level); - player_init(&tux); + tux.init(); if(st_gl_mode != ST_GL_TEST) load_hs(); @@ -621,22 +636,21 @@ int gameloop(const char * subset, int levelnb, int mode) if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE) levelintro(); - timer_init(&time_left,YES); + timer_init(&time_left,true); start_timers(); if(st_gl_mode == ST_GL_LOAD_GAME) loadgame(levelnb); - /* --- MAIN GAME LOOP!!! --- */ - jump = NO; + jump = false; done = 0; quit = 0; - frame = 0; + global_frame_counter = 0; game_pause = 0; - timer_init(&fps_timer,YES); - timer_init(&frame_timer,YES); + timer_init(&fps_timer,true); + timer_init(&frame_timer,true); fps_cnt = 0; /* Clear screen: */ @@ -654,17 +668,17 @@ int gameloop(const char * subset, int levelnb, int mode) game_draw(); do { - jump = NO; + jump = false; /* Calculate the movement-factor */ frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE); if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */ - frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85; - + frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85; + if(!timer_check(&frame_timer)) { timer_start(&frame_timer,25); - ++frame; + ++global_frame_counter; } /* Handle events: */ @@ -675,18 +689,18 @@ int gameloop(const char * subset, int levelnb, int mode) if(show_menu) { - if(current_menu == &game_menu) + if(current_menu == game_menu) { - switch (menu_check(&game_menu)) + switch (game_menu->check()) { case 2: st_pause_ticks_stop(); break; case 3: - update_load_save_game_menu(&save_game_menu, NO); + update_load_save_game_menu(save_game_menu, false); break; case 4: - update_load_save_game_menu(&load_game_menu, YES); + update_load_save_game_menu(load_game_menu, true); break; case 7: st_pause_ticks_stop(); @@ -694,17 +708,17 @@ int gameloop(const char * subset, int levelnb, int mode) break; } } - else if(current_menu == &options_menu) + else if(current_menu == options_menu) { process_options_menu(); } - else if(current_menu == &save_game_menu ) + else if(current_menu == save_game_menu ) { - process_save_load_game_menu(YES); + process_save_load_game_menu(true); } - else if(current_menu == &load_game_menu ) + else if(current_menu == load_game_menu ) { - process_save_load_game_menu(NO); + process_save_load_game_menu(false); } } @@ -713,18 +727,18 @@ int gameloop(const char * subset, int levelnb, int mode) if(!game_pause && !show_menu) { - /*float z = frame_ratio; - frame_ratio = 1; - while(z >= 1) - {*/ + /*float z = frame_ratio; + frame_ratio = 1; + while(z >= 1) + {*/ if (game_action() == 0) { /* == 0: no more lives */ /* == -1: continues */ return 0; } - /* --z; - }*/ + /* --z; + }*/ } else { @@ -732,17 +746,17 @@ int gameloop(const char * subset, int levelnb, int mode) SDL_Delay(50); } - if(debug_mode && debug_fps == YES) + if(debug_mode && debug_fps) SDL_Delay(60); /*Draw the current scene to the screen */ /*If the machine running the game is too slow skip the drawing of the frame (so the calculations are more precise and - the FPS aren't affected).*/ + the FPS aren't affected).*/ /*if( ! fps_fps < 50.0 ) - game_draw(); - else - jump = YES;*/ /*FIXME: Implement this tweak right.*/ + game_draw(); + else + jump = true;*/ /*FIXME: Implement this tweak right.*/ game_draw(); /* Time stops in pause mode */ @@ -755,14 +769,13 @@ int gameloop(const char * subset, int levelnb, int mode) last_update_time = update_time; update_time = st_get_ticks(); - /* Pause till next frame, if the machine running the game is too fast: */ /* FIXME: Works great for in OpenGl mode, where the CPU doesn't have to do that much. But - the results in SDL mode aren't perfect (thought the 100 FPS are reached), even on an AMD2500+. */ - if(last_update_time >= update_time - 12 && jump != YES ) + the results in SDL mode aren't perfect (thought the 100 FPS are reached), even on an AMD2500+. */ + if(last_update_time >= update_time - 12 && !jump) SDL_Delay(10); /*if((update_time - last_update_time) < 10) - SDL_Delay((11 - (update_time - last_update_time))/2);*/ + SDL_Delay((11 - (update_time - last_update_time))/2);*/ @@ -773,14 +786,14 @@ int gameloop(const char * subset, int levelnb, int mode) /* are we low on time ? */ if ((timer_get_left(&time_left) < TIME_WARNING) && (get_current_music() != HURRYUP_MUSIC)) /* play the fast music */ - { + { set_current_music(HURRYUP_MUSIC); play_current_music(); - } + } } else - player_kill(&tux,KILL); + tux.kill(KILL); /* Calculate frames per second */ @@ -807,7 +820,7 @@ int gameloop(const char * subset, int levelnb, int mode) unloadshared(); arrays_free(); - game_started = NO; + game_started = false; return(quit); } @@ -1131,7 +1144,21 @@ void loadshared(void) "/images/shared/bag-right-1.png", USE_ALPHA); + /* Mr. Bomb */ + for(int i=0; i<4; ++i) { + char num[4]; + snprintf(num, 4, "%d", i); + texture_load(&img_mrbomb_left[i], + datadir + "/images/shared/mrbomb-left-" + num + ".png", USE_ALPHA); + texture_load(&img_mrbomb_right[i], + datadir + "/images/shared/mrbomb-right-" + num + ".png", USE_ALPHA); + } + /* stalactite */ + texture_load(&img_stalactite, + datadir + "/images/shared/stalactite.png", USE_ALPHA); + texture_load(&img_stalactite_broken, + datadir + "/images/shared/stalactite-broken.png", USE_ALPHA); /* Upgrades: */ @@ -1187,10 +1214,10 @@ void loadshared(void) // NULL or something else. And it will be dangerous to // play with not-initialized pointers. // This is also true with if (use_music) - Send a mail to me: neoneurone@users.sf.net, if you have another opinion. :) + Send a mail to me: neoneurone@users.sf.net, if you have another opinion. :) */ for (i = 0; i < NUM_SOUNDS; i++) - sounds[i] = load_sound(soundfilenames[i]); + sounds[i] = load_sound(datadir + soundfilenames[i]); /* Herring song */ herring_song = load_song(datadir + "/music/SALCON.MOD"); @@ -1258,6 +1285,14 @@ void unloadshared(void) texture_free(&img_money_right[i]); } + for(i = 0; i < 4; i++) { + texture_free(&img_mrbomb_left[i]); + texture_free(&img_mrbomb_right[i]); + } + + texture_free(&img_stalactite); + texture_free(&img_stalactite_broken); + texture_free(&img_box_full); texture_free(&img_box_empty); @@ -1293,177 +1328,216 @@ void unloadshared(void) /* Draw a tile on the screen: */ -void drawshape(float x, float y, unsigned char c) +void drawshape(float x, float y, unsigned int c) { - int z; + if (c != 0) + { + Tile* ptile = TileManager::instance()->get(c); + if(ptile) + { + if(ptile->images.size() > 1) + { + texture_draw(&ptile->images[( ((global_frame_counter*25) / ptile->anim_speed) % (ptile->images.size()))],x,y); + } + else if (ptile->images.size() == 1) + { + texture_draw(&ptile->images[0],x,y); + } + else + { + printf("Tile not dravable %u\n", c); + } + } + } + /* if (c == 'X' || c == 'x') - texture_draw(&img_brick[0], x, y, NO_UPDATE); + texture_draw(&img_brick[0], x, y); else if (c == 'Y' || c == 'y') - texture_draw(&img_brick[1], x, y, NO_UPDATE); + texture_draw(&img_brick[1], x, y); else if (c == 'A' || c =='B' || c == '!') - texture_draw(&img_box_full, x, y, NO_UPDATE); + texture_draw(&img_box_full, x, y); else if (c == 'a') - texture_draw(&img_box_empty, x, y, NO_UPDATE); + texture_draw(&img_box_empty, x, y); else if (c >= 'C' && c <= 'F') - texture_draw(&img_cloud[0][c - 'C'], x, y, NO_UPDATE); + texture_draw(&img_cloud[0][c - 'C'], x, y); else if (c >= 'c' && c <= 'f') - texture_draw(&img_cloud[1][c - 'c'], x, y, NO_UPDATE); + texture_draw(&img_cloud[1][c - 'c'], x, y); else if (c >= 'G' && c <= 'J') - texture_draw(&img_bkgd_tile[0][c - 'G'], x, y, NO_UPDATE); + texture_draw(&img_bkgd_tile[0][c - 'G'], x, y); else if (c >= 'g' && c <= 'j') - texture_draw(&img_bkgd_tile[1][c - 'g'], x, y, NO_UPDATE); + texture_draw(&img_bkgd_tile[1][c - 'g'], x, y); else if (c == '#') - texture_draw(&img_solid[0], x, y, NO_UPDATE); + texture_draw(&img_solid[0], x, y); else if (c == '[') - texture_draw(&img_solid[1], x, y, NO_UPDATE); + texture_draw(&img_solid[1], x, y); else if (c == '=') - texture_draw(&img_solid[2], x, y, NO_UPDATE); + texture_draw(&img_solid[2], x, y); else if (c == ']') - texture_draw(&img_solid[3], x, y, NO_UPDATE); + texture_draw(&img_solid[3], x, y); else if (c == '$') { - - z = (frame / 2) % 6; + z = (global_frame_counter / 2) % 6; if (z < 4) - texture_draw(&img_distro[z], x, y, NO_UPDATE); + texture_draw(&img_distro[z], x, y); else if (z == 4) - texture_draw(&img_distro[2], x, y, NO_UPDATE); + texture_draw(&img_distro[2], x, y); else if (z == 5) - texture_draw(&img_distro[1], x, y, NO_UPDATE); + texture_draw(&img_distro[1], x, y); } else if (c == '^') { - z = (frame / 3) % 3; + z = (global_frame_counter / 3) % 3; - texture_draw(&img_waves[z], x, y, NO_UPDATE); + texture_draw(&img_waves[z], x, y); } else if (c == '*') - texture_draw(&img_poletop, x, y, NO_UPDATE); + texture_draw(&img_poletop, x, y); else if (c == '|') { - texture_draw(&img_pole, x, y, NO_UPDATE); + texture_draw(&img_pole, x, y); } else if (c == '\\') { - z = (frame / 3) % 2; + z = (global_frame_counter / 3) % 2; - texture_draw(&img_flag[z], x + 16, y, NO_UPDATE); + texture_draw(&img_flag[z], x + 16, y); } else if (c == '&') - texture_draw(&img_water, x, y, NO_UPDATE); + texture_draw(&img_water, x, y);*/ + } /* What shape is at some position? */ - -unsigned char shape(float x, float y) +unsigned int shape(float x, float y) { int xx, yy; - unsigned char c; + unsigned int c; yy = ((int)y / 32); xx = ((int)x / 32); if (yy >= 0 && yy < 15 && xx >= 0 && xx <= current_level.width) { - c = current_level.tiles[yy][xx]; + c = current_level.ia_tiles[yy][xx]; } else - c = '.'; + c = 0; return(c); } -/* Is is ground? */ - +Tile* gettile(float x, float y) +{ + return TileManager::instance()->get(shape(x, y)); +} -int issolid(float x, float y) +bool issolid(float x, float y) { - if (isbrick(x, y) || - isice(x, y) || - (shape(x, y) == '[') || - (shape(x, y) == '=') || - (shape(x, y) == ']') || - (shape(x, y) == 'A') || - (shape(x, y) == 'B') || - (shape(x, y) == '!') || - (shape(x, y) == 'a')) + Tile* tile = TileManager::instance()->get + (shape(x,y)); + if(tile) { - return YES; + if(tile->solid == true) + return true; + else + return false; + } + else + { + return false; } - - return NO; } - /* Is it a brick? */ -int isbrick(float x, float y) +bool isbrick(float x, float y) { - if (shape(x, y) == 'X' || - shape(x, y) == 'x' || - shape(x, y) == 'Y' || - shape(x, y) == 'y') + Tile* tile = TileManager::instance()->get + (shape(x,y)); + if(tile) { - return YES; + if(tile->brick == true) + return true; + else + return false; + } + else + { + return false; } - - return NO; } /* Is it ice? */ -int isice(float x, float y) +bool isice(float x, float y) { - if (shape(x, y) == '#') + Tile* tile = TileManager::instance()->get + (shape(x,y)); + if(tile) { - return YES; + if(tile->ice == true) + return true; + else + return false; + } + else + { + return false; } - - return NO; } - /* Is it a full box? */ -int isfullbox(float x, float y) +bool isfullbox(float x, float y) { - if (shape(x, y) == 'A' || - shape(x, y) == 'B' || - shape(x, y) == '!') + Tile* tile = TileManager::instance()->get + (shape(x,y)); + if(tile) + { + if(tile->fullbox == true) + return true; + else + return false; + } + else { - return YES; + return false; } +} - return NO; +bool isdistro(float x, float y) +{ + Tile* tile = TileManager::instance()->get(shape(x,y)); + return tile && tile->distro; } /* Break a brick: */ void trybreakbrick(float x, float y) { - if (isbrick(x, y)) + Tile* tile = gettile(x, y); + if (tile->brick) { - if (shape(x, y) == 'x' || shape(x, y) == 'y') + if (tile->data > 0) { /* Get a distro from it: */ - add_bouncy_distro(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32); - if (counting_distros == NO) + if (!counting_distros) { - counting_distros = YES; + counting_distros = true; distro_counter = 50; } if (distro_counter <= 0) - level_change(¤t_level,x, y, 'a'); + level_change(¤t_level,x, y, TM_IA, tile->next_tile2); play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); score = score + SCORE_DISTRO; @@ -1472,8 +1546,7 @@ void trybreakbrick(float x, float y) else { /* Get rid of it: */ - - level_change(¤t_level,x, y,'.'); + level_change(¤t_level,x, y, TM_IA, tile->next_tile); } @@ -1504,53 +1577,53 @@ void bumpbrick(float x, float y) /* Empty a box: */ - void tryemptybox(float x, float y, int col_side) { -if (!isfullbox(x, y)) - return; - -// according to the collision side, set the upgrade direction - -if(col_side == LEFT) - col_side = RIGHT; -else - col_side = LEFT; - -switch(shape(x,y)) - { - case 'A': /* Box with a distro! */ - add_bouncy_distro(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32 - 32); - play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); - score = score + SCORE_DISTRO; - distros++; - break; - case 'B': /* Add an upgrade! */ - if (tux.size == SMALL) /* Tux is small, add mints! */ - add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_MINTS); - else /* Tux is big, add coffee: */ - add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_COFFEE); - play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER); - break; - case '!': /* Add a golden herring */ - add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_HERRING); - break; - default: - break; - } + Tile* tile = gettile(x,y); + if (!tile->fullbox) + return; -/* Empty the box: */ -level_change(¤t_level,x, y, 'a'); -} + // according to the collision side, set the upgrade direction + if(col_side == LEFT) + col_side = RIGHT; + else + col_side = LEFT; + switch(tile->data) + { + case 1: //'A': /* Box with a distro! */ + add_bouncy_distro(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32 - 32); + play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + score = score + SCORE_DISTRO; + distros++; + break; + + case 2: // 'B': /* Add an upgrade! */ + if (tux.size == SMALL) /* Tux is small, add mints! */ + add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_MINTS); + else /* Tux is big, add coffee: */ + add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_COFFEE); + play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER); + break; + + case 3:// '!': /* Add a golden herring */ + add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_HERRING); + break; + default: + break; + } -/* Try to grab a distro: */ + /* Empty the box: */ + level_change(¤t_level,x, y, TM_IA, tile->next_tile); +} +/* Try to grab a distro: */ void trygrabdistro(float x, float y, int bounciness) { - if (shape(x, y) == '$') + Tile* tile = gettile(x, y); + if (tile && tile->distro) { - level_change(¤t_level,x, y, '.'); + level_change(¤t_level,x, y, TM_IA, tile->next_tile); play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); if (bounciness == BOUNCE) @@ -1565,36 +1638,23 @@ void trygrabdistro(float x, float y, int bounciness) } /* Try to bump a bad guy from below: */ - void trybumpbadguy(float x, float y) { - int i; - - /* Bad guys: */ - - for (i = 0; i < num_bad_guys; i++) + for (unsigned int i = 0; i < bad_guys.size(); i++) { - if (bad_guys[i].base.alive && - bad_guys[i].base.x >= x - 32 && bad_guys[i].base.x <= x + 32 && + if (bad_guys[i].base.x >= x - 32 && bad_guys[i].base.x <= x + 32 && bad_guys[i].base.y >= y - 16 && bad_guys[i].base.y <= y + 16) { - if (bad_guys[i].kind == BAD_BSOD || - bad_guys[i].kind == BAD_LAPTOP) - { - bad_guys[i].dying = FALLING; - bad_guys[i].base.ym = -8; - play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER); - } + bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP); } } /* Upgrades: */ - - for (i = 0; i < num_upgrades; i++) + for (unsigned int i = 0; i < upgrades.size(); i++) { - if (upgrades[i].base.alive && upgrades[i].base.height == 32 && + if (upgrades[i].base.height == 32 && upgrades[i].base.x >= x - 32 && upgrades[i].base.x <= x + 32 && upgrades[i].base.y >= y - 16 && upgrades[i].base.y <= y + 16) { @@ -1608,46 +1668,46 @@ void trybumpbadguy(float x, float y) /* (Status): */ void drawstatus(void) { - int i; + char str[60]; sprintf(str, "%d", score); - text_draw(&white_text, "SCORE", 0, 0, 1, NO_UPDATE); - text_draw(&gold_text, str, 96, 0, 1, NO_UPDATE); + text_draw(&white_text, "SCORE", 0, 0, 1); + text_draw(&gold_text, str, 96, 0, 1); if(st_gl_mode != ST_GL_TEST) { sprintf(str, "%d", hs_score); - text_draw(&white_text, "HIGH", 0, 20, 1, NO_UPDATE); - text_draw(&gold_text, str, 96, 20, 1, NO_UPDATE); + text_draw(&white_text, "HIGH", 0, 20, 1); + text_draw(&gold_text, str, 96, 20, 1); } else { - text_draw(&white_text,"Press ESC To Return",0,20,1, NO_UPDATE); + text_draw(&white_text,"Press ESC To Return",0,20,1); } - if (timer_get_left(&time_left) > TIME_WARNING || (frame % 10) < 5) + if (timer_get_left(&time_left) > TIME_WARNING || (global_frame_counter % 10) < 5) { sprintf(str, "%d", timer_get_left(&time_left) / 1000 ); - text_draw(&white_text, "TIME", 224, 0, 1, NO_UPDATE); - text_draw(&gold_text, str, 304, 0, 1, NO_UPDATE); + text_draw(&white_text, "TIME", 224, 0, 1); + text_draw(&gold_text, str, 304, 0, 1); } sprintf(str, "%d", distros); - text_draw(&white_text, "DISTROS", screen->h, 0, 1, NO_UPDATE); - text_draw(&gold_text, str, 608, 0, 1, NO_UPDATE); + text_draw(&white_text, "DISTROS", screen->h, 0, 1); + text_draw(&gold_text, str, 608, 0, 1); - text_draw(&white_text, "LIVES", screen->h, 20, 1, NO_UPDATE); + text_draw(&white_text, "LIVES", screen->h, 20, 1); if(show_fps) { sprintf(str, "%2.1f", fps_fps); - text_draw(&white_text, "FPS", screen->h, 40, 1, NO_UPDATE); - text_draw(&gold_text, str, screen->h + 60, 40, 1, NO_UPDATE); + text_draw(&white_text, "FPS", screen->h, 40, 1); + text_draw(&gold_text, str, screen->h + 60, 40, 1); } - for(i=0; i < tux.lives; ++i) + for(int i=0; i < tux.lives; ++i) { - texture_draw(&tux_life,565+(18*i),20,NO_UPDATE); + texture_draw(&tux_life,565+(18*i),20); } } @@ -1658,13 +1718,13 @@ void drawendscreen(void) clearscreen(0, 0, 0); - text_drawf(&blue_text, "GAMEOVER", 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&blue_text, "GAMEOVER", 0, 200, A_HMIDDLE, A_TOP, 1); sprintf(str, "SCORE: %d", score); - text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1); sprintf(str, "DISTROS: %d", distros); - text_drawf(&gold_text, str, 0, 256, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&gold_text, str, 0, 256, A_HMIDDLE, A_TOP, 1); flipscreen(); SDL_Delay(2000); @@ -1676,13 +1736,13 @@ void drawresultscreen(void) clearscreen(0, 0, 0); - text_drawf(&blue_text, "Result:", 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&blue_text, "Result:", 0, 200, A_HMIDDLE, A_TOP, 1); sprintf(str, "SCORE: %d", score); - text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1); sprintf(str, "DISTROS: %d", distros); - text_drawf(&gold_text, str, 0, 256, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&gold_text, str, 0, 256, A_HMIDDLE, A_TOP, 1); flipscreen(); SDL_Delay(2000); @@ -1701,7 +1761,6 @@ void savegame(int slot) if (fi == NULL) { fprintf(stderr, "Warning: I could not open the slot file "); - } else { @@ -1711,7 +1770,7 @@ void savegame(int slot) fwrite(&score,sizeof(int),1,fi); fwrite(&distros,sizeof(int),1,fi); fwrite(&scroll_x,sizeof(float),1,fi); - fwrite(&tux,sizeof(player_type),1,fi); + fwrite(&tux,sizeof(Player),1,fi); timer_fwrite(&tux.invincible_timer,fi); timer_fwrite(&tux.skidding_timer,fi); timer_fwrite(&tux.safe_timer,fi); @@ -1742,8 +1801,6 @@ void loadgame(int slot) } else { - - fgets(str, 100, fi); strcpy(level_subset, str); level_subset[strlen(level_subset)-1] = '\0'; @@ -1756,6 +1813,7 @@ void loadgame(int slot) arrays_free(); arrays_init(); activate_bad_guys(); + activate_particle_systems(); level_free_gfx(); level_load_gfx(¤t_level); level_free_song(); @@ -1766,7 +1824,7 @@ void loadgame(int slot) fread(&score,sizeof(int),1,fi); fread(&distros,sizeof(int),1,fi); fread(&scroll_x,sizeof(float),1,fi); - fread(&tux,sizeof(player_type),1,fi); + fread(&tux, sizeof(Player), 1, fi); timer_fread(&tux.invincible_timer,fi); timer_fread(&tux.skidding_timer,fi); timer_fread(&tux.safe_timer,fi); @@ -1811,6 +1869,5 @@ void slotinfo(char **pinfo, int slot) *pinfo = (char*) malloc(sizeof(char) * (strlen(tmp)+1)); strcpy(*pinfo,tmp); - }