From: Tobias Gläßer Date: Wed, 18 Feb 2004 00:09:55 +0000 (+0000) Subject: huge CVS merge, see ChangeLog for details. X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=6e7cc3b4259e75a61df2984571d0ab1994c7cceb;p=supertux.git huge CVS merge, see ChangeLog for details. SVN-Revision: 125 --- diff --git a/src/badguy.c b/src/badguy.c index 71dcda6a5..fe5b7e34d 100644 --- a/src/badguy.c +++ b/src/badguy.c @@ -16,6 +16,15 @@ #include "scene.h" #include "screen.h" +texture_type img_bsod_squished_left, img_bsod_squished_right, +img_bsod_falling_left, img_bsod_falling_right, +img_laptop_flat_left, img_laptop_flat_right, +img_laptop_falling_left, img_laptop_falling_right; +texture_type img_bsod_left[4], img_bsod_right[4], +img_laptop_left[3], img_laptop_right[3], +img_money_left[2], img_money_right[2]; +bitmask *bm_bsod; + void badguy_create_bitmasks() { /*bm_bsod = img_bsod_left[0];*/ @@ -36,6 +45,7 @@ void badguy_init(bad_guy_type* pbad, float x, float y, int kind) pbad->dir = LEFT; pbad->seen = NO; timer_init(&pbad->timer); + physic_init(&pbad->physic); } void badguy_action(bad_guy_type* pbad) @@ -70,8 +80,14 @@ void badguy_action(bad_guy_type* pbad) if (!pbad->dying) { - if (issolid(pbad->base.x, pbad->base.y)) - pbad->dir = !pbad->dir; + if (issolid( pbad->base.x - 1, (int) pbad->base.y)) + { + pbad->dir = RIGHT; + } + else if (issolid( pbad->base.x + pbad->base.width-1, (int) pbad->base.y)) + { + pbad->dir = LEFT; + } } /* Fall if we get off the ground: */ @@ -213,31 +229,22 @@ void badguy_action(bad_guy_type* pbad) pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio; - - /* Fall if we get off the ground: */ - - if (pbad->dying != FALLING) - { - if (!issolid(pbad->base.x, pbad->base.y + 32)) - { - if (pbad->base.ym < MAX_YM) - { - pbad->base.ym = pbad->base.ym + GRAVITY * frame_ratio; - } - } - else - { - /* Land: */ - - if (pbad->base.ym > 0) - { - pbad->base.y = (int)(pbad->base.y / 32) * 32; - pbad->base.ym = -MAX_YM; - } - } - } - else - pbad->base.ym = pbad->base.ym + GRAVITY * frame_ratio; + if(physic_get_state(&pbad->physic) == -1) + physic_set_state(&pbad->physic,PH_VTU); + + if(issolid(pbad->base.x, pbad->base.y + 32)) + { + physic_set_state(&pbad->physic,PH_VTU); + pbad->base.ym = -0.6; + } + else if(issolid(pbad->base.x, pbad->base.y - 1)) + { /* This works, but isn't the best solution imagineable */ + pbad->base.ym = physic_get_velocity(&pbad->physic,-6.); + } + else + { + pbad->base.ym = physic_get_velocity(&pbad->physic,6.); + } if (pbad->base.y > screen->h) pbad->base.alive = NO; @@ -427,7 +434,7 @@ void badguy_draw(bad_guy_type* pbad) } else if (pbad->kind == BAD_MONEY) { - if (pbad->base.ym > -16) + if (pbad->base.ym != 300 /* > -16*/) { if (pbad->dir == LEFT) { @@ -491,7 +498,7 @@ void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object) play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER); break; case CO_BADGUY: - pbad_c = p_c_object; + pbad_c = (bad_guy_type*) p_c_object; if (pbad->mode != FLAT) pbad->dir = !pbad->dir; else @@ -508,7 +515,7 @@ void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object) pbad->dir = !pbad->dir; break; case CO_PLAYER: - pplayer_c = p_c_object; + pplayer_c = (player_type*) p_c_object; if (pbad->kind == BAD_BSOD) { pbad->dying = SQUISHED; diff --git a/src/badguy.h b/src/badguy.h index 1d04a3ce5..258e12a99 100644 --- a/src/badguy.h +++ b/src/badguy.h @@ -18,6 +18,7 @@ #include "type.h" #include "timer.h" #include "texture.h" +#include "physic.h" #include "collision.h" /* Enemy modes: */ @@ -39,6 +40,7 @@ typedef struct bad_guy_type int frame; base_type base; timer_type timer; + physic_type physic; } bad_guy_type; @@ -50,15 +52,15 @@ enum { BAD_MONEY }; -texture_type img_bsod_squished_left, img_bsod_squished_right, +extern texture_type img_bsod_squished_left, img_bsod_squished_right, img_bsod_falling_left, img_bsod_falling_right, img_laptop_flat_left, img_laptop_flat_right, img_laptop_falling_left, img_laptop_falling_right; -texture_type img_bsod_left[4], img_bsod_right[4], +extern texture_type img_bsod_left[4], img_bsod_right[4], img_laptop_left[3], img_laptop_right[3], img_money_left[2], img_money_right[2]; -bitmask *bm_bsod; +extern bitmask *bm_bsod; void badguy_create_bitmasks(); diff --git a/src/bitmask.c b/src/bitmask.c index b3be49955..3607f0175 100644 --- a/src/bitmask.c +++ b/src/bitmask.c @@ -30,12 +30,12 @@ bitmask *bitmask_create(int w, int h) { - bitmask *temp = malloc(sizeof(bitmask)); + bitmask *temp = (bitmask*) malloc(sizeof(bitmask)); if (! temp) return 0; temp->w = w; temp->h = h; - temp->bits = calloc(h*((w - 1)/BITW_LEN + 1),sizeof(BITW)); + temp->bits = (long unsigned int*) calloc(h*((w - 1)/BITW_LEN + 1),sizeof(BITW)); if (! temp->bits) { free(temp); @@ -51,12 +51,12 @@ bitmask *bitmask_create_SDL(SDL_Surface* surf) int bpp; Uint8* p; - bitmask *temp = malloc(sizeof(bitmask)); + bitmask *temp = (bitmask*) malloc(sizeof(bitmask)); if (! temp) return 0; temp->w = surf->w; temp->h = surf->h; - temp->bits = calloc(surf->h*((surf->w - 1)/BITW_LEN + 1),sizeof(BITW)); + temp->bits = (long unsigned int*) calloc(surf->h*((surf->w - 1)/BITW_LEN + 1),sizeof(BITW)); if (! temp->bits) { free(temp); diff --git a/src/collision.c b/src/collision.c index 6e2a3930d..de8a536d5 100644 --- a/src/collision.c +++ b/src/collision.c @@ -62,16 +62,16 @@ void collision_handler() { if(rectcollision(&bullets[i].base,&bad_guys[j].base) == YES) { - /* We have detected a collision and now call the collision functions of the collided objects. */ - bullet_collision(&bullets[i], CO_BADGUY); - badguy_collision(&bad_guys[j], &bullets[i], CO_BULLET); + /* We have detected a collision and now call the collision functions of the collided objects. */ + bullet_collision(&bullets[i], CO_BADGUY); + badguy_collision(&bad_guys[j], &bullets[i], CO_BULLET); } } } } } - - /* CO_BADGUY & CO_BADGUY check */ + + /* CO_BADGUY & CO_BADGUY check */ for(i = 0; i < num_bad_guys; ++i) { if(bad_guys[i].base.alive) @@ -82,47 +82,49 @@ void collision_handler() { if(rectcollision(&bad_guys[i].base,&bad_guys[j].base) == YES) { - /* We have detected a collision and now call the collision functions of the collided objects. */ - badguy_collision(&bad_guys[j], &bad_guys[i], CO_BADGUY); - badguy_collision(&bad_guys[i], &bad_guys[j], CO_BADGUY); - } + /* We have detected a collision and now call the collision functions of the collided objects. */ + badguy_collision(&bad_guys[j], &bad_guys[i], CO_BADGUY); + badguy_collision(&bad_guys[i], &bad_guys[j], CO_BADGUY); + } } } } } - /* CO_BADGUY & CO_PLAYER check */ + /* CO_BADGUY & CO_PLAYER check */ for(i = 0; i < num_bad_guys; ++i) { if(bad_guys[i].base.alive) { - if(bad_guys[i].dying == NO && rectcollision_offset(&bad_guys[i].base,&tux.base,0,0) == YES && tux.base.ym > 0) - { - /* We have detected a collision and now call the collision functions of the collided objects. */ - badguy_collision(&bad_guys[i], &tux, CO_PLAYER); - } - if(rectcollision(&bad_guys[i].base,&tux.base) == YES) - { - player_collision(&tux, &bad_guys[i], CO_BADGUY); - } - + if(bad_guys[i].dying == NO && rectcollision_offset(&bad_guys[i].base,&tux.base,0,0) == YES ) + { + /* We have detected a collision and now call the collision functions of the collided objects. */ + if (tux.base.ym > 0) + { + badguy_collision(&bad_guys[i], &tux, CO_PLAYER); + } + else + { + player_collision(&tux, &bad_guys[i], CO_BADGUY); + } + } } } - /* CO_UPGRADE & CO_PLAYER check */ + /* CO_UPGRADE & CO_PLAYER check */ for(i = 0; i < num_upgrades; ++i) { if(upgrades[i].base.alive) { - if(rectcollision(&upgrades[i].base,&tux.base) == YES) - { - /* We have detected a collision and now call the collision functions of the collided objects. */ - upgrade_collision(&upgrades[i], &tux, CO_PLAYER); - } + if(rectcollision(&upgrades[i].base,&tux.base) == YES) + { + /* We have detected a collision and now call the collision functions of the collided objects. */ + upgrade_collision(&upgrades[i], &tux, CO_PLAYER); + } } } - + } diff --git a/src/gameloop.c b/src/gameloop.c index b1b550e12..ce373b195 100644 --- a/src/gameloop.c +++ b/src/gameloop.c @@ -42,6 +42,7 @@ /* extern variables */ extern char* soundfilenames[NUM_SOUNDS]; +st_level current_level; /* Local variables: */ @@ -52,13 +53,15 @@ SDLKey key; char level_subset[100]; char str[60]; float fps_fps; +int st_gl_mode; +unsigned int last_update_time; +unsigned int update_time; +int pause_menu_frame; /* Local function prototypes: */ void levelintro(void); void initgame(void); -void loadlevelsong(void); -void unloadlevelsong(void); void loadshared(void); void unloadshared(void); void drawstatus(void); @@ -72,13 +75,13 @@ void levelintro(void) clearscreen(0, 0, 0); sprintf(str, "LEVEL %d", level); - text_drawf(&red_text, str, 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&blue_text, str, 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE); sprintf(str, "%s", current_level.name); text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1, NO_UPDATE); sprintf(str, "TUX x %d", tux.lives); - text_drawf(&blue_text, str, 0, 256, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&white_text, str, 0, 256, A_HMIDDLE, A_TOP, 1, NO_UPDATE); flipscreen(); @@ -139,16 +142,18 @@ void game_event(void) case SDLK_ESCAPE: /* Escape: Open/Close the menu: */ if(!game_pause) { - if(show_menu) - { - show_menu = 0; - st_pause_ticks_stop(); - } + if(st_gl_mode == ST_GL_TEST) + quit = 1; + else if(show_menu) + { + show_menu = 0; + st_pause_ticks_stop(); + } else - { - show_menu = 1; - st_pause_ticks_start(); - } + { + show_menu = 1; + st_pause_ticks_start(); + } } break; default: @@ -167,15 +172,15 @@ void game_event(void) if(!show_menu) { if(game_pause) - { - game_pause = 0; - st_pause_ticks_stop(); - } + { + game_pause = 0; + st_pause_ticks_stop(); + } else - { - game_pause = 1; - st_pause_ticks_start(); - } + { + game_pause = 1; + st_pause_ticks_start(); + } } break; case SDLK_TAB: @@ -200,11 +205,11 @@ void game_event(void) break; case SDLK_l: if(debug_mode == YES) - --tux.lives; + --tux.lives; break; case SDLK_s: if(debug_mode == YES) - score += 1000; + score += 1000; break; default: break; @@ -281,7 +286,6 @@ int game_action(void) { /* Tux either died, or reached the end of a level! */ - if (playing_music()) halt_music(); @@ -291,24 +295,29 @@ int game_action(void) /* End of a level! */ level++; next_level = 0; - drawresultscreen(); + if(st_gl_mode == ST_GL_PLAY) + drawresultscreen(); player_level_begin(&tux); } else { - player_dying(&tux); /* No more lives!? */ if (tux.lives < 0) { - drawendscreen(); + if(st_gl_mode == ST_GL_PLAY) + drawendscreen(); - if (score > hs_score) - save_hs(score); - unloadlevelgfx(); - unloadlevelsong(); + if(st_gl_mode == ST_GL_PLAY) + { + if (score > hs_score) + save_hs(score); + } + level_free_gfx(); + level_free(¤t_level); + level_free_song(); unloadshared(); arrays_free(); return(0); @@ -319,15 +328,18 @@ int game_action(void) player_level_begin(&tux); set_defaults(); - loadlevel(¤t_level,"default",level); + level_free(¤t_level); + if(level_load(¤t_level,level_subset,level) != 0) + exit(1); arrays_free(); arrays_init(); activate_bad_guys(); - unloadlevelgfx(); - loadlevelgfx(¤t_level); - unloadlevelsong(); - loadlevelsong(); - levelintro(); + level_free_gfx(); + level_load_gfx(¤t_level); + level_free_song(); + level_load_song(¤t_level); + if(st_gl_mode == ST_GL_PLAY) + levelintro(); start_timers(); } @@ -421,7 +433,7 @@ void game_draw(void) /* Draw the real background */ if(current_level.bkgd_image[0] != '\0') { - s = scroll_x / 30; + 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); } @@ -504,10 +516,18 @@ void game_draw(void) if(game_pause) - text_drawf(&red_text, "PAUSE", 0, 230, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + { + x = screen->h / 20; + for(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); + } if(show_menu) - done = drawmenu(); + menu_process_current(); /* (Update it all!) */ @@ -518,13 +538,15 @@ void game_draw(void) /* --- GAME LOOP! --- */ -int gameloop(void) +int gameloop(char * subset, int levelnb, int mode) { - - /*Uint32 last_time, now_time*/ - int fps_cnt, jump; + int fps_cnt, jump, done; timer_type fps_timer, frame_timer; + level = levelnb; + st_gl_mode = mode; + strcpy(level_subset,subset); + /* Clear screen: */ clearscreen(0, 0, 0); @@ -534,21 +556,26 @@ int gameloop(void) /* Init the game: */ arrays_init(); - initmenu(); - menumenu = MENU_GAME; + menu_reset(); + menu_set_current(&game_menu); + initgame(); loadshared(); set_defaults(); - loadlevel(¤t_level,"default",level); - loadlevelgfx(¤t_level); + if(level_load(¤t_level,level_subset,level) != 0) + exit(1); + level_load_gfx(¤t_level); activate_bad_guys(); - loadlevelsong(); - load_hs(); + level_load_song(¤t_level); + if(st_gl_mode == ST_GL_PLAY) + load_hs(); player_init(&tux); - levelintro(); + if(st_gl_mode == ST_GL_PLAY) + levelintro(); + start_timers(); /* --- MAIN GAME LOOP!!! --- */ @@ -565,12 +592,8 @@ int gameloop(void) game_draw(); do { - jump = NO; - - /* Set the time the last update and the time of the current update */ - last_update_time = update_time; - update_time = st_get_ticks(); - + jump = NO; + /* Calculate the movement-factor */ frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE); @@ -585,10 +608,36 @@ int gameloop(void) tux.input.old_fire = tux.input.fire; - printf("%lf\n",frame_ratio); - + /*printf("%lf\n",frame_ratio);*/ + game_event(); + if(show_menu) + { + if(current_menu == &game_menu) + { + switch (menu_check(&game_menu)) + { + case 0: + st_pause_ticks_stop(); + break; + case 1: + savegame(); + break; + case 2: + loadgame(NULL); + break; + case 4: + done = 1; + break; + } + } + else if(current_menu == &options_menu) + { + process_options_menu(); + } + } + /* Handle actions: */ @@ -602,15 +651,18 @@ int gameloop(void) } } else - SDL_Delay(50); - - if(tux.input.down == DOWN) - SDL_Delay(30); - + { + ++pause_menu_frame; + SDL_Delay(50); + } + + if(tux.input.down == DOWN) + SDL_Delay(30); + /*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 @@ -623,11 +675,18 @@ int gameloop(void) continue; } + /* Set the time the last update and the time of the current update */ + 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+. */ + 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 ) SDL_Delay(10); + //if((update_time - last_update_time) < 10) + // SDL_Delay((11 - (update_time - last_update_time))/2); @@ -662,7 +721,7 @@ int gameloop(void) /* Calculate frames per second */ if(show_fps) { - ++fps_cnt; + ++fps_cnt; fps_fps = (1000.0 / (float)timer_get_gone(&fps_timer)) * (float)fps_cnt; if(!timer_check(&fps_timer)) @@ -678,8 +737,9 @@ int gameloop(void) if (playing_music()) halt_music(); - unloadlevelgfx(); - unloadlevelsong(); + level_free_gfx(); + level_free(¤t_level); + level_free_song(); unloadshared(); arrays_free(); @@ -691,44 +751,10 @@ int gameloop(void) void initgame(void) { - level = 1; score = 0; distros = 0; } -/* Free music data for this level: */ - -void unloadlevelsong(void) -{ - free_music(level_song); - free_music(level_song_fast); -} - -/* Load music: */ - -void loadlevelsong(void) -{ - - char * song_path; - char * song_subtitle; - - song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + - strlen(current_level.song_title) + 8)); - sprintf(song_path, "%s/music/%s", DATA_PREFIX, current_level.song_title); - level_song = load_song(song_path); - free(song_path); - - - song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + - strlen(current_level.song_title) + 8 + 5)); - song_subtitle = strdup(current_level.song_title); - strcpy(strstr(song_subtitle, "."), "\0"); - sprintf(song_path, "%s/music/%s-fast%s", DATA_PREFIX, song_subtitle, strstr(current_level.song_title, ".")); - level_song_fast = load_song(song_path); - free(song_subtitle); - free(song_path); -} - /* Load graphics/sounds shared between all levels: */ void loadshared(void) @@ -1273,7 +1299,7 @@ void drawshape(float x, float y, unsigned char c) /* Mark this as the end position of the level! */ - endpos = x; + endpos = (int)x; } else if (c == '\\') { @@ -1309,6 +1335,26 @@ unsigned char shape(float x, float y) /* Is is ground? */ + +int 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')) + { + return YES; + } + + return NO; +} + +/* int issolid(float x, float y) { if (isbrick(x, y) || @@ -1334,7 +1380,7 @@ int issolid(float x, float y) } return NO; -} +}*/ /* Is it a brick? */ @@ -1447,6 +1493,9 @@ void tryemptybox(float x, float y) { if (shape(x, y) == 'A') { + + DEBUG_MSG("Here I am"); + /* Box with a distro! */ add_bouncy_distro(((x + 1) / 32) * 32, @@ -1562,31 +1611,38 @@ void drawstatus(void) int i; sprintf(str, "%d", score); - text_draw(&blue_text, "SCORE", 0, 0, 1, NO_UPDATE); + text_draw(&white_text, "SCORE", 0, 0, 1, NO_UPDATE); text_draw(&gold_text, str, 96, 0, 1, NO_UPDATE); - sprintf(str, "%d", hs_score); - text_draw(&blue_text, "HIGH", 0, 20, 1, NO_UPDATE); - text_draw(&gold_text, str, 96, 20, 1, NO_UPDATE); - + if(st_gl_mode == ST_GL_PLAY) + { + 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); + } + else if(st_gl_mode == ST_GL_TEST) + { + text_draw(&white_text,"Press ESC To Return",0,20,1, NO_UPDATE); + } + if (timer_get_left(&time_left) > TIME_WARNING || (frame % 10) < 5) { sprintf(str, "%d", timer_get_left(&time_left) / 1000 ); - text_draw(&blue_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, NO_UPDATE); + text_draw(&gold_text, str, 304, 0, 1, NO_UPDATE); } sprintf(str, "%d", distros); - text_draw(&blue_text, "DISTROS", screen->h, 0, 1, NO_UPDATE); + text_draw(&white_text, "DISTROS", screen->h, 0, 1, NO_UPDATE); text_draw(&gold_text, str, 608, 0, 1, NO_UPDATE); - text_draw(&blue_text, "LIVES", screen->h, 20, 1, NO_UPDATE); + text_draw(&white_text, "LIVES", screen->h, 20, 1, NO_UPDATE); if(show_fps) { - sprintf(str, "%f", fps_fps); - text_draw(&blue_text, "FPS", screen->h, 40, 1, NO_UPDATE); - text_draw(&blue_text, str, screen->h + 60, 40, 1, NO_UPDATE); + 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); } for(i=0; i < tux.lives; ++i) @@ -1620,7 +1676,7 @@ void drawresultscreen(void) clearscreen(0, 0, 0); - text_drawf(&red_text, "Result:", 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + text_drawf(&blue_text, "Result:", 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE); sprintf(str, "SCORE: %d", score); text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1, NO_UPDATE); @@ -1688,14 +1744,16 @@ void loadgame(char* filename) { player_level_begin(&tux); set_defaults(); - loadlevel(¤t_level,"default",level); + level_free(¤t_level); + if(level_load(¤t_level,level_subset,level) != 0) + exit(1); arrays_free(); arrays_init(); activate_bad_guys(); - unloadlevelgfx(); - loadlevelgfx(¤t_level); - unloadlevelsong(); - loadlevelsong(); + level_free_gfx(); + level_load_gfx(¤t_level); + level_free_song(); + level_load_song(¤t_level); levelintro(); start_timers(); diff --git a/src/gameloop.h b/src/gameloop.h index 2a1ab16e5..21b9e3621 100644 --- a/src/gameloop.h +++ b/src/gameloop.h @@ -15,6 +15,7 @@ #include "sound.h" #include "type.h" +#include "level.h" /* Bounciness of distros: */ @@ -35,14 +36,21 @@ enum { UPGRADE_HERRING }; +extern st_level current_level; + /* Scores: */ #define SCORE_BRICK 5 #define SCORE_DISTRO 25 +/* GameLoop modes */ + +#define ST_GL_PLAY 0 +#define ST_GL_TEST 1 + /* Function prototypes: */ -int gameloop(void); +int gameloop(char * subset, int levelnb, int mode); void savegame(void); void loadgame(char* filename); int issolid(float x, float y); diff --git a/src/globals.h b/src/globals.h index 65f9c221b..9d9fc1c70 100644 --- a/src/globals.h +++ b/src/globals.h @@ -16,19 +16,18 @@ #include #include "text.h" +#include "menu.h" -SDL_Surface * screen; -text_type black_text, gold_text, blue_text, red_text; +extern SDL_Surface * screen; +extern text_type black_text, gold_text, white_text, white_small_text, blue_text, red_text, yellow_nums; -int use_gl, use_joystick, use_fullscreen, debug_mode, show_fps; - -int game_started, level_editor_started; +extern int use_gl, use_joystick, use_fullscreen, debug_mode, show_fps; /* SuperTux directory ($HOME/.supertux) and save directory($HOME/.supertux/save) */ -char *st_dir, *st_save_dir; +extern char *st_dir, *st_save_dir; #ifdef JOY_YES -SDL_Joystick * js; +extern SDL_Joystick * js; #endif #endif /* SUPERTUX_GLOBALS_H */ diff --git a/src/high_scores.c b/src/high_scores.c index 22210c09f..c209148eb 100644 --- a/src/high_scores.c +++ b/src/high_scores.c @@ -16,9 +16,12 @@ #include "screen.h" #include "texture.h" +int hs_score; +char hs_name[62]; /* highscores global variables*/ + FILE * opendata(char * mode) { - char * filename; + char * filename = NULL; FILE * fi; @@ -64,12 +67,12 @@ void load_hs(void) { FILE * fi; char temp[128]; - int c, strl; + int c, i, strl; hs_score = 100; strcpy(hs_name, "Grandma\0"); c = 0; - + /* Try to open file: */ fi = opendata("r"); @@ -97,9 +100,9 @@ void load_hs(void) { fprintf(stderr, "name found\n"); strl = strlen("name="); - hs_name[strl-1]='\0'; - for(c = strl; c < strlen(temp); c++) - hs_name[c-strl] = temp[c]; + for(c = strl, i = 0; c < strlen(temp); ++c, ++i) + hs_name[i] = temp[c]; + hs_name[i]= '\0'; } } } @@ -111,6 +114,8 @@ void load_hs(void) void save_hs(int score) { + char str[80]; + texture_type bkgd; SDL_Event event; FILE * fi; @@ -120,18 +125,41 @@ void save_hs(int score) hs_score = score; + menu_reset(); + menu_set_current(&highscore_menu); + + if(!highscore_menu.item[0].input) + highscore_menu.item[0].input = (char*) malloc(strlen(hs_name) + 1); + + strcpy(highscore_menu.item[0].input,hs_name); + /* ask for player's name */ - menumenu = MENU_HIGHSCORE; show_menu = 1; while(show_menu) { texture_draw_bg(&bkgd, NO_UPDATE); - drawmenu(); + + text_drawf(&blue_text, "Congratulations", 0, 130, A_HMIDDLE, A_TOP, 2, NO_UPDATE); + text_draw(&blue_text, "Your score:", 150, 180, 1, NO_UPDATE); + sprintf(str, "%d", hs_score); + text_draw(&yellow_nums, str, 350, 170, 1, NO_UPDATE); + + menu_process_current(); flipscreen(); while(SDL_PollEvent(&event)) if(event.type == SDL_KEYDOWN) menu_event(&event.key.keysym); + + switch (menu_check(&highscore_menu)) + { + case 0: + if(highscore_menu.item[0].input != NULL) + strcpy(hs_name, highscore_menu.item[0].input); + break; + } + + SDL_Delay(25); } diff --git a/src/high_scores.h b/src/high_scores.h index 0b8d91ad3..c15ade6c9 100644 --- a/src/high_scores.h +++ b/src/high_scores.h @@ -7,8 +7,8 @@ # include -int hs_score; -char hs_name[62]; /* highscores global variables*/ +extern int hs_score; +extern char hs_name[62]; /* highscores global variables*/ void save_hs(int score); void load_hs(); diff --git a/src/intro.c b/src/intro.c index 0efb9b576..d60f0882f 100644 --- a/src/intro.c +++ b/src/intro.c @@ -70,8 +70,8 @@ int intro(void) /* Allocate buffer for height array: */ - height = malloc(sizeof(int) * (gown_upset.w)); - height_speed = malloc(sizeof(int) * (gown_upset.w)); + height = (int*) malloc(sizeof(int) * (gown_upset.w)); + height_speed = (int*) malloc(sizeof(int) * (gown_upset.w)); /* Initialize height arrays: */ @@ -137,7 +137,7 @@ int intro(void) texture_draw(&tux_sit, 270, 400, UPDATE); texture_draw(&gown_sit, 320, 400, UPDATE); - text_drawf(&blue_text, intro_text[0], 0, -8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE); + text_drawf(&white_text, intro_text[0], 0, -8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE); } @@ -146,8 +146,8 @@ int intro(void) ++scene; /* Helicopter begins to fly in: */ - erasecenteredtext(intro_text[0], 456, &bkgd, NO_UPDATE, 1); - text_drawf(&blue_text, intro_text[1], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE); + erasecenteredtext(intro_text[0], 454, &bkgd, NO_UPDATE, 1); + text_drawf(&white_text, intro_text[1], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE); } @@ -200,8 +200,8 @@ int intro(void) texture_draw(&tux_upset, 270, 400, UPDATE); - erasecenteredtext(intro_text[1], 456, &bkgd, UPDATE, 1); - text_drawf(&blue_text, intro_text[2], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE); + erasecenteredtext(intro_text[1], 454, &bkgd, UPDATE, 1); + text_drawf(&white_text, intro_text[2], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE); } @@ -254,8 +254,8 @@ int intro(void) texture_draw(&tux_mad, 270, 400, UPDATE); - erasecenteredtext(intro_text[2], 456, &bkgd, UPDATE, 1); - text_drawf(&blue_text, intro_text[3], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE); + erasecenteredtext(intro_text[2], 454, &bkgd, UPDATE, 1); + text_drawf(&white_text, intro_text[3], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE); } diff --git a/src/level.c b/src/level.c index b9f0ea47b..db92a4c72 100644 --- a/src/level.c +++ b/src/level.c @@ -18,29 +18,113 @@ #include "screen.h" #include "level.h" -/* Load data for this level: */ +texture_type img_bkgd, img_bkgd_tile[2][4], img_solid[4], img_brick[2]; + +void subset_init(st_subset* st_subset) +{ + st_subset->title = NULL; + st_subset->description = NULL; + st_subset->levels = 0; +} -void loadlevel(st_level* plevel, char *subset, int level) +void subset_load(st_subset* st_subset, char *subset) +{ + FILE* fi; + char filename[1024]; + char str[1024]; + int len,i; + + st_subset->name = (char*) malloc(sizeof(char)*(strlen(subset)+1)); + strcpy(st_subset->name,subset); + + snprintf(filename, 1024, "%s/levels/%s/info", st_dir, subset); + if(!faccessible(filename)) + snprintf(filename, 1024, "%s/levels/%s/info", DATA_PREFIX, subset); + if(faccessible(filename)) + { + fi = fopen(filename, "r"); + if (fi == NULL) + { + perror(filename); + } + + /* Load title info: */ + fgets(str, 40, fi); + st_subset->title = (char*) malloc(sizeof(char)*(strlen(str)+1)); + strcpy(st_subset->title, str); + + /* Load the description: */ + + str[0] = '\0'; + st_subset->description = NULL; + len = 0; + while(fgets(str, 300, fi) != NULL) + { + len += strlen(str); + if(st_subset->description == NULL) + st_subset->description = (char*) calloc(len+1,sizeof(char)); + else + st_subset->description = (char*) realloc(st_subset->description, sizeof(char) * (len+1)); + strcat(st_subset->description,str); + } + fclose(fi); + + snprintf(str, 1024, "%s.png", filename); + if(faccessible(str)) + { + texture_load(&st_subset->image,str,IGNORE_ALPHA); + } + else + { + snprintf(filename, 1024, "%s/images/status/level-subset-info.png", DATA_PREFIX); + texture_load(&st_subset->image,filename,IGNORE_ALPHA); + } + } + + for(i=1; i != -1; ++i) + { + /* Get the number of levels in this subset */ + snprintf(filename, 1024, "%s/levels/%s/level%d.dat", st_dir, subset,i); + if(!faccessible(filename)) + { + snprintf(filename, 1024, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset,i); + if(!faccessible(filename)) + break; + } + } + st_subset->levels = --i; +} + +void subset_free(st_subset* st_subset) +{ + free(st_subset->title); + free(st_subset->description); + free(st_subset->name); + texture_free(&st_subset->image); + st_subset->levels = 0; +} + +/* Load data for this level: */ +/* Returns -1, if the loading of the level failed. */ +int level_load(st_level* plevel, char *subset, int level) { int y; FILE * fi; char str[80]; - char * filename; + char filename[1024]; char * line; /* Load data file: */ - filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20) + strlen(subset)); - sprintf(filename, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level); + snprintf(filename, 1024, "%s/levels/%s/level%d.dat", st_dir, subset, level); + if(!faccessible(filename)) + snprintf(filename, 1024, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level); fi = fopen(filename, "r"); if (fi == NULL) { perror(filename); - st_shutdown(); - free(filename); - exit(-1); + return -1; } - free(filename); /* Load header info: */ @@ -92,7 +176,7 @@ void loadlevel(st_level* plevel, char *subset, int level) { fprintf(stderr, "Couldn't allocate space to load level data!"); fclose(fi); - exit(1); + return -1; } @@ -105,39 +189,40 @@ void loadlevel(st_level* plevel, char *subset, int level) fprintf(stderr, "Level %s isn't complete!\n",plevel->name); free(line); fclose(fi); - exit(1); + return -1; } line[strlen(line) - 1] = '\0'; - plevel->tiles[y] = strdup(line); + plevel->tiles[y] = (unsigned char*) strdup(line); } free(line); fclose(fi); - + return 0; } /* Save data for level: */ -void savelevel(st_level* plevel, char * subset, int level) +void level_save(st_level* plevel, char * subset, int level) { FILE * fi; - char * filename; + char filename[1024]; int y; char str[80]; /* Save data file: */ + sprintf(str, "/levels/%s/", subset); + fcreatedir(str); + snprintf(filename, 1024, "%s/levels/%s/level%d.dat", st_dir, subset, level); + if(!fwriteable(filename)) + snprintf(filename, 1024, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level); - filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20) + strlen(subset)); - sprintf(filename, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level); fi = fopen(filename, "w"); if (fi == NULL) { perror(filename); st_shutdown(); - free(filename); exit(-1); } - free(filename); fputs(plevel->name, fi); fputs("\n", fi); @@ -147,7 +232,7 @@ void savelevel(st_level* plevel, char * subset, int level) fputs(str, fi); fputs(plevel->song_title, fi); /* song filename */ fputs("\n",fi); - fputs(plevel->bkgd_image, fi); /* background image */ + fputs(plevel->bkgd_image, fi); /* background image */ sprintf(str, "\n%d\n", plevel->bkgd_red); /* red background color */ fputs(str, fi); sprintf(str, "%d\n", plevel->bkgd_green); /* green background color */ @@ -159,7 +244,7 @@ void savelevel(st_level* plevel, char * subset, int level) for(y = 0; y < 15; ++y) { - fputs(plevel->tiles[y], fi); + fputs((const char*)plevel->tiles[y], fi); fputs("\n", fi); } @@ -169,9 +254,12 @@ void savelevel(st_level* plevel, char * subset, int level) /* Unload data for this level: */ -void unloadlevel(st_level* plevel) +void level_free(st_level* plevel) { - free(plevel->tiles); + int i; + for(i=0; i < 15; ++i) + free(plevel->tiles[i]); + plevel->name[0] = '\0'; plevel->theme[0] = '\0'; plevel->song_title[0] = '\0'; @@ -180,26 +268,26 @@ void unloadlevel(st_level* plevel) /* Load graphics: */ -void loadlevelgfx(st_level *plevel) +void level_load_gfx(st_level *plevel) { - load_level_image(&img_brick[0],plevel->theme,"brick0.png", IGNORE_ALPHA); - load_level_image(&img_brick[1],plevel->theme,"brick1.png", IGNORE_ALPHA); + level_load_image(&img_brick[0],plevel->theme,"brick0.png", IGNORE_ALPHA); + level_load_image(&img_brick[1],plevel->theme,"brick1.png", IGNORE_ALPHA); - load_level_image(&img_solid[0],plevel->theme,"solid0.png", USE_ALPHA); - load_level_image(&img_solid[1],plevel->theme,"solid1.png", USE_ALPHA); - load_level_image(&img_solid[2],plevel->theme,"solid2.png", USE_ALPHA); - load_level_image(&img_solid[3],plevel->theme,"solid3.png", USE_ALPHA); + level_load_image(&img_solid[0],plevel->theme,"solid0.png", USE_ALPHA); + level_load_image(&img_solid[1],plevel->theme,"solid1.png", USE_ALPHA); + level_load_image(&img_solid[2],plevel->theme,"solid2.png", USE_ALPHA); + level_load_image(&img_solid[3],plevel->theme,"solid3.png", USE_ALPHA); - load_level_image(&img_bkgd_tile[0][0],plevel->theme,"bkgd-00.png", USE_ALPHA); - load_level_image(&img_bkgd_tile[0][1],plevel->theme,"bkgd-01.png", USE_ALPHA); - load_level_image(&img_bkgd_tile[0][2],plevel->theme,"bkgd-02.png", USE_ALPHA); - load_level_image(&img_bkgd_tile[0][3],plevel->theme,"bkgd-03.png", USE_ALPHA); + level_load_image(&img_bkgd_tile[0][0],plevel->theme,"bkgd-00.png", USE_ALPHA); + level_load_image(&img_bkgd_tile[0][1],plevel->theme,"bkgd-01.png", USE_ALPHA); + level_load_image(&img_bkgd_tile[0][2],plevel->theme,"bkgd-02.png", USE_ALPHA); + level_load_image(&img_bkgd_tile[0][3],plevel->theme,"bkgd-03.png", USE_ALPHA); - load_level_image(&img_bkgd_tile[1][0],plevel->theme,"bkgd-10.png", USE_ALPHA); - load_level_image(&img_bkgd_tile[1][1],plevel->theme,"bkgd-11.png", USE_ALPHA); - load_level_image(&img_bkgd_tile[1][2],plevel->theme,"bkgd-12.png", USE_ALPHA); - load_level_image(&img_bkgd_tile[1][3],plevel->theme,"bkgd-13.png", USE_ALPHA); + level_load_image(&img_bkgd_tile[1][0],plevel->theme,"bkgd-10.png", USE_ALPHA); + level_load_image(&img_bkgd_tile[1][1],plevel->theme,"bkgd-11.png", USE_ALPHA); + level_load_image(&img_bkgd_tile[1][2],plevel->theme,"bkgd-12.png", USE_ALPHA); + level_load_image(&img_bkgd_tile[1][3],plevel->theme,"bkgd-13.png", USE_ALPHA); if(strcmp(plevel->bkgd_image,"") != 0) { @@ -208,13 +296,12 @@ void loadlevelgfx(st_level *plevel) if(!faccessible(fname)) snprintf(fname, 1024, "%s/images/background/%s", DATA_PREFIX, plevel->bkgd_image); texture_load(&img_bkgd, fname, IGNORE_ALPHA); - printf("%s",fname); } } /* Free graphics data for this level: */ -void unloadlevelgfx(void) +void level_free_gfx(void) { int i; @@ -233,7 +320,7 @@ void unloadlevelgfx(void) /* Load a level-specific graphic... */ -void load_level_image(texture_type* ptexture, char* theme, char * file, int use_alpha) +void level_load_image(texture_type* ptexture, char* theme, char * file, int use_alpha) { char fname[1024]; @@ -257,3 +344,35 @@ void level_change(st_level* plevel, float x, float y, unsigned char c) plevel->tiles[yy][xx] = c; } +/* Free music data for this level: */ + +void level_free_song(void) +{ + free_music(level_song); + free_music(level_song_fast); +} + +/* Load music: */ + +void level_load_song(st_level* plevel) +{ + + char * song_path; + char * song_subtitle; + + song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + + strlen(plevel->song_title) + 8)); + sprintf(song_path, "%s/music/%s", DATA_PREFIX, plevel->song_title); + level_song = load_song(song_path); + free(song_path); + + + song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + + strlen(plevel->song_title) + 8 + 5)); + song_subtitle = strdup(plevel->song_title); + strcpy(strstr(song_subtitle, "."), "\0"); + sprintf(song_path, "%s/music/%s-fast%s", DATA_PREFIX, song_subtitle, strstr(plevel->song_title, ".")); + level_song_fast = load_song(song_path); + free(song_subtitle); + free(song_path); +} diff --git a/src/level.h b/src/level.h index a21a0b28d..ffadfa5b7 100644 --- a/src/level.h +++ b/src/level.h @@ -15,6 +15,21 @@ #include "texture.h" +/* This type holds meta-information about a level-subset. */ +/* It could be extended to handle manipulation of subsets. */ +typedef struct st_subset + { + char *name; + char *title; + char *description; + texture_type image; + int levels; + } st_subset; + +void subset_init(st_subset* st_subset); +void subset_load(st_subset* st_subset, char *subset); +void subset_free(st_subset* st_subset); + #define LEVEL_NAME_MAX 20 typedef struct st_level /*It is easier to read the sources IMHO, if we don't write something like int a,b,c; */ @@ -30,15 +45,17 @@ typedef struct st_level /*It is easier to read the sources IMHO, if we don't wri int bkgd_blue; int width; } st_level; - -texture_type img_bkgd, img_bkgd_tile[2][4], img_solid[4], img_brick[2]; -void loadlevel(st_level* plevel, char * subset, int level); -void savelevel(st_level* plevel, char * subset, int level); -void unloadlevel(st_level* plevel); -void loadlevelgfx(st_level* plevel); -void unloadlevelgfx(); -void load_level_image(texture_type* ptexture, char* theme, char * file, int use_alpha); +extern texture_type img_bkgd, img_bkgd_tile[2][4], img_solid[4], img_brick[2]; + +int level_load(st_level* plevel, char * subset, int level); +void level_save(st_level* plevel, char * subset, int level); +void level_free(st_level* plevel); +void level_load_gfx(st_level* plevel); +void level_free_gfx(); +void level_load_image(texture_type* ptexture, char* theme, char * file, int use_alpha); void level_change(st_level* plevel, float x, float y, unsigned char c); +void level_load_song(st_level* plevel); +void level_free_song(void); #endif /*SUPERTUX_LEVEL_H*/ diff --git a/src/leveleditor.c b/src/leveleditor.c index 7f014b11c..4a7a3826d 100644 --- a/src/leveleditor.c +++ b/src/leveleditor.c @@ -1,4 +1,3 @@ - /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * @@ -29,8 +28,8 @@ #include "menu.h" #include "level.h" #include "badguy.h" -#include "gameloop.h" #include "scene.h" +#include "button.h" /* definitions to aid development */ #define DONE_LEVELEDITOR 1 @@ -40,11 +39,11 @@ /* definitions that affect gameplay */ #define KEY_CURSOR_SPEED 32 #define KEY_CURSOR_FASTSPEED 64 -// when pagedown/up pressed speed: +/* when pagedown/up pressed speed:*/ #define PAGE_CURSOR_SPEED 13*32 #define CURSOR_LEFT_MARGIN 96 -#define CURSOR_RIGHT_MARGIN 512 +#define CURSOR_RIGHT_MARGIN 600 /* right_margin should noticed that the cursor is 32 pixels, so it should subtract that value */ @@ -52,52 +51,38 @@ #define MOUSE_RIGHT_MARGIN 608 #define MOUSE_POS_SPEED 32 -/* Level Intro: */ -/* - clearscreen(0, 0, 0); - - sprintf(str, "Editing Level %s", levelfilename); - drawcenteredtext(str, 200, letters_red, NO_UPDATE, 1); - - sprintf(str, "%s", levelname); - drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1); - - flipscreen(); - - SDL_Delay(1000); -*/ - /* gameloop funcs declerations */ void loadshared(void); void unloadshared(void); /* own declerations */ - -void savelevel(); +/* crutial ones (main loop) */ +int le_init(); +void le_quit(); +void le_drawlevel(); +void le_checkevents(); void le_change(float x, float y, unsigned char c); -void showhelp(); +void le_showhelp(); void le_set_defaults(void); void le_activate_bad_guys(void); -/* global variables (based on the gameloop ones) */ - -int level; -st_level current_level; -char level_subset[100]; -int show_grid; - -int frame; -texture_type selection; -int last_time, now_time; - -void le_quit(void) -{ - unloadlevelgfx(); - unloadshared(); - arrays_free(); - texture_free(&selection); -} +/* leveleditor internals */ +static int le_level_changed; /* if changes, ask for saving, when quiting*/ +static int pos_x, cursor_x, cursor_y, cursor_tile, fire; +static int le_level; +static st_level le_current_level; +static st_subset le_level_subset; +static int le_show_grid; +static int le_frame; +static texture_type le_selection; +static int done; +static char le_current_tile; +static int le_mouse_pressed; +static button_type le_test_level_bt; +static button_type le_next_level_bt; +static button_type le_previous_level_bt; +static button_type le_rubber_bt; void le_activate_bad_guys(void) { @@ -109,17 +94,17 @@ void le_activate_bad_guys(void) the badguys from tiles */ for (y = 0; y < 15; ++y) - 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'); + for (x = 0; x < le_current_level.width; ++x) + if (le_current_level.tiles[y][x] >= '0' && le_current_level.tiles[y][x] <= '9') + add_bad_guy(x * 32, y * 32, le_current_level.tiles[y][x] - '0'); } void le_set_defaults() { /* Set defaults: */ - if(current_level.time_left == 0) - current_level.time_left = 255; + if(le_current_level.time_left == 0) + le_current_level.time_left = 255; } /* FIXME: Needs to be implemented. It should ask the user for the level(file)name and then let him create a new level based on this. */ @@ -130,422 +115,516 @@ void newlevel() void selectlevel() {} -int leveleditor() +int leveleditor(int levelnb) { - char str[LEVEL_NAME_MAX]; - int done; - int x, y, i; /* for cicles */ - int pos_x, cursor_x, cursor_y, cursor_tile, fire; - SDL_Event event; - SDLKey key; - SDLMod keymod; + int last_time, now_time; - strcpy(level_subset,"default"); - show_grid = NO; - - level = 1; + le_level = levelnb; + if(le_init() != 0) + return 1; - initmenu(); - menumenu = MENU_LEVELEDITOR; - show_menu = YES; + while(1) + { + last_time = SDL_GetTicks(); + le_frame++; - frame = 0; /* support for frames in some tiles, like waves and bad guys */ + le_checkevents(); - arrays_init(); - - loadshared(); - set_defaults(); + if(cursor_x < pos_x + CURSOR_LEFT_MARGIN) + pos_x = cursor_x - CURSOR_LEFT_MARGIN; - loadlevel(¤t_level,"default",level); - loadlevelgfx(¤t_level); + if(cursor_x > pos_x + CURSOR_RIGHT_MARGIN) + pos_x = cursor_x - CURSOR_RIGHT_MARGIN; - le_activate_bad_guys(); - le_set_defaults(); + /* make sure we respect the borders */ + if(cursor_x < 0) + cursor_x = 0; + if(cursor_x > (le_current_level.width*32) - 32) + cursor_x = (le_current_level.width*32) - 32; - texture_load(&selection,DATA_PREFIX "/images/leveleditor/select.png", USE_ALPHA); + if(pos_x < 0) + pos_x = 0; + if(pos_x > (le_current_level.width * 32) - screen->w + 32) + pos_x = (le_current_level.width * 32) - screen->w + 32; + + /* draw the level */ + le_drawlevel(); + + if(show_menu) + { + menu_process_current(); + if(current_menu == &leveleditor_menu) + { + switch (menu_check(&leveleditor_menu)) + { + case 0: + show_menu = NO; + break; + case 4: + done = DONE_LEVELEDITOR; + break; + } + } + } + + if(done) + { + le_quit(); + return 0; + } + + if(done == DONE_QUIT) + { + le_quit(); + return 1; + } + + SDL_Delay(25); + now_time = SDL_GetTicks(); + if (now_time < last_time + FPS) + SDL_Delay(last_time + FPS - now_time); /* delay some time */ + + flipscreen(); + } + + return done; +} + +int le_init() +{ + subset_load(&le_level_subset,"default"); + le_show_grid = YES; done = 0; - pos_x = 0; - cursor_x = 3*32; - cursor_y = 2*32; - fire = DOWN; + menu_reset(); + menu_set_current(&leveleditor_menu); + le_frame = 0; /* support for frames in some tiles, like waves and bad guys */ - SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + arrays_init(); + loadshared(); + le_set_defaults(); - while(1) + le_level_changed = NO; + if(level_load(&le_current_level, le_level_subset.name, le_level) != 0) { - clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue); + le_quit(); + return 1; + } + if(le_current_level.time_left == 0) + le_current_level.time_left = 255; - last_time = SDL_GetTicks(); - frame++; + level_load_gfx(&le_current_level); - keymod = SDL_GetModState(); + le_current_tile = '.'; + le_mouse_pressed = NO; + le_activate_bad_guys(); - while(SDL_PollEvent(&event)) - { - // testing SDL_KEYDOWN, SDL_KEYUP and SDL_QUIT events - switch(event.type) - { - case SDL_KEYDOWN: // key pressed - key = event.key.keysym.sym; - if(show_menu) - { - menu_event(&event.key.keysym); - break; - } - switch(key) - { - case SDLK_LEFT: - if(fire == DOWN) - cursor_x -= KEY_CURSOR_SPEED; - else - cursor_x -= KEY_CURSOR_FASTSPEED; - - if(cursor_x < 0) - cursor_x = 0; - break; - case SDLK_RIGHT: - if(fire == DOWN) - cursor_x += KEY_CURSOR_SPEED; - else - cursor_x += KEY_CURSOR_FASTSPEED; - - if(cursor_x > (current_level.width*32) - 32) - cursor_x = (current_level.width*32) - 32; - break; - case SDLK_UP: - if(fire == DOWN) - cursor_y -= KEY_CURSOR_SPEED; - else - cursor_y -= KEY_CURSOR_FASTSPEED; - - if(cursor_y < 0) - cursor_y = 0; - break; - case SDLK_DOWN: - if(fire == DOWN) - cursor_y += KEY_CURSOR_SPEED; - else - cursor_y += KEY_CURSOR_FASTSPEED; - - if(cursor_y > screen->h-32) - cursor_y = screen->h-32; - break; - case SDLK_LCTRL: - fire =UP; - break; - case SDLK_F1: - showhelp(); - break; - case SDLK_HOME: - cursor_x = 0; - break; - case SDLK_END: - cursor_x = (current_level.width * 32) - 32; - break; - case SDLK_PAGEUP: - cursor_x -= PAGE_CURSOR_SPEED; + texture_load(&le_selection,DATA_PREFIX "/images/leveleditor/select.png", USE_ALPHA); + button_load(&le_test_level_bt,"/images/icons/test-level.png","Test Level","Press this button to test the level that is currently being edited.",150,screen->h - 64); + button_load(&le_next_level_bt,"/images/icons/up.png","Test Level","Press this button to test the level that is currently being edited.",screen->w-32,0); + button_load(&le_previous_level_bt,"/images/icons/down.png","Test Level","Press this button to test the level that is currently being edited.",screen->w-32,16); + button_load(&le_rubber_bt,"/images/icons/rubber.png","Test Level","Press this button to test the level that is currently being edited.",screen->w-32,32); + + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - if(cursor_x < 0) - cursor_x = 0; - break; - case SDLK_PAGEDOWN: - cursor_x += PAGE_CURSOR_SPEED; + return 0; +} - if(cursor_x > (current_level.width*32) - 32) - cursor_x = (current_level.width*32) - 32; - break; - case SDLK_F9: - if(!show_grid) - show_grid = YES; - else - show_grid = NO; - break; - case SDLK_PERIOD: - le_change(cursor_x, cursor_y, '.'); - break; - case SDLK_a: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'A'); - else - le_change(cursor_x, cursor_y, 'a'); - break; - case SDLK_b: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'B'); - break; - case SDLK_c: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'C'); - else - le_change(cursor_x, cursor_y, 'c'); - break; - case SDLK_d: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'D'); - else - le_change(cursor_x, cursor_y, 'd'); - break; - case SDLK_e: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'E'); - else - le_change(cursor_x, cursor_y, 'e'); - break; - case SDLK_f: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'F'); - else - le_change(cursor_x, cursor_y, 'f'); - break; - case SDLK_g: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'G'); - else - le_change(cursor_x, cursor_y, 'g'); - break; - case SDLK_h: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'H'); - else - le_change(cursor_x, cursor_y, 'h'); - break; - case SDLK_i: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'I'); - else - le_change(cursor_x, cursor_y, 'i'); - break; - case SDLK_j: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'J'); - else - le_change(cursor_x, cursor_y, 'j'); - break; - case SDLK_x: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'X'); - else - le_change(cursor_x, cursor_y, 'x'); - break; - case SDLK_y: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, 'Y'); - else - le_change(cursor_x, cursor_y, 'y'); - break; - case SDLK_LEFTBRACKET: - le_change(cursor_x, cursor_y, '['); - break; - case SDLK_RIGHTBRACKET: - le_change(cursor_x, cursor_y, ']'); - break; - case SDLK_HASH: - case SDLK_3: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, '#'); - break; - case SDLK_DOLLAR: - case SDLK_4: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, '$'); - break; - case SDLK_BACKSLASH: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, '|'); - else - le_change(cursor_x, cursor_y, '\\'); - break; - case SDLK_CARET: - le_change(cursor_x, cursor_y, '^'); - break; - case SDLK_AMPERSAND: - case SDLK_6: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, '&'); - break; - case SDLK_EQUALS: - case SDLK_0: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, '='); - else /* let's add a bad guy */ - le_change(cursor_x, cursor_y, '0'); - - add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_BSOD); - break; - case SDLK_1: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, '!'); - else /* let's add a bad guy */ - le_change(cursor_x, cursor_y, '1'); +void le_quit(void) +{ + /*if(level_changed == YES) + if(askforsaving() == CANCEL) + return;*/ //FIXME - add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_LAPTOP); - break; - case SDLK_2: - le_change(cursor_x, cursor_y, '2'); - add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_MONEY); - break; - case SDLK_PLUS: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, '*'); - break; - default: - break; - } - break; - case SDL_KEYUP: // key released - switch(event.key.keysym.sym) - { - case SDLK_LCTRL: - fire = DOWN; - break; - case SDLK_ESCAPE: - if(!show_menu) - show_menu = YES; - else - show_menu = NO; - break; - default: - break; - } - break; - /* case SDL_MOUSEBUTTONDOWN: - if(event.button.button == SDL_BUTTON_LEFT) - { - This will draw current tile in the cursor position, when the interface is done. - } - break;*/ - case SDL_MOUSEMOTION: - if(!show_menu) - { - x = event.motion.x; - y = event.motion.y; + button_free(&le_test_level_bt); + level_free_gfx(); + level_free(&le_current_level); + unloadshared(); + arrays_free(); + texture_free(&le_selection); +} - cursor_x = ((int)(pos_x + x) / 32) * 32; - cursor_y = ((int) y / 32) * 32; - } - break; - case SDL_QUIT: // window closed - done = DONE_QUIT; - break; - default: - break; - } - } +void le_drawlevel() +{ + int y,x,i,s; + static char str[LEVEL_NAME_MAX]; - /* mouse movements */ - /* x = event.motion.x; - if(x < MOUSE_LEFT_MARGIN) - pos_x -= MOUSE_POS_SPEED; - else if(x > MOUSE_RIGHT_MARGIN) - pos_x += MOUSE_POS_SPEED;*/ + /* Draw the real background */ + if(le_current_level.bkgd_image[0] != '\0') + { + s = pos_x / 30; + texture_draw_part(&img_bkgd,s,0,0,0,img_bkgd.w - s - 32, img_bkgd.h, NO_UPDATE); + texture_draw_part(&img_bkgd,0,0,screen->w - s - 32 ,0,s,img_bkgd.h, NO_UPDATE); + } + else + { + clearscreen(le_current_level.bkgd_red, le_current_level.bkgd_green, le_current_level.bkgd_blue); + } + /* clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue); */ - if(cursor_x < pos_x + CURSOR_LEFT_MARGIN) - pos_x = cursor_x - CURSOR_LEFT_MARGIN; + for (y = 0; y < 15; ++y) + for (x = 0; x < 19; ++x) + { + drawshape(x * 32, y * 32, le_current_level.tiles[y][x + (pos_x / 32)]); + } + + /* draw whats inside stuff when cursor is selecting those */ + cursor_tile = le_current_level.tiles[cursor_y/32][cursor_x/32]; + switch(cursor_tile) + { + case 'B': + texture_draw(&img_mints, cursor_x - pos_x, cursor_y, NO_UPDATE); + break; + case '!': + texture_draw(&img_golden_herring, cursor_x - pos_x, cursor_y, NO_UPDATE); + break; + case 'x': + case 'y': + case 'A': + texture_draw(&img_distro[(le_frame / 5) % 4], cursor_x - pos_x, cursor_y, NO_UPDATE); + break; + default: + break; + } - if(cursor_x > pos_x + CURSOR_RIGHT_MARGIN) - pos_x = cursor_x - CURSOR_RIGHT_MARGIN; + /* Draw the Bad guys: */ + for (i = 0; i < num_bad_guys; ++i) + { + if(bad_guys[i].base.alive == NO) + continue; + /* to support frames: img_bsod_left[(frame / 5) % 4] */ + if(bad_guys[i].kind == BAD_BSOD) + texture_draw(&img_bsod_left[(le_frame / 5) % 4], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE); + else if(bad_guys[i].kind == BAD_LAPTOP) + texture_draw(&img_laptop_left[(le_frame / 5) % 3], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE); + else if (bad_guys[i].kind == BAD_MONEY) + texture_draw(&img_money_left[(le_frame / 5) % 2], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE); + } - if(pos_x < 0) - pos_x = 0; - if(pos_x > (current_level.width * 32) - screen->w) - pos_x = (current_level.width * 32) - screen->w; - - for (y = 0; y < 15; ++y) - for (x = 0; x < 21; ++x) - drawshape(x * 32, y * 32, current_level.tiles[y][x + (pos_x / 32)]); - -/* draw whats inside stuff when cursor is selecting those */ -cursor_tile = current_level.tiles[cursor_y/32][cursor_x/32]; -switch(cursor_tile) - { - case 'B': - texture_draw(&img_mints, cursor_x - pos_x, cursor_y, NO_UPDATE); - break; - case '!': - texture_draw(&img_golden_herring, cursor_x - pos_x, cursor_y, NO_UPDATE); - break; - case 'x': - case 'y': - case 'A': - texture_draw(&img_distro[(frame / 5) % 4], cursor_x - pos_x, cursor_y, NO_UPDATE); - break; - default: - break; - } - - /* Draw the Bad guys: */ - for (i = 0; i < num_bad_guys; ++i) - { - if(bad_guys[i].base.alive == NO) - continue; - /* to support frames: img_bsod_left[(frame / 5) % 4] */ - if(bad_guys[i].kind == BAD_BSOD) - texture_draw(&img_bsod_left[(frame / 5) % 4], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE); - else if(bad_guys[i].kind == BAD_LAPTOP) - texture_draw(&img_laptop_left[(frame / 5) % 3], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE); - else if (bad_guys[i].kind == BAD_MONEY) - texture_draw(&img_money_left[(frame / 5) % 2], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE); - } + /* draw a grid (if selected) */ + if(le_show_grid) + { + for(x = 0; x < 19; x++) + fillrect(x*32, 0, 1, screen->h, 225, 225, 225,255); + for(y = 0; y < 15; y++) + fillrect(0, y*32, screen->w - 32, 1, 225, 225, 225,255); + } + + fillrect(screen->w - 32, 0, 32, screen->h, 50, 50, 50,255); + drawshape(19 * 32, 14 * 32, le_current_tile); -/* draw a grid (if selected) */ -if(show_grid) - { - for(x = 0; x < 21; x++) - fillrect(x*32, 0, 1, 480, 225, 225, 225); - for(y = 0; y < 15; y++) - fillrect(0, y*32, 640, 1, 225, 225, 225); - } + button_draw(&le_test_level_bt); + button_draw(&le_next_level_bt); + button_draw(&le_previous_level_bt); + button_draw(&le_rubber_bt); + + texture_draw(&le_selection, ((int)(cursor_x - pos_x)/32)*32, cursor_y, NO_UPDATE); - texture_draw(&selection, ((int)(cursor_x - pos_x)/32)*32, cursor_y, NO_UPDATE); + sprintf(str, "%d", le_current_level.time_left); + text_draw(&white_text, "TIME", 324, 0, 1, NO_UPDATE); + text_draw(&gold_text, str, 404, 0, 1, NO_UPDATE); - sprintf(str, "%d", current_level.time_left); - text_draw(&blue_text, "TIME", 324, 0, 1, NO_UPDATE); - text_draw(&gold_text, str, 404, 0, 1, NO_UPDATE); + text_draw(&white_text, "NAME", 0, 0, 1, NO_UPDATE); + text_draw(&gold_text, le_current_level.name, 80, 0, 1, NO_UPDATE); - sprintf(str, "%s", current_level.name); - text_draw(&blue_text, "NAME", 0, 0, 1, NO_UPDATE); - text_draw(&gold_text, str, 80, 0, 1, NO_UPDATE); + sprintf(str, "%d/%d", le_level,le_level_subset.levels); + text_draw(&white_text, "NUMB", 0, 20, 1, NO_UPDATE); + text_draw(&gold_text, str, 80, 20, 1, NO_UPDATE); - text_draw(&blue_text, "F1 for Help", 10, 430, 1, NO_UPDATE); + text_draw(&white_small_text, "F1 for Help", 10, 430, 1, NO_UPDATE); + text_draw(&white_small_text, "F2 for Testing", 150, 430, 1, NO_UPDATE); +} - if(show_menu) - { - done = drawmenu(); - if(done) - { - le_quit(); - return 0; - } - } - if(done == DONE_QUIT) +void le_checkevents() +{ + SDL_Event event; + SDLKey key; + SDLMod keymod; + int x,y; + + keymod = SDL_GetModState(); + + while(SDL_PollEvent(&event)) + { + /* testing SDL_KEYDOWN, SDL_KEYUP and SDL_QUIT events*/ + switch(event.type) { - le_quit(); - return 1; - } + case SDL_KEYDOWN: // key pressed + key = event.key.keysym.sym; + if(show_menu) + { + menu_event(&event.key.keysym); + break; + } + switch(key) + { + case SDLK_ESCAPE: + if(!show_menu) + show_menu = YES; + else + show_menu = NO; + break; + case SDLK_LEFT: + if(fire == DOWN) + cursor_x -= KEY_CURSOR_SPEED; + else + cursor_x -= KEY_CURSOR_FASTSPEED; + break; + case SDLK_RIGHT: + if(fire == DOWN) + cursor_x += KEY_CURSOR_SPEED; + else + cursor_x += KEY_CURSOR_FASTSPEED; + break; + case SDLK_UP: + if(fire == DOWN) + cursor_y -= KEY_CURSOR_SPEED; + else + cursor_y -= KEY_CURSOR_FASTSPEED; + + if(cursor_y < 0) + cursor_y = 0; + break; + case SDLK_DOWN: + if(fire == DOWN) + cursor_y += KEY_CURSOR_SPEED; + else + cursor_y += KEY_CURSOR_FASTSPEED; + + if(cursor_y > screen->h-32) + cursor_y = screen->h-32; + break; + case SDLK_LCTRL: + fire =UP; + break; + case SDLK_F1: + le_showhelp(); + break; + case SDLK_F2: + level_save(&le_current_level,"test",le_level); + gameloop("test",le_level, ST_GL_TEST); + menu_set_current(&leveleditor_menu); + arrays_init(); + level_load_gfx(&le_current_level); + loadshared(); + le_activate_bad_guys(); + break; + case SDLK_HOME: + cursor_x = 0; + break; + case SDLK_END: + cursor_x = (le_current_level.width * 32) - 32; + break; + case SDLK_PAGEUP: + cursor_x -= PAGE_CURSOR_SPEED; + break; + case SDLK_PAGEDOWN: + cursor_x += PAGE_CURSOR_SPEED; + break; + case SDLK_F9: + le_show_grid = !le_show_grid; + break; + case SDLK_PERIOD: + le_change(cursor_x, cursor_y, '.'); + break; + case SDLK_a: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'A'); + else + le_change(cursor_x, cursor_y, 'a'); + break; + case SDLK_b: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'B'); + break; + case SDLK_c: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'C'); + else + le_change(cursor_x, cursor_y, 'c'); + break; + case SDLK_d: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'D'); + else + le_change(cursor_x, cursor_y, 'd'); + break; + case SDLK_e: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'E'); + else + le_change(cursor_x, cursor_y, 'e'); + break; + case SDLK_f: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'F'); + else + le_change(cursor_x, cursor_y, 'f'); + break; + case SDLK_g: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'G'); + else + le_change(cursor_x, cursor_y, 'g'); + break; + case SDLK_h: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'H'); + else + le_change(cursor_x, cursor_y, 'h'); + break; + case SDLK_i: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'I'); + else + le_change(cursor_x, cursor_y, 'i'); + break; + case SDLK_j: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'J'); + else + le_change(cursor_x, cursor_y, 'j'); + break; + case SDLK_x: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'X'); + else + le_change(cursor_x, cursor_y, 'x'); + break; + case SDLK_y: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, 'Y'); + else + le_change(cursor_x, cursor_y, 'y'); + break; + case SDLK_LEFTBRACKET: + le_change(cursor_x, cursor_y, '['); + break; + case SDLK_RIGHTBRACKET: + le_change(cursor_x, cursor_y, ']'); + break; + case SDLK_HASH: + case SDLK_3: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, '#'); + break; + case SDLK_DOLLAR: + case SDLK_4: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, '$'); + break; + case SDLK_BACKSLASH: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, '|'); + else + le_change(cursor_x, cursor_y, '\\'); + break; + case SDLK_CARET: + le_change(cursor_x, cursor_y, '^'); + break; + case SDLK_AMPERSAND: + case SDLK_6: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, '&'); + break; + case SDLK_EQUALS: + case SDLK_0: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, '='); + else /* let's add a bad guy */ + le_change(cursor_x, cursor_y, '0'); + + add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_BSOD); + break; + case SDLK_1: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, '!'); + else /* let's add a bad guy */ + le_change(cursor_x, cursor_y, '1'); - SDL_Delay(50); - now_time = SDL_GetTicks(); - if (now_time < last_time + FPS) - SDL_Delay(last_time + FPS - now_time); /* delay some time */ + add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_LAPTOP); + break; + case SDLK_2: + le_change(cursor_x, cursor_y, '2'); - flipscreen(); + add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_MONEY); + break; + case SDLK_PLUS: + if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) + le_change(cursor_x, cursor_y, '*'); + break; + default: + break; + } + break; + case SDL_KEYUP: // key released + switch(event.key.keysym.sym) + { + case SDLK_LCTRL: + fire = DOWN; + break; + default: + break; + } + break; + case SDL_MOUSEBUTTONDOWN: + if(event.button.button == SDL_BUTTON_LEFT) + { + le_mouse_pressed = YES; + } + break; + case SDL_MOUSEBUTTONUP: + if(event.button.button == SDL_BUTTON_LEFT) + { + le_mouse_pressed = NO; + } + break; + case SDL_MOUSEMOTION: + if(!show_menu) + { + x = event.motion.x; + y = event.motion.y; + + cursor_x = ((int)(pos_x + x) / 32) * 32; + cursor_y = ((int) y / 32) * 32; + } + break; + case SDL_QUIT: // window closed + done = DONE_QUIT; + break; + default: + break; + } + } + + if(le_mouse_pressed) + { + le_change(cursor_x, cursor_y, le_current_tile); + if(button_pressed(&le_test_level_bt,x,y)) + { + level_save(&le_current_level,"test",le_level); + gameloop("test",le_level, ST_GL_TEST); + menu_set_current(&leveleditor_menu); + arrays_init(); + level_load_gfx(&le_current_level); + loadshared(); + le_activate_bad_guys(); + } } - return done; } void le_change(float x, float y, unsigned char c) { -int i; -int xx, yy; + int i; + int xx, yy; - level_change(¤t_level,x,y,c); + level_change(&le_current_level,x,y,c); - yy = (y / 32); - xx = (x / 32); + yy = ((int)y / 32); + xx = ((int)x / 32); /* if there is a bad guy over there, remove it */ for(i = 0; i < num_bad_guys; ++i) @@ -554,7 +633,7 @@ int xx, yy; bad_guys[i].base.alive = NO; } -void showhelp() +void le_showhelp() { SDL_Event event; int i, done; @@ -583,11 +662,11 @@ void showhelp() "Esc - Menu"}; - text_drawf(&red_text, "- Help -", 0, 30, A_HMIDDLE, A_TOP, 2, NO_UPDATE); + text_drawf(&blue_text, "- Help -", 0, 30, A_HMIDDLE, A_TOP, 2, NO_UPDATE); text_draw(&gold_text, "Keys:", 80, 60, 1, NO_UPDATE); - + for(i = 0; i < sizeof(text)/sizeof(char *); i++) - text_draw(&blue_text, text[i], 40, 90+(i*16), 1, NO_UPDATE); + text_draw(&white_text, text[i], 40, 90+(i*16), 1, NO_UPDATE); text_drawf(&gold_text, "Press Any Key to Continue", 0, 460, A_HMIDDLE, A_TOP, 1, NO_UPDATE); diff --git a/src/leveleditor.h b/src/leveleditor.h index a22be9af1..e083a6431 100644 --- a/src/leveleditor.h +++ b/src/leveleditor.h @@ -1,5 +1,23 @@ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ -int level_editor_started; -int leveleditor(); +/* December 28, 2003 - February 1st, 2004 */ + +/* leveleditor.h - A built-in level editor for SuperTux + by Ricardo Cruz */ + +int leveleditor(int levelnb); void newlevel(void); void selectlevel(void); +void le_savelevel(); +void editlevel(void); +void testlevel(void); +int le_init(void); +void le_checkevents(void); + diff --git a/src/menu.c b/src/menu.c index d86a880a6..e398cfdec 100644 --- a/src/menu.c +++ b/src/menu.c @@ -16,6 +16,8 @@ #include #endif +#include +#include #include #include "defines.h" @@ -26,512 +28,331 @@ #include "sound.h" #include "scene.h" #include "leveleditor.h" -#include "gameloop.h" #include "timer.h" #include "high_scores.h" -/* Set defaults */ -void initmenu(void) -{ - menu_change = NO; - show_menu = NO; - menuitem = 0; - menumenu = 0; - menuaction = -1; +/* (global) menu variables */ +int menuaction; +int show_menu; +int menu_change; +texture_type checkbox, checkbox_checked; - delete_character = 0; - strcpy(input_string, ""); -} +menu_type main_menu, game_menu, options_menu, leveleditor_menu, highscore_menu; +menu_type* current_menu, * last_menu; + +/* input implementation variables */ +int delete_character; +char mn_input_char; -/* ---- Menu Options - Item Sound On/off ----*/ -void menu_option_sound() +/* Set the current menu */ +void menu_set_current(menu_type* pmenu) { - if (audio_device == YES) + if(pmenu != current_menu) { - if(menuitem == 1) - { - if(use_sound == YES) - { - text_drawf(&red_text, "Sound ON", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - } - else - { - text_drawf(&red_text, "Sound OFF", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - } - - if(menuaction == MN_HIT) - { /* Disable/Enable sound */ - if(use_sound == YES) - { - use_sound = NO; - } - else - { - use_sound = YES; - } - menu_change = YES; - } - } - else - { - if(use_sound == YES) - text_drawf(&blue_text, "Sound ON", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - else - text_drawf(&blue_text, "Sound OFF", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - } + menu_change = YES; + last_menu = current_menu; + current_menu = pmenu; } +} + +/* Return a pointer to a new menu item */ +menu_item_type* menu_item_create(int kind, char *text, int init_toggle, void* target_menu) +{ + menu_item_type *pnew_item = (menu_item_type*) malloc(sizeof(menu_item_type)); + pnew_item->kind = kind; + pnew_item->text = (char*) malloc(sizeof(char) * (strlen(text) + 1)); + strcpy(pnew_item->text,text); + if(kind == MN_TOGGLE) + pnew_item->toggled = init_toggle; else - { /* if audio_device != YES */ - /* let the user move over the deactivated option */ - if (menuitem == 1) - { - text_drawf(&red_text, "Sound OFF", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - } - else + pnew_item->toggled = NO; + pnew_item->target_menu = target_menu; + pnew_item->input = NULL; + return pnew_item; +} + +/* Free a menu and all its items */ +void menu_free(menu_type* pmenu) +{ + int i; + if(pmenu->num_items != 0 && pmenu->item != NULL) + { + for(i = 0; i < pmenu->num_items; ++i) { - text_drawf(&red_text, "Sound OFF", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); + free(pmenu->item[i].text); + free(pmenu->item[i].input); } + free(pmenu->item); } } +/* Initialize a menu */ +void menu_init(menu_type* pmenu) +{ + pmenu->num_items = 0; + pmenu->active_item = 0; + pmenu->item = NULL; +} + +/* Add an item to a menu */ +void menu_additem(menu_type* pmenu, menu_item_type* pmenu_item) +{ + ++pmenu->num_items; + pmenu->item = (menu_item_type*) realloc(pmenu->item, sizeof(menu_item_type) * pmenu->num_items); + memcpy(&pmenu->item[pmenu->num_items-1],pmenu_item,sizeof(menu_item_type)); +} -/* ---- Menu Options - Item Music On/off ----*/ -void menu_option_music() +/* Process actions done on the menu */ +void menu_action(menu_type* pmenu) { - if (audio_device == YES) + int i; + + if(pmenu->num_items != 0 && pmenu->item != NULL) { - if(menuitem == 2) + switch(menuaction) { - if(use_music == YES) + case MN_UP: + if(pmenu->active_item > 0) + --pmenu->active_item; + else + pmenu->active_item = pmenu->num_items-1; + break; + case MN_DOWN: + if(pmenu->active_item < pmenu->num_items-1) + ++pmenu->active_item; + else + pmenu->active_item = 0; + break; + case MN_HIT: + if(pmenu->item[pmenu->active_item].kind == MN_GOTO && pmenu->item[pmenu->active_item].target_menu != NULL) + menu_set_current((menu_type*)pmenu->item[pmenu->active_item].target_menu); + else if(pmenu->item[pmenu->active_item].kind == MN_TOGGLE) { - text_drawf(&red_text, "Music ON", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); + pmenu->item[pmenu->active_item].toggled = !pmenu->item[pmenu->active_item].toggled; + menu_change = YES; } - else + else if(pmenu->item[pmenu->active_item].kind == MN_ACTION || pmenu->item[pmenu->active_item].kind == MN_TEXTFIELD) { - text_drawf(&red_text, "Music OFF", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); + pmenu->item[pmenu->active_item].toggled = YES; } - if(menuaction == MN_HIT) - { /* Disable/Enable music */ - if(use_music == YES) - { /* In the menu no music is played, so we have to check only use_music */ - if(playing_music()) - halt_music(); - use_music = NO; - } - else + else if(pmenu->item[pmenu->active_item].kind == MN_BACK) + { + if(last_menu != NULL) + menu_set_current(last_menu); + } + break; + case MN_REMOVE: + if(pmenu->item[pmenu->active_item].kind == MN_TEXTFIELD) + { + if(pmenu->item[pmenu->active_item].input != NULL) { - use_music = YES; - if (!playing_music()) + i = strlen(pmenu->item[pmenu->active_item].input); + + while(delete_character > 0) /* remove charactes */ { - play_current_music(); + pmenu->item[pmenu->active_item].input[i-1] = '\0'; + delete_character--; } } - menu_change = YES; } - } /* if menuitem != 2 : print normal blue font */ - else - { - if(use_music == YES) + break; + case MN_INPUT: + if(pmenu->item[pmenu->active_item].kind == MN_TEXTFIELD) { - text_drawf(&blue_text, "Music ON", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - } - else - { - text_drawf(&blue_text, "Music OFF", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); + if(pmenu->item[pmenu->active_item].input != NULL) + { + i = strlen(pmenu->item[pmenu->active_item].input); + pmenu->item[pmenu->active_item].input = (char*) realloc(pmenu->item[pmenu->active_item].input,sizeof(char)*(i + 2)); + pmenu->item[pmenu->active_item].input[i] = mn_input_char; + pmenu->item[pmenu->active_item].input[i+1] = '\0'; + } + else + { + pmenu->item[pmenu->active_item].input = (char*) malloc(2*sizeof(char)); + pmenu->item[pmenu->active_item].input[0] = mn_input_char; + pmenu->item[pmenu->active_item].input[1] = '\0'; + } } + break; } } - else - { /* if audio_device != YES */ - /* let the user move over the deactivated option */ - if (menuitem == 2) - { - text_drawf(&red_text, "Music OFF", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - } - else - { - text_drawf(&black_text, "Music OFF", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - } - } + + menuaction = -1; + + if(pmenu->item[pmenu->active_item].kind == MN_DEACTIVE) + menu_action(pmenu); } -int menu_main(void) +/* Check, if the value of the active menu item has changed. */ +int menu_check(menu_type* pmenu) { - /* Does the menu item exist? If not, we reset to the most down item */ - if(menuitem > MENU_MAIN_ITEM_MAX) - menuitem =0; - else if(menuitem < 0) - menuitem = MENU_MAIN_ITEM_MAX; - - /*The menu looks different, when the game is started */ - if(menuitem == 0) - { - text_drawf(&red_text, "Start Game", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* we are ready to start the game, if this item got hit */ - { - game_started = 1; - show_menu = 0; - } - } - else - text_drawf(&blue_text, "Start Game", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - - if(menuitem == 1) - { - text_drawf(&red_text, "Options", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Switch to the 'Options' menu */ - { - menumenu = MENU_OPTIONS; - menu_change = YES; - } - } - else - text_drawf(&blue_text, "Options", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - - if(menuitem == 2) + if(pmenu->num_items != 0 && pmenu->item != NULL) { - text_drawf(&red_text, "Level editor", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Set variables, so that the level editor is executed */ + if((pmenu->item[pmenu->active_item].kind == MN_ACTION || pmenu->item[pmenu->active_item].kind == MN_TEXTFIELD) && pmenu->item[pmenu->active_item].toggled == YES) { - level_editor_started = YES; + pmenu->item[pmenu->active_item].toggled = NO; show_menu = 0; + return pmenu->active_item; } - } - else - text_drawf(&blue_text, "Level editor", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - - if(menuitem == 3) - { - text_drawf(&red_text, "Quit", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Quit a running game or the application */ + else if(pmenu->item[pmenu->active_item].kind == MN_TOGGLE) { - return 1; + return pmenu->active_item; } + else + return -1; } else - { - text_drawf(&blue_text, "Quit", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - } - - return 0; + return -1; } -int menu_game(void) +/* Draw the current menu. */ +void menu_draw(menu_type* pmenu) { - /* Does the menu item exist? If not, we reset to the most down item */ - if(menuitem > MENU_GAME_ITEM_MAX) - menuitem = 0; - else if(menuitem < 0) - menuitem = MENU_GAME_ITEM_MAX; - - /*The menu looks different, when the game is started */ - if(menuitem == 0) - { - text_drawf(&red_text, "Return To Game", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */ - { - show_menu = 0; - st_pause_ticks_stop(); - } - } - else - text_drawf(&blue_text, "Return To Game", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - - if(menuitem == 1) - { - text_drawf(&red_text, "Save Game", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */ - { - show_menu = 0; - savegame(); - } - } - else - text_drawf(&blue_text, "Save Game", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); + int i, y, menu_height, menu_width; - if(menuitem == 2) + /* The width of the menu has to be more than the width of the text with the most characters */ + menu_width = 0; + for(i = 0; i < pmenu->num_items; ++i) { - text_drawf(&red_text, "Load Game", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */ + y = strlen(pmenu->item[i].text) + (pmenu->item[i].input ? strlen(pmenu->item[i].input) : 0); + if( y > menu_width ) { - char *x = NULL; /* In C, you can do this... */ - - show_menu = 0; - loadgame(x); + menu_width = y; + if( pmenu->item[i].kind == MN_TOGGLE) + menu_width += 2; } } - else - text_drawf(&blue_text, "Load Game", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); + menu_width = menu_width * 16 + 48; + menu_height = (pmenu->num_items) * 24; + + /* Draw a transparent background */ + fillrect(screen->w/2 - menu_width/2,screen->h/2-(((pmenu->num_items)*24)/2),menu_width,menu_height,150,150,150,100); - if(menuitem == 3) + for(i = 0; i < pmenu->num_items; ++i) { - text_drawf(&red_text, "Options", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Switch to the 'Options' menu */ + if(pmenu->item[i].kind == MN_DEACTIVE) { - menumenu = MENU_OPTIONS; - menu_change = YES; + text_drawf(&black_text,pmenu->item[i].text,0,(i)*24 - menu_height/2 + 10,A_HMIDDLE, A_VMIDDLE,2,NO_UPDATE); } - } - else - text_drawf(&blue_text, "Options", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - - if(menuitem == 4) - { - text_drawf(&red_text, "Quit Game", 0, 320, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Quit a running game */ - return 1; - } - else - { - text_drawf(&blue_text, "Quit Game", 0, 320, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - } - - return 0; -} - -int menu_options(void) -{ - if(menuitem > MENU_OPTIONS_ITEM_MAX ) - menuitem = 0; - else if(menuitem < 0) - menuitem = MENU_OPTIONS_ITEM_MAX; - - if(menuitem == 0) - { - if(use_fullscreen) - text_drawf(&red_text, "Fullscreen ON", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - else - text_drawf(&red_text, "Fullscreen OFF", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Disable/Enable fullscreen */ + else if(pmenu->item[i].kind == MN_TEXTFIELD) { - if(use_fullscreen) - use_fullscreen = 0; - else - use_fullscreen = 1; - st_video_setup(); - menu_change = YES; - } - } - else - { - if(use_fullscreen) - text_drawf(&blue_text, "Fullscreen ON", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - else - text_drawf(&blue_text, "Fullscreen OFF", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - } - - /* handle menu sound on/off option */ - menu_option_sound(); - - /* handle menu music on/off option */ - menu_option_music(); - - if(menuitem == 3) - { - text_drawf(&red_text, "Back", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Go back to main menu. */ - { - if(game_started) - menumenu = MENU_GAME; + text_drawf(&gold_text,pmenu->item[i].input,(strlen(pmenu->item[i].text) * 16)/2,(i)*24 - menu_height/2 + 10,A_HMIDDLE, A_VMIDDLE,2,NO_UPDATE); + if(i == pmenu->active_item) + { + text_drawf(&blue_text,pmenu->item[i].text,-((strlen(pmenu->item[i].input) * 16)/2),(i)*24 - menu_height/2 + 10,A_HMIDDLE, A_VMIDDLE,3,NO_UPDATE); + } else - menumenu = MENU_MAIN; - menu_change = YES; + { + text_drawf(&white_text,pmenu->item[i].text,-((strlen(pmenu->item[i].input) * 16)/2),(i)*24 - menu_height/2 +10,A_HMIDDLE, A_VMIDDLE,2,NO_UPDATE); + } } - } - else - text_drawf(&blue_text, "Back", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - - return 0; -} - -/* Menu LevelEditor */ -int menu_leveleditor(void) -{ - if(menuitem > MENU_LEVELEDITOR_ITEM_MAX ) - menuitem = 0; - else if(menuitem < 0) - menuitem = MENU_LEVELEDITOR_ITEM_MAX; - - if(menuitem == 0) - { - text_drawf(&red_text, "Return To Level Editor", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */ - show_menu = 0; - } - else - text_drawf(&blue_text, "Return To Level Editor", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - - if(menuitem == 1) - { - text_drawf(&red_text, "New Level", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */ + else if(i == pmenu->active_item) { - show_menu = 0; - newlevel(); + text_drawf(&blue_text,pmenu->item[i].text,0,(i)*24 - menu_height/2 + 10 ,A_HMIDDLE, A_VMIDDLE,3,NO_UPDATE); } - } - else - text_drawf(&blue_text, "New Level", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - - if(menuitem == 2) - { - text_drawf(&red_text, "Load Level", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Create a new Level and load it into the level-editor. */ + else { - show_menu = 0; - selectlevel(); + text_drawf(&white_text,pmenu->item[i].text,0,(i)*24 - menu_height/2 + 10,A_HMIDDLE, A_VMIDDLE,2,NO_UPDATE); } - } - else - text_drawf(&blue_text, "Load Level", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - - if(menuitem == 3) - { - text_drawf(&red_text, "Save Level", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Save the current level in the level-editor. */ + if(pmenu->item[i].kind == MN_TOGGLE) { - show_menu = 0; - savelevel(¤t_level,"default",level); - text_drawf(&gold_text, "SAVED!", 0, 240, A_HMIDDLE, A_TOP, 1, NO_UPDATE); - flipscreen(); - SDL_Delay(1000); - } - } - else - text_drawf(&blue_text, "Save Level", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuitem == 4) - { - text_drawf(&red_text, "Quit Level Editor", 0, 320, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - if(menuaction == MN_HIT) /* Quit the level-editor. (to the main-menu) */ - { - return 1; + if(pmenu->item[i].toggled == YES) + texture_draw(&checkbox_checked,screen->w / 2 + (strlen(pmenu->item[i].text) * 16)/2 + 16,(i)*24 - menu_height/2 + 10 + screen->h / 2 -8,NO_UPDATE); + else + texture_draw(&checkbox,screen->w / 2 + (strlen(pmenu->item[i].text) * 16)/2 + 16,(i)*24 - menu_height/2 + 10 + screen->h / 2 - 8,NO_UPDATE); } } - else - text_drawf(&blue_text, "Quit Level Editor", 0, 320, A_HMIDDLE, A_TOP, 2, NO_UPDATE); - - return 0; } -/* Menu HighScore (ask for player's name) */ -int menu_highscore() +/* Reset/Set global defaults */ +void menu_reset(void) { -char str[60]; - -while(delete_character > 0) /* remove charactes */ - { - hs_name[strlen(hs_name)-1] = '\0'; - delete_character--; - } - -strcat(hs_name, input_string); - -text_drawf(&red_text, "Congratulations", 0, 130, A_HMIDDLE, A_TOP, 2, NO_UPDATE); -text_draw(&red_text, "Your score:", 30, 250, 1, NO_UPDATE); -sprintf(str, "%d", hs_score); -text_draw(&blue_text, str, 350, 250, 1, NO_UPDATE); - -text_draw(&red_text, "Enter your name:", 30, 280, 1, NO_UPDATE); -text_draw(&blue_text, hs_name, 350, 280, 1, NO_UPDATE); - -strcpy(input_string, ""); - -if(menuaction == MN_HIT) /* name written */ - show_menu = 0; + menu_change = NO; + show_menu = NO; + menuaction = -1; + current_menu = NULL; + last_menu = NULL; -return 0; + delete_character = 0; + mn_input_char = '\0'; } /* --- MENU --- */ -/* Draw the menu and execute the (menu)events */ -int drawmenu(void) +/* Draw the current menu and execute the (menu)events */ +void menu_process_current(void) { - int quit = 0; - menu_change = NO; - - if(menuaction == MN_UP) - --menuitem; /* Go one menu-item up */ - else if(menuaction == MN_DOWN) - ++menuitem; /* Go one menu-item down */ - - - switch(menumenu) - { - case MENU_MAIN: - quit = menu_main(); - break; - case MENU_GAME: - quit = menu_game(); - break; - case MENU_OPTIONS: - quit = menu_options(); - break; - case MENU_LEVELEDITOR: - quit = menu_leveleditor(); - break; - case MENU_HIGHSCORE: - quit = menu_highscore(); - break; - default: - break; - } + if(current_menu != NULL) + { + menu_action(current_menu); + menu_draw(current_menu); + } menuaction = -1; - - return quit; } /* Check for menu event */ void menu_event(SDL_keysym* keysym) { -SDLKey key = keysym->sym; -SDLMod keymod; -char ch[2]; - -keymod = SDL_GetModState(); - -/* If the current unicode character is an ASCII character, - assign it to ch. */ -if ( (keysym->unicode & 0xFF80) == 0 ) { - ch[0] = keysym->unicode & 0x7F; - ch[1] = '\0'; -} -else { - /* An International Character. */ -} + SDLKey key = keysym->sym; + SDLMod keymod; + keymod = SDL_GetModState(); + char ch[2]; + + /* If the current unicode character is an ASCII character, + assign it to ch. */ + if ( (keysym->unicode & 0xFF80) == 0 ) + { + ch[0] = keysym->unicode & 0x7F; + ch[1] = '\0'; + } + else + { + /* An International Character. */ + } -switch(key) - { - case SDLK_UP: /* Menu Up */ - menuaction = MN_UP; - menu_change = YES; - break; - case SDLK_DOWN: /* Menu Down */ - menuaction = MN_DOWN; - menu_change = YES; - break; - case SDLK_SPACE: /* Menu Hit */ - case SDLK_RETURN: - menuaction = MN_HIT; - menu_change = YES; - break; - - case SDLK_DELETE: - case SDLK_BACKSPACE: - delete_character++; - break; - default: - if( key >= SDLK_0 && key <= SDLK_9) - strcat( input_string, /* (key - SDLK_0) */ ch); - else if( key >= SDLK_a && SDLK_z ) - { - strcat( input_string, ch); - } - break; + switch(key) + { + case SDLK_UP: /* Menu Up */ + menuaction = MN_UP; + menu_change = YES; + break; + case SDLK_DOWN: /* Menu Down */ + menuaction = MN_DOWN; + menu_change = YES; + break; + case SDLK_SPACE: /* Menu Hit */ + case SDLK_RETURN: + menuaction = MN_HIT; + menu_change = YES; + break; + case SDLK_DELETE: + case SDLK_BACKSPACE: + menuaction = MN_REMOVE; + menu_change = YES; + delete_character++; + break; + default: + if( key >= SDLK_0 && key <= SDLK_9) + { + menuaction = MN_INPUT; + menu_change = YES; + mn_input_char = *ch; + } + else if( key >= SDLK_a && key <= SDLK_z ) + { + menuaction = MN_INPUT; + menu_change = YES; + mn_input_char = *ch; + } + else + { + mn_input_char = '\0'; } + break; + } /* FIXME: NO JOYSTICK SUPPORT */ diff --git a/src/menu.h b/src/menu.h index 92a801a15..edccfb809 100644 --- a/src/menu.h +++ b/src/menu.h @@ -15,43 +15,71 @@ #include -/* (global) menu variables */ -int menuaction; -int menuitem; -int menumenu; -int show_menu; -int menu_change; +typedef struct menu_item_type +{ + int kind; + char *text; + char *input; + int toggled; + void* target_menu; +} +menu_item_type; + +menu_item_type* menu_item_create(int kind, char *text, int init_toggle, void* target_menu); + +typedef struct menu_type +{ + int num_items; + int active_item; + menu_item_type *item; +} +menu_type; -#define MENU_MAIN_ITEM_MAX 3 -#define MENU_GAME_ITEM_MAX 4 -#define MENU_OPTIONS_ITEM_MAX 3 -#define MENU_LEVELEDITOR_ITEM_MAX 4 +void menu_init(menu_type* pmenu); +void menu_free(menu_type* pmenu); +void menu_additem(menu_type* pmenu, menu_item_type* pmenu_item); +void menu_action(menu_type* pmenu); +int menu_check(menu_type* pmenu); +void menu_draw(menu_type* pmenu); +void menu_set_current(menu_type* pmenu); + +/* Kinds of menu items */ +enum { + MN_ACTION, + MN_GOTO, + MN_TOGGLE, + MN_BACK, + MN_DEACTIVE, + MN_TEXTFIELD +}; /* Action done on the menu */ enum { MN_UP, MN_DOWN, - MN_HIT + MN_HIT, + MN_INPUT, + MN_REMOVE }; -/* Menus */ -enum { - MENU_MAIN, - MENU_GAME, - MENU_OPTIONS, - MENU_LEVELEDITOR, - MENU_HIGHSCORE -}; +/* (global) menu variables */ +extern int menuaction; +extern int show_menu; +extern int menu_change; +extern texture_type checkbox, checkbox_checked; + +extern menu_type main_menu, game_menu, options_menu, leveleditor_menu, highscore_menu; +extern menu_type* current_menu, * last_menu; /* input implementation variables */ -int delete_character; -char input_string[62]; +extern int delete_character; +extern char mn_input_char; -/* Initialize the menu variables */ -void initmenu(void); +/* Reset the global menu variables */ +void menu_reset(void); /* "Calculate" and draw the menu */ -int drawmenu(void); +void menu_process_current(void); /* Check for a menu event */ void menu_event(SDL_keysym* keysym); diff --git a/src/player.c b/src/player.c index b10a33466..e064bf7bb 100644 --- a/src/player.c +++ b/src/player.c @@ -17,6 +17,20 @@ #include "scene.h" #include "screen.h" +texture_type tux_life, +tux_right[3], tux_left[3], +bigtux_right[3], bigtux_left[3], +bigtux_right_jump, bigtux_left_jump, +ducktux_right, ducktux_left, +skidtux_right, skidtux_left, +firetux_right[3], firetux_left[3], +bigfiretux_right[3], bigfiretux_left[3], +bigfiretux_right_jump, bigfiretux_left_jump, +duckfiretux_right, duckfiretux_left, +skidfiretux_right, skidfiretux_left, +cape_right[2], cape_left[2], +bigcape_right[2], bigcape_left[2]; + void player_init(player_type* pplayer) { pplayer->base.width = 32; @@ -132,7 +146,10 @@ void player_level_begin(player_type* pplayer) pplayer->input.old_fire = UP; pplayer->input.right = UP; pplayer->input.up = UP; - + + timer_init(&pplayer->invincible_timer); + timer_init(&pplayer->skidding_timer); + timer_init(&pplayer->safe_timer); } void player_action(player_type* pplayer) @@ -152,338 +169,428 @@ void player_action(player_type* pplayer) if (!pplayer->dying) { - if (issolid(pplayer->base.x, pplayer->base.y + 31) && - !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y + 31)) - { - while (issolid(pplayer->base.x, pplayer->base.y + 31)) - { - if (pplayer->base.xm < 0) - pplayer->base.x++; - else if (pplayer->base.xm > 0) - pplayer->base.x--; - } + /* FIXME: this code is COMPLETLY broken!!! */ + if (issolid(pplayer->base.x, pplayer->base.y + 31) && + !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y + 31)) + { + while (issolid(pplayer->base.x, pplayer->base.y + 31)) + { + if (pplayer->base.xm < 0) + pplayer->base.x++; + else if (pplayer->base.xm > 0) + pplayer->base.x--; + } - pplayer->base.xm = 0; - } + pplayer->base.xm = 0; + } - if (issolid(pplayer->base.x, pplayer->base.y) && - !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y)) - { - while (issolid(pplayer->base.x, (pplayer->base.y))) - { - if (pplayer->base.xm < 0) - pplayer->base.x++; - else if (pplayer->base.xm > 0) - pplayer->base.x--; - } + if (issolid(pplayer->base.x, pplayer->base.y) && + !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y)) + { + while (issolid(pplayer->base.x, (pplayer->base.y))) + { + if (pplayer->base.xm < 0) + pplayer->base.x++; + else if (pplayer->base.xm > 0) + pplayer->base.x--; + } - pplayer->base.xm = 0; - } + pplayer->base.xm = 0; + } - if (issolid(pplayer->base.x, pplayer->base.y + 31)) - { - /* Set down properly: */ + if (issolid(pplayer->base.x, pplayer->base.y + 31)) + { + /* Set down properly: */ - int debug_int = 0; - while (issolid(pplayer->base.x, pplayer->base.y + 31)) - { - ++debug_int; - if(debug_int > 32) - { - DEBUG_MSG("FIXME - UNDER certain circumstances I'm hanging in a loop here!"); - /*the circumstances are: - issolid() is true and base.ym == 0 - use of floating point varibles for base stuff*/ - break; - } - if (pplayer->base.ym < 0) - pplayer->base.y++; - else if (pplayer->base.ym > 0) - pplayer->base.y--; - } + int debug_int = 0; + while (issolid(pplayer->base.x, pplayer->base.y + 31)) + { + ++debug_int; + if(debug_int > 32) + { + DEBUG_MSG("FIXME - UNDER certain circumstances I'm hanging in a loop here!"); + /*the circumstances are: + issolid() is true and base.ym == 0 + use of floating point varibles for base stuff*/ + break; + } + if (pplayer->base.ym < 0) + pplayer->base.y++; + else if (pplayer->base.ym > 0) + pplayer->base.y--; + } - /* Reset score multiplier (for multi-hits): */ + /* Reset score multiplier (for multi-hits): */ - if (pplayer->base.ym > 0) - score_multiplier = 1; + if (pplayer->base.ym > 0) + score_multiplier = 1; - /* Stop jumping! */ + /* Stop jumping! */ + pplayer->base.ym = 0; + pplayer->jumping = NO; + pplayer->input.up = UP; + } + /* FIXME: this code is COMPLETLY broken!!! */ + /*if (issolid(pplayer->base.x, pplayer->base.y) || + (pplayer->size == BIG && !pplayer->duck && + (issolid(pplayer->base.x, pplayer->base.y - 32)))) + {*/ + /*if (!issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y) && + (pplayer->size == SMALL || pplayer->duck || + !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32)))*/ + + if (((!issolid(pplayer->base.x, pplayer->base.y- pplayer->base.ym * frame_ratio) && (issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x, pplayer->base.y+31)))) + ||((!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y) && (issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y))))) + /*(pplayer->size == SMALL || pplayer->duck || + !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))*/ + { + pplayer->base.y = pplayer->base.y- pplayer->base.ym * frame_ratio; pplayer->base.ym = 0; - pplayer->jumping = NO; - pplayer->input.up = UP; + } + + if ((!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y) && (issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y)) + /*(pplayer->size == SMALL || pplayer->duck || + !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))*/) || ( pplayer->size == BIG && ( + (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y+32) && (issolid(pplayer->base.x, pplayer->base.y+32) || issolid(pplayer->base.x+32, pplayer->base.y+32)) + /*(pplayer->size == SMALL || pplayer->duck || + !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))*/)))) + { + pplayer->base.x = pplayer->base.x- pplayer->base.xm * frame_ratio; + pplayer->base.xm = 0; + } + + if (pplayer->base.ym <= 0) + { + if (isbrick(pplayer->base.x, pplayer->base.y) || + isfullbox(pplayer->base.x, pplayer->base.y)) + { + trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE); + trybumpbadguy(pplayer->base.x, pplayer->base.y - 64); + bumpbrick(pplayer->base.x, pplayer->base.y); + tryemptybox(pplayer->base.x, pplayer->base.y); } + if (isbrick(pplayer->base.x+ 31, pplayer->base.y) || + isfullbox(pplayer->base.x+ 31, pplayer->base.y)) + { + trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE); + trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64); + bumpbrick(pplayer->base.x+ 31, pplayer->base.y); + tryemptybox(pplayer->base.x+ 31, pplayer->base.y); + } + /* Get a distro from a brick? */ - /* Bump into things: */ + if (shape(pplayer->base.x, pplayer->base.y) == 'x' || + shape(pplayer->base.x, pplayer->base.y) == 'y') + { + add_bouncy_distro(((pplayer->base.x+ 1) + / 32) * 32, + (int)(pplayer->base.y / 32) * 32); - if (issolid(pplayer->base.x, pplayer->base.y) || - (pplayer->size == BIG && !pplayer->duck && - (issolid(pplayer->base.x, pplayer->base.y - 32)))) + if (counting_distros == NO) + { + counting_distros = YES; + distro_counter = 100; + } + + if (distro_counter <= 0) + level_change(¤t_level,pplayer->base.x,pplayer->base.y, 'a'); + + play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + score = score + SCORE_DISTRO; + distros++; + } + else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' || + shape(pplayer->base.x+ 31, pplayer->base.y) == 'y') { - if (!issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y) && - (pplayer->size == SMALL || pplayer->duck || - !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))) + add_bouncy_distro(((pplayer->base.x+ 1 + 31) + / 32) * 32, + (int)(pplayer->base.y / 32) * 32); + + if (counting_distros == NO) { - pplayer->base.x = pplayer->base.x- pplayer->base.xm; - pplayer->base.xm = 0; + counting_distros = YES; + distro_counter = 100; } - else if (!issolid(pplayer->base.x, pplayer->base.y - pplayer->base.ym) && - (pplayer->size == SMALL || pplayer->duck || - !issolid(pplayer->base.x, pplayer->base.y - 32 - pplayer->base.ym))) + + if (distro_counter <= 0) + level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a'); + + play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + score = score + SCORE_DISTRO; + distros++; + } + + } + else +{ + pplayer->base.ym = 0; + pplayer->jumping = NO; + timer_start(&pplayer->jump_timer,MAX_JUMP_TIME); +} + /*}*/ + /* Bump into things: * / + + if (issolid(pplayer->base.x, pplayer->base.y) || + (pplayer->size == BIG && !pplayer->duck && + (issolid(pplayer->base.x, pplayer->base.y - 32)))) + { + + if (!issolid(pplayer->base.x, pplayer->base.y - pplayer->base.ym) && + (pplayer->size == SMALL || pplayer->duck || + !issolid(pplayer->base.x, pplayer->base.y - 32 - pplayer->base.ym))) + { + if (pplayer->base.ym <= 0) { - if (pplayer->base.ym <= 0) - { - /* Jumping up? */ + /* Jumping up? */ + /* FIXME: this code is COMPLETLY broken!!! */ + if (pplayer->size == BIG) + { + /* Break bricks and empty boxes: * / - if (pplayer->size == BIG) - { - /* Break bricks and empty boxes: */ + if (!pplayer->duck) + { + if (isbrick(pplayer->base.x, pplayer->base.y - 32) || + isfullbox(pplayer->base.x, pplayer->base.y - 32)) + { + trygrabdistro(pplayer->base.x, pplayer->base.y - 64, BOUNCE); + trybumpbadguy(pplayer->base.x, pplayer->base.y - 96); - if (!pplayer->duck) - { - if (isbrick(pplayer->base.x, pplayer->base.y - 32) || - isfullbox(pplayer->base.x, pplayer->base.y - 32)) - { - trygrabdistro(pplayer->base.x, pplayer->base.y - 64, BOUNCE); - trybumpbadguy(pplayer->base.x, pplayer->base.y - 96); + if (isfullbox(pplayer->base.x, pplayer->base.y - 32)) + { + bumpbrick(pplayer->base.x, pplayer->base.y - 32); + } - if (isfullbox(pplayer->base.x, pplayer->base.y - 32)) - { - bumpbrick(pplayer->base.x, pplayer->base.y - 32); - } + trybreakbrick(pplayer->base.x, pplayer->base.y - 32); + tryemptybox(pplayer->base.x, pplayer->base.y - 32); + } - trybreakbrick(pplayer->base.x, pplayer->base.y - 32); - tryemptybox(pplayer->base.x, pplayer->base.y - 32); - } + if (isbrick(pplayer->base.x+ 31, pplayer->base.y - 32) || + isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32)) + { + trygrabdistro(pplayer->base.x+ 31, + pplayer->base.y - 64, + BOUNCE); + trybumpbadguy(pplayer->base.x+ 31, + pplayer->base.y - 96); - if (isbrick(pplayer->base.x+ 31, pplayer->base.y - 32) || - isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32)) - { - trygrabdistro(pplayer->base.x+ 31, - pplayer->base.y - 64, - BOUNCE); - trybumpbadguy(pplayer->base.x+ 31, - pplayer->base.y - 96); - - if (isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32)) - { - bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 32); - } - - trybreakbrick(pplayer->base.x+ 31, - pplayer->base.y - 32); - tryemptybox(pplayer->base.x+ 31, - pplayer->base.y - 32); - } - } - else /* ducking */ - { - if (isbrick(pplayer->base.x, pplayer->base.y) || - isfullbox(pplayer->base.x, pplayer->base.y)) - { - trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE); - trybumpbadguy(pplayer->base.x, pplayer->base.y - 64); - if (isfullbox(pplayer->base.x, pplayer->base.y)) - bumpbrick(pplayer->base.x, pplayer->base.y); - trybreakbrick(pplayer->base.x, pplayer->base.y); - tryemptybox(pplayer->base.x, pplayer->base.y); - } + if (isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32)) + { + bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 32); + } - if (isbrick(pplayer->base.x+ 31, pplayer->base.y) || - isfullbox(pplayer->base.x+ 31, pplayer->base.y)) - { - trygrabdistro(pplayer->base.x+ 31, - pplayer->base.y - 32, - BOUNCE); - trybumpbadguy(pplayer->base.x+ 31, - pplayer->base.y - 64); - if (isfullbox(pplayer->base.x+ 31, pplayer->base.y)) - bumpbrick(pplayer->base.x+ 31, pplayer->base.y); - trybreakbrick(pplayer->base.x+ 31, pplayer->base.y); - tryemptybox(pplayer->base.x+ 31, pplayer->base.y); - } - } - } - else - { - /* It's a brick and we're small, make the brick - bounce, and grab any distros above it: */ + trybreakbrick(pplayer->base.x+ 31, + pplayer->base.y - 32); + tryemptybox(pplayer->base.x+ 31, + pplayer->base.y - 32); + } + } + else /* ducking * / + { + if (isbrick(pplayer->base.x, pplayer->base.y) || + isfullbox(pplayer->base.x, pplayer->base.y)) + { + trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE); + trybumpbadguy(pplayer->base.x, pplayer->base.y - 64); + if (isfullbox(pplayer->base.x, pplayer->base.y)) + bumpbrick(pplayer->base.x, pplayer->base.y); + trybreakbrick(pplayer->base.x, pplayer->base.y); + tryemptybox(pplayer->base.x, pplayer->base.y); + } - if (isbrick(pplayer->base.x, pplayer->base.y) || - isfullbox(pplayer->base.x, pplayer->base.y)) - { - trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE); - trybumpbadguy(pplayer->base.x, pplayer->base.y - 64); - bumpbrick(pplayer->base.x, pplayer->base.y); - tryemptybox(pplayer->base.x, pplayer->base.y); - } + if (isbrick(pplayer->base.x+ 31, pplayer->base.y) || + isfullbox(pplayer->base.x+ 31, pplayer->base.y)) + { + trygrabdistro(pplayer->base.x+ 31, + pplayer->base.y - 32, + BOUNCE); + trybumpbadguy(pplayer->base.x+ 31, + pplayer->base.y - 64); + if (isfullbox(pplayer->base.x+ 31, pplayer->base.y)) + bumpbrick(pplayer->base.x+ 31, pplayer->base.y); + trybreakbrick(pplayer->base.x+ 31, pplayer->base.y); + tryemptybox(pplayer->base.x+ 31, pplayer->base.y); + } + } + } + else + { + /* It's a brick and we're small, make the brick + bounce, and grab any distros above it: * / - if (isbrick(pplayer->base.x+ 31, pplayer->base.y) || - isfullbox(pplayer->base.x+ 31, pplayer->base.y)) - { - trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE); - trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64); - bumpbrick(pplayer->base.x+ 31, pplayer->base.y); - tryemptybox(pplayer->base.x+ 31, pplayer->base.y); - } + if (isbrick(pplayer->base.x, pplayer->base.y) || + isfullbox(pplayer->base.x, pplayer->base.y)) + { + trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE); + trybumpbadguy(pplayer->base.x, pplayer->base.y - 64); + bumpbrick(pplayer->base.x, pplayer->base.y); + tryemptybox(pplayer->base.x, pplayer->base.y); + } + if (isbrick(pplayer->base.x+ 31, pplayer->base.y) || + isfullbox(pplayer->base.x+ 31, pplayer->base.y)) + { + trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE); + trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64); + bumpbrick(pplayer->base.x+ 31, pplayer->base.y); + tryemptybox(pplayer->base.x+ 31, pplayer->base.y); + } - /* Get a distro from a brick? */ - if (shape(pplayer->base.x, pplayer->base.y) == 'x' || - shape(pplayer->base.x, pplayer->base.y) == 'y') - { - add_bouncy_distro(((pplayer->base.x+ 1) - / 32) * 32, - (int)(pplayer->base.y / 32) * 32); + /* Get a distro from a brick? * / - if (counting_distros == NO) - { - counting_distros = YES; - distro_counter = 100; - } + if (shape(pplayer->base.x, pplayer->base.y) == 'x' || + shape(pplayer->base.x, pplayer->base.y) == 'y') + { + add_bouncy_distro(((pplayer->base.x+ 1) + / 32) * 32, + (int)(pplayer->base.y / 32) * 32); - if (distro_counter <= 0) - level_change(¤t_level,pplayer->base.x,pplayer->base.y, 'a'); + if (counting_distros == NO) + { + counting_distros = YES; + distro_counter = 100; + } - play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); - score = score + SCORE_DISTRO; - distros++; - } - else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' || - shape(pplayer->base.x+ 31, pplayer->base.y) == 'y') - { - add_bouncy_distro(((pplayer->base.x+ 1 + 31) - / 32) * 32, - (int)(pplayer->base.y / 32) * 32); + if (distro_counter <= 0) + level_change(¤t_level,pplayer->base.x,pplayer->base.y, 'a'); - if (counting_distros == NO) - { - counting_distros = YES; - distro_counter = 100; - } + play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + score = score + SCORE_DISTRO; + distros++; + } + else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' || + shape(pplayer->base.x+ 31, pplayer->base.y) == 'y') + { + add_bouncy_distro(((pplayer->base.x+ 1 + 31) + / 32) * 32, + (int)(pplayer->base.y / 32) * 32); + + if (counting_distros == NO) + { + counting_distros = YES; + distro_counter = 100; + } - if (distro_counter <= 0) - level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a'); + if (distro_counter <= 0) + level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a'); - play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); - score = score + SCORE_DISTRO; - distros++; - } - } + play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + score = score + SCORE_DISTRO; + distros++; + } + } - /* Bump head: */ + /* Bump head: * / - pplayer->base.y = (int)(pplayer->base.y / 32) * 32 + 30; - } - else - { - /* Land on feet: */ + pplayer->base.y = (int)(pplayer->base.y / 32) * 32 + 30; + } + else + { + /* Land on feet: * / - pplayer->base.y = (int)(pplayer->base.y / 32) * 32 - 32; - } + pplayer->base.y = (int)(pplayer->base.y / 32) * 32 - 32; + } - pplayer->base.ym = 0; - pplayer->jumping = NO; - /*pplayer->jump_counter = MAX_JUMP_COUNT;*/ - /*timer_init(&pplayer->jump_timer);*/ - timer_start(&pplayer->jump_timer,MAX_JUMP_TIME); - } - } + pplayer->base.ym = 0; + pplayer->jumping = NO; + timer_start(&pplayer->jump_timer,MAX_JUMP_TIME); + }*/ } +} - player_grabdistros(pplayer); +player_grabdistros(pplayer); - /* Slow down horizontally: */ +/* Slow down horizontally: */ - if (!pplayer->dying) - { - if (pplayer->input.right == UP && pplayer->input.left == UP) - { - if (isice(pplayer->base.x, pplayer->base.y + 32) || - !issolid(pplayer->base.x, pplayer->base.y + 32)) - { - /* Slowly on ice or in air: */ +if (!pplayer->dying) + { + if (pplayer->input.right == UP && pplayer->input.left == UP) + { + if (isice(pplayer->base.x, pplayer->base.y + 32) || + !issolid(pplayer->base.x, pplayer->base.y + 32)) + { + /* Slowly on ice or in air: */ - if (pplayer->base.xm > 0) - pplayer->base.xm--; - else if (pplayer->base.xm < 0) - pplayer->base.xm++; - } - else - { - /* Quickly, otherwise: */ + if (pplayer->base.xm > 0) + pplayer->base.xm--; + else if (pplayer->base.xm < 0) + pplayer->base.xm++; + } + else + { + /* Quickly, otherwise: */ - pplayer->base.xm = pplayer->base.xm / 2; - } - } + pplayer->base.xm = pplayer->base.xm / 2; + } + } - /* Drop vertically: */ + /* Drop vertically: */ - if (!issolid(pplayer->base.x, pplayer->base.y + 32)) - { - pplayer->base.ym = pplayer->base.ym + GRAVITY; + if (!issolid(pplayer->base.x, pplayer->base.y + 32)) + { + pplayer->base.ym = pplayer->base.ym + GRAVITY; - if (pplayer->base.ym > MAX_YM) - pplayer->base.ym = MAX_YM; - } - } + if (pplayer->base.ym > MAX_YM) + pplayer->base.ym = MAX_YM; + } + } - timer_check(&pplayer->safe_timer); +timer_check(&pplayer->safe_timer); - /* ---- DONE HANDLING TUX! --- */ +/* ---- DONE HANDLING TUX! --- */ - /* Handle invincibility timer: */ +/* Handle invincibility timer: */ - if (current_music == HERRING_MUSIC && !timer_check(&pplayer->invincible_timer)) - { - /* - no, we are no more invincible - or we were not in invincible mode - but are we in hurry ? - */ +if (current_music == HERRING_MUSIC && !timer_check(&pplayer->invincible_timer)) + { + /* + no, we are no more invincible + or we were not in invincible mode + but are we in hurry ? + */ - if (timer_get_left(&time_left) < TIME_WARNING) - { - /* yes, we are in hurry - stop the herring_song, prepare to play the correct - fast level_song ! - */ - current_music = HURRYUP_MUSIC; - } - else - { - current_music = LEVEL_MUSIC; - } + if (timer_get_left(&time_left) < TIME_WARNING) + { + /* yes, we are in hurry + stop the herring_song, prepare to play the correct + fast level_song ! + */ + current_music = HURRYUP_MUSIC; + } + else + { + current_music = LEVEL_MUSIC; + } - /* stop the old music if it's being played */ - if (playing_music()) - halt_music(); - } + /* stop the old music if it's being played */ + if (playing_music()) + halt_music(); + } - /* Handle skidding: */ +/* Handle skidding: */ - timer_check(&pplayer->skidding_timer); +timer_check(&pplayer->skidding_timer); - /* End of level? */ +/* End of level? */ - if (pplayer->base.x - scroll_x >= endpos && endpos != 0) - { - next_level = 1; - } +if (pplayer->base.x - scroll_x >= endpos && endpos != 0) + { + next_level = 1; + } } @@ -569,536 +676,540 @@ void player_handle_horizontal_input(player_type *pplayer, int dir) void player_handle_vertical_input(player_type *pplayer) { - if(!timer_started(&pplayer->jump_timer)) - { - timer_start(&pplayer->jump_timer,MAX_JUMP_TIME); + if(!timer_started(&pplayer->jump_timer)) + { + timer_start(&pplayer->jump_timer,MAX_JUMP_TIME); - /* Taking off? */ + /* Taking off? */ - if (!issolid(pplayer->base.x, pplayer->base.y + 32) || - pplayer->base.ym != 0) - { - /* If they're not on the ground, or are currently moving - vertically, don't jump! */ + if (!issolid(pplayer->base.x, pplayer->base.y + 32) || + pplayer->base.ym != 0) + { + /* If they're not on the ground, or are currently moving + vertically, don't jump! */ - pplayer->jumping = NO; - timer_stop(&pplayer->jump_timer); - } - else - { - /* Make sure we're not standing back up into a solid! */ + pplayer->jumping = NO; + timer_stop(&pplayer->jump_timer); + } + else + { + /* Make sure we're not standing back up into a solid! */ - if (pplayer->size == SMALL || pplayer->duck == NO || - !issolid(pplayer->base.x, pplayer->base.y)) - { - pplayer->jumping = YES; + if (pplayer->size == SMALL || pplayer->duck == NO || + !issolid(pplayer->base.x, pplayer->base.y)) + { + pplayer->jumping = YES; - if (pplayer->size == SMALL) - play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER); - else - play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER); - } - } - } + if (pplayer->size == SMALL) + play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER); + else + play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER); + } + } + } - /* Keep jumping for a while: */ + /* Keep jumping for a while: */ - if (timer_check(&pplayer->jump_timer)) - { - pplayer->base.ym = pplayer->base.ym - JUMP_SPEED * frame_ratio; - if (pplayer->base.ym < -YM_FOR_JUMP) - pplayer->base.ym = -YM_FOR_JUMP; - } - } - - void player_input(player_type *pplayer) - { - /* Handle key and joystick state: */ + if (timer_check(&pplayer->jump_timer)) + { + pplayer->base.ym = pplayer->base.ym - JUMP_SPEED * frame_ratio; + if (pplayer->base.ym < -YM_FOR_JUMP) + pplayer->base.ym = -YM_FOR_JUMP; + } +} +void player_input(player_type *pplayer) +{ + /* Handle key and joystick state: */ - if (pplayer->input.right == DOWN && pplayer->input.left == UP) - { - player_handle_horizontal_input(pplayer,RIGHT); - } - else if (pplayer->input.left == DOWN && pplayer->input.right == UP) - { - player_handle_horizontal_input(pplayer,LEFT); - } - /* Jump/jumping? */ + if (pplayer->input.right == DOWN && pplayer->input.left == UP) + { + player_handle_horizontal_input(pplayer,RIGHT); + } + else if (pplayer->input.left == DOWN && pplayer->input.right == UP) + { + player_handle_horizontal_input(pplayer,LEFT); + } - if ( pplayer->input.up == DOWN) - { - player_handle_vertical_input(pplayer); - } - else - timer_stop(&pplayer->jump_timer); - - /* Shoot! */ + /* Jump/jumping? */ - if (pplayer->input.fire == DOWN && pplayer->input.old_fire == UP && pplayer->got_coffee) - { - add_bullet(pplayer->base.x, pplayer->base.y, pplayer->base.xm, pplayer->dir); - } + if ( pplayer->input.up == DOWN) + { + player_handle_vertical_input(pplayer); + } + else + timer_stop(&pplayer->jump_timer); + /* Shoot! */ - /* Duck! */ + if (pplayer->input.fire == DOWN && pplayer->input.old_fire == UP && pplayer->got_coffee) + { + add_bullet(pplayer->base.x, pplayer->base.y, pplayer->base.xm, pplayer->dir); + } - if (pplayer->input.down == DOWN) - { - if (pplayer->size == BIG) - pplayer->duck = YES; - } - else - { - if (pplayer->size == BIG && pplayer->duck == YES) - { - /* Make sure we're not standing back up into a solid! */ - if (!issolid(pplayer->base.x, pplayer->base.y - 32)) - pplayer->duck = NO; - } - else - pplayer->duck = NO; - } + /* Duck! */ - /* (Tux): */ + if (pplayer->input.down == DOWN) + { + if (pplayer->size == BIG) + pplayer->duck = YES; + } + else + { + if (pplayer->size == BIG && pplayer->duck == YES) + { + /* Make sure we're not standing back up into a solid! */ - if (pplayer->input.right == UP && pplayer->input.left == UP) - { - pplayer->frame_main = 1; - pplayer->frame = 1; - } - else - { - if ((pplayer->input.fire == DOWN && (frame % 2) == 0) || - (frame % 4) == 0) - pplayer->frame_main = (pplayer->frame_main + 1) % 4; + if (!issolid(pplayer->base.x, pplayer->base.y - 32)) + pplayer->duck = NO; + } + else + pplayer->duck = NO; + } - pplayer->frame = pplayer->frame_main; + /* (Tux): */ - if (pplayer->frame == 3) - pplayer->frame = 1; - } + if (pplayer->input.right == UP && pplayer->input.left == UP) + { + pplayer->frame_main = 1; + pplayer->frame = 1; + } + else + { + if ((pplayer->input.fire == DOWN && (frame % 2) == 0) || + (frame % 4) == 0) + pplayer->frame_main = (pplayer->frame_main + 1) % 4; - } + pplayer->frame = pplayer->frame_main; - void player_grabdistros(player_type *pplayer) - { - /* Grab distros: */ - if (!pplayer->dying) - { - trygrabdistro(pplayer->base.x, pplayer->base.y, NO_BOUNCE); - trygrabdistro(pplayer->base.x+ 31, pplayer->base.y, NO_BOUNCE); + if (pplayer->frame == 3) + pplayer->frame = 1; + } - if (pplayer->size == BIG && !pplayer->duck) - { - trygrabdistro(pplayer->base.x, pplayer->base.y - 32, NO_BOUNCE); - trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32, NO_BOUNCE); - } - } +} +void player_grabdistros(player_type *pplayer) +{ + /* Grab distros: */ + if (!pplayer->dying) + { + trygrabdistro(pplayer->base.x, pplayer->base.y, NO_BOUNCE); + trygrabdistro(pplayer->base.x+ 31, pplayer->base.y, NO_BOUNCE); - /* Enough distros for a One-up? */ + if (pplayer->size == BIG && !pplayer->duck) + { + trygrabdistro(pplayer->base.x, pplayer->base.y - 32, NO_BOUNCE); + trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32, NO_BOUNCE); + } + } - if (distros >= DISTROS_LIFEUP) - { - distros = distros - DISTROS_LIFEUP; - if(pplayer->lives < MAX_LIVES) - pplayer->lives++; - /*We want to hear the sound even, if MAX_LIVES is reached*/ - play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER); - } - } - void player_draw(player_type* pplayer) - { - if (!timer_started(&pplayer->safe_timer) || (frame % 2) == 0) - { - if (pplayer->size == SMALL) - { - if (timer_started(&pplayer->invincible_timer)) - { - /* Draw cape: */ + /* Enough distros for a One-up? */ - if (pplayer->dir == RIGHT) - { - texture_draw(&cape_right[frame % 2], - pplayer->base.x- scroll_x, pplayer->base.y, - NO_UPDATE); - } - else - { - texture_draw(&cape_left[frame % 2], - pplayer->base.x- scroll_x, pplayer->base.y, - NO_UPDATE); - } - } + if (distros >= DISTROS_LIFEUP) + { + distros = distros - DISTROS_LIFEUP; + if(pplayer->lives < MAX_LIVES) + pplayer->lives++; + /*We want to hear the sound even, if MAX_LIVES is reached*/ + play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER); + } +} +void player_draw(player_type* pplayer) +{ + if (!timer_started(&pplayer->safe_timer) || (frame % 2) == 0) + { + if (pplayer->size == SMALL) + { + if (timer_started(&pplayer->invincible_timer)) + { + /* Draw cape: */ - if (!pplayer->got_coffee) - { - if (pplayer->dir == RIGHT) - { - texture_draw(&tux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE); - } - else - { - texture_draw(&tux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE); - } - } - else - { - /* Tux got coffee! */ + if (pplayer->dir == RIGHT) + { + texture_draw(&cape_right[frame % 2], + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + else + { + texture_draw(&cape_left[frame % 2], + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + } - if (pplayer->dir == RIGHT) - { - texture_draw(&firetux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE); - } - else - { - texture_draw(&firetux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE); - } - } - } - else - { - if (timer_started(&pplayer->invincible_timer)) - { - /* Draw cape: */ - if (pplayer->dir == RIGHT) - { - texture_draw(&bigcape_right[frame % 2], - pplayer->base.x- scroll_x - 8 - 16, pplayer->base.y - 32, - NO_UPDATE); - } - else - { - texture_draw(&bigcape_left[frame % 2], - pplayer->base.x-scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - } + if (!pplayer->got_coffee) + { + if (pplayer->dir == RIGHT) + { + texture_draw(&tux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE); + } + else + { + texture_draw(&tux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE); + } + } + else + { + /* Tux got coffee! */ - if (!pplayer->got_coffee) - { - if (!pplayer->duck) - { - if (!timer_started(&pplayer->skidding_timer)) - { - if (!pplayer->jumping || pplayer->base.ym > 0) - { - if (pplayer->dir == RIGHT) - { - texture_draw(&bigtux_right[pplayer->frame], - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - else - { - texture_draw(&bigtux_left[pplayer->frame], - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - } - else - { - if (pplayer->dir == RIGHT) - { - texture_draw(&bigtux_right_jump, - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - else - { - texture_draw(&bigtux_left_jump, - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - } - } - else - { - if (pplayer->dir == RIGHT) - { - texture_draw(&skidtux_right, - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - else - { - texture_draw(&skidtux_left, - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - } - } - else - { - if (pplayer->dir == RIGHT) - { - texture_draw(&ducktux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y - 16, - NO_UPDATE); - } - else - { - texture_draw(&ducktux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y - 16, - NO_UPDATE); - } - } - } - else - { - /* Tux has coffee! */ + if (pplayer->dir == RIGHT) + { + texture_draw(&firetux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE); + } + else + { + texture_draw(&firetux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE); + } + } + } + else + { + if (timer_started(&pplayer->invincible_timer)) + { + /* Draw cape: */ - if (!pplayer->duck) - { - if (!timer_started(&pplayer->skidding_timer)) - { - if (!pplayer->jumping || pplayer->base.ym > 0) - { - if (pplayer->dir == RIGHT) - { - texture_draw(&bigfiretux_right[pplayer->frame], - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - else - { - texture_draw(&bigfiretux_left[pplayer->frame], - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - } - else - { - if (pplayer->dir == RIGHT) - { - texture_draw(&bigfiretux_right_jump, - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - else - { - texture_draw(&bigfiretux_left_jump, - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - } - } - else - { - if (pplayer->dir == RIGHT) - { - texture_draw(&skidfiretux_right, - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - else - { - texture_draw(&skidfiretux_left, - pplayer->base.x- scroll_x - 8, pplayer->base.y - 32, - NO_UPDATE); - } - } - } - else - { - if (pplayer->dir == RIGHT) - { - texture_draw(&duckfiretux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y - 16, - NO_UPDATE); - } - else - { - texture_draw(&duckfiretux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y - 16, - NO_UPDATE); - } - } - } - } - } - } + if (pplayer->dir == RIGHT) + { + texture_draw(&bigcape_right[frame % 2], + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + else + { + texture_draw(&bigcape_left[frame % 2], + pplayer->base.x-scroll_x, pplayer->base.y, + NO_UPDATE); + } + } - void player_collision(player_type* pplayer, void* p_c_object, int c_object) - { - bad_guy_type* pbad_c = NULL; + if (!pplayer->got_coffee) + { + if (!pplayer->duck) + { + if (!timer_started(&pplayer->skidding_timer)) + { + if (!pplayer->jumping || pplayer->base.ym > 0) + { + if (pplayer->dir == RIGHT) + { + texture_draw(&bigtux_right[pplayer->frame], + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + else + { + texture_draw(&bigtux_left[pplayer->frame], + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + } + else + { + if (pplayer->dir == RIGHT) + { + texture_draw(&bigtux_right_jump, + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + else + { + texture_draw(&bigtux_left_jump, + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + } + } + else + { + if (pplayer->dir == RIGHT) + { + texture_draw(&skidtux_right, + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + else + { + texture_draw(&skidtux_left, + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + } + } + else + { + if (pplayer->dir == RIGHT) + { + texture_draw(&ducktux_right, pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + else + { + texture_draw(&ducktux_left, pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + } + } + else + { + /* Tux has coffee! */ - switch (c_object) - { - case CO_BADGUY: - pbad_c = p_c_object; - /* Hurt the player if he just touched it: */ + if (!pplayer->duck) + { + if (!timer_started(&pplayer->skidding_timer)) + { + if (!pplayer->jumping || pplayer->base.ym > 0) + { + if (pplayer->dir == RIGHT) + { + texture_draw(&bigfiretux_right[pplayer->frame], + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + else + { + texture_draw(&bigfiretux_left[pplayer->frame], + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + } + else + { + if (pplayer->dir == RIGHT) + { + texture_draw(&bigfiretux_right_jump, + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + else + { + texture_draw(&bigfiretux_left_jump, + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + } + } + else + { + if (pplayer->dir == RIGHT) + { + texture_draw(&skidfiretux_right, + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + else + { + texture_draw(&skidfiretux_left, + pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + } + } + else + { + if (pplayer->dir == RIGHT) + { + texture_draw(&duckfiretux_right, pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + else + { + texture_draw(&duckfiretux_left, pplayer->base.x- scroll_x, pplayer->base.y, + NO_UPDATE); + } + } + } + } + } +} - if (!pbad_c->dying && !pplayer->dying && - !timer_started(&pplayer->safe_timer) && - pbad_c->mode != HELD) - { - if (pbad_c->mode == FLAT && pplayer->input.fire != DOWN) - { - /* Kick: */ +void player_collision(player_type* pplayer, void* p_c_object, int c_object) +{ + bad_guy_type* pbad_c = NULL; + + switch (c_object) + { + case CO_BADGUY: + pbad_c = (bad_guy_type*) p_c_object; + /* Hurt the player if he just touched it: */ - pbad_c->mode = KICK; - play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER); + if (!pbad_c->dying && !pplayer->dying && + !timer_started(&pplayer->safe_timer) && + pbad_c->mode != HELD) + { + if (pbad_c->mode == FLAT && pplayer->input.fire != DOWN) + { + /* Kick: */ - if (pplayer->base.x<= pbad_c->base.x) - { - pbad_c->dir = RIGHT; - pbad_c->base.x = pbad_c->base.x + 16; - } - else - { - pbad_c->dir = LEFT; - pbad_c->base.x = pbad_c->base.x - 16; - } + pbad_c->mode = KICK; + play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER); - timer_start(&pbad_c->timer,5000); - } - else if (pbad_c->mode == FLAT && pplayer->input.fire == DOWN) - { - pbad_c->mode = HELD; - pbad_c->base.y-=8; - } - else if (pbad_c->mode == KICK) - { - if (pplayer->base.y < pbad_c->base.y - 16 && - timer_started(&pbad_c->timer)) - { - /* Step on (stop being kicked) */ + if (pplayer->base.x<= pbad_c->base.x) + { + pbad_c->dir = RIGHT; + pbad_c->base.x = pbad_c->base.x + 16; + } + else + { + pbad_c->dir = LEFT; + pbad_c->base.x = pbad_c->base.x - 16; + } - pbad_c->mode = FLAT; - play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER); - timer_start(&pbad_c->timer, 10000); - } - else - { - /* Hurt if you get hit by kicked laptop: */ - - if (timer_started(&pbad_c->timer)) - { - if (!timer_started(&pplayer->invincible_timer)) - { - player_kill(pplayer,SHRINK); - } - else - { - pbad_c->dying = FALLING; - pbad_c->base.ym = -8; - play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER); - } - } - } - } - else - { - if (!timer_started(&pplayer->invincible_timer )) - { - player_kill(pplayer,SHRINK); - } - else - { - pbad_c->dying = FALLING; - pbad_c->base.ym = -8; - play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER); - } - } - } - score_multiplier++; - break; - } + timer_start(&pbad_c->timer,5000); + } + else if (pbad_c->mode == FLAT && pplayer->input.fire == DOWN) + { + pbad_c->mode = HELD; + pbad_c->base.y-=8; + } + else if (pbad_c->mode == KICK) + { + if (pplayer->base.y < pbad_c->base.y - 16 && + timer_started(&pbad_c->timer)) + { + /* Step on (stop being kicked) */ - } + pbad_c->mode = FLAT; + play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER); + timer_start(&pbad_c->timer, 10000); + } + else + { + /* Hurt if you get hit by kicked laptop: */ - /* Kill Player! */ + if (timer_started(&pbad_c->timer)) + { + if (!timer_started(&pplayer->invincible_timer)) + { + player_kill(pplayer,SHRINK); + } + else + { + pbad_c->dying = FALLING; + pbad_c->base.ym = -8; + play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER); + } + } + } + } + else + { + if (!timer_started(&pplayer->invincible_timer )) + { + player_kill(pplayer,SHRINK); + } + else + { + pbad_c->dying = FALLING; + pbad_c->base.ym = -8; + play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER); + } + } + score_multiplier++; + } + break; + default: + break; + } - void player_kill(player_type* pplayer, int mode) - { - pplayer->base.ym = -5; +} - play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER); +/* Kill Player! */ - if (pplayer->dir == RIGHT) - pplayer->base.xm = -8; - else if (pplayer->dir == LEFT) - pplayer->base.xm = 8; +void player_kill(player_type* pplayer, int mode) +{ + pplayer->base.ym = -5; - if (mode == SHRINK && pplayer->size == BIG) - { - if (pplayer->got_coffee) - pplayer->got_coffee = NO; + play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER); - pplayer->size = SMALL; + if (pplayer->dir == RIGHT) + pplayer->base.xm = -8; + else if (pplayer->dir == LEFT) + pplayer->base.xm = 8; - timer_start(&pplayer->safe_timer,TUX_SAFE_TIME); - } - else - { - pplayer->dying = 1; - } - } + if (mode == SHRINK && pplayer->size == BIG) + { + if (pplayer->got_coffee) + pplayer->got_coffee = NO; - void player_dying(player_type *pplayer) - { - pplayer->base.ym = pplayer->base.ym + GRAVITY; + pplayer->size = SMALL; + pplayer->base.height = 32; + + timer_start(&pplayer->safe_timer,TUX_SAFE_TIME); + } + else + { + pplayer->dying = 1; + } +} - /* He died :^( */ +void player_dying(player_type *pplayer) +{ + pplayer->base.ym = pplayer->base.ym + GRAVITY; - --pplayer->lives; - player_remove_powerups(pplayer); - pplayer->dying = NO; + /* He died :^( */ - player_level_begin(pplayer); + --pplayer->lives; + player_remove_powerups(pplayer); + pplayer->dying = NO; - } + player_level_begin(pplayer); - /* Remove Tux's power ups */ - void player_remove_powerups(player_type* pplayer) - { - pplayer->got_coffee = NO; - pplayer->size = SMALL; - } +} - void player_keep_in_bounds(player_type* pplayer) - { - /* Keep tux in bounds: */ - if (pplayer->base.x< 0) - pplayer->base.x= 0; - else if(pplayer->base.x< scroll_x) - pplayer->base.x= scroll_x; - else if (pplayer->base.x< 160 + scroll_x && scroll_x > 0 && debug_mode == YES) - { - scroll_x = pplayer->base.x- 160; - /*pplayer->base.x+= 160;*/ +/* Remove Tux's power ups */ +void player_remove_powerups(player_type* pplayer) +{ + pplayer->got_coffee = NO; + pplayer->size = SMALL; + pplayer->base.height = 32; +} - if(scroll_x < 0) - scroll_x = 0; +void player_keep_in_bounds(player_type* pplayer) +{ + /* Keep tux in bounds: */ + if (pplayer->base.x< 0) + pplayer->base.x= 0; + else if(pplayer->base.x< scroll_x) + pplayer->base.x= scroll_x; + else if (pplayer->base.x< 160 + scroll_x && scroll_x > 0 && debug_mode == YES) + { + scroll_x = pplayer->base.x- 160; + /*pplayer->base.x+= 160;*/ - } - else if (pplayer->base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w)) - { - /* Scroll the screen in past center: */ + if(scroll_x < 0) + scroll_x = 0; - scroll_x = pplayer->base.x- screen->w / 2; - /*pplayer->base.x= 320 + scroll_x;*/ + } + else if (pplayer->base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w)) + { + /* Scroll the screen in past center: */ - if (scroll_x > ((current_level.width * 32) - screen->w)) - scroll_x = ((current_level.width * 32) - screen->w); - } - else if (pplayer->base.x> 608 + scroll_x) - { - /* ... unless there's no more to scroll! */ + scroll_x = pplayer->base.x- screen->w / 2; + /*pplayer->base.x= 320 + scroll_x;*/ - /*pplayer->base.x= 608 + scroll_x;*/ - } + if (scroll_x > ((current_level.width * 32) - screen->w)) + scroll_x = ((current_level.width * 32) - screen->w); + } + else if (pplayer->base.x> 608 + scroll_x) + { + /* ... unless there's no more to scroll! */ - /* Keep in-bounds, vertically: */ + /*pplayer->base.x= 608 + scroll_x;*/ + } - if (pplayer->base.y < 0) - pplayer->base.y = 0; - else if (pplayer->base.y > screen->h) - { - player_kill(&tux,KILL); - } - } + /* Keep in-bounds, vertically: */ + + if (pplayer->base.y < 0) + pplayer->base.y = 0; + else if (pplayer->base.y > screen->h) + { + player_kill(&tux,KILL); + } +} diff --git a/src/player.h b/src/player.h index 1b3dc5549..27a91366c 100644 --- a/src/player.h +++ b/src/player.h @@ -69,7 +69,7 @@ typedef struct player_type } player_type; -texture_type tux_life, +extern texture_type tux_life, tux_right[3], tux_left[3], bigtux_right[3], bigtux_left[3], bigtux_right_jump, bigtux_left_jump, diff --git a/src/scene.c b/src/scene.c index 40dedc098..92c8c2d92 100644 --- a/src/scene.c +++ b/src/scene.c @@ -13,6 +13,29 @@ #include #include "scene.h" +int score, distros, level, next_level, game_pause, quit, score_multiplier, endpos, counting_distros, distro_counter; +timer_type super_bkgd_timer; +float scroll_x; +int frame; +bouncy_distro_type *bouncy_distros; +broken_brick_type *broken_bricks; +bouncy_brick_type *bouncy_bricks; +bad_guy_type *bad_guys; +floating_score_type *floating_scores; +upgrade_type *upgrades; +bullet_type *bullets; +int num_bad_guys; +int num_bouncy_distros; +int num_broken_bricks; +int num_bouncy_bricks; +int num_floating_scores; +int num_upgrades; +int num_bullets; +player_type tux; +texture_type img_box_full, img_box_empty, img_mints, img_coffee, img_super_bkgd, img_red_glow; +timer_type time_left; +double frame_ratio; + /* Initialize all 'dynamic' arrays */ void arrays_init(void) { @@ -64,14 +87,14 @@ void set_defaults(void) /* Add score: */ -void add_score(int x, int y, int s) +void add_score(float x, float y, int s) { int i, found; /* Add the score: */ - score = score + s; + score += s; /* Add a floating score thing to the game: */ @@ -87,7 +110,7 @@ void add_score(int x, int y, int s) if (found == -1) { ++num_floating_scores; - floating_scores = realloc(floating_scores,num_floating_scores*sizeof(floating_score_type)); + floating_scores = (floating_score_type*) realloc(floating_scores,num_floating_scores*sizeof(floating_score_type)); floating_score_init(&floating_scores[num_floating_scores-1],x,y,s); found = -1; } @@ -115,7 +138,7 @@ void add_bouncy_distro(float x, float y) if (found == -1) { ++num_bouncy_distros; - bouncy_distros = realloc(bouncy_distros,num_bouncy_distros*sizeof(bouncy_distro_type)); + bouncy_distros = (bouncy_distro_type*) realloc(bouncy_distros,num_bouncy_distros*sizeof(bouncy_distro_type)); found = num_bouncy_distros - 1; } @@ -155,7 +178,7 @@ void add_broken_brick_piece(float x, float y, float xm, float ym) if (found == -1) { ++num_broken_bricks; - broken_bricks = realloc(broken_bricks,num_broken_bricks*sizeof(broken_brick_type)); + broken_bricks = (broken_brick_type*) realloc(broken_bricks,num_broken_bricks*sizeof(broken_brick_type)); found = num_broken_bricks - 1; } @@ -183,7 +206,7 @@ void add_bouncy_brick(float x, float y) if (found == -1) { ++num_bouncy_bricks; - bouncy_bricks = realloc(bouncy_bricks,num_bouncy_bricks*sizeof(bouncy_brick_type)); + bouncy_bricks = (bouncy_brick_type*) realloc(bouncy_bricks,num_bouncy_bricks*sizeof(bouncy_brick_type)); found = num_bouncy_bricks - 1; } @@ -211,7 +234,7 @@ void add_bad_guy(float x, float y, int kind) if (found == -1) { ++num_bad_guys; - bad_guys = realloc(bad_guys,num_bad_guys*sizeof(bad_guy_type)); + bad_guys = (bad_guy_type*) realloc(bad_guys,num_bad_guys*sizeof(bad_guy_type)); found = num_bad_guys - 1; } @@ -238,7 +261,7 @@ void add_upgrade(float x, float y, int kind) if (found == -1) { ++num_upgrades; - upgrades = realloc(upgrades,num_upgrades*sizeof(upgrade_type)); + upgrades = (upgrade_type*) realloc(upgrades,num_upgrades*sizeof(upgrade_type)); found = num_upgrades - 1; } @@ -265,7 +288,7 @@ void add_bullet(float x, float y, float xm, int dir) if (found == -1) { ++num_bullets; - bullets = realloc(bullets,num_bullets*sizeof(bullet_type)); + bullets = (bullet_type*) realloc(bullets,num_bullets*sizeof(bullet_type)); found = num_bullets - 1; } diff --git a/src/scene.h b/src/scene.h index 4304007e7..52e7ce736 100644 --- a/src/scene.h +++ b/src/scene.h @@ -22,35 +22,30 @@ #include "level.h" #define FRAME_RATE 10 // 100 Frames per second (10ms) -int score, distros, level, next_level, game_pause, -done, quit, score_multiplier, endpos, counting_distros, distro_counter; -timer_type super_bkgd_timer; -float scroll_x; -int frame; -bouncy_distro_type *bouncy_distros; -broken_brick_type *broken_bricks; -bouncy_brick_type *bouncy_bricks; -bad_guy_type *bad_guys; -floating_score_type *floating_scores; -upgrade_type *upgrades; -bullet_type *bullets; -int num_bad_guys; -int num_bouncy_distros; -int num_broken_bricks; -int num_bouncy_bricks; -int num_floating_scores; -int num_upgrades; -int num_bullets; -player_type tux; -SDL_Rect src, dest; -texture_type img_box_full, img_box_empty, img_mints, img_coffee, img_super_bkgd, img_red_glow; -st_level current_level; -unsigned int last_update_time; -unsigned int update_time; -timer_type time_left; -double frame_ratio; +extern int score, distros, level, next_level, game_pause, quit, score_multiplier, endpos, counting_distros, distro_counter; +extern timer_type super_bkgd_timer; +extern float scroll_x; +extern int frame; +extern bouncy_distro_type *bouncy_distros; +extern broken_brick_type *broken_bricks; +extern bouncy_brick_type *bouncy_bricks; +extern bad_guy_type *bad_guys; +extern floating_score_type *floating_scores; +extern upgrade_type *upgrades; +extern bullet_type *bullets; +extern int num_bad_guys; +extern int num_bouncy_distros; +extern int num_broken_bricks; +extern int num_bouncy_bricks; +extern int num_floating_scores; +extern int num_upgrades; +extern int num_bullets; +extern player_type tux; +extern texture_type img_box_full, img_box_empty, img_mints, img_coffee, img_super_bkgd, img_red_glow; +extern timer_type time_left; +extern double frame_ratio; -void add_score(int x, int y, int s); +void add_score(float x, float y, int s); void set_defaults(void); void arrays_init(void); void arrays_free(void); diff --git a/src/screen.c b/src/screen.c index bbd2c60e8..349c1ab76 100644 --- a/src/screen.c +++ b/src/screen.c @@ -35,7 +35,7 @@ void load_and_display_image(char * file) { SDL_Surface * img; - + img = load_image(file, IGNORE_ALPHA); SDL_BlitSurface(img, NULL, screen, NULL); SDL_FreeSurface(img); @@ -44,47 +44,79 @@ void load_and_display_image(char * file) /* --- CLEAR SCREEN --- */ -void clearscreen(float r, float g, float b) +void clearscreen(int r, int g, int b) { #ifndef NOOPENGL if(use_gl) - { - glClearColor(r/256, g/256, b/256, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - } + { + glClearColor(r/256, g/256, b/256, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + } else #endif - SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b)); - + + SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b)); + } /* --- FILL A RECT --- */ -void fillrect(float x, float y, float w, float h, float r, float g, float b) +void fillrect(float x, float y, float w, float h, int r, int g, int b, int a) { #ifndef NOOPENGL -if(use_gl) - { - glBegin(GL_QUADS); - glColor3ub(r, g, b); - glVertex2i(x, y); - glVertex2i(x+w, y); - glVertex2i(x+w, y+h); - glVertex2i(x, y+h); - glEnd(); - } -else - { + if(use_gl) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4ub(r, g, b,a); + + glBegin(GL_POLYGON); + glVertex2f(x, y); + glVertex2f(x+w, y); + glVertex2f(x+w, y+h); + glVertex2f(x, y+h); + glEnd(); + glDisable(GL_BLEND); + } + else + { #endif - SDL_Rect rect; - rect.x = x; - rect.y = y; - rect.w = w; - rect.h = h; - - SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b)); + SDL_Rect src, rect; + SDL_Surface *temp = NULL; + + rect.x = (int)x; + rect.y = (int)y; + rect.w = (int)w; + rect.h = (int)h; + + if(a != 255) + { + temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, + screen->format->Rmask, + screen->format->Gmask, + screen->format->Bmask, + screen->format->Amask); + + + src.x = 0; + src.y = 0; + src.w = rect.w; + src.h = rect.h; + + SDL_FillRect(temp, &src, SDL_MapRGB(screen->format, r, g, b)); + + SDL_SetAlpha(temp, SDL_SRCALPHA, a); + + SDL_BlitSurface(temp,0,screen,&rect); + + SDL_FreeSurface(temp); + } + else + SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b)); + #ifndef NOOPENGL - } + + } #endif } @@ -94,44 +126,44 @@ else void updatescreen(void) { if(use_gl) /*clearscreen(0,0,0);*/ - SDL_GL_SwapBuffers(); + SDL_GL_SwapBuffers(); else SDL_UpdateRect(screen, 0, 0, screen->w, screen->h); } void flipscreen(void) { -if(use_gl) -SDL_GL_SwapBuffers(); -else -SDL_Flip(screen); + if(use_gl) + SDL_GL_SwapBuffers(); + else + SDL_Flip(screen); } /* --- LOAD AN IMAGE --- */ SDL_Surface * load_image(char * file, int use_alpha) { -/* -if(!faccessible(file)) -{ -if(!faccessible(st_dir, -*/ + /* + if(!faccessible(file)) + { + if(!faccessible(st_dir, + */ SDL_Surface * temp, * surf; - + temp = IMG_Load(file); if (temp == NULL) st_abort("Can't load", file); - + surf = SDL_DisplayFormatAlpha(temp); if (surf == NULL) st_abort("Can't covert to display format", file); - + if (use_alpha == IGNORE_ALPHA) SDL_SetAlpha(surf, 0, 0); - + SDL_FreeSurface(temp); return(surf); @@ -139,8 +171,8 @@ if(!faccessible(st_dir, void update_rect(SDL_Surface *scr, Sint32 x, Sint32 y, Sint32 w, Sint32 h) { -if(!use_gl) -SDL_UpdateRect(scr, x, y, w, h); + if(!use_gl) + SDL_UpdateRect(scr, x, y, w, h); } @@ -149,18 +181,18 @@ SDL_UpdateRect(scr, x, y, w, h); void erasetext(char * text, int x, int y, texture_type * ptexture, int update, int shadowsize) { SDL_Rect dest; - - + + dest.x = x; dest.y = y; dest.w = strlen(text) * 16 + shadowsize; dest.h = 17; - + if (dest.w > screen->w) dest.w = screen->w; - + texture_draw_part(ptexture,dest.x,dest.y,dest.x,dest.y,dest.w,dest.h,update); - + if (update == UPDATE) update_rect(screen, dest.x, dest.y, dest.w, dest.h); } diff --git a/src/screen.h b/src/screen.h index 7eb8bf8bf..bab496ac7 100644 --- a/src/screen.h +++ b/src/screen.h @@ -25,8 +25,8 @@ #define IGNORE_ALPHA 1 void load_and_display_image(char * file); -void clearscreen(float r, float g, float b); -void fillrect(float x, float y, float w, float h, float r, float g, float b); +void clearscreen(int r, int g, int b); +void fillrect(float x, float y, float w, float h, int r, int g, int b, int a); void updatescreen(void); void flipscreen(void); SDL_Surface * load_image(char * file, int use_alpha); diff --git a/src/setup.c b/src/setup.c index d7b67f6cb..91b218958 100644 --- a/src/setup.c +++ b/src/setup.c @@ -23,8 +23,9 @@ #ifdef LINUX #include -#include #include +#include +#include #include #endif @@ -33,6 +34,7 @@ #include "setup.h" #include "screen.h" #include "texture.h" +#include "menu.h" /* Local function prototypes: */ @@ -49,17 +51,126 @@ int faccessible(char *filename) return YES; } +/* Can we write to this location? */ +int fwriteable(char *filename) +{ + FILE* fi; + fi = fopen(filename, "wa"); + if (fi == NULL) + { + return NO; + } + return YES; +} -/* --- SETUP --- */ +/* Makes sure a directory is created in either the SuperTux base directory or the SuperTux base directory.*/ +int fcreatedir(char* relative_dir) +{ + char path[1024]; + snprintf(path, 1024, "%s/%s/", st_dir, relative_dir); + if(mkdir(path,0755) != 0) + { + snprintf(path, 1024, "%s/%s/", DATA_PREFIX, relative_dir); + if(mkdir(path,0755) != 0) + { + return NO; + } + else + { + return YES; + } + } + else + { + return YES; + } +} -void st_directory_setup(void) +/* Get all names of sub-directories in a certain directory. */ +/* Returns the number of sub-directories found. */ +/* Note: The user has to free the allocated space. */ +char ** dsubdirs(char *rel_path, char* expected_file, int* num) { + DIR *dirStructP; + struct dirent *direntp; + int i = 0; + char ** sdirs= NULL; + char filename[100]; + char path[1024]; + + sprintf(path,"%s/%s",st_dir,rel_path); + if((dirStructP = opendir(path)) != NULL) + { + while((direntp = readdir(dirStructP)) != NULL) + { + if ( direntp->d_type == DT_DIR ) + { + if(expected_file != NULL) + { + sprintf(filename,"%s/%s/%s",path,direntp->d_name,expected_file); + if(!faccessible(filename)) + continue; + } - /* Set SuperTux configuration and save directories */ + sdirs = (char**) realloc(sdirs, sizeof(char*) * (i+1)); + sdirs[i] = (char*) malloc(sizeof(char) * strlen(direntp->d_name) + 1 ); + strcpy(sdirs[i],direntp->d_name); + ++i; + } + } + closedir(dirStructP); + } + sprintf(path,"%s/%s",DATA_PREFIX,rel_path); + if((dirStructP = opendir(path)) != NULL) + { + while((direntp = readdir(dirStructP)) != NULL) + { + if ( direntp->d_type == DT_DIR ) + { + if(expected_file != NULL) + { + sprintf(filename,"%s/%s/%s",path,direntp->d_name,expected_file); + if(!faccessible(filename)) + { + continue; + } + else + { + sprintf(filename,"%s/%s/%s/%s",st_dir,rel_path,direntp->d_name,expected_file); + if(faccessible(filename)) + continue; + } + } + + sdirs = (char**) realloc(sdirs, sizeof(char*) * (i+1)); + sdirs[i] = (char*) malloc(sizeof(char) * strlen(direntp->d_name) + 1 ); + strcpy(sdirs[i],direntp->d_name); + ++i; + } + } + closedir(dirStructP); + } + + *num = i; + return sdirs; +} + +void free_strings(char **strings, int num) +{ +int i; +for(i=0; i < num; ++i) +free(strings[i]); +} + +/* --- SETUP --- */ +/* Set SuperTux configuration and save directories */ +void st_directory_setup(void) +{ + char *home; + char str[1024]; /* Get home directory (from $HOME variable)... if we can't determine it, use the current directory ("."): */ - char *home; if (getenv("HOME") != NULL) home = getenv("HOME"); else @@ -75,18 +186,113 @@ void st_directory_setup(void) strcpy(st_save_dir,st_dir); strcat(st_save_dir,"/save"); - /* Create them. In the case they exist it won't destroy anything. */ + /* Create them. In the case they exist they won't destroy anything. */ #ifdef LINUX mkdir(st_dir, 0755); mkdir(st_save_dir, 0755); + + sprintf(str, "%s/levels", st_dir); + mkdir(str, 0755); #else #ifdef WIN32 mkdir(st_dir); mkdir(st_save_dir); + sprintf(str, "%s/levels", st_dir); + mkdir(str); #endif #endif + +} + +/* Create and setup menus. */ +void st_menu(void) +{ + + menu_init(&main_menu); + menu_additem(&main_menu,menu_item_create(MN_ACTION,"Start Game",0,0)); + menu_additem(&main_menu,menu_item_create(MN_ACTION,"Load Game",0,0)); + menu_additem(&main_menu,menu_item_create(MN_GOTO,"Options",0,&options_menu)); + menu_additem(&main_menu,menu_item_create(MN_ACTION,"Level editor",0,0)); + menu_additem(&main_menu,menu_item_create(MN_ACTION,"Quit",0,0)); + + menu_init(&options_menu); + menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Fullscreen",use_fullscreen,0)); + if(audio_device == YES) + { + menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Sound",use_sound,0)); + menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Music",use_music,0)); + } + else + { + menu_additem(&options_menu,menu_item_create(MN_DEACTIVE,"Sound",use_sound,0)); + menu_additem(&options_menu,menu_item_create(MN_DEACTIVE,"Music",use_music,0)); + } + menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Show FPS",show_fps,0)); + menu_additem(&options_menu,menu_item_create(MN_BACK,"Back",0,0)); + + menu_init(&leveleditor_menu); + menu_additem(&leveleditor_menu,menu_item_create(MN_ACTION,"Return To Level Editor",0,0)); + menu_additem(&leveleditor_menu,menu_item_create(MN_ACTION,"New Level",0,0)); + menu_additem(&leveleditor_menu,menu_item_create(MN_ACTION,"Load Level",0,0)); + menu_additem(&leveleditor_menu,menu_item_create(MN_ACTION,"Save Level",0,0)); + menu_additem(&leveleditor_menu,menu_item_create(MN_ACTION,"Quit Level Editor",0,0)); + + menu_init(&game_menu); + menu_additem(&game_menu,menu_item_create(MN_ACTION,"Return To Game",0,0)); + menu_additem(&game_menu,menu_item_create(MN_ACTION,"Save Game",0,0)); + menu_additem(&game_menu,menu_item_create(MN_ACTION,"Load Game",0,0)); + menu_additem(&game_menu,menu_item_create(MN_GOTO,"Options",0,&options_menu)); + menu_additem(&game_menu,menu_item_create(MN_ACTION,"Quit Game",0,0)); + + menu_init(&highscore_menu); + menu_additem(&highscore_menu,menu_item_create(MN_TEXTFIELD,"Enter your name:",0,0)); + +} + +/* Handle changes made to global settings in the options menu. */ +void process_options_menu(void) +{ + switch (menu_check(&options_menu)) + { + case 0: + if(use_fullscreen != options_menu.item[0].toggled) + { + use_fullscreen = !use_fullscreen; + st_video_setup(); + } + break; + case 1: + if(use_sound != options_menu.item[1].toggled) + use_sound = !use_sound; + break; + case 2: + if(use_music != options_menu.item[2].toggled) + { + if(use_music == YES) + { + if(playing_music()) + { + halt_music(); + } + use_music = NO; + } + else + { + use_music = YES; + if (!playing_music()) + { + play_current_music(); + } + } + } + break; + case 3: + if(show_fps != options_menu.item[3].toggled) + show_fps = !show_fps; + break; + } } void st_general_setup(void) @@ -96,12 +302,19 @@ void st_general_setup(void) srand(SDL_GetTicks()); /* Load global images: */ - - text_load(&black_text,DATA_PREFIX "/images/status/letters-black.png"); - text_load(&gold_text,DATA_PREFIX "/images/status/letters-gold.png"); - text_load(&blue_text,DATA_PREFIX "/images/status/letters-blue.png"); - text_load(&red_text,DATA_PREFIX "/images/status/letters-red.png"); - + + text_load(&black_text,DATA_PREFIX "/images/status/letters-black.png", TEXT_TEXT, 16,18); + text_load(&gold_text,DATA_PREFIX "/images/status/letters-gold.png", TEXT_TEXT, 16,18); + text_load(&blue_text,DATA_PREFIX "/images/status/letters-blue.png", TEXT_TEXT, 16,18); + text_load(&red_text,DATA_PREFIX "/images/status/letters-red.png", TEXT_TEXT, 16,18); + text_load(&white_text,DATA_PREFIX "/images/status/letters-white.png", TEXT_TEXT, 16,18); + text_load(&white_small_text,DATA_PREFIX "/images/status/letters-white-small.png", TEXT_TEXT, 8,9); + text_load(&yellow_nums,DATA_PREFIX "/images/status/numbers.png", TEXT_NUM, 32,32); + + /* Load GUI/menu images: */ + texture_load(&checkbox, DATA_PREFIX "/images/status/checkbox.png", USE_ALPHA); + texture_load(&checkbox_checked, DATA_PREFIX "/images/status/checkbox-checked.png", USE_ALPHA); + /* Set icon image: */ seticon(); @@ -109,11 +322,37 @@ void st_general_setup(void) } +void st_general_free(void) +{ + + /* Free global images: */ + + text_free(&black_text); + text_free(&gold_text); + text_free(&white_text); + text_free(&blue_text); + text_free(&red_text); + text_free(&white_small_text); + + /* Free GUI/menu images: */ + texture_free(&checkbox); + texture_free(&checkbox_checked); + + /* Free menus */ + + menu_free(&main_menu); + menu_free(&game_menu); + menu_free(&options_menu); + menu_free(&leveleditor_menu); + menu_free(&highscore_menu); + +} + void st_video_setup(void) { -if(screen != NULL) - SDL_FreeSurface(screen); + if(screen != NULL) + SDL_FreeSurface(screen); /* Init SDL Video: */ @@ -129,12 +368,12 @@ if(screen != NULL) /* Open display: */ if(use_gl) - st_video_setup_gl(); + st_video_setup_gl(); else - st_video_setup_sdl(); - + st_video_setup_sdl(); + texture_setup(); - + /* Set window manager stuff: */ SDL_WM_SetCaption("Super Tux", "Super Tux"); @@ -143,6 +382,8 @@ if(screen != NULL) void st_video_setup_sdl(void) { + SDL_FreeSurface(screen); + if (use_fullscreen == YES) { screen = SDL_SetVideoMode(640, 480, 16, SDL_FULLSCREEN ) ; /* | SDL_HWSURFACE); */ @@ -156,7 +397,7 @@ void st_video_setup_sdl(void) use_fullscreen = NO; } } - else + else { screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF ); @@ -175,15 +416,15 @@ void st_video_setup_gl(void) { #ifndef NOOPENGL - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if (use_fullscreen == YES) { - screen = SDL_SetVideoMode(640, 480, 32, SDL_FULLSCREEN | SDL_OPENGL ) ; /* | SDL_HWSURFACE); */ + screen = SDL_SetVideoMode(640, 480, 32, SDL_FULLSCREEN | SDL_OPENGL | SDL_OPENGLBLIT ) ; /* | SDL_HWSURFACE); */ if (screen == NULL) { fprintf(stderr, @@ -194,7 +435,7 @@ void st_video_setup_gl(void) use_fullscreen = NO; } } - else + else { screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_OPENGL | SDL_OPENGLBLIT ); @@ -207,23 +448,24 @@ void st_video_setup_gl(void) exit(1); } } - - /* - * Set up OpenGL for 2D rendering. - */ - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - - glViewport(0, 0, screen->w, screen->h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, screen->w, screen->h, 0, -1.0, 1.0); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(0.0f, 0.0f, 0.0f); - + + /* + * Set up OpenGL for 2D rendering. + */ + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + glViewport(0, 0, screen->w, screen->h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, screen->w, screen->h, 0, -1.0, 1.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, 0.0f); + #endif + } void st_joystick_setup(void) @@ -393,7 +635,7 @@ void seticon(void) /* Create mask: */ masklen = (((icon -> w) + 7) / 8) * (icon -> h); - mask = malloc(masklen * sizeof(Uint8)); + mask = (Uint8*) malloc(masklen * sizeof(Uint8)); memset(mask, 0xFF, masklen); @@ -421,7 +663,7 @@ void parseargs(int argc, char * argv[]) debug_mode = NO; use_fullscreen = NO; show_fps = NO; - use_gl = NO; + use_gl = NO; #ifndef NOSOUND @@ -453,13 +695,14 @@ void parseargs(int argc, char * argv[]) show_fps = YES; } else if (strcmp(argv[i], "--opengl") == 0 || - strcmp(argv[i], "-gl") == 0) + strcmp(argv[i], "-gl") == 0) { - #ifndef NOOPENGL +#ifndef NOOPENGL /* Use OpengGL: */ use_gl = YES; - #endif +#endif + } else if (strcmp(argv[i], "--usage") == 0) { @@ -512,7 +755,7 @@ void parseargs(int argc, char * argv[]) printf("---------- Command-line options ----------\n\n"); printf(" --opengl - If opengl support was compiled in, this will enable the EXPERIMENTAL OpenGL mode.\n\n"); - + printf(" --disable-sound - If sound support was compiled in, this will\n disable sound for this session of the game.\n\n"); printf(" --disable-music - Like above, but this will disable music.\n\n"); diff --git a/src/setup.h b/src/setup.h index db406ade3..fdd5c6b39 100644 --- a/src/setup.h +++ b/src/setup.h @@ -16,7 +16,11 @@ #include "sound.h" int faccessible(char *filename); - void st_directory_setup(void); + int fcreatedir(char* relative_dir); + int fwriteable(char *filename); + char ** dsubdirs(char *rel_path, char* expected_file, int* num); + void free_strings(char **strings, int num); + void st_directory_setup(void); void st_general_setup(void); void st_video_setup_sdl(void); void st_video_setup_gl(void); @@ -24,7 +28,9 @@ void st_audio_setup(void); void st_joystick_setup(void); void st_shutdown(void); + void st_menu(void); void st_abort(char * reason, char * details); + void process_options_menu(void); void parseargs(int argc, char * argv[]); #endif diff --git a/src/sound.c b/src/sound.c index 8750dcd36..a7b424126 100644 --- a/src/sound.c +++ b/src/sound.c @@ -10,19 +10,17 @@ April 22, 2000 - December 28, 2003 */ -/* why do we need this ? -#ifdef LINUX -#include -#include -#include -#endif -*/ - #include "defines.h" #include "globals.h" #include "sound.h" #include "setup.h" +/*global variable*/ +int use_sound; /* handle sound on/off menu and command-line option */ +int use_music; /* handle music on/off menu and command-line option */ +int audio_device; /* != 0: available and initialized */ +int current_music; + char * soundfilenames[NUM_SOUNDS] = { DATA_PREFIX "/sounds/jump.wav", DATA_PREFIX "/sounds/bigjump.wav", @@ -49,6 +47,9 @@ char * soundfilenames[NUM_SOUNDS] = { #include +Mix_Chunk * sounds[NUM_SOUNDS]; +Mix_Music * level_song, * level_song_fast, * herring_song; + /* --- OPEN THE AUDIO DEVICE --- */ int open_audio (int frequency, Uint16 format, int channels, int chunksize) @@ -228,6 +229,9 @@ void play_current_music(void) #else +void* sounds[NUM_SOUNDS]; +void* level_song, *herring_song; + int open_audio (int frequency, int format, int channels, int chunksize) { return -1; diff --git a/src/sound.h b/src/sound.h index 600d217cb..63733131a 100644 --- a/src/sound.h +++ b/src/sound.h @@ -22,9 +22,9 @@ #define SOUND_RESERVED_CHANNELS 2 /*global variable*/ -int use_sound; /* handle sound on/off menu and command-line option */ -int use_music; /* handle music on/off menu and command-line option */ -int audio_device; /* != 0: available and initialized */ +extern int use_sound; /* handle sound on/off menu and command-line option */ +extern int use_music; /* handle music on/off menu and command-line option */ +extern int audio_device; /* != 0: available and initialized */ /* enum of different internal music types */ enum Music_Type { @@ -32,7 +32,9 @@ enum Music_Type { LEVEL_MUSIC, HURRYUP_MUSIC, HERRING_MUSIC -} current_music; +}; + +extern int current_music; /* panning effects: terrible :-) ! */ enum Sound_Speaker { @@ -69,8 +71,8 @@ enum { #include /* variables for stocking the sound and music */ -Mix_Chunk * sounds[NUM_SOUNDS]; -Mix_Music * level_song, * level_song_fast, * herring_song; +extern Mix_Chunk * sounds[NUM_SOUNDS]; +extern Mix_Music * level_song, * level_song_fast, * herring_song; /* functions handling the sound and music */ int open_audio(int frequency, Uint16 format, int channels, int chunksize); @@ -91,8 +93,8 @@ void play_current_music(void); #else /* fake variables */ -void* sounds[NUM_SOUNDS]; -void* level_song, *herring_song; +extern void* sounds[NUM_SOUNDS]; +extern void* level_song, *herring_song; /* fake sound handlers */ int open_audio (int frequency, int format, int channels, int chunksize); diff --git a/src/special.c b/src/special.c index ea6f6fc21..181c0440c 100644 --- a/src/special.c +++ b/src/special.c @@ -20,6 +20,10 @@ #include "globals.h" #include "player.h" +texture_type img_bullet; +texture_type img_golden_herring; +bitmask* bm_bullet; + void create_special_bitmasks() { bm_bullet = bitmask_create_SDL(img_bullet.sdl_surface); @@ -133,8 +137,8 @@ void upgrade_action(upgrade_type *pupgrade) pupgrade->base.x = pupgrade->base.x + pupgrade->base.xm * frame_ratio; pupgrade->base.y = pupgrade->base.y + pupgrade->base.ym * frame_ratio; - if (issolid(pupgrade->base.x, pupgrade->base.y + 31) || - issolid(pupgrade->base.x + 31, pupgrade->base.y + 31)) + if (issolid(pupgrade->base.x, pupgrade->base.y + 31.) || + issolid(pupgrade->base.x + 31., pupgrade->base.y + 31.)) { if (pupgrade->base.ym > 0) { @@ -153,10 +157,16 @@ void upgrade_action(upgrade_type *pupgrade) else pupgrade->base.ym = pupgrade->base.ym + GRAVITY; - if (issolid(pupgrade->base.x, pupgrade->base.y)) - { - pupgrade->base.xm = -pupgrade->base.xm; - } + if (issolid(pupgrade->base.x - 1, (int) pupgrade->base.y)) + { + if(pupgrade->base.xm < 0) + pupgrade->base.xm = -pupgrade->base.xm; + } + else if (issolid(pupgrade->base.x + pupgrade->base.width-1, (int) pupgrade->base.y)) + { + if(pupgrade->base.xm > 0) + pupgrade->base.xm = -pupgrade->base.xm; + } } @@ -171,16 +181,17 @@ void upgrade_action(upgrade_type *pupgrade) void upgrade_draw(upgrade_type* pupgrade) { +SDL_Rect dest; if (pupgrade->base.alive) { if (pupgrade->base.height < 32) { /* Rising up... */ - dest.x = pupgrade->base.x - scroll_x; - dest.y = pupgrade->base.y + 32 - pupgrade->base.height; + dest.x = (int)(pupgrade->base.x - scroll_x); + dest.y = (int)(pupgrade->base.y + 32 - pupgrade->base.height); dest.w = 32; - dest.h = pupgrade->base.height; + dest.h = (int)pupgrade->base.height; if (pupgrade->kind == UPGRADE_MINTS) texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h,NO_UPDATE); @@ -223,7 +234,7 @@ void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object) /* Remove the upgrade: */ /* p_c_object is CO_PLAYER, so assign it to pplayer */ - pplayer = p_c_object; + pplayer = (player_type*) p_c_object; pupgrade->base.alive = NO; @@ -233,6 +244,7 @@ void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object) { play_sound(sounds[SND_EXCELLENT], SOUND_CENTER_SPEAKER); pplayer->size = BIG; + pplayer->base.height = 64; timer_start(&super_bkgd_timer, 350); } else if (pupgrade->kind == UPGRADE_COFFEE) diff --git a/src/special.h b/src/special.h index dfd9b1da9..7190428a9 100644 --- a/src/special.h +++ b/src/special.h @@ -36,12 +36,12 @@ typedef struct bullet_type } bullet_type; -texture_type img_bullet; -bitmask* bm_bullet; +extern texture_type img_bullet; +extern bitmask* bm_bullet; void create_special_bitmasks(); -texture_type img_golden_herring; +extern texture_type img_golden_herring; void upgrade_init(upgrade_type *pupgrade, float x, float y, int kind); void upgrade_action(upgrade_type *pupgrade); diff --git a/src/supertux.c b/src/supertux.c index ad86fd69d..9561911e6 100644 --- a/src/supertux.c +++ b/src/supertux.c @@ -31,6 +31,7 @@ int main(int argc, char * argv[]) st_video_setup(); st_joystick_setup(); st_general_setup(); + st_menu(); done = intro(); @@ -39,13 +40,6 @@ int main(int argc, char * argv[]) while (!done) { done = title(); - if (!done) - { - if(game_started) - done = gameloop(); - else if(level_editor_started) - done = leveleditor(1); - } } clearscreen(0, 0, 0); diff --git a/src/supertux.h b/src/supertux.h index 44cba5ee8..e0dc998db 100644 --- a/src/supertux.h +++ b/src/supertux.h @@ -1,5 +1,5 @@ -#if !defined( SUPERTUX_SUPERTUX_H ) -#define SUPERTUX_SUPERTUX_H 1 +#ifndef SUPERTUX_SUPERTUX_H +#define SUPERTUX_SUPERTUX_H #ifdef LINUX #include #include @@ -14,4 +14,4 @@ #include "gameloop.h" #include "leveleditor.h" #include "screen.h" -#endif +#endif /*SUPERTUX_SUPERTUX_H*/ diff --git a/src/text.c b/src/text.c index 0e2b84582..81295cf90 100644 --- a/src/text.c +++ b/src/text.c @@ -10,82 +10,163 @@ // // +#include #include #include "globals.h" #include "defines.h" #include "screen.h" #include "text.h" -void text_load(text_type* ptext, char* file) +void text_load(text_type* ptext, char* file, int kind, int w, int h) { - int x, y, c; + int x, y; + int mx, my; + SDL_Surface *conv; - c = 0; + if(kind == TEXT_TEXT) + { + ptext->chars = (texture_type*) malloc(sizeof(texture_type) * 79); + ptext->shadow_chars = (texture_type*) malloc(sizeof(texture_type) * 79); + mx = 26; + my = 3; + } + else if(kind == TEXT_NUM) + { + ptext->chars = (texture_type*) malloc(sizeof(texture_type) * 10); + ptext->shadow_chars = (texture_type*) malloc(sizeof(texture_type) * 10); + mx = 10; + my = 1; + } + else + { + ptext->chars = NULL; + ptext->shadow_chars = NULL; + mx = 0; + my = 0; + } + ptext->kind = kind; + ptext->w = w; + ptext->h = h; - for(y = 0; y < 3 ; ++y) + for(y = 0; y < my ; ++y) { - for(x = 0; x < 26 ; ++x) + for(x = 0; x < mx ; ++x) { - texture_load_part(&ptext->chars[c],file,x*16,y*16,16,16, USE_ALPHA); - ++c; + texture_load_part(&ptext->chars[y*mx+x],file,x*w,y*h,w,h, USE_ALPHA); } } + + /* Load shadow font. */ + for(y = 0; y < my ; ++y) + { + for(x = 0; x < mx ; ++x) + { + int pixels; + int i; + conv = SDL_DisplayFormatAlpha(ptext->chars[y*mx+x].sdl_surface); + pixels = conv->w * conv->h; + SDL_LockSurface(conv); + for(i = 0; i < pixels; ++i) + { + Uint32 *p = (Uint32 *)conv->pixels + i; + *p = *p & conv->format->Amask; + } + SDL_UnlockSurface(conv); + SDL_SetAlpha(conv, SDL_SRCALPHA, 128); + texture_from_sdl_surface(&ptext->shadow_chars[y*mx+x],conv,USE_ALPHA); + } + } + } void text_draw(text_type* ptext, char* text, int x, int y, int shadowsize, int update) { - int len; - int i; + if(text != NULL) + { + if(shadowsize != 0) + text_draw_chars(ptext,&ptext->shadow_chars[0], text,x+shadowsize,y+shadowsize, update); + + text_draw_chars(ptext,ptext->chars, text,x,y, update); + } +} -if(shadowsize != 0) -text_draw(&black_text,text,x+shadowsize,y+shadowsize, 0, update); +void text_draw_chars(text_type* ptext, texture_type* pchars, char* text, int x, int y, int update) +{ + int i,len; len = strlen(text); - for( i = 0; i < len; ++i) + if(ptext->kind == TEXT_TEXT) + { + for( i = 0; i < len; ++i) + { + if( text[i] >= 'A' && text[i] <= 'Z') + { + texture_draw(&pchars[(int)(text[i] - 'A')],x+i*ptext->w,y,update); + } + else if( text[i] >= 'a' && text[i] <= 'z') + { + texture_draw(&pchars[(int)(text[i] - 'a') + 26],x+i*ptext->w,y,update); + } + else if ( text[i] >= '!' && text[i] <= '9') + { + texture_draw(&pchars[(int)(text[i] - '!') + 52],x+i*ptext->w,y,update); + } + else if ( text[i] == '?') + { + texture_draw(&pchars[77],x+i*ptext->w,y,update); + } + else if ( text[i] == '\n') + { + y += ptext->h + 2; + } + } + } + else if(ptext->kind == TEXT_NUM) { - if( text[i] >= 'A' && text[i] <= 'Z') - { - texture_draw(&ptext->chars[(int)(text[i] - 'A')],x+i*16,y,update); - } - else if( text[i] >= 'a' && text[i] <= 'z') - { - texture_draw(&ptext->chars[(int)(text[i] - 'a') + 26],x+i*16,y,update); - } - else if ( text[i] >= '!' && text[i] <= '9') - { - texture_draw(&ptext->chars[(int)(text[i] - '!') + 52],x+i*16,y,update); - } - else if ( text[i] == '?') - { - texture_draw(&ptext->chars[77],x+i*16,y,update); - } - else if ( text[i] == '\n') - { - y += 18; - } + for( i = 0; i < len; ++i) + { + if ( text[i] >= '0' && text[i] <= '9') + { + texture_draw(&pchars[(int)(text[i] - '0')],x+i*ptext->w,y,update); + } + else if ( text[i] == '\n') + { + y += ptext->h + 2; + } + } } } void text_drawf(text_type* ptext, char* text, int x, int y, int halign, int valign, int shadowsize, int update) { -if(halign == A_RIGHT) -x += screen->w; -else if(halign == A_HMIDDLE) -x += screen->w/2 - ((strlen(text)*16)/2); - -if(valign == A_BOTTOM) -y += screen->h - 16; -else if(valign == A_VMIDDLE) -y += screen->h/2; + if(text != NULL) + { + if(halign == A_RIGHT) + x += screen->w; + else if(halign == A_HMIDDLE) + x += screen->w/2 - ((strlen(text)*ptext->w)/2); -text_draw(ptext,text,x,y,shadowsize,update); + if(valign == A_BOTTOM) + y += screen->h - ptext->h; + else if(valign == A_VMIDDLE) + y += screen->h/2 - ptext->h/2; + text_draw(ptext,text,x,y,shadowsize,update); + } } void text_free(text_type* ptext) { int c; - for( c = 0; c < 78; ++c) - texture_free(&ptext->chars[c]); + if(ptext->kind == TEXT_TEXT) + { + for( c = 0; c < 78; ++c) + texture_free(&ptext->chars[c]); + } + else if(ptext->kind == TEXT_NUM) + { + for( c = 0; c < 10; ++c) + texture_free(&ptext->chars[c]); + } } diff --git a/src/text.h b/src/text.h index a395f1149..f04ada2a3 100644 --- a/src/text.h +++ b/src/text.h @@ -18,10 +18,20 @@ /* Text type */ typedef struct text_type { - texture_type chars[78]; + texture_type* chars; + texture_type* shadow_chars; + int kind; + int w; + int h; } text_type; +/* Kinds of texts. */ +enum { + TEXT_TEXT, + TEXT_NUM +}; + enum { A_LEFT, A_HMIDDLE, @@ -32,8 +42,9 @@ enum { A_NONE }; -void text_load(text_type* ptext, char* file); +void text_load(text_type* ptext, char* file, int kind, int w, int h); void text_draw(text_type* ptext, char* text, int x, int y, int shadowsize, int update); +void text_draw_chars(text_type* ptext, texture_type* pchars, char* text, int x, int y, int update); void text_drawf(text_type* ptext, char* text, int x, int y, int halign, int valign, int shadowsize, int update); void text_free(text_type* ptext); diff --git a/src/texture.c b/src/texture.c index 303e7d839..803c5b301 100644 --- a/src/texture.c +++ b/src/texture.c @@ -17,6 +17,14 @@ #include "setup.h" #include "texture.h" +void (*texture_load) (texture_type* ptexture, char * file, int use_alpha); +void (*texture_load_part) (texture_type* ptexture, char * file, int x, int y, int w, int h, int use_alpha); +void (*texture_free) (texture_type* ptexture); +void (*texture_draw) (texture_type* ptexture, float x, float y, int update); +void (*texture_draw_bg) (texture_type* ptexture, int update); +void (*texture_draw_part) (texture_type* ptexture, float sx, float sy, float x, float y, float w, float h, int update); + + void texture_setup(void) { #ifdef NOOPENGL @@ -73,7 +81,7 @@ static int power_of_two(int input) return value; } -void texture_create_gl(SDL_Surface * surf, GLint * tex) +void texture_create_gl(SDL_Surface * surf, GLuint * tex) { Uint32 saved_flags; Uint8 saved_alpha; @@ -120,6 +128,7 @@ void texture_create_gl(SDL_Surface * surf, GLint * tex) glPixelStorei(GL_UNPACK_ROW_LENGTH, conv->pitch / conv->format->BytesPerPixel); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, conv->pixels); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glDisable(GL_BLEND); SDL_FreeSurface(conv); } @@ -131,8 +140,10 @@ void texture_free_gl(texture_type* ptexture) void texture_draw_gl(texture_type* ptexture, float x, float y, int update) { +float pw = power_of_two(ptexture->w); +float ph = power_of_two(ptexture->h); - + glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -143,18 +154,22 @@ void texture_draw_gl(texture_type* ptexture, float x, float y, int update) glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(x, y); - glTexCoord2f((float)ptexture->w / (float)power_of_two(ptexture->w), 0); + glTexCoord2f((float)ptexture->w / pw, 0); glVertex2f((float)ptexture->w+x, y); - glTexCoord2f((float)ptexture->w / (float)power_of_two(ptexture->w), (float)ptexture->h / (float)power_of_two(ptexture->h)); glVertex2f((float)ptexture->w+x, (float)ptexture->h+y); - glTexCoord2f(0, (float)ptexture->h / (float)power_of_two(ptexture->h)); + glTexCoord2f((float)ptexture->w / pw, (float)ptexture->h / ph); glVertex2f((float)ptexture->w+x, (float)ptexture->h+y); + glTexCoord2f(0, (float)ptexture->h / ph); glVertex2f(x, (float)ptexture->h+y); glEnd(); - + + glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); } void texture_draw_bg_gl(texture_type* ptexture, int update) { +float pw = power_of_two(ptexture->w); +float ph = power_of_two(ptexture->h); + glColor3ub(255, 255, 255); glEnable(GL_TEXTURE_2D); @@ -163,17 +178,21 @@ void texture_draw_bg_gl(texture_type* ptexture, int update) glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(0, 0); - glTexCoord2f((float)ptexture->w / (float)power_of_two(ptexture->w), 0); + glTexCoord2f((float)ptexture->w / pw, 0); glVertex2f(screen->w, 0); - glTexCoord2f((float)ptexture->w / (float)power_of_two(ptexture->w), (float)ptexture->h / power_of_two(ptexture->h)); + glTexCoord2f((float)ptexture->w / pw, (float)ptexture->h / ph); glVertex2f(screen->w, screen->h); - glTexCoord2f(0, (float)ptexture->h / (float)power_of_two(ptexture->h)); + glTexCoord2f(0, (float)ptexture->h / ph); glVertex2f(0, screen->h); glEnd(); + + glDisable(GL_TEXTURE_2D); } void texture_draw_part_gl(texture_type* ptexture,float sx, float sy, float x, float y, float w, float h, int update) { +float pw = power_of_two(ptexture->w); +float ph = power_of_two(ptexture->h); glBindTexture(GL_TEXTURE_2D, ptexture->gl_texture); @@ -186,16 +205,17 @@ void texture_draw_part_gl(texture_type* ptexture,float sx, float sy, float x, fl glBegin(GL_QUADS); - glTexCoord2f(sx / (float)power_of_two(ptexture->w), sy / (float)power_of_two(ptexture->h)); + glTexCoord2f(sx / pw, sy / ph); glVertex2f(x, y); - glTexCoord2f((float)(sx + w) / (float)power_of_two(ptexture->w), sy / (float)power_of_two(ptexture->h)); + glTexCoord2f((float)(sx + w) / pw, sy / ph); glVertex2f(w+x, y); - glTexCoord2f((sx+w) / (float)power_of_two(ptexture->w), (sy+h) / (float)power_of_two(ptexture->h)); + glTexCoord2f((sx+w) / pw, (sy+h) / ph); glVertex2f(w +x, h+y); - glTexCoord2f(sx / (float)power_of_two(ptexture->w), (float)(sy+h) / (float)power_of_two(ptexture->h)); + glTexCoord2f(sx / pw, (float)(sy+h) / ph); glVertex2f(x, h+y); glEnd(); + glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); } @@ -210,6 +230,9 @@ void texture_load_sdl(texture_type* ptexture, char * file, int use_alpha) if (temp == NULL) st_abort("Can't load", file); + if(use_alpha == IGNORE_ALPHA) + ptexture->sdl_surface = SDL_DisplayFormat(temp); + else ptexture->sdl_surface = SDL_DisplayFormatAlpha(temp); if (ptexture->sdl_surface == NULL) @@ -260,6 +283,9 @@ void texture_load_part_sdl(texture_type* ptexture, char * file, int x, int y, in SDL_SetAlpha(temp,0,0); SDL_BlitSurface(temp, &src, conv, NULL); + if(use_alpha == IGNORE_ALPHA) + ptexture->sdl_surface = SDL_DisplayFormat(conv); + else ptexture->sdl_surface = SDL_DisplayFormatAlpha(conv); if (ptexture->sdl_surface == NULL) @@ -277,16 +303,30 @@ void texture_load_part_sdl(texture_type* ptexture, char * file, int x, int y, in void texture_from_sdl_surface(texture_type* ptexture, SDL_Surface* sdl_surf, int use_alpha) { - - /* SDL_Surface * temp; - - temp = IMG_Load(file); - - if (temp == NULL) - st_abort("Can't load", file);*/ - + Uint32 saved_flags; + Uint8 saved_alpha; + + /* Save the alpha blending attributes */ + saved_flags = sdl_surf->flags&(SDL_SRCALPHA|SDL_RLEACCELOK); + saved_alpha = sdl_surf->format->alpha; + if ( (saved_flags & SDL_SRCALPHA) + == SDL_SRCALPHA ) + { + SDL_SetAlpha(sdl_surf, 0, 0); + } + + if(use_alpha == IGNORE_ALPHA) + ptexture->sdl_surface = SDL_DisplayFormat(sdl_surf); + else ptexture->sdl_surface = SDL_DisplayFormatAlpha(sdl_surf); + /* Restore the alpha blending attributes */ + if ( (saved_flags & SDL_SRCALPHA) + == SDL_SRCALPHA ) + { + SDL_SetAlpha(ptexture->sdl_surface, saved_flags, saved_alpha); + } + if (ptexture->sdl_surface == NULL) st_abort("Can't covert to display format", "SURFACE"); @@ -307,15 +347,15 @@ void texture_from_sdl_surface(texture_type* ptexture, SDL_Surface* sdl_surf, int void texture_draw_sdl(texture_type* ptexture, float x, float y, int update) { + SDL_Rect dest; - dest.x = x; - dest.y = y; + dest.x = (int)x; + dest.y = (int)y; dest.w = ptexture->w; dest.h = ptexture->h; - SDL_BlitSurface(ptexture->sdl_surface, NULL, screen, &dest); - + if (update == UPDATE) SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h); } @@ -324,14 +364,14 @@ void texture_draw_sdl(texture_type* ptexture, float x, float y, int update) void texture_draw_bg_sdl(texture_type* ptexture, int update) { SDL_Rect dest; - + dest.x = 0; dest.y = 0; dest.w = screen->w; dest.h = screen->h; - - SDL_BlitSurface(ptexture->sdl_surface, NULL, screen, &dest); - + + SDL_SoftStretch(ptexture->sdl_surface, NULL, screen, &dest); + if (update == UPDATE) SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h); } @@ -340,15 +380,15 @@ void texture_draw_part_sdl(texture_type* ptexture, float sx, float sy, float x, { SDL_Rect src, dest; - src.x = sx; - src.y = sy; - src.w = w; - src.h = h; + src.x = (int)sx; + src.y = (int)sy; + src.w = (int)w; + src.h = (int)h; - dest.x = x; - dest.y = y; - dest.w = w; - dest.h = h; + dest.x = (int)x; + dest.y = (int)y; + dest.w = (int)w; + dest.h = (int)h; SDL_BlitSurface(ptexture->sdl_surface, &src, screen, &dest); diff --git a/src/texture.h b/src/texture.h index 0448d0e5b..9904b2901 100644 --- a/src/texture.h +++ b/src/texture.h @@ -22,19 +22,19 @@ typedef struct texture_type { SDL_Surface* sdl_surface; - unsigned gl_texture; + GLuint gl_texture; int w; int h; } texture_type; void texture_setup(void); -void (*texture_load) (texture_type* ptexture, char * file, int use_alpha); -void (*texture_load_part) (texture_type* ptexture, char * file, int x, int y, int w, int h, int use_alpha); -void (*texture_free) (texture_type* ptexture); -void (*texture_draw) (texture_type* ptexture, float x, float y, int update); -void (*texture_draw_bg) (texture_type* ptexture, int update); -void (*texture_draw_part) (texture_type* ptexture, float sx, float sy, float x, float y, float w, float h, int update); +extern void (*texture_load) (texture_type* ptexture, char * file, int use_alpha); +extern void (*texture_load_part) (texture_type* ptexture, char * file, int x, int y, int w, int h, int use_alpha); +extern void (*texture_free) (texture_type* ptexture); +extern void (*texture_draw) (texture_type* ptexture, float x, float y, int update); +extern void (*texture_draw_bg) (texture_type* ptexture, int update); +extern void (*texture_draw_part) (texture_type* ptexture, float sx, float sy, float x, float y, float w, float h, int update); void texture_load_sdl(texture_type* ptexture, char * file, int use_alpha); void texture_load_part_sdl(texture_type* ptexture, char * file, int x, int y, int w, int h, int use_alpha); void texture_free_sdl(texture_type* ptexture); @@ -49,7 +49,7 @@ void texture_free_gl(texture_type* ptexture); void texture_draw_gl(texture_type* ptexture, float x, float y, int update); void texture_draw_bg_gl(texture_type* ptexture, int update); void texture_draw_part_gl(texture_type* ptexture, float sx, float sy, float x, float y, float w, float h, int update); -void texture_create_gl(SDL_Surface * surf, GLint * tex); +void texture_create_gl(SDL_Surface * surf, GLuint * tex); #endif #endif /*SUPERTUX_TEXTURE_H*/ diff --git a/src/timer.c b/src/timer.c index 41b60d1df..ffe58cd05 100644 --- a/src/timer.c +++ b/src/timer.c @@ -14,6 +14,8 @@ #include "defines.h" #include "timer.h" +unsigned int st_pause_ticks, st_pause_count; + unsigned int st_get_ticks(void) { if(st_pause_count != 0) diff --git a/src/timer.h b/src/timer.h index e99aa1dad..9529242bc 100644 --- a/src/timer.h +++ b/src/timer.h @@ -21,8 +21,7 @@ typedef struct timer_type } timer_type; -unsigned int st_pause_ticks; -unsigned int st_pause_count; +extern unsigned int st_pause_ticks, st_pause_count; unsigned int st_get_ticks(void); void st_pause_ticks_init(void); diff --git a/src/title.c b/src/title.c index 39a99b906..9908fa105 100644 --- a/src/title.c +++ b/src/title.c @@ -32,23 +32,30 @@ #include "menu.h" #include "texture.h" #include "timer.h" - +#include "setup.h" +#include "level.h" +#include "gameloop.h" +#include "leveleditor.h" /* --- TITLE SCREEN --- */ int title(void) { - texture_type title, anim1, anim2; + texture_type title, img_choose_subset, anim1, anim2; SDL_Event event; SDLKey key; - int done, quit, frame, pict; + int done, quit, frame, pict, i; char str[80]; + char **level_subsets; + level_subsets = NULL; + int subsets_num; + level_subsets = dsubdirs("/levels", "info", &subsets_num); + st_subset subset; + subset_init(&subset); - game_started = 0; - level_editor_started = 0; - - /* Init menu variables */ - initmenu(); + /* Rest menu variables */ + menu_reset(); + menu_set_current(&main_menu); clearscreen(0, 0, 0); updatescreen(); @@ -58,20 +65,17 @@ int title(void) texture_load(&title,DATA_PREFIX "/images/title/title.png", IGNORE_ALPHA); texture_load(&anim1,DATA_PREFIX "/images/title/title-anim2.png", IGNORE_ALPHA); texture_load(&anim2,DATA_PREFIX "/images/title/title-anim1.png", IGNORE_ALPHA); - + texture_load(&img_choose_subset,DATA_PREFIX "/images/status/choose-level-subset.png", IGNORE_ALPHA); /* --- Main title loop: --- */ done = 0; quit = 0; show_menu = 1; - frame = 0; - /* Draw the title background: */ - texture_draw(&title, 0, 0, NO_UPDATE); - + texture_draw_bg(&title, NO_UPDATE); /* Draw the high score: */ load_hs(); @@ -82,10 +86,7 @@ int title(void) while (!done && !quit) { - frame++; - - /* Handle events: */ while (SDL_PollEvent(&event)) @@ -125,32 +126,102 @@ int title(void) menuaction = MN_HIT; } - #endif } - if(use_gl || menu_change) - { - /* Draw the title background: */ + /* Draw the title background: */ - texture_draw_bg(&title, NO_UPDATE); + texture_draw_bg(&title, NO_UPDATE); - /* Draw the high score: */ - sprintf(str, "High score: %d", hs_score); - text_drawf(&gold_text, str, 0, -40, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE); - sprintf(str, "by %s", hs_name); - text_drawf(&gold_text, str, 0, -20, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE); - - } + /* Draw the high score: */ + sprintf(str, "High score: %d", hs_score); + text_drawf(&gold_text, str, 0, -40, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE); + sprintf(str, "by %s", hs_name); + text_drawf(&gold_text, str, 0, -20, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE); /* Don't draw menu, if quit is true */ if(show_menu && !quit) - quit = drawmenu(); - - if(game_started || level_editor_started) - done = 1; + menu_process_current(); + if(current_menu == &main_menu) + { + switch (menu_check(&main_menu)) + { + case 0: + done = 0; + i = 0; + subset_load(&subset,level_subsets[0]); + while(!done) + { + texture_draw(&img_choose_subset, 50, 0, NO_UPDATE); + if(subsets_num != 0) + { + texture_draw(&subset.image,135,78,NO_UPDATE); + text_drawf(&gold_text, subset.title, 0, 20, A_HMIDDLE, A_TOP, 1, NO_UPDATE); + } + updatescreen(); + SDL_Delay(50); + while(SDL_PollEvent(&event) && !done) + { + switch(event.type) + { + case SDL_QUIT: + done = 1; + quit = 1; + case SDL_KEYDOWN: // key pressed + /* Keypress... */ + + key = event.key.keysym.sym; + + if(key == SDLK_LEFT) + { + if(i > 0) + { + --i; + subset_free(&subset); + subset_load(&subset,level_subsets[i]); + } + } + else if(key == SDLK_RIGHT) + { + if(i < subsets_num -1) + { + ++i; + subset_free(&subset); + subset_load(&subset,level_subsets[i]); + } + } + else if(key == SDLK_SPACE || key == SDLK_RETURN) + { + done = YES; + quit = gameloop(subset.name,1,ST_GL_PLAY); + subset_free(&subset); + } + else if(key == SDLK_ESCAPE) + { + done = YES; + } + break; + default: + break; + } + } + } + break; + case 3: + done = 1; + quit = leveleditor(1); + break; + case 4: + quit = 1; + break; + } + } + else if(current_menu == &options_menu) + { + process_options_menu(); + } /* Animate title screen: */ pict = (frame / 5) % 3; @@ -161,7 +232,7 @@ int title(void) texture_draw(&anim1, 560, 270, NO_UPDATE); else if (pict == 2) texture_draw(&anim2, 560, 270, NO_UPDATE); - + flipscreen(); /* Pause: */ @@ -169,14 +240,12 @@ int title(void) SDL_Delay(50); } - - /* Free surfaces: */ texture_free(&title); texture_free(&anim1); texture_free(&anim2); - + free_strings(level_subsets,subsets_num); /* Return to main! */ diff --git a/src/type.h b/src/type.h index f2d472bf3..0eb6d4227 100644 --- a/src/type.h +++ b/src/type.h @@ -29,7 +29,5 @@ typedef struct base_type } base_type; -//double get_frame_ratio(base_type* pbase); - #endif /*SUPERTUX_TYPE_H*/ diff --git a/src/world.c b/src/world.c index 0afcff486..05bac447e 100644 --- a/src/world.c +++ b/src/world.c @@ -18,6 +18,7 @@ #include "defines.h" #include "world.h" +texture_type img_distro[4]; void bouncy_distro_init(bouncy_distro_type* pbouncy_distro, float x, float y) { @@ -75,6 +76,7 @@ void broken_brick_action(broken_brick_type* pbroken_brick) void broken_brick_draw(broken_brick_type* pbroken_brick) { +SDL_Rect src, dest; if (pbroken_brick->base.alive) { src.x = rand() % 16; @@ -82,8 +84,8 @@ void broken_brick_draw(broken_brick_type* pbroken_brick) src.w = 16; src.h = 16; - dest.x = pbroken_brick->base.x - scroll_x; - dest.y = pbroken_brick->base.y; + dest.x = (int)(pbroken_brick->base.x - scroll_x); + dest.y = (int)pbroken_brick->base.y; dest.w = 16; dest.h = 16; @@ -126,25 +128,26 @@ void bouncy_brick_action(bouncy_brick_type* pbouncy_brick) void bouncy_brick_draw(bouncy_brick_type* pbouncy_brick) { int s; - + SDL_Rect dest; + if (pbouncy_brick->base.alive) { if (pbouncy_brick->base.x >= scroll_x - 32 && pbouncy_brick->base.x <= scroll_x + screen->w) { - dest.x = pbouncy_brick->base.x - scroll_x; - dest.y = pbouncy_brick->base.y; + dest.x = (int)(pbouncy_brick->base.x - scroll_x); + dest.y = (int)pbouncy_brick->base.y; dest.w = 32; dest.h = 32; if(current_level.bkgd_image[0] == '\0') { fillrect(pbouncy_brick->base.x - scroll_x,pbouncy_brick->base.y,32,32,current_level.bkgd_red,current_level.bkgd_green, - current_level.bkgd_blue); + current_level.bkgd_blue,0); } else { - s = scroll_x / 30; + s = (int)scroll_x / 30; texture_draw_part(&img_bkgd,dest.x + s,dest.y,dest.x,dest.y,dest.w,dest.h,NO_UPDATE); } @@ -181,7 +184,7 @@ void floating_score_draw(floating_score_type* pfloating_score) { char str[10]; sprintf(str, "%d", pfloating_score->value); - text_draw(&gold_text, str, pfloating_score->base.x + 16 - strlen(str) * 8, pfloating_score->base.y, 1, NO_UPDATE); + text_draw(&gold_text, str, (int)pfloating_score->base.x + 16 - strlen(str) * 8, (int)pfloating_score->base.y, 1, NO_UPDATE); } } diff --git a/src/world.h b/src/world.h index e85ccdaaa..d1dc7c011 100644 --- a/src/world.h +++ b/src/world.h @@ -22,7 +22,7 @@ typedef struct bouncy_distro_type /*It is easier to read the sources IMHO, if we } bouncy_distro_type; -texture_type img_distro[4]; +extern texture_type img_distro[4]; void bouncy_distro_init(bouncy_distro_type* pbouncy_distro, float x, float y); void bouncy_distro_action(bouncy_distro_type* pbouncy_distro);