bool replay_load_syspath(Replay *rpy, const char *path, ReplayReadMode mode) { log_info("Loading %s (%s)", path, replay_mode_string(mode)); SDL_RWops *file; #ifndef __WINDOWS__ if(!strcmp(path, "-")) file = SDL_RWFromFP(stdin,false); else file = SDL_RWFromFile(path, "rb"); #else file = SDL_RWFromFile(path, "rb"); #endif if(!file) { log_warn("SDL_RWFromFile() failed: %s", SDL_GetError()); return false; } bool result = replay_read(rpy, file, mode, path); if(!result) { replay_destroy(rpy); } SDL_RWclose(file); return result; }
void replay_event_loop(void) { while (!quit_services) { if (!replay_connected) { /* this time fudging is to get some of the logging right */ self->link_time = self->boot = now; cManager.uplink->state = AUTHENTICATING; irc_introduce(cManager.uplink->password); replay_connected = 1; } else if (!replay_read()) { log_module(MAIN_LOG, LOG_ERROR, "Connection to server lost."); close_socket(); } timeq_run(); } }
int replay_load(Replay *rpy, char *name) { char *p = replay_getpath(name, !strendswith(name, REPLAY_EXTENSION)); printf("replay_load(): loading %s\n", p); FILE *fp = fopen(p, "r"); free(p); if(!fp) { printf("replay_load(): fopen() failed\n"); return False; } int result = replay_read(rpy, fp); fclose(fp); return result; }
bool replay_load(Replay *rpy, const char *name, ReplayReadMode mode) { char *p = replay_getpath(name, !strendswith(name, REPLAY_EXTENSION)); char *sp = vfs_repr(p, true); log_info("Loading %s (%s)", sp, replay_mode_string(mode)); SDL_RWops *file = vfs_open(p, VFS_MODE_READ); free(p); if(!file) { log_warn("VFS error: %s", vfs_get_error()); free(sp); return false; } bool result = replay_read(rpy, file, mode, sp); if(!result) { replay_destroy(rpy); } free(sp); SDL_RWclose(file); return result; }
void GameLoop::next_screen() { if(nullptr != m_screen) m_screen->stop(); if(nullptr == m_screen) { NetworkMode mode = the_context.configuration->network_mode; if(NetworkMode::SERVER == mode) { m_server_screen = m_screen_factory.create_server(); m_screen = m_server_screen.get(); } else { if(NetworkMode::LOCAL == mode) { m_client.reset(new LocalClient()); } else { if(!the_context.configuration->server_url.has_value()) throw GameException("Client mode requires server_url configuration."); auto net_client = std::make_unique<ENetClient>(the_context.configuration->server_url->c_str(), the_context.configuration->port); // network implementation m_client.reset(new BasicClient(std::move(net_client))); } m_screen_factory.set_client(m_client.get()); // If we want to play back a replay, feed it all to the client // and let the normal timing in the game loop take care of it. auto replay_path = the_context.configuration->replay_path; if(replay_path.has_value() && !std::filesystem::is_regular_file(replay_path.value())) { Log::error("Replay not found: %s", replay_path->u8string().c_str()); replay_path.reset(); } if(replay_path.has_value()) { std::ifstream stream{replay_path.value()}; Journal journal = replay_read(stream); GameMeta meta = journal.meta(); meta.winner = NOONE; // this is currently necessary to prevent early exit m_client->send_reset(meta); m_client->game_start(); for(InputDiscovered id : journal.inputs()) { m_client->send_input(id.input); } m_game_screen = m_screen_factory.create_game(); m_screen = m_game_screen.get(); // We do not copy-save the same game again in replay mode. the_context.configuration->autorecord = false; } else { m_menu_screen = m_screen_factory.create_menu(); m_screen = m_menu_screen.get(); } } // debug //DrawPink pink_draw(m_sdl_factory, 255, 0, 255); //m_pink_screen = std::make_unique<PinkScreen>(std::move(pink_draw)); //m_screen = m_pink_screen.get(); } else if(ServerScreen* serv = dynamic_cast<ServerScreen*>(m_screen)) { m_server_screen.release(); m_screen = nullptr; } else if(MenuScreen* menu = dynamic_cast<MenuScreen*>(m_screen)) { if(MenuScreen::Result::PLAY == menu->result()) { m_client->game_start(); // create game state from meta info m_game_screen = m_screen_factory.create_game(); m_transition_screen = m_screen_factory.create_transition(*menu, *m_game_screen); m_screen = m_transition_screen.get(); } else if(MenuScreen::Result::QUIT == menu->result()) { m_menu_screen.release(); m_screen = nullptr; } } else if(GameScreen* game = dynamic_cast<GameScreen*>(m_screen)) { if(the_context.configuration->replay_path.has_value()) { // After a replay, just exit. // NOTE: if we did not, we would have to restore the autorecord config flag. m_game_screen.release(); m_screen = nullptr; } else { // Go back to menu m_menu_screen = m_screen_factory.create_menu(); m_transition_screen = m_screen_factory.create_transition(*game, *m_menu_screen); m_screen = m_transition_screen.get(); } } else if(TransitionScreen* transition = dynamic_cast<TransitionScreen*>(m_screen)) { m_screen = &transition->successor(); m_transition_screen.release(); // BUG! We keep the predecessor screen around unnecessarily. } else if(PinkScreen* pink = dynamic_cast<PinkScreen*>(m_screen)) { if(m_pink_screen.get() == pink) { DrawPink creme_draw(250, 220, 220); m_creme_screen = std::make_unique<PinkScreen>(std::move(creme_draw)); m_transition_screen = m_screen_factory.create_transition(*pink, *m_creme_screen); m_screen = m_transition_screen.get(); } else { DrawPink pink_draw(255, 0, 255); m_pink_screen = std::make_unique<PinkScreen>(std::move(pink_draw)); m_transition_screen = m_screen_factory.create_transition(*pink, *m_pink_screen); m_screen = m_transition_screen.get(); } } else { assert(false); // unknown type of m_screen } }