/* ==================================================================== Create a framed progress bar. ==================================================================== */ GuiWidget *gui_progressbar_create( GuiWidget *parent, int x, int y, int width, int height, void (*user_event_handler)(GuiWidget*,GuiEvent*), int max, int value ) { GuiWidget *widget = gui_widget_create( parent, GUI_PROGRESSBAR, x, y, width, height, default_event_handler, user_event_handler ); /* create surface, wallpaper and frame it */ widget->surface = stk_surface_create( SDL_SWSURFACE, width, height ); SDL_SetColorKey( widget->surface, 0,0 ); stk_surface_apply_wallpaper( widget->surface, 0,0,-1,-1, gui_theme->widget_wallpaper, -1 ); widget->border = stk_surface_apply_frame( widget->surface, 0, 0, -1, -1, gui_theme->widget_frame ); /* size w/o border */ widget->width -= 2 * widget->border; widget->height -= 2 * widget->border; /* set value */ widget->spec.progressbar.max = max; gui_progressbar_set_value( widget, value ); /* done */ return widget; }
GuiWidget* gui_radiogroup_create( GuiWidget *parent, int x, int y, int width, int height, int with_frame, void (*user_event_handler)(GuiWidget*,GuiEvent*), int item_count, char **items, int min, int max ) { int px, py, i, j, gap = 4; GuiWidget *widget = gui_widget_create( parent, GUI_RADIOGROUP, x, y, width, height, default_event_handler, user_event_handler ); /* events */ gui_widget_enable_event( widget, GUI_CLICKED ); /* create surface, wallpaper and frame it */ widget->surface = stk_surface_create( SDL_SWSURFACE, width, height ); SDL_SetColorKey( widget->surface, 0,0 ); stk_surface_apply_wallpaper( widget->surface, 0,0,-1,-1, gui_theme->widget_wallpaper, -1 ); if ( with_frame ) widget->border = stk_surface_apply_frame( widget->surface, 0, 0, -1, -1, gui_theme->widget_frame ); /* size w/o border */ widget->width -= 2 * widget->border; widget->height -= 2 * widget->border; /* various */ widget->spec.radiogroup.size = item_count; widget->spec.radiogroup.min = min; widget->spec.radiogroup.max = max; widget->spec.radiogroup.single_check = -1; /* compute offset of single items */ widget->spec.radiogroup.offset = (height - 2 * widget->border) / item_count; /* position of first checkbox */ widget->spec.radiogroup.x = widget->border + gap; widget->spec.radiogroup.y = widget->border + (widget->spec.radiogroup.offset - gui_theme->checkbox_size) / 2; /* add empty checkboxes and labels */ gui_theme->label_font->align = STK_FONT_ALIGN_CENTER_Y; px = widget->spec.radiogroup.x; py = widget->spec.radiogroup.y; for ( i = 0, j = 0; i < widget->spec.radiogroup.size; i++, py += widget->spec.radiogroup.offset, j++ ) { stk_surface_blit( gui_theme->checkbox, 0, 0, gui_theme->checkbox_size, gui_theme->checkbox_size, widget->surface, px, py ); stk_font_write( gui_theme->label_font, widget->surface, px + gui_theme->checkbox_size + gap, py + gui_theme->checkbox_size/2, -1, items[j] ); } /* create empty checkers */ widget->spec.radiogroup.checks = calloc( item_count, sizeof( int ) ); if ( widget->spec.radiogroup.checks == 0 ) GUI_ABORT( "Out Of Memory" ); return widget; }
/* ==================================================================== Enter a string and return True if ENTER received and False if ESCAPE received. ==================================================================== */ int enter_string( StkFont *font, char *caption, char *edit, int limit ) { SDL_Event event; int go_on = 1; int ret = 0; SDL_Surface *buffer = stk_surface_create( SDL_SWSURFACE, stk_display->w, stk_display->h ); int length = strlen( edit ); SDL_SetColorKey(buffer, 0, 0); stk_surface_blit( stk_display, 0,0,-1,-1, buffer, 0,0 ); font->align = STK_FONT_ALIGN_CENTER_X | STK_FONT_ALIGN_CENTER_Y; while ( go_on && !stk_quit_request ) { stk_surface_fill( stk_display, 0,0,-1,-1, 0x0 ); stk_surface_alpha_blit( buffer, 0,0,-1,-1, stk_display, 0,0, 128 ); stk_font_write(font, stk_display, stk_display->w / 2, stk_display->h / 2, STK_OPAQUE, caption); write_text_with_cursor(font, stk_display, stk_display->w / 2, stk_display->h / 2 + font->height, edit, STK_OPAQUE); stk_display_update( STK_UPDATE_ALL ); event.type = SDL_NOEVENT; SDL_PollEvent(&event); /* TEST */ switch ( event.type ) { case SDL_QUIT: stk_quit_request = 1; break; case SDL_KEYDOWN: switch ( event.key.keysym.sym ) { case SDLK_ESCAPE: ret = 0; go_on = 0; break; case SDLK_RETURN: ret = 1; go_on = 0; break; case SDLK_BACKSPACE: if ( length > 0 ) edit[--length] = 0; break; default: if ( event.key.keysym.sym >= 32 && event.key.keysym.sym < 128 && length < limit ) { edit[length++] = event.key.keysym.unicode; edit[length] = 0; } break; } break; } } stk_surface_blit( buffer, 0,0,-1,-1, stk_display, 0,0 ); stk_display_update( STK_UPDATE_ALL ); SDL_FreeSurface(buffer); /* reset the relative position so paddle wont jump */ SDL_GetRelativeMouseState(0,0); return ret; }
/* create various resources like shrapnells */ void client_game_create() { frame_create(); shrapnells_init(); shine_load(); init_angles(); /* background */ bkgnd = stk_surface_create( SDL_SWSURFACE, stk_display->w, stk_display->h ); SDL_SetColorKey( bkgnd, 0, 0 ); stk_surface_fill( bkgnd, 0,0,-1,-1, 0x0 ); }
/* ==================================================================== Create shadow surface for specified region in surface. Return Value: Shadow surface ==================================================================== */ SDL_Surface* create_shadow( SDL_Surface *surf, int x, int y, int w, int h ) { SDL_Surface *shadow = 0; int i, j; Uint32 white = SDL_MapRGB( stk_display->format, 0xff, 0xff, 0xff ); Uint32 black = SDL_MapRGB( stk_display->format, 0, 0, 0 ); shadow = stk_surface_create( SDL_SWSURFACE, w, h ); SDL_SetColorKey( shadow, SDL_SRCCOLORKEY, white ); for ( i = 0; i < w; i++ ) for ( j = 0; j < h; j++ ) { if ( surf->flags & SDL_SRCCOLORKEY && stk_surface_get_pixel( surf, i, j ) == surf->format->colorkey ) stk_surface_set_pixel( shadow, i, j, white ); else stk_surface_set_pixel( shadow, i, j, black ); } return shadow; }
/* ==================================================================== Load theme by name or delete current theme (is done by load too so it might be used to change a theme as well.) ==================================================================== */ void theme_load( char *name ) { SDL_Surface *surf; struct stat filestat; char aux[128]; int i; printf( "Loading theme '%s'\n", name ); /* clear resources */ theme_delete(); /* set theme directory */ theme_set_dir( name ); /* load resources */ /* explosions */ exp_pic = theme_load_surf( "explosions.png" ); exp_dark_pic = theme_load_surf( "explosions_dark.png" ); /* main game font */ font = theme_load_font_fixed( "f_game.png", 32, 96, 10 ); font->align = STK_FONT_ALIGN_CENTER_X | STK_FONT_ALIGN_CENTER_Y; /* normal chat font (messages by server) */ chat_font_normal = theme_load_font_fixed( "f_small_yellow.png", 32, 96, 8 ); /* error font (messages by server) */ chat_font_error = theme_load_font_fixed( "f_small_red.png", 32, 96, 8 ); /* username font (also for server) */ chat_font_name = theme_load_font_fixed( "f_small_white.png", 32, 96, 8 ); /* main game sounds */ #ifdef AUDIO_ENABLED wav_click = theme_load_sound( "click.wav" ); wav_damn = theme_load_sound( "damn.wav" ); wav_dammit = theme_load_sound( "dammit.wav" ); wav_wontgiveup = theme_load_sound( "wontgiveup.wav" ); wav_excellent = theme_load_sound( "excellent.wav" ); wav_verygood = theme_load_sound( "verygood.wav" ); #endif /* brick pics and shadow template */ brick_pic = theme_load_surf( "bricks.png" ); /* default color key is: BLACK but you may specify a special key by adding a column of one pixel width at the end of the file */ if ( brick_pic->w & 1 ) SDL_SetColorKey( brick_pic, SDL_SRCCOLORKEY, stk_surface_get_pixel( brick_pic, brick_pic->w - 1, 0 ) ); brick_shadow = create_shadow( brick_pic, 0, 0, brick_pic->w, brick_pic->h ); /* brick destruction sound */ #ifdef AUDIO_ENABLED wav_boom = theme_load_sound( "exp.wav" ); #endif /* paddle and weapon */ paddle_pic = theme_load_surf( "paddle.png" ); SDL_SetColorKey( paddle_pic, SDL_SRCCOLORKEY, stk_surface_get_pixel( paddle_pic, 0, 0 ) ); if ( paddle_pic->w < 6 * paddle_cw ) { /* no top paddle specified so duplicate first one */ surf = stk_surface_create( SDL_SWSURFACE, paddle_pic->w*2, paddle_pic->h ); SDL_SetColorKey( surf, SDL_SRCCOLORKEY, paddle_pic->format->colorkey ); SDL_FillRect( surf, 0, paddle_pic->format->colorkey ); stk_surface_blit( paddle_pic, 0,0,-1,-1, surf, 0,0 ); stk_surface_blit( paddle_pic, 0,0,-1,-1, surf, paddle_pic->w,0 ); stk_surface_free( &paddle_pic ); paddle_pic = surf; } weapon_pic = theme_load_surf( "weapon.png" ); paddle_shadow = create_shadow( paddle_pic, 0, 0, paddle_pic->w, paddle_pic->h ); weapon_shadow = create_shadow( weapon_pic, 0, 0, weapon_pic->w, weapon_pic->h ); ammo_pic = theme_load_surf( "ammo.png" ); SDL_SetColorKey( ammo_pic, SDL_SRCCOLORKEY, 0x0 ); /* paddle sounds */ #ifdef AUDIO_ENABLED wav_expand = theme_load_sound( "expand.wav" ); wav_shrink = theme_load_sound( "shrink.wav" ); wav_frozen = theme_load_sound( "freeze.wav" ); #endif /* ball gfx */ ball_pic = theme_load_surf( "ball.png" ); SDL_SetColorKey( ball_pic, SDL_SRCCOLORKEY, stk_surface_get_pixel( ball_pic, 0, 0 ) ); ball_shadow = create_shadow( ball_pic, 0, 0, ball_w, ball_h ); /* ball sounds */ #ifdef AUDIO_ENABLED wav_reflect_brick = theme_load_sound( "reflect_brick.wav" ); wav_reflect_paddle = theme_load_sound( "reflect_paddle.wav" ); wav_attach = theme_load_sound( "attach.wav" ); #endif /* shot gfx */ shot_pic = theme_load_surf( "shot.png" ); shot_shadow = create_shadow( shot_pic, 0, 0, shot_w, shot_h ); #ifdef AUDIO_ENABLED wav_shot = theme_load_sound( "shot.wav" ); #endif /* extra pic */ extra_pic = theme_load_surf( "extras.png" ); SDL_SetColorKey( extra_pic, 0, 0 ); /* default color key is: disabled but you may specify a special key by adding a column of one pixel width at the end of the file */ if ( extra_pic->w & 1 ) SDL_SetColorKey( extra_pic, SDL_SRCCOLORKEY, stk_surface_get_pixel( extra_pic, extra_pic->w - 1, 0 ) ); extra_shadow = create_shadow( extra_pic, 0, 0, extra_pic->w, extra_pic->h ); /* extra sounds */ #ifdef AUDIO_ENABLED wav_score = theme_load_sound( "score.wav" ); wav_metal = theme_load_sound( "metal.wav" ); wav_speedup = theme_load_sound( "speedup.wav" ); wav_speeddown = theme_load_sound( "speeddown.wav" ); wav_std = theme_load_sound( "standard.wav" ); wav_wall = theme_load_sound( "wall.wav" ); wav_joker = theme_load_sound( "joker.wav" ); wav_goldshower = theme_load_sound( "goldshower.wav" ); wav_chaos = theme_load_sound( "chaos.wav" ); wav_darkness = theme_load_sound( "darkness.wav" ); wav_ghost = theme_load_sound( "ghost.wav" ); wav_timeadd = theme_load_sound( "timeadd.wav" ); wav_expl_ball = theme_load_sound( "expl_ball.wav" ); wav_weak_ball = theme_load_sound( "weak_ball.wav" ); wav_bonus_magnet = theme_load_sound( "bonus_magnet.wav" ); wav_malus_magnet = theme_load_sound( "malus_magnet.wav" ); wav_disable = theme_load_sound( "disable.wav" ); #endif /* shine pic */ shine_pic = theme_load_surf( "shine.png" ); /* chatroom */ cr_up = theme_load_surf( "scroll_up.png" ); cr_down = theme_load_surf( "scroll_down.png" ); cr_track = theme_load_surf( "scroll_track.png" ); cr_wallpaper = theme_load_surf( "cr_back.png" ); SDL_SetColorKey( cr_wallpaper, 0,0 ); /* frame box */ fr_hori = theme_load_surf( "fr_hori.png" ); fr_vert = theme_load_surf( "fr_vert.png" ); fr_luc = theme_load_surf( "fr_luc.png" ); fr_llc = theme_load_surf( "fr_llc.png" ); fr_ruc = theme_load_surf( "fr_ruc.png" ); fr_rlc = theme_load_surf( "fr_rlc.png" ); /* frame */ theme_load_frame(); /* wall */ sprintf( theme_path, "%s/floor.png", theme_dir ); if ( stat( theme_path, &filestat ) == -1 ) { /* build default floor */ wall_pic = stk_surface_create( SDL_SWSURFACE, stk_display->w - 2 * BRICK_WIDTH, BRICK_HEIGHT ); /* bricks must have been loaded at this point! */ for ( i = 0; i < MAP_WIDTH - 2; i++ ) stk_surface_blit( brick_pic, 0, 0, BRICK_WIDTH, BRICK_HEIGHT, wall_pic, i * BRICK_WIDTH, 0 ); } else { /* load floor */ wall_pic = theme_load_surf( "floor.png" ); } /* backgrounds */ theme_load_bkgnds(); /* build nuke bkgnd */ nuke_bkgnd = stk_surface_create( SDL_SWSURFACE, stk_display->w, stk_display->h ); surf = stk_surface_load( SDL_SWSURFACE, "nukeback.png" ); stk_surface_apply_wallpaper( nuke_bkgnd, 0,0,-1,-1, surf, 128 ); stk_surface_free( &surf ); stk_surface_gray( nuke_bkgnd, 0,0,-1,-1, 0 ); /* manager */ mbkgnd = theme_load_surf( "menuback.png" ); SDL_SetColorKey( mbkgnd, 0, 0 ); mfont = theme_load_font_fixed( "f_small_yellow.png", 32, 96, 8 ); mhfont = theme_load_font_fixed( "f_white.png", 32, 96, 10 ); mcfont = theme_load_font_fixed( "f_yellow.png", 32, 96, 10 ); #ifdef AUDIO_ENABLED wav_menu_click = theme_load_sound( "menu_click.wav" ); wav_menu_motion = theme_load_sound( "menu_motion.wav" ); #endif /* add version to background */ mfont->align = STK_FONT_ALIGN_RIGHT | STK_FONT_ALIGN_BOTTOM; sprintf( aux, "v%s", VERSION ); stk_font_write( mfont, mbkgnd, mbkgnd->w - 4, stk_display->h - 4 - mfont->height, STK_OPAQUE, aux ); stk_font_write( mfont, mbkgnd, mbkgnd->w - 4, stk_display->h - 4, STK_OPAQUE, "http://lgames.sf.net" ); /* charts */ /* load resources */ cfont = theme_load_font_fixed( "f_small_yellow.png", 32, 96, 8 ); chfont = theme_load_font_fixed( "f_small_white.png", 32, 96, 8 ); ccfont = theme_load_font_fixed( "f_yellow.png", 32, 96, 10 ); /* warp picture */ warp_pic = theme_load_surf( "warp.png" ); }
int confirm( StkFont *font, char *str, int type ) { SDL_Event event; int go_on = 1; int ret = 0; SDL_Surface *buffer = stk_surface_create( SDL_SWSURFACE, stk_display->w, stk_display->h ); SDL_SetColorKey(buffer, 0, 0); #ifdef AUDIO_ENABLED stk_sound_play( wav_click ); #endif event_clear_sdl_queue(); stk_surface_blit( stk_display, 0,0,-1,-1, buffer, 0,0 ); if ( type == CONFIRM_PAUSE ) stk_surface_gray( stk_display, 0,0,-1,-1,0 ); else draw_confirm_screen( font, buffer, str ); stk_display_update( STK_UPDATE_ALL ); while (go_on && !stk_quit_request) { SDL_WaitEvent(&event); /* TEST */ switch ( event.type ) { case SDL_QUIT: stk_quit_request = 1; break; case SDL_MOUSEBUTTONUP: if ( type == CONFIRM_ANY_KEY ) { ret = 1; go_on = 0; } /* else if ( type == CONFIRM_YES_NO ) { if ( event.button.button == LEFT_BUTTON ) ret = 1; else ret = 0; go_on = 0; }*/ break; case SDL_KEYDOWN: if ( type == CONFIRM_ANY_KEY ) { ret = 1; go_on = 0; break; } else if ( type == CONFIRM_PAUSE ) { if ( event.key.keysym.sym == SDLK_p ) { ret = 1; go_on = 0; break; } else if ( event.key.keysym.sym == SDLK_f ) { config.fullscreen = !config.fullscreen; stk_display_apply_fullscreen( config.fullscreen ); draw_confirm_screen( font, buffer, str ); stk_display_update( STK_UPDATE_ALL ); } } else switch (event.key.keysym.sym) { case SDLK_y: go_on = 0; ret = 1; break; case SDLK_ESCAPE: case SDLK_n: go_on = 0; ret = 0; default: break; } break; } } #ifdef AUDIO_ENABLED stk_sound_play( wav_click ); #endif stk_surface_blit( buffer, 0,0,-1,-1, stk_display, 0,0 ); stk_display_update( STK_UPDATE_ALL ); SDL_FreeSurface(buffer); /* reset the relative position so paddle wont jump */ SDL_GetRelativeMouseState(0,0); return ret; }
/* ==================================================================== Enter nuke mode and allow player to disintegrate single bricks by spending 5% of his/her score. ==================================================================== */ void game_nuke( void ) { char buf[128]; SDL_Event event; int x,y,i,j,leave = 0; SDL_Surface *buffer = stk_surface_create( SDL_SWSURFACE, stk_display->w, stk_display->h ); SDL_Surface *red_mask = stk_surface_create( SDL_SWSURFACE, BRICK_WIDTH, BRICK_HEIGHT ); stk_surface_fill( red_mask, 0,0,-1,-1, 0xFF0000 ); SDL_SetAlpha( red_mask, SDL_SRCALPHA, 128 ); SDL_SetColorKey(buffer, 0, 0); #ifdef AUDIO_ENABLED stk_sound_play( wav_click ); #endif SDL_SetEventFilter(0); event_clear_sdl_queue(); /* backup screen contents */ stk_surface_blit( stk_display, 0,0,-1,-1, buffer, 0,0 ); /* display bricks darkened */ stk_surface_blit( nuke_bkgnd, 0,0,-1,-1, stk_display, 0,0 ); for ( i = 1; i < MAP_WIDTH - 1; i++ ) for ( j = 1; j < MAP_HEIGHT - 1; j++ ) if ( game->bricks[i][j].id >= 0 ) stk_surface_alpha_blit( brick_pic, game->bricks[i][j].id * BRICK_WIDTH, 0, BRICK_WIDTH, BRICK_HEIGHT, stk_display, i*BRICK_WIDTH, j*BRICK_HEIGHT, 128 ); /* info */ font->align = STK_FONT_ALIGN_LEFT; sprintf( buf, "Plane Of Inner Stability entered (Score: %i)", l_paddle->player->stats.total_score + l_paddle->score ); stk_font_write( font, stk_display, BRICK_WIDTH, (MAP_HEIGHT-1)*BRICK_HEIGHT, 128, buf ); /* show score of player */ stk_display_update( STK_UPDATE_ALL ); x = y = -1; while (!leave && !stk_quit_request) { SDL_WaitEvent(&event); switch ( event.type ) { case SDL_QUIT: stk_quit_request = 1; break; case SDL_MOUSEBUTTONDOWN: if ( x != -1 ) if ( confirm( font, "Disintegrate Brick? (Costs 5% of your score.) y/n", CONFIRM_YES_NO ) ) { /* implant a bomb to this brick and return */ game_set_current( local_game ); brick_start_expl( x,y, BRICK_EXP_TIME, local_game->paddles[0] ); local_game->bricks[x][y].score = 0; game_set_current( game ); l_paddle->player->stats.total_score -= (int)(0.05 * (l_paddle->score + l_paddle->player->stats.total_score)); leave = 1; } break; case SDL_MOUSEMOTION: if ( x != -1 ) { /* clear old selection */ stk_surface_blit( nuke_bkgnd, x*BRICK_WIDTH, y*BRICK_HEIGHT, BRICK_WIDTH, BRICK_HEIGHT, stk_display, x*BRICK_WIDTH, y*BRICK_HEIGHT ); stk_surface_alpha_blit( brick_pic, game->bricks[x][y].id * BRICK_WIDTH, 0, BRICK_WIDTH, BRICK_HEIGHT, stk_display, x*BRICK_WIDTH, y*BRICK_HEIGHT, 128 ); stk_display_store_drect(); x = y = -1; } /* make new selection if brick */ i = event.motion.x / BRICK_WIDTH; j = event.motion.y / BRICK_HEIGHT; if ( i >= 1 && i <= MAP_WIDTH -2 ) if ( j >= 1 && j <= MAP_HEIGHT - 2 ) if ( game->bricks[i][j].id >= 0 ) { x = i; y = j; stk_surface_blit( red_mask, 0,0,-1,-1, stk_display,x*BRICK_WIDTH, y*BRICK_HEIGHT ); stk_display_store_drect(); } break; case SDL_KEYDOWN: if ( event.key.keysym.sym == SDLK_ESCAPE ) leave = 1; break; } stk_display_update( STK_UPDATE_RECTS ); } stk_surface_blit( buffer, 0,0,-1,-1, stk_display, 0,0 ); stk_display_update( STK_UPDATE_ALL ); SDL_FreeSurface(red_mask); SDL_FreeSurface(buffer); SDL_SetEventFilter(event_filter); }
/* ==================================================================== Display a info message (gray screen a bit and display text), send a MSG_READY when player has clicked and wait for a remote answer (timeout 10 secs). Waiting may be cancelled by pressing ESCAPE which results in sending a MSG_GAME_EXITED. Return Value: True if both peers clicked to continue, False if the connection was cancelled for some reason. ==================================================================== */ int display_info( StkFont *font, char *str, NetSocket *peer ) { #if 0 char error[128]; Net_Msg msg; SDL_Event event; int ret = 0, leave = 0; SDL_Surface *buffer = stk_surface_create( SDL_SWSURFACE, stk_display->w, stk_display->h ); SDL_SetColorKey(buffer, 0, 0); #ifdef AUDIO_ENABLED stk_sound_play( wav_click ); #endif event_clear_sdl_queue(); stk_surface_blit( stk_display, 0,0,-1,-1, buffer, 0,0 ); draw_confirm_screen( font, buffer, str ); stk_display_update( STK_UPDATE_ALL ); stk_wait_for_input(); net_write_empty_msg( peer, MSG_READY ); draw_confirm_screen( font, buffer, "Waiting for remote answer..." ); stk_display_update( STK_UPDATE_ALL ); event_clear_sdl_queue(); while ( !leave ) { if ( SDL_PollEvent( &event ) ) if ( (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE) || event.type == SDL_QUIT ) { net_write_empty_msg( peer, MSG_GAME_EXITED ); leave = 1; break; } if ( net_read_msg( peer, &msg, 0 ) ) switch ( msg.type ) { case MSG_READY: ret = 1; leave = 1; break; case MSG_GAME_EXITED: ret = 0; leave = 1; sprintf( error, "remote player cancelled the game\n" ); confirm( font, error, CONFIRM_ANY_KEY ); break; } SDL_Delay( 10 ); } #ifdef AUDIO_ENABLED stk_sound_play( wav_click ); #endif stk_surface_blit( buffer, 0,0,-1,-1, stk_display, 0,0 ); stk_display_update( STK_UPDATE_ALL ); SDL_FreeSurface(buffer); /* reset the relative position so paddle wont jump */ SDL_GetRelativeMouseState(0,0); return ret; #endif return 1; }
/* modify the client and its state according to the key pressed */ static int handle_default_key( int key, int *abort ) { SDL_Surface *buffer; switch ( key ) { case SDLK_F1: case SDLK_h: if ( client_state != CS_PLAY ) break; if ( game->game_type == GT_NETWORK ) break; /* only for single player */ grab_input(0); help_run(); grab_input(1); return 1; case SDLK_q: case SDLK_ESCAPE: /* recv_stats or final_stats means we already broke up * the game so ESC will directly quit */ if ( client_state == CS_RECV_STATS || client_state == CS_FINAL_STATS ) { *abort = 1; break; } if ( client_state == CS_CONFIRM_QUIT ) break; if ( client_state == CS_PAUSE ) break; if ( players_count() == 0 ) break; set_state(CS_CONFIRM_QUIT); if ( game->game_type == GT_LOCAL && game_set != 0 /*not testing a level*/ ) display_text( font, "Quit Game? y/n#(If yes, this game may be resumed later.#No highscore entry is created yet.)" ); else display_text( font, "Quit Game? y/n" ); return 1; case SDLK_r: if ( client_state != CS_PLAY ) break; if ( game->game_type == GT_NETWORK ) break; /* only for single player */ if ( game_set == 0 ) break; /* test level */ if ( cur_player->lives < 2 ) break; set_state(CS_CONFIRM_RESTART); display_text( font, "Restart Level? y/n" ); return 1; case SDLK_d: if ( client_state != CS_PLAY ) break; if ( game->game_type == GT_NETWORK ) break; /* only for single player */ if ( !allow_disintegrate ) break; if ( game->level_type != LT_NORMAL ) break; /* not in bonus levels */ grab_input(0); game_nuke(); grab_input(1); return 1; case SDLK_f: buffer = stk_surface_create( SDL_SWSURFACE, 640, 480 ); SDL_BlitSurface( stk_display, 0, buffer, 0 ); config.fullscreen = !config.fullscreen; stk_display_apply_fullscreen( config.fullscreen ); SDL_BlitSurface( buffer, 0, stk_display, 0 ); stk_display_update( STK_UPDATE_ALL); SDL_FreeSurface( buffer ); return 1; case SDLK_s: #ifdef AUDIO_ENABLED config.sound = !config.sound; stk_audio_enable_sound( config.sound ); #endif return 1; case SDLK_a: config.anim++; if ( config.anim >= 4 ) config.anim = 0; return 1; case SDLK_TAB: stk_display_take_screenshot(); return 1; case SDLK_t: return 0; case SDLK_p: if ( client_state == CS_PLAY ) client_set_pause(1); else if (client_state==CS_PAUSE) client_set_pause(0); return 1; default: if ( client_state != CS_PLAY ) break; if ( game->game_type != GT_LOCAL ) break; if ( game->bricks_left > game->warp_limit ) break; if ( game_set == 0 ) break; /* test level */ if ( game->level_type != LT_NORMAL ) break; /* not in bonus levels */ if ( key == config.k_warp ) { set_state(CS_CONFIRM_WARP); display_text( font, "Warp to next level? y/n" ); return 1; } break; } return 0; }
/* initiate the level of the game context by using the player's * snapshot. the snapshot must've been previously set either by * net update or locally. 'l_pos' is either PADDLE_BOTTOM or TOP * indicating which paddle client controls in network game. */ static int init_level( Player *player, int l_pos ) { int length; char str[32]; /* init level by replacing with the players snapshot. this will * screw the total brick count thus stats are useless for local * game but they are not used anyway as the remote/local game * context contains the real stats */ if ( game->game_type == GT_LOCAL ) game_init( local_game, &player->snapshot ); game_init( game, &player->snapshot ); /* if special level copy the local game data as snapshot */ if ( game->game_type == GT_LOCAL ) if ( player->snapshot.type!=LT_NORMAL ) memcpy( game->bricks, local_game->bricks, sizeof(game->bricks) ); /* initiate frame for game type */ frame_init(); /* create offscreen */ offscreen = stk_surface_create( SDL_SWSURFACE, stk_display->w, stk_display->h ); SDL_SetColorKey( offscreen, 0, 0 ); /* add&create background */ if ( game->game_type == GT_LOCAL ) bkgnd_draw( bkgnd, bkgnd_ids[player->level_id] ); else bkgnd_draw( bkgnd, -1 ); /* add frame */ frame_draw(); /* add bricks */ bricks_draw(); /* draw lives */ if ( game->game_type == GT_LOCAL ) frame_draw_lives( player->lives, game->diff->max_lives ); /* determine what is the local and what is the remote paddle and * connect the proper players with each paddle */ if ( game->game_type == GT_LOCAL ) { l_paddle = game->paddles[PADDLE_BOTTOM]; l_paddle->player = player; r_paddle = 0; } else { if ( l_pos == PADDLE_BOTTOM ) { l_paddle = game->paddles[PADDLE_BOTTOM]; r_paddle = game->paddles[PADDLE_TOP]; } else { l_paddle = game->paddles[PADDLE_TOP]; r_paddle = game->paddles[PADDLE_BOTTOM]; } /* player 0 is always the local player */ l_paddle->player = &players[0]; r_paddle->player = &players[1]; /* let top paddle use alternative graphics if any */ if ( paddle_pic->w > 3*paddle_cw ) game->paddles[PADDLE_TOP]->pic_x_offset = 3*paddle_cw; } player->paddle_id = l_pos; /* displays */ if ( game->game_type == GT_LOCAL ) { /* we put these displays to the old positions at the top of the frame */ sprintf( str, "%s", player->name ); length = strlen(best_name); if (strlen(player->name)>length ) length = strlen(player->name); length *= 8; display_player[0] = displays_add( 402, 0, length + 4, 16, str, player->lives, 0 ); display_score[0] = displays_add( stk_display->w - 52 - 76, 0, 76, 16, "", player->stats.total_score, 9 ); display_player[0]->use_alpha = 0; display_score[0]->use_alpha = 0; /* for special levels we need a small display in the right lower corner */ if (game->isBonusLevel) bl_display = displays_add( stk_display->w - BRICK_WIDTH - 20 - 76, ( MAP_HEIGHT - 1 ) * BRICK_HEIGHT + 2, 76, 16, "", 0, 9 ); else bl_display = 0; } else { /* wins */ sprintf( str, "%s ~x%i", game->paddles[0]->player->name, game->paddles[0]->player->stats.wins ); length = strlen( str ) * 8; display_player[0] = displays_add( BRICK_WIDTH + 20, ( MAP_HEIGHT - 1 ) * BRICK_HEIGHT + 2, length + 4, 16, str, 0, 0 ); sprintf( str, "%s ~x%i", game->paddles[1]->player->name, game->paddles[1]->player->stats.wins ); length = strlen( str ) * 8; display_player[1] = displays_add( BRICK_WIDTH + 20, 2, length + 4, 16, str, 0, 0 ); /* scores */ display_score[0] = displays_add( stk_display->w - BRICK_WIDTH - 20 - 76, ( MAP_HEIGHT - 1 ) * BRICK_HEIGHT + 2, 76, 16, "", game->paddles[0]->score, 9 ); display_score[1] = displays_add( stk_display->w - BRICK_WIDTH - 20 - 76, 2, 76, 16, "", game->paddles[1]->score, 9 ); } /* initiate credit */ if ( game->game_type == GT_LOCAL && game_set ) credit_init( game->title, game->author, player->level_id, game_set->count ); else credit_init( game->title, game->author, player->level_id, 0/*don't display info*/ ); /* show offscreen */ stk_surface_blit( offscreen, 0,0,-1,-1, stk_display, 0,0 ); /* no refresh rect as we want to use dim effect */ return 1; }