LoadPanel::LoadPanel(PlayerInfo &player, UI &gamePanels) : player(player), gamePanels(gamePanels), selectedPilot(player.Identifier()) { // If you have a player loaded, and the player is on a planet, makes sure // the player is saved so that any snapshot you create will be of the // player's current state, rather than one planet ago. if(player.GetPlanet() && !player.IsDead()) player.Save(); UpdateLists(); }
LoadPanel::LoadPanel(PlayerInfo &player, UI &gamePanels) : player(player), gamePanels(gamePanels), selectedPilot(player.Identifier()) { // If you have a player loaded, and the player is on a planet, makes sure // the player is saved so that any snapshot you create will be of the // player's current state, rather than one planet ago. Only do this if the // game is paused, i.e. the "main panel" is not on top: if(player.GetPlanet() && !player.IsDead() && !gamePanels.IsTop(&*gamePanels.Root())) player.Save(); UpdateLists(); }
int main(int argc, char *argv[]) { Conversation conversation; bool debugMode = false; for(const char *const *it = argv + 1; *it; ++it) { string arg = *it; if(arg == "-h" || arg == "--help") { PrintHelp(); return 0; } else if(arg == "-v" || arg == "--version") { PrintVersion(); return 0; } else if(arg == "-t" || arg == "--talk") conversation = LoadConversation(); else if(arg == "-d" || arg == "--debug") debugMode = true; } PlayerInfo player; try { SDL_Init(SDL_INIT_VIDEO); // Begin loading the game data. GameData::BeginLoad(argv); Audio::Init(GameData::Sources()); // On Windows, make sure that the sleep timer has at least 1 ms resolution // to avoid irregular frame rates. #ifdef _WIN32 timeBeginPeriod(1); #endif player.LoadRecent(); player.ApplyChanges(); // Check how big the window can be. SDL_DisplayMode mode; if(SDL_GetCurrentDisplayMode(0, &mode)) return DoError("Unable to query monitor resolution!"); Preferences::Load(); Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI; if(Preferences::Has("fullscreen")) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; // Make the window just slightly smaller than the monitor resolution. int maxWidth = mode.w; int maxHeight = mode.h; // Restore this after toggling fullscreen. int restoreWidth = 0; int restoreHeight = 0; if(maxWidth < 640 || maxHeight < 480) return DoError("Monitor resolution is too small!"); if(Screen::RawWidth() && Screen::RawHeight()) { // Never allow the saved screen width to be leaving less than 100 // pixels free around the window. This avoids the problem where you // maximize without going full-screen, and next time the window pops // up you can't access the resize control because it is offscreen. Screen::SetRaw( min(Screen::RawWidth(), (maxWidth - 100)), min(Screen::RawHeight(), (maxHeight - 100))); if(flags & SDL_WINDOW_FULLSCREEN_DESKTOP) { restoreWidth = Screen::RawWidth(); restoreHeight = Screen::RawHeight(); Screen::SetRaw(maxWidth, maxHeight); } } else Screen::SetRaw(maxWidth - 100, maxHeight - 100); // Make sure the zoom factor is not set too high for the full UI to fit. if(Screen::Height() < 700) Screen::SetZoom(100); // Create the window. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); #ifdef _WIN32 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #endif SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_Window *window = SDL_CreateWindow("Endless Sky", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Screen::RawWidth(), Screen::RawHeight(), flags); if(!window) return DoError("Unable to create window!"); SDL_GLContext context = SDL_GL_CreateContext(window); if(!context) return DoError("Unable to create OpenGL context! Check if your system supports OpenGL 3.0.", window); if(SDL_GL_MakeCurrent(window, context)) return DoError("Unable to set the current OpenGL context!", window, context); SDL_GL_SetSwapInterval(1); // Initialize GLEW. #ifndef __APPLE__ glewExperimental = GL_TRUE; if(glewInit() != GLEW_OK) return DoError("Unable to initialize GLEW!", window, context); #endif // Check that the OpenGL version is high enough. const char *glVersion = reinterpret_cast<const char *>(glGetString(GL_VERSION)); if(!glVersion || !*glVersion) return DoError("Unable to query the OpenGL version!", window, context); const char *glslVersion = reinterpret_cast<const char *>(glGetString(GL_SHADING_LANGUAGE_VERSION)); if(!glslVersion || !*glslVersion) { ostringstream out; out << "Unable to query the GLSL version. OpenGL version is " << glVersion << "."; return DoError(out.str(), window, context); } if(*glVersion < '3') { ostringstream out; out << "Endless Sky requires OpenGL version 3.0 or higher." << endl; out << "Your OpenGL version is " << glVersion << ", GLSL version " << glslVersion << "." << endl; out << "Please update your graphics drivers."; return DoError(out.str(), window, context); } glClearColor(0.f, 0.f, 0.0f, 1.f); glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); GameData::LoadShaders(); { // Check whether this is a high-DPI window. int width = 0; int height = 0; SDL_GL_GetDrawableSize(window, &width, &height); Screen::SetHighDPI(width > Screen::RawWidth() && height > Screen::RawHeight()); // Fix a possible race condition leading to the wrong window dimensions. glViewport(0, 0, width, height); } UI gamePanels; UI menuPanels; menuPanels.Push(new MenuPanel(player, gamePanels)); if(!conversation.IsEmpty()) menuPanels.Push(new ConversationPanel(player, conversation)); string swizzleName = "_texture_swizzle"; #ifndef __APPLE__ const char *extensions = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)); if(!strstr(extensions, swizzleName.c_str())) #else bool hasSwizzle = false; GLint extensionCount; glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); for(GLint i = 0; i < extensionCount && !hasSwizzle; ++i) { const char *extension = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i)); hasSwizzle = (extension && strstr(extension, swizzleName.c_str())); } if(!hasSwizzle) #endif menuPanels.Push(new Dialog( "Note: your computer does not support the \"texture swizzling\" OpenGL feature, " "which Endless Sky uses to draw ships in different colors depending on which " "government they belong to. So, all human ships will be the same color, which " "may be confusing. Consider upgrading your graphics driver (or your OS).")); FrameTimer timer(60); bool isPaused = false; while(!menuPanels.IsDone()) { // Handle any events that occurred in this frame. SDL_Event event; while(SDL_PollEvent(&event)) { UI &activeUI = (menuPanels.IsEmpty() ? gamePanels : menuPanels); // The caps lock key slows the game down (to make it easier to // see and debug things that are happening quickly). if(debugMode && (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) && event.key.keysym.sym == SDLK_CAPSLOCK) { timer.SetFrameRate((event.key.keysym.mod & KMOD_CAPS) ? 10 : 60); } else if(debugMode && event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_BACKQUOTE) { isPaused = !isPaused; } else if(event.type == SDL_KEYDOWN && menuPanels.IsEmpty() && Command(event.key.keysym.sym).Has(Command::MENU) && !gamePanels.IsEmpty() && gamePanels.Top()->IsInterruptible()) { menuPanels.Push(shared_ptr<Panel>( new MenuPanel(player, gamePanels))); } else if(event.type == SDL_QUIT) { menuPanels.Quit(); } else if(event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { int width = event.window.data1 & ~1; int height = event.window.data2 & ~1; if(width != Screen::RawWidth() || height != Screen::RawHeight()) { Screen::SetRaw(width, height); if((event.window.data1 | event.window.data2) & 1) SDL_SetWindowSize(window, Screen::RawWidth(), Screen::RawHeight()); SDL_GL_GetDrawableSize(window, &width, &height); glViewport(0, 0, width, height); } } else if(event.type == SDL_KEYDOWN && (Command(event.key.keysym.sym).Has(Command::FULLSCREEN) || (event.key.keysym.sym == SDLK_RETURN && event.key.keysym.mod & KMOD_ALT))) { if(restoreWidth) { SDL_SetWindowFullscreen(window, 0); Screen::SetRaw(restoreWidth, restoreHeight); SDL_SetWindowSize(window, Screen::RawWidth(), Screen::RawHeight()); restoreWidth = 0; restoreHeight = 0; } else { restoreWidth = Screen::RawWidth(); restoreHeight = Screen::RawHeight(); Screen::SetRaw(maxWidth, maxHeight); SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); } int width, height; SDL_GL_GetDrawableSize(window, &width, &height); glViewport(0, 0, width, height); } else if(activeUI.Handle(event)) { // No need to do anything more! } } Font::ShowUnderlines(SDL_GetModState() & KMOD_ALT); // Tell all the panels to step forward, then draw them. ((!isPaused && menuPanels.IsEmpty()) ? gamePanels : menuPanels).StepAll(); Audio::Step(); // That may have cleared out the menu, in which case we should draw // the game panels instead: (menuPanels.IsEmpty() ? gamePanels : menuPanels).DrawAll(); SDL_GL_SwapWindow(window); timer.Wait(); } // If you quit while landed on a planet, save the game. if(player.GetPlanet()) player.Save(); // The Preferences class reads the screen dimensions, so update them if // the window is full screen: bool isFullscreen = (restoreWidth != 0); Preferences::Set("fullscreen", isFullscreen); if(isFullscreen) Screen::SetRaw(restoreWidth, restoreHeight); Preferences::Save(); Cleanup(window, context); } catch(const runtime_error &error) { DoError(error.what()); } return 0; }
void ReqLogin::OnSuccess() { // Check for session ID or login failure TheVe1ReqManager::Instance()->SetLoggedIn(false); // Format of XML: // <session/> <- Child(1) PXml p = m_xml.getChildNode(1); if (SafeStrCmp(p.getName(), "session")) { #ifdef XML_DEBUG std::cout << "found session element\n"; #endif std::string sessionId = p.getText(); std::string playername; int objId = -1; // object ID for local player // Get player name and object ID for local player p = m_xml.getChildNode(2); if (SafeStrCmp(p.getName(), "playername")) { playername = p.getText(); std::cout << "**Got player name! \"" << playername << "\"\n"; } else { // Got session ID but no player name, WTF ? std::cout << "Got session ID but no player name, WTF??\n"; } p = m_xml.getChildNode(3); if (SafeStrCmp(p.getName(), "objid")) { objId = ToInt(p.getText()); std::cout << "**Got local player object ID: " << objId << "\n"; } else { // Got session ID but we don't know the object ID for the local player. WTF ? std::cout << "Got session ID but we don't know the object ID for the local player. WTF?\n"; } p = m_xml.getChildNode(4); if (SafeStrCmp(p.getName(), "loc")) { int loc = ToInt(p.getText()); // TODO Use ResetLocalPlayer() to set start pos/loc ????? TheGSStartGame::Instance()->SetStartLoc(loc); std::cout << "Got start location: " << loc << "\n"; } else { // Reset here to well known start location. ResetLocalPlayer(); std::cout << "No start location.\n"; } std::cout << "Got session ID! " << sessionId << "\n"; TheVe1ReqManager::Instance()->SetSessionId(sessionId); TheVe1ReqManager::Instance()->SetLoggedIn(true); // Check if we are set up std::string playerInfoFilename = playername + ".txt"; // TODO Sanitise the filename ThePlayerInfoManager::Instance()->SetCurrentPlayer(playerInfoFilename); ThePlayerInfoManager::Instance()->Save(); PlayerInfo* pi = ThePlayerInfoManager::Instance()->GetPI(); pi->PISetInt(PI_KEY("player obj id"), objId); pi->PISetString(PI_KEY("playername"), playername); pi->PISetString(PI_KEY("email"), m_email); pi->Save(); // Set options for this player TheGSOptions::Instance()->LoadSettingsFromPI(pi); // TODO Do we need to set this via ObjectUpdater too, so it gets sent to all clients ? // Set ID of this player object as the local player ID SetLocalPlayerId(objId); Assert(pi); // Play happy logged in sound TheSoundManager::Instance()->PlayWav("Sound/button112.wav"); if (GetGameMode() == AMJU_MODE_EDIT) { TheGame::Instance()->SetCurrentState(TheGSStartGame::Instance()); } else { // Handle research info: session, mode, etc. ChooseMode(); } } else { std::cout << "Didn't get sesssion ID from server :-(\n"; TheGSLoginWaiting::Instance()->SetErrorString("Didn't get session ID from server"); } }