summaryrefslogtreecommitdiffhomepage
path: root/StarsEx/Starshatter.cpp
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2022-04-01 21:23:39 +0200
committerAki <please@ignore.pl>2022-04-01 21:23:39 +0200
commit3c487c5cd69c53d6fea948643c0a76df03516605 (patch)
tree72730c7b8b26a5ef8fc9a987ec4c16129efd5aac /StarsEx/Starshatter.cpp
parent8f353abd0bfe18baddd8a8250ab7c4f2d1c83a6e (diff)
downloadstarshatter-3c487c5cd69c53d6fea948643c0a76df03516605.zip
starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.gz
starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.bz2
Moved Stars45 to StarsEx
Diffstat (limited to 'StarsEx/Starshatter.cpp')
-rw-r--r--StarsEx/Starshatter.cpp2838
1 files changed, 2838 insertions, 0 deletions
diff --git a/StarsEx/Starshatter.cpp b/StarsEx/Starshatter.cpp
new file mode 100644
index 0000000..77aaca5
--- /dev/null
+++ b/StarsEx/Starshatter.cpp
@@ -0,0 +1,2838 @@
+/* Starshatter: The Open Source Project
+ Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors
+ Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors
+ Copyright (c) 1997-2006, Destroyer Studios LLC.
+
+ AUTHOR: John DiCamillo
+
+*/
+
+
+#include "Starshatter.h"
+
+#include "MenuScreen.h"
+#include "LoadScreen.h"
+#include "PlanScreen.h"
+#include "CmpnScreen.h"
+
+#include "AudioConfig.h"
+#include "MusicDirector.h"
+#include "HUDSounds.h"
+#include "Player.h"
+
+#include "Shot.h"
+#include "Drive.h"
+#include "LandingGear.h"
+#include "Explosion.h"
+#include "FlightDeck.h"
+#include "NavLight.h"
+#include "Debris.h"
+#include "Contact.h"
+#include "QuantumDrive.h"
+#include "Sensor.h"
+#include "Power.h"
+#include "SystemDesign.h"
+#include "WeaponDesign.h"
+
+#include "Campaign.h"
+#include "CampaignSaveGame.h"
+#include "CombatRoster.h"
+#include "CombatZone.h"
+#include "CampaignPlan.h"
+
+#include "Galaxy.h"
+#include "StarSystem.h"
+#include "Mission.h"
+#include "Sim.h"
+#include "SimEvent.h"
+#include "Element.h"
+#include "Ship.h"
+#include "ShipCtrl.h"
+#include "ShipDesign.h"
+#include "HUDView.h"
+#include "Mfd.h"
+#include "RadioMessage.h"
+#include "RadioTraffic.h"
+#include "RadioVox.h"
+#include "CameraDirector.h"
+#include "ModConfig.h"
+#include "KeyMap.h"
+
+#include "GameScreen.h"
+#include "QuantumView.h"
+#include "QuitView.h"
+#include "RadioView.h"
+#include "TacticalView.h"
+#include "DisplayView.h"
+
+#include "LoadDlg.h"
+#include "TacRefDlg.h"
+#include "CmpLoadDlg.h"
+#include "Terrain.h"
+
+#include "NetClientConfig.h"
+#include "NetServerConfig.h"
+#include "NetLayer.h"
+#include "NetLobbyClient.h"
+#include "NetLobbyServer.h"
+#include "NetGame.h"
+#include "NetUtil.h"
+
+#include "ParseUtil.h"
+#include "Token.h"
+
+#include "MachineInfo.h"
+#include "Game.h"
+#include "GameWinDX9.h"
+#include "Clock.h"
+#include "ContentBundle.h"
+#include "VideoFactory.h"
+#include "Screen.h"
+#include "Window.h"
+#include "ActiveWindow.h"
+#include "Button.h"
+#include "CameraView.h"
+#include "ImgView.h"
+#include "FadeView.h"
+#include "Color.h"
+#include "Bitmap.h"
+#include "Font.h"
+#include "FontMgr.h"
+#include "Keyboard.h"
+#include "Joystick.h"
+#include "MouseController.h"
+#include "Mouse.h"
+#include "TrackIR.h"
+#include "EventDispatch.h"
+#include "MultiController.h"
+#include "Archive.h"
+#include "DataLoader.h"
+#include "Random.h"
+#include "Universe.h"
+#include "Video.h"
+#include "VideoSettings.h"
+#include "WebBrowser.h"
+
+// +--------------------------------------------------------------------+
+
+int quick_mode = 0;
+char quick_mission_name[64];
+Mission* quick_mission = 0;
+
+int Starshatter::keymap[256];
+int Starshatter::keyalt[256];
+Starshatter* Starshatter::instance = 0;
+
+static Mission* current_mission = 0;
+static Mission* cutscene_mission = 0;
+static double cutscene_basetime = 0;
+static int cut_efx_volume = 100;
+static int cut_wrn_volume = 100;
+static double time_til_change = 0;
+static bool exit_latch = true;
+static bool show_missions = false;
+static bool use_file_system = false;
+static bool no_splash = false;
+
+enum CHAT_MODES {
+ CHAT_BROADCAST = 1,
+ CHAT_TEAM = 2,
+ CHAT_WING = 3,
+ CHAT_UNIT = 4
+};
+
+// +--------------------------------------------------------------------+
+
+Starshatter::Starshatter()
+: gamewin(0), menuscreen(0), loadscreen(0), planscreen(0),
+cmpnscreen(0), gamescreen(0), splash(0), splash_index(0),
+input(0), loader(0), cam_dir(0), music_dir(0),
+field_of_view(2), time_mark(0), minutes(0),
+player_ship(0), net_lobby(0),
+spinning(false), tactical(false), mouse_x(0), mouse_y(0),
+game_mode(MENU_MODE), mouse_input(0), head_tracker(0),
+terminal(0), verdana(0), limerick18(0), limerick12(0),
+HUDfont(0), GUIfont(0), GUI_small_font(0), title_font(0),
+ocrb(0), req_change_video(0), video_changed(0),
+lens_flare(true), corona(true), nebula(true), dust(0),
+load_step(0), load_progress(0),
+chat_mode(0), exit_time(1.2), cutscene(0)
+{
+ if (!instance)
+ instance = this;
+
+ app_name = "Starshatter: The Open Source Project";
+ title_text = "STARSHATTER";
+ palette_name = "alpha";
+
+ if (!DataLoader::GetLoader())
+ DataLoader::Initialize();
+
+ loader = DataLoader::GetLoader();
+ int loadstat = loader->EnableDatafile("shatter.dat");
+
+ if (loadstat != DataLoader::DATAFILE_OK) {
+ const char* err_msg = loadstat == DataLoader::DATAFILE_INVALID ?
+ "The file 'shatter.dat' appears to have been damaged. Please re-install Starshatter." :
+ "Starshatter cannot open the file 'shatter.dat'. Please re-install Starshatter.";
+
+ ::MessageBox(hwnd, err_msg, "Starshatter - Error", MB_OK);
+ ::Print(err_msg);
+ ::Print("\n\nFATAL ERROR: EXIT.");
+ exit(-1);
+ }
+
+ if (loader->FindFile("vox.dat"))
+ loader->EnableDatafile("vox.dat");
+
+ if (loader->FindFile("start.dat"))
+ loader->EnableDatafile("start.dat");
+
+ if (loader->FindFile("content.dat"))
+ loader->EnableDatafile("content.dat");
+
+ //if (loadstat != DataLoader::DATAFILE_OK) {
+ // const char* err_msg = loadstat == DataLoader::DATAFILE_INVALID ?
+ // "The file 'content.dat' appears to have been damaged. Please re-install the latest Starshatter update." :
+ // "Starshatter cannot open the file 'content.dat'. Please re-install the latest Starshatter update.";
+
+ // ::MessageBox(hwnd, err_msg, "Starshatter - Error", MB_OK);
+ // ::Print(err_msg);
+ // ::Print("\n\nFATAL ERROR: EXIT.");
+ // exit(-1);
+ //}
+
+ LoadVideoConfig("video.cfg");
+
+ // create the fonts
+ loader->SetDataPath("Fonts/");
+
+ HUDfont = new Font("HUDfont");
+ FontMgr::Register("HUD", HUDfont);
+
+ GUIfont = new Font("GUIfont");
+ FontMgr::Register("GUI", GUIfont);
+
+ GUI_small_font = new Font("GUIsmall");
+ FontMgr::Register("GUIsmall", GUI_small_font);
+
+ limerick12 = new Font("Limerick12");
+ limerick18 = new Font("Limerick18");
+ terminal = new Font("Terminal");
+ verdana = new Font("Verdana");
+ ocrb = new Font("OCRB");
+
+ FontMgr::Register("Limerick12", limerick12);
+ FontMgr::Register("Limerick18", limerick18);
+ FontMgr::Register("Terminal", terminal);
+ FontMgr::Register("Verdana", verdana);
+ FontMgr::Register("OCRB", ocrb);
+
+ loader->SetDataPath(0);
+
+ ZeroMemory(keymap, sizeof(keymap));
+ ZeroMemory(keyalt, sizeof(keyalt));
+}
+
+Starshatter::~Starshatter()
+{
+ if (video_changed) {
+ SaveVideoConfig("video.cfg");
+ }
+
+ DeleteFile("video2.cfg");
+ StopLobby();
+
+ if (Status() <= EXIT)
+ Player::Save();
+
+ delete menuscreen;
+ delete loadscreen;
+ delete planscreen;
+ delete gamescreen;
+ delete cmpnscreen;
+
+ menuscreen = 0;
+ loadscreen = 0;
+ planscreen = 0;
+ gamescreen = 0;
+ cmpnscreen = 0;
+
+ music_dir = 0;
+
+ // delete all the ships and stuff
+ // BEFORE getting rid of the system
+ // and weapons catalogs!
+ delete world;
+ world = 0; // don't let base class double delete the world
+
+ delete quick_mission;
+
+ AudioConfig::Close();
+ HUDSounds::Close();
+ MusicDirector::Close();
+
+ Player::Close();
+ Drive::Close();
+ LandingGear::Close();
+ MFD::Close();
+ Explosion::Close();
+ FlightDeck::Close();
+ Campaign::Close();
+ CombatRoster::Close();
+ Galaxy::Close();
+ RadioTraffic::Close();
+ RadioVox::Close();
+ Ship::Close();
+ WeaponDesign::Close();
+ SystemDesign::Close();
+ ModConfig::Close();
+ NetClientConfig::Close();
+ TacticalView::Close();
+ QuantumView::Close();
+ QuitView::Close();
+ RadioView::Close();
+ NetServerConfig::Close();
+
+ Mouse::Close();
+ EventDispatch::Close();
+ FontMgr::Close();
+ Button::Close();
+ DataLoader::Close();
+
+ delete ocrb;
+ delete limerick12;
+ delete limerick18;
+ delete verdana;
+ delete terminal;
+ delete HUDfont;
+ delete GUIfont;
+ delete GUI_small_font;
+ delete input;
+ delete head_tracker;
+
+ instance = 0;
+}
+
+void
+Starshatter::Exit()
+{
+ MusicDirector::SetMode(MusicDirector::NONE);
+ SetGameMode(EXIT_MODE);
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+Starshatter::OnHelp()
+{
+ WebBrowser browser;
+ browser.OpenURL("http://matrixgames.com/support");
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::MapKeys()
+{
+ int nkeys = keycfg.GetNumKeys();
+
+ if (nkeys > 0) {
+ Starshatter::MapKeys(&keycfg, nkeys);
+ input->MapKeys(keycfg.GetMapping(), nkeys);
+ }
+}
+
+void
+Starshatter::MapKeys(KeyMap* mapping, int nkeys)
+{
+ for (int i = 0; i < nkeys; i++) {
+ KeyMapEntry* k = mapping->GetKeyMap(i);
+
+ if (k->act >= KEY_MAP_FIRST && k->act <= KEY_MAP_LAST)
+ MapKey(k->act, k->key, k->alt);
+ }
+}
+
+void
+Starshatter::MapKey(int act, int key, int alt)
+{
+ keymap[act] = key;
+ keyalt[act] = alt;
+
+ GetAsyncKeyState(key);
+ GetAsyncKeyState(alt);
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+Starshatter::Init(HINSTANCE hi, HINSTANCE hpi, LPSTR cmdline, int nCmdShow)
+{
+ if (strstr(cmdline, "-win") || strstr(cmdline, "-dbg")) {
+ if (video_settings) {
+ video_settings->is_windowed = true;
+
+ Print(" STARSHATTER RUNNING IN WINDOW MODE\n");
+ }
+ }
+
+ if (strstr(cmdline, "-filesys")) {
+ use_file_system = true;
+ Print(" FILE SYSTEM ENABLED\n");
+ }
+
+ if (strstr(cmdline, "-nosplash")) {
+ no_splash = true;
+ }
+
+ if (loader)
+ loader->UseFileSystem(use_file_system);
+
+ return GameWinDX9::Init(hi, hpi, cmdline, nCmdShow);
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+Starshatter::InitGame()
+{
+ if (!GameWinDX9::InitGame())
+ return false;
+
+ RandomInit();
+
+ AudioConfig::Initialize();
+ ModConfig::Initialize();
+
+ InitMouse();
+
+ Button::Initialize();
+ EventDispatch::Create();
+ NetClientConfig::Initialize();
+ Player::Initialize();
+ HUDSounds::Initialize();
+
+ int nkeys = keycfg.LoadKeyMap("key.cfg", 256);
+
+ if (nkeys)
+ Print(" Loaded key.cfg\n\n");
+
+ // create the appropriate motion controller and player_ship
+ input = new MultiController;
+ Keyboard* k = new Keyboard;
+ input->AddController(k);
+ ActivateKeyboardLayout(GetKeyboardLayout(0), 0);
+
+ mouse_input = new MouseController;
+ input->AddController(mouse_input);
+
+ ::Print("\nStarshatter::InitGame() create joystick\n");
+ Joystick* j = new Joystick;
+ j->SetSensitivity(15, 5000);
+ input->AddController(j);
+
+ Joystick::EnumerateDevices();
+ ::Print("\n");
+
+ head_tracker = new TrackIR();
+ MapKeys();
+
+ SystemDesign::Initialize("sys.def");
+ WeaponDesign::Initialize("wep.def");
+ MusicDirector::Initialize();
+
+ // if no splashes, we need to initialize the campaign engine now
+ if (no_splash) {
+ Ship::Initialize();
+ Galaxy::Initialize();
+ CombatRoster::Initialize();
+ Campaign::Initialize();
+ }
+
+ // otherwise, the campaign engine will get initialized during the splashes
+ else {
+ SetupSplash();
+ }
+
+ time_mark = Clock::GetInstance()->GameTime();
+ minutes = 0;
+
+ return true;
+}
+
+void
+Starshatter::InitMouse()
+{
+ if (loader) {
+ loader->SetDataPath(0);
+
+ Mouse::Create(screen);
+ Mouse::Show(false);
+ Mouse::LoadCursor(Mouse::ARROW, "MouseArrow.pcx", Mouse::HOTSPOT_NW);
+ Mouse::LoadCursor(Mouse::CROSS, "MouseCross.pcx", Mouse::HOTSPOT_CTR);
+ Mouse::LoadCursor(Mouse::DRAG, "MouseDrag.pcx", Mouse::HOTSPOT_NW);
+ Mouse::SetCursor(Mouse::ARROW);
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::RequestChangeVideo()
+{
+ req_change_video = true;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::StartOrResumeGame()
+{
+ if (game_mode != MENU_MODE && game_mode != CMPN_MODE)
+ return;
+
+ Player* p = Player::GetCurrentPlayer();
+ if (!p)
+ return;
+
+ List<Campaign>& list = Campaign::GetAllCampaigns();
+ Campaign* c = 0;
+ Text saved = CampaignSaveGame::GetResumeFile();
+
+
+ // resume saved game?
+ if (saved.length()) {
+ CampaignSaveGame savegame;
+ savegame.Load(saved);
+ c = savegame.GetCampaign();
+ }
+
+ // start training campaign?
+ else if (p->Trained() < 255) {
+ c = list[0];
+ c->Load();
+ }
+
+ // start new dynamic campaign sequence?
+ else {
+ c = list[1];
+ c->Load();
+ }
+
+ if (c)
+ Campaign::SelectCampaign(c->Name());
+
+ Mouse::Show(false);
+ SetGameMode(CLOD_MODE);
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+Starshatter::UseFileSystem()
+{
+ return use_file_system;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::OpenTacticalReference()
+{
+ if (menuscreen && game_mode == MENU_MODE) {
+ menuscreen->ShowLoadDlg();
+
+ LoadDlg* load_dlg = menuscreen->GetLoadDlg();
+
+ if (load_dlg && load_dlg->IsShown()) {
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.tac-ref");
+ load_progress = 1;
+ catalog_index = 0;
+ }
+ else {
+ menuscreen->ShowTacRefDlg();
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::SetGameMode(int m)
+{
+ if (game_mode == m)
+ return;
+
+ const char* mode_name[] = {
+ "MENU_MODE", // main menu
+ "CLOD_MODE", // loading campaign
+ "CMPN_MODE", // operational command for dynamic campaign
+ "PREP_MODE", // loading mission info for planning
+ "PLAN_MODE", // mission briefing
+ "LOAD_MODE", // loading mission into simulator
+ "PLAY_MODE", // active simulation
+ "EXIT_MODE" // shutting down
+ };
+
+ if (m >= MENU_MODE && m <= EXIT_MODE)
+ Print(">>> Starshatter::SetGameMode(%d) (%s)\n", m, mode_name[m]);
+ else
+ Print(">>> Starshatter::SetGameMode(%d) (UNKNOWN MODE)\n", m);
+
+ MouseController* mouse_con = MouseController::GetInstance();
+ if (mouse_con)
+ mouse_con->SetActive(false);
+
+ if (m == CLOD_MODE || m == PREP_MODE || m == LOAD_MODE) {
+ load_step = 0;
+ load_progress = 0;
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.general");
+ paused = true;
+ }
+
+ else if (m == CMPN_MODE) {
+ load_step = 0;
+ load_progress = 100;
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.complete");
+ paused = false;
+ }
+
+ else if (m == PLAY_MODE) {
+ Print(" Starting Game...\n");
+
+ player_ship = 0;
+ load_progress = 100;
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.complete");
+
+ if (!world) {
+ CreateWorld();
+ InstantiateMission();
+ }
+
+ if (gamescreen)
+ gamescreen->SetFieldOfView(field_of_view);
+
+ HUDView::ClearMessages();
+ RadioView::ClearMessages();
+
+ Clock::GetInstance()->SetTimeCompression(1.0);
+ Pause(false);
+
+ Print(" Stardate: %.1f\n", StarSystem::GetBaseTime());
+ }
+
+ else if (m == PLAN_MODE) {
+ if (game_mode == PLAY_MODE) {
+ Print(" Returning to Plan Mode...\n");
+ if (soundcard)
+ soundcard->StopSoundEffects();
+
+ StopNetGame();
+ Pause(true);
+ Print(" Stardate: %.1f\n", StarSystem::GetBaseTime());
+ }
+ }
+
+ else if (m == MENU_MODE) {
+ Print(" Returning to Main Menu...\n");
+
+ if (game_mode == PLAN_MODE || game_mode == PLAY_MODE) {
+ if (soundcard)
+ soundcard->StopSoundEffects();
+
+ StopNetGame();
+ }
+
+ paused = true;
+ }
+
+ if (m == EXIT_MODE) {
+ Print(" Shutting Down (Returning to Windows)...\n");
+
+ if (game_mode == PLAN_MODE || game_mode == PLAY_MODE) {
+ if (soundcard)
+ soundcard->StopSoundEffects();
+
+ StopNetGame();
+ }
+
+ Print(" Stardate: %.1f\n", StarSystem::GetBaseTime());
+ Print(" Bitmap Cache Footprint: %d KB\n", Bitmap::CacheMemoryFootprint() / 1024);
+
+ paused = true;
+ }
+
+ FlushKeys();
+ game_mode = m;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+Starshatter::ChangeVideo()
+{
+ bool result = false;
+
+ if (menuscreen) {
+ delete menuscreen;
+ menuscreen = 0;
+ }
+
+ if (loadscreen) {
+ delete loadscreen;
+ loadscreen = 0;
+ }
+
+ if (planscreen) {
+ delete planscreen;
+ planscreen = 0;
+ }
+
+ if (gamescreen) {
+ delete gamescreen;
+ gamescreen = 0;
+ }
+
+ if (cmpnscreen) {
+ delete cmpnscreen;
+ cmpnscreen = 0;
+ }
+
+ loader->SetDataPath(0);
+
+ LoadVideoConfig("video2.cfg");
+
+ result = ResetVideo();
+
+ InitMouse();
+
+ req_change_video = false;
+ video_changed = true;
+
+ return result;
+}
+
+bool
+Starshatter::ResizeVideo()
+{
+ if (GameWinDX9::ResizeVideo()) {
+ InitMouse();
+ Mouse::Show(true);
+
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::CreateWorld()
+{
+ RadioTraffic::Initialize();
+ RadioView::Initialize();
+ RadioVox::Initialize();
+ QuantumView::Initialize();
+ QuitView::Initialize();
+ TacticalView::Initialize();
+
+ // create world
+ if (!world) {
+ Sim* sim = new Sim(input);
+ world = sim;
+ Print(" World Created.\n");
+ }
+
+ cam_dir = CameraDirector::GetInstance();
+}
+
+void
+Starshatter::InstantiateMission()
+{
+ current_mission = 0;
+
+ if (Campaign::GetCampaign()) {
+ current_mission = Campaign::GetCampaign()->GetMission();
+ }
+
+ Sim* sim = (Sim*) world;
+
+ if (sim) {
+ bool dynamic = false;
+ Campaign* campaign = Campaign::GetCampaign();
+
+ if (campaign && campaign->IsDynamic())
+ dynamic = true;
+
+ sim->UnloadMission();
+ sim->LoadMission(current_mission);
+ sim->ExecMission();
+ sim->SetTestMode(test_mode && !dynamic ? true : false);
+
+ Print(" Mission Instantiated.\n");
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+int
+Starshatter::KeyDown(int action) const
+{
+ int k = Joystick::KeyDownMap(action) ||
+ Keyboard::KeyDownMap(action);
+
+ return k;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+Starshatter::GameLoop()
+{
+ cam_dir = CameraDirector::GetInstance();
+
+ if (active && paused) {
+ // Route Events to EventTargets
+ EventDispatch* ed = EventDispatch::GetInstance();
+ if (ed)
+ ed->Dispatch();
+
+ UpdateWorld();
+ GameState();
+ UpdateScreen();
+ CollectStats();
+
+ /***
+ static DWORD vmf_time = 0;
+
+ if (real_time() - vmf_time > 5000) {
+ vmf_time = real_time();
+ DWORD vmf = video->VidMemFree() / (1024 * 1024);
+ ::Print("\n###### %02d:%02d - Video Memory Free: %d MB\n\n",
+ vmf_time / 60000,
+ vmf_time / 1000,
+ vmf);
+ }
+ ***/
+ }
+
+ Game::GameLoop();
+ return false; // must return false to keep processing
+ // true tells the outer loop to sleep until a
+ // windows event is available
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::UpdateWorld()
+{
+ Galaxy* galaxy = Galaxy::GetInstance();
+ if (galaxy) galaxy->ExecFrame();
+
+ // Cutscene missions have a tendency to mess with the stardate
+ // to manage time-of-day and camera effects. It's a bad idea to
+ // evaluate campaign actions and events while the cutscene is
+ // changing the time base.
+ if (!cutscene_mission) {
+ Campaign* campaign = Campaign::GetCampaign();
+ if (campaign) campaign->ExecFrame();
+ }
+
+ if (paused) {
+ if (world)
+ world->ExecFrame(0);
+ }
+
+ else {
+ Drive::StartFrame();
+
+ if (world)
+ world->ExecFrame(Clock::GetInstance()->Delta());
+ }
+
+ if (game_mode == PLAY_MODE || InCutscene()) {
+ if (cam_dir) {
+ if (head_tracker && head_tracker->IsRunning() && !InCutscene()) {
+ head_tracker->ExecFrame();
+ cam_dir->VirtualHead(head_tracker->GetAzimuth(), head_tracker->GetElevation());
+ cam_dir->VirtualHeadOffset(head_tracker->GetX(), head_tracker->GetY(), head_tracker->GetZ());
+ }
+
+ cam_dir->ExecFrame(Clock::GetInstance()->GuiDelta());
+ }
+
+ Sim* sim = Sim::GetSim();
+ SimRegion* rgn = sim ? sim->GetActiveRegion() : 0;
+
+ if (rgn) {
+ ListIter<Ship> iter = rgn->Ships();
+ while (++iter) {
+ Ship* s = iter.value();
+ s->SelectDetail(Clock::GetInstance()->Delta());
+ }
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::GameState()
+{
+ if (splash) {
+ static bool quick_splash = false;
+
+ if (GetKey() != 0)
+ quick_splash = true;
+
+ if (quick_splash) {
+ splash->FadeIn(0);
+ splash->StopHold();
+ splash->FadeOut(0);
+ }
+
+ if (splash->Done()) {
+ splash = 0; // this will get deleted along with gamewin
+ splash_index++;
+
+ if (gamewin) {
+ screen->DelWindow(gamewin);
+ delete gamewin;
+ gamewin = 0;
+ }
+
+ if (splash_index < 2) {
+ Ship::Initialize();
+ Galaxy::Initialize();
+ SetupSplash();
+ }
+ else {
+ CombatRoster::Initialize();
+ Campaign::Initialize();
+ SetupMenuScreen();
+ }
+
+ FlushKeys();
+ }
+ }
+
+ else if (game_mode == MENU_MODE) {
+ bool campaign_select = false;
+
+ if (cmpnscreen) {
+ campaign_select = cmpnscreen->IsShown();
+ cmpnscreen->Hide();
+ }
+
+ if (gamescreen)
+ gamescreen->Hide();
+
+ if (planscreen)
+ planscreen->Hide();
+
+ if (loadscreen)
+ loadscreen->Hide();
+
+ if (!menuscreen) {
+ SetupMenuScreen();
+ }
+ else {
+ menuscreen->Show();
+
+ if (campaign_select)
+ menuscreen->ShowCmpSelectDlg();
+ }
+
+ if (MusicDirector::GetInstance() &&
+ MusicDirector::GetInstance()->GetMode() != MusicDirector::CREDITS)
+ MusicDirector::SetMode(MusicDirector::MENU);
+
+ DoMenuScreenFrame();
+ }
+
+ else if (game_mode == CLOD_MODE ||
+ game_mode == PREP_MODE ||
+ game_mode == LOAD_MODE) {
+ if (menuscreen)
+ menuscreen->Hide();
+
+ if (planscreen)
+ planscreen->Hide();
+
+ if (cmpnscreen)
+ cmpnscreen->Hide();
+
+ if (!loadscreen)
+ SetupLoadScreen();
+ else
+ loadscreen->Show();
+
+ if (game_mode == CLOD_MODE)
+ MusicDirector::SetMode(MusicDirector::MENU);
+ else
+ MusicDirector::SetMode(MusicDirector::BRIEFING);
+
+ DoLoadScreenFrame();
+ }
+
+ else if (game_mode == PLAN_MODE) {
+ if (menuscreen)
+ menuscreen->Hide();
+
+ if (cmpnscreen)
+ menuscreen->Hide();
+
+ if (loadscreen)
+ loadscreen->Hide();
+
+ if (gamescreen)
+ gamescreen->Hide();
+
+ if (!planscreen)
+ SetupPlanScreen();
+ else
+ planscreen->Show();
+
+ Player* p = Player::GetCurrentPlayer();
+ if (p && p->ShowAward()) {
+ if (!planscreen->IsAwardShown())
+ planscreen->ShowAwardDlg();
+ }
+
+ else if (ShipStats::NumStats()) {
+ if (!planscreen->IsDebriefShown()) {
+ planscreen->ShowDebriefDlg();
+ show_missions = true;
+ }
+ }
+
+ else {
+ if (!planscreen->IsMsnShown() && !planscreen->IsNavShown())
+ planscreen->ShowMsnDlg();
+ }
+
+ MusicDirector::SetMode(MusicDirector::BRIEFING);
+
+ DoPlanScreenFrame();
+ }
+
+
+ else if (game_mode == CMPN_MODE) {
+ if (menuscreen)
+ menuscreen->Hide();
+
+ if (planscreen)
+ planscreen->Hide();
+
+ if (loadscreen)
+ loadscreen->Hide();
+
+ if (gamescreen)
+ gamescreen->Hide();
+
+ if (!cmpnscreen)
+ SetupCmpnScreen();
+ else
+ cmpnscreen->Show();
+
+ DoCmpnScreenFrame();
+ }
+
+ else if (game_mode == PLAY_MODE) {
+ if (menuscreen)
+ menuscreen->Hide();
+
+ if (cmpnscreen)
+ cmpnscreen->Hide();
+
+ if (planscreen)
+ planscreen->Hide();
+
+ if (loadscreen)
+ loadscreen->Hide();
+
+ if (!gamescreen)
+ SetupGameScreen();
+ else
+ gamescreen->Show();
+
+ DoGameScreenFrame();
+ }
+
+ if (game_mode == EXIT_MODE) {
+ exit_time -= Clock::GetInstance()->GuiDelta();
+
+ if (exit_time <= 0)
+ Game::Exit();
+ }
+
+ if (net_lobby)
+ net_lobby->ExecFrame();
+
+ if (music_dir)
+ music_dir->ExecFrame();
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::DoMenuScreenFrame()
+{
+ if (!Mouse::RButton()) {
+ Mouse::SetCursor(Mouse::ARROW);
+ Mouse::Show(true);
+ }
+
+ if (time_til_change > 0)
+ time_til_change -= Clock::GetInstance()->GuiDelta();
+
+ if (!menuscreen)
+ return;
+
+ if (KeyDown(KEY_EXIT)) {
+ if (time_til_change <= 0) {
+ time_til_change = 0.5;
+
+ if (!exit_latch && !menuscreen->CloseTopmost()) {
+ menuscreen->ShowExitDlg();
+ }
+ }
+
+ exit_latch = true;
+ }
+ else {
+ exit_latch = false;
+ }
+
+ LoadDlg* load_dlg = menuscreen->GetLoadDlg();
+
+ if (load_dlg && load_dlg->IsShown()) {
+ // load all ship designs in the standard catalog
+ if (catalog_index < ShipDesign::StandardCatalogSize()) {
+ ShipDesign::PreloadCatalog(catalog_index++);
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.tac-ref");
+
+ if (load_progress < 95)
+ load_progress++;
+ }
+
+ else {
+ menuscreen->ShowTacRefDlg();
+ }
+ }
+
+ if (show_missions) {
+ if (net_lobby)
+ menuscreen->ShowNetLobbyDlg();
+ else
+ menuscreen->ShowMsnSelectDlg();
+
+ show_missions = false;
+ }
+
+ menuscreen->ExecFrame();
+
+ if (req_change_video) {
+ ChangeVideo();
+ SetupMenuScreen();
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::DoPlanScreenFrame()
+{
+ Mouse::SetCursor(Mouse::ARROW);
+
+ if (time_til_change > 0)
+ time_til_change -= Clock::GetInstance()->GuiDelta();
+
+ if (KeyDown(KEY_EXIT)) {
+ if (time_til_change <= 0) {
+ time_til_change = 1;
+
+ if (!exit_latch && !planscreen->CloseTopmost()) {
+ Campaign* campaign = Campaign::GetCampaign();
+ if (campaign && (campaign->IsDynamic() || campaign->IsTraining()))
+ SetGameMode(CMPN_MODE);
+ else
+ SetGameMode(MENU_MODE);
+ }
+ }
+
+ exit_latch = true;
+ }
+ else {
+ exit_latch = false;
+ }
+
+ planscreen->ExecFrame();
+ show_missions = true;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::DoCmpnScreenFrame()
+{
+ Mouse::SetCursor(Mouse::ARROW);
+
+ if (time_til_change > 0)
+ time_til_change -= Clock::GetInstance()->GuiDelta();
+
+ exit_latch = KeyDown(KEY_EXIT) ? true : false;
+
+ if (InCutscene() && player_ship) {
+ // warp effect:
+ if (player_ship->WarpFactor() > 1) {
+ if (player_ship->WarpFactor() > field_of_view)
+ cmpnscreen->SetFieldOfView(player_ship->WarpFactor());
+ else
+ cmpnscreen->SetFieldOfView(field_of_view);
+ }
+
+ else {
+ if (cmpnscreen->GetFieldOfView() != field_of_view)
+ cmpnscreen->SetFieldOfView(field_of_view);
+ }
+ }
+
+ if (InCutscene() && exit_latch) {
+ time_til_change = 1;
+ EndCutscene();
+ EndMission();
+ cmpnscreen->SetFieldOfView(field_of_view);
+ }
+
+ else if (time_til_change <= 0 && exit_latch) {
+ time_til_change = 1;
+
+ if (!cmpnscreen || !cmpnscreen->CloseTopmost()) {
+ SetGameMode(MENU_MODE);
+ }
+ }
+
+ // time control for campaign mode:
+ else if (game_mode == CMPN_MODE) {
+ if (time_til_change <= 0) {
+ if (KeyDown(KEY_PAUSE)) {
+ time_til_change = 1;
+ Pause(!paused);
+ }
+
+ else if (KeyDown(KEY_TIME_COMPRESS)) {
+ time_til_change = 1;
+ double compression = Clock::GetInstance()->TimeCompression() * 2;
+ if (compression > 8.0)
+ compression = 8.0;
+ Clock::GetInstance()->SetTimeCompression(compression);
+ }
+
+ else if (KeyDown(KEY_TIME_EXPAND)) {
+ time_til_change = 1;
+ double compression = Clock::GetInstance()->TimeCompression() / 2;
+ if (compression < 0.5)
+ compression = 0.5;
+ Clock::GetInstance()->SetTimeCompression(compression);
+ }
+ }
+ }
+
+ if (show_missions && !InCutscene()) {
+ cmpnscreen->ShowCmdMissionsDlg();
+ show_missions = false;
+ }
+
+ cmpnscreen->ExecFrame();
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::DoLoadScreenFrame()
+{
+ Mouse::Show(false);
+ Mouse::SetCursor(Mouse::ARROW);
+
+ if (game_mode == CLOD_MODE) {
+ CmpLoadDlg* dlg = loadscreen->GetCmpLoadDlg();
+
+ switch (load_step) {
+ case 0:
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.campaign");
+ load_progress = 1;
+ catalog_index = 0;
+ break;
+
+ case 1:
+ // load all ship designs in the standard catalog
+ if (catalog_index < ShipDesign::StandardCatalogSize()) {
+ ShipDesign::PreloadCatalog(catalog_index++);
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.campaign");
+
+ if (load_progress < 80)
+ load_progress++;
+
+ load_step = 0; // force return to current step on next frame
+ }
+ else {
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.start");
+ load_progress = 80;
+ }
+ break;
+
+ case 2:
+ if (Campaign::GetCampaign())
+ Campaign::GetCampaign()->Start();
+ break;
+
+ default:
+ if (dlg && load_progress < 100) {
+ load_progress++;
+ }
+ else {
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.ready");
+ load_progress = 100;
+ SetGameMode(CMPN_MODE);
+ }
+ break;
+ }
+ }
+ else {
+ switch (load_step) {
+ case 0:
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.drives");
+ load_progress = 0;
+ break;
+
+ case 1:
+ Drive::Initialize();
+ LandingGear::Initialize();
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.explosions");
+ load_progress = 5;
+ break;
+
+ case 2:
+ Explosion::Initialize();
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.systems");
+ load_progress = 10;
+ break;
+
+ case 3:
+ FlightDeck::Initialize();
+ NavLight::Initialize();
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.ships");
+ load_progress = 15;
+ break;
+
+ case 4:
+ Ship::Initialize();
+ Shot::Initialize();
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.hud");
+ load_progress = 20;
+ break;
+
+ case 5:
+ MFD::Initialize();
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.menus");
+ load_progress = 25;
+ break;
+
+ case 6:
+ RadioTraffic::Initialize();
+ RadioView::Initialize();
+ TacticalView::Initialize();
+
+ if (!gamescreen && game_mode != PREP_MODE)
+ SetupGameScreen();
+
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.mission");
+ load_progress = 65;
+ break;
+
+ case 7:
+ if (game_mode == PREP_MODE) {
+ if (Campaign::GetCampaign())
+ Campaign::GetCampaign()->GetMission();
+ SetGameMode(PLAN_MODE);
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.loaded");
+ load_progress = 100;
+ Button::PlaySound(4);
+ }
+ else {
+ CreateWorld();
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.simulation");
+ load_progress = 75;
+ }
+ break;
+
+ case 8:
+ InstantiateMission();
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.viewscreen");
+ load_progress = 90;
+ break;
+
+ default:
+ SetGameMode(PLAY_MODE);
+ load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.ready");
+ load_progress = 100;
+ break;
+ }
+ }
+
+ load_step++;
+ loadscreen->ExecFrame();
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::PlayerCam(int mode)
+{
+ if (player_ship && !player_ship->InTransition() && player_ship->GetFlightPhase() >= Ship::LOCKED) {
+ gamescreen->CloseTopmost();
+ if (mode == CameraDirector::MODE_DROP) {
+ player_ship->DropCam(15, 0);
+ cam_dir->SetShip(player_ship);
+ cam_dir->SetMode(CameraDirector::MODE_DROP, 0);
+ }
+
+ else {
+ cam_dir->SetMode(mode);
+
+ if (mode == CameraDirector::MODE_ORBIT) {
+ MouseController* mouse_con = MouseController::GetInstance();
+ if (mouse_con)
+ mouse_con->SetActive(false);
+ }
+ }
+ }
+}
+
+void
+Starshatter::ViewSelection()
+{
+ Sim* sim = (Sim*) world;
+ List<Ship>& seln = sim->GetSelection().container();
+
+ if (cam_dir) {
+ if (seln.isEmpty())
+ cam_dir->SetViewObject(player_ship);
+
+ else if (seln.size() == 1)
+ cam_dir->SetViewObject(seln[0]);
+
+ else
+ cam_dir->SetViewObjectGroup(seln);
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::DoGameScreenFrame()
+{
+ Sim* sim = (Sim*) world;
+
+ if (!gamescreen || !sim)
+ return;
+
+ if (InCutscene()) {
+ if (player_ship) {
+ // warp effect:
+ if (player_ship->WarpFactor() > 1) {
+ if (player_ship->WarpFactor() > field_of_view)
+ gamescreen->SetFieldOfView(player_ship->WarpFactor());
+ else
+ gamescreen->SetFieldOfView(field_of_view);
+ }
+
+ else {
+ if (gamescreen->GetFieldOfView() != field_of_view)
+ gamescreen->SetFieldOfView(field_of_view);
+ }
+ }
+
+ gamescreen->FrameRate(Clock::GetInstance()->Rate());
+ gamescreen->ExecFrame();
+
+ if (KeyDown(KEY_EXIT)) {
+ gamescreen->SetFieldOfView(field_of_view);
+ exit_latch = true;
+ time_til_change = 1;
+
+ sim->SkipCutscene();
+ }
+
+ return;
+ }
+
+ if (time_til_change > 0)
+ time_til_change -= Clock::GetInstance()->GuiDelta();
+
+ if (exit_latch && !KeyDown(KEY_EXIT))
+ exit_latch = false;
+
+ DoMouseFrame();
+
+ HUDView* hud_view = HUDView::GetInstance();
+
+ // changing to a new ship?
+ if (player_ship != sim->GetPlayerShip()) {
+ gamescreen->HideNavDlg();
+ gamescreen->HideFltDlg();
+ gamescreen->HideEngDlg();
+
+ Ship* new_player = sim->GetPlayerShip();
+
+ if (new_player) {
+ if (new_player->IsDropship() && Ship::GetFlightModel() < 2 && Ship::GetControlModel() < 1)
+ input->SwapYawRoll(true);
+ else
+ input->SwapYawRoll(false);
+
+ if (hud_view) {
+ hud_view->SetHUDMode(HUDView::HUD_MODE_TAC);
+ hud_view->HideHUDWarn();
+ }
+ }
+ }
+
+ player_ship = sim->GetPlayerShip();
+
+ if (player_ship) {
+ // warp effect:
+ if (player_ship->WarpFactor() > 1) {
+ if (player_ship->WarpFactor() > field_of_view)
+ gamescreen->SetFieldOfView(player_ship->WarpFactor());
+ else
+ gamescreen->SetFieldOfView(field_of_view);
+ }
+
+ else {
+ if (gamescreen->GetFieldOfView() != field_of_view)
+ gamescreen->SetFieldOfView(field_of_view);
+ }
+
+ gamescreen->ShowExternal();
+
+ if (CameraDirector::GetCameraMode() >= CameraDirector::MODE_ORBIT && !player_ship->InTransition())
+ tactical = true;
+ else
+ tactical = false;
+
+ if (player_ship->InTransition())
+ gamescreen->CloseTopmost();
+ }
+
+ if (chat_mode) {
+ DoChatMode();
+ }
+
+ else {
+ DoGameKeys();
+ }
+
+ gamescreen->FrameRate(Clock::GetInstance()->Rate());
+ gamescreen->ExecFrame();
+
+ if (Clock::GetInstance()->GameTime() - time_mark > 60000) {
+ time_mark = Clock::GetInstance()->GameTime();
+ minutes++;
+ if (minutes > 60)
+ Print(" TIME %2d:%02d:00\n", minutes/60, minutes%60);
+ else
+ Print(" TIME %2d:00\n", minutes);
+ }
+}
+
+void
+Starshatter::DoGameKeys()
+{
+ Sim* sim = (Sim*) world;
+ HUDView* hud_view = HUDView::GetInstance();
+
+ if (time_til_change <= 0) {
+ if (KeyDown(KEY_CAM_BRIDGE)) {
+ PlayerCam(CameraDirector::MODE_COCKPIT);
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_CAM_VIRT)) {
+ PlayerCam(CameraDirector::MODE_VIRTUAL);
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_CAM_CHASE)) {
+ PlayerCam(CameraDirector::MODE_CHASE);
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_CAM_DROP)) {
+ PlayerCam(CameraDirector::MODE_DROP);
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_CAM_EXTERN)) {
+ PlayerCam(CameraDirector::MODE_ORBIT);
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_TARGET_PADLOCK)) {
+ PlayerCam(CameraDirector::MODE_TARGET);
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_SWAP_ROLL_YAW)) {
+ input->SwapYawRoll(!input->GetSwapYawRoll());
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_ZOOM_WIDE)) {
+ time_til_change = 0.5;
+ if (gamescreen->GetFieldOfView() <= 2)
+ field_of_view = 3; // wide
+ else
+ field_of_view = 2; // normal
+
+ // don't mess with fov during warp:
+ if (player_ship && player_ship->WarpFactor() <= 1)
+ gamescreen->SetFieldOfView(field_of_view);
+ }
+
+ else if (!exit_latch && KeyDown(KEY_EXIT)) {
+ exit_latch = true;
+ time_til_change = 0.5;
+
+ if (!gamescreen->CloseTopmost()) {
+ QuitView* quit = QuitView::GetInstance();
+ if (quit)
+ quit->ShowMenu();
+ else
+ SetGameMode(Starshatter::PLAN_MODE);
+ }
+ }
+
+ else if (KeyDown(KEY_PAUSE)) {
+ Pause(!paused);
+ time_til_change = 0.5;
+ }
+
+
+ else if (KeyDown(KEY_TIME_COMPRESS)) {
+ time_til_change = 0.5;
+ if (NetGame::IsNetGame())
+ Clock::GetInstance()->SetTimeCompression(1.0);
+ else {
+ double compression = Clock::GetInstance()->TimeCompression() * 2;
+ if (compression > 4.0)
+ compression = 4.0;
+ Clock::GetInstance()->SetTimeCompression(compression);
+ }
+ }
+
+ else if (KeyDown(KEY_TIME_EXPAND)) {
+ time_til_change = 0.5;
+
+ if (NetGame::IsNetGame())
+ Clock::GetInstance()->SetTimeCompression(1.0);
+ else {
+ double compression = Clock::GetInstance()->TimeCompression() / 2;
+ if (compression < 0.5)
+ compression = 0.5;
+ Clock::GetInstance()->SetTimeCompression(compression);
+ }
+ }
+
+ else if (KeyDown(KEY_TIME_SKIP)) {
+ time_til_change = 0.5;
+
+ if (player_ship && !NetGame::IsNetGame()) {
+ player_ship->TimeSkip();
+ }
+ }
+
+ else if (KeyDown(KEY_COMMAND_MODE)) {
+ if (player_ship) {
+ time_til_change = 0.5;
+ player_ship->CommandMode();
+ }
+ }
+
+ /*** For Debug Convenience Only: ***/
+ else if (KeyDown(KEY_INC_STARDATE)) {
+ StarSystem::SetBaseTime(StarSystem::GetBaseTime() + 600, true);
+ }
+
+ else if (KeyDown(KEY_DEC_STARDATE)) {
+ StarSystem::SetBaseTime(StarSystem::GetBaseTime() - 600, true);
+ }
+ /***/
+ }
+
+ if (gamescreen && time_til_change <= 0) {
+ if (KeyDown(KEY_MFD1)) {
+ gamescreen->CycleMFDMode(0);
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_MFD2)) {
+ gamescreen->CycleMFDMode(1);
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_MFD3)) {
+ gamescreen->CycleMFDMode(2);
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_MFD4)) {
+ gamescreen->CycleMFDMode(3);
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_RADIO_MENU)) {
+ RadioView* radio_view = RadioView::GetInstance();
+ if (radio_view) {
+ if (radio_view->IsMenuShown())
+ radio_view->CloseMenu();
+ else
+ radio_view->ShowMenu();
+ }
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_QUANTUM_MENU)) {
+ QuantumView* quantum_view = QuantumView::GetInstance();
+ if (quantum_view) {
+ if (quantum_view->IsMenuShown())
+ quantum_view->CloseMenu();
+ else
+ quantum_view->ShowMenu();
+ }
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_CAM_VIEW_SELECTION)) {
+ time_til_change = 0.5;
+ ViewSelection();
+ }
+
+ else if (KeyDown(KEY_HUD_MODE)) {
+ time_til_change = 0.5;
+ if (hud_view)
+ hud_view->CycleHUDMode();
+ }
+
+ else if (KeyDown(KEY_HUD_COLOR)) {
+ time_til_change = 0.5;
+ if (hud_view)
+ hud_view->CycleHUDColor();
+ }
+
+ else if (KeyDown(KEY_HUD_WARN)) {
+ time_til_change = 0.5;
+ if (hud_view)
+ hud_view->CycleHUDWarn();
+ }
+
+ else if (KeyDown(KEY_HUD_INST)) {
+ time_til_change = 0.5;
+ if (hud_view)
+ hud_view->CycleHUDInst();
+ }
+
+ else if (KeyDown(KEY_SELF_DESTRUCT)) {
+ time_til_change = 0.5;
+
+ if (player_ship && !player_ship->InTransition()) {
+ double damage = player_ship->Design()->scuttle;
+
+ if (NetGame::IsNetGameClient()) {
+ NetUtil::SendSelfDestruct(player_ship, damage);
+ }
+ else {
+ Point scuttle_loc = player_ship->Location() + RandomDirection() * player_ship->Radius();
+ player_ship->InflictDamage(damage, 0, 1, scuttle_loc);
+ }
+
+ if (player_ship->Integrity() < 1) {
+ ::Print(" %s 0-0-0-Destruct-0\n\n", player_ship->Name());
+
+ ShipStats* s = ShipStats::Find(player_ship->Name());
+ if (s)
+ s->AddEvent(SimEvent::DESTROYED, player_ship->Name());
+
+ player_ship->DeathSpiral();
+ }
+ }
+ }
+ }
+
+ if (gamescreen && player_ship && time_til_change <= 0 && !::GetAsyncKeyState(VK_SHIFT) && !::GetAsyncKeyState(VK_MENU)) {
+ if (KeyDown(KEY_NAV_DLG)) {
+ gamescreen->ShowNavDlg();
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_WEP_DLG)) {
+ if (player_ship && player_ship->Design()->wep_screen)
+ gamescreen->ShowWeaponsOverlay();
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_FLT_DLG)) {
+ if (player_ship && player_ship->NumFlightDecks() > 0)
+ gamescreen->ShowFltDlg();
+ time_til_change = 0.5;
+ }
+
+ else if (KeyDown(KEY_ENG_DLG)) {
+ if (player_ship && player_ship->Design()->repair_screen)
+ gamescreen->ShowEngDlg();
+ time_til_change = 0.5;
+ }
+ }
+
+ if (cam_dir) {
+ double spin = (PI/2) * Clock::GetInstance()->Delta(); // Game::GetInstance()->GetClock()->GuiDelta();
+
+ if (KeyDown(KEY_CAM_EXT_PLUS_AZ))
+ cam_dir->ExternalAzimuth(spin);
+
+ else if (KeyDown(KEY_CAM_EXT_MINUS_AZ))
+ cam_dir->ExternalAzimuth(-spin);
+
+ if (KeyDown(KEY_CAM_EXT_PLUS_EL))
+ cam_dir->ExternalElevation(spin);
+
+ else if (KeyDown(KEY_CAM_EXT_MINUS_EL))
+ cam_dir->ExternalElevation(-spin);
+
+ if (KeyDown(KEY_CAM_VIRT_PLUS_AZ))
+ cam_dir->VirtualAzimuth(-spin);
+
+ else if (KeyDown(KEY_CAM_VIRT_MINUS_AZ))
+ cam_dir->VirtualAzimuth(spin);
+
+ if (KeyDown(KEY_CAM_VIRT_PLUS_EL))
+ cam_dir->VirtualElevation(spin);
+
+ else if (KeyDown(KEY_CAM_VIRT_MINUS_EL))
+ cam_dir->VirtualElevation(-spin);
+
+ if (KeyDown(KEY_CAM_EXT_PLUS_RANGE)){
+ if (!gamescreen->IsNavShown()) {
+ cam_dir->ExternalRange((float) (1 + 1.5 * Clock::GetInstance()->Delta())); // 1.1f);
+ }
+ }
+
+ else if (KeyDown(KEY_CAM_EXT_MINUS_RANGE)) {
+ if (!gamescreen->IsNavShown()) {
+ cam_dir->ExternalRange((float) (1 - 1.5 * Clock::GetInstance()->Delta())); // 0.9f);
+ }
+ }
+
+ if (tactical && !gamescreen->IsFormShown()) {
+ if (Mouse::Wheel()) {
+ int w = Mouse::Wheel();
+
+ if (w < 0) {
+ while (w < 0) {
+ cam_dir->ExternalRange(1.25f);
+ w += 120;
+ }
+ }
+ else {
+ while (w > 0) {
+ cam_dir->ExternalRange(0.75f);
+ w -= 120;
+ }
+ }
+ }
+
+ else if (Mouse::LButton() && Mouse::RButton()) {
+ if (mouse_dy < 0)
+ cam_dir->ExternalRange(0.85f);
+ else if (mouse_dy > 0)
+ cam_dir->ExternalRange(1.15f);
+ }
+
+ else if (Mouse::MButton() && time_til_change <= 0) {
+ time_til_change = 0.5;
+ ViewSelection();
+ }
+
+ else {
+ if (mouse_dx || mouse_dy) {
+ if (CameraDirector::GetCameraMode() == CameraDirector::MODE_VIRTUAL) {
+ cam_dir->VirtualAzimuth( mouse_dx * 0.2 * DEGREES);
+ cam_dir->VirtualElevation(mouse_dy * 0.2 * DEGREES);
+ }
+ else {
+ cam_dir->ExternalAzimuth( mouse_dx * 0.2 * DEGREES);
+ cam_dir->ExternalElevation(mouse_dy * 0.2 * DEGREES);
+ }
+ }
+ }
+ }
+ }
+
+ // radio message hot keys:
+ static bool comm_key = false;
+
+ if (KeyDown(KEY_COMM_ATTACK_TGT)) {
+ if (!comm_key)
+ RadioTraffic::SendQuickMessage(player_ship, RadioMessage::ATTACK);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_COMM_ESCORT_TGT)) {
+ if (!comm_key)
+ RadioTraffic::SendQuickMessage(player_ship, RadioMessage::ESCORT);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_COMM_WEP_FREE)) {
+ if (!comm_key)
+ RadioTraffic::SendQuickMessage(player_ship, RadioMessage::WEP_FREE);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_COMM_WEP_HOLD)) {
+ if (!comm_key)
+ RadioTraffic::SendQuickMessage(player_ship, RadioMessage::FORM_UP);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_COMM_COVER_ME)) {
+ if (!comm_key)
+ RadioTraffic::SendQuickMessage(player_ship, RadioMessage::COVER_ME);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_COMM_SKIP_NAV)) {
+ if (!comm_key)
+ RadioTraffic::SendQuickMessage(player_ship, RadioMessage::SKIP_NAVPOINT);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_COMM_RETURN_TO_BASE)) {
+ if (!comm_key)
+ RadioTraffic::SendQuickMessage(player_ship, RadioMessage::RTB);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_COMM_CALL_INBOUND)) {
+ if (!comm_key)
+ RadioTraffic::SendQuickMessage(player_ship, RadioMessage::CALL_INBOUND);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_COMM_REQUEST_PICTURE)) {
+ if (!comm_key)
+ RadioTraffic::SendQuickMessage(player_ship, RadioMessage::REQUEST_PICTURE);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_COMM_REQUEST_SUPPORT)) {
+ if (!comm_key)
+ RadioTraffic::SendQuickMessage(player_ship, RadioMessage::REQUEST_SUPPORT);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_CHAT_BROADCAST)) {
+ if (!comm_key)
+ SetChatMode(CHAT_BROADCAST);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_CHAT_TEAM)) {
+ if (!comm_key)
+ SetChatMode(CHAT_TEAM);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_CHAT_WING)) {
+ if (!comm_key)
+ SetChatMode(CHAT_WING);
+ comm_key = true;
+ }
+
+ else if (KeyDown(KEY_CHAT_UNIT) && sim->GetSelection().container().size()) {
+ if (!comm_key)
+ SetChatMode(CHAT_UNIT);
+ comm_key = true;
+ }
+
+ else {
+ comm_key = false;
+ }
+}
+
+void
+Starshatter::DoChatMode()
+{
+ Player* p = Player::GetCurrentPlayer();
+ bool send_chat = false;
+ Text name = "Player";
+
+ if (player_ship)
+ name = player_ship->Name();
+
+ if (p)
+ name = p->Name();
+
+ if (chat_text.length()) {
+ if (chat_text[0] >= '0' && chat_text[0] <= '9') {
+ if (p) {
+ chat_text = p->ChatMacro(chat_text[0] - '0');
+ send_chat = true;
+ }
+ }
+ }
+
+ if (KeyDown(KEY_EXIT)) {
+ SetChatMode(0);
+ time_til_change = 0.5;
+ }
+
+ else if (send_chat || Keyboard::KeyDown(VK_RETURN)) {
+ switch (chat_mode) {
+ default:
+ case CHAT_BROADCAST:
+ {
+ NetUtil::SendChat(0, name, chat_text);
+ }
+ break;
+
+ case CHAT_TEAM:
+ if (player_ship) {
+ NetUtil::SendChat(player_ship->GetIFF()+1, name, chat_text);
+ }
+ break;
+
+ case CHAT_WING:
+ if (player_ship) {
+ Element* elem = player_ship->GetElement();
+ if (elem) {
+ for (int i = 1; i <= elem->NumShips(); i++) {
+ Ship* s = elem->GetShip(i);
+ if (s && s != player_ship)
+ NetUtil::SendChat(s->GetObjID(), name, chat_text);
+ }
+ }
+ }
+ break;
+
+ case CHAT_UNIT:
+ {
+ Sim* sim = Sim::GetSim();
+ ListIter<Ship> seln = sim->GetSelection();
+
+ while (++seln) {
+ Ship* s = seln.value();
+ if (s != player_ship)
+ NetUtil::SendChat(s->GetObjID(), name, chat_text);
+ }
+ }
+ break;
+ }
+
+ HUDView::Message("%s> %s", name.data(), chat_text.data());
+
+ SetChatMode(0);
+ time_til_change = 0.5;
+ }
+
+ else {
+ int key = 0;
+ int shift = 0;
+
+ while (GetKeyPlus(key, shift)) {
+ if (key >= 'A' && key <= 'Z') {
+ if (shift & 1)
+ chat_text += (char) key;
+ else
+ chat_text += (char) tolower(key);
+ }
+ else {
+ switch (key) {
+ case VK_BACK:
+ chat_text = chat_text.substring(0, chat_text.length()-1);
+ break;
+
+ case VK_SPACE: chat_text += ' '; break;
+ case '0': if (shift & 1) chat_text += ')'; else chat_text += '0'; break;
+ case '1': if (shift & 1) chat_text += '!'; else chat_text += '1'; break;
+ case '2': if (shift & 1) chat_text += '@'; else chat_text += '2'; break;
+ case '3': if (shift & 1) chat_text += '#'; else chat_text += '3'; break;
+ case '4': if (shift & 1) chat_text += '$'; else chat_text += '4'; break;
+ case '5': if (shift & 1) chat_text += '%'; else chat_text += '5'; break;
+ case '6': if (shift & 1) chat_text += '^'; else chat_text += '6'; break;
+ case '7': if (shift & 1) chat_text += '&'; else chat_text += '7'; break;
+ case '8': if (shift & 1) chat_text += '*'; else chat_text += '8'; break;
+ case '9': if (shift & 1) chat_text += '('; else chat_text += '9'; break;
+ case 186: if (shift & 1) chat_text += ':'; else chat_text += ';'; break;
+ case 187: if (shift & 1) chat_text += '+'; else chat_text += '='; break;
+ case 188: if (shift & 1) chat_text += '<'; else chat_text += ','; break;
+ case 189: if (shift & 1) chat_text += '_'; else chat_text += '-'; break;
+ case 190: if (shift & 1) chat_text += '>'; else chat_text += '.'; break;
+ case 191: if (shift & 1) chat_text += '?'; else chat_text += '/'; break;
+ case 192: if (shift & 1) chat_text += '~'; else chat_text += '`'; break;
+ case 219: if (shift & 1) chat_text += '{'; else chat_text += '['; break;
+ case 221: if (shift & 1) chat_text += '}'; else chat_text += ']'; break;
+ case 220: if (shift & 1) chat_text += '|'; else chat_text += '\\'; break;
+ case 222: if (shift & 1) chat_text += '"'; else chat_text += '\''; break;
+ }
+ }
+ }
+ }
+}
+
+void
+Starshatter::SetChatMode(int mode)
+{
+ if (mode >= 0 && mode <= 4 && mode != chat_mode) {
+ chat_text = "";
+
+ if (!NetGame::IsNetGame()) {
+ chat_mode = 0;
+ }
+ else {
+ chat_mode = mode;
+
+ // flush input before reading chat message:
+ if (chat_mode) {
+ FlushKeys();
+ }
+
+ // flush input before sampling flight controls:
+ else {
+ for (int i = 1; i < 255; i++) {
+ Keyboard::KeyDown(i);
+ }
+ }
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::DoMouseFrame()
+{
+ EventDispatch* event_dispatch = EventDispatch::GetInstance();
+ if (event_dispatch && event_dispatch->GetCapture())
+ return;
+
+ mouse_dx = 0;
+ mouse_dy = 0;
+
+ static int old_mouse_x = 0;
+ static int old_mouse_y = 0;
+
+ if (!spinning && Mouse::RButton()) {
+ spinning = true;
+ old_mouse_x = Mouse::X();
+ old_mouse_y = Mouse::Y();
+ mouse_x = Mouse::X();
+ mouse_y = Mouse::Y();
+ Mouse::Show(false);
+ }
+
+ else if (spinning) {
+ if (!Mouse::RButton()) {
+ spinning = false;
+
+ if (tactical) {
+ Mouse::Show(true);
+ Mouse::SetCursor(Mouse::ARROW);
+ }
+
+ Mouse::SetCursorPos(old_mouse_x, old_mouse_y);
+ }
+
+ else {
+ mouse_dx = Mouse::X() - mouse_x;
+ mouse_dy = Mouse::Y() - mouse_y;
+
+ Mouse::SetCursorPos(mouse_x, mouse_y);
+ }
+ }
+
+ else if (cutscene || !player_ship) {
+ Mouse::Show(false);
+ return;
+ }
+
+ // hide mouse cursor when mouse controller is actively steering:
+ else if (mouse_input && mouse_input->Active()) {
+ if (mouse_input->Selector() == 1) {
+ Mouse::Show(false);
+ }
+
+ else if (mouse_input->Selector() == 2) {
+ Mouse::Show(true);
+ Mouse::SetCursor(Mouse::CROSS);
+ }
+ }
+
+ else {
+ HUDView* hud_view = HUDView::GetInstance();
+
+ if (hud_view && hud_view->GetHUDMode() != HUDView::HUD_MODE_OFF) {
+ Mouse::Show(true);
+ Mouse::SetCursor(Mouse::ARROW);
+ }
+ }
+
+ if (gamescreen && gamescreen->IsFormShown())
+ return;
+
+ TacticalView* tac_view = TacticalView::GetInstance();
+
+ if (tac_view)
+ tac_view->DoMouseFrame();
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::SetupSplash()
+{
+ Color::SetFade(0);
+
+ if (gamewin) {
+ screen->DelWindow(gamewin);
+ delete gamewin;
+ gamewin = 0;
+ }
+
+ switch (splash_index) {
+ case 0:
+ splash_image.ClearImage();
+ loader->SetDataPath(0);
+ loader->LoadBitmap("matrix.pcx", splash_image);
+ break;
+
+ case 1:
+ default:
+ splash_image.ClearImage();
+ loader->SetDataPath(0);
+ loader->LoadBitmap("studio.pcx", splash_image);
+ break;
+ }
+
+ int screen_width = GetScreenWidth();
+ int screen_height = GetScreenHeight();
+
+ gamewin = new Window(screen, 0, 0, screen_width, screen_height);
+ splash = new FadeView(gamewin, 2, 2, 2);
+
+ gamewin->AddView(splash);
+ gamewin->AddView(new ImgView(gamewin, &splash_image));
+ screen->AddWindow(gamewin);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::SetupMenuScreen()
+{
+ if (menuscreen) {
+ delete menuscreen;
+ menuscreen = 0;
+ }
+
+ menuscreen = new MenuScreen();
+ menuscreen->Setup(screen);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::SetupCmpnScreen()
+{
+ if (cmpnscreen) {
+ delete cmpnscreen;
+ cmpnscreen = 0;
+ }
+
+ cmpnscreen = new CmpnScreen();
+ cmpnscreen->Setup(screen);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::SetupPlanScreen()
+{
+ if (planscreen) {
+ delete planscreen;
+ planscreen = 0;
+ }
+
+ planscreen = new PlanScreen();
+ planscreen->Setup(screen);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::SetupLoadScreen()
+{
+ if (loadscreen) {
+ delete loadscreen;
+ loadscreen = 0;
+ }
+
+ loadscreen = new LoadScreen();
+ loadscreen->Setup(screen);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::SetupGameScreen()
+{
+ if (gamescreen) {
+ delete gamescreen;
+ gamescreen = 0;
+ }
+
+ gamescreen = new GameScreen();
+ gamescreen->Setup(screen);
+ gamescreen->SetFieldOfView(field_of_view);
+
+ // initialize player_ship's MFD choices:
+ Player::SelectPlayer(Player::GetCurrentPlayer());
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::LoadVideoConfig(const char* filename)
+{
+ // set up defaults:
+ int screen_width = 1280;
+ int screen_height = 720;
+ int screen_depth = 32;
+ int gamma = 128;
+ int terrain_detail_level = 3;
+ bool shadows_enabled = true;
+ bool spec_maps_enabled = true;
+ bool bump_maps_enabled = true;
+ bool vertex_shader = true;
+ bool pixel_shader = true;
+ float depth_bias = video_settings->depth_bias;
+
+ max_tex_size = 2048;
+
+ if (MachineInfo::GetCpuSpeed() >= 1000 && MachineInfo::GetTotalRam() > 128)
+ terrain_detail_level = 4;
+
+ Terrain::SetDetailLevel(terrain_detail_level);
+
+ // read the config file:
+ BYTE* block = 0;
+ int blocklen = 0;
+
+ FILE* f = ::fopen(filename, "rb");
+
+ if (f) {
+ ::fseek(f, 0, SEEK_END);
+ blocklen = ftell(f);
+ ::fseek(f, 0, SEEK_SET);
+
+ block = new BYTE[blocklen+1];
+ block[blocklen] = 0;
+
+ ::fread(block, blocklen, 1, f);
+ ::fclose(f);
+ }
+
+ if (blocklen == 0)
+ return;
+
+ Parser parser(new BlockReader((const char*) block, blocklen));
+ Term* term = parser.ParseTerm();
+
+ if (!term) {
+ Print("ERROR: could not parse '%s'.\n", filename);
+ exit(-3);
+ }
+ else {
+ TermText* file_type = term->isText();
+ if (!file_type || file_type->value() != "VIDEO") {
+ Print("WARNING: invalid %s file. Using defaults\n", filename);
+ return;
+ }
+ }
+
+ do {
+ delete term;
+
+ term = parser.ParseTerm();
+
+ if (term) {
+ TermDef* def = term->isDef();
+ if (def) {
+ if (def->name()->value() == "width") {
+ int w;
+ GetDefNumber(w, def, filename);
+
+ switch (w) {
+ case 800:
+ screen_width = 800;
+ screen_height = 600;
+ break;
+
+ case 1024:
+ screen_width = 1024;
+ screen_height = 768;
+ break;
+
+ case 1152:
+ screen_width = 1152;
+ screen_height = 864;
+ break;
+
+ case 1280:
+ screen_width = 1280;
+ screen_height = 960;
+ break;
+
+ case 1440:
+ screen_width = 1440;
+ screen_height = 900;
+ break;
+
+ default:
+ screen_width = w;
+ screen_height = (w*3)/4;
+ break;
+ }
+ }
+
+ else if (def->name()->value() == "height") {
+ int h;
+ GetDefNumber(h, def, filename);
+
+ if (screen_width == 1280 && (h == 800 || h == 1024))
+ screen_height = h;
+ else if (screen_width == 1600 && (h == 900 || h == 1200))
+ screen_height = h;
+ }
+
+ else if (def->name()->value() == "depth" ||
+ def->name()->value() == "bpp") {
+
+ int bpp;
+ GetDefNumber(bpp, def, filename);
+
+ switch (bpp) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ screen_depth = bpp;
+ break;
+
+ default:
+ Print("WARNING: Invalid screen bpp (%d) in '%s'\n", bpp, filename);
+ screen_depth = 8;
+ break;
+ }
+ }
+
+ else if (def->name()->value() == "max_tex") {
+ int n;
+ GetDefNumber(n, def, filename);
+ if (n >= 64 && n <= 4096)
+ max_tex_size = n;
+ }
+
+ else if (def->name()->value() == "gamma") {
+ int level;
+ GetDefNumber(level, def, filename);
+ if (level >= 0 && level <= 255)
+ gamma = level;
+ }
+
+ else if (def->name()->value() == "terrain_detail_level") {
+ GetDefNumber(terrain_detail_level, def, filename);
+ Terrain::SetDetailLevel(terrain_detail_level);
+ }
+
+ else if (def->name()->value() == "terrain_texture_enable") {
+ bool enable;
+ GetDefBool(enable, def, filename);
+
+ // no longer supported!
+ }
+
+ else if (def->name()->value() == "shadows") {
+ GetDefBool(shadows_enabled, def, filename);
+ }
+
+ else if (def->name()->value() == "spec_maps") {
+ GetDefBool(spec_maps_enabled, def, filename);
+ }
+
+ else if (def->name()->value() == "bump_maps") {
+ GetDefBool(bump_maps_enabled, def, filename);
+ }
+
+ else if (def->name()->value() == "vertex_shader") {
+ GetDefBool(vertex_shader, def, filename);
+ }
+
+ else if (def->name()->value() == "pixel_shader") {
+ GetDefBool(pixel_shader, def, filename);
+ }
+
+ else if (def->name()->value().contains("bias")) {
+ GetDefNumber(depth_bias, def, filename);
+ }
+
+ else if (def->name()->value() == "flare") {
+ bool b;
+ GetDefBool(b, def, filename);
+ lens_flare = b;
+ }
+
+ else if (def->name()->value() == "corona") {
+ bool b;
+ GetDefBool(b, def, filename);
+ corona = b;
+ }
+
+ else if (def->name()->value() == "nebula") {
+ bool b;
+ GetDefBool(b, def, filename);
+ nebula = b;
+ }
+
+ else if (def->name()->value() == "dust") {
+ GetDefNumber(dust, def, filename);
+ }
+
+ else if (def->name()->value().indexOf("cam_range") == 0) {
+ double range_max = 0;
+ GetDefNumber(range_max, def, filename);
+ CameraDirector::SetRangeLimit(range_max);
+ }
+ }
+ else {
+ Print("WARNING: term ignored in '%s'\n", filename);
+ term->print();
+ }
+ }
+ }
+ while (term);
+
+ loader->ReleaseBuffer(block);
+
+ if (video_settings) {
+ video_settings->fullscreen_mode.width = screen_width;
+ video_settings->fullscreen_mode.height = screen_height;
+
+ if (screen_depth == 16)
+ video_settings->fullscreen_mode.format = VideoMode::FMT_R5G6B5;
+ else
+ video_settings->fullscreen_mode.format = VideoMode::FMT_X8R8G8B8;
+
+ video_settings->gamma = gamma;
+ video_settings->shadows = shadows_enabled;
+ video_settings->specmaps = spec_maps_enabled;
+ video_settings->bumpmaps = bump_maps_enabled;
+ video_settings->enable_vs = vertex_shader;
+ video_settings->enable_ps = pixel_shader;
+ video_settings->depth_bias = depth_bias;
+ }
+
+ if (video) {
+ video->SetShadowEnabled(shadows_enabled);
+ video->SetSpecMapEnabled(spec_maps_enabled);
+ video->SetBumpMapEnabled(bump_maps_enabled);
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::SaveVideoConfig(const char* filename)
+{
+ if (!video_settings)
+ return;
+
+ FILE* f = fopen(filename, "wb");
+ if (f) {
+ fprintf(f, "VIDEO\n\n");
+ fprintf(f, "width: %4d\n", video_settings->fullscreen_mode.width);
+ fprintf(f, "height: %4d\n", video_settings->fullscreen_mode.height);
+ fprintf(f, "depth: %4d\n", video_settings->fullscreen_mode.format == VideoMode::FMT_R5G6B5 ? 16 : 32);
+ fprintf(f, "\n");
+ fprintf(f, "max_tex: %4d\n", max_tex_size);
+ fprintf(f, "primary3D: %s\n", "true");
+ fprintf(f, "gamma: %4d\n", video_settings->gamma);
+ fprintf(f, "\n");
+ fprintf(f, "terrain_detail_level: %d\n", Terrain::DetailLevel());
+ fprintf(f, "terrain_texture_enable: %true\n");
+ fprintf(f, "\n");
+
+ fprintf(f, "shadows: %s\n", video_settings->shadows ? "true" : "false");
+ fprintf(f, "spec_maps: %s\n", video_settings->specmaps ? "true" : "false");
+ fprintf(f, "bump_maps: %s\n", video_settings->bumpmaps ? "true" : "false");
+ fprintf(f, "bias: %f\n", video_settings->depth_bias);
+ fprintf(f, "\n");
+
+ fprintf(f, "flare: %s\n", lens_flare ? "true" : "false");
+ fprintf(f, "corona: %s\n", corona ? "true" : "false");
+ fprintf(f, "nebula: %s\n", nebula ? "true" : "false");
+ fprintf(f, "dust: %d\n", dust);
+
+ if (CameraDirector::GetRangeLimit() != 300e3)
+ fprintf(f, " cam_range_max: %f,\n", CameraDirector::GetRangeLimit());
+
+ fclose(f);
+ }
+
+ video_changed = false;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Starshatter::ExecCutscene(const char* msn_file, const char* path)
+{
+ if (InCutscene() || !msn_file || !*msn_file) return;
+
+ if (!world)
+ CreateWorld();
+
+ cutscene_mission = new Mission(0);
+ cutscene_basetime = StarSystem::GetBaseTime();
+
+ if (cutscene_mission->Load(msn_file, path)) {
+ Sim* sim = (Sim*) world;
+
+ if (sim) {
+ bool dynamic = false;
+ Campaign* campaign = Campaign::GetCampaign();
+
+ if (campaign && campaign->IsDynamic())
+ dynamic = true;
+
+ sim->UnloadMission();
+ sim->LoadMission(cutscene_mission, true); // attempt to preload the tex cache
+ sim->ExecMission();
+ sim->ShowGrid(false);
+ player_ship = sim->GetPlayerShip();
+
+ Print(" Cutscene Instantiated.\n");
+
+ UpdateWorld();
+ }
+ }
+ else {
+ delete cutscene_mission;
+ cutscene_mission = 0;
+ cutscene_basetime = 0;
+ }
+}
+
+void
+Starshatter::BeginCutscene()
+{
+ Sim* sim = Sim::GetSim();
+
+ if (cutscene == 0 && !sim->IsNetGame()) {
+ HUDView* hud_view = HUDView::GetInstance();
+ if (hud_view)
+ hud_view->SetHUDMode(HUDView::HUD_MODE_OFF);
+
+ if (sim->GetPlayerShip())
+ sim->GetPlayerShip()->SetControls(0);
+
+ AudioConfig* audio_cfg = AudioConfig::GetInstance();
+
+ if (audio_cfg) {
+ cut_efx_volume = audio_cfg->GetEfxVolume();
+ cut_wrn_volume = audio_cfg->GetWrnVolume();
+ }
+
+ Ship::SetFlightModel(Ship::FM_ARCADE);
+ }
+
+ cutscene++;
+}
+
+void
+Starshatter::EndCutscene()
+{
+ cutscene--;
+
+ if (cutscene == 0) {
+ DisplayView* disp_view = DisplayView::GetInstance();
+ if (disp_view)
+ disp_view->ClearDisplay();
+
+ HUDView* hud_view = HUDView::GetInstance();
+ if (hud_view)
+ hud_view->SetHUDMode(HUDView::HUD_MODE_TAC);
+
+ Sim* sim = Sim::GetSim();
+ if (sim->GetPlayerShip())
+ sim->GetPlayerShip()->SetControls(sim->GetControls());
+
+ if (cam_dir) {
+ cam_dir->SetViewOrbital(0);
+ CameraDirector::SetRangeLimits(10, CameraDirector::GetRangeLimit());
+ cam_dir->SetOrbitPoint(PI/4,PI/4,1);
+ cam_dir->SetOrbitRates(0,0,0);
+ }
+
+ AudioConfig* audio_cfg = AudioConfig::GetInstance();
+
+ if (audio_cfg) {
+ audio_cfg->SetEfxVolume(cut_efx_volume);
+ audio_cfg->SetWrnVolume(cut_wrn_volume);
+ }
+
+ Player* p = Player::GetCurrentPlayer();
+ if (p)
+ Ship::SetFlightModel(p->FlightModel());
+ }
+}
+
+void
+Starshatter::EndMission()
+{
+ if (cutscene_mission) {
+ Sim* sim = Sim::GetSim();
+
+ if (sim && sim->GetMission() == cutscene_mission) {
+ ShipStats::Initialize();
+ sim->UnloadMission();
+
+ // restore world clock (true => absolute time reference)
+ if (cutscene_basetime != 0)
+ StarSystem::SetBaseTime(cutscene_basetime, true);
+
+ delete cutscene_mission;
+ cutscene_mission = 0;
+ cutscene_basetime = 0;
+
+ return;
+ }
+ }
+
+ SetGameMode(Starshatter::PLAN_MODE);
+}
+
+Mission*
+Starshatter::GetCutsceneMission() const
+{
+ return cutscene_mission;
+}
+
+const char*
+Starshatter::GetSubtitles() const
+{
+ if (cutscene_mission)
+ return cutscene_mission->Subtitles();
+
+ return "";
+}
+
+// +--------------------------------------------------------------------+
+
+int
+Starshatter::GetLobbyMode()
+{
+ return lobby_mode;
+}
+
+void
+Starshatter::SetLobbyMode(int mode)
+{
+ lobby_mode = mode;
+}
+
+void
+Starshatter::StartLobby()
+{
+ if (!net_lobby) {
+ if (lobby_mode == NET_LOBBY_SERVER) {
+ NetServerConfig::Initialize();
+ NetServerConfig* server_config = NetServerConfig::GetInstance();
+
+ if (server_config)
+ net_lobby = new NetLobbyServer;
+ }
+
+ else {
+ NetClientConfig* client_config = NetClientConfig::GetInstance();
+ if (client_config)
+ client_config->Login();
+
+ net_lobby = NetLobby::GetInstance();
+ }
+ }
+
+ lobby_mode = NET_LOBBY_CLIENT;
+}
+
+void
+Starshatter::StopLobby()
+{
+ if (net_lobby) {
+ if (net_lobby->IsServer()) {
+ delete net_lobby;
+ NetServerConfig::Close();
+ }
+
+ else {
+ NetClientConfig* client_config = NetClientConfig::GetInstance();
+ if (client_config)
+ client_config->Logout();
+ }
+
+ net_lobby = 0;
+ }
+
+ lobby_mode = NET_LOBBY_CLIENT;
+}
+
+void
+Starshatter::StopNetGame()
+{
+ // local server:
+ NetLobby* lobby = NetLobby::GetInstance();
+
+ if (lobby && lobby->IsServer()) {
+ lobby->GameStop();
+ }
+
+ // client connected to remote server:
+ else {
+ NetClientConfig* config = NetClientConfig::GetInstance();
+ if (config && config->GetHostRequest()) {
+ config->Login();
+
+ NetLobbyClient* conn = config->GetConnection();
+
+ if (conn) {
+ conn->GameStop();
+ conn->SelectMission(0);
+ }
+ }
+ }
+}