void Game::TimeStep(float step) { PROFILE_SCOPED() m_time += step; // otherwise planets lag time accel changes by a frame if (m_state == STATE_HYPERSPACE && Pi::game->GetTime() >= m_hyperspaceEndTime) m_time = m_hyperspaceEndTime; m_space->TimeStep(step); // XXX ui updates, not sure if they belong here Pi::cpan->TimeStepUpdate(step); Sfx::TimeStepAll(step, m_space->GetRootFrame()); if (m_state == STATE_HYPERSPACE) { if (Pi::game->GetTime() >= m_hyperspaceEndTime) { SwitchToNormalSpace(); m_player->EnterSystem(); RequestTimeAccel(TIMEACCEL_1X); } else m_hyperspaceProgress += step; return; } if (m_wantHyperspace) { assert(m_state == STATE_NORMAL); SwitchToHyperspace(); return; } }
void Pi::HandleEvents() { SDL_Event event; Pi::mouseMotion[0] = Pi::mouseMotion[1] = 0; while (SDL_PollEvent(&event)) { Gui::HandleSDLEvent(&event); switch (event.type) { case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE) { // only accessible once game started if (currentView != 0) { if (currentView != gameMenuView) { RequestTimeAccel(0); SetTimeAccel(0); SetView(gameMenuView); } else RequestTimeAccel(1); } break; } // special keys. LCTRL+turd if ((KeyState(SDLK_LCTRL) || (KeyState(SDLK_RCTRL)))) { if (event.key.keysym.sym == SDLK_q) Pi::Quit(); if (event.key.keysym.sym == SDLK_s) { Render::ToggleShaders(); } if (event.key.keysym.sym == SDLK_h) { Render::ToggleHDR(); } if (event.key.keysym.sym == SDLK_i) Pi::showDebugInfo = !Pi::showDebugInfo; if (event.key.keysym.sym == SDLK_p) { Sint64 crime, fine; Polit::GetCrime(&crime, &fine); printf("Criminal record: %llx, $%lld\n", crime, fine); Polit::AddCrime(0x1, 100); Polit::GetCrime(&crime, &fine); printf("Criminal record now: %llx, $%lld\n", crime, fine); } if (event.key.keysym.sym == SDLK_PRINT) { char buf[256]; const time_t t = time(0); struct tm *_tm = localtime(&t); strftime(buf, sizeof(buf), "screenshot-%Y%m%d-%H%M%S.tga", _tm); Screendump(buf); fprintf(stderr, "Screendump to %s\n", buf); } #ifdef DEBUG if (event.key.keysym.sym == SDLK_m) { Pi::player->SetMoney(Pi::player->GetMoney() + 10000000); } if (event.key.keysym.sym == SDLK_F12) { matrix4x4d m; Pi::player->GetRotMatrix(m); vector3d dir = m*vector3d(0,0,-1); /* add test object */ if (KeyState(SDLK_RSHIFT)) { Missile *missile = new Missile(ShipType::MISSILE_GUIDED, Pi::player, Pi::player->GetCombatTarget()); missile->SetRotMatrix(m); missile->SetFrame(Pi::player->GetFrame()); missile->SetPosition(Pi::player->GetPosition()+50.0*dir); missile->SetVelocity(Pi::player->GetVelocity()); Space::AddBody(missile); } else if (KeyState(SDLK_LSHIFT)) { SpaceStation *s = static_cast<SpaceStation*>(Pi::player->GetNavTarget()); if (s) { int port = s->GetFreeDockingPort(); if (port != -1) { printf("Putting ship into station\n"); // Make police ship intent on killing the player Ship *ship = new Ship(ShipType::LADYBIRD); ship->AIKill(Pi::player); ship->SetFrame(Pi::player->GetFrame()); ship->SetDockedWith(s, port); Space::AddBody(ship); } else { printf("No docking ports free dude\n"); } } else { printf("Select a space station...\n"); } } else { Ship *ship = new Ship(ShipType::LADYBIRD); ship->m_equipment.Set(Equip::SLOT_LASER, 0, Equip::PULSECANNON_1MW); ship->AIKill(Pi::player); ship->SetFrame(Pi::player->GetFrame()); ship->SetPosition(Pi::player->GetPosition()+100.0*dir); ship->SetVelocity(Pi::player->GetVelocity()); ship->m_equipment.Add(Equip::DRIVE_CLASS2); ship->m_equipment.Add(Equip::RADAR_MAPPER); ship->m_equipment.Add(Equip::SCANNER); ship->m_equipment.Add(Equip::SHIELD_GENERATOR); ship->m_equipment.Add(Equip::HYDROGEN, 10); Space::AddBody(ship); } } #endif /* DEBUG */ // XXX only works on X11 //if (event.key.keysym.sym == SDLK_F11) SDL_WM_ToggleFullScreen(Pi::scrSurface); if (event.key.keysym.sym == SDLK_F10) Pi::SetView(Pi::objectViewerView); if (event.key.keysym.sym == SDLK_F9) { std::string name = join_path(GetFullSavefileDirPath().c_str(), "_quicksave", 0); Serializer::SaveGame(name.c_str()); Pi::cpan->MsgLog()->Message("", "Game saved to "+name); } } Pi::keyState[event.key.keysym.sym] = 1; Pi::keyModState = event.key.keysym.mod; Pi::onKeyPress.emit(&event.key.keysym); break; case SDL_KEYUP: Pi::keyState[event.key.keysym.sym] = 0; Pi::keyModState = event.key.keysym.mod; Pi::onKeyRelease.emit(&event.key.keysym); break; case SDL_MOUSEBUTTONDOWN: Pi::mouseButton[event.button.button] = 1; Pi::onMouseButtonDown.emit(event.button.button, event.button.x, event.button.y); break; case SDL_MOUSEBUTTONUP: Pi::mouseButton[event.button.button] = 0; Pi::onMouseButtonUp.emit(event.button.button, event.button.x, event.button.y); break; case SDL_MOUSEMOTION: Pi::mouseMotion[0] += event.motion.xrel; Pi::mouseMotion[1] += event.motion.yrel; // SDL_GetRelativeMouseState(&Pi::mouseMotion[0], &Pi::mouseMotion[1]); break; case SDL_JOYAXISMOTION: if (joysticks[event.jaxis.which].joystick == NULL) break; if (event.jaxis.value == -32768) joysticks[event.jaxis.which].axes[event.jaxis.axis] = 1.f; else joysticks[event.jaxis.which].axes[event.jaxis.axis] = -event.jaxis.value / 32767.f; break; case SDL_JOYBUTTONUP: case SDL_JOYBUTTONDOWN: if (joysticks[event.jaxis.which].joystick == NULL) break; joysticks[event.jbutton.which].buttons[event.jbutton.button] = event.jbutton.state != 0; break; case SDL_JOYHATMOTION: if (joysticks[event.jaxis.which].joystick == NULL) break; joysticks[event.jhat.which].hats[event.jhat.hat] = event.jhat.value; break; case SDL_QUIT: Pi::Quit(); break; } } }
bool Game::UpdateTimeAccel() { // don't modify the timeaccel if the game is paused if (m_requestedTimeAccel == Game::TIMEACCEL_PAUSED) { SetTimeAccel(Game::TIMEACCEL_PAUSED); return false; } TimeAccel newTimeAccel = m_requestedTimeAccel; // ludicrous speed if (m_player->GetFlightState() == Ship::HYPERSPACE) { newTimeAccel = Game::TIMEACCEL_HYPERSPACE; RequestTimeAccel(newTimeAccel); } // force down to timeaccel 1 during the docking sequence else if (m_player->GetFlightState() == Ship::DOCKING) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10X); RequestTimeAccel(newTimeAccel); } // normal flight else if (m_player->GetFlightState() == Ship::FLYING) { // special timeaccel lock rules while in alert if (m_player->GetAlertState() == Ship::ALERT_SHIP_NEARBY) newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10X); else if (m_player->GetAlertState() == Ship::ALERT_SHIP_FIRING) newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_1X); else if (!m_forceTimeAccel) { // check we aren't too near to objects for timeaccel // for (Space::BodyIterator i = m_space->BodiesBegin(); i != m_space->BodiesEnd(); ++i) { if ((*i) == m_player) continue; if ((*i)->IsType(Object::HYPERSPACECLOUD)) continue; vector3d toBody = m_player->GetPosition() - (*i)->GetPositionRelTo(m_player->GetFrame()); double dist = toBody.Length(); double rad = (*i)->GetBoundingRadius(); if (dist < 1000.0) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_1X); } else if (dist < std::min(rad+0.0001*AU, rad*1.1)) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10X); } else if (dist < std::min(rad+0.001*AU, rad*5.0)) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_100X); } else if (dist < std::min(rad+0.01*AU,rad*10.0)) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_1000X); } else if (dist < std::min(rad+0.1*AU, rad*1000.0)) { newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10000X); } } } } // no change if (newTimeAccel == m_timeAccel) return false; SetTimeAccel(newTimeAccel); return true; }