From: Tobias Gläßer Date: Tue, 24 Feb 2004 14:43:27 +0000 (+0000) Subject: many code-cleanups. merged leveleditor patch from Ricardo Cruz. Fixed bugs. many... X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=cf865a9388d9dce0422510c5369a2471191d1299;p=supertux.git many code-cleanups. merged leveleditor patch from Ricardo Cruz. Fixed bugs. many improvements to the leveleditor. gameplay is still broken, but a bit better now. a lot more things ... SVN-Revision: 147 --- diff --git a/src/badguy.c b/src/badguy.c index 7f6f28ec0..622d25451 100644 --- a/src/badguy.c +++ b/src/badguy.c @@ -80,11 +80,11 @@ void badguy_action(bad_guy_type* pbad) if (!pbad->dying) { - if (issolid( pbad->base.x - 1, (int) pbad->base.y)) + if (issolid( pbad->base.x - 1, (int) pbad->base.y + 16)) { pbad->dir = RIGHT; } - else if (issolid( pbad->base.x + pbad->base.width-1, (int) pbad->base.y)) + else if (issolid( pbad->base.x + pbad->base.width-1, (int) pbad->base.y + 16)) { pbad->dir = LEFT; } diff --git a/src/bitmask.h b/src/bitmask.h index 932f8c4a5..cc2b9a430 100644 --- a/src/bitmask.h +++ b/src/bitmask.h @@ -61,8 +61,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef BITMASK_H -#define BITMASK_H +#ifndef SUPERTUX_BITMASK_H +#define SUPERTUX_BITMASK_H #include @@ -140,4 +140,4 @@ void bitmask_draw(bitmask *a,bitmask *b,int xoffset, int yoffset); /* Create a bitmask from a SDL_Surface */ bitmask* bitmask_create_SDL(SDL_Surface* surf); -#endif +#endif /*SUPERTUX_BITMASK_H*/ diff --git a/src/button.c b/src/button.c index ee7dbc740..be7808a96 100644 --- a/src/button.c +++ b/src/button.c @@ -14,33 +14,25 @@ #include #include "setup.h" #include "screen.h" +#include "globals.h" #include "button.h" -void button_load(button_type* pbutton,char* icon_file, char* text, char* info, int x, int y) +void button_load(button_type* pbutton,char* icon_file, char* info, SDLKey shortcut, int x, int y) { -char filename[1024]; + char filename[1024]; -if(icon_file != NULL) -{ - snprintf(filename, 1024, "%s/%s", DATA_PREFIX, icon_file); - if(!faccessible(filename)) - snprintf(filename, 1024, "%s/images/icons/default-icon.png", DATA_PREFIX); -} -else -{ -snprintf(filename, 1024, "%s/images/icons/default-icon.png", DATA_PREFIX); -} -texture_load(&pbutton->icon,filename,USE_ALPHA); - - if(text == NULL) + if(icon_file != NULL) { - pbutton->text = NULL; + snprintf(filename, 1024, "%s/%s", DATA_PREFIX, icon_file); + if(!faccessible(filename)) + snprintf(filename, 1024, "%s/images/icons/default-icon.png", DATA_PREFIX); } else { - pbutton->text = (char*) malloc(sizeof(char)*(strlen(text) + 1)); - strcpy(pbutton->text,text); + snprintf(filename, 1024, "%s/images/icons/default-icon.png", DATA_PREFIX); } + texture_load(&pbutton->icon,filename,USE_ALPHA); + if(info == NULL) { pbutton->info = NULL; @@ -50,11 +42,22 @@ texture_load(&pbutton->icon,filename,USE_ALPHA); pbutton->info = (char*) malloc(sizeof(char)*(strlen(info) + 1)); strcpy(pbutton->info,info); } + + pbutton->shortcut = shortcut; + pbutton->x = x; pbutton->y = y; pbutton->w = pbutton->icon.w; pbutton->h = pbutton->icon.h; pbutton->state = -1; + pbutton->show_info = NO; +} + +button_type* button_create(char* icon_file, char* info, SDLKey shortcut, int x, int y) +{ + button_type* pnew_button = (button_type*) malloc(sizeof(button_type)); + button_load(pnew_button,icon_file, info, shortcut, x, y); + return pnew_button; } void button_draw(button_type* pbutton) @@ -62,19 +65,127 @@ void button_draw(button_type* pbutton) fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,75,75,75,200); fillrect(pbutton->x+1,pbutton->y+1,pbutton->w-2,pbutton->h-2,175,175,175,200); texture_draw(&pbutton->icon,pbutton->x,pbutton->y,NO_UPDATE); + if(pbutton->show_info == YES) + { + char str[80]; + if(pbutton->info) + text_draw(&white_small_text, pbutton->info, pbutton->x - strlen(pbutton->info) * white_small_text.w, pbutton->y, 1, NO_UPDATE); + sprintf(str,"(%s)", SDL_GetKeyName(pbutton->shortcut)); + text_draw(&white_small_text, str, pbutton->x - strlen(str) * white_small_text.w, pbutton->y + white_small_text.h+2, 1, NO_UPDATE); + } } void button_free(button_type* pbutton) { -free(pbutton->text); -free(pbutton->info); -texture_free(&pbutton->icon); + free(pbutton->info); + texture_free(&pbutton->icon); +} + +void button_event(button_type* pbutton, SDL_Event *event) +{ + if(event->type == SDL_KEYDOWN) + { + SDLKey key = event->key.keysym.sym; + if(key == pbutton->shortcut) + pbutton->state = BN_CLICKED; + } + else if(event->motion.x > pbutton->x && event->motion.x < pbutton->x + pbutton->w && + event->motion.y > pbutton->y && event->motion.y < pbutton->y + pbutton->h) + { + if(event->type == SDL_MOUSEBUTTONDOWN) + { + if(event->button.button == SDL_BUTTON_LEFT) + { + pbutton->state = BN_PRESSED; + } + else + { + pbutton->show_info = YES; + } + } + if(event->type == SDL_MOUSEBUTTONUP) + { + if(event->button.button == SDL_BUTTON_LEFT && pbutton->state == BN_PRESSED) + { + pbutton->state = BN_CLICKED; + } + else if(event->button.button != SDL_BUTTON_LEFT && pbutton->state != BN_PRESSED) + { + pbutton->show_info = YES; + } + } + } + else if(event->type == SDL_MOUSEMOTION) + { + + if(pbutton->show_info) + { + pbutton->show_info = NO; + } + } +} + +int button_get_state(button_type* pbutton) +{ + int state; + if(pbutton->state == BN_CLICKED) + { + state = pbutton->state; + pbutton->state = -1; + return state; + } + else + return pbutton->state; +} + +void button_panel_init(button_panel_type* pbutton_panel, int x, int y, int w, int h) +{ + pbutton_panel->num_items = 0; + pbutton_panel->item = NULL; + pbutton_panel->x = x; + pbutton_panel->y = y; + pbutton_panel->w = w; + pbutton_panel->h = h; +} + +void button_panel_free(button_panel_type* pbutton_panel) +{ + int i; + for(i = 0; i < pbutton_panel->num_items; ++i) + { + button_free(&pbutton_panel->item[i]); + } + if(pbutton_panel->num_items) + free(pbutton_panel->item); } -int button_pressed(button_type* pbutton, int x, int y) +void button_panel_draw(button_panel_type* pbutton_panel) { -if(x >= pbutton->x && x <= pbutton->x + pbutton->w && y >= pbutton->y && y <= pbutton->y + pbutton->h) -return YES; -else -return NO; + int i; + for(i = 0; i < pbutton_panel->num_items; ++i) + { + button_draw(&pbutton_panel->item[i]); + } } + +void button_panel_additem(button_panel_type* pbutton_panel, button_type* pbutton) +{ +int max_cols, row, col; + + ++pbutton_panel->num_items; + pbutton_panel->item = (button_type*) realloc(pbutton_panel->item, sizeof(button_type) * pbutton_panel->num_items); + memcpy(&pbutton_panel->item[pbutton_panel->num_items-1],pbutton,sizeof(button_type)); + free(pbutton); + + /* A button_panel takes control of the buttons it contains and arranges them */ + + max_cols = pbutton_panel->w / 32; + + row = pbutton_panel->num_items / max_cols; + col = pbutton_panel->num_items % max_cols; + + pbutton_panel->item[pbutton_panel->num_items-1].x = pbutton_panel->x + row * 32; + pbutton_panel->item[pbutton_panel->num_items-1].y = pbutton_panel->y + col * 32; + +} + diff --git a/src/button.h b/src/button.h index 12925fa5d..030702afe 100644 --- a/src/button.h +++ b/src/button.h @@ -1,7 +1,7 @@ // // C Interface: button // -// Description: +// Description: // // // Author: Tobias Glaesser , (C) 2004 @@ -15,25 +15,44 @@ #include "texture.h" +enum { + BN_CLICKED, + BN_PRESSED +}; + typedef struct button_type { texture_type icon; char *info; - char *text; + SDLKey shortcut; int x; int y; int w; int h; + int show_info; int state; - } button_type; - -void button_load(button_type* pbutton,char* icon_file, char* text, char* info, int x, int y); + } +button_type; + +void button_load(button_type* pbutton,char* icon_file, char* info, SDLKey shortcut, int x, int y); +button_type* button_create(char* icon_file, char* info, SDLKey shortcut, int x, int y); void button_draw(button_type* pbutton); void button_free(button_type* pbutton); -int button_pressed(button_type* pbutton, int x, int y); +void button_event(button_type* pbutton, SDL_Event* event); +int button_get_state(button_type* pbutton); -enum { - BN_PRESSED -}; +typedef struct button_panel_type + { + int num_items; + int x,y; + int w,h; + button_type* item; + } +button_panel_type; + +void button_panel_init(button_panel_type* pbutton_panel, int x, int y, int w, int h); +void button_panel_free(button_panel_type* pbutton_panel); +void button_panel_draw(button_panel_type* pbutton_panel); +void button_panel_additem(button_panel_type* pbutton_panel, button_type* pbutton); #endif /*SUPERTUX_BUTTON_H*/ diff --git a/src/gameloop.c b/src/gameloop.c index 28a995659..54b1c03ce 100644 --- a/src/gameloop.c +++ b/src/gameloop.c @@ -41,27 +41,26 @@ /* extern variables */ -extern char* soundfilenames[NUM_SOUNDS]; st_level current_level; +int game_started = NO; /* Local variables: */ -texture_type img_waves[3], img_water, img_pole, img_poletop, img_flag[2]; -texture_type img_cloud[2][4]; -SDL_Event event; -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; +static texture_type img_waves[3], img_water, img_pole, img_poletop, img_flag[2]; +static texture_type img_cloud[2][4]; +static SDL_Event event; +static SDLKey key; +static char level_subset[100]; +static char str[60]; +static float fps_fps; +static int st_gl_mode; +static unsigned int last_update_time; +static unsigned int update_time; +static int pause_menu_frame; /* Local function prototypes: */ void levelintro(void); -void initgame(void); void loadshared(void); void unloadshared(void); void drawstatus(void); @@ -146,12 +145,13 @@ void game_event(void) quit = 1; else if(show_menu) { - menu_set_current(&game_menu); + menu_set_current(&game_menu); show_menu = 0; st_pause_ticks_stop(); } else { + menu_set_current(&game_menu); show_menu = 1; st_pause_ticks_start(); } @@ -186,7 +186,15 @@ void game_event(void) break; case SDLK_TAB: if(debug_mode == YES) + { tux.size = !tux.size; + if(tux.size == BIG) + { + tux.base.height = 64; + } + else + tux.base.height = 32; + } break; case SDLK_END: if(debug_mode == YES) @@ -296,7 +304,7 @@ int game_action(void) /* End of a level! */ level++; next_level = 0; - if(st_gl_mode == ST_GL_PLAY) + if(st_gl_mode != ST_GL_TEST) drawresultscreen(); player_level_begin(&tux); } @@ -308,10 +316,10 @@ int game_action(void) if (tux.lives < 0) { - if(st_gl_mode == ST_GL_PLAY) + if(st_gl_mode != ST_GL_TEST) drawendscreen(); - if(st_gl_mode == ST_GL_PLAY) + if(st_gl_mode != ST_GL_TEST) { if (score > hs_score) save_hs(score); @@ -339,7 +347,7 @@ int game_action(void) level_load_gfx(¤t_level); level_free_song(); level_load_song(¤t_level); - if(st_gl_mode == ST_GL_PLAY) + if(st_gl_mode != ST_GL_TEST) levelintro(); start_timers(); } @@ -544,41 +552,43 @@ int gameloop(char * subset, int levelnb, int mode) int fps_cnt, jump, done; timer_type fps_timer, frame_timer; - level = levelnb; + game_started = YES; + st_gl_mode = mode; + level = levelnb; strcpy(level_subset,subset); - /* Clear screen: */ - - clearscreen(0, 0, 0); - updatescreen(); - + if(st_gl_mode != ST_GL_LOAD_GAME) + { + /* Init the game: */ + arrays_init(); + set_defaults(); - /* Init the game: */ - arrays_init(); + if(level_load(¤t_level,level_subset,level) != 0) + exit(1); + level_load_gfx(¤t_level); + activate_bad_guys(); + level_load_song(¤t_level); - menu_reset(); - menu_set_current(&game_menu); + } - initgame(); - loadshared(); - set_defaults(); + player_init(&tux); - if(level_load(¤t_level,level_subset,level) != 0) - exit(1); - level_load_gfx(¤t_level); - activate_bad_guys(); - level_load_song(¤t_level); - if(st_gl_mode == ST_GL_PLAY) + if(st_gl_mode != ST_GL_TEST) load_hs(); - player_init(&tux); + loadshared(); if(st_gl_mode == ST_GL_PLAY) levelintro(); + start_timers(); + if(st_gl_mode == ST_GL_LOAD_GAME) + loadgame(levelnb); + + /* --- MAIN GAME LOOP!!! --- */ jump = NO; @@ -590,9 +600,14 @@ int gameloop(char * subset, int levelnb, int mode) timer_init(&frame_timer); fps_cnt = 0; - while (SDL_PollEvent(&event)) - {} - + /* Clear screen: */ + + clearscreen(0, 0, 0); + updatescreen(); + + while (SDL_PollEvent(&event)) + {} + game_draw(); do { @@ -626,7 +641,10 @@ int gameloop(char * subset, int levelnb, int mode) st_pause_ticks_stop(); break; case 1: - savegame(); + update_load_save_game_menu(&save_game_menu, NO); + break; + case 2: + update_load_save_game_menu(&load_game_menu, YES); break; case 4: done = 1; @@ -637,6 +655,14 @@ int gameloop(char * subset, int levelnb, int mode) { process_options_menu(); } + else if(current_menu == &save_game_menu ) + { + process_save_load_game_menu(YES); + } + else if(current_menu == &load_game_menu ) + { + process_save_load_game_menu(NO); + } } @@ -686,8 +712,8 @@ int gameloop(char * subset, int levelnb, int mode) 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); + /*if((update_time - last_update_time) < 10) + SDL_Delay((11 - (update_time - last_update_time))/2);*/ @@ -744,18 +770,12 @@ int gameloop(char * subset, int levelnb, int mode) unloadshared(); arrays_free(); + game_started = NO; + return(quit); } -/* Initialize the game stuff: */ - -void initgame(void) -{ - score = 0; - distros = 0; -} - /* Load graphics/sounds shared between all levels: */ void loadshared(void) @@ -1139,7 +1159,7 @@ void loadshared(void) /* Herring song */ herring_song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + - strlen("SALCON.MOD") + 8)); /* FIXME: We need a real herring_song! Thats a fake.:) */ + strlen("SALCON.MOD") + 8)); sprintf(herring_song_path, "%s/music/%s", DATA_PREFIX, "SALCON.MOD"); @@ -1379,7 +1399,7 @@ int issolid(float x, float y) { return YES; } - + return NO; }*/ @@ -1494,9 +1514,9 @@ void tryemptybox(float x, float y) { if (shape(x, y) == 'A') { - - DEBUG_MSG("Here I am"); - + + DEBUG_MSG("Here I am"); + /* Box with a distro! */ add_bouncy_distro(((x + 1) / 32) * 32, @@ -1615,13 +1635,13 @@ void drawstatus(void) text_draw(&white_text, "SCORE", 0, 0, 1, NO_UPDATE); text_draw(&gold_text, str, 96, 0, 1, NO_UPDATE); - if(st_gl_mode == ST_GL_PLAY) + if(st_gl_mode != ST_GL_TEST) { sprintf(str, "%d", hs_score); text_draw(&white_text, "HIGH", 0, 20, 1, NO_UPDATE); text_draw(&gold_text, str, 96, 20, 1, NO_UPDATE); } - else if(st_gl_mode == ST_GL_TEST) + else { text_draw(&white_text,"Press ESC To Return",0,20,1, NO_UPDATE); } @@ -1689,61 +1709,63 @@ void drawresultscreen(void) SDL_Delay(2000); } -void savegame(void) +void savegame(int slot) { - char savefile[300]; - time_t current_time = time(NULL); - struct tm* time_struct; + char savefile[1024]; FILE* fi; + unsigned int ui; - time_struct = localtime(¤t_time); - sprintf(savefile,"%s/%d-%d-%d-%d.save",st_save_dir,time_struct->tm_year+1900,time_struct->tm_mon,time_struct->tm_mday,time_struct->tm_hour); - printf("%s",savefile); - + sprintf(savefile,"%s/slot%d.save",st_save_dir,slot); fi = fopen(savefile, "wb"); if (fi == NULL) { - fprintf(stderr, "Warning: I could not open the high score file "); + fprintf(stderr, "Warning: I could not open the slot file "); } else { - fwrite(&level,4,1,fi); - fwrite(&score,4,1,fi); - fwrite(&distros,4,1,fi); - fwrite(&tux.base.x,4,1,fi); - fwrite(&tux.base.y,4,1,fi); - fwrite(&scroll_x,4,1,fi); - fwrite(¤t_level.time_left,4,1,fi); + fputs(level_subset, fi); + fputs("\n", fi); + fwrite(&level,sizeof(int),1,fi); + fwrite(&score,sizeof(int),1,fi); + fwrite(&distros,sizeof(int),1,fi); + fwrite(&tux,sizeof(player_type),1,fi); + fwrite(&scroll_x,sizeof(float),1,fi); + fwrite(&time_left,sizeof(float),1,fi); + ui = st_get_ticks(); + fwrite(&ui,sizeof(int),1,fi); } fclose(fi); } -void loadgame(char* filename) +void loadgame(int slot) { - char savefile[300]; + char savefile[1024]; + char str[100]; FILE* fi; - time_t current_time = time(NULL); - struct tm* time_struct; - - time_struct = localtime(¤t_time); - sprintf(savefile,"%s/%d-%d-%d-%d.save",st_save_dir,time_struct->tm_year+1900,time_struct->tm_mon,time_struct->tm_mday,time_struct->tm_hour); - printf("%s",savefile); + unsigned int ui; + sprintf(savefile,"%s/slot%d.save",st_save_dir,slot); fi = fopen(savefile, "rb"); if (fi == NULL) { - fprintf(stderr, "Warning: I could not open the high score file "); + fprintf(stderr, "Warning: I could not open the slot file "); } else { - player_level_begin(&tux); + + + fgets(str, 100, fi); + strcpy(level_subset, str); + level_subset[strlen(level_subset)-1] = '\0'; + fread(&level,sizeof(int),1,fi); + set_defaults(); level_free(¤t_level); if(level_load(¤t_level,level_subset,level) != 0) @@ -1756,16 +1778,58 @@ void loadgame(char* filename) level_free_song(); level_load_song(¤t_level); levelintro(); - start_timers(); + timer_start(&time_left,current_level.time_left*1000); + update_time = st_get_ticks(); + + fread(&score,sizeof(int),1,fi); + fread(&distros,sizeof(int),1,fi); + fread(&tux,sizeof(player_type),1,fi); + fread(&scroll_x,sizeof(float),1,fi); + fread(&time_left,sizeof(float),1,fi); + fread(&ui,sizeof(int),1,fi); + time_left.time += st_get_ticks() - ui; + tux.invincible_timer.time += st_get_ticks() - ui; + tux.skidding_timer.time += st_get_ticks() - ui; + tux.safe_timer.time += st_get_ticks() - ui; + tux.vphysic.start_time += st_get_ticks() - ui; + tux.hphysic.start_time += st_get_ticks() - ui; + tux.vphysic.start_time += st_get_ticks() - ui; + fclose(fi); + } + +} + +void slotinfo(char **pinfo, int slot) +{ + FILE* fi; + char slotfile[1024]; + char tmp[200]; + char str[5]; + int slot_level; + sprintf(slotfile,"%s/slot%d.save",st_save_dir,slot); - fread(&level,4,1,fi); - fread(&score,4,1,fi); - fread(&distros,4,1,fi); - fread(&tux.base.x,4,1,fi); - fread(&tux.base.y,4,1,fi); - fread(&scroll_x,4,1,fi); - fread(¤t_level.time_left,4,1,fi); + fi = fopen(slotfile, "rb"); + + sprintf(tmp,"Slot %d - ",slot); + + if (fi == NULL) + { + strcat(tmp,"Free"); + } + else + { + fgets(str, 100, fi); + str[strlen(str)-1] = '\0'; + strcat(tmp, str); + strcat(tmp, " / Level:"); + fread(&slot_level,sizeof(int),1,fi); + sprintf(str,"%d",slot_level); + strcat(tmp,str); fclose(fi); } + *pinfo = (char*) malloc(sizeof(char) * (strlen(tmp)+1)); + strcpy(*pinfo,tmp); + } + diff --git a/src/gameloop.h b/src/gameloop.h index 21b9e3621..ce8b9a283 100644 --- a/src/gameloop.h +++ b/src/gameloop.h @@ -10,49 +10,28 @@ April 11, 2000 - Junuary 1st, 2004 */ -#if !defined( SUPERTUX_GAMELOOP_H ) -#define SUPERTUX_GAMELOOP_H 1 +#ifndef SUPERTUX_GAMELOOP_H +#define SUPERTUX_GAMELOOP_H #include "sound.h" #include "type.h" #include "level.h" -/* Bounciness of distros: */ - -#define NO_BOUNCE 0 -#define BOUNCE 1 - - -/* One-ups... */ - -#define DISTROS_LIFEUP 100 - - -/* Upgrade types: */ - -enum { - UPGRADE_MINTS, - UPGRADE_COFFEE, - 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 +#define ST_GL_LOAD_GAME 2 + +extern int game_started; +extern st_level current_level; /* Function prototypes: */ int gameloop(char * subset, int levelnb, int mode); -void savegame(void); -void loadgame(char* filename); +void savegame(int slot); +void loadgame(int slot); +void slotinfo(char **pinfo, int slot); int issolid(float x, float y); int isbrick(float x, float y); int isice(float x, float y); @@ -72,5 +51,6 @@ void add_bouncy_brick(float x, float y); void add_bad_guy(float x, float y, int kind); void add_upgrade(float x, float y, int kind); void add_bullet(float x, float y, float xm, int dir); -#endif + +#endif /*SUPERTUX_GAMELOOP_H*/ diff --git a/src/high_scores.h b/src/high_scores.h index c15ade6c9..d5dd38d68 100644 --- a/src/high_scores.h +++ b/src/high_scores.h @@ -5,7 +5,7 @@ */ -# include +#include extern int hs_score; extern char hs_name[62]; /* highscores global variables*/ diff --git a/src/intro.c b/src/intro.c index fffdaf755..ad223786b 100644 --- a/src/intro.c +++ b/src/intro.c @@ -205,7 +205,7 @@ int intro(void) } - if (timer_get_gone(&timer) >= 5000 && timer_get_gone(&timer) <= 8000 && height[j] != 105) + if (timer_get_gone(&timer) >= 5000 && timer_get_gone(&timer) <= 8000) { /* Beam gown up! */ @@ -236,8 +236,6 @@ int intro(void) height[j] = 400 + rand() % 10 - (int)(300. * ((float)(timer_get_gone(&timer) - 5000)/(float)3000.)); if(height[j] < 105) height[j] = 105; - - height_speed[j] = (float)(timer_get_gone(&timer) - 5000) / 300.; } update_rect(screen, diff --git a/src/level.c b/src/level.c index db92a4c72..7a8436594 100644 --- a/src/level.c +++ b/src/level.c @@ -17,6 +17,7 @@ #include "setup.h" #include "screen.h" #include "level.h" +#include "physic.h" texture_type img_bkgd, img_bkgd_tile[2][4], img_solid[4], img_brick[2]; @@ -167,7 +168,13 @@ int level_load(st_level* plevel, char *subset, int level) /* (Level width) */ fgets(str, 10, fi); plevel->width = atoi(str); - + + /* (Level gravity) */ + fgets(str, 10, fi); + plevel->gravity = atof(str); + + /* Set the global gravity to the latest loaded level's gravity */ + gravity = plevel->gravity; /* Allocate some space for the line-reading! */ @@ -241,7 +248,9 @@ void level_save(st_level* plevel, char * subset, int level) fputs(str, fi); sprintf(str, "%d\n", plevel->width); /* level width */ fputs(str, fi); - + sprintf(str, "%2.1f\n", plevel->gravity); /* level gravity */ + fputs(str, fi); + for(y = 0; y < 15; ++y) { fputs((const char*)plevel->tiles[y], fi); diff --git a/src/level.h b/src/level.h index ffadfa5b7..27c94a7f4 100644 --- a/src/level.h +++ b/src/level.h @@ -44,6 +44,7 @@ typedef struct st_level /*It is easier to read the sources IMHO, if we don't wri int bkgd_green; int bkgd_blue; int width; + float gravity; } st_level; extern texture_type img_bkgd, img_bkgd_tile[2][4], img_solid[4], img_brick[2]; diff --git a/src/leveleditor.c b/src/leveleditor.c index 602a35f07..7a50922da 100644 --- a/src/leveleditor.c +++ b/src/leveleditor.c @@ -39,6 +39,7 @@ /* definitions that affect gameplay */ #define KEY_CURSOR_SPEED 32 #define KEY_CURSOR_FASTSPEED 64 + /* when pagedown/up pressed speed:*/ #define PAGE_CURSOR_SPEED 13*32 @@ -48,6 +49,10 @@ so it should subtract that value */ #define MOUSE_POS_SPEED 20 +/* look */ +#define SELECT_W 2 // size of the selections lines +#define SELECT_CLR 0, 255, 0, 255 // lines color (R, G, B, A) + /* gameloop funcs declerations */ void loadshared(void); @@ -65,6 +70,8 @@ void le_showhelp(); void le_set_defaults(void); void le_activate_bad_guys(void); +void le_highlight_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; @@ -81,7 +88,13 @@ 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; +static button_type le_select_mode_one_bt; +static button_type le_select_mode_two_bt; +static button_type le_bad_bsod_bt; +static button_panel_type le_bt_panel; +static square selection; +static int le_selection_mode; static SDL_Event event; void le_activate_bad_guys(void) @@ -123,7 +136,7 @@ int leveleditor(int levelnb) if(le_init() != 0) return 1; - while(1) + while(YES) { last_time = SDL_GetTicks(); le_frame++; @@ -184,7 +197,7 @@ int le_init() subset_load(&le_level_subset,"default"); le_show_grid = YES; -// level_changed = NO; + /* level_changed = NO;*/ fire = DOWN; done = 0; menu_reset(); @@ -211,16 +224,44 @@ int le_init() le_activate_bad_guys(); 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); + + /* Load buttons */ + button_load(&le_test_level_bt,"/images/icons/test-level.png","Test Level",SDLK_F4,150,screen->h - 64); + button_load(&le_next_level_bt,"/images/icons/up.png","Test Level", SDLK_PAGEUP,screen->w-64,0); + button_load(&le_previous_level_bt,"/images/icons/down.png","Test Level",SDLK_PAGEDOWN,screen->w-32,0); + button_load(&le_rubber_bt,"/images/icons/rubber.png","Rubber",SDLK_DELETE,screen->w-64,32); + button_load(&le_select_mode_one_bt,"/images/icons/select-mode1.png","Select Tile",SDLK_F3,screen->w-64,16); + button_load(&le_select_mode_two_bt,"/images/icons/select-mode2.png","Select Tiles",SDLK_F3,screen->w-32,16); + button_load(&le_bad_bsod_bt,"/images/shared/bsod-left-1.png","Select Tiles",'0',screen->w-32,32); + button_panel_init(&le_bt_panel, 500,100, 64, 400); + button_panel_additem(&le_bt_panel, button_create("/images/shared/bsod-left-1.png","Select Tiles",'0',screen->w-32,32)); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); return 0; } +void le_goto_level(int levelnb) +{ + + level_free(&le_current_level); + if(level_load(&le_current_level, le_level_subset.name, levelnb) != 0) + { + level_load(&le_current_level, le_level_subset.name, le_level); + } + else + { + le_level = levelnb; + } + if(le_current_level.time_left == 0) + le_current_level.time_left = 255; + + level_free_gfx(); + level_load_gfx(&le_current_level); + + le_activate_bad_guys(); +} + void le_quit(void) { /*if(level_changed == YES) @@ -261,25 +302,25 @@ void le_drawlevel() { drawshape(x * 32 - ((int)pos_x % 32), y * 32, le_current_level.tiles[y][x + (int)(pos_x / 32)]); - /* draw whats inside stuff when cursor is selecting those */ - /* (draw them all the time - is this the right behaviour?) */ - switch(le_current_level.tiles[y][x + (int)(pos_x/32)]) - { - case 'B': - texture_draw(&img_mints, x * 32 - ((int)pos_x % 32), y*32, NO_UPDATE); - break; - case '!': - texture_draw(&img_golden_herring, x * 32 - ((int)pos_x % 32), y*32, NO_UPDATE); - break; - case 'x': - case 'y': - case 'A': - texture_draw(&img_distro[(frame / 5) % 4], x * 32 - ((int)pos_x % 32), y*32, NO_UPDATE); - break; - default: - break; + /* draw whats inside stuff when cursor is selecting those */ + /* (draw them all the time - is this the right behaviour?) */ + switch(le_current_level.tiles[y][x + (int)(pos_x/32)]) + { + case 'B': + texture_draw(&img_mints, x * 32 - ((int)pos_x % 32), y*32, NO_UPDATE); + break; + case '!': + texture_draw(&img_golden_herring, x * 32 - ((int)pos_x % 32), y*32, NO_UPDATE); + break; + case 'x': + case 'y': + case 'A': + texture_draw(&img_distro[(frame / 5) % 4], x * 32 - ((int)pos_x % 32), y*32, NO_UPDATE); + break; + default: + break; + } } - } /* Draw the Bad guys: */ for (i = 0; i < num_bad_guys; ++i) @@ -295,30 +336,48 @@ void le_drawlevel() texture_draw(&img_money_left[(le_frame / 5) % 2], bad_guys[i].base.x - pos_x, bad_guys[i].base.y, NO_UPDATE); } -/* Draw the player: */ -// for now, the position is fixed at (0, 240) -texture_draw(&tux_right[(frame / 5) % 3], 0 - pos_x, 240, NO_UPDATE); + /* Draw the player: */ + /* for now, the position is fixed at (0, 240) */ + texture_draw(&tux_right[(frame / 5) % 3], 0 - pos_x, 240, NO_UPDATE); /* draw a grid (if selected) */ if(le_show_grid) { - for(x = 0; x < 20; x++) + for(x = 0; x < 19; x++) fillrect(x*32 - ((int)pos_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); } - texture_draw(&le_selection, cursor_x - pos_x, cursor_y, NO_UPDATE); + if(le_selection_mode == CURSOR) + texture_draw(&le_selection, cursor_x - pos_x, cursor_y, NO_UPDATE); + else if(le_selection_mode == SQUARE) + { + int w, h; + le_highlight_selection(); + /* draw current selection */ + w = selection.x2 - selection.x1; + h = selection.y2 - selection.y1; + fillrect(selection.x1 - pos_x, selection.y1, w, SELECT_W, SELECT_CLR); + fillrect(selection.x1 - pos_x + w, selection.y1, SELECT_W, h, SELECT_CLR); + fillrect(selection.x1 - pos_x, selection.y1 + h, w, SELECT_W, SELECT_CLR); + fillrect(selection.x1 - pos_x, selection.y1, SELECT_W, h, SELECT_CLR); + } + /* draw button bar */ - fillrect(screen->w - 32, 0, 32, screen->h, 50, 50, 50,255); + fillrect(screen->w - 64, 0, 64, screen->h, 50, 50, 50,255); drawshape(19 * 32, 14 * 32, le_current_tile); button_draw(&le_test_level_bt); button_draw(&le_next_level_bt); button_draw(&le_previous_level_bt); button_draw(&le_rubber_bt); - + button_draw(&le_select_mode_one_bt); + button_draw(&le_select_mode_two_bt); + button_draw(&le_bad_bsod_bt); + button_panel_draw(&le_bt_panel); + 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); @@ -345,316 +404,442 @@ void le_checkevents() while(SDL_PollEvent(&event)) { /* testing SDL_KEYDOWN, SDL_KEYUP and SDL_QUIT events*/ - switch(event.type) + if(event.type == SDL_KEYDOWN || ((event.type == SDL_MOUSEBUTTONDOWN || SDL_MOUSEMOTION) && (event.motion.x > 0 && event.motion.x < screen->w - 64 && + event.motion.y > 0 && event.motion.y < screen->h))) { - case SDL_KEYDOWN: // key pressed - key = event.key.keysym.sym; - if(show_menu) - { - menu_event(&event.key.keysym); - break; - } - switch(key) + + switch(event.type) { - 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; + 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; - if(cursor_x < pos_x + MOUSE_LEFT_MARGIN) - pos_x = cursor_x - MOUSE_LEFT_MARGIN; + if(cursor_x < pos_x + MOUSE_LEFT_MARGIN) + pos_x = cursor_x - MOUSE_LEFT_MARGIN; - break; - case SDLK_RIGHT: - 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; - if(cursor_x > pos_x + MOUSE_RIGHT_MARGIN-32) - pos_x = cursor_x - MOUSE_RIGHT_MARGIN+32; + if(cursor_x > pos_x + MOUSE_RIGHT_MARGIN-32) + pos_x = cursor_x - MOUSE_RIGHT_MARGIN+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: - 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; - pos_x = cursor_x; - break; - case SDLK_END: - cursor_x = (le_current_level.width * 32) - 32; - pos_x = cursor_x; - break; - case SDLK_PAGEUP: - cursor_x -= PAGE_CURSOR_SPEED; + 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_HOME: + cursor_x = 0; + pos_x = cursor_x; + break; + case SDLK_END: + cursor_x = (le_current_level.width * 32) - 32; + pos_x = cursor_x; + break; + case SDLK_PAGEUP: + cursor_x -= PAGE_CURSOR_SPEED; - if(cursor_x < pos_x + MOUSE_LEFT_MARGIN) - pos_x = cursor_x - MOUSE_LEFT_MARGIN; + if(cursor_x < pos_x + MOUSE_LEFT_MARGIN) + pos_x = cursor_x - MOUSE_LEFT_MARGIN; - break; - case SDLK_PAGEDOWN: - cursor_x += PAGE_CURSOR_SPEED; + break; + case SDLK_PAGEDOWN: + cursor_x += PAGE_CURSOR_SPEED; - if(cursor_x > pos_x + MOUSE_RIGHT_MARGIN-32) - pos_x = cursor_x - MOUSE_RIGHT_MARGIN+32; + if(cursor_x > pos_x + MOUSE_RIGHT_MARGIN-32) + pos_x = cursor_x - MOUSE_RIGHT_MARGIN+32; + 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_current_tile = 'A'; + else + le_current_tile = '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'); + 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'); + break; + case SDLK_2: + le_change(cursor_x, cursor_y, '2'); + 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 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, '^'); + case SDL_KEYUP: // key released + switch(event.key.keysym.sym) + { + case SDLK_LCTRL: + fire = DOWN; + break; + default: + break; + } break; - case SDLK_AMPERSAND: - case SDLK_6: - if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS) - le_change(cursor_x, cursor_y, '&'); + case SDL_MOUSEBUTTONDOWN: + if(event.button.button == SDL_BUTTON_LEFT) + { + le_mouse_pressed = YES; + + selection.x1 = event.motion.x + pos_x; + selection.y1 = event.motion.y; + selection.x2 = event.motion.x + pos_x; + selection.y2 = event.motion.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); + case SDL_MOUSEBUTTONUP: + if(event.button.button == SDL_BUTTON_LEFT) + { + le_mouse_pressed = NO; + } 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'); + case SDL_MOUSEMOTION: + if(!show_menu) + { + x = event.motion.x; + y = event.motion.y; - 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'); + cursor_x = ((int)(pos_x + x) / 32) * 32; + cursor_y = ((int) y / 32) * 32; - 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: + if(le_mouse_pressed == YES) + { + selection.x2 = x + pos_x; + selection.y2 = y; + } + } break; - } - break; - case SDL_KEYUP: // key released - switch(event.key.keysym.sym) - { - case SDLK_LCTRL: - fire = DOWN; + case SDL_QUIT: // window closed + done = DONE_QUIT; 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(event.type == SDL_KEYDOWN || ((event.type == SDL_MOUSEBUTTONDOWN || SDL_MOUSEMOTION) && (event.motion.x > screen->w-64 && event.motion.x < screen->w && + event.motion.y > 0 && event.motion.y < screen->h))) + { + /* Check for button events */ + button_event(&le_test_level_bt,&event); + if(button_get_state(&le_test_level_bt) == BN_CLICKED) + le_testlevel(); + button_event(&le_next_level_bt,&event); + if(button_get_state(&le_next_level_bt) == BN_CLICKED) + { + if(le_level < le_level_subset.levels) + le_goto_level(++le_level); + } + button_event(&le_previous_level_bt,&event); + if(button_get_state(&le_previous_level_bt) == BN_CLICKED) + { + if(le_level > 1) + le_goto_level(--le_level); } + button_event(&le_rubber_bt,&event); + if(button_get_state(&le_rubber_bt) == BN_CLICKED) + le_current_tile = '.'; + button_event(&le_select_mode_one_bt,&event); + if(button_get_state(&le_select_mode_one_bt) == BN_CLICKED) + le_selection_mode = CURSOR; + button_event(&le_select_mode_two_bt,&event); + if(button_get_state(&le_select_mode_two_bt) == BN_CLICKED) + le_selection_mode = SQUARE; + button_event(&le_bad_bsod_bt,&event); + if(button_get_state(&le_bad_bsod_bt) == BN_CLICKED) + le_current_tile = '0'; } if(le_mouse_pressed) { le_change(cursor_x, cursor_y, le_current_tile); - if(button_pressed(&le_test_level_bt,x,y)) - le_testlevel(); } -if(!show_menu) /* scroll screen when mouse is in a margin */ - { - if(event.motion.x > MOUSE_RIGHT_MARGIN && event.motion.x < screen->w-32) - pos_x += MOUSE_POS_SPEED; - else if(event.motion.x > 0 && event.motion.x < MOUSE_LEFT_MARGIN) - pos_x -= MOUSE_POS_SPEED; - } +} + +void le_highlight_selection() +{ + int x,y,i; + int x1, x2, y1, y2; + + if(selection.x1 < selection.x2) + { + x1 = selection.x1; + x2 = selection.x2; + } + else + { + x1 = selection.x2; + x2 = selection.x1; + } + if(selection.y1 < selection.y2) + { + y1 = selection.y1; + y2 = selection.y2; + } + else + { + y1 = selection.y2; + y2 = selection.y1; + } + + x1 /= 32; + x2 /= 32; + y1 /= 32; + y2 /= 32; + + fillrect(x1*32-pos_x, y1*32,32* (x2 - x1 + 1),32 * (y2 - y1 + 1),173,234,177,103); } void le_change(float x, float y, unsigned char c) { - int i; - int xx, yy; + int xx,yy,i; + int x1, x2, y1, y2; - level_change(&le_current_level,x,y,c); + /* level_changed = YES; */ - yy = ((int)y / 32); - xx = ((int)x / 32); + switch(le_selection_mode) + { + case CURSOR: + level_change(&le_current_level,x,y,c); + + 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) + if (bad_guys[i].base.alive) + if(xx == bad_guys[i].base.x/32 && yy == bad_guys[i].base.y/32) + bad_guys[i].base.alive = NO; - /* if there is a bad guy over there, remove it */ - for(i = 0; i < num_bad_guys; ++i) - if (bad_guys[i].base.alive) - if(xx == bad_guys[i].base.x/32 && yy == bad_guys[i].base.y/32) - bad_guys[i].base.alive = NO; + if(c == '0') /* if it's a bad guy */ + add_bad_guy(xx*32, yy*32, BAD_BSOD); + else if(c == '1') + add_bad_guy(xx*32, yy*32, BAD_LAPTOP); + else if(c == '2') + add_bad_guy(xx*32, yy*32, BAD_MONEY); + + break; + case SQUARE: + if(selection.x1 < selection.x2) + { + x1 = selection.x1; + x2 = selection.x2; + } + else + { + x1 = selection.x2; + x2 = selection.x1; + } + if(selection.y1 < selection.y2) + { + y1 = selection.y1; + y2 = selection.y2; + } + else + { + y1 = selection.y2; + y2 = selection.y1; + } + + x1 /= 32; + x2 /= 32; + y1 /= 32; + y2 /= 32; + + /* if there is a bad guy over there, remove it */ + for(i = 0; i < num_bad_guys; ++i) + if(bad_guys[i].base.alive) + if(bad_guys[i].base.x/32 >= x1 && bad_guys[i].base.x/32 <= x2 + && bad_guys[i].base.y/32 >= y1 && bad_guys[i].base.y/32 <= y2) + bad_guys[i].base.alive = NO; + + for(xx = x1; xx <= x2; xx++) + for(yy = y1; yy <= y2; yy++) + { + level_change(&le_current_level, xx*32, yy*32, c); + + if(c == '0') // if it's a bad guy + add_bad_guy(xx*32, yy*32, BAD_BSOD); + else if(c == '1') + add_bad_guy(xx*32, yy*32, BAD_LAPTOP); + else if(c == '2') + add_bad_guy(xx*32, yy*32, BAD_MONEY); + } + break; + default: + break; + } } void le_testlevel() { -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(); + 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(); } void le_showhelp() @@ -683,6 +868,7 @@ void le_showhelp() "0-2 - BadGuys", "./Del - Remove tile", "F9 - Show/Hide Grid", + "F3 - Change Selection Mode", "Esc - Menu"}; diff --git a/src/leveleditor.h b/src/leveleditor.h index e083a6431..0317e8bfc 100644 --- a/src/leveleditor.h +++ b/src/leveleditor.h @@ -12,6 +12,21 @@ /* leveleditor.h - A built-in level editor for SuperTux by Ricardo Cruz */ +#ifndef SUPERTUX_LEVELEDITOR_H +#define SUPERTUX_LEVELEDITOR_H + +typedef struct square + { + int x1, y1, x2, y2; + } +square; + +/* selection modes */ +enum { + CURSOR, + SQUARE +}; + int leveleditor(int levelnb); void newlevel(void); void selectlevel(void); @@ -21,3 +36,4 @@ void testlevel(void); int le_init(void); void le_checkevents(void); +#endif /*SUPERTUX_LEVELEDITOR_H*/ diff --git a/src/menu.c b/src/menu.c index 245995db7..146909cdf 100644 --- a/src/menu.c +++ b/src/menu.c @@ -71,6 +71,16 @@ menu_item_type* menu_item_create(int kind, char *text, int init_toggle, void* ta return pnew_item; } +void menu_item_change_text(menu_item_type* pmenu_item, char *text) +{ + if(text) + { + free(pmenu_item->text); + pmenu_item->text = (char*) malloc(sizeof(char )*(strlen(text)+1)); + strcpy(pmenu_item->text,text); + } +} + /* Free a menu and all its items */ void menu_free(menu_type* pmenu) { @@ -100,6 +110,7 @@ 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)); + free(pmenu_item); } /* Process actions done on the menu */ @@ -199,7 +210,7 @@ int menu_check(menu_type* pmenu) show_menu = 0; return pmenu->active_item; } - else if(pmenu->item[pmenu->active_item].kind == MN_TOGGLE) + else if(pmenu->item[pmenu->active_item].kind == MN_TOGGLE || pmenu->item[pmenu->active_item].kind == MN_GOTO) { return pmenu->active_item; } @@ -273,9 +284,9 @@ void menu_draw(menu_type* pmenu) 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 if(pmenu->item[i].kind == MN_BACK) - { - texture_draw(&back,screen->w / 2 + (strlen(pmenu->item[i].text) * 16)/2 + 16,(i)*24 - menu_height/2 + 10 + screen->h / 2 -8,NO_UPDATE); - } + { + texture_draw(&back,screen->w / 2 + (strlen(pmenu->item[i].text) * 16)/2 + 16,(i)*24 - menu_height/2 + 10 + screen->h / 2 -8,NO_UPDATE); + } } } diff --git a/src/menu.h b/src/menu.h index 64adf9854..98467eb02 100644 --- a/src/menu.h +++ b/src/menu.h @@ -14,6 +14,7 @@ #define SUPERTUX_MENU_H #include +#include "texture.h" typedef struct menu_item_type { @@ -26,6 +27,7 @@ typedef struct menu_item_type menu_item_type; menu_item_type* menu_item_create(int kind, char *text, int init_toggle, void* target_menu); +void menu_item_change_text(menu_item_type* pmenu_item, char *text); typedef struct menu_type { @@ -69,7 +71,7 @@ extern int show_menu; extern int menu_change; extern texture_type checkbox, checkbox_checked, back; -extern menu_type main_menu, game_menu, options_menu, leveleditor_menu, highscore_menu, load_game_menu, save_game_menu;; +extern menu_type main_menu, game_menu, options_menu, leveleditor_menu, highscore_menu, load_game_menu, save_game_menu; extern menu_type* current_menu, * last_menu; /* input implementation variables */ diff --git a/src/physic.c b/src/physic.c index 2988bd0e2..f95c923d7 100644 --- a/src/physic.c +++ b/src/physic.c @@ -14,6 +14,8 @@ #include "defines.h" #include "physic.h" +float gravity; + void physic_init(physic_type* pphysic) { pphysic->state = -1; @@ -37,6 +39,17 @@ void physic_set_start_vy(physic_type* pphysic, float start_vy) pphysic->start_vy = start_vy; } +void physic_set_start_vx(physic_type* pphysic, float start_vx) +{ + pphysic->start_vx = start_vx; +} + +void physic_set_acceleration(physic_type* pphysic, float acceleration) +{ + pphysic->acceleration = acceleration; +} + + int physic_is_set(physic_type* pphysic) { if(pphysic->state != -1) @@ -48,17 +61,19 @@ int physic_is_set(physic_type* pphysic) float physic_get_velocity(physic_type* pphysic) { if(pphysic->state == PH_VT) - return - (pphysic->start_vy - 10.* ((float)(st_get_ticks() - pphysic->start_time))/1000.); + return - (pphysic->start_vy - gravity* ((float)(st_get_ticks() - pphysic->start_time))/1000.); + else if(pphysic->state == PH_HA) + return - (pphysic->start_vx - pphysic->acceleration * ((float)(st_get_ticks() - pphysic->start_time))/1000.); } float physic_get_max_distance(physic_type* pphysic) { - return (pphysic->start_vy * pphysic->start_vy / 2.*10.); + return (pphysic->start_vy * pphysic->start_vy / 2.*gravity); } unsigned int physic_get_max_time(physic_type* pphysic) { - return (unsigned int)((pphysic->start_vy / 10.) * 1000); + return (unsigned int)((pphysic->start_vy / gravity) * 1000); } unsigned int physic_get_time_gone(physic_type* pphysic) diff --git a/src/physic.h b/src/physic.h index 17bf6868f..38f923f20 100644 --- a/src/physic.h +++ b/src/physic.h @@ -16,7 +16,8 @@ #include "timer.h" enum { - PH_VT /* Vertical throw.*/ + PH_VT, /* Vertical throw.*/ + PH_HA /* Horizontal acceleration. */ }; /* Physic type: */ @@ -25,14 +26,21 @@ typedef struct physic_type { int state; float start_vy; + float start_vx; + float acceleration; unsigned int start_time; } physic_type; +/* global variables. */ +extern float gravity; + void physic_init(physic_type* pphysic); int physic_get_state(physic_type* pphysic); void physic_set_state(physic_type* pphysic, int nstate); void physic_set_start_vy(physic_type* pphysic, float start_vy); +void physic_set_start_vx(physic_type* pphysic, float start_vx); +void physic_set_acceleration(physic_type* pphysic, float acceleration); int physic_is_set(physic_type* pphysic); float physic_get_velocity(physic_type* pphysic); float physic_get_max_distance(physic_type* pphysic); diff --git a/src/player.c b/src/player.c index 759bb82d3..459865cc1 100644 --- a/src/player.c +++ b/src/player.c @@ -52,6 +52,8 @@ void player_init(player_type* pplayer) pplayer->frame_main = 0; pplayer->frame = 0; pplayer->lives = 3; + pplayer->score = 0; + pplayer->distros = 0; pplayer->input.down = UP; pplayer->input.fire = UP; @@ -69,6 +71,8 @@ void player_init(player_type* pplayer) timer_init(&pplayer->invincible_timer); timer_init(&pplayer->skidding_timer); timer_init(&pplayer->safe_timer); + physic_init(&pplayer->hphysic); + physic_init(&pplayer->vphysic); } int player_key_event(player_type* pplayer, SDLKey key, int state) @@ -129,8 +133,8 @@ void player_action(player_type* pplayer) /* Move tux: */ - pplayer->base.x= pplayer->base.x+ pplayer->base.xm * frame_ratio; - pplayer->base.y = pplayer->base.y + pplayer->base.ym * frame_ratio; + pplayer->base.x += pplayer->base.xm * frame_ratio; + pplayer->base.y += pplayer->base.ym * frame_ratio; player_keep_in_bounds(pplayer); @@ -138,124 +142,78 @@ void player_action(player_type* pplayer) if (!pplayer->dying) { - /* 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; - }*/ - - /*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; - }*/ - - 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--; - } - - /* Reset score multiplier (for multi-hits): */ - - if (pplayer->base.ym > 0) - score_multiplier = 1; - - - /* 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(physic_is_set(&pplayer->vphysic)) + { + pplayer->base.ym = physic_get_velocity(&pplayer->vphysic); + } + else {*/ - /*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 + 16, pplayer->base.y + pplayer->base.height)) + { + if(!physic_is_set(&pplayer->vphysic)) + { + physic_set_state(&pplayer->vphysic,PH_VT); + physic_set_start_vy(&pplayer->vphysic,0.); + } + pplayer->base.ym = physic_get_velocity(&pplayer->vphysic); + } + else + { + /* Land: */ - 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))*/ + if (pplayer->base.ym > 0) + { + pplayer->base.y = (int)(pplayer->base.y / 32) * 32; + pplayer->base.ym = 0; + } + physic_init(&pplayer->vphysic); + } + + while(issolid( pplayer->base.x + 16, pplayer->base.y + pplayer->base.height) && !issolid( pplayer->base.x + 16, pplayer->base.y)) { - pplayer->base.y = pplayer->base.y- pplayer->base.ym * frame_ratio; - pplayer->base.ym = 0; + --pplayer->base.y; } - - if (((issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y)) && (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y)) - /*(pplayer->size == SMALL || pplayer->duck || - !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))*/) || - (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y+pplayer->base.height) && (issolid(pplayer->base.x, pplayer->base.y+pplayer->base.height) || issolid(pplayer->base.x +32, pplayer->base.y+pplayer->base.height)))) + while(issolid( pplayer->base.x + 16, pplayer->base.y) && !issolid( pplayer->base.x + 16, pplayer->base.y + pplayer->base.height)) { - pplayer->base.x = pplayer->base.x- pplayer->base.xm * frame_ratio; - pplayer->base.xm = 0; + ++pplayer->base.y; } - - if (pplayer->base.ym <= 0) - { - if (isbrick(pplayer->base.x, pplayer->base.y) || - isfullbox(pplayer->base.x, pplayer->base.y)) + while(issolid( pplayer->base.x - 1, pplayer->base.y) || issolid( pplayer->base.x - 1, pplayer->base.y+pplayer->base.height)) + { + ++pplayer->base.x; + } + while(issolid( pplayer->base.x + 32, pplayer->base.y) || issolid( pplayer->base.x + 32, pplayer->base.y+pplayer->base.height)) + { + --pplayer->base.x; + } + + if (isbrick(pplayer->base.x, pplayer->base.y - 1) || + isfullbox(pplayer->base.x, pplayer->base.y - 1)) { 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); + bumpbrick(pplayer->base.x, pplayer->base.y - 1); + tryemptybox(pplayer->base.x, pplayer->base.y - 1); } - if (isbrick(pplayer->base.x+ 31, pplayer->base.y) || - isfullbox(pplayer->base.x+ 31, pplayer->base.y)) + if (isbrick(pplayer->base.x+ 31, pplayer->base.y - 1) || + isfullbox(pplayer->base.x+ 31, pplayer->base.y - 1)) { 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); + bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 1); + tryemptybox(pplayer->base.x+ 31, pplayer->base.y - 1); } + + /* Get a distro from a brick? */ - if (shape(pplayer->base.x, pplayer->base.y) == 'x' || - shape(pplayer->base.x, pplayer->base.y) == 'y') + if (shape(pplayer->base.x, pplayer->base.y - 1) == 'x' || + shape(pplayer->base.x, pplayer->base.y - 1) == 'y') { add_bouncy_distro(((pplayer->base.x+ 1) / 32) * 32, - (int)(pplayer->base.y / 32) * 32); + (int)(pplayer->base.y - 1 / 32) * 32); if (counting_distros == NO) { @@ -264,18 +222,18 @@ void player_action(player_type* pplayer) } if (distro_counter <= 0) - level_change(¤t_level,pplayer->base.x,pplayer->base.y, 'a'); + level_change(¤t_level,pplayer->base.x,pplayer->base.y - 1, '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') + else if (shape(pplayer->base.x+ 31, pplayer->base.y - 1) == 'x' || + shape(pplayer->base.x+ 31, pplayer->base.y - 1) == 'y') { add_bouncy_distro(((pplayer->base.x+ 1 + 31) / 32) * 32, - (int)(pplayer->base.y / 32) * 32); + (int)(pplayer->base.y - 1 / 32) * 32); if (counting_distros == NO) { @@ -284,110 +242,108 @@ void player_action(player_type* pplayer) } if (distro_counter <= 0) - level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y, 'a'); + level_change(¤t_level,pplayer->base.x+ 31, pplayer->base.y - 1, '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))) + + player_grabdistros(pplayer); + + /* 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; + }*/ + + /*if (issolid(pplayer->base.x, pplayer->base.y) && + !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y)) { - if (pplayer->base.ym <= 0) + while (issolid(pplayer->base.x, (pplayer->base.y))) { - /* Jumping up? */ - /* FIXME: this code is COMPLETLY broken!!! */ - if (pplayer->size == BIG) - { - /* Break bricks and empty boxes: * / + if (pplayer->base.xm < 0) + pplayer->base.x++; + else if (pplayer->base.xm > 0) + pplayer->base.x--; + } - if (!pplayer->duck) + pplayer->base.xm = 0; + }*/ + + /*if (issolid(pplayer->base.x, pplayer->base.y + 31)) { - 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); + /* Set down properly: * / - if (isfullbox(pplayer->base.x, pplayer->base.y - 32)) + int debug_int = 0; + while (issolid(pplayer->base.x, pplayer->base.y + 31)) + { + ++debug_int; + if(debug_int > 32) { - bumpbrick(pplayer->base.x, pplayer->base.y - 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; } - - trybreakbrick(pplayer->base.x, pplayer->base.y - 32); - tryemptybox(pplayer->base.x, pplayer->base.y - 32); + if (pplayer->base.ym < 0) + pplayer->base.y++; + else if (pplayer->base.ym > 0) + pplayer->base.y--; } - 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); - } + /* Reset score multiplier (for multi-hits): */ - trybreakbrick(pplayer->base.x+ 31, - pplayer->base.y - 32); - tryemptybox(pplayer->base.x+ 31, - pplayer->base.y - 32); - } - } - else /* ducking * / + if (pplayer->base.ym > 0) + score_multiplier = 1; + + + /* 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))* / { - 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); - } + pplayer->base.y = pplayer->base.y- pplayer->base.ym * frame_ratio; + pplayer->base.ym = 0; + } - 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); - } + if (((issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y)) && (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y)) + /*(pplayer->size == SMALL || pplayer->duck || + !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))* /) || + (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y+pplayer->base.height) && (issolid(pplayer->base.x, pplayer->base.y+pplayer->base.height) || issolid(pplayer->base.x +32, pplayer->base.y+pplayer->base.height)))) + { + pplayer->base.x = pplayer->base.x- pplayer->base.xm * frame_ratio; + pplayer->base.xm = 0; } - } - else - { - /* It's a brick and we're small, make the brick - bounce, and grab any distros above it: * / + if (pplayer->base.ym <= 0) + { if (isbrick(pplayer->base.x, pplayer->base.y) || isfullbox(pplayer->base.x, pplayer->base.y)) { @@ -405,8 +361,6 @@ void player_action(player_type* pplayer) 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' || @@ -449,115 +403,275 @@ void player_action(player_type* pplayer) score = score + SCORE_DISTRO; distros++; } - } - - /* 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 - 32; - } - 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) + { + /* Jumping up? */ + /* FIXME: this code is COMPLETLY broken!!! */ + 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 (isfullbox(pplayer->base.x, pplayer->base.y - 32)) + { + bumpbrick(pplayer->base.x, pplayer->base.y - 32); + } -player_grabdistros(pplayer); + 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 (isfullbox(pplayer->base.x+ + printf("%f",pplayer->base.ym); 31, pplayer->base.y - 32)) + { + bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 32); + } -/* Slow down horizontally: */ + 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 (!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)) + 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 { - /* Slowly on ice or in air: */ + /* It's a brick and we're small, make the brick + bounce, and grab any distros above it: * / + + 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 (pplayer->base.xm > 0) - pplayer->base.xm--; - else if (pplayer->base.xm < 0) - pplayer->base.xm++; + 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 (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') + { + 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'); + + play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + score = score + SCORE_DISTRO; + distros++; + } } - else + + + /* Bump head: * / + + pplayer->base.y = (int)(pplayer->base.y / 32) * 32 + 30; + } + else { - /* Quickly, otherwise: */ + /* Land on feet: * / - pplayer->base.xm = pplayer->base.xm / 2; + pplayer->base.y = (int)(pplayer->base.y / 32) * 32 - 32; } - } + pplayer->base.ym = 0; + pplayer->jumping = NO; + timer_start(&pplayer->jump_timer,MAX_JUMP_TIME); + }*/ + } + } - /* Drop vertically: */ - if (!issolid(pplayer->base.x, pplayer->base.y + 32)) - { - pplayer->base.ym = pplayer->base.ym + GRAVITY; + /* + player_grabdistros(pplayer); + */ - if (pplayer->base.ym > MAX_YM) - pplayer->base.ym = MAX_YM; - } + /* 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->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; + } } + /* Drop vertically: * / -timer_check(&pplayer->safe_timer); + 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; + } + } -/* ---- DONE HANDLING TUX! --- */ -/* Handle invincibility timer: */ + timer_check(&pplayer->safe_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 ? - */ + /* ---- DONE HANDLING TUX! --- */ - 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; - } + /* Handle invincibility timer: */ - /* stop the old music if it's being played */ - if (playing_music()) - halt_music(); - } -/* Handle skidding: */ + 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 ? + */ -timer_check(&pplayer->skidding_timer); -/* End of level? */ + 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 (pplayer->base.x - scroll_x >= endpos && endpos != 0) - { - next_level = 1; - } + /* stop the old music if it's being played */ + if (playing_music()) + halt_music(); + } + + /* Handle skidding: */ + + timer_check(&pplayer->skidding_timer); + + /* End of level? */ + + if (pplayer->base.x - scroll_x >= endpos && endpos != 0) + { + next_level = 1; + } } @@ -643,31 +757,15 @@ void player_handle_horizontal_input(player_type *pplayer, int dir) void player_handle_vertical_input(player_type *pplayer) { - if(!timer_started(&pplayer->jump_timer)) + if(pplayer->input.up == DOWN) { - timer_start(&pplayer->jump_timer,MAX_JUMP_TIME); - - - /* Taking off? */ - - if (!issolid(pplayer->base.x, pplayer->base.y + 32) || - pplayer->base.ym != 0) + if (issolid(pplayer->base.x + 16, pplayer->base.y + pplayer->base.height + 1)) { - /* 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! */ - - if (pplayer->size == SMALL || pplayer->duck == NO || - !issolid(pplayer->base.x, pplayer->base.y)) + if(!physic_is_set(&pplayer->vphysic)) { + physic_set_state(&pplayer->vphysic,PH_VT); + physic_set_start_vy(&pplayer->vphysic,5.2); pplayer->jumping = YES; - if (pplayer->size == SMALL) play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER); else @@ -675,15 +773,80 @@ void player_handle_vertical_input(player_type *pplayer) } } } + else if(pplayer->input.up == UP && pplayer->jumping == YES) + { + /* Land: * / + DEBUG_MSG("Stop Jump"); + pplayer->jumping = NO; + + if (pplayer->base.ym > 0) + { + pplayer->base.y = (int)(pplayer->base.y / 32) * 32; + pplayer->base.ym = 0; + } + physic_init(&pplayer->vphysic); + } + else if(pplayer->input.up == UP) + {*/ + if (issolid(pplayer->base.x + 16, pplayer->base.y + pplayer->base.height + 1)) + { + physic_init(&pplayer->vphysic); + pplayer->jumping == NO; + } + else + { + pplayer->jumping = NO; + physic_set_state(&pplayer->vphysic,PH_VT); + physic_set_start_vy(&pplayer->vphysic,0); + if(physic_is_set(&pplayer->vphysic) && pplayer->vphysic.start_vx != 0) + { + physic_set_start_vy(&pplayer->vphysic,0); + } + else + { + if(!physic_is_set(&pplayer->vphysic)) + { + physic_set_state(&pplayer->vphysic,PH_VT); + } + } + } + } + + /* 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! * / + + pplayer->jumping = NO; + timer_stop(&pplayer->jump_timer); + } + else + { + /* Make sure we're not standing back up into a solid! * / - /* Keep jumping for a while: */ + 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); + } + }*/ + + /* 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; - } + pplayer->base.ym = pplayer->base.ym/*-YM_FOR_JUMP* /; + }*/ } void player_input(player_type *pplayer) @@ -699,15 +862,20 @@ void player_input(player_type *pplayer) { player_handle_horizontal_input(pplayer,LEFT); } + else + { + if(pplayer->base.xm > 0) + pplayer->base.xm = (int)(pplayer->base.xm - frame_ratio); + else if(pplayer->base.xm < 0) + pplayer->base.xm = (int)(pplayer->base.xm + frame_ratio); + } /* Jump/jumping? */ - if ( pplayer->input.up == DOWN) + if ( pplayer->input.up == DOWN || (pplayer->input.up == UP && pplayer->jumping == YES)) { player_handle_vertical_input(pplayer); } - else - timer_stop(&pplayer->jump_timer); /* Shoot! */ @@ -730,7 +898,7 @@ void player_input(player_type *pplayer) { /* Make sure we're not standing back up into a solid! */ - if (!issolid(pplayer->base.x, pplayer->base.y - 32)) + if (!issolid(pplayer->base.x + 16, pplayer->base.y - 16)) pplayer->duck = NO; } else @@ -1118,7 +1286,7 @@ void player_kill(player_type* pplayer, int mode) void player_dying(player_type *pplayer) { - pplayer->base.ym = pplayer->base.ym + GRAVITY; + pplayer->base.ym = pplayer->base.ym + gravity; /* He died :^( */ diff --git a/src/player.h b/src/player.h index 0f4528a67..3167644e4 100644 --- a/src/player.h +++ b/src/player.h @@ -20,6 +20,7 @@ #include "texture.h" #include "collision.h" #include "sound.h" +#include "physic.h" /* Times: */ @@ -27,6 +28,15 @@ #define TUX_INVINCIBLE_TIME 10000 #define TIME_WARNING 20000 /* When to alert player they're low on time! */ +/* One-ups... */ + +#define DISTROS_LIFEUP 100 + +/* Scores: */ + +#define SCORE_BRICK 5 +#define SCORE_DISTRO 25 + typedef struct player_keymap_type { int jump; @@ -52,6 +62,8 @@ typedef struct player_type { player_input_type input; player_keymap_type keymap; + int score; + int distros; int got_coffee; int size; int duck; @@ -63,9 +75,10 @@ typedef struct player_type int lives; base_type base; timer_type invincible_timer; - timer_type jump_timer; timer_type skidding_timer; timer_type safe_timer; + physic_type vphysic; + physic_type hphysic; } player_type; diff --git a/src/screen.c b/src/screen.c index 2387b1372..3301201a6 100644 --- a/src/screen.c +++ b/src/screen.c @@ -34,18 +34,6 @@ #define SGN(x) ((x)>0 ? 1 : ((x)==0 ? 0:(-1))) #define ABS(x) ((x)>0 ? (x) : (-x)) -/* --- LOAD AND DISPLAY AN IMAGE --- */ - -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); -} - - /* --- CLEAR SCREEN --- */ void clearscreen(int r, int g, int b) @@ -104,6 +92,7 @@ void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel) } } +/* Draw a single pixel on the screen. */ void drawpixel(int x, int y, Uint32 pixel) { /* Lock the screen for direct access to the pixels */ @@ -192,6 +181,17 @@ void drawline(int x1, int y1, int x2, int y2, int r, int g, int b, int a) void fillrect(float x, float y, float w, float h, int r, int g, int b, int a) { +if(w < 0) + { + x += w; + w = -w; + } +if(h < 0) + { + y += h; + h = -h; + } + #ifndef NOOPENGL if(use_gl) { @@ -268,36 +268,6 @@ void flipscreen(void) SDL_Flip(screen); } -/* --- LOAD AN IMAGE --- */ - -SDL_Surface * load_image(char * file, int use_alpha) -{ - /* - 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); -} - void update_rect(SDL_Surface *scr, Sint32 x, Sint32 y, Sint32 w, Sint32 h) { if(!use_gl) diff --git a/src/screen.h b/src/screen.h index b6229b662..f8c73eb1f 100644 --- a/src/screen.h +++ b/src/screen.h @@ -24,13 +24,11 @@ #define USE_ALPHA 0 #define IGNORE_ALPHA 1 -void load_and_display_image(char * file); void drawline(int x1, int y1, int x2, int y2, int r, int g, int b, int a); 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); void update_rect(SDL_Surface *scr, Sint32 x, Sint32 y, Sint32 w, Sint32 h); #endif /*SUPERTUX_SCREEN_H*/ diff --git a/src/setup.c b/src/setup.c index 8e299f382..963379b33 100644 --- a/src/setup.c +++ b/src/setup.c @@ -35,6 +35,7 @@ #include "screen.h" #include "texture.h" #include "menu.h" +#include "gameloop.h" /* Local function prototypes: */ @@ -107,7 +108,7 @@ char ** dsubdirs(char *rel_path, char* expected_file, int* num) struct stat buf; sprintf(absolute_filename, "%s/%s", path, direntp->d_name); - + if (stat(absolute_filename, &buf) == 0 && S_ISDIR(buf.st_mode)) { if(expected_file != NULL) @@ -219,7 +220,6 @@ void st_directory_setup(void) /* 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_GOTO,"Load Game",0,&load_game_menu)); @@ -251,13 +251,25 @@ void st_menu(void) menu_init(&load_game_menu); menu_additem(&load_game_menu,menu_item_create(MN_LABEL,"Load Game",0,0)); + menu_additem(&load_game_menu,menu_item_create(MN_DEACTIVE,"Slot 1",0,0)); + menu_additem(&load_game_menu,menu_item_create(MN_DEACTIVE,"Slot 2",0,0)); + menu_additem(&load_game_menu,menu_item_create(MN_DEACTIVE,"Slot 3",0,0)); + menu_additem(&load_game_menu,menu_item_create(MN_DEACTIVE,"Slot 4",0,0)); + menu_additem(&load_game_menu,menu_item_create(MN_DEACTIVE,"Slot 5",0,0)); + menu_additem(&load_game_menu,menu_item_create(MN_BACK,"Back",0,0)); menu_init(&save_game_menu); menu_additem(&save_game_menu,menu_item_create(MN_LABEL,"Save Game",0,0)); - + menu_additem(&save_game_menu,menu_item_create(MN_DEACTIVE,"Slot 1",0,0)); + menu_additem(&save_game_menu,menu_item_create(MN_DEACTIVE,"Slot 2",0,0)); + menu_additem(&save_game_menu,menu_item_create(MN_DEACTIVE,"Slot 3",0,0)); + menu_additem(&save_game_menu,menu_item_create(MN_DEACTIVE,"Slot 4",0,0)); + menu_additem(&save_game_menu,menu_item_create(MN_DEACTIVE,"Slot 5",0,0)); + menu_additem(&save_game_menu,menu_item_create(MN_BACK,"Back",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,&save_game_menu)); + menu_additem(&game_menu,menu_item_create(MN_GOTO,"Save Game",0,&save_game_menu)); menu_additem(&game_menu,menu_item_create(MN_GOTO,"Load Game",0,&load_game_menu)); 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)); @@ -267,6 +279,48 @@ void st_menu(void) } +void update_load_save_game_menu(menu_type* pmenu, int load) +{ + int i; + + for(i = 1; i < 6; ++i) + { + char *tmp; + slotinfo(&tmp,i); + if(load && strlen(tmp) == strlen("Slot X - Free") ) + pmenu->item[i].kind = MN_DEACTIVE; + else + pmenu->item[i].kind = MN_ACTION; + menu_item_change_text(&pmenu->item[i],tmp); + free(tmp); + } +} + +void process_save_load_game_menu(int save) +{ + int slot; + switch (slot = menu_check(save ? &save_game_menu : &load_game_menu)) + { + default: + if(slot != -1) + { + if(save == YES) + { + savegame(slot); + } + else + { + if(game_started == NO) + gameloop("whatever",slot,ST_GL_LOAD_GAME); + else + loadgame(slot); + } + st_pause_ticks_stop(); + } + break; + } +} + /* Handle changes made to global settings in the options menu. */ void process_options_menu(void) { @@ -331,7 +385,7 @@ void st_general_setup(void) texture_load(&checkbox, DATA_PREFIX "/images/status/checkbox.png", USE_ALPHA); texture_load(&checkbox_checked, DATA_PREFIX "/images/status/checkbox-checked.png", USE_ALPHA); texture_load(&back, DATA_PREFIX "/images/status/back.png", USE_ALPHA); - + /* Set icon image: */ seticon(); @@ -355,7 +409,7 @@ void st_general_free(void) texture_free(&checkbox); texture_free(&checkbox_checked); texture_free(&back); - + /* Free menus */ menu_free(&main_menu); diff --git a/src/setup.h b/src/setup.h index fdd5c6b39..df9efe51e 100644 --- a/src/setup.h +++ b/src/setup.h @@ -10,27 +10,31 @@ April 11, 2000 - April 13, 2000 */ -#if !defined( SUPERTUX_SETUP_H ) -#define SUPERTUX_SETUP_H 1 +#ifndef SUPERTUX_SETUP_H +#define SUPERTUX_SETUP_H - #include "sound.h" +#include "menu.h" +#include "sound.h" - int faccessible(char *filename); - 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); - void st_video_setup(void); - 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 +int faccessible(char *filename); +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); +void st_video_setup(void); +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 process_save_load_game_menu(int save); +void update_load_save_game_menu(menu_type* pmenu, int load); +void parseargs(int argc, char * argv[]); + +#endif /*SUPERTUX_SETUP_H*/ diff --git a/src/sound.h b/src/sound.h index 63733131a..eb862edae 100644 --- a/src/sound.h +++ b/src/sound.h @@ -66,6 +66,8 @@ enum { NUM_SOUNDS }; +extern char* soundfilenames[NUM_SOUNDS]; + #ifndef NOSOUND #include diff --git a/src/special.h b/src/special.h index 7190428a9..e7b9eb5b7 100644 --- a/src/special.h +++ b/src/special.h @@ -23,6 +23,14 @@ #include "collision.h" #include "player.h" +/* Upgrade types: */ + +enum { + UPGRADE_MINTS, + UPGRADE_COFFEE, + UPGRADE_HERRING +}; + typedef struct upgrade_type { int kind; diff --git a/src/supertux.c b/src/supertux.c index 9561911e6..3ae6fd9af 100644 --- a/src/supertux.c +++ b/src/supertux.c @@ -3,7 +3,7 @@ Super Tux - by Bill Kendrick + by Bill Kendrick & Tobias Glaesser bill@newbreedsoftware.com http://www.newbreedsoftware.com/supertux/ diff --git a/src/supertux.h b/src/supertux.h index e0dc998db..3daaaf6cf 100644 --- a/src/supertux.h +++ b/src/supertux.h @@ -1,17 +1,19 @@ #ifndef SUPERTUX_SUPERTUX_H #define SUPERTUX_SUPERTUX_H - #ifdef LINUX - #include - #include - #include - #endif - #include "defines.h" - #include "globals.h" - #include "setup.h" - #include "intro.h" - #include "title.h" - #include "gameloop.h" - #include "leveleditor.h" - #include "screen.h" +#ifdef LINUX +#include +#include +#include +#endif + +#include "defines.h" +#include "globals.h" +#include "setup.h" +#include "intro.h" +#include "title.h" +#include "gameloop.h" +#include "leveleditor.h" +#include "screen.h" + #endif /*SUPERTUX_SUPERTUX_H*/ diff --git a/src/title.c b/src/title.c index f6afbcff4..5e2af7668 100644 --- a/src/title.c +++ b/src/title.c @@ -162,10 +162,10 @@ int title(void) subset_load(&subset,level_subsets[0]); while(!done) { - texture_draw(&img_choose_subset, 50, 0, NO_UPDATE); + texture_draw(&img_choose_subset,(screen->w - img_choose_subset.w) / 2, 0, NO_UPDATE); if(subsets_num != 0) { - texture_draw(&subset.image,135,78,NO_UPDATE); + texture_draw(&subset.image,(screen->w - subset.image.w) / 2 + 25,78,NO_UPDATE); text_drawf(&gold_text, subset.title, 0, 20, A_HMIDDLE, A_TOP, 1, NO_UPDATE); } updatescreen(); @@ -218,6 +218,9 @@ int title(void) } } break; + case 1: + update_load_save_game_menu(&load_game_menu, YES); + break; case 3: done = 1; quit = leveleditor(1); @@ -231,6 +234,10 @@ int title(void) { process_options_menu(); } + else if(current_menu == &load_game_menu) + { + process_save_load_game_menu(NO); + } flipscreen(); diff --git a/src/world.c b/src/world.c index 05bac447e..37af9bb9b 100644 --- a/src/world.c +++ b/src/world.c @@ -32,9 +32,9 @@ void bouncy_distro_action(bouncy_distro_type* pbouncy_distro) { if (pbouncy_distro->base.alive) { - pbouncy_distro->base.y = pbouncy_distro->base.y + pbouncy_distro->base.ym; + pbouncy_distro->base.y = pbouncy_distro->base.y + pbouncy_distro->base.ym * frame_ratio; - pbouncy_distro->base.ym++; + pbouncy_distro->base.ym += 1. * frame_ratio; if (pbouncy_distro->base.ym >= 0) pbouncy_distro->base.alive = NO; diff --git a/src/world.h b/src/world.h index d1dc7c011..5acc38936 100644 --- a/src/world.h +++ b/src/world.h @@ -16,6 +16,11 @@ #include #include "type.h" +/* Bounciness of distros: */ + +#define NO_BOUNCE 0 +#define BOUNCE 1 + typedef struct bouncy_distro_type /*It is easier to read the sources IMHO, if we don't write something like int a,b,c; */ { base_type base;