/* create network/local game context and initiate game state: * network needs to receive the level data and a local game * has to load the next level */ int client_game_init_local( char *setname ) { Set_Chart *chart; int i, warp_limit; warp_limit = config.rel_warp_limit; allow_disintegrate = 1; /* the original levelsets do not need these workarounds */ if ( STRCMP( setname, "LBreakout2" ) || STRCMP( setname, "LBreakout1" ) ) { warp_limit = 100; allow_disintegrate = 0; } /* the approach for a local game is to use the same * settings as a network game. the receiving of packets * is simply faked by a local_game context that * runs the game locally. but to use only one game loop * we do not use it directly but apply its modificiations * to game which is visualized */ local_game = game_create( GT_LOCAL, config.diff, warp_limit ); game_set_current( local_game ); game_set_convex_paddle( config.convex ); game_set_ball_auto_return( !config.return_on_click ); game_set_ball_random_angle( config.random_angle ); game_set_ball_accelerated_speed( config.maxballspeed_float ); local_game->localServerGame = 1; /* load levels: * only required for local games. in network both players * just require a single level that can store the incoming * data that is send by the server via the net. */ if ( !strcmp( setname, TOURNAMENT ) ) game_set = levelset_load_all( levelset_names, gameSeed, config.addBonusLevels ); else game_set = levelset_load( setname, ((config.addBonusLevels)?gameSeed:0) ); if ( game_set == 0 ) return 0; /* load highest score so far if any */ chart = chart_set_query(setname); strcpy(best_name,"nobody"); best_score = 0; if (chart) { strcpy(best_name,chart->entries[0].name); best_score = chart->entries[0].score; } /* create client game context */ game = game_create( GT_LOCAL, config.diff, warp_limit ); game_set_current( game ); /* a local game is not limited in its communication */ client_comm_delay = 0; no_comm_since = 0; /* prepare warp icon at frame */ warp_blinks = 4; warp_blink = 1; /* set list of level background ids */ for ( i = 0; i < MAX_LEVELS; i++ ) bkgnd_ids[i] = rand() % bkgnd_count; /* initiate players */ players_clear(); for ( i = 0; i < config.player_count; i++ ) player_add( config.player_names[i], game->diff->lives, levelset_get_first( game_set ) ); cur_player = players_get_first(); /* init first level */ init_level( cur_player, PADDLE_BOTTOM ); /* if only one player don't show score table */ client_state = CS_NONE; if ( player_count > 1 ) set_state( CS_SCORE_TABLE ); else set_state( CS_PLAY ); /* one player starts immediately */ return 1; }
int main(int argc, char **argv) { char user[64]; screen_init(); if (setjmp(fatal_error_jmp_buf) == 0) { char *setname = DEFAULTSET; levelset *set; level *l; gamestate *gs; progress p; int i, action, n, saveslot = 0; gamestate *saves[10]; get_user(user, sizeof(user)); /* * Pick up argv[1] in case it describes an alternate level * set. */ if (argc > 1) setname = argv[1]; set = levelset_load(setname); p = progress_load(set, user); for (i = 0; i < 10; i++) saves[i] = savepos_load(set, user, i); while (1) { action = screen_main_menu(set, saves, p.levnum+1, p.levnum); if (action > 0) { l = set->levels[action-1]; gs = init_game(l); gs->levnum = action; saveslot = 0; } else if (action == -100) { break; /* direct quit from main menu */ } else if (action <= -10) { /* delete a saved position */ n = -action-10; if (saves[n]) gamestate_free(saves[n]); saves[n] = NULL; savepos_del(set, user, n); gs = NULL; } else { /* load a saved position */ n = -action; if (!saves[n]) /* don't segfault */ continue; gs = gamestate_copy(saves[n]); l = set->levels[gs->levnum-1]; saveslot = n; } if (gs) { screen_level_init(); while (gs->status == PLAYING) { gamestate *newgs; int k; screen_level_display(gs, NULL); k = screen_level_getmove(); if (k == 'h' || k == 'j' || k == 'l' || k == 'k') { newgs = make_move(gs, k); gamestate_free(gs); gs = newgs; } else if (k == 's') { n = screen_saveslot_ask('s', saves, saveslot); if (n >= 0) { saveslot = n; saves[saveslot] = gamestate_copy(gs); savepos_save(set, user, saveslot, gs); } } else if (k == 'r') { n = screen_saveslot_ask('r', saves, saveslot); if (n >= 0 && saves[n]) { saveslot = n; gamestate_free(gs); gs = gamestate_copy(saves[saveslot]); l = set->levels[gs->levnum-1]; } } else if (k == 'q') { break; } } if (gs->status != PLAYING) { int increased_level = FALSE; char *msg; if (gs->status == DIED) { msg = "GAME OVER"; } else if (gs->status == COMPLETED) { msg = "LEVEL COMPLETE"; if (p.levnum < gs->levnum) { p.levnum = gs->levnum; p.date = time(NULL); progress_save(set, user, p); increased_level = TRUE; } } else { msg = "!INTERNAL ERROR!"; } screen_level_display(gs, msg); screen_level_finish(); if (increased_level && p.levnum == set->nlevels) { screen_completed_game(); } } } } } else { screen_finish(); fprintf(stderr, "Fatal error: %s\n", fatal_error_string); exit(2); } screen_finish(); return 0; }