From 3c487c5cd69c53d6fea948643c0a76df03516605 Mon Sep 17 00:00:00 2001 From: Aki Date: Fri, 1 Apr 2022 21:23:39 +0200 Subject: Moved Stars45 to StarsEx --- Stars45/ActiveWindow.cpp | 1000 ------- Stars45/ActiveWindow.h | 324 --- Stars45/Archive.cpp | 589 ---- Stars45/Archive.h | 89 - Stars45/Asteroid.cpp | 114 - Stars45/Asteroid.h | 34 - Stars45/AudDlg.cpp | 199 -- Stars45/AudDlg.h | 78 - Stars45/AudioConfig.cpp | 382 --- Stars45/AudioConfig.h | 70 - Stars45/AwardDlg.cpp | 151 - Stars45/AwardDlg.h | 58 - Stars45/AwardShowDlg.cpp | 157 -- Stars45/AwardShowDlg.h | 62 - Stars45/BaseScreen.h | 82 - Stars45/Bitmap.cpp | 1616 ----------- Stars45/Bitmap.h | 123 - Stars45/Bmp.cpp | 251 -- Stars45/Bmp.h | 77 - Stars45/Bolt.cpp | 173 -- Stars45/Bolt.h | 64 - Stars45/Button.cpp | 685 ----- Stars45/Button.h | 120 - Stars45/CMakeLists.txt | 348 --- Stars45/Callsign.cpp | 100 - Stars45/Callsign.h | 28 - Stars45/Camera.cpp | 210 -- Stars45/Camera.h | 60 - Stars45/CameraDirector.cpp | 1194 -------- Stars45/CameraDirector.h | 155 - Stars45/CameraView.cpp | 800 ------ Stars45/CameraView.h | 113 - Stars45/Campaign.cpp | 2339 --------------- Stars45/Campaign.h | 281 -- Stars45/CampaignMissionFighter.cpp | 2154 -------------- Stars45/CampaignMissionFighter.h | 120 - Stars45/CampaignMissionRequest.cpp | 37 - Stars45/CampaignMissionRequest.h | 83 - Stars45/CampaignMissionStarship.cpp | 1403 --------- Stars45/CampaignMissionStarship.h | 106 - Stars45/CampaignPlan.h | 57 - Stars45/CampaignPlanAssignment.cpp | 156 - Stars45/CampaignPlanAssignment.h | 49 - Stars45/CampaignPlanEvent.cpp | 1274 --------- Stars45/CampaignPlanEvent.h | 71 - Stars45/CampaignPlanMission.cpp | 372 --- Stars45/CampaignPlanMission.h | 57 - Stars45/CampaignPlanMovement.cpp | 166 -- Stars45/CampaignPlanMovement.h | 43 - Stars45/CampaignPlanStrategic.cpp | 481 ---- Stars45/CampaignPlanStrategic.h | 58 - Stars45/CampaignSaveGame.cpp | 733 ----- Stars45/CampaignSaveGame.h | 68 - Stars45/CampaignSituationReport.cpp | 414 --- Stars45/CampaignSituationReport.h | 58 - Stars45/CarrierAI.cpp | 398 --- Stars45/CarrierAI.h | 63 - Stars45/Clock.cpp | 143 - Stars45/Clock.h | 54 - Stars45/CmdDlg.cpp | 182 -- Stars45/CmdDlg.h | 82 - Stars45/CmdForceDlg.cpp | 715 ----- Stars45/CmdForceDlg.h | 68 - Stars45/CmdIntelDlg.cpp | 392 --- Stars45/CmdIntelDlg.h | 75 - Stars45/CmdMissionsDlg.cpp | 324 --- Stars45/CmdMissionsDlg.h | 64 - Stars45/CmdMsgDlg.cpp | 90 - Stars45/CmdMsgDlg.h | 53 - Stars45/CmdOrdersDlg.cpp | 138 - Stars45/CmdOrdersDlg.h | 55 - Stars45/CmdTheaterDlg.cpp | 214 -- Stars45/CmdTheaterDlg.h | 61 - Stars45/CmdTitleDlg.cpp | 76 - Stars45/CmdTitleDlg.h | 55 - Stars45/CmpCompleteDlg.cpp | 106 - Stars45/CmpCompleteDlg.h | 49 - Stars45/CmpFileDlg.cpp | 189 -- Stars45/CmpFileDlg.h | 63 - Stars45/CmpLoadDlg.cpp | 116 - Stars45/CmpLoadDlg.h | 45 - Stars45/CmpSceneDlg.cpp | 186 -- Stars45/CmpSceneDlg.h | 67 - Stars45/CmpSelectDlg.cpp | 609 ---- Stars45/CmpSelectDlg.h | 92 - Stars45/CmpnScreen.cpp | 636 ----- Stars45/CmpnScreen.h | 136 - Stars45/Color.cpp | 680 ----- Stars45/Color.h | 294 -- Stars45/CombatAction.cpp | 350 --- Stars45/CombatAction.h | 204 -- Stars45/CombatAssignment.cpp | 66 - Stars45/CombatAssignment.h | 56 - Stars45/CombatEvent.cpp | 151 - Stars45/CombatEvent.h | 121 - Stars45/CombatGroup.cpp | 1590 ----------- Stars45/CombatGroup.h | 230 -- Stars45/CombatRoster.cpp | 91 - Stars45/CombatRoster.h | 47 - Stars45/CombatUnit.cpp | 384 --- Stars45/CombatUnit.h | 132 - Stars45/CombatZone.cpp | 280 -- Stars45/CombatZone.h | 102 - Stars45/Combatant.cpp | 170 -- Stars45/Combatant.h | 72 - Stars45/ComboBox.cpp | 432 --- Stars45/ComboBox.h | 104 - Stars45/ComboList.cpp | 436 --- Stars45/ComboList.h | 91 - Stars45/Component.cpp | 175 -- Stars45/Component.h | 99 - Stars45/Computer.cpp | 92 - Stars45/Computer.h | 40 - Stars45/ConfirmDlg.cpp | 148 - Stars45/ConfirmDlg.h | 63 - Stars45/Contact.cpp | 364 --- Stars45/Contact.h | 90 - Stars45/ContentBundle.cpp | 194 -- Stars45/ContentBundle.h | 56 - Stars45/CtlDlg.cpp | 460 --- Stars45/CtlDlg.h | 118 - Stars45/D3DXImage.cpp | 221 -- Stars45/D3DXImage.h | 42 - Stars45/DataLoader.cpp | 1015 ------- Stars45/DataLoader.h | 85 - Stars45/DebriefDlg.cpp | 373 --- Stars45/DebriefDlg.h | 80 - Stars45/Debris.cpp | 218 -- Stars45/Debris.h | 42 - Stars45/DetailSet.cpp | 225 -- Stars45/DetailSet.h | 72 - Stars45/Director.h | 43 - Stars45/DisplayView.cpp | 237 -- Stars45/DisplayView.h | 70 - Stars45/Drive.cpp | 500 ---- Stars45/Drive.h | 92 - Stars45/DriveSprite.cpp | 141 - Stars45/DriveSprite.h | 46 - Stars45/Drone.cpp | 194 -- Stars45/Drone.h | 68 - Stars45/DropShipAI.cpp | 120 - Stars45/DropShipAI.h | 46 - Stars45/EditBox.cpp | 448 --- Stars45/EditBox.h | 91 - Stars45/Element.cpp | 665 ----- Stars45/Element.h | 171 -- Stars45/Encrypt.cpp | 168 -- Stars45/Encrypt.h | 37 - Stars45/EngDlg.cpp | 1042 ------- Stars45/EngDlg.h | 105 - Stars45/EventDispatch.cpp | 273 -- Stars45/EventDispatch.h | 61 - Stars45/EventTarget.h | 58 - Stars45/ExceptionHandler.cpp | 431 --- Stars45/ExitDlg.cpp | 150 - Stars45/ExitDlg.h | 59 - Stars45/Explosion.cpp | 609 ---- Stars45/Explosion.h | 83 - Stars45/FadeView.cpp | 133 - Stars45/FadeView.h | 54 - Stars45/Farcaster.cpp | 287 -- Stars45/Farcaster.h | 91 - Stars45/FighterAI.cpp | 1832 ------------ Stars45/FighterAI.h | 84 - Stars45/FighterTacticalAI.cpp | 561 ---- Stars45/FighterTacticalAI.h | 55 - Stars45/FirstTimeDlg.cpp | 145 - Stars45/FirstTimeDlg.h | 55 - Stars45/Fix.cpp | 22 - Stars45/Fix.h | 120 - Stars45/FlightComp.cpp | 303 -- Stars45/FlightComp.h | 62 - Stars45/FlightDeck.cpp | 1185 -------- Stars45/FlightDeck.h | 194 -- Stars45/FlightPlanner.cpp | 370 --- Stars45/FlightPlanner.h | 50 - Stars45/FltDlg.cpp | 1084 ------- Stars45/FltDlg.h | 80 - Stars45/Font.cpp | 1229 -------- Stars45/Font.h | 142 - Stars45/FontMgr.cpp | 56 - Stars45/FontMgr.h | 49 - Stars45/FormDef.cpp | 1268 --------- Stars45/FormDef.h | 331 --- Stars45/FormWindow.cpp | 807 ------ Stars45/FormWindow.h | 76 - Stars45/FormatUtil.cpp | 335 --- Stars45/FormatUtil.h | 46 - Stars45/Galaxy.cpp | 281 -- Stars45/Galaxy.h | 73 - Stars45/Game.cpp | 292 -- Stars45/Game.h | 117 - Stars45/GameScreen.cpp | 1251 --------- Stars45/GameScreen.h | 191 -- Stars45/GameWinDX9.cpp | 662 ----- Stars45/GameWinDX9.h | 79 - Stars45/Geometry.cpp | 696 ----- Stars45/Geometry.h | 303 -- Stars45/Graphic.cpp | 168 -- Stars45/Graphic.h | 138 - Stars45/Grid.cpp | 90 - Stars45/Grid.h | 49 - Stars45/GroundAI.cpp | 189 -- Stars45/GroundAI.h | 60 - Stars45/HUDSounds.cpp | 116 - Stars45/HUDSounds.h | 45 - Stars45/HUDView.cpp | 4373 ---------------------------- Stars45/HUDView.h | 217 -- Stars45/Hangar.cpp | 932 ------ Stars45/Hangar.h | 126 - Stars45/HardPoint.cpp | 102 - Stars45/HardPoint.h | 81 - Stars45/Hoop.cpp | 154 - Stars45/Hoop.h | 44 - Stars45/IA3D.H | 128 - Stars45/ImageBox.cpp | 296 -- Stars45/ImageBox.h | 70 - Stars45/ImgView.cpp | 77 - Stars45/ImgView.h | 50 - Stars45/Instruction.cpp | 568 ---- Stars45/Instruction.h | 165 -- Stars45/Intel.cpp | 44 - Stars45/Intel.h | 36 - Stars45/JoyDlg.cpp | 229 -- Stars45/JoyDlg.h | 55 - Stars45/Joystick.cpp | 914 ------ Stars45/Joystick.h | 82 - Stars45/KeyDlg.cpp | 197 -- Stars45/KeyDlg.h | 64 - Stars45/KeyMap.cpp | 825 ------ Stars45/KeyMap.h | 180 -- Stars45/Keyboard.cpp | 215 -- Stars45/Keyboard.h | 73 - Stars45/LandingGear.cpp | 278 -- Stars45/LandingGear.h | 65 - Stars45/Layout.cpp | 249 -- Stars45/Layout.h | 64 - Stars45/Light.cpp | 70 - Stars45/Light.h | 95 - Stars45/ListBox.cpp | 1332 --------- Stars45/ListBox.h | 169 -- Stars45/LoadDlg.cpp | 76 - Stars45/LoadDlg.h | 40 - Stars45/LoadScreen.cpp | 160 -- Stars45/LoadScreen.h | 63 - Stars45/Locale_ss.cpp | 234 -- Stars45/Locale_ss.h | 52 - Stars45/MCIWave.cpp | 150 - Stars45/MCIWave.h | 24 - Stars45/MachineInfo.cpp | 823 ------ Stars45/MachineInfo.h | 41 - Stars45/Main.cpp | 150 - Stars45/MapView.cpp | 3482 ----------------------- Stars45/MapView.h | 222 -- Stars45/Menu.cpp | 141 - Stars45/Menu.h | 123 - Stars45/MenuDlg.cpp | 273 -- Stars45/MenuDlg.h | 85 - Stars45/MenuScreen.cpp | 1073 ------- Stars45/MenuScreen.h | 198 -- Stars45/MenuView.cpp | 331 --- Stars45/MenuView.h | 76 - Stars45/Mfd.cpp | 1405 --------- Stars45/Mfd.h | 103 - Stars45/Mission.cpp | 2160 -------------- Stars45/Mission.h | 425 --- Stars45/MissionEvent.cpp | 872 ------ Stars45/MissionEvent.h | 166 -- Stars45/MissionTemplate.cpp | 844 ------ Stars45/MissionTemplate.h | 116 - Stars45/ModConfig.cpp | 373 --- Stars45/ModConfig.h | 74 - Stars45/ModDlg.cpp | 342 --- Stars45/ModDlg.h | 93 - Stars45/ModInfo.cpp | 290 -- Stars45/ModInfo.h | 121 - Stars45/ModInfoDlg.cpp | 113 - Stars45/ModInfoDlg.h | 64 - Stars45/MotionController.h | 230 -- Stars45/Mouse.cpp | 190 -- Stars45/Mouse.h | 74 - Stars45/MouseController.cpp | 245 -- Stars45/MouseController.h | 69 - Stars45/MsnDlg.cpp | 303 -- Stars45/MsnDlg.h | 72 - Stars45/MsnEditDlg.cpp | 895 ------ Stars45/MsnEditDlg.h | 115 - Stars45/MsnEditNavDlg.cpp | 298 -- Stars45/MsnEditNavDlg.h | 77 - Stars45/MsnElemDlg.cpp | 804 ------ Stars45/MsnElemDlg.h | 98 - Stars45/MsnEventDlg.cpp | 414 --- Stars45/MsnEventDlg.h | 85 - Stars45/MsnNavDlg.cpp | 102 - Stars45/MsnNavDlg.h | 53 - Stars45/MsnObjDlg.cpp | 315 --- Stars45/MsnObjDlg.h | 67 - Stars45/MsnPkgDlg.cpp | 335 --- Stars45/MsnPkgDlg.h | 65 - Stars45/MsnSelectDlg.cpp | 498 ---- Stars45/MsnSelectDlg.h | 80 - Stars45/MsnWepDlg.cpp | 515 ---- Stars45/MsnWepDlg.h | 85 - Stars45/MultiController.cpp | 128 - Stars45/MultiController.h | 67 - Stars45/MusicDirector.cpp | 519 ---- Stars45/MusicDirector.h | 115 - Stars45/MusicTrack.cpp | 272 -- Stars45/MusicTrack.h | 76 - Stars45/NPClient.h | 190 -- Stars45/NPClientWraps.cpp | 256 -- Stars45/NPClientWraps.h | 33 - Stars45/NavAI.cpp | 621 ---- Stars45/NavAI.h | 73 - Stars45/NavDlg.cpp | 1125 -------- Stars45/NavDlg.h | 118 - Stars45/NavLight.cpp | 187 -- Stars45/NavLight.h | 66 - Stars45/NavSystem.cpp | 112 - Stars45/NavSystem.h | 54 - Stars45/NetAddrDlg.cpp | 158 -- Stars45/NetAddrDlg.h | 59 - Stars45/NetAdminChat.cpp | 120 - Stars45/NetAdminChat.h | 32 - Stars45/NetAdminServer.cpp | 884 ------ Stars45/NetAdminServer.h | 90 - Stars45/NetAuth.cpp | 204 -- Stars45/NetAuth.h | 50 - Stars45/NetBrokerClient.cpp | 237 -- Stars45/NetBrokerClient.h | 42 - Stars45/NetChat.cpp | 51 - Stars45/NetChat.h | 51 - Stars45/NetClientConfig.cpp | 331 --- Stars45/NetClientConfig.h | 72 - Stars45/NetClientDlg.cpp | 430 --- Stars45/NetClientDlg.h | 79 - Stars45/NetData.cpp | 1451 ---------- Stars45/NetData.h | 965 ------- Stars45/NetFileServlet.cpp | 117 - Stars45/NetFileServlet.h | 49 - Stars45/NetGame.cpp | 328 --- Stars45/NetGame.h | 126 - Stars45/NetGameClient.cpp | 1068 ------- Stars45/NetGameClient.h | 86 - Stars45/NetGameServer.cpp | 1202 -------- Stars45/NetGameServer.h | 89 - Stars45/NetLobby.cpp | 628 ----- Stars45/NetLobby.h | 288 -- Stars45/NetLobbyClient.cpp | 807 ------ Stars45/NetLobbyClient.h | 103 - Stars45/NetLobbyDlg.cpp | 473 ---- Stars45/NetLobbyDlg.h | 88 - Stars45/NetLobbyServer.cpp | 1361 --------- Stars45/NetLobbyServer.h | 118 - Stars45/NetPacket.cpp | 354 --- Stars45/NetPacket.h | 73 - Stars45/NetPassDlg.cpp | 141 - Stars45/NetPassDlg.h | 57 - Stars45/NetPlayer.cpp | 468 --- Stars45/NetPlayer.h | 97 - Stars45/NetServerConfig.cpp | 470 ---- Stars45/NetServerConfig.h | 101 - Stars45/NetServerDlg.cpp | 177 -- Stars45/NetServerDlg.h | 63 - Stars45/NetUnitDlg.cpp | 641 ----- Stars45/NetUnitDlg.h | 92 - Stars45/NetUser.cpp | 115 - Stars45/NetUser.h | 111 - Stars45/NetUtil.cpp | 422 --- Stars45/NetUtil.h | 55 - Stars45/OptDlg.cpp | 320 --- Stars45/OptDlg.h | 86 - Stars45/PCX.CPP | 514 ---- Stars45/Panic.cpp | 50 - Stars45/Panic.h | 19 - Stars45/ParseUtil.cpp | 479 ---- Stars45/ParseUtil.h | 51 - Stars45/Parser.cpp | 307 -- Stars45/Parser.h | 45 - Stars45/Particles.cpp | 262 -- Stars45/Particles.h | 85 - Stars45/Pcx.h | 67 - Stars45/Physical.cpp | 774 ----- Stars45/Physical.h | 204 -- Stars45/PlanScreen.cpp | 392 --- Stars45/PlanScreen.h | 107 - Stars45/Player.cpp | 1553 ---------- Stars45/Player.h | 186 -- Stars45/PlayerDlg.cpp | 389 --- Stars45/PlayerDlg.h | 85 - Stars45/PngImage.cpp | 255 -- Stars45/PngImage.h | 47 - Stars45/Polygon.cpp | 738 ----- Stars45/Polygon.h | 158 -- Stars45/Power.cpp | 299 -- Stars45/Power.h | 61 - Stars45/Projector.cpp | 473 ---- Stars45/Projector.h | 105 - Stars45/QuantumDrive.cpp | 245 -- Stars45/QuantumDrive.h | 72 - Stars45/QuantumFlash.cpp | 173 -- Stars45/QuantumFlash.h | 59 - Stars45/QuantumView.cpp | 317 --- Stars45/QuantumView.h | 72 - Stars45/QuitView.cpp | 302 -- Stars45/QuitView.h | 63 - Stars45/RLoc.cpp | 86 - Stars45/RLoc.h | 70 - Stars45/RadioHandler.cpp | 557 ---- Stars45/RadioHandler.h | 52 - Stars45/RadioMessage.cpp | 163 -- Stars45/RadioMessage.h | 154 - Stars45/RadioTraffic.cpp | 392 --- Stars45/RadioTraffic.h | 64 - Stars45/RadioView.cpp | 641 ----- Stars45/RadioView.h | 88 - Stars45/RadioVox.cpp | 248 -- Stars45/RadioVox.h | 58 - Stars45/Random.cpp | 146 - Stars45/Random.h | 34 - Stars45/Reader.cpp | 109 - Stars45/Reader.h | 67 - Stars45/Res.cpp | 26 - Stars45/Res.h | 36 - Stars45/RichTextBox.cpp | 452 --- Stars45/RichTextBox.h | 64 - Stars45/Scene.cpp | 258 -- Stars45/Scene.h | 75 - Stars45/Screen.cpp | 160 -- Stars45/Screen.h | 64 - Stars45/ScrollWindow.cpp | 629 ----- Stars45/ScrollWindow.h | 131 - Stars45/SeekerAI.cpp | 255 -- Stars45/SeekerAI.h | 72 - Stars45/Sensor.cpp | 849 ------ Stars45/Sensor.h | 85 - Stars45/Sha1.cpp | 589 ---- Stars45/Sha1.h | 89 - Stars45/Shadow.cpp | 174 -- Stars45/Shadow.h | 69 - Stars45/Shield.cpp | 258 -- Stars45/Shield.h | 76 - Stars45/ShieldRep.cpp | 248 -- Stars45/ShieldRep.h | 47 - Stars45/Ship.cpp | 5313 ----------------------------------- Stars45/Ship.h | 582 ---- Stars45/ShipAI.cpp | 1360 --------- Stars45/ShipAI.h | 152 - Stars45/ShipCtrl.cpp | 339 --- Stars45/ShipCtrl.h | 58 - Stars45/ShipDesign.cpp | 3702 ------------------------ Stars45/ShipDesign.h | 291 -- Stars45/ShipKiller.cpp | 261 -- Stars45/ShipKiller.h | 54 - Stars45/ShipSolid.cpp | 94 - Stars45/ShipSolid.h | 51 - Stars45/Shot.cpp | 625 ---- Stars45/Shot.h | 128 - Stars45/Sim.cpp | 3814 ------------------------- Stars45/Sim.h | 329 --- Stars45/SimEvent.cpp | 261 -- Stars45/SimEvent.h | 162 -- Stars45/SimObject.cpp | 148 - Stars45/SimObject.h | 98 - Stars45/Skin.cpp | 172 -- Stars45/Skin.h | 91 - Stars45/Sky.cpp | 723 ----- Stars45/Sky.h | 104 - Stars45/Slider.cpp | 555 ---- Stars45/Slider.h | 106 - Stars45/Solid.cpp | 2476 ---------------- Stars45/Solid.h | 312 -- Stars45/Sound.cpp | 284 -- Stars45/Sound.h | 149 - Stars45/SoundCard.cpp | 103 - Stars45/SoundCard.h | 76 - Stars45/SoundD3D.cpp | 1296 --------- Stars45/SoundD3D.h | 162 -- Stars45/Sprite.cpp | 378 --- Stars45/Sprite.h | 89 - Stars45/StarServer.cpp | 436 --- Stars45/StarServer.h | 74 - Stars45/StarSystem.cpp | 1953 ------------- Stars45/StarSystem.h | 321 --- Stars45/Stars.ico | Bin 2998 -> 0 bytes Stars45/Stars.rc.conf | 39 - Stars45/Starshatter.cpp | 2838 ------------------- Stars45/Starshatter.h | 219 -- Stars45/StarshipAI.cpp | 821 ------ Stars45/StarshipAI.h | 61 - Stars45/StarshipTacticalAI.cpp | 280 -- Stars45/StarshipTacticalAI.h | 46 - Stars45/SteerAI.cpp | 451 --- Stars45/SteerAI.h | 124 - Stars45/System.cpp | 397 --- Stars45/System.h | 173 -- Stars45/SystemDesign.cpp | 166 -- Stars45/SystemDesign.h | 53 - Stars45/TacRefDlg.cpp | 688 ----- Stars45/TacRefDlg.h | 100 - Stars45/TacticalAI.cpp | 957 ------- Stars45/TacticalAI.h | 90 - Stars45/TacticalView.cpp | 1494 ---------- Stars45/TacticalView.h | 119 - Stars45/Term.cpp | 119 - Stars45/Term.h | 171 -- Stars45/Terrain.cpp | 559 ---- Stars45/Terrain.h | 118 - Stars45/TerrainApron.cpp | 334 --- Stars45/TerrainApron.h | 70 - Stars45/TerrainClouds.cpp | 267 -- Stars45/TerrainClouds.h | 63 - Stars45/TerrainHaze.cpp | 88 - Stars45/TerrainHaze.h | 45 - Stars45/TerrainLayer.h | 62 - Stars45/TerrainPatch.cpp | 1112 -------- Stars45/TerrainPatch.h | 93 - Stars45/TerrainRegion.cpp | 264 -- Stars45/TerrainRegion.h | 125 - Stars45/TexCubeDX9.cpp | 118 - Stars45/TexCubeDX9.h | 48 - Stars45/TexDX9.cpp | 416 --- Stars45/TexDX9.h | 78 - Stars45/Thruster.cpp | 594 ---- Stars45/Thruster.h | 96 - Stars45/Token.cpp | 544 ---- Stars45/Token.h | 145 - Stars45/TrackIR.cpp | 245 -- Stars45/TrackIR.h | 52 - Stars45/Trail.cpp | 199 -- Stars45/Trail.h | 59 - Stars45/Types.h | 65 - Stars45/Universe.h | 31 - Stars45/VersionInfo.cpp.conf | 9 - Stars45/VersionInfo.h | 12 - Stars45/VidDlg.cpp | 544 ---- Stars45/VidDlg.h | 106 - Stars45/Video.cpp | 63 - Stars45/Video.h | 241 -- Stars45/VideoDX9.cpp | 3618 ------------------------ Stars45/VideoDX9.h | 194 -- Stars45/VideoDX9Enum.cpp | 1063 ------- Stars45/VideoDX9Enum.h | 184 -- Stars45/VideoDX9VertexBuffer.cpp | 279 -- Stars45/VideoDX9VertexBuffer.h | 78 - Stars45/VideoFactory.cpp | 69 - Stars45/VideoFactory.h | 41 - Stars45/VideoSettings.cpp | 273 -- Stars45/VideoSettings.h | 132 - Stars45/View.h | 51 - Stars45/Water.cpp | 293 -- Stars45/Water.h | 53 - Stars45/Wave.h | 51 - Stars45/Weapon.cpp | 1184 -------- Stars45/Weapon.h | 203 -- Stars45/WeaponDesign.cpp | 725 ----- Stars45/WeaponDesign.h | 186 -- Stars45/WeaponGroup.cpp | 346 --- Stars45/WeaponGroup.h | 105 - Stars45/Weather.cpp | 177 -- Stars45/Weather.h | 66 - Stars45/WebBrowser.cpp | 131 - Stars45/WebBrowser.h | 45 - Stars45/WepView.cpp | 529 ---- Stars45/WepView.h | 87 - Stars45/Window.cpp | 934 ------ Stars45/Window.h | 103 - Stars45/WndProc.cpp | 259 -- Stars45/WndProc.h | 21 - Stars45/resource.h | 6 - 570 files changed, 184206 deletions(-) delete mode 100644 Stars45/ActiveWindow.cpp delete mode 100644 Stars45/ActiveWindow.h delete mode 100644 Stars45/Archive.cpp delete mode 100644 Stars45/Archive.h delete mode 100644 Stars45/Asteroid.cpp delete mode 100644 Stars45/Asteroid.h delete mode 100644 Stars45/AudDlg.cpp delete mode 100644 Stars45/AudDlg.h delete mode 100644 Stars45/AudioConfig.cpp delete mode 100644 Stars45/AudioConfig.h delete mode 100644 Stars45/AwardDlg.cpp delete mode 100644 Stars45/AwardDlg.h delete mode 100644 Stars45/AwardShowDlg.cpp delete mode 100644 Stars45/AwardShowDlg.h delete mode 100644 Stars45/BaseScreen.h delete mode 100644 Stars45/Bitmap.cpp delete mode 100644 Stars45/Bitmap.h delete mode 100644 Stars45/Bmp.cpp delete mode 100644 Stars45/Bmp.h delete mode 100644 Stars45/Bolt.cpp delete mode 100644 Stars45/Bolt.h delete mode 100644 Stars45/Button.cpp delete mode 100644 Stars45/Button.h delete mode 100644 Stars45/CMakeLists.txt delete mode 100644 Stars45/Callsign.cpp delete mode 100644 Stars45/Callsign.h delete mode 100644 Stars45/Camera.cpp delete mode 100644 Stars45/Camera.h delete mode 100644 Stars45/CameraDirector.cpp delete mode 100644 Stars45/CameraDirector.h delete mode 100644 Stars45/CameraView.cpp delete mode 100644 Stars45/CameraView.h delete mode 100644 Stars45/Campaign.cpp delete mode 100644 Stars45/Campaign.h delete mode 100644 Stars45/CampaignMissionFighter.cpp delete mode 100644 Stars45/CampaignMissionFighter.h delete mode 100644 Stars45/CampaignMissionRequest.cpp delete mode 100644 Stars45/CampaignMissionRequest.h delete mode 100644 Stars45/CampaignMissionStarship.cpp delete mode 100644 Stars45/CampaignMissionStarship.h delete mode 100644 Stars45/CampaignPlan.h delete mode 100644 Stars45/CampaignPlanAssignment.cpp delete mode 100644 Stars45/CampaignPlanAssignment.h delete mode 100644 Stars45/CampaignPlanEvent.cpp delete mode 100644 Stars45/CampaignPlanEvent.h delete mode 100644 Stars45/CampaignPlanMission.cpp delete mode 100644 Stars45/CampaignPlanMission.h delete mode 100644 Stars45/CampaignPlanMovement.cpp delete mode 100644 Stars45/CampaignPlanMovement.h delete mode 100644 Stars45/CampaignPlanStrategic.cpp delete mode 100644 Stars45/CampaignPlanStrategic.h delete mode 100644 Stars45/CampaignSaveGame.cpp delete mode 100644 Stars45/CampaignSaveGame.h delete mode 100644 Stars45/CampaignSituationReport.cpp delete mode 100644 Stars45/CampaignSituationReport.h delete mode 100644 Stars45/CarrierAI.cpp delete mode 100644 Stars45/CarrierAI.h delete mode 100644 Stars45/Clock.cpp delete mode 100644 Stars45/Clock.h delete mode 100644 Stars45/CmdDlg.cpp delete mode 100644 Stars45/CmdDlg.h delete mode 100644 Stars45/CmdForceDlg.cpp delete mode 100644 Stars45/CmdForceDlg.h delete mode 100644 Stars45/CmdIntelDlg.cpp delete mode 100644 Stars45/CmdIntelDlg.h delete mode 100644 Stars45/CmdMissionsDlg.cpp delete mode 100644 Stars45/CmdMissionsDlg.h delete mode 100644 Stars45/CmdMsgDlg.cpp delete mode 100644 Stars45/CmdMsgDlg.h delete mode 100644 Stars45/CmdOrdersDlg.cpp delete mode 100644 Stars45/CmdOrdersDlg.h delete mode 100644 Stars45/CmdTheaterDlg.cpp delete mode 100644 Stars45/CmdTheaterDlg.h delete mode 100644 Stars45/CmdTitleDlg.cpp delete mode 100644 Stars45/CmdTitleDlg.h delete mode 100644 Stars45/CmpCompleteDlg.cpp delete mode 100644 Stars45/CmpCompleteDlg.h delete mode 100644 Stars45/CmpFileDlg.cpp delete mode 100644 Stars45/CmpFileDlg.h delete mode 100644 Stars45/CmpLoadDlg.cpp delete mode 100644 Stars45/CmpLoadDlg.h delete mode 100644 Stars45/CmpSceneDlg.cpp delete mode 100644 Stars45/CmpSceneDlg.h delete mode 100644 Stars45/CmpSelectDlg.cpp delete mode 100644 Stars45/CmpSelectDlg.h delete mode 100644 Stars45/CmpnScreen.cpp delete mode 100644 Stars45/CmpnScreen.h delete mode 100644 Stars45/Color.cpp delete mode 100644 Stars45/Color.h delete mode 100644 Stars45/CombatAction.cpp delete mode 100644 Stars45/CombatAction.h delete mode 100644 Stars45/CombatAssignment.cpp delete mode 100644 Stars45/CombatAssignment.h delete mode 100644 Stars45/CombatEvent.cpp delete mode 100644 Stars45/CombatEvent.h delete mode 100644 Stars45/CombatGroup.cpp delete mode 100644 Stars45/CombatGroup.h delete mode 100644 Stars45/CombatRoster.cpp delete mode 100644 Stars45/CombatRoster.h delete mode 100644 Stars45/CombatUnit.cpp delete mode 100644 Stars45/CombatUnit.h delete mode 100644 Stars45/CombatZone.cpp delete mode 100644 Stars45/CombatZone.h delete mode 100644 Stars45/Combatant.cpp delete mode 100644 Stars45/Combatant.h delete mode 100644 Stars45/ComboBox.cpp delete mode 100644 Stars45/ComboBox.h delete mode 100644 Stars45/ComboList.cpp delete mode 100644 Stars45/ComboList.h delete mode 100644 Stars45/Component.cpp delete mode 100644 Stars45/Component.h delete mode 100644 Stars45/Computer.cpp delete mode 100644 Stars45/Computer.h delete mode 100644 Stars45/ConfirmDlg.cpp delete mode 100644 Stars45/ConfirmDlg.h delete mode 100644 Stars45/Contact.cpp delete mode 100644 Stars45/Contact.h delete mode 100644 Stars45/ContentBundle.cpp delete mode 100644 Stars45/ContentBundle.h delete mode 100644 Stars45/CtlDlg.cpp delete mode 100644 Stars45/CtlDlg.h delete mode 100644 Stars45/D3DXImage.cpp delete mode 100644 Stars45/D3DXImage.h delete mode 100644 Stars45/DataLoader.cpp delete mode 100644 Stars45/DataLoader.h delete mode 100644 Stars45/DebriefDlg.cpp delete mode 100644 Stars45/DebriefDlg.h delete mode 100644 Stars45/Debris.cpp delete mode 100644 Stars45/Debris.h delete mode 100644 Stars45/DetailSet.cpp delete mode 100644 Stars45/DetailSet.h delete mode 100644 Stars45/Director.h delete mode 100644 Stars45/DisplayView.cpp delete mode 100644 Stars45/DisplayView.h delete mode 100644 Stars45/Drive.cpp delete mode 100644 Stars45/Drive.h delete mode 100644 Stars45/DriveSprite.cpp delete mode 100644 Stars45/DriveSprite.h delete mode 100644 Stars45/Drone.cpp delete mode 100644 Stars45/Drone.h delete mode 100644 Stars45/DropShipAI.cpp delete mode 100644 Stars45/DropShipAI.h delete mode 100644 Stars45/EditBox.cpp delete mode 100644 Stars45/EditBox.h delete mode 100644 Stars45/Element.cpp delete mode 100644 Stars45/Element.h delete mode 100644 Stars45/Encrypt.cpp delete mode 100644 Stars45/Encrypt.h delete mode 100644 Stars45/EngDlg.cpp delete mode 100644 Stars45/EngDlg.h delete mode 100644 Stars45/EventDispatch.cpp delete mode 100644 Stars45/EventDispatch.h delete mode 100644 Stars45/EventTarget.h delete mode 100644 Stars45/ExceptionHandler.cpp delete mode 100644 Stars45/ExitDlg.cpp delete mode 100644 Stars45/ExitDlg.h delete mode 100644 Stars45/Explosion.cpp delete mode 100644 Stars45/Explosion.h delete mode 100644 Stars45/FadeView.cpp delete mode 100644 Stars45/FadeView.h delete mode 100644 Stars45/Farcaster.cpp delete mode 100644 Stars45/Farcaster.h delete mode 100644 Stars45/FighterAI.cpp delete mode 100644 Stars45/FighterAI.h delete mode 100644 Stars45/FighterTacticalAI.cpp delete mode 100644 Stars45/FighterTacticalAI.h delete mode 100644 Stars45/FirstTimeDlg.cpp delete mode 100644 Stars45/FirstTimeDlg.h delete mode 100644 Stars45/Fix.cpp delete mode 100644 Stars45/Fix.h delete mode 100644 Stars45/FlightComp.cpp delete mode 100644 Stars45/FlightComp.h delete mode 100644 Stars45/FlightDeck.cpp delete mode 100644 Stars45/FlightDeck.h delete mode 100644 Stars45/FlightPlanner.cpp delete mode 100644 Stars45/FlightPlanner.h delete mode 100644 Stars45/FltDlg.cpp delete mode 100644 Stars45/FltDlg.h delete mode 100644 Stars45/Font.cpp delete mode 100644 Stars45/Font.h delete mode 100644 Stars45/FontMgr.cpp delete mode 100644 Stars45/FontMgr.h delete mode 100644 Stars45/FormDef.cpp delete mode 100644 Stars45/FormDef.h delete mode 100644 Stars45/FormWindow.cpp delete mode 100644 Stars45/FormWindow.h delete mode 100644 Stars45/FormatUtil.cpp delete mode 100644 Stars45/FormatUtil.h delete mode 100644 Stars45/Galaxy.cpp delete mode 100644 Stars45/Galaxy.h delete mode 100644 Stars45/Game.cpp delete mode 100644 Stars45/Game.h delete mode 100644 Stars45/GameScreen.cpp delete mode 100644 Stars45/GameScreen.h delete mode 100644 Stars45/GameWinDX9.cpp delete mode 100644 Stars45/GameWinDX9.h delete mode 100644 Stars45/Geometry.cpp delete mode 100644 Stars45/Geometry.h delete mode 100644 Stars45/Graphic.cpp delete mode 100644 Stars45/Graphic.h delete mode 100644 Stars45/Grid.cpp delete mode 100644 Stars45/Grid.h delete mode 100644 Stars45/GroundAI.cpp delete mode 100644 Stars45/GroundAI.h delete mode 100644 Stars45/HUDSounds.cpp delete mode 100644 Stars45/HUDSounds.h delete mode 100644 Stars45/HUDView.cpp delete mode 100644 Stars45/HUDView.h delete mode 100644 Stars45/Hangar.cpp delete mode 100644 Stars45/Hangar.h delete mode 100644 Stars45/HardPoint.cpp delete mode 100644 Stars45/HardPoint.h delete mode 100644 Stars45/Hoop.cpp delete mode 100644 Stars45/Hoop.h delete mode 100644 Stars45/IA3D.H delete mode 100644 Stars45/ImageBox.cpp delete mode 100644 Stars45/ImageBox.h delete mode 100644 Stars45/ImgView.cpp delete mode 100644 Stars45/ImgView.h delete mode 100644 Stars45/Instruction.cpp delete mode 100644 Stars45/Instruction.h delete mode 100644 Stars45/Intel.cpp delete mode 100644 Stars45/Intel.h delete mode 100644 Stars45/JoyDlg.cpp delete mode 100644 Stars45/JoyDlg.h delete mode 100644 Stars45/Joystick.cpp delete mode 100644 Stars45/Joystick.h delete mode 100644 Stars45/KeyDlg.cpp delete mode 100644 Stars45/KeyDlg.h delete mode 100644 Stars45/KeyMap.cpp delete mode 100644 Stars45/KeyMap.h delete mode 100644 Stars45/Keyboard.cpp delete mode 100644 Stars45/Keyboard.h delete mode 100644 Stars45/LandingGear.cpp delete mode 100644 Stars45/LandingGear.h delete mode 100644 Stars45/Layout.cpp delete mode 100644 Stars45/Layout.h delete mode 100644 Stars45/Light.cpp delete mode 100644 Stars45/Light.h delete mode 100644 Stars45/ListBox.cpp delete mode 100644 Stars45/ListBox.h delete mode 100644 Stars45/LoadDlg.cpp delete mode 100644 Stars45/LoadDlg.h delete mode 100644 Stars45/LoadScreen.cpp delete mode 100644 Stars45/LoadScreen.h delete mode 100644 Stars45/Locale_ss.cpp delete mode 100644 Stars45/Locale_ss.h delete mode 100644 Stars45/MCIWave.cpp delete mode 100644 Stars45/MCIWave.h delete mode 100644 Stars45/MachineInfo.cpp delete mode 100644 Stars45/MachineInfo.h delete mode 100644 Stars45/Main.cpp delete mode 100644 Stars45/MapView.cpp delete mode 100644 Stars45/MapView.h delete mode 100644 Stars45/Menu.cpp delete mode 100644 Stars45/Menu.h delete mode 100644 Stars45/MenuDlg.cpp delete mode 100644 Stars45/MenuDlg.h delete mode 100644 Stars45/MenuScreen.cpp delete mode 100644 Stars45/MenuScreen.h delete mode 100644 Stars45/MenuView.cpp delete mode 100644 Stars45/MenuView.h delete mode 100644 Stars45/Mfd.cpp delete mode 100644 Stars45/Mfd.h delete mode 100644 Stars45/Mission.cpp delete mode 100644 Stars45/Mission.h delete mode 100644 Stars45/MissionEvent.cpp delete mode 100644 Stars45/MissionEvent.h delete mode 100644 Stars45/MissionTemplate.cpp delete mode 100644 Stars45/MissionTemplate.h delete mode 100644 Stars45/ModConfig.cpp delete mode 100644 Stars45/ModConfig.h delete mode 100644 Stars45/ModDlg.cpp delete mode 100644 Stars45/ModDlg.h delete mode 100644 Stars45/ModInfo.cpp delete mode 100644 Stars45/ModInfo.h delete mode 100644 Stars45/ModInfoDlg.cpp delete mode 100644 Stars45/ModInfoDlg.h delete mode 100644 Stars45/MotionController.h delete mode 100644 Stars45/Mouse.cpp delete mode 100644 Stars45/Mouse.h delete mode 100644 Stars45/MouseController.cpp delete mode 100644 Stars45/MouseController.h delete mode 100644 Stars45/MsnDlg.cpp delete mode 100644 Stars45/MsnDlg.h delete mode 100644 Stars45/MsnEditDlg.cpp delete mode 100644 Stars45/MsnEditDlg.h delete mode 100644 Stars45/MsnEditNavDlg.cpp delete mode 100644 Stars45/MsnEditNavDlg.h delete mode 100644 Stars45/MsnElemDlg.cpp delete mode 100644 Stars45/MsnElemDlg.h delete mode 100644 Stars45/MsnEventDlg.cpp delete mode 100644 Stars45/MsnEventDlg.h delete mode 100644 Stars45/MsnNavDlg.cpp delete mode 100644 Stars45/MsnNavDlg.h delete mode 100644 Stars45/MsnObjDlg.cpp delete mode 100644 Stars45/MsnObjDlg.h delete mode 100644 Stars45/MsnPkgDlg.cpp delete mode 100644 Stars45/MsnPkgDlg.h delete mode 100644 Stars45/MsnSelectDlg.cpp delete mode 100644 Stars45/MsnSelectDlg.h delete mode 100644 Stars45/MsnWepDlg.cpp delete mode 100644 Stars45/MsnWepDlg.h delete mode 100644 Stars45/MultiController.cpp delete mode 100644 Stars45/MultiController.h delete mode 100644 Stars45/MusicDirector.cpp delete mode 100644 Stars45/MusicDirector.h delete mode 100644 Stars45/MusicTrack.cpp delete mode 100644 Stars45/MusicTrack.h delete mode 100644 Stars45/NPClient.h delete mode 100644 Stars45/NPClientWraps.cpp delete mode 100644 Stars45/NPClientWraps.h delete mode 100644 Stars45/NavAI.cpp delete mode 100644 Stars45/NavAI.h delete mode 100644 Stars45/NavDlg.cpp delete mode 100644 Stars45/NavDlg.h delete mode 100644 Stars45/NavLight.cpp delete mode 100644 Stars45/NavLight.h delete mode 100644 Stars45/NavSystem.cpp delete mode 100644 Stars45/NavSystem.h delete mode 100644 Stars45/NetAddrDlg.cpp delete mode 100644 Stars45/NetAddrDlg.h delete mode 100644 Stars45/NetAdminChat.cpp delete mode 100644 Stars45/NetAdminChat.h delete mode 100644 Stars45/NetAdminServer.cpp delete mode 100644 Stars45/NetAdminServer.h delete mode 100644 Stars45/NetAuth.cpp delete mode 100644 Stars45/NetAuth.h delete mode 100644 Stars45/NetBrokerClient.cpp delete mode 100644 Stars45/NetBrokerClient.h delete mode 100644 Stars45/NetChat.cpp delete mode 100644 Stars45/NetChat.h delete mode 100644 Stars45/NetClientConfig.cpp delete mode 100644 Stars45/NetClientConfig.h delete mode 100644 Stars45/NetClientDlg.cpp delete mode 100644 Stars45/NetClientDlg.h delete mode 100644 Stars45/NetData.cpp delete mode 100644 Stars45/NetData.h delete mode 100644 Stars45/NetFileServlet.cpp delete mode 100644 Stars45/NetFileServlet.h delete mode 100644 Stars45/NetGame.cpp delete mode 100644 Stars45/NetGame.h delete mode 100644 Stars45/NetGameClient.cpp delete mode 100644 Stars45/NetGameClient.h delete mode 100644 Stars45/NetGameServer.cpp delete mode 100644 Stars45/NetGameServer.h delete mode 100644 Stars45/NetLobby.cpp delete mode 100644 Stars45/NetLobby.h delete mode 100644 Stars45/NetLobbyClient.cpp delete mode 100644 Stars45/NetLobbyClient.h delete mode 100644 Stars45/NetLobbyDlg.cpp delete mode 100644 Stars45/NetLobbyDlg.h delete mode 100644 Stars45/NetLobbyServer.cpp delete mode 100644 Stars45/NetLobbyServer.h delete mode 100644 Stars45/NetPacket.cpp delete mode 100644 Stars45/NetPacket.h delete mode 100644 Stars45/NetPassDlg.cpp delete mode 100644 Stars45/NetPassDlg.h delete mode 100644 Stars45/NetPlayer.cpp delete mode 100644 Stars45/NetPlayer.h delete mode 100644 Stars45/NetServerConfig.cpp delete mode 100644 Stars45/NetServerConfig.h delete mode 100644 Stars45/NetServerDlg.cpp delete mode 100644 Stars45/NetServerDlg.h delete mode 100644 Stars45/NetUnitDlg.cpp delete mode 100644 Stars45/NetUnitDlg.h delete mode 100644 Stars45/NetUser.cpp delete mode 100644 Stars45/NetUser.h delete mode 100644 Stars45/NetUtil.cpp delete mode 100644 Stars45/NetUtil.h delete mode 100644 Stars45/OptDlg.cpp delete mode 100644 Stars45/OptDlg.h delete mode 100644 Stars45/PCX.CPP delete mode 100644 Stars45/Panic.cpp delete mode 100644 Stars45/Panic.h delete mode 100644 Stars45/ParseUtil.cpp delete mode 100644 Stars45/ParseUtil.h delete mode 100644 Stars45/Parser.cpp delete mode 100644 Stars45/Parser.h delete mode 100644 Stars45/Particles.cpp delete mode 100644 Stars45/Particles.h delete mode 100644 Stars45/Pcx.h delete mode 100644 Stars45/Physical.cpp delete mode 100644 Stars45/Physical.h delete mode 100644 Stars45/PlanScreen.cpp delete mode 100644 Stars45/PlanScreen.h delete mode 100644 Stars45/Player.cpp delete mode 100644 Stars45/Player.h delete mode 100644 Stars45/PlayerDlg.cpp delete mode 100644 Stars45/PlayerDlg.h delete mode 100644 Stars45/PngImage.cpp delete mode 100644 Stars45/PngImage.h delete mode 100644 Stars45/Polygon.cpp delete mode 100644 Stars45/Polygon.h delete mode 100644 Stars45/Power.cpp delete mode 100644 Stars45/Power.h delete mode 100644 Stars45/Projector.cpp delete mode 100644 Stars45/Projector.h delete mode 100644 Stars45/QuantumDrive.cpp delete mode 100644 Stars45/QuantumDrive.h delete mode 100644 Stars45/QuantumFlash.cpp delete mode 100644 Stars45/QuantumFlash.h delete mode 100644 Stars45/QuantumView.cpp delete mode 100644 Stars45/QuantumView.h delete mode 100644 Stars45/QuitView.cpp delete mode 100644 Stars45/QuitView.h delete mode 100644 Stars45/RLoc.cpp delete mode 100644 Stars45/RLoc.h delete mode 100644 Stars45/RadioHandler.cpp delete mode 100644 Stars45/RadioHandler.h delete mode 100644 Stars45/RadioMessage.cpp delete mode 100644 Stars45/RadioMessage.h delete mode 100644 Stars45/RadioTraffic.cpp delete mode 100644 Stars45/RadioTraffic.h delete mode 100644 Stars45/RadioView.cpp delete mode 100644 Stars45/RadioView.h delete mode 100644 Stars45/RadioVox.cpp delete mode 100644 Stars45/RadioVox.h delete mode 100644 Stars45/Random.cpp delete mode 100644 Stars45/Random.h delete mode 100644 Stars45/Reader.cpp delete mode 100644 Stars45/Reader.h delete mode 100644 Stars45/Res.cpp delete mode 100644 Stars45/Res.h delete mode 100644 Stars45/RichTextBox.cpp delete mode 100644 Stars45/RichTextBox.h delete mode 100644 Stars45/Scene.cpp delete mode 100644 Stars45/Scene.h delete mode 100644 Stars45/Screen.cpp delete mode 100644 Stars45/Screen.h delete mode 100644 Stars45/ScrollWindow.cpp delete mode 100644 Stars45/ScrollWindow.h delete mode 100644 Stars45/SeekerAI.cpp delete mode 100644 Stars45/SeekerAI.h delete mode 100644 Stars45/Sensor.cpp delete mode 100644 Stars45/Sensor.h delete mode 100644 Stars45/Sha1.cpp delete mode 100644 Stars45/Sha1.h delete mode 100644 Stars45/Shadow.cpp delete mode 100644 Stars45/Shadow.h delete mode 100644 Stars45/Shield.cpp delete mode 100644 Stars45/Shield.h delete mode 100644 Stars45/ShieldRep.cpp delete mode 100644 Stars45/ShieldRep.h delete mode 100644 Stars45/Ship.cpp delete mode 100644 Stars45/Ship.h delete mode 100644 Stars45/ShipAI.cpp delete mode 100644 Stars45/ShipAI.h delete mode 100644 Stars45/ShipCtrl.cpp delete mode 100644 Stars45/ShipCtrl.h delete mode 100644 Stars45/ShipDesign.cpp delete mode 100644 Stars45/ShipDesign.h delete mode 100644 Stars45/ShipKiller.cpp delete mode 100644 Stars45/ShipKiller.h delete mode 100644 Stars45/ShipSolid.cpp delete mode 100644 Stars45/ShipSolid.h delete mode 100644 Stars45/Shot.cpp delete mode 100644 Stars45/Shot.h delete mode 100644 Stars45/Sim.cpp delete mode 100644 Stars45/Sim.h delete mode 100644 Stars45/SimEvent.cpp delete mode 100644 Stars45/SimEvent.h delete mode 100644 Stars45/SimObject.cpp delete mode 100644 Stars45/SimObject.h delete mode 100644 Stars45/Skin.cpp delete mode 100644 Stars45/Skin.h delete mode 100644 Stars45/Sky.cpp delete mode 100644 Stars45/Sky.h delete mode 100644 Stars45/Slider.cpp delete mode 100644 Stars45/Slider.h delete mode 100644 Stars45/Solid.cpp delete mode 100644 Stars45/Solid.h delete mode 100644 Stars45/Sound.cpp delete mode 100644 Stars45/Sound.h delete mode 100644 Stars45/SoundCard.cpp delete mode 100644 Stars45/SoundCard.h delete mode 100644 Stars45/SoundD3D.cpp delete mode 100644 Stars45/SoundD3D.h delete mode 100644 Stars45/Sprite.cpp delete mode 100644 Stars45/Sprite.h delete mode 100644 Stars45/StarServer.cpp delete mode 100644 Stars45/StarServer.h delete mode 100644 Stars45/StarSystem.cpp delete mode 100644 Stars45/StarSystem.h delete mode 100644 Stars45/Stars.ico delete mode 100644 Stars45/Stars.rc.conf delete mode 100644 Stars45/Starshatter.cpp delete mode 100644 Stars45/Starshatter.h delete mode 100644 Stars45/StarshipAI.cpp delete mode 100644 Stars45/StarshipAI.h delete mode 100644 Stars45/StarshipTacticalAI.cpp delete mode 100644 Stars45/StarshipTacticalAI.h delete mode 100644 Stars45/SteerAI.cpp delete mode 100644 Stars45/SteerAI.h delete mode 100644 Stars45/System.cpp delete mode 100644 Stars45/System.h delete mode 100644 Stars45/SystemDesign.cpp delete mode 100644 Stars45/SystemDesign.h delete mode 100644 Stars45/TacRefDlg.cpp delete mode 100644 Stars45/TacRefDlg.h delete mode 100644 Stars45/TacticalAI.cpp delete mode 100644 Stars45/TacticalAI.h delete mode 100644 Stars45/TacticalView.cpp delete mode 100644 Stars45/TacticalView.h delete mode 100644 Stars45/Term.cpp delete mode 100644 Stars45/Term.h delete mode 100644 Stars45/Terrain.cpp delete mode 100644 Stars45/Terrain.h delete mode 100644 Stars45/TerrainApron.cpp delete mode 100644 Stars45/TerrainApron.h delete mode 100644 Stars45/TerrainClouds.cpp delete mode 100644 Stars45/TerrainClouds.h delete mode 100644 Stars45/TerrainHaze.cpp delete mode 100644 Stars45/TerrainHaze.h delete mode 100644 Stars45/TerrainLayer.h delete mode 100644 Stars45/TerrainPatch.cpp delete mode 100644 Stars45/TerrainPatch.h delete mode 100644 Stars45/TerrainRegion.cpp delete mode 100644 Stars45/TerrainRegion.h delete mode 100644 Stars45/TexCubeDX9.cpp delete mode 100644 Stars45/TexCubeDX9.h delete mode 100644 Stars45/TexDX9.cpp delete mode 100644 Stars45/TexDX9.h delete mode 100644 Stars45/Thruster.cpp delete mode 100644 Stars45/Thruster.h delete mode 100644 Stars45/Token.cpp delete mode 100644 Stars45/Token.h delete mode 100644 Stars45/TrackIR.cpp delete mode 100644 Stars45/TrackIR.h delete mode 100644 Stars45/Trail.cpp delete mode 100644 Stars45/Trail.h delete mode 100644 Stars45/Types.h delete mode 100644 Stars45/Universe.h delete mode 100644 Stars45/VersionInfo.cpp.conf delete mode 100644 Stars45/VersionInfo.h delete mode 100644 Stars45/VidDlg.cpp delete mode 100644 Stars45/VidDlg.h delete mode 100644 Stars45/Video.cpp delete mode 100644 Stars45/Video.h delete mode 100644 Stars45/VideoDX9.cpp delete mode 100644 Stars45/VideoDX9.h delete mode 100644 Stars45/VideoDX9Enum.cpp delete mode 100644 Stars45/VideoDX9Enum.h delete mode 100644 Stars45/VideoDX9VertexBuffer.cpp delete mode 100644 Stars45/VideoDX9VertexBuffer.h delete mode 100644 Stars45/VideoFactory.cpp delete mode 100644 Stars45/VideoFactory.h delete mode 100644 Stars45/VideoSettings.cpp delete mode 100644 Stars45/VideoSettings.h delete mode 100644 Stars45/View.h delete mode 100644 Stars45/Water.cpp delete mode 100644 Stars45/Water.h delete mode 100644 Stars45/Wave.h delete mode 100644 Stars45/Weapon.cpp delete mode 100644 Stars45/Weapon.h delete mode 100644 Stars45/WeaponDesign.cpp delete mode 100644 Stars45/WeaponDesign.h delete mode 100644 Stars45/WeaponGroup.cpp delete mode 100644 Stars45/WeaponGroup.h delete mode 100644 Stars45/Weather.cpp delete mode 100644 Stars45/Weather.h delete mode 100644 Stars45/WebBrowser.cpp delete mode 100644 Stars45/WebBrowser.h delete mode 100644 Stars45/WepView.cpp delete mode 100644 Stars45/WepView.h delete mode 100644 Stars45/Window.cpp delete mode 100644 Stars45/Window.h delete mode 100644 Stars45/WndProc.cpp delete mode 100644 Stars45/WndProc.h delete mode 100644 Stars45/resource.h (limited to 'Stars45') diff --git a/Stars45/ActiveWindow.cpp b/Stars45/ActiveWindow.cpp deleted file mode 100644 index 4c99ef8..0000000 --- a/Stars45/ActiveWindow.cpp +++ /dev/null @@ -1,1000 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Window class -*/ - -#include -#include "ActiveWindow.h" -#include "EventDispatch.h" -#include "Color.h" -#include "Bitmap.h" -#include "Font.h" -#include "FontMgr.h" -#include "Layout.h" -#include "Polygon.h" -#include "Screen.h" -#include "View.h" -#include "Video.h" - -// +--------------------------------------------------------------------+ - -Font* ActiveWindow::sys_font = 0; -Color ActiveWindow::sys_back_color = Color(128,128,128); -Color ActiveWindow::sys_fore_color = Color( 0, 0, 0); - -void ActiveWindow::SetSystemFont(Font* f) { sys_font = f; } -void ActiveWindow::SetSystemBackColor(Color c) { sys_back_color = c; } -void ActiveWindow::SetSystemForeColor(Color c) { sys_fore_color = c; } - -// +--------------------------------------------------------------------+ - -ActiveWindow::ActiveWindow(Screen* screen, int ax, int ay, int aw, int ah, - DWORD aid, DWORD s, ActiveWindow* pParent) - : Window(screen, ax, ay, aw, ah), id(aid), style(s), focus(false), - enabled(true), text_align(DT_CENTER), single_line(false), alpha(1), - texture(0), back_color(sys_back_color), fore_color(sys_fore_color), - parent(pParent), form(0), transparent(false), topmost(true), - layout(0), rows(1), cols(1), polys(0), vset(0), mtl(0), - fixed_width(0), fixed_height(0), hide_partial(true) -{ - ZeroMemory(tab, sizeof(tab)); - - font = sys_font; - - if (parent) { - parent->AddChild(this); - } - else { - screen->AddWindow(this); - } - - shown = false; - Show(); - - char buf[32]; - sprintf_s(buf, "ActiveWindow %d", id); //-V576 - desc = buf; -} - -// +--------------------------------------------------------------------+ - -ActiveWindow::~ActiveWindow() -{ - if (layout) delete layout; - - screen->DelWindow(this); - Hide(); - clients.destroy(); - children.destroy(); - - if (polys) delete [] polys; - if (vset) delete vset; - if (mtl) delete mtl; -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::Show() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - dispatch->Register(this); - - ListIter v_iter = view_list; - while (++v_iter) { - View* view = v_iter.value(); - view->OnShow(); - } - - ListIter c_iter = children; - while (++c_iter) { - ActiveWindow* child = c_iter.value(); - child->Show(); - } - - shown = true; -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::Hide() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) { - dispatch->Unregister(this); - focus = false; - } - - ListIter v_iter = view_list; - while (++v_iter) { - View* view = v_iter.value(); - view->OnHide(); - } - - ListIter c_iter = children; - while (++c_iter) { - ActiveWindow* child = c_iter.value(); - child->Hide(); - } - - shown = false; -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::MoveTo(const Rect& r) -{ - if (rect.x == r.x && - rect.y == r.y && - rect.w == r.w && - rect.h == r.h) - return; - - rect = r; - CalcGrid(); - - ListIter v = view_list; - while (++v) - v->OnWindowMove(); - - if (layout) - layout->DoLayout(this); -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::AddChild(ActiveWindow* child) -{ - if (child) - children.append(child); -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::DoLayout() -{ - if (layout) - layout->DoLayout(this); -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::UseLayout(const std::vector& min_x, -const std::vector& min_y, -const std::vector& weight_x, -const std::vector& weight_y) -{ - if (!layout) - layout = new Layout; - - if (layout) - layout->SetConstraints(min_x, min_y, weight_x, weight_y); -} - -void -ActiveWindow::UseLayout(const std::vector& min_x, -const std::vector& min_y, -const std::vector& weight_x, -const std::vector& weight_y) -{ - if (!layout) - layout = new Layout; - - if (layout) - layout->SetConstraints(min_x, min_y, weight_x, weight_y); -} - -void -ActiveWindow::UseLayout(int nrows, -int ncols, -int* min_x, -int* min_y, -float* weight_x, -float* weight_y) -{ - if (!layout) - layout = new Layout; - - if (layout) - layout->SetConstraints(nrows, ncols, min_x, min_y, weight_x, weight_y); -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::Paint() -{ - Draw(); -} - -// +--------------------------------------------------------------------+ - -Color -ActiveWindow::ShadeColor(Color c, double shade) -{ - int ishade = (int) (shade * Color::SHADE_LEVELS); - return c.ShadeColor(ishade); -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::Draw() -{ - int w = rect.w; - int h = rect.h; - - if (w < 1 || h < 1 || !shown) - return; - - float old_alpha = alpha; - - if (!enabled) - SetAlpha(0.5); - - if (!transparent) { - if (texture && texture->Width()) { - DrawTextureGrid(); - } - else { - FillRect(0, 0, w, h, ShadeColor(back_color, 1.0)); - } - } - - if (enabled && view_list.size()) { - ListIter v = view_list; - while (++v) - v->Refresh(); - } - - if (!transparent) { - DrawStyleRect(0, 0, w, h, style); - } - - // draw text here: - DrawTabbedText(); - - if (!enabled) - SetAlpha(old_alpha); - - // update children windows: - ListIter iter = children; - while (++iter) { - ActiveWindow* child = iter.value(); - child->Draw(); - } -} - -void -ActiveWindow::CalcGrid() -{ - if (polys) delete [] polys; - if (vset) delete vset; - if (mtl) delete mtl; - - rows = 1; - cols = 1; - - if (!texture || texture->Width() < 1) - return; - - if (margins.left > 0) cols++; - if (margins.right > 0) cols++; - if (margins.top > 0) rows++; - if (margins.bottom > 0) rows++; - - int npolys = rows*cols; - int nverts = (rows+1) * (cols+1); - - if (style & WIN_FRAME_ONLY && npolys == 9) - npolys = 8; // skip the center poly - - if (npolys > 0) { - int i, j; - int x_offsets[4]; - int y_offsets[4]; - float u_offsets[4]; - float v_offsets[4]; - - x_offsets[0] = 0; - x_offsets[1] = margins.left ? margins.left : rect.w - margins.right; - x_offsets[2] = cols==2 ? rect.w : rect.w - margins.right; - x_offsets[3] = rect.w; - - y_offsets[0] = 0; - y_offsets[1] = margins.top ? margins.top : rect.h - margins.bottom; - y_offsets[2] = rows==2 ? rect.h : rect.h - margins.bottom; - y_offsets[3] = rect.h; - - float tex_w = (float) texture->Width(); - float tex_h = (float) texture->Height(); - - if (tex_w > rect.w) tex_w = (float) rect.w; - if (tex_h > rect.h) tex_h = (float) rect.h; - - u_offsets[0] = 0.0f; - u_offsets[1] = margins.left ? (float) margins.left : tex_w - (float) margins.right; - u_offsets[2] = cols==2 ? tex_w : tex_w - (float) margins.right; - u_offsets[3] = tex_w; - - v_offsets[0] = 0.0f; - v_offsets[1] = margins.top ? (float) margins.top : tex_h - (float) margins.bottom; - v_offsets[2] = rows==2 ? tex_h : tex_h - (float) margins.bottom; - v_offsets[3] = tex_h; - - tex_w = (float) texture->Width(); - tex_h = (float) texture->Height(); - - vset = new VertexSet(nverts); - - int v = 0; - - Color c = Color::White; - c.SetAlpha((BYTE) (alpha*255)); - - vset->space = VertexSet::SCREEN_SPACE; - - for (i = 0; i <= rows; i++) { - for (j = 0; j <= cols; j++) { - vset->diffuse[v] = c.Value(); - - vset->s_loc[v].x = (float) (rect.x + x_offsets[j]) - 0.5f; - vset->s_loc[v].y = (float) (rect.y + y_offsets[i]) - 0.5f; - vset->s_loc[v].z = 0.0f; - vset->rw[v] = 1.0f; - - vset->tu[v] = u_offsets[j] / tex_w; - vset->tv[v] = v_offsets[i] / tex_h; - - v++; - } - } - - mtl = new Material; - mtl->tex_diffuse = texture; - - polys = new Poly[npolys]; - - Poly* p = polys; - - ZeroMemory(polys, npolys*sizeof(Poly)); - - for (i = 0; i < rows; i++) { - for (j = 0; j < cols; j++) { - if (style & WIN_FRAME_ONLY) { - if (i == 1 && j == 1) - continue; - } - - p->nverts = 4; - p->vertex_set = vset; - p->material = mtl; - - p->verts[0] = (i+0)*(cols+1) + j; - p->verts[1] = (i+0)*(cols+1) + j + 1; - p->verts[2] = (i+1)*(cols+1) + j + 1; - p->verts[3] = (i+1)*(cols+1) + j; - - p++; - } - } - } -} - -void -ActiveWindow::DrawTextureGrid() -{ - int npolys = rows*cols; - - if (style & WIN_FRAME_ONLY && npolys == 9) - npolys = 8; // skip the center poly - - if (mtl) { - mtl->tex_diffuse = texture; - } - - int blend = Video::BLEND_SOLID; - - if (alpha < 1) - blend = Video::BLEND_ALPHA; - - Video* video = screen->GetVideo(); - video->SetRenderState(Video::TEXTURE_WRAP, 0); - video->DrawScreenPolys(npolys, polys, blend); - video->SetRenderState(Video::TEXTURE_WRAP, 1); -} - -void -ActiveWindow::DrawStyleRect(const Rect& r, int style) -{ - DrawStyleRect(r.x, r.y, r.x+r.w, r.y+r.h, style); -} - -void -ActiveWindow::DrawStyleRect(int x1, int y1, int x2, int y2, int style) -{ - if (style & WIN_THIN_FRAME) { - DrawRect(x1,y1,x2-1,y2-1, ShadeColor(fore_color, 1.0)); - } - else if (style & WIN_THICK_FRAME) { - DrawRect(x1+0,y1+0,x2-1,y2-1, ShadeColor(fore_color, 1.0)); - DrawRect(x1+1,y1+1,x2-2,y2-2, ShadeColor(fore_color, 1.0)); - DrawRect(x1+2,y1+2,x2-3,y2-3, ShadeColor(fore_color, 1.0)); - } - else { - // draw bevel: - if ((style & WIN_RAISED_FRAME) && (style & WIN_SUNK_FRAME)) { - Color c = ShadeColor(back_color, 1.6); // full highlight - DrawLine(x1, y1, x2-1, y1, c); - DrawLine(x1, y1, x1, y2-1, c); - - c = ShadeColor(back_color, 1.3); // soft highlight - DrawLine(x1+1,y1+1, x2-2, y1+1, c); - DrawLine(x1+1,y1+1, x1+1, y2-2, c); - - c = ShadeColor(back_color, 0.6); // soft shadow - DrawLine(x2-2,y1+1, x2-2,y2-1, c); - DrawLine(x1+1,y2-2, x2-1,y2-2, c); - - c = ShadeColor(back_color, 0.3); // full shadow - DrawLine(x2-1,y1, x2-1,y2, c); - DrawLine(x1 ,y2-1, x2,y2-1, c); - - DrawRect(x1+4,y1+4, x2-5,y2-5, ShadeColor(back_color, 0.6)); // soft shadow - DrawRect(x1+5,y1+5, x2-6,y2-6, ShadeColor(back_color, 0.3)); // full shadow - DrawLine(x1+5,y2-6, x2-5,y2-6, ShadeColor(back_color, 1.3)); // soft highlight (bottom) - DrawLine(x2-6,y1+5, x2-6,y2-6, ShadeColor(back_color, 1.3)); // soft highlight (side) - DrawLine(x1+4,y2-5, x2-4,y2-5, ShadeColor(back_color, 1.6)); // soft highlight (bottom) - DrawLine(x2-5,y1+4, x2-5,y2-5, ShadeColor(back_color, 1.6)); // soft highlight (side) - } - - else if (style & WIN_RAISED_FRAME) { - Color c = ShadeColor(back_color, 1.6); // full highlight - DrawLine(x1, y1, x2-1, y1, c); - DrawLine(x1, y1, x1, y2-1, c); - - c = ShadeColor(back_color, 1.3); // soft highlight - DrawLine(x1+1,y1+1, x2-2, y1+1, c); - DrawLine(x1+1,y1+1, x1+1, y2-2, c); - - c = ShadeColor(back_color, 0.6); // soft shadow - DrawLine(x2-2,y1+1, x2-2,y2-1, c); - DrawLine(x1+1,y2-2, x2-1,y2-2, c); - - c = ShadeColor(back_color, 0.3); // full shadow - DrawLine(x2-1,y1, x2-1,y2, c); - DrawLine(x1 ,y2-1, x2,y2-1, c); - } - - else if (style & WIN_SUNK_FRAME) { - Color c = ShadeColor(back_color, 0.3); // full shadow - DrawLine(x1+1,y1+1, x1+1, y2, c); - DrawLine(x1+1,y1+1, x2, y1+1, c); - - c = ShadeColor(back_color, 0.6); // soft shadow - DrawLine(x1, y1, x1, y2, c); - DrawLine(x1, y1, x2, y1, c); - - c = ShadeColor(back_color, 1.3); // soft highlight - DrawLine(x2-2,y1+1, x2-2,y2-1, c); - DrawLine(x1+1,y2-2, x2-1,y2-2, c); - - c = ShadeColor(back_color, 1.6); // full highlight - DrawLine(x2-1,y1+1, x2-1,y2, c); - DrawLine(x1 ,y2-1, x2,y2-1, c); - } - - // draw frame: - if (style & WIN_BLACK_FRAME) - DrawRect(x1,y1,x2-1,y2-1, ShadeColor(Color::Black, 1.0)); - else if (style & WIN_WHITE_FRAME) - DrawRect(x1,y1,x2-1,y2-1, ShadeColor(Color::White, 1.0)); - } -} - -void -ActiveWindow::DrawTabbedText() -{ - if (shown && font && text.length()) { - Rect label_rect; - - if (text_insets.left) { - label_rect.w = rect.w; - label_rect.h = rect.h; - - label_rect.Inset(text_insets.left, - text_insets.right, - text_insets.top, - text_insets.bottom); - } - else { - int border_size = 4; - - if (style & WIN_RAISED_FRAME && style & WIN_SUNK_FRAME) - border_size = 8; - - label_rect.x = border_size; - label_rect.y = border_size; - label_rect.w = rect.w - border_size * 2; - label_rect.h = rect.h - border_size * 2; - } - - font->SetAlpha(alpha); - - // no tabs set: - if (tab[0] == 0) { - DWORD text_flags = DT_WORDBREAK | text_align; - - if (single_line) - text_flags = text_flags | DT_SINGLELINE; - - if (style & WIN_TEXT_SHADOW) { - label_rect.x++; - label_rect.y++; - - if (transparent) { - font->SetColor(back_color); - DrawText(text.data(), 0, label_rect, text_flags); - } - - else { - Color shadow = ShadeColor(back_color, 1.6); - font->SetColor(shadow); - DrawText(text.data(), 0, label_rect, text_flags); - } - - label_rect.x--; - label_rect.y--; - } - - Color fore = ShadeColor(fore_color, 1); - font->SetColor(fore); - DrawText(text.data(), 0, label_rect, text_flags); - } - - // use tabs: - else { - } - - font->SetAlpha(1); - } -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::SetTabStop(int n, int x) -{ - if (n >= 0 && n < 10) - tab[n] = x; -} - -int -ActiveWindow::GetTabStop(int n) const -{ - if (n >= 0 && n < 10) - return tab[n]; - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::SetText(const char* t) -{ - if (t && text != t) { - int len = strlen(t); - - if (len > 0) { - char* buf = new char[2*len]; - - if (buf != 0) { - const char* src = t; - char* dst = buf; - - while (*src) { - if (*src != '\\') { - *dst++ = *src++; - } - else { - src++; - - switch (*src) { - case 'n': *dst++ = '\n'; break; - case 't': *dst++ = '\t'; break; - default: *dst++ = *src; break; - } - - src++; - } - } - - *dst = 0; - - if (text != buf) { - text = buf; - } - - delete [] buf; - } - } - else { - text = t; - } - } -} - -void -ActiveWindow::SetText(const Text& t) -{ - if (t && text != t) { - int len = t.length(); - - if (len > 0 && t.contains('\\')) { - char* buf = new char[2*len]; - - if (buf != 0) { - const char* src = t; - char* dst = buf; - - while (*src) { - if (*src != '\\') { - *dst++ = *src++; - } - else { - src++; - - switch (*src) { - case 'n': *dst++ = '\n'; break; - case 't': *dst++ = '\t'; break; - default: *dst++ = *src; break; - } - - src++; - } - } - - *dst = 0; - - if (text != buf) { - text = buf; - } - - delete [] buf; - } - } - else { - text = t; - } - } -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::AddText(const char* t) -{ - if (t) { - text += t; - } -} - -void -ActiveWindow::AddText(const Text& t) -{ - if (t) { - text += t; - } -} - -void -ActiveWindow::SetTextAlign(DWORD a) -{ - if (a == DT_LEFT || a == DT_RIGHT || a == DT_CENTER) - text_align = a; -} - -void -ActiveWindow::SetMargins(const Insets& m) -{ - margins = m; - CalcGrid(); -} - -void -ActiveWindow::SetTextInsets(const Insets& t) -{ - text_insets = t; -} - -void -ActiveWindow::SetCellInsets(const Insets& c) -{ - cell_insets = c; -} - -void -ActiveWindow::SetCells(int cx, int cy, int cw, int ch) -{ - cells.x = cx; - cells.y = cy; - cells.w = cw; - cells.h = ch; - - if (cells.w < 1) - cells.w = 1; - - if (cells.h < 1) - cells.h = 1; -} - -void -ActiveWindow::SetAlpha(double a) -{ - if (alpha != a) { - alpha = (float) a; - - Color c = Color::White; - c.SetAlpha((BYTE) (alpha*255)); - - if (vset && vset->nverts) { - for (int i = 0; i < vset->nverts; i++) { - vset->diffuse[i] = c.Value(); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::DrawText(const char* txt, int count, Rect& txt_rect, DWORD flags) -{ - if (font) { - font->SetAlpha(alpha); - Window::DrawText(txt, count, txt_rect, flags); - } -} - -// +--------------------------------------------------------------------+ - -void -ActiveWindow::RegisterClient(int eid, ActiveWindow* client, PFVAWE callback) -{ - AWMap* map = new AWMap(eid, client, callback); - - if (map != 0) - clients.append(map); -} - -void -ActiveWindow::UnregisterClient(int eid, ActiveWindow* client) -{ - AWMap test(eid, client, 0); - int index = clients.index(&test); - - if (index >= 0) - delete clients.removeIndex(index); -} - -void -ActiveWindow::ClientEvent(int eid, int x, int y) -{ - event.window = this; - event.eid = eid; - event.x = x; - event.y = y; - - ListIter map = clients; - while (++map) { - if (map->eid == eid) - map->func(map->client, &event); - } -} - -// +--------------------------------------------------------------------+ - -int ActiveWindow::OnMouseEnter(int x, int y) -{ - ClientEvent(EID_MOUSE_ENTER, x, y); - return 0; -} - -int ActiveWindow::OnMouseExit(int x, int y) -{ - ClientEvent(EID_MOUSE_EXIT, x, y); - return 0; -} - -int ActiveWindow::OnMouseMove(int x, int y) -{ - ClientEvent(EID_MOUSE_MOVE, x, y); - return 0; -} - -int ActiveWindow::OnMouseWheel(int wheel) -{ - ClientEvent(EID_MOUSE_WHEEL, wheel, 0); - return 0; -} - -int ActiveWindow::OnLButtonDown(int x, int y) -{ - ClientEvent(EID_LBUTTON_DOWN, x, y); - return 0; -} - -int ActiveWindow::OnLButtonUp(int x, int y) -{ - ClientEvent(EID_LBUTTON_UP, x, y); - return 0; -} - -int ActiveWindow::OnClick() -{ - ClientEvent(EID_CLICK); - return 0; -} - -int ActiveWindow::OnSelect() -{ - ClientEvent(EID_SELECT); - return 0; -} - -int ActiveWindow::OnRButtonDown(int x, int y) -{ - ClientEvent(EID_RBUTTON_DOWN, x, y); - return 0; -} - -int ActiveWindow::OnRButtonUp(int x, int y) -{ - ClientEvent(EID_RBUTTON_UP, x, y); - return 0; -} - -int ActiveWindow::OnKeyDown(int vk, int flags) -{ - ClientEvent(EID_KEY_DOWN, vk, flags); - return 0; -} - -int ActiveWindow::OnDragStart(int x, int y) -{ - ClientEvent(EID_DRAG_START, x, y); - return 0; -} - -int ActiveWindow::OnDragDrop(int x, int y, ActiveWindow* source) -{ - ClientEvent(EID_DRAG_DROP, x, y); - return 0; -} - -Rect ActiveWindow::TargetRect() const -{ - return rect; -} - -// +--------------------------------------------------------------------+ - -void ActiveWindow::SetFocus() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - dispatch->SetFocus(this); - - focus = true; - ClientEvent(EID_SET_FOCUS); -} - -void ActiveWindow::KillFocus() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - dispatch->KillFocus(this); - - focus = false; - ClientEvent(EID_KILL_FOCUS); -} - -// +--------------------------------------------------------------------+ - -ActiveWindow* -ActiveWindow::GetCapture() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - return (ActiveWindow*) dispatch->GetCapture(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -bool -ActiveWindow::SetCapture() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - return dispatch->CaptureMouse(this) == 1; - - return false; -} - -// +--------------------------------------------------------------------+ - -int -ActiveWindow::ReleaseCapture() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - return dispatch->ReleaseMouse(this); - - return 0; -} - -// +--------------------------------------------------------------------+ - -bool -ActiveWindow::IsFormActive() const -{ - if (form) - return form->IsTopMost(); - - return true; -} - -// +--------------------------------------------------------------------+ - -ActiveWindow* -ActiveWindow::FindChild(DWORD id) -{ - ListIter iter = children; - while (++iter) { - ActiveWindow* w = iter.value(); - if (w->GetID() == id) - return w; - - ActiveWindow* w2 = w->FindChild(id); - - if (w2) - return w2; - } - - return 0; -} - - -// +--------------------------------------------------------------------+ - -ActiveWindow* -ActiveWindow::FindChild(int x, int y) -{ - ActiveWindow* mouse_tgt = 0; - - ListIter iter = children; - while (++iter) { - ActiveWindow* test = iter.value(); - if (test->TargetRect().Contains(x,y)) - mouse_tgt = test; - } - - return mouse_tgt; -} diff --git a/Stars45/ActiveWindow.h b/Stars45/ActiveWindow.h deleted file mode 100644 index ebcbdd2..0000000 --- a/Stars45/ActiveWindow.h +++ /dev/null @@ -1,324 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Active Window class (a window that knows how to draw itself) -*/ - -#ifndef ActiveWindow_h -#define ActiveWindow_h - -#include -#include "Types.h" -#include "Color.h" -#include "Geometry.h" -#include "Bitmap.h" -#include "Window.h" -#include "EventTarget.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -struct Poly; -struct Material; -struct VertexSet; -class Layout; - -// +--------------------------------------------------------------------+ - -enum { - WIN_NO_FRAME = 0x0000, - WIN_BLACK_FRAME = 0x0001, - WIN_WHITE_FRAME = 0x0002, - WIN_THIN_FRAME = 0x0004, - WIN_THICK_FRAME = 0x0008, - WIN_RAISED_FRAME = 0x0010, - WIN_SUNK_FRAME = 0x0020, - WIN_TEXT_SHADOW = 0x0040, - WIN_FRAME_ONLY = 0x0080 -}; - -enum { - EID_CREATE, - EID_DESTROY, - EID_MOUSE_MOVE, - EID_CLICK, - EID_SELECT, - EID_LBUTTON_DOWN, - EID_LBUTTON_UP, - EID_RBUTTON_DOWN, - EID_RBUTTON_UP, - EID_KEY_DOWN, - EID_SET_FOCUS, - EID_KILL_FOCUS, - EID_MOUSE_ENTER, - EID_MOUSE_EXIT, - EID_MOUSE_WHEEL, - EID_DRAG_START, - EID_DRAG_DROP, - - EID_USER_1, - EID_USER_2, - EID_USER_3, - EID_USER_4, - - EID_NUM_EVENTS -}; - -// +--------------------------------------------------------------------+ - -class ActiveWindow; - -struct AWEvent -{ - static const char* TYPENAME() { return "AWEvent"; } - - AWEvent() : window(0), eid(0), x(0), y(0) { } - AWEvent(ActiveWindow* w, int e, int ax=0, int ay=0) : window(w), eid(e), x(ax), y(ay) { } - - int operator == (const AWEvent& e) const { return (window == e.window) && - (eid == e.eid) && - (x == e.x) && - (y == e.y); } - - ActiveWindow* window; - int eid; - int x; - int y; -}; - -typedef void (*PFVAWE)(ActiveWindow*, AWEvent*); - -struct AWMap -{ - static const char* TYPENAME() { return "AWMap"; } - - AWMap() : eid(0), client(0), func(0) { } - AWMap(int e, ActiveWindow* w, PFVAWE f) : eid(e), client(w), func(f) { } - - int operator == (const AWMap& m) const { return (eid == m.eid) && - (client == m.client); } - - int eid; - ActiveWindow* client; - PFVAWE func; -}; - -// +--------------------------------------------------------------------+ - -class ActiveWindow : public Window, -public EventTarget -{ -public: - static const char* TYPENAME() { return "ActiveWindow"; } - - ActiveWindow(Screen* s, int ax, int ay, int aw, int ah, - DWORD id=0, DWORD style=0, ActiveWindow* parent=0); - virtual ~ActiveWindow(); - - int operator == (const ActiveWindow& w) const { return id == w.id; } - - // Operations: - virtual void Paint(); // blt to screen - virtual void Draw(); // refresh backing store - virtual void Show(); - virtual void Hide(); - virtual void MoveTo(const Rect& r); - virtual void UseLayout(const std::vector& min_x, - const std::vector& min_y, - const std::vector& weight_x, - const std::vector& weight_y); - virtual void UseLayout(const std::vector& min_x, - const std::vector& min_y, - const std::vector& weight_x, - const std::vector& weight_y); - virtual void UseLayout(int ncols, - int nrows, - int* min_x, - int* min_y, - float* weight_x, - float* weight_y); - virtual void DoLayout(); - - // Event Target Interface: - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnClick(); - virtual int OnSelect(); - virtual int OnRButtonDown(int x, int y); - virtual int OnRButtonUp(int x, int y); - virtual int OnMouseEnter(int x, int y); - virtual int OnMouseExit(int x, int y); - virtual int OnMouseWheel(int wheel); - - virtual int OnKeyDown(int vk, int flags); - - virtual const char* GetDescription() const { return desc; } - - // pseudo-events: - virtual int OnDragStart(int x, int y); - virtual int OnDragDrop(int x, int y, ActiveWindow* source); - - virtual ActiveWindow* FindControl(int x, int y) { return 0; } - virtual Rect TargetRect() const; - - virtual ActiveWindow* GetCapture(); - virtual bool SetCapture(); - virtual int ReleaseCapture(); - - // Property accessors: - virtual void SetFocus(); - virtual void KillFocus(); - virtual bool HasFocus() const { return focus; } - - void SetEnabled(bool e=true) { enabled = e; } - bool IsEnabled() const { return enabled; } - bool IsVisible() const { return shown; } - - DWORD GetID() const { return id; } - void SetStyle(DWORD s) { style = s; } - DWORD GetStyle() const { return style; } - - void SetText(const char* t); - void SetText(const Text& t); - void AddText(const char* t); - void AddText(const Text& t); - const Text& GetText() const { return text; } - - void SetAltText(const char* t) { alt_text = t; } - void SetAltText(const Text& t) { alt_text = t; } - const Text& GetAltText() const { return alt_text; } - - void SetTexture(Bitmap* bmp) { texture = bmp; } - Bitmap* GetTexture() { return texture; } - void SetMargins(const Insets& m); - Insets& GetMargins() { return margins; } - void SetTextInsets(const Insets& t); - Insets& GetTextInsets() { return text_insets; } - - List& GetChildren() { return children; } - void SetCellInsets(const Insets& c); - Insets& GetCellInsets() { return cell_insets; } - void SetCells(int cx, int cy, int cw=1, int ch=1); - void SetCells(const Rect& r) { cells = r; } - Rect& GetCells() { return cells; } - void SetFixedWidth(int w) { fixed_width = w; } - int GetFixedWidth() const { return fixed_width; } - void SetFixedHeight(int h) { fixed_height = h; } - int GetFixedHeight() const { return fixed_height;} - - void SetAlpha(double a); - double GetAlpha() const { return alpha; } - void SetBackColor(Color c) { back_color = c; } - Color GetBackColor() const { return back_color; } - void SetBaseColor(Color c) { base_color = c; } - Color GetBaseColor() const { return base_color; } - void SetForeColor(Color c) { fore_color = c; } - Color GetForeColor() const { return fore_color; } - void SetSingleLine(bool a) { single_line = a; } - bool GetSingleLine() const { return single_line; } - void SetTextAlign(DWORD a); - DWORD GetTextAlign() const { return text_align; } - void SetTransparent(bool t) { transparent = t; } - bool GetTransparent() const { return transparent; } - void SetHidePartial(bool a) { hide_partial = a; } - bool GetHidePartial() const { return hide_partial;} - - void SetTabStop(int n, int x); - int GetTabStop(int n) const; - - void DrawText(const char* txt, int count, Rect& txt_rect, DWORD flags); - - // class properties: - static void SetSystemFont(Font* f); - static void SetSystemBackColor(Color c); - static void SetSystemForeColor(Color c); - - // callback function registration: - virtual void RegisterClient(int EID, ActiveWindow* client, PFVAWE callback); - virtual void UnregisterClient(int EID, ActiveWindow* client); - virtual void ClientEvent(int EID, int x=0, int y=0); - - // form context: - virtual ActiveWindow* GetForm() { return form; } - virtual void SetForm(ActiveWindow* f) { form = f; } - virtual bool IsFormActive() const; - virtual bool IsTopMost() const { return topmost; } - virtual void SetTopMost(bool t) { topmost = t; } - - virtual ActiveWindow* FindChild(DWORD id); - virtual ActiveWindow* FindChild(int x, int y); - -protected: - virtual Color ShadeColor(Color c, double shade); - virtual void AddChild(ActiveWindow* child); - virtual void DrawStyleRect(const Rect& r, int style); - virtual void DrawStyleRect(int x1, int y1, int x2, int y2, int style); - virtual void DrawTabbedText(); - virtual void DrawTextureGrid(); - virtual void CalcGrid(); - - DWORD id; - DWORD style; - DWORD text_align; - bool single_line; - bool focus; - bool enabled; - bool hide_partial; - float alpha; - Color back_color; - Color base_color; - Color fore_color; - Text text; - Text alt_text; - Text desc; - Bitmap* texture; - Insets margins; - Insets text_insets; - Insets cell_insets; - Rect cells; - int fixed_width; - int fixed_height; - int tab[10]; - - ActiveWindow* parent; - ActiveWindow* form; - bool transparent; - bool topmost; - - Layout* layout; - List children; - List clients; - AWEvent event; - - int rows; - int cols; - Poly* polys; - VertexSet* vset; - Material* mtl; - - static Font* sys_font; - static Color sys_back_color; - static Color sys_fore_color; -}; - -#define DEF_MAP_CLIENT(cname, fname)\ - void Map##cname##fname(ActiveWindow* client, AWEvent* event) \ - { cname* c = (cname*) client; c->fname(event); } - -#define REGISTER_CLIENT(eid, ctrl, cname, fname)\ - if (ctrl) ctrl->RegisterClient(eid, this, Map##cname##fname); - -#define UNREGISTER_CLIENT(eid, ctrl, cname)\ - if (ctrl) ctrl->UnregisterClient(eid, this); - -#endif // ActiveWindow_h - diff --git a/Stars45/Archive.cpp b/Stars45/Archive.cpp deleted file mode 100644 index 9d859c2..0000000 --- a/Stars45/Archive.cpp +++ /dev/null @@ -1,589 +0,0 @@ -/* 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 "Types.h" -#include "Archive.h" -#include "Utils.h" - -#include -#include -#include -#include -#include -#include - -#include "zlib.h" - -// +--------------------------------------------------------------------+ - -int verbose = 1; -int err; - -#define CHECK_ERR(err, msg) { \ - if (err != Z_OK) { \ - fprintf(stderr, "%s error: %d\n", msg, err); \ - exit(1); \ - } \ - } - -// +--------------------------------------------------------------------+ - -DataArchive::DataArchive(const char* name) -{ - ZeroMemory(this, sizeof(DataArchive)); - - if (name) - LoadDatafile(name); -} - -DataArchive::~DataArchive() -{ - delete [] block_map; - delete [] directory; -} - -// +--------------------------------------------------------------------+ - -void DataArchive::WriteEntry(int index, BYTE* buf) -{ - int f = _open(datafile, _O_RDWR|_O_CREAT|_O_BINARY, _S_IREAD|_S_IWRITE); - - if (f != -1) { - header.dir_size_comp = DirBlocks() * BLOCK_SIZE; - dirbuf = new BYTE[header.dir_size_comp]; - - if (!dirbuf) { - err = Z_MEM_ERROR; - } - - else { - err = compress(dirbuf, &header.dir_size_comp, - (BYTE*) directory, header.nfiles * sizeof(DataEntry)); - CHECK_ERR(err, "compress"); - - header.dir_blocks = Blocks(header.dir_size_comp) * BLOCK_SIZE; - - _lseek(f, 0, SEEK_SET); - _write(f, &header, sizeof(DataHeader)); - _lseek(f, sizeof(DataHeader) + header.dir_offset, SEEK_SET); - _write(f, dirbuf, header.dir_blocks); - - delete [] dirbuf; - dirbuf = 0; - } - - if (buf && directory && directory[index].size_comp) { - _lseek(f, sizeof(DataHeader) + directory[index].offset, SEEK_SET); - _write(f, buf, directory[index].size_comp); - } - _close(f); - } - else - perror("WriteEntry"); -} - -// +--------------------------------------------------------------------+ - -DWORD DataArchive::Blocks(DWORD raw_size) -{ - int full_blocks = raw_size / BLOCK_SIZE; - int part_blocks = (raw_size % BLOCK_SIZE) > 0; - - return full_blocks + part_blocks; -} - -DWORD DataArchive::DirBlocks() -{ - DWORD result = Blocks(header.nfiles * sizeof(DataEntry)); - if (result == 0) result = 1; - return result; -} - -DWORD DataArchive::FileBlocks(int index) -{ - if (index >= 0 && index < (int) header.nfiles && directory) - return Blocks(directory[index].size_comp); - - return 0; -} - -// +--------------------------------------------------------------------+ - -void DataArchive::CreateBlockMap() -{ - delete [] block_map; - block_map = 0; - - if (header.nfiles == 0) return; - - DWORD i,j; - DWORD dir_usage = header.dir_offset + DirBlocks() * BLOCK_SIZE; - DWORD max_usage = dir_usage; - - for (i = 0; i < header.nfiles; i++) { - DWORD last_block = directory[i].offset + FileBlocks(i) * BLOCK_SIZE; - if (last_block > max_usage) - max_usage = last_block; - } - - nblocks = max_usage/BLOCK_SIZE; - block_map = new DWORD[nblocks]; - - if (!block_map) { - nblocks = 0; - } - - else { - ZeroMemory(block_map, nblocks*sizeof(DWORD)); - - DWORD first_block = header.dir_offset/BLOCK_SIZE + - (header.dir_offset%BLOCK_SIZE > 0); - - for (j = 0; j < DirBlocks(); j++) - block_map[first_block+j] = 1; - - for (i = 0; i < header.nfiles; i++) { - DWORD first_block = directory[i].offset/BLOCK_SIZE + - (directory[i].offset%BLOCK_SIZE > 0); - - for (j = 0; j < FileBlocks(i); j++) - block_map[first_block+j] = i+2; - } - } -} - -// +--------------------------------------------------------------------+ - -int DataArchive::FindDataBlocks(int need) -{ - if ((int) (nblocks)-need > 0) { - DWORD start; - int i; - - for (start = 0; start < nblocks-need; start++) { - for (i = 0; block_map[start+i] == 0 && i < need; i++); - - if (i == need) return start*BLOCK_SIZE; - - start += i; - } - } - - return nblocks*BLOCK_SIZE; -} - -// +--------------------------------------------------------------------+ - -void DataArchive::LoadDatafile(const char* name) -{ - if (!name) return; - - delete [] directory; - delete [] block_map; - - ZeroMemory(this, sizeof(DataArchive)); - strncpy_s(datafile, name, NAMELEN-1); - - FILE* f; - fopen_s(&f, datafile, "rb"); - if (f) { - fread(&header, sizeof(DataHeader), 1, f); - - if (header.version != VERSION) { - Print("ERROR: datafile '%s' invalid version '%d'\n", - datafile, header.version); - fclose(f); - ZeroMemory(&header, sizeof(header)); - return; - } - - DWORD len = DirBlocks() * BLOCK_SIZE; - DWORD dirsize = header.nfiles + 64; - - dirbuf = new BYTE[len]; - directory = new DataEntry[dirsize]; - - if (!dirbuf || !directory) { - err = Z_MEM_ERROR; - } - - else { - ZeroMemory(directory, sizeof(DataEntry) * dirsize); - - fseek(f, sizeof(DataHeader) + header.dir_offset, SEEK_SET); - fread(dirbuf, header.dir_size_comp, 1, f); - - int err = uncompress((BYTE*) directory, &len, -#pragma warning(suppress: 6029) - dirbuf, header.dir_size_comp); - if (err != Z_OK) - ZeroMemory(directory, sizeof(DataEntry) * dirsize); - - delete [] dirbuf; - dirbuf = 0; - - CreateBlockMap(); - } - } - else { - Print("Creating Archive '%s'...\n", datafile); - - header.version = VERSION; - header.nfiles = 0; - header.dir_blocks = 0; - header.dir_size_comp = 0; - header.dir_offset = 0; - - nblocks = DirBlocks(); - - delete [] block_map; - block_map = 0; - } -} - -// +--------------------------------------------------------------------+ - -int DataArchive::FindEntry(const char* req_name) -{ - int entry = -1; - - if (req_name && *req_name && directory) { - char path[256]; - int len = strlen(req_name); - - ZeroMemory(path, sizeof(path)); - - for (int c = 0; c < len; c++) { - if (req_name[c] == '\\') - path[c] = '/'; - else - path[c] = req_name[c]; - } - - for (DWORD i = 0; i < header.nfiles; i++) { - if (!_stricmp(directory[i].name, path)) - return i; - } - } - - return entry; -} - -// +--------------------------------------------------------------------+ - -BYTE* DataArchive::CompressEntry(int i) -{ - if (directory && i >= 0 && i < (int) header.nfiles) { - char* name = directory[i].name; - - FILE* f; - fopen_s(&f, name, "rb"); - - if (f) { - fseek(f, 0, SEEK_END); - DWORD len = ftell(f); - fseek(f, 0, SEEK_SET); - - BYTE* buf = new BYTE[len]; - - if (!buf) { - err = Z_MEM_ERROR; - } - - else { - fread(buf, len, 1, f); - fclose(f); - - directory[i].size_orig = len; - - directory[i].size_comp = (int) (len * 1.1); - BYTE* cbuf = new BYTE[directory[i].size_comp]; - - if (!cbuf) { - err = Z_MEM_ERROR; - } - else { - err = compress(cbuf, &directory[i].size_comp, buf, len); - CHECK_ERR(err, "compress"); - } - - delete [] buf; - return cbuf; - } - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -int DataArchive::ExpandEntry(int i, BYTE*& buf, bool null_terminate) -{ - DWORD len = 0; - - if (directory && i >= 0 && i < (int) header.nfiles) { - FILE* f; - fopen_s(&f, datafile, "rb"); - - if (f) { - DWORD clen = directory[i].size_comp; - BYTE* cbuf = new BYTE[clen]; - - if (!cbuf) { - err = Z_MEM_ERROR; - } - - else { - fseek(f, sizeof(DataHeader) + directory[i].offset, SEEK_SET); - fread(cbuf, clen, 1, f); - - len = directory[i].size_orig; - - if (null_terminate) { - buf = new BYTE[len+1]; - if (buf) buf[len] = 0; - } - - else { - buf = new BYTE[len]; - } - - if (!buf) { - err = Z_MEM_ERROR; - } - - else { - err = uncompress(buf, &len, cbuf, clen); - if (err != Z_OK) { - delete [] buf; - buf = 0; - } - } - - delete [] cbuf; - fclose(f); - } - } - } - - return len; -} - -// +--------------------------------------------------------------------+ - -int DataArchive::InsertEntry(const char* name) -{ - if (name && *name) { - char path[256]; - DWORD len = strlen(name); - - ZeroMemory(path, sizeof(path)); - - for (DWORD c = 0; c < len; c++) { - if (name[c] == '\\') - path[c] = '/'; - else - path[c] = name[c]; - } - - int dirsize = header.nfiles + 64; - - if (directory && dirsize) { - for (int i = 0; i < dirsize; i++) { - if (directory[i].size_orig == 0) { - ZeroMemory(directory[i].name, NAMELEN); - strncpy_s(directory[i].name, path, NAMELEN); - directory[i].name[NAMELEN-1] = '\0'; - directory[i].size_orig = 1; - - return i; - } - } - } - - DataEntry* dir = new DataEntry[dirsize + 64]; - - if (directory && dirsize) { - ZeroMemory(dir, (dirsize + 64) * sizeof(DataEntry)); - CopyMemory(dir, directory, dirsize * sizeof(DataEntry)); - } - - delete [] directory; - - header.nfiles = dirsize + 64; - directory = dir; - - ZeroMemory(directory[dirsize].name, NAMELEN); - strncpy_s(directory[dirsize].name, path, NAMELEN); - directory[dirsize].name[NAMELEN-1] = '\0'; - directory[dirsize].size_orig = 1; - - return dirsize; - } - - return -1; -} - -// +--------------------------------------------------------------------+ - -void DataArchive::RemoveEntry(int index) -{ - if (directory && index >= 0 && index < (int) header.nfiles) - ZeroMemory(&directory[index], sizeof(DataEntry)); -} - -// +--------------------------------------------------------------------+ - -void DataArchive::Insert(const char* name) -{ - DWORD old_blocks = 0, old_offset = 0, new_blocks = 0; - DWORD old_dir_blocks = 0, old_dir_offset = 0, new_dir_blocks = 0; - int added = 0; - - int index = FindEntry(name); - - if (index < 0) { - old_dir_blocks = DirBlocks(); - old_dir_offset = header.dir_offset; - - index = InsertEntry(name); - - if (index >= (int) header.nfiles) { - header.nfiles = index+1; - added = 1; - } - - new_dir_blocks = DirBlocks(); - - if (new_dir_blocks > old_dir_blocks) { - header.dir_offset = FindDataBlocks(new_dir_blocks); - CreateBlockMap(); - } - } - else { - old_blocks = FileBlocks(index); - old_offset = directory[index].offset; - } - - if (index >= 0) { - DataEntry& e = directory[index]; - - if (verbose) Print(" Inserting: %-16s ", e.name); - - BYTE* buf = CompressEntry(index); - - if (!buf) { - // this is (almost) unrecoverable, - // so we quit before screwing things up: - Print("ERROR: Could not compress %d:%s\n", index, directory[index].name); - exit(1); - } - - new_blocks = FileBlocks(index); - - // the file is new, or got bigger, - // need to find room for the data: - if (new_blocks > old_blocks) { - directory[index].offset = FindDataBlocks(new_blocks); - CreateBlockMap(); - } - - WriteEntry(index, buf); - delete [] buf; - - if (verbose) { - int ratio = (int) (100.0 * (double) e.size_comp / (double) e.size_orig); - Print("%9d => %9d (%2d%%)\n", e.size_orig, e.size_comp, ratio); - } - } - else if (added) - header.nfiles--; -} - -// +--------------------------------------------------------------------+ - -void DataArchive::Extract(const char* name) -{ - int index = FindEntry(name); - - if (!directory || index < 0 || index >= (int) header.nfiles) { - Print("Could not extract '%s', not found\n", name); - return; - } - - BYTE* buf; - ExpandEntry(index, buf); - - FILE* f; - fopen_s(&f, directory[index].name, "wb"); - if (f) { - fwrite(buf, directory[index].size_orig, 1, f); - fclose(f); - } - else - Print("Could not extract '%s', could not open file for writing\n", name); - - delete [] buf; - - if (verbose) Print(" Extracted: %s\n", name); -} - -// +--------------------------------------------------------------------+ - -void DataArchive::Remove(const char* name) -{ - int index = FindEntry(name); - - if (!directory || index < 0 || index >= (int) header.nfiles) { - Print("Could not remove '%s', not found\n", name); - return; - } - - RemoveEntry(index); - WriteEntry(index, 0); - - if (verbose) Print(" Removed: %s\n", name); -} - -// +--------------------------------------------------------------------+ - -void DataArchive::List() -{ - int total_orig = 0; - int total_comp = 0; - - printf("DATAFILE: %s\n", datafile); - printf("Files: %d\n", header.nfiles); //-V576 - printf("\n"); - - if (directory && header.nfiles) { - printf("Index Orig Size Comp Size Ratio Name\n"); - printf("----- --------- --------- ----- ----------------\n"); - - for (DWORD i = 0; i < header.nfiles; i++) { - DataEntry& e = directory[i]; - int ratio = (int) (100.0 * (double) e.size_comp / (double) e.size_orig); - - printf("%5d %9d %9d %2d%% %s\n", i+1, e.size_orig, e.size_comp, ratio, e.name); //-V576 - - total_orig += e.size_orig; - total_comp += e.size_comp; - } - - int total_ratio = (int) (100.0 * (double) total_comp / (double) total_orig); - - printf("----- --------- --------- -----\n"); - printf("TOTAL %9d %9d %2d%%\n\n", total_orig, total_comp, total_ratio); - } -} - - -// +--------------------------------------------------------------------+ - diff --git a/Stars45/Archive.h b/Stars45/Archive.h deleted file mode 100644 index ac22f28..0000000 --- a/Stars45/Archive.h +++ /dev/null @@ -1,89 +0,0 @@ -/* 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 - -*/ - -#ifndef Archive_h -#define Archive_h - -// +------------------------------------------------------------------+ - -#define VERSION 0x0010 -#define BLOCK_SIZE 1024 -#define FILE_BLOCK 1024 -#define NAMELEN 64 - -// +------------------------------------------------------------------+ - -struct DataHeader -{ - static const char* TYPENAME() { return "DataHeader"; } - - DWORD version; - DWORD nfiles; - DWORD dir_blocks; - DWORD dir_size_comp; - DWORD dir_offset; -}; - -struct DataEntry -{ - static const char* TYPENAME() { return "DataEntry"; } - - char name[NAMELEN]; - DWORD size_orig; - DWORD size_comp; - DWORD offset; -}; - -class DataArchive -{ -public: - static const char* TYPENAME() { return "DataArchive"; } - - // ctor: - DataArchive(const char* name = 0); - ~DataArchive(); - - // operations: - void LoadDatafile(const char* name); - void Insert(const char* name); - void Extract(const char* name); - void Remove(const char* name); - void List(); - - void WriteEntry(int index, BYTE* buf); - int FindEntry(const char* req_name); - int ExpandEntry(int index, BYTE*& buf, bool null_terminate=false); - BYTE* CompressEntry(int index); - int InsertEntry(const char* name); - void RemoveEntry(int index); - DWORD Blocks(DWORD raw_size); - DWORD DirBlocks(); - DWORD FileBlocks(int index); - int FindDataBlocks(int blocks_needed); - void CreateBlockMap(); - - DWORD NumFiles() { return header.nfiles; } - DataEntry* GetFile(int i) { if (i>=0 && i<(int)header.nfiles) return &directory[i]; return 0; } - - const char* Name() const { return datafile; } - -private: - // persistent data members: - DataHeader header; - DataEntry* directory; - BYTE* dirbuf; - - // transient members: - char datafile[NAMELEN]; - - DWORD* block_map; - DWORD nblocks; -}; - -#endif // Archive_h diff --git a/Stars45/Asteroid.cpp b/Stars45/Asteroid.cpp deleted file mode 100644 index fa0f175..0000000 --- a/Stars45/Asteroid.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Asteroid Sprite animation class -*/ - -#include "Asteroid.h" -#include "Shot.h" -#include "Explosion.h" -#include "Sim.h" - -#include "Solid.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Game.h" - -// +--------------------------------------------------------------------+ - -static Point asteroid_velocity = Point(0,0,0); -static Model* asteroid_model[32]; - -// +--------------------------------------------------------------------+ - -Asteroid::Asteroid(int t, const Vec3& pos, double m) - : Debris(asteroid_model[t%6], pos, asteroid_velocity, m) -{ - life = -1; -} - -// +--------------------------------------------------------------------+ - -void -Asteroid::Initialize() -{ - ZeroMemory(asteroid_model, sizeof(asteroid_model)); - - DataLoader* loader = DataLoader::GetLoader(); - Text old_path = loader->GetDataPath(); - loader->SetDataPath("Galaxy/Asteroids/"); - - int n = 0; - - Model* a = new Model; - if (a) { - a->Load("a1.mag", 100); - asteroid_model[n++] = a; - } - - a = new Model; - if (a) { - a->Load("a2.mag", 50); - asteroid_model[n++] = a; - } - - a = new Model; - if (a) { - a->Load("a1.mag", 8); - asteroid_model[n++] = a; - } - - a = new Model; - if (a) { - a->Load("a2.mag", 10); - asteroid_model[n++] = a; - } - - a = new Model; - if (a) { - a->Load("a3.mag", 30); - asteroid_model[n++] = a; - } - - a = new Model; - if (a) { - a->Load("a4.mag", 20); - asteroid_model[n++] = a; - } - - List mod_asteroids; - loader->SetDataPath("Mods/Galaxy/Asteroids/"); - loader->ListFiles("*.mag", mod_asteroids); - - ListIter iter = mod_asteroids; - while (++iter && n < 32) { - a = new Model; - if (a) { - a->Load(*iter.value(), 50); - asteroid_model[n++] = a; - } - } - - loader->SetDataPath(old_path); -} - -void -Asteroid::Close() -{ - for (int i = 0; i < 32; i++) - delete asteroid_model[i]; - - ZeroMemory(asteroid_model, sizeof(asteroid_model)); -} - -// +--------------------------------------------------------------------+ - - - diff --git a/Stars45/Asteroid.h b/Stars45/Asteroid.h deleted file mode 100644 index b26b116..0000000 --- a/Stars45/Asteroid.h +++ /dev/null @@ -1,34 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Asteroid Sprite class -*/ - -#ifndef Asteroid_h -#define Asteroid_h - -#include "Types.h" -#include "Geometry.h" -#include "SimObject.h" -#include "Debris.h" - -// +--------------------------------------------------------------------+ - -class Asteroid : public Debris -{ -public: - Asteroid(int type, const Vec3& pos, double mass); - - static void Initialize(); - static void Close(); -}; - -#endif // Asteroid_h - diff --git a/Stars45/AudDlg.cpp b/Stars45/AudDlg.cpp deleted file mode 100644 index ec25996..0000000 --- a/Stars45/AudDlg.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "AudDlg.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "AudioConfig.h" - -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "MachineInfo.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(AudDlg, OnApply); -DEF_MAP_CLIENT(AudDlg, OnCancel); -DEF_MAP_CLIENT(AudDlg, OnAudio); -DEF_MAP_CLIENT(AudDlg, OnVideo); -DEF_MAP_CLIENT(AudDlg, OnOptions); -DEF_MAP_CLIENT(AudDlg, OnControls); -DEF_MAP_CLIENT(AudDlg, OnMod); - -// +--------------------------------------------------------------------+ - -AudDlg::AudDlg(Screen* s, FormDef& def, BaseScreen* mgr) - : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), - apply(0), cancel(0), vid_btn(0), aud_btn(0), ctl_btn(0), opt_btn(0), - mod_btn(0), closed(true) -{ - Init(def); -} - -AudDlg::~AudDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -AudDlg::RegisterControls() -{ - if (apply) - return; - - efx_volume_slider = (Slider*) FindControl(201); - gui_volume_slider = (Slider*) FindControl(202); - wrn_volume_slider = (Slider*) FindControl(203); - vox_volume_slider = (Slider*) FindControl(204); - - menu_music_slider = (Slider*) FindControl(205); - game_music_slider = (Slider*) FindControl(206); - - apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, apply, AudDlg, OnApply); - - cancel = (Button*) FindControl(2); - REGISTER_CLIENT(EID_CLICK, cancel, AudDlg, OnCancel); - - vid_btn = (Button*) FindControl(901); - REGISTER_CLIENT(EID_CLICK, vid_btn, AudDlg, OnVideo); - - aud_btn = (Button*) FindControl(902); - REGISTER_CLIENT(EID_CLICK, aud_btn, AudDlg, OnAudio); - - ctl_btn = (Button*) FindControl(903); - REGISTER_CLIENT(EID_CLICK, ctl_btn, AudDlg, OnControls); - - opt_btn = (Button*) FindControl(904); - REGISTER_CLIENT(EID_CLICK, opt_btn, AudDlg, OnOptions); - - mod_btn = (Button*) FindControl(905); - if (mod_btn) { - REGISTER_CLIENT(EID_CLICK, mod_btn, AudDlg, OnMod); - } -} - -// +--------------------------------------------------------------------+ - -void -AudDlg::Show() -{ - FormWindow::Show(); - - if (closed && AudioConfig::GetInstance()) { - AudioConfig* audio = AudioConfig::GetInstance(); - - if (efx_volume_slider) - efx_volume_slider->SetValue(audio->GetEfxVolume()); - - if (gui_volume_slider) - gui_volume_slider->SetValue(audio->GetGuiVolume()); - - if (wrn_volume_slider) - wrn_volume_slider->SetValue(audio->GetWrnVolume()); - - if (vox_volume_slider) - vox_volume_slider->SetValue(audio->GetVoxVolume()); - - if (menu_music_slider) - menu_music_slider->SetValue(audio->GetMenuMusic()); - - if (game_music_slider) - game_music_slider->SetValue(audio->GetGameMusic()); - } - - if (vid_btn) vid_btn->SetButtonState(0); - if (aud_btn) aud_btn->SetButtonState(1); - if (ctl_btn) ctl_btn->SetButtonState(0); - if (opt_btn) opt_btn->SetButtonState(0); - if (mod_btn) mod_btn->SetButtonState(0); - - closed = false; -} - -// +--------------------------------------------------------------------+ - -void -AudDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnApply(0); - } -} - -// +--------------------------------------------------------------------+ - -void AudDlg::OnAudio(AWEvent* event) { manager->ShowAudDlg(); } -void AudDlg::OnVideo(AWEvent* event) { manager->ShowVidDlg(); } -void AudDlg::OnOptions(AWEvent* event) { manager->ShowOptDlg(); } -void AudDlg::OnControls(AWEvent* event) { manager->ShowCtlDlg(); } -void AudDlg::OnMod(AWEvent* event) { manager->ShowModDlg(); } - -// +--------------------------------------------------------------------+ - -void -AudDlg::OnApply(AWEvent* event) -{ - if (manager) - manager->ApplyOptions(); -} - -void -AudDlg::OnCancel(AWEvent* event) -{ - manager->CancelOptions(); -} - -// +--------------------------------------------------------------------+ - -void -AudDlg::Apply() -{ - if (!closed && AudioConfig::GetInstance()) { - AudioConfig* audio = AudioConfig::GetInstance(); - - if (efx_volume_slider) - audio->SetEfxVolume(efx_volume_slider->GetValue()); - - if (gui_volume_slider) - audio->SetGuiVolume(gui_volume_slider->GetValue()); - - if (wrn_volume_slider) - audio->SetWrnVolume(wrn_volume_slider->GetValue()); - - if (vox_volume_slider) - audio->SetVoxVolume(vox_volume_slider->GetValue()); - - if (menu_music_slider) - audio->SetMenuMusic(menu_music_slider->GetValue()); - - if (game_music_slider) - audio->SetGameMusic(game_music_slider->GetValue()); - - audio->Save(); - } - - closed = true; -} - -void -AudDlg::Cancel() -{ - closed = true; -} diff --git a/Stars45/AudDlg.h b/Stars45/AudDlg.h deleted file mode 100644 index 35658f0..0000000 --- a/Stars45/AudDlg.h +++ /dev/null @@ -1,78 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef AudDlg_h -#define AudDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class BaseScreen; - -// +--------------------------------------------------------------------+ - -class AudDlg : public FormWindow -{ -public: - AudDlg(Screen* s, FormDef& def, BaseScreen* mgr); - virtual ~AudDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void Apply(); - virtual void Cancel(); - - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - - virtual void OnAudio(AWEvent* event); - virtual void OnVideo(AWEvent* event); - virtual void OnOptions(AWEvent* event); - virtual void OnControls(AWEvent* event); - virtual void OnMod(AWEvent* event); - -protected: - BaseScreen* manager; - - Slider* efx_volume_slider; - Slider* gui_volume_slider; - Slider* wrn_volume_slider; - Slider* vox_volume_slider; - - Slider* menu_music_slider; - Slider* game_music_slider; - - Button* aud_btn; - Button* vid_btn; - Button* opt_btn; - Button* ctl_btn; - Button* mod_btn; - - Button* apply; - Button* cancel; - - bool closed; -}; - -#endif // AudDlg_h - diff --git a/Stars45/AudioConfig.cpp b/Stars45/AudioConfig.cpp deleted file mode 100644 index 8d4d74a..0000000 --- a/Stars45/AudioConfig.cpp +++ /dev/null @@ -1,382 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Audio Configuration class -*/ - -#include "AudioConfig.h" - -#include "DataLoader.h" -#include "ParseUtil.h" -#include "Button.h" -#include "Game.h" - -// +--------------------------------------------------------------------+ - -static AudioConfig* audio_config = 0; - -// +--------------------------------------------------------------------+ - -AudioConfig::AudioConfig() - : menu_music(90), - game_music(90), - efx_volume(90), - gui_volume(90), - wrn_volume(90), - vox_volume(90), - training(false) -{ - if (!audio_config) - audio_config = this; -} - -AudioConfig::~AudioConfig() -{ - if (audio_config == this) - audio_config = 0; -} - -// +--------------------------------------------------------------------+ - -void -AudioConfig::Initialize() -{ - audio_config = new AudioConfig; - if (audio_config) - audio_config->Load(); -} - -void -AudioConfig::Close() -{ - delete audio_config; - audio_config = 0; -} - -AudioConfig* -AudioConfig::GetInstance() -{ - return audio_config; -} - -// +--------------------------------------------------------------------+ - -int -AudioConfig::MenuMusic() -{ - if (audio_config) - return -50 * (100 - audio_config->menu_music); - - return 0; -} - -int -AudioConfig::GameMusic() -{ - int vol = 0; - - if (audio_config) { - vol = -50 * (100 - audio_config->game_music); - - if (audio_config->training) - vol -= 2000; - } - - return vol; -} - -int -AudioConfig::EfxVolume() -{ - int vol = 0; - - if (audio_config) { - vol = -50 * (100 - audio_config->efx_volume); - - if (audio_config->training) - vol -= 2000; - } - - return vol; -} - -int -AudioConfig::GuiVolume() -{ - if (audio_config) - return -50 * (100 - audio_config->gui_volume); - - return 0; -} - -int -AudioConfig::WrnVolume() -{ - int vol = 0; - - if (audio_config) { - vol = -50 * (100 - audio_config->wrn_volume); - - if (audio_config->training) - vol -= 2000; - } - - return vol; -} - -int -AudioConfig::VoxVolume() -{ - int vol = 0; - - if (audio_config) { - vol = -50 * (100 - audio_config->vox_volume); - - if (audio_config->training && vol < -750) - vol = -750; - } - - return vol; -} - -int -AudioConfig::Silence() -{ - return -5000; -} - -void -AudioConfig::SetTraining(bool t) -{ - if (audio_config) - audio_config->training = t; -} - -// +--------------------------------------------------------------------+ - -void -AudioConfig::SetMenuMusic(int v) -{ - if (v < 0) v = 0; - else if (v > 100) v = 100; - - menu_music = v; -} - -void -AudioConfig::SetGameMusic(int v) -{ - if (v < 0) v = 0; - else if (v > 100) v = 100; - - game_music = v; -} - -void -AudioConfig::SetEfxVolume(int v) -{ - if (v < 0) v = 0; - else if (v > 100) v = 100; - - efx_volume = v; -} - -void -AudioConfig::SetGuiVolume(int v) -{ - if (v < 0) v = 0; - else if (v > 100) v = 100; - - gui_volume = v; - Button::SetVolume(-50 * (100 - gui_volume)); -} - -void -AudioConfig::SetWrnVolume(int v) -{ - if (v < 0) v = 0; - else if (v > 100) v = 100; - - wrn_volume = v; - Button::SetVolume(-50 * (100 - wrn_volume)); -} - -void -AudioConfig::SetVoxVolume(int v) -{ - if (v < 0) v = 0; - else if (v > 100) v = 100; - - vox_volume = v; -} - -// +--------------------------------------------------------------------+ - -void -AudioConfig::Load() -{ - DataLoader* loader = DataLoader::GetLoader(); - Text old_path = loader->GetDataPath(); - loader->SetDataPath(0); - - // read the config file: - BYTE* block = 0; - int blocklen = 0; - const char* filename = "audio.cfg"; - - FILE* f; - ::fopen_s(&f, 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() != "AUDIO") { - Print("WARNING: invalid %s file. Using defaults\n", filename); - return; - } - } - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - int v = 0; - TermDef* def = term->isDef(); - - if (def) { - if (def->name()->value() == "menu_music") { - GetDefNumber(v, def, filename); - - if (v < 0 || v > 100) { - Print("WARNING: Invalid menu_music (%d) in '%s'\n", v, filename); - } - else { - menu_music = v; - } - } - - else if (def->name()->value() == "game_music") { - GetDefNumber(v, def, filename); - - if (v < 0 || v > 100) { - Print("WARNING: Invalid game_music (%d) in '%s'\n", v, filename); - } - else { - game_music = v; - } - } - - else if (def->name()->value() == "efx_volume") { - GetDefNumber(v, def, filename); - - if (v < 0 || v > 100) { - Print("WARNING: Invalid efx_volume (%d) in '%s'\n", v, filename); - } - else { - efx_volume = v; - } - } - - else if (def->name()->value() == "gui_volume") { - GetDefNumber(v, def, filename); - - if (v < 0 || v > 100) { - Print("WARNING: Invalid gui_volume (%d) in '%s'\n", v, filename); - } - else { - gui_volume = v; - - Button::SetVolume(-50 * (100 - gui_volume)); - } - } - - else if (def->name()->value() == "wrn_volume") { - GetDefNumber(v, def, filename); - - if (v < 0 || v > 100) { - Print("WARNING: Invalid wrn_volume (%d) in '%s'\n", v, filename); - } - else { - wrn_volume = v; - } - } - - else if (def->name()->value() == "vox_volume") { - GetDefNumber(v, def, filename); - - if (v < 0 || v > 100) { - Print("WARNING: Invalid vox_volume (%d) in '%s'\n", v, filename); - } - else { - vox_volume = v; - } - } - - else - Print("WARNING: unknown label '%s' in '%s'\n", - def->name()->value().data(), filename); - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - Print("\n"); - } - } - } - while (term); - - loader->ReleaseBuffer(block); - loader->SetDataPath(old_path); -} - -void -AudioConfig::Save() -{ - FILE* f; - fopen_s(&f, "audio.cfg", "wb"); - if (f) { - fprintf(f, "AUDIO\n\n"); - fprintf(f, "menu_music: %3d\n", menu_music); - fprintf(f, "game_music: %3d\n\n", game_music); - fprintf(f, "efx_volume: %3d\n", efx_volume); - fprintf(f, "gui_volume: %3d\n", gui_volume); - fprintf(f, "wrn_volume: %3d\n", wrn_volume); - fprintf(f, "vox_volume: %3d\n", vox_volume); - fclose(f); - } -} - -// +--------------------------------------------------------------------+ - - - diff --git a/Stars45/AudioConfig.h b/Stars45/AudioConfig.h deleted file mode 100644 index f721592..0000000 --- a/Stars45/AudioConfig.h +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Audio Configuration class -*/ - -#ifndef AudioConfig_h -#define AudioConfig_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class AudioConfig -{ -public: - AudioConfig(); - ~AudioConfig(); - - static void Initialize(); - static void Close(); - static AudioConfig* GetInstance(); - - void Load(); - void Save(); - - static int MenuMusic(); - static int GameMusic(); - static int EfxVolume(); - static int GuiVolume(); - static int WrnVolume(); - static int VoxVolume(); - static int Silence(); - static void SetTraining(bool t); - - int GetMenuMusic() const { return menu_music; } - int GetGameMusic() const { return game_music; } - int GetEfxVolume() const { return efx_volume; } - int GetGuiVolume() const { return gui_volume; } - int GetWrnVolume() const { return wrn_volume; } - int GetVoxVolume() const { return vox_volume; } - - void SetMenuMusic(int v); - void SetGameMusic(int v); - void SetEfxVolume(int v); - void SetGuiVolume(int v); - void SetWrnVolume(int v); - void SetVoxVolume(int v); - -protected: - int menu_music; - int game_music; - - int efx_volume; - int gui_volume; - int wrn_volume; - int vox_volume; - - bool training; -}; - -#endif // AudioConfig_h - diff --git a/Stars45/AwardDlg.cpp b/Stars45/AwardDlg.cpp deleted file mode 100644 index bdaf4a5..0000000 --- a/Stars45/AwardDlg.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "AwardDlg.h" -#include "PlanScreen.h" -#include "Starshatter.h" -#include "Ship.h" -#include "Player.h" -#include "Campaign.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "EditBox.h" -#include "ImageBox.h" -#include "FormatUtil.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Sound.h" -#include "Panic.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(AwardDlg, OnClose); - -// +--------------------------------------------------------------------+ - -AwardDlg::AwardDlg(Screen* s, FormDef& def, PlanScreen* mgr) - : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), - lbl_name(0), lbl_info(0), img_rank(0), btn_close(0), exit_latch(true) -{ - Init(def); -} - -AwardDlg::~AwardDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -AwardDlg::RegisterControls() -{ - lbl_name = FindControl(203); - lbl_info = FindControl(201); - img_rank = (ImageBox*) FindControl(202); - - btn_close = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, btn_close, AwardDlg, OnClose); -} - -// +--------------------------------------------------------------------+ - -void -AwardDlg::Show() -{ - FormWindow::Show(); - ShowPlayer(); - - exit_latch = true; -} - -// +--------------------------------------------------------------------+ - -void -AwardDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - if (!exit_latch) - OnClose(0); - } - - else if (Keyboard::KeyDown(VK_ESCAPE)) { - if (!exit_latch) - OnClose(0); - } - - else { - exit_latch = false; - } -} - -// +--------------------------------------------------------------------+ - -void -AwardDlg::ShowPlayer() -{ - Player* p = Player::GetCurrentPlayer(); - - if (p) { - if (lbl_name) { - lbl_name->SetText(p->AwardName()); - } - - if (lbl_info) { - lbl_info->SetText(p->AwardDesc()); - } - - if (img_rank) { - img_rank->SetPicture(*p->AwardImage()); - img_rank->Show(); - } - - Sound* congrats = p->AwardSound(); - if (congrats) { - congrats->Play(); - } - } - else { - if (lbl_info) lbl_info->SetText(""); - if (img_rank) img_rank->Hide(); - } -} - -// +--------------------------------------------------------------------+ - -void -AwardDlg::OnClose(AWEvent* event) -{ - Player* player = Player::GetCurrentPlayer(); - if (player) - player->ClearShowAward(); - - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - Mouse::Show(false); - - Campaign* campaign = Campaign::GetCampaign(); - if (campaign && campaign->GetCampaignId() < Campaign::SINGLE_MISSIONS) - stars->SetGameMode(Starshatter::CMPN_MODE); - else - stars->SetGameMode(Starshatter::MENU_MODE); - } - - else - Panic::Panic("AwardDlg::OnClose() - Game instance not found"); -} diff --git a/Stars45/AwardDlg.h b/Stars45/AwardDlg.h deleted file mode 100644 index 26996d5..0000000 --- a/Stars45/AwardDlg.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef AwardDlg_h -#define AwardDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class PlanScreen; -class Player; - -// +--------------------------------------------------------------------+ - -class AwardDlg : public FormWindow -{ -public: - AwardDlg(Screen* s, FormDef& def, PlanScreen* mgr); - virtual ~AwardDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnClose(AWEvent* event); - virtual void ShowPlayer(); - -protected: - PlanScreen* manager; - - ActiveWindow* lbl_name; - ActiveWindow* lbl_info; - ImageBox* img_rank; - Button* btn_close; - - bool exit_latch; -}; - -#endif // AwardDlg_h - diff --git a/Stars45/AwardShowDlg.cpp b/Stars45/AwardShowDlg.cpp deleted file mode 100644 index 10e6423..0000000 --- a/Stars45/AwardShowDlg.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "AwardShowDlg.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "Ship.h" -#include "Player.h" -#include "Campaign.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "EditBox.h" -#include "ImageBox.h" -#include "FormatUtil.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(AwardShowDlg, OnClose); - -// +--------------------------------------------------------------------+ - -AwardShowDlg::AwardShowDlg(Screen* s, FormDef& def, MenuScreen* mgr) - : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), - lbl_name(0), lbl_info(0), img_rank(0), btn_close(0), exit_latch(true), - rank(-1), medal(-1) -{ - Init(def); -} - -AwardShowDlg::~AwardShowDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -AwardShowDlg::RegisterControls() -{ - lbl_name = FindControl(203); - lbl_info = FindControl(201); - img_rank = (ImageBox*) FindControl(202); - - btn_close = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, btn_close, AwardShowDlg, OnClose); -} - -// +--------------------------------------------------------------------+ - -void -AwardShowDlg::Show() -{ - FormWindow::Show(); - ShowAward(); -} - -// +--------------------------------------------------------------------+ - -void -AwardShowDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - if (!exit_latch) - OnClose(0); - } - - else if (Keyboard::KeyDown(VK_ESCAPE)) { - if (!exit_latch) - OnClose(0); - } - - else { - exit_latch = false; - } -} - -// +--------------------------------------------------------------------+ - -void -AwardShowDlg::SetRank(int r) -{ - rank = r; - medal = -1; -} - -void -AwardShowDlg::SetMedal(int m) -{ - rank = -1; - medal = m; -} - -// +--------------------------------------------------------------------+ - -void -AwardShowDlg::ShowAward() -{ - if (rank >= 0) { - if (lbl_name) { - lbl_name->SetText(Text("Rank of ") + Player::RankName(rank)); - } - - if (lbl_info) { - lbl_info->SetText(Player::RankDescription(rank)); - } - - if (img_rank) { - img_rank->SetPicture(*Player::RankInsignia(rank, 1)); - img_rank->Show(); - } - } - - else if (medal >= 0) { - if (lbl_name) { - lbl_name->SetText(Player::MedalName(medal)); - } - - if (lbl_info) { - lbl_info->SetText(Player::MedalDescription(medal)); - } - - if (img_rank) { - img_rank->SetPicture(*Player::MedalInsignia(medal, 1)); - img_rank->Show(); - } - } - - else { - if (lbl_name) lbl_name->SetText(""); - if (lbl_info) lbl_info->SetText(""); - if (img_rank) img_rank->Hide(); - } -} - -// +--------------------------------------------------------------------+ - -void -AwardShowDlg::OnClose(AWEvent* event) -{ - manager->ShowPlayerDlg(); -} diff --git a/Stars45/AwardShowDlg.h b/Stars45/AwardShowDlg.h deleted file mode 100644 index d606be6..0000000 --- a/Stars45/AwardShowDlg.h +++ /dev/null @@ -1,62 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef AwardShowDlg_h -#define AwardShowDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; - -// +--------------------------------------------------------------------+ - -class AwardShowDlg : public FormWindow -{ -public: - AwardShowDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~AwardShowDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnClose(AWEvent* event); - virtual void ShowAward(); - virtual void SetRank(int r); - virtual void SetMedal(int r); - -protected: - MenuScreen* manager; - - ActiveWindow* lbl_name; - ActiveWindow* lbl_info; - ImageBox* img_rank; - Button* btn_close; - - bool exit_latch; - - int rank; - int medal; -}; - -#endif // AwardShowDlg_h - diff --git a/Stars45/BaseScreen.h b/Stars45/BaseScreen.h deleted file mode 100644 index b10dbdb..0000000 --- a/Stars45/BaseScreen.h +++ /dev/null @@ -1,82 +0,0 @@ -/* 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 - -*/ - -#ifndef BaseScreen_h -#define BaseScreen_h - -#include "Types.h" -#include "Bitmap.h" -#include "Screen.h" - -// +--------------------------------------------------------------------+ - -class Screen; -class Sim; -class Window; -class Font; -class NavDlg; -class MsnElemDlg; -class AudDlg; -class VidDlg; -class ModDlg; -class ModInfoDlg; -class OptDlg; -class CtlDlg; -class KeyDlg; -class JoyDlg; -class MsgDlg; - -// +--------------------------------------------------------------------+ - -class BaseScreen -{ -public: - BaseScreen() { } - virtual ~BaseScreen() { } - - virtual void ShowNavDlg() { } - virtual void HideNavDlg() { } - virtual bool IsNavShown() { return false; } - virtual NavDlg* GetNavDlg() { return 0; } - - virtual void ShowMsnElemDlg() { } - virtual void HideMsnElemDlg() { } - virtual MsnElemDlg* GetMsnElemDlg() { return 0; } - - virtual AudDlg* GetAudDlg() const { return 0; } - virtual VidDlg* GetVidDlg() const { return 0; } - virtual ModDlg* GetModDlg() const { return 0; } - virtual ModInfoDlg* GetModInfoDlg() const { return 0; } - virtual OptDlg* GetOptDlg() const { return 0; } - virtual CtlDlg* GetCtlDlg() const { return 0; } - virtual JoyDlg* GetJoyDlg() const { return 0; } - virtual KeyDlg* GetKeyDlg() const { return 0; } - - virtual void ShowAudDlg() { } - virtual void ShowVidDlg() { } - virtual void ShowModDlg() { } - virtual void ShowModInfoDlg() { } - virtual void ShowOptDlg() { } - virtual void ShowCtlDlg() { } - virtual void ShowJoyDlg() { } - virtual void ShowKeyDlg() { } - - virtual void ShowMsgDlg() { } - virtual void HideMsgDlg() { } - virtual bool IsMsgShown() { return false; } - virtual MsgDlg* GetMsgDlg() { return 0; } - - virtual void ApplyOptions() { } - virtual void CancelOptions() { } -}; - -// +--------------------------------------------------------------------+ - -#endif // BaseScreen_h - diff --git a/Stars45/Bitmap.cpp b/Stars45/Bitmap.cpp deleted file mode 100644 index 70cff64..0000000 --- a/Stars45/Bitmap.cpp +++ /dev/null @@ -1,1616 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Bitmap Resource class -*/ - -#include "Bitmap.h" -#include "Clock.h" -#include "Video.h" -#include "Color.h" -#include "GameWinDX9.h" - -// +--------------------------------------------------------------------+ - -static inline void swap(int& a, int& b) { int tmp=a; a=b; b=tmp; } -static inline void sort(int& a, int& b) { if (a>b) swap(a,b); } -static inline void swap(double& a, double& b) { double tmp=a; a=b; b=tmp; } -static inline void sort(double& a, double& b) { if (a>b) swap(a,b); } -static void draw_strip(BYTE* dst, int pitch, int pixsize, int x, int y, int len, Color color); -static void draw_vline(BYTE* dst, int pitch, int pixsize, int x, int y, int len, Color color); - -class WinPlot -{ -public: - WinPlot(Bitmap* bmp); - void plot(int x, int y, DWORD val, int exch=0); - -private: - BYTE* s; - int pitch, pixsize; -}; - -WinPlot::WinPlot(Bitmap* bmp) -{ - s = bmp->GetSurface(); - pitch = bmp->Pitch(); - pixsize = bmp->PixSize(); -} - -void WinPlot::plot(int x, int y, DWORD val, int exch) -{ - if (exch) swap(x,y); - BYTE* dst = s + y*pitch + x*pixsize; - - switch (pixsize) { - case 1: *dst = (BYTE) val; break; - case 2: { LPWORD dst2 = (LPWORD) dst; *dst2 = (WORD) val; } break; - case 4: { LPDWORD dst4 = (LPDWORD) dst; *dst4 = (DWORD) val; } break; - } -} - -// +--------------------------------------------------------------------+ - -Bitmap::Bitmap() - : type(BMP_SOLID), width(0), height(0), - ownpix(false), alpha_loaded(false), texture(false), - pix(0), hipix(0), mapsize(0), - last_modified(0) -{ - strcpy_s(filename, "Bitmap()"); -} - -Bitmap::Bitmap(int w, int h, ColorIndex* p, int t) - : type(t), width(w), height(h), - ownpix(false), alpha_loaded(false), texture(false), - pix(p), hipix(0), mapsize(w*h), - last_modified(Clock::GetInstance()->RealTime()) -{ - sprintf_s(filename, "Bitmap(%d, %d, index, type=%d)", w, h, (int) t); -} - -Bitmap::Bitmap(int w, int h, Color* p, int t) - : type(t), width(w), height(h), - ownpix(false), alpha_loaded(false), texture(false), - pix(0), hipix(p), mapsize(w*h), - last_modified(Clock::GetInstance()->RealTime()) -{ - sprintf_s(filename, "Bitmap(%d, %d, hicolor, type=%d)", w, h, (int) t); -} - -// +--------------------------------------------------------------------+ - -Bitmap::~Bitmap() -{ - if (ownpix) { - delete [] pix; - delete [] hipix; - } -} - -// +--------------------------------------------------------------------+ - -int -Bitmap::BmpSize() const -{ - return mapsize * PixSize(); -} - -int -Bitmap::RowSize() const -{ - return width; -} - -int -Bitmap::Pitch() const -{ - return width * PixSize(); -} - -int -Bitmap::PixSize() const -{ - if (hipix) - return sizeof(Color); - - else if (pix) - return sizeof(ColorIndex); - - return 0; -} - -BYTE* -Bitmap::GetSurface() -{ - if (ownpix) { - if (hipix) - return (BYTE*) hipix; - - return (BYTE*) pix; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::BitBlt(int x, int y, const Bitmap& srcBmp, int sx, int sy, int w, int h, bool blend) -{ - if (!ownpix || x < 0 || y < 0 || x >= width || y >= height) - return; - - if (sx < 0 || sy < 0 || sx >= srcBmp.Width() || sy >= srcBmp.Height()) - return; - - if (hipix) { - if (srcBmp.HiPixels()) { - int dpitch = width; - int spitch = srcBmp.Width(); - int rowlen = w * sizeof(Color); - Color* dst = hipix + (y*dpitch) + x; - Color* src = srcBmp.HiPixels() + (sy*spitch) + sx; - - if (!blend) { - for (int i = 0; i < h; i++) { - memcpy(dst, src, rowlen); - dst += dpitch; - src += spitch; - } - } - else { - for (int i = 0; i < h; i++) { - Color* ps = src; - Color* pd = dst; - - for (int n = 0; n < w; n++) { - if (ps->Value()) - pd->Set(Color::FormattedBlend(ps->Value(), pd->Value())); - ps++; - pd++; - } - - dst += dpitch; - src += spitch; - } - } - } - - else { - int dpitch = width; - int spitch = srcBmp.Width(); - Color* dst = hipix + (y*dpitch) + x; - ColorIndex* src = srcBmp.Pixels() + (sy*spitch) + sx; - - if (!blend) { - for (int j = 0; j < h; j++) { - for (int i = 0; i < w; i++) { - dst[i].Set(src[i].Formatted()); - } - - dst += dpitch; - src += spitch; - } - } - else { - for (int i = 0; i < h; i++) { - ColorIndex* ps = src; - Color* pd = dst; - - for (int n = 0; n < w; n++) { - if (ps->Index()) - pd->Set(Color::FormattedBlend(ps->Formatted(), pd->Value())); - ps++; - pd++; - } - } - - dst += dpitch; - src += spitch; - } - } - } - - else if (pix) { - if (srcBmp.Pixels()) { - int dpitch = width; - int spitch = srcBmp.Width(); - int rowlen = w; - Color* dst = hipix + (y*dpitch) + x; - Color* src = srcBmp.HiPixels() + (sy*spitch) + sx; - - for (int i = 0; i < h; i++) { -#pragma warning(suppress: 28183) - memcpy(dst, src, rowlen); - dst += dpitch; - src += spitch; - } - } - } - - alpha_loaded = srcBmp.alpha_loaded; - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::CopyBitmap(const Bitmap& rhs) -{ - if (ownpix) { - delete [] pix; - delete [] hipix; - pix = 0; - hipix = 0; - } - - type = rhs.type; - width = rhs.width; - height = rhs.height; - alpha_loaded = rhs.alpha_loaded; - texture = rhs.texture; - ownpix = true; - - mapsize = width * height; - - if (rhs.pix) { - pix = new ColorIndex[mapsize]; - - if (!pix) { - width = 0; - height = 0; - mapsize = 0; - } - - else { - memcpy(pix, rhs.pix, mapsize*sizeof(ColorIndex)); - } - } - - if (rhs.hipix) { - hipix = new Color[mapsize]; - - if (!hipix && !pix) { - width = 0; - height = 0; - mapsize = 0; - } - - else { - memcpy(hipix, rhs.hipix, mapsize*sizeof(Color)); - } - } - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::ClearImage() -{ - if (ownpix) { - delete [] pix; - delete [] hipix; - pix = 0; - hipix = 0; - } - - type = BMP_SOLID; - width = 0; - height = 0; - mapsize = 0; - ownpix = false; - texture = false; - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::CopyImage(int w, int h, BYTE* p, int t) -{ - if (ownpix) { - delete [] pix; - pix = 0; - } - else { - hipix = 0; - } - - type = t; - width = w; - height = h; - ownpix = true; - texture = false; - mapsize = w * h; - - pix = new ColorIndex[mapsize]; - - if (!pix) { - width = 0; - height = 0; - mapsize = 0; - } - - else { - memcpy(pix, p, mapsize); - } - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::CopyHighColorImage(int w, int h, DWORD* p, int t) -{ - if (ownpix) { - delete [] hipix; - hipix = 0; - } - else { - pix = 0; - } - - type = t; - width = w; - height = h; - ownpix = true; - texture = false; - mapsize = w * h; - - hipix = new Color[mapsize]; - - if (!hipix) { - width = 0; - height = 0; - mapsize = 0; - } - - else { - memcpy(hipix, p, mapsize*sizeof(DWORD)); - } - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::CopyAlphaImage(int w, int h, BYTE* a) -{ - if (!hipix || width != w || height != h) - return; - - type = BMP_TRANSLUCENT; - alpha_loaded = true; - - Color* p = hipix; - - for (int i = 0; i < mapsize; i++) { - p->SetAlpha(*a); - p++; - a++; - } - - last_modified = Clock::GetInstance()->RealTime(); -} - -void -Bitmap::CopyAlphaRedChannel(int w, int h, DWORD* a) -{ - if (!hipix || width != w || height != h) - return; - - type = BMP_TRANSLUCENT; - alpha_loaded = true; - - Color* p = hipix; - - for (int i = 0; i < mapsize; i++) { - p->SetAlpha((BYTE) ((*a & Color::RMask) >> Color::RShift)); - p++; - a++; - } - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::AutoMask(DWORD mask) -{ - if (!hipix || !mapsize || alpha_loaded) - return; - - type = BMP_TRANSLUCENT; - alpha_loaded = true; - - Color* p = hipix; - DWORD m = mask & Color::RGBMask; - - for (int i = 0; i < mapsize; i++) { - if ((p->Value() & Color::RGBMask) == m) - p->SetAlpha(0); - else - p->SetAlpha(255); - - p++; - } - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::FillColor(Color c) -{ - if (!width || !height) - return; - - if (pix) { - ColorIndex* p = pix; - BYTE index = c.Index(); - - for (int i = 0; i < mapsize; i++) - *p++ = index; - } - - if (hipix) { - Color* p = hipix; - DWORD value = c.Value(); - - for (int i = 0; i < mapsize; i++) { - p->Set(value); - p++; - } - } - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::ScaleTo(int w, int h) -{ - if (w < 1 || h < 1) - return; - - double dx = (double) width / (double) w; - double dy = (double) height / (double) h; - - bool mem_ok = true; - - if (hipix) { - Color* src = hipix; - Color* buf = new Color[w*h]; - Color* dst = buf; - - if (!buf) { - mem_ok = false; - } - - else { - for (int y = 0; y < h; y++) { - int y_offset = (int) (y * dy); - for (int x = 0; x < w; x++) { - int x_offset = (int) (x * dx); - src = hipix + (y_offset * width) + x_offset; - *dst++ = *src; - } - } - - if (ownpix) - delete [] hipix; - - hipix = buf; - ownpix = true; - } - } - - if (pix) { - ColorIndex* src = pix; - ColorIndex* buf = new ColorIndex[w*h]; - ColorIndex* dst = buf; - - if (!buf) { - mem_ok = false; - } - - else { - for (int y = 0; y < h; y++) { - int y_offset = (int) (y * dy); - for (int x = 0; x < w; x++) { - int x_offset = (int) (x * dx); - src = pix + (y_offset * width) + x_offset; - *dst++ = *src; - } - } - - if (ownpix) - delete [] pix; - - pix = buf; - ownpix = true; - } - } - - if (mem_ok) { - width = w; - height = h; - mapsize = width * height; - } -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::MakeIndexed() -{ - if (hipix) { - if (pix && ownpix) - delete [] pix; - pix = new ColorIndex[mapsize]; - - if (pix) { - Color* src = hipix; - ColorIndex* dst = pix; - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - *dst++ = src->Index(); - src++; - } - } - - if (!ownpix) - hipix = 0; - - ownpix = true; - } - } -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::MakeHighColor() -{ - if (pix) { - if (hipix && ownpix) - delete [] hipix; - - hipix = new Color[mapsize]; - - if (hipix) { - ColorIndex* src = pix; - Color* dst = hipix; - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - *dst++ = src->Index(); - src++; - } - } - - if (!ownpix) - pix = 0; - - ownpix = true; - } - } -} - -// +--------------------------------------------------------------------+ - -static int FindBestTexSize(int n, int max_size) -{ - int delta = 100000; - int best = 1; - - for (int i = 0; i < 12; i++) { - int size = 1 << i; - - if (size > max_size) - break; - - int dx = abs(n-size); - - if (size < n) - dx *= 4; - - if (dx < delta) { - delta = dx; - best = size; - } - } - - return best; -} - -void -Bitmap::MakeTexture() -{ - if (width < 1 || height < 1 || (!pix && !hipix)) { - if (ownpix) { - delete [] pix; - delete [] hipix; - } - - width = 0; - height = 0; - pix = 0; - hipix = 0; - texture = false; - return; - } - - // texture surface format is 32-bit RGBA: - if (pix && !hipix) { - MakeHighColor(); - } - - // check size and aspect ratio: - int max_tex_size = GameWinDX9::GetInstance()->MaxTexSize(); - int max_tex_aspect = GameWinDX9::GetInstance()->MaxTexAspect(); - - int best_width = FindBestTexSize(width, max_tex_size); - int best_height = FindBestTexSize(height, max_tex_size); - int aspect = 1; - - // correct sizes for aspect if necessary: - if (best_width > best_height) { - aspect = best_width / best_height; - - if (aspect > max_tex_aspect) - best_height = best_width / max_tex_aspect; - } - - else { - aspect = best_height / best_width; - - if (aspect > max_tex_aspect) - best_width = best_height / max_tex_aspect; - } - - // rescale if necessary: - if (width != best_width || height != best_height) - ScaleTo(best_width, best_width); - - texture = true; -} - -// +--------------------------------------------------------------------+ - -ColorIndex -Bitmap::GetIndex(int x, int y) const -{ - ColorIndex result(0); - - if (x < 0 || y < 0 || x > width-1 || y > height-1) - return result; - - if (pix) { - result = *(pix + y*width + x); - } - else if (hipix) { - result = (hipix + y*width + x)->Index(); - } - - return result; -} - -// +--------------------------------------------------------------------+ - -Color -Bitmap::GetColor(int x, int y) const -{ - Color result = Color::Black; - - if (x < 0 || y < 0 || x > width-1 || y > height-1) - return result; - - if (pix) { - result = (pix + y*width + x)->Index(); - } - else if (hipix) { - result = *(hipix + y*width + x); - } - - return result; -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::SetIndex(int x, int y, ColorIndex c) -{ - if (x < 0 || y < 0 || x > width || y > height) - return; - - if (pix) { - *(pix + y*width + x) = c; - } - else if (hipix) { - *(hipix + y*width + x) = c.Index(); - } - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::SetColor(int x, int y, Color c) -{ - if (x < 0 || y < 0 || x > width || y > height) - return; - - if (pix) { - *(pix + y*width + x) = c.Index(); - } - else if (hipix) { - *(hipix + y*width + x) = c; - } - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::SetFilename(const char* s) -{ - if (s) { - int n = strlen(s); - - if (n >= 60) { - ZeroMemory(filename, sizeof(filename)); - strcpy_s(filename, "..."); - strcat_s(filename, s + n - 59); - filename[63] = 0; - } - - else { - strcpy_s(filename, s); - } - } -} - -// +--------------------------------------------------------------------+ - -Bitmap* -Bitmap::Default() -{ - static Bitmap def; - - if (!def.width) { - def.width = def.height = 64; - def.mapsize = 64*64; - def.ownpix = true; - def.pix = new ColorIndex[def.mapsize]; - - // 8 bit palette mode - if (def.pix) { - ColorIndex* p = def.pix; - - for (int y = 0; y < 64; y++) { - for (int x = 0; x < 64; x++) { - double distance = sqrt((x-32.0)*(x-32.0) + (y-32.0)*(y-32.0)); - if (distance > 31.0) distance = 31.0; - BYTE color = 24 + (BYTE) distance; - - if (x == 0 || y == 0) color = 255; - else if (x == 32 || y == 32) color = 251; - - *p++ = color; - } - } - } - } - - return &def; -} - -// +--------------------------------------------------------------------+ - -static List bitmap_cache; - -Bitmap* -Bitmap::GetBitmapByID(HANDLE bmp_id) -{ - for (int i = 0; i < bitmap_cache.size(); i++) { - if (bitmap_cache[i]->Handle() == bmp_id) { - return bitmap_cache[i]; - } - } - - return 0; -} - -Bitmap* -Bitmap::CheckCache(const char* filename) -{ - for (int i = 0; i < bitmap_cache.size(); i++) { - if (!_stricmp(bitmap_cache[i]->GetFilename(), filename)) { - return bitmap_cache[i]; - } - } - - return 0; -} - -void -Bitmap::AddToCache(Bitmap* bmp) -{ - bitmap_cache.append(bmp); -} - -void -Bitmap::CacheUpdate() -{ - for (int i = 0; i < bitmap_cache.size(); i++) { - Bitmap* bmp = bitmap_cache[i]; - - if (bmp->IsTexture()) - bmp->MakeTexture(); - } -} - -void -Bitmap::ClearCache() -{ - bitmap_cache.destroy(); -} - -DWORD -Bitmap::CacheMemoryFootprint() -{ - DWORD result = sizeof(bitmap_cache); - result += bitmap_cache.size() * sizeof(Bitmap*); - - for (int i = 0; i < bitmap_cache.size(); i++) { - Bitmap* bmp = bitmap_cache[i]; - - if (bmp->pix) - result += bmp->mapsize * sizeof(ColorIndex); - - if (bmp->hipix) - result += bmp->mapsize * sizeof(Color); - } - - return result; -} - -// +--------------------------------------------------------------------+ - -bool -Bitmap::ClipLine(int& x1, int& y1, int& x2, int& y2) -{ - // vertical lines: - if (x1==x2) { - clip_vertical: - sort(y1,y2); - if (x1 < 0 || x1 >= width) return false; - if (y1 < 0) y1 = 0; - if (y2 >= height) y2 = height; - return true; - } - - // horizontal lines: - if (y1==y2) { - clip_horizontal: - sort(x1,x2); - if (y1 < 0 || y1 >= height) return false; - if (x1 < 0) x1 = 0; - if (x2 > width) x2 = width; - return true; - } - - // general lines: - - // sort left to right: - if (x1 > x2) { - swap(x1,x2); - swap(y1,y2); - } - - double m = (double)(y2-y1) / (double)(x2-x1); - double b = (double) y1 - (m * x1); - - // clip: - if (x1 < 0) { x1 = 0; y1 = (int) b; } - if (x1 >= width) return false; - if (x2 < 0) return false; - if (x2 > width-1) { x2 = width-1; y2 = (int) (m * x2 + b); } - - if (y1 < 0 && y2 < 0) return false; - if (y1 >= height && y2 >= height) return false; - - if (y1 < 0) { y1 = 0; x1 = (int) (-b/m); } - if (y1 >= height) { y1 = height-1; x1 = (int) ((y1-b)/m); } - if (y2 < 0) { y2 = 0; x2 = (int) (-b/m); } - if (y2 >= height) { y2 = height-1; x2 = (int) ((y2-b)/m); } - - if (x1 == x2) - goto clip_vertical; - - if (y1 == y2) - goto clip_horizontal; - - return true; -} - -// +--------------------------------------------------------------------+ - -bool -Bitmap::ClipLine(double& x1, double& y1, double& x2, double& y2) -{ - // vertical lines: - if (x1==x2) { - clip_vertical: - sort(y1,y2); - if (x1 < 0 || x1 >= width) return false; - if (y1 < 0) y1 = 0; - if (y2 >= height) y2 = height; - return true; - } - - // horizontal lines: - if (y1==y2) { - clip_horizontal: - sort(x1,x2); - if (y1 < 0 || y1 >= height) return false; - if (x1 < 0) x1 = 0; - if (x2 > width) x2 = width; - return true; - } - - // general lines: - - // sort left to right: - if (x1 > x2) { - swap(x1,x2); - swap(y1,y2); - } - - double m = (double)(y2-y1) / (double)(x2-x1); - double b = (double) y1 - (m * x1); - - // clip: - if (x1 < 0) { x1 = 0; y1 = b; } - if (x1 >= width) return false; - if (x2 < 0) return false; - if (x2 > width-1) { x2 = width-1; y2 = (m * x2 + b); } - - if (y1 < 0 && y2 < 0) return false; - if (y1 >= height && y2 >= height) return false; - - if (y1 < 0) { y1 = 0; x1 = (-b/m); } - if (y1 >= height) { y1 = height-1; x1 = ((y1-b)/m); } - if (y2 < 0) { y2 = 0; x2 = (-b/m); } - if (y2 >= height) { y2 = height-1; x2 = ((y2-b)/m); } - - if (x1 == x2) - goto clip_vertical; - - if (y1 == y2) - goto clip_horizontal; - - return true; -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::DrawLine(int x1, int y1, int x2, int y2, Color color) -{ - BYTE* s = GetSurface(); - - if (!s) return; - - last_modified = Clock::GetInstance()->RealTime(); - - // vertical lines: - if (x1==x2) { - draw_vertical: - sort(y1,y2); - int fh = y2-y1; - if (x1 < 0 || x1 >= width) return; - if (y1 < 0) y1 = 0; - if (y2 >= height) y2 = height; - fh = y2-y1; - draw_vline(s, Pitch(), PixSize(), x1, y1, fh, color); - return; - } - - // horizontal lines: - if (y1==y2) { - draw_horizontal: - sort(x1,x2); - int fw = x2-x1; - if (y1 < 0 || y1 >= height) return; - if (x1 < 0) x1 = 0; - if (x2 > width) x2 = width; - fw = x2-x1; - draw_strip(s, Pitch(), PixSize(), x1, y1, fw, color); - return; - } - - // general lines: - - // sort left to right: - if (x1 > x2) { - swap(x1,x2); - swap(y1,y2); - } - - double m = (double)(y2-y1) / (double)(x2-x1); - double b = (double) y1 - (m * x1); - - // clip: - if (x1 < 0) { x1 = 0; y1 = (int) b; } - if (x1 >= width) return; - if (x2 < 0) return; - if (x2 > width-1) { x2 = width-1; y2 = (int) (m * x2 + b); } - - if (y1 < 0 && y2 < 0) return; - if (y1 >= height && y2 >= height) return; - - if (y1 < 0) { y1 = 0; x1 = (int) (-b/m); } - if (y1 >= height) { y1 = height-1; x1 = (int) ((y1-b)/m); } - if (y2 < 0) { y2 = 0; x2 = (int) (-b/m); } - if (y2 >= height) { y2 = height-1; x2 = (int) ((y2-b)/m); } - - if (x1 > x2) - return; - - if (x1 == x2) - goto draw_vertical; - - if (y1 == y2) - goto draw_horizontal; - - // plot the line using - /* - Symmetric Double Step Line Algorithm - by Brian Wyvill - from "Graphics Gems", Academic Press, 1990 -*/ - - WinPlot plotter(this); - - DWORD pix = color.Value(); - int sign_x=1, sign_y=1, step, reflect; - int i, inc1, inc2, c, D, x_end, pixleft; - int dx = x2 - x1; - int dy = y2 - y1; - - if (dx < 0) { - sign_x = -1; - dx *= -1; - } - if (dy < 0) { - sign_y = -1; - dy *= -1; - } - - // decide increment sign by the slope sign - if (sign_x == sign_y) - step = 1; - else - step = -1; - - if (dy > dx) { // chooses axis of greatest movement (make * dx) - swap(x1, y1); - swap(x2, y2); - swap(dx, dy); - reflect = 1; - } else - reflect = 0; - - if (x1 > x2) { // start from the smaller coordinate - swap(x1,x2); - swap(y1,y2); - } - - /* Note dx=n implies 0 - n or (dx+1) pixels to be set */ - /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */ - /* In fact (dx-1)/4 as 2 pixels are already plottted */ - x_end = (dx - 1) / 4; - pixleft = (dx - 1) % 4; /* number of pixels left over at the end */ - - plotter.plot(x1, y1, pix, reflect); - plotter.plot(x2, y2, pix, reflect); /* plot first two points */ - - inc2 = 4 * dy - 2 * dx; - if (inc2 < 0) { /* slope less than 1/2 */ - c = 2 * dy; - inc1 = 2 * c; - D = inc1 - dx; - - for (i = 0; i < x_end; i++) { /* plotting loop */ - ++x1; - --x2; - if (D < 0) { - /* pattern 1 forwards */ - plotter.plot(x1, y1, pix, reflect); - plotter.plot(++x1, y1, pix, reflect); - /* pattern 1 backwards */ - plotter.plot(x2, y2, pix, reflect); - plotter.plot(--x2, y2, pix, reflect); - D += inc1; - } - else { - if (D < c) { - /* pattern 2 forwards */ - plotter.plot(x1, y1, pix, reflect); - plotter.plot(++x1, y1 += step, pix, reflect); - /* pattern 2 backwards */ - plotter.plot(x2, y2, pix, reflect); - plotter.plot(--x2, y2 -= step, pix, reflect); - } - else { - /* pattern 3 forwards */ - plotter.plot(x1, y1 += step, pix, reflect); - plotter.plot(++x1, y1, pix, reflect); - /* pattern 3 backwards */ - plotter.plot(x2, y2 -= step, pix, reflect); - plotter.plot(--x2, y2, pix, reflect); - } - D += inc2; - } - } /* end for */ - - /* plot last pattern */ - if (pixleft) { - if (D < 0) { - plotter.plot(++x1, y1, pix, reflect); /* pattern 1 */ - if (pixleft > 1) - plotter.plot(++x1, y1, pix, reflect); - if (pixleft > 2) - plotter.plot(--x2, y2, pix, reflect); - } - else { - if (D < c) { - plotter.plot(++x1, y1, pix, reflect); /* pattern 2 */ - if (pixleft > 1) - plotter.plot(++x1, y1 += step, pix, reflect); - if (pixleft > 2) - plotter.plot(--x2, y2, pix, reflect); - } - else { - /* pattern 3 */ - plotter.plot(++x1, y1 += step, pix, reflect); - if (pixleft > 1) - plotter.plot(++x1, y1, pix, reflect); - if (pixleft > 2) - plotter.plot(--x2, y2 -= step, pix, reflect); - } - } - } /* end if pixleft */ - } - /* end slope < 1/2 */ - else { /* slope greater than 1/2 */ - c = 2 * (dy - dx); - inc1 = 2 * c; - D = inc1 + dx; - for (i = 0; i < x_end; i++) { - ++x1; - --x2; - if (D > 0) { - /* pattern 4 forwards */ - plotter.plot(x1, y1 += step, pix, reflect); - plotter.plot(++x1, y1 += step, pix, reflect); - /* pattern 4 backwards */ - plotter.plot(x2, y2 -= step, pix, reflect); - plotter.plot(--x2, y2 -= step, pix, reflect); - D += inc1; - } else { - if (D < c) { - /* pattern 2 forwards */ - plotter.plot(x1, y1, pix, reflect); - plotter.plot(++x1, y1 += step, pix, reflect); - - /* pattern 2 backwards */ - plotter.plot(x2, y2, pix, reflect); - plotter.plot(--x2, y2 -= step, pix, reflect); - } else { - /* pattern 3 forwards */ - plotter.plot(x1, y1 += step, pix, reflect); - plotter.plot(++x1, y1, pix, reflect); - /* pattern 3 backwards */ - plotter.plot(x2, y2 -= step, pix, reflect); - plotter.plot(--x2, y2, pix, reflect); - } - D += inc2; - } - } /* end for */ - /* plot last pattern */ - if (pixleft) { - if (D > 0) { - plotter.plot(++x1, y1 += step, pix, reflect); /* pattern 4 */ - if (pixleft > 1) - plotter.plot(++x1, y1 += step, pix, reflect); - if (pixleft > 2) - plotter.plot(--x2, y2 -= step, pix, reflect); - } else { - if (D < c) { - plotter.plot(++x1, y1, pix, reflect); /* pattern 2 */ - if (pixleft > 1) - plotter.plot(++x1, y1 += step, pix, reflect); - if (pixleft > 2) - plotter.plot(--x2, y2, pix, reflect); - } else { - /* pattern 3 */ - plotter.plot(++x1, y1 += step, pix, reflect); - if (pixleft > 1) - plotter.plot(++x1, y1, pix, reflect); - if (pixleft > 2) { - if (D > c) /* step 3 */ - plotter.plot(--x2, y2 -= step, pix, reflect); - else /* step 2 */ - plotter.plot(--x2, y2, pix, reflect); - } - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::DrawRect(int x1, int y1, int x2, int y2, Color color) -{ - sort(x1,x2); - sort(y1,y2); - - int fw = x2-x1; - int fh = y2-y1; - - if (fw == 0 || fh == 0) return; - - // perform clip - int left = (x1 >= 0); - int right = (x2 <= width); - int top = (y1 >= 0); - int bottom = (y2 <= height); - - BYTE* s = GetSurface(); - if (!s) return; - int pitch = Pitch(); - int pixsize = PixSize(); - - if (left) draw_vline(s, pitch, pixsize, x1, y1, fh, color); - if (right) draw_vline(s, pitch, pixsize, x2, y1, fh, color); - if (top) draw_strip(s, pitch, pixsize, x1, y1, fw, color); - if (bottom) draw_strip(s, pitch, pixsize, x1, y2, fw, color); - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::DrawRect(const Rect& r, Color color) -{ - if (r.w == 0 || r.h == 0) return; - - int x1 = r.x; - int y1 = r.y; - int x2 = r.x + r.w; - int y2 = r.y + r.h; - - // perform clip - int left = (x1 >= 0); - int right = (x2 <= width); - int top = (y1 >= 0); - int bottom = (y2 <= height); - - BYTE* s = GetSurface(); - if (!s) return; - int pitch = Pitch(); - int pixsize = PixSize(); - - if (left) draw_vline(s, pitch, pixsize, x1, y1, r.h, color); - if (right) draw_vline(s, pitch, pixsize, x2, y1, r.h, color); - if (top) draw_strip(s, pitch, pixsize, x1, y1, r.w, color); - if (bottom) draw_strip(s, pitch, pixsize, x1, y2, r.w, color); - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::FillRect(int x1, int y1, int x2, int y2, Color color) -{ - // perform clip - if (x1 < 0) x1 = 0; - if (x2 > width-1) x2 = width-1; - if (y1 < 0) y1 = 0; - if (y2 > height) y2 = height; - - int fw = x2-x1; - int fh = y2-y1; - - if (fw == 0 || fh == 0) return; - - BYTE* s = GetSurface(); - if (!s) return; - int pitch = Pitch(); - int pixsize = PixSize(); - - for (int i = 0; i < fh; i++) - draw_strip(s, pitch, pixsize, x1, y1+i, fw, color); - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::FillRect(const Rect& r, Color color) -{ - int x1 = r.x; - int y1 = r.y; - int x2 = r.x + r.w; - int y2 = r.y + r.h; - - // perform clip - if (x1 < 0) x1 = 0; - if (x2 > width-1) x2 = width-1; - if (y1 < 0) y1 = 0; - if (y2 > height) y2 = height; - - int fw = x2-x1; - int fh = y2-y1; - - if (fw == 0 || fh == 0) return; - - BYTE* s = GetSurface(); - if (!s) return; - int pitch = Pitch(); - int pixsize = PixSize(); - - for (int i = 0; i < fh; i++) - draw_strip(s, pitch, pixsize, x1, y1+i, fw, color); - - last_modified = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -Bitmap::DrawEllipse(int x1, int y1, int x2, int y2, Color color, BYTE quad) -{ - BYTE* orig = GetSurface(); - BYTE* s = orig; - - if (!s) return; - - sort(x1,x2); - sort(y1,y2); - - int fw = x2-x1; - int fh = y2-y1; - - if (fw < 1 || fh < 1) return; - - // clip: - if (x1 >= width || x2 < 0) return; - if (y1 >= height || y2 < 0) return; - - double a = fw / 2.0; - double b = fh / 2.0; - double a2 = a*a; - double b2 = b*b; - - int x = 0; - int y = (int) b; - int x0 = (x1+x2)/2; - int y0 = (y1+y2)/2; - - // clip super-giant ellipses: - if (x1 < 0 && y1 < 0 && x2 > width && y2 > height) { - double r2 = (a2 32 * height) - return; - - double ul = (x1-x0)*(x1-x0) + (y1-y0)*(y1-y0); - double ur = (x2-x0)*(x2-x0) + (y1-y0)*(y1-y0); - double ll = (x1-x0)*(x1-x0) + (y2-y0)*(y2-y0); - double lr = (x2-x0)*(x2-x0) + (y2-y0)*(y2-y0); - - if (ul > r2 && ur > r2 && ll > r2 && lr > r2) - return; - } - - DrawEllipsePoints(x0,y0,x,y,color,quad); - - // region 1 - double d1 = (b2)-(a2*b)+(0.25*a2); - while ((a2)*(y-0.5) > (b2)*(x+1)) { - if (d1 < 0) - d1 += b2*(2*x+3); - else { - d1 += b2*(2*x+3) + a2*(-2*y+2); - y--; - } - x++; - - DrawEllipsePoints(x0,y0,x,y,color,quad); - } - - // region 2 - double d2 = b2*(x+0.5)*(x+0.5) + a2*(y-1)*(y-1) - a2*b2; - while (y > 0) { - if (d2 < 0) { - d2 += b2*(2*x+2) + a2*(-2*y+3); - x++; - } - else - d2 += a2*(-2*y+3); - y--; - - DrawEllipsePoints(x0,y0,x,y,color,quad); - } - - last_modified = Clock::GetInstance()->RealTime(); -} - -void -Bitmap::DrawEllipsePoints(int x0, int y0, int x, int y, Color c, BYTE quad) -{ - BYTE* s = GetSurface(); - - if (!s) return; - - int pitch = Pitch(); - int pixsize = PixSize(); - - int left = x0-x; - int right = x0+x+1; - int top = y0-y; - int bottom = y0+y+1; - - // clip: - if (left >= width || right < 0) return; - if (top >= height || bottom < 0) return; - - BYTE* dst = 0; - DWORD cf = c.Value(); - - if (left >= 0 && top >= 0 && quad&1) { - dst = s + top*pitch + left*pixsize; - - switch (pixsize) { - case 1: *dst = (BYTE) cf; break; - case 2: { LPWORD sw = (LPWORD) dst; *sw = (WORD) cf; } break; - case 4: { LPDWORD sd = (LPDWORD) dst; *sd = (DWORD) cf; } break; - } - } - - if (right < width && top >= 0 && quad&2) { - dst = s + top*pitch + right*pixsize; - - switch (pixsize) { - case 1: *dst = (BYTE) cf; break; - case 2: { LPWORD sw = (LPWORD) dst; *sw = (WORD) cf; } break; - case 4: { LPDWORD sd = (LPDWORD) dst; *sd = (DWORD) cf; } break; - } - } - - if (left >= 0 && bottom < height && quad&4) { - dst = s + bottom*pitch + left*pixsize; - - switch (pixsize) { - case 1: *dst = (BYTE) cf; break; - case 2: { LPWORD sw = (LPWORD) dst; *sw = (WORD) cf; } break; - case 4: { LPDWORD sd = (LPDWORD) dst; *sd = (DWORD) cf; } break; - } - } - - if (right < width && bottom < height && quad&4) { - dst = s + bottom*pitch + right*pixsize; - - switch (pixsize) { - case 1: *dst = (BYTE) cf; break; - case 2: { LPWORD sw = (LPWORD) dst; *sw = (WORD) cf; } break; - case 4: { LPDWORD sd = (LPDWORD) dst; *sd = (DWORD) cf; } break; - } - } -} - -// +--------------------------------------------------------------------+ - -static void draw_strip(BYTE* s, int pitch, int pixsize, int x, int y, int len, Color color) -{ - if (!s) return; - s += y*pitch + x*pixsize; - - DWORD value = color.Formatted(); - - switch (pixsize) { - case 1: { - if (len > 1) - memset(s, (BYTE) value, len); - } - break; - - case 2: { - LPWORD sw = (LPWORD) s; - for (int x = 0; x < len; x++) { - *sw++ = (WORD) value; - } - } - break; - - case 4: { - Color* sd = (Color*) s; - for (int x = 0; x < len; x++) { - *sd++ = color; - } - } - break; - } -} - -// +--------------------------------------------------------------------+ - -static void draw_vline(BYTE* s, int pitch, int pixsize, int x, int y, int len, Color color) -{ - if (!s) return; - s += (y)*pitch + (x)*pixsize; - - DWORD value = color.Formatted(); - - switch (pixsize) { - case 1: { - for (int y = 0; y < len; y++) { - *s = (BYTE) value; - s += pitch; - } - } - break; - - case 2: { - LPWORD sw = (LPWORD) s; - pitch /= 2; - - for (int y = 0; y < len; y++) { - *sw = (WORD) value; - sw += pitch; - } - } - break; - - case 4: { - Color* sd = (Color*) s; - pitch /= 4; - - for (int y = 0; y < len; y++) { - *sd = color; - sd += pitch; - } - } - break; - } -} - - diff --git a/Stars45/Bitmap.h b/Stars45/Bitmap.h deleted file mode 100644 index 11eea10..0000000 --- a/Stars45/Bitmap.h +++ /dev/null @@ -1,123 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Bitmap Resource class -*/ - -#ifndef Bitmap_h -#define Bitmap_h - -#include "Res.h" -#include "Types.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Color; -class ColorIndex; - -class Bitmap : public Resource -{ -public: - static const char* TYPENAME() { return "Bitmap"; } - - enum BMP_TYPES { BMP_SOLID, BMP_TRANSPARENT, BMP_TRANSLUCENT }; - - Bitmap(); - Bitmap(int w, int h, ColorIndex* p=0, int t=BMP_SOLID); - Bitmap(int w, int h, Color* p, int t=BMP_SOLID); - virtual ~Bitmap(); - - int IsIndexed() const { return pix != 0; } - int IsHighColor() const { return hipix != 0; } - int IsDual() const { return IsIndexed() && - IsHighColor(); } - - void SetType(int t) { type = t; } - int Type() const { return type; } - bool IsSolid() const { return type==BMP_SOLID; } - bool IsTransparent() const { return type==BMP_TRANSPARENT; } - bool IsTranslucent() const { return type==BMP_TRANSLUCENT; } - - int Width() const { return width; } - int Height() const { return height; } - ColorIndex* Pixels() const { return pix; } - Color* HiPixels() const { return hipix; } - int BmpSize() const; - int RowSize() const; - - ColorIndex GetIndex(int x, int y) const; - Color GetColor(int x, int y) const; - void SetIndex(int x, int y, ColorIndex c); - void SetColor(int x, int y, Color c); - - void FillColor(Color c); - - void ClearImage(); - void BitBlt(int x, int y, const Bitmap& srcImage, int sx, int sy, int w, int h, bool blend=false); - void CopyBitmap(const Bitmap& rhs); - void CopyImage(int w, int h, BYTE* p, int t=BMP_SOLID); - void CopyHighColorImage(int w, int h, DWORD* p, int t=BMP_SOLID); - void CopyAlphaImage(int w, int h, BYTE* p); - void CopyAlphaRedChannel(int w, int h, DWORD* p); - void AutoMask(DWORD mask=0); - - virtual BYTE* GetSurface(); - virtual int Pitch() const; - virtual int PixSize() const; - bool ClipLine(int& x1, int& y1, int& x2, int& y2); - bool ClipLine(double& x1, double& y1, double& x2, double& y2); - void DrawLine(int x1, int y1, int x2, int y2, Color color); - void DrawRect(int x1, int y1, int x2, int y2, Color color); - void DrawRect(const Rect& r, Color color); - void FillRect(int x1, int y1, int x2, int y2, Color color); - void FillRect(const Rect& r, Color color); - void DrawEllipse(int x1, int y1, int x2, int y2, Color color, BYTE quad=0x0f); - void DrawEllipsePoints(int x0, int y0, int x, int y, Color c, BYTE quad); - - void ScaleTo(int w, int h); - void MakeIndexed(); - void MakeHighColor(); - void MakeTexture(); - bool IsTexture() const { return texture; } - void TakeOwnership() { ownpix = true; } - - const char* GetFilename() const { return filename; } - void SetFilename(const char* s); - - DWORD LastModified() const { return last_modified; } - - static Bitmap* Default(); - - static Bitmap* GetBitmapByID(HANDLE bmp_id); - static Bitmap* CheckCache(const char* filename); - static void AddToCache(Bitmap* bmp); - static void CacheUpdate(); - static void ClearCache(); - static DWORD CacheMemoryFootprint(); - -protected: - int type; - int width; - int height; - int mapsize; - - bool ownpix; - bool alpha_loaded; - bool texture; - - ColorIndex* pix; - Color* hipix; - DWORD last_modified; - char filename[64]; -}; - -#endif // Bitmap_h - diff --git a/Stars45/Bmp.cpp b/Stars45/Bmp.cpp deleted file mode 100644 index 345b9eb..0000000 --- a/Stars45/Bmp.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - BMP image file loader -*/ - - -#include "Bmp.h" - -#include -#include -#include - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -BmpImage::BmpImage() - : width(0), height(0), image(0) -{ } - -BmpImage::BmpImage(short w, short h, unsigned long* hibits) -{ - ZeroMemory(this, sizeof(BmpImage)); - - width = w; - height = h; - - file_hdr.type = 19778; // 'BM' - file_hdr.size = sizeof(BmpFileHeader) + - sizeof(BmpInfoHeader) + - w * h * 3; - - file_hdr.offset = sizeof(BmpFileHeader) + - sizeof(BmpInfoHeader); - - info_hdr.hdr_size = sizeof(BmpInfoHeader); - info_hdr.width = width; - info_hdr.height = height; - info_hdr.planes = 1; - info_hdr.bit_count = 24; - - int pixels = width * height; - - image = new DWORD [pixels]; - - if (image && pixels) { - for (int i = 0; i < pixels; i++) - image[i] = hibits[i]; - } -} - -BmpImage::~BmpImage() -{ - delete [] image; -} - -// +--------------------------------------------------------------------+ - -int BmpImage::Load(char *filename) -{ - int status = BMP_INVALID; - FILE* f; - - fopen_s(&f, filename,"rb"); - if (f == NULL) - return BMP_NOFILE; - - fread(&file_hdr.type, sizeof(WORD), 1, f); - fread(&file_hdr.size, sizeof(DWORD), 1, f); - fread(&file_hdr.rsvd1, sizeof(WORD), 1, f); - fread(&file_hdr.rsvd2, sizeof(WORD), 1, f); - fread(&file_hdr.offset, sizeof(DWORD), 1, f); - fread(&info_hdr, BMP_INFO_HDR_SIZE, 1, f); - - if (info_hdr.width > 32768 || info_hdr.height > 32768 || - (info_hdr.width&3) || (info_hdr.height&3) || - info_hdr.compression != 0) { - fclose(f); - return BMP_INVALID; - } - - width = (WORD) info_hdr.width; - height = (WORD) info_hdr.height; - - // read 256 color BMP file - if (info_hdr.bit_count == 8) { - fread(palette, sizeof(palette), 1, f); - - int pixels = width*height; - - delete [] image; - image = new DWORD[pixels]; - if (image == NULL) - return BMP_NOMEM; - - for (int row = height-1; row >= 0; row--) { - for (int col = 0; col < width; col++) { - BYTE index = fgetc(f); - image[row*width+col] = palette[index]; - } - } - - status = BMP_OK; - } - - // read 24-bit (true COLOR) BMP file - else if (info_hdr.bit_count == 24) { - int pixels = width*height; - - delete [] image; - image = new DWORD[pixels]; - if (image == NULL) - return BMP_NOMEM; - - for (int row = height-1; row >= 0; row--) { - for (int col = 0; col < width; col++) { - DWORD blue = fgetc(f); - DWORD green = fgetc(f); - DWORD red = fgetc(f); - - image[row*width+col] = 0xff000000 | (red << 16) | (green << 8) | blue; - } - } - - status = BMP_OK; - } - - fclose(f); - return status; -} - -// +--------------------------------------------------------------------+ - -int BmpImage::LoadBuffer(unsigned char* buf, int len) -{ - int status = BMP_INVALID; - BYTE* fp; - - if (buf == NULL) - return BMP_NOFILE; - - fp = buf; - memcpy(&info_hdr, buf + BMP_FILE_HDR_SIZE, BMP_INFO_HDR_SIZE); - fp += BMP_FILE_HDR_SIZE + BMP_INFO_HDR_SIZE; - - if (info_hdr.width > 32768 || info_hdr.height > 32768 || - (info_hdr.width&3) || (info_hdr.height&3) || - info_hdr.compression != 0) { - return BMP_INVALID; - } - - width = (WORD) info_hdr.width; - height = (WORD) info_hdr.height; - - // read 256 color BMP file - if (info_hdr.bit_count == 8) { - memcpy(palette, fp, sizeof(palette)); - fp += sizeof(palette); - - int pixels = width*height; - - delete [] image; - image = new DWORD[pixels]; - if (image == NULL) - return BMP_NOMEM; - - for (int row = height-1; row >= 0; row--) { - for (int col = 0; col < width; col++) { - BYTE index = *fp++; - image[row*width+col] = palette[index]; - } - } - - status = BMP_OK; - } - - // read 24-bit (true COLOR) BMP file - else if (info_hdr.bit_count == 24) { - int pixels = width*height; - - delete [] image; - image = new DWORD[pixels]; - if (image == NULL) - return BMP_NOMEM; - - for (int row = height-1; row >= 0; row--) { - for (int col = 0; col < width; col++) { - DWORD blue = *fp++; - DWORD green = *fp++; - DWORD red = *fp++; - - image[row*width+col] = 0xff000000 | (red << 16) | (green << 8) | blue; - } - } - - status = BMP_OK; - } - - return status; -} - -// +--------------------------------------------------------------------+ - -int BmpImage::Save(char *filename) -{ - int status = BMP_INVALID; - FILE* f; - - fopen_s(&f, filename,"wb"); - if (f == NULL) - return BMP_NOFILE; - - info_hdr.bit_count = 24; - info_hdr.compression = 0; - - fwrite(&file_hdr.type, sizeof(WORD), 1, f); - fwrite(&file_hdr.size, sizeof(DWORD), 1, f); - fwrite(&file_hdr.rsvd1, sizeof(WORD), 1, f); - fwrite(&file_hdr.rsvd2, sizeof(WORD), 1, f); - fwrite(&file_hdr.offset, sizeof(DWORD), 1, f); - fwrite(&info_hdr, BMP_INFO_HDR_SIZE, 1, f); - - // write 24-bit (TRUE COLOR) BMP file - for (int row = height-1; row >= 0; row--) { - for (int col = 0; col < width; col++) { - DWORD pixel = image[row*width+col]; - - BYTE blue = (BYTE) ((pixel & 0x000000ff) >> 0); - BYTE green = (BYTE) ((pixel & 0x0000ff00) >> 8); - BYTE red = (BYTE) ((pixel & 0x00ff0000) >> 16); - - fwrite(&blue, 1, 1, f); - fwrite(&green, 1, 1, f); - fwrite(&red, 1, 1, f); - } - } - - status = BMP_OK; - - fclose(f); - return status; -} - diff --git a/Stars45/Bmp.h b/Stars45/Bmp.h deleted file mode 100644 index 7f914b9..0000000 --- a/Stars45/Bmp.h +++ /dev/null @@ -1,77 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - BMP image file loader -*/ - -#ifndef BMP_H -#define BMP_H - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -enum { BMP_OK, BMP_NOMEM, BMP_INVALID, BMP_NOFILE }; - -struct BmpFileHeader -{ - WORD type; - DWORD size; - WORD rsvd1; - WORD rsvd2; - DWORD offset; -}; - -struct BmpInfoHeader -{ - DWORD hdr_size; - DWORD width; - DWORD height; - WORD planes; - WORD bit_count; - DWORD compression; - DWORD img_size; - DWORD x_pixels_per_meter; - DWORD y_pixels_per_meter; - DWORD colors_used; - DWORD colors_important; -}; - -const int BMP_FILE_HDR_SIZE = 14; -const int BMP_INFO_HDR_SIZE = 40; - -// +--------------------------------------------------------------------+ - -struct BmpImage -{ - static const char* TYPENAME() { return "BmpImage"; } - - BmpImage(short w, short h, unsigned long* hibits); - - BmpImage(); - ~BmpImage(); - - int Load(char *filename); - int Save(char *filename); - - int LoadBuffer(unsigned char* buf, int len); - - BmpFileHeader file_hdr; - BmpInfoHeader info_hdr; - DWORD palette[256]; - DWORD* image; - WORD width; - WORD height; -}; - -// +--------------------------------------------------------------------+ - - -#endif // BMP_H diff --git a/Stars45/Bolt.cpp b/Stars45/Bolt.cpp deleted file mode 100644 index 7483678..0000000 --- a/Stars45/Bolt.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - 3D Bolt (Polygon) Object -*/ - -#include "Bolt.h" -#include "Bitmap.h" -#include "Camera.h" -#include "Video.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -Bolt::Bolt(double len, double wid, Bitmap* tex, int share) - : vset(4), poly(0), texture(tex), length(len), width(wid), shade(1.0), - vpn(0, 1, 0), shared(share) -{ - trans = true; - - loc = Vec3(0.0f, 0.0f, 1000.0f); - - vset.nverts = 4; - - vset.loc[0] = Point( width, 0, 1000); - vset.loc[1] = Point( width, -length, 1000); - vset.loc[2] = Point(-width, -length, 1000); - vset.loc[3] = Point(-width, 0, 1000); - - vset.tu[0] = 0.0f; - vset.tv[0] = 0.0f; - vset.tu[1] = 1.0f; - vset.tv[1] = 0.0f; - vset.tu[2] = 1.0f; - vset.tv[2] = 1.0f; - vset.tu[3] = 0.0f; - vset.tv[3] = 1.0f; - - Plane plane(vset.loc[0], vset.loc[1], vset.loc[2]); - - for (int i = 0; i < 4; i++) { - vset.nrm[i] = plane.normal; - } - - mtl.Ka = Color::White; - mtl.Kd = Color::White; - mtl.Ks = Color::Black; - mtl.Ke = Color::White; - mtl.tex_diffuse = texture; - mtl.tex_emissive = texture; - mtl.blend = Video::BLEND_ADDITIVE; - - poly.nverts = 4; - poly.vertex_set = &vset; - poly.material = &mtl; - poly.verts[0] = 0; - poly.verts[1] = 1; - poly.verts[2] = 2; - poly.verts[3] = 3; - - radius = (float) ((length>width) ? (length) : (width*2)); - - if (texture) { - strncpy_s(name, texture->GetFilename(), 31); - name[31] = 0; - } -} - -// +--------------------------------------------------------------------+ - -Bolt::~Bolt() -{ -} - -// +--------------------------------------------------------------------+ - -void -Bolt::Render(Video* video, DWORD flags) -{ - if ((flags & RENDER_ADDITIVE) == 0) - return; - - if (visible && !hidden && video && life) { - const Camera* camera = video->GetCamera(); - - Point head = loc; - Point tail = origin; - Point vtail = tail - head; - Point vcam = camera->Pos() - loc; - Point vtmp = vcam.cross(vtail); - vtmp.Normalize(); - Point vlat = vtmp * -width; - Vec3 vnrm = camera->vpn() * -1; - - vset.loc[0] = head + vlat; - vset.loc[1] = tail + vlat; - vset.loc[2] = tail - vlat; - vset.loc[3] = head - vlat; - - vset.nrm[0] = vnrm; - vset.nrm[1] = vnrm; - vset.nrm[2] = vnrm; - vset.nrm[3] = vnrm; - - ColorValue white((float) shade, (float) shade, (float) shade); - mtl.Ka = white; - mtl.Kd = white; - mtl.Ks = Color::Black; - mtl.Ke = white; - - video->DrawPolys(1, &poly); - } -} - -// +--------------------------------------------------------------------+ - -void -Bolt::Update() -{ -} - -// +--------------------------------------------------------------------+ - -void -Bolt::TranslateBy(const Point& ref) -{ - loc = loc - ref; - origin = origin - ref; -} - -// +--------------------------------------------------------------------+ - -void -Bolt::SetOrientation(const Matrix& o) -{ - vpn = Point(o(2,0), o(2,1), o(2,2)); - origin = loc + (vpn * -length); -} - -void -Bolt::SetDirection(const Point& v) -{ - vpn = v; - origin = loc + (vpn * -length); -} - -void -Bolt::SetEndPoints(const Point& from, const Point& to) -{ - loc = to; - origin = from; - vpn = to - from; - length = vpn.Normalize(); - radius = (float) length; -} - -void -Bolt::SetTextureOffset(double from, double to) -{ - vset.tu[0] = (float) from; - vset.tu[1] = (float) to; - vset.tu[2] = (float) to; - vset.tu[3] = (float) from; -} - - diff --git a/Stars45/Bolt.h b/Stars45/Bolt.h deleted file mode 100644 index 07418ac..0000000 --- a/Stars45/Bolt.h +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - 3D Bolt (Polygon) Object -*/ - -#ifndef Bolt_h -#define Bolt_h - -#include "Graphic.h" -#include "Polygon.h" - -// +--------------------------------------------------------------------+ - -class Bolt : public Graphic -{ -public: - static const char* TYPENAME() { return "Bolt"; } - - Bolt(double len=16, double wid=1, Bitmap* tex=0, int share=0); - virtual ~Bolt(); - - // operations - virtual void Render(Video* video, DWORD flags); - virtual void Update(); - - // accessors / mutators - virtual void SetOrientation(const Matrix& o); - void SetDirection(const Point& v); - void SetEndPoints(const Point& from, const Point& to); - void SetTextureOffset(double from, double to); - - virtual void TranslateBy(const Point& ref); - - double Shade() const { return shade; } - void SetShade(double s) { shade = s; } - virtual bool IsBolt() const { return true; } - -protected: - double length; - double width; - double shade; - - Poly poly; - Material mtl; - VertexSet vset; - Bitmap* texture; - int shared; - - Point vpn; - Point origin; -}; - -// +--------------------------------------------------------------------+ - -#endif // Bolt_h - diff --git a/Stars45/Button.cpp b/Stars45/Button.cpp deleted file mode 100644 index 72867e8..0000000 --- a/Stars45/Button.cpp +++ /dev/null @@ -1,685 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Button class -*/ - -#include "Button.h" -#include "Video.h" -#include "Bitmap.h" -#include "Font.h" -#include "Sound.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -static Sound* button_sound = 0; -static Sound* click_sound = 0; -static Sound* swish_sound = 0; -static Sound* chirp_sound = 0; -static Sound* accept_sound = 0; -static Sound* reject_sound = 0; -static Sound* confirm_sound = 0; -static Sound* list_select_sound = 0; -static Sound* list_scroll_sound = 0; -static Sound* list_drop_sound = 0; -static Sound* combo_open_sound = 0; -static Sound* combo_close_sound = 0; -static Sound* combo_hilite_sound = 0; -static Sound* combo_select_sound = 0; -static Sound* menu_open_sound = 0; -static Sound* menu_close_sound = 0; -static Sound* menu_select_sound = 0; -static Sound* menu_hilite_sound = 0; - -static int gui_volume = 0; - -// +--------------------------------------------------------------------+ - -Button::Button(Screen* s, int ax, int ay, int aw, int ah, DWORD aid) - : ActiveWindow(s, ax, ay, aw, ah, aid) -{ - animated = true; - bevel_width = 5; - border = false; - button_state = 0; - drop_shadow = false; - sticky = false; - picture_loc = 1; - captured = false; - pre_state = 0; - text_align = DT_CENTER; - - standard_image = 0; - activated_image = 0; - transition_image = 0; - - char buf[32]; - sprintf_s(buf, "Button %d", id); //-V576 - desc = buf; -} - -Button::Button(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid) - : ActiveWindow(p->GetScreen(), ax, ay, aw, ah, aid, 0, p) -{ - animated = true; - bevel_width = 5; - border = false; - button_state = 0; - drop_shadow = false; - sticky = false; - picture_loc = 1; - captured = false; - pre_state = 0; - text_align = DT_CENTER; - - standard_image = 0; - activated_image = 0; - transition_image = 0; - - char buf[32]; - sprintf_s(buf, "Button %d", id); //-V576 - desc = buf; -} - -// +--------------------------------------------------------------------+ - -Button::~Button() -{ -} - -// +--------------------------------------------------------------------+ - -static void LoadInterfaceSound(DataLoader* loader, const char* wave, Sound*& s) -{ - loader->LoadSound(wave, s, 0, true); // optional sound effect - - if (s) - s->SetFlags(s->GetFlags() | Sound::INTERFACE); -} - -void -Button::Initialize() -{ - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Sounds/"); - - LoadInterfaceSound(loader, "button.wav", button_sound); - LoadInterfaceSound(loader, "click.wav", click_sound); - LoadInterfaceSound(loader, "swish.wav", swish_sound); - LoadInterfaceSound(loader, "chirp.wav", chirp_sound); - LoadInterfaceSound(loader, "accept.wav", accept_sound); - LoadInterfaceSound(loader, "reject.wav", reject_sound); - LoadInterfaceSound(loader, "confirm.wav", confirm_sound); - LoadInterfaceSound(loader, "list_select.wav", list_select_sound); - LoadInterfaceSound(loader, "list_scroll.wav", list_scroll_sound); - LoadInterfaceSound(loader, "list_drop.wav", list_drop_sound); - LoadInterfaceSound(loader, "combo_open.wav", combo_open_sound); - LoadInterfaceSound(loader, "combo_close.wav", combo_close_sound); - LoadInterfaceSound(loader, "combo_hilite.wav", combo_hilite_sound); - LoadInterfaceSound(loader, "combo_select.wav", combo_select_sound); - LoadInterfaceSound(loader, "menu_open.wav", menu_open_sound); - LoadInterfaceSound(loader, "menu_close.wav", menu_close_sound); - LoadInterfaceSound(loader, "menu_select.wav", menu_select_sound); - LoadInterfaceSound(loader, "menu_hilite.wav", menu_hilite_sound); - - loader->SetDataPath(0); -} - -// +--------------------------------------------------------------------+ - -void -Button::Close() -{ - delete button_sound; - delete click_sound; - delete swish_sound; - delete chirp_sound; - delete accept_sound; - delete reject_sound; - delete confirm_sound; - delete list_select_sound; - delete list_scroll_sound; - delete list_drop_sound; - delete combo_open_sound; - delete combo_close_sound; - delete combo_hilite_sound; - delete combo_select_sound; - delete menu_open_sound; - delete menu_close_sound; - delete menu_select_sound; - delete menu_hilite_sound; -} - -// +--------------------------------------------------------------------+ - -void -Button::Draw() -{ - if (!IsShown()) return; - - int x = 0; - int y = 0; - int w = rect.w; - int h = rect.h; - int img_w = picture.Width(); - int img_h = picture.Height(); - - float old_alpha = alpha; - - if (!enabled) - SetAlpha(0.35); - - Rect btn_rect(x,y,w,h); - - if (!transparent) { - if (standard_image) { - if (!enabled) { - texture = standard_image; - } - - else { - switch (button_state) { - case -1: - texture = activated_image; - break; - - default: - case 0: - texture = standard_image; - break; - - case 1: - if (sticky) - texture = activated_image; - else - texture = transition_image; - break; - - case 2: - texture = transition_image; - break; - } - } - - if (!texture) - texture = standard_image; - - DrawTextureGrid(); - } - - else { - FillRect(0, 0, w, h, ShadeColor(back_color, 1.0)); - DrawStyleRect(0, 0, w, h, style); - } - } - - // draw the picture (if any) - if (picture.Width()) { - Rect irect = CalcPictureRect(); - DrawImage(&picture, irect); - } - - // draw text here: - if (font && text.length()) { - Rect label_rect = CalcLabelRect(img_w,img_h); - int vert_space = label_rect.h; - int horz_space = label_rect.w; - int align = DT_WORDBREAK | text_align; - - DrawText(text.data(), 0, label_rect, DT_CALCRECT | align); - vert_space = (vert_space - label_rect.h)/2; - - label_rect.w = horz_space; - - if (vert_space > 0) - label_rect.y += vert_space; - - if (animated && button_state > 0) { - label_rect.x += button_state; - label_rect.y += button_state; - } - - if (drop_shadow) { - label_rect.x++; - label_rect.y++; - - font->SetColor(back_color); - DrawText(text.data(), text.length(), label_rect, align); - - label_rect.x--; - label_rect.y--; - } - - font->SetColor(fore_color); - DrawText(text.data(), text.length(), label_rect, align); - } - - if (!enabled) - SetAlpha(old_alpha); -} - -Rect Button::CalcLabelRect(int img_w, int img_h) -{ - // fit the text in the bevel: - Rect label_rect; - label_rect.x = 0; - label_rect.y = 0; - label_rect.w = rect.w; - label_rect.h = rect.h; - - if (text_align == DT_LEFT) - label_rect.Deflate(bevel_width + 8, bevel_width + 1); - else - label_rect.Deflate(bevel_width + 1, bevel_width + 1); - - // and around the picture, if any: - if (img_h != 0) - { - switch (picture_loc) - { - default: - case 0: // the four corner positions - case 2: // and the center position - case 4: // don't affect the text position - case 6: - case 8: - break; - - case 1: // north - label_rect.y += img_h; - label_rect.h -= img_h; - break; - - case 3: // west - label_rect.x += img_w; - label_rect.w -= img_w; - break; - - case 5: // east - label_rect.w -= img_w; - break; - - case 7: // south - label_rect.h -= img_h; - break; - } - } - - return label_rect; -} - -// +--------------------------------------------------------------------+ - -Rect -Button::CalcPictureRect() -{ - int w = rect.w; - int h = rect.h; - int img_w = picture.Width(); - int img_h = picture.Height(); - - if (img_h > h) img_h = h-2; - if (img_w > w) img_w = w-2; - - int img_x_offset = bevel_width; - int img_y_offset = bevel_width; - - switch (picture_loc) - { - default: - // TOP ROW: - case 0: break; - - case 1: img_x_offset = (w/2-img_w/2); - break; - - case 2: img_x_offset = w - img_w - bevel_width; - break; - - // MIDDLE ROW: - case 3: img_y_offset = (h/2-img_h/2); - break; - case 4: img_x_offset = (w/2-img_w/2); - img_y_offset = (h/2-img_h/2); - break; - case 5: img_x_offset = w - img_w - bevel_width; - img_y_offset = (h/2-img_h/2); - break; - - // BOTTOM ROW: - case 6: - img_y_offset = h - img_h - bevel_width; - break; - case 7: img_x_offset = (w/2-img_w/2); - img_y_offset = h - img_h - bevel_width; - break; - case 8: img_x_offset = w - img_w - bevel_width; - img_y_offset = h - img_h - bevel_width; - break; - } - - Rect img_rect; - img_rect.x = img_x_offset; - img_rect.y = img_y_offset; - - if (animated && button_state > 0) { - img_rect.x += button_state; - img_rect.y += button_state; - } - - img_rect.w = img_w; - img_rect.h = img_h; - - return img_rect; -} - -// +--------------------------------------------------------------------+ - -void -Button::DrawImage(Bitmap* bmp, const Rect& irect) -{ - if (bmp) { - DrawBitmap(irect.x, - irect.y, - irect.x + irect.w, - irect.y + irect.h, - bmp, - Video::BLEND_ALPHA); - } -} - -// +--------------------------------------------------------------------+ - -int Button::OnMouseMove(int x, int y) -{ - bool dirty = false; - - if (captured) - { - ActiveWindow* test = GetCapture(); - - if (test != this) - { - captured = false; - button_state = pre_state; - dirty = true; - } - - else if (sticky) - { - if (button_state == 2) - { - if (!rect.Contains(x,y)) - { - button_state = pre_state; - dirty = true; - } - } - else - { - if (rect.Contains(x,y)) - { - button_state = 2; - dirty = true; - } - } - } - else - { - if (button_state == 1) - { - if (!rect.Contains(x,y)) - { - button_state = 0; - dirty = true; - } - } - else - { - if (rect.Contains(x,y)) - { - button_state = 1; - dirty = true; - } - } - } - } - - return ActiveWindow::OnMouseMove(x,y); -} - -int Button::OnLButtonDown(int x, int y) -{ - if (!captured) - captured = SetCapture(); - - if (sticky) - button_state = 2; - else - button_state = 1; - - return ActiveWindow::OnLButtonDown(x,y); -} - -int Button::OnLButtonUp(int x, int y) -{ - if (captured) { - ReleaseCapture(); - captured = false; - } - - button_state = pre_state; - return ActiveWindow::OnLButtonUp(x,y); -} - -void Button::SetVolume(int vol) -{ - if (vol >= -10000 && vol <= 0) - gui_volume = vol; -} - -void Button::PlaySound(int n) -{ - Sound* sound = 0; - - switch (n) { - default: - case SND_BUTTON: if (button_sound) sound = button_sound->Duplicate(); break; - case SND_CLICK: if (click_sound) sound = click_sound->Duplicate(); break; - case SND_SWISH: if (swish_sound) sound = swish_sound->Duplicate(); break; - case SND_CHIRP: if (chirp_sound) sound = chirp_sound->Duplicate(); break; - case SND_ACCEPT: if (accept_sound) sound = accept_sound->Duplicate(); break; - case SND_REJECT: if (reject_sound) sound = reject_sound->Duplicate(); break; - case SND_CONFIRM: if (confirm_sound) sound = confirm_sound->Duplicate(); break; - case SND_LIST_SELECT: if (list_select_sound) sound = list_select_sound->Duplicate(); break; - case SND_LIST_SCROLL: if (list_scroll_sound) sound = list_scroll_sound->Duplicate(); break; - case SND_LIST_DROP: if (list_drop_sound) sound = list_drop_sound->Duplicate(); break; - case SND_COMBO_OPEN: if (combo_open_sound) sound = combo_open_sound->Duplicate(); break; - case SND_COMBO_CLOSE: if (combo_close_sound) sound = combo_close_sound->Duplicate(); break; - case SND_COMBO_HILITE: if (combo_hilite_sound) sound = combo_hilite_sound->Duplicate(); break; - case SND_COMBO_SELECT: if (combo_select_sound) sound = combo_select_sound->Duplicate(); break; - case SND_MENU_OPEN: if (menu_open_sound) sound = menu_open_sound->Duplicate(); break; - case SND_MENU_CLOSE: if (menu_close_sound) sound = menu_close_sound->Duplicate(); break; - case SND_MENU_SELECT: if (menu_select_sound) sound = menu_select_sound->Duplicate(); break; - case SND_MENU_HILITE: if (menu_hilite_sound) sound = menu_hilite_sound->Duplicate(); break; - } - - if (sound) { - sound->SetVolume(gui_volume); - sound->Play(); - } -} - -int Button::OnClick() -{ - PlaySound(SND_BUTTON); - - if (sticky) - button_state = !pre_state; - - pre_state = button_state; - - return ActiveWindow::OnClick(); -} - -int Button::OnMouseEnter(int mx, int my) -{ - if (button_state >= 0) - pre_state = button_state; - - if (button_state == 0) - button_state = -1; - - if (IsEnabled() && IsShown()) - PlaySound(SND_SWISH); - - return ActiveWindow::OnMouseEnter(mx, my); -} - -int Button::OnMouseExit(int mx, int my) -{ - if (button_state == -1) - button_state = pre_state; - - return ActiveWindow::OnMouseExit(mx, my); -} - -// +--------------------------------------------------------------------+ - -void Button::SetStandardImage(Bitmap* img) -{ - standard_image = img; - texture = standard_image; -} - -void Button::SetActivatedImage(Bitmap* img) -{ - activated_image = img; -} - -void Button::SetTransitionImage(Bitmap* img) -{ - transition_image = img; -} - -// +--------------------------------------------------------------------+ - -short Button::GetBevelWidth() -{ - return bevel_width; -} - -void Button::SetBevelWidth(short nNewValue) -{ - if (nNewValue < 0) nNewValue = 0; - if (nNewValue > rect.w/2) nNewValue = rect.w/2; - bevel_width = nNewValue; -} - -bool Button::GetBorder() -{ - return border; -} - -void Button::SetBorder(bool bNewValue) -{ - border = bNewValue; -} - -Color Button::GetBorderColor() -{ - return border_color; -} - -void Button::SetBorderColor(Color newValue) -{ - border_color = newValue; -} - -Color Button::GetActiveColor() -{ - return active_color; -} - -void Button::SetActiveColor(Color newValue) -{ - active_color = newValue; -} - -bool Button::GetAnimated() -{ - return animated; -} - -void Button::SetAnimated(bool bNewValue) -{ - animated = bNewValue; -} - -bool Button::GetDropShadow() -{ - return drop_shadow; -} - -void Button::SetDropShadow(bool bNewValue) -{ - drop_shadow = bNewValue; -} - -// +--------------------------------------------------------------------+ - -short Button::GetButtonState() -{ - return button_state; -} - -void Button::SetButtonState(short n) -{ - if (button_state != n && n >= -2 && n <= 2) { - button_state = n; - pre_state = n; - } -} - -void Button::GetPicture(Bitmap& img) -{ - img.CopyBitmap(picture); -} - -void Button::SetPicture(const Bitmap& img) -{ - picture.CopyBitmap(img); - picture.AutoMask(); -} - -short Button::GetPictureLocation() -{ - return picture_loc; -} - -void Button::SetPictureLocation(short n) -{ - if (picture_loc != n && n >= 0 && n <= 8) { - picture_loc = n; - } -} - -bool Button::GetSticky() -{ - return sticky; -} - -void Button::SetSticky(bool n) -{ - if (sticky != n) - sticky = n; -} - diff --git a/Stars45/Button.h b/Stars45/Button.h deleted file mode 100644 index 4fcaa55..0000000 --- a/Stars45/Button.h +++ /dev/null @@ -1,120 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Button class -*/ - -#ifndef Button_h -#define Button_h - -#include "Types.h" -#include "ActiveWindow.h" -#include "Bitmap.h" - -// +--------------------------------------------------------------------+ - -class Button : public ActiveWindow -{ -public: - enum SOUNDS { - SND_BUTTON, - SND_CLICK, - SND_SWISH, - SND_CHIRP, - SND_ACCEPT, - SND_REJECT, - SND_CONFIRM, - SND_LIST_SELECT, - SND_LIST_SCROLL, - SND_LIST_DROP, - SND_COMBO_OPEN, - SND_COMBO_CLOSE, - SND_COMBO_HILITE, - SND_COMBO_SELECT, - SND_MENU_OPEN, - SND_MENU_CLOSE, - SND_MENU_SELECT, - SND_MENU_HILITE - }; - - Button(Screen* s, int ax, int ay, int aw, int ah, DWORD id=0); - Button(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD id=0); - virtual ~Button(); - - static void Initialize(); - static void Close(); - static void PlaySound(int n=0); - static void SetVolume(int vol); - - // Operations: - virtual void Draw(); // refresh backing store - - // Event Target Interface: - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnClick(); - virtual int OnMouseEnter(int x, int y); - virtual int OnMouseExit(int x, int y); - - // Property accessors: - Color GetActiveColor(); - void SetActiveColor(Color c); - bool GetAnimated(); - void SetAnimated(bool bNewValue); - short GetBevelWidth(); - void SetBevelWidth(short nNewValue); - bool GetBorder(); - void SetBorder(bool bNewValue); - Color GetBorderColor(); - void SetBorderColor(Color c); - short GetButtonState(); - void SetButtonState(short nNewValue); - bool GetDropShadow(); - void SetDropShadow(bool bNewValue); - void GetPicture(Bitmap& img); - void SetPicture(const Bitmap& img); - short GetPictureLocation(); - void SetPictureLocation(short nNewValue); - bool GetSticky(); - void SetSticky(bool bNewValue); - - void SetStandardImage(Bitmap* img); - void SetActivatedImage(Bitmap* img); - void SetTransitionImage(Bitmap* img); - -protected: - Rect CalcLabelRect(int img_w, int img_h); - Rect CalcPictureRect(); - void DrawImage(Bitmap* bmp, const Rect& irect); - - bool animated; - bool drop_shadow; - bool sticky; - bool border; - - Color active_color; - Color border_color; - - bool captured; - int pre_state; - short bevel_width; - short button_state; - - short picture_loc; - Bitmap picture; - - Bitmap* standard_image; // state = 0 - Bitmap* activated_image; // state = 1 (if sticky) - Bitmap* transition_image; // state = 2 (if sticky) -}; - -#endif // Button_h - diff --git a/Stars45/CMakeLists.txt b/Stars45/CMakeLists.txt deleted file mode 100644 index 4ff9b4a..0000000 --- a/Stars45/CMakeLists.txt +++ /dev/null @@ -1,348 +0,0 @@ -project(Stars45) -include(GitDescribe) -include(GitToResource) -add_executable( - Stars45 WIN32 - ActiveWindow.cpp - Archive.cpp - Asteroid.cpp - AudDlg.cpp - AudioConfig.cpp - AwardDlg.cpp - AwardShowDlg.cpp - Bitmap.cpp - Bmp.cpp - Bolt.cpp - Button.cpp - Callsign.cpp - Camera.cpp - CameraDirector.cpp - CameraView.cpp - Campaign.cpp - CampaignMissionFighter.cpp - CampaignMissionRequest.cpp - CampaignMissionStarship.cpp - CampaignPlanAssignment.cpp - CampaignPlanEvent.cpp - CampaignPlanMission.cpp - CampaignPlanMovement.cpp - CampaignPlanStrategic.cpp - CampaignSaveGame.cpp - CampaignSituationReport.cpp - CarrierAI.cpp - Clock.cpp - CmdDlg.cpp - CmdForceDlg.cpp - CmdIntelDlg.cpp - CmdMissionsDlg.cpp - CmdMsgDlg.cpp - CmdOrdersDlg.cpp - CmdTheaterDlg.cpp - CmdTitleDlg.cpp - CmpCompleteDlg.cpp - CmpFileDlg.cpp - CmpLoadDlg.cpp - CmpSceneDlg.cpp - CmpSelectDlg.cpp - CmpnScreen.cpp - Color.cpp - CombatAction.cpp - CombatAssignment.cpp - CombatEvent.cpp - CombatGroup.cpp - CombatRoster.cpp - CombatUnit.cpp - CombatZone.cpp - Combatant.cpp - ComboBox.cpp - ComboList.cpp - Component.cpp - Computer.cpp - ConfirmDlg.cpp - Contact.cpp - ContentBundle.cpp - CtlDlg.cpp - D3DXImage.cpp - DataLoader.cpp - DebriefDlg.cpp - Debris.cpp - DetailSet.cpp - DisplayView.cpp - Drive.cpp - DriveSprite.cpp - Drone.cpp - DropShipAI.cpp - EditBox.cpp - Element.cpp - Encrypt.cpp - EngDlg.cpp - EventDispatch.cpp - ExceptionHandler.cpp - ExitDlg.cpp - Explosion.cpp - FadeView.cpp - Farcaster.cpp - FighterAI.cpp - FighterTacticalAI.cpp - FirstTimeDlg.cpp - Fix.cpp - FlightComp.cpp - FlightDeck.cpp - FlightPlanner.cpp - FltDlg.cpp - Font.cpp - FontMgr.cpp - FormDef.cpp - FormWindow.cpp - FormatUtil.cpp - Galaxy.cpp - Game.cpp - GameScreen.cpp - GameWinDX9.cpp - Geometry.cpp - Graphic.cpp - Grid.cpp - GroundAI.cpp - HUDSounds.cpp - HUDView.cpp - Hangar.cpp - HardPoint.cpp - Hoop.cpp - ImageBox.cpp - ImgView.cpp - Instruction.cpp - Intel.cpp - JoyDlg.cpp - Joystick.cpp - KeyDlg.cpp - KeyMap.cpp - Keyboard.cpp - LandingGear.cpp - Layout.cpp - Light.cpp - ListBox.cpp - LoadDlg.cpp - LoadScreen.cpp - Locale_ss.cpp - MCIWave.cpp - MachineInfo.cpp - Main.cpp - MapView.cpp - Menu.cpp - MenuDlg.cpp - MenuScreen.cpp - MenuView.cpp - Mfd.cpp - Mission.cpp - MissionEvent.cpp - MissionTemplate.cpp - ModConfig.cpp - ModDlg.cpp - ModInfo.cpp - ModInfoDlg.cpp - Mouse.cpp - MouseController.cpp - MsnDlg.cpp - MsnEditDlg.cpp - MsnEditNavDlg.cpp - MsnElemDlg.cpp - MsnEventDlg.cpp - MsnNavDlg.cpp - MsnObjDlg.cpp - MsnPkgDlg.cpp - MsnSelectDlg.cpp - MsnWepDlg.cpp - MultiController.cpp - MusicDirector.cpp - MusicTrack.cpp - NPClientWraps.cpp - NavAI.cpp - NavDlg.cpp - NavLight.cpp - NavSystem.cpp - NetAddrDlg.cpp - NetAdminChat.cpp - NetAdminServer.cpp - NetAuth.cpp - NetBrokerClient.cpp - NetChat.cpp - NetClientConfig.cpp - NetClientDlg.cpp - NetData.cpp - NetFileServlet.cpp - NetGame.cpp - NetGameClient.cpp - NetGameServer.cpp - NetLobby.cpp - NetLobbyClient.cpp - NetLobbyDlg.cpp - NetLobbyServer.cpp - NetPacket.cpp - NetPassDlg.cpp - NetPlayer.cpp - NetServerConfig.cpp - NetServerDlg.cpp - NetUnitDlg.cpp - NetUser.cpp - NetUtil.cpp - OptDlg.cpp - PCX.CPP - Panic.cpp - ParseUtil.cpp - Parser.cpp - Particles.cpp - Physical.cpp - PlanScreen.cpp - Player.cpp - PlayerDlg.cpp - PngImage.cpp - Polygon.cpp - Power.cpp - Projector.cpp - QuantumDrive.cpp - QuantumFlash.cpp - QuantumView.cpp - QuitView.cpp - RLoc.cpp - RadioHandler.cpp - RadioMessage.cpp - RadioTraffic.cpp - RadioView.cpp - RadioVox.cpp - Random.cpp - Reader.cpp - Res.cpp - RichTextBox.cpp - Scene.cpp - Screen.cpp - ScrollWindow.cpp - SeekerAI.cpp - Sensor.cpp - Sha1.cpp - Shadow.cpp - Shield.cpp - ShieldRep.cpp - Ship.cpp - ShipAI.cpp - ShipCtrl.cpp - ShipDesign.cpp - ShipKiller.cpp - ShipSolid.cpp - Shot.cpp - Sim.cpp - SimEvent.cpp - SimObject.cpp - Skin.cpp - Sky.cpp - Slider.cpp - Solid.cpp - Sound.cpp - SoundCard.cpp - SoundD3D.cpp - Sprite.cpp - StarServer.cpp - StarSystem.cpp - Starshatter.cpp - StarshipAI.cpp - StarshipTacticalAI.cpp - SteerAI.cpp - System.cpp - SystemDesign.cpp - TacRefDlg.cpp - TacticalAI.cpp - TacticalView.cpp - Term.cpp - Terrain.cpp - TerrainApron.cpp - TerrainClouds.cpp - TerrainHaze.cpp - TerrainPatch.cpp - TerrainRegion.cpp - TexCubeDX9.cpp - TexDX9.cpp - Thruster.cpp - Token.cpp - TrackIR.cpp - Trail.cpp - VidDlg.cpp - Video.cpp - VideoDX9.cpp - VideoDX9Enum.cpp - VideoDX9VertexBuffer.cpp - VideoFactory.cpp - VideoSettings.cpp - Water.cpp - Weapon.cpp - WeaponDesign.cpp - WeaponGroup.cpp - Weather.cpp - WebBrowser.cpp - WepView.cpp - Window.cpp - WndProc.cpp - ) -target_include_directories( - Stars45 - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} - ) -target_link_libraries( - Stars45 - PUBLIC FoundationEx - PUBLIC NetEx - PUBLIC Zlib::zlib - PUBLIC Vorbis::vorbis - PUBLIC Vorbis::vorbisfile - PUBLIC Ogg::ogg - PUBLIC Png::png - PUBLIC Opcode - ) -target_compile_definitions( - Stars45 - PRIVATE _ALLOW_KEYWORD_MACROS - ) -git_describe(VERSION) -git_to_resource(RC_VERSION ${VERSION}) -configure_file(Stars.rc.conf ${CMAKE_CURRENT_BINARY_DIR}/Stars.rc @ONLY) -configure_file(VersionInfo.cpp.conf ${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.cpp @ONLY) -target_sources( - Stars45 - PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/Stars.rc - PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.cpp - ) -set_target_properties(Stars45 PROPERTIES OUTPUT_NAME Starshatter) -if(MSVC) - target_include_directories( - Stars45 - PUBLIC $ENV{DXSDK_DIR}/Include - PUBLIC ${WINDOWSSDK_PATH}/um - PUBLIC ${WINDOWSSDK_PATH}/shared - ) - target_link_libraries( - Stars45 - PUBLIC ${WINDOWSSDK_LIBPATH}/um/x86/Ws2_32.lib - PUBLIC ${WINDOWSSDK_LIBPATH}/um/x86/Vfw32.lib - PUBLIC ${WINDOWSSDK_LIBPATH}/um/x86/wsock32.lib - PUBLIC ${WINDOWSSDK_LIBPATH}/um/x86/winmm.lib - PUBLIC ${WINDOWSSDK_LIBPATH}/um/x86/version.lib - PUBLIC $ENV{DXSDK_DIR}/Lib/x86/dinput8.lib - PUBLIC $ENV{DXSDK_DIR}/Lib/x86/dsound.lib - PUBLIC $ENV{DXSDK_DIR}/Lib/x86/d3d9.lib - PUBLIC $ENV{DXSDK_DIR}/Lib/x86/d3dx9.lib - PUBLIC $ENV{DXSDK_DIR}/Lib/x86/dxguid.lib - ) -else() - target_link_libraries( - Stars45 - PUBLIC -l:libws2_32.a - PUBLIC -l:libvfw32.a - PUBLIC -l:libwsock32.a - PUBLIC -l:libwinmm.a - PUBLIC -l:libversion.a - PUBLIC -l:libdinput8.a - PUBLIC -l:libdsound.a - PUBLIC -l:libd3d9.a - PUBLIC -l:libd3dx9.a - PUBLIC -l:libdxguid.a - ) -endif() -install(TARGETS Stars45 RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}) diff --git a/Stars45/Callsign.cpp b/Stars45/Callsign.cpp deleted file mode 100644 index 7cb7499..0000000 --- a/Stars45/Callsign.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Package Callsign catalog class -*/ - -#include "Callsign.h" - -// +----------------------------------------------------------------------+ - -static int callsign_index = -1; - -static char civilian_catalog[32][16] = { - "Aleph", "Vehan", "Galvin", "Caleb", - "Mercury", "Lancet", "Hera", "Zeus", - "Odin", "Thor", "Nereus", "Klono", - "Athena", "Helios", "Leto", "Nivas", - - "Selene", "Proteus", "Triton", "Thetis", - "Aurora", "Ceres", "Rana", "Doradus", - "Perseus", "Corina", "Cygnus", "Lago", - "Andil", "Galen", "Temas", "Dalan" -}; - -static char alliance_catalog[32][16] = { - "Alpha", "Bravo", "Delta", "Echo", - "Ranger", "Magic", "Falcon", "Omega", - "Vulcan", "Hammer", "Nomad", "Dragon", - "Sierra", "Tango", "Victor", "Zulu", - - "Sentry", "Wolf", "Zeta", "Jackal", - "Merlin", "Eagle", "Blade", "Tiger", - "Raptor", "Ares", "Condor", "Rogue", - "Hornet", "Gold", "Mustang", "Voodoo" -}; - -static char hegemony_catalog[32][16] = { - "Nagal", "Nalak", "Olkar", "Kalar", - "Narom", "Tranor", "Orrin", "Orlak", - "Nardik", "Sorrin", "Amnar", "Kizek", - "Orten", "Ronar", "Molkar", "Ternal", - - "Martak", "Komar", "Malik", "Morgul", - "Kliek", "Torlan", "Arvin", "Artak", - "Ralka", "Sernal", "Roten", "Reza", - "Tinet", "Aliek", "Salar", "Sona" -}; - -static char pirate_catalog[32][16] = { - "Raider", "Skull", "Black", "Blood", - "Roger", "Hook", "Galleon", "Privateer", - "Cutlass", "Sabre", "Pike", "Blackbeard", - "Pistol", "Cortez", "Pirate", "Buccaneer", - - "Raider", "Skull", "Black", "Blood", - "Morgan", "Redbeard", "Cutlass", "Sabre", - "Iron", "Stocks", "Quarter", "Gray", - "Ruby", "Cross", "Pirate", "Raider" -}; - -static char zolon_catalog[32][16] = { - "Cancer", "Krill", "Bluefin", "Scylla", - "Charybdis","Finback", "Mantis", "Skate", - "Sealion", "Lamprey", "Tarpon", "Hammerhead", - "Orca", "Skipjack", "Sculpin", "Thresher", - - "Devilray", "Chinook", "Moray", "Seastar", - "Heron", "Puffin", "Rockeye", "Tiburon", - "Coho", "Stingray", "Mako", "Conger", - "Scad", "Pompano", "Tusk", "Nautilus" -}; - - -// +----------------------------------------------------------------------+ - -const char* -Callsign::GetCallsign(int IFF) -{ - if (callsign_index < 0) - callsign_index = rand()/1000; - - if (callsign_index > 31) - callsign_index = 0; - - switch (IFF) { - case 0: return civilian_catalog[callsign_index++]; - default: - case 1: return alliance_catalog[callsign_index++]; - case 2: return hegemony_catalog[callsign_index++]; - case 3: return pirate_catalog[callsign_index++]; - case 4: return zolon_catalog[callsign_index++]; - } -} diff --git a/Stars45/Callsign.h b/Stars45/Callsign.h deleted file mode 100644 index 0d621ac..0000000 --- a/Stars45/Callsign.h +++ /dev/null @@ -1,28 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Package Callsign catalog class -*/ - -#ifndef Callsign_h -#define Callsign_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class Callsign -{ -public: - static const char* GetCallsign(int IFF=1); -}; - -#endif // Callsign_h - diff --git a/Stars45/Camera.cpp b/Stars45/Camera.cpp deleted file mode 100644 index c8671e1..0000000 --- a/Stars45/Camera.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Camera Class - Position and Point of View -*/ - -#include "Camera.h" - -// +--------------------------------------------------------------------+ - -Camera::Camera(double x, double y, double z) - : pos(x,y,z) -{ } - -Camera::~Camera() -{ } - -// +--------------------------------------------------------------------+ - -void -Camera::MoveTo(double x, double y, double z) -{ - pos.x = x; - pos.y = y; - pos.z = z; -} - -void -Camera::MoveTo(const Point& p) -{ - pos.x = p.x; - pos.y = p.y; - pos.z = p.z; -} - -// +--------------------------------------------------------------------+ - -void -Camera::MoveBy(double dx, double dy, double dz) -{ - pos.x += dx; - pos.y += dz; - pos.z += dy; -} - -void -Camera::MoveBy(const Point& p) -{ - pos.x += p.x; - pos.y += p.y; - pos.z += p.z; -} - -// +--------------------------------------------------------------------+ - -void -Camera::Clone(const Camera& cam) -{ - pos = cam.pos; - orientation = cam.orientation; -} - -// +--------------------------------------------------------------------+ - -void -Camera::LookAt(const Point& target, const Point& eye, const Point& up) -{ - Point zaxis = target - eye; zaxis.Normalize(); - Point xaxis = up.cross(zaxis); xaxis.Normalize(); - Point yaxis = zaxis.cross(xaxis); yaxis.Normalize(); - - orientation(0,0) = xaxis.x; - orientation(0,1) = xaxis.y; - orientation(0,2) = xaxis.z; - - orientation(1,0) = yaxis.x; - orientation(1,1) = yaxis.y; - orientation(1,2) = yaxis.z; - - orientation(2,0) = zaxis.x; - orientation(2,1) = zaxis.y; - orientation(2,2) = zaxis.z; - - pos = eye; -} - -// +--------------------------------------------------------------------+ - -void -Camera::LookAt(const Point& target) -{ - // No navel gazing: - if (target == Pos()) - return; - - Point tgt, tmp = target - Pos(); - - // Rotate into the view orientation: - tgt.x = (tmp * vrt()); - tgt.y = (tmp * vup()); - tgt.z = (tmp * vpn()); - - if (tgt.z == 0) { - Pitch(0.5); - Yaw(0.5); - LookAt(target); - return; - } - - double az = atan(tgt.x/tgt.z); - double el = atan(tgt.y/tgt.z); - - // if target is behind, offset by 180 degrees: - if (tgt.z < 0) - az -= PI; - - Pitch(-el); - Yaw(az); - - // roll to upright position: - double deflection = vrt().y; - while (fabs(deflection) > 0.001) { - double theta = asin(deflection/vrt().length()); - Roll(-theta); - - deflection = vrt().y; - } -} - - -// +--------------------------------------------------------------------+ - -bool -Camera::Padlock(const Point& target, double alimit, double e_lo, double e_hi) -{ - // No navel gazing: - if (target == Pos()) - return false; - - Point tgt, tmp = target - Pos(); - - // Rotate into the view orientation: - tgt.x = (tmp * vrt()); - tgt.y = (tmp * vup()); - tgt.z = (tmp * vpn()); - - if (tgt.z == 0) { - Yaw(0.1); - - tgt.x = (tmp * vrt()); - tgt.y = (tmp * vup()); - tgt.z = (tmp * vpn()); - - if (tgt.z == 0) - return false; - } - - bool locked = true; - double az = atan(tgt.x/tgt.z); - double orig = az; - - // if target is behind, offset by 180 degrees: - if (tgt.z < 0) - az -= PI; - - while (az > PI) az -= 2*PI; - while (az < -PI) az += 2*PI; - - if (alimit > 0) { - if (az < -alimit) { - az = -alimit; - locked = false; - } - else if (az > alimit) { - az = alimit; - locked = false; - } - } - - Yaw(az); - - // Rotate into the new view orientation: - tgt.x = (tmp * vrt()); - tgt.y = (tmp * vup()); - tgt.z = (tmp * vpn()); - - double el = atan(tgt.y/tgt.z); - - if (e_lo > 0 && el < -e_lo) { - el = -e_lo; - locked = false; - } - - else if (e_hi > 0 && el > e_hi) { - el = e_hi; - locked = false; - } - - Pitch(-el); - - return locked; -} - diff --git a/Stars45/Camera.h b/Stars45/Camera.h deleted file mode 100644 index f0988f2..0000000 --- a/Stars45/Camera.h +++ /dev/null @@ -1,60 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Camera class - Position and Point of View -*/ - -#ifndef Camera_h -#define Camera_h - -// +--------------------------------------------------------------------+ - -#include "Types.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Camera -{ -public: - static const char* TYPENAME() { return "Camera"; } - - Camera(double x=0.0, double y=0.0, double z=0.0); - virtual ~Camera(); - - void Aim(double roll, double pitch, double yaw) { orientation.Rotate(roll, pitch, yaw); } - void Roll(double roll) { orientation.Roll(roll); } - void Pitch(double pitch) { orientation.Pitch(pitch); } - void Yaw(double yaw) { orientation.Yaw(yaw); } - - void MoveTo(double x, double y, double z); - void MoveTo(const Point& p); - void MoveBy(double dx, double dy, double dz); - void MoveBy(const Point& p); - - void Clone(const Camera& cam); - void LookAt(const Point& target); - void LookAt(const Point& target, const Point& eye, const Point& up); - bool Padlock(const Point& target, double alimit=-1, double e_lo=-1, double e_hi=-1); - - Point Pos() const { return pos; } - Point vrt() const { return Point(orientation(0,0), orientation(0,1), orientation(0,2)); } - Point vup() const { return Point(orientation(1,0), orientation(1,1), orientation(1,2)); } - Point vpn() const { return Point(orientation(2,0), orientation(2,1), orientation(2,2)); } - - const Matrix& Orientation() const { return orientation; } - -protected: - Point pos; - Matrix orientation; -}; - -#endif // Camera_h - diff --git a/Stars45/CameraDirector.cpp b/Stars45/CameraDirector.cpp deleted file mode 100644 index 7da704c..0000000 --- a/Stars45/CameraDirector.cpp +++ /dev/null @@ -1,1194 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Camera Director singleton manages the main view camera based on the current ship -*/ - -#include "CameraDirector.h" -#include "Ship.h" -#include "FlightDeck.h" -#include "Contact.h" -#include "Sim.h" -#include "StarSystem.h" -#include "Terrain.h" -#include "HUDView.h" -#include "DetailSet.h" -#include "Starshatter.h" - -#include "Game.h" - -// +----------------------------------------------------------------------+ - -CameraDirector* CameraDirector::instance = 0; - -static double range_max_limit = 300e3; - -// +----------------------------------------------------------------------+ - -CameraDirector* -CameraDirector::GetInstance() -{ - if (!instance) - instance = new CameraDirector; - - return instance; -} - -// +----------------------------------------------------------------------+ - -CameraDirector::CameraDirector() - : mode(MODE_COCKPIT), requested_mode(MODE_NONE), old_mode(MODE_NONE), - sim(0), ship(0), region(0), external_ship(0), external_body(0), - virt_az(0), virt_el(0), virt_x(0), virt_y(0), virt_z(0), - azimuth(PI/4), elevation(PI/4), az_rate(0), el_rate(0), range_rate(0), - range(0), range_min(100), range_max(range_max_limit), - base_range(0), transition(0), hud(0) -{ - instance = this; -} - -// +--------------------------------------------------------------------+ - -CameraDirector::~CameraDirector() -{ - if (instance == this) - instance = 0; -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::Reset() -{ - mode = MODE_COCKPIT; - requested_mode = MODE_NONE; - old_mode = MODE_NONE; - - sim = 0; - ship = 0; - region = 0; - external_ship = 0; - external_body = 0; - transition = 0; - hud = 0; -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::SetShip(Ship* s) -{ - sim = Sim::GetSim(); - hud = HUDView::GetInstance(); - - // can't take control of a dead ship: - if (s && (s->Life() == 0 || s->IsDying() || s->IsDead())) - return; - - // leaving the old ship, so make sure it is visible: - if (ship && ship != s) { - ship->ShowRep(); - ship->HideCockpit(); - } - - // taking control of the new ship: - ship = s; - - if (ship) { - Observe(ship); - region = ship->GetRegion(); - - if (sim && ship->GetRegion() != sim->GetActiveRegion()) - sim->ActivateRegion(ship->GetRegion()); - - range = ship->Radius() * 4; - - if (mode == MODE_COCKPIT) - mode = MODE_CHASE; - - SetMode(MODE_COCKPIT); - ExecFrame(0); - } -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::SetMode(int m, double t) -{ - if (requested_mode == m) - return; - - external_point = Point(); - - // save current mode for after transition: - if (m == MODE_DROP && mode != MODE_DROP) - old_mode = mode; - - // if manually leaving drop mode, forget about - // restoring the previous mode when the drop - // expires... - else if (m != MODE_DROP && mode == MODE_DROP) - old_mode = MODE_NONE; - - if (m == MODE_VIRTUAL && ship && !ship->Cockpit()) - return; - - if (mode == m) { - if (mode == MODE_TARGET || mode == MODE_ORBIT) - CycleViewObject(); - - return; - } - - if (m > MODE_NONE && m < MODE_LAST) { - if (m <= MODE_VIRTUAL) { - requested_mode = m; - transition = t; - external_ship = 0; - ClearGroup(); - - // no easy way to do a smooth transition between - // certain modes, so just go immediately: - if ((mode == MODE_TARGET && m == MODE_CHASE) || - (mode == MODE_COCKPIT && m == MODE_VIRTUAL) || - (mode == MODE_VIRTUAL && m == MODE_COCKPIT)) - { - mode = m; - requested_mode = 0; - transition = 0; - } - } - - else if (m == MODE_TRANSLATE || m == MODE_ZOOM) { - requested_mode = m; - transition = t; - base_range = range; - } - - else if (m >= MODE_DOCKING) { - mode = m; - transition = 0; - external_ship = 0; - ClearGroup(); - } - - virt_az = 0; - virt_el = 0; - virt_x = 0; - virt_y = 0; - virt_z = 0; - } -} - -// +--------------------------------------------------------------------+ - -static const char* get_camera_mode_name(int m) -{ - switch (m) { - default: - case CameraDirector::MODE_NONE: return ""; break; - case CameraDirector::MODE_COCKPIT: return ""; break; - case CameraDirector::MODE_CHASE: return "Chase Cam"; break; - case CameraDirector::MODE_TARGET: return "Padlock"; break; - case CameraDirector::MODE_THREAT: return "Threatlock"; break; - case CameraDirector::MODE_VIRTUAL: return "Virtual"; break; - case CameraDirector::MODE_ORBIT: - case CameraDirector::MODE_TRANSLATE: - case CameraDirector::MODE_ZOOM: return "Orbit Cam"; break; - case CameraDirector::MODE_DOCKING: return "Dock Cam"; break; - case CameraDirector::MODE_DROP: return ""; break; - } -} - -const char* -CameraDirector::GetModeName() -{ - int m = GetCameraMode(); - - if (m != CameraDirector::MODE_VIRTUAL) { - return get_camera_mode_name(m); - } - else if (instance) { - if (instance->virt_az > 30*DEGREES && instance->virt_az < 100*DEGREES) - return "RIGHT"; - - else if (instance->virt_az >= 100*DEGREES) - return "RIGHT-AFT"; - - else if (instance->virt_az < -30*DEGREES && instance->virt_az > -100*DEGREES) - return "LEFT"; - - else if (instance->virt_az <= -100*DEGREES) - return "LEFT-AFT"; - - else if (instance->virt_el > 15*DEGREES) - return "UP"; - - else if (instance->virt_el < -15*DEGREES) - return "DOWN"; - - return get_camera_mode_name(m); - } - - return ""; -} - -int -CameraDirector::GetCameraMode() -{ - if (instance) { - int op_mode = instance->mode; - if (instance->requested_mode > instance->mode) - op_mode = instance->requested_mode; - return op_mode; - } - - return 0; -} - -void -CameraDirector::SetCameraMode(int m, double t) -{ - if (instance) - instance->SetMode(m, t); -} - -// +--------------------------------------------------------------------+ - -double -CameraDirector::GetRangeLimit() -{ - return range_max_limit; -} - -void -CameraDirector::SetRangeLimit(double r) -{ - if (r >= 1e3) - range_max_limit = r; -} - -void -CameraDirector::SetRangeLimits(double min, double max) -{ - if (instance) { - instance->range_min = min; - instance->range_max = max; - } -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::ClearGroup() -{ - external_group.clear(); -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::CycleViewObject() -{ - if (!ship) return; - - Ship* current = external_ship; - external_ship = 0; - - ListIter iter = ship->ContactList(); - while (++iter && !external_ship) { - Contact* c = iter.value(); - Ship* c_ship = c->GetShip(); - - if (c_ship && !current) { - external_ship = c_ship; - } - - else if (current && c_ship == current) { - while (++iter && !external_ship) { - c = iter.value(); - if (c->ActLock()) - external_ship = c->GetShip(); - } - } - } - - if (external_ship != current) { - if (external_ship) { - if (external_ship->Life() == 0 || external_ship->IsDying() || external_ship->IsDead()) { - external_point = external_ship->Location(); - external_ship = 0; - } - else { - Observe(external_ship); - } - } - - if (mode == MODE_ORBIT) { - SetMode(MODE_TRANSLATE); - ExternalRange(1); - } - } -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::SetViewOrbital(Orbital* orb) -{ - external_body = orb; - - if (external_body) { - range_min = external_body->Radius() * 2.5; - ClearGroup(); - external_ship = 0; - - if (sim) { - region = sim->FindNearestSpaceRegion(orb); - if (region) - sim->ActivateRegion(region); - } - - if (ship && !region) - region = ship->GetRegion(); - } -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::SetViewObject(Ship* obj, bool quick) -{ - if (!ship) return; - if (!obj) { - obj = ship; - region = ship->GetRegion(); - } - - external_body = 0; - external_point = Point(); - - Starshatter* stars = Starshatter::GetInstance(); - - if (obj->GetIFF() != ship->GetIFF() && !stars->InCutscene()) { - // only view solid contacts: - Contact* c = ship->FindContact(obj); - if (!c || !c->ActLock()) - return; - } - - if (mode == MODE_TARGET) { - ClearGroup(); - if (external_ship) { - external_ship = 0; - } - } - else if (mode >= MODE_ORBIT) { - if (quick) { - mode = MODE_ORBIT; - transition = 0; - } - else { - SetMode(MODE_TRANSLATE); - } - - if (external_group.size()) { - ClearGroup(); - - if (external_ship) { - external_ship = 0; - } - } - - else { - if ((obj == external_ship) || (obj==ship && external_ship==0)) { - if (!quick) - SetMode(MODE_ZOOM); - } - - else if (external_ship) { - external_ship = 0; - } - } - } - - if (external_ship != obj) { - external_ship = obj; - - if (external_ship) { - region = external_ship->GetRegion(); - - if (external_ship->Life() == 0 || external_ship->IsDying() || external_ship->IsDead()) { - external_ship = 0; - range_min = 100; - } - else { - Observe(external_ship); - - if (sim) - sim->ActivateRegion(external_ship->GetRegion()); - - range_min = external_ship->Radius() * 1.5; - } - } - - Observe(external_ship); - ExternalRange(1); - } -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::SetViewObjectGroup(ListIter group, bool quick) -{ - if (!ship) return; - - Starshatter* stars = Starshatter::GetInstance(); - - if (!stars->InCutscene()) { - // only view solid contacts: - while (++group) { - Ship* s = group.value(); - - if (s->GetIFF() != ship->GetIFF()) { - Contact* c = ship->FindContact(s); - if (!c || !c->ActLock()) - return; - } - - if (s->Life() == 0 || s->IsDying() || s->IsDead()) - return; - } - } - - group.reset(); - - if (external_group.size() > 1 && - external_group.size() == group.size()) { - - bool same = true; - - for (int i = 0; same && i < external_group.size(); i++) { - if (external_group[i] != group.container()[i]) - same = false; - } - - if (same) { - SetMode(MODE_ZOOM); - return; - } - } - - ClearGroup(); - - if (quick) { - mode = MODE_ORBIT; - transition = 0; - } - else { - SetMode(MODE_TRANSLATE); - } - - external_group.append(group.container()); - - ListIter iter = external_group; - while (++iter) { - Ship* s = iter.value(); - region = s->GetRegion(); - Observe(s); - } -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::VirtualHead(double az, double el) -{ - if (mode == MODE_VIRTUAL || mode == MODE_TARGET || mode == MODE_COCKPIT) { - const double alimit = 3*PI/4; - const double e_lo = PI/8; - const double e_hi = PI/3; - const double escale = e_hi; - - virt_az = az * alimit; - virt_el = el * escale; - - if (virt_az > alimit) - virt_az = alimit; - - else if (virt_az < -alimit) - virt_az = -alimit; - - if (virt_el > e_hi) - virt_el = e_hi; - - else if (virt_el < -e_lo) - virt_el = -e_lo; - } -} - -void -CameraDirector::VirtualHeadOffset(double x, double y, double z) -{ - if (mode == MODE_VIRTUAL || mode == MODE_TARGET || mode == MODE_COCKPIT) { - virt_x = x; - virt_y = y; - virt_z = z; - } -} - -void -CameraDirector::VirtualAzimuth(double delta) -{ - if (mode == MODE_VIRTUAL || mode == MODE_TARGET || mode == MODE_COCKPIT) { - virt_az += delta; - - const double alimit = 3*PI/4; - - if (virt_az > alimit) - virt_az = alimit; - - else if (virt_az < -alimit) - virt_az = -alimit; - } -} - -void -CameraDirector::VirtualElevation(double delta) -{ - if (mode == MODE_VIRTUAL || mode == MODE_TARGET || mode == MODE_COCKPIT) { - virt_el += delta; - - const double e_lo = PI/8; - const double e_hi = PI/3; - - if (virt_el > e_hi) - virt_el = e_hi; - - else if (virt_el < -e_lo) - virt_el = -e_lo; - } -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::ExternalAzimuth(double delta) -{ - azimuth += delta; - - if (azimuth > PI) - azimuth = -2*PI + azimuth; - - else if (azimuth < -PI) - azimuth = 2*PI + azimuth; -} - -void -CameraDirector::ExternalElevation(double delta) -{ - elevation += delta; - - const double limit = (0.43 * PI); - - if (elevation > limit) - elevation = limit; - else if (elevation < -limit) - elevation = -limit; -} - -void -CameraDirector::ExternalRange(double delta) -{ - range *= delta; - - if (ship && ship->IsAirborne()) - range_max = 30e3; - else - range_max = range_max_limit; - - if (range < range_min) - range = range_min; - - else if (range > range_max) - range = range_max; -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::SetOrbitPoint(double a, double e, double r) -{ - azimuth = a; - elevation = e; - range = r; - - if (external_body) { - if (range < external_body->Radius() * 2) - range = external_body->Radius() * 2; - - else if (range > external_body->Radius() * 6) - range = external_body->Radius() * 6; - } - - else { - if (range < range_min) - range = range_min; - - else if (range > range_max) - range = range_max; - } -} - -void -CameraDirector::SetOrbitRates(double ar, double er, double rr) -{ - az_rate = ar; - el_rate = er; - - range_rate = rr; -} - -// +--------------------------------------------------------------------+ - -bool -CameraDirector::Update(SimObject* obj) -{ - if (obj->Type() == SimObject::SIM_SHIP) { - Ship* s = (Ship*) obj; - if (ship == s) - ship = 0; - - if (external_ship == s) { - external_point = s->Location(); - external_ship = 0; - } - - if (external_group.contains(s)) - external_group.remove(s); - } - - return SimObserver::Update(obj); -} - -const char* -CameraDirector::GetObserverName() const -{ - return "CameraDirector"; -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::ExecFrame(double seconds) -{ - if (!ship) - return; - - hud = HUDView::GetInstance(); - - int flight_phase = ship->GetFlightPhase(); - - if (flight_phase < Ship::LOCKED) - SetMode(MODE_DOCKING); - - if (ship->IsAirborne()) { - if (flight_phase >= Ship::DOCKING) - SetMode(MODE_DOCKING); - } - else { - if (flight_phase >= Ship::RECOVERY) - SetMode(MODE_DOCKING); - } - - if (flight_phase >= Ship::LOCKED && flight_phase < Ship::ACTIVE) { - int m = GetMode(); - if (m != MODE_COCKPIT && m != MODE_VIRTUAL) - SetMode(MODE_COCKPIT); - } - - if (ship->InTransition()) { - SetMode(MODE_DROP); - } - // automatically restore mode after transition: - else if (old_mode != MODE_NONE) { - mode = old_mode; - requested_mode = old_mode; - old_mode = MODE_NONE; - } - - int op_mode = mode; - if (requested_mode > mode) - op_mode = requested_mode; - - Starshatter* stars = Starshatter::GetInstance(); - - // if we are in padlock, and have not locked a ship - // try to padlock the current target: - if (op_mode == MODE_TARGET && !external_ship) { - SimObject* tgt = ship->GetTarget(); - if (tgt && tgt->Type() == SimObject::SIM_SHIP) - SetViewObject((Ship*) tgt); - } - - // if in an external mode, check the external ship: - else if (op_mode >= MODE_TARGET && op_mode <= MODE_ZOOM) { - if (external_ship && external_ship != ship && !stars->InCutscene()) { - Contact* c = ship->FindContact(external_ship); - if (!c || !c->ActLock()) { - SetViewObject(ship); - } - } - } - - if (ship->Rep()) { - if (op_mode == MODE_COCKPIT) { - ship->HideRep(); - ship->HideCockpit(); - } - else if (op_mode == MODE_VIRTUAL || op_mode == MODE_TARGET) { - if (ship->Cockpit()) { - ship->HideRep(); - ship->ShowCockpit(); - } - else { - ship->ShowRep(); - } - } - else { - ship->Rep()->SetForeground(op_mode == MODE_DOCKING); - ship->ShowRep(); - ship->HideCockpit(); - } - } - - if (hud && hud->Ambient() != Color::Black) - sim->GetScene()->SetAmbient( hud->Ambient() ); - else - sim->GetScene()->SetAmbient( sim->GetStarSystem()->Ambient() ); - - switch (op_mode) { - default: - case MODE_COCKPIT: Cockpit(seconds); break; - case MODE_CHASE: Chase(seconds); break; - case MODE_TARGET: Target(seconds); break; - case MODE_THREAT: Threat(seconds); break; - case MODE_VIRTUAL: Virtual(seconds); break; - case MODE_ORBIT: - case MODE_TRANSLATE: - case MODE_ZOOM: Orbit(seconds); break; - case MODE_DOCKING: Docking(seconds); break; - case MODE_DROP: Drop(seconds); break; - } - - if (ship->Shake() > 0 && - (op_mode < MODE_ORBIT || - (op_mode == MODE_VIRTUAL && ship->Cockpit()))) { - - Point vib = ship->Vibration() * 0.2; - camera.MoveBy(vib); - camera.Aim(0, vib.y, vib.z); - } - - Transition(seconds); - DetailSet::SetReference(region, camera.Pos()); -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::Transition(double seconds) -{ - if (transition > 0) - transition -= seconds * 1.5; - - if (transition <= 0) { - transition = 0; - - if (requested_mode && requested_mode != mode) - mode = requested_mode; - - requested_mode = 0; - - if (mode == MODE_TRANSLATE || mode == MODE_ZOOM) { - if (mode == MODE_ZOOM) - range = range_min; - - mode = MODE_ORBIT; - } - } -} - -// +--------------------------------------------------------------------+ - -bool -CameraDirector::IsViewCentered() -{ - if (instance) { - double fvaz = fabs(instance->virt_az); - double fvel = fabs(instance->virt_el); - - return fvaz < 15*DEGREES && fvel < 15*DEGREES; - } - - return true; -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::Cockpit(double seconds) -{ - camera.Clone(ship->Cam()); - - Point bridge = ship->BridgeLocation(); - Point cpos = camera.Pos() + - camera.vrt() * bridge.x + - camera.vpn() * bridge.y + - camera.vup() * bridge.z; - - camera.MoveTo(cpos); -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::Virtual(double seconds) -{ - camera.Clone(ship->Cam()); - - Point bridge = ship->BridgeLocation(); - Point cpos = camera.Pos() + - camera.vrt() * (bridge.x + virt_x) + - camera.vpn() * (bridge.y + virt_z) + - camera.vup() * (bridge.z + virt_y); - - camera.MoveTo(cpos); - - camera.Yaw(virt_az); - camera.Pitch(-virt_el); - - double fvaz = fabs(virt_az); - double fvel = fabs(virt_el); - - if (fvaz > 0.01*DEGREES && fvaz < 15*DEGREES) { - double bleed = fvaz * 2; - - if (virt_az > 0) - virt_az -= bleed * seconds; - else - virt_az += bleed * seconds; - } - - if (fvel > 0.01*DEGREES && fvel < 15*DEGREES) { - double bleed = fvel; - - if (virt_el > 0) - virt_el -= bleed * seconds; - else - virt_el += bleed * seconds; - } -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::Chase(double seconds) -{ - double step = 1; - - if (requested_mode == MODE_COCKPIT) - step = transition; - - else if (requested_mode == MODE_CHASE) - step = 1 - transition; - - camera.Clone(ship->Cam()); - Point velocity = camera.vpn(); - - if (ship->Velocity().length() > 10) { - velocity = ship->Velocity(); - velocity.Normalize(); - velocity *= 0.25; - velocity += camera.vpn() * 2; - velocity.Normalize(); - } - - Point chase = ship->ChaseLocation(); - Point bridge = ship->BridgeLocation(); - Point cpos = camera.Pos() + - camera.vrt() * bridge.x * (1-step) + - camera.vpn() * bridge.y * (1-step) + - camera.vup() * bridge.z * (1-step) + - velocity * chase.y * step + - camera.vup() * chase.z * step; - - camera.MoveTo(cpos); -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::Target(double seconds) -{ - Point target_loc = external_point; - - if (external_ship) - target_loc = external_ship->Location(); - - if (!external_ship || external_ship == ship) { - if (!external_point) { - if (ship->Cockpit()) - Virtual(seconds); - else - Orbit(seconds); - - return; - } - } - - double step = 1; - - if (requested_mode == MODE_COCKPIT) - step = transition; - - else if (requested_mode == MODE_TARGET) - step = 1 - transition; - - if (ship->Cockpit()) { - // internal padlock: - Cockpit(seconds); - camera.Padlock(target_loc, 3*PI/4, PI/8, PI/3); - } - else { - // external padlock: - Point delta = target_loc - ship->Location(); - delta.Normalize(); - delta *= -5 * ship->Radius() * step; - delta.y += ship->Radius() * step; - - camera.MoveTo(ship->Location() + delta); - camera.LookAt(target_loc); - } -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::Threat(double seconds) -{ - Chase(seconds); -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::Orbit(double seconds) -{ - Point cpos = ship->Location(); - int op_mode = GetCameraMode(); - - if (seconds < 0) seconds = 0; - else if (seconds > 0.2) seconds = 0.2; - - // auto rotate - azimuth += az_rate * seconds; - elevation += el_rate * seconds; - range *= 1 + range_rate * seconds; - - if (external_body && external_body->Rep()) { - range_min = external_body->Radius() * 2.5; - cpos = external_body->Rep()->Location(); - } - - else if (external_group.size()) { - Point neg(1e9, 1e9, 1e9); - Point pos(-1e9, -1e9, -1e9); - - ListIter iter(external_group); - while (++iter) { - Point loc = iter->Location(); - - if (loc.x < neg.x) neg.x = loc.x; - if (loc.x > pos.x) pos.x = loc.x; - if (loc.y < neg.y) neg.y = loc.y; - if (loc.y > pos.y) pos.y = loc.y; - if (loc.z < neg.z) neg.z = loc.z; - if (loc.z > pos.z) pos.z = loc.z; - } - - double dx = pos.x - neg.x; - double dy = pos.y - neg.y; - double dz = pos.z - neg.z; - - if (dx > dy) { - if (dx > dz) range_min = dx * 1.2; - else range_min = dz * 1.2; - } - else { - if (dy > dz) range_min = dy * 1.2; - else range_min = dz * 1.2; - } - - // focus on median location: - cpos = neg + Point(dx/2, dy/2, dz/2); - } - else if (external_ship) { - range_min = external_ship->Radius() * 1.5; - cpos = external_ship->Location(); - } - else { - range_min = ship->Radius() * 1.5; - cpos = ship->Location(); - } - - if (range < range_min) - range = range_min; - - double er = range; - double az = azimuth; - double el = elevation; - - if (requested_mode == MODE_TRANSLATE) { - cpos = cpos*(1-transition) + base_loc*(transition); - } - - else if (requested_mode == MODE_ZOOM) { - er = base_range * transition; - - if (er < range_min) { - er = range_min; - range = range_min; - transition = 0; - requested_mode = 0; - } - } - - // transitions: - else if (mode < MODE_ORBIT || requested_mode > 0 && requested_mode < MODE_ORBIT) { - double az0 = ship->CompassHeading(); - if (fabs(az-az0) > PI) az0 -= 2*PI; - - double r0 = 0; - double z0 = 0; - - if (mode == MODE_CHASE || requested_mode == MODE_CHASE || - mode == MODE_TARGET || requested_mode == MODE_TARGET) { - r0 = ship->ChaseLocation().length(); - z0 = 20 * DEGREES; - } - - // pull out: - if (mode < MODE_ORBIT) { - er *= (1-transition); - az *= (1-transition); - el *= (1-transition); - - er += r0 * transition; - az += az0 * transition; - el += z0 * transition; - } - - // push in: - else { - er *= transition; - az *= transition; - el *= transition; - - er += r0 * (1-transition); - az += az0 * (1-transition); - el += z0 * (1-transition); - } - } - - else { - // save base location for next time we re-focus - base_loc = cpos; - } - - double dx = er * sin(az) * cos(el); - double dy = er * cos(az) * cos(el); - double dz = er * sin(el); - - Point cloc = cpos + Point(dx,dz,dy); - - Terrain* terrain = ship->GetRegion()->GetTerrain(); - - if (terrain) { - double cam_agl = cloc.y - terrain->Height(cloc.x, cloc.z); - - if (cam_agl < 100) - cloc.y = terrain->Height(cloc.x, cloc.z) + 100; - } - - if (external_ship == 0 && er < 0.5 * ship->Radius()) - ship->Rep()->Hide(); - - camera.MoveTo(cloc.x, cloc.y, cloc.z); - camera.LookAt(cpos); -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::Docking(double seconds) -{ - FlightDeck* dock = ship->GetDock(); - - if (!dock) { - Cockpit(seconds); - return; - } - - if (!ship->IsAirborne()) - sim->GetScene()->SetAmbient(Color(120,130,140)); - int flight_phase = ship->GetFlightPhase(); - - Point bridge = ship->BridgeLocation(); - Point cloc = ship->Location() + - ship->Cam().vrt() * bridge.x + - ship->Cam().vpn() * bridge.y + - ship->Cam().vup() * bridge.z; - - Point cpos = dock->CamLoc(); - - // preflight: - if (flight_phase < Ship::LOCKED) { - base_loc = cpos; - } - - else if (flight_phase == Ship::LOCKED) { - if (hud) - hud->SetHUDMode(HUDView::HUD_MODE_TAC); - cpos = base_loc * transition + - cloc * (1-transition); - } - - // recovery: - else if (flight_phase > Ship::APPROACH) { - if (hud) - hud->SetTacticalMode(1); - } - - camera.MoveTo(cpos); - camera.LookAt(cloc); -} - -// +--------------------------------------------------------------------+ - -void -CameraDirector::Drop(double seconds) -{ - // orbital transitions use "drop cam" at transition_loc - camera.MoveTo(ship->TransitionLocation()); - camera.LookAt(ship->Location()); -} diff --git a/Stars45/CameraDirector.h b/Stars45/CameraDirector.h deleted file mode 100644 index 6cd59da..0000000 --- a/Stars45/CameraDirector.h +++ /dev/null @@ -1,155 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Camera Director singleton manages the main view camera based on the current ship -*/ - -#ifndef CameraDirector_h -#define CameraDirector_h - -#include "Types.h" -#include "Camera.h" -#include "SimObject.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class HUDView; -class Orbital; -class Ship; -class Sim; - -// +--------------------------------------------------------------------+ - -class CameraDirector : public SimObserver -{ -public: - static const char* TYPENAME() { return "CameraDirector"; } - - enum CAM_MODE { - MODE_NONE, - - MODE_COCKPIT, - MODE_CHASE, - MODE_TARGET, - MODE_THREAT, - MODE_ORBIT, - MODE_VIRTUAL, - MODE_TRANSLATE, - MODE_ZOOM, - MODE_DOCKING, - MODE_DROP, - - MODE_LAST - }; - - // CONSTRUCTORS: - CameraDirector(); - virtual ~CameraDirector(); - - int operator == (const CameraDirector& that) const { return this == &that; } - - static CameraDirector* GetInstance(); - - // CAMERA: - static int GetCameraMode(); - static void SetCameraMode(int m, double trans_time=1); - static const char* GetModeName(); - - static double GetRangeLimit(); - static void SetRangeLimit(double r); - static void SetRangeLimits(double min, double max); - - virtual void Reset(); - virtual void SetMode(int m, double trans_time=1); - virtual int GetMode() const { return requested_mode > MODE_NONE ? requested_mode : mode; } - virtual Camera* GetCamera() { return &camera; } - virtual Ship* GetShip() { return ship; } - virtual void SetShip(Ship* s); - - virtual void VirtualHead(double az, double el); - virtual void VirtualHeadOffset(double x, double y, double z); - virtual void VirtualAzimuth(double delta); - virtual void VirtualElevation(double delta); - virtual void ExternalAzimuth(double delta); - virtual void ExternalElevation(double delta); - virtual void ExternalRange(double delta); - virtual void SetOrbitPoint(double az, double el, double range); - virtual void SetOrbitRates(double az_rate, double el_rate, double r_rate); - - static bool IsViewCentered(); - - virtual void CycleViewObject(); - - virtual Orbital* GetViewOrbital() const { return external_body; } - virtual Ship* GetViewObject() const { return external_ship; } - - virtual void SetViewOrbital(Orbital* orb); - virtual void SetViewObject(Ship* obj, bool quick=false); - virtual void SetViewObjectGroup(ListIter group, bool quick=false); - virtual void ClearGroup(); - - // BEHAVIORS: - virtual void ExecFrame(double s); - virtual void Transition(double s); - - // SimObserver: - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - -protected: - virtual void Cockpit(double s); - virtual void Chase(double s); - virtual void Target(double s); - virtual void Threat(double s); - virtual void Virtual(double s); - virtual void Orbit(double s); - virtual void Docking(double s); - virtual void Drop(double s); - - int mode; - int requested_mode; - int old_mode; - Camera camera; - - Ship* ship; - - SimRegion* region; - Orbital* external_body; - Ship* external_ship; - List external_group; - Point external_point; - - Point base_loc; - - double virt_az; - double virt_el; - double virt_x; - double virt_y; - double virt_z; - double azimuth; - double elevation; - double az_rate; - double el_rate; - double range_rate; - double range; - double range_min; - double range_max; - double base_range; - double transition; - - Sim* sim; - HUDView* hud; - - static CameraDirector* instance; -}; - -#endif // CameraDirector_h - diff --git a/Stars45/CameraView.cpp b/Stars45/CameraView.cpp deleted file mode 100644 index 9f58dd8..0000000 --- a/Stars45/CameraView.cpp +++ /dev/null @@ -1,800 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - 3D Projection Camera View class - uses abstract PolyRender class to draw the triangles -*/ - -#include "CameraView.h" -#include "Color.h" -#include "Window.h" -#include "Scene.h" -#include "Light.h" -#include "Solid.h" -#include "Shadow.h" -#include "Sprite.h" -#include "Video.h" -#include "Bitmap.h" -#include "Screen.h" -#include "Game.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -static Camera emergency_cam; -static Scene emergency_scene; - -// +--------------------------------------------------------------------+ - -CameraView::CameraView(Window* c, Camera* cam, Scene* s) - : View(c), video(0), camera(cam), projector(c, cam), scene(s), - lens_flare_enable(0), halo_bitmap(0), infinite(0), - projection_type(Video::PROJECTION_PERSPECTIVE) -{ - elem_bitmap[0] = 0; - elem_bitmap[1] = 0; - elem_bitmap[2] = 0; - - if (!camera) - camera = &emergency_cam; - - if (!scene) - scene = &emergency_scene; - - Rect r = window->GetRect(); - width = r.w; - height = r.h; -} - -CameraView::~CameraView() -{ -} - -// +--------------------------------------------------------------------+ - -void -CameraView::UseCamera(Camera* cam) -{ - if (cam) - camera = cam; - else - camera = &emergency_cam; - - projector.UseCamera(camera); -} - -void -CameraView::UseScene(Scene* s) -{ - if (s) - scene = s; - else - scene = &emergency_scene; -} - -void -CameraView::SetFieldOfView(double fov) -{ - projector.SetFieldOfView(fov); -} - -double -CameraView::GetFieldOfView() const -{ - return projector.GetFieldOfView(); -} - -void -CameraView::SetProjectionType(DWORD pt) -{ - projector.SetOrthogonal(pt == Video::PROJECTION_ORTHOGONAL); - projection_type = pt; -} - -DWORD -CameraView::GetProjectionType() const -{ - return projection_type; -} - -void -CameraView::OnWindowMove() -{ - Rect r = window->GetRect(); - projector.UseWindow(window); - - width = r.w; - height = r.h; -} - - -// +--------------------------------------------------------------------+ -// Enable or disable lens flare effect, and provide bitmaps for rendering -// +--------------------------------------------------------------------+ - -void -CameraView::LensFlare(int on, double dim) -{ - lens_flare_enable = on; - lens_flare_dim = dim; -} - -void -CameraView::LensFlareElements(Bitmap* halo, Bitmap* e1, Bitmap* e2, Bitmap* e3) -{ - if (halo) - halo_bitmap = halo; - - if (e1) - elem_bitmap[0] = e1; - - if (e2) - elem_bitmap[1] = e2; - - if (e3) - elem_bitmap[2] = e3; -} - -// +--------------------------------------------------------------------+ - -int -CameraView::SetInfinite(int i) -{ - int old = infinite; - infinite = i; - projector.SetInfinite(i); - return old; -} - -// +--------------------------------------------------------------------+ -// Compute the Depth of a Graphic -// +--------------------------------------------------------------------+ - -void -CameraView::FindDepth(Graphic* g) -{ - if (infinite) { - g->SetDepth(1.0e20f); - return; - } - - // Translate into a viewpoint-relative coordinate - Vec3 loc = g->Location() - camera->Pos(); - - // Rotate into the view orientation - float z = (float) (loc * camera->vpn()); - g->SetDepth(z); -} - -// +--------------------------------------------------------------------+ - -void -CameraView::Refresh() -{ - // disabled: - if (camera == &emergency_cam) - return; - - // prologue: - video = Video::GetInstance(); - if (!video) - return; - - int cw = window->Width(); - int ch = window->Height(); - - cvrt = camera->vrt(); - cvup = camera->vup(); - cvpn = camera->vpn(); - - TranslateScene(); - MarkVisibleObjects(); - - Rect old_rect; - video->GetWindowRect(old_rect); - - video->SetCamera(camera); - video->SetWindowRect(window->GetRect()); - video->SetProjection((float) GetFieldOfView(), 1.0f, 1.0e6f, projection_type); - - // project and render: - RenderBackground(); - RenderScene(); - RenderForeground(); - RenderSprites(); - RenderLensFlare(); - - UnTranslateScene(); - - video->SetWindowRect(old_rect); -} - -// +--------------------------------------------------------------------+ -// Translate all objects and lights to camera relative coordinates: -// +--------------------------------------------------------------------+ - -void -CameraView::TranslateScene() -{ - camera_loc = camera->Pos(); - - ListIter g_iter = scene->Graphics(); - while (++g_iter) { - Graphic* graphic = g_iter.value(); - - if (!graphic->IsInfinite()) - graphic->TranslateBy(camera_loc); - } - - g_iter.attach(scene->Foreground()); - while (++g_iter) { - Graphic* graphic = g_iter.value(); - graphic->TranslateBy(camera_loc); - } - - g_iter.attach(scene->Sprites()); - while (++g_iter) { - Graphic* graphic = g_iter.value(); - - if (!graphic->IsInfinite()) - graphic->TranslateBy(camera_loc); - } - - ListIter l_iter = scene->Lights(); - while (++l_iter) { - Light* light = l_iter.value(); - light->TranslateBy(camera_loc); - } - - camera->MoveTo(0,0,0); -} - -// +--------------------------------------------------------------------+ -// Translate all objects and lights back to original positions: -// +--------------------------------------------------------------------+ - -void -CameraView::UnTranslateScene() -{ - Point reloc = -camera_loc; - - ListIter g_iter = scene->Graphics(); - while (++g_iter) { - Graphic* graphic = g_iter.value(); - - if (!graphic->IsInfinite()) - graphic->TranslateBy(reloc); - } - - g_iter.attach(scene->Foreground()); - while (++g_iter) { - Graphic* graphic = g_iter.value(); - graphic->TranslateBy(reloc); - } - - g_iter.attach(scene->Sprites()); - while (++g_iter) { - Graphic* graphic = g_iter.value(); - - if (!graphic->IsInfinite()) - graphic->TranslateBy(reloc); - } - - ListIter l_iter = scene->Lights(); - while (++l_iter) { - Light* light = l_iter.value(); - light->TranslateBy(reloc); - } - - camera->MoveTo(camera_loc); -} - -// +--------------------------------------------------------------------+ -// Mark visible objects -// +--------------------------------------------------------------------+ - -void -CameraView::MarkVisibleObjects() -{ - projector.StartFrame(); - graphics.clear(); - - ListIter graphic_iter = scene->Graphics(); - while (++graphic_iter) { - Graphic* graphic = graphic_iter.value(); - - if (graphic->Hidden()) - continue; - - if (graphic->CheckVisibility(projector)) { - graphic->Update(); - graphics.append(graphic); - } - else { - graphic->ProjectScreenRect(0); - } - } -} - -void -CameraView::MarkVisibleLights(Graphic* graphic, DWORD flags) -{ - if (flags < Graphic::RENDER_FIRST_LIGHT) { - flags = flags | Graphic::RENDER_FIRST_LIGHT | Graphic::RENDER_ADD_LIGHT; - } - - if (graphic->IsVisible()) { - Vec3 eye = camera->Pos(); - - ListIter light_iter = scene->Lights(); - - while (++light_iter) { - Light* light = light_iter.value(); - bool bright_enough = light->Type() == Light::LIGHT_DIRECTIONAL || - light->Intensity() >= 1e9; - - if (!bright_enough) { - Point test = graphic->Location() - light->Location(); - if (test.length() < light->Intensity()*10) - bright_enough = true; - } - - // turn off lights that won't be used this pass: - if (light->CastsShadow()) { - if ((flags & Graphic::RENDER_ADD_LIGHT) == 0) - bright_enough = false; - } - else { - if ((flags & Graphic::RENDER_FIRST_LIGHT) == 0) - bright_enough = false; - } - - double obs_radius = graphic->Radius(); - if (obs_radius < 100) - obs_radius = 100; - - light->SetActive(bright_enough); - } - } -} - -// +--------------------------------------------------------------------+ - -void -CameraView::RenderBackground() -{ - if (scene->Background().isEmpty()) return; - - video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID); - video->SetRenderState(Video::Z_ENABLE, FALSE); - video->SetRenderState(Video::Z_WRITE_ENABLE, FALSE); - video->SetRenderState(Video::STENCIL_ENABLE, FALSE); - video->SetRenderState(Video::LIGHTING_ENABLE, TRUE); - - // solid items: - ListIter iter = scene->Background(); - while (++iter) { - Graphic* g = iter.value(); - - if (!g->Hidden()) - Render(g, Graphic::RENDER_SOLID); - } - - // blended items: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - - if (!g->Hidden()) - Render(g, Graphic::RENDER_ALPHA); - } - - // glowing items: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - - if (!g->Hidden()) - Render(g, Graphic::RENDER_ADDITIVE); - } -} - -// +--------------------------------------------------------------------+ - -void -CameraView::RenderForeground() -{ - bool foregroundVisible = false; - - ListIter iter = scene->Foreground(); - while (++iter && !foregroundVisible) { - Graphic* g = iter.value(); - if (g && !g->Hidden()) - foregroundVisible = true; - } - - if (!foregroundVisible) - return; - - video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID); - video->SetRenderState(Video::Z_ENABLE, TRUE); - video->SetRenderState(Video::Z_WRITE_ENABLE, TRUE); - video->SetRenderState(Video::STENCIL_ENABLE, FALSE); - video->SetRenderState(Video::LIGHTING_ENABLE, TRUE); - video->SetProjection((float) GetFieldOfView(), 1.0f, 1.0e6f, projection_type); - - if (video->IsShadowEnabled() || video->IsBumpMapEnabled()) { - // solid items, ambient and non-shadow lights: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - Render(g, Graphic::RENDER_SOLID | Graphic::RENDER_FIRST_LIGHT); - } - - video->SetAmbient(Color::Black); - video->SetRenderState(Video::LIGHTING_PASS, 2); - - // solid items, shadow lights: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - Render(g, Graphic::RENDER_SOLID | Graphic::RENDER_ADD_LIGHT); - } - } - - else { - // solid items: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - Render(g, Graphic::RENDER_SOLID); - } - } - - video->SetAmbient(scene->Ambient()); - video->SetRenderState(Video::LIGHTING_PASS, 0); - video->SetRenderState(Video::STENCIL_ENABLE, FALSE); - video->SetRenderState(Video::Z_ENABLE, TRUE); - video->SetRenderState(Video::Z_WRITE_ENABLE, FALSE); - - // blended items: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - Render(g, Graphic::RENDER_ALPHA); - g->ProjectScreenRect(&projector); - } - - // glowing items: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - Render(g, Graphic::RENDER_ADDITIVE); - g->ProjectScreenRect(&projector); - } -} - -// +--------------------------------------------------------------------+ - -void -CameraView::RenderSprites() -{ - if (scene->Sprites().isEmpty()) return; - - video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID); - video->SetRenderState(Video::Z_ENABLE, TRUE); - video->SetRenderState(Video::Z_WRITE_ENABLE, FALSE); - video->SetRenderState(Video::STENCIL_ENABLE, FALSE); - video->SetRenderState(Video::LIGHTING_ENABLE, TRUE); - - // compute depth: - ListIter iter = scene->Sprites(); - while (++iter) { - Graphic* g = iter.value(); - if (g && g->IsVisible() && !g->Hidden()) { - FindDepth(g); - } - } - - // sort the list: - scene->Sprites().sort(); - - // blended items: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - Render(g, Graphic::RENDER_ALPHA); - } - - // glowing items: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - Render(g, Graphic::RENDER_ADDITIVE); - } -} - -// +--------------------------------------------------------------------+ -// Render the whole scene, sorted back to front -// +--------------------------------------------------------------------+ - -void -CameraView::RenderScene() -{ - if (graphics.isEmpty()) return; - - int i = 0; - int ngraphics = graphics.size(); - - // compute depth: - ListIter iter = graphics; - while (++iter) { - Graphic* g = iter.value(); - if (g && !g->Hidden()) { - FindDepth(g); - - if (g->IsSolid()) { - Solid* solid = (Solid*) g; - - solid->SelectDetail(&projector); - - if (video->IsShadowEnabled()) { - MarkVisibleLights(solid, Graphic::RENDER_ADD_LIGHT); - solid->UpdateShadows(scene->Lights()); - } - } - } - } - - // sort the list: - graphics.sort(); - - Graphic* g = graphics.last(); - if (g->Depth() > 5e6) { - RenderSceneObjects(true); - video->ClearDepthBuffer(); - } - - RenderSceneObjects(false); -} - -void -CameraView::RenderSceneObjects(bool distant) -{ - ListIter iter = graphics; - - video->SetAmbient(scene->Ambient()); - video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID); - video->SetRenderState(Video::Z_ENABLE, TRUE); - video->SetRenderState(Video::Z_WRITE_ENABLE, TRUE); - video->SetRenderState(Video::LIGHTING_ENABLE, TRUE); - - if (distant) - video->SetProjection((float) GetFieldOfView(), 5.0e6f, 1.0e12f, projection_type); - else - video->SetProjection((float) GetFieldOfView(), 1.0f, 1.0e6f, projection_type); - - if (video->IsShadowEnabled() || video->IsBumpMapEnabled()) { - // solid items, ambient and non-shadow lights: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - - if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) { - Render(g, Graphic::RENDER_SOLID | Graphic::RENDER_FIRST_LIGHT); - } - } - - // send shadows to stencil buffer: - if (video->IsShadowEnabled()) { - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) { - if (g->IsSolid()) { - Solid* solid = (Solid*) g; - - ListIter shadow_iter = solid->GetShadows(); - while (++shadow_iter) { - Shadow* shadow = shadow_iter.value(); - shadow->Render(video); - } - } - } - } - } - - video->SetAmbient(Color::Black); - video->SetRenderState(Video::LIGHTING_PASS, 2); - video->SetRenderState(Video::STENCIL_ENABLE, TRUE); - - // solid items, shadow lights: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - - if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) { - Render(g, Graphic::RENDER_SOLID | Graphic::RENDER_ADD_LIGHT); - } - } - } - - else { - // solid items: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - - if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) { - Render(g, Graphic::RENDER_SOLID); - } - } - } - - video->SetAmbient(scene->Ambient()); - video->SetRenderState(Video::LIGHTING_PASS, 0); - video->SetRenderState(Video::STENCIL_ENABLE, FALSE); - video->SetRenderState(Video::Z_ENABLE, TRUE); - video->SetRenderState(Video::Z_WRITE_ENABLE, FALSE); - - // blended items: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - - if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) { - Render(g, Graphic::RENDER_ALPHA); - g->ProjectScreenRect(&projector); - } - } - - // glowing items: - iter.reset(); - while (++iter) { - Graphic* g = iter.value(); - - if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) { - Render(g, Graphic::RENDER_ADDITIVE); - g->ProjectScreenRect(&projector); - } - } -} - -void -CameraView::Render(Graphic* g, DWORD flags) -{ - if (g && g->IsVisible() && !g->Hidden()) { - if (g->IsSolid()) { - MarkVisibleLights(g, flags); - video->SetLights(scene->Lights()); - } - - g->Render(video, flags); - } -} - -// +--------------------------------------------------------------------+ -// Draw the lens flare effect, if enabled and light source visible -// +--------------------------------------------------------------------+ - -void -CameraView::RenderLensFlare() -{ - if (!lens_flare_enable || lens_flare_dim < 0.01) - return; - - if (!halo_bitmap) - return; - - video->SetRenderState(Video::STENCIL_ENABLE, FALSE); - video->SetRenderState(Video::Z_ENABLE, FALSE); - video->SetRenderState(Video::Z_WRITE_ENABLE, FALSE); - - Vec3 flare_pos; - Vec3 sun_pos; - Vec3 center((float)width/2.0f, (float)height/2.0f, 1.0f); - int flare_visible = 0; - - ListIter light_iter = scene->Lights(); - while (++light_iter) { - Light* light = light_iter.value(); - - if (!light->IsActive()) - continue; - - if (light->Type() == Light::LIGHT_DIRECTIONAL && light->Intensity() < 1) - continue; - - double distance = (light->Location()-camera->Pos()).length(); - - // only do lens flare for the sun: - if (distance > 1e9) { - if (projector.IsVisible(light->Location(), 1.0f)) { - // FOUND IT: TRANSFORM/PROJECT FLARE LOCATION - Point sun_pos = light->Location(); - - if (light->CastsShadow() && scene->IsLightObscured(camera->Pos(), sun_pos, -1)) - continue; - - projector.Transform(sun_pos); - - if (sun_pos.z < 100) - continue; - - projector.Project(sun_pos, false); - - int x = (int) (sun_pos.x); - int y = (int) (sun_pos.y); - int w = (int) (window->Width() / 4.0); - int h = w; - - // halo: - window->DrawBitmap(x-w,y-h,x+w,y+h, halo_bitmap, Video::BLEND_ADDITIVE); - - // lens elements: - if (elem_bitmap[0]) { - Point vector = center - sun_pos; - float vlen = (float) vector.length(); - vector.Normalize(); - - static int nelem = 12; - static int elem_indx[] = { 0, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 2 }; - static float elem_dist[] = { -0.2f, 0.5f, 0.55f, 0.62f, 1.23f, 1.33f, 1.35f, 0.8f, 0.9f, 1.4f, 1.7f, 1.8f }; - static float elem_size[] = { 0.3f, 0.2f, 0.4f, 0.3f, 0.4f, 0.2f, 0.6f, 0.1f, 0.1f, 1.6f, 1.0f, 0.2f }; - - for (int elem = 0; elem < nelem; elem++) { - Bitmap* img = elem_bitmap[elem_indx[elem]]; - - /*** - if (elem == 10) - shade *= 0.5; - ***/ - - if (img == 0) - img = elem_bitmap[0]; - - flare_pos = sun_pos + (vector * elem_dist[elem] * vlen); - x = (int) (flare_pos.x); - y = (int) (flare_pos.y); - w = (int) (window->Width() / 8.0 * elem_size[elem]); - h = w; - - window->DrawBitmap(x-w,y-h,x+w,y+h, img, Video::BLEND_ADDITIVE); - } - } - } - } - } -} - -// +--------------------------------------------------------------------+ -// Rotate and translate a plane in world space to view space. -// +--------------------------------------------------------------------+ - -void -CameraView::WorldPlaneToView(Plane& plane) -{ - // Determine the distance from the viewpoint - Vec3 tnormal = plane.normal; - - if (!infinite) - plane.distance -= (float) (camera->Pos() * tnormal); - - // Rotate the normal into view orientation - plane.normal.x = tnormal * cvrt; - plane.normal.y = tnormal * cvup; - plane.normal.z = tnormal * cvpn; -} - -void -CameraView::SetDepthScale(float scale) -{ - projector.SetDepthScale(scale); -} diff --git a/Stars45/CameraView.h b/Stars45/CameraView.h deleted file mode 100644 index 4c2b357..0000000 --- a/Stars45/CameraView.h +++ /dev/null @@ -1,113 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - 3D Projection Camera View class -*/ - -#ifndef CameraView_h -#define CameraView_h - -#include "Types.h" -#include "View.h" -#include "Camera.h" -#include "Projector.h" -#include "Video.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Video; -class Scene; -class Bitmap; - -class Graphic; - -// +--------------------------------------------------------------------+ - -class CameraView : public View -{ -public: - static const char* TYPENAME() { return "CameraView"; } - - CameraView(Window* c, Camera* cam, Scene* s); - virtual ~CameraView(); - - // Operations: - virtual void Refresh(); - virtual void OnWindowMove(); - virtual void UseCamera(Camera* cam); - virtual void UseScene(Scene* scene); - virtual void LensFlareElements(Bitmap* halo, Bitmap* e1=0, Bitmap* e2=0, Bitmap* e3=0); - virtual void LensFlare(int on, double dim = 1); - virtual void SetDepthScale(float scale); - - // accessors: - Camera* GetCamera() const { return camera; } - Projector* GetProjector() { return &projector; } - Scene* GetScene() const { return scene; } - virtual void SetFieldOfView(double fov); - virtual double GetFieldOfView() const; - virtual void SetProjectionType(DWORD pt); - virtual DWORD GetProjectionType() const; - - Point Pos() const { return camera->Pos(); } - Point vrt() { return camera->vrt(); } - Point vup() { return camera->vup(); } - Point vpn() { return camera->vpn(); } - const Matrix& Orientation() const { return camera->Orientation(); } - - Point SceneOffset() const { return camera_loc; } - - // projection and clipping geometry: - virtual void TranslateScene(); - virtual void UnTranslateScene(); - virtual void MarkVisibleObjects(); - virtual void MarkVisibleLights(Graphic* g, DWORD flags); - - virtual void RenderScene(); - virtual void RenderSceneObjects(bool distant=false); - virtual void RenderForeground(); - virtual void RenderBackground(); - virtual void RenderSprites(); - virtual void RenderLensFlare(); - virtual void Render(Graphic* g, DWORD flags); - - virtual void FindDepth(Graphic* g); - virtual int SetInfinite(int i); - -protected: - Camera* camera; - Scene* scene; - Video* video; - - virtual void WorldPlaneToView(Plane& plane); - - Point camera_loc; - Vec3 cvrt; - Vec3 cvup; - Vec3 cvpn; - - Projector projector; - int infinite; - int width; - int height; - DWORD projection_type; - - // lens flare: - int lens_flare_enable; - double lens_flare_dim; - Bitmap* halo_bitmap; - Bitmap* elem_bitmap[3]; - - List graphics; -}; - -#endif // CameraView_h - diff --git a/Stars45/Campaign.cpp b/Stars45/Campaign.cpp deleted file mode 100644 index af1eb86..0000000 --- a/Stars45/Campaign.cpp +++ /dev/null @@ -1,2339 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Campaign defines a strategic military scenario. -*/ - -#include "Campaign.h" -#include "CampaignPlanStrategic.h" -#include "CampaignPlanAssignment.h" -#include "CampaignPlanEvent.h" -#include "CampaignPlanMission.h" -#include "CampaignPlanMovement.h" -#include "CampaignSituationReport.h" -#include "CampaignSaveGame.h" -#include "Combatant.h" -#include "CombatAction.h" -#include "CombatEvent.h" -#include "CombatGroup.h" -#include "CombatRoster.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Galaxy.h" -#include "Mission.h" -#include "StarSystem.h" -#include "Starshatter.h" -#include "Player.h" - -#include "ContentBundle.h" -#include "Bitmap.h" -#include "Clock.h" -#include "DataLoader.h" -#include "ParseUtil.h" -#include "Random.h" -#include "FormatUtil.h" - - -const int TIME_NEVER = (int) 1e9; -const int ONE_DAY = (int) 24 * 3600; - -// +====================================================================+ - -MissionInfo::MissionInfo() - : mission(0), start(0), type(0), id(0), min_rank(0), max_rank(0), - action_id(0), action_status(0), exec_once(0), - start_before(TIME_NEVER), start_after(0) -{ } - -MissionInfo::~MissionInfo() -{ - delete mission; -} - -bool -MissionInfo::IsAvailable() -{ - Campaign* campaign = Campaign::GetCampaign(); - Player* player = Player::GetCurrentPlayer(); - CombatGroup* player_group = campaign->GetPlayerGroup(); - - if (campaign->GetTime() < start_after) - return false; - - if (campaign->GetTime() > start_before) - return false; - - if (region.length() && player_group->GetRegion() != region) - return false; - - if (min_rank && player->Rank() < min_rank) - return false; - - if (max_rank && player->Rank() > max_rank) - return false; - - if (exec_once < 0) - return false; - - if (exec_once > 0) - exec_once = -1; - - return true; -} - -// +====================================================================+ - -TemplateList::TemplateList() - : mission_type(0), group_type(0), index(0) -{ } - -TemplateList::~TemplateList() -{ - missions.destroy(); -} - -// +====================================================================+ - -static List campaigns; -static Campaign* current_campaign = 0; - -// +--------------------------------------------------------------------+ - -Campaign::Campaign(int id, const char* n) - : campaign_id(id), name(n), mission_id(-1), mission(0), net_mission(0), - scripted(false), sequential(false), time(0), startTime(0), loadTime(0), - player_group(0), player_unit(0), status(CAMPAIGN_INIT), lockout(0), - loaded_from_savegame(false) -{ - ZeroMemory(path, sizeof(path)); - Load(); -} - -Campaign::Campaign(int id, const char* n, const char* p) - : campaign_id(id), name(n), mission_id(-1), mission(0), net_mission(0), - scripted(false), sequential(false), time(0), startTime(0), loadTime(0), - player_group(0), player_unit(0), status(CAMPAIGN_INIT), lockout(0), - loaded_from_savegame(false) -{ - ZeroMemory(path, sizeof(path)); - strncpy(path, p, sizeof(path)); - Load(); -} - -// +--------------------------------------------------------------------+ - -Campaign::~Campaign() -{ - for (int i = 0; i < NUM_IMAGES; i++) - image[i].ClearImage(); - - delete net_mission; - - actions.destroy(); - events.destroy(); - missions.destroy(); - templates.destroy(); - planners.destroy(); - zones.destroy(); - combatants.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -Campaign::Initialize() -{ - Campaign* c = 0; - DataLoader* loader = DataLoader::GetLoader(); - - for (int i = 1; i < 100; i++) { - char path[256]; - sprintf_s(path, "Campaigns/%02d/", i); - - loader->UseFileSystem(true); - loader->SetDataPath(path); - - if (loader->FindFile("campaign.def")) { - char txt[256]; - sprintf_s(txt, "Dynamic Campaign %02d", i); - c = new Campaign(i, txt); - - if (c) { - campaigns.insertSort(c); - } - } - } - - c = new Campaign(SINGLE_MISSIONS, "Single Missions"); - if (c) { - campaigns.insertSort(c); - current_campaign = c; - } - - c = new Campaign(MULTIPLAYER_MISSIONS, "Multiplayer Missions"); - if (c) { - campaigns.insertSort(c); - } - - c = new Campaign(CUSTOM_MISSIONS, "Custom Missions"); - if (c) { - campaigns.insertSort(c); - } -} - -void -Campaign::Close() -{ - Print("Campaign::Close() - destroying all campaigns\n"); - current_campaign = 0; - campaigns.destroy(); -} - -Campaign* -Campaign::GetCampaign() -{ - return current_campaign; -} - -Campaign* -Campaign::SelectCampaign(const char* name) -{ - Campaign* c = 0; - ListIter iter = campaigns; - - while (++iter && !c) { - if (!_stricmp(iter->Name(), name)) - c = iter.value(); - } - - if (c) { - Print("Campaign: Selected '%s'\n", c->Name()); - current_campaign = c; - } - else { - Print("Campaign: could not find '%s'\n", name); - } - - return c; -} - -Campaign* -Campaign::CreateCustomCampaign(const char* name, const char* path) -{ - int id = 0; - - if (name && *name && path && *path) { - ListIter iter = campaigns; - - while (++iter) { - Campaign* c = iter.value(); - if (c->GetCampaignId() >= id) - id = c->GetCampaignId() + 1; - - if (!strcmp(c->Name(), name)) { - Print("Campaign: custom campaign '%s' already exists.\n", name); - return 0; - } - } - } - - if (id == 0) - id = CUSTOM_MISSIONS + 1; - - Campaign* c = new Campaign(id, name, path); - Print("Campaign: created custom campaign %d '%s'\n", id, name); - campaigns.append(c); - - return c; -} - -List& -Campaign::GetAllCampaigns() -{ - return campaigns; -} - -int -Campaign::GetLastCampaignId() -{ - int result = 0; - - for (int i = 0; i < campaigns.size(); i++) { - Campaign* c = campaigns.at(i); - - if (c->IsDynamic() && c->GetCampaignId() > result) { - result = c->GetCampaignId(); - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -CombatEvent* -Campaign::GetLastEvent() -{ - CombatEvent* result = 0; - - if (!events.isEmpty()) - result = events.last(); - - return result; -} - -// +--------------------------------------------------------------------+ - -int -Campaign::CountNewEvents() const -{ - int result = 0; - - for (int i = 0; i < events.size(); i++) - if (/*events[i]->Source() != CombatEvent::TACNET &&*/ !events[i]->Visited()) - result++; - - return result; -} - -// +--------------------------------------------------------------------+ - -void -Campaign::Clear() -{ - missions.destroy(); - planners.destroy(); - combatants.destroy(); - events.destroy(); - actions.destroy(); - - player_group = 0; - player_unit = 0; - - updateTime = time; -} - -// +--------------------------------------------------------------------+ - -void -Campaign::Load() -{ - // first, unload any existing data: - Unload(); - - if (!path[0]) { - // then load the campaign from files: - switch (campaign_id) { - case SINGLE_MISSIONS: strcpy_s(path, "Missions/"); break; - case CUSTOM_MISSIONS: strcpy_s(path, "Mods/Missions/"); break; - case MULTIPLAYER_MISSIONS: strcpy_s(path, "Multiplayer/"); break; - default: sprintf_s(path, "Campaigns/%02d/", campaign_id); break; - } - } - - DataLoader* loader = DataLoader::GetLoader(); - loader->UseFileSystem(true); - loader->SetDataPath(path); - systems.clear(); - - if (loader->FindFile("zones.def")) - zones.append(CombatZone::Load("zones.def")); - - for (int i = 0; i < zones.size(); i++) { - Text s = zones[i]->System(); - bool found = false; - - for (int n = 0; !found && n < systems.size(); n++) { - if (s == systems[n]->Name()) - found = true; - } - - if (!found) - systems.append(Galaxy::GetInstance()->GetSystem(s)); - } - - loader->UseFileSystem(Starshatter::UseFileSystem()); - - if (loader->FindFile("campaign.def")) - LoadCampaign(loader); - - if (campaign_id == CUSTOM_MISSIONS) { - loader->SetDataPath(path); - LoadCustomMissions(loader); - } - else { - bool found = false; - - if (loader->FindFile("missions.def")) { - loader->SetDataPath(path); - LoadMissionList(loader); - found = true; - } - - if (loader->FindFile("templates.def")) { - loader->SetDataPath(path); - LoadTemplateList(loader); - found = true; - } - - if (!found) { - loader->SetDataPath(path); - LoadCustomMissions(loader); - } - } - - loader->UseFileSystem(true); - loader->SetDataPath(path); - - if (loader->FindFile("image.pcx")) { - loader->LoadBitmap("image.pcx", image[ 0]); - loader->LoadBitmap("selected.pcx", image[ 1]); - loader->LoadBitmap("unavail.pcx", image[ 2]); - loader->LoadBitmap("banner.pcx", image[ 3]); - } - - loader->SetDataPath(0); - loader->UseFileSystem(Starshatter::UseFileSystem()); -} - -void -Campaign::Unload() -{ - SetStatus(CAMPAIGN_INIT); - - Clock::GetInstance()->ResetGameTime(); - StarSystem::SetBaseTime(0); - - startTime = Stardate(); - loadTime = startTime; - lockout = 0; - - for (int i = 0; i < NUM_IMAGES; i++) - image[i].ClearImage(); - - Clear(); - - zones.destroy(); -} - -void -Campaign::LoadCampaign(DataLoader* loader, bool full) -{ - BYTE* block = 0; - const char* filename = "campaign.def"; - - loader->UseFileSystem(true); - loader->LoadBuffer(filename, block, true); - loader->UseFileSystem(Starshatter::UseFileSystem()); - Parser parser(new BlockReader((const char*) block)); - - Term* term = parser.ParseTerm(); - - if (!term) { - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "CAMPAIGN") { - return; - } - } - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "name") { - if (!def->term() || !def->term()->isText()) { - ::Print("WARNING: name missing in '%s/%s'\n", loader->GetDataPath(), filename); - } - else { - name = def->term()->isText()->value(); - name = ContentBundle::GetInstance()->GetText(name); - } - } - else if (def->name()->value() == "desc") { - if (!def->term() || !def->term()->isText()) { - ::Print("WARNING: description missing in '%s/%s'\n", loader->GetDataPath(), filename); - } - else { - description = def->term()->isText()->value(); - description = ContentBundle::GetInstance()->GetText(description); - } - } - else if (def->name()->value() == "situation") { - if (!def->term() || !def->term()->isText()) { - ::Print("WARNING: situation missing in '%s/%s'\n", loader->GetDataPath(), filename); - } - else { - situation = def->term()->isText()->value(); - situation = ContentBundle::GetInstance()->GetText(situation); - } - } - else if (def->name()->value() == "orders") { - if (!def->term() || !def->term()->isText()) { - ::Print("WARNING: orders missing in '%s/%s'\n", loader->GetDataPath(), filename); - } - else { - orders = def->term()->isText()->value(); - orders = ContentBundle::GetInstance()->GetText(orders); - } - } - else if (def->name()->value() == "scripted") { - if (def->term() && def->term()->isBool()) { - scripted = def->term()->isBool()->value(); - } - } - else if (def->name()->value() == "sequential") { - if (def->term() && def->term()->isBool()) { - sequential = def->term()->isBool()->value(); - } - } - else if (full && def->name()->value() == "combatant") { - if (!def->term() || !def->term()->isStruct()) { - ::Print("WARNING: combatant struct missing in '%s/%s'\n", loader->GetDataPath(), filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - char name[64]; - int iff = 0; - CombatGroup* force = 0; - CombatGroup* clone = 0; - - ZeroMemory(name, sizeof(name)); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") { - GetDefText(name, pdef, filename); - - force = CombatRoster::GetInstance()->GetForce(name); - - if (force) - clone = force->Clone(false); // shallow copy - } - - else if (pdef->name()->value() == "group") { - ParseGroup(pdef->term()->isStruct(), force, clone, filename); - } - } - } - - loader->SetDataPath(path); - Combatant* c = new Combatant(name, clone); - if (c) { - combatants.append(c); - } - else { - Unload(); - return; - } - } - } - else if (full && def->name()->value() == "action") { - if (!def->term() || !def->term()->isStruct()) { - ::Print("WARNING: action struct missing in '%s/%s'\n", loader->GetDataPath(), filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseAction(val, filename); - } - } - } - } - } - while (term); - - loader->ReleaseBuffer(block); -} - -// +--------------------------------------------------------------------+ - -void -Campaign::ParseGroup(TermStruct* val, -CombatGroup* force, -CombatGroup* clone, -const char* filename) -{ - if (!val) { - ::Print("invalid combat group in campaign %s\n", name.data()); - return; - } - - int type = 0; - int id = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "type") { - char type_name[64]; - GetDefText(type_name, pdef, filename); - type = CombatGroup::TypeFromName(type_name); - } - - else if (pdef->name()->value() == "id") { - GetDefNumber(id, pdef, filename); - } - } - } - - if (type && id) { - CombatGroup* g = force->FindGroup(type, id); - - // found original group, now clone it over - if (g && g->GetParent()) { - CombatGroup* parent = CloneOver(force, clone, g->GetParent()); - parent->AddComponent(g->Clone()); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Campaign::ParseAction(TermStruct* val, const char* filename) -{ - if (!val) { - ::Print("invalid action in campaign %s\n", name.data()); - return; - } - - int id = 0; - int type = 0; - int subtype = 0; - int opp_type = -1; - int team = 0; - int source = 0; - Vec3 loc(0.0f, 0.0f, 0.0f); - Text system; - Text region; - Text file; - Text image; - Text scene; - Text text; - int count = 1; - int start_before = TIME_NEVER; - int start_after = 0; - int min_rank = 0; - int max_rank = 100; - int delay = 0; - int probability = 100; - - int asset_type = 0; - int asset_id = 0; - int target_type = 0; - int target_id = 0; - int target_iff = 0; - - CombatAction* action = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "id") { - GetDefNumber(id, pdef, filename); - } - else if (pdef->name()->value() == "type") { - char txt[64]; - GetDefText(txt, pdef, filename); - type = CombatAction::TypeFromName(txt); - } - else if (pdef->name()->value() == "subtype") { - if (pdef->term()->isNumber()) { - GetDefNumber(subtype, pdef, filename); - } - - else if (pdef->term()->isText()) { - char txt[64]; - GetDefText(txt, pdef, filename); - - if (type == CombatAction::MISSION_TEMPLATE) { - subtype = Mission::TypeFromName(txt); - } - else if (type == CombatAction::COMBAT_EVENT) { - subtype = CombatEvent::TypeFromName(txt); - } - else if (type == CombatAction::INTEL_EVENT) { - subtype = Intel::IntelFromName(txt); - } - } - } - else if (pdef->name()->value() == "opp_type") { - if (pdef->term()->isNumber()) { - GetDefNumber(opp_type, pdef, filename); - } - - else if (pdef->term()->isText()) { - char txt[64]; - GetDefText(txt, pdef, filename); - - if (type == CombatAction::MISSION_TEMPLATE) { - opp_type = Mission::TypeFromName(txt); - } - } - } - else if (pdef->name()->value() == "source") { - char txt[64]; - GetDefText(txt, pdef, filename); - source = CombatEvent::SourceFromName(txt); - } - else if (pdef->name()->value() == "team") { - GetDefNumber(team, pdef, filename); - } - else if (pdef->name()->value() == "iff") { - GetDefNumber(team, pdef, filename); - } - else if (pdef->name()->value() == "count") { - GetDefNumber(count, pdef, filename); - } - else if (pdef->name()->value().contains("before")) { - if (pdef->term()->isNumber()) { - GetDefNumber(start_before, pdef, filename); - } - else { - GetDefTime(start_before, pdef, filename); - start_before -= ONE_DAY; - } - } - else if (pdef->name()->value().contains("after")) { - if (pdef->term()->isNumber()) { - GetDefNumber(start_after, pdef, filename); - } - else { - GetDefTime(start_after, pdef, filename); - start_after -= ONE_DAY; - } - } - else if (pdef->name()->value() == "min_rank") { - if (pdef->term()->isNumber()) { - GetDefNumber(min_rank, pdef, filename); - } - else { - char rank_name[64]; - GetDefText(rank_name, pdef, filename); - min_rank = Player::RankFromName(rank_name); - } - } - else if (pdef->name()->value() == "max_rank") { - if (pdef->term()->isNumber()) { - GetDefNumber(max_rank, pdef, filename); - } - else { - char rank_name[64]; - GetDefText(rank_name, pdef, filename); - max_rank = Player::RankFromName(rank_name); - } - } - else if (pdef->name()->value() == "delay") { - GetDefNumber(delay, pdef, filename); - } - else if (pdef->name()->value() == "probability") { - GetDefNumber(probability, pdef, filename); - } - else if (pdef->name()->value() == "asset_type") { - char type_name[64]; - GetDefText(type_name, pdef, filename); - asset_type = CombatGroup::TypeFromName(type_name); - } - else if (pdef->name()->value() == "target_type") { - char type_name[64]; - GetDefText(type_name, pdef, filename); - target_type = CombatGroup::TypeFromName(type_name); - } - else if (pdef->name()->value() == "location" || - pdef->name()->value() == "loc") { - GetDefVec(loc, pdef, filename); - } - else if (pdef->name()->value() == "system" || - pdef->name()->value() == "sys") { - GetDefText(system, pdef, filename); - } - else if (pdef->name()->value() == "region" || - pdef->name()->value() == "rgn" || - pdef->name()->value() == "zone") { - GetDefText(region, pdef, filename); - } - else if (pdef->name()->value() == "file") { - GetDefText(file, pdef, filename); - } - else if (pdef->name()->value() == "image") { - GetDefText(image, pdef, filename); - } - else if (pdef->name()->value() == "scene") { - GetDefText(scene, pdef, filename); - } - else if (pdef->name()->value() == "text") { - GetDefText(text, pdef, filename); - text = ContentBundle::GetInstance()->GetText(text); - } - else if (pdef->name()->value() == "asset_id") { - GetDefNumber(asset_id, pdef, filename); - } - else if (pdef->name()->value() == "target_id") { - GetDefNumber(target_id, pdef, filename); - } - else if (pdef->name()->value() == "target_iff") { - GetDefNumber(target_iff, pdef, filename); - } - - else if (pdef->name()->value() == "asset_kill") { - if (!action) - action = new CombatAction(id, type, subtype, team); - - if (action) { - char txt[64]; - GetDefText(txt, pdef, filename); - action->AssetKills().append(new Text(txt)); - } - } - - else if (pdef->name()->value() == "target_kill") { - if (!action) - action = new CombatAction(id, type, subtype, team); - - if (action) { - char txt[64]; - GetDefText(txt, pdef, filename); - action->TargetKills().append(new Text(txt)); - } - } - - else if (pdef->name()->value() == "req") { - if (!action) - action = new CombatAction(id, type, subtype, team); - - if (!pdef->term() || !pdef->term()->isStruct()) { - ::Print("WARNING: action req struct missing in '%s'\n", filename); - } - else if (action) { - TermStruct* val2 = pdef->term()->isStruct(); - - int act = 0; - int stat = CombatAction::COMPLETE; - bool _not = false; - - Combatant* c1 = 0; - Combatant* c2 = 0; - int comp = 0; - int score = 0; - int intel = 0; - int gtype = 0; - int gid = 0; - - for (int i = 0; i < val2->elements()->size(); i++) { - TermDef* pdef2 = val2->elements()->at(i)->isDef(); - if (pdef2) { - if (pdef2->name()->value() == "action") { - GetDefNumber(act, pdef2, filename); - } - else if (pdef2->name()->value() == "status") { - char txt[64]; - GetDefText(txt, pdef2, filename); - stat = CombatAction::StatusFromName(txt); - } - else if (pdef2->name()->value() == "not") { - GetDefBool(_not, pdef2, filename); - } - - else if (pdef2->name()->value() == "c1") { - char txt[64]; - GetDefText(txt, pdef2, filename); - c1 = GetCombatant(txt); - } - else if (pdef2->name()->value() == "c2") { - char txt[64]; - GetDefText(txt, pdef2, filename); - c2 = GetCombatant(txt); - } - else if (pdef2->name()->value() == "comp") { - char txt[64]; - GetDefText(txt, pdef2, filename); - comp = CombatActionReq::CompFromName(txt); - } - else if (pdef2->name()->value() == "score") { - GetDefNumber(score, pdef2, filename); - } - else if (pdef2->name()->value() == "intel") { - if (pdef2->term()->isNumber()) { - GetDefNumber(intel, pdef2, filename); - } - else if (pdef2->term()->isText()) { - char txt[64]; - GetDefText(txt, pdef2, filename); - intel = Intel::IntelFromName(txt); - } - } - else if (pdef2->name()->value() == "group_type") { - char type_name[64]; - GetDefText(type_name, pdef2, filename); - gtype = CombatGroup::TypeFromName(type_name); - } - else if (pdef2->name()->value() == "group_id") { - GetDefNumber(gid, pdef2, filename); - } - } - } - - if (act) - action->AddRequirement(act, stat, _not); - - else if (gtype) - action->AddRequirement(c1, gtype, gid, comp, score, intel); - - else - action->AddRequirement(c1, c2, comp, score); - } - } - } - } - - if (!action) - action = new CombatAction(id, type, subtype, team); - - if (action) { - action->SetSource(source); - action->SetOpposingType(opp_type); - action->SetLocation(loc); - action->SetSystem(system); - action->SetRegion(region); - action->SetFilename(file); - action->SetImageFile(image); - action->SetSceneFile(scene); - action->SetCount(count); - action->SetStartAfter(start_after); - action->SetStartBefore(start_before); - action->SetMinRank(min_rank); - action->SetMaxRank(max_rank); - action->SetDelay(delay); - action->SetProbability(probability); - - action->SetAssetId(asset_id); - action->SetAssetType(asset_type); - action->SetTargetId(target_id); - action->SetTargetIFF(target_iff); - action->SetTargetType(target_type); - action->SetText(text); - - actions.append(action); - } -} - -// +--------------------------------------------------------------------+ - -CombatGroup* -Campaign::CloneOver(CombatGroup* force, CombatGroup* clone, CombatGroup* group) -{ - CombatGroup* orig_parent = group->GetParent(); - - if (orig_parent) { - CombatGroup* clone_parent = clone->FindGroup(orig_parent->Type(), orig_parent->GetID()); - - if (!clone_parent) - clone_parent = CloneOver(force, clone, orig_parent); - - CombatGroup* new_clone = clone->FindGroup(group->Type(), group->GetID()); - - if (!new_clone) { - new_clone = group->Clone(false); - clone_parent->AddComponent(new_clone); - } - - return new_clone; - } - else { - return clone; - } -} - -// +--------------------------------------------------------------------+ - -void -Campaign::LoadMissionList(DataLoader* loader) -{ - bool ok = true; - BYTE* block = 0; - const char* filename = "Missions.def"; - - loader->UseFileSystem(true); - loader->LoadBuffer(filename, block, true); - loader->UseFileSystem(Starshatter::UseFileSystem()); - Parser parser(new BlockReader((const char*) block)); - - Term* term = parser.ParseTerm(); - - if (!term) { - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "MISSIONLIST") { - ::Print("WARNING: invalid mission list file '%s'\n", filename); - term->print(10); - return; - } - } - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "mission") { - if (!def->term() || !def->term()->isStruct()) { - ::Print("WARNING: mission struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - int id = 0; - Text name; - Text desc; - char script[256]; - char system[256]; - char region[256]; - int start = 0; - int type = 0; - - ZeroMemory(script, sizeof(script)); - - strcpy_s(system, "Unknown"); - strcpy_s(region, "Unknown"); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "id") - GetDefNumber(id, pdef, filename); - - else if (pdef->name()->value() == "name") { - GetDefText(name, pdef, filename); - name = ContentBundle::GetInstance()->GetText(name); - } - - else if (pdef->name()->value() == "desc") { - GetDefText(desc, pdef, filename); - if (desc.length() > 0 && desc.length() < 32) - desc = ContentBundle::GetInstance()->GetText(desc); - } - - else if (pdef->name()->value() == "start") - GetDefTime(start, pdef, filename); - - else if (pdef->name()->value() == "system") - GetDefText(system, pdef, filename); - - else if (pdef->name()->value() == "region") - GetDefText(region, pdef, filename); - - else if (pdef->name()->value() == "script") - GetDefText(script, pdef, filename); - - else if (pdef->name()->value() == "type") { - char typestr[64]; - GetDefText(typestr, pdef, filename); - type = Mission::TypeFromName(typestr); - } - } - } - - MissionInfo* info = new MissionInfo; - if (info) { - info->id = id; - info->name = name; - info->description = desc; - info->system = system; - info->region = region; - info->script = script; - info->start = start; - info->type = type; - info->mission = 0; - - info->script.setSensitive(false); - - missions.append(info); - } - else { - ok = false; - } - } - } - } - } - } - while (term); - - loader->ReleaseBuffer(block); - - if (!ok) - Unload(); -} - -void -Campaign::LoadCustomMissions(DataLoader* loader) -{ - bool ok = true; - List files; - loader->UseFileSystem(true); - loader->ListFiles("*.*", files); - - for (int i = 0; i < files.size(); i++) { - Text file = *files[i]; - file.setSensitive(false); - - if (file.contains(".def")) { - BYTE* block = 0; - const char* filename = file.data(); - - loader->UseFileSystem(true); - loader->LoadBuffer(filename, block, true); - loader->UseFileSystem(Starshatter::UseFileSystem()); - - if (strstr((const char*) block, "MISSION") == (const char*) block) { - Text name; - Text desc; - Text system = "Unknown"; - Text region = "Unknown"; - int start = 0; - int type = 0; - int msn_id = 0; - - Parser parser(new BlockReader((const char*) block)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'\n", filename); - continue; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "MISSION") { - Print("ERROR: invalid mission file '%s'\n", filename); - term->print(10); - continue; - } - } - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "name") { - GetDefText(name, def, filename); - name = ContentBundle::GetInstance()->GetText(name); - } - - else if (def->name()->value() == "type") { - char typestr[64]; - GetDefText(typestr, def, filename); - type = Mission::TypeFromName(typestr); - } - - else if (def->name()->value() == "id") - GetDefNumber(msn_id, def, filename); - - else if (def->name()->value() == "desc") { - GetDefText(desc, def, filename); - if (desc.length() > 0 && desc.length() < 32) - desc = ContentBundle::GetInstance()->GetText(desc); - } - - else if (def->name()->value() == "system") - GetDefText(system, def, filename); - - else if (def->name()->value() == "region") - GetDefText(region, def, filename); - - else if (def->name()->value() == "start") - GetDefTime(start, def, filename); - } - } - } - while (term); - - loader->ReleaseBuffer(block); - - if (strstr(filename, "custom") == filename) { - sscanf_s(filename+6, "%d", &msn_id); - - if (msn_id <= i) - msn_id = i+1; - } - else if (msn_id < 1) { - msn_id = i+1; - } - - MissionInfo* info = new MissionInfo; - if (info) { - info->id = msn_id; - info->name = name; - info->type = type; - info->description = desc; - info->system = system; - info->region = region; - info->script = filename; - info->start = start; - info->mission = 0; - - info->script.setSensitive(false); - - missions.append(info); - } - else { - ok = false; - } - } - else { - Print("Invalid Custom Mission File: '%s'\n", filename); - } - - loader->ReleaseBuffer(block); - } - } - - files.destroy(); - - if (!ok) - Unload(); - else - missions.sort(); -} - -void -Campaign::LoadTemplateList(DataLoader* loader) -{ - BYTE* block = 0; - const char* filename = "Templates.def"; - - loader->UseFileSystem(true); - loader->LoadBuffer(filename, block, true); - loader->UseFileSystem(Starshatter::UseFileSystem()); - Parser parser(new BlockReader((const char*) block)); - - Term* term = parser.ParseTerm(); - - if (!term) { - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "TEMPLATELIST") { - ::Print("WARNING: invalid template list file '%s'\n", filename); - term->print(10); - return; - } - } - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "mission") { - if (!def->term() || !def->term()->isStruct()) { - ::Print("WARNING: mission struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - char name[256]; - char script[256]; - char region[256]; - int id = 0; - int msn_type = 0; - int grp_type = 0; - - int min_rank = 0; - int max_rank = 0; - int action_id = 0; - int action_status = 0; - int exec_once = 0; - int start_before = TIME_NEVER; - int start_after = 0; - - name[0] = 0; - script[0] = 0; - region[0] = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "id") - GetDefNumber(id, pdef, filename); - - else if (pdef->name()->value() == "name") - GetDefText(name, pdef, filename); - - else if (pdef->name()->value() == "script") - GetDefText(script, pdef, filename); - - else if (pdef->name()->value() == "rgn" || pdef->name()->value() == "region") - GetDefText(region, pdef, filename); - - else if (pdef->name()->value() == "type") { - char typestr[64]; - GetDefText(typestr, pdef, filename); - msn_type = Mission::TypeFromName(typestr); - } - - else if (pdef->name()->value() == "group") { - char typestr[64]; - GetDefText(typestr, pdef, filename); - grp_type = CombatGroup::TypeFromName(typestr); - } - - else if (pdef->name()->value() == "min_rank") - GetDefNumber(min_rank, pdef, filename); - - else if (pdef->name()->value() == "max_rank") - GetDefNumber(max_rank, pdef, filename); - - else if (pdef->name()->value() == "action_id") - GetDefNumber(action_id, pdef, filename); - - else if (pdef->name()->value() == "action_status") - GetDefNumber(action_status, pdef, filename); - - else if (pdef->name()->value() == "exec_once") - GetDefNumber(exec_once, pdef, filename); - - else if (pdef->name()->value().contains("before")) { - if (pdef->term()->isNumber()) { - GetDefNumber(start_before, pdef, filename); - } - else { - GetDefTime(start_before, pdef, filename); - start_before -= ONE_DAY; - } - } - else if (pdef->name()->value().contains("after")) { - if (pdef->term()->isNumber()) { - GetDefNumber(start_after, pdef, filename); - } - else { - GetDefTime(start_after, pdef, filename); - start_after -= ONE_DAY; - } - } - } - } - - MissionInfo* info = new MissionInfo; - if (info) { - info->id = id; - info->name = name; - info->script = script; - info->region = region; - info->type = msn_type; - info->min_rank = min_rank; - info->max_rank = max_rank; - info->action_id = action_id; - info->action_status = action_status; - info->exec_once = exec_once; - info->start_before = start_before; - info->start_after = start_after; - - info->script.setSensitive(false); - - TemplateList* templist = GetTemplateList(msn_type, grp_type); - - if (!templist) { - templist = new TemplateList; - templist->mission_type = msn_type; - templist->group_type = grp_type; - templates.append(templist); - } - - templist->missions.append(info); - } - } - } - } - } - } - while (term); - - loader->ReleaseBuffer(block); -} - -// +--------------------------------------------------------------------+ - -void -Campaign::CreatePlanners() -{ - if (planners.size() > 0) - planners.destroy(); - - CampaignPlan* p; - - // PLAN EVENT MUST BE FIRST PLANNER: - p = new CampaignPlanEvent(this); - if (p) - planners.append(p); - - p = new CampaignPlanStrategic(this); - if (p) - planners.append(p); - - p = new CampaignPlanAssignment(this); - if (p) - planners.append(p); - - p = new CampaignPlanMovement(this); - if (p) - planners.append(p); - - p = new CampaignPlanMission(this); - if (p) - planners.append(p); - - if (lockout > 0 && planners.size()) { - ListIter plan = planners; - while (++plan) - plan->SetLockout(lockout); - } -} - -// +--------------------------------------------------------------------+ - -int -Campaign::GetPlayerIFF() -{ - int iff = 1; - - if (player_group) - iff = player_group->GetIFF(); - - return iff; -} - -void -Campaign::SetPlayerGroup(CombatGroup* pg) -{ - if (player_group != pg) { - ::Print("Campaign::SetPlayerGroup(%s)\n", pg ? pg->Name().data() : "0"); - - // should verify that the player group is - // actually part of this campaign, first! - - player_group = pg; - player_unit = 0; - - // need to regenerate missions when changing - // player combat group: - if (IsDynamic()) { - ::Print(" destroying mission list...\n"); - missions.destroy(); - } - } -} - -void -Campaign::SetPlayerUnit(CombatUnit* unit) -{ - if (player_unit != unit) { - ::Print("Campaign::SetPlayerUnit(%s)\n", unit ? unit->Name().data() : "0"); - - // should verify that the player unit is - // actually part of this campaign, first! - - player_unit = unit; - - if (unit) - player_group = unit->GetCombatGroup(); - - // need to regenerate missions when changing - // player combat unit: - if (IsDynamic()) { - ::Print(" destroying mission list...\n"); - missions.destroy(); - } - } -} - -// +--------------------------------------------------------------------+ - -CombatZone* -Campaign::GetZone(const char* rgn) -{ - ListIter z = zones; - while (++z) { - if (z->HasRegion(rgn)) - return z.value(); - } - - return 0; -} - -StarSystem* -Campaign::GetSystem(const char* sys) -{ - return Galaxy::GetInstance()->GetSystem(sys); -} - -Combatant* -Campaign::GetCombatant(const char* cname) -{ - ListIter iter = combatants; - while (++iter) { - Combatant* c = iter.value(); - if (!strcmp(c->Name(), cname)) - return c; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -Mission* -Campaign::GetMission() -{ - return GetMission(mission_id); -} - -Mission* -Campaign::GetMission(int id) -{ - if (id < 0) { - ::Print("ERROR - Campaign::GetMission(%d) invalid mission id\n", id); - return 0; - } - - if (mission && mission->Identity() == id) { - return mission; - } - - MissionInfo* info = 0; - for (int i = 0; !info && i < missions.size(); i++) - if (missions[i]->id == id) - info = missions[i]; - - if (info) { - if (!info->mission) { - ::Print("Campaign::GetMission(%d) loading mission...\n", id); - info->mission = new Mission(id, info->script, path); - if (info->mission) - info->mission->Load(); - } - - if (IsDynamic()) { - if (info->mission) { - if (!_stricmp(info->mission->Situation(), "Unknown")) { - ::Print("Campaign::GetMission(%d) generating sitrep...\n", id); - CampaignSituationReport sitrep(this, info->mission); - sitrep.GenerateSituationReport(); - } - } - else { - ::Print("Campaign::GetMission(%d) could not find/load mission.\n", id); - } - } - - return info->mission; - } - - return 0; -} - -Mission* -Campaign::GetMissionByFile(const char* filename) -{ - if (!filename || !*filename) { - ::Print("ERROR - Campaign::GetMissionByFile() invalid filename\n"); - return 0; - } - - int id = 0; - int maxid = 0; - MissionInfo* info = 0; - - for (int i = 0; !info && i < missions.size(); i++) { - MissionInfo* m = missions[i]; - - if (m->id > maxid) - maxid = m->id; - - if (m->script == filename) - info = m; - } - - if (info) { - id = info->id; - - if (!info->mission) { - ::Print("Campaign::GetMission(%d) loading mission...\n", id); - info->mission = new Mission(id, info->script, path); - if (info->mission) - info->mission->Load(); - } - - if (IsDynamic()) { - if (info->mission) { - if (!_stricmp(info->mission->Situation(), "Unknown")) { - ::Print("Campaign::GetMission(%d) generating sitrep...\n", id); - CampaignSituationReport sitrep(this, info->mission); - sitrep.GenerateSituationReport(); - } - } - else { - ::Print("Campaign::GetMission(%d) could not find/load mission.\n", id); - } - } - } - - else { - info = new MissionInfo; - if (info) { - info->id = maxid+1; - info->name = "New Custom Mission"; - info->script = filename; - info->mission = new Mission(info->id, info->script, "Mods/Missions/"); - info->mission->SetName(info->name); - - info->script.setSensitive(false); - - missions.append(info); - } - } - - return info->mission; -} - -MissionInfo* -Campaign::CreateNewMission() -{ - int id = 0; - int maxid = 0; - MissionInfo* info = 0; - - if (campaign_id == MULTIPLAYER_MISSIONS) - maxid = 10; - - for (int i = 0; !info && i < missions.size(); i++) { - MissionInfo* m = missions[i]; - - if (m->id > maxid) - maxid = m->id; - } - - char filename[64]; - sprintf_s(filename, "custom%03d.def", maxid+1); - - info = new MissionInfo; - if (info) { - info->id = maxid+1; - info->name = "New Custom Mission"; - info->script = filename; - info->mission = new Mission(info->id, filename, path); - info->mission->SetName(info->name); - - info->script.setSensitive(false); - - missions.append(info); - } - - return info; -} - -void -Campaign::DeleteMission(int id) -{ - if (id < 0) { - ::Print("ERROR - Campaign::DeleteMission(%d) invalid mission id\n", id); - return; - } - - MissionInfo* m = 0; - int index = -1; - - for (int i = 0; !m && i < missions.size(); i++) { - if (missions[i]->id == id) { - m = missions[i]; - index = i; - } - } - - if (m) { - char full_path[256]; - - if (path[strlen(path)-1] == '/') - sprintf_s(full_path, "%s%s", path, m->script.data()); - else - sprintf_s(full_path, "%s/%s", path, m->script.data()); - - DeleteFile(full_path); - Load(); - } - - else { - ::Print("ERROR - Campaign::DeleteMission(%d) could not find mission\n", id); - } -} - -MissionInfo* -Campaign::GetMissionInfo(int id) -{ - if (id < 0) { - ::Print("ERROR - Campaign::GetMissionInfo(%d) invalid mission id\n", id); - return 0; - } - - MissionInfo* m = 0; - for (int i = 0; !m && i < missions.size(); i++) - if (missions[i]->id == id) - m = missions[i]; - - if (m) { - if (!m->mission) { - m->mission = new Mission(id, m->script); - if (m->mission) - m->mission->Load(); - } - - return m; - } - - else { - ::Print("ERROR - Campaign::GetMissionInfo(%d) could not find mission\n", id); - } - - return 0; -} - -void -Campaign::ReloadMission(int id) -{ - if (mission && mission == net_mission) { - delete net_mission; - net_mission = 0; - } - - mission = 0; - - if (id >= 0 && id < missions.size()) { - MissionInfo* m = missions[id]; - delete m->mission; - m->mission = 0; - } -} - -void -Campaign::LoadNetMission(int id, const char* net_mission_script) -{ - if (mission && mission == net_mission) { - delete net_mission; - net_mission = 0; - } - - mission_id = id; - mission = new Mission(id); - - if (mission && mission->ParseMission(net_mission_script)) - mission->Validate(); - - net_mission = mission; -} - -// +--------------------------------------------------------------------+ - -CombatAction* -Campaign::FindAction(int action_id) -{ - ListIter iter = actions; - while (++iter) { - CombatAction* a = iter.value(); - - if (a->Identity() == action_id) - return a; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -MissionInfo* -Campaign::FindMissionTemplate(int mission_type, CombatGroup* player_group) -{ - MissionInfo* info = 0; - - if (!player_group) - return info; - - TemplateList* templates = GetTemplateList(mission_type, player_group->Type()); - - if (!templates || !templates->missions.size()) - return info; - - int tries = 0; - int msize = templates->missions.size(); - - while (!info && tries < msize) { - // get next template: - int index = templates->index; - - if (index >= msize) - index = 0; - - info = templates->missions[index]; - templates->index = index + 1; - tries++; - - // validate the template: - if (info) { - if (info->action_id) { - CombatAction* a = FindAction(info->action_id); - - if (a && a->Status() != info->action_status) - info = 0; - } - - if (info && !info->IsAvailable()) { - info = 0; - } - } - } - - return info; -} - -// +--------------------------------------------------------------------+ - -TemplateList* -Campaign::GetTemplateList(int msn_type, int grp_type) -{ - for (int i = 0; i < templates.size(); i++) { - if (templates[i]->mission_type == msn_type && - templates[i]->group_type == grp_type) - return templates[i]; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Campaign::SetMissionId(int id) -{ - ::Print("Campaign::SetMissionId(%d)\n", id); - - if (id > 0) - mission_id = id; - else - ::Print(" retaining mission id = %d\n", mission_id); -} - -// +--------------------------------------------------------------------+ - -long double -Campaign::Stardate() -{ - return StarSystem::Stardate(); -} - -// +--------------------------------------------------------------------+ - -void -Campaign::SelectDefaultPlayerGroup(CombatGroup* g, int type) -{ - if (player_group || !g) return; - - if (g->Type() == type && !g->IsReserve() && g->Value() > 0) { - player_group = g; - player_unit = 0; - return; - } - - for (int i = 0; i < g->GetComponents().size(); i++) - SelectDefaultPlayerGroup(g->GetComponents()[i], type); -} - -// +--------------------------------------------------------------------+ - -void -Campaign::Prep() -{ - // if this is a new campaign, - // create combatants from roster and template: - if (IsDynamic() && combatants.isEmpty()) { - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(path); - LoadCampaign(loader, true); - } - - StarSystem::SetBaseTime(loadTime); - - // load scripted missions: - if (IsScripted() && actions.isEmpty()) { - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(path); - LoadCampaign(loader, true); - - ListIter m = missions; - while (++m) { - GetMission(m->id); - } - } - - CheckPlayerGroup(); -} - -void -Campaign::Start() -{ - ::Print("Campaign::Start()\n"); - - Prep(); - - // create planners: - CreatePlanners(); - SetStatus(CAMPAIGN_ACTIVE); -} - -void -Campaign::ExecFrame() -{ - if (InCutscene()) - return; - - time = Stardate() - startTime; - - if (status < CAMPAIGN_ACTIVE) - return; - - if (IsDynamic()) { - bool completed = false; - ListIter m = missions; - while (++m) { - if (m->mission && m->mission->IsComplete()) { - ::Print("Campaign::ExecFrame() completed mission %d '%s'\n", m->id, m->name.data()); - completed = true; - } - } - - if (completed) { - ::Print("Campaign::ExecFrame() destroying mission list after completion...\n"); - missions.destroy(); - - if (!player_group || player_group->IsFighterGroup()) - time += 10 * 3600; - else - time += 20 * 3600; - - StarSystem::SetBaseTime(startTime + time - Clock::GetInstance()->GameTime()/1000.0); - } - else { - m.reset(); - - while (++m) { - if (m->start < time && !m->mission->IsActive()) { - MissionInfo* info = m.removeItem(); - - if (info) - ::Print("Campaign::ExecFrame() deleting expired mission %d start: %d current: %d\n", - info->id, - info->start, - (int) time); - - delete info; - } - } - } - - // PLAN EVENT MUST BE FIRST PLANNER: - if (loaded_from_savegame && planners.size() > 0) { - CampaignPlanEvent* plan_event = (CampaignPlanEvent*) planners.first(); - plan_event->ExecScriptedEvents(); - - loaded_from_savegame = false; - } - - ListIter plan = planners; - while (++plan) { - CheckPlayerGroup(); - plan->ExecFrame(); - } - - CheckPlayerGroup(); - - // Auto save game AFTER planners have run! - // This is done to ensure that campaign status - // is properly recorded after winning or losing - // the campaign. - - if (completed) { - CampaignSaveGame save(this); - save.SaveAuto(); - } - } - else { - // PLAN EVENT MUST BE FIRST PLANNER: - if (planners.size() > 0) { - CampaignPlanEvent* plan_event = (CampaignPlanEvent*) planners.first(); - plan_event->ExecScriptedEvents(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Campaign::LockoutEvents(int seconds) -{ - lockout = seconds; -} - -void -Campaign::CheckPlayerGroup() -{ - if (!player_group || player_group->IsReserve() || player_group->CalcValue() < 1) { - int player_iff = GetPlayerIFF(); - player_group = 0; - - CombatGroup* force = 0; - for (int i = 0; i < combatants.size() && !force; i++) { - if (combatants[i]->GetIFF() == player_iff) { - force = combatants[i]->GetForce(); - } - } - - if (force) { - force->CalcValue(); - SelectDefaultPlayerGroup(force, CombatGroup::WING); - - if (!player_group) - SelectDefaultPlayerGroup(force, CombatGroup::DESTROYER_SQUADRON); - } - } - - if (player_unit && player_unit->GetValue() < 1) - SetPlayerUnit(0); -} - -// +--------------------------------------------------------------------+ - - -void -Campaign::StartMission() -{ - Mission* m = GetMission(); - - if (m) { - ::Print("\n\nCampaign Start Mission - %d. '%s'\n", m->Identity(), m->Name()); - - if (!scripted) { - long double gtime = (long double) Clock::GetInstance()->GameTime() / 1000.0; - long double base = startTime + m->Start() - 15 - gtime; - - StarSystem::SetBaseTime(base); - - long double current_time = Stardate() - startTime; - - char buffer[32]; - FormatDayTime(buffer, current_time); - ::Print(" current time: %s\n", buffer); - - FormatDayTime(buffer, m->Start()); - ::Print(" mission start: %s\n", buffer); - ::Print("\n"); - } - } -} - -void -Campaign::RollbackMission() -{ - ::Print("Campaign::RollbackMission()\n"); - - Mission* m = GetMission(); - - if (m) { - if (!scripted) { - long double gtime = (long double) Clock::GetInstance()->GameTime() / 1000.0; - long double base = startTime + m->Start() - 60 - gtime; - - StarSystem::SetBaseTime(base); - - long double current_time = Stardate() - startTime; - ::Print(" mission start: %d\n", m->Start()); - ::Print(" current time: %d\n", (int) current_time); - } - - m->SetActive(false); - m->SetComplete(false); - } -} - -// +--------------------------------------------------------------------+ - -bool -Campaign::InCutscene() const -{ - Starshatter* stars = Starshatter::GetInstance(); - return stars ? stars->InCutscene() : false; -} - -bool -Campaign::IsDynamic() const -{ - return campaign_id >= DYNAMIC_CAMPAIGN && - campaign_id < SINGLE_MISSIONS; -} - -bool -Campaign::IsTraining() const -{ - return campaign_id == TRAINING_CAMPAIGN; -} - -bool -Campaign::IsScripted() const -{ - return scripted; -} - -bool -Campaign::IsSequential() const -{ - return sequential; -} - -// +--------------------------------------------------------------------+ - -static CombatGroup* FindGroup(CombatGroup* g, int type, int id) -{ - if (g->Type() == type && g->GetID() == id) - return g; - - CombatGroup* result = 0; - - ListIter subgroup = g->GetComponents(); - while (++subgroup && !result) - result = FindGroup(subgroup.value(), type, id); - - return result; -} - -CombatGroup* -Campaign::FindGroup(int iff, int type, int id) -{ - CombatGroup* result = 0; - - ListIter combatant = combatants; - while (++combatant && !result) { - if (combatant->GetIFF() == iff) { - result = ::FindGroup(combatant->GetForce(), type, id); - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -static void FindGroups(CombatGroup* g, int type, CombatGroup* near_group, -List& groups) -{ - if (g->Type() == type && g->IntelLevel() > Intel::RESERVE) { - if (!near_group || g->GetAssignedZone() == near_group->GetAssignedZone()) - groups.append(g); - } - - ListIter subgroup = g->GetComponents(); - while (++subgroup) - FindGroups(subgroup.value(), type, near_group, groups); -} - -CombatGroup* -Campaign::FindGroup(int iff, int type, CombatGroup* near_group) -{ - CombatGroup* result = 0; - List groups; - - ListIter combatant = combatants; - while (++combatant) { - if (combatant->GetIFF() == iff) { - FindGroups(combatant->GetForce(), type, near_group, groups); - } - } - - if (groups.size() > 0) { - int index = (int) Random(0, groups.size()); - if (index >= groups.size()) index = groups.size() - 1; - result = groups[index]; - } - - return result; -} - -// +--------------------------------------------------------------------+ - -static void FindStrikeTargets(CombatGroup* g, CombatGroup* strike_group, -List& groups) -{ - if (!strike_group || !strike_group->GetAssignedZone()) return; - - if (g->IsStrikeTarget() && g->IntelLevel() > Intel::RESERVE) { - if (strike_group->GetAssignedZone() == g->GetAssignedZone() || - strike_group->GetAssignedZone()->HasRegion(g->GetRegion())) - groups.append(g); - } - - ListIter subgroup = g->GetComponents(); - while (++subgroup) - FindStrikeTargets(subgroup.value(), strike_group, groups); -} - -CombatGroup* -Campaign::FindStrikeTarget(int iff, CombatGroup* strike_group) -{ - CombatGroup* result = 0; - - List groups; - - ListIter combatant = GetCombatants(); - while (++combatant) { - if (combatant->GetIFF() != 0 && combatant->GetIFF() != iff) { - FindStrikeTargets(combatant->GetForce(), strike_group, groups); - } - } - - if (groups.size() > 0) { - int index = rand() % groups.size(); - result = groups[index]; - } - - return result; -} - -// +--------------------------------------------------------------------+ - -void -Campaign::CommitExpiredActions() -{ - ListIter iter = actions; - while (++iter) { - CombatAction* a = iter.value(); - - if (a->IsAvailable()) - a->SetStatus(CombatAction::COMPLETE); - } - - updateTime = time; -} - -// +--------------------------------------------------------------------+ - -int -Campaign::GetPlayerTeamScore() -{ - int score_us = 0; - int score_them = 0; - - if (player_group) { - int iff = player_group->GetIFF(); - - ListIter iter = combatants; - while (++iter) { - Combatant* c = iter.value(); - - if (iff <= 1) { - if (c->GetIFF() <= 1) - score_us += c->Score(); - else - score_them += c->Score(); - } - - else { - if (c->GetIFF() <= 1) - score_them += c->Score(); - else - score_us += c->Score(); - } - } - } - - return score_us - score_them; -} - -// +--------------------------------------------------------------------+ - -void -Campaign::SetStatus(int s) -{ - status = s; - - // record the win in player profile: - if (status == CAMPAIGN_SUCCESS) { - Player* player = Player::GetCurrentPlayer(); - - if (player) - player->SetCampaignComplete(campaign_id); - } - - if (status > CAMPAIGN_ACTIVE) { - ::Print("Campaign::SetStatus() destroying mission list at campaign end\n"); - missions.destroy(); - } -} - -// +--------------------------------------------------------------------+ - -static void GetCombatUnits(CombatGroup* g, List& units) -{ - if (g) { - ListIter unit = g->GetUnits(); - while (++unit) { - CombatUnit* u = unit.value(); - - if (u->Count() - u->DeadCount() > 0) - units.append(u); - } - - ListIter comp = g->GetComponents(); - while (++comp) { - CombatGroup* g2 = comp.value(); - - if (!g2->IsReserve()) - GetCombatUnits(g2, units); - } - } -} - -int -Campaign::GetAllCombatUnits(int iff, List& units) -{ - units.clear(); - - ListIter iter = combatants; - while (++iter) { - Combatant* c = iter.value(); - - if (iff < 0 || c->GetIFF() == iff) { - GetCombatUnits(c->GetForce(), units); - } - } - - return units.size(); -} diff --git a/Stars45/Campaign.h b/Stars45/Campaign.h deleted file mode 100644 index 1343fec..0000000 --- a/Stars45/Campaign.h +++ /dev/null @@ -1,281 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Campaign defines a strategic military scenario. This class - owns (or generates) the Mission list that defines the action - in the campaign. -*/ - -#ifndef Campaign_h -#define Campaign_h - -#include "Types.h" -#include "Bitmap.h" -#include "Geometry.h" -#include "Text.h" -#include "Term.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class CampaignPlan; -class Combatant; -class CombatAction; -class CombatEvent; -class CombatGroup; -class CombatUnit; -class CombatZone; -class DataLoader; -class Mission; -class MissionTemplate; -class StarSystem; - -// +--------------------------------------------------------------------+ - -class MissionInfo -{ -public: - static const char* TYPENAME() { return "MissionInfo"; } - - MissionInfo(); - ~MissionInfo(); - - int operator == (const MissionInfo& m) const { return id == m.id; } - int operator < (const MissionInfo& m) const { return id < m.id; } - int operator <= (const MissionInfo& m) const { return id <= m.id; } - - bool IsAvailable(); - - int id; - Text name; - Text player_info; - Text description; - Text system; - Text region; - Text script; - int start; - int type; - - int min_rank; - int max_rank; - int action_id; - int action_status; - int exec_once; - int start_before; - int start_after; - - Mission* mission; -}; - -class TemplateList -{ -public: - static const char* TYPENAME() { return "TemplateList"; } - - TemplateList(); - ~TemplateList(); - - int mission_type; - int group_type; - int index; - List missions; -}; - -// +--------------------------------------------------------------------+ - -class Campaign -{ -public: - static const char* TYPENAME() { return "Campaign"; } - - enum CONSTANTS { - TRAINING_CAMPAIGN = 1, - DYNAMIC_CAMPAIGN, - MOD_CAMPAIGN = 100, - SINGLE_MISSIONS = 1000, - MULTIPLAYER_MISSIONS, - CUSTOM_MISSIONS, - - NUM_IMAGES = 6 - }; - - enum STATUS { - CAMPAIGN_INIT, - CAMPAIGN_ACTIVE, - CAMPAIGN_SUCCESS, - CAMPAIGN_FAILED - }; - - Campaign(int id, const char* name=0); - Campaign(int id, const char* name, const char* path); - virtual ~Campaign(); - - int operator == (const Campaign& s) const { return name == s.name; } - int operator < (const Campaign& s) const { return campaign_id < s.campaign_id; } - - // operations: - virtual void Load(); - virtual void Prep(); - virtual void Start(); - virtual void ExecFrame(); - virtual void Unload(); - - virtual void Clear(); - virtual void CommitExpiredActions(); - virtual void LockoutEvents(int seconds); - virtual void CheckPlayerGroup(); - void CreatePlanners(); - - // accessors: - const char* Name() const { return name; } - const char* Description() const { return description; } - const char* Path() const { return path; } - - const char* Situation() const { return situation; } - const char* Orders() const { return orders; } - - void SetSituation(const char* s) { situation = s; } - void SetOrders(const char* o) { orders = o; } - - int GetPlayerTeamScore(); - List& GetMissionList() { return missions; } - List& GetCombatants() { return combatants; } - List& GetZones() { return zones; } - List& GetSystemList() { return systems; } - List& GetActions() { return actions; } - List& GetEvents() { return events; } - CombatEvent* GetLastEvent(); - - CombatAction* FindAction(int id); - - int CountNewEvents() const; - - int GetPlayerIFF(); - CombatGroup* GetPlayerGroup() { return player_group; } - void SetPlayerGroup(CombatGroup* pg); - CombatUnit* GetPlayerUnit() { return player_unit; } - void SetPlayerUnit(CombatUnit* pu); - - Combatant* GetCombatant(const char* name); - CombatGroup* FindGroup(int iff, int type, int id); - CombatGroup* FindGroup(int iff, int type, CombatGroup* near_group=0); - CombatGroup* FindStrikeTarget(int iff, CombatGroup* strike_group); - - StarSystem* GetSystem(const char* sys); - CombatZone* GetZone(const char* rgn); - MissionInfo* CreateNewMission(); - void DeleteMission(int id); - Mission* GetMission(); - Mission* GetMission(int id); - Mission* GetMissionByFile(const char* filename); - MissionInfo* GetMissionInfo(int id); - MissionInfo* FindMissionTemplate(int msn_type, CombatGroup* player_group); - void ReloadMission(int id); - void LoadNetMission(int id, const char* net_mission); - void StartMission(); - void RollbackMission(); - - void SetCampaignId(int id); - int GetCampaignId() const { return campaign_id; } - void SetMissionId(int id); - int GetMissionId() const { return mission_id; } - Bitmap* GetImage(int n) { return &image[n]; } - long double GetTime() const { return time; } - long double GetStartTime() const { return startTime; } - void SetStartTime(long double t) { startTime = t; } - long double GetLoadTime() const { return loadTime; } - void SetLoadTime(long double t) { loadTime = t; } - long double GetUpdateTime() const { return updateTime; } - void SetUpdateTime(long double t) { updateTime = t; } - - bool InCutscene() const; - bool IsDynamic() const; - bool IsTraining() const; - bool IsScripted() const; - bool IsSequential() const; - bool IsSaveGame() const { return loaded_from_savegame; } - void SetSaveGame(bool s) { loaded_from_savegame = s; } - - bool IsActive() const { return status == CAMPAIGN_ACTIVE; } - bool IsComplete() const { return status == CAMPAIGN_SUCCESS; } - bool IsFailed() const { return status == CAMPAIGN_FAILED; } - void SetStatus(int s); - int GetStatus() const { return status; } - - int GetAllCombatUnits(int iff, List& units); - - static void Initialize(); - static void Close(); - static Campaign* GetCampaign(); - static List& - GetAllCampaigns(); - static int GetLastCampaignId(); - static Campaign* SelectCampaign(const char* name); - static Campaign* CreateCustomCampaign(const char* name, const char* path); - - static long double Stardate(); - -protected: - void LoadCampaign(DataLoader* loader, bool full=false); - void LoadTemplateList(DataLoader* loader); - void LoadMissionList(DataLoader* loader); - void LoadCustomMissions(DataLoader* loader); - void ParseGroup(TermStruct* val, - CombatGroup* force, - CombatGroup* clone, - const char* filename); - void ParseAction(TermStruct* val, - const char* filename); - CombatGroup* CloneOver(CombatGroup* force, - CombatGroup* clone, - CombatGroup* group); - void SelectDefaultPlayerGroup(CombatGroup* g, int type); - TemplateList* GetTemplateList(int msn_type, int grp_type); - - // attributes: - int campaign_id; - int status; - char filename[64]; - char path[64]; - Text name; - Text description; - Text situation; - Text orders; - Bitmap image[NUM_IMAGES]; - - bool scripted; - bool sequential; - bool loaded_from_savegame; - - List combatants; - List systems; - List zones; - List planners; - List missions; - List templates; - List actions; - List events; - CombatGroup* player_group; - CombatUnit* player_unit; - - int mission_id; - Mission* mission; - Mission* net_mission; - - long double time; - long double loadTime; - long double startTime; - long double updateTime; - int lockout; -}; - -#endif // Campaign_h - diff --git a/Stars45/CampaignMissionFighter.cpp b/Stars45/CampaignMissionFighter.cpp deleted file mode 100644 index be39d58..0000000 --- a/Stars45/CampaignMissionFighter.cpp +++ /dev/null @@ -1,2154 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignMissionFighter generates missions and mission - info for the player's FIGHTER SQUADRON as part of a - dynamic campaign. -*/ - -#include "CampaignMissionFighter.h" -#include "CampaignMissionRequest.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAssignment.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Callsign.h" -#include "Galaxy.h" -#include "Mission.h" -#include "MissionTemplate.h" -#include "Instruction.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Starshatter.h" -#include "StarSystem.h" -#include "Player.h" - -#include "ContentBundle.h" -#include "Random.h" - -static int pkg_id = 1000; -extern int dump_missions; - -// +--------------------------------------------------------------------+ - -CampaignMissionFighter::CampaignMissionFighter(Campaign* c) - : campaign(c), squadron(0), mission(0), player_elem(0), - strike_group(0), strike_target(0), prime_target(0), - carrier_elem(0), ward(0), escort(0), airborne(false), airbase(false), - ownside(0), enemy(-1), mission_type(0), mission_info(0) -{ - if (!campaign || !campaign->GetPlayerGroup()) { - ::Print("ERROR - CMF campaign=0x%08x player_group=0x%08x\n", - campaign, (DWORD) campaign?campaign->GetPlayerGroup():0); - return; - } - - CombatGroup* player_group = campaign->GetPlayerGroup(); - - switch (player_group->Type()) { - case CombatGroup::WING: { - CombatGroup* wing = player_group; - ListIter iter = wing->GetComponents(); - - while (++iter) { - if (iter->Type() == CombatGroup::FIGHTER_SQUADRON) { - squadron = iter.value(); - } - } - } - break; - - case CombatGroup::FIGHTER_SQUADRON: - case CombatGroup::INTERCEPT_SQUADRON: - case CombatGroup::ATTACK_SQUADRON: - squadron = player_group; - break; - - default: - ::Print("ERROR - CMF invalid player group: %s IFF %d\n", - player_group->GetDescription(), - player_group->GetIFF()); - break; - } - - if (squadron) { - CombatGroup* carrier = squadron->FindCarrier(); - - if (carrier && carrier->Type() == CombatGroup::STARBASE) { - airbase = true; - } - } -} - -CampaignMissionFighter::~CampaignMissionFighter() {} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::CreateMission(CampaignMissionRequest* req) -{ - if (!campaign || !squadron || !req) - return; - - ::Print("\n-----------------------------------------------\n"); - if (req->Script().length()) - ::Print("CMF CreateMission() request: %s '%s'\n", - Mission::RoleName(req->Type()), - (const char*) req->Script()); - - else - ::Print("CMF CreateMission() request: %s %s\n", - Mission::RoleName(req->Type()), - req->GetObjective() ? req->GetObjective()->Name().data() : "(no target)"); - - request = req; - mission_info = 0; - - if (request->GetPrimaryGroup()) { - switch (request->GetPrimaryGroup()->Type()) { - case CombatGroup::FIGHTER_SQUADRON: - case CombatGroup::INTERCEPT_SQUADRON: - case CombatGroup::ATTACK_SQUADRON: - squadron = request->GetPrimaryGroup(); - break; - } - } - - ownside = squadron->GetIFF(); - - for (int i = 0; i < campaign->GetCombatants().size(); i++) { - int iff = campaign->GetCombatants().at(i)->GetIFF(); - if (iff > 0 && iff != ownside) { - enemy = iff; - break; - } - } - - static int id_key = 1; - GenerateMission(id_key++); - DefineMissionObjectives(); - - MissionInfo* info = DescribeMission(); - - if (info) { - campaign->GetMissionList().append(info); - - ::Print("CMF Created %03d '%s' %s\n\n", - info->id, - (const char*) info->name, - Mission::RoleName(mission->Type())); - - if (dump_missions) { - Text script = mission->Serialize(); - char fname[32]; - - sprintf_s(fname, "msn%03d.def", info->id); - FILE* f; - fopen_s(&f, fname, "wb"); - if (f) { - fprintf(f, "%s\n", script.data()); - fclose(f); - } - } - } - else { - ::Print("CMF failed to create mission.\n"); - } -} - -// +--------------------------------------------------------------------+ - -Mission* -CampaignMissionFighter::GenerateMission(int id) -{ - bool found = false; - - SelectType(); - - if (request && request->Script().length()) { - MissionTemplate* mt = new MissionTemplate(id, request->Script(), campaign->Path()); - if (mt) - mt->SetPlayerSquadron(squadron); - mission = mt; - found = true; - } - - else { - mission_info = campaign->FindMissionTemplate(mission_type, squadron); - found = mission_info != 0; - - if (found) { - MissionTemplate* mt = new MissionTemplate(id, mission_info->script, campaign->Path()); - if (mt) - mt->SetPlayerSquadron(squadron); - mission = mt; - } - else { - mission = new Mission(id); - if (mission) - mission->SetType(mission_type); - } - } - - if (!mission) { - Exit(); - return 0; - } - - char name[64]; - sprintf_s(name, "Fighter Mission %d", id); - - mission->SetName(name); - mission->SetTeam(squadron->GetIFF()); - mission->SetStart(request->StartTime()); - - SelectRegion(); - GenerateStandardElements(); - CreatePatrols(); - - if (!found) { - GenerateMissionElements(); - mission->SetOK(true); - mission->Validate(); - } - - else { - mission->Load(); - - if (mission->IsOK()) { - player_elem = mission->GetPlayer(); - prime_target = mission->GetTarget(); - ward = mission->GetWard(); - - Player* p = Player::GetCurrentPlayer(); - - if (player_elem && p) - player_elem->SetAlert(!p->FlyingStart()); - } - - // if there was a problem, scrap the mission - // and start over: - else { - delete mission; - - mission = new Mission(id); - mission->SetType(mission_type); - mission->SetName(name); - mission->SetTeam(squadron->GetIFF()); - mission->SetStart(request->StartTime()); - - SelectRegion(); - GenerateStandardElements(); - GenerateMissionElements(); - - mission->SetOK(true); - mission->Validate(); - } - } - - return mission; -} - -// +--------------------------------------------------------------------+ - -bool -CampaignMissionFighter::IsGroundObjective(CombatGroup* obj) -{ - bool ground = false; - - if (obj) { - CombatGroup* pgroup = campaign->GetPlayerGroup(); - - if (pgroup) { - CombatZone* zone = pgroup->GetAssignedZone(); - - if (zone) { - StarSystem* system = campaign->GetSystem(zone->System()); - - if (system) { - OrbitalRegion* region = system->FindRegion(obj->GetRegion()); - - if (region && region->Type() == Orbital::TERRAIN) { - ground = true; - } - } - } - } - } - - return ground; -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::SelectType() -{ - int type = Mission::PATROL; - - if (request) { - type = request->Type(); - if (type == Mission::STRIKE) { - strike_group = request->GetPrimaryGroup(); - - // verify that objective is a ground target: - if (!IsGroundObjective(request->GetObjective())) { - type = Mission::ASSAULT; - } - } - - else if (type == Mission::ESCORT_STRIKE) { - strike_group = request->GetSecondaryGroup(); - if (!strike_group || strike_group->CalcValue() < 1) { - type = Mission::SWEEP; - strike_group = 0; - } - } - } - - mission_type = type; -} - -void -CampaignMissionFighter::SelectRegion() -{ - CombatZone* zone = squadron->GetAssignedZone(); - - if (!zone) - zone = squadron->GetCurrentZone(); - - if (zone) { - mission->SetStarSystem(campaign->GetSystem(zone->System())); - mission->SetRegion(*zone->GetRegions().at(0)); - - orb_region = mission->GetRegion(); - - if (zone->GetRegions().size() > 1) { - air_region = *zone->GetRegions().at(1); - - StarSystem* system = mission->GetStarSystem(); - OrbitalRegion* rgn = 0; - - if (system) - rgn = system->FindRegion(air_region); - - if (!rgn || rgn->Type() != Orbital::TERRAIN) - air_region = ""; - } - - if (air_region.length() > 0) { - if (request && IsGroundObjective(request->GetObjective())) { - airborne = true; - } - - else if (mission->Type() >= Mission::AIR_PATROL && - mission->Type() <= Mission::AIR_INTERCEPT) { - airborne = true; - } - - else if (mission->Type() == Mission::STRIKE || - mission->Type() == Mission::ESCORT_STRIKE) { - if (strike_group) { - strike_target = campaign->FindStrikeTarget(ownside, strike_group); - - if (strike_target && strike_target->GetRegion() == air_region) - airborne = true; - } - } - - if (airbase) { - mission->SetRegion(air_region); - } - } - } - - else { - ::Print("WARNING: CMF - No zone for '%s'\n", squadron->Name().data()); - - StarSystem* s = campaign->GetSystemList()[0]; - - mission->SetStarSystem(s); - mission->SetRegion(s->Regions()[0]->Name()); - } - - if (!airborne) { - switch (mission->Type()) { - case Mission::AIR_PATROL: mission->SetType(Mission::PATROL); break; - case Mission::AIR_SWEEP: mission->SetType(Mission::SWEEP); break; - case Mission::AIR_INTERCEPT: mission->SetType(Mission::INTERCEPT); break; - default: break; - } - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::GenerateStandardElements() -{ - ListIter z_iter = campaign->GetZones(); - while (++z_iter) { - CombatZone* z = z_iter.value(); - - ListIter iter = z->GetForces(); - while (++iter) { - ZoneForce* force = iter.value(); - ListIter group = force->GetGroups(); - - while (++group) { - CombatGroup* g = group.value(); - - switch (g->Type()) { - case CombatGroup::INTERCEPT_SQUADRON: - case CombatGroup::FIGHTER_SQUADRON: - case CombatGroup::ATTACK_SQUADRON: - case CombatGroup::LCA_SQUADRON: - CreateSquadron(g); - break; - - case CombatGroup::DESTROYER_SQUADRON: - case CombatGroup::BATTLE_GROUP: - case CombatGroup::CARRIER_GROUP: - CreateElements(g); - break; - - case CombatGroup::MINEFIELD: - case CombatGroup::BATTERY: - case CombatGroup::MISSILE: - case CombatGroup::STATION: - case CombatGroup::STARBASE: - case CombatGroup::SUPPORT: - case CombatGroup::COURIER: - case CombatGroup::MEDICAL: - case CombatGroup::SUPPLY: - case CombatGroup::REPAIR: - CreateElements(g); - break; - - case CombatGroup::CIVILIAN: - case CombatGroup::WAR_PRODUCTION: - case CombatGroup::FACTORY: - case CombatGroup::REFINERY: - case CombatGroup::RESOURCE: - case CombatGroup::INFRASTRUCTURE: - case CombatGroup::TRANSPORT: - case CombatGroup::NETWORK: - case CombatGroup::HABITAT: - case CombatGroup::STORAGE: - case CombatGroup::NON_COM: - CreateElements(g); - break; - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::GenerateMissionElements() -{ - CreateWards(); - CreatePlayer(squadron); - CreateTargets(); - CreateEscorts(); - - if (player_elem) { - Instruction* obj = new Instruction(mission->GetRegion(), - Point(0,0,0), - Instruction::RTB); - - if (obj) - player_elem->AddObjective(obj); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::CreateElements(CombatGroup* g) -{ - MissionElement* elem = 0; - List& units = g->GetUnits(); - - CombatUnit* cmdr = 0; - - for (int i = 0; i < units.size(); i++) { - elem = CreateSingleElement(g, units[i]); - - if (elem) { - if (!cmdr) { - cmdr = units[i]; - } - else { - elem->SetCommander(cmdr->Name()); - - if (g->Type() == CombatGroup::CARRIER_GROUP && - elem->MissionRole() == Mission::ESCORT) { - Instruction* obj = new Instruction(Instruction::ESCORT, cmdr->Name()); - if (obj) - elem->AddObjective(obj); - } - } - - mission->AddElement(elem); - } - } -} - -MissionElement* -CampaignMissionFighter::CreateSingleElement(CombatGroup* g, CombatUnit* u) -{ - if (!g || g->IsReserve()) return 0; - if (!u || u->LiveCount() < 1) return 0; - - // make sure this unit is actually in the right star system: - Galaxy* galaxy = Galaxy::GetInstance(); - if (galaxy) { - if (galaxy->FindSystemByRegion(u->GetRegion()) != - galaxy->FindSystemByRegion(squadron->GetRegion())) { - return 0; - } - } - - // make sure this unit isn't already in the mission: - ListIter e_iter = mission->GetElements(); - while (++e_iter) { - MissionElement* elem = e_iter.value(); - - if (elem->GetCombatUnit() == u) - return 0; - } - - MissionElement* elem = new MissionElement; - if (!elem) { - Exit(); - return 0; - } - - if (u->Name().length()) - elem->SetName(u->Name()); - else - elem->SetName(u->DesignName()); - - elem->SetElementID(pkg_id++); - - elem->SetDesign(u->GetDesign()); - elem->SetCount(u->LiveCount()); - elem->SetIFF(u->GetIFF()); - elem->SetIntelLevel(g->IntelLevel()); - elem->SetRegion(u->GetRegion()); - elem->SetHeading(u->GetHeading()); - - int unit_index = g->GetUnits().index(u); - Point base_loc = u->Location(); - bool exact = u->IsStatic(); // exact unit-level placement - - if (base_loc.length() < 1) { - base_loc = g->Location(); - exact = false; - } - - if (unit_index < 0 || unit_index > 0 && !exact) { - Point loc = RandomDirection(); - - if (!u->IsStatic()) { - while (fabs(loc.y) > fabs(loc.x)) - loc = RandomDirection(); - - loc *= 10e3 + 9e3 * unit_index; - } - else { - loc *= 2e3 + 2e3 * unit_index; - } - - elem->SetLocation(base_loc + loc); - } - else { - elem->SetLocation(base_loc); - } - - if (g->Type() == CombatGroup::CARRIER_GROUP) { - if (u->Type() == Ship::CARRIER) { - elem->SetMissionRole(Mission::FLIGHT_OPS); - - if (squadron && elem->GetCombatGroup() == squadron->FindCarrier()) - carrier_elem = elem; - - else if (!carrier_elem && u->GetIFF() == squadron->GetIFF()) - carrier_elem = elem; - } - else { - elem->SetMissionRole(Mission::ESCORT); - } - } - else if (u->Type() == Ship::STATION || - u->Type() == Ship::STARBASE) { - elem->SetMissionRole(Mission::FLIGHT_OPS); - - if (squadron && elem->GetCombatGroup() == squadron->FindCarrier()) { - carrier_elem = elem; - - if (u->Type() == Ship::STARBASE) - airbase = true; - } - } - else if (u->Type() == Ship::FARCASTER) { - elem->SetMissionRole(Mission::OTHER); - - // link farcaster to other terminus: - Text name = u->Name(); - int dash = -1; - - for (int i = 0; i < (int) name.length(); i++) - if (name[i] == '-') - dash = i; - - Text src = name.substring(0, dash); - Text dst = name.substring(dash+1, name.length() - (dash+1)); - - Instruction* obj = new Instruction(Instruction::VECTOR, dst + "-" + src); - elem->AddObjective(obj); - } - else if ((u->Type() & Ship::STARSHIPS) != 0) { - elem->SetMissionRole(Mission::FLEET); - } - - elem->SetCombatGroup(g); - elem->SetCombatUnit(u); - - return elem; -} - -CombatUnit* -CampaignMissionFighter::FindCarrier(CombatGroup* g) -{ - CombatGroup* carrier = g->FindCarrier(); - - if (carrier && carrier->GetUnits().size()) { - MissionElement* carrier_elem = mission->FindElement(carrier->Name()); - - if (carrier_elem) - return carrier->GetUnits().at(0); - } - - return 0; -} - -void -CampaignMissionFighter::CreateSquadron(CombatGroup* g) -{ - if (!g || g->IsReserve()) return; - - CombatUnit* fighter = g->GetUnits().at(0); - CombatUnit* carrier = FindCarrier(g); - - if (!fighter || !carrier) return; - - int live_count = fighter->LiveCount(); - int maint_count = (live_count > 4) ? live_count / 2 : 0; - - MissionElement* elem = new MissionElement; - - if (!elem) { - Exit(); - return; - } - - elem->SetName(g->Name()); - elem->SetElementID(pkg_id++); - - elem->SetDesign(fighter->GetDesign()); - elem->SetCount(fighter->Count()); - elem->SetDeadCount(fighter->DeadCount()); - elem->SetMaintCount(maint_count); - elem->SetIFF(fighter->GetIFF()); - elem->SetIntelLevel(g->IntelLevel()); - elem->SetRegion(fighter->GetRegion()); - - elem->SetCarrier(carrier->Name()); - elem->SetCommander(carrier->Name()); - elem->SetLocation(carrier->Location() + RandomPoint()); - - elem->SetCombatGroup(g); - elem->SetCombatUnit(fighter); - - mission->AddElement(elem); -} - -void -CampaignMissionFighter::CreatePlayer(CombatGroup* g) -{ - int pkg_size = 2; - - if (mission->Type() == Mission::STRIKE || mission->Type() == Mission::ASSAULT) { - if (request && request->GetObjective()) { - int tgt_type = request->GetObjective()->Type(); - - if (tgt_type >= CombatGroup::FLEET && tgt_type <= CombatGroup::CARRIER_GROUP) - pkg_size = 4; - - if (tgt_type == CombatGroup::STATION || tgt_type == CombatGroup::STARBASE) - pkg_size = 4; - } - } - - MissionElement* elem = CreateFighterPackage(g, pkg_size, mission->Type()); - - if (elem) { - Player* p = Player::GetCurrentPlayer(); - elem->SetAlert(p ? !p->FlyingStart() : true); - elem->SetPlayer(1); - - if (ward) { - Point approach = elem->Location() - ward->Location(); - approach.Normalize(); - - Point pickup = ward->Location() + approach * 50e3; - double delta = (pickup - elem->Location()).length(); - - if (delta > 30e3) { - Instruction* n = new Instruction(elem->Region(), pickup, Instruction::ESCORT); - n->SetTarget(ward->Name()); - n->SetSpeed(750); - elem->AddNavPoint(n); - } - - Instruction* obj = new Instruction(Instruction::ESCORT, ward->Name()); - - switch (mission->Type()) { - case Mission::ESCORT_FREIGHT: - obj->SetTargetDesc(Text("the star freighter ") + ward->Name()); - break; - - case Mission::ESCORT_SHUTTLE: - obj->SetTargetDesc(Text("the shuttle ") + ward->Name()); - break; - - case Mission::ESCORT_STRIKE: - obj->SetTargetDesc(Text("the ") + ward->Name() + Text(" strike package")); - break; - - case Mission::DEFEND: - obj->SetTargetDesc(Text("the ") + ward->Name()); - break; - - default: - if (ward->GetCombatGroup()) { - obj->SetTargetDesc(Text("the ") + ward->GetCombatGroup()->GetDescription()); - } - else { - obj->SetTargetDesc(Text("the ") + ward->Name()); - } - break; - } - - elem->AddObjective(obj); - } - - mission->AddElement(elem); - - player_elem = elem; - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::CreatePatrols() -{ - List patrols; - - ListIter iter = mission->GetElements(); - while (++iter) { - MissionElement* squad_elem = iter.value(); - CombatGroup* squadron = squad_elem->GetCombatGroup(); - CombatUnit* unit = squad_elem->GetCombatUnit(); - - if (!squad_elem->IsSquadron() || !squadron || !unit || unit->LiveCount() < 4) - continue; - - if (squadron->Type() == CombatGroup::INTERCEPT_SQUADRON || - squadron->Type() == CombatGroup::FIGHTER_SQUADRON) { - - StarSystem* system = mission->GetStarSystem(); - CombatGroup* base = squadron->FindCarrier(); - - if (!base) - continue; - - OrbitalRegion* region = system->FindRegion(base->GetRegion()); - - if (!region) - continue; - - int patrol_type = Mission::PATROL; - Point base_loc; - - if (region->Type() == Orbital::TERRAIN) { - patrol_type = Mission::AIR_PATROL; - - if (RandomChance(2,3)) - continue; - } - - base_loc = base->Location() + RandomPoint() * 1.5; - - if (region->Type() == Orbital::TERRAIN) - base_loc += Point(0, 0, 14.0e3); - - MissionElement* elem = CreateFighterPackage(squadron, 2, patrol_type); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(base->GetRegion()); - elem->SetLocation(base_loc); - patrols.append(elem); - } - } - } - - iter.attach(patrols); - while (++iter) - mission->AddElement(iter.value()); -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::CreateWards() -{ - switch (mission->Type()) { - case Mission::ESCORT_FREIGHT: CreateWardFreight(); break; - case Mission::ESCORT_SHUTTLE: CreateWardShuttle(); break; - case Mission::ESCORT_STRIKE: CreateWardStrike(); break; - default: break; - } -} - -void -CampaignMissionFighter::CreateWardFreight() -{ - if (!mission || !mission->GetStarSystem()) return; - - CombatUnit* carrier = FindCarrier(squadron); - CombatGroup* freight = 0; - - if (request) - freight = request->GetObjective(); - - if (!freight) - freight = campaign->FindGroup(ownside, CombatGroup::FREIGHT); - - if (!freight || freight->CalcValue() < 1) return; - - CombatUnit* unit = freight->GetNextUnit(); - if (!unit) return; - - MissionElement* elem = CreateSingleElement(freight, unit); - if (!elem) return; - - elem->SetMissionRole(Mission::CARGO); - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(squadron->GetRegion()); - - if (carrier) - elem->SetLocation(carrier->Location() + RandomPoint() * 2); - - ward = elem; - mission->AddElement(elem); - - - StarSystem* system = mission->GetStarSystem(); - OrbitalRegion* rgn1 = system->FindRegion(elem->Region()); - Point delta = rgn1->Location() - rgn1->Primary()->Location(); - Point npt_loc = elem->Location(); - Instruction* n = 0; - - delta.Normalize(); - delta *= 200.0e3; - - npt_loc += delta; - - n = new Instruction(elem->Region(), - npt_loc, - Instruction::VECTOR); - - if (n) { - n->SetSpeed(500); - elem->AddNavPoint(n); - } - - Text rgn2 = elem->Region(); - List& zones = campaign->GetZones(); - if (zones[zones.size()-1]->HasRegion(rgn2)) - rgn2 = *zones[0]->GetRegions()[0]; - else - rgn2 = *zones[zones.size()-1]->GetRegions()[0]; - - n = new Instruction(rgn2, - Point(0, 0, 0), - Instruction::VECTOR); - - if (n) { - n->SetSpeed(750); - elem->AddNavPoint(n); - } -} - -void -CampaignMissionFighter::CreateWardShuttle() -{ - if (!mission || !mission->GetStarSystem()) return; - - CombatUnit* carrier = FindCarrier(squadron); - CombatGroup* shuttle = campaign->FindGroup(ownside, CombatGroup::LCA_SQUADRON); - - if (!shuttle || shuttle->CalcValue() < 1) return; - - List& units = shuttle->GetUnits(); - - MissionElement* elem = CreateFighterPackage(shuttle, 1, Mission::CARGO); - if (!elem) return; - - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(orb_region); - elem->Loadouts().destroy(); - - if (carrier) - elem->SetLocation(carrier->Location() + RandomPoint() * 2); - - ward = elem; - mission->AddElement(elem); - - // if there is terrain nearby, then have the shuttle fly down to it: - if (air_region.length() > 0) { - StarSystem* system = mission->GetStarSystem(); - OrbitalRegion* rgn1 = system->FindRegion(elem->Region()); - Point delta = rgn1->Location() - rgn1->Primary()->Location(); - Point npt_loc = elem->Location(); - Instruction* n = 0; - - delta.Normalize(); - delta *= -200.0e3; - - npt_loc += delta; - - n = new Instruction(elem->Region(), - npt_loc, - Instruction::VECTOR); - - if (n) { - n->SetSpeed(500); - elem->AddNavPoint(n); - } - - n = new Instruction(air_region, - Point(0, 0, 10.0e3), - Instruction::VECTOR); - - if (n) { - n->SetSpeed(500); - elem->AddNavPoint(n); - } - } - - // otherwise, escort the shuttle in for a landing on the carrier: - else if (carrier) { - Point src = carrier->Location() + RandomDirection() * 150e3; - Point dst = carrier->Location() + RandomDirection() * 25e3; - Instruction* n = 0; - - elem->SetLocation(src); - - n = new Instruction(elem->Region(), dst, Instruction::DOCK); - if (n) { - n->SetTarget(carrier->Name()); - n->SetSpeed(500); - elem->AddNavPoint(n); - } - } -} - -void -CampaignMissionFighter::CreateWardStrike() -{ - if (!mission || !mission->GetStarSystem()) return; - - CombatUnit* carrier = FindCarrier(squadron); - CombatGroup* strike = strike_group; - - if (!strike || strike->CalcValue() < 1) return; - - List& units = strike->GetUnits(); - - int type = Mission::ASSAULT; - - if (airborne) - type = Mission::STRIKE; - - MissionElement* elem = CreateFighterPackage(strike, 2, type); - if (!elem) return; - - if (strike->GetParent() == squadron->GetParent()) { - Player* p = Player::GetCurrentPlayer(); - elem->SetAlert(p ? !p->FlyingStart() : true); - } - - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(squadron->GetRegion()); - - if (strike_target) { - Instruction* obj = new Instruction(Instruction::ASSAULT, strike_target->Name()); - - if (obj) { - if (airborne) - obj->SetAction(Instruction::STRIKE); - - elem->AddObjective(obj); - } - } - - ward = elem; - mission->AddElement(elem); - - - StarSystem* system = mission->GetStarSystem(); - OrbitalRegion* rgn1 = system->FindRegion(elem->Region()); - Point delta = rgn1->Location() - rgn1->Primary()->Location(); - Point npt_loc = elem->Location(); - Instruction* n = 0; - - if (airborne) { - delta.Normalize(); - delta *= -30.0e3; - npt_loc += delta; - - n = new Instruction(elem->Region(), - npt_loc, - Instruction::VECTOR); - if (n) { - n->SetSpeed(500); - elem->AddNavPoint(n); - } - - npt_loc = Point(0, 0, 10.0e3); - - n = new Instruction(air_region, - npt_loc, - Instruction::VECTOR); - if (n) { - n->SetSpeed(500); - elem->AddNavPoint(n); - } - } - - // IP: - if (strike_target) { - delta = strike_target->Location() - npt_loc; - delta.Normalize(); - delta *= 15.0e3; - - npt_loc = strike_target->Location() + delta + Point(0, 0, 8.0e3); - - n = new Instruction(strike_target->GetRegion(), - npt_loc, - Instruction::STRIKE); - if (n) { - n->SetSpeed(500); - elem->AddNavPoint(n); - } - } - - if (airborne) { - n = new Instruction(air_region, - Point(0, 0, 30.0e3), - Instruction::VECTOR); - if (n) { - n->SetSpeed(500); - elem->AddNavPoint(n); - } - } - - if (carrier) { - n = new Instruction(elem->Region(), - carrier->Location() - Point(0, -20.0e3, 0), - Instruction::VECTOR); - if (n) { - n->SetSpeed(500); - elem->AddNavPoint(n); - } - } - - // find the strike target element: - if (strike_target) { - prime_target = mission->FindElement(strike_target->Name()); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::CreateEscorts() -{ - bool escort_needed = false; - - if (mission->Type() == Mission::STRIKE || mission->Type() == Mission::ASSAULT) { - if (request && request->GetObjective()) { - int tgt_type = request->GetObjective()->Type(); - - if (tgt_type == CombatGroup::CARRIER_GROUP || - tgt_type == CombatGroup::STATION || - tgt_type == CombatGroup::STARBASE) - - escort_needed = true; - } - } - - if (player_elem && escort_needed) { - CombatGroup* s = FindSquadron(ownside, CombatGroup::INTERCEPT_SQUADRON); - - if (s && s->IsAssignable()) { - MissionElement* elem = CreateFighterPackage(s, 2, Mission::ESCORT_STRIKE); - - if (elem) { - Point offset = Point(2.0e3, 2.0e3, 1.0e3); - - ListIter npt_iter = player_elem->NavList(); - while (++npt_iter) { - Instruction* npt = npt_iter.value(); - Instruction* n = new Instruction(npt->RegionName(), - npt->Location() + offset, - Instruction::ESCORT); - if (n) { - n->SetSpeed(npt->Speed()); - elem->AddNavPoint(n); - } - } - - mission->AddElement(elem); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::CreateTargets() -{ - switch (mission->Type()) { - default: - case Mission::DEFEND: - case Mission::PATROL: CreateTargetsPatrol(); break; - case Mission::SWEEP: CreateTargetsSweep(); break; - case Mission::INTERCEPT: CreateTargetsIntercept(); break; - case Mission::ESCORT_FREIGHT: CreateTargetsFreightEscort(); break; - - case Mission::ESCORT: - case Mission::ESCORT_SHUTTLE: CreateTargetsShuttleEscort(); break; - case Mission::ESCORT_STRIKE: CreateTargetsStrikeEscort(); break; - case Mission::STRIKE: CreateTargetsStrike(); break; - case Mission::ASSAULT: CreateTargetsAssault(); break; - } -} - -void -CampaignMissionFighter::CreateTargetsPatrol() -{ - if (!squadron || !player_elem) return; - - Text region = squadron->GetRegion(); - Point base_loc = player_elem->Location(); - Point patrol_loc; - - if (airborne) - base_loc = RandomPoint() * 2 + Point(0, 0, 12.0e3); - - else if (carrier_elem) - base_loc = carrier_elem->Location(); - - if (airborne) { - if (!airbase) - PlanetaryInsertion(player_elem); - region = air_region; - patrol_loc = base_loc + - RandomDirection() * Random( 60e3, 100e3); - } - else { - patrol_loc = base_loc + - RandomDirection() * Random(110e3, 160e3); - } - - Instruction* n = new Instruction(region, - patrol_loc, - Instruction::PATROL); - if (n) - player_elem->AddNavPoint(n); - - int ntargets = (int) Random(2.0,5.1); - - while (ntargets > 0) { - int t = CreateRandomTarget(region, patrol_loc); - ntargets -= t; - if (t < 1) break; - } - - if (airborne && !airbase) { - OrbitalInsertion(player_elem); - } - - Instruction* obj = new Instruction(*n); - obj->SetTargetDesc("inbound enemy units"); - player_elem->AddObjective(obj); - - if (carrier_elem && !airborne) { - obj = new Instruction(Instruction::DEFEND, carrier_elem->Name()); - if (obj) { - obj->SetTargetDesc(Text("the ") + carrier_elem->Name() + " battle group"); - player_elem->AddObjective(obj); - } - } -} - -void -CampaignMissionFighter::CreateTargetsSweep() -{ - if (!squadron || !player_elem) return; - - double traverse = PI; - double a = Random(-PI/2, PI/2); - Point base_loc = player_elem->Location(); - Point sweep_loc = base_loc; - Text region = player_elem->Region(); - Instruction* n = 0; - - if (carrier_elem) - base_loc = carrier_elem->Location(); - - if (airborne) { - PlanetaryInsertion(player_elem); - region = air_region; - sweep_loc = RandomPoint() + Point(0, 0, 10.0e3); // keep it airborne! - } - - sweep_loc += Point(sin(a), -cos(a), 0) * 100.0e3; - - n = new Instruction(region, - sweep_loc, - Instruction::VECTOR); - if (n) { - n->SetSpeed(750); - player_elem->AddNavPoint(n); - } - - int index = 0; - int ntargets = 6; - - while (traverse > 0) { - double a1 = Random(PI/4, PI/2); - traverse -= a1; - a += a1; - - sweep_loc += Point(sin(a), -cos(a), 0) * 80.0e3; - - n = new Instruction(region, - sweep_loc, - Instruction::SWEEP); - if (n) { - n->SetSpeed(750); - n->SetFormation(Instruction::SPREAD); - player_elem->AddNavPoint(n); - } - - if (ntargets && RandomChance()) { - ntargets -= CreateRandomTarget(region, sweep_loc); - } - - index++; - } - - if (ntargets > 0) - CreateRandomTarget(region, sweep_loc); - - if (airborne && !airbase) { - OrbitalInsertion(player_elem); - region = player_elem->Region(); - } - - sweep_loc = base_loc; - sweep_loc.y += 30.0e3; - - n = new Instruction(region, - sweep_loc, - Instruction::VECTOR); - if (n) { - n->SetSpeed(750); - player_elem->AddNavPoint(n); - } - - Instruction* obj = new Instruction(region, - sweep_loc, - Instruction::SWEEP); - if (obj) { - obj->SetTargetDesc("enemy patrols"); - player_elem->AddObjective(obj); - } - - if (carrier_elem && !airborne) { - obj = new Instruction(Instruction::DEFEND, carrier_elem->Name()); - if (obj) { - obj->SetTargetDesc(Text("the ") + carrier_elem->Name() + " battle group"); - player_elem->AddObjective(obj); - } - } -} - -void -CampaignMissionFighter::CreateTargetsIntercept() -{ - if (!squadron || !player_elem) return; - - CombatUnit* carrier = FindCarrier(squadron); - CombatGroup* s = FindSquadron(enemy, CombatGroup::ATTACK_SQUADRON); - CombatGroup* s2 = FindSquadron(enemy, CombatGroup::FIGHTER_SQUADRON); - - if (!s || !s2) return; - - int ninbound = 2 + (int) (RandomIndex() < 5); - bool second = ninbound > 2; - Text attacker; - - while (ninbound--) { - MissionElement* elem = CreateFighterPackage(s, 4, Mission::ASSAULT); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->Loadouts().destroy(); - elem->Loadouts().append(new MissionLoad(-1, "Hvy Ship Strike")); - - if (carrier) { - Instruction* obj = new Instruction(Instruction::ASSAULT, carrier->Name()); - if (obj) { - elem->AddObjective(obj); - elem->SetLocation(carrier->Location() + RandomPoint() * 6); - } - } - else { - elem->SetLocation(squadron->Location() + RandomPoint() * 5); - } - - mission->AddElement(elem); - - attacker = elem->Name(); - - if (!prime_target) { - prime_target = elem; - Instruction* obj = new Instruction(Instruction::INTERCEPT, attacker); - if (obj) { - obj->SetTargetDesc(Text("inbound strike package '") + elem->Name() + "'"); - player_elem->AddObjective(obj); - } - } - - MissionElement* e2 = CreateFighterPackage(s2, 2, Mission::ESCORT); - if (e2) { - e2->SetIntelLevel(Intel::KNOWN); - e2->SetLocation(elem->Location() + RandomPoint() * 0.25); - - Instruction* obj = new Instruction(Instruction::ESCORT, elem->Name()); - if (obj) - e2->AddObjective(obj); - mission->AddElement(e2); - } - } - } - - if (second) { - // second friendly fighter package - CombatGroup* s = FindSquadron(ownside, CombatGroup::FIGHTER_SQUADRON); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 2, Mission::INTERCEPT); - if (elem) { - Player* p = Player::GetCurrentPlayer(); - elem->SetAlert(p ? !p->FlyingStart() : true); - - Instruction* obj = new Instruction(Instruction::INTERCEPT, attacker); - if (obj) - elem->AddObjective(obj); - mission->AddElement(elem); - } - } - } - - if (carrier && !airborne) { - Instruction* obj = new Instruction(Instruction::DEFEND, carrier->Name()); - if (obj) { - obj->SetTargetDesc(Text("the ") + carrier->Name() + " battle group"); - player_elem->AddObjective(obj); - } - } -} - -void -CampaignMissionFighter::CreateTargetsFreightEscort() -{ - if (!squadron || !player_elem) return; - - if (!ward) { - CreateTargetsPatrol(); - return; - } - - CombatUnit* carrier = FindCarrier(squadron); - CombatGroup* s = FindSquadron(enemy, CombatGroup::ATTACK_SQUADRON); - CombatGroup* s2 = FindSquadron(enemy, CombatGroup::FIGHTER_SQUADRON); - - if (!s) s = s2; - - if (!s || !s2) return; - - MissionElement* elem = CreateFighterPackage(s, 2, Mission::ASSAULT); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - - elem->SetLocation(ward->Location() + RandomPoint() * 5); - - Instruction* obj = new Instruction(Instruction::ASSAULT, ward->Name()); - if (obj) - elem->AddObjective(obj); - mission->AddElement(elem); - - MissionElement* e2 = CreateFighterPackage(s2, 2, Mission::ESCORT); - if (e2) { - e2->SetIntelLevel(Intel::KNOWN); - e2->SetLocation(elem->Location() + RandomPoint() * 0.25); - - Instruction* obj2 = new Instruction(Instruction::ESCORT, elem->Name()); - if (obj2) - e2->AddObjective(obj2); - mission->AddElement(e2); - } - } - - Instruction* obj3 = new Instruction(mission->GetRegion(), - Point(0,0,0), - Instruction::PATROL); - - if (obj3) { - obj3->SetTargetDesc("enemy patrols"); - player_elem->AddObjective(obj3); - } -} - -void -CampaignMissionFighter::CreateTargetsShuttleEscort() -{ - CreateTargetsFreightEscort(); -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::CreateTargetsStrikeEscort() -{ - if (!squadron || !player_elem) return; - - if (ward) { - Point offset = Point(2.0e3, 2.0e3, 1.0e3); - - ListIter npt_iter = ward->NavList(); - while (++npt_iter) { - Instruction* npt = npt_iter.value(); - Instruction* n = new Instruction(npt->RegionName(), - npt->Location() + offset, - Instruction::ESCORT); - if (n) { - n->SetSpeed(npt->Speed()); - player_elem->AddNavPoint(n); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::CreateTargetsStrike() -{ - if (!squadron || !player_elem) return; - - if (request && request->GetObjective()) - strike_target = request->GetObjective(); - - if (strike_target && strike_group) { - CreateElements(strike_target); - - ListIter e_iter = mission->GetElements(); - while (++e_iter) { - MissionElement* elem = e_iter.value(); - - if (elem->GetCombatGroup() == strike_target) { - prime_target = elem; - Instruction* obj = new Instruction(Instruction::STRIKE, elem->Name()); - if (obj) { - obj->SetTargetDesc(Text("preplanned target '") + elem->Name() + "'"); - player_elem->AddObjective(obj); - } - - // create flight plan: - RLoc rloc; - Point loc = Point(0, 0, 15e3); - Instruction* n = 0; - - PlanetaryInsertion(player_elem); - - // target approach and strike: - Point delta = prime_target->Location() - loc; - - if (delta.length() >= 100e3) { - Point mid = loc + delta * 0.5; - mid.z = 10.0e3; - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(mid); - rloc.SetDistance(20e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(90*DEGREES); - rloc.SetAzimuthVar(25*DEGREES); - - n = new Instruction(prime_target->Region(), - Point(), - Instruction::VECTOR); - if (n) { - n->SetSpeed(750); - n->GetRLoc() = rloc; - player_elem->AddNavPoint(n); - } - - loc = mid; - } - - delta = loc - prime_target->Location(); - delta.Normalize(); - delta *= 25.0e3; - - loc = prime_target->Location() + delta; - loc.z = 8.0e3; - - n = new Instruction(prime_target->Region(), - loc, - Instruction::STRIKE); - if (n) { - n->SetSpeed(500); - player_elem->AddNavPoint(n); - } - - // exeunt: - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(Point(0, 0, 30.0e3)); - rloc.SetDistance(50e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(-90*DEGREES); - rloc.SetAzimuthVar(25*DEGREES); - - n = new Instruction(prime_target->Region(), - Point(), - Instruction::VECTOR); - if (n) { - n->SetSpeed(750); - n->GetRLoc() = rloc; - player_elem->AddNavPoint(n); - } - - if (carrier_elem) { - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(carrier_elem->Location()); - rloc.SetDistance(60e3); - rloc.SetDistanceVar(10e3); - rloc.SetAzimuth(180*DEGREES); - rloc.SetAzimuthVar(30*DEGREES); - - n = new Instruction(carrier_elem->Region(), - Point(), - Instruction::RTB); - if (n) { - n->SetSpeed(750); - n->GetRLoc() = rloc; - player_elem->AddNavPoint(n); - } - } - - break; - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::CreateTargetsAssault() -{ - if (!squadron || !player_elem) return; - - CombatGroup* assigned = 0; - - if (request) - assigned = request->GetObjective(); - - if (assigned) { - if (assigned->Type() > CombatGroup::WING && assigned->Type() < CombatGroup::FLEET) { - mission->AddElement(CreateFighterPackage(assigned, 2, Mission::CARGO)); - } - else { - CreateElements(assigned); - } - - // select the prime target element - choose the lowest ranking - // unit of a DESRON, CBG, or CVBG: - - ListIter e_iter = mission->GetElements(); - while (++e_iter) { - MissionElement* elem = e_iter.value(); - - if (elem->GetCombatGroup() == assigned) { - if (!prime_target || assigned->Type() <= CombatGroup::CARRIER_GROUP) { - prime_target = elem; - } - } - } - - if (prime_target) { - MissionElement* elem = prime_target; - - Instruction* obj = new Instruction(Instruction::ASSAULT, elem->Name()); - if (obj) { - obj->SetTargetDesc(Text("preplanned target '") + elem->Name() + "'"); - player_elem->AddObjective(obj); - } - - // create flight plan: - RLoc rloc; - Vec3 dummy(0,0,0); - Instruction* instr = 0; - Point loc = player_elem->Location(); - Point tgt = elem->Location(); - Point mid; - - CombatGroup* tgt_group = elem->GetCombatGroup(); - if (tgt_group && tgt_group->GetFirstUnit() && tgt_group->IsMovable()) { - tgt = tgt_group->GetFirstUnit()->Location(); - } - - if (carrier_elem) - loc = carrier_elem->Location(); - - mid = loc + (elem->Location() - loc) * 0.5; - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(mid); - rloc.SetDistance(40e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(90*DEGREES); - rloc.SetAzimuthVar(45*DEGREES); - - instr = new Instruction(elem->Region(), dummy, Instruction::VECTOR); - if (instr) { - instr->SetSpeed(750); - instr->GetRLoc() = rloc; - - player_elem->AddNavPoint(instr); - - if (RandomChance()) { - CreateRandomTarget(elem->Region(), rloc.Location()); - } - } - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(tgt); - rloc.SetDistance(60e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(120*DEGREES); - rloc.SetAzimuthVar(15*DEGREES); - - instr = new Instruction(elem->Region(), dummy, Instruction::ASSAULT); - if (instr) { - instr->SetSpeed(750); - instr->GetRLoc() = rloc; - instr->SetTarget(elem->Name()); - - player_elem->AddNavPoint(instr); - } - - if (carrier_elem) { - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(loc); - rloc.SetDistance(30e3); - rloc.SetDistanceVar(0); - rloc.SetAzimuth(180*DEGREES); - rloc.SetAzimuthVar(60*DEGREES); - - instr = new Instruction(carrier_elem->Region(), dummy, Instruction::RTB); - if (instr) { - instr->SetSpeed(500); - instr->GetRLoc() = rloc; - - player_elem->AddNavPoint(instr); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -int -CampaignMissionFighter::CreateRandomTarget(const char* rgn, Point base_loc) -{ - if (!mission) return 0; - - int ntargets = 0; - int ttype = RandomIndex(); - bool oca = (mission->Type() == Mission::SWEEP); - - if (ttype < 8) { - CombatGroup* s = 0; - - if (ttype < 4) - s = FindSquadron(enemy, CombatGroup::INTERCEPT_SQUADRON); - else - s = FindSquadron(enemy, CombatGroup::FIGHTER_SQUADRON); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 2, Mission::SWEEP); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint() * 1.5); - mission->AddElement(elem); - ntargets++; - } - } - } - else if (ttype < 12) { - if (oca) { - CombatGroup* s = FindSquadron(enemy, CombatGroup::LCA_SQUADRON); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 1, Mission::CARGO); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint() * 2); - mission->AddElement(elem); - ntargets++; - - CombatGroup* s2 = FindSquadron(enemy, CombatGroup::FIGHTER_SQUADRON); - - if (s2) { - MissionElement* e2 = CreateFighterPackage(s2, 2, Mission::ESCORT); - if (e2) { - e2->SetIntelLevel(Intel::KNOWN); - e2->SetRegion(rgn); - e2->SetLocation(elem->Location() + RandomPoint() * 0.5); - - Instruction* obj = new Instruction(Instruction::ESCORT, elem->Name()); - if (obj) - e2->AddObjective(obj); - mission->AddElement(e2); - ntargets++; - } - } - } - } - } - else { - CombatGroup* s = FindSquadron(enemy, CombatGroup::ATTACK_SQUADRON); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 2, Mission::ASSAULT); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint() * 1.3); - mission->AddElement(elem); - ntargets++; - } - } - } - } - else if (ttype < 15) { - if (oca) { - CombatGroup* s = 0; - - if (airborne) - s = FindSquadron(enemy, CombatGroup::LCA_SQUADRON); - else - s = FindSquadron(enemy, CombatGroup::FREIGHT); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 1, Mission::CARGO); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint() * 2); - mission->AddElement(elem); - ntargets++; - - CombatGroup* s2 = FindSquadron(enemy, CombatGroup::INTERCEPT_SQUADRON); - - if (s2) { - MissionElement* e2 = CreateFighterPackage(s2, 2, Mission::ESCORT); - if (e2) { - e2->SetIntelLevel(Intel::KNOWN); - e2->SetRegion(rgn); - e2->SetLocation(elem->Location() + RandomPoint() * 0.5); - - Instruction* obj = new Instruction(Instruction::ESCORT, elem->Name()); - if (obj) - e2->AddObjective(obj); - mission->AddElement(e2); - ntargets++; - } - } - } - } - } - else { - CombatGroup* s = FindSquadron(enemy, CombatGroup::ATTACK_SQUADRON); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 2, Mission::ASSAULT); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint() * 1.1); - mission->AddElement(elem); - ntargets++; - - CombatGroup* s2 = FindSquadron(enemy, CombatGroup::FIGHTER_SQUADRON); - - if (s2) { - MissionElement* e2 = CreateFighterPackage(s2, 2, Mission::ESCORT); - if (e2) { - e2->SetIntelLevel(Intel::KNOWN); - e2->SetRegion(rgn); - e2->SetLocation(elem->Location() + RandomPoint() * 0.5); - - Instruction* obj = new Instruction(Instruction::ESCORT, elem->Name()); - if (obj) - e2->AddObjective(obj); - mission->AddElement(e2); - ntargets++; - } - } - } - } - } - } - else { - CombatGroup* s = FindSquadron(enemy, CombatGroup::LCA_SQUADRON); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 2, Mission::CARGO); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint() * 2); - mission->AddElement(elem); - ntargets++; - } - } - } - - return ntargets; -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::PlanetaryInsertion(MissionElement* elem) -{ - if (!mission || !elem) return; - if (!mission->GetStarSystem()) return; - - MissionElement* carrier = mission->FindElement(elem->Commander()); - StarSystem* system = mission->GetStarSystem(); - OrbitalRegion* rgn1 = system->FindRegion(elem->Region()); - OrbitalRegion* rgn2 = system->FindRegion(air_region); - Point npt_loc = elem->Location(); - Instruction* n = 0; - Player* p = Player::GetCurrentPlayer(); - - int flying_start = p ? p->FlyingStart() : 0; - - if (carrier && !flying_start) { - npt_loc = carrier->Location() + Point(1e3, -5e3, 0); - } - - if (rgn1 && rgn2) { - double delta_t = mission->Start() - campaign->GetTime(); - Point r1 = rgn1->PredictLocation(delta_t); - Point r2 = rgn2->PredictLocation(delta_t); - - Point delta = r2 - r1; - - delta.y *= -1; - delta.Normalize(); - delta *= 10e3; - - npt_loc += delta; - - n = new Instruction(elem->Region(), - npt_loc, - Instruction::VECTOR); - if (n) { - n->SetSpeed(750); - elem->AddNavPoint(n); - } - } - - n = new Instruction(air_region, - Point(0, 0, 15e3), - Instruction::VECTOR); - if (n) { - n->SetSpeed(750); - elem->AddNavPoint(n); - } -} - -void -CampaignMissionFighter::OrbitalInsertion(MissionElement* elem) -{ - Instruction* n = new Instruction(air_region, - Point(0, 0, 30.0e3), - Instruction::VECTOR); - if (n) { - n->SetSpeed(750); - elem->AddNavPoint(n); - } -} - -// +--------------------------------------------------------------------+ - -MissionElement* -CampaignMissionFighter::CreateFighterPackage(CombatGroup* squadron, int count, int role) -{ - if (!squadron) return 0; - - CombatUnit* fighter = squadron->GetUnits().at(0); - CombatUnit* carrier = FindCarrier(squadron); - - if (!fighter) - return 0; - - int avail = fighter->LiveCount(); - int actual = count; - - if (avail < actual) - actual = avail; - - if (avail < 1) { - ::Print("CMF - Insufficient fighters in squadron '%s' - %d required, %d available\n", - squadron->Name().data(), count, avail); - return 0; - } - - MissionElement* elem = new MissionElement; - if (!elem) { - Exit(); - return 0; - } - - elem->SetName(Callsign::GetCallsign(fighter->GetIFF())); - elem->SetElementID(pkg_id++); - - if (carrier) { - elem->SetCommander(carrier->Name()); - elem->SetHeading(carrier->GetHeading()); - } - else { - elem->SetHeading(fighter->GetHeading()); - } - - elem->SetDesign(fighter->GetDesign()); - elem->SetCount(actual); - elem->SetIFF(fighter->GetIFF()); - elem->SetIntelLevel(squadron->IntelLevel()); - elem->SetRegion(fighter->GetRegion()); - elem->SetSquadron(squadron->Name()); - elem->SetMissionRole(role); - - switch (role) { - case Mission::ASSAULT: - if (request->GetObjective() && - request->GetObjective()->Type() == CombatGroup::MINEFIELD) - elem->Loadouts().append(new MissionLoad(-1, "Rockets")); - else - elem->Loadouts().append(new MissionLoad(-1, "Ship Strike")); - break; - - case Mission::STRIKE: - elem->Loadouts().append(new MissionLoad(-1, "Ground Strike")); - break; - - default: - elem->Loadouts().append(new MissionLoad(-1, "ACM Medium Range")); - break; - } - - if (carrier) { - Point offset = RandomPoint() * 0.3; - offset.y = fabs(offset.y); - offset.z += 2e3; - elem->SetLocation(carrier->Location() + offset); - } - else { - elem->SetLocation(fighter->Location() + RandomPoint()); - } - - elem->SetCombatGroup(squadron); - elem->SetCombatUnit(fighter); - - return elem; -} - -// +--------------------------------------------------------------------+ - -static CombatGroup* FindCombatGroup(CombatGroup* g, int type) -{ - if (g->IntelLevel() <= Intel::RESERVE) - return 0; - - if (g->GetUnits().size() > 0) { - for (int i = 0; i < g->GetUnits().size(); i++) { - CombatUnit* u = g->GetUnits().at(i); - if (g->Type() == type && u->LiveCount() > 0) - return g; - } - } - - CombatGroup* result = 0; - - ListIter subgroup = g->GetComponents(); - while (++subgroup && !result) - result = FindCombatGroup(subgroup.value(), type); - - return result; -} - -// +--------------------------------------------------------------------+ - -CombatGroup* -CampaignMissionFighter::FindSquadron(int iff, int type) -{ - if (!squadron) return 0; - - CombatGroup* result = 0; - Campaign* campaign = Campaign::GetCampaign(); - - if (campaign) { - ListIter combatant = campaign->GetCombatants(); - while (++combatant && !result) { - if (combatant->GetIFF() == iff) { - result = ::FindCombatGroup(combatant->GetForce(), type); - - if (result && result->CountUnits() < 1) { - result = 0; - } - } - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::DefineMissionObjectives() -{ - if (!mission || !player_elem) return; - - if (prime_target) mission->SetTarget(prime_target); - if (ward) mission->SetWard(ward); - - Text objectives; - - for (int i = 0; i < player_elem->Objectives().size(); i++) { - Instruction* obj = player_elem->Objectives().at(i); - objectives += "* "; - objectives += obj->GetDescription(); - objectives += ".\n"; - } - - mission->SetObjective(objectives); -} - -// +--------------------------------------------------------------------+ - -MissionInfo* -CampaignMissionFighter::DescribeMission() -{ - if (!mission || !player_elem) return 0; - - char name[256]; - char player_info[256]; - - if (mission_info && mission_info->name.length()) - sprintf_s(name, "MSN-%03d %s", mission->Identity(), mission_info->name.data()); - else if (ward) - sprintf_s(name, "MSN-%03d %s %s", mission->Identity(), ContentBundle::GetInstance()->GetText(mission->TypeName()).data(), ward->Name().data()); - else if (prime_target) - sprintf_s(name, "MSN-%03d %s %s %s", mission->Identity(), ContentBundle::GetInstance()->GetText(mission->TypeName()).data(), - Ship::ClassName(prime_target->GetDesign()->type), - prime_target->Name().data()); - else - sprintf_s(name, "MSN-%03d %s", mission->Identity(), ContentBundle::GetInstance()->GetText(mission->TypeName()).data()); - - if (player_elem) { - sprintf_s(player_info, "%d x %s %s '%s'", - player_elem->Count(), - (const char*) player_elem->GetDesign()->abrv, - (const char*) player_elem->GetDesign()->name, - (const char*) player_elem->Name()); - } - - MissionInfo* info = new MissionInfo; - - info->id = mission->Identity(); - info->mission = mission; - info->name = name; - info->type = mission->Type(); - info->player_info = player_info; - info->description = mission->Objective(); - info->start = mission->Start(); - - if (mission->GetStarSystem()) - info->system = mission->GetStarSystem()->Name(); - info->region = mission->GetRegion(); - - mission->SetName(name); - - return info; -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionFighter::Exit() -{ - Starshatter* stars = Starshatter::GetInstance(); - if (stars) - stars->SetGameMode(Starshatter::MENU_MODE); -} diff --git a/Stars45/CampaignMissionFighter.h b/Stars45/CampaignMissionFighter.h deleted file mode 100644 index 997a760..0000000 --- a/Stars45/CampaignMissionFighter.h +++ /dev/null @@ -1,120 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignMissionFighter generates missions and mission - info for the player's FIGHTER SQUADRON as part of a - dynamic campaign. -*/ - -#ifndef CampaignMissionFighter_h -#define CampaignMissionFighter_h - -#include "Types.h" -#include "Geometry.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class CampaignMissionRequest; -class CombatGroup; -class CombatUnit; -class CombatZone; -class Mission; -class MissionElement; -class MissionInfo; -class MissionTemplate; - -// +--------------------------------------------------------------------+ - -class CampaignMissionFighter -{ -public: - static const char* TYPENAME() { return "CampaignMissionFighter"; } - - CampaignMissionFighter(Campaign* c); - virtual ~CampaignMissionFighter(); - - virtual void CreateMission(CampaignMissionRequest* request); - -protected: - virtual Mission* GenerateMission(int id); - virtual void SelectType(); - virtual void SelectRegion(); - virtual void GenerateStandardElements(); - virtual void GenerateMissionElements(); - virtual void CreateElements(CombatGroup* g); - virtual void CreateSquadron(CombatGroup* g); - virtual void CreatePlayer(CombatGroup* g); - - virtual void CreatePatrols(); - virtual void CreateWards(); - virtual void CreateWardFreight(); - virtual void CreateWardShuttle(); - virtual void CreateWardStrike(); - - virtual void CreateEscorts(); - - virtual void CreateTargets(); - virtual void CreateTargetsPatrol(); - virtual void CreateTargetsSweep(); - virtual void CreateTargetsIntercept(); - virtual void CreateTargetsFreightEscort(); - virtual void CreateTargetsShuttleEscort(); - virtual void CreateTargetsStrikeEscort(); - virtual void CreateTargetsStrike(); - virtual void CreateTargetsAssault(); - virtual int CreateRandomTarget(const char* rgn, Point base_loc); - - virtual bool IsGroundObjective(CombatGroup* obj); - - virtual void PlanetaryInsertion(MissionElement* elem); - virtual void OrbitalInsertion(MissionElement* elem); - - virtual MissionElement* - CreateSingleElement(CombatGroup* g, - CombatUnit* u); - virtual MissionElement* - CreateFighterPackage(CombatGroup* squadron, - int count, - int role); - - virtual CombatGroup* FindSquadron(int iff, int type); - virtual CombatUnit* FindCarrier(CombatGroup* g); - - virtual void DefineMissionObjectives(); - virtual MissionInfo* DescribeMission(); - virtual void Exit(); - - Campaign* campaign; - CampaignMissionRequest* request; - MissionInfo* mission_info; - - CombatGroup* squadron; - CombatGroup* strike_group; - CombatGroup* strike_target; - Mission* mission; - MissionElement* player_elem; - MissionElement* carrier_elem; - MissionElement* ward; - MissionElement* prime_target; - MissionElement* escort; - Text air_region; - Text orb_region; - bool airborne; - bool airbase; - int ownside; - int enemy; - int mission_type; -}; - -#endif // CampaignMissionFighter_h - diff --git a/Stars45/CampaignMissionRequest.cpp b/Stars45/CampaignMissionRequest.cpp deleted file mode 100644 index e8fbc68..0000000 --- a/Stars45/CampaignMissionRequest.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignMissionRequest -*/ - -#include "CampaignMissionRequest.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAssignment.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Mission.h" -#include "Instruction.h" -#include "ShipDesign.h" -#include "StarSystem.h" -#include "Random.h" - -// +--------------------------------------------------------------------+ - -CampaignMissionRequest::CampaignMissionRequest(Campaign* c, - int t, - int s, - CombatGroup* p, - CombatGroup* tgt) - : campaign(c), type(t), opp_type(-1), start(s), - primary_group(p), secondary_group(0), - objective(tgt), use_loc(false) -{ } diff --git a/Stars45/CampaignMissionRequest.h b/Stars45/CampaignMissionRequest.h deleted file mode 100644 index 1c99b32..0000000 --- a/Stars45/CampaignMissionRequest.h +++ /dev/null @@ -1,83 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignMissionRequest -*/ - -#ifndef CampaignMissionRequest_h -#define CampaignMissionRequest_h - -#include "Types.h" -#include "Geometry.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class CombatGroup; -class CombatUnit; -class CombatZone; -class Mission; -class MissionElement; -class MissionInfo; - -// +--------------------------------------------------------------------+ - -class CampaignMissionRequest -{ -public: - static const char* TYPENAME() { return "CampaignMissionRequest"; } - - CampaignMissionRequest(Campaign* c, int type, int start, - CombatGroup* primary, CombatGroup* tgt=0); - - Campaign* GetCampaign() { return campaign; } - int Type() { return type; } - int OpposingType() { return opp_type; } - int StartTime() { return start; } - CombatGroup* GetPrimaryGroup() { return primary_group; } - CombatGroup* GetSecondaryGroup() { return secondary_group; } - CombatGroup* GetObjective() { return objective; } - - bool IsLocSpecified() { return use_loc; } - const Text& RegionName() { return region; } - Point Location() { return location; } - const Text& Script() { return script; } - - void SetType(int t) { type = t; } - void SetOpposingType(int t) { opp_type = t; } - void SetStartTime(int s) { start = s; } - void SetPrimaryGroup(CombatGroup* g) { primary_group = g; } - void SetSecondaryGroup(CombatGroup* g) { secondary_group = g; } - void SetObjective(CombatGroup* g) { objective = g; } - - void SetRegionName(const char* rgn) { region = rgn; use_loc = true; } - void SetLocation(const Point& loc) { location = loc; use_loc = true; } - void SetScript(const char* s) { script = s; } - -private: - Campaign* campaign; - - int type; // type of mission - int opp_type; // opposing mission type - int start; // start time - CombatGroup* primary_group; // player's group - CombatGroup* secondary_group; // optional support group - CombatGroup* objective; // target or ward - - bool use_loc; // use the specified location - Text region; - Point location; - Text script; -}; - -#endif // CampaignMissionRequest_h - diff --git a/Stars45/CampaignMissionStarship.cpp b/Stars45/CampaignMissionStarship.cpp deleted file mode 100644 index 60d88af..0000000 --- a/Stars45/CampaignMissionStarship.cpp +++ /dev/null @@ -1,1403 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignMissionStarship generates missions and mission - info for the player's STARSHIP GROUP as part of a - dynamic campaign. -*/ - -#include "CampaignMissionStarship.h" -#include "CampaignMissionRequest.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAssignment.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Callsign.h" -#include "Mission.h" -#include "MissionTemplate.h" -#include "Instruction.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Starshatter.h" -#include "StarSystem.h" -#include "Player.h" -#include "ContentBundle.h" -#include "Random.h" - -static int pkg_id = 1000; -extern int dump_missions; - -// +--------------------------------------------------------------------+ - -CampaignMissionStarship::CampaignMissionStarship(Campaign* c) - : campaign(c), player_group(0), player_unit(0), mission(0), player(0), - strike_group(0), strike_target(0), prime_target(0), - ward(0), escort(0), ownside(0), enemy(-1), mission_type(0) -{ - if (!campaign || !campaign->GetPlayerGroup()) { - ::Print("ERROR - CMS campaign=0x%08x player_group=0x%08x\n", - campaign, (DWORD) campaign?campaign->GetPlayerGroup():0); - return; - } - - player_group = campaign->GetPlayerGroup(); - player_unit = campaign->GetPlayerUnit(); -} - -CampaignMissionStarship::~CampaignMissionStarship() {} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::CreateMission(CampaignMissionRequest* req) -{ - if (!campaign || !req) - return; - - ::Print("\n-----------------------------------------------\n"); - if (req->Script().length()) - ::Print("CMS CreateMission() request: %s '%s'\n", - Mission::RoleName(req->Type()), - (const char*) req->Script()); - - else - ::Print("CMS CreateMission() request: %s %s\n", - Mission::RoleName(req->Type()), - req->GetObjective() ? req->GetObjective()->Name().data() : "(no target)"); - - request = req; - - if (!player_group) - return; - - if (request->GetPrimaryGroup() != player_group) { - player_group = request->GetPrimaryGroup(); - player_unit = 0; - } - - ownside = player_group->GetIFF(); - mission_info = 0; - - for (int i = 0; i < campaign->GetCombatants().size(); i++) { - int iff = campaign->GetCombatants().at(i)->GetIFF(); - if (iff > 0 && iff != ownside) { - enemy = iff; - break; - } - } - - static int id_key = 1; - GenerateMission(id_key++); - DefineMissionObjectives(); - - MissionInfo* info = DescribeMission(); - - if (info) { - campaign->GetMissionList().append(info); - - ::Print("CMS Created %03d '%s' %s\n\n", - info->id, - (const char*) info->name, - Mission::RoleName(mission->Type())); - - if (dump_missions) { - Text script = mission->Serialize(); - char fname[32]; - - sprintf_s(fname, "msn%03d.def", info->id); - FILE* f; - fopen_s(&f, fname, "wb"); - if (f) { - fprintf(f, "%s\n", script.data()); - fclose(f); - } - } - } - - else { - ::Print("CMS failed to create mission.\n"); - } -} - -// +--------------------------------------------------------------------+ - -Mission* -CampaignMissionStarship::GenerateMission(int id) -{ - bool found = false; - - SelectType(); - - if (request && request->Script().length()) { - MissionTemplate* mt = new MissionTemplate(id, request->Script(), campaign->Path()); - if (mt) - mt->SetPlayerSquadron(player_group); - mission = mt; - found = true; - } - - else { - mission_info = campaign->FindMissionTemplate(mission_type, player_group); - - found = mission_info != 0; - - if (found) { - MissionTemplate* mt = new MissionTemplate(id, mission_info->script, campaign->Path()); - if (mt) - mt->SetPlayerSquadron(player_group); - mission = mt; - } - else { - mission = new Mission(id); - if (mission) - mission->SetType(mission_type); - } - } - - if (!mission || !player_group) { - Exit(); - return 0; - } - - char name[64]; - sprintf_s(name, "Starship Mission %d", id); - - mission->SetName(name); - mission->SetTeam(player_group->GetIFF()); - mission->SetStart(request->StartTime()); - - SelectRegion(); - GenerateStandardElements(); - - if (!found) { - GenerateMissionElements(); - mission->SetOK(true); - mission->Validate(); - } - - else { - CreatePlayer(); - mission->Load(); - - if (mission->IsOK()) { - player = mission->GetPlayer(); - prime_target = mission->GetTarget(); - ward = mission->GetWard(); - } - - // if there was a problem, scrap the mission - // and start over: - else { - delete mission; - - mission = new Mission(id); - - if (!mission) { - Exit(); - return 0; - } - - mission->SetType(mission_type); - mission->SetName(name); - mission->SetTeam(player_group->GetIFF()); - mission->SetStart(request->StartTime()); - - SelectRegion(); - GenerateStandardElements(); - GenerateMissionElements(); - - mission->SetOK(true); - mission->Validate(); - } - } - - return mission; -} - -void -CampaignMissionStarship::SelectType() -{ - if (request) - mission_type = request->Type(); - - else - mission_type = Mission::PATROL; - - if (player_unit && player_unit->GetShipClass() == Ship::CARRIER) - mission_type = Mission::FLIGHT_OPS; -} - -void -CampaignMissionStarship::SelectRegion() -{ - if (!player_group) { - ::Print("WARNING: CMS - no player group in SelectRegion\n"); - return; - } - - CombatZone* zone = player_group->GetAssignedZone(); - - if (!zone) - zone = player_group->GetCurrentZone(); - - if (zone) { - mission->SetStarSystem(campaign->GetSystem(zone->System())); - - if (zone->HasRegion(player_group->GetRegion())) - mission->SetRegion(player_group->GetRegion()); - - else - mission->SetRegion(*zone->GetRegions().at(0)); - } - - else { - ::Print("WARNING: CMS - No zone for '%s'\n", player_group->Name().data()); - - StarSystem* s = campaign->GetSystemList()[0]; - - mission->SetStarSystem(s); - mission->SetRegion(s->Regions()[0]->Name()); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::GenerateStandardElements() -{ - ListIter z = campaign->GetZones(); - while (++z) { - ListIter iter = z->GetForces(); - while (++iter) { - ZoneForce* force = iter.value(); - ListIter group = force->GetGroups(); - - while (++group) { - CombatGroup* g = group.value(); - - switch (g->Type()) { - case CombatGroup::INTERCEPT_SQUADRON: - case CombatGroup::FIGHTER_SQUADRON: - case CombatGroup::ATTACK_SQUADRON: - case CombatGroup::LCA_SQUADRON: - CreateSquadron(g); - break; - - case CombatGroup::DESTROYER_SQUADRON: - case CombatGroup::BATTLE_GROUP: - case CombatGroup::CARRIER_GROUP: - CreateElements(g); - break; - - case CombatGroup::MINEFIELD: - case CombatGroup::BATTERY: - case CombatGroup::MISSILE: - case CombatGroup::STATION: - case CombatGroup::STARBASE: - case CombatGroup::SUPPORT: - case CombatGroup::COURIER: - case CombatGroup::MEDICAL: - case CombatGroup::SUPPLY: - case CombatGroup::REPAIR: - CreateElements(g); - break; - - case CombatGroup::CIVILIAN: - case CombatGroup::WAR_PRODUCTION: - case CombatGroup::FACTORY: - case CombatGroup::REFINERY: - case CombatGroup::RESOURCE: - case CombatGroup::INFRASTRUCTURE: - case CombatGroup::TRANSPORT: - case CombatGroup::NETWORK: - case CombatGroup::HABITAT: - case CombatGroup::STORAGE: - case CombatGroup::NON_COM: - CreateElements(g); - break; - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::GenerateMissionElements() -{ - CreatePlayer(); - CreateWards(); - CreateTargets(); - - if (ward && player) { - Instruction* obj = new Instruction(Instruction::ESCORT, ward->Name()); - - if (obj) { - switch (mission->Type()) { - case Mission::ESCORT_FREIGHT: - obj->SetTargetDesc(Text("the star freighter ") + ward->Name()); - break; - - case Mission::ESCORT_SHUTTLE: - obj->SetTargetDesc(Text("the shuttle ") + ward->Name()); - break; - - case Mission::ESCORT_STRIKE: - obj->SetTargetDesc(Text("the ") + ward->Name() + Text(" strike package")); - break; - - default: - if (ward->GetCombatGroup()) { - obj->SetTargetDesc(Text("the ") + ward->GetCombatGroup()->GetDescription()); - } - else { - obj->SetTargetDesc(Text("the ") + ward->Name()); - } - break; - } - - player->AddObjective(obj); - } - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::CreatePlayer() -{ - // prepare elements for the player's group - MissionElement* elem = 0; - - if (player_group) { - ListIter iter = mission->GetElements(); - while (++iter) { - MissionElement* e = iter.value(); - if (e->GetCombatGroup() == player_group) { - player_group_elements.append(e); - - // match the player to the requested unit, if possible: - if ((!player_unit && !elem) || (player_unit == e->GetCombatUnit())) { - elem = e; - } - } - } - } - - if (elem) { - elem->SetPlayer(1); - elem->SetCommandAI(0); - player = elem; - } - else if (player_group) { - ::Print("CMS GenerateMissionElements() could not find player element '%s'\n", - player_group->Name().data()); - } - else { - ::Print("CMS GenerateMissionElements() could not find player element (no player group)\n"); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::CreateElements(CombatGroup* g) -{ - MissionElement* elem = 0; - List& units = g->GetUnits(); - - CombatUnit* cmdr = 0; - - for (int i = 0; i < units.size(); i++) { - elem = CreateSingleElement(g, units[i]); - - if (elem) { - if (!cmdr) { - cmdr = units[i]; - - if (player_group && player_group->GetIFF() == g->GetIFF()) { - // the grand admiral is all powerful! - Player* player = Player::GetCurrentPlayer(); - if (player && player->Rank() >= 10) { - elem->SetCommander(player_group->Name()); - } - } - } - else { - elem->SetCommander(cmdr->Name()); - - if (g->Type() == CombatGroup::CARRIER_GROUP && - elem->MissionRole() == Mission::ESCORT) { - Instruction* obj = new Instruction(Instruction::ESCORT, cmdr->Name()); - if (obj) { - obj->SetTargetDesc(Text("the ") + g->GetDescription()); - elem->AddObjective(obj); - } - } - } - - mission->AddElement(elem); - } - } -} - -MissionElement* -CampaignMissionStarship::CreateSingleElement(CombatGroup* g, CombatUnit* u) -{ - if (!g || g->IsReserve()) return 0; - if (!u || u->LiveCount() < 1) return 0; - if (!mission->GetStarSystem()) return 0; - - // no ground units in starship missions: - StarSystem* system = mission->GetStarSystem(); - OrbitalRegion* rgn = system->FindRegion(u->GetRegion()); - - if (!rgn || rgn->Type() == Orbital::TERRAIN) - return 0; - - // make sure this unit isn't already in the mission: - ListIter e_iter = mission->GetElements(); - while (++e_iter) { - MissionElement* elem = e_iter.value(); - - if (elem->GetCombatUnit() == u) - return 0; - } - - MissionElement* elem = new MissionElement; - if (!elem) { - Exit(); - return 0; - } - - if (u->Name().length()) - elem->SetName(u->Name()); - else - elem->SetName(u->DesignName()); - - elem->SetElementID(pkg_id++); - - elem->SetDesign(u->GetDesign()); - elem->SetCount(u->LiveCount()); - elem->SetIFF(u->GetIFF()); - elem->SetIntelLevel(g->IntelLevel()); - elem->SetRegion(u->GetRegion()); - elem->SetHeading(u->GetHeading()); - - int unit_index = g->GetUnits().index(u); - Point base_loc = u->Location(); - bool exact = u->IsStatic(); // exact unit-level placement - - if (base_loc.length() < 1) { - base_loc = g->Location(); - exact = false; - } - - if (unit_index < 0 || unit_index > 0 && !exact) { - Point loc = RandomDirection(); - - if (!u->IsStatic()) { - while (fabs(loc.y) > fabs(loc.x)) - loc = RandomDirection(); - - loc *= 10e3 + 9e3 * unit_index; - } - else { - loc *= 2e3 + 2e3 * unit_index; - } - - elem->SetLocation(base_loc + loc); - } - else { - elem->SetLocation(base_loc); - } - - if (g->Type() == CombatGroup::CARRIER_GROUP) { - if (u->Type() == Ship::CARRIER) { - elem->SetMissionRole(Mission::FLIGHT_OPS); - } - else { - elem->SetMissionRole(Mission::ESCORT); - } - } - else if (u->Type() == Ship::STATION || u->Type() == Ship::FARCASTER) { - elem->SetMissionRole(Mission::OTHER); - - // link farcaster to other terminus: - if (u->Type() == Ship::FARCASTER) { - Text name = u->Name(); - int dash = -1; - - for (int i = 0; i < (int) name.length(); i++) - if (name[i] == '-') - dash = i; - - Text src = name.substring(0, dash); - Text dst = name.substring(dash+1, name.length() - (dash+1)); - - Instruction* obj = new Instruction(Instruction::VECTOR, dst + "-" + src); - if (obj) - elem->AddObjective(obj); - } - } - else if ((u->Type() & Ship::STARSHIPS) != 0) { - elem->SetMissionRole(Mission::FLEET); - } - - elem->SetCombatGroup(g); - elem->SetCombatUnit(u); - - return elem; -} - -CombatUnit* -CampaignMissionStarship::FindCarrier(CombatGroup* g) -{ - CombatGroup* carrier = g->FindCarrier(); - - if (carrier && carrier->GetUnits().size()) { - MissionElement* carrier_elem = mission->FindElement(carrier->Name()); - - if (carrier_elem) - return carrier->GetUnits().at(0); - } - - return 0; -} - -void -CampaignMissionStarship::CreateSquadron(CombatGroup* g) -{ - if (!g || g->IsReserve()) return; - - CombatUnit* fighter = g->GetUnits().at(0); - CombatUnit* carrier = FindCarrier(g); - - if (!fighter || !carrier) return; - - int live_count = fighter->LiveCount(); - int maint_count = (live_count > 4) ? live_count / 2 : 0; - - MissionElement* elem = new MissionElement; - - if (!elem) { - Exit(); - return; - } - - elem->SetName(g->Name()); - elem->SetElementID(pkg_id++); - - elem->SetDesign(fighter->GetDesign()); - elem->SetCount(fighter->Count()); - elem->SetDeadCount(fighter->DeadCount()); - elem->SetMaintCount(maint_count); - elem->SetIFF(fighter->GetIFF()); - elem->SetIntelLevel(g->IntelLevel()); - elem->SetRegion(fighter->GetRegion()); - - elem->SetCarrier(carrier->Name()); - elem->SetCommander(carrier->Name()); - elem->SetLocation(carrier->Location() + RandomPoint()); - - elem->SetCombatGroup(g); - elem->SetCombatUnit(fighter); - - mission->AddElement(elem); -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::CreateWards() -{ - switch (mission->Type()) { - case Mission::ESCORT_FREIGHT: CreateWardFreight(); break; - default: break; - } -} - -void -CampaignMissionStarship::CreateWardFreight() -{ - if (!mission || !mission->GetStarSystem() || !player_group) return; - - CombatGroup* freight = 0; - - if (request) - freight = request->GetObjective(); - - if (!freight) - freight = campaign->FindGroup(ownside, CombatGroup::FREIGHT); - - if (!freight || freight->CalcValue() < 1) return; - - CombatUnit* unit = freight->GetNextUnit(); - if (!unit) return; - - MissionElement* elem = CreateSingleElement(freight, unit); - if (!elem) return; - - elem->SetMissionRole(Mission::CARGO); - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(player_group->GetRegion()); - - ward = elem; - mission->AddElement(elem); - - - StarSystem* system = mission->GetStarSystem(); - OrbitalRegion* rgn1 = system->FindRegion(elem->Region()); - Point delta = rgn1->Location() - rgn1->Primary()->Location(); - Point navpt_loc = elem->Location(); - Instruction* n = 0; - - delta.Normalize(); - delta *= 200.0e3; - - navpt_loc += delta; - - n = new Instruction(elem->Region(), - navpt_loc, - Instruction::VECTOR); - if (n) { - n->SetSpeed(500); - elem->AddNavPoint(n); - } - - Text rgn2 = elem->Region(); - List& zones = campaign->GetZones(); - if (zones[zones.size()-1]->HasRegion(rgn2)) - rgn2 = *zones[0]->GetRegions()[0]; - else - rgn2 = *zones[zones.size()-1]->GetRegions()[0]; - - n = new Instruction(rgn2, - Point(0, 0, 0), - Instruction::VECTOR); - if (n) { - n->SetSpeed(750); - elem->AddNavPoint(n); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::CreateEscorts() -{ -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::CreateTargets() -{ - if (player_group && player_group->Type() == CombatGroup::CARRIER_GROUP) { - CreateTargetsCarrier(); - } - - else { - switch (mission->Type()) { - default: - case Mission::PATROL: CreateTargetsPatrol(); break; - case Mission::ASSAULT: - case Mission::STRIKE: CreateTargetsAssault(); break; - case Mission::ESCORT_FREIGHT: CreateTargetsFreightEscort(); break; - } - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::CreateTargetsAssault() -{ - if (!player) return; - - CombatGroup* assigned = 0; - - if (request) - assigned = request->GetObjective(); - - if (assigned) { - CreateElements(assigned); - - ListIter e_iter = mission->GetElements(); - while (++e_iter) { - MissionElement* elem = e_iter.value(); - - if (elem->GetCombatGroup() == assigned) { - if (!prime_target) { - prime_target = elem; - - MissionElement* player_lead = player_group_elements[0]; - - if (!player_lead) return; - - Instruction* obj = new Instruction(Instruction::ASSAULT, prime_target->Name()); - if (obj) { - obj->SetTargetDesc(Text("preplanned target '") + prime_target->Name() + "'"); - player_lead->AddObjective(obj); - } - - // create flight plan: - RLoc rloc; - RLoc* ref = 0; - Vec3 dummy(0,0,0); - Instruction* instr = 0; - Point loc = player_lead->Location(); - Point tgt = prime_target->Location(); - Point mid; - - mid = loc + (prime_target->Location() - loc) * 0.35; - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(mid); - rloc.SetDistance(50e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(90*DEGREES); - rloc.SetAzimuthVar(45*DEGREES); - - instr = new Instruction(prime_target->Region(), dummy, Instruction::VECTOR); - - if (!instr) - return; - - instr->SetSpeed(750); - instr->GetRLoc() = rloc; - - ref = &instr->GetRLoc(); - - player_lead->AddNavPoint(instr); - - for (int i = 1; i < player_group_elements.size(); i++) { - MissionElement* pge = player_group_elements[i]; - RLoc rloc2; - - rloc2.SetReferenceLoc(ref); - rloc2.SetDistance(50e3); - rloc2.SetDistanceVar(5e3); - - instr = new Instruction(prime_target->Region(), dummy, Instruction::VECTOR); - - if (!instr) - return; - - instr->SetSpeed(750); - instr->GetRLoc() = rloc2; - - pge->AddNavPoint(instr); - } - - double extra = 10e3; - - if (prime_target && prime_target->GetDesign()) { - switch (prime_target->GetDesign()->type) { - default: extra = 20e3; break; - case Ship::FRIGATE: extra = 25e3; break; - case Ship::DESTROYER: extra = 30e3; break; - case Ship::CRUISER: extra = 50e3; break; - case Ship::BATTLESHIP: extra = 70e3; break; - case Ship::DREADNAUGHT: extra = 80e3; break; - case Ship::SWACS: extra = 30e3; break; - case Ship::CARRIER: extra = 90e3; break; - } - } - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(tgt); - rloc.SetDistance(100e3 + extra); - rloc.SetDistanceVar(15e3); - rloc.SetAzimuth(90*DEGREES); - rloc.SetAzimuthVar(45*DEGREES); - - instr = new Instruction(prime_target->Region(), dummy, Instruction::ASSAULT); - - if (!instr) - return; - - instr->SetSpeed(500); - instr->GetRLoc() = rloc; - instr->SetTarget(prime_target->Name()); - - ref = &instr->GetRLoc(); - - player_lead->AddNavPoint(instr); - - for (int i = 1; i < player_group_elements.size(); i++) { - MissionElement* pge = player_group_elements[i]; - RLoc rloc2; - - rloc2.SetReferenceLoc(ref); - rloc2.SetDistance(50e3); - rloc2.SetDistanceVar(5e3); - - instr = new Instruction(prime_target->Region(), dummy, Instruction::ASSAULT); - - if (!instr) - return; - - instr->SetSpeed(500); - instr->GetRLoc() = rloc2; - instr->SetTarget(prime_target->Name()); - - pge->AddNavPoint(instr); - } - } - } - } - } -} - - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::CreateTargetsCarrier() -{ - if (!player_group || !player) return; - - Text region = player_group->GetRegion(); - Point base_loc = player->Location(); - Point patrol_loc = base_loc + - RandomDirection() * Random( 75e3, 150e3); - Point loc2 = patrol_loc + - RandomDirection() * Random( 50e3, 100e3); - - - int ntargets = 2 + (RandomChance() ? 1 : 0); - int ntries = 8; - - while (ntargets > 0 && ntries > 0) { - Point target_loc = RandomChance() ? patrol_loc : loc2; - int t = CreateRandomTarget(region, target_loc); - ntargets -= t; - if (t < 1) ntries--; - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::CreateTargetsPatrol() -{ - if (!player_group || !player) return; - - Text region = player_group->GetRegion(); - Point base_loc = player->Location(); - Point patrol_loc = base_loc + - RandomDirection() * Random(170e3, 250e3); - - Instruction* n = new Instruction(region, - patrol_loc, - Instruction::PATROL); - player->AddNavPoint(n); - - for (int i = 1; i < player_group_elements.size(); i++) { - MissionElement* elem = player_group_elements[i]; - - n = new Instruction(region, - patrol_loc + RandomDirection() * Random(20e3, 40e3), - Instruction::PATROL); - if (n) - elem->AddNavPoint(n); - } - - Point loc2 = patrol_loc + RandomDirection() * Random(150e3, 200e3); - - n = new Instruction(region, - loc2, - Instruction::PATROL); - if (n) - player->AddNavPoint(n); - - for (int i = 1; i < player_group_elements.size(); i++) { - MissionElement* elem = player_group_elements[i]; - - n = new Instruction(region, - loc2 + RandomDirection() * Random(20e3, 40e3), - Instruction::PATROL); - - if (n) - elem->AddNavPoint(n); - } - - int ntargets = 2 + (RandomChance() ? 1 : 0); - int ntries = 8; - - while (ntargets > 0 && ntries > 0) { - Point target_loc = RandomChance() ? patrol_loc : loc2; - int t = CreateRandomTarget(region, target_loc); - ntargets -= t; - if (t < 1) ntries--; - } - - Instruction* obj = new Instruction(*n); - if (obj) { - obj->SetTargetDesc("inbound enemy units"); - player->AddObjective(obj); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::CreateTargetsFreightEscort() -{ - if (!ward) { - CreateTargetsPatrol(); - return; - } - - CombatGroup* s = FindSquadron(enemy, CombatGroup::ATTACK_SQUADRON); - CombatGroup* s2 = FindSquadron(enemy, CombatGroup::FIGHTER_SQUADRON); - - if (!s || !s2) return; - - MissionElement* elem = CreateFighterPackage(s, 2, Mission::ASSAULT); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - - elem->SetLocation(ward->Location() + RandomPoint() * 5); - - Instruction* obj = new Instruction(Instruction::ASSAULT, ward->Name()); - if (obj) - elem->AddObjective(obj); - mission->AddElement(elem); - - MissionElement* e2 = CreateFighterPackage(s2, 2, Mission::ESCORT); - if (e2) { - e2->SetIntelLevel(Intel::KNOWN); - e2->SetLocation(elem->Location() + RandomPoint() * 0.25); - - Instruction* obj2 = new Instruction(Instruction::ESCORT, elem->Name()); - if (obj2) - e2->AddObjective(obj2); - mission->AddElement(e2); - } - } - - Instruction* obj3 = new Instruction(mission->GetRegion(), - Point(0,0,0), - Instruction::PATROL); - if (player && obj3) { - obj3->SetTargetDesc("enemy patrols"); - player->AddObjective(obj3); - } -} - -// +--------------------------------------------------------------------+ - -int -CampaignMissionStarship::CreateRandomTarget(const char* rgn, Point base_loc) -{ - int ntargets = 0; - int ttype = RandomIndex(); - - if (player_group && player_group->Type() == CombatGroup::CARRIER_GROUP) { - switch (ttype) { - case 0: - case 1: - case 2: - case 3: ttype = 0; break; - case 4: - case 5: ttype = 1; break; - case 6: - case 7: ttype = 2; break; - case 8: - case 9: ttype = 3; break; - case 10: - case 11: ttype = 4; break; - case 12: - case 13: - case 14: - case 15: ttype = 5; break; - } - } - else { - switch (ttype) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: ttype = 0; break; - case 6: - case 7: - case 8: ttype = 1; break; - case 9: - case 10: ttype = 4; break; - case 11: - case 12: - case 13: - case 14: - case 15: ttype = 5; break; - } - } - - switch (ttype) { - case 0: { - CombatGroup* s = 0; - - s = FindSquadron(enemy, CombatGroup::DESTROYER_SQUADRON); - - if (s) { - for (int i = 0; i < 2; i++) { - CombatUnit* u = s->GetRandomUnit(); - MissionElement* elem = CreateSingleElement(s, u); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint() * 1.5); - elem->SetMissionRole(Mission::FLEET); - mission->AddElement(elem); - ntargets++; - } - } - } - } - break; - - case 1: { - CombatGroup* s = FindSquadron(enemy, CombatGroup::LCA_SQUADRON); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 2, Mission::CARGO); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint() * 2); - mission->AddElement(elem); - ntargets++; - - CombatGroup* s2 = FindSquadron(enemy, CombatGroup::FIGHTER_SQUADRON); - - if (s2) { - MissionElement* e2 = CreateFighterPackage(s2, 2, Mission::ESCORT); - if (e2) { - e2->SetIntelLevel(Intel::KNOWN); - e2->SetRegion(rgn); - e2->SetLocation(elem->Location() + RandomPoint() * 0.5); - - Instruction* obj = new Instruction(Instruction::ESCORT, elem->Name()); - if (obj) - e2->AddObjective(obj); - - mission->AddElement(e2); - } - } - } - } - } - break; - - case 2: { - CombatGroup* s = FindSquadron(enemy, CombatGroup::INTERCEPT_SQUADRON); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 4, Mission::PATROL); - if (elem) { - elem->SetIntelLevel(Intel::SECRET); - elem->SetRegion(rgn); - elem->SetLocation(base_loc); - mission->AddElement(elem); - ntargets++; - } - } - } - break; - - case 3: { - CombatGroup* s = FindSquadron(enemy, CombatGroup::FIGHTER_SQUADRON); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 3, Mission::ASSAULT); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->Loadouts().destroy(); - elem->Loadouts().append(new MissionLoad(-1, "Ship Strike")); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint()); - mission->AddElement(elem); - - if (player) { - Instruction* n = new Instruction(player->Region(), - player->Location() + RandomPoint(), - Instruction::ASSAULT); - n->SetTarget(player->Name()); - elem->AddNavPoint(n); - } - - ntargets++; - } - } - } - break; - - case 4: { - CombatGroup* s = FindSquadron(enemy, CombatGroup::ATTACK_SQUADRON); - - if (s) { - MissionElement* elem = CreateFighterPackage(s, 2, Mission::ASSAULT); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->Loadouts().destroy(); - elem->Loadouts().append(new MissionLoad(-1, "Hvy Ship Strike")); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint() * 1.3); - mission->AddElement(elem); - - if (player) { - Instruction* n = new Instruction(player->Region(), - player->Location() + RandomPoint(), - Instruction::ASSAULT); - n->SetTarget(player->Name()); - elem->AddNavPoint(n); - } - - ntargets++; - } - } - } - break; - - default: { - CombatGroup* s = 0; - - s = FindSquadron(enemy, CombatGroup::FREIGHT); - - if (s) { - CombatUnit* u = s->GetRandomUnit(); - MissionElement* elem = CreateSingleElement(s, u); - if (elem) { - elem->SetIntelLevel(Intel::KNOWN); - elem->SetRegion(rgn); - elem->SetLocation(base_loc + RandomPoint() * 2); - elem->SetMissionRole(Mission::CARGO); - mission->AddElement(elem); - ntargets++; - - CombatGroup* s2 = FindSquadron(enemy, CombatGroup::INTERCEPT_SQUADRON); - - if (s2) { - MissionElement* e2 = CreateFighterPackage(s2, 2, Mission::ESCORT); - if (e2) { - e2->SetIntelLevel(Intel::KNOWN); - e2->SetRegion(rgn); - e2->SetLocation(elem->Location() + RandomPoint() * 0.5); - - Instruction* obj = new Instruction(Instruction::ESCORT, elem->Name()); - if (obj) - e2->AddObjective(obj); - mission->AddElement(e2); - ntargets++; - } - } - } - } - } - break; - } - - return ntargets; -} - -// +--------------------------------------------------------------------+ - -MissionElement* -CampaignMissionStarship::CreateFighterPackage(CombatGroup* squadron, int count, int role) -{ - if (!squadron || squadron->IsReserve()) - return 0; - - CombatUnit* fighter = squadron->GetUnits().at(0); - CombatUnit* carrier = FindCarrier(squadron); - - if (!fighter) - return 0; - - int avail = fighter->LiveCount(); - int actual = count; - - if (avail < actual) - actual = avail; - - if (avail < 1) { - ::Print("CMS - Insufficient fighters in squadron '%s' - %d required, %d available\n", - squadron->Name().data(), count, avail); - return 0; - } - - MissionElement* elem = new MissionElement; - - if (!elem) { - Exit(); - return 0; - } - - elem->SetName(Callsign::GetCallsign(fighter->GetIFF())); - elem->SetElementID(pkg_id++); - - if (carrier) { - elem->SetCommander(carrier->Name()); - elem->SetHeading(carrier->GetHeading()); - } - else { - elem->SetHeading(fighter->GetHeading()); - } - - elem->SetDesign(fighter->GetDesign()); - elem->SetCount(actual); - elem->SetIFF(fighter->GetIFF()); - elem->SetIntelLevel(squadron->IntelLevel()); - elem->SetRegion(fighter->GetRegion()); - elem->SetSquadron(fighter->Name()); - elem->SetMissionRole(role); - elem->Loadouts().append(new MissionLoad(-1, "ACM Medium Range")); - - if (carrier) - elem->SetLocation(carrier->Location() + RandomPoint() * 0.3); - else - elem->SetLocation(fighter->Location() + RandomPoint()); - - elem->SetCombatGroup(squadron); - elem->SetCombatUnit(fighter); - - return elem; -} - -// +--------------------------------------------------------------------+ - -CombatGroup* -CampaignMissionStarship::FindSquadron(int iff, int type) -{ - if (!player_group) return 0; - - CombatGroup* result = 0; - CombatZone* zone = player_group->GetAssignedZone(); - if (!zone) zone = player_group->GetCurrentZone(); - - if (!zone) { - ::Print("CMS Warning: no zone for %s\n", player_group->Name().data()); - return result; - } - - ZoneForce* force = zone->FindForce(iff); - - if (force) { - List groups; - ListIter group = force->GetGroups(); - while (++group) { - CombatGroup* g = group.value(); - - if (g->Type() == type && g->CountUnits() > 0) { - result = g; - groups.append(g); - } - } - - if (groups.size() > 1) { - int index = (int) Random(0, groups.size()); - if (index >= groups.size()) index = groups.size() - 1; - result = groups[index]; - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::DefineMissionObjectives() -{ - if (!mission || !player) return; - - if (prime_target) mission->SetTarget(prime_target); - if (ward) mission->SetWard(ward); - - Text objectives; - - if (player->Objectives().size() > 0) { - for (int i = 0; i < player->Objectives().size(); i++) { - Instruction* obj = player->Objectives().at(i); - objectives += "* "; - objectives += obj->GetDescription(); - objectives += ".\n"; - } - } - else { - objectives += "* Perform standard fleet operations in the "; - objectives += mission->GetRegion(); - objectives += " sector.\n"; - } - - mission->SetObjective(objectives); -} - -// +--------------------------------------------------------------------+ - -MissionInfo* -CampaignMissionStarship::DescribeMission() -{ - if (!mission || !player) return 0; - - char name[256]; - char player_info[256]; - - if (mission_info && mission_info->name.length()) - sprintf_s(name, "MSN-%03d %s", mission->Identity(), mission_info->name.data()); - else if (ward) - sprintf_s(name, "MSN-%03d %s %s", mission->Identity(), ContentBundle::GetInstance()->GetText(mission->TypeName()).data(), ward->Name().data()); - else if (prime_target) - sprintf_s(name, "MSN-%03d %s %s %s", mission->Identity(), ContentBundle::GetInstance()->GetText(mission->TypeName()).data(), - Ship::ClassName(prime_target->GetDesign()->type), - prime_target->Name().data()); - else - sprintf_s(name, "MSN-%03d %s", mission->Identity(), ContentBundle::GetInstance()->GetText(mission->TypeName()).data()); - - if (player) { - strcpy_s(player_info, player->GetCombatGroup()->GetDescription()); - } - - MissionInfo* info = new MissionInfo; - - if (info) { - info->id = mission->Identity(); - info->mission = mission; - info->name = name; - info->type = mission->Type(); - info->player_info = player_info; - info->description = mission->Objective(); - info->start = mission->Start(); - - if (mission->GetStarSystem()) - info->system = mission->GetStarSystem()->Name(); - info->region = mission->GetRegion(); - } - - mission->SetName(name); - - return info; -} - -// +--------------------------------------------------------------------+ - -void -CampaignMissionStarship::Exit() -{ - Starshatter* stars = Starshatter::GetInstance(); - if (stars) - stars->SetGameMode(Starshatter::MENU_MODE); -} diff --git a/Stars45/CampaignMissionStarship.h b/Stars45/CampaignMissionStarship.h deleted file mode 100644 index 5398c11..0000000 --- a/Stars45/CampaignMissionStarship.h +++ /dev/null @@ -1,106 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignMissionStarship generates missions and mission - info for the player's STARSHIP GROUP as part of a - dynamic campaign. -*/ - -#ifndef CampaignMissionStarship_h -#define CampaignMissionStarship_h - -#include "Types.h" -#include "Geometry.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class CampaignMissionRequest; -class CombatGroup; -class CombatUnit; -class CombatZone; -class Mission; -class MissionElement; -class MissionInfo; -class MissionTemplate; - -// +--------------------------------------------------------------------+ - -class CampaignMissionStarship -{ -public: - static const char* TYPENAME() { return "CampaignMissionStarship"; } - - CampaignMissionStarship(Campaign* c); - virtual ~CampaignMissionStarship(); - - virtual void CreateMission(CampaignMissionRequest* request); - -protected: - virtual Mission* GenerateMission(int id); - virtual void SelectType(); - virtual void SelectRegion(); - virtual void GenerateStandardElements(); - virtual void GenerateMissionElements(); - virtual void CreateElements(CombatGroup* g); - virtual void CreateSquadron(CombatGroup* g); - virtual void CreatePlayer(); - - virtual void CreateWards(); - virtual void CreateWardFreight(); - - virtual void CreateEscorts(); - - virtual void CreateTargets(); - virtual void CreateTargetsAssault(); - virtual void CreateTargetsPatrol(); - virtual void CreateTargetsCarrier(); - virtual void CreateTargetsFreightEscort(); - virtual int CreateRandomTarget(const char* rgn, Point base_loc); - - virtual MissionElement* - CreateSingleElement(CombatGroup* g, - CombatUnit* u); - virtual MissionElement* - CreateFighterPackage(CombatGroup* squadron, - int count, - int role); - - virtual CombatGroup* FindSquadron(int iff, int type); - virtual CombatUnit* FindCarrier(CombatGroup* g); - - virtual void DefineMissionObjectives(); - virtual MissionInfo* DescribeMission(); - virtual void Exit(); - - Campaign* campaign; - CampaignMissionRequest* request; - MissionInfo* mission_info; - - CombatUnit* player_unit; - CombatGroup* player_group; - CombatGroup* strike_group; - CombatGroup* strike_target; - Mission* mission; - List player_group_elements; - MissionElement* player; - MissionElement* ward; - MissionElement* prime_target; - MissionElement* escort; - - int ownside; - int enemy; - int mission_type; -}; - -#endif // CampaignMissionStarship_h - diff --git a/Stars45/CampaignPlan.h b/Stars45/CampaignPlan.h deleted file mode 100644 index 035e589..0000000 --- a/Stars45/CampaignPlan.h +++ /dev/null @@ -1,57 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlan defines the interface for all campaign - planning algorithms. Known subclasses: - CampaignPlanStrategic - strategic planning - CampaignPlanAssignment - logistics planning - CampaignPlanMission - mission planning - CampaignPlanMovement - starship movement - CampaignPlanEvent - scripted events -*/ - -#ifndef CampaignPlan_h -#define CampaignPlan_h - -#include "Types.h" -#include "Text.h" -#include "Term.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class Combatant; -class CombatGroup; -class CombatUnit; - -// +--------------------------------------------------------------------+ - -class CampaignPlan -{ -public: - static const char* TYPENAME() { return "CampaignPlan"; } - - CampaignPlan(Campaign* c) : campaign(c), exec_time(-1e6) { } - virtual ~CampaignPlan() { } - - int operator == (const CampaignPlan& p) const { return this == &p; } - - // operations: - virtual void ExecFrame() { } - virtual void SetLockout(int seconds) { } - -protected: - Campaign* campaign; - double exec_time; -}; - -#endif // CampaignPlan_h - diff --git a/Stars45/CampaignPlanAssignment.cpp b/Stars45/CampaignPlanAssignment.cpp deleted file mode 100644 index c4381ed..0000000 --- a/Stars45/CampaignPlanAssignment.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlanAssignment creates combat assignments for - assets within each combat zone as the third step in - force tasking. -*/ - -#include "CampaignPlanAssignment.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAssignment.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Mission.h" - -// +--------------------------------------------------------------------+ - -void -CampaignPlanAssignment::ExecFrame() -{ - if (campaign && campaign->IsActive()) { - // once every few minutes is plenty: - if (Campaign::Stardate() - exec_time < 300) - return; - - ListIter iter = campaign->GetCombatants(); - while (++iter) { - ProcessCombatant(iter.value()); - } - - exec_time = Campaign::Stardate(); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanAssignment::ProcessCombatant(Combatant* c) -{ - CombatGroup* force = c->GetForce(); - if (force) { - force->CalcValue(); - force->ClearAssignments(); - } - - ListIter zone = campaign->GetZones(); - while (++zone) { - ProcessZone(c, zone.value()); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanAssignment::BuildZoneList(CombatGroup* g, CombatZone* zone, List& groups) -{ - if (!g) - return; - - if (g->GetAssignedZone() == zone) - groups.append(g); - - ListIter iter = g->GetComponents(); - while (++iter) - BuildZoneList(iter.value(), zone, groups); -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanAssignment::BuildAssetList(const int* pref, -List& groups, -List& assets) -{ - if (!pref) - return; - - while (*pref) { - ListIter g = groups; - while (++g) { - if (g->Type() == *pref && g->CountUnits() > 0) - assets.append(g.value()); - } - - pref++; - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanAssignment::ProcessZone(Combatant* c, CombatZone* zone) -{ - List groups; - BuildZoneList(c->GetForce(), zone, groups); - - ZoneForce* force = zone->FindForce(c->GetIFF()); - - // defensive assignments: - ListIter def = force->GetDefendList(); - while (++def) { - List assets; - BuildAssetList(CombatGroup::PreferredDefender(def->Type()), groups, assets); - - ListIter g = assets; - while (++g) { - CombatAssignment* a = new - CombatAssignment(Mission::DEFEND, - def.value(), - g.value()); - - if (a) - g->GetAssignments().append(a); - } - } - - // offensive assignments: - ListIter tgt = force->GetTargetList(); - while (++tgt) { - CombatGroup* target = tgt.value(); - - List assets; - BuildAssetList(CombatGroup::PreferredAttacker(tgt->Type()), groups, assets); - - ListIter g = assets; - while (++g) { - CombatGroup* asset = g.value(); - int mtype = Mission::ASSAULT; - - if (target->IsStrikeTarget()) - mtype = Mission::STRIKE; - - else if (target->IsFighterGroup()) - mtype = Mission::SWEEP; - - else if (target->Type() == CombatGroup::LCA_SQUADRON) - mtype = Mission::INTERCEPT; - - CombatAssignment* a = new - CombatAssignment(mtype, target, asset); - - if (a) - g->GetAssignments().append(a); - } - } -} - diff --git a/Stars45/CampaignPlanAssignment.h b/Stars45/CampaignPlanAssignment.h deleted file mode 100644 index 4427fc0..0000000 --- a/Stars45/CampaignPlanAssignment.h +++ /dev/null @@ -1,49 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlanAssignment creates combat assignments for - assets within each combat zone as the third step in - force tasking. -*/ - -#ifndef CampaignPlanAssignment_h -#define CampaignPlanAssignment_h - -#include "Types.h" -#include "CampaignPlan.h" - -// +--------------------------------------------------------------------+ - -class CombatGroup; -class CombatUnit; -class CombatZone; - -// +--------------------------------------------------------------------+ - -class CampaignPlanAssignment : public CampaignPlan -{ -public: - static const char* TYPENAME() { return "CampaignPlanAssignment"; } - - CampaignPlanAssignment(Campaign* c) : CampaignPlan(c) { } - virtual ~CampaignPlanAssignment() { } - - // operations: - virtual void ExecFrame(); - -protected: - virtual void ProcessCombatant(Combatant* c); - virtual void ProcessZone(Combatant* c, CombatZone* zone); - virtual void BuildZoneList(CombatGroup* g, CombatZone* zone, List& list); - virtual void BuildAssetList(const int* pref, List& avail, List& assets); -}; - -#endif // CampaignPlanAssignment_h - diff --git a/Stars45/CampaignPlanEvent.cpp b/Stars45/CampaignPlanEvent.cpp deleted file mode 100644 index f487984..0000000 --- a/Stars45/CampaignPlanEvent.cpp +++ /dev/null @@ -1,1274 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlanEvent generates simulated combat - events based on a statistical analysis of the - combatants within the context of a dynamic - campaign. -*/ - -#include "CampaignPlanEvent.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAction.h" -#include "CombatAssignment.h" -#include "CombatEvent.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Mission.h" -#include "Random.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ - -CampaignPlanEvent::CampaignPlanEvent(Campaign* c) - : CampaignPlan(c), event_time(0) -{ - if (campaign) { - event_time = (int) campaign->GetTime(); - } -} - -CampaignPlanEvent::~CampaignPlanEvent() -{ } - -// +--------------------------------------------------------------------+ - -void -CampaignPlanEvent::ExecFrame() -{ - if (campaign && campaign->IsActive()) { - if (!campaign->GetPlayerGroup()) - return; - - // once every twenty minutes is plenty: - if (Campaign::Stardate() - exec_time < 1200) - return; - - if (!ExecScriptedEvents()) - ExecStatisticalEvents(); - - exec_time = Campaign::Stardate(); - event_time = (int) campaign->GetTime(); - } -} - -void -CampaignPlanEvent::SetLockout(int seconds) -{ - exec_time = Campaign::Stardate() + seconds; -} - -// +--------------------------------------------------------------------+ - -bool -CampaignPlanEvent::ExecScriptedEvents() -{ - bool scripted_event = false; - - if (campaign) { - ListIter iter = campaign->GetActions(); - while (++iter) { - CombatAction* action = iter.value(); - - if (action->IsAvailable()) { - - switch (action->Type()) { - case CombatAction::COMBAT_EVENT: - { - CombatEvent* event = new - CombatEvent(campaign, - action->Subtype(), - (int) campaign->GetTime(), - action->GetIFF(), - action->Source(), - action->Region()); - - if (!event) - return false; - - event->SetTitle(action->GetText()); - - if (*action->Filename() != 0) - event->SetFilename(action->Filename()); - - if (*action->ImageFile() != 0) - event->SetImageFile(action->ImageFile()); - - if (*action->SceneFile() != 0) - event->SetSceneFile(action->SceneFile()); - - event->Load(); - - ProsecuteKills(action); - campaign->GetEvents().append(event); - - action->FireAction(); - scripted_event = true; - - if (action->Subtype() == CombatEvent::CAMPAIGN_END) { - ::Print(">>>>> CAMPAIGN %d END (Action %03d) <<<<<\n", campaign->GetCampaignId(), action->Identity()); - campaign->SetStatus(Campaign::CAMPAIGN_SUCCESS); - } - - else if (action->Subtype() == CombatEvent::CAMPAIGN_FAIL) { - ::Print(">>>>> CAMPAIGN %d FAIL (Action %03d) <<<<<\n", campaign->GetCampaignId(), action->Identity()); - campaign->SetStatus(Campaign::CAMPAIGN_FAILED); - } - } - break; - - case CombatAction::STRATEGIC_DIRECTIVE: - { - CombatGroup* g = campaign->FindGroup(action->GetIFF(), - action->AssetType(), - action->AssetId()); - - if (g) { - g->SetStrategicDirection(action->GetText()); - action->FireAction(); - } - else { - action->FailAction(); - } - - scripted_event = true; - } - break; - - case CombatAction::CAMPAIGN_SITUATION: - { - campaign->SetSituation(action->GetText()); - action->FireAction(); - scripted_event = true; - } - break; - - case CombatAction::CAMPAIGN_ORDERS: - { - campaign->SetOrders(action->GetText()); - action->FireAction(); - scripted_event = true; - } - break; - - case CombatAction::INTEL_EVENT: - { - CombatGroup* g = campaign->FindGroup(action->GetIFF(), - action->AssetType(), - action->AssetId()); - - if (g) { - g->SetIntelLevel(action->Subtype()); - action->FireAction(); - } - else { - ::Print("WARNING: Action %d (intel level) Could not find group (IFF:%d, type:%d, id:%d)\n", - action->Identity(), - action->GetIFF(), - action->AssetType(), - action->AssetId()); - - action->FailAction(); - } - - scripted_event = true; - } - break; - - case CombatAction::ZONE_ASSIGNMENT: - { - CombatGroup* g = campaign->FindGroup(action->GetIFF(), - action->AssetType(), - action->AssetId()); - - if (g) { - bool found = false; - - if (*action->Region()) { - CombatZone* zone = campaign->GetZone(action->Region()); - - if (zone) { - g->SetAssignedZone(zone); - g->SetZoneLock(true); - found = true; - - // don't announce the move unless it's for the player's team: - if (action->GetIFF() == campaign->GetPlayerIFF() && _stricmp(action->GetText(), "do-not-display")) { - CombatEvent* event = new - CombatEvent(campaign, - CombatEvent::MOVE_TO, - (int) campaign->GetTime(), - action->GetIFF(), - CombatEvent::FORCOM, - action->Region()); - - if (!event) - return false; - - Text title = Text(g->Name()) + " Orders: Proceed to " + action->Region() + " Sector"; - event->SetTitle(title); - - double eta = campaign->GetTime() + 3600; - eta -= fmod(eta, 1800); - - char text[64]; - FormatDayTime(text, eta); - - Text info = "ORDERS:\n\nEffective immediately, "; - info += g->GetDescription(); - info += " and all associated units shall proceed to "; - info += action->Region(); - info += " sector and commence spaceborne operations in that area. ETA rendevous point "; - info += text; - info += ".\n\nFleet Admiral A. Evars FORCOM\nCommanding"; - - event->SetInformation(info); - - if (*action->ImageFile() != 0) - event->SetImageFile(action->ImageFile()); - - if (*action->SceneFile() != 0) - event->SetSceneFile(action->SceneFile()); - - event->Load(); - campaign->GetEvents().append(event); - } - } - } - - if (!found) { - ::Print("WARNING: Action %d Could not find assigned zone '%s' for '%s'\n", - action->Identity(), - action->Region() ? action->Region() : "NULL", - g->Name().data()); - - g->SetAssignedZone(0); - } - - action->FireAction(); - } - else { - ::Print("WARNING: Action %d (zone assignment) Could not find group (IFF:%d, type:%d, id:%d)\n", - action->Identity(), - action->GetIFF(), - action->AssetType(), - action->AssetId()); - - action->FailAction(); - } - - scripted_event = true; - } - break; - - case CombatAction::SYSTEM_ASSIGNMENT: - { - CombatGroup* g = campaign->FindGroup(action->GetIFF(), - action->AssetType(), - action->AssetId()); - - if (g) { - bool found = false; - - if (*action->System()) { - Text system = action->System(); - - if (campaign->GetSystem(system)) { - g->SetAssignedSystem(system); - found = true; - - // don't announce the move unless it's for the player's team: - if (action->GetIFF() == campaign->GetPlayerIFF() && _stricmp(action->GetText(), "do-not-display")) { - CombatEvent* event = new - CombatEvent(campaign, - CombatEvent::MOVE_TO, - (int) campaign->GetTime(), - action->GetIFF(), - CombatEvent::FORCOM, - action->Region()); - - if (!event) - return false; - - Text title = Text(g->Name()) + " Orders: Proceed to " + action->System() + " System"; - event->SetTitle(title); - - double eta = campaign->GetTime() + 3600; - eta -= fmod(eta, 1800); - - char text[64]; - FormatDayTime(text, eta); - - Text info = "ORDERS:\n\nEffective immediately, "; - info += g->GetDescription(); - info += " and all associated units shall proceed to the "; - info += action->System(); - info += " star system and commence spaceborne operations in that area. ETA rendevous point "; - info += text; - info += ".\n\nFleet Admiral A. Evars FORCOM\nCommanding"; - - event->SetInformation(info); - - if (*action->ImageFile() != 0) - event->SetImageFile(action->ImageFile()); - - if (*action->SceneFile() != 0) - event->SetSceneFile(action->SceneFile()); - - event->Load(); - campaign->GetEvents().append(event); - } - } - } - - if (!found) { - ::Print("WARNING: Action %d Could not find assigned system '%s' for '%s'\n", - action->Identity(), - action->System() ? action->System() : "NULL", - g->Name().data()); - - g->SetAssignedSystem(""); - } - - action->FireAction(); - } - else { - ::Print("WARNING: Action %d (system assignment) Could not find group (IFF:%d, type:%d, id:%d)\n", - action->Identity(), - action->GetIFF(), - action->AssetType(), - action->AssetId()); - - action->FailAction(); - } - - scripted_event = true; - } - break; - - case CombatAction::NO_ACTION: - action->FireAction(); - scripted_event = true; - break; - - default: - break; - } - } - } - } - - return scripted_event; -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanEvent::ProsecuteKills(CombatAction* action) -{ - if (action->AssetKills().size() > 0) { - CombatGroup* g = campaign->FindGroup(action->GetIFF(), - action->AssetType(), - action->AssetId()); - - if (g) { - ListIter iter = action->AssetKills(); - while (++iter) { - Text* name = iter.value(); - CombatUnit* asset = g->FindUnit(*name); - - if (asset) { - int value_killed = asset->Kill(1); - - ListIter iter = campaign->GetCombatants(); - while (++iter) { - Combatant* c = iter.value(); - if (c->GetIFF() > 0 && c->GetIFF() != asset->GetIFF()) { - // damage to neutral assets must be scored to bad guys: - if (asset->GetIFF() > 0 || c->GetIFF() > 1) { - c->AddScore(value_killed); - break; - } - } - } - } - } - } - } - - if (action->TargetKills().size() > 0) { - CombatGroup* g = campaign->FindGroup(action->TargetIFF(), - action->TargetType(), - action->TargetId()); - - if (g) { - ListIter iter = action->TargetKills(); - while (++iter) { - Text* name = iter.value(); - CombatUnit* target = g->FindUnit(*name); - - if (target) { - int value_killed = target->Kill(1); - - ListIter iter = campaign->GetCombatants(); - while (++iter) { - Combatant* c = iter.value(); - if (c->GetIFF() > 0 && c->GetIFF() != target->GetIFF()) { - // damage to neutral assets must be scored to bad guys: - if (target->GetIFF() > 0 || c->GetIFF() > 1) { - c->AddScore(value_killed); - break; - } - } - } - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -bool -CampaignPlanEvent::ExecStatisticalEvents() -{ - bool result = false; - - if (campaign) { - ListIter iter = campaign->GetCombatants(); - while (++iter && !result) { - Combatant* c = iter.value(); - CombatAssignment* a = ChooseAssignment(c->GetForce()); - - // prefer assignments not in player's zone: - if (a) { - CombatGroup* objective = a->GetObjective(); - CombatGroup* player = campaign->GetPlayerGroup(); - - if (objective && player && - objective->GetCurrentZone() == player->GetCurrentZone()) - a = ChooseAssignment(c->GetForce()); - } - - if (a) { - result = CreateEvent(a); - } - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -bool -CampaignPlanEvent::CreateEvent(CombatAssignment* a) -{ - CombatEvent* event = 0; - - if (campaign && a && a->GetResource() && RandomChance(1,2)) { - event_time = (int) Random(event_time, campaign->GetTime()); - - CombatGroup* group = a->GetResource(); - - if (group == campaign->GetPlayerGroup()) { - - if (group->Type() == CombatGroup::DESTROYER_SQUADRON || - group->Type() == CombatGroup::BATTLE_GROUP || - group->Type() == CombatGroup::CARRIER_GROUP) { - - return false; - } - } - - CombatGroup* target = a->GetObjective(); - - if (target && target == campaign->GetPlayerGroup()) { - - if (target->Type() == CombatGroup::DESTROYER_SQUADRON || - target->Type() == CombatGroup::BATTLE_GROUP || - target->Type() == CombatGroup::CARRIER_GROUP) { - - return false; - } - } - - switch (a->Type()) { - case Mission::DEFEND: - event = CreateEventDefend(a); - break; - - case Mission::ASSAULT: - if (group->IsStarshipGroup()) - event = CreateEventStarship(a); - else - event = CreateEventFighterAssault(a); - break; - - case Mission::STRIKE: - if (group->IsStarshipGroup()) - event = CreateEventStarship(a); - else - event = CreateEventFighterStrike(a); - break; - - case Mission::SWEEP: - event = CreateEventFighterSweep(a); - break; - } - - if (event) { - campaign->GetEvents().append(event); - return true; - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -static void FindAssignments(CombatGroup* g, List& alist) -{ - if (!g) return; - - alist.append(g->GetAssignments()); - - ListIter iter = g->GetComponents(); - while (++iter) - FindAssignments(iter.value(), alist); -} - -CombatAssignment* -CampaignPlanEvent::ChooseAssignment(CombatGroup* g) -{ - List alist; - FindAssignments(g, alist); - - int tries = 5; - - if (alist.size() > 0) { - while (tries-- > 0) { - int index = (int) Random(0, alist.size()); - - if (index >= alist.size()) - index = 0; - - CombatAssignment* a = alist[index]; - - if (!a) continue; - - CombatGroup* resource = a->GetResource(); - CombatGroup* objective = a->GetObjective(); - - if (!resource || !objective) - continue; - - if (resource->IsReserve() || objective->IsReserve()) - continue; - - if (resource->CalcValue() < 50 || objective->CalcValue() < 50) - continue; - - if (resource == campaign->GetPlayerGroup() || objective == campaign->GetPlayerGroup()) - continue; - - return a; - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -CombatEvent* -CampaignPlanEvent::CreateEventDefend(CombatAssignment* a) -{ - bool friendly = IsFriendlyAssignment(a); - - if (!friendly) - return 0; - - CombatEvent* event = 0; - CombatGroup* group = a->GetResource(); - CombatGroup* obj = a->GetObjective(); - CombatUnit* unit = group->GetRandomUnit(); - CombatUnit* tgt = obj->GetRandomUnit(); - - if (!unit || !tgt) - return 0; - - bool success = Success(a); - Text rgn = group->GetRegion(); - Text title = Text(group->Name()) + " in Defensive Engagement"; - Text info; - - event = new CombatEvent(campaign, - CombatEvent::DEFEND, - event_time, - group->GetIFF(), - CombatEvent::TACNET, - rgn); - - if (!event) - return 0; - - int tgt_count = 0; - int unit_count = 0; - - if (!success) { - if (tgt) { - if (tgt->Kill(1) > 0) - tgt_count++; - Combatant* c = group->GetCombatant(); - if (c) c->AddScore(tgt->GetSingleValue()); - } - - if (unit && RandomChance(1,5)) { - if (unit->Kill(1) > 0) - unit_count++; - Combatant* c = obj->GetCombatant(); - if (c) c->AddScore(unit->GetSingleValue()); - } - } - - CombatGroup* us = group; - CombatGroup* them = obj; - int us_count = unit_count; - int them_count = tgt_count; - - if (obj->IsStrikeTarget()) { - info = Text("EVENT: ") + rgn + " Sector\n\n"; - } - - else { - info = Text("MISSION: Escort ") + obj->Name() + ", " + rgn + " Sector\n\n"; - } - - info += GetTeamName(group); - info += Text(" ") + group->GetDescription(); - - if (success) - info += " successfully defended "; - else - info += " was unable to defend "; - - info += GetTeamName(obj); - info += Text(" ") + obj->GetDescription() + ".\n\n"; - - // need to find an enemy group to do the attacking... - - event->SetTitle(title); - event->SetInformation(info); - return event; -} - -// +--------------------------------------------------------------------+ - -CombatEvent* -CampaignPlanEvent::CreateEventFighterAssault(CombatAssignment* a) -{ - CombatEvent* event = 0; - CombatGroup* group = a->GetResource(); - CombatGroup* obj = a->GetObjective(); - CombatUnit* unit = group->GetRandomUnit(); - CombatUnit* tgt = obj->GetRandomUnit(); - - if (!unit || !tgt) - return 0; - - bool success = Success(a); - Text rgn = group->GetRegion(); - Text title = Text(group->Name()); - Text info; - - event = new CombatEvent(campaign, - CombatEvent::ATTACK, - event_time, - group->GetIFF(), - CombatEvent::TACNET, - rgn); - - if (!event) - return 0; - - title += Text(" Assault ") + obj->Name(); - - int tgt_count = 0; - int unit_count = 0; - - if (success) { - if (tgt) { - int killed = tgt->Kill(1 + tgt->Count()/2); - if (killed > 0) - tgt_count += killed / tgt->GetSingleValue(); - Combatant* c = group->GetCombatant(); - if (c) c->AddScore(tgt->GetSingleValue()); - } - - if (unit && RandomChance(1,5)) { - if (unit->Kill(1) > 0) - unit_count++; - Combatant* c = obj->GetCombatant(); - if (c) c->AddScore(unit->GetSingleValue()); - } - } - else { - for (int i = 0; i < 2; i++) { - if (unit && RandomChance(1,4)) { - if (unit->Kill(1) > 0) - unit_count++; - Combatant* c = obj->GetCombatant(); - if (c) c->AddScore(unit->GetSingleValue()); - } - } - } - - CombatGroup* us = group; - CombatGroup* them = obj; - int us_count = unit_count; - int them_count = tgt_count; - - bool friendly = IsFriendlyAssignment(a); - - if (friendly) { - info = Text("MISSION: Strike, ") + rgn + " Sector\n\n"; - } - - else { - info = Text("EVENT: ") + rgn + " Sector\n\n"; - - us = obj; - them = group; - us_count = tgt_count; - them_count = unit_count; - } - - info += GetTeamName(group); - info += Text(" ") + group->GetDescription(); - - if (success) - info += " successfully assault "; - else if (!friendly) - info += " assault averted against "; - else - info += " attempted assault on "; - - info += GetTeamName(obj); - info += Text(" ") + obj->GetDescription() + ".\n\n"; - - char text[256]; - - if (them_count) { - if (friendly) { - if (them_count > 1) - sprintf_s(text, "ENEMY KILLED:\t %d %s destroyed\n", them_count, tgt->Name().data()); - else - sprintf_s(text, "ENEMY KILLED:\t %s destroyed\n", tgt->Name().data()); - } else { - sprintf_s(text, "ENEMY KILLED:\t %d %s destroyed\n", them_count, them->Name().data()); - } - - info += text; - } else { - info += "ENEMY KILLED:\t 0\n"; - } - - if (us_count) { - if (!friendly) - sprintf_s(text, "ALLIED LOSSES:\t %s destroyed\n", tgt->Name().data()); - else - sprintf_s(text, "ALLIED LOSSES:\t %d %s destroyed", us_count, us->Name().data()); - - info += text; - } - else { - info += "ALLIED LOSSES:\t 0"; - } - - - event->SetTitle(title); - event->SetInformation(info); - return event; -} - -// +--------------------------------------------------------------------+ - -CombatEvent* -CampaignPlanEvent::CreateEventFighterStrike(CombatAssignment* a) -{ - CombatEvent* event = 0; - CombatGroup* group = a->GetResource(); - CombatGroup* obj = a->GetObjective(); - CombatUnit* unit = group->GetRandomUnit(); - CombatUnit* tgt = obj->GetRandomUnit(); - - if (!unit || !tgt) - return 0; - - bool success = Success(a); - Text rgn = group->GetRegion(); - Text title = Text(group->Name()); - Text info; - - event = new CombatEvent(campaign, - CombatEvent::ATTACK, - event_time, - group->GetIFF(), - CombatEvent::TACNET, - rgn); - - if (!event) - return 0; - - if (unit) - title += Text(" ") + unit->GetDesign()->abrv + "s"; - - if (success) { - title += " Successfully Strike " + obj->Name(); - } - else { - title += " Attempt Strike on " + obj->Name(); - } - - int tgt_count = 0; - int unit_count = 0; - - if (success) { - if (tgt) { - int killed = tgt->Kill(1 + tgt->Count()/2); - if (killed > 0) - tgt_count += killed / tgt->GetSingleValue(); - Combatant* c = group->GetCombatant(); - if (c) c->AddScore(tgt->GetSingleValue()); - } - - if (unit && RandomChance(1,5)) { - if (unit->Kill(1) > 0) - unit_count++; - Combatant* c = obj->GetCombatant(); - if (c) c->AddScore(unit->GetSingleValue()); - } - } - else { - for (int i = 0; i < 2; i++) { - if (unit && RandomChance(1,4)) { - if (unit->Kill(1) > 0) - unit_count++; - Combatant* c = obj->GetCombatant(); - if (c) c->AddScore(unit->GetSingleValue()); - } - } - } - - CombatGroup* us = group; - CombatGroup* them = obj; - int us_count = unit_count; - int them_count = tgt_count; - - bool friendly = IsFriendlyAssignment(a); - - if (friendly) { - info = Text("MISSION: Strike, ") + rgn + " Sector\n\n"; - } - - else { - info = Text("EVENT: ") + rgn + " Sector\n\n"; - - us = obj; - them = group; - us_count = tgt_count; - them_count = unit_count; - } - - info += GetTeamName(group); - info += Text(" ") + group->GetDescription(); - - if (success) - info += " successfully strike "; - else if (!friendly) - info += " strike against "; - else - info += " attempted strike on "; - - info += GetTeamName(obj); - info += Text(" ") + obj->GetDescription(); - - if (!success && !friendly) - info += " averted.\n\n"; - else - info += ".\n\n"; - - char text[256]; - - if (them_count) { - if (friendly) { - if (them_count > 1) - sprintf_s(text, "ENEMY KILLED:\t %d %s destroyed\n", them_count, tgt->Name().data()); - else - sprintf_s(text, "ENEMY KILLED:\t %s destroyed\n", tgt->Name().data()); - } else { - sprintf_s(text, "ENEMY KILLED:\t %d %s destroyed\n", them_count, them->Name().data()); - } - - info += text; - } else { - info += "ENEMY KILLED:\t 0\n"; - } - - if (us_count) { - if (!friendly) - sprintf_s(text, "ALLIED LOSSES:\t %s destroyed\n", tgt->Name().data()); - else - sprintf_s(text, "ALLIED LOSSES:\t %d %s destroyed", us_count, us->Name().data()); - - info += text; - } else { - info += "ALLIED LOSSES:\t 0"; - } - - event->SetTitle(title); - event->SetInformation(info); - return event; -} - -// +--------------------------------------------------------------------+ - -CombatEvent* -CampaignPlanEvent::CreateEventFighterSweep(CombatAssignment* a) -{ - CombatEvent* event = 0; - CombatGroup* group = a->GetResource(); - CombatGroup* obj = a->GetObjective(); - CombatUnit* unit = group->GetRandomUnit(); - CombatUnit* tgt = obj->GetRandomUnit(); - - if (!unit || !tgt) - return 0; - - bool success = Success(a); - Text rgn = group->GetRegion(); - Text title = Text(group->Name()); - Text info; - - event = new CombatEvent(campaign, - CombatEvent::ATTACK, - event_time, - group->GetIFF(), - CombatEvent::TACNET, - rgn); - - if (!event) - return 0; - - if (unit) - title += Text(" ") + unit->GetDesign()->abrv + "s"; - else - title += " Fighters"; - - if (RandomChance(1, 4)) title += " Clash with "; - else if (RandomChance(1, 4)) title += " Engage "; - else if (RandomChance(1, 4)) title += " Intercept "; - else title += " Encounter "; - - title += obj->Name(); - - int tgt_count = 0; - int unit_count = 0; - - if (success) { - for (int i = 0; i < 2; i++) { - if (tgt && RandomChance(3,4)) { - if (tgt->Kill(1) > 0) - tgt_count++; - Combatant* c = group->GetCombatant(); - if (c) c->AddScore(tgt->GetSingleValue()); - } - } - - if (tgt_count > 1) { - if (tgt && RandomChance(1,4)) { - if (tgt->Kill(1) > 0) - tgt_count++; - Combatant* c = group->GetCombatant(); - if (c) c->AddScore(tgt->GetSingleValue()); - } - } - - else { - if (unit && RandomChance(1,5)) { - if (unit->Kill(1) > 0) - unit_count++; - Combatant* c = obj->GetCombatant(); - if (c) c->AddScore(unit->GetSingleValue()); - } - } - } - else { - for (int i = 0; i < 2; i++) { - if (unit && RandomChance(3,4)) { - if (unit->Kill(1) > 0) - unit_count++; - Combatant* c = obj->GetCombatant(); - if (c) c->AddScore(unit->GetSingleValue()); - } - } - - if (tgt && RandomChance(1,4)) { - if (tgt->Kill(1) > 0) - tgt_count++; - Combatant* c = group->GetCombatant(); - if (c) c->AddScore(tgt->GetSingleValue()); - } - } - - CombatGroup* us = group; - CombatGroup* them = obj; - int us_count = unit_count; - int them_count = tgt_count; - - bool friendly = IsFriendlyAssignment(a); - - if (!friendly) { - us = obj; - them = group; - us_count = tgt_count; - them_count = unit_count; - } - - if (friendly) { - if (RandomChance()) - info = Text("MISSION: OCA Sweep, ") + rgn + " Sector\n\n"; - else - info = Text("MISSION: FORCAP, ") + rgn + " Sector\n\n"; - - info += GetTeamName(group); - info += Text(" ") + group->GetDescription(); - info += Text(" engaged ") + GetTeamName(obj); - info += Text(" ") + obj->GetDescription() + ".\n\n"; - } - else { - info = Text("MISSION: Patrol, ") + rgn + " Sector\n\n"; - - info += GetTeamName(obj); - info += Text(" ") + obj->GetDescription(); - info += Text(" engaged ") + GetTeamName(group); - info += Text(" ") + group->GetDescription() + ".\n\n"; - } - - char text[256]; - - if (them_count) { - sprintf_s(text, "ENEMY KILLED:\t %d %s destroyed\n", them_count, them->Name().data()); - - info += text; - } else { - info += "ENEMY KILLED:\t 0\n"; - } - - if (us_count) { - sprintf_s(text, "ALLIED LOSSES:\t %d %s destroyed", us_count, us->Name().data()); - info += text; - } else { - info += "ALLIED LOSSES:\t 0"; - } - - event->SetTitle(title); - event->SetInformation(info); - return event; -} - -// +--------------------------------------------------------------------+ - -CombatEvent* -CampaignPlanEvent::CreateEventStarship(CombatAssignment* a) -{ - CombatEvent* event = 0; - CombatGroup* group = a->GetResource(); - CombatGroup* obj = a->GetObjective(); - CombatUnit* unit = group->GetRandomUnit(); - CombatUnit* tgt = obj->GetRandomUnit(); - - if (!unit || !tgt) - return 0; - - bool success = Success(a); - Text rgn = group->GetRegion(); - Text title = Text(group->Name()); - Text info; - - event = new CombatEvent(campaign, - CombatEvent::ATTACK, - event_time, - group->GetIFF(), - CombatEvent::TACNET, - group->GetRegion()); - - if (!event) - return 0; - - title += Text(" Assaults ") + a->GetObjective()->Name(); - - int tgt_count = 0; - int unit_count = 0; - - if (success) { - if (tgt) { - if (tgt->Kill(1) > 0) - tgt_count++; - Combatant* c = group->GetCombatant(); - if (c) c->AddScore(tgt->GetSingleValue()); - } - - if (unit && RandomChance(1,5)) { - if (unit->Kill(1) > 0) - unit_count++; - Combatant* c = obj->GetCombatant(); - if (c) c->AddScore(unit->GetSingleValue()); - } - } - else { - for (int i = 0; i < 2; i++) { - if (unit && RandomChance(1,4)) { - if (unit->Kill(1) > 0) - unit_count++; - Combatant* c = obj->GetCombatant(); - if (c) c->AddScore(unit->GetSingleValue()); - } - } - } - - CombatGroup* us = group; - CombatGroup* them = obj; - int us_count = unit_count; - int them_count = tgt_count; - - bool friendly = IsFriendlyAssignment(a); - - if (friendly) { - info = Text("MISSION: Fleet Action, ") + rgn + " Sector\n\n"; - } - - else { - info = Text("EVENT: ") + rgn + " Sector\n\n"; - - us = obj; - them = group; - us_count = tgt_count; - them_count = unit_count; - } - - info += GetTeamName(group); - info += Text(" ") + group->GetDescription(); - - if (success) - info += " successfully assaulted "; - else if (!friendly) - info += " assault against "; - else - info += " attempted assault on "; - - info += GetTeamName(obj); - info += Text(" ") + obj->GetDescription(); - - if (!success && !friendly) - info += " failed.\n\n"; - else - info += ".\n\n"; - - char text[256]; - - if (them_count) { - if (friendly) { - if (tgt->Count() > 1) { - sprintf_s(text, "ENEMY KILLED:\t %d %s destroyed\n", them_count, tgt->Name().data()); - } else { - sprintf_s(text, "ENEMY KILLED:\t %s destroyed\n", tgt->Name().data()); - } - } else { - if (unit->Count() > 1) { - sprintf_s(text, "ENEMY KILLED:\t %d %s destroyed\n", them_count, unit->Name().data()); - } else { - sprintf_s(text, "ENEMY KILLED:\t %s destroyed\n", unit->Name().data()); - } - } - - info += text; - } else { - info += "ENEMY KILLED:\t 0\n"; - } - - if (us_count) { - if (!friendly) - sprintf_s(text, "ALLIED LOSSES:\t %s destroyed\n", tgt->Name().data()); - else - sprintf_s(text, "ALLIED LOSSES:\t %s destroyed", unit->Name().data()); - - info += text; - } else { - info += "ALLIED LOSSES:\t 0"; - } - - event->SetTitle(title); - event->SetInformation(info); - return event; -} - -// +--------------------------------------------------------------------+ - -bool -CampaignPlanEvent::IsFriendlyAssignment(CombatAssignment* a) -{ - if (!campaign || !a || !a->GetResource()) - return false; - - int a_team = a->GetResource()->GetIFF(); - CombatGroup* player = campaign->GetPlayerGroup(); - - if (player && (player->GetIFF() == a_team)) - return true; - - return false; -} - -bool -CampaignPlanEvent::Success(CombatAssignment* a) -{ - if (!campaign || !a || !a->GetResource()) - return false; - - int odds = 6 - campaign->GetCampaignId(); - - if (odds < 1) - odds = 1; - - bool success = RandomChance(odds, 5); - - if (!IsFriendlyAssignment(a)) - success = !success; - - return success; -} - -// +--------------------------------------------------------------------+ - -Text -CampaignPlanEvent::GetTeamName(CombatGroup* g) -{ - while (g->GetParent()) - g = g->GetParent(); - - return g->Name(); -} diff --git a/Stars45/CampaignPlanEvent.h b/Stars45/CampaignPlanEvent.h deleted file mode 100644 index 77fbae2..0000000 --- a/Stars45/CampaignPlanEvent.h +++ /dev/null @@ -1,71 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlanEvent generates simulated combat - events based on a statistical analysis of the - combatants within the context of a dynamic - campaign. -*/ - -#ifndef CampaignPlanEvent_h -#define CampaignPlanEvent_h - -#include "Types.h" -#include "CampaignPlan.h" - -// +--------------------------------------------------------------------+ - -class CombatAction; -class CombatAssignment; -class CombatEvent; -class CombatGroup; -class CombatUnit; -class CombatZone; - -// +--------------------------------------------------------------------+ - -class CampaignPlanEvent : public CampaignPlan -{ -public: - static const char* TYPENAME() { return "CampaignPlanEvent"; } - - CampaignPlanEvent(Campaign* c); - virtual ~CampaignPlanEvent(); - - // operations: - virtual void ExecFrame(); - virtual void SetLockout(int seconds); - - virtual bool ExecScriptedEvents(); - virtual bool ExecStatisticalEvents(); - -protected: - virtual void ProsecuteKills(CombatAction* action); - - virtual CombatAssignment* - ChooseAssignment(CombatGroup* c); - virtual bool CreateEvent(CombatAssignment* a); - - virtual CombatEvent* CreateEventDefend(CombatAssignment* a); - virtual CombatEvent* CreateEventFighterAssault(CombatAssignment* a); - virtual CombatEvent* CreateEventFighterStrike(CombatAssignment* a); - virtual CombatEvent* CreateEventFighterSweep(CombatAssignment* a); - virtual CombatEvent* CreateEventStarship(CombatAssignment* a); - - virtual bool IsFriendlyAssignment(CombatAssignment* a); - virtual bool Success(CombatAssignment* a); - virtual Text GetTeamName(CombatGroup* g); - - // attributes: - int event_time; -}; - -#endif // CampaignPlanEvent_h - diff --git a/Stars45/CampaignPlanMission.cpp b/Stars45/CampaignPlanMission.cpp deleted file mode 100644 index fb8b38c..0000000 --- a/Stars45/CampaignPlanMission.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlanMission generates missions and mission - info for the player's combat group as part of a - dynamic campaign. -*/ - -#include "CampaignPlanMission.h" -#include "CampaignMissionRequest.h" -#include "CampaignMissionFighter.h" -#include "CampaignMissionStarship.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAction.h" -#include "CombatAssignment.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Mission.h" -#include "StarSystem.h" -#include "Random.h" - - -// +--------------------------------------------------------------------+ - -void -CampaignPlanMission::ExecFrame() -{ - if (campaign && campaign->IsActive()) { - player_group = campaign->GetPlayerGroup(); - if (!player_group) return; - - int missionCount = campaign->GetMissionList().size(); - - if (missionCount > 0) { - // starships only get one mission to pick from: - if (player_group->IsStarshipGroup()) - return; - - // fighters get a maximum of five missions: - if (missionCount >= 5) - return; - - // otherwise, once every few seconds is plenty: - if (Campaign::Stardate() - exec_time < 1) - return; - } - - SelectStartTime(); - - if (player_group->IsFighterGroup()) { - slot++; - if (slot > 2) slot = 0; - - CampaignMissionRequest* request = PlanFighterMission(); - CampaignMissionFighter generator(campaign); - generator.CreateMission(request); - delete request; - } - - else if (player_group->IsStarshipGroup()) { - // starships should always check for campaign and strategic missions - slot = 0; - - CampaignMissionRequest* request = PlanStarshipMission(); - CampaignMissionStarship generator(campaign); - generator.CreateMission(request); - delete request; - } - - exec_time = Campaign::Stardate(); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanMission::SelectStartTime() -{ - const int HOUR = 3600; // 60 minutes - const int MISSION_DELAY = 1800; // 30 minutes - double base_time = 0; - - List& info_list = campaign->GetMissionList(); - - if (info_list.size() > 0) { - MissionInfo* info = info_list[info_list.size()-1]; - base_time = info->start; - } - - if (base_time == 0) - base_time = campaign->GetTime() + MISSION_DELAY; - - start = (int) base_time + MISSION_DELAY; - start -= start % MISSION_DELAY; -} - -// +--------------------------------------------------------------------+ - -CampaignMissionRequest* -CampaignPlanMission::PlanStarshipMission() -{ - CampaignMissionRequest* request = 0; - - if (!request) request = PlanCampaignMission(); - if (!request) request = PlanStrategicMission(); - if (!request) request = PlanRandomStarshipMission(); - - return request; -} - -// +--------------------------------------------------------------------+ - -CampaignMissionRequest* -CampaignPlanMission::PlanFighterMission() -{ - CampaignMissionRequest* request = 0; - - if (!request) request = PlanCampaignMission(); - if (!request) request = PlanStrategicMission(); - if (!request) request = PlanRandomFighterMission(); - - return request; -} - -// +--------------------------------------------------------------------+ - -CampaignMissionRequest* -CampaignPlanMission::PlanCampaignMission() -{ - CampaignMissionRequest* request = 0; - - ListIter iter = campaign->GetActions(); - while (++iter && !request) { - CombatAction* action = iter.value(); - - if (action->Type() != CombatAction::MISSION_TEMPLATE) - continue; - - if (action->IsAvailable()) { - - // only fire each action once every two hours: - if (action->ExecTime() > 0 && campaign->GetTime() - action->ExecTime() < 7200) - continue; - - CombatGroup* g = campaign->FindGroup(action->GetIFF(), - action->AssetType(), - action->AssetId()); - - if (g && (g == player_group || - (player_group->Type() == CombatGroup::WING && - player_group->FindGroup(g->Type(), g->GetID())))) { - - request = new - CampaignMissionRequest(campaign, - action->Subtype(), - start, - g); - - if (request) { - request->SetOpposingType(action->OpposingType()); - request->SetScript(action->GetText()); - } - - action->FireAction(); - } - } - } - - return request; -} - -// +--------------------------------------------------------------------+ - -CampaignMissionRequest* -CampaignPlanMission::PlanStrategicMission() -{ - CampaignMissionRequest* request = 0; - - if (slot > 1) - return request; - - // build list of assignments: - List assignments; - assignments.append(player_group->GetAssignments()); - - if (player_group->Type() == CombatGroup::WING) { - ListIter iter = player_group->GetComponents(); - while (++iter) { - CombatGroup* g = iter.value(); - assignments.append(g->GetAssignments()); - } - } - - // pick next assignment as basis for mission: - static int assignment_index = 0; - - if (assignments.size()) { - if (assignment_index >= assignments.size()) - assignment_index = 0; - - CombatAssignment* a = assignments[assignment_index++]; - - request = new - CampaignMissionRequest(campaign, - a->Type(), - start, - a->GetResource()); - - if (request) - request->SetObjective(a->GetObjective()); - } - - return request; -} - -// +--------------------------------------------------------------------+ - -static int mission_type_index = -1; -static int mission_types[16] = { - Mission::PATROL, - Mission::PATROL, - Mission::ESCORT_FREIGHT, - Mission::PATROL, - Mission::ESCORT_FREIGHT, - Mission::PATROL, - Mission::ESCORT_FREIGHT, - Mission::ESCORT_FREIGHT, - Mission::PATROL, - Mission::ESCORT_FREIGHT, - Mission::PATROL, - Mission::ESCORT_FREIGHT, - Mission::PATROL, - Mission::PATROL, - Mission::ESCORT_FREIGHT, - Mission::PATROL -}; - -// +--------------------------------------------------------------------+ - -CampaignMissionRequest* -CampaignPlanMission::PlanRandomStarshipMission() -{ - int type = Mission::PATROL; - int r = RandomIndex(); - int ownside = player_group->GetIFF(); - - if (mission_type_index < 0) - mission_type_index = r; - - else if (mission_type_index >= 16) - mission_type_index = 0; - - type = mission_types[mission_type_index++]; - - if (type == Mission::ESCORT_FREIGHT) { - CombatGroup* freight = campaign->FindGroup(ownside, CombatGroup::FREIGHT); - if (!freight || freight->CountUnits() < 1) - type = Mission::PATROL; - } - - CampaignMissionRequest* request = 0; - request = new - CampaignMissionRequest(campaign, type, start, player_group); - - return request; -} - -// +--------------------------------------------------------------------+ - -static int fighter_mission_index = 0; -static int fighter_mission_types[16] = { - Mission::PATROL, - Mission::SWEEP, - Mission::ESCORT_SHUTTLE, - Mission::AIR_PATROL, - Mission::SWEEP, - Mission::ESCORT_SHUTTLE, - Mission::PATROL, - Mission::PATROL, - Mission::AIR_SWEEP, - Mission::PATROL, - Mission::AIR_PATROL, - Mission::ESCORT_SHUTTLE, - Mission::PATROL, - Mission::SWEEP, - Mission::PATROL, - Mission::AIR_SWEEP -}; - -CampaignMissionRequest* -CampaignPlanMission::PlanRandomFighterMission() -{ - CampaignMissionRequest* request = 0; - int type = fighter_mission_types[fighter_mission_index++]; - int ownside = player_group->GetIFF(); - CombatGroup* primary = player_group; - CombatGroup* obj = 0; - - if (fighter_mission_index > 15) - fighter_mission_index = 0; - - if (type == Mission::ESCORT_FREIGHT) { - CombatGroup* freight = campaign->FindGroup(ownside, CombatGroup::FREIGHT); - if (!freight || freight->CalcValue() < 1) - type = Mission::PATROL; - else - obj = freight; - } - - else if (type == Mission::ESCORT_SHUTTLE) { - CombatGroup* shuttle = campaign->FindGroup(ownside, CombatGroup::LCA_SQUADRON); - if (!shuttle || shuttle->CalcValue() < 1) - type = Mission::PATROL; - else - obj = shuttle; - } - - else if (primary->Type() == CombatGroup::WING) { - if (RandomChance()) - primary = primary->FindGroup(CombatGroup::INTERCEPT_SQUADRON); - else - primary = primary->FindGroup(CombatGroup::FIGHTER_SQUADRON); - } - - if (type >= Mission::AIR_PATROL && type <= Mission::AIR_INTERCEPT) { - CombatZone* zone = 0; - bool airborne = false; - - if (primary) - zone = primary->GetAssignedZone(); - - if (zone && zone->GetRegions().size() > 1) { - Text air_region = *zone->GetRegions().at(1); - StarSystem* system = campaign->GetSystem(zone->System()); - - if (system) { - OrbitalRegion* rgn = system->FindRegion(air_region); - - if (rgn && rgn->Type() == Orbital::TERRAIN) - airborne = true; - } - } - - if (!airborne) { - if (type == Mission::AIR_INTERCEPT) - type = Mission::INTERCEPT; - - else if (type == Mission::AIR_SWEEP) - type = Mission::SWEEP; - - else - type = Mission::PATROL; - } - } - - request = new - CampaignMissionRequest(campaign, type, start, primary); - - if (request) - request->SetObjective(obj); - - return request; -} diff --git a/Stars45/CampaignPlanMission.h b/Stars45/CampaignPlanMission.h deleted file mode 100644 index 903fac5..0000000 --- a/Stars45/CampaignPlanMission.h +++ /dev/null @@ -1,57 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlanMission generates missions and mission - info for the player's combat group as part of a - dynamic campaign. -*/ - -#ifndef CampaignPlanMission_h -#define CampaignPlanMission_h - -#include "Types.h" -#include "CampaignPlan.h" - -// +--------------------------------------------------------------------+ - -class CampaignMissionRequest; -class CombatGroup; -class CombatUnit; -class CombatZone; - -// +--------------------------------------------------------------------+ - -class CampaignPlanMission : public CampaignPlan -{ -public: - static const char* TYPENAME() { return "CampaignPlanMission"; } - - CampaignPlanMission(Campaign* c) : CampaignPlan(c), start(0), slot(0) { } - virtual ~CampaignPlanMission() { } - - // operations: - virtual void ExecFrame(); - -protected: - virtual void SelectStartTime(); - virtual CampaignMissionRequest* PlanCampaignMission(); - virtual CampaignMissionRequest* PlanStrategicMission(); - virtual CampaignMissionRequest* PlanRandomStarshipMission(); - virtual CampaignMissionRequest* PlanRandomFighterMission(); - virtual CampaignMissionRequest* PlanStarshipMission(); - virtual CampaignMissionRequest* PlanFighterMission(); - - CombatGroup* player_group; - int start; - int slot; -}; - -#endif // CampaignPlanMission_h - diff --git a/Stars45/CampaignPlanMovement.cpp b/Stars45/CampaignPlanMovement.cpp deleted file mode 100644 index 8d692aa..0000000 --- a/Stars45/CampaignPlanMovement.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlanMovement simulates random patrol movements - of starship groups between missions. -*/ - -#include "CampaignPlanMovement.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Random.h" -#include "ShipDesign.h" - -// +--------------------------------------------------------------------+ - -void -CampaignPlanMovement::ExecFrame() -{ - if (campaign && campaign->IsActive()) { - if (Campaign::Stardate() - exec_time < 7200) - return; - - campaign->GetAllCombatUnits(-1, all_units); - - ListIter iter = all_units; - while (++iter) { - CombatUnit* u = iter.value(); - - if (u->IsStarship() && !u->IsStatic()) - MoveUnit(u); - } - - all_units.clear(); - - exec_time = Campaign::Stardate(); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanMovement::MoveUnit(CombatUnit* u) -{ - if (u) { - // starship repair: - double damage = u->GetSustainedDamage(); - - if (damage > 0 && u->GetDesign()) { - int percent = (int) (100 * damage / u->GetDesign()->integrity); - - if (percent > 50) { - u->SetSustainedDamage(0.90 * damage); - } - } - - Point loc = u->Location(); - Point dir = loc; - double dist = dir.Normalize(); - - const double MAX_RAD = 320e3; - const double MIN_DIST = 150e3; - - if (dist < MAX_RAD) { - double scale = 1 - dist/MAX_RAD; - - loc += dir * (Random(30e3, 90e3) * scale) + RandomDirection() * 10e3; - - if (fabs(loc.z) > 20e3) - loc.z *= 0.1; - - u->MoveTo(loc); - - CombatGroup* g = u->GetCombatGroup(); - if (g && g->Type() > CombatGroup::FLEET && g->GetFirstUnit() == u) { - g->MoveTo(loc); - - if (g->IntelLevel() > Intel::KNOWN) - g->SetIntelLevel(Intel::KNOWN); - } - } - - else if (dist > 1.25 * MAX_RAD) { - double scale = 1 - dist/MAX_RAD; - - loc += dir * (Random(80e3, 120e3) * scale) + RandomDirection() * 3e3; - - if (fabs(loc.z) > 20e3) - loc.z *= 0.1; - - u->MoveTo(loc); - - CombatGroup* g = u->GetCombatGroup(); - if (g && g->Type() > CombatGroup::FLEET && g->GetFirstUnit() == u) { - g->MoveTo(loc); - - if (g->IntelLevel() > Intel::KNOWN) - g->SetIntelLevel(Intel::KNOWN); - } - } - - else { - loc += RandomDirection() * 30e3; - - if (fabs(loc.z) > 20e3) - loc.z *= 0.1; - - u->MoveTo(loc); - - CombatGroup* g = u->GetCombatGroup(); - if (g && g->Type() > CombatGroup::FLEET && g->GetFirstUnit() == u) { - g->MoveTo(loc); - - if (g->IntelLevel() > Intel::KNOWN) - g->SetIntelLevel(Intel::KNOWN); - } - } - - CombatUnit* closest_unit = 0; - double closest_dist = 1e6; - - ListIter iter = all_units; - while (++iter) { - CombatUnit* unit = iter.value(); - - if (unit->GetCombatGroup() != u->GetCombatGroup() && unit->GetRegion() == u->GetRegion() && !unit->IsDropship()) { - Point delta = loc - unit->Location(); - dist = delta.Normalize(); - - if (dist < closest_dist) { - closest_unit = unit; - closest_dist = dist; - } - } - } - - if (closest_unit && closest_dist < MIN_DIST) { - Point delta = loc - closest_unit->Location(); - dist = delta.Normalize(); - - loc += delta * 1.1 * (MIN_DIST - closest_dist); - - if (fabs(loc.z) > 20e3) - loc.z *= 0.1; - - u->MoveTo(loc); - - CombatGroup* g = u->GetCombatGroup(); - if (g && g->Type() > CombatGroup::FLEET && g->GetFirstUnit() == u) { - g->MoveTo(loc); - - if (g->IntelLevel() > Intel::KNOWN) - g->SetIntelLevel(Intel::KNOWN); - } - } - } -} diff --git a/Stars45/CampaignPlanMovement.h b/Stars45/CampaignPlanMovement.h deleted file mode 100644 index 4f5f0d1..0000000 --- a/Stars45/CampaignPlanMovement.h +++ /dev/null @@ -1,43 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlanMovement simulates random patrol movements - of starship groups between missions. This agitation - keeps the ships from bunching up in the middle of a - sector. -*/ - -#ifndef CampaignPlanMovement_h -#define CampaignPlanMovement_h - -#include "Types.h" -#include "CampaignPlan.h" - -// +--------------------------------------------------------------------+ - -class CampaignPlanMovement : public CampaignPlan -{ -public: - static const char* TYPENAME() { return "CampaignPlanMovement"; } - - CampaignPlanMovement(Campaign* c) : CampaignPlan(c) { } - virtual ~CampaignPlanMovement() { } - - // operations: - virtual void ExecFrame(); - -protected: - void MoveUnit(CombatUnit* u); - - List all_units; -}; - -#endif // CampaignPlanMovement_h - diff --git a/Stars45/CampaignPlanStrategic.cpp b/Stars45/CampaignPlanStrategic.cpp deleted file mode 100644 index 209c888..0000000 --- a/Stars45/CampaignPlanStrategic.cpp +++ /dev/null @@ -1,481 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlanStrategic prioritizes targets and defensible - allied forces as the first step in force tasking. -*/ - -#include "CampaignPlanStrategic.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Random.h" - -// +--------------------------------------------------------------------+ - -void -CampaignPlanStrategic::ExecFrame() -{ - if (campaign && campaign->IsActive()) { - if (Campaign::Stardate() - exec_time < 300) - return; - - ListIter zone = campaign->GetZones(); - while (++zone) - zone->Clear(); - - ListIter iter = campaign->GetCombatants(); - while (++iter) { - Combatant* c = iter.value(); - CombatGroup* force = c->GetForce(); - - force->CalcValue(); - - PlaceGroup(force); - ScoreCombatant(c); - ScoreNeeds(c); - - force->ClearUnlockedZones(); - AssignZones(c); - ResolveZoneMovement(force); - } - - exec_time = Campaign::Stardate(); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanStrategic::PlaceGroup(CombatGroup* g) -{ - if (!g) - return; - - Text rgn = g->GetRegion(); - CombatZone* zone = campaign->GetZone(rgn); - - // if we couldn't find anything suitable, - // just pick a zone at random: - if (!zone && g->IsMovable()) { - int nzones = campaign->GetZones().size(); - int n = RandomIndex() % nzones; - zone = campaign->GetZones().at(n); - - Text assigned_rgn; - if (!campaign->GetZone(rgn)) { - assigned_rgn = *zone->GetRegions().at(0); - g->AssignRegion(assigned_rgn); - } - } - - if (zone && !zone->HasGroup(g)) - zone->AddGroup(g); - - ListIter iter = g->GetComponents(); - while (++iter) - PlaceGroup(iter.value()); -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanStrategic::ScoreCombatant(Combatant* c) -{ - // prep lists: - c->GetDefendList().clear(); - c->GetTargetList().clear(); - - ScoreDefensible(c); - - ListIter iter = campaign->GetCombatants(); - while (++iter) { - if (iter->GetIFF() > 0 && iter->GetIFF() != c->GetIFF()) - ScoreTargets(c, iter.value()); - } - - // sort lists: - c->GetDefendList().sort(); - c->GetTargetList().sort(); -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanStrategic::ScoreDefensible(Combatant* c) -{ - if (c->GetForce()) - ScoreDefend(c, c->GetForce()); -} - -void -CampaignPlanStrategic::ScoreDefend(Combatant* c, CombatGroup* g) -{ - if (!g || g->IsReserve()) - return; - - if (g->IsDefensible()) { - g->SetPlanValue(g->Value()); - c->GetDefendList().append(g); - - CombatZone* zone = campaign->GetZone(g->GetRegion()); - ZoneForce* force = 0; - - if (zone) - force = zone->FindForce(c->GetIFF()); - - if (force) - force->GetDefendList().append(g); - } - - ListIter iter = g->GetComponents(); - while (++iter) { - ScoreDefend(c, iter.value()); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanStrategic::ScoreTargets(Combatant* c, Combatant* t) -{ - if (t->GetForce()) - ScoreTarget(c, t->GetForce()); -} - -void -CampaignPlanStrategic::ScoreTarget(Combatant* c, CombatGroup* g) -{ - if (!g || g->IntelLevel() <= Intel::SECRET) - return; - - if (g->IsTargetable()) { - g->SetPlanValue(g->Value() * c->GetTargetStratFactor(g->Type())); - c->GetTargetList().append(g); - - CombatZone* zone = campaign->GetZone(g->GetRegion()); - ZoneForce* force = 0; - - if (zone) - force = zone->FindForce(c->GetIFF()); - - if (force) - force->GetTargetList().append(g); - } - - ListIter iter = g->GetComponents(); - while (++iter) { - ScoreTarget(c, iter.value()); - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanStrategic::ScoreNeeds(Combatant* c) -{ - ListIter zone = campaign->GetZones(); - while (++zone) { - ZoneForce* force = zone->FindForce(c->GetIFF()); - - // clear needs: - force->SetNeed(CombatGroup::CARRIER_GROUP, 0); - force->SetNeed(CombatGroup::BATTLE_GROUP, 0); - force->SetNeed(CombatGroup::DESTROYER_SQUADRON, 0); - force->SetNeed(CombatGroup::ATTACK_SQUADRON, 0); - force->SetNeed(CombatGroup::FIGHTER_SQUADRON, 0); - force->SetNeed(CombatGroup::INTERCEPT_SQUADRON, 0); - - // what defensive assets are needed in this zone? - ListIter def = force->GetDefendList(); - while (++def) { - int defender_type = *CombatGroup::PreferredDefender(def->Type()); - force->AddNeed(defender_type, def->Value()); - } - - // what offensive assets are needed in this zone? - ListIter tgt = force->GetTargetList(); - while (++tgt) { - int attacker_type = *CombatGroup::PreferredAttacker(tgt->Type()); - force->AddNeed(attacker_type, tgt->Value()); - } - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanStrategic::BuildGroupList(CombatGroup* g, List& groups) -{ - if (!g || g->IsReserve()) - return; - - if (g->IsAssignable()) - groups.append(g); - - ListIter iter = g->GetComponents(); - while (++iter) - BuildGroupList(iter.value(), groups); -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanStrategic::AssignZones(Combatant* c) -{ - // find the list of assignable groups, in priority order: - List groups; - BuildGroupList(c->GetForce(), groups); - groups.sort(); - - // for each group, assign a zone: - ListIter g_iter = groups; - - // first pass: fighter and attack squadrons assigned to star bases - while (++g_iter) { - CombatGroup* g = g_iter.value(); - int gtype = g->Type(); - - if (gtype == CombatGroup::ATTACK_SQUADRON || - gtype == CombatGroup::FIGHTER_SQUADRON || - gtype == CombatGroup::INTERCEPT_SQUADRON) { - CombatGroup* parent = g->GetParent(); - - if (parent && parent->Type() == CombatGroup::WING) - parent = parent->GetParent(); - - if (!parent || parent->Type() == CombatGroup::CARRIER_GROUP) - continue; - - // these groups are attached to fixed resources, - // so they must be assigned to the parent's zone: - CombatZone* parent_zone = campaign->GetZone(parent->GetRegion()); - - if (parent_zone) { - ZoneForce* parent_force = parent_zone->FindForce(g->GetIFF()); - - if (parent_force) { - g->SetAssignedZone(parent_zone); - parent_force->AddNeed(g->Type(), -(g->Value())); - } - } - } - } - - // second pass: carrier groups - g_iter.reset(); - while (++g_iter) { - CombatGroup* g = g_iter.value(); - int gtype = g->Type(); - - if (gtype == CombatGroup::CARRIER_GROUP) { - int current_zone_need = 0; - int highest_zone_need = 0; - CombatZone* highest_zone = 0; - ZoneForce* highest_force = 0; - CombatZone* current_zone = 0; - ZoneForce* current_force = 0; - - List possible_zones; - - if (g->IsZoneLocked()) { - current_zone = g->GetAssignedZone(); - current_force = current_zone->FindForce(g->GetIFF()); - } - - else { - ListIter z_iter = campaign->GetZones(); - while (++z_iter) { - CombatZone* zone = z_iter.value(); - ZoneForce* force = zone->FindForce(g->GetIFF()); - int need = force->GetNeed(CombatGroup::CARRIER_GROUP) + - force->GetNeed(CombatGroup::ATTACK_SQUADRON) + - force->GetNeed(CombatGroup::FIGHTER_SQUADRON) + - force->GetNeed(CombatGroup::INTERCEPT_SQUADRON); - - if (g->IsSystemLocked() && zone->System() != g->GetAssignedSystem()) - continue; - - possible_zones.append(zone); - - if (zone->HasRegion(g->GetRegion())) { - current_zone_need = need; - current_zone = zone; - current_force = force; - } - - if (need > highest_zone_need) { - highest_zone_need = need; - highest_zone = zone; - highest_force = force; - } - } - } - - CombatZone* assigned_zone = current_zone; - ZoneForce* assigned_force = current_force; - - if (highest_zone_need > current_zone_need) { - assigned_zone = highest_zone; - assigned_force = highest_force; - } - - // if we couldn't find anything suitable, - // just pick a zone at random: - if (!assigned_zone) { - if (possible_zones.isEmpty()) - possible_zones.append(campaign->GetZones()); - - int nzones = possible_zones.size(); - int n = RandomIndex() % nzones; - - assigned_zone = possible_zones.at(n); - assigned_force = assigned_zone->FindForce(g->GetIFF()); - } - - if (assigned_force && assigned_zone) { - Text assigned_rgn; - if (!campaign->GetZone(g->GetRegion())) { - assigned_rgn = *assigned_zone->GetRegions().at(0); - g->AssignRegion(assigned_rgn); - } - - g->SetAssignedZone(assigned_zone); - assigned_force->AddNeed(g->Type(), -(g->Value())); - - // also assign the carrier's wing and squadrons to the same zone: - ListIter squadron = g->GetComponents(); - while (++squadron) { - squadron->SetAssignedZone(assigned_zone); - assigned_force->AddNeed(squadron->Type(), -(squadron->Value())); - - if (squadron->Type() == CombatGroup::WING) { - ListIter s = squadron->GetComponents(); - while (++s) { - s->SetAssignedZone(assigned_zone); - assigned_force->AddNeed(s->Type(), -(s->Value())); - } - } - } - } - } - } - - // third pass: everything else - g_iter.reset(); - while (++g_iter) { - CombatGroup* g = g_iter.value(); - int gtype = g->Type(); - - if (gtype == CombatGroup::BATTLE_GROUP || gtype == CombatGroup::DESTROYER_SQUADRON) { - int current_zone_need = 0; - int highest_zone_need = 0; - CombatZone* highest_zone = 0; - ZoneForce* highest_force = 0; - CombatZone* current_zone = 0; - ZoneForce* current_force = 0; - - List possible_zones; - - if (g->IsZoneLocked()) { - current_zone = g->GetAssignedZone(); - current_force = current_zone->FindForce(g->GetIFF()); - } - - else { - ListIter z_iter = campaign->GetZones(); - while (++z_iter) { - CombatZone* zone = z_iter.value(); - ZoneForce* force = zone->FindForce(g->GetIFF()); - int need = force->GetNeed(g->Type()); - - if (g->IsSystemLocked() && zone->System() != g->GetAssignedSystem()) - continue; - - possible_zones.append(zone); - - // battle groups can do double-duty: - if (gtype == CombatGroup::BATTLE_GROUP) - need += force->GetNeed(CombatGroup::DESTROYER_SQUADRON); - - if (zone->HasRegion(g->GetRegion())) { - current_zone_need = need; - current_zone = zone; - current_force = force; - } - - if (need > highest_zone_need) { - highest_zone_need = need; - highest_zone = zone; - highest_force = force; - } - } - } - - if (highest_zone_need > current_zone_need) { - g->SetAssignedZone(highest_zone); - - if (highest_force) - highest_force->AddNeed(g->Type(), -(g->Value())); - } - else { - if (!current_zone) { - if (possible_zones.isEmpty()) - possible_zones.append(campaign->GetZones()); - - int nzones = possible_zones.size(); - int n = RandomIndex() % nzones; - - current_zone = possible_zones.at(n); - current_force = current_zone->FindForce(g->GetIFF()); - } - - g->SetAssignedZone(current_zone); - - if (current_force) - current_force->AddNeed(g->Type(), -(g->Value())); - - Text assigned_rgn; - if (!campaign->GetZone(g->GetRegion())) { - assigned_rgn = *current_zone->GetRegions().at(0); - g->AssignRegion(assigned_rgn); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -CampaignPlanStrategic::ResolveZoneMovement(CombatGroup* g) -{ - CombatZone* zone = g->GetAssignedZone(); - bool move = false; - - if (zone && !zone->HasRegion(g->GetRegion())) { - move = true; - CombatZone* old_zone = g->GetCurrentZone(); - if (old_zone) - old_zone->RemoveGroup(g); - zone->AddGroup(g); - } - - ListIter comp = g->GetComponents(); - while (++comp) - ResolveZoneMovement(comp.value()); - - // assign region last, to allow components to - // resolve their zones: - if (zone && move) - g->AssignRegion(*zone->GetRegions().at(0)); -} diff --git a/Stars45/CampaignPlanStrategic.h b/Stars45/CampaignPlanStrategic.h deleted file mode 100644 index 6df1ba7..0000000 --- a/Stars45/CampaignPlanStrategic.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignPlanStrategic prioritizes targets and defensible - allied forces as the first step in force tasking. This - algorithm computes which enemy resources are most important - to attack, based on the AI value of each combat group, and - strategic weighting factors that help shape the strategy - to the objectives for the current campaign. -*/ - -#ifndef CampaignPlanStrategic_h -#define CampaignPlanStrategic_h - -#include "Types.h" -#include "CampaignPlan.h" - -// +--------------------------------------------------------------------+ - -class CampaignPlanStrategic : public CampaignPlan -{ -public: - static const char* TYPENAME() { return "CampaignPlanStrategic"; } - - CampaignPlanStrategic(Campaign* c) : CampaignPlan(c) { } - virtual ~CampaignPlanStrategic() { } - - // operations: - virtual void ExecFrame(); - -protected: - void PlaceGroup(CombatGroup* g); - - void ScoreCombatant(Combatant* c); - - void ScoreDefensible(Combatant* c); - void ScoreDefend(Combatant* c, CombatGroup* g); - - void ScoreTargets(Combatant* c, Combatant* t); - void ScoreTarget(Combatant* c, CombatGroup* g); - - void ScoreNeeds(Combatant* c); - - // zone alocation: - void BuildGroupList(CombatGroup* g, List& groups); - void AssignZones(Combatant* c); - void ResolveZoneMovement(CombatGroup* g); -}; - -#endif // CampaignPlanStrategic_h - diff --git a/Stars45/CampaignSaveGame.cpp b/Stars45/CampaignSaveGame.cpp deleted file mode 100644 index f4b16ce..0000000 --- a/Stars45/CampaignSaveGame.cpp +++ /dev/null @@ -1,733 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignSaveGame contains the logic needed to save and load - campaign games in progress. -*/ - -#include "CampaignSaveGame.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAction.h" -#include "CombatEvent.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Galaxy.h" -#include "Mission.h" -#include "StarSystem.h" -#include "Player.h" - -#include "Game.h" -#include "DataLoader.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -static const char* SAVE_DIR = "SaveGame"; - -// +--------------------------------------------------------------------+ - -CampaignSaveGame::CampaignSaveGame(Campaign* c) - : campaign(c) -{ } - -// +--------------------------------------------------------------------+ - -CampaignSaveGame::~CampaignSaveGame() -{ } - -// +--------------------------------------------------------------------+ - -Text -CampaignSaveGame::GetSaveDirectory() -{ - return GetSaveDirectory(Player::GetCurrentPlayer()); -} - -Text -CampaignSaveGame::GetSaveDirectory(Player* player) -{ - if (player) { - char save_dir[32]; - sprintf_s(save_dir, "%s/%02d", SAVE_DIR, player->Identity()); - - return save_dir; - } - - return SAVE_DIR; -} - -void -CampaignSaveGame::CreateSaveDirectory() -{ - HANDLE hDir = CreateFile(SAVE_DIR, 0, 0, 0, OPEN_EXISTING, 0, 0); - - if (hDir == INVALID_HANDLE_VALUE) - CreateDirectory(SAVE_DIR, NULL); - else - CloseHandle(hDir); - - hDir = CreateFile(GetSaveDirectory(), 0, 0, 0, OPEN_EXISTING, 0, 0); - - if (hDir == INVALID_HANDLE_VALUE) - CreateDirectory(GetSaveDirectory(), NULL); - else - CloseHandle(hDir); -} - -// +--------------------------------------------------------------------+ - -static char multiline[4096]; -static char* FormatMultiLine(const char* s) -{ - int i = 4095; - char* p = multiline; - - while (*s && i > 0) { - if (*s == '\n') { - *p++ = '\\'; - *p++ = 'n'; - s++; - i -= 2; - } - else if (*s == '"') { - *p++ = '\\'; - *p++ = '"'; - s++; - i -= 2; - } - else { - *p++ = *s++; - i--; - } - } - - *p = 0; - return multiline; -} - -static char* ParseMultiLine(const char* s) -{ - int i = 4095; - char* p = multiline; - - while (*s && i > 0) { - if (*s == '\\') { - s++; - if (*s == 'n') { - *p++ = '\n'; -#pragma warning(suppress: 6269) - *s++; - i--; - } - else if (*s == '"') { - *p++ = '"'; -#pragma warning(suppress: 6269) - *s++; - i--; - } - else { - *p++ = *s++; - i--; - } - } - else { - *p++ = *s++; - i--; - } - } - - *p = 0; - return multiline; -} - -void -CampaignSaveGame::Load(const char* filename) -{ - Print("-------------------------\nLOADING SAVEGAME (%s).\n", filename); - campaign = 0; - - if (!filename || !filename[0]) return; - - DataLoader* loader = DataLoader::GetLoader(); - bool use_file_sys = loader->IsFileSystemEnabled(); - loader->UseFileSystem(true); - loader->SetDataPath(GetSaveDirectory() + "/"); - - BYTE* block; - loader->LoadBuffer(filename, block, true); - loader->UseFileSystem(use_file_sys); - - Sleep(10); - - Parser parser(new BlockReader((const char*) block)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse save game '%s'\n", filename); - loader->SetDataPath(0); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "SAVEGAME") { - Print("ERROR: invalid save game file '%s'\n", filename); - term->print(10); - loader->SetDataPath(0); - delete term; - return; - } - } - - int grp_iff = 0; - int grp_type = 0; - int grp_id = 0; - int status = 0; - double baseTime = 0; - double time = 0; - Text unit; - Text sitrep; - Text orders; - - do { - Sleep(5); - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "campaign") { - Text cname; - int cid=0; - - if (def->term()) { - if (def->term()->isText()) - cname = def->term()->isText()->value(); - else if (def->term()->isNumber()) - cid = (int) def->term()->isNumber()->value(); - } - - if (!campaign) { - List& list = Campaign::GetAllCampaigns(); - - for (int i = 0; i < list.size() && !campaign; i++) { - Campaign* c = list.at(i); - - if (cname == c->Name() || cid == c->GetCampaignId()) { - campaign = c; - campaign->Load(); - campaign->Prep(); // restore campaign to pristine state - - loader->SetDataPath(GetSaveDirectory() + "/"); - } - } - } - } - - else if (def->name()->value() == "grp_iff") { - GetDefNumber(grp_iff, def, filename); - } - - else if (def->name()->value() == "grp_type") { - GetDefNumber(grp_type, def, filename); - } - - else if (def->name()->value() == "grp_id") { - GetDefNumber(grp_id, def, filename); - } - - else if (def->name()->value() == "unit") { - GetDefText(unit, def, filename); - } - - else if (def->name()->value() == "status") { - GetDefNumber(status, def, filename); - } - - else if (def->name()->value() == "basetime") { - GetDefNumber(baseTime, def, filename); - } - - else if (def->name()->value() == "time") { - GetDefNumber(time, def, filename); - } - - else if (def->name()->value() == "sitrep") { - GetDefText(sitrep, def, filename); - } - - else if (def->name()->value() == "orders") { - GetDefText(orders, def, filename); - } - - else if (def->name()->value() == "combatant") { - if (!def->term() || !def->term()->isStruct()) { - ::Print("WARNING: combatant struct missing in '%s/%s'\n", loader->GetDataPath(), filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - char name[64]; - int iff = 0; - int score = 0; - - ZeroMemory(name, sizeof(name)); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") - GetDefText(name, pdef, filename); - - else if (pdef->name()->value() == "iff") { - GetDefNumber(iff, pdef, filename); - } - - else if (pdef->name()->value() == "score") { - GetDefNumber(score, pdef, filename); - } - } - } - - if (campaign && name[0]) { - Combatant* combatant = campaign->GetCombatant(name); - - if (combatant) { - CombatGroup::MergeOrderOfBattle(block, filename, iff, combatant, campaign); - combatant->SetScore(score); - } - else { - ::Print("WARNING: could not find combatant '%s' in campaign.\n", name); - } - } - } - } - else if (def->name()->value() == "event") { - if (!def->term() || !def->term()->isStruct()) { - ::Print("WARNING: event struct missing in '%s/%s'\n", loader->GetDataPath(), filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - char type[64]; - char source[64]; - char region[64]; - char title[256]; - char file[256]; - char image[256]; - char scene[256]; - char info[4096]; - int time = 0; - int team = 0; - int points = 0; - - type[0] = 0; - info[0] = 0; - file[0] = 0; - image[0] = 0; - scene[0] = 0; - title[0] = 0; - region[0] = 0; - source[0] = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "type") - GetDefText(type, pdef, filename); - - else if (pdef->name()->value() == "source") - GetDefText(source, pdef, filename); - - else if (pdef->name()->value() == "region") - GetDefText(region, pdef, filename); - - else if (pdef->name()->value() == "title") - GetDefText(title, pdef, filename); - - else if (pdef->name()->value() == "file") - GetDefText(file, pdef, filename); - - else if (pdef->name()->value() == "image") - GetDefText(image, pdef, filename); - - else if (pdef->name()->value() == "scene") - GetDefText(scene, pdef, filename); - - else if (pdef->name()->value() == "info") - GetDefText(info, pdef, filename); - - else if (pdef->name()->value() == "time") - GetDefNumber(time, pdef, filename); - - else if (pdef->name()->value() == "team") - GetDefNumber(team, pdef, filename); - - else if (pdef->name()->value() == "points") - GetDefNumber(points, pdef, filename); - } - } - - if (campaign && type[0]) { - loader->SetDataPath(campaign->Path()); - - CombatEvent* event = new - CombatEvent(campaign, - CombatEvent::TypeFromName(type), - time, - team, - CombatEvent::SourceFromName(source), - region); - - if (event) { - event->SetTitle(title); - event->SetFilename(file); - event->SetImageFile(image); - event->SetSceneFile(scene); - event->Load(); - - if (info[0]) - event->SetInformation(ParseMultiLine(info)); - - event->SetVisited(true); - campaign->GetEvents().append(event); - } - } - } - } - else if (def->name()->value() == "action") { - if (!def->term() || !def->term()->isStruct()) { - ::Print("WARNING: action struct missing in '%s/%s'\n", loader->GetDataPath(), filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - int id = -1; - int stat = 0; - int count = 0; - int after = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "id") - GetDefNumber(id, pdef, filename); - - else if (pdef->name()->value() == "stat") - GetDefNumber(stat, pdef, filename); - - else if (pdef->name()->value() == "count") - GetDefNumber(count, pdef, filename); - - else if (pdef->name()->value().contains("after")) - GetDefNumber(after, pdef, filename); - } - } - - if (campaign && id >= 0) { - ListIter a_iter = campaign->GetActions(); - while (++a_iter) { - CombatAction* a = a_iter.value(); - if (a->Identity() == id) { - a->SetStatus(stat); - - if (count) - a->SetCount(count); - - if (after) - a->SetStartAfter(after); - - break; - } - } - } - } - } - } - } - } - while (term); - - if (term) { - delete term; - term = 0; - } - - if (campaign) { - campaign->SetSaveGame(true); - - List& list = Campaign::GetAllCampaigns(); - - if (status < Campaign::CAMPAIGN_SUCCESS) { - campaign->SetStatus(status); - if (sitrep.length()) campaign->SetSituation(sitrep); - if (orders.length()) campaign->SetOrders(orders); - campaign->SetStartTime(baseTime); - campaign->SetLoadTime(baseTime + time); - campaign->LockoutEvents(3600); - campaign->Start(); - - if (grp_type >= CombatGroup::FLEET && grp_type <= CombatGroup::PRIVATE) { - CombatGroup* player_group = campaign->FindGroup(grp_iff, grp_type, grp_id); - if (player_group) { - CombatUnit* player_unit = 0; - - if (unit.length()) - player_unit = player_group->FindUnit(unit); - - if (player_unit) - campaign->SetPlayerUnit(player_unit); - else - campaign->SetPlayerGroup(player_group); - } - } - } - - // failed - restart current campaign: - else if (status == Campaign::CAMPAIGN_FAILED) { - Print("CampaignSaveGame: Loading FAILED campaign, restarting '%s'\n", - campaign->Name()); - - campaign->Load(); - campaign->Prep(); // restore campaign to pristine state - campaign->SetSaveGame(false); - - loader->SetDataPath(GetSaveDirectory() + "/"); - } - - // start next campaign: - else if (status == Campaign::CAMPAIGN_SUCCESS) { - Print("CampaignSaveGame: Loading COMPLETED campaign '%s', searching for next campaign...\n", - campaign->Name()); - - bool found = false; - - for (int i = 0; i < list.size() && !found; i++) { - Campaign* c = list.at(i); - - if (c->GetCampaignId() == campaign->GetCampaignId()+1) { - campaign = c; - campaign->Load(); - campaign->Prep(); // restore campaign to pristine state - - Print("Advanced to campaign %d '%s'\n", - campaign->GetCampaignId(), - campaign->Name()); - - loader->SetDataPath(GetSaveDirectory() + "/"); - found = true; - } - } - - // if no next campaign found, start over from the beginning: - for (int i = 0; i < list.size() && !found; i++) { - Campaign* c = list.at(i); - - if (c->IsDynamic()) { - campaign = c; - campaign->Load(); - campaign->Prep(); // restore campaign to pristine state - - Print("Completed full series, restarting at %d '%s'\n", - campaign->GetCampaignId(), - campaign->Name()); - - loader->SetDataPath(GetSaveDirectory() + "/"); - found = true; - } - } - } - } - - loader->ReleaseBuffer(block); - loader->SetDataPath(0); - Print("SAVEGAME LOADED (%s).\n\n", filename); -} - -// +--------------------------------------------------------------------+ - -void -CampaignSaveGame::Save(const char* name) -{ - if (!campaign) return; - - CreateSaveDirectory(); - - Text s = GetSaveDirectory() + Text("/") + Text(name); - - FILE* f; - fopen_s(&f, s, "wb"); - - if (f) { - char timestr[32]; - FormatDayTime(timestr, campaign->GetTime()); - - CombatGroup* player_group = campaign->GetPlayerGroup(); - CombatUnit* player_unit = campaign->GetPlayerUnit(); - - fprintf(f, "SAVEGAME\n\n"); - fprintf(f, "campaign: \"%s\"\n\n", campaign->Name()); - fprintf(f, "grp_iff: %d\n", (int) player_group->GetIFF()); - fprintf(f, "grp_type: %d\n", (int) player_group->Type()); - fprintf(f, "grp_id: %d\n", (int) player_group->GetID()); - if (player_unit) - fprintf(f, "unit: \"%s\"\n", player_unit->Name().data()); - - fprintf(f, "status: %d\n", (int) campaign->GetStatus()); - fprintf(f, "basetime: %f\n", campaign->GetStartTime()); - fprintf(f, "time: %f // %s\n\n", - campaign->GetTime(), - timestr); - - fprintf(f, "sitrep: \"%s\"\n", campaign->Situation()); - fprintf(f, "orders: \"%s\"\n\n", campaign->Orders()); - - ListIter c_iter = campaign->GetCombatants(); - while (++c_iter) { - Combatant* c = c_iter.value(); - - fprintf(f, "combatant: {"); - fprintf(f, " name:\"%s\",", c->Name()); - fprintf(f, " iff:%d,", c->GetIFF()); - fprintf(f, " score:%d,", c->Score()); - fprintf(f, " }\n"); - } - - fprintf(f, "\n"); - - ListIter a_iter = campaign->GetActions(); - while (++a_iter) { - CombatAction* a = a_iter.value(); - fprintf(f, "action: { id:%4d, stat:%d", a->Identity(), a->Status()); - - if (a->Status() == CombatAction::PENDING) { - if (a->Count()) - fprintf(f, ", count:%d", a->Count()); - - if (a->StartAfter()) - fprintf(f, ", after:%d", a->StartAfter()); - } - - fprintf(f, " }\n"); - } - - fprintf(f, "\n"); - - ListIter e_iter = campaign->GetEvents(); - while (++e_iter) { - CombatEvent* e = e_iter.value(); - - fprintf(f, "event: {"); - fprintf(f, " type:%-18s,", e->TypeName()); - fprintf(f, " time:0x%08x,", e->Time()); - fprintf(f, " team:%d,", e->GetIFF()); - fprintf(f, " points:%d,", e->Points()); - fprintf(f, " source:\"%s\",", e->SourceName()); - fprintf(f, " region:\"%s\",", e->Region()); - fprintf(f, " title:\"%s\",", e->Title()); - if (e->Filename()) - fprintf(f, " file:\"%s\",", e->Filename()); - if (e->ImageFile()) - fprintf(f, " image:\"%s\",", e->ImageFile()); - if (e->SceneFile()) - fprintf(f, " scene:\"%s\",", e->SceneFile()); - if (!e->Filename() || *e->Filename() == 0) - fprintf(f, " info:\"%s\"", FormatMultiLine(e->Information())); - fprintf(f, " }\n"); - } - - fprintf(f, "\n// ORDER OF BATTLE:\n\n"); - fclose(f); - - c_iter.reset(); - while (++c_iter) { - Combatant* c = c_iter.value(); - CombatGroup* g = c->GetForce(); - CombatGroup::SaveOrderOfBattle(s, g); - } - } -} - -void -CampaignSaveGame::Delete(const char* name) -{ - DeleteFile(GetSaveDirectory() + "/" + name); -} - -void -CampaignSaveGame::RemovePlayer(Player* p) -{ - List save_list; - Text save_dir = GetSaveDirectory(p) + "/"; - - DataLoader* loader = DataLoader::GetLoader(); - bool use_file_sys = loader->IsFileSystemEnabled(); - loader->UseFileSystem(true); - loader->SetDataPath(save_dir); - loader->ListFiles("*.*", save_list); - loader->SetDataPath(0); - loader->UseFileSystem(use_file_sys); - - for (int i = 0; i < save_list.size(); i++) { - Text* filename = save_list[i]; - DeleteFile(save_dir + filename->data()); - } - - save_list.destroy(); - - RemoveDirectory(GetSaveDirectory(p)); -} - -// +--------------------------------------------------------------------+ - -void -CampaignSaveGame::SaveAuto() -{ - Save("AutoSave"); -} - -void -CampaignSaveGame::LoadAuto() -{ - Load("AutoSave"); -} - -// +--------------------------------------------------------------------+ - -Text -CampaignSaveGame::GetResumeFile() -{ - // check for auto save game: - FILE* f; - ::fopen_s(&f, GetSaveDirectory() + "/AutoSave", "rb"); - - if (f) { - ::fclose(f); - - return "AutoSave"; - } - - return Text(); -} - -int -CampaignSaveGame::GetSaveGameList(List& save_list) -{ - DataLoader* loader = DataLoader::GetLoader(); - bool use_file_sys = loader->IsFileSystemEnabled(); - loader->UseFileSystem(true); - loader->SetDataPath(GetSaveDirectory() + "/"); - loader->ListFiles("*.*", save_list); - loader->SetDataPath(0); - loader->UseFileSystem(use_file_sys); - - return save_list.size(); -} diff --git a/Stars45/CampaignSaveGame.h b/Stars45/CampaignSaveGame.h deleted file mode 100644 index 3f4e895..0000000 --- a/Stars45/CampaignSaveGame.h +++ /dev/null @@ -1,68 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignSaveGame contains the logic needed to save and load - campaign games in progress. -*/ - -#ifndef CampaignSaveGame_h -#define CampaignSaveGame_h - -#include "Types.h" -#include "Geometry.h" -#include "Text.h" -#include "Term.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class CampaignPlan; -class Combatant; -class CombatGroup; -class CombatZone; -class DataLoader; -class Mission; -class Player; -class StarSystem; - -// +--------------------------------------------------------------------+ - -class CampaignSaveGame -{ -public: - static const char* TYPENAME() { return "CampaignSaveGame"; } - - CampaignSaveGame(Campaign* c=0); - virtual ~CampaignSaveGame(); - - virtual Campaign* GetCampaign() { return campaign; } - - virtual void Load(const char* name); - virtual void Save(const char* name); - static void Delete(const char* name); - static void RemovePlayer(Player* p); - - virtual void LoadAuto(); - virtual void SaveAuto(); - - static Text GetResumeFile(); - static int GetSaveGameList(List& save_list); - -private: - static Text GetSaveDirectory(); - static Text GetSaveDirectory(Player* p); - static void CreateSaveDirectory(); - - Campaign* campaign; -}; - -#endif // CampaignSaveGame_h - diff --git a/Stars45/CampaignSituationReport.cpp b/Stars45/CampaignSituationReport.cpp deleted file mode 100644 index c83ad8d..0000000 --- a/Stars45/CampaignSituationReport.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignSituationReport generates the situation report - portion of the briefing for a dynamically generated - mission in a dynamic campaign. -*/ - -#include "CampaignSituationReport.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAssignment.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Callsign.h" -#include "Mission.h" -#include "Instruction.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "StarSystem.h" -#include "Random.h" -#include "Player.h" - -// +--------------------------------------------------------------------+ - -CampaignSituationReport::CampaignSituationReport(Campaign* c, Mission* m) - : campaign(c), mission(m) -{} - -CampaignSituationReport::~CampaignSituationReport() {} - -// +--------------------------------------------------------------------+ - -void -CampaignSituationReport::GenerateSituationReport() -{ - if (!campaign || !mission) - return; - - sitrep = Text(); - - GlobalSituation(); - MissionSituation(); - - mission->SetSituation(sitrep); -} - -// +--------------------------------------------------------------------+ - -static const char* outlooks[4] = { "good", "fluid", "poor", "bleak" }; - -void -CampaignSituationReport::GlobalSituation() -{ - if (campaign->GetTime() < 40 * 3600) - sitrep = Text(campaign->Name()) + Text(" is still in its early stages and the situation is "); - else - sitrep = Text("The overall outlook for ") + Text(campaign->Name()) + Text(" is "); - - int score = campaign->GetPlayerTeamScore(); - - if (score > 1000) - sitrep += outlooks[0]; - else if (score > -1000) - sitrep += outlooks[1]; - else if (score > -2000) - sitrep += outlooks[2]; - else - sitrep += outlooks[3]; - - sitrep += ". "; - - Text strat_dir; - - CombatGroup* pg = campaign->GetPlayerGroup(); - - if (pg) - strat_dir = pg->GetStrategicDirection(); - - if (strat_dir.length()) - sitrep += strat_dir; - else - sitrep += Text("Establishing and maintaining military control of the ") + - mission->GetStarSystem()->Name() + " System remains a key priority."; -} - -// +--------------------------------------------------------------------+ - -void -CampaignSituationReport::MissionSituation() -{ - if (mission) { - MissionElement* player = mission->GetPlayer(); - MissionElement* target = mission->GetTarget(); - MissionElement* ward = mission->GetWard(); - MissionElement* escort = FindEscort(player); - Text threat = GetThreatInfo(); - Text sector = mission->GetRegion(); - - sector += " sector."; - - switch (mission->Type()) { - case Mission::PATROL: - case Mission::AIR_PATROL: - sitrep += "\n\nThis mission is a routine patrol of the "; - sitrep += sector; - break; - - case Mission::SWEEP: - case Mission::AIR_SWEEP: - sitrep += "\n\nFor this mission, you will be performing a fighter sweep of the "; - sitrep += sector; - break; - - case Mission::INTERCEPT: - case Mission::AIR_INTERCEPT: - sitrep += "\n\nWe have detected hostile elements inbound. "; - sitrep += "Your mission is to intercept them before they are able to engage their targets."; - break; - - - case Mission::STRIKE: - sitrep += "\n\nThe goal of this mission is to perform a strike on preplanned targets in the "; - sitrep += sector; - - if (target) { - sitrep += " Your package has been assigned to strike the "; - - if (target->GetCombatGroup()) - sitrep += target->GetCombatGroup()->GetDescription(); - else - sitrep += target->Name(); - - sitrep += "."; - } - break; - - case Mission::ASSAULT: - sitrep += "\n\nThis mission is to assault preplanned targets in the "; - sitrep += sector; - - if (target) { - sitrep += " Your package has been assigned to strike the "; - - if (target->GetCombatGroup()) - sitrep += target->GetCombatGroup()->GetDescription(); - else - sitrep += target->Name(); - - sitrep += "."; - } - break; - - case Mission::DEFEND: - if (ward) { - sitrep += "\n\nFor this mission, you will need to defend "; - sitrep += ward->Name(); - sitrep += " in the "; - sitrep += sector; - } - else { - sitrep += "\n\nThis is a defensive patrol mission in the "; - sitrep += sector; - } - break; - - case Mission::ESCORT: - if (ward) { - sitrep += "\n\nFor this mission, you will need to escort the "; - sitrep += ward->Name(); - sitrep += " in the "; - sitrep += sector; - } - else { - sitrep += "\n\nThis is an escort mission in the "; - sitrep += sector; - } - break; - - case Mission::ESCORT_FREIGHT: - if (ward) { - sitrep += "\n\nFor this mission, you will need to escort the freighter "; - sitrep += ward->Name(); - sitrep += "."; - } - else { - sitrep += "\n\nThis is a freight escort mission in the "; - sitrep += sector; - } - break; - - case Mission::ESCORT_SHUTTLE: - if (ward) { - sitrep += "\n\nFor this mission, you will need to escort the shuttle "; - sitrep += ward->Name(); - sitrep += "."; - } - else { - sitrep += "\n\nThis is a shuttle escort mission in the "; - sitrep += sector; - } - break; - - case Mission::ESCORT_STRIKE: - if (ward) { - sitrep += "\n\nFor this mission, you will need to protect the "; - sitrep += ward->Name(); - sitrep += " strike package from hostile interceptors."; - } - else { - sitrep += "\n\nFor this mission, you will be responsible for strike escort duty."; - } - break; - - case Mission::INTEL: - case Mission::SCOUT: - case Mission::RECON: - sitrep += "\n\nThis is an intelligence gathering mission in the "; - sitrep += sector; - break; - - case Mission::BLOCKADE: - sitrep += "\n\nThis mission is part of the blockade operation in the "; - sitrep += sector; - break; - - case Mission::FLEET: - sitrep += "\n\nThis mission is a routine fleet patrol of the "; - sitrep += sector; - break; - - case Mission::BOMBARDMENT: - sitrep += "\n\nOur goal for this mission is to engage and destroy preplanned targets in the "; - sitrep += sector; - break; - - case Mission::FLIGHT_OPS: - sitrep += "\n\nFor this mission, the "; - sitrep += player->Name(); - sitrep += " will be conducting combat flight operations in the "; - sitrep += sector; - break; - - case Mission::TRAINING: - sitrep += "\n\nThis will be a training mission."; - break; - - case Mission::TRANSPORT: - case Mission::CARGO: - case Mission::OTHER: - default: - break; - } - - if (threat.length()) { - sitrep += " "; - sitrep += threat; - sitrep += "\n\n"; - } - } - else { - sitrep += "\n\n"; - } - - Text rank; - Text name; - - Player* p = Player::GetCurrentPlayer(); - - if (p) { - if (p->Rank() > 6) - rank = ", Admiral"; - else - rank = Text(", ") + Player::RankName(p->Rank()); - - name = Text(", ") + p->Name(); - } - - sitrep += "You have a mission to perform. "; - - switch (RandomIndex()) { - case 0: sitrep += "You'd better go get to it!"; break; - case 1: sitrep += "And let's be careful out there!"; break; - case 2: sitrep += "Good luck, sir!"; break; - case 3: sitrep += "Let's keep up the good work out there."; break; - case 4: sitrep += "Don't lose your focus."; break; - case 5: sitrep += "Good luck out there."; break; - case 6: sitrep += "What are you waiting for, cocktail hour?"; break; - case 7: sitrep += Text("Godspeed") + rank + "!"; break; - case 8: sitrep += Text("Good luck") + rank + "!"; break; - case 9: sitrep += Text("Good luck") + name + "!"; break; - case 10: sitrep += "If everything is clear, get your team ready and get underway."; - break; - case 11: sitrep += Text("Go get to it") + rank + "!"; break; - case 12: sitrep += "The clock is ticking, so let's move it!"; break; - case 13: sitrep += "Stay sharp out there!"; break; - case 14: sitrep += Text("Go get 'em") + rank + "!"; break; - case 15: sitrep += "Now get out of here and get to work!"; break; - } -} - -// +--------------------------------------------------------------------+ - -MissionElement* -CampaignSituationReport::FindEscort(MissionElement* player) -{ - MissionElement* escort = 0; - - if (!mission || !player) return escort; - - ListIter iter = mission->GetElements(); - while (++iter) { - MissionElement* elem = iter.value(); - - } - - return escort; -} - -// +--------------------------------------------------------------------+ - -Text -CampaignSituationReport::GetThreatInfo() -{ - Text threat_info; - - int enemy_fighters = 0; - int enemy_starships = 0; - int enemy_sites = 0; - - if (mission && mission->GetPlayer()) { - MissionElement* player = mission->GetPlayer(); - Text rgn0 = player->Region(); - Text rgn1; - int iff = player->GetIFF(); - - ListIter nav = player->NavList(); - while (++nav) { - if (rgn0 != nav->RegionName()) - rgn1 = nav->RegionName(); - } - - ListIter elem = mission->GetElements(); - while (++elem) { - if (elem->GetIFF() > 0 && elem->GetIFF() != iff && elem->IntelLevel() > Intel::SECRET) { - if (elem->IsGroundUnit()) { - if (!elem->GetDesign() || - elem->GetDesign()->type != Ship::SAM) - continue; - - if (elem->Region() != rgn0 && - elem->Region() != rgn1) - continue; - } - - int mission_role = elem->MissionRole(); - - if (mission_role == Mission::STRIKE || - mission_role == Mission::INTEL || - mission_role == Mission::CARGO || - mission_role == Mission::TRANSPORT) - continue; - - if (elem->GetDesign()->type >= Ship::MINE && elem->GetDesign()->type <= Ship::DEFSAT) - enemy_sites += elem->Count(); - - else if (elem->IsDropship()) - enemy_fighters += elem->Count(); - - else if (elem->IsStarship()) - enemy_starships += elem->Count(); - - else if (elem->IsGroundUnit()) - enemy_sites += elem->Count(); - } - } - } - - if (enemy_starships > 0) { - threat_info = "We have reports of several enemy starships in the vicinity."; - - if (enemy_fighters > 0) { - threat_info += " Also be advised that enemy fighters may be operating nearby."; - } - - else if (enemy_sites > 0) { - threat_info += " And be on the lookout for mines and defense satellites."; - } - } - - else if (enemy_fighters > 0) { - threat_info = "We have reports of several enemy fighters in your operating area."; - } - - else if (enemy_sites > 0) { - if (mission->Type() >= Mission::AIR_PATROL && mission->Type() <= Mission::STRIKE) - threat_info = "Remember to check air-to-ground sensors for SAM and AAA sites."; - else - threat_info = "Be on the lookout for mines and defense satellites."; - } - else { - threat_info = "We have no reliable information on threats in your operating area."; - } - - return threat_info; -} diff --git a/Stars45/CampaignSituationReport.h b/Stars45/CampaignSituationReport.h deleted file mode 100644 index f169923..0000000 --- a/Stars45/CampaignSituationReport.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CampaignSituationReport generates the situation report - portion of the briefing for a dynamically generated - mission in a dynamic campaign. -*/ - -#ifndef CampaignSituationReport_h -#define CampaignSituationReport_h - -#include "Types.h" -#include "Geometry.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class CombatGroup; -class CombatUnit; -class CombatZone; -class Mission; -class MissionElement; - -// +--------------------------------------------------------------------+ - -class CampaignSituationReport -{ -public: - static const char* TYPENAME() { return "CampaignSituationReport"; } - - CampaignSituationReport(Campaign* c, Mission* m); - virtual ~CampaignSituationReport(); - - virtual void GenerateSituationReport(); - -protected: - virtual void GlobalSituation(); - virtual void MissionSituation(); - virtual MissionElement* - FindEscort(MissionElement* elem); - virtual Text GetThreatInfo(); - - Campaign* campaign; - Mission* mission; - Text sitrep; -}; - -#endif // CampaignSituationReport_h - diff --git a/Stars45/CarrierAI.cpp b/Stars45/CarrierAI.cpp deleted file mode 100644 index 92ac561..0000000 --- a/Stars45/CarrierAI.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - "Air Boss" AI class for managing carrier fighter squadrons -*/ - -#include "CarrierAI.h" -#include "ShipAI.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Element.h" -#include "FlightPlanner.h" -#include "Instruction.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "Hangar.h" -#include "FlightDeck.h" -#include "Mission.h" -#include "Contact.h" -#include "Sim.h" -#include "StarSystem.h" -#include "Callsign.h" -#include "NetUtil.h" - -#include "Clock.h" -#include "Random.h" - -// +----------------------------------------------------------------------+ - -CarrierAI::CarrierAI(Ship* s, int level) - : sim(0), ship(s), hangar(0), exec_time(0), flight_planner(0), - hold_time(0), ai_level(level) -{ - if (ship) { - sim = Sim::GetSim(); - hangar = ship->GetHangar(); - - for (int i = 0; i < 4; i++) - patrol_elem[i] = 0; - - if (ship) - flight_planner = new FlightPlanner(ship); - - hold_time = (int) Clock::GetInstance()->GameTime(); - } -} - -CarrierAI::~CarrierAI() -{ - delete flight_planner; -} - -// +--------------------------------------------------------------------+ - -void -CarrierAI::ExecFrame(double secs) -{ - const int INIT_HOLD = 15000; - const int EXEC_PERIOD = 3000; - - if (!sim || !ship || !hangar) - return; - - if (((int) Clock::GetInstance()->GameTime() - hold_time >= INIT_HOLD) && - ((int) Clock::GetInstance()->GameTime() - exec_time > EXEC_PERIOD)) { - - CheckHostileElements(); - CheckPatrolCoverage(); - - exec_time = (int) Clock::GetInstance()->GameTime(); - } -} - -// +--------------------------------------------------------------------+ - -bool -CarrierAI::CheckPatrolCoverage() -{ - const DWORD PATROL_PERIOD = 900 * 1000; - - // pick up existing patrol elements: - - ListIter iter = sim->GetElements(); - while (++iter) { - Element* elem = iter.value(); - - if (elem->GetCarrier() == ship && - (elem->Type() == Mission::PATROL || - elem->Type() == Mission::SWEEP || - elem->Type() == Mission::AIR_PATROL || - elem->Type() == Mission::AIR_SWEEP) && - !elem->IsSquadron() && - !elem->IsFinished()) { - - bool found = false; - int open = -1; - - for (int i = 0; i < 4; i++) { - if (patrol_elem[i] == elem) - found = true; - - else if (patrol_elem[i] == 0 && open < 0) - open = i; - } - - if (!found && open >= 0) { - patrol_elem[open] = elem; - } - } - } - - // manage the four screening patrols: - - for (int i = 0; i < 4; i++) { - Element* elem = patrol_elem[i]; - - if (elem) { - if (elem->IsFinished()) { - patrol_elem[i] = 0; - } - - else { - LaunchElement(elem); - } - } - - else if (Clock::GetInstance()->GameTime() - hangar->GetLastPatrolLaunch() > PATROL_PERIOD || - hangar->GetLastPatrolLaunch() == 0) { - Element* patrol = CreatePackage(0, 2, Mission::PATROL, 0, "ACM Medium Range"); - if (patrol) { - patrol_elem[i] = patrol; - - if (flight_planner) - flight_planner->CreatePatrolRoute(patrol, i); - - hangar->SetLastPatrolLaunch(Clock::GetInstance()->GameTime()); - return true; - } - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -CarrierAI::CheckHostileElements() -{ - List assigned; - ListIter iter = sim->GetElements(); - while (++iter) { - Element* elem = iter.value(); - - // if this element is hostile to us - // or if the element is a target objective - // of the carrier, or is hostile to any - // of our squadrons... - - bool hostile = false; - - if (elem->IsHostileTo(ship) || elem->IsObjectiveTargetOf(ship)) { - hostile = true; - } - else { - for (int i = 0; i < hangar->NumSquadrons() && !hostile; i++) { - int squadron_iff = hangar->SquadronIFF(i); - - if (elem->IsHostileTo(squadron_iff)) - hostile = true; - } - } - - if (hostile) { - sim->GetAssignedElements(elem, assigned); - - // is one of our fighter elements already assigned to this target? - bool found = false; - ListIter a_iter = assigned; - while (++a_iter && !found) { - Element* a = a_iter.value(); - - if (a->GetCarrier() == ship) - found = true; - } - - // nobody is assigned yet, create an attack package - if (!found && CreateStrike(elem)) { - hold_time = (int) Clock::GetInstance()->GameTime() + 30000; - return true; - } - } - } - - return false; -} - -bool -CarrierAI::CreateStrike(Element* elem) -{ - Element* strike = 0; - Ship* target = elem->GetShip(1); - - if (target && !target->IsGroundUnit()) { - Contact* contact = ship->FindContact(target); - if (contact && contact->GetIFF(ship) > 0) { - - // fighter intercept - if (target->IsDropship()) { - int squadron = 0; - if (hangar->NumShipsReady(1) >= hangar->NumShipsReady(0)) - squadron = 1; - - int count = 2; - - if (count < elem->NumShips()) - count = elem->NumShips(); - - strike = CreatePackage(squadron, count, Mission::INTERCEPT, elem->Name(), "ACM Medium Range"); - - if (strike) { - strike->SetAssignment(elem); - - if (flight_planner) - flight_planner->CreateStrikeRoute(strike, elem); - } - } - - // starship or station assault - else { - int squadron = 0; - if (hangar->NumSquadrons() > 1) - squadron = 1; - if (hangar->NumSquadrons() > 2) - squadron = 2; - - int count = 2; - - if (target->Class() > Ship::FRIGATE) { - count = 4; - strike = CreatePackage(squadron, count, Mission::ASSAULT, elem->Name(), "Hvy Ship Strike"); - } - else { - count = 2; - strike = CreatePackage(squadron, count, Mission::ASSAULT, elem->Name(), "Ship Strike"); - } - - if (strike) { - strike->SetAssignment(elem); - - if (flight_planner) - flight_planner->CreateStrikeRoute(strike, elem); - - // strike escort if target has fighter protection: - if (target->GetHangar()) { - if (squadron > 1) squadron--; - Element* escort = CreatePackage(squadron, 2, Mission::ESCORT_STRIKE, strike->Name(), "ACM Short Range"); - - if (escort && flight_planner) - flight_planner->CreateEscortRoute(escort, strike); - } - } - } - } - } - - return strike != 0; -} - -// +--------------------------------------------------------------------+ - -Element* -CarrierAI::CreatePackage(int squadron, int size, int code, const char* target, const char* loadname) -{ - if (squadron < 0 || size < 1 || code < Mission::PATROL || hangar->NumShipsReady(squadron) < size) - return 0; - - Sim* sim = Sim::GetSim(); - const char* call = sim->FindAvailCallsign(ship->GetIFF()); - Element* elem = sim->CreateElement(call, ship->GetIFF(), code); - FlightDeck* deck = 0; - int queue = 1000; - int* load = 0; - const ShipDesign* - design = hangar->SquadronDesign(squadron); - - elem->SetSquadron(hangar->SquadronName(squadron)); - elem->SetCarrier(ship); - - if (target) { - int i_code = 0; - - switch (code) { - case Mission::ASSAULT: i_code = Instruction::ASSAULT; break; - case Mission::STRIKE: i_code = Instruction::STRIKE; break; - - case Mission::AIR_INTERCEPT: - case Mission::INTERCEPT: i_code = Instruction::INTERCEPT; break; - - case Mission::ESCORT: - case Mission::ESCORT_STRIKE: - case Mission::ESCORT_FREIGHT: - i_code = Instruction::ESCORT; break; - - case Mission::DEFEND: i_code = Instruction::DEFEND; break; - } - - Instruction* objective = new Instruction(i_code, target); - if (objective) - elem->AddObjective(objective); - } - - if (design && loadname) { - Text name = loadname; - name.setSensitive(false); - - ListIter sl = (List&) design->loadouts; - while (++sl) { - if (name == sl->name) { - load = sl->load; - elem->SetLoadout(load); - } - } - } - - for (int i = 0; i < ship->NumFlightDecks(); i++) { - FlightDeck* d = ship->GetFlightDeck(i); - - if (d && d->IsLaunchDeck()) { - int dq = hangar->PreflightQueue(d); - - if (dq < queue) { - queue = dq; - deck = d; - } - } - } - - int npackage = 0; - int slots[4]; - - for (int i = 0; i < 4; i++) - slots[i] = -1; - - for (int slot = 0; slot < hangar->SquadronSize(squadron); slot++) { - const HangarSlot* s = hangar->GetSlot(squadron, slot); - - if (hangar->GetState(s) == Hangar::STORAGE) { - if (npackage < 4) - slots[npackage] = slot; - - hangar->GotoAlert(squadron, slot, deck, elem, load, code > Mission::SWEEP); - npackage++; - - if (npackage >= size) - break; - } - } - - NetUtil::SendElemCreate(elem, squadron, slots, code <= Mission::SWEEP); - - return elem; -} - -// +--------------------------------------------------------------------+ - -bool -CarrierAI::LaunchElement(Element* elem) -{ - bool result = false; - - if (!elem) - return result; - - for (int squadron = 0; squadron < hangar->NumSquadrons(); squadron++) { - for (int slot = 0; slot < hangar->SquadronSize(squadron); slot++) { - const HangarSlot* s = hangar->GetSlot(squadron, slot); - - if (hangar->GetState(s) == Hangar::ALERT && - hangar->GetPackageElement(s) == elem) { - - hangar->Launch(squadron, slot); - NetUtil::SendShipLaunch(ship, squadron, slot); - - result = true; - } - } - } - - return result; -} diff --git a/Stars45/CarrierAI.h b/Stars45/CarrierAI.h deleted file mode 100644 index cd5a732..0000000 --- a/Stars45/CarrierAI.h +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - "Air Boss" AI class for managing carrier fighter squadrons -*/ - -#ifndef CarrierAI_h -#define CarrierAI_h - -#include "Types.h" -#include "Director.h" - -// +--------------------------------------------------------------------+ - -class Sim; -class Ship; -class ShipAI; -class Instruction; -class Hangar; -class Element; -class FlightPlanner; - -// +--------------------------------------------------------------------+ - -class CarrierAI : public Director -{ -public: - CarrierAI(Ship* s, int level); - virtual ~CarrierAI(); - - virtual void ExecFrame(double seconds); - -protected: - virtual bool CheckPatrolCoverage(); - virtual bool CheckHostileElements(); - - virtual bool CreateStrike(Element* elem); - - virtual Element* CreatePackage(int squad, int size, int code, const char* target=0, const char* loadname=0); - virtual bool LaunchElement(Element* elem); - - Sim* sim; - Ship* ship; - Hangar* hangar; - FlightPlanner* flight_planner; - int exec_time; - int hold_time; - int ai_level; - - Element* patrol_elem[4]; -}; - -// +--------------------------------------------------------------------+ - -#endif // CarrierAI_h - diff --git a/Stars45/Clock.cpp b/Stars45/Clock.cpp deleted file mode 100644 index e5db6c3..0000000 --- a/Stars45/Clock.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* 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. -*/ - -#include "Clock.h" - -#include - -static constexpr double NO_COMPRESSION {1.0}; -static constexpr double STARTING_DELTA {1.0 / 60.0}; - -Clock* Clock::instance = nullptr; - - -Clock* -Clock::GetInstance() -{ - return instance; -} - - -bool -Clock::Init() -{ - if (instance == nullptr) { - instance = new Clock(); - return instance != nullptr; - } - return false; -} - - -void -Clock::Close() -{ - if (instance != nullptr) { - delete instance; - instance = nullptr; - } -} - - -Clock::Clock() : - m_point {inner_clock::now()}, - m_game_elapsed {inner_clock::duration::zero()}, - m_real_elapsed {inner_clock::duration::zero()}, - m_compression {NO_COMPRESSION}, - m_delta {STARTING_DELTA}, - m_gui_delta {STARTING_DELTA}, - m_rate {0.0} -{ -} - - -void -Clock::Set() -{ - m_point = inner_clock::now(); - m_delta = STARTING_DELTA; - m_gui_delta = STARTING_DELTA; -} - - -double -Clock::Step() -{ - const auto next = inner_clock::now(); - const auto delta = next - m_point; - m_game_elapsed += std::chrono::duration_cast(delta * m_compression); - m_real_elapsed += delta; - const std::chrono::duration seconds = delta; - m_delta = seconds.count() * m_compression; - m_gui_delta = seconds.count(); - m_point = next; - m_rate = 1 / m_gui_delta; - return m_delta; -} - - -void -Clock::ResetGameTime() -{ - m_game_elapsed = inner_clock::duration::zero(); -} - - -void -Clock::SkipGameTime(double seconds) -{ - const std::chrono::duration skip {seconds}; - m_game_elapsed += std::chrono::duration_cast(skip); -} - - -double -Clock::Delta() const -{ - return m_delta; -} - - -double -Clock::GuiDelta() const -{ - return m_gui_delta; -} - - -double -Clock::Rate() const -{ - return m_rate; -} - - -double -Clock::TimeCompression() const -{ - return m_compression; -} - - -Clock::count_type -Clock::GameTime() const -{ - return std::chrono::duration_cast(m_game_elapsed).count(); -} - - -Clock::count_type -Clock::RealTime() const -{ - return std::chrono::duration_cast(m_real_elapsed).count(); -} - - -void -Clock::SetTimeCompression(double compression) -{ - m_compression = compression; -} diff --git a/Stars45/Clock.h b/Stars45/Clock.h deleted file mode 100644 index 4f51330..0000000 --- a/Stars45/Clock.h +++ /dev/null @@ -1,54 +0,0 @@ -/* 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. -*/ - -#ifndef Clock_h -#define Clock_h - -#include - - -class Clock -{ -public: - using inner_clock = std::chrono::high_resolution_clock; - using elapsed_duration = std::chrono::milliseconds; - using count_type = elapsed_duration::rep; - - static Clock* GetInstance(); - static bool Init(); - static void Close(); - - void Set(); - double Step(); - void ResetGameTime(); - void SkipGameTime(double seconds); - - double Delta() const; - double GuiDelta() const; - double Rate() const; - double TimeCompression() const; - count_type GameTime() const; - count_type RealTime() const; - - void SetTimeCompression(double compression); - -protected: - Clock(); - - inner_clock::time_point m_point; - inner_clock::duration m_game_elapsed; - inner_clock::duration m_real_elapsed; - double m_compression; - double m_delta; - double m_gui_delta; - double m_rate; - -private: - static Clock* instance; -}; - - -#endif // Clock_h diff --git a/Stars45/CmdDlg.cpp b/Stars45/CmdDlg.cpp deleted file mode 100644 index d260c6c..0000000 --- a/Stars45/CmdDlg.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog Active Window class -*/ - -#include "CmdDlg.h" -#include "CmpFileDlg.h" -#include "CmpnScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "ShipDesign.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ - -CmdDlg::CmdDlg(CmpnScreen* mgr) - : cmpn_screen(mgr), - txt_group(0), txt_score(0), txt_name(0), txt_time(0), - btn_save(0), btn_exit(0), stars(0), campaign(0), mode(0) -{ - stars = Starshatter::GetInstance(); - campaign = Campaign::GetCampaign(); - - for (int i = 0; i < 5; i++) - btn_mode[i] = 0; -} - -CmdDlg::~CmdDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -CmdDlg::RegisterCmdControls(FormWindow* win) -{ - btn_save = (Button*) win->FindControl( 1); - btn_exit = (Button*) win->FindControl( 2); - - for (int i = 0; i < 5; i++) { - btn_mode[i] = (Button*) win->FindControl(100 + i); - } - - txt_group = win->FindControl(200); - txt_score = win->FindControl(201); - txt_name = win->FindControl(300); - txt_time = win->FindControl(301); -} - -// +--------------------------------------------------------------------+ - -void -CmdDlg::ShowCmdDlg() -{ - campaign = Campaign::GetCampaign(); - - if (txt_name) { - if (campaign) - txt_name->SetText(campaign->Name()); - else - txt_name->SetText("No Campaign Selected"); - } - - ShowMode(); - - if (btn_save) - btn_save->SetEnabled(!campaign->IsTraining()); - - if (btn_mode[MODE_FORCES]) btn_mode[MODE_FORCES]->SetEnabled(!campaign->IsTraining()); - if (btn_mode[MODE_INTEL]) btn_mode[MODE_INTEL]->SetEnabled(!campaign->IsTraining()); -} - -// +--------------------------------------------------------------------+ - -void -CmdDlg::ExecFrame() -{ - CombatGroup* g = campaign->GetPlayerGroup(); - if (g && txt_group) - txt_group->SetText(g->GetDescription()); - - if (txt_score) { - char score[32]; - sprintf_s(score, "Team Score: %d", campaign->GetPlayerTeamScore()); txt_score->SetText(score); txt_score->SetTextAlign(DT_RIGHT); - } - - if (txt_time) { - double t = campaign->GetTime(); - char daytime[32]; - FormatDayTime(daytime, t); - txt_time->SetText(daytime); - } - - int unread = campaign->CountNewEvents(); - - if (btn_mode[MODE_INTEL]) { - if (unread > 0) { - char text[64]; - sprintf_s(text, "INTEL (%d)", unread); - btn_mode[MODE_INTEL]->SetText(text); - } - else { - btn_mode[MODE_INTEL]->SetText("INTEL"); - } - } -} - -// +--------------------------------------------------------------------+ - -void -CmdDlg::ShowMode() -{ - for (int i = 0; i < 5; i++) { - if (btn_mode[i]) btn_mode[i]->SetButtonState(0); - } - - if (mode < 0 || mode > 4) - mode = 0; - - if (btn_mode[mode]) btn_mode[mode]->SetButtonState(1); -} - -void -CmdDlg::OnMode(AWEvent* event) -{ - for (int i = MODE_ORDERS; i < NUM_MODES; i++) { - Button* btn = btn_mode[i]; - - if (event->window == btn) { - mode = i; - } - } - - switch (mode) { - case MODE_ORDERS: cmpn_screen->ShowCmdOrdersDlg(); break; - case MODE_THEATER: cmpn_screen->ShowCmdTheaterDlg(); break; - case MODE_FORCES: cmpn_screen->ShowCmdForceDlg(); break; - case MODE_INTEL: cmpn_screen->ShowCmdIntelDlg(); break; - case MODE_MISSIONS: cmpn_screen->ShowCmdMissionsDlg(); break; - default: cmpn_screen->ShowCmdOrdersDlg(); break; - } -} - -void -CmdDlg::OnSave(AWEvent* event) -{ - if (campaign && cmpn_screen) { - CmpFileDlg* fdlg = cmpn_screen->GetCmpFileDlg(); - - cmpn_screen->ShowCmpFileDlg(); - } -} - -void -CmdDlg::OnExit(AWEvent* event) -{ - if (stars) { - Mouse::Show(false); - stars->SetGameMode(Starshatter::MENU_MODE); - } -} - -// +--------------------------------------------------------------------+ diff --git a/Stars45/CmdDlg.h b/Stars45/CmdDlg.h deleted file mode 100644 index 6d4ba40..0000000 --- a/Stars45/CmdDlg.h +++ /dev/null @@ -1,82 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog Active Window class -*/ - -#ifndef CmdDlg_h -#define CmdDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class CmpnScreen; -class Campaign; -class Combatant; -class CombatGroup; -class CombatUnit; -class Starshatter; - -// +--------------------------------------------------------------------+ - -class CmdDlg -{ -public: - enum MODE { - MODE_ORDERS, - MODE_THEATER, - MODE_FORCES, - MODE_INTEL, - MODE_MISSIONS, - NUM_MODES - }; - - CmdDlg(CmpnScreen* mgr); - virtual ~CmdDlg(); - - virtual void RegisterCmdControls(FormWindow* win); - virtual void ShowCmdDlg(); - - virtual void ExecFrame(); - - // Operations: - virtual void OnMode(AWEvent* event); - virtual void OnSave(AWEvent* event); - virtual void OnExit(AWEvent* event); - -protected: - virtual void ShowMode(); - - CmpnScreen* cmpn_screen; - - ActiveWindow* txt_group; - ActiveWindow* txt_score; - ActiveWindow* txt_name; - ActiveWindow* txt_time; - Button* btn_mode[NUM_MODES]; - Button* btn_save; - Button* btn_exit; - - Starshatter* stars; - Campaign* campaign; - - int mode; -}; - -#endif // CmdDlg_h - diff --git a/Stars45/CmdForceDlg.cpp b/Stars45/CmdForceDlg.cpp deleted file mode 100644 index 91f8cb6..0000000 --- a/Stars45/CmdForceDlg.cpp +++ /dev/null @@ -1,715 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Order of Battle Tab) -*/ - -#include "CmdForceDlg.h" -#include "CmdMsgDlg.h" -#include "CmpnScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAssignment.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Player.h" -#include "Weapon.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CmdForceDlg, OnMode); -DEF_MAP_CLIENT(CmdForceDlg, OnSave); -DEF_MAP_CLIENT(CmdForceDlg, OnExit); -DEF_MAP_CLIENT(CmdForceDlg, OnForces); -DEF_MAP_CLIENT(CmdForceDlg, OnCombat); -DEF_MAP_CLIENT(CmdForceDlg, OnTransfer); - -// +--------------------------------------------------------------------+ - -CmdForceDlg::CmdForceDlg(Screen* s, FormDef& def, CmpnScreen* mgr) - : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), CmdDlg(mgr), - cmb_forces(0), lst_combat(0), lst_desc(0), - stars(0), campaign(0), current_group(0), current_unit(0), - btn_transfer(0) -{ - stars = Starshatter::GetInstance(); - campaign = Campaign::GetCampaign(); - - Init(def); -} - -CmdForceDlg::~CmdForceDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::RegisterControls() -{ - cmb_forces = (ComboBox*) FindControl(400); - lst_combat = (ListBox*) FindControl(401); - lst_desc = (ListBox*) FindControl(402); - btn_transfer = (Button*) FindControl(403); - - RegisterCmdControls(this); - - if (btn_save) - REGISTER_CLIENT(EID_CLICK, btn_save, CmdForceDlg, OnSave); - - if (btn_exit) - REGISTER_CLIENT(EID_CLICK, btn_exit, CmdForceDlg, OnExit); - - for (int i = 0; i < 5; i++) { - if (btn_mode[i]) - REGISTER_CLIENT(EID_CLICK, btn_mode[i], CmdForceDlg, OnMode); - } - - if (cmb_forces) - REGISTER_CLIENT(EID_SELECT, cmb_forces, CmdForceDlg, OnForces); - - if (lst_combat) { - lst_combat->AddColumn("datatype", 0); - REGISTER_CLIENT(EID_SELECT, lst_combat, CmdForceDlg, OnCombat); - } - - if (btn_transfer) { - btn_transfer->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_transfer, CmdForceDlg, OnTransfer); - } -} - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::ExecFrame() -{ - CmdDlg::ExecFrame(); -} - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::Show() -{ - mode = MODE_FORCES; - - FormWindow::Show(); - ShowCmdDlg(); - - cmb_forces->ClearItems(); - - campaign = Campaign::GetCampaign(); - - if (campaign) { - List& combatants = campaign->GetCombatants(); - - if (combatants.size() > 0) { - for (int i = 0; i < combatants.size(); i++) { - if (IsVisible(combatants[i])) { - cmb_forces->AddItem(combatants[i]->Name()); - } - } - - cmb_forces->SetSelection(0); - Combatant* c = combatants[0]; - ShowCombatant(c); - } - } -} - -// +--------------------------------------------------------------------+ - -bool -CmdForceDlg::IsVisible(Combatant* c) -{ - int nvis = 0; - - if (c) { - CombatGroup* force = c->GetForce(); - - if (force) { - List& groups = force->GetComponents(); - for (int i = 0; i < groups.size(); i++) { - CombatGroup* g = groups[i]; - - if (g->Type() < CombatGroup::CIVILIAN && - g->CountUnits() > 0 && - g->IntelLevel() >= Intel::KNOWN) - - nvis++; - } - } - } - - return nvis > 0; -} - -// +--------------------------------------------------------------------+ - -static char pipe_stack[32]; -static bool blank_line = false; - -void -CmdForceDlg::ShowCombatant(Combatant* c) -{ - if (!lst_combat || !c) return; - - lst_combat->ClearItems(); - ZeroMemory(pipe_stack, 32); - - CombatGroup* force = c->GetForce(); - - if (force) { - List& groups = force->GetComponents(); - for (int i = 0; i < groups.size(); i++) { - CombatGroup* g = groups[i]; - if (g->Type() < CombatGroup::CIVILIAN && g->CountUnits() > 0) - AddCombatGroup(g); - } - } - - current_group = 0; - current_unit = 0; - - if (lst_desc) lst_desc->ClearItems(); - if (btn_transfer) btn_transfer->SetEnabled(false); -} - -void -CmdForceDlg::AddCombatGroup(CombatGroup* grp, bool last_child) -{ - if (!lst_combat || !grp || grp->IntelLevel() < Intel::KNOWN) return; - - char prefix[4]; - - if (!grp->GetParent() || grp->GetParent()->Type() == CombatGroup::FORCE) { - if (!grp->IsExpanded()) { - prefix[0] = Font::PIPE_PLUS; - prefix[1] = 0; - } - else { - prefix[0] = Font::PIPE_MINUS; - prefix[1] = 0; - } - } - else { - prefix[0] = last_child ? Font::PIPE_LL : Font::PIPE_LT; - prefix[1] = Font::PIPE_HORZ; - prefix[2] = 0; - prefix[3] = 0; - - if (grp->GetLiveComponents().size() > 0 || grp->GetUnits().size() > 0) { - if (grp->IsExpanded()) - prefix[1] = Font::PIPE_MINUS; - else - prefix[1] = Font::PIPE_PLUS; - } - } - - int index = lst_combat->AddItemWithData( - Text(pipe_stack) + - Text(prefix) + - grp->GetDescription(), - (DWORD) grp); - lst_combat->SetItemData(index-1, 1, 0); - blank_line = false; - - int stacklen = strlen(pipe_stack); - - if (!grp->GetParent() || grp->GetParent()->Type() == CombatGroup::FORCE) - ; // no stack after first entry - else if (prefix[0] == Font::PIPE_LT) - pipe_stack[stacklen++] = Font::PIPE_VERT; - else - pipe_stack[stacklen++] = Font::PIPE_NBSP; - pipe_stack[stacklen] = 0; - - if (grp->IsExpanded() && grp->GetUnits().size() > 0) { - prefix[0] = (grp->GetLiveComponents().size() > 0) ? Font::PIPE_VERT : Font::PIPE_NBSP; - prefix[1] = Font::PIPE_NBSP; - prefix[2] = 0; - prefix[3] = 0; - - ListIter unit_iter = grp->GetUnits(); - while (++unit_iter) { - CombatUnit* unit = unit_iter.value(); - char info[512]; - int damage = (int) (100 * unit->GetSustainedDamage() / unit->GetDesign()->integrity); - - if (damage < 1 || unit->DeadCount() >= unit->Count()) { - sprintf_s(info, "%s%s%s", pipe_stack, prefix, unit->GetDescription()); - } else { - sprintf_s(info, "%s%s%s %d%% damage", pipe_stack, prefix, unit->GetDescription(), damage); - } - - int index = lst_combat->AddItemWithData(info, (DWORD) unit); - - lst_combat->SetItemData(index-1, 1, 1); - lst_combat->SetItemColor(index-1, lst_combat->GetForeColor() * 0.65); - } - - // blank line after last unit in group: - lst_combat->AddItem(Text(pipe_stack) + Text(prefix)); - blank_line = true; - } - - if (grp->IsExpanded() && grp->GetLiveComponents().size() > 0) { - List& groups = grp->GetLiveComponents(); - for (int i = 0; i < groups.size(); i++) { - AddCombatGroup(groups[i], i == groups.size()-1); - } - - // blank line after last group in group: - if (!blank_line) { - lst_combat->AddItem(pipe_stack); - blank_line = true; - } - } - - if (stacklen > 1) - pipe_stack[stacklen-1] = 0; - else - pipe_stack[0] = 0; -} - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::OnForces(AWEvent* event) -{ - Text name = cmb_forces->GetSelectedItem(); - - campaign = Campaign::GetCampaign(); - - if (campaign) { - ListIter iter = campaign->GetCombatants(); - - while (++iter) { - Combatant* c = iter.value(); - - if (name == c->Name()) { - ShowCombatant(c); - break; - } - } - } -} - -// +--------------------------------------------------------------------+ - -struct WepGroup { - Text name; - int count; - - WepGroup() : count(0) { } -}; - -WepGroup* FindWepGroup(WepGroup* weapons, const char* name) -{ - WepGroup* group = 0; - WepGroup* iter = weapons; - int w = 0; - int first = -1; - - while (!group && w < 8) { - if (first < 0 && iter->name.length() == 0) - first = w; - - if (!_stricmp(iter->name, name)) - group = iter; - - iter++; - w++; - } - - if (!group && first >= 0) { - group = weapons + first; - group->name = name; - } - - return group; -} - -void -CmdForceDlg::OnCombat(AWEvent* event) -{ - static int old_index = -1; - - int top_index = 0; - bool expand = false; - DWORD data = 0; - DWORD type = 0; - - current_group = 0; - current_unit = 0; - - if (lst_combat) { - top_index = lst_combat->GetTopIndex(); - - int index = lst_combat->GetListIndex(); - data = lst_combat->GetItemData(index); - type = lst_combat->GetItemData(index, 1); - Text item = lst_combat->GetItemText(index); - int nplus = item.indexOf(Font::PIPE_PLUS); - int xplus = -1; - int dx = 10000; - - if (nplus < 0) - nplus = item.indexOf(Font::PIPE_MINUS); - - if (nplus >= 0 && nplus < 64) { - char pipe[64]; - strncpy(pipe, item.data(), nplus+1); - pipe[nplus+1] = 0; - - Rect rect(0, 0, 1000, 20); - lst_combat->DrawText(pipe, 0, rect, DT_LEFT|DT_SINGLELINE|DT_VCENTER|DT_CALCRECT); - - xplus = rect.w; - } - - if (xplus > 0) { - dx = Mouse::X() - (lst_combat->GetRect().x + xplus - 16); - } - - // look for click on plus/minus in pipe - if (dx >= 0 && dx < 16) { - if (data && type == 0) { - CombatGroup* grp = (CombatGroup*) data; - grp->SetExpanded(!grp->IsExpanded()); - expand = true; - - current_group = grp; - current_unit = 0; - } - } - - old_index = index; - } - - if (campaign && data) { - if (!expand) { - lst_desc->ClearItems(); - - // combat group - if (type == 0) { - CombatGroup* grp = (CombatGroup*) data; - - current_group = grp; - current_unit = 0; - - // if has units, show location and assignment - if (grp->GetUnits().size() > 0) { - char txt[64]; - int n; - - n = lst_desc->AddItem("Group:") - 1; - lst_desc->SetItemText(n, 1, grp->GetDescription()); - n = lst_desc->AddItem("Sector:") - 1; - lst_desc->SetItemText(n, 1, grp->GetRegion()); - - lst_desc->AddItem(" "); - n = lst_desc->AddItem("Sorties:") - 1; - - if (grp->Sorties() >= 0) - sprintf_s(txt, "%d", grp->Sorties()); - else - strcpy_s(txt, "Unavail"); - - lst_desc->SetItemText(n, 1, txt); - - n = lst_desc->AddItem("Kills:") - 1; - - if (grp->Kills() >= 0) - sprintf_s(txt, "%d", grp->Kills()); - else - strcpy_s(txt, "Unavail"); - - lst_desc->SetItemText(n, 1, txt); - - n = lst_desc->AddItem("Eff Rating:") - 1; - - if (grp->Points() >= 0) { - if (grp->Sorties() > 0) - sprintf_s(txt, "%.1f", (double) grp->Points() / grp->Sorties()); - else - sprintf_s(txt, "%.1f", (double) grp->Points()); - } else { - strcpy_s(txt, "Unavail"); - } - - lst_desc->SetItemText(n, 1, txt); - } - - // else (if high-level) show components - else { - int n; - - n = lst_desc->AddItem("Group:") - 1; - lst_desc->SetItemText(n, 1, grp->GetDescription()); - - ListIter c = grp->GetLiveComponents(); - while (++c) { - n = lst_desc->AddItem("-") - 1; - lst_desc->SetItemText(n, 1, c->GetDescription()); - } - } - } - // combat unit - else { - CombatUnit* unit = (CombatUnit*) data; - current_group = unit->GetCombatGroup(); - current_unit = unit; - - int n; - char txt[64]; - - n = lst_desc->AddItem("Unit:") - 1; - lst_desc->SetItemText(n, 1, unit->GetDescription()); - n = lst_desc->AddItem("Sector:") - 1; - lst_desc->SetItemText(n, 1, unit->GetRegion()); - - const ShipDesign* design = unit->GetDesign(); - if (design) { - lst_desc->AddItem(" "); - n = lst_desc->AddItem("Type:") - 1; - lst_desc->SetItemText(n, 1, Ship::ClassName(design->type)); - n = lst_desc->AddItem("Class:") - 1; - lst_desc->SetItemText(n, 1, design->DisplayName()); - - if (design->type < Ship::STATION) - FormatNumber(txt, design->radius/2); - else - FormatNumber(txt, design->radius*2); - - strcat_s(txt, " m"); - - n = lst_desc->AddItem("Length:") - 1; - lst_desc->SetItemText(n, 1, txt); - - FormatNumber(txt, design->mass); - strcat_s(txt, " T"); - - n = lst_desc->AddItem("Mass:") - 1; - lst_desc->SetItemText(n, 1, txt); - - FormatNumber(txt, design->integrity); - n = lst_desc->AddItem("Hull:") - 1; - lst_desc->SetItemText(n, 1, txt); - - if (design->weapons.size()) { - lst_desc->AddItem(" "); - n = lst_desc->AddItem("Weapons:") - 1; - - WepGroup groups[8]; - for (int w = 0; w < design->weapons.size(); w++) { - Weapon* gun = design->weapons[w]; - WepGroup* group = FindWepGroup(groups, gun->Group()); - - if (group) - group->count++; - } - - for (int g = 0; g < 8; g++) { - WepGroup* group = &groups[g]; - if (group && group->count) { - sprintf_s(txt, "%s (%d)", group->name.data(), group->count); - if (g > 0) n = lst_desc->AddItem(" ") - 1; - lst_desc->SetItemText(n, 1, txt); - } - } - } - } - } - } - - else { - List& combatants = campaign->GetCombatants(); - Combatant* c = combatants[0]; - - if (cmb_forces) { - Text name = cmb_forces->GetSelectedItem(); - - for (int i = 0; i < combatants.size(); i++) { - c = combatants[i]; - - if (name == c->Name()) { - break; - } - } - } - - if (c) { - ShowCombatant(c); - - lst_combat->ScrollTo(top_index); - lst_combat->SetSelected(old_index); - } - } - } - - if (btn_transfer && campaign && current_group) - btn_transfer->SetEnabled( campaign->IsActive() && - CanTransfer(current_group) ); -} - -// +--------------------------------------------------------------------+ - -bool -CmdForceDlg::CanTransfer(CombatGroup* grp) -{ - if (!grp || !campaign) - return false; - - if (grp->Type() < CombatGroup::WING) - return false; - - if (grp->Type() > CombatGroup::CARRIER_GROUP) - return false; - - if (grp->Type() == CombatGroup::FLEET || - grp->Type() == CombatGroup::LCA_SQUADRON) - return false; - - CombatGroup* player_group = campaign->GetPlayerGroup(); - if (player_group->GetIFF() != grp->GetIFF()) - return false; - - return true; -} - - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::OnSave(AWEvent* event) -{ - CmdDlg::OnSave(event); -} - -void -CmdForceDlg::OnExit(AWEvent* event) -{ - CmdDlg::OnExit(event); -} - -void -CmdForceDlg::OnMode(AWEvent* event) -{ - CmdDlg::OnMode(event); -} - - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::OnTransfer(AWEvent* event) -{ - if (campaign && current_group) { - - // check player rank/responsibility: - Player* player = Player::GetCurrentPlayer(); - int cmd_class = Ship::FIGHTER; - - switch (current_group->Type()) { - case CombatGroup::WING: - case CombatGroup::INTERCEPT_SQUADRON: - case CombatGroup::FIGHTER_SQUADRON: - cmd_class = Ship::FIGHTER; - break; - - case CombatGroup::ATTACK_SQUADRON: - cmd_class = Ship::ATTACK; - break; - - case CombatGroup::LCA_SQUADRON: - cmd_class = Ship::LCA; - break; - - case CombatGroup::DESTROYER_SQUADRON: - cmd_class = Ship::DESTROYER; - break; - - case CombatGroup::BATTLE_GROUP: - cmd_class = Ship::CRUISER; - break; - - case CombatGroup::CARRIER_GROUP: - case CombatGroup::FLEET: - cmd_class = Ship::CARRIER; - break; - } - - char transfer_info[512]; - - if (player->CanCommand(cmd_class)) { - if (current_unit) { - campaign->SetPlayerUnit(current_unit); - - sprintf_s(transfer_info, "Your transfer request has been approved, %s %s. You are now assigned to the %s. Good luck.\n\nFleet Admiral A. Evars FORCOM\nCommanding", - Player::RankName(player->Rank()), - player->Name().data(), - current_unit->GetDescription()); - } - else { - campaign->SetPlayerGroup(current_group); - - sprintf_s(transfer_info, "Your transfer request has been approved, %s %s. You are now assigned to the %s. Good luck.\n\nFleet Admiral A. Evars FORCOM\nCommanding", - Player::RankName(player->Rank()), - player->Name().data(), - current_group->GetDescription()); - } - - Button::PlaySound(Button::SND_ACCEPT); - - CmdMsgDlg* msgdlg = manager->GetCmdMsgDlg(); - msgdlg->Title()->SetText("Transfer Approved"); - msgdlg->Message()->SetText(transfer_info); - msgdlg->Message()->SetTextAlign(DT_LEFT); - - manager->ShowCmdMsgDlg(); - } - - else { - Button::PlaySound(Button::SND_REJECT); - - sprintf_s(transfer_info, "Your transfer request has been denied, %s %s. The %s requires a command rank of %s. Please return to your unit and your duties.\n\nFleet Admiral A. Evars FORCOM\nCommanding", - Player::RankName(player->Rank()), - player->Name().data(), - current_group->GetDescription(), - Player::RankName(Player::CommandRankRequired(cmd_class))); - - CmdMsgDlg* msgdlg = manager->GetCmdMsgDlg(); - msgdlg->Title()->SetText("Transfer Denied"); - msgdlg->Message()->SetText(transfer_info); - msgdlg->Message()->SetTextAlign(DT_LEFT); - - manager->ShowCmdMsgDlg(); - } - } -} diff --git a/Stars45/CmdForceDlg.h b/Stars45/CmdForceDlg.h deleted file mode 100644 index f85e9e9..0000000 --- a/Stars45/CmdForceDlg.h +++ /dev/null @@ -1,68 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Order of Battle Tab) -*/ - -#ifndef CmdForceDlg_h -#define CmdForceDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "CmdDlg.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class CmdForceDlg : public FormWindow, -public CmdDlg -{ -public: - CmdForceDlg(Screen* s, FormDef& def, CmpnScreen* mgr); - virtual ~CmdForceDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnMode(AWEvent* event); - virtual void OnSave(AWEvent* event); - virtual void OnExit(AWEvent* event); - virtual void OnForces(AWEvent* event); - virtual void OnCombat(AWEvent* event); - virtual void OnTransfer(AWEvent* event); - -protected: - void ShowCombatant(Combatant* c); - void AddCombatGroup(CombatGroup* grp, bool last_child=false); - bool CanTransfer(CombatGroup* grp); - bool IsVisible(Combatant* c); - - CmpnScreen* manager; - - ComboBox* cmb_forces; - ListBox* lst_combat; - ListBox* lst_desc; - Button* btn_transfer; - - Starshatter* stars; - Campaign* campaign; - CombatGroup* current_group; - CombatUnit* current_unit; -}; - -#endif // CmdForceDlg_h - diff --git a/Stars45/CmdIntelDlg.cpp b/Stars45/CmdIntelDlg.cpp deleted file mode 100644 index afa7dd2..0000000 --- a/Stars45/CmdIntelDlg.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Intel/Newsfeed Tab) -*/ - -#include "CmdIntelDlg.h" -#include "CmpnScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatEvent.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "ShipDesign.h" -#include "Starshatter.h" -#include "Sim.h" -#include "CameraDirector.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CmdIntelDlg, OnMode); -DEF_MAP_CLIENT(CmdIntelDlg, OnSave); -DEF_MAP_CLIENT(CmdIntelDlg, OnExit); -DEF_MAP_CLIENT(CmdIntelDlg, OnNews); -DEF_MAP_CLIENT(CmdIntelDlg, OnPlay); - -// +--------------------------------------------------------------------+ - -CmdIntelDlg::CmdIntelDlg(Screen* s, FormDef& def, CmpnScreen* mgr) - : FormWindow(s, 0, 0, s->Width(), s->Height()), CmdDlg(mgr), manager(mgr), - stars(0), campaign(0), update_time(0), start_scene(0), - cam_view(0), dsp_view(0) -{ - stars = Starshatter::GetInstance(); - campaign = Campaign::GetCampaign(); - - if (campaign) - update_time = campaign->GetUpdateTime(); - - Init(def); -} - -CmdIntelDlg::~CmdIntelDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -CmdIntelDlg::RegisterControls() -{ - lst_news = (ListBox*) FindControl(401); - txt_news = (RichTextBox*) FindControl(402); - img_news = (ImageBox*) FindControl(403); - mov_news = FindControl(404); - btn_play = (Button*) FindControl(405); - - RegisterCmdControls(this); - - if (btn_save) - REGISTER_CLIENT(EID_CLICK, btn_save, CmdIntelDlg, OnSave); - - if (btn_exit) - REGISTER_CLIENT(EID_CLICK, btn_exit, CmdIntelDlg, OnExit); - - if (btn_play) - REGISTER_CLIENT(EID_CLICK, btn_play, CmdIntelDlg, OnPlay); - - for (int i = 0; i < 5; i++) { - if (btn_mode[i]) - REGISTER_CLIENT(EID_CLICK, btn_mode[i], CmdIntelDlg, OnMode); - } - - if (lst_news) { - REGISTER_CLIENT(EID_SELECT, lst_news, CmdIntelDlg, OnNews); - } - - if (img_news) { - img_news->GetPicture(bmp_default); - } - - if (mov_news) { - CameraDirector* cam_dir = CameraDirector::GetInstance(); - cam_view = new CameraView(mov_news, cam_dir->GetCamera(), 0); - if (cam_view) - mov_news->AddView(cam_view); - - dsp_view = DisplayView::GetInstance(); - if (dsp_view) { - dsp_view->SetWindow(mov_news); - mov_news->AddView(dsp_view); - } - - mov_news->Hide(); - } -} - -// +--------------------------------------------------------------------+ - -void -CmdIntelDlg::Show() -{ - mode = MODE_INTEL; - - FormWindow::Show(); - ShowCmdDlg(); - - if (btn_play) - btn_play->Hide(); - - if (mov_news) - mov_news->Hide(); -} - -// +--------------------------------------------------------------------+ - -void -CmdIntelDlg::ExecFrame() -{ - CmdDlg::ExecFrame(); - - if (campaign != Campaign::GetCampaign() || campaign->GetUpdateTime() != update_time) { - campaign = Campaign::GetCampaign(); - update_time = campaign->GetUpdateTime(); - - lst_news->ClearItems(); - txt_news->SetText(""); - - if (img_news) - img_news->SetPicture(bmp_default); - } - - if (campaign) { - List& events = campaign->GetEvents(); - bool auto_scroll = false; - - if (events.size() > lst_news->NumItems()) { - while (events.size() > lst_news->NumItems()) { - CombatEvent* info = events[lst_news->NumItems()]; - - const char* unread = info->Visited() ? " " : "*"; - int i = lst_news->AddItemWithData(unread, (DWORD) info) - 1; - - char dateline[32]; - FormatDayTime(dateline, info->Time()); - lst_news->SetItemText(i, 1, dateline); - lst_news->SetItemText(i, 2, info->Title()); - lst_news->SetItemText(i, 3, info->Region()); - lst_news->SetItemText(i, 4, ContentBundle::GetInstance()->GetText(info->SourceName())); - - if (!info->Visited()) - auto_scroll = true; - } - - if (lst_news->GetSortColumn() > 0) - lst_news->SortItems(); - } - - else if (events.size() < lst_news->NumItems()) { - lst_news->ClearItems(); - - for (int i = 0; i < events.size(); i++) { - CombatEvent* info = events[i]; - - const char* unread = info->Visited() ? " " : "*"; - int j = lst_news->AddItemWithData(unread, (DWORD) info) - 1; - - char dateline[32]; - FormatDayTime(dateline, info->Time()); - lst_news->SetItemText(j, 1, dateline); - lst_news->SetItemText(j, 2, info->Title()); - lst_news->SetItemText(j, 3, info->Region()); - lst_news->SetItemText(j, 4, ContentBundle::GetInstance()->GetText(info->SourceName())); - - if (!info->Visited()) - auto_scroll = true; - } - - if (lst_news->GetSortColumn() > 0) - lst_news->SortItems(); - - txt_news->SetText(""); - - if (img_news) - img_news->SetPicture(bmp_default); - } - - if (auto_scroll) { - int first_unread = -1; - - for (int i = 0; i < lst_news->NumItems(); i++) { - if (lst_news->GetItemText(i, 0) == "*") { - first_unread = i; - break; - } - } - - if (first_unread >= 0) - lst_news->ScrollTo(first_unread); - } - } - - Starshatter* stars = Starshatter::GetInstance(); - - if (start_scene > 0) { - ShowMovie(); - - start_scene--; - - if (start_scene == 0) { - if (stars && campaign) { - stars->ExecCutscene(event_scene, campaign->Path()); - - if (stars->InCutscene()) { - Sim* sim = Sim::GetSim(); - - if (sim) { - cam_view->UseCamera(CameraDirector::GetInstance()->GetCamera()); - cam_view->UseScene(sim->GetScene()); - } - } - } - - event_scene = ""; - } - } - else { - if (dsp_view) - dsp_view->ExecFrame(); - - if (stars->InCutscene()) - ShowMovie(); - else - HideMovie(); - } -} - -// +--------------------------------------------------------------------+ - -void -CmdIntelDlg::OnSave(AWEvent* event) -{ - CmdDlg::OnSave(event); -} - -void -CmdIntelDlg::OnExit(AWEvent* event) -{ - CmdDlg::OnExit(event); -} - -void -CmdIntelDlg::OnMode(AWEvent* event) -{ - CmdDlg::OnMode(event); -} - - -// +--------------------------------------------------------------------+ - -void -CmdIntelDlg::OnNews(AWEvent* e) -{ - CombatEvent* event = 0; - int index = lst_news->GetSelection(); - - if (index >= 0) { - event = (CombatEvent*) lst_news->GetItemData(index, 0); - } - - if (event) { - Text info(""); - info += event->Title(); - info += "\n\n"; - info += event->Information(); - - txt_news->SetText(info); - txt_news->EnsureVisible(0); - - lst_news->SetItemText(index, 0, " "); - - if (img_news) { - if (event->Image().Width() >= 64) - img_news->SetPicture(event->Image()); - else - img_news->SetPicture(bmp_default); - } - - if (btn_play) { - if (event->SceneFile() && *event->SceneFile()) - btn_play->Show(); - else - btn_play->Hide(); - } - - if (!event->Visited() && btn_play->IsEnabled()) - OnPlay(0); - - event->SetVisited(true); - } - else { - txt_news->SetText(""); - - if (img_news) - img_news->SetPicture(bmp_default); - - if (btn_play) - btn_play->Hide(); - } -} - -// +--------------------------------------------------------------------+ - -void -CmdIntelDlg::OnPlay(AWEvent* e) -{ - CombatEvent* event = 0; - int index = lst_news->GetSelection(); - - if (index >= 0) { - event = (CombatEvent*) lst_news->GetItemData(index, 0); - } - - if (mov_news && cam_view && event && event->SceneFile() && *event->SceneFile()) { - event_scene = event->SceneFile(); - start_scene = 2; - ShowMovie(); - } -} - -void -CmdIntelDlg::ShowMovie() -{ - if (mov_news) { - mov_news->Show(); - dsp_view->SetWindow(mov_news); - - if (img_news) img_news->Hide(); - if (txt_news) txt_news->Hide(); - if (btn_play) btn_play->Hide(); - } -} - -void -CmdIntelDlg::HideMovie() -{ - CombatEvent* event = 0; - int index = lst_news->GetSelection(); - bool play = false; - - if (index >= 0) { - event = (CombatEvent*) lst_news->GetItemData(index, 0); - - if (event && event->SceneFile() && *event->SceneFile()) - play = true; - } - - if (mov_news) { - mov_news->Hide(); - - if (img_news) img_news->Show(); - if (txt_news) txt_news->Show(); - if (btn_play) { - if (play) - btn_play->Show(); - else - btn_play->Hide(); - } - } -} diff --git a/Stars45/CmdIntelDlg.h b/Stars45/CmdIntelDlg.h deleted file mode 100644 index b0783c4..0000000 --- a/Stars45/CmdIntelDlg.h +++ /dev/null @@ -1,75 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Intel/Newsfeed Tab) -*/ - -#ifndef CmdIntelDlg_h -#define CmdIntelDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "CmdDlg.h" -#include "CameraView.h" -#include "DisplayView.h" - -#include "Bitmap.h" -#include "Button.h" -#include "ImageBox.h" -#include "ListBox.h" -#include "RichTextBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class CmdIntelDlg : public FormWindow, -public CmdDlg -{ -public: - CmdIntelDlg(Screen* s, FormDef& def, CmpnScreen* mgr); - virtual ~CmdIntelDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnMode(AWEvent* event); - virtual void OnSave(AWEvent* event); - virtual void OnExit(AWEvent* event); - virtual void OnNews(AWEvent* event); - virtual void OnPlay(AWEvent* event); - -protected: - virtual void ShowMovie(); - virtual void HideMovie(); - - CmpnScreen* manager; - - ListBox* lst_news; - RichTextBox* txt_news; - ImageBox* img_news; - Button* btn_play; - ActiveWindow* mov_news; - CameraView* cam_view; - DisplayView* dsp_view; - - Bitmap bmp_default; - - Starshatter* stars; - Campaign* campaign; - double update_time; - int start_scene; - Text event_scene; -}; - -#endif // CmdIntelDlg_h - diff --git a/Stars45/CmdMissionsDlg.cpp b/Stars45/CmdMissionsDlg.cpp deleted file mode 100644 index ee5b265..0000000 --- a/Stars45/CmdMissionsDlg.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Mission List Tab) -*/ - -#include "CmdMissionsDlg.h" -#include "CmpnScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAssignment.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Mission.h" -#include "ShipDesign.h" -#include "Player.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CmdMissionsDlg, OnMode); -DEF_MAP_CLIENT(CmdMissionsDlg, OnSave); -DEF_MAP_CLIENT(CmdMissionsDlg, OnExit); -DEF_MAP_CLIENT(CmdMissionsDlg, OnMission); -DEF_MAP_CLIENT(CmdMissionsDlg, OnAccept); - -// +--------------------------------------------------------------------+ - -CmdMissionsDlg::CmdMissionsDlg(Screen* s, FormDef& def, CmpnScreen* mgr) - : FormWindow(s, 0, 0, s->Width(), s->Height()), CmdDlg(mgr), manager(mgr), - lst_missions(0), txt_desc(0), btn_accept(0), - stars(0), campaign(0), mission(0) -{ - stars = Starshatter::GetInstance(); - campaign = Campaign::GetCampaign(); - - Init(def); -} - -CmdMissionsDlg::~CmdMissionsDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -CmdMissionsDlg::RegisterControls() -{ - lst_missions = (ListBox*) FindControl(401); - txt_desc = FindControl(402); - btn_accept = (Button*) FindControl(403); - - RegisterCmdControls(this); - - if (btn_save) - REGISTER_CLIENT(EID_CLICK, btn_save, CmdMissionsDlg, OnSave); - - if (btn_exit) - REGISTER_CLIENT(EID_CLICK, btn_exit, CmdMissionsDlg, OnExit); - - for (int i = 0; i < 5; i++) { - if (btn_mode[i]) - REGISTER_CLIENT(EID_CLICK, btn_mode[i], CmdMissionsDlg, OnMode); - } - - if (lst_missions) { - REGISTER_CLIENT(EID_SELECT, lst_missions, CmdMissionsDlg, OnMission); - } - - if (btn_accept) { - btn_accept->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_accept, CmdMissionsDlg, OnAccept); - } -} - -// +--------------------------------------------------------------------+ - -void -CmdMissionsDlg::Show() -{ - mode = MODE_MISSIONS; - - FormWindow::Show(); - ShowCmdDlg(); - - campaign = Campaign::GetCampaign(); - - if (campaign) { - if (lst_missions) { - lst_missions->ClearItems(); - - Player* player = Player::GetCurrentPlayer(); - List& missions = campaign->GetMissionList(); - for (int i = 0; i < missions.size(); i++) { - MissionInfo* info = missions[i]; - lst_missions->AddItemWithData(info->name, info->id); - - Mission* m = info->mission; - if (m) { - if (m->Type() == Mission::TRAINING && player->HasTrained(m->Identity())) { - lst_missions->SetItemText(i, 1, ContentBundle::GetInstance()->GetText("CmdMissionsDlg.training")); - } - else { - lst_missions->SetItemText(i, 1, m->TypeName()); - } - } - - char start_time[64]; - FormatDayTime(start_time, info->start); - lst_missions->SetItemText(i, 2, start_time); - } - } - } -} - -void -CmdMissionsDlg::ExecFrame() -{ - CmdDlg::ExecFrame(); - - if (campaign) { - List& missions = campaign->GetMissionList(); - Player* player = Player::GetCurrentPlayer(); - - if (missions.size() > lst_missions->NumItems()) { - while (missions.size() > lst_missions->NumItems()) { - MissionInfo* info = missions[lst_missions->NumItems()]; - int i = lst_missions->AddItemWithData(info->name, info->id) - 1; - - Mission* m = info->mission; - if (m) { - if (m->Type() == Mission::TRAINING && player->HasTrained(m->Identity())) { - lst_missions->SetItemText(i, 1, ContentBundle::GetInstance()->GetText("CmdMissionsDlg.training")); - } - else { - lst_missions->SetItemText(i, 1, m->TypeName()); - } - } - - char start_time[64]; - FormatDayTime(start_time, info->start); - lst_missions->SetItemText(i, 2, start_time); - } - } - - else if (missions.size() < lst_missions->NumItems()) { - lst_missions->ClearItems(); - - for (int i = 0; i < missions.size(); i++) { - MissionInfo* info = missions[i]; - lst_missions->AddItemWithData(info->name, info->id); - - Mission* m = info->mission; - if (m) { - if (m->Type() == Mission::TRAINING && player->HasTrained(m->Identity())) { - lst_missions->SetItemText(i, 1, ContentBundle::GetInstance()->GetText("CmdMissionsDlg.training")); - } - else { - lst_missions->SetItemText(i, 1, m->TypeName()); - } - } - - char start_time[64]; - FormatDayTime(start_time, info->start); - lst_missions->SetItemText(i, 2, start_time); - } - } - - else if (missions.size() > 0 && lst_missions->NumItems() > 0) { - int id = lst_missions->GetItemData(0); - MissionInfo* info = campaign->GetMissionInfo(id); - - if (!info) { - int seln = -1; - int seln_id = 0; - - for (int i = 0; i < lst_missions->NumItems(); i++) - if (lst_missions->IsSelected(i)) - seln = i; - - if (seln >= 0) - seln_id = lst_missions->GetItemData(seln); - - lst_missions->ClearItems(); - seln = -1; - - for (int i = 0; i < missions.size(); i++) { - MissionInfo* info = missions[i]; - lst_missions->AddItemWithData(info->name, info->id); - - Mission* m = info->mission; - if (m) { - if (m->Type() == Mission::TRAINING && player->HasTrained(m->Identity())) { - lst_missions->SetItemText(i, 1, ContentBundle::GetInstance()->GetText("CmdMissionsDlg.training")); - } - else { - lst_missions->SetItemText(i, 1, m->TypeName()); - } - } - - char start_time[64]; - FormatDayTime(start_time, info->start); - lst_missions->SetItemText(i, 2, start_time); - - if (info->id == seln_id) - seln = i; - } - - if (seln >= 0) - lst_missions->SetSelected(seln); - } - } - - bool found = false; - - for (int i = 0; i < missions.size() && !found; i++) { - MissionInfo* info = missions[i]; - if (info->mission == mission) - found = true; - } - - if (!found) { - mission = 0; - txt_desc->SetText(""); - btn_accept->SetEnabled(false); - } - } -} - -// +--------------------------------------------------------------------+ - -void -CmdMissionsDlg::OnSave(AWEvent* event) -{ - CmdDlg::OnSave(event); -} - -void -CmdMissionsDlg::OnExit(AWEvent* event) -{ - CmdDlg::OnExit(event); -} - -void -CmdMissionsDlg::OnMode(AWEvent* event) -{ - CmdDlg::OnMode(event); -} - - -// +--------------------------------------------------------------------+ - -void -CmdMissionsDlg::OnMission(AWEvent* event) -{ - if (campaign && lst_missions) { - MissionInfo* info = 0; - mission = 0; - - for (int i = 0; i < lst_missions->NumItems(); i++) { - if (lst_missions->IsSelected(i)) { - int id = lst_missions->GetItemData(i); - info = campaign->GetMissionInfo(id); - } - } - - btn_accept->SetEnabled((info != 0) ? true : false); - - if (info) { - Text desc(""); - desc += info->name; - desc += "\n\n"; - desc += info->player_info; - desc += "\n\n"; - desc += info->description; - - txt_desc->SetText(desc); - mission = info->mission; - } - else { - txt_desc->SetText(" "); - } - } -} - -// +--------------------------------------------------------------------+ - -void -CmdMissionsDlg::OnAccept(AWEvent* event) -{ - if (!campaign || !mission) { - ::Print(" ERROR CMD::Accept campaign=0x%08x mission=0x%08x\n", campaign, mission); - return; - } - - ::Print(" CMD::Accept Mission %d\n", mission->Identity()); - - Mouse::Show(false); - campaign->SetMissionId(mission->Identity()); - campaign->StartMission(); - stars->SetGameMode(Starshatter::PREP_MODE); -} diff --git a/Stars45/CmdMissionsDlg.h b/Stars45/CmdMissionsDlg.h deleted file mode 100644 index 9098735..0000000 --- a/Stars45/CmdMissionsDlg.h +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Mission List Tab) -*/ - -#ifndef CmdMissionsDlg_h -#define CmdMissionsDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "CmdDlg.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Mission; - -// +--------------------------------------------------------------------+ - -class CmdMissionsDlg : public FormWindow, -public CmdDlg -{ -public: - CmdMissionsDlg(Screen* s, FormDef& def, CmpnScreen* mgr); - virtual ~CmdMissionsDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnMode(AWEvent* event); - virtual void OnSave(AWEvent* event); - virtual void OnExit(AWEvent* event); - virtual void OnMission(AWEvent* event); - virtual void OnAccept(AWEvent* event); - -protected: - CmpnScreen* manager; - - ListBox* lst_missions; - ActiveWindow* txt_desc; - Button* btn_accept; - - Starshatter* stars; - Campaign* campaign; - Mission* mission; -}; - -#endif // CmdMissionsDlg_h - diff --git a/Stars45/CmdMsgDlg.cpp b/Stars45/CmdMsgDlg.cpp deleted file mode 100644 index 0d0b0ba..0000000 --- a/Stars45/CmdMsgDlg.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "CmdMsgDlg.h" -#include "CmpnScreen.h" -#include "Starshatter.h" - -#include "Game.h" -#include "ListBox.h" -#include "ComboBox.h" -#include "Button.h" -#include "Keyboard.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CmdMsgDlg, OnApply); - -// +--------------------------------------------------------------------+ - -CmdMsgDlg::CmdMsgDlg(Screen* s, FormDef& def, CmpnScreen* mgr) - : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), - exit_latch(false) -{ - Init(def); -} - -CmdMsgDlg::~CmdMsgDlg() -{ -} - -void -CmdMsgDlg::RegisterControls() -{ - title = FindControl(100); - message = FindControl(101); - - apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, apply, CmdMsgDlg, OnApply); -} - -// +--------------------------------------------------------------------+ - -void -CmdMsgDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnApply(0); - } - - if (Keyboard::KeyDown(VK_ESCAPE)) { - if (!exit_latch) - OnApply(0); - - exit_latch = true; - } - else { - exit_latch = false; - } -} - -// +--------------------------------------------------------------------+ - -void -CmdMsgDlg::Show() -{ - FormWindow::Show(); - SetFocus(); -} - -// +--------------------------------------------------------------------+ - -void -CmdMsgDlg::OnApply(AWEvent* event) -{ - if (manager) - manager->CloseTopmost(); -} - -// +--------------------------------------------------------------------+ diff --git a/Stars45/CmdMsgDlg.h b/Stars45/CmdMsgDlg.h deleted file mode 100644 index cc9e466..0000000 --- a/Stars45/CmdMsgDlg.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Navigation Active Window class -*/ - -#ifndef CmdMsgDlg_h -#define CmdMsgDlg_h - -#include "Types.h" -#include "FormWindow.h" - -// +--------------------------------------------------------------------+ - -class CmpnScreen; - -// +--------------------------------------------------------------------+ - -class CmdMsgDlg : public FormWindow -{ -public: - CmdMsgDlg(Screen* s, FormDef& def, CmpnScreen* mgr); - virtual ~CmdMsgDlg(); - - virtual void RegisterControls(); - virtual void Show(); - - // Operations: - virtual void ExecFrame(); - virtual void OnApply(AWEvent* event); - - ActiveWindow* Title() { return title; } - ActiveWindow* Message() { return message; } - -protected: - CmpnScreen* manager; - - ActiveWindow* title; - ActiveWindow* message; - - Button* apply; - bool exit_latch; -}; - -#endif // CmdMsgDlg_h - diff --git a/Stars45/CmdOrdersDlg.cpp b/Stars45/CmdOrdersDlg.cpp deleted file mode 100644 index 7fd4183..0000000 --- a/Stars45/CmdOrdersDlg.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Campaign Orders Tab) -*/ - -#include "CmdOrdersDlg.h" -#include "CmdDlg.h" -#include "CmpnScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "ShipDesign.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CmdOrdersDlg, OnMode); -DEF_MAP_CLIENT(CmdOrdersDlg, OnSave); -DEF_MAP_CLIENT(CmdOrdersDlg, OnExit); - -// +--------------------------------------------------------------------+ - -CmdOrdersDlg::CmdOrdersDlg(Screen* s, FormDef& def, CmpnScreen* mgr) - : FormWindow(s, 0, 0, s->Width(), s->Height()), CmdDlg(mgr), manager(mgr), - lbl_orders(0), stars(0), campaign(0) -{ - stars = Starshatter::GetInstance(); - campaign = Campaign::GetCampaign(); - - Init(def); -} - -CmdOrdersDlg::~CmdOrdersDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -CmdOrdersDlg::RegisterControls() -{ - lbl_orders = FindControl(400); - - RegisterCmdControls(this); - - if (btn_save) - REGISTER_CLIENT(EID_CLICK, btn_save, CmdOrdersDlg, OnSave); - - if (btn_exit) - REGISTER_CLIENT(EID_CLICK, btn_exit, CmdOrdersDlg, OnExit); - - for (int i = 0; i < 5; i++) { - if (btn_mode[i]) - REGISTER_CLIENT(EID_CLICK, btn_mode[i], CmdOrdersDlg, OnMode); - } -} - -// +--------------------------------------------------------------------+ - -void -CmdOrdersDlg::Show() -{ - mode = MODE_ORDERS; - - FormWindow::Show(); - ShowCmdDlg(); - - campaign = Campaign::GetCampaign(); - - if (campaign && lbl_orders) { - Text orders(""); - orders += ContentBundle::GetInstance()->GetText("CmdOrdersDlg.situation"); - orders += "\n"; - if (*campaign->Situation()) - orders += campaign->Situation(); - else - orders += campaign->Description(); - - orders += "\n\n"; - orders += ContentBundle::GetInstance()->GetText("CmdOrdersDlg.orders"); - orders += "\n"; - orders += campaign->Orders(); - - lbl_orders->SetText(orders); - } -} - -// +--------------------------------------------------------------------+ - -void -CmdOrdersDlg::ExecFrame() -{ - CmdDlg::ExecFrame(); -} - -// +--------------------------------------------------------------------+ - -void -CmdOrdersDlg::OnSave(AWEvent* event) -{ - CmdDlg::OnSave(event); -} - -void -CmdOrdersDlg::OnExit(AWEvent* event) -{ - CmdDlg::OnExit(event); -} - -void -CmdOrdersDlg::OnMode(AWEvent* event) -{ - CmdDlg::OnMode(event); -} - diff --git a/Stars45/CmdOrdersDlg.h b/Stars45/CmdOrdersDlg.h deleted file mode 100644 index 7b7f55e..0000000 --- a/Stars45/CmdOrdersDlg.h +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Campaign Orders Tab) -*/ - -#ifndef CmdOrdersDlg_h -#define CmdOrdersDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "CmdDlg.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class CmdOrdersDlg : public FormWindow, -public CmdDlg -{ -public: - CmdOrdersDlg(Screen* s, FormDef& def, CmpnScreen* mgr); - virtual ~CmdOrdersDlg(); - - virtual void RegisterControls(); - virtual void ExecFrame(); - virtual void Show(); - - // Operations: - virtual void OnMode(AWEvent* event); - virtual void OnSave(AWEvent* event); - virtual void OnExit(AWEvent* event); - -protected: - CmpnScreen* manager; - - ActiveWindow* lbl_orders; - - Starshatter* stars; - Campaign* campaign; -}; - -#endif // CmdOrdersDlg_h - diff --git a/Stars45/CmdTheaterDlg.cpp b/Stars45/CmdTheaterDlg.cpp deleted file mode 100644 index b07fa70..0000000 --- a/Stars45/CmdTheaterDlg.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Theater Map Tab) -*/ - -#include "CmdTheaterDlg.h" -#include "CmdDlg.h" -#include "CmpnScreen.h" -#include "Galaxy.h" -#include "Starshatter.h" -#include "StarSystem.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "ShipDesign.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CmdTheaterDlg, OnMode); -DEF_MAP_CLIENT(CmdTheaterDlg, OnSave); -DEF_MAP_CLIENT(CmdTheaterDlg, OnExit); -DEF_MAP_CLIENT(CmdTheaterDlg, OnView); - -// Supported Selection Modes: - -const int SELECT_NONE = -1; -const int SELECT_SYSTEM = 0; -const int SELECT_PLANET = 1; -const int SELECT_REGION = 2; -const int SELECT_STATION = 3; -const int SELECT_STARSHIP = 4; -const int SELECT_FIGHTER = 5; - -const int VIEW_GALAXY = 0; -const int VIEW_SYSTEM = 1; -const int VIEW_REGION = 2; - -// +--------------------------------------------------------------------+ - -CmdTheaterDlg::CmdTheaterDlg(Screen* s, FormDef& def, CmpnScreen* mgr) - : FormWindow(s, 0, 0, s->Width(), s->Height()), CmdDlg(mgr), manager(mgr), - map_theater(0), map_view(0), stars(0), campaign(0) -{ - stars = Starshatter::GetInstance(); - campaign = Campaign::GetCampaign(); - - Init(def); -} - -CmdTheaterDlg::~CmdTheaterDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -CmdTheaterDlg::RegisterControls() -{ - map_theater = FindControl(400); - - RegisterCmdControls(this); - - if (btn_save) - REGISTER_CLIENT(EID_CLICK, btn_save, CmdTheaterDlg, OnSave); - - if (btn_exit) - REGISTER_CLIENT(EID_CLICK, btn_exit, CmdTheaterDlg, OnExit); - - for (int i = 0; i < 5; i++) { - if (btn_mode[i]) - REGISTER_CLIENT(EID_CLICK, btn_mode[i], CmdTheaterDlg, OnMode); - } - - if (map_theater) - map_view = new MapView(map_theater); - - for (int i = 0; i < 3; i++) { - view_btn[i] = (Button*) FindControl(401 + i); - REGISTER_CLIENT(EID_CLICK, view_btn[i], CmdTheaterDlg, OnView); - } - - zoom_in_btn = (Button*) FindControl(410); - zoom_out_btn = (Button*) FindControl(411); -} - -// +--------------------------------------------------------------------+ - -void -CmdTheaterDlg::Show() -{ - mode = MODE_THEATER; - - FormWindow::Show(); - ShowCmdDlg(); - - campaign = Campaign::GetCampaign(); - - if (campaign && map_theater) { - map_view->SetCampaign(campaign); - } -} - -// +--------------------------------------------------------------------+ - -void -CmdTheaterDlg::ExecFrame() -{ - CmdDlg::ExecFrame(); - - if (!map_view) - return; - - if (Keyboard::KeyDown(VK_ADD) || - (zoom_in_btn && zoom_in_btn->GetButtonState() > 0)) { - map_view->ZoomIn(); - } - else if (Keyboard::KeyDown(VK_SUBTRACT) || - (zoom_out_btn && zoom_out_btn->GetButtonState() > 0)) { - map_view->ZoomOut(); - } - - else if (Mouse::Wheel() > 0) { - map_view->ZoomIn(); - map_view->ZoomIn(); - map_view->ZoomIn(); - } - - else if (Mouse::Wheel() < 0) { - map_view->ZoomOut(); - map_view->ZoomOut(); - map_view->ZoomOut(); - } -} - -// +--------------------------------------------------------------------+ - -void -CmdTheaterDlg::OnSave(AWEvent* event) -{ - CmdDlg::OnSave(event); -} - -void -CmdTheaterDlg::OnExit(AWEvent* event) -{ - CmdDlg::OnExit(event); -} - -void -CmdTheaterDlg::OnMode(AWEvent* event) -{ - CmdDlg::OnMode(event); -} - -// +--------------------------------------------------------------------+ - -void -CmdTheaterDlg::OnView(AWEvent* event) -{ - int use_filter_mode = -1; - - view_btn[VIEW_GALAXY]->SetButtonState(0); - view_btn[VIEW_SYSTEM]->SetButtonState(0); - view_btn[VIEW_REGION]->SetButtonState(0); - - if (view_btn[0] == event->window) { - if (map_view) map_view->SetViewMode(VIEW_GALAXY); - view_btn[VIEW_GALAXY]->SetButtonState(1); - use_filter_mode = SELECT_SYSTEM; - } - - else if (view_btn[VIEW_SYSTEM] == event->window) { - if (map_view) map_view->SetViewMode(VIEW_SYSTEM); - view_btn[VIEW_SYSTEM]->SetButtonState(1); - use_filter_mode = SELECT_REGION; - } - - else if (view_btn[VIEW_REGION] == event->window) { - if (map_view) map_view->SetViewMode(VIEW_REGION); - view_btn[VIEW_REGION]->SetButtonState(1); - use_filter_mode = SELECT_STARSHIP; - } - - if (use_filter_mode >= 0) { - if (map_view) map_view->SetSelectionMode(use_filter_mode); - } -} - -// +--------------------------------------------------------------------+ - - - diff --git a/Stars45/CmdTheaterDlg.h b/Stars45/CmdTheaterDlg.h deleted file mode 100644 index 102db50..0000000 --- a/Stars45/CmdTheaterDlg.h +++ /dev/null @@ -1,61 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Order of Battle Tab) -*/ - -#ifndef CmdTheaterDlg_h -#define CmdTheaterDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "CmdDlg.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "MapView.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class CmdTheaterDlg : public FormWindow, -public CmdDlg -{ -public: - CmdTheaterDlg(Screen* s, FormDef& def, CmpnScreen* mgr); - virtual ~CmdTheaterDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnMode(AWEvent* event); - virtual void OnSave(AWEvent* event); - virtual void OnExit(AWEvent* event); - virtual void OnView(AWEvent* event); - -protected: - CmpnScreen* manager; - - ActiveWindow* map_theater; - MapView* map_view; - Button* view_btn[3]; - Button* zoom_in_btn; - Button* zoom_out_btn; - - Starshatter* stars; - Campaign* campaign; -}; - -#endif // CmdTheaterDlg_h - diff --git a/Stars45/CmdTitleDlg.cpp b/Stars45/CmdTitleDlg.cpp deleted file mode 100644 index dfc89ff..0000000 --- a/Stars45/CmdTitleDlg.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Operational Command Dialog (Intel/Newsfeed Tab) -*/ - -#include "CmdTitleDlg.h" -#include "CmpnScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatEvent.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "ShipDesign.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -// +--------------------------------------------------------------------+ - -CmdTitleDlg::CmdTitleDlg(Screen* s, FormDef& def, CmpnScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -stars(0), campaign(0), showTime(0) -{ - stars = Starshatter::GetInstance(); - campaign = Campaign::GetCampaign(); - - Init(def); -} - -CmdTitleDlg::~CmdTitleDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -CmdTitleDlg::RegisterControls() -{ - img_title = (ImageBox*) FindControl(200); -} - -// +--------------------------------------------------------------------+ - -void -CmdTitleDlg::Show() -{ - FormWindow::Show(); -} - -// +--------------------------------------------------------------------+ - -void -CmdTitleDlg::ExecFrame() -{ -} diff --git a/Stars45/CmdTitleDlg.h b/Stars45/CmdTitleDlg.h deleted file mode 100644 index 9bac729..0000000 --- a/Stars45/CmdTitleDlg.h +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Campaign Title Card -*/ - -#ifndef CmdTitleDlg_h -#define CmdTitleDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ImageBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class CmpnScreen; -class Campaign; -class Starshatter; - -// +--------------------------------------------------------------------+ - -class CmdTitleDlg : public FormWindow -{ -public: - CmdTitleDlg(Screen* s, FormDef& def, CmpnScreen* mgr); - virtual ~CmdTitleDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - -protected: - CmpnScreen* manager; - - ImageBox* img_title; - - Starshatter* stars; - Campaign* campaign; - double showTime; -}; - -#endif // CmdTitleDlg_h - diff --git a/Stars45/CmpCompleteDlg.cpp b/Stars45/CmpCompleteDlg.cpp deleted file mode 100644 index a80e460..0000000 --- a/Stars45/CmpCompleteDlg.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "CmpCompleteDlg.h" -#include "CmpnScreen.h" -#include "Campaign.h" -#include "CombatEvent.h" -#include "Starshatter.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ImageBox.h" -#include "Button.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CmpCompleteDlg, OnClose); - -// +--------------------------------------------------------------------+ - -CmpCompleteDlg::CmpCompleteDlg(Screen* s, FormDef& def, CmpnScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -lbl_info(0), img_title(0), btn_close(0) -{ - Init(def); -} - -CmpCompleteDlg::~CmpCompleteDlg() -{ -} - -void -CmpCompleteDlg::RegisterControls() -{ - img_title = (ImageBox*) FindControl(100); - lbl_info = FindControl(101); - btn_close = (Button*) FindControl(1); - - REGISTER_CLIENT(EID_CLICK, btn_close, CmpCompleteDlg, OnClose); -} - -void -CmpCompleteDlg::Show() -{ - FormWindow::Show(); - - Campaign* c = Campaign::GetCampaign(); - - if (img_title && c) { - DataLoader* loader = DataLoader::GetLoader(); - Starshatter* stars = Starshatter::GetInstance(); - CombatEvent* event = c->GetLastEvent(); - char img_name[256]; - - if (event) { - strcpy_s(img_name, event->ImageFile()); - - if (!strstr(img_name, ".pcx")) { - strcat_s(img_name, ".pcx"); - } - - if (loader) { - loader->SetDataPath(c->Path()); - loader->LoadBitmap(img_name, banner); - loader->SetDataPath(0); - - Rect tgt_rect; - tgt_rect.w = img_title->Width(); - tgt_rect.h = img_title->Height(); - - img_title->SetTargetRect(tgt_rect); - img_title->SetPicture(banner); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -CmpCompleteDlg::ExecFrame() -{ -} - -// +--------------------------------------------------------------------+ - -void -CmpCompleteDlg::OnClose(AWEvent* event) -{ - if (manager) - manager->ShowCmdDlg(); -} diff --git a/Stars45/CmpCompleteDlg.h b/Stars45/CmpCompleteDlg.h deleted file mode 100644 index 95cbc07..0000000 --- a/Stars45/CmpCompleteDlg.h +++ /dev/null @@ -1,49 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Campaign title card and load progress dialog -*/ - -#ifndef CmpCompleteDlg_h -#define CmpCompleteDlg_h - -#include "Types.h" -#include "FormWindow.h" - -// +--------------------------------------------------------------------+ - -class CmpnScreen; - -// +--------------------------------------------------------------------+ - -class CmpCompleteDlg : public FormWindow -{ -public: - CmpCompleteDlg(Screen* s, FormDef& def, CmpnScreen* mgr); - virtual ~CmpCompleteDlg(); - - virtual void RegisterControls(); - virtual void Show(); - - // Operations: - virtual void ExecFrame(); - virtual void OnClose(AWEvent* event); - -protected: - ImageBox* img_title; - ActiveWindow* lbl_info; - Button* btn_close; - Bitmap banner; - - CmpnScreen* manager; -}; - -#endif // CmpCompleteDlg_h - diff --git a/Stars45/CmpFileDlg.cpp b/Stars45/CmpFileDlg.cpp deleted file mode 100644 index 1f359e5..0000000 --- a/Stars45/CmpFileDlg.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Select Dialog Active Window class -*/ - -#include "CmpFileDlg.h" -#include "CmpnScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "CampaignSaveGame.h" -#include "CombatGroup.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "EditBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "FormatUtil.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CmpFileDlg, OnSave); -DEF_MAP_CLIENT(CmpFileDlg, OnCancel); -DEF_MAP_CLIENT(CmpFileDlg, OnCampaign); - -// +--------------------------------------------------------------------+ - -CmpFileDlg::CmpFileDlg(Screen* s, FormDef& def, CmpnScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -exit_latch(false), btn_save(0), btn_cancel(0), edt_name(0), lst_campaigns(0) -{ - Init(def); -} - -CmpFileDlg::~CmpFileDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -CmpFileDlg::RegisterControls() -{ - btn_save = (Button*) FindControl(1); - btn_cancel = (Button*) FindControl(2); - - if (btn_save) - REGISTER_CLIENT(EID_CLICK, btn_save, CmpFileDlg, OnSave); - - if (btn_cancel) - REGISTER_CLIENT(EID_CLICK, btn_cancel, CmpFileDlg, OnCancel); - - edt_name = (EditBox*) FindControl(200); - - if (edt_name) - edt_name->SetText(""); - - lst_campaigns = (ListBox*) FindControl(201); - - if (lst_campaigns) - REGISTER_CLIENT(EID_SELECT, lst_campaigns, CmpFileDlg, OnCampaign); -} - -// +--------------------------------------------------------------------+ - -void -CmpFileDlg::Show() -{ - FormWindow::Show(); - - if (lst_campaigns) { - lst_campaigns->ClearItems(); - lst_campaigns->SetLineHeight(12); - - List save_list; - - CampaignSaveGame::GetSaveGameList(save_list); - save_list.sort(); - - for (int i = 0; i < save_list.size(); i++) - lst_campaigns->AddItem(*save_list[i]); - - save_list.destroy(); - } - - if (edt_name) { - char save_name[256]; - save_name[0] = 0; - - campaign = Campaign::GetCampaign(); - if (campaign && campaign->GetPlayerGroup()) { - const char* op_name = campaign->Name(); - char day[32]; - CombatGroup* group = campaign->GetPlayerGroup(); - - if (strstr(op_name, "Operation ")) - op_name += 10; - - FormatDay(day, campaign->GetTime()); - - sprintf_s(save_name, "%s %s (%s)", - op_name, - day, - group->GetRegion().data()); - } - - edt_name->SetText(save_name); - edt_name->SetFocus(); - } -} - -// +--------------------------------------------------------------------+ - -void -CmpFileDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnSave(0); - } - - if (Keyboard::KeyDown(VK_ESCAPE)) { - if (!exit_latch) - OnCancel(0); - - exit_latch = true; - } - else { - exit_latch = false; - } -} - -// +--------------------------------------------------------------------+ - -void -CmpFileDlg::OnSave(AWEvent* event) -{ - if (edt_name && edt_name->GetText().length() > 0) { - campaign = Campaign::GetCampaign(); - CampaignSaveGame save(campaign); - - char filename[256]; - strcpy_s(filename, edt_name->GetText()); - char* newline = strchr(filename, '\n'); - if (newline) - *newline = 0; - - save.Save(filename); - save.SaveAuto(); - - if (manager) - manager->HideCmpFileDlg(); - } -} - -void -CmpFileDlg::OnCancel(AWEvent* event) -{ - if (manager) - manager->HideCmpFileDlg(); -} - -// +--------------------------------------------------------------------+ - -void -CmpFileDlg::OnCampaign(AWEvent* event) -{ - int n = lst_campaigns->GetSelection(); - - if (n >= 0) { - Text cmpn = lst_campaigns->GetItemText(n); - - if (edt_name) - edt_name->SetText(cmpn); - } -} \ No newline at end of file diff --git a/Stars45/CmpFileDlg.h b/Stars45/CmpFileDlg.h deleted file mode 100644 index f9f60fc..0000000 --- a/Stars45/CmpFileDlg.h +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Select Dialog Active Window class -*/ - -#ifndef CmpFileDlg_h -#define CmpFileDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class CmpnScreen; -class Campaign; -class Starshatter; - -// +--------------------------------------------------------------------+ - -class CmpFileDlg : public FormWindow -{ -public: - CmpFileDlg(Screen* s, FormDef& def, CmpnScreen* mgr); - virtual ~CmpFileDlg(); - - virtual void RegisterControls(); - virtual void Show(); - - // Operations: - virtual void ExecFrame(); - - virtual void OnSave(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnCampaign(AWEvent* event); - -protected: - CmpnScreen* manager; - Campaign* campaign; - - Button* btn_save; - Button* btn_cancel; - EditBox* edt_name; - ListBox* lst_campaigns; - - bool exit_latch; -}; - -#endif // CmpFileDlg_h - diff --git a/Stars45/CmpLoadDlg.cpp b/Stars45/CmpLoadDlg.cpp deleted file mode 100644 index 08fefd7..0000000 --- a/Stars45/CmpLoadDlg.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "CmpLoadDlg.h" -#include "Campaign.h" -#include "Starshatter.h" -#include "FormatUtil.h" - -#include "Clock.h" -#include "DataLoader.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ImageBox.h" -#include "Slider.h" - -// +--------------------------------------------------------------------+ - -CmpLoadDlg::CmpLoadDlg(Screen* s, FormDef& def) -: FormWindow(s, 0, 0, s->Width(), s->Height()), -lbl_progress(0), lbl_activity(0), lbl_title(0), img_title(0), show_time(0) -{ - Init(def); -} - -CmpLoadDlg::~CmpLoadDlg() -{ -} - -void -CmpLoadDlg::RegisterControls() -{ - img_title = (ImageBox*) FindControl(100); - lbl_title = FindControl(200); - lbl_activity = FindControl(101); - lbl_progress = (Slider*) FindControl(102); -} - -void -CmpLoadDlg::Show() -{ - FormWindow::Show(); - - Campaign* campaign = Campaign::GetCampaign(); - - if (campaign) { - Bitmap* bmp = campaign->GetImage(3); - if (img_title && bmp) { - Rect tgt_rect; - tgt_rect.w = img_title->Width(); - tgt_rect.h = img_title->Height(); - - img_title->SetTargetRect(tgt_rect); - img_title->SetPicture(*bmp); - } - - if (lbl_title) - lbl_title->SetText(campaign->Name()); - } - - show_time = Clock::GetInstance()->RealTime(); -} - -// +--------------------------------------------------------------------+ - -void -CmpLoadDlg::ExecFrame() -{ - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - if (lbl_activity) lbl_activity->SetText(stars->GetLoadActivity()); - if (lbl_progress) lbl_progress->SetValue(stars->GetLoadProgress()); - } -} - -// +--------------------------------------------------------------------+ - -void -CmpLoadDlg::MoveTo(const Rect& r) -{ - FormWindow::MoveTo(r); - - Campaign* campaign = Campaign::GetCampaign(); - - if (campaign && img_title && campaign->GetImage(3)) { - Bitmap* bmp = campaign->GetImage(3); - - Rect tgt_rect; - tgt_rect.w = img_title->Width(); - tgt_rect.h = img_title->Height(); - - img_title->SetTargetRect(tgt_rect); - img_title->SetPicture(*bmp); - } -} - -// +--------------------------------------------------------------------+ - -bool -CmpLoadDlg::IsDone() -{ - if (Clock::GetInstance()->RealTime() - show_time < 5000) - return false; - - return true; -} diff --git a/Stars45/CmpLoadDlg.h b/Stars45/CmpLoadDlg.h deleted file mode 100644 index 5357a46..0000000 --- a/Stars45/CmpLoadDlg.h +++ /dev/null @@ -1,45 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Campaign title card and load progress dialog -*/ - -#ifndef CmpLoadDlg_h -#define CmpLoadDlg_h - -#include "Types.h" -#include "FormWindow.h" - -// +--------------------------------------------------------------------+ - -class CmpLoadDlg : public FormWindow -{ -public: - CmpLoadDlg(Screen* s, FormDef& def); - virtual ~CmpLoadDlg(); - - // Operations: - virtual void ExecFrame(); - virtual void MoveTo(const Rect& r); - virtual void RegisterControls(); - virtual void Show(); - - virtual bool IsDone(); - -protected: - ActiveWindow* lbl_activity; - Slider* lbl_progress; - ActiveWindow* lbl_title; - ImageBox* img_title; - DWORD show_time; -}; - -#endif // CmpLoadDlg_h - diff --git a/Stars45/CmpSceneDlg.cpp b/Stars45/CmpSceneDlg.cpp deleted file mode 100644 index 4cedc21..0000000 --- a/Stars45/CmpSceneDlg.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "CmpSceneDlg.h" -#include "CmpnScreen.h" -#include "GameScreen.h" -#include "Campaign.h" -#include "CombatEvent.h" -#include "Starshatter.h" -#include "Sim.h" -#include "CameraDirector.h" -#include "Mission.h" -#include "MissionEvent.h" - -#include "Clock.h" -#include "DataLoader.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ImageBox.h" -#include "RichTextBox.h" -#include "Button.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -// +--------------------------------------------------------------------+ - -CmpSceneDlg::CmpSceneDlg(Screen* s, FormDef& def, CmpnScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -mov_scene(0), subtitles_box(0), cam_view(0), disp_view(0), old_disp_win(0), -flare1(0), flare2(0), flare3(0), flare4(0), subtitles_delay(0), subtitles_time(0) -{ - Init(def); - - DataLoader* loader = DataLoader::GetLoader(); - const char* oldpath = loader->GetDataPath(); - - loader->SetDataPath(0); - loader->LoadTexture("flare0+.pcx", flare1, Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("flare2.pcx", flare2, Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("flare3.pcx", flare3, Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("flare4.pcx", flare4, Bitmap::BMP_TRANSLUCENT); - loader->SetDataPath(oldpath); -} - -CmpSceneDlg::~CmpSceneDlg() -{ -} - -void -CmpSceneDlg::RegisterControls() -{ - mov_scene = FindControl(101); - subtitles_box = (RichTextBox*) FindControl(102); - - if (mov_scene) { - CameraDirector* cam_dir = CameraDirector::GetInstance(); - cam_view = new CameraView(mov_scene, cam_dir->GetCamera(), 0); - if (cam_view) - mov_scene->AddView(cam_view); - - disp_view = DisplayView::GetInstance(); - } -} - -void -CmpSceneDlg::Show() -{ - FormWindow::Show(); - - Starshatter* stars = Starshatter::GetInstance(); - - if (stars->InCutscene()) { - Sim* sim = Sim::GetSim(); - - if (sim) { - cam_view->UseCamera(CameraDirector::GetInstance()->GetCamera()); - cam_view->UseScene(sim->GetScene()); - } - - // initialize lens flare bitmaps: - if (stars->LensFlare()) { - cam_view->LensFlareElements(flare1, flare4, flare2, flare3); - cam_view->LensFlare(true); - } - - // if lens flare disabled, just create the corona: - else if (stars->Corona()) { - cam_view->LensFlareElements(flare1, 0, 0, 0); - cam_view->LensFlare(true); - } - - if (disp_view) { - old_disp_win = disp_view->GetWindow(); - - disp_view->SetWindow(mov_scene); - mov_scene->AddView(disp_view); - } - - if (subtitles_box) { - subtitles_box->SetText(stars->GetSubtitles()); - subtitles_delay = 0; - subtitles_time = 0; - } - } -} - -void -CmpSceneDlg::Hide() -{ - FormWindow::Hide(); - - if (disp_view && mov_scene && old_disp_win) { - mov_scene->DelView(disp_view); - disp_view->SetWindow(old_disp_win); - } -} - -// +--------------------------------------------------------------------+ - -CameraView* -CmpSceneDlg::GetCameraView() -{ - return cam_view; -} - -DisplayView* -CmpSceneDlg::GetDisplayView() -{ - return disp_view; -} - -// +--------------------------------------------------------------------+ - -void -CmpSceneDlg::ExecFrame() -{ - Starshatter* stars = Starshatter::GetInstance(); - Mission* cutscene_mission = stars->GetCutsceneMission(); - - if (cutscene_mission && disp_view) { - disp_view->ExecFrame(); - - if (subtitles_box && subtitles_box->GetLineCount() > 0) { - if (subtitles_delay == 0) { - int nlines = subtitles_box->GetLineCount(); - - MissionEvent* begin_scene = cutscene_mission->FindEvent(MissionEvent::BEGIN_SCENE); - MissionEvent* end_scene = cutscene_mission->FindEvent(MissionEvent::END_SCENE); - - if (begin_scene && end_scene) { - double total_time = end_scene->Time() - begin_scene->Time(); - subtitles_delay = total_time / nlines; - subtitles_time = Clock::GetInstance()->RealTime() / 1000.0 + subtitles_delay; - } - else { - subtitles_delay = -1; - } - } - - if (subtitles_delay > 0) { - double seconds = Clock::GetInstance()->RealTime() / 1000.0; - - if (subtitles_time <= seconds) { - subtitles_time = seconds + subtitles_delay; - subtitles_box->Scroll(ScrollWindow::SCROLL_DOWN); - } - } - } - } - else { - manager->ShowCmdDlg(); - } -} - diff --git a/Stars45/CmpSceneDlg.h b/Stars45/CmpSceneDlg.h deleted file mode 100644 index 70dd24d..0000000 --- a/Stars45/CmpSceneDlg.h +++ /dev/null @@ -1,67 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Campaign title card and load progress dialog -*/ - -#ifndef CmpSceneDlg_h -#define CmpSceneDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "CameraView.h" -#include "DisplayView.h" - -#include "ImageBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class CmpnScreen; - -// +--------------------------------------------------------------------+ - -class CmpSceneDlg : public FormWindow -{ -public: - CmpSceneDlg(Screen* s, FormDef& def, CmpnScreen* mgr); - virtual ~CmpSceneDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void Hide(); - - // Operations: - virtual void ExecFrame(); - - CameraView* GetCameraView(); - DisplayView* GetDisplayView(); - -protected: - ActiveWindow* mov_scene; - RichTextBox* subtitles_box; - CameraView* cam_view; - DisplayView* disp_view; - Window* old_disp_win; - - Bitmap* flare1; - Bitmap* flare2; - Bitmap* flare3; - Bitmap* flare4; - - CmpnScreen* manager; - - double subtitles_delay; - double subtitles_time; -}; - -#endif // CmpSceneDlg_h - diff --git a/Stars45/CmpSelectDlg.cpp b/Stars45/CmpSelectDlg.cpp deleted file mode 100644 index 95f9efa..0000000 --- a/Stars45/CmpSelectDlg.cpp +++ /dev/null @@ -1,609 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Select Dialog Active Window class -*/ - -#include - -#include "CmpSelectDlg.h" -#include "ConfirmDlg.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "CampaignSaveGame.h" -#include "CombatGroup.h" -#include "ShipDesign.h" -#include "Player.h" - -#include "Clock.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CmpSelectDlg, OnNew); -DEF_MAP_CLIENT(CmpSelectDlg, OnSaved); -DEF_MAP_CLIENT(CmpSelectDlg, OnDelete); -DEF_MAP_CLIENT(CmpSelectDlg, OnConfirmDelete); -DEF_MAP_CLIENT(CmpSelectDlg, OnAccept); -DEF_MAP_CLIENT(CmpSelectDlg, OnCancel); -DEF_MAP_CLIENT(CmpSelectDlg, OnCampaignSelect); - -// +--------------------------------------------------------------------+ - -CmpSelectDlg::CmpSelectDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -lst_campaigns(0), btn_new(0), btn_saved(0), btn_delete(0), -btn_accept(0), btn_cancel(0), description(0), stars(0), campaign(0), -selected_mission(-1), show_saved(false), loading(false), -loaded(false), hproc(0) -{ - stars = Starshatter::GetInstance(); - select_msg = ContentBundle::GetInstance()->GetText("CmpSelectDlg.select_msg"); - Init(def); -} - -CmpSelectDlg::~CmpSelectDlg() -{ - StopLoadProc(); - images.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -CmpSelectDlg::RegisterControls() -{ - btn_new = (Button*) FindControl(100); - btn_saved = (Button*) FindControl(101); - btn_delete = (Button*) FindControl(102); - btn_accept = (Button*) FindControl( 1); - btn_cancel = (Button*) FindControl( 2); - - if (btn_new) - REGISTER_CLIENT(EID_CLICK, btn_new, CmpSelectDlg, OnNew); - - if (btn_saved) - REGISTER_CLIENT(EID_CLICK, btn_saved, CmpSelectDlg, OnSaved); - - if (btn_delete) { - btn_delete->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_delete, CmpSelectDlg, OnDelete); - REGISTER_CLIENT(EID_USER_1, btn_delete, CmpSelectDlg, OnConfirmDelete); - } - - if (btn_accept) { - btn_accept->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_accept, CmpSelectDlg, OnAccept); - } - - if (btn_cancel) { - btn_cancel->SetEnabled(true); - REGISTER_CLIENT(EID_CLICK, btn_cancel, CmpSelectDlg, OnCancel); - } - - description = FindControl(200); - - lst_campaigns = (ListBox*) FindControl(201); - - if (lst_campaigns) - REGISTER_CLIENT(EID_SELECT, lst_campaigns, CmpSelectDlg, OnCampaignSelect); - - ShowNewCampaigns(); -} - -// +--------------------------------------------------------------------+ - -void -CmpSelectDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - if (btn_accept && btn_accept->IsEnabled()) - OnAccept(0); - } - - const std::lock_guard lock(sync); - - if (loaded) { - loaded = false; - - if (btn_cancel) - btn_cancel->SetEnabled(true); - - if (description && btn_accept) { - if (campaign) { - Campaign::SelectCampaign(campaign->Name()); - - if (load_index >= 0) { - if (lst_campaigns) { - images[load_index]->CopyBitmap(*campaign->GetImage(1)); - lst_campaigns->SetItemImage(load_index, images[load_index]); - } - - description->SetText(Text("") + - campaign->Name() + - Text("\n\n") + - Text("") + - ContentBundle::GetInstance()->GetText("CmpSelectDlg.scenario") + - Text("\n\t") + - campaign->Description()); - } - else { - char time_buf[32]; - char score_buf[32]; - - double t = campaign->GetLoadTime() - campaign->GetStartTime(); - FormatDayTime(time_buf, t); - - sprintf_s(score_buf, "%d", campaign->GetPlayerTeamScore()); - - Text desc = Text("") + - campaign->Name() + - Text("\n\n") + - Text("") + - ContentBundle::GetInstance()->GetText("CmpSelectDlg.scenario") + - Text("\n\t") + - campaign->Description() + - Text("\n\n") + - ContentBundle::GetInstance()->GetText("CmpSelectDlg.campaign-time") + - Text("\n\t") + - time_buf + - Text("\n\n") + - ContentBundle::GetInstance()->GetText("CmpSelectDlg.assignment") + - Text("\n\t"); - - if (campaign->GetPlayerGroup()) - desc += campaign->GetPlayerGroup()->GetDescription(); - else - desc += "n/a"; - - desc += Text("\n\n") + - ContentBundle::GetInstance()->GetText("CmpSelectDlg.team-score") + - Text("\n\t") + - score_buf; - - description->SetText(desc); - } - - btn_accept->SetEnabled(true); - - if (btn_delete) - btn_delete->SetEnabled(show_saved); - } - else { - description->SetText(select_msg); - btn_accept->SetEnabled(true); - } - } - } -} - -bool -CmpSelectDlg::CanClose() -{ - const std::lock_guard lock(sync); - return !loading; -} - -// +--------------------------------------------------------------------+ - -void -CmpSelectDlg::ShowNewCampaigns() -{ - const std::lock_guard lock(sync); - - if (loading && description) { - description->SetText(ContentBundle::GetInstance()->GetText("CmpSelectDlg.already-loading")); - Button::PlaySound(Button::SND_REJECT); - return; - } - - if (btn_new) - btn_new->SetButtonState(1); - - if (btn_saved) - btn_saved->SetButtonState(0); - - if (btn_delete) - btn_delete->SetEnabled(false); - - if (lst_campaigns) { - images.destroy(); - - lst_campaigns->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_PLAIN); - lst_campaigns->SetLeading(0); - lst_campaigns->ClearItems(); - lst_campaigns->SetLineHeight(100); - - Player* player = Player::GetCurrentPlayer(); - if (!player) return; - - ListIter iter = Campaign::GetAllCampaigns(); - while (++iter) { - Campaign* c = iter.value(); - - if (c->GetCampaignId() < Campaign::SINGLE_MISSIONS) { - Bitmap* bmp = new Bitmap; - bmp->CopyBitmap(*c->GetImage(0)); - images.append(bmp); - - int n = lst_campaigns->AddImage(bmp) - 1; - lst_campaigns->SetItemText(n, c->Name()); - - // if campaign is not available, show the grayed-out image - - // FULL GAME CRITERIA (based on player record): - if (c->GetCampaignId() > 2 && c->GetCampaignId() < 10 && - !player->HasCompletedCampaign(c->GetCampaignId()-1)) { - images[n]->CopyBitmap(*c->GetImage(2)); - lst_campaigns->SetItemImage(n, images[n]); - } - - // Two additional sequences of ten campaigns (10-19 and 20-29) - // for mod authors to use: - else if (c->GetCampaignId() >= 10 && c->GetCampaignId() < 30 && - (c->GetCampaignId() % 10) != 0 && - !player->HasCompletedCampaign(c->GetCampaignId()-1)) { - images[n]->CopyBitmap(*c->GetImage(2)); - lst_campaigns->SetItemImage(n, images[n]); - } - - // NOTE: Campaigns 10, 20, and 30-99 are always enabled if they exist! - } - } - } - - if (description) - description->SetText(select_msg); - - if (btn_accept) - btn_accept->SetEnabled(false); - - show_saved = false; -} - -// +--------------------------------------------------------------------+ - -void -CmpSelectDlg::ShowSavedCampaigns() -{ - const std::lock_guard lock(sync); - - if (loading && description) { - description->SetText(ContentBundle::GetInstance()->GetText("CmpSelectDlg.already-loading")); - Button::PlaySound(Button::SND_REJECT); - return; - } - - if (btn_new) - btn_new->SetButtonState(0); - - if (btn_saved) - btn_saved->SetButtonState(1); - - if (btn_delete) - btn_delete->SetEnabled(false); - - if (lst_campaigns) { - lst_campaigns->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - lst_campaigns->SetLeading(4); - lst_campaigns->ClearItems(); - lst_campaigns->SetLineHeight(12); - - List save_list; - - CampaignSaveGame::GetSaveGameList(save_list); - save_list.sort(); - - for (int i = 0; i < save_list.size(); i++) - lst_campaigns->AddItem(*save_list[i]); - - save_list.destroy(); - } - - if (description) - description->SetText(select_msg); - - if (btn_accept) - btn_accept->SetEnabled(false); - - show_saved = true; -} - -// +--------------------------------------------------------------------+ - -void -CmpSelectDlg::OnCampaignSelect(AWEvent* event) -{ - if (description && lst_campaigns) { - const std::lock_guard lock(sync); - - if (loading) { - description->SetText(ContentBundle::GetInstance()->GetText("CmpSelectDlg.already-loading")); - Button::PlaySound(Button::SND_REJECT); - return; - } - - load_index = -1; - load_file = ""; - - Player* player = Player::GetCurrentPlayer(); - if (!player) return; - - // NEW CAMPAIGN: - if (btn_new && btn_new->GetButtonState()) { - List& list = Campaign::GetAllCampaigns(); - - for (int i = 0; i < lst_campaigns->NumItems(); i++) { - Campaign* c = list[i]; - - // is campaign available? - // FULL GAME CRITERIA (based on player record): - if (c->GetCampaignId() <= 2 || - player->HasCompletedCampaign(c->GetCampaignId()-1)) - { - - if (lst_campaigns->IsSelected(i)) { - images[i]->CopyBitmap(*c->GetImage(1)); - lst_campaigns->SetItemImage(i, images[i]); - - const std::lock_guard lock(sync); - load_index = i; - } - else { - images[i]->CopyBitmap(*c->GetImage(0)); - lst_campaigns->SetItemImage(i, images[i]); - } - } - - // if not, then don't select - else { - images[i]->CopyBitmap(*c->GetImage(2)); - lst_campaigns->SetItemImage(i, images[i]); - - if (lst_campaigns->IsSelected(i)) { - description->SetText(select_msg); - } - } - } - } - - // SAVED CAMPAIGN: - else { - int seln = lst_campaigns->GetSelection(); - - if (seln < 0) { - description->SetText(select_msg); - } - - else { - load_index = -1; - load_file = lst_campaigns->GetItemText(seln); - } - } - - if (btn_accept) - btn_accept->SetEnabled(false); - } - - if (!loading && (load_index >= 0 || load_file.length() > 0)) { - if (btn_cancel) - btn_cancel->SetEnabled(false); - - StartLoadProc(); - } -} - -// +--------------------------------------------------------------------+ - -void -CmpSelectDlg::Show() -{ - FormWindow::Show(); - ShowNewCampaigns(); -} - -// +--------------------------------------------------------------------+ - -void -CmpSelectDlg::OnNew(AWEvent* event) -{ - ShowNewCampaigns(); -} - -void -CmpSelectDlg::OnSaved(AWEvent* event) -{ - ShowSavedCampaigns(); -} - -void -CmpSelectDlg::OnDelete(AWEvent* event) -{ - load_file = ""; - - if (lst_campaigns) { - int seln = lst_campaigns->GetSelection(); - - if (seln < 0) { - description->SetText(select_msg); - btn_accept->SetEnabled(false); - } - - else { - load_index = -1; - load_file = lst_campaigns->GetItemText(seln); - } - } - - if (load_file.length()) { - ConfirmDlg* confirm = manager->GetConfirmDlg(); - if (confirm) { - char msg[256]; - sprintf_s(msg, ContentBundle::GetInstance()->GetText("CmpSelectDlg.are-you-sure"), load_file.data()); - confirm->SetMessage(msg); - confirm->SetTitle(ContentBundle::GetInstance()->GetText("CmpSelectDlg.confirm")); - - manager->ShowConfirmDlg(); - } - - else { - OnConfirmDelete(event); - } - } - - ShowSavedCampaigns(); -} - -void -CmpSelectDlg::OnConfirmDelete(AWEvent* event) -{ - if (load_file.length()) { - CampaignSaveGame::Delete(load_file); - } - - ShowSavedCampaigns(); -} - -// +--------------------------------------------------------------------+ - -void -CmpSelectDlg::OnAccept(AWEvent* event) -{ - const std::lock_guard lock(sync); - - if (loading) - return; - - // if this is to be a new campaign, - // re-instaniate the campaign object - if (btn_new->GetButtonState()) - Campaign::GetCampaign()->Load(); - else - Clock::GetInstance()->ResetGameTime(); - - Mouse::Show(false); - stars->SetGameMode(Starshatter::CLOD_MODE); -} - -void -CmpSelectDlg::OnCancel(AWEvent* event) -{ - manager->ShowMenuDlg(); -} - -// +--------------------------------------------------------------------+ - -DWORD WINAPI CmpSelectDlgLoadProc(LPVOID link); - -void -CmpSelectDlg::StartLoadProc() -{ - if (hproc != 0) { - DWORD result = 0; - GetExitCodeThread(hproc, &result); - - if (result != STILL_ACTIVE) { - CloseHandle(hproc); - hproc = 0; - } - else { - return; - } - } - - if (hproc == 0) { - campaign = 0; - loading = true; - loaded = false; - - if (description) - description->SetText(ContentBundle::GetInstance()->GetText("CmpSelectDlg.loading")); - - DWORD thread_id = 0; - hproc = CreateThread(0, 4096, CmpSelectDlgLoadProc, (LPVOID) this, 0, &thread_id); - - if (hproc == 0) { - static int report = 10; - if (report > 0) { - ::Print("WARNING: CmpSelectDlg() failed to create thread (err=%08x)\n", GetLastError()); - report--; - - if (report == 0) - ::Print(" Further warnings of this type will be supressed.\n"); - } - } - } -} - -void -CmpSelectDlg::StopLoadProc() -{ - if (hproc != 0) { - WaitForSingleObject(hproc, 2500); - CloseHandle(hproc); - hproc = 0; - } -} - -DWORD WINAPI CmpSelectDlgLoadProc(LPVOID link) -{ - CmpSelectDlg* dlg = (CmpSelectDlg*) link; - - if (dlg) - return dlg->LoadProc(); - - return (DWORD) E_POINTER; -} - -DWORD -CmpSelectDlg::LoadProc() -{ - Campaign* c = 0; - - // NEW CAMPAIGN: - if (load_index >= 0) { - List& list = Campaign::GetAllCampaigns(); - - if (load_index < list.size()) { - c = list[load_index]; - c->Load(); - } - } - - // SAVED CAMPAIGN: - else { - CampaignSaveGame savegame; - savegame.Load(load_file); - c = savegame.GetCampaign(); - } - - sync.lock(); - - loading = false; - loaded = true; - campaign = c; - - sync.unlock(); - - return 0; -} - -// +--------------------------------------------------------------------+ diff --git a/Stars45/CmpSelectDlg.h b/Stars45/CmpSelectDlg.h deleted file mode 100644 index 093e21d..0000000 --- a/Stars45/CmpSelectDlg.h +++ /dev/null @@ -1,92 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Select Dialog Active Window class -*/ - -#ifndef CmpSelectDlg_h -#define CmpSelectDlg_h - -#include - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class Campaign; -class Starshatter; - -// +--------------------------------------------------------------------+ - -class CmpSelectDlg : public FormWindow -{ -public: - CmpSelectDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~CmpSelectDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - virtual bool CanClose(); - - // Operations: - virtual void OnCampaignSelect(AWEvent* event); - virtual void OnNew(AWEvent* event); - virtual void OnSaved(AWEvent* event); - virtual void OnDelete(AWEvent* event); - virtual void OnConfirmDelete(AWEvent* event); - virtual void OnAccept(AWEvent* event); - virtual void OnCancel(AWEvent* event); - - virtual DWORD LoadProc(); - -protected: - virtual void StartLoadProc(); - virtual void StopLoadProc(); - virtual void ShowNewCampaigns(); - virtual void ShowSavedCampaigns(); - - MenuScreen* manager; - - Button* btn_new; - Button* btn_saved; - Button* btn_delete; - Button* btn_accept; - Button* btn_cancel; - - ListBox* lst_campaigns; - - ActiveWindow* description; - - Starshatter* stars; - Campaign* campaign; - int selected_mission; - HANDLE hproc; - std::mutex sync; - bool loading; - bool loaded; - Text load_file; - int load_index; - bool show_saved; - List images; - - Text select_msg; -}; - -#endif // CmpSelectDlg_h - diff --git a/Stars45/CmpnScreen.cpp b/Stars45/CmpnScreen.cpp deleted file mode 100644 index 970eaf9..0000000 --- a/Stars45/CmpnScreen.cpp +++ /dev/null @@ -1,636 +0,0 @@ -/* 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 "CmpnScreen.h" - -#include "CmdForceDlg.h" -#include "CmdMissionsDlg.h" -#include "CmdOrdersDlg.h" -#include "CmdTheaterDlg.h" -#include "CmdIntelDlg.h" -#include "CmpCompleteDlg.h" -#include "CmdMsgDlg.h" -#include "CmpFileDlg.h" -#include "CmpSceneDlg.h" -#include "Campaign.h" -#include "CombatEvent.h" -#include "Mission.h" -#include "Sim.h" -#include "Starshatter.h" -#include "StarSystem.h" -#include "Player.h" -#include "MusicDirector.h" - -#include "GameWinDX9.h" -#include "ContentBundle.h" -#include "Video.h" -#include "Screen.h" -#include "Window.h" -#include "ActiveWindow.h" -#include "FormDef.h" -#include "Mouse.h" -#include "Color.h" -#include "Bitmap.h" -#include "Font.h" -#include "FontMgr.h" -#include "EventDispatch.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -CmpnScreen::CmpnScreen() -: screen(0), -cmd_force_dlg(0), cmd_missions_dlg(0), cmd_orders_dlg(0), -cmd_intel_dlg(0), cmd_theater_dlg(0), cmd_msg_dlg(0), cmp_file_dlg(0), -cmp_end_dlg(0), cmp_scene_dlg(0), -isShown(false), campaign(0), stars(0), completion_stage(0) -{ - loader = DataLoader::GetLoader(); - stars = Starshatter::GetInstance(); -} - -CmpnScreen::~CmpnScreen() -{ - TearDown(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::Setup(Screen* s) -{ - if (!s) - return; - - screen = s; - - loader->UseFileSystem(true); - - FormDef cmd_orders_def("CmdOrdersDlg", 0); - cmd_orders_def.Load("CmdOrdersDlg"); - cmd_orders_dlg = new CmdOrdersDlg(screen, cmd_orders_def, this); - - FormDef cmd_force_def("CmdForceDlg", 0); - cmd_force_def.Load("CmdForceDlg"); - cmd_force_dlg = new CmdForceDlg(screen, cmd_force_def, this); - - FormDef cmd_theater_def("CmdTheaterDlg", 0); - cmd_theater_def.Load("CmdTheaterDlg"); - cmd_theater_dlg = new CmdTheaterDlg(screen, cmd_theater_def, this); - - FormDef cmd_intel_def("CmdIntelDlg", 0); - cmd_intel_def.Load("CmdIntelDlg"); - cmd_intel_dlg = new CmdIntelDlg(screen, cmd_intel_def, this); - - FormDef cmd_missions_def("CmdMissionsDlg", 0); - cmd_missions_def.Load("CmdMissionsDlg"); - cmd_missions_dlg = new CmdMissionsDlg(screen, cmd_missions_def, this); - - FormDef file_def("FileDlg", 0); - file_def.Load("FileDlg"); - cmp_file_dlg = new CmpFileDlg(screen, file_def, this); - - FormDef msg_def("CmdMsgDlg", 0); - msg_def.Load("CmdMsgDlg"); - cmd_msg_dlg = new CmdMsgDlg(screen, msg_def, this); - - FormDef end_def("CmpCompleteDlg", 0); - end_def.Load("CmpCompleteDlg"); - cmp_end_dlg = new CmpCompleteDlg(screen, end_def, this); - - FormDef scene_def("CmpSceneDlg", 0); - scene_def.Load("CmpSceneDlg"); - cmp_scene_dlg = new CmpSceneDlg(screen, scene_def, this); - - loader->UseFileSystem(Starshatter::UseFileSystem()); - - HideAll(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::TearDown() -{ - if (screen) { - screen->DelWindow(cmd_force_dlg); - screen->DelWindow(cmd_missions_dlg); - screen->DelWindow(cmd_orders_dlg); - screen->DelWindow(cmd_intel_dlg); - screen->DelWindow(cmd_theater_dlg); - screen->DelWindow(cmd_msg_dlg); - screen->DelWindow(cmp_file_dlg); - screen->DelWindow(cmp_end_dlg); - screen->DelWindow(cmp_scene_dlg); - } - - delete cmd_force_dlg; - delete cmd_missions_dlg; - delete cmd_orders_dlg; - delete cmd_intel_dlg; - delete cmd_theater_dlg; - delete cmd_msg_dlg; - delete cmp_file_dlg; - delete cmp_end_dlg; - delete cmp_scene_dlg; - - cmd_force_dlg = 0; - cmd_missions_dlg = 0; - cmd_orders_dlg = 0; - cmd_intel_dlg = 0; - cmd_theater_dlg = 0; - cmd_msg_dlg = 0; - cmp_file_dlg = 0; - cmp_end_dlg = 0; - cmp_scene_dlg = 0; - screen = 0; -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::SetFieldOfView(double fov) -{ - if (cmp_scene_dlg) - cmp_scene_dlg->GetCameraView()->SetFieldOfView(fov); -} - -// +--------------------------------------------------------------------+ - -double -CmpnScreen::GetFieldOfView() const -{ - if (cmp_scene_dlg) - return cmp_scene_dlg->GetCameraView()->GetFieldOfView(); - - return 2; -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ExecFrame() -{ - GameWinDX9::GetInstance()->SetScreenColor(Color::Black); - - if (cmd_orders_dlg && cmd_orders_dlg->IsShown()) { - cmd_orders_dlg->ExecFrame(); - } - - else if (cmd_force_dlg && cmd_force_dlg->IsShown()) { - cmd_force_dlg->ExecFrame(); - } - - else if (cmd_theater_dlg && cmd_theater_dlg->IsShown()) { - cmd_theater_dlg->ExecFrame(); - } - - else if (cmd_missions_dlg && cmd_missions_dlg->IsShown()) { - cmd_missions_dlg->ExecFrame(); - } - - else if (cmd_intel_dlg && cmd_intel_dlg->IsShown()) { - cmd_intel_dlg->ExecFrame(); - } - - if (cmp_file_dlg && cmp_file_dlg->IsShown()) { - cmp_file_dlg->ExecFrame(); - } - - if (cmd_msg_dlg && cmd_msg_dlg->IsShown()) { - cmd_msg_dlg->ExecFrame(); - } - - else if (cmp_end_dlg && cmp_end_dlg->IsShown()) { - cmp_end_dlg->ExecFrame(); - completion_stage = 2; - } - - else if (cmp_scene_dlg && cmp_scene_dlg->IsShown()) { - cmp_scene_dlg->ExecFrame(); - - if (completion_stage > 0) - completion_stage = 2; - } - - else if (campaign) { - // if campaign is complete - if (completion_stage == 0) { - Player* player = Player::GetCurrentPlayer(); - char msg_info[1024]; - - if (!player) - return; - - if (campaign->IsTraining()) { - int all_missions = (1<GetMissionList().size())-1; - - if (player->Trained() >= all_missions && player->Trained() < 255) { - player->SetTrained(255); - cmd_msg_dlg->Title()->SetText(ContentBundle::GetInstance()->GetText("CmpnScreen.training")); - sprintf_s(msg_info, ContentBundle::GetInstance()->GetText("CmpnScreen.congrats"), - Player::RankName(player->Rank()), - player->Name().data()); - - cmd_msg_dlg->Message()->SetText(msg_info); - cmd_msg_dlg->Message()->SetTextAlign(DT_LEFT); - - ShowCmdMsgDlg(); - completion_stage = 1; - } - } - - else if (campaign->IsComplete() || campaign->IsFailed()) { - bool cutscene = false; - CombatEvent* event = campaign->GetLastEvent(); - - if (event && !event->Visited() && event->SceneFile() && *event->SceneFile()) { - stars->ExecCutscene(event->SceneFile(), campaign->Path()); - - if (stars->InCutscene()) { - cutscene = true; - ShowCmpSceneDlg(); - } - } - - if (!cutscene) { - ShowCmpCompleteDlg(); - } - - if (campaign->IsComplete()) - MusicDirector::SetMode(MusicDirector::VICTORY); - else - MusicDirector::SetMode(MusicDirector::DEFEAT); - - completion_stage = 1; - } - } - - // if message has been shown, restart - else if (completion_stage > 1) { - completion_stage = 0; - - if (campaign->IsTraining()) { - List& list = Campaign::GetAllCampaigns(); - Campaign* c = list[1]; - - if (c) { - c->Load(); - Campaign::SelectCampaign(c->Name()); - stars->SetGameMode(Starshatter::CLOD_MODE); - return; - } - } - - // continue on to the next available campaign: - if (campaign->GetCampaignId() < Campaign::GetLastCampaignId()) { - stars->StartOrResumeGame(); - } - - // if this was the last campaign, just go back to the menu: - else { - Mouse::Show(false); - MusicDirector::SetMode(MusicDirector::MENU); - stars->SetGameMode(Starshatter::MENU_MODE); - return; - } - } - } - - if (completion_stage < 1) { - MusicDirector::SetMode(MusicDirector::MENU); - Mouse::Show(!IsCmpSceneShown()); - } -} - -// +--------------------------------------------------------------------+ - -bool -CmpnScreen::CloseTopmost() -{ - bool processed = false; - - if (IsCmdMsgShown()) { - HideCmdMsgDlg(); - processed = true; - } - - else if (IsCmpFileShown()) { - HideCmpFileDlg(); - processed = true; - } - - return processed; -} - -void -CmpnScreen::Show() -{ - if (!isShown) { - isShown = true; - - campaign = Campaign::GetCampaign(); - completion_stage = 0; - - bool cutscene = false; - CombatEvent* event = 0; - - if (campaign->IsActive() && !campaign->GetEvents().isEmpty()) { - ListIter iter = campaign->GetEvents(); - while (++iter) { - event = iter.value(); - - if (event && !event->Visited() && event->SceneFile() && *event->SceneFile()) { - stars->ExecCutscene(event->SceneFile(), campaign->Path()); - - if (stars->InCutscene()) { - cutscene = true; - ShowCmpSceneDlg(); - } - - event->SetVisited(true); - break; - } - } - } - - if (!cutscene) - ShowCmdDlg(); - } -} - -void -CmpnScreen::Hide() -{ - if (isShown) { - HideAll(); - isShown = false; - } -} - -void -CmpnScreen::HideAll() -{ - if (cmd_force_dlg) cmd_force_dlg->Hide(); - if (cmd_missions_dlg) cmd_missions_dlg->Hide(); - if (cmd_orders_dlg) cmd_orders_dlg->Hide(); - if (cmd_intel_dlg) cmd_intel_dlg->Hide(); - if (cmd_theater_dlg) cmd_theater_dlg->Hide(); - if (cmd_msg_dlg) cmd_msg_dlg->Hide(); - if (cmp_file_dlg) cmp_file_dlg->Hide(); - if (cmp_end_dlg) cmp_end_dlg->Hide(); - if (cmp_scene_dlg) cmp_scene_dlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ShowCmdDlg() -{ - ShowCmdOrdersDlg(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ShowCmdForceDlg() -{ - HideAll(); - cmd_force_dlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::HideCmdForceDlg() -{ - if (IsCmdForceShown()) - cmd_force_dlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -bool -CmpnScreen::IsCmdForceShown() -{ - return cmd_force_dlg && cmd_force_dlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ShowCmdOrdersDlg() -{ - HideAll(); - cmd_orders_dlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::HideCmdOrdersDlg() -{ - if (IsCmdOrdersShown()) - cmd_orders_dlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -bool -CmpnScreen::IsCmdOrdersShown() -{ - return cmd_orders_dlg && cmd_orders_dlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ShowCmdMissionsDlg() -{ - HideAll(); - cmd_missions_dlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::HideCmdMissionsDlg() -{ - if (IsCmdMissionsShown()) - cmd_missions_dlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -bool -CmpnScreen::IsCmdMissionsShown() -{ - return cmd_missions_dlg && cmd_missions_dlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ShowCmdIntelDlg() -{ - HideAll(); - cmd_intel_dlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::HideCmdIntelDlg() -{ - if (IsCmdIntelShown()) - cmd_intel_dlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -bool -CmpnScreen::IsCmdIntelShown() -{ - return cmd_intel_dlg && cmd_intel_dlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ShowCmdTheaterDlg() -{ - HideAll(); - cmd_theater_dlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::HideCmdTheaterDlg() -{ - if (IsCmdTheaterShown()) - cmd_theater_dlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -bool -CmpnScreen::IsCmdTheaterShown() -{ - return cmd_theater_dlg && cmd_theater_dlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ShowCmpFileDlg() -{ - cmp_file_dlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::HideCmpFileDlg() -{ - if (IsCmpFileShown()) - cmp_file_dlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -bool -CmpnScreen::IsCmpFileShown() -{ - return cmp_file_dlg && cmp_file_dlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ShowCmdMsgDlg() -{ - cmd_msg_dlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::HideCmdMsgDlg() -{ - if (IsCmdMsgShown()) - cmd_msg_dlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -bool -CmpnScreen::IsCmdMsgShown() -{ - return cmd_msg_dlg && cmd_msg_dlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ShowCmpCompleteDlg() -{ - cmp_end_dlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::HideCmpCompleteDlg() -{ - if (IsCmpCompleteShown()) - cmp_end_dlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -bool -CmpnScreen::IsCmpCompleteShown() -{ - return cmp_end_dlg && cmp_end_dlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::ShowCmpSceneDlg() -{ - cmp_scene_dlg->Show(); - Mouse::Show(false); -} - -// +--------------------------------------------------------------------+ - -void -CmpnScreen::HideCmpSceneDlg() -{ - if (IsCmpSceneShown()) - cmp_scene_dlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -bool -CmpnScreen::IsCmpSceneShown() -{ - return cmp_scene_dlg && cmp_scene_dlg->IsShown(); -} diff --git a/Stars45/CmpnScreen.h b/Stars45/CmpnScreen.h deleted file mode 100644 index 443de9e..0000000 --- a/Stars45/CmpnScreen.h +++ /dev/null @@ -1,136 +0,0 @@ -/* 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 - -*/ - -#ifndef CmpnScreen_h -#define CmpnScreen_h - -#include "Types.h" -#include "Bitmap.h" -#include "Screen.h" -#include "BaseScreen.h" - -// +--------------------------------------------------------------------+ - -class CmdForceDlg; -class CmdMissionsDlg; -class CmdOrdersDlg; -class CmdIntelDlg; -class CmdTheaterDlg; - -class CmdMsgDlg; -class CmpFileDlg; -class CmpCompleteDlg; -class CmpSceneDlg; - -class Campaign; -class Starshatter; - -class Bitmap; -class DataLoader; -class Font; -class FormEx; -class Screen; -class Video; - -// +--------------------------------------------------------------------+ - -class CmpnScreen -{ -public: - CmpnScreen(); - virtual ~CmpnScreen(); - - virtual void Setup(Screen* screen); - virtual void TearDown(); - virtual bool CloseTopmost(); - - virtual bool IsShown() const { return isShown; } - virtual void Show(); - virtual void Hide(); - - virtual void ShowCmdDlg(); - - virtual void ShowCmdForceDlg(); - virtual void HideCmdForceDlg(); - virtual bool IsCmdForceShown(); - virtual CmdForceDlg* GetCmdForceDlg() { return cmd_force_dlg; } - - virtual void ShowCmdMissionsDlg(); - virtual void HideCmdMissionsDlg(); - virtual bool IsCmdMissionsShown(); - virtual CmdMissionsDlg* GetCmdMissionsDlg() { return cmd_missions_dlg; } - - virtual void ShowCmdOrdersDlg(); - virtual void HideCmdOrdersDlg(); - virtual bool IsCmdOrdersShown(); - virtual CmdOrdersDlg* GetCmdOrdersDlg() { return cmd_orders_dlg; } - - virtual void ShowCmdIntelDlg(); - virtual void HideCmdIntelDlg(); - virtual bool IsCmdIntelShown(); - virtual CmdIntelDlg* GetCmdIntelDlg() { return cmd_intel_dlg; } - - virtual void ShowCmdTheaterDlg(); - virtual void HideCmdTheaterDlg(); - virtual bool IsCmdTheaterShown(); - virtual CmdTheaterDlg* GetCmdTheaterDlg() { return cmd_theater_dlg; } - - virtual void ShowCmpFileDlg(); - virtual void HideCmpFileDlg(); - virtual bool IsCmpFileShown(); - virtual CmpFileDlg* GetCmpFileDlg() { return cmp_file_dlg; } - - virtual void ShowCmdMsgDlg(); - virtual void HideCmdMsgDlg(); - virtual bool IsCmdMsgShown(); - virtual CmdMsgDlg* GetCmdMsgDlg() { return cmd_msg_dlg; } - - virtual void ShowCmpCompleteDlg(); - virtual void HideCmpCompleteDlg(); - virtual bool IsCmpCompleteShown(); - virtual CmpCompleteDlg* GetCmpCompleteDlg() { return cmp_end_dlg; } - - virtual void ShowCmpSceneDlg(); - virtual void HideCmpSceneDlg(); - virtual bool IsCmpSceneShown(); - virtual CmpSceneDlg* GetCmpSceneDlg() { return cmp_scene_dlg; } - - virtual void HideAll(); - virtual void ExecFrame(); - - void SetFieldOfView(double fov); - double GetFieldOfView() const; - -private: - Screen* screen; - - CmdForceDlg* cmd_force_dlg; - CmdOrdersDlg* cmd_orders_dlg; - CmdMissionsDlg* cmd_missions_dlg; - CmdIntelDlg* cmd_intel_dlg; - CmdTheaterDlg* cmd_theater_dlg; - - CmdMsgDlg* cmd_msg_dlg; - CmpFileDlg* cmp_file_dlg; - CmpCompleteDlg* cmp_end_dlg; - CmpSceneDlg* cmp_scene_dlg; - - DataLoader* loader; - - bool isShown; - - Campaign* campaign; - Starshatter* stars; - int completion_stage; -}; - -// +--------------------------------------------------------------------+ - -#endif // CmpnScreen_h - diff --git a/Stars45/Color.cpp b/Stars45/Color.cpp deleted file mode 100644 index 15687be..0000000 --- a/Stars45/Color.cpp +++ /dev/null @@ -1,680 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Universal Color Format class -*/ - -#include "Color.h" -#include "Video.h" -#include "Pcx.h" -#include "Fix.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -Color Color::White = Color(255,255,255); -Color Color::Black = Color( 0, 0, 0); -Color Color::Gray = Color(128,128,128); -Color Color::LightGray = Color(192,192,192); -Color Color::DarkGray = Color( 64, 64, 64); -Color Color::BrightRed = Color(255, 0, 0); -Color Color::BrightBlue = Color( 0, 0,255); -Color Color::BrightGreen= Color( 0,255, 0); -Color Color::DarkRed = Color(128, 0, 0); -Color Color::DarkBlue = Color( 0, 0,128); -Color Color::DarkGreen = Color( 0,128, 0); -Color Color::Yellow = Color(255,255, 0); -Color Color::Cyan = Color( 0,255,255); -Color Color::Magenta = Color(255, 0,255); -Color Color::Tan = Color(180,150,120); -Color Color::Brown = Color(128,100, 80); -Color Color::Violet = Color(128, 0,128); -Color Color::Orange = Color(255,150, 20); - -bool Color::standard_format = false; -int Color::texture_alpha_level = 0; -ColorFormat Color::format = ColorFormat(256); -ColorFormat Color::texture_format[4] = { ColorFormat(256), ColorFormat(256), ColorFormat(256), ColorFormat(256) }; -PALETTEENTRY Color::palette[256]; -BYTE Color::table[32768]; -double Color::fade = 1.0; -Color Color::fade_color; -Video* Color::video = 0; -DWORD ColorIndex::texture_palettes[4][256]; -DWORD ColorIndex::unfaded_palette[256]; -DWORD ColorIndex::formatted_palette[256]; -DWORD ColorIndex::shade_table[256*256]; -BYTE ColorIndex::blend_table[256*256]; -DWORD* ColorIndex::texture_palette = ColorIndex::texture_palettes[0]; - -// +--------------------------------------------------------------------+ - -Color::Color(BYTE index) -{ - PALETTEENTRY* p = &palette[index]; - - Set(p->peRed, p->peGreen, p->peBlue); -} - -// +--------------------------------------------------------------------+ - -Color& -Color::operator+=(const Color& c) -{ - int r = Red() + c.Red(); if (r > 255) r = 255; - int g = Green() + c.Green(); if (g > 255) g = 255; - int b = Blue() + c.Blue(); if (b > 255) b = 255; - - Set((BYTE) r, (BYTE) g, (BYTE) b); - return *this; -} - -Color -Color::operator+(DWORD d) const -{ - int r = Red() + ((d & RMask) >> RShift); if (r > 255) r = 255; - int g = Green() + ((d & GMask) >> GShift); if (g > 255) g = 255; - int b = Blue() + ((d & BMask) >> BShift); if (b > 255) b = 255; - - return Color((BYTE) r,(BYTE) g,(BYTE) b); -} - -// +--------------------------------------------------------------------+ - -Color -Color::operator+(const Color& c) const -{ - float src_alpha = c.fAlpha(); - float dst_alpha = 1.0f - src_alpha; - - BYTE r = (BYTE)((fRed() *dst_alpha + c.fRed() *src_alpha)*255.0f); - BYTE g = (BYTE)((fGreen()*dst_alpha + c.fGreen()*src_alpha)*255.0f); - BYTE b = (BYTE)((fBlue() *dst_alpha + c.fBlue() *src_alpha)*255.0f); - - return Color(r, g, b); -} - -// +--------------------------------------------------------------------+ - -Color -Color::operator*(const Color& c) const -{ - BYTE r = (BYTE) ((fRed() * c.fRed()) *255.0f); - BYTE g = (BYTE) ((fGreen() * c.fGreen()) *255.0f); - BYTE b = (BYTE) ((fBlue() * c.fBlue()) *255.0f); - - return Color(r, g, b); -} - -// +--------------------------------------------------------------------+ - -Color -Color::operator*(double scale) const -{ - int r = fast_f2i(Red() * scale); if (r > 255) r = 255; - int g = fast_f2i(Green() * scale); if (g > 255) g = 255; - int b = fast_f2i(Blue() * scale); if (b > 255) b = 255; - int a = fast_f2i(Alpha() * scale); if (a > 255) a = 255; - - return Color((BYTE) r, (BYTE) g, (BYTE) b, (BYTE) a); -} - -Color -Color::dim(double scale) const -{ - int r = fast_f2i(Red() * scale); - int g = fast_f2i(Green() * scale); - int b = fast_f2i(Blue() * scale); - - return Color((BYTE) r, (BYTE) g, (BYTE) b, (BYTE) Alpha()); -} - -// +--------------------------------------------------------------------+ - -DWORD -Color::Formatted() const -{ - if (format.pal) { - return Index(); - } - - else { - if (fade != 1.0) { - double step = (1.0 - fade); - - DWORD r = ((int) ((fRed() - (fRed() - fade_color.fRed()) * step)*255.0)) >> format.rdown; - DWORD g = ((int) ((fGreen() - (fGreen() - fade_color.fGreen())* step)*255.0)) >> format.gdown; - DWORD b = ((int) ((fBlue() - (fBlue() - fade_color.fBlue()) * step)*255.0)) >> format.bdown; - DWORD a = Alpha()>>format.adown; - - return (r<>format.rdown; - DWORD g = Green()>>format.gdown; - DWORD b = Blue() >>format.bdown; - DWORD a = Alpha()>>format.adown; - - return (r<>format.rdown; - DWORD g = Green()>>format.gdown; - DWORD b = Blue() >>format.bdown; - DWORD a = Alpha()>>format.adown; - - return (r<>tf.adown; - } - - else if (texture_alpha_level == 1) { - // transparent: - a = 255>>tf.adown; - } - - else if (texture_alpha_level == 2) { - // translucent: - if (r || g || b) - a = ((r+g+b+255)>>2)>>tf.adown; - } - - r = r >>tf.rdown; - g = g >>tf.gdown; - b = b >>tf.bdown; - - return (r< SHADE_LEVELS) { // shade towards white - double step = (shade - range)/range; - - sr = fr - (fr - 1.0) * step; - sg = fg - (fg - 1.0) * step; - sb = fb - (fb - 1.0) * step; - } - - return Color((BYTE) (sr*255.0), (BYTE) (sg*255.0), (BYTE) (sb*255.0), (BYTE) Alpha()); -} - -// +--------------------------------------------------------------------+ - -DWORD -Color::Shaded(int shade) const -{ - return ShadeColor(shade).Formatted(); -} - -// +--------------------------------------------------------------------+ - -Color -Color::Unformat(DWORD formatted_color) -{ - if (format.pal) { - return Color((BYTE) formatted_color); - } - else if (standard_format) { - Color c; - c.Set(formatted_color); - return c; - } - else { - BYTE r = (BYTE) ((formatted_color & format.rmask)>>format.rshift) << format.rdown; - BYTE g = (BYTE) ((formatted_color & format.gmask)>>format.gshift) << format.gdown; - BYTE b = (BYTE) ((formatted_color & format.bmask)>>format.bshift) << format.bdown; - BYTE a = (BYTE) ((formatted_color & format.amask)>>format.ashift) << format.adown; - - return Color(r,g,b,a); - } -} - -// +--------------------------------------------------------------------+ - -Color -Color::Scale(const Color& c1, const Color& c2, double scale) -{ - BYTE r = (BYTE) ((c1.fRed() + (c2.fRed() - c1.fRed() )*scale) * 255); - BYTE g = (BYTE) ((c1.fGreen() + (c2.fGreen() - c1.fGreen())*scale) * 255); - BYTE b = (BYTE) ((c1.fBlue() + (c2.fBlue() - c1.fBlue() )*scale) * 255); - BYTE a = (BYTE) ((c1.fAlpha() + (c2.fAlpha() - c1.fAlpha())*scale) * 255); - - return Color(r,g,b,a); -} - -// +--------------------------------------------------------------------+ - -DWORD -Color::FormattedBlend(DWORD c1, DWORD c2) -{ - if (format.pal) { - return ColorIndex::blend_table[(BYTE) c1 * 256 + (BYTE) c2]; - } - else { - ColorFormat& cf = format; - - DWORD r = (c1 & cf.rmask) + (c2 & cf.rmask); - DWORD g = (c1 & cf.gmask) + (c2 & cf.gmask); - DWORD b = (c1 & cf.bmask) + (c2 & cf.bmask); - - if (r & ~cf.rmask) r = cf.rmask; - if (g & ~cf.gmask) g = cf.gmask; - if (b & ~cf.bmask) b = cf.bmask; - - return (DWORD) (r|g|b); - } -} - -// +--------------------------------------------------------------------+ - -void -Color::UseVideo(Video* v) -{ - video = v; -} - -// +--------------------------------------------------------------------+ - -void -Color::UseFormat(const ColorFormat& cf) -{ - format = cf; - - if (format.rmask == RMask && format.gmask == GMask && format.bmask == BMask) - standard_format = true; - else - standard_format = false; - - if (cf.pal) { - for (int i = 0; i < 256; i++) { - ColorIndex::formatted_palette[i] = i; - ColorIndex::unfaded_palette[i] = i; - } - } - else { - double old_fade = fade; - - for (int i = 0; i < 256; i++) { - ColorIndex::formatted_palette[i] = Color(i).Formatted(); - - fade = 1.0; - ColorIndex::unfaded_palette[i] = Color(i).Formatted(); - fade = old_fade; - } - } -} - -// +--------------------------------------------------------------------+ - -void -Color::UseTextureFormat(const ColorFormat& cf, int alpha_level) -{ - texture_format[alpha_level] = cf; - - if (cf.pal) { - for (int i = 0; i < 256; i++) { - ColorIndex::texture_palettes[alpha_level][i] = i; - } - } - else { - double old_fade = fade; - - for (int i = 0; i < 256; i++) { - int old_texture_alpha_level = texture_alpha_level; - texture_alpha_level = alpha_level; - ColorIndex::texture_palettes[alpha_level][i] = Color(i).TextureFormat(); - texture_alpha_level = old_texture_alpha_level; - } - } -} - -// +--------------------------------------------------------------------+ - -void -Color::WithTextureFormat(int alpha_level) -{ - texture_alpha_level = alpha_level; - ColorIndex::texture_palette = ColorIndex::texture_palettes[alpha_level]; -} - -// +--------------------------------------------------------------------+ - -static BYTE MatchRGB(PALETTEENTRY* pal, BYTE r, BYTE g, BYTE b) -{ - double mindist = 100000000.0; - BYTE match = 0; - - for (int i = 0; i < 256; i++) { - PALETTEENTRY* p = pal++; - - double dr = p->peRed - r; - double dg = p->peGreen - g; - double db = p->peBlue - b; - - double d = (dr*dr) + (dg*dg) + (db*db); - - if (d < mindist) { - mindist = d; - match = i; - - if (d < 1.0) - return match; - } - } - - return match; -} - -// +--------------------------------------------------------------------+ - -void -Color::SetPalette(PALETTEENTRY* pal, int palsize, BYTE* invpal) -{ - for (int i = 0; i < palsize; i++) - palette[i] = pal[i]; - - if (invpal) { - for (int i = 0; i < 32768; i++) - table[i] = invpal[i]; - } - else { - for (int i = 0; i < 32768; i++) { - BYTE r = (i >> 10) & 0x1f; - BYTE g = (i >> 5) & 0x1f; - BYTE b = (i ) & 0x1f; - - Color c(r<<3, g<<3, b<<3); - - table[i] = MatchRGB(palette, r<<3, g<<3, b<<3); - } - } - - // set up formatted palette: - UseFormat(format); - - for (int i = 0; i < 4; i++) - UseTextureFormat(texture_format[i], i); - - // set up shade table: - double old_fade = fade; - fade = 1.0; - BuildShadeTable(); - fade = old_fade; - - // and blend table: - BuildBlendTable(); -} - -// +--------------------------------------------------------------------+ - -void -Color::SavePalette(const char* basename) -{ - char filename[256]; - - sprintf_s(filename, "%s.ipl", basename); - FILE* f; - fopen_s(&f, filename, "wb"); - if (f) { - fwrite(table, sizeof(table), 1, f); - fclose(f); - } -} - -// +--------------------------------------------------------------------+ - -void -Color::SetFade(double f, Color c, int build_shade) -{ - static int shade_built = 0; - - if (fade == f && fade_color == c && (build_shade ? shade_built : 1)) - return; - - fade = f; - fade_color = c; - - // set up formatted palette: - UseFormat(format); - - // if this is a paletted video mode, - // modify the video palette as well: - if (format.pal && video) { - PALETTEENTRY fade_palette[256]; - - double step = (1.0 - fade); - for (int i = 0; i < 256; i++) { - PALETTEENTRY& entry = fade_palette[i]; - ColorIndex c = ColorIndex(i); - - entry.peRed = ((int) ((c.fRed() - (c.fRed() - fade_color.fRed()) * step)*255.0)); - entry.peGreen = ((int) ((c.fGreen() - (c.fGreen() - fade_color.fGreen())* step)*255.0)); - entry.peBlue = ((int) ((c.fBlue() - (c.fBlue() - fade_color.fBlue()) * step)*255.0)); - entry.peFlags = 0; - } - } - - // otherwise, we need to re-compute - // the shade table: - else { - if (build_shade) { - BuildShadeTable(); - shade_built = 1; - } - else { - shade_built = 0; - } - } -} - -// +--------------------------------------------------------------------+ - -void -Color::BuildShadeTable() -{ - for (int shade = 0; shade < SHADE_LEVELS*2; shade++) - for (int index = 0; index < 256; index++) - ColorIndex::shade_table[shade*256+index] = Color(index).Shaded(shade); -} - -// +--------------------------------------------------------------------+ - -void -Color::BuildBlendTable() -{ - for (int src = 0; src < 256; src++) { - for (int dst = 0; dst < 256; dst++) { - ColorIndex src_clr = ColorIndex(src); - ColorIndex dst_clr = ColorIndex(dst); - - int r = src_clr.Red() + dst_clr.Red(); - int g = src_clr.Green() + dst_clr.Green(); - int b = src_clr.Blue() + dst_clr.Blue(); - - if (r>255) r=255; - if (g>255) g=255; - if (b>255) b=255; - - ColorIndex::blend_table[src*256+dst] = Color((BYTE)r,(BYTE)g,(BYTE)b).Index(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Color::SaveShadeTable(const char* basename) -{ - if (!format.pal) - return; - - char filename[256]; - sprintf_s(filename, "%s_clut.pcx", basename); - - BYTE clut[256*256]; - BYTE* pc = clut; - int i; - for (i = 0; i < SHADE_LEVELS*2; i++) - for (int j = 0; j < 256; j++) - *pc++ = (BYTE) ColorIndex::shade_table[i*256+j]; - - for (; i < 256; i++) - for (int j = 0; j < 256; j++) - *pc++ = (BYTE) 0; - - PcxImage pcx(256, 256, clut, (BYTE*) palette); - pcx.Save(filename); -} - - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - - -ColorValue& -ColorValue::operator+=(const ColorValue& c) -{ - r += c.r; - g += c.g; - b += c.b; - - return *this; -} - -ColorValue -ColorValue::operator+(const ColorValue& c) const -{ - float src_alpha = c.a; - float dst_alpha = 1.0f - a; - - float fr = (r * dst_alpha) + (c.r * src_alpha); - float fg = (g * dst_alpha) + (c.g * src_alpha); - float fb = (b * dst_alpha) + (c.b * src_alpha); - - return ColorValue(fr, fg, fb); -} - -ColorValue -ColorValue::operator*(const ColorValue& c) const -{ - return ColorValue(r*c.r, g*c.g, b*c.b); -} - -ColorValue -ColorValue::operator*(double scale) const -{ - return ColorValue((float) (r*scale), - (float) (g*scale), - (float) (b*scale), - (float) (a*scale)); -} - -ColorValue -ColorValue::dim(double scale) const -{ - return ColorValue((float) (r*scale), - (float) (g*scale), - (float) (b*scale)); -} - -// +--------------------------------------------------------------------+ - -inline BYTE bclamp(float x) { return (BYTE) ((x<0) ? 0 : (x>255) ? 255 : x); } - -Color -ColorValue::ToColor() const -{ - return Color(bclamp(r * 255.0f), - bclamp(g * 255.0f), - bclamp(b * 255.0f), - bclamp(a * 255.0f)); -} diff --git a/Stars45/Color.h b/Stars45/Color.h deleted file mode 100644 index cecdb4b..0000000 --- a/Stars45/Color.h +++ /dev/null @@ -1,294 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Universal Color Format class -*/ - -#ifndef Color_h -#define Color_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class Video; - -// +--------------------------------------------------------------------+ - -struct ColorFormat -{ - ColorFormat(int palsize) - : pal(palsize), bpp(8), - rdown(0), rshift(0), rmask(0), - gdown(0), gshift(0), gmask(0), - bdown(0), bshift(0), bmask(0), - adown(0), ashift(0), amask(0) { } - - ColorFormat(int size, BYTE r, BYTE rs, BYTE g, BYTE gs, BYTE b, BYTE bs, BYTE a=0, BYTE as=0) - : pal(0), bpp(size), - rdown(8-r), rshift(rs), rmask(((1<> RShift; } - DWORD Green() const { return (rgba & GMask) >> GShift; } - DWORD Blue() const { return (rgba & BMask) >> BShift; } - DWORD Alpha() const { return (rgba & AMask) >> AShift; } - - float fRed() const { return (float)(Red() /255.0); } - float fGreen() const { return (float)(Green()/255.0); } - float fBlue() const { return (float)(Blue() /255.0); } - float fAlpha() const { return (float)(Alpha()/255.0); } - - BYTE Index() const { return table[((rgba&RMask)>>(RShift+3)<<10)| - ((rgba&GMask)>>(GShift+3)<< 5)| - ((rgba&BMask)>>(BShift+3))]; } - - inline BYTE IndexedBlend(BYTE dst) const; - static DWORD FormattedBlend(DWORD c1, DWORD c2); - - DWORD TextureFormat(int keep_alpha=0) const; - DWORD Formatted() const; - DWORD Unfaded() const; - Color ShadeColor(int shade) const; - DWORD Shaded(int shade) const; - Color Faded() const; - - // some useful colors - static Color White; - static Color Black; - static Color Gray; - static Color LightGray; - static Color DarkGray; - static Color BrightRed; - static Color BrightBlue; - static Color BrightGreen; - static Color DarkRed; - static Color DarkBlue; - static Color DarkGreen; - static Color Yellow; - static Color Cyan; - static Color Magenta; - static Color Tan; - static Color Brown; - static Color Violet; - static Color Orange; - - static void UseVideo(Video* v); - static void UseFormat(const ColorFormat& cf); - static void UseTextureFormat(const ColorFormat& cf, int alpha_level=0); - static void WithTextureFormat(int alpha_level=0); - static void SetPalette(PALETTEENTRY* pal, int palsize, BYTE* invpal=0); - static void SavePalette(const char* basename); - static void SetFade(double f, Color c=Black, int build_shade=false); - - static const ColorFormat& GetTextureFormat(int alpha_level=0) { return texture_format[alpha_level]; } - static const ColorFormat& GetScreenFormat() { return format; } - - // indexed color initialization: - static void BuildShadeTable(); - static void SaveShadeTable(const char* basename); - static void BuildBlendTable(); - - static double GetFade() { return fade; } - static Color GetFadeColor() { return fade_color; } - - static Color Scale(const Color& c1, const Color& c2, double scale); - static Color Unformat(DWORD formatted_color); - -private: - DWORD rgba; - - static bool standard_format; - static PALETTEENTRY palette[256]; - static BYTE table[32768]; - static ColorFormat format; - static int texture_alpha_level; - static ColorFormat texture_format[4]; - static double fade; - static Color fade_color; - static Video* video; -}; - -// +--------------------------------------------------------------------+ - -class ColorValue -{ - friend class Color; - -public: - static const char* TYPENAME() { return "ColorValue"; } - - ColorValue() : r(0), g(0), b(0), a(0) { } - ColorValue(const ColorValue& c) : r(c.r), g(c.g), b(c.b), a(c.a) { } - ColorValue(const Color& c) : r( c.fRed() ), - g( c.fGreen() ), - b( c.fBlue() ), - a( c.fAlpha() ) { } - ColorValue(float ar, - float ag, - float ab, - float aa=1.0f) : r(ar), g(ag), b(ab), a(aa) { } - - int operator==(const ColorValue& c) const { return r==c.r && g==c.g && b==c.b && a==c.a; } - int operator!=(const ColorValue& c) const { return r!=c.r || g!=c.g || b!=c.b || a!=c.a; } - ColorValue& operator+=(const ColorValue& c); // simple summation - - ColorValue operator+(const ColorValue& c) const; // color alpha blending - ColorValue operator*(const ColorValue& c) const; // color modulation - ColorValue operator*(double scale) const; - ColorValue dim(double scale) const; - - void Set(float ar, float ag, float ab, float aa=1.0f) { r=ar; g=ag; b=ab; a=aa; } - - void SetRed(float ar) { r=ar; } - void SetGreen(float ag) { g=ag; } - void SetBlue(float ab) { b=ab; } - void SetAlpha(float aa) { a=aa; } - - float Red() const { return r; } - float Green() const { return g; } - float Blue() const { return b; } - float Alpha() const { return a; } - - Color ToColor() const; - DWORD TextureFormat(int keep_alpha=0) const { return ToColor().TextureFormat(keep_alpha); } - DWORD Formatted() const { return ToColor().Formatted(); } - DWORD Unfaded() const { return ToColor().Unfaded(); } - Color ShadeColor(int shade) const { return ToColor().ShadeColor(shade); } - DWORD Shaded(int shade) const { return ToColor().Shaded(shade); } - Color Faded() const { return ToColor().Faded(); } - -private: - float r, g, b, a; -}; - -// +--------------------------------------------------------------------+ - -class ColorIndex -{ - friend class Color; - -public: - static const char* TYPENAME() { return "ColorIndex"; } - - ColorIndex() : index(0) { } - ColorIndex(const ColorIndex& c) : index(c.index) { } - ColorIndex(BYTE r, BYTE g, BYTE b) { index = Color(r,g,b).Index(); } - ColorIndex(BYTE i) : index(i) { } - - ColorIndex& operator= (const ColorIndex& c) { index = c.index; return *this; } - int operator==(const ColorIndex& c) const { return index == c.index; } - int operator!=(const ColorIndex& c) const { return index != c.index; } - - BYTE Index() const { return index; } - - DWORD Red() const { return Color::palette[index].peRed; } - DWORD Green() const { return Color::palette[index].peGreen; } - DWORD Blue() const { return Color::palette[index].peBlue; } - - float fRed() const { return (float)(Red() /255.0); } - float fGreen() const { return (float)(Green()/255.0); } - float fBlue() const { return (float)(Blue() /255.0); } - - DWORD TextureFormat() const { return texture_palette[index]; } - DWORD Unfaded() const { return unfaded_palette[index]; } - DWORD Formatted() const { return formatted_palette[index]; } - DWORD Shaded(int shade) const { return shade_table[shade*256+index]; } - ColorIndex Faded() const { return ColorIndex(index); } - - // note: this will only work in 8-bit color mode... - ColorIndex ShadeColor(int s) const { return ColorIndex((BYTE)(shade_table[s*256+index])); } - - // for poly shading optimization - static DWORD* ShadeTable() { return shade_table; } - - BYTE IndexedBlend(BYTE dst) const { return blend_table[dst*256+index]; } - -private: - BYTE index; - - static DWORD* texture_palette; - static DWORD texture_palettes[4][256]; - static DWORD unfaded_palette[256]; - static DWORD formatted_palette[256]; - static DWORD shade_table[256*256]; - static BYTE blend_table[256*256]; -}; - -inline BYTE Color::IndexedBlend(BYTE dst) const { return ColorIndex::blend_table[dst*256+Index()]; } - -#endif // Color_h - diff --git a/Stars45/CombatAction.cpp b/Stars45/CombatAction.cpp deleted file mode 100644 index 2f2a748..0000000 --- a/Stars45/CombatAction.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A significant (newsworthy) event in the dynamic campaign. -*/ - -#include "CombatAction.h" -#include "CombatGroup.h" -#include "Campaign.h" -#include "Combatant.h" -#include "Player.h" -#include "Random.h" - -// +----------------------------------------------------------------------+ - -CombatAction::CombatAction(int n, int typ, int sub, int iff) - : id(n), type(typ), subtype(sub), opp_type(-1), team(iff), - status(PENDING), count(0), rval(-1), source(0), time(0), - start_before((int) 1e9), start_after(0), - min_rank(0), max_rank(100), - delay(0), probability(100), asset_type(0), target_type(0) -{ } - -CombatAction::~CombatAction() -{ - requirements.destroy(); - asset_kills.destroy(); - target_kills.destroy(); -} - -// +----------------------------------------------------------------------+ - -bool -CombatAction::IsAvailable() const -{ - CombatAction* pThis = (CombatAction*) this; - - if (rval < 0) { - pThis->rval = (int) Random(0, 100); - - if (rval > probability) - pThis->status = SKIPPED; - } - - if (status != PENDING) - return false; - - if (min_rank > 0 || max_rank < 100) { - Player* player = Player::GetCurrentPlayer(); - - if (player->Rank() < min_rank || player->Rank() > max_rank) - return false; - } - - Campaign* campaign = Campaign::GetCampaign(); - if (campaign) { - if (campaign->GetTime() < start_after) { - return false; - } - - if (campaign->GetTime() > start_before) { - pThis->status = FAILED; // too late! - return false; - } - - // check requirements against actions in current campaign: - ListIter iter = pThis->requirements; - while (++iter) { - CombatActionReq* r = iter.value(); - bool ok = false; - - if (r->action > 0) { - ListIter action = campaign->GetActions(); - while (++action) { - CombatAction* a = action.value(); - - if (a->Identity() == r->action) { - if (r->_not) { - if (a->Status() == r->stat) - return false; - } - else { - if (a->Status() != r->stat) - return false; - } - } - } - } - - // group-based requirement - else if (r->group_type > 0) { - if (r->c1) { - CombatGroup* group = r->c1->FindGroup(r->group_type, r->group_id); - - if (group) { - int test = 0; - int comp = 0; - - if (r->intel) { - test = group->IntelLevel(); - comp = r->intel; - } - - else { - test = group->CalcValue(); - comp = r->score; - } - - switch (r->comp) { - case CombatActionReq::LT: ok = (test < comp); break; - case CombatActionReq::LE: ok = (test <= comp); break; - case CombatActionReq::GT: ok = (test > comp); break; - case CombatActionReq::GE: ok = (test >= comp); break; - case CombatActionReq::EQ: ok = (test == comp); break; - } - } - - if (!ok) - return false; - } - } - - // score-based requirement - else { - int test = 0; - - if (r->comp <= CombatActionReq::EQ) { // absolute - if (r->c1) { - int test = r->c1->Score(); - - switch (r->comp) { - case CombatActionReq::LT: ok = (test < r->score); break; - case CombatActionReq::LE: ok = (test <= r->score); break; - case CombatActionReq::GT: ok = (test > r->score); break; - case CombatActionReq::GE: ok = (test >= r->score); break; - case CombatActionReq::EQ: ok = (test == r->score); break; - } - } - } - - else { // relative - if (r->c1 && r->c2) { - int test = r->c1->Score() - r->c2->Score(); - - switch (r->comp) { - case CombatActionReq::RLT: ok = (test < r->score); break; - case CombatActionReq::RLE: ok = (test <= r->score); break; - case CombatActionReq::RGT: ok = (test > r->score); break; - case CombatActionReq::RGE: ok = (test >= r->score); break; - case CombatActionReq::REQ: ok = (test == r->score); break; - } - } - } - - if (!ok) - return false; - } - - if (delay > 0) { - pThis->start_after = (int) campaign->GetTime() + delay; - pThis->delay = 0; - return IsAvailable(); - } - } - } - - return true; -} - -// +----------------------------------------------------------------------+ - -void -CombatAction::FireAction() -{ - Campaign* campaign = Campaign::GetCampaign(); - if (campaign) - time = (int) campaign->GetTime(); - - if (count >= 1) - count--; - - if (count < 1) - status = COMPLETE; -} - -void -CombatAction::FailAction() -{ - Campaign* campaign = Campaign::GetCampaign(); - if (campaign) - time = (int) campaign->GetTime(); - - count = 0; - status = FAILED; -} - -// +----------------------------------------------------------------------+ - -void -CombatAction::AddRequirement(int action, int stat, bool _not) -{ - requirements.append(new CombatActionReq(action, stat, _not)); -} - -void -CombatAction::AddRequirement(Combatant* c1, Combatant* c2, int comp, int score) -{ - requirements.append(new CombatActionReq(c1, c2, comp, score)); -} - -void -CombatAction::AddRequirement(Combatant* c1, int group_type, int group_id, int comp, int score, int intel) -{ - requirements.append(new CombatActionReq(c1, group_type, group_id, comp, score, intel)); -} - -// +----------------------------------------------------------------------+ - -int -CombatAction::TypeFromName(const char* n) -{ - int type = 0; - - if (!_stricmp(n, "NO_ACTION")) - type = NO_ACTION; - - else if (!_stricmp(n, "MARKER")) - type = NO_ACTION; - - else if (!_stricmp(n, "STRATEGIC_DIRECTIVE")) - type = STRATEGIC_DIRECTIVE; - - else if (!_stricmp(n, "STRATEGIC")) - type = STRATEGIC_DIRECTIVE; - - else if (!_stricmp(n, "ZONE_ASSIGNMENT")) - type = ZONE_ASSIGNMENT; - - else if (!_stricmp(n, "ZONE")) - type = ZONE_ASSIGNMENT; - - else if (!_stricmp(n, "SYSTEM_ASSIGNMENT")) - type = SYSTEM_ASSIGNMENT; - - else if (!_stricmp(n, "SYSTEM")) - type = SYSTEM_ASSIGNMENT; - - else if (!_stricmp(n, "MISSION_TEMPLATE")) - type = MISSION_TEMPLATE; - - else if (!_stricmp(n, "MISSION")) - type = MISSION_TEMPLATE; - - else if (!_stricmp(n, "COMBAT_EVENT")) - type = COMBAT_EVENT; - - else if (!_stricmp(n, "EVENT")) - type = COMBAT_EVENT; - - else if (!_stricmp(n, "INTEL_EVENT")) - type = INTEL_EVENT; - - else if (!_stricmp(n, "INTEL")) - type = INTEL_EVENT; - - else if (!_stricmp(n, "CAMPAIGN_SITUATION")) - type = CAMPAIGN_SITUATION; - - else if (!_stricmp(n, "SITREP")) - type = CAMPAIGN_SITUATION; - - else if (!_stricmp(n, "CAMPAIGN_ORDERS")) - type = CAMPAIGN_ORDERS; - - else if (!_stricmp(n, "ORDERS")) - type = CAMPAIGN_ORDERS; - - return type; -} - -int -CombatAction::StatusFromName(const char* n) -{ - int stat = 0; - - if (!_stricmp(n, "PENDING")) - stat = PENDING; - - else if (!_stricmp(n, "ACTIVE")) - stat = ACTIVE; - - else if (!_stricmp(n, "SKIPPED")) - stat = SKIPPED; - - else if (!_stricmp(n, "FAILED")) - stat = FAILED; - - else if (!_stricmp(n, "COMPLETE")) - stat = COMPLETE; - - return stat; -} - - -// +----------------------------------------------------------------------+ - -int -CombatActionReq::CompFromName(const char* n) -{ - int comp = 0; - - if (!_stricmp(n, "LT")) - comp = LT; - - else if (!_stricmp(n, "LE")) - comp = LE; - - else if (!_stricmp(n, "GT")) - comp = GT; - - else if (!_stricmp(n, "GE")) - comp = GE; - - else if (!_stricmp(n, "EQ")) - comp = EQ; - - else if (!_stricmp(n, "RLT")) - comp = RLT; - - else if (!_stricmp(n, "RLE")) - comp = RLE; - - else if (!_stricmp(n, "RGT")) - comp = RGT; - - else if (!_stricmp(n, "RGE")) - comp = RGE; - - else if (!_stricmp(n, "REQ")) - comp = REQ; - - return comp; -} diff --git a/Stars45/CombatAction.h b/Stars45/CombatAction.h deleted file mode 100644 index 4ad544d..0000000 --- a/Stars45/CombatAction.h +++ /dev/null @@ -1,204 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A planned action (mission/story/strategy) in a dynamic campaign. -*/ - -#ifndef CombatAction_h -#define CombatAction_h - -#include "Types.h" -#include "Geometry.h" -#include "Text.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Combatant; -class CombatAction; -class CombatActionReq; - -// +--------------------------------------------------------------------+ - -class CombatAction -{ -public: - static const char* TYPENAME() { return "CombatAction"; } - - enum TYPE - { - NO_ACTION, - STRATEGIC_DIRECTIVE, - ZONE_ASSIGNMENT, - SYSTEM_ASSIGNMENT, - MISSION_TEMPLATE, - COMBAT_EVENT, - INTEL_EVENT, - CAMPAIGN_SITUATION, - CAMPAIGN_ORDERS - }; - - enum STATUS - { - PENDING, - ACTIVE, - SKIPPED, - FAILED, - COMPLETE - }; - - CombatAction(int id, int type, int subtype, int team); - ~CombatAction(); - - int operator == (const CombatAction& a) const { return id == a.id; } - - bool IsAvailable() const; - void FireAction(); - void FailAction(); - void AddRequirement(int action, int stat, bool _not = false); - void AddRequirement(Combatant* c1, Combatant* c2, int comp, int score); - void AddRequirement(Combatant* c1, int group_type, int group_id, int comp, int score, int intel=0); - static int TypeFromName(const char* n); - static int StatusFromName(const char* n); - - // accessors/mutators: - int Identity() const { return id; } - int Type() const { return type; } - int Subtype() const { return subtype; } - int OpposingType() const { return opp_type; } - int GetIFF() const { return team; } - int Status() const { return status; } - int Source() const { return source; } - Point Location() const { return loc; } - const char* System() const { return system; } - const char* Region() const { return region; } - const char* Filename() const { return text_file; } - const char* ImageFile() const { return image_file; } - const char* SceneFile() const { return scene_file; } - int Count() const { return count; } - int ExecTime() const { return time; } - int StartBefore() const { return start_before; } - int StartAfter() const { return start_after; } - int MinRank() const { return min_rank; } - int MaxRank() const { return max_rank; } - int Delay() const { return delay; } - int Probability() const { return probability; } - int AssetType() const { return asset_type; } - int AssetId() const { return asset_id; } - List& AssetKills() { return asset_kills; } - int TargetType() const { return target_type; } - int TargetId() const { return target_id; } - int TargetIFF() const { return target_iff; } - List& TargetKills() { return target_kills; } - const char* GetText() const { return text; } - - void SetType(int t) { type = (char) t; } - void SetSubtype(int s) { subtype = (char) s; } - void SetOpposingType(int t){ opp_type = (char) t; } - void SetIFF(int t) { team = (char) t; } - void SetStatus(int s) { status = (char) s; } - void SetSource(int s) { source = s; } - void SetLocation(const Point& p) { loc = p; } - void SetSystem(Text sys) { system = sys; } - void SetRegion(Text rgn) { region = rgn; } - void SetFilename(Text f) { text_file = f; } - void SetImageFile(Text f) { image_file = f; } - void SetSceneFile(Text f) { scene_file = f; } - void SetCount(int n) { count = (char) n; } - void SetExecTime(int t) { time = t; } - void SetStartBefore(int s) { start_before = s; } - void SetStartAfter(int s) { start_after = s; } - void SetMinRank(int n) { min_rank = (char) n; } - void SetMaxRank(int n) { max_rank = (char) n; } - void SetDelay(int d) { delay = d; } - void SetProbability(int n) { probability = n; } - void SetAssetType(int t) { asset_type = t; } - void SetAssetId(int n) { asset_id = n; } - void SetTargetType(int t) { target_type = t; } - void SetTargetId(int n) { target_id = n; } - void SetTargetIFF(int n) { target_iff = n; } - void SetText(Text t) { text = t; } - - -private: - int id; - char type; - char subtype; - char opp_type; - char team; - char status; - char min_rank; - char max_rank; - int source; - Point loc; - Text system; - Text region; - Text text_file; - Text image_file; - Text scene_file; - char count; - int start_before; - int start_after; - int delay; - int probability; - int rval; - int time; - - Text text; - int asset_type; - int asset_id; - List asset_kills; - int target_type; - int target_id; - int target_iff; - List target_kills; - - List requirements; -}; - -// +--------------------------------------------------------------------+ - -class CombatActionReq { -public: - static const char* TYPENAME() { return "CombatActionReq"; } - - enum COMPARISON_OPERATOR { - LT, LE, GT, GE, EQ, // absolute score comparison - RLT, RLE, RGT, RGE, REQ // delta score comparison - }; - - CombatActionReq(int a, int s, bool n = false) - : action(a), stat(s), _not(n), c1(0), c2(0), comp(0), score(0), intel(0) { } - - CombatActionReq(Combatant* a1, Combatant* a2, int comparison, int value) - : action(0), stat(0), _not(0), c1(a1), c2(a2), group_type(0), group_id(0), - comp(comparison), score(value), intel(0) { } - - CombatActionReq(Combatant* a1, int gtype, int gid, int comparison, int value, int intel_level=0) - : action(0), stat(0), _not(0), c1(a1), c2(0), group_type(gtype), group_id(gid), - comp(comparison), score(value), intel(intel_level) { } - - static int CompFromName(const char* sym); - - int action; - int stat; - bool _not; - - Combatant* c1; - Combatant* c2; - int comp; - int score; - int intel; - int group_type; - int group_id; -}; - -#endif // CombatAction_h - diff --git a/Stars45/CombatAssignment.cpp b/Stars45/CombatAssignment.cpp deleted file mode 100644 index e9d931e..0000000 --- a/Stars45/CombatAssignment.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - High level assignment of one group to damage another -*/ - -#include "CombatAssignment.h" -#include "CombatGroup.h" -#include "Mission.h" - -// +--------------------------------------------------------------------+ - -CombatAssignment::CombatAssignment(int t, CombatGroup* obj, CombatGroup* rsc) - : type(t), objective(obj), resource(rsc) -{ -} - -// +--------------------------------------------------------------------+ - -CombatAssignment::~CombatAssignment() -{ -} - -// +--------------------------------------------------------------------+ -// This is used to sort assignments into a priority list. -// Higher priorities should come first in the list, so the -// sense of the operator is "backwards" from the usual. - -int -CombatAssignment::operator < (const CombatAssignment& a) const -{ - if (!objective) - return 0; - - if (!a.objective) - return 1; - - return objective->GetPlanValue() > a.objective->GetPlanValue(); -} - -// +--------------------------------------------------------------------+ - -const char* -CombatAssignment::GetDescription() const -{ - static char desc[256]; - - if (!resource) - sprintf_s(desc, "%s %s", - (const char*) Mission::RoleName(type), - (const char*) objective->Name()); - else - sprintf_s(desc, "%s %s %s", - (const char*) resource->Name(), - (const char*) Mission::RoleName(type), - (const char*) objective->Name()); - - return desc; -} diff --git a/Stars45/CombatAssignment.h b/Stars45/CombatAssignment.h deleted file mode 100644 index d917b28..0000000 --- a/Stars45/CombatAssignment.h +++ /dev/null @@ -1,56 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - High level assignment of one group to damage another -*/ - -#ifndef CombatAssignment_h -#define CombatAssignment_h - -#include "Types.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class CombatGroup; -class SimRegion; - -// +--------------------------------------------------------------------+ - -class CombatAssignment -{ -public: - static const char* TYPENAME() { return "CombatAssignment"; } - - CombatAssignment(int t, CombatGroup* obj, CombatGroup* rsc=0); - ~CombatAssignment(); - - int operator < (const CombatAssignment& a) const; - - // operations: - void SetObjective(CombatGroup* o) { objective = o; } - void SetResource(CombatGroup* r) { resource = r; } - - // accessors: - int Type() { return type; } - CombatGroup* GetObjective() { return objective; } - CombatGroup* GetResource() { return resource; } - - const char* GetDescription() const; - bool IsActive() const { return resource != 0; } - -private: - int type; - CombatGroup* objective; - CombatGroup* resource; -}; - - -#endif // CombatAssignment_h diff --git a/Stars45/CombatEvent.cpp b/Stars45/CombatEvent.cpp deleted file mode 100644 index 8c02142..0000000 --- a/Stars45/CombatEvent.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A significant (newsworthy) event in the dynamic campaign. -*/ - -#include "CombatEvent.h" -#include "CombatGroup.h" -#include "Campaign.h" -#include "Player.h" -#include "ShipDesign.h" -#include "Ship.h" - -#include "Term.h" -#include "ParseUtil.h" -#include "FormatUtil.h" -#include "DataLoader.h" - -// +----------------------------------------------------------------------+ - -CombatEvent::CombatEvent(Campaign* c, int typ, int tim, int tem, -int src, const char* rgn) -: campaign(c), type(typ), time(tim), team(tem), source(src), -region(rgn), points(0), visited(false) -{ } - -// +----------------------------------------------------------------------+ - -const char* -CombatEvent::SourceName() const -{ - return SourceName(source); -} - -// +----------------------------------------------------------------------+ - -const char* -CombatEvent::TypeName() const -{ - return TypeName(type); -} - -// +----------------------------------------------------------------------+ - -const char* -CombatEvent::SourceName(int n) -{ - switch (n) { - case FORCOM: return "FORCOM"; - case TACNET: return "TACNET"; - case INTEL: return "SECURE"; - case MAIL: return "Mail"; - case NEWS: return "News"; - } - - return "Unknown"; -} - -int -CombatEvent::SourceFromName(const char* n) -{ - for (int i = FORCOM; i <= NEWS; i++) - if (!_stricmp(n, SourceName(i))) - return i; - - return -1; -} - -// +----------------------------------------------------------------------+ - -const char* -CombatEvent::TypeName(int n) -{ - switch (n) { - case ATTACK: return "ATTACK"; - case DEFEND: return "DEFEND"; - case MOVE_TO: return "MOVE_TO"; - case CAPTURE: return "CAPTURE"; - case STRATEGY: return "STRATEGY"; - case STORY: return "STORY"; - case CAMPAIGN_START: return "CAMPAIGN_START"; - case CAMPAIGN_END: return "CAMPAIGN_END"; - case CAMPAIGN_FAIL: return "CAMPAIGN_FAIL"; - } - - return "Unknown"; -} - -int -CombatEvent::TypeFromName(const char* n) -{ - for (int i = ATTACK; i <= CAMPAIGN_FAIL; i++) - if (!_stricmp(n, TypeName(i))) - return i; - - return -1; -} - -// +----------------------------------------------------------------------+ - -void -CombatEvent::Load() -{ - DataLoader* loader = DataLoader::GetLoader(); - - if (!campaign || !loader) - return; - - loader->SetDataPath(campaign->Path()); - - if (file.length() > 0) { - const char* filename = file.data(); - BYTE* block = 0; - - loader->LoadBuffer(filename, block, true); - info = (const char*) block; - loader->ReleaseBuffer(block); - - if (info.contains('$')) { - Player* player = Player::GetCurrentPlayer(); - CombatGroup* group = campaign->GetPlayerGroup(); - - if (player) { - info = FormatTextReplace(info, "$NAME", player->Name().data()); - info = FormatTextReplace(info, "$RANK", Player::RankName(player->Rank())); - } - - if (group) { - info = FormatTextReplace(info, "$GROUP", group->GetDescription()); - } - - char timestr[32]; - FormatDayTime(timestr, campaign->GetTime(), true); - info = FormatTextReplace(info, "$TIME", timestr); - } - } - - if (type < CAMPAIGN_END && image_file.length() > 0) { - loader->LoadBitmap(image_file, image); - } - - loader->SetDataPath(0); -} - diff --git a/Stars45/CombatEvent.h b/Stars45/CombatEvent.h deleted file mode 100644 index 94f8d8a..0000000 --- a/Stars45/CombatEvent.h +++ /dev/null @@ -1,121 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A significant (newsworthy) event in the dynamic campaign. -*/ - -#ifndef CombatEvent_h -#define CombatEvent_h - -#include "Types.h" -#include "Geometry.h" -#include "Bitmap.h" -#include "Text.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class CombatGroup; -class CombatUnit; - -// +--------------------------------------------------------------------+ - -class CombatEvent -{ -public: - static const char* TYPENAME() { return "CombatEvent"; } - - enum EVENT_TYPE { - ATTACK, - DEFEND, - MOVE_TO, - CAPTURE, - STRATEGY, - - CAMPAIGN_START, - STORY, - CAMPAIGN_END, - CAMPAIGN_FAIL - }; - - enum EVENT_SOURCE { - FORCOM, - TACNET, - INTEL, - MAIL, - NEWS - }; - - CombatEvent(Campaign* c, int type, int time, int team, int source, const char* rgn); - - int operator == (const CombatEvent& u) const { return this == &u; } - - // accessors/mutators: - int Type() const { return type; } - int Time() const { return time; } - int GetIFF() const { return team; } - int Points() const { return points; } - int Source() const { return source; } - Point Location() const { return loc; } - const char* Region() const { return region; } - const char* Title() const { return title; } - const char* Information() const { return info; } - const char* Filename() const { return file; } - const char* ImageFile() const { return image_file; } - const char* SceneFile() const { return scene_file; } - Bitmap& Image() { return image; } - const char* SourceName() const; - const char* TypeName() const; - bool Visited() const { return visited; } - - void SetType(int t) { type = t; } - void SetTime(int t) { time = t; } - void SetIFF(int t) { team = t; } - void SetPoints(int p) { points = p; } - void SetSource(int s) { source = s; } - void SetLocation(const Point& p) { loc = p; } - void SetRegion(Text rgn) { region = rgn; } - void SetTitle(Text t) { title = t; } - void SetInformation(Text t) { info = t; } - void SetFilename(Text f) { file = f; } - void SetImageFile(Text f) { image_file = f; } - void SetSceneFile(Text f) { scene_file = f; } - void SetVisited(bool v) { visited = v; } - - // operations: - void Load(); - - // utilities: - static int TypeFromName(const char* n); - static int SourceFromName(const char* n); - static const char* TypeName(int n); - static const char* SourceName(int n); - -private: - Campaign* campaign; - int type; - int time; - int team; - int points; - int source; - bool visited; - Point loc; - Text region; - Text title; - Text info; - Text file; - Text image_file; - Text scene_file; - Bitmap image; -}; - -#endif // CombatEvent_h - diff --git a/Stars45/CombatGroup.cpp b/Stars45/CombatGroup.cpp deleted file mode 100644 index 42976bd..0000000 --- a/Stars45/CombatGroup.cpp +++ /dev/null @@ -1,1590 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - An element in the dynamic campaign -*/ - -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Combatant.h" -#include "CombatAssignment.h" -#include "Campaign.h" -#include "ShipDesign.h" -#include "Ship.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "ParseUtil.h" - -// +----------------------------------------------------------------------+ - -CombatGroup::CombatGroup(int t, int n, const char* s, int iff_code, int e, CombatGroup* p) -: type(t), id(n), name(s), iff(iff_code), enemy_intel(e), -parent(p), value(0), plan_value(0), unit_index(0), combatant(0), -expanded(false), sorties(0), kills(0), points(0), -current_zone(0), assigned_zone(0), zone_lock(false) -{ - if (parent) - parent->AddComponent(this); -} - -CombatGroup::~CombatGroup() -{ - assignments.destroy(); - components.destroy(); - units.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -CombatGroup::AddComponent(CombatGroup* g) -{ - if (g) { - g->parent = this; - components.append(g); - } -} - -// +--------------------------------------------------------------------+ - -bool -CombatGroup::IsAssignable() const -{ - switch (type) { - case CARRIER_GROUP: - case BATTLE_GROUP: - case DESTROYER_SQUADRON: - case ATTACK_SQUADRON: - case FIGHTER_SQUADRON: - case INTERCEPT_SQUADRON: - case LCA_SQUADRON: - return ((CombatGroup*) this)->CalcValue() > 0; - } - - return false; -} - -bool -CombatGroup::IsTargetable() const -{ - // neutral / non-combatants are not *strategic* targets - // for any combatant: - if (iff < 1 || iff >= 100) - return false; - - // civilian / non-combatant are not strategic targets: - if (type == PASSENGER || - type == PRIVATE || - type == MEDICAL || - type == HABITAT) - return false; - - // must have units of our own to be targetable: - if (units.size() < 1) - return false; - - return ((CombatGroup*) this)->CalcValue() > 0; -} - -bool -CombatGroup::IsDefensible() const -{ - if (type >= SUPPORT) - return ((CombatGroup*) this)->CalcValue() > 0; - - return false; -} - -bool -CombatGroup::IsStrikeTarget() const -{ - if (type < BATTALION || - type == MINEFIELD || // assault, not strike - type == PASSENGER || - type == PRIVATE || - type == MEDICAL || - type == HABITAT) - return false; - - return ((CombatGroup*) this)->CalcValue() > 0; -} - -// +--------------------------------------------------------------------+ - -bool -CombatGroup::IsMovable() const -{ - switch (type) { - case CARRIER_GROUP: - case BATTLE_GROUP: - case DESTROYER_SQUADRON: - case ATTACK_SQUADRON: - case FIGHTER_SQUADRON: - case INTERCEPT_SQUADRON: - case LCA_SQUADRON: - case COURIER: - case MEDICAL: - case SUPPLY: - case REPAIR: - case FREIGHT: - case PASSENGER: - case PRIVATE: - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -CombatGroup::IsFighterGroup() const -{ - switch (type) { - case WING: - case INTERCEPT_SQUADRON: - case FIGHTER_SQUADRON: - case ATTACK_SQUADRON: - return true; - } - - return false; -} - -bool -CombatGroup::IsStarshipGroup() const -{ - switch (type) { - case DESTROYER_SQUADRON: - case BATTLE_GROUP: - case CARRIER_GROUP: - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -CombatGroup::IsReserve() const -{ - if (enemy_intel <= Intel::RESERVE) - return true; - - if (parent) - return parent->IsReserve(); - - return false; -} - -// +--------------------------------------------------------------------+ - -const int* -CombatGroup::PreferredAttacker(int type) -{ - static int p[8]; - - ZeroMemory(p, sizeof(p)); - - switch (type) { - //case FLEET: - case DESTROYER_SQUADRON: p[0] = DESTROYER_SQUADRON; - p[1] = BATTLE_GROUP; - p[2] = CARRIER_GROUP; - p[3] = ATTACK_SQUADRON; - break; - - case BATTLE_GROUP: p[0] = BATTLE_GROUP; - p[1] = DESTROYER_SQUADRON; - p[2] = CARRIER_GROUP; - p[3] = ATTACK_SQUADRON; - break; - - case CARRIER_GROUP: p[0] = ATTACK_SQUADRON; - p[1] = BATTLE_GROUP; - p[2] = DESTROYER_SQUADRON; - p[3] = CARRIER_GROUP; - break; - - //case WING: - case LCA_SQUADRON: - case ATTACK_SQUADRON: - case INTERCEPT_SQUADRON: - case FIGHTER_SQUADRON: p[0] = INTERCEPT_SQUADRON; - p[1] = FIGHTER_SQUADRON; - break; - - //case BATTALION: - case STATION: p[0] = BATTLE_GROUP; - p[1] = CARRIER_GROUP; - break; - - case STARBASE: - case BATTERY: - case MISSILE: p[0] = ATTACK_SQUADRON; - p[1] = FIGHTER_SQUADRON; - break; - - //case C3I: - case MINEFIELD: - case COMM_RELAY: - case EARLY_WARNING: - case FWD_CONTROL_CTR: - case ECM: p[0] = ATTACK_SQUADRON; - p[1] = FIGHTER_SQUADRON; - p[2] = DESTROYER_SQUADRON; - break; - - //case SUPPORT: - case COURIER: - case MEDICAL: - case SUPPLY: - case REPAIR: p[0] = DESTROYER_SQUADRON; - p[1] = BATTLE_GROUP; - p[2] = ATTACK_SQUADRON; - break; - - //case CIVILIAN: - - //case WAR_PRODuCTION: - case FACTORY: - case REFINERY: - case RESOURCE: p[0] = ATTACK_SQUADRON; - p[1] = FIGHTER_SQUADRON; - break; - - //case INFRASTRUCTURE: - case TRANSPORT: - case NETWORK: - case HABITAT: - case STORAGE: p[0] = ATTACK_SQUADRON; - p[1] = FIGHTER_SQUADRON; - break; - - //case NON_COM: - case FREIGHT: - case PASSENGER: - case PRIVATE: p[0] = DESTROYER_SQUADRON; - p[1] = ATTACK_SQUADRON; - break; - } - - return p; -} - -// +--------------------------------------------------------------------+ - -const int* -CombatGroup::PreferredDefender(int type) -{ - static int p[8]; - - ZeroMemory(p, sizeof(p)); - - switch (type) { - //case FLEET: - case CARRIER_GROUP: - case BATTLE_GROUP: - case DESTROYER_SQUADRON: - - //case WING: - case LCA_SQUADRON: - case ATTACK_SQUADRON: - case INTERCEPT_SQUADRON: - case FIGHTER_SQUADRON: break; - - //case BATTALION: - case STATION: p[0] = BATTLE_GROUP; - p[1] = CARRIER_GROUP; - p[2] = DESTROYER_SQUADRON; - break; - case STARBASE: - case MINEFIELD: - case BATTERY: - case MISSILE: p[0] = FIGHTER_SQUADRON; - p[1] = INTERCEPT_SQUADRON; - break; - - //case C3I: - case COMM_RELAY: - case EARLY_WARNING: - case FWD_CONTROL_CTR: - case ECM: p[0] = FIGHTER_SQUADRON; - p[1] = INTERCEPT_SQUADRON; - break; - - //case SUPPORT: - case COURIER: - case MEDICAL: - case SUPPLY: - case REPAIR: p[0] = DESTROYER_SQUADRON; - p[1] = BATTLE_GROUP; - p[2] = ATTACK_SQUADRON; - break; - - //case CIVILIAN: - - //case WAR_PRODuCTION: - case FACTORY: - case REFINERY: - case RESOURCE: p[0] = FIGHTER_SQUADRON; - p[1] = INTERCEPT_SQUADRON; - break; - - //case INFRASTRUCTURE: - case TRANSPORT: - case NETWORK: - case HABITAT: - case STORAGE: p[0] = FIGHTER_SQUADRON; - p[1] = INTERCEPT_SQUADRON; - break; - - //case NON_COM: - case FREIGHT: - case PASSENGER: - case PRIVATE: p[0] = DESTROYER_SQUADRON; - p[1] = BATTLE_GROUP; - break; - } - - return p; -} - -// +--------------------------------------------------------------------+ - -CombatGroup* -CombatGroup::FindGroup(int t, int n) -{ - CombatGroup* result = 0; - - if (type == t && (n < 0 || id == n)) - result = this; - - ListIter group = components; - while (!result && ++group) { - result = group->FindGroup(t, n); - } - - return result; -} - -// +--------------------------------------------------------------------+ - -CombatGroup* -CombatGroup::Clone(bool deep) -{ - CombatGroup* clone = new - CombatGroup(type, id, name, iff, enemy_intel); - - clone->combatant = combatant; - clone->region = region; - clone->location = location; - clone->value = value; - clone->expanded = expanded; - - for (int i = 0; i < units.size(); i++) { - CombatUnit* u = new CombatUnit(*units[i]); - u->SetCombatGroup(clone); - clone->units.append(u); - } - - if (deep) { - for (int i = 0; i < components.size(); i++) { - CombatGroup* g = components[i]->Clone(deep); - clone->AddComponent(g); - - if (g->Type() == FIGHTER_SQUADRON || - g->Type() == INTERCEPT_SQUADRON || - g->Type() == ATTACK_SQUADRON || - g->Type() == LCA_SQUADRON) { - - if (units.size() > 0) { - CombatUnit* carrier = units[0]; - - for (int u = 0; u < g->GetUnits().size(); u++) { - CombatUnit* unit = g->GetUnits()[u]; - - if (unit->Type() >= Ship::FIGHTER || - unit->Type() <= Ship::LCA) { - unit->SetCarrier(carrier); - unit->SetRegion(carrier->GetRegion()); - } - } - } - } - } - } - - return clone; -} - -// +--------------------------------------------------------------------+ - -const char* -CombatGroup::GetOrdinal() const -{ - static char ordinal[16]; - - int last_two_digits = id % 100; - - if (last_two_digits > 10 && last_two_digits < 20) { - sprintf_s(ordinal, "ordinal.%d", last_two_digits); - Text suffix = ContentBundle::GetInstance()->GetText(ordinal); - - if (suffix != ordinal) - sprintf_s(ordinal, "%d%s", id, suffix.data()); - else - sprintf_s(ordinal, "%dth", id); - } - else { - int last_digit = last_two_digits % 10; - sprintf_s(ordinal, "ordinal.%d", last_digit); - Text suffix = ContentBundle::GetInstance()->GetText(ordinal); - if (suffix != ordinal) - sprintf_s(ordinal, "%d%s", id, suffix.data()); - else if (last_digit == 1) - sprintf_s(ordinal, "%dst", id); - else if (last_digit == 2) - sprintf_s(ordinal, "%dnd", id); - else if (last_digit == 3) - sprintf_s(ordinal, "%drd", id); - else - sprintf_s(ordinal, "%dth", id); - } - - return ordinal; -} - -const char* -CombatGroup::GetDescription() const -{ - static char desc[256]; - static char name_desc[256]; - - if (name.length()) - sprintf_s(name_desc, " \"%s\"", (const char*) name); - else - name_desc[0] = 0; - - switch (type) { - case FORCE: strcpy_s(desc, (const char*) name); break; - - case FLEET: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.FLEET").data(), name_desc); break; - case CARRIER_GROUP: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.CARRIER_GROUP").data(), name_desc); break; - case BATTLE_GROUP: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.BATTLE_GROUP").data(), name_desc); break; - case DESTROYER_SQUADRON: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.DESTROYER_SQUADRON").data(), name_desc); break; - - case WING: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.WING").data(), name_desc); break; - case ATTACK_SQUADRON: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.ATTACK_SQUADRON").data(), name_desc); break; - case FIGHTER_SQUADRON: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.FIGHTER_SQUADRON").data(), name_desc); break; - case INTERCEPT_SQUADRON: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.INTERCEPT_SQUADRON").data(), name_desc); break; - case LCA_SQUADRON: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.LCA_SQUADRON").data(), name_desc); break; - - case BATTALION: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.BATTALION").data(), name_desc); break; - case STATION: sprintf_s(desc, "%s %s", ContentBundle::GetInstance()->GetText("CombatGroup.STATION").data(), name.data()); break; - case STARBASE: sprintf_s(desc, "%s %d%s", ContentBundle::GetInstance()->GetText("CombatGroup.STARBASE").data(), id, name_desc); break; - case MINEFIELD: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.MINEFIELD").data(), name_desc); break; - case BATTERY: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.BATTERY").data(), name_desc); break; - case MISSILE: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.MISSILE").data(), name_desc); break; - - case C3I: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.C3I").data(), name_desc); break; - case COMM_RELAY: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.COMM_RELAY").data(), name_desc); break; - case EARLY_WARNING: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.EARLY_WARNING").data(), name_desc); break; - case FWD_CONTROL_CTR: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.FWD_CONTROL_CTR").data(), name_desc); break; - case ECM: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.ECM").data(), name_desc); break; - - case SUPPORT: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.SUPPORT").data(), name_desc); break; - case COURIER: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.COURIER").data(), name_desc); break; - case SUPPLY: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.SUPPLY").data(), name_desc); break; - case REPAIR: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.REPAIR").data(), name_desc); break; - case MEDICAL: sprintf_s(desc, "%s %s%s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.MEDICAL").data(), name_desc); break; - - case CIVILIAN: - case WAR_PRODUCTION: - case FACTORY: - case REFINERY: - case RESOURCE: strcpy_s(desc, (const char*) name); break; - - case INFRASTRUCTURE: - case TRANSPORT: - case NETWORK: - case HABITAT: - case STORAGE: - case FREIGHT: - case PASSENGER: - case PRIVATE: strcpy_s(desc, (const char*) name); break; - - default: sprintf_s(desc, "%s%s", ContentBundle::GetInstance()->GetText("CombatGroup.default").data(), name_desc); break; - } - - return desc; -} - -const char* -CombatGroup::GetShortDescription() const -{ - static char desc[256]; - - switch (type) { - case FORCE: strcpy_s(desc, (const char*) name); break; - - case FLEET: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.FLEET").data()); break; - case CARRIER_GROUP: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.CARRIER_GROUP").data()); break; - case BATTLE_GROUP: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.BATTLE_GROUP").data()); break; - case DESTROYER_SQUADRON: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.DESTROYER_SQUADRON").data()); break; - - case WING: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.WING").data()); break; - case ATTACK_SQUADRON: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.ATTACK_SQUADRON").data()); break; - case FIGHTER_SQUADRON: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.FIGHTER_SQUADRON").data()); break; - case INTERCEPT_SQUADRON: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.INTERCEPT_SQUADRON").data()); break; - case LCA_SQUADRON: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.LCA_SQUADRON").data()); break; - - case BATTALION: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.BATTALION").data()); break; - case STATION: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.STATION").data()); break; - case STARBASE: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.STARBASE").data()); break; - case MINEFIELD: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.MINEFIELD").data()); break; - case BATTERY: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.BATTERY").data()); break; - - case C3I: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.C3I").data()); break; - case COMM_RELAY: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.COMM_RELAY").data()); break; - case EARLY_WARNING: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.EARLY_WARNING").data()); break; - case FWD_CONTROL_CTR: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.FWD_CONTROL_CTR").data()); break; - case ECM: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.ECM").data()); break; - - case SUPPORT: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.SUPPORT").data()); break; - case COURIER: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.COURIER").data()); break; - case MEDICAL: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.MEDICAL").data()); break; - case SUPPLY: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.SUPPLY").data()); break; - case REPAIR: sprintf_s(desc, "%s %s", GetOrdinal(), ContentBundle::GetInstance()->GetText("CombatGroup.abrv.REPAIR").data()); break; - - case CIVILIAN: - case WAR_PRODUCTION: - case FACTORY: - case REFINERY: - case RESOURCE: strcpy_s(desc, (const char*) name); break; - - case INFRASTRUCTURE: - case TRANSPORT: - case NETWORK: - case HABITAT: - case STORAGE: - case FREIGHT: - case PASSENGER: - case PRIVATE: strcpy_s(desc, (const char*) name); break; - - default: sprintf_s(desc, "%s", ContentBundle::GetInstance()->GetText("CombatGroup.abrv.default").data()); break; - } - - return desc; -} - -// +--------------------------------------------------------------------+ - -double -CombatGroup::GetNextJumpTime() const -{ - double t = 0; - - ListIter unit = ((CombatGroup*) this)->units; - while (++unit) - if (unit->GetNextJumpTime() > t) - t = unit->GetNextJumpTime(); - - return t; -} - -// +--------------------------------------------------------------------+ - -void -CombatGroup::MoveTo(const Point& loc) -{ - location = loc; -} - -// +--------------------------------------------------------------------+ - -void -CombatGroup::SetAssignedSystem(const char* s) -{ - assigned_system = s; - assigned_zone = 0; - zone_lock = false; - - ListIter iter = components; - while (++iter) { - CombatGroup* g = iter.value(); - g->SetAssignedSystem(s); - } -} - -void -CombatGroup::SetAssignedZone(CombatZone* z) -{ - assigned_zone = z; - - if (!assigned_zone) - zone_lock = false; - - ListIter iter = components; - while (++iter) { - CombatGroup* g = iter.value(); - g->SetAssignedZone(z); - } -} - -void -CombatGroup::ClearUnlockedZones() -{ - if (!zone_lock) - assigned_zone = 0; - - ListIter iter = components; - while (++iter) { - CombatGroup* g = iter.value(); - g->ClearUnlockedZones(); - } -} - -void -CombatGroup::SetZoneLock(bool lock) -{ - if (!assigned_zone) - zone_lock = false; - else - zone_lock = lock; - - if (zone_lock) - assigned_system = Text(); - - ListIter iter = components; - while (++iter) { - CombatGroup* g = iter.value(); - g->SetZoneLock(lock); - } -} - -// +--------------------------------------------------------------------+ - -void -CombatGroup::SetIntelLevel(int n) -{ - if (n < Intel::RESERVE || n > Intel::TRACKED) return; - - enemy_intel = n; - - // if this group has been discovered, the entire - // branch of the OOB tree must be exposed. Otherwise, - // no missions would ever be planned against this - // combat group. - - if (n > Intel::SECRET) { - CombatGroup* p = parent; - while (p) { - if (p->enemy_intel < Intel::KNOWN) - p->enemy_intel = Intel::KNOWN; - - p = p->parent; - } - } -} - -// +--------------------------------------------------------------------+ - -int -CombatGroup::CalcValue() -{ - int val = 0; - - ListIter unit = units; - while (++unit) - val += unit->GetValue(); - - ListIter comp = components; - while (++comp) - val += comp->CalcValue(); - - value = val; - return value; -} - -int -CombatGroup::CountUnits() const -{ - int n = 0; - - CombatGroup* g = (CombatGroup*) this; - - ListIter unit = g->units; - while (++unit) - n += unit->Count() - unit->DeadCount(); - - CombatGroup* pThis = ((CombatGroup*) this); - pThis->live_comp.clear(); - ListIter iter = g->components; - while (++iter) { - CombatGroup* comp = iter.value(); - - if (!comp->IsReserve()) { - int unit_count = comp->CountUnits(); - if (unit_count > 0) - pThis->live_comp.append(comp); - - n += unit_count; - } - } - - return n; -} - -// +--------------------------------------------------------------------+ - -void -CombatGroup::ClearAssignments() -{ - assignments.destroy(); - - ListIter comp = components; - while (++comp) - comp->ClearAssignments(); -} - -// +--------------------------------------------------------------------+ - -CombatGroup* -CombatGroup::FindCarrier() -{ - CombatGroup* p = GetParent(); - - while (p != 0 && - p->Type() != CombatGroup::CARRIER_GROUP && - p->Type() != CombatGroup::STATION && - p->Type() != CombatGroup::STARBASE) - p = p->GetParent(); - - if (p && p->GetUnits().size()) - return p; - - return 0; -} - -CombatUnit* -CombatGroup::GetRandomUnit() -{ - CombatUnit* result = 0; - List live; - - ListIter unit = units; - while (++unit) { - if (unit->Count() - unit->DeadCount() > 0) - live.append(unit.value()); - } - - if (live.size() > 0) { - int ntries = 5; - while (!result && ntries-- > 0) { - int index = rand() % live.size(); - result = live[index]; - - int ship_class = result->GetShipClass(); - if (ship_class >= Ship::CRUISER && - ship_class <= Ship::FARCASTER) - result = 0; - } - } - - if (!result) { - ListIter comp = components; - while (++comp && !result) { - CombatUnit* u = comp->GetRandomUnit(); - if (u) - result = u; - } - } - - return result; -} - -CombatUnit* -CombatGroup::GetFirstUnit() -{ - int tmp_index = unit_index; - unit_index = 0; - CombatUnit* result = GetNextUnit(); - unit_index = tmp_index; - - return result; -} - -CombatUnit* -CombatGroup::GetNextUnit() -{ - if (units.size() > 0) { - List live; - - ListIter unit = units; - while (++unit) { - if (unit->Count() - unit->DeadCount() > 0) - live.append(unit.value()); - } - - if (live.size() > 0) { - return live[unit_index++ % live.size()]; - } - } - - if (components.size() > 0) { - return components[unit_index % components.size()]->GetNextUnit(); - } - - return 0; -} - -CombatUnit* -CombatGroup::FindUnit(const char* name) -{ - if (units.size() > 0) { - ListIter iter = units; - while (++iter) { - CombatUnit* unit = iter.value(); - if (unit->Name() == name) { - if (unit->Count() - unit->DeadCount() > 0) - return unit; - else - return 0; - } - } - } - - return 0; -} - -void -CombatGroup::AssignRegion(Text rgn) -{ - region = rgn; - - ListIter comp = components; - while (++comp) - comp->AssignRegion(rgn); - - ListIter unit = units; - while (++unit) - unit->SetRegion(rgn); -} - -// +--------------------------------------------------------------------+ - -static const char* group_name[] = { - "", - "force", - "wing", - "intercept_squadron", - "fighter_squadron", - "attack_squadron", - "lca_squadron", - "fleet", - "destroyer_squadron", - "battle_group", - "carrier_group", - "battalion", - "minefield", - "battery", - "missile", - "station", - "starbase", - "c3i", - "comm_relay", - "early_warning", - "fwd_control_ctr", - "ecm", - "support", - "courier", - "medical", - "supply", - "repair", - "civilian", - "war_production", - "factory", - "refinery", - "resource", - "infrastructure", - "transport", - "network", - "habitat", - "storage", - "non_com", - "freight", - "passenger", - "private" -}; - -// +--------------------------------------------------------------------+ - -int -CombatGroup::TypeFromName(const char* type_name) -{ - for (int i = FORCE; i < PRIVATE; i++) - if (!_stricmp(type_name, group_name[i])) - return i; - - return 0; -} - -const char* -CombatGroup::NameFromType(int type) -{ - return group_name[type]; -} - -// +--------------------------------------------------------------------+ - -int ShipClassFromName(const char* type_name) -{ - return Ship::ClassForName(type_name); -} - -// +--------------------------------------------------------------------+ - -#define GET_DEF_BOOL(n) if (pdef->name()->value()==(#n)) GetDefBool((n), pdef, filename) -#define GET_DEF_TEXT(n) if (pdef->name()->value()==(#n)) GetDefText((n), pdef, filename) -#define GET_DEF_NUM(n) if (pdef->name()->value()==(#n)) GetDefNumber((n), pdef, filename) -#define GET_DEF_VEC(n) if (pdef->name()->value()==(#n)) GetDefVec((n), pdef, filename) - -CombatGroup* -CombatGroup::LoadOrderOfBattle(const char* filename, int team, Combatant* combatant) -{ - CombatGroup* force = 0; - DataLoader* loader = DataLoader::GetLoader(); - BYTE* block; - loader->LoadBuffer(filename, block, true); - - Parser parser(new BlockReader((const char*) block)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse order of battle '%s'\n", filename); - return 0; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "ORDER_OF_BATTLE") { - Print("ERROR: invalid Order of Battle file '%s'\n", filename); - term->print(10); - return 0; - } - } - - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "group") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: group struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - char name[256]; - char type[64]; - char intel[64]; - char region[64]; - char system[64]; - char parent_type[64]; - int parent_id = 0; - int id = 0; - int iff = -1; - Vec3 loc = Vec3(1.0e9f,0.0f,0.0f); - - List unit_list; - char unit_name[64]; - char unit_regnum[16]; - char unit_design[64]; - char unit_skin[64]; - int unit_class = 0; - int unit_count = 1; - int unit_dead = 0; - int unit_damage = 0; - int unit_heading= 0; - int unit_index = 0; - - *name = 0; - *type = 0; - *intel = 0; - *region = 0; - *system = 0; - *parent_type = 0; - *unit_name = 0; - *unit_regnum = 0; - *unit_design = 0; - *unit_skin = 0; - - strcpy_s(intel, "KNOWN"); - - // all groups in this OOB default to the IFF of the main force - if (force) - iff = force->GetIFF(); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef && (iff < 0 || team < 0 || iff == team)) { - GET_DEF_TEXT(name); - else GET_DEF_TEXT(type); - else GET_DEF_TEXT(intel); - else GET_DEF_TEXT(region); - else GET_DEF_TEXT(system); - else GET_DEF_VEC(loc); - else GET_DEF_TEXT(parent_type); - else GET_DEF_NUM(parent_id); - else GET_DEF_NUM(iff); - else GET_DEF_NUM(id); - else GET_DEF_NUM(unit_index); - - else if ((iff == team || team < 0) && pdef->name()->value() == "unit") { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: unit struct missing for group '%s' in '%s'\n", name, filename); - } - else { - TermStruct* val = pdef->term()->isStruct(); - - char unit_region[64]; - char design[256]; - Vec3 unit_loc = Vec3(1.0e9f,0.0f,0.0f); - unit_count = 1; - - ZeroMemory(unit_region, sizeof(unit_region)); - ZeroMemory(design, sizeof(design)); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") { - GetDefText(unit_name, pdef, filename); - } - else if (pdef->name()->value() == "regnum") { - GetDefText(unit_regnum, pdef, filename); - } - else if (pdef->name()->value() == "region") { - GetDefText(unit_region, pdef, filename); - } - else if (pdef->name()->value() == "loc") { - GetDefVec(unit_loc, pdef, filename); - } - else if (pdef->name()->value() == "type") { - char typestr[32]; - GetDefText(typestr, pdef, filename); - unit_class = ShipDesign::ClassForName(typestr); - } - else if (pdef->name()->value() == "design") { - GetDefText(unit_design, pdef, filename); - } - else if (pdef->name()->value() == "skin") { - GetDefText(unit_skin, pdef, filename); - } - else if (pdef->name()->value() == "count") { - GetDefNumber(unit_count, pdef, filename); - } - else if (pdef->name()->value() == "dead_count") { - GetDefNumber(unit_dead, pdef, filename); - } - else if (pdef->name()->value() == "damage") { - GetDefNumber(unit_damage, pdef, filename); - } - else if (pdef->name()->value() == "heading") { - GetDefNumber(unit_heading, pdef, filename); - } - } - } - - if (!ShipDesign::CheckName(unit_design)) { - Print("ERROR: invalid design '%s' for unit '%s' in '%s'\n", unit_design, unit_name, filename); - return 0; - } - - CombatUnit* cu = new CombatUnit(unit_name, unit_regnum, unit_class, unit_design, unit_count, iff); - cu->SetRegion(unit_region); - cu->SetSkin(unit_skin); - cu->MoveTo(unit_loc); - cu->Kill(unit_dead); - cu->SetSustainedDamage(unit_damage); - cu->SetHeading(unit_heading * DEGREES); - unit_list.append(cu); - } - } - } - } // elements - - if (iff >= 0 && (iff == team || team < 0)) { - CombatGroup* parent_group = 0; - - if (force) { - parent_group = force->FindGroup(TypeFromName(parent_type), parent_id); - } - - CombatGroup* g = new - CombatGroup(TypeFromName(type), id, name, iff, Intel::IntelFromName(intel), parent_group); - - g->region = region; - g->combatant = combatant; - g->unit_index = unit_index; - - if (loc.x >= 1e9) { - if (parent_group) - g->location = parent_group->location; - else - g->location = Vec3(0,0,0); - } - else { - g->location = loc; - } - - if (unit_list.size()) { - unit_list[0]->SetLeader(true); - - ListIter u = unit_list; - while (++u) { - u->SetCombatGroup(g); - - if (u->GetRegion().length() < 1) { - u->SetRegion(g->GetRegion()); - u->MoveTo(g->Location()); - } - - if (parent_group && - (u->Type() == Ship::FIGHTER || - u->Type() == Ship::ATTACK)) { - - CombatUnit* carrier = 0; - CombatGroup* p = parent_group; - - while (p && !carrier) { - if (p->units.size() && p->units[0]->Type() == Ship::CARRIER) { - carrier = p->units[0]; - u->SetCarrier(carrier); - u->SetRegion(carrier->GetRegion()); - } - - p = p->parent; - } - } - } - - g->units.append(unit_list); - } - - if (!force) - force = g; - } // iff == team? - } // group-struct - } // group - } // def - } // term - } - while (term); - - loader->ReleaseBuffer(block); - Print("Order of Battle Loaded (%s).\n", force ? force->Name().data() : "unknown force"); - - if (force) - force->CalcValue(); - - return force; -} - -// +--------------------------------------------------------------------+ - -void -CombatGroup::MergeOrderOfBattle(BYTE* block, const char* filename, int team, Combatant* combatant, Campaign* campaign) -{ - CombatGroup* force = 0; - - Parser parser(new BlockReader((const char*) block)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse order of battle '%s'\n", filename); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "SAVEGAME") { - Print("ERROR: invalid Save Game file '%s'\n", filename); - term->print(10); - return; - } - } - - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "group") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: group struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - char name[256]; - char type[64]; - char intel[64]; - char region[64]; - char system[64]; - char zone[64]; - bool zone_locked = false; - int id = 0; - int iff = -1; - int sorties = -1; - int kills = -1; - int points = -1; - Vec3 loc = Vec3(1.0e9f,0.0f,0.0f); - - List unit_list; - char unit_name[64]; - char unit_regnum[16]; - char unit_design[64]; - int unit_class = 0; - int unit_count = 1; - int unit_dead = 0; - int unit_damage = 0; - int unit_heading= 0; - int unit_index = 0; - - *name = 0; - *type = 0; - *intel = 0; - *region = 0; - *system = 0; - *zone = 0; - *unit_name = 0; - *unit_regnum = 0; - *unit_design = 0; - - strcpy_s(intel, "KNOWN"); - - // all groups in this OOB default to the IFF of the main force - if (force) - iff = force->GetIFF(); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef && (iff < 0 || team < 0 || iff == team)) { - GET_DEF_TEXT(name); - else GET_DEF_TEXT(type); - else GET_DEF_TEXT(intel); - else GET_DEF_TEXT(region); - else GET_DEF_TEXT(system); - else GET_DEF_TEXT(zone); - else GET_DEF_BOOL(zone_locked); - else GET_DEF_VEC(loc); - else GET_DEF_NUM(iff); - else GET_DEF_NUM(id); - else GET_DEF_NUM(sorties); - else GET_DEF_NUM(kills); - else GET_DEF_NUM(points); - else GET_DEF_NUM(unit_index); - - else if ((iff == team || team < 0) && pdef->name()->value() == "unit") { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: unit struct missing for group '%s' in '%s'\n", name, filename); - } - else { - TermStruct* val = pdef->term()->isStruct(); - - char unit_region[64]; - char design[256]; - Vec3 unit_loc=Vec3(0.0f,0.0f,0.0f); - unit_count = 1; - - ZeroMemory(unit_region, sizeof(unit_region)); - ZeroMemory(design, sizeof(design)); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") { - GetDefText(unit_name, pdef, filename); - } - else if (pdef->name()->value() == "regnum") { - GetDefText(unit_regnum, pdef, filename); - } - else if (pdef->name()->value() == "region") { - GetDefText(unit_region, pdef, filename); - } - else if (pdef->name()->value() == "loc") { - GetDefVec(unit_loc, pdef, filename); - } - else if (pdef->name()->value() == "type") { - char typestr[32]; - GetDefText(typestr, pdef, filename); - unit_class = ShipDesign::ClassForName(typestr); - } - else if (pdef->name()->value() == "design") { - GetDefText(unit_design, pdef, filename); - } - else if (pdef->name()->value() == "count") { - GetDefNumber(unit_count, pdef, filename); - } - else if (pdef->name()->value() == "dead_count") { - GetDefNumber(unit_dead, pdef, filename); - } - else if (pdef->name()->value() == "damage") { - GetDefNumber(unit_damage, pdef, filename); - } - else if (pdef->name()->value() == "heading") { - GetDefNumber(unit_heading, pdef, filename); - } - } - } - - if (!ShipDesign::CheckName(unit_design)) { - Print("ERROR: invalid design '%s' for unit '%s' in '%s'\n", unit_design, unit_name, filename); - return; - } - - if (force) { - CombatUnit* cu = new CombatUnit(unit_name, unit_regnum, unit_class, unit_design, unit_count, iff); - cu->SetRegion(unit_region); - cu->MoveTo(unit_loc); - cu->Kill(unit_dead); - cu->SetSustainedDamage(unit_damage); - cu->SetHeading(unit_heading * DEGREES); - unit_list.append(cu); - } - } - } - } - } // elements - - if (iff >= 0 && (iff == team || team < 0)) { - // have we found the force group we are looking for yet? - if (!force && !_stricmp(name, combatant->Name())) { - force = combatant->GetForce(); - } - - else { - if (!force) - continue; - - // if we already have a force, and we find a second one, - // it must be the start of a different combatant. - // So don't process any further: - if (TypeFromName(type) == CombatGroup::FORCE) { - break; - } - } - - CombatGroup* g = force->FindGroup(TypeFromName(type), id); - - if (!g) { - ::Print("WARNING: unexpected combat group %s %d '%s' in '%s'\n", type, id, name, filename); - continue; - } - - g->region = region; - g->combatant = combatant; - g->location = loc; - g->enemy_intel = Intel::IntelFromName(intel); - g->unit_index = unit_index; - - if (*zone) { - CombatZone* combat_zone = campaign->GetZone(zone); - - if (combat_zone) { - g->SetAssignedZone(combat_zone); - g->SetZoneLock(zone_locked); - } - else { - ::Print("WARNING: could not find combat zone '%s' for group %s %d '%s' in '%s'\n", zone, type, id, name, filename); - } - } - else if (*system) { - g->SetAssignedSystem(system); - } - - if (sorties >= 0) g->SetSorties(sorties); - if (kills >= 0) g->SetKills(kills); - if (points >= 0) g->SetPoints(points); - - if (unit_list.size()) { - ListIter u_iter = unit_list; - while (++u_iter) { - CombatUnit* load_unit = u_iter.value(); - CombatUnit* u = g->FindUnit(load_unit->Name()); - - if (u) { - if (load_unit->GetRegion().length() > 0) { - u->SetRegion(load_unit->GetRegion()); - u->MoveTo(load_unit->Location()); - } - else { - u->SetRegion(g->GetRegion()); - u->MoveTo(g->Location()); - } - u->SetDeadCount(load_unit->DeadCount()); - u->SetSustainedDamage(load_unit->GetSustainedDamage()); - u->SetHeading(load_unit->GetHeading()); - } - } - - unit_list.destroy(); - } - - if (!force) - force = g; - } // iff == team? - } // group-struct - } // group - } // def - } // term - } - while (term); - - Print("Order of Battle Loaded (%s).\n", force ? force->Name().data() : "unknown force"); - - if (force) - force->CalcValue(); -} - -// +--------------------------------------------------------------------+ - -Text FormatNumber(double n) -{ - char buffer[64]; - - if (fabs(n) < 1000) - sprintf_s(buffer, "%d", (int) n); - - else if (fabs(n) < 1e6) { - int nn = (int) n / 1000; - sprintf_s(buffer, "%de3", nn); - } - - else - sprintf_s(buffer, "%g", n); - - return buffer; -} - -void -SaveCombatUnit(FILE* f, CombatUnit* u) -{ - int type = u->Type(); - - if (type == 0 && u->GetDesign()) - type = u->GetDesign()->type; - - fprintf(f, "\n unit: {"); - fprintf(f, " name: \"%s\",", u->Name().data()); - fprintf(f, " type: \"%s\",", Ship::ClassName(type)); - fprintf(f, " design: \"%s\",", u->DesignName().data()); - - if (u->Count() > 1) { - fprintf(f, " count: %d,", u->Count()); - } - else { - fprintf(f, " regnum:\"%s\",", u->Registry().data()); - } - - if (u->GetRegion().length() > 0) { - fprintf(f, " region:\"%s\",", u->GetRegion().data()); - - Text x = FormatNumber(u->Location().x); - Text y = FormatNumber(u->Location().y); - Text z = FormatNumber(u->Location().z); - - fprintf(f, " loc:(%s, %s, %s),", x.data(), y.data(), z.data()); - } - - fprintf(f, " dead_count: %d, damage: %d, heading: %d },", - (int) u->DeadCount(), - (int) u->GetSustainedDamage(), - (int) (u->GetHeading() / DEGREES)); -} - -void -SaveCombatGroup(FILE* f, CombatGroup* g) -{ - fprintf(f, "group: {"); - fprintf(f, " type: %s,", CombatGroup::NameFromType(g->Type())); - fprintf(f, " id: %d,", g->GetID()); - fprintf(f, " name: \"%s\",", g->Name().data()); - fprintf(f, " intel: %s,", Intel::NameFromIntel(g->IntelLevel())); - fprintf(f, " iff: %d,", g->GetIFF()); - fprintf(f, " unit_index: %d,", g->UnitIndex()); - - if (g->GetRegion().length()) { - fprintf(f, " region:\"%s\",", g->GetRegion().data()); - } - - if (g->GetAssignedSystem().length()) { - fprintf(f, " system: \"%s\",", g->GetAssignedSystem().data()); - } - - if (g->GetAssignedZone()) { - fprintf(f, " zone: \"%s\",", g->GetAssignedZone()->Name().data()); - if (g->IsZoneLocked()) { - fprintf(f, " zone_locked: true,"); - } - } - - Text x = FormatNumber(g->Location().x); - Text y = FormatNumber(g->Location().y); - Text z = FormatNumber(g->Location().z); - - fprintf(f, " loc: (%s, %s, %s),", x.data(), y.data(), z.data()); - - CombatGroup* parent = g->GetParent(); - if (parent) { - fprintf(f, " parent_type:%s,", CombatGroup::NameFromType(parent->Type())); - fprintf(f, " parent_id:%d,", parent->GetID()); - } - - fprintf(f, " sorties: %d,", g->Sorties()); - fprintf(f, " kills: %d,", g->Kills()); - fprintf(f, " points: %d,", g->Points()); - - ListIter u = g->GetUnits(); - while (++u) { - SaveCombatUnit(f, u.value()); - } - - fprintf(f, " }\n"); - - ListIter c = g->GetComponents(); - while (++c) { - SaveCombatGroup(f, c.value()); - } -} - -void -CombatGroup::SaveOrderOfBattle(const char* filename, CombatGroup* force) -{ - FILE* f; - ::fopen_s(&f, filename, "a+"); - - if (f) { - SaveCombatGroup(f, force); - fprintf(f, "\n"); - fclose(f); - } -} diff --git a/Stars45/CombatGroup.h b/Stars45/CombatGroup.h deleted file mode 100644 index da34ff0..0000000 --- a/Stars45/CombatGroup.h +++ /dev/null @@ -1,230 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#ifndef CombatGroup_h -#define CombatGroup_h - -#include "Types.h" -#include "Geometry.h" -#include "Text.h" -#include "List.h" -#include "Intel.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class Combatant; -class CombatGroup; -class CombatUnit; -class CombatZone; -class CombatAssignment; - -// +--------------------------------------------------------------------+ - -class CombatGroup -{ -public: - static const char* TYPENAME() { return "CombatGroup"; } - - enum GROUP_TYPE { - FORCE = 1, // Commander In Chief - - WING, // Air Force - INTERCEPT_SQUADRON, // a2a fighter - FIGHTER_SQUADRON, // multi-role fighter - ATTACK_SQUADRON, // strike / attack - LCA_SQUADRON, // landing craft - - FLEET, // Navy - DESTROYER_SQUADRON, // destroyer - BATTLE_GROUP, // heavy cruiser(s) - CARRIER_GROUP, // fleet carrier - - BATTALION, // Army - MINEFIELD, - BATTERY, - MISSILE, - STATION, // orbital station - STARBASE, // planet-side base - - C3I, // Command, Control, Communications, Intelligence - COMM_RELAY, - EARLY_WARNING, - FWD_CONTROL_CTR, - ECM, - - SUPPORT, - COURIER, - MEDICAL, - SUPPLY, - REPAIR, - - CIVILIAN, // root for civilian groups - - WAR_PRODUCTION, - FACTORY, - REFINERY, - RESOURCE, - - INFRASTRUCTURE, - TRANSPORT, - NETWORK, - HABITAT, - STORAGE, - - NON_COM, // other civilian traffic - FREIGHT, - PASSENGER, - PRIVATE - }; - - CombatGroup(int t, int n, const char* s, int i, int e, CombatGroup* p=0); - ~CombatGroup(); - - // comparison operators are used to sort combat groups into a priority list - // in DESCENDING order, so the sense of the comparison is backwards from - // usual... - int operator < (const CombatGroup& g) const { return value > g.value; } - int operator <= (const CombatGroup& g) const { return value >= g.value; } - int operator == (const CombatGroup& g) const { return this == &g; } - - // operations: - static CombatGroup* LoadOrderOfBattle(const char* fname, int iff, Combatant* combatant); - static void SaveOrderOfBattle(const char* fname, CombatGroup* force); - static void MergeOrderOfBattle(BYTE* block, const char* fname, int iff, Combatant* combatant, Campaign* campaign); - - void AddComponent(CombatGroup* g); - CombatGroup* FindGroup(int t, int n=-1); - CombatGroup* Clone(bool deep=true); - - // accessors and mutators: - const char* GetDescription() const; - const char* GetShortDescription() const; - - void SetCombatant(Combatant* c) { combatant = c; } - - Combatant* GetCombatant() { return combatant; } - CombatGroup* GetParent() { return parent; } - List& GetComponents() { return components; } - List& GetLiveComponents() { return live_comp; } - List& GetUnits() { return units; } - CombatUnit* GetRandomUnit(); - CombatUnit* GetFirstUnit(); - CombatUnit* GetNextUnit(); - CombatUnit* FindUnit(const char* name); - CombatGroup* FindCarrier(); - - const Text& Name() const { return name; } - int Type() const { return type; } - int CountUnits() const; - int IntelLevel() const { return enemy_intel;} - int GetID() const { return id; } - int GetIFF() const { return iff; } - Point Location() const { return location; } - void MoveTo(const Point& loc); - const Text& GetRegion() const { return region; } - void SetRegion(Text rgn) { region = rgn; } - void AssignRegion(Text rgn); - int Value() const { return value; } - int Sorties() const { return sorties; } - void SetSorties(int n) { sorties = n; } - int Kills() const { return kills; } - void SetKills(int n) { kills = n; } - int Points() const { return points; } - void SetPoints(int n) { points = n; } - int UnitIndex() const { return unit_index; } - - double GetNextJumpTime() const; - - double GetPlanValue() const { return plan_value; } - void SetPlanValue(double v) { plan_value = v; } - - bool IsAssignable() const; - bool IsTargetable() const; - bool IsDefensible() const; - bool IsStrikeTarget() const; - bool IsMovable() const; - bool IsFighterGroup() const; - bool IsStarshipGroup() const; - bool IsReserve() const; - - // these two methods return zero terminated arrays of - // integers identifying the preferred assets for attack - // or defense in priority order: - static const int* PreferredAttacker(int type); - static const int* PreferredDefender(int type); - - bool IsExpanded() const { return expanded; } - void SetExpanded(bool e) { expanded = e; } - - const Text& GetAssignedSystem() const { return assigned_system; } - void SetAssignedSystem(const char* s); - CombatZone* GetCurrentZone() const { return current_zone; } - void SetCurrentZone(CombatZone* z) { current_zone = z; } - CombatZone* GetAssignedZone() const { return assigned_zone; } - void SetAssignedZone(CombatZone* z); - void ClearUnlockedZones(); - bool IsZoneLocked() const { return assigned_zone && zone_lock; } - void SetZoneLock(bool lock=true); - bool IsSystemLocked() const { return assigned_system.length() > 0; } - - const Text& GetStrategicDirection() const { return strategic_direction; } - void SetStrategicDirection(Text dir) { strategic_direction = dir; } - - void SetIntelLevel(int n); - int CalcValue(); - - List& GetAssignments() { return assignments; } - void ClearAssignments(); - - static int TypeFromName(const char* name); - static const char* NameFromType(int type); - -private: - const char* GetOrdinal() const; - - // attributes: - int type; - int id; - Text name; - int iff; - int enemy_intel; - - double plan_value; // scratch pad for plan modules - - List units; - List components; - List live_comp; - Combatant* combatant; - CombatGroup* parent; - Text region; - Point location; - int value; - int unit_index; - - int sorties; - int kills; - int points; - - bool expanded; // for tree control - - Text assigned_system; - CombatZone* current_zone; - CombatZone* assigned_zone; - bool zone_lock; - List assignments; - - Text strategic_direction; -}; - -#endif // CombatGroup_h - diff --git a/Stars45/CombatRoster.cpp b/Stars45/CombatRoster.cpp deleted file mode 100644 index 9f552a9..0000000 --- a/Stars45/CombatRoster.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - The complete roster of all known persistent entities - for all combatants in the game. -*/ - -#include "CombatRoster.h" -#include "CombatGroup.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -static CombatRoster* roster = 0; - -// +--------------------------------------------------------------------+ - -CombatRoster::CombatRoster() -{ - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Campaigns/"); - - List files; - loader->ListFiles("*.def", files); - - for (int i = 0; i < files.size(); i++) { - Text filename = *files[i]; - - if (!filename.contains("/") && !filename.contains("\\")) { - loader->SetDataPath("Campaigns/"); - CombatGroup* g = CombatGroup::LoadOrderOfBattle(filename, -1, 0); - forces.append(g); - } - } - - files.destroy(); -} - -// +--------------------------------------------------------------------+ - -CombatRoster::~CombatRoster() -{ - forces.destroy(); -} - -// +--------------------------------------------------------------------+ - -CombatGroup* -CombatRoster::GetForce(const char* name) -{ - ListIter iter = forces; - while (++iter) { - CombatGroup* f = iter.value(); - - if (f->Name() == name) - return f; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -CombatRoster::Initialize() -{ - roster = new CombatRoster(); -} - -void -CombatRoster::Close() -{ - delete roster; - roster = 0; -} - -CombatRoster* -CombatRoster::GetInstance() -{ - return roster; -} \ No newline at end of file diff --git a/Stars45/CombatRoster.h b/Stars45/CombatRoster.h deleted file mode 100644 index 65b7bd2..0000000 --- a/Stars45/CombatRoster.h +++ /dev/null @@ -1,47 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - The complete roster of all known persistent entities - for all combatants in the game. -*/ - -#ifndef CombatRoster_h -#define CombatRoster_h - -#include "Types.h" -#include "Geometry.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class CombatGroup; - -// +--------------------------------------------------------------------+ - -class CombatRoster -{ - CombatRoster(); - ~CombatRoster(); - -public: - static const char* TYPENAME() { return "CombatRoster"; } - - static void Initialize(); - static void Close(); - static CombatRoster* GetInstance(); - - CombatGroup* GetForce(const char* name); - -private: - List forces; -}; - - -#endif // CombatRoster_h diff --git a/Stars45/CombatUnit.cpp b/Stars45/CombatUnit.cpp deleted file mode 100644 index b7af000..0000000 --- a/Stars45/CombatUnit.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A ship, station, or ground unit in the dynamic campaign. -*/ - -#include "CombatUnit.h" -#include "CombatGroup.h" -#include "Campaign.h" -#include "ShipDesign.h" -#include "Ship.h" - -#include "Game.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ -#undef random -inline double random() { return (double) rand() / (double) RAND_MAX; } - -// +----------------------------------------------------------------------+ - -CombatUnit::CombatUnit(const char* n, const char* reg, int t, const char* d, int c, int i) -: name(n), regnum(reg), type(t), design_name(d), design(0), -count(c), iff(i), leader(false), dead_count(0), available(c), -carrier(0), plan_value(0), launch_time(-1e6), jump_time(0), -sustained_damage(0), target(0), group(0), heading(0) -{ } - -CombatUnit::CombatUnit(const CombatUnit& u) -: name(u.name), regnum(u.regnum), type(u.type), design_name(u.design_name), -design(u.design), count(u.count), iff(u.iff), -dead_count(u.dead_count), available(u.available), -leader(u.leader), region(u.region), location(u.location), -carrier(u.carrier), plan_value(0), launch_time(u.launch_time), -jump_time(u.jump_time), sustained_damage(u.sustained_damage), -target(0), group(0), heading(u.heading) -{ } - -// +----------------------------------------------------------------------+ - -const ShipDesign* -CombatUnit::GetDesign() -{ - if (!design) - design = ShipDesign::Get(design_name); - - return design; -} - -int -CombatUnit::GetShipClass() const -{ - if (design) - return design->type; - - return type; -} - -int -CombatUnit::GetValue() const -{ - return GetSingleValue() * LiveCount(); -} - -int -CombatUnit::GetSingleValue() const -{ - return Ship::Value(GetShipClass()); -} - -// +----------------------------------------------------------------------+ - -const char* -CombatUnit::GetDescription() const -{ - if (!design) { - CombatUnit* pThis = (CombatUnit*) this; // cast-away const - pThis->GetDesign(); - } - - static char desc[256]; - - if (!design) { - strcpy_s(desc, ContentBundle::GetInstance()->GetText("[unknown]").data()); - } - - else if (count > 1) { - sprintf_s(desc, "%dx %s %s", LiveCount(), design->abrv, design->DisplayName()); - } - - else { - if (regnum.length() > 0) - sprintf_s(desc, "%s-%s %s", design->abrv, (const char*) regnum, (const char*) name); - else - sprintf_s(desc, "%s %s", design->abrv, (const char*) name); - - if (dead_count > 0) { - strcat_s(desc, " "); - strcat_s(desc, ContentBundle::GetInstance()->GetText("killed.in.action")); - } - } - - return desc; -} - -// +----------------------------------------------------------------------+ - -bool -CombatUnit::CanLaunch() const -{ - bool result = false; - - switch (type) { - case Ship::FIGHTER: - case Ship::ATTACK: result = (Campaign::Stardate() - launch_time) >= 300; - break; - - case Ship::CORVETTE: - case Ship::FRIGATE: - case Ship::DESTROYER: - case Ship::CRUISER: - case Ship::CARRIER: result = true; - break; - } - - return result; -} - -// +----------------------------------------------------------------------+ - -Color -CombatUnit::MarkerColor() const -{ - return Ship::IFFColor(iff); -} - -bool -CombatUnit::IsGroundUnit() const -{ - return (design && (design->type & Ship::GROUND_UNITS)) ? true : false; -} - -bool -CombatUnit::IsStarship() const -{ - return (design && (design->type & Ship::STARSHIPS)) ? true : false; -} - -bool -CombatUnit::IsDropship() const -{ - return (design && (design->type & Ship::DROPSHIPS)) ? true : false; -} - -bool -CombatUnit::IsStatic() const -{ - return design && (design->type >= Ship::STATION); -} - -// +----------------------------------------------------------------------+ - -double -CombatUnit::MaxRange() const -{ - return 100e3; -} - -double CombatUnit::MaxEffectiveRange() const -{ - return 50e3; -} - -double CombatUnit::OptimumRange() const -{ - if (type == Ship::FIGHTER || type == Ship::ATTACK) - return 15e3; - - return 30e3; -} - -// +----------------------------------------------------------------------+ - -bool CombatUnit::CanDefend(CombatUnit* unit) const -{ - if (unit == 0 || unit == this) - return false; - - if (type > Ship::STATION) - return false; - - double distance = (location - unit->location).length(); - - if (type > unit->type) - return false; - - if (distance > MaxRange()) - return false; - - return true; -} - -// +----------------------------------------------------------------------+ - -double CombatUnit::PowerVersus(CombatUnit* tgt) const -{ - if (tgt == 0 || tgt == this || available < 1) - return 0; - - if (type > Ship::STATION) - return 0; - - double effectiveness = 1; - double distance = (location - tgt->location).length(); - - if (distance > MaxRange()) - return 0; - - if (distance > MaxEffectiveRange()) - effectiveness = 0.5; - - if (type == Ship::FIGHTER) { - if (tgt->type == Ship::FIGHTER || tgt->type == Ship::ATTACK) - return Ship::FIGHTER * 2 * available * effectiveness; - else - return 0; - } - else if (type == Ship::ATTACK) { - if (tgt->type > Ship::ATTACK) - return Ship::ATTACK * 3 * available * effectiveness; - else - return 0; - } - else if (type == Ship::CARRIER) { - return 0; - } - else if (type == Ship::SWACS) { - return 0; - } - else if (type == Ship::CRUISER) { - if (tgt->type <= Ship::ATTACK) - return type * effectiveness; - - else - return 0; - } - else { - if (tgt->type > Ship::ATTACK) - return type * effectiveness; - else - return type * 0.1 * effectiveness; - } - - return 0; -} - -// +----------------------------------------------------------------------+ - -int -CombatUnit::AssignMission() -{ - int assign = count; - - if (count > 4) - assign = 4; - - if (assign > 0) { - available -= assign; - launch_time = Campaign::Stardate(); - return assign; - } - - return 0; -} - -// +----------------------------------------------------------------------+ - -void -CombatUnit::CompleteMission() -{ - Disengage(); - - if (count > 4) - available += 4; - - else - available += count; -} - -// +----------------------------------------------------------------------+ - -void -CombatUnit::MoveTo(const Point& loc) -{ - if (!carrier) - location = loc; - else - location = carrier->location; -} - -// +----------------------------------------------------------------------+ - -void -CombatUnit::Engage(CombatUnit* tgt) -{ - if (!tgt) - Disengage(); - - else if (!tgt->attackers.contains(this)) - tgt->attackers.append(this); - - target = tgt; -} - -void -CombatUnit::Disengage() -{ - if (target) - target->attackers.remove(this); - - target = 0; -} - -// +----------------------------------------------------------------------+ - -static int KillGroup(CombatGroup* group) -{ - int value_killed = 0; - - if (group) { - ListIter u_iter = group->GetUnits(); - while (++u_iter) { - CombatUnit* u = u_iter.value(); - value_killed += u->Kill(u->LiveCount()); - } - - ListIter g_iter = group->GetComponents(); - while (++g_iter) { - CombatGroup* g = g_iter.value(); - value_killed += KillGroup(g); - } - } - - return value_killed; -} - -int -CombatUnit::Kill(int n) -{ - int killed = n; - - if (killed > LiveCount()) - killed = LiveCount(); - - dead_count += killed; - - int value_killed = killed * GetSingleValue(); - - if (killed) { - // if unit could support children, kill them too: - if (type == Ship::CARRIER || - type == Ship::STATION || - type == Ship::STARBASE) { - - if (group) { - ListIter iter = group->GetComponents(); - while (++iter) { - CombatGroup* g = iter.value(); - value_killed += KillGroup(g); - } - } - } - } - - return value_killed; -} - diff --git a/Stars45/CombatUnit.h b/Stars45/CombatUnit.h deleted file mode 100644 index b9e26c2..0000000 --- a/Stars45/CombatUnit.h +++ /dev/null @@ -1,132 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A ship, station, or ground unit in the dynamic campaign. -*/ - -#ifndef CombatUnit_h -#define CombatUnit_h - -#include "Types.h" -#include "Geometry.h" -#include "Color.h" -#include "Text.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class CombatGroup; -class ShipDesign; - -// +--------------------------------------------------------------------+ - -class CombatUnit -{ -public: - static const char* TYPENAME() { return "CombatUnit"; } - - CombatUnit(const char* n, const char* reg, int t, const char* dname, int number, int i); - CombatUnit(const CombatUnit& unit); - - int operator == (const CombatUnit& u) const { return this == &u; } - - const char* GetDescription() const; - - int GetValue() const; - int GetSingleValue() const; - bool CanDefend(CombatUnit* unit) const; - bool CanLaunch() const; - double PowerVersus(CombatUnit* tgt) const; - int AssignMission(); - void CompleteMission(); - - double MaxRange() const; - double MaxEffectiveRange() const; - double OptimumRange() const; - - void Engage(CombatUnit* tgt); - void Disengage(); - - // accessors and mutators: - const Text& Name() const { return name; } - const Text& Registry() const { return regnum; } - const Text& DesignName() const { return design_name; } - const Text& Skin() const { return skin; } - void SetSkin(const char* s) { skin = s; } - int Type() const { return type; } - int Count() const { return count; } - int LiveCount() const { return count - dead_count; } - int DeadCount() const { return dead_count; } - void SetDeadCount(int n) { dead_count = n; } - int Kill(int n); - int Available() const { return available; } - int GetIFF() const { return iff; } - bool IsLeader() const { return leader; } - void SetLeader(bool l) { leader = l; } - Point Location() const { return location; } - void MoveTo(const Point& loc); - Text GetRegion() const { return region; } - void SetRegion(Text rgn) { region = rgn; } - CombatGroup* GetCombatGroup() const { return group; } - void SetCombatGroup(CombatGroup* g){ group = g; } - - Color MarkerColor() const; - bool IsGroundUnit() const; - bool IsStarship() const; - bool IsDropship() const; - bool IsStatic() const; - - CombatUnit* GetCarrier() const { return carrier; } - void SetCarrier(CombatUnit* c) { carrier = c; } - - const ShipDesign* GetDesign(); - int GetShipClass() const; - - List& GetAttackers() { return attackers; } - - double GetPlanValue() const { return plan_value; } - void SetPlanValue(int v) { plan_value = v; } - - double GetSustainedDamage() const { return sustained_damage; } - void SetSustainedDamage(double d) { sustained_damage = d; } - - double GetHeading() const { return heading; } - void SetHeading(double d) { heading = d; } - - double GetNextJumpTime() const { return jump_time; } - -private: - Text name; - Text regnum; - Text design_name; - Text skin; - int type; - const ShipDesign* design; - int count; - int dead_count; - int available; - int iff; - bool leader; - Text region; - Point location; - double plan_value; // scratch pad for plan modules - double launch_time; - double jump_time; - double sustained_damage; - double heading; - - CombatUnit* carrier; - List attackers; - CombatUnit* target; - CombatGroup* group; -}; - -#endif // CombatUnit_h - diff --git a/Stars45/CombatZone.cpp b/Stars45/CombatZone.cpp deleted file mode 100644 index 21dbcd5..0000000 --- a/Stars45/CombatZone.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CombatZone is used by the dynamic campaign strategy - and logistics algorithms to assign forces to locations - within the campaign. A CombatZone is a collection of - closely related sectors, and the assets contained - within them. -*/ - -#include "CombatZone.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "Campaign.h" -#include "ShipDesign.h" -#include "Ship.h" - -#include "Game.h" -#include "DataLoader.h" -#include "ParseUtil.h" - -// +----------------------------------------------------------------------+ - -CombatZone::CombatZone() -{ -} - -CombatZone::~CombatZone() -{ - regions.destroy(); - forces.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -CombatZone::Clear() -{ - forces.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -CombatZone::AddGroup(CombatGroup* group) -{ - if (group) { - int iff = group->GetIFF(); - ZoneForce* f = FindForce(iff); - f->AddGroup(group); - group->SetCurrentZone(this); - } -} - -void -CombatZone::RemoveGroup(CombatGroup* group) -{ - if (group) { - int iff = group->GetIFF(); - ZoneForce* f = FindForce(iff); - f->RemoveGroup(group); - group->SetCurrentZone(0); - } -} - -bool -CombatZone::HasGroup(CombatGroup* group) -{ - if (group) { - int iff = group->GetIFF(); - ZoneForce* f = FindForce(iff); - return f->HasGroup(group); - } - - return false; -} - -// +--------------------------------------------------------------------+ - -void -CombatZone::AddRegion(const char* rgn) -{ - if (rgn && *rgn) { - regions.append(new Text(rgn)); - - if (name.length() < 1) - name = rgn; - } -} - -// +--------------------------------------------------------------------+ - -bool -CombatZone::HasRegion(const char* rgn) -{ - if (rgn && *rgn && regions.size()) { - Text test(rgn); - return regions.contains(&test); - } - - return false; -} - -// +--------------------------------------------------------------------+ - -ZoneForce* -CombatZone::FindForce(int iff) -{ - ListIter f = forces; - while (++f) { - if (f->GetIFF() == iff) - return f.value(); - } - - return MakeForce(iff); -} - -// +--------------------------------------------------------------------+ - -ZoneForce* -CombatZone::MakeForce(int iff) -{ - ZoneForce* f = new ZoneForce(iff); - forces.append(f); - return f; -} - -// +--------------------------------------------------------------------+ - -static List zonelist; - -List& -CombatZone::Load(const char* filename) -{ - zonelist.clear(); - - DataLoader* loader = DataLoader::GetLoader(); - BYTE* block = 0; - - loader->LoadBuffer(filename, block, true); - Parser parser(new BlockReader((const char*) block)); - - Term* term = parser.ParseTerm(); - - if (!term) { - return zonelist; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "ZONES") { - return zonelist; - } - } - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "zone") { - if (!def->term() || !def->term()->isStruct()) { - ::Print("WARNING: zone struct missing in '%s%s'\n", loader->GetDataPath(), filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - CombatZone* zone = new CombatZone(); - char rgn[64]; - ZeroMemory(rgn, sizeof(rgn)); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "region") { - GetDefText(rgn, pdef, filename); - zone->AddRegion(rgn); - } - else if (pdef->name()->value() == "system") { - GetDefText(rgn, pdef, filename); - zone->system = rgn; - } - } - } - - zonelist.append(zone); - } - } - } - } - } - while (term); - - loader->ReleaseBuffer(block); - - return zonelist; -} - -// +--------------------------------------------------------------------+ - -ZoneForce::ZoneForce(int i) -{ - iff = i; - - for (int n = 0; n < 8; n++) - need[n] = 0; -} - -void -ZoneForce::AddGroup(CombatGroup* group) -{ - if (group) - groups.append(group); -} - -void -ZoneForce::RemoveGroup(CombatGroup* group) -{ - if (group) - groups.remove(group); -} - -bool -ZoneForce::HasGroup(CombatGroup* group) -{ - if (group) - return groups.contains(group); - - return false; -} - -int -ZoneForce::GetNeed(int group_type) const -{ - switch (group_type) { - case CombatGroup::CARRIER_GROUP: return need[0]; - case CombatGroup::BATTLE_GROUP: return need[1]; - case CombatGroup::DESTROYER_SQUADRON: return need[2]; - case CombatGroup::ATTACK_SQUADRON: return need[3]; - case CombatGroup::FIGHTER_SQUADRON: return need[4]; - case CombatGroup::INTERCEPT_SQUADRON: return need[5]; - } - - return 0; -} - -void -ZoneForce::SetNeed(int group_type, int needed) -{ - switch (group_type) { - case CombatGroup::CARRIER_GROUP: need[0] = needed; break; - case CombatGroup::BATTLE_GROUP: need[1] = needed; break; - case CombatGroup::DESTROYER_SQUADRON: need[2] = needed; break; - case CombatGroup::ATTACK_SQUADRON: need[3] = needed; break; - case CombatGroup::FIGHTER_SQUADRON: need[4] = needed; break; - case CombatGroup::INTERCEPT_SQUADRON: need[5] = needed; break; - } -} - -void -ZoneForce::AddNeed(int group_type, int needed) -{ - switch (group_type) { - case CombatGroup::CARRIER_GROUP: need[0] += needed; break; - case CombatGroup::BATTLE_GROUP: need[1] += needed; break; - case CombatGroup::DESTROYER_SQUADRON: need[2] += needed; break; - case CombatGroup::ATTACK_SQUADRON: need[3] += needed; break; - case CombatGroup::FIGHTER_SQUADRON: need[4] += needed; break; - case CombatGroup::INTERCEPT_SQUADRON: need[5] += needed; break; - } -} - diff --git a/Stars45/CombatZone.h b/Stars45/CombatZone.h deleted file mode 100644 index ff04313..0000000 --- a/Stars45/CombatZone.h +++ /dev/null @@ -1,102 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - CombatZone is used by the dynamic campaign strategy - and logistics algorithms to assign forces to locations - within the campaign. A CombatZone is a collection of - closely related sectors, and the assets contained - within them. -*/ - -#ifndef CombatZone_h -#define CombatZone_h - -#include "Types.h" -#include "Geometry.h" -#include "Text.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class CombatGroup; -class CombatUnit; -class ZoneForce; - -// +--------------------------------------------------------------------+ - -class CombatZone -{ -public: - static const char* TYPENAME() { return "CombatZone"; } - - CombatZone(); - ~CombatZone(); - - int operator == (const CombatZone& g) const { return this == &g; } - - const Text& Name() const { return name; } - const Text& System() const { return system; } - void AddGroup(CombatGroup* g); - void RemoveGroup(CombatGroup* g); - bool HasGroup(CombatGroup* g); - void AddRegion(const char* rgn); - bool HasRegion(const char* rgn); - List& GetRegions() { return regions; } - List& GetForces() { return forces; } - - ZoneForce* FindForce(int iff); - ZoneForce* MakeForce(int iff); - - void Clear(); - - static List& - Load(const char* filename); - -private: - // attributes: - Text name; - Text system; - List regions; - List forces; -}; - -// +--------------------------------------------------------------------+ - -class ZoneForce -{ -public: - ZoneForce(int i); - - int GetIFF() { return iff; } - List& GetGroups() { return groups; } - List& GetTargetList() { return target_list; } - List& GetDefendList() { return defend_list; } - - void AddGroup(CombatGroup* g); - void RemoveGroup(CombatGroup* g); - bool HasGroup(CombatGroup* g); - - int GetNeed(int group_type) const; - void SetNeed(int group_type, int needed); - void AddNeed(int group_type, int needed); - -private: - // attributes: - int iff; - List groups; - List defend_list; - List target_list; - int need[8]; -}; - -// +--------------------------------------------------------------------+ - -#endif // CombatZone_h - diff --git a/Stars45/Combatant.cpp b/Stars45/Combatant.cpp deleted file mode 100644 index b6d8794..0000000 --- a/Stars45/Combatant.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - One side in a military conflict -*/ - -#include "Combatant.h" -#include "CombatGroup.h" -#include "Mission.h" - -#include "Game.h" - -// +--------------------------------------------------------------------+ - -static void SetCombatant(CombatGroup* g, Combatant* c) -{ - if (!g) return; - - g->SetCombatant(c); - - ListIter iter = g->GetComponents(); - while (++iter) - SetCombatant(iter.value(), c); -} - -// +--------------------------------------------------------------------+ - -Combatant::Combatant(const char* com_name, const char* fname, int team) - : name(com_name), iff(team), score(0), force(0) -{ - for (int i = 0; i < 6; i++) - target_factor[i] = 1; - - target_factor[2] = 1000; - - if (fname) - force = CombatGroup::LoadOrderOfBattle(fname, iff, this); -} - -Combatant::Combatant(const char* com_name, CombatGroup* f) - : name(com_name), iff(0), score(0), force(f) -{ - for (int i = 0; i < 6; i++) - target_factor[i] = 1; - - target_factor[2] = 1000; - - if (force) { - SetCombatant(force, this); - iff = force->GetIFF(); - } -} - -// +--------------------------------------------------------------------+ - -Combatant::~Combatant() -{ - mission_list.clear(); - target_list.clear(); - defend_list.clear(); - delete force; -} - -// +--------------------------------------------------------------------+ - -CombatGroup* -Combatant::FindGroup(int type, int id) -{ - if (force) - return force->FindGroup(type, id); - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Combatant::AddMission(Mission* mission) -{ - mission_list.append(mission); -} - -// +--------------------------------------------------------------------+ - -double -Combatant::GetTargetStratFactor(int type) -{ - switch (type) { - case CombatGroup::FLEET: - case CombatGroup::CARRIER_GROUP: - case CombatGroup::BATTLE_GROUP: - case CombatGroup::DESTROYER_SQUADRON: return target_factor[0]; - - case CombatGroup::WING: - case CombatGroup::ATTACK_SQUADRON: - case CombatGroup::INTERCEPT_SQUADRON: - case CombatGroup::FIGHTER_SQUADRON: return target_factor[1]; - - case CombatGroup::BATTERY: - case CombatGroup::MISSILE: return target_factor[2]; - - case CombatGroup::BATTALION: - case CombatGroup::STARBASE: - case CombatGroup::C3I: - case CombatGroup::COMM_RELAY: - case CombatGroup::EARLY_WARNING: - case CombatGroup::FWD_CONTROL_CTR: - case CombatGroup::ECM: return target_factor[3]; - - case CombatGroup::SUPPORT: - case CombatGroup::COURIER: - case CombatGroup::MEDICAL: - case CombatGroup::SUPPLY: - case CombatGroup::REPAIR: return target_factor[4]; - } - - return target_factor[5]; -} - -// +--------------------------------------------------------------------+ - -void -Combatant::SetTargetStratFactor(int type, double factor) -{ - switch (type) { - case CombatGroup::FLEET: - case CombatGroup::CARRIER_GROUP: - case CombatGroup::BATTLE_GROUP: - case CombatGroup::DESTROYER_SQUADRON: target_factor[0] = factor; - break; - - case CombatGroup::WING: - case CombatGroup::ATTACK_SQUADRON: - case CombatGroup::INTERCEPT_SQUADRON: - case CombatGroup::FIGHTER_SQUADRON: target_factor[1] = factor; - break; - - case CombatGroup::BATTALION: - case CombatGroup::STARBASE: - case CombatGroup::BATTERY: - case CombatGroup::MISSILE: target_factor[2] = factor; - break; - - case CombatGroup::C3I: - case CombatGroup::COMM_RELAY: - case CombatGroup::EARLY_WARNING: - case CombatGroup::FWD_CONTROL_CTR: - case CombatGroup::ECM: target_factor[3] = factor; - break; - - case CombatGroup::SUPPORT: - case CombatGroup::COURIER: - case CombatGroup::MEDICAL: - case CombatGroup::SUPPLY: - case CombatGroup::REPAIR: target_factor[4] = factor; - break; - - default: target_factor[5] = factor; - break; - } -} - - diff --git a/Stars45/Combatant.h b/Stars45/Combatant.h deleted file mode 100644 index cb73285..0000000 --- a/Stars45/Combatant.h +++ /dev/null @@ -1,72 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - One side in a military conflict -*/ - -#ifndef Combatant_h -#define Combatant_h - -#include "Types.h" -#include "Geometry.h" -#include "Text.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class CombatGroup; -class Mission; - -// +--------------------------------------------------------------------+ - -class Combatant -{ -public: - static const char* TYPENAME() { return "Combatant"; } - - Combatant(const char* com_name, const char* file_name, int iff); - Combatant(const char* com_name, CombatGroup* force); - ~Combatant(); - - // operations: - - // accessors: - const char* Name() const { return name; } - int GetIFF() const { return iff; } - int Score() const { return score; } - const char* GetDescription() const { return name; } - CombatGroup* GetForce() { return force; } - CombatGroup* FindGroup(int type, int id=-1); - List& GetTargetList() { return target_list; } - List& GetDefendList() { return defend_list; } - List& GetMissionList() { return mission_list; } - - void AddMission(Mission* m); - void SetScore(int points) { score = points; } - void AddScore(int points) { score += points; } - - double GetTargetStratFactor(int type); - void SetTargetStratFactor(int type, double f); - -private: - Text name; - int iff; - int score; - - CombatGroup* force; - List target_list; - List defend_list; - List mission_list; - - double target_factor[8]; -}; - - -#endif // Combatant_h diff --git a/Stars45/ComboBox.cpp b/Stars45/ComboBox.cpp deleted file mode 100644 index 4269a96..0000000 --- a/Stars45/ComboBox.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Drop-down list of Buttons class -*/ - -#include "ComboBox.h" -#include "ComboList.h" -#include "Button.h" -#include "Video.h" -#include "Screen.h" -#include "Bitmap.h" -#include "Font.h" -#include "EventDispatch.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: -DEF_MAP_CLIENT(ComboBox, OnListSelect); -DEF_MAP_CLIENT(ComboBox, OnListExit); - -// +--------------------------------------------------------------------+ - -ComboBox::ComboBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid) - : ActiveWindow(p->GetScreen(), ax, ay, aw, ah, aid, 0, p) -{ - button_state = 0; - captured = 0; - pre_state = 0; - seln = 0; - list = 0; - list_showing = false; - border = true; - animated = true; - bevel_width = 5; - - char buf[32]; - sprintf_s(buf, "ComboBox %d", id); //-V576 - desc = buf; -} - -ComboBox::ComboBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid) - : ActiveWindow(s, ax, ay, aw, ah, aid) -{ - button_state = 0; - captured = 0; - pre_state = 0; - seln = 0; - list = 0; - list_showing = false; - border = true; - animated = true; - bevel_width = 5; - - char buf[32]; - sprintf_s(buf, "ComboBox %d", id); //-V576 - desc = buf; -} - -// +--------------------------------------------------------------------+ - -ComboBox::~ComboBox() -{ - items.destroy(); - - if (list && !list_showing) - delete list; -} - -// +--------------------------------------------------------------------+ - -void ComboBox::SetBevelWidth(short nNewValue) -{ - if (nNewValue < 0) nNewValue = 0; - bevel_width = nNewValue; -} - -void ComboBox::SetBorder(bool bNewValue) -{ - border = bNewValue; -} - -void ComboBox::SetBorderColor(Color newValue) -{ - border_color = newValue; -} - -void ComboBox::SetActiveColor(Color newValue) -{ - active_color = newValue; -} - -void ComboBox::SetAnimated(bool bNewValue) -{ - animated = bNewValue; -} - -// +--------------------------------------------------------------------+ - -void -ComboBox::Draw() -{ - int x = 0; - int y = 0; - int w = rect.w; - int h = rect.h; - - if (w < 1 || h < 1 || !shown) - return; - - Rect btn_rect(x,y,w,h); - - // draw the bevel: - DrawRectSimple(btn_rect, button_state); - - // draw the border: - if (border) - DrawRect(0,0,w-1,h-1,border_color); - - // draw the arrow: - POINT arrow[3]; - double h3 = (double)h/3.0; - - arrow[0].x = (int) (w-2*h3); - arrow[0].y = (int) (h3); - arrow[1].x = (int) (w-h3); - arrow[1].y = (int) (h3); - arrow[2].x = (int) ((arrow[1].x + arrow[0].x)/2); - arrow[2].y = (int) (2*h3); - - FillPoly(3, arrow, border_color); - - // draw text here: - Text caption = text; - if (GetSelectedIndex() >= 0) - caption = GetSelectedItem(); - - if (font && caption.length()) { - int border_size = 4; - - if (style & WIN_RAISED_FRAME && style & WIN_SUNK_FRAME) - border_size = 8; - - Rect label_rect = CalcLabelRect(); - int vert_space = label_rect.h; - int horz_space = label_rect.w; - - DrawText(caption.data(), 0, label_rect, DT_CALCRECT | DT_WORDBREAK | text_align); - vert_space = (vert_space - label_rect.h)/2; - - label_rect.w = horz_space; - - if (vert_space > 0) - label_rect.y += vert_space; - - if (animated && button_state > 0) { - label_rect.x += button_state; - label_rect.y += button_state; - } - - font->SetColor(fore_color); - DrawText(caption.data(), 0, label_rect, DT_WORDBREAK | text_align); - } -} - -Rect ComboBox::CalcLabelRect() -{ - // fit the text in the bevel: - Rect label_rect; - label_rect.x = 0; - label_rect.y = 0; - label_rect.w = rect.w; - label_rect.h = rect.h; - - label_rect.Deflate(bevel_width, bevel_width); - - return label_rect; -} - -// +--------------------------------------------------------------------+ - -void -ComboBox::DrawRectSimple(Rect& rect, int state) -{ - if (state && active_color != Color::Black) - FillRect(rect, active_color); - else - FillRect(rect, back_color); -} - -// +--------------------------------------------------------------------+ - -int ComboBox::OnMouseMove(int x, int y) -{ - bool dirty = false; - - if (captured) - { - ActiveWindow* test = GetCapture(); - - if (test != this) - { - captured = false; - button_state = 0; - dirty = true; - } - - else - { - if (button_state == 1) - { - if (!rect.Contains(x,y)) - { - button_state = 0; - dirty = true; - } - } - else - { - if (rect.Contains(x,y)) - { - button_state = 1; - dirty = true; - } - } - } - } - - return ActiveWindow::OnMouseMove(x,y); -} - -int ComboBox::OnLButtonDown(int x, int y) -{ - if (!captured) - captured = SetCapture(); - - button_state = 1; - - return ActiveWindow::OnLButtonDown(x,y); -} - -int ComboBox::OnLButtonUp(int x, int y) -{ - if (captured) { - ReleaseCapture(); - captured = 0; - } - - button_state = -1; - ShowList(); - Button::PlaySound(Button::SND_COMBO_OPEN); - return ActiveWindow::OnLButtonUp(x,y); -} - -int ComboBox::OnClick() -{ - return ActiveWindow::OnClick(); -} - -int ComboBox::OnMouseEnter(int mx, int my) -{ - if (button_state == 0) - button_state = -1; - - return ActiveWindow::OnMouseEnter(mx, my); -} - -int ComboBox::OnMouseExit(int mx, int my) -{ - if (button_state == -1) - button_state = 0; - - return ActiveWindow::OnMouseExit(mx, my); -} - -// +--------------------------------------------------------------------+ - -void ComboBox::MoveTo(const Rect& r) -{ - ActiveWindow::MoveTo(r); - - if (list) { - delete list; - list = 0; - } -} - -void ComboBox::ShowList() -{ - if (!list) { - list = new ComboList(this, screen, - rect.x, rect.y, - rect.w, rect.h, - items.size()); - - } - - if (list) { - list->SetTextAlign(text_align); - list->SetFont(font); - list->SetText(text); - list->SetSelection(seln); - list->SetItems(items); - - list->Show(); - list_showing = true; - - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) { - dispatch->MouseEnter(list); - dispatch->SetFocus(list); - } - - REGISTER_CLIENT(EID_CLICK, list, ComboBox, OnListSelect); - REGISTER_CLIENT(EID_MOUSE_EXIT, list, ComboBox, OnListExit); - } -} - -void ComboBox::HideList() -{ - if (list) { - // These will be handled by the list window itself (i hope) - UNREGISTER_CLIENT(EID_CLICK, list, ComboBox); - UNREGISTER_CLIENT(EID_MOUSE_EXIT, list, ComboBox); - - list->Hide(); - list_showing = false; - } -} - -// +--------------------------------------------------------------------+ - -void ComboBox::OnListSelect(AWEvent* event) -{ - if (list) { - int new_seln = list->GetSelectedIndex(); - - if (new_seln >= 0 && new_seln < items.size()) - seln = new_seln; - - HideList(); - OnSelect(); - Button::PlaySound(Button::SND_COMBO_SELECT); - } -} - -void ComboBox::OnListExit(AWEvent* event) -{ - //HideList(); - //Button::PlaySound(Button::SND_COMBO_CLOSE); -} - -// +--------------------------------------------------------------------+ - -int ComboBox::NumItems() -{ - return items.size(); -} - -void ComboBox::ClearItems() -{ - items.destroy(); - seln = 0; -} - -void ComboBox::AddItem(const char* item) -{ - Text* t = new Text(item); - - if (t) items.append(t); -} - -const char* ComboBox::GetItem(int index) -{ - if (index >= 0 && index < items.size()) - return items[index]->data(); - else - return 0; -} - -void ComboBox::SetItem(int index, const char* item) -{ - if (index >= 0 && index < items.size()) { - *items[index] = item; - } - - else { - Text* t = new Text(item); - if (t) - items.append(t); - } -} - -void ComboBox::SetLabel(const char* label) -{ - SetText(label); -} - -int ComboBox::GetCount() -{ - return items.size(); -} - -const char* ComboBox::GetSelectedItem() -{ - if (seln >= 0 && seln < items.size()) - return items[seln]->data(); - else - return 0; -} - -int ComboBox::GetSelectedIndex() -{ - if (seln >= 0 && seln < items.size()) - return seln; - else - return -1; -} - -void ComboBox::SetSelection(int index) -{ - if (seln != index && index >= 0 && index < items.size()) { - seln = index; - } -} - diff --git a/Stars45/ComboBox.h b/Stars45/ComboBox.h deleted file mode 100644 index a27f827..0000000 --- a/Stars45/ComboBox.h +++ /dev/null @@ -1,104 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ComboBox class -*/ - -#ifndef ComboBox_h -#define ComboBox_h - -#include "Types.h" -#include "ActiveWindow.h" -#include "Bitmap.h" - -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class ComboList; - -// +--------------------------------------------------------------------+ - -class ComboBox : public ActiveWindow -{ -public: - static const char* TYPENAME() { return "ComboBox"; } - - ComboBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid=0); - ComboBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid=0); - virtual ~ComboBox(); - - // Operations: - virtual void Draw(); - virtual void ShowList(); - virtual void HideList(); - virtual void MoveTo(const Rect& r); - - // Event Target Interface: - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnClick(); - virtual int OnMouseEnter(int x, int y); - virtual int OnMouseExit(int x, int y); - - virtual void OnListSelect(AWEvent* event); - virtual void OnListExit(AWEvent* event); - - // Property accessors: - virtual int NumItems(); - virtual void ClearItems(); - virtual void AddItem(const char* item); - virtual const char* GetItem(int index); - virtual void SetItem(int index, const char* item); - virtual void SetLabel(const char* label); - - virtual int GetCount(); - virtual const char* GetSelectedItem(); - virtual int GetSelectedIndex(); - virtual void SetSelection(int index); - - Color GetActiveColor() const { return active_color; } - void SetActiveColor(Color c); - bool GetAnimated() const { return animated; } - void SetAnimated(bool bNewValue); - short GetBevelWidth() const { return bevel_width; } - void SetBevelWidth(short nNewValue); - bool GetBorder() const { return border; } - void SetBorder(bool bNewValue); - Color GetBorderColor() const { return border_color; } - void SetBorderColor(Color c); - short GetButtonState() const { return button_state; } - void SetButtonState(short nNewValue); - - bool IsListShowing() const { return list_showing; } - -protected: - Rect CalcLabelRect(); - void DrawRectSimple(Rect& rect, int stat); - - List items; - ComboList* list; - bool list_showing; - bool animated; - bool border; - int seln; - int captured; - int bevel_width; - int button_state; - int pre_state; - - Color active_color; - Color border_color; -}; - -#endif // ComboBox_h - diff --git a/Stars45/ComboList.cpp b/Stars45/ComboList.cpp deleted file mode 100644 index 4d03809..0000000 --- a/Stars45/ComboList.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Drop-down list of Buttons class -*/ - -#define NOMINMAX - -#include - -#include "ComboList.h" -#include "ComboBox.h" -#include "Button.h" -#include "Video.h" -#include "Bitmap.h" -#include "Font.h" -#include "Screen.h" - -// +--------------------------------------------------------------------+ - -ComboList::ComboList(ComboBox* ctrl, ActiveWindow* p, int ax, int ay, int aw, int ah, int maxentries) - : ScrollWindow(p, ax, ay, aw, ah + (ah-2)*maxentries + 2, 0, 0, p), combo_box(ctrl) -{ - button_state = 0; - button_height = ah; - captured = 0; - seln = -1; - max_entries = maxentries; - scroll = 0; - scrolling = false; - border = true; - animated = true; - bevel_width = 5; - - if (ctrl) - CopyStyle(*ctrl); - - rect.h = (ah-2)*maxentries + 2; - - int screen_height = Video::GetInstance()->Height(); - - if (rect.h > screen_height) { - rect.y = 0; - rect.h = screen_height; - } - - else if (rect.y + rect.h > screen_height) { - rect.y = screen_height - rect.h; - } -} - -ComboList::ComboList(ComboBox* ctrl, Screen* s, int ax, int ay, int aw, int ah, int maxentries) - : ScrollWindow(s, ax, ay, aw, ah + (ah-2)*maxentries + 2, 0), combo_box(ctrl) -{ - button_state = 0; - button_height = ah; - captured = 0; - seln = -1; - max_entries = maxentries; - scroll = 0; - scrolling = false; - border = true; - animated = true; - bevel_width = 5; - - if (ctrl) - CopyStyle(*ctrl); - - rect.h = (ah-2)*maxentries + 2; - - int screen_height = Video::GetInstance()->Height(); - - if (rect.h > screen_height) { - rect.y = 0; - rect.h = screen_height; - } - - else if (rect.y + rect.h > screen_height) { - rect.y = screen_height - rect.h; - } - - screen->AddWindow(this); // just in case the base ctor couldn't do this -} - -// +--------------------------------------------------------------------+ - -ComboList::~ComboList() -{ - items.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -ComboList::CopyStyle(const ComboBox& ctrl) -{ - active_color = ctrl.GetActiveColor(); - border_color = ctrl.GetBorderColor(); - fore_color = ctrl.GetForeColor(); - back_color = ctrl.GetBackColor(); - - animated = ctrl.GetAnimated(); - bevel_width = ctrl.GetBevelWidth(); - border = ctrl.GetBorder(); -} - -// +--------------------------------------------------------------------+ - -void -ComboList::Show() -{ - if (!scrolling) { - scrolling = 1; - scroll = 0; - } - - ScrollWindow::Show(); -} - -void -ComboList::Hide() -{ - scrolling = 0; - scroll = 0; - ScrollWindow::Hide(); -} - -// +--------------------------------------------------------------------+ - -void -ComboList::Draw() -{ - int x = 0; - int y = 0; - int w = rect.w; - int h = button_height; - - int index = 0; - - // opening: - if (scrolling > 0) { - int limit = std::min(items.size(), max_entries); - - if (scroll < limit) { - if (limit > 6) - scroll += 4; - - else if (limit > 4) - scroll += 2; - - else - scroll += 1; - } - - if (scroll >= limit) { - scroll = limit; - scrolling = 0; - } - } - - // closing: - else if (scrolling < 0) { - if (scroll > 0) - scroll--; - else - scrolling = 0; - } - - if (items.size() < 1) { - Rect btn_rect(x,y,w,h); - DrawItem(" ", btn_rect, 0); - } - else { - ListIter item = items; - while (++item && index < max_entries) { - Rect btn_rect(x,y,w,h); - int sub_state = (index == seln) ? button_state : 0; - - DrawItem(*item, btn_rect, sub_state); - - y += button_height-2; - index++; - } - } - - DrawRect(0,0,rect.w-1,rect.h-1,fore_color); -} - -// +--------------------------------------------------------------------+ - -void -ComboList::DrawRectSimple(Rect& rect, int state) -{ - if (state && active_color != Color::Black) - FillRect(rect, active_color); - else - FillRect(rect, back_color); -} - -void -ComboList::DrawItem(Text label, Rect& btn_rect, int state) -{ - int x = btn_rect.x; - int y = btn_rect.y; - int w = btn_rect.w; - int h = btn_rect.h; - - // draw the bevel: - DrawRectSimple(btn_rect, state); - - // draw text here: - if (font && label.length()) { - int border_size = 4; - - if (style & WIN_RAISED_FRAME && style & WIN_SUNK_FRAME) - border_size = 8; - - Rect label_rect = CalcLabelRect(btn_rect); - int vert_space = label_rect.h; - int horz_space = label_rect.w; - - DrawText(label.data(), 0, label_rect, DT_CALCRECT | DT_WORDBREAK | text_align); - vert_space = (vert_space - label_rect.h)/2; - - label_rect.w = horz_space; - - if (vert_space > 0) - label_rect.y += vert_space; - - if (animated && state > 0) { - label_rect.x += state; - label_rect.y += state; - } - - font->SetColor(fore_color); - DrawText(label.data(), 0, label_rect, DT_WORDBREAK | text_align); - } -} - -Rect ComboList::CalcLabelRect(const Rect& btn_rect) -{ - // fit the text in the bevel: - Rect label_rect = btn_rect; - label_rect.Deflate(bevel_width, bevel_width); - - return label_rect; -} - -int ComboList::CalcSeln(int x, int y) -{ - y -= rect.y; - - if (button_height < 1) - return 0; - - return (int) (y / (button_height-2)); -} - -// +--------------------------------------------------------------------+ - -int ComboList::OnMouseMove(int x, int y) -{ - if (captured) - { - ActiveWindow* test = GetCapture(); - - if (test != this) - { - captured = false; - button_state = -1; - } - } - - int new_seln = CalcSeln(x,y); - - if (new_seln != seln) { - seln = new_seln; - Button::PlaySound(Button::SND_COMBO_HILITE); - } - - return ActiveWindow::OnMouseMove(x,y); -} - -int ComboList::OnLButtonDown(int x, int y) -{ - if (!captured) - captured = SetCapture(); - - seln = CalcSeln(x,y); - button_state = 1; - - return ActiveWindow::OnLButtonDown(x,y); -} - -int ComboList::OnLButtonUp(int x, int y) -{ - if (captured) { - ReleaseCapture(); - captured = 0; - } - - seln = CalcSeln(x,y); - button_state = -1; - return ActiveWindow::OnLButtonUp(x,y); -} - -int ComboList::OnClick() -{ - return ActiveWindow::OnClick(); -} - -int ComboList::OnMouseEnter(int mx, int my) -{ - if (button_state == 0) - button_state = -1; - - return ActiveWindow::OnMouseEnter(mx, my); -} - -int ComboList::OnMouseExit(int mx, int my) -{ - if (button_state == -1) - button_state = 0; - - return ActiveWindow::OnMouseExit(mx, my); -} - -void ComboList::KillFocus() -{ - if (combo_box) - combo_box->HideList(); -} - -// +--------------------------------------------------------------------+ - -void ComboList::ClearItems() -{ - items.destroy(); -} - -// +--------------------------------------------------------------------+ - -void ComboList::AddItem(const char* item) -{ - items.append(new Text(item)); -} - -void ComboList::AddItems(ListIter item) -{ - while (++item) - items.append(new Text(*item)); -} - -void ComboList::SetItems(ListIter item) -{ - items.destroy(); - while (++item) - items.append(new Text(*item)); - - // Resize window: - - int ah = button_height; - max_entries = items.size(); - Rect r = rect; - r.y = combo_box->Y(); - int length = max_entries; - - if (length < 1) - length = 1; - - r.h = (ah-2)*length + 2; - - int screen_height = Video::GetInstance()->Height(); - - if (r.h > screen_height) { - r.y = 0; - r.h = screen_height; - } - - else if (r.y + r.h > screen_height) { - r.y = screen_height - r.h; - } - - MoveTo(r); -} - -const char* ComboList::GetItem(int index) -{ - if (index >= 0 && index < items.size()) - return items[index]->data(); - else - return 0; -} - -void ComboList::SetItem(int index, const char* item) -{ - if (index >= 0 && index < items.size()) - *items[index] = item; - else - items.append(new Text(item)); -} - -int ComboList::GetCount() -{ - return items.size(); -} - -const char* ComboList::GetSelectedItem() -{ - if (seln >= 0 && seln < items.size()) - return items[seln]->data(); - else - return 0; -} - -int ComboList::GetSelectedIndex() -{ - if (seln >= 0 && seln < items.size()) - return seln; - else - return -1; -} - -void ComboList::SetSelection(int index) -{ - if (index >= 0 && index < items.size()) - seln = index; -} - diff --git a/Stars45/ComboList.h b/Stars45/ComboList.h deleted file mode 100644 index 290b328..0000000 --- a/Stars45/ComboList.h +++ /dev/null @@ -1,91 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ComboList class -*/ - -#ifndef ComboList_h -#define ComboList_h - -#include "Types.h" -#include "ScrollWindow.h" -#include "Bitmap.h" - -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class ComboBox; - -// +--------------------------------------------------------------------+ - -class ComboList : public ScrollWindow -{ -public: - static const char* TYPENAME() { return "ComboList"; } - - ComboList(ComboBox* ctrl, ActiveWindow* p, int ax, int ay, int aw, int ah, int maxentries); - ComboList(ComboBox* ctrl, Screen* s, int ax, int ay, int aw, int ah, int maxentries); - virtual ~ComboList(); - - // Operations: - virtual void Draw(); - virtual void Show(); - virtual void Hide(); - - // Event Target Interface: - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnClick(); - virtual int OnMouseEnter(int x, int y); - virtual int OnMouseExit(int x, int y); - virtual void KillFocus(); - - // Property accessors: - virtual void ClearItems(); - virtual void AddItem(const char* item); - virtual void AddItems(ListIter item_list); - virtual void SetItems(ListIter item_list); - virtual const char* GetItem(int index); - virtual void SetItem(int index, const char* item); - - virtual int GetCount(); - virtual const char* GetSelectedItem(); - virtual int GetSelectedIndex(); - virtual void SetSelection(int index); - -protected: - void DrawRectSimple(Rect& rect, int stat); - void DrawItem(Text label, Rect& btn_rect, int state); - Rect CalcLabelRect(const Rect& btn_rect); - int CalcSeln(int x, int y); - void CopyStyle(const ComboBox& ctrl); - - ComboBox* combo_box; - List items; - bool animated; - bool border; - int seln; - int captured; - int bevel_width; - int button_state; - int button_height; - int max_entries; - int scroll; - int scrolling; - - Color active_color; - Color border_color; -}; - -#endif // ComboList_h - diff --git a/Stars45/Component.cpp b/Stars45/Component.cpp deleted file mode 100644 index 97e1460..0000000 --- a/Stars45/Component.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Generic ship system sub-component class -*/ - -#include "Component.h" -#include "System.h" -#include "Game.h" - -// +----------------------------------------------------------------------+ - -ComponentDesign::ComponentDesign() -: repair_time(0.0f), replace_time(0.0f), spares(0), affects(0) -{ } - -// +----------------------------------------------------------------------+ - -ComponentDesign::~ComponentDesign() -{ } - -// +----------------------------------------------------------------------+ - -Component::Component(ComponentDesign* d, System* s) -: design(d), system(s), -status(NOMINAL), availability(100.0f), time_remaining(0.0f), -spares(0), jerried(0) -{ - if (design) - spares = design->spares; -} - -// +----------------------------------------------------------------------+ - -Component::Component(const Component& c) -: design(c.design), system(c.system), -status(c.status), availability(c.availability), time_remaining(c.time_remaining), -spares(c.spares), jerried(c.jerried) -{ -} - -// +--------------------------------------------------------------------+ - -Component::~Component() -{ } - -// +--------------------------------------------------------------------+ - -void -Component::ExecMaintFrame(double seconds) -{ - if (status > NOMINAL) { - time_remaining -= (float) seconds; - - // when repairs are complete: - if (time_remaining <= 0) { - if (status == REPAIR) { - // did we just jerry-rig a failed component? - if (availability < 50) - jerried++; - - if (jerried < 5) - availability += 50.0f - 10 * jerried; - if (availability > 100) availability = 100.0f; - } - else { - availability = 100.0f; - } - - if (availability > 99) - status = NOMINAL; - else if (availability > 49) - status = DEGRADED; - else - status = CRITICAL; - - time_remaining = 0.0f; - - if (system) - system->CalcStatus(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Component::ApplyDamage(double damage) -{ - availability -= (float) damage; - if (availability < 1) availability = 0.0f; - - if (status < REPLACE) { - if (availability > 99) - status = NOMINAL; - else if (availability > 49) - status = DEGRADED; - else - status = CRITICAL; - } - - if (system) - system->CalcStatus(); -} - -// +--------------------------------------------------------------------+ - -void -Component::Repair() -{ - if (status < NOMINAL) { - status = REPAIR; - time_remaining = design->repair_time; - - if (system) - system->CalcStatus(); - } -} - -// +--------------------------------------------------------------------+ - -void -Component::Replace() -{ - if (status <= NOMINAL) { - status = REPLACE; - spares--; - time_remaining = design->replace_time; - - if (system) - system->CalcStatus(); - } -} - -// +--------------------------------------------------------------------+ - -float -Component::Availability() const -{ - if (status > NOMINAL && availability > 50) - return 50.0f; - - return availability; -} - -float -Component::TimeRemaining() const -{ - return (float) time_remaining; -} - -int -Component::SpareCount() const -{ - return spares; -} - -bool -Component::IsJerried() const -{ - return jerried?true:false; -} - -int -Component::NumJerried() const -{ - return jerried; -} \ No newline at end of file diff --git a/Stars45/Component.h b/Stars45/Component.h deleted file mode 100644 index 55763c3..0000000 --- a/Stars45/Component.h +++ /dev/null @@ -1,99 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Generic ship system sub-component class -*/ - -#ifndef Component_h -#define Component_h - -#include "Types.h" -#include "Geometry.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class ComponentDesign -{ -public: - static const char* TYPENAME() { return "ComponentDesign"; } - - ComponentDesign(); - ~ComponentDesign(); - int operator == (const ComponentDesign& rhs) const { return (name == rhs.name); } - - // identification: - Text name; - Text abrv; - - float repair_time; - float replace_time; - int spares; - DWORD affects; -}; - -// +--------------------------------------------------------------------+ - -class System; - -// +--------------------------------------------------------------------+ - -class Component -{ -public: - static const char* TYPENAME() { return "Component"; } - - enum STATUS { DESTROYED, CRITICAL, DEGRADED, NOMINAL, REPLACE, REPAIR }; - enum DAMAGE { DAMAGE_EFFICIENCY = 0x01, - DAMAGE_SAFETY = 0x02, - DAMAGE_STABILITY = 0x04 }; - - Component(ComponentDesign* d, System* s); - Component(const Component& c); - virtual ~Component(); - - const char* Name() const { return design->name; } - const char* Abbreviation() const { return design->abrv; } - float RepairTime() const { return design->repair_time; } - float ReplaceTime() const { return design->replace_time; } - - bool DamageEfficiency() const { return (design->affects & DAMAGE_EFFICIENCY)?true:false; } - bool DamageSafety() const { return (design->affects & DAMAGE_SAFETY)?true:false; } - bool DamageStability() const { return (design->affects & DAMAGE_STABILITY)?true:false; } - - STATUS Status() const { return status; } - float Availability() const; - float TimeRemaining() const; - int SpareCount() const; - bool IsJerried() const; - int NumJerried() const; - - void SetSystem(System* s) { system = s; } - System* GetSystem() const { return system; } - - virtual void ApplyDamage(double damage); - virtual void ExecMaintFrame(double seconds); - virtual void Repair(); - virtual void Replace(); - -protected: - ComponentDesign* design; - - // Component health status: - STATUS status; - float availability; - float time_remaining; - int spares; - int jerried; - System* system; -}; - -#endif // Component_h - diff --git a/Stars45/Computer.cpp b/Stars45/Computer.cpp deleted file mode 100644 index 60f5ee0..0000000 --- a/Stars45/Computer.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Computer System class -*/ - -#include "Computer.h" -#include "Game.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ - -static int computer_value[] = { - 0, 1, 1, 1, 1 -}; - -// +----------------------------------------------------------------------+ - -Computer::Computer(int comp_type, const char* comp_name) -: System(COMPUTER, comp_type, comp_name, 1, 1, 1, 1) -{ - SetAbbreviation(ContentBundle::GetInstance()->GetText("sys.computer.abrv")); - power_flags = POWER_WATTS | POWER_CRITICAL; - - if (subtype == FLIGHT) { - crit_level = -1.0f; - } -} - -// +----------------------------------------------------------------------+ - -Computer::Computer(const Computer& c) -: System(c) -{ - Mount(c); - SetAbbreviation(c.Abbreviation()); - power_flags = POWER_WATTS | POWER_CRITICAL; - - if (subtype == FLIGHT) { - crit_level = -1.0f; - } -} - -// +--------------------------------------------------------------------+ - -Computer::~Computer() -{ } - -// +--------------------------------------------------------------------+ - -void -Computer::ApplyDamage(double damage) -{ - System::ApplyDamage(damage); -} - -// +--------------------------------------------------------------------+ - -void -Computer::ExecFrame(double seconds) -{ - energy = 0.0f; - System::ExecFrame(seconds); -} - -// +--------------------------------------------------------------------+ - -void -Computer::Distribute(double delivered_energy, double seconds) -{ - if (IsPowerOn()) { - // convert Joules to Watts: - energy = (float) (delivered_energy/seconds); - - // brown out: - if (energy < capacity*0.75f) - power_on = false; - - // spike: - else if (energy > capacity*1.5f) { - power_on = false; - ApplyDamage(50); - } - } -} diff --git a/Stars45/Computer.h b/Stars45/Computer.h deleted file mode 100644 index 1117799..0000000 --- a/Stars45/Computer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Various computer systems class -*/ - -#ifndef Computer_h -#define Computer_h - -#include "Types.h" -#include "System.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Computer : public System -{ -public: - enum CompType { AVIONICS=1, FLIGHT, TACTICAL }; - - Computer(int comp_type, const char* comp_name); - Computer(const Computer& rhs); - virtual ~Computer(); - - virtual void ApplyDamage(double damage); - virtual void ExecFrame(double seconds); - virtual void Distribute(double delivered_energy, double seconds); - -protected: -}; - -#endif // Computer_h - diff --git a/Stars45/ConfirmDlg.cpp b/Stars45/ConfirmDlg.cpp deleted file mode 100644 index 4e528f5..0000000 --- a/Stars45/ConfirmDlg.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - General-purpose confirmation dialog class -*/ - -#include "ConfirmDlg.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "FormatUtil.h" - -#include "Game.h" -#include "Keyboard.h" -#include "Button.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(ConfirmDlg, OnApply); -DEF_MAP_CLIENT(ConfirmDlg, OnCancel); - -// +--------------------------------------------------------------------+ - -ConfirmDlg::ConfirmDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -parent_control(0), btn_apply(0), btn_cancel(0) -{ - Init(def); -} - -ConfirmDlg::~ConfirmDlg() -{ -} - -void -ConfirmDlg::RegisterControls() -{ - if (btn_apply) - return; - - btn_apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, btn_apply, ConfirmDlg, OnApply); - - btn_cancel = (Button*) FindControl(2); - REGISTER_CLIENT(EID_CLICK, btn_cancel, ConfirmDlg, OnCancel); - - lbl_title = FindControl(100); - lbl_message = FindControl(101); -} - -// +--------------------------------------------------------------------+ - -ActiveWindow* -ConfirmDlg::GetParentControl() -{ - return parent_control; -} - -void -ConfirmDlg::SetParentControl(ActiveWindow* p) -{ - parent_control = p; -} - -Text -ConfirmDlg::GetTitle() -{ - if (lbl_title) - return lbl_title->GetText(); - - return ""; -} - -void -ConfirmDlg::SetTitle(const char* t) -{ - if (lbl_title) - lbl_title->SetText(t); -} - -Text -ConfirmDlg::GetMessage() -{ - if (lbl_message) - return lbl_message->GetText(); - - return ""; -} - -void -ConfirmDlg::SetMessage(const char* m) -{ - if (lbl_message) - lbl_message->SetText(m); -} - -// +--------------------------------------------------------------------+ - -void -ConfirmDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnApply(0); - } - - if (Keyboard::KeyDown(VK_ESCAPE)) { - OnCancel(0); - } -} - -// +--------------------------------------------------------------------+ - -void -ConfirmDlg::Show() -{ - if (!IsShown()) { - Button::PlaySound(Button::SND_CONFIRM); - } - - FormWindow::Show(); - SetFocus(); -} - -// +--------------------------------------------------------------------+ - -void -ConfirmDlg::OnApply(AWEvent* event) -{ - manager->HideConfirmDlg(); - - if (parent_control) - parent_control->ClientEvent(EID_USER_1); -} - -void -ConfirmDlg::OnCancel(AWEvent* event) -{ - manager->HideConfirmDlg(); -} - -// +--------------------------------------------------------------------+ diff --git a/Stars45/ConfirmDlg.h b/Stars45/ConfirmDlg.h deleted file mode 100644 index d57235c..0000000 --- a/Stars45/ConfirmDlg.h +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - General-purpose confirmation dialog class -*/ - -#ifndef ConfirmDlg_h -#define ConfirmDlg_h - -#include "Types.h" -#include "FormWindow.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; - -// +--------------------------------------------------------------------+ - -class ConfirmDlg : public FormWindow -{ -public: - ConfirmDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~ConfirmDlg(); - - virtual void RegisterControls(); - virtual void Show(); - - ActiveWindow* GetParentControl(); - void SetParentControl(ActiveWindow* p); - - Text GetTitle(); - void SetTitle(const char* t); - - Text GetMessage(); - void SetMessage(const char* m); - - // Operations: - virtual void ExecFrame(); - - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - -protected: - MenuScreen* manager; - - ActiveWindow* lbl_title; - ActiveWindow* lbl_message; - - Button* btn_apply; - Button* btn_cancel; - - ActiveWindow* parent_control; -}; - -#endif // ConfirmDlg_h - diff --git a/Stars45/Contact.cpp b/Stars45/Contact.cpp deleted file mode 100644 index 2dbec5a..0000000 --- a/Stars45/Contact.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Integrated (Passive and Active) Sensor Package class implementation -*/ - -#include "Contact.h" -#include "Drone.h" -#include "Sensor.h" -#include "Ship.h" -#include "Sim.h" -#include "WeaponDesign.h" - -#include "Game.h" -#include "Clock.h" - -// +----------------------------------------------------------------------+ - -const int DEFAULT_TRACK_UPDATE = 500; // milliseconds -const int DEFAULT_TRACK_LENGTH = 20; // 10 seconds -const double DEFAULT_TRACK_AGE = 10; // 10 seconds -const double SENSOR_THRESHOLD = 0.25; - -// +----------------------------------------------------------------------+ - -Contact::Contact() -: ship(0), shot(0), d_pas(0.0f), d_act(0.0f), -track(0), ntrack(0), time(0), track_time(0), probe(false) -{ - acquire_time = Clock::GetInstance()->GameTime(); -} - -Contact::Contact(Ship* s, float p, float a) -: ship(s), shot(0), d_pas(p), d_act(a), -track(0), ntrack(0), time(0), track_time(0), probe(false) -{ - acquire_time = Clock::GetInstance()->GameTime(); - Observe(ship); -} - -Contact::Contact(Shot* s, float p, float a) -: ship(0), shot(s), d_pas(p), d_act(a), -track(0), ntrack(0), time(0), track_time(0), probe(false) -{ - acquire_time = Clock::GetInstance()->GameTime(); - Observe(shot); -} - -// +----------------------------------------------------------------------+ - -Contact::~Contact() -{ - delete [] track; -} - -// +----------------------------------------------------------------------+ - -int -Contact::operator == (const Contact& c) const -{ - if (ship) - return ship == c.ship; - - else if (shot) - return shot == c.shot; - - return 0; -} - -// +----------------------------------------------------------------------+ - -bool -Contact::Update(SimObject* obj) -{ - if (obj == ship || obj == shot) { - ship = 0; - shot = 0; - d_act = 0; - d_pas = 0; - - ClearTrack(); - } - - return SimObserver::Update(obj); -} - -const char* -Contact::GetObserverName() const -{ - static char name[128]; - - if (ship) - sprintf_s(name, "Contact Ship='%s'", ship->Name()); - else if (shot) - sprintf_s(name, "Contact Shot='%s' %s", shot->Name(), shot->DesignName()); - else - sprintf_s(name, "Contact (unknown)"); - - return name; -} - -// +----------------------------------------------------------------------+ - -double -Contact::Age() const -{ - double age = 0; - - if (!ship && !shot) - return age; - - double seconds = (Clock::GetInstance()->GameTime() - time) / 1000.0; - - age = 1.0 - seconds/DEFAULT_TRACK_AGE; - - if (age < 0) - age = 0; - - return age; -} - -int -Contact::GetIFF(const Ship* observer) const -{ - int i = 0; - - if (ship) { - i = ship->GetIFF(); - - // if the contact is on our side or has locked us up, - // we know whose side he's on. - - // Otherwise: - if (i != observer->GetIFF() && !Threat(observer)) { - if (d_pas < 2*SENSOR_THRESHOLD && d_act < SENSOR_THRESHOLD && !Visible(observer)) - i = -1000; // indeterminate iff reading - } - } - - else if (shot && shot->Owner()) { - i = shot->Owner()->GetIFF(); - } - - return i; -} - -bool -Contact::ActLock() const -{ - return d_act >= SENSOR_THRESHOLD; -} - -bool -Contact::PasLock() const -{ - return d_pas >= SENSOR_THRESHOLD; -} - -// +----------------------------------------------------------------------+ - -void -Contact::GetBearing(const Ship* observer, double& az, double& el, double& rng) const -{ - // translate: - Point targ_pt = loc - observer->Location(); - - // rotate: - const Camera* cam = &observer->Cam(); - double tx = targ_pt * cam->vrt(); - double ty = targ_pt * cam->vup(); - double tz = targ_pt * cam->vpn(); - - // convert to spherical coords: - rng = targ_pt.length(); - az = asin(fabs(tx) / rng); - el = asin(fabs(ty) / rng); - - if (tx < 0) az = -az; - if (ty < 0) el = -el; - - // correct az/el for back hemisphere: - if (tz < 0) { - if (az < 0) az = -PI - az; - else az = PI - az; - } -} - -double -Contact::Range(const Ship* observer, double limit) const -{ - double r = Point(loc - observer->Location()).length(); - - // if passive only, return approximate range: - if (!ActLock()) { - const int chunk = 25000; - - if (!PasLock()) { - r = (int) limit; - } - - else if (r <= chunk) { - r = chunk; - } - - else { - int r1 = (int) (r + chunk/2) / chunk; - r = r1 * chunk; - } - } - - return r; -} - -// +----------------------------------------------------------------------+ - -bool -Contact::InFront(const Ship* observer) const -{ - // translate: - Point targ_pt = loc - observer->Location(); - - // rotate: - const Camera* cam = &observer->Cam(); - double tz = targ_pt * cam->vpn(); - - if (tz > 1.0) - return true; - - return false; -} - -bool -Contact::Threat(const Ship* observer) const -{ - bool threat = false; - - if (observer && observer->Life() != 0) { - if (ship && ship->Life() != 0) { - threat = (ship->GetIFF() && - ship->GetIFF() != observer->GetIFF() && - ship->GetEMCON() > 2 && - ship->IsTracking((Ship*) observer) && - ship->Weapons().size() > 0); - - if (threat && observer->GetIFF() == 0) - threat = ship->GetIFF() > 1; - } - - else if (shot) { - threat = shot->IsTracking((Ship*) observer); - - if (!threat && shot->Design()->probe && shot->GetIFF() != observer->GetIFF()) { - Point probe_pt = shot->Location() - observer->Location(); - double prng = probe_pt.length(); - - threat = (prng < shot->Design()->lethal_radius); - } - } - } - - return threat; -} - -bool -Contact::Visible(const Ship* observer) const -{ - // translate: - Point targ_pt = loc - observer->Location(); - double radius = 0; - - if (ship) - radius = ship->Radius(); - - else if (shot) - radius = shot->Radius(); - - // rotate: - const Camera* cam = &observer->Cam(); - double rng = targ_pt.length(); - - return radius/rng > 0.002; -} - -// +----------------------------------------------------------------------+ - -void -Contact::Reset() -{ - if (Game::GetInstance()->Paused()) return; - - float step_down = (float) (Clock::GetInstance()->Delta() / 10); - - if (d_pas > 0) - d_pas -= step_down; - - if (d_act > 0) - d_act -= step_down; -} - -void -Contact::Merge(Contact* c) -{ - if (c->GetShip() == ship && c->GetShot() == shot) { - if (c->d_pas > d_pas) - d_pas = c->d_pas; - - if (c->d_act > d_act) - d_act = c->d_act; - } -} - -void -Contact::ClearTrack() -{ - delete [] track; - track = 0; - ntrack = 0; -} - -void -Contact::UpdateTrack() -{ - time = Clock::GetInstance()->GameTime(); - - if (shot || (ship && ship->IsGroundUnit())) - return; - - if (!track) { - track = new Point[DEFAULT_TRACK_LENGTH]; - track[0] = loc; - ntrack = 1; - track_time = time; - } - - else if (time - track_time > DEFAULT_TRACK_UPDATE) { - if (loc != track[0]) { - for (int i = DEFAULT_TRACK_LENGTH-2; i >= 0; i--) - track[i+1] = track[i]; - - track[0] = loc; - if (ntrack < DEFAULT_TRACK_LENGTH) ntrack++; - } - - track_time = time; - } -} - -// +----------------------------------------------------------------------+ - -Point -Contact::TrackPoint(int i) const -{ - if (track && i < ntrack) - return track[i]; - - return Point(); -} diff --git a/Stars45/Contact.h b/Stars45/Contact.h deleted file mode 100644 index 7177e6b..0000000 --- a/Stars45/Contact.h +++ /dev/null @@ -1,90 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Sensor Contact class -*/ - -#ifndef Contact_h -#define Contact_h - -#include "Types.h" -#include "SimObject.h" -#include "System.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class Shot; - -class Contact : public SimObserver -{ - friend class Sensor; - -public: - static const char* TYPENAME() { return "Contact"; } - - Contact(); - Contact(Ship* s, float p, float a); - Contact(Shot* s, float p, float a); - virtual ~Contact(); - - int operator == (const Contact& c) const; - - Ship* GetShip() const { return ship; } - Shot* GetShot() const { return shot; } - Point Location() const { return loc; } - - double PasReturn() const { return d_pas; } - double ActReturn() const { return d_act; } - bool PasLock() const; - bool ActLock() const; - double Age() const; - bool IsProbed() const { return probe; } - - DWORD AcquisitionTime() const { return acquire_time; } - - int GetIFF(const Ship* observer) const; - void GetBearing(const Ship* observer, double& az, double& el, double& r) const; - double Range(const Ship* observer, - double limit=75e3) const; - - bool InFront(const Ship* observer) const; - bool Threat(const Ship* observer) const; - bool Visible(const Ship* observer) const; - - void Reset(); - void Merge(Contact* c); - void ClearTrack(); - void UpdateTrack(); - int TrackLength() const { return ntrack; } - Point TrackPoint(int i) const; - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - -private: - Ship* ship; - Shot* shot; - Point loc; - DWORD acquire_time; - DWORD time; - - Point* track; - int ntrack; - DWORD track_time; - - float d_pas; // power output - float d_act; // mass, size - bool probe; // scanned by probe -}; - -#endif // Contact_h - diff --git a/Stars45/ContentBundle.cpp b/Stars45/ContentBundle.cpp deleted file mode 100644 index cd10893..0000000 --- a/Stars45/ContentBundle.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Chained collection of localized strings -*/ - -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -ContentBundle* ContentBundle::GetInstance() -{ - static ContentBundle instance{}; - return &instance; -} - -// +--------------------------------------------------------------------+ - -ContentBundle::ContentBundle() : ContentBundle("content", nullptr) -{ -} - -// +--------------------------------------------------------------------+ - -ContentBundle::ContentBundle(const char* bundle, Locale* locale) -{ - Load(bundle, locale); -} - -// +--------------------------------------------------------------------+ - -ContentBundle::~ContentBundle() -{ -} - -// +--------------------------------------------------------------------+ - -bool -ContentBundle::Init() -{ - DataLoader* loader = DataLoader::GetLoader(); - List bundles; - - loader->SetDataPath("Content/"); - loader->ListFiles("content*", bundles); - - ListIter iter = bundles; - while (++iter) { - Text* filename = iter.value(); - int n = filename->indexOf('_'); - if (n > 0) { - Locale::ParseLocale(filename->data() + n); // unused? - } - } - - loader->SetDataPath(0); - return true; -} - -// +--------------------------------------------------------------------+ - -void -ContentBundle::UseLocale(Locale* locale) -{ - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Content/"); - Load("content", locale); - loader->SetDataPath(nullptr); -} - -// +--------------------------------------------------------------------+ - -void -ContentBundle::Load(const char* bundle, Locale* locale) -{ - if (values.size() > 0) { - values.clear(); - } - Text file = FindFile(bundle, locale); - if (file.length() > 0) { - LoadBundle(file); - } -} - -// +--------------------------------------------------------------------+ - -Text -ContentBundle::GetText(const char* key) const -{ - return values.find(key, Text(key)); -} - -// +--------------------------------------------------------------------+ - -Text -ContentBundle::FindFile(const char* bundle, Locale* locale) -{ - Text result; - Text basename = Text(bundle); - DataLoader* loader = DataLoader::GetLoader(); - - if (loader && bundle) { - if (locale) { - result = basename + locale->GetFullCode() + ".txt"; - - if (loader->FindFile(result)) - return result; - - result = basename + "_" + locale->GetLanguage() + ".txt"; - - if (loader->FindFile(result)) - return result; - } - - result = basename + ".txt"; - - if (loader->FindFile(result)) - return result; - } - - return Text(); -} - -// +--------------------------------------------------------------------+ - -void -ContentBundle::LoadBundle(const char* filename) -{ - DataLoader* loader = DataLoader::GetLoader(); - if (loader && filename && *filename) { - BYTE* buffer = 0; - loader->LoadBuffer(filename, buffer, true, true); - if (buffer && *buffer) { - char key[1024]; - char val[2048]; - char* p = (char*) buffer; - int s = 0, ik = 0, iv = 0; - - key[0] = 0; - val[0] = 0; - - while (*p) { - if (*p == '=') { - s = 1; - } - else if (*p == '\n' || *p == '\r') { - if (key[0] && val[0]) - values.insert(Text(key).trim(), Text(val).trim()); - - ZeroMemory(key, 1024); - ZeroMemory(val, 2048); - s = 0; - ik = 0; - iv = 0; - } - else if (s == 0) { - if (!key[0]) { - if (*p == '#') { - s = -1; // comment - } - else if (!isspace(*p)) { - key[ik++] = *p; - } - } - else { - key[ik++] = *p; - } - } - else if (s == 1) { - if (!isspace(*p)) { - s = 2; - val[iv++] = *p; - } - } - else if (s == 2) { - val[iv++] = *p; - } - - p++; - } - - loader->ReleaseBuffer(buffer); - } - } -} diff --git a/Stars45/ContentBundle.h b/Stars45/ContentBundle.h deleted file mode 100644 index f94e0d9..0000000 --- a/Stars45/ContentBundle.h +++ /dev/null @@ -1,56 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Chained collection of localized strings -*/ - -#ifndef ContentBundle_h -#define ContentBundle_h - -#include "Types.h" -#include "Dictionary.h" -#include "Text.h" -#include "Locale_ss.h" - -// +--------------------------------------------------------------------+ - -class ContentBundle -{ -public: - static const char* TYPENAME() { return "ContentBundle"; } - - static ContentBundle* GetInstance(); - - ContentBundle(); - ContentBundle(const char* bundle, Locale* locale); - virtual ~ContentBundle(); - - bool Init(); - void UseLocale(Locale* locale); - void Load(const char* bundle, Locale* locale); - - ContentBundle(ContentBundle&& that) = delete; - ContentBundle(const ContentBundle& that) = delete; - operator = (const ContentBundle& that) = delete; - - const Text& GetName() const { return name; } - Text GetText(const char* key) const; - bool IsLoaded() const { return !values.isEmpty(); } - -protected: - void LoadBundle(const char* filename); - Text FindFile(const char* bundle, Locale* locale); - - Text name; - Dictionary values; -}; - -#endif // ContentBundle_h - diff --git a/Stars45/CtlDlg.cpp b/Stars45/CtlDlg.cpp deleted file mode 100644 index fc74e17..0000000 --- a/Stars45/CtlDlg.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Control Options (keyboard/joystick) Dialog Active Window class -*/ - -#include "CtlDlg.h" -#include "KeyDlg.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "Ship.h" - -#include "DataLoader.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Joystick.h" -#include "MachineInfo.h" -#include "Clock.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CtlDlg, OnCommand); -DEF_MAP_CLIENT(CtlDlg, OnCategory); -DEF_MAP_CLIENT(CtlDlg, OnControlModel); -DEF_MAP_CLIENT(CtlDlg, OnJoySelect); -DEF_MAP_CLIENT(CtlDlg, OnJoyThrottle); -DEF_MAP_CLIENT(CtlDlg, OnJoyRudder); -DEF_MAP_CLIENT(CtlDlg, OnJoySensitivity); -DEF_MAP_CLIENT(CtlDlg, OnJoyAxis); -DEF_MAP_CLIENT(CtlDlg, OnMouseSelect); -DEF_MAP_CLIENT(CtlDlg, OnMouseSensitivity); -DEF_MAP_CLIENT(CtlDlg, OnMouseInvert); -DEF_MAP_CLIENT(CtlDlg, OnApply); -DEF_MAP_CLIENT(CtlDlg, OnCancel); -DEF_MAP_CLIENT(CtlDlg, OnAudio); -DEF_MAP_CLIENT(CtlDlg, OnVideo); -DEF_MAP_CLIENT(CtlDlg, OnOptions); -DEF_MAP_CLIENT(CtlDlg, OnControls); -DEF_MAP_CLIENT(CtlDlg, OnMod); - -// +--------------------------------------------------------------------+ - -CtlDlg::CtlDlg(Screen* s, FormDef& def, BaseScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -selected_category(0), command_index(0), control_model(0), -joy_select(0), joy_throttle(0), joy_rudder(0), joy_sensitivity(0), -mouse_select(0), mouse_sensitivity(0), mouse_invert(0), -apply(0), cancel(0), vid_btn(0), aud_btn(0), ctl_btn(0), opt_btn(0), mod_btn(0), -closed(true) -{ - Init(def); -} - -CtlDlg::~CtlDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -CtlDlg::RegisterControls() -{ - if (apply) - return; - - for (int i = 0; i < 4; i++) { - category[i] = (Button*) FindControl(101 + i); - REGISTER_CLIENT(EID_CLICK, category[i], CtlDlg, OnCategory); - } - - commands = (ListBox*) FindControl(200); - REGISTER_CLIENT(EID_SELECT, commands, CtlDlg, OnCommand); - - control_model_combo = (ComboBox*) FindControl(210); - REGISTER_CLIENT(EID_SELECT, control_model_combo, CtlDlg, OnControlModel); - - joy_select_combo = (ComboBox*) FindControl(211); - REGISTER_CLIENT(EID_SELECT, joy_select_combo, CtlDlg, OnJoySelect); - - joy_throttle_combo = (ComboBox*) FindControl(212); - REGISTER_CLIENT(EID_SELECT, joy_throttle_combo, CtlDlg, OnJoyThrottle); - - joy_rudder_combo = (ComboBox*) FindControl(213); - REGISTER_CLIENT(EID_SELECT, joy_rudder_combo, CtlDlg, OnJoyRudder); - - joy_sensitivity_slider = (Slider*) FindControl(214); - - if (joy_sensitivity_slider) { - joy_sensitivity_slider->SetRangeMin(0); - joy_sensitivity_slider->SetRangeMax(10); - joy_sensitivity_slider->SetStepSize(1); - REGISTER_CLIENT(EID_CLICK, joy_sensitivity_slider, CtlDlg, OnJoySensitivity); - } - - joy_axis_button = (Button*) FindControl(215); - REGISTER_CLIENT(EID_CLICK, joy_axis_button, CtlDlg, OnJoyAxis); - - mouse_select_combo = (ComboBox*) FindControl(511); - REGISTER_CLIENT(EID_SELECT, mouse_select_combo, CtlDlg, OnMouseSelect); - - mouse_sensitivity_slider = (Slider*) FindControl(514); - if (mouse_sensitivity_slider) { - mouse_sensitivity_slider->SetRangeMin(0); - mouse_sensitivity_slider->SetRangeMax(50); - mouse_sensitivity_slider->SetStepSize(1); - REGISTER_CLIENT(EID_CLICK, mouse_sensitivity_slider, CtlDlg, OnMouseSensitivity); - } - - mouse_invert_checkbox = (Button*) FindControl(515); - REGISTER_CLIENT(EID_CLICK, mouse_invert_checkbox, CtlDlg, OnMouseInvert); - - apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, apply, CtlDlg, OnApply); - - cancel = (Button*) FindControl(2); - REGISTER_CLIENT(EID_CLICK, cancel, CtlDlg, OnCancel); - - vid_btn = (Button*) FindControl(901); - REGISTER_CLIENT(EID_CLICK, vid_btn, CtlDlg, OnVideo); - - aud_btn = (Button*) FindControl(902); - REGISTER_CLIENT(EID_CLICK, aud_btn, CtlDlg, OnAudio); - - ctl_btn = (Button*) FindControl(903); - REGISTER_CLIENT(EID_CLICK, ctl_btn, CtlDlg, OnControls); - - opt_btn = (Button*) FindControl(904); - REGISTER_CLIENT(EID_CLICK, opt_btn, CtlDlg, OnOptions); - - mod_btn = (Button*) FindControl(905); - if (mod_btn) { - REGISTER_CLIENT(EID_CLICK, mod_btn, CtlDlg, OnMod); - } -} - -// +--------------------------------------------------------------------+ - -void -CtlDlg::Show() -{ - if (!IsShown()) - FormWindow::Show(); - - if (closed) - ShowCategory(); - else - UpdateCategory(); - - if (vid_btn) vid_btn->SetButtonState(0); - if (aud_btn) aud_btn->SetButtonState(0); - if (ctl_btn) ctl_btn->SetButtonState(1); - if (opt_btn) opt_btn->SetButtonState(0); - if (mod_btn) mod_btn->SetButtonState(0); - - closed = false; -} - -// +--------------------------------------------------------------------+ - -void -CtlDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnApply(0); - } -} - -// +--------------------------------------------------------------------+ - -void -CtlDlg::ShowCategory() -{ - if (!commands || !category[0]) - return; - - for (int i = 0; i < 4; i++) { - if (i == selected_category) - category[i]->SetButtonState(1); - else - category[i]->SetButtonState(0); - } - - commands->ClearItems(); - commands->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - commands->SetLeading(2); - - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - KeyMap& keymap = stars->GetKeyMap(); - int n = 0; - - for (int i = 0; i < 256; i++) { - KeyMapEntry* k = keymap.GetKeyMap(i); - - switch (k->act) { - case 0: - break; - - case KEY_CONTROL_MODEL: - control_model = k->key; - control_model_combo->SetSelection(control_model); - break; - - case KEY_JOY_SELECT: - joy_select = k->key; - joy_select_combo->SetSelection(joy_select); - break; - - case KEY_JOY_RUDDER: - joy_rudder = k->key; - joy_rudder_combo->SetSelection(joy_rudder); - break; - - case KEY_JOY_THROTTLE: - joy_throttle = k->key; - joy_throttle_combo->SetSelection(joy_throttle); - break; - - case KEY_JOY_SENSE: - joy_sensitivity = k->key; - joy_sensitivity_slider->SetValue(joy_sensitivity); - break; - - case KEY_JOY_SWAP: - break; - - case KEY_JOY_DEAD_ZONE: - break; - - case KEY_MOUSE_SELECT: - mouse_select = k->key; - mouse_select_combo->SetSelection(mouse_select); - break; - - case KEY_MOUSE_SENSE: - mouse_sensitivity = k->key; - mouse_sensitivity_slider->SetValue(mouse_sensitivity); - break; - - case KEY_MOUSE_INVERT: - mouse_invert = k->key; - mouse_invert_checkbox->SetButtonState(mouse_invert > 0); - break; - - case KEY_AXIS_YAW: - case KEY_AXIS_PITCH: - case KEY_AXIS_ROLL: - case KEY_AXIS_THROTTLE: - - case KEY_AXIS_YAW_INVERT: - case KEY_AXIS_PITCH_INVERT: - case KEY_AXIS_ROLL_INVERT: - case KEY_AXIS_THROTTLE_INVERT: - break; - - default: - if (keymap.GetCategory(i) == selected_category) { - commands->AddItemWithData(keymap.DescribeAction(i), (DWORD) i); - commands->SetItemText(n++, 1, keymap.DescribeKey(i)); - } - break; - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -CtlDlg::UpdateCategory() -{ - if (!commands) - return; - - Starshatter* stars = Starshatter::GetInstance(); - KeyMap& keymap = stars->GetKeyMap(); - - for (int i = 0; i < commands->NumItems(); i++) { - int key = commands->GetItemData(i); - commands->SetItemText(i, 1, keymap.DescribeKey(key)); - } -} - -// +--------------------------------------------------------------------+ - -void -CtlDlg::OnCategory(AWEvent* event) -{ - selected_category = 0; - - for (int i = 0; i < 4; i++) - if (event->window == category[i]) - selected_category = i; - - ShowCategory(); -} - -// +--------------------------------------------------------------------+ - -static DWORD command_click_time = 0; - -void -CtlDlg::OnCommand(AWEvent* event) -{ - int list_index = commands->GetListIndex(); - - // double-click: - if (list_index == command_index && Clock::GetInstance()->RealTime() - command_click_time < 350) { - KeyDlg* key_dlg = 0; - - if (manager) - key_dlg = manager->GetKeyDlg(); - - if (key_dlg) { - key_dlg->SetKeyMapIndex(commands->GetItemData(list_index)); - } - - if (manager) - manager->ShowKeyDlg(); - } - - command_click_time = Clock::GetInstance()->RealTime(); - command_index = list_index; -} - -// +--------------------------------------------------------------------+ - -void -CtlDlg::OnControlModel(AWEvent* event) -{ - control_model = control_model_combo->GetSelectedIndex(); -} - -// +--------------------------------------------------------------------+ - -void -CtlDlg::OnJoySelect(AWEvent* event) -{ - joy_select = joy_select_combo->GetSelectedIndex(); -} - -void -CtlDlg::OnJoyThrottle(AWEvent* event) -{ - joy_throttle = joy_throttle_combo->GetSelectedIndex(); -} - -void -CtlDlg::OnJoyRudder(AWEvent* event) -{ - joy_rudder = joy_rudder_combo->GetSelectedIndex(); -} - -void -CtlDlg::OnJoySensitivity(AWEvent* event) -{ - joy_sensitivity = joy_sensitivity_slider->GetValue(); -} - -void -CtlDlg::OnJoyAxis(AWEvent* event) -{ - if (manager) - manager->ShowJoyDlg(); -} - -// +--------------------------------------------------------------------+ - -void -CtlDlg::OnMouseSelect(AWEvent* event) -{ - mouse_select = mouse_select_combo->GetSelectedIndex(); -} - -void -CtlDlg::OnMouseSensitivity(AWEvent* event) -{ - mouse_sensitivity = mouse_sensitivity_slider->GetValue(); -} - -void -CtlDlg::OnMouseInvert(AWEvent* event) -{ - mouse_invert = mouse_invert_checkbox->GetButtonState() > 0; -} - -// +--------------------------------------------------------------------+ - -void CtlDlg::OnAudio(AWEvent* event) { manager->ShowAudDlg(); } -void CtlDlg::OnVideo(AWEvent* event) { manager->ShowVidDlg(); } -void CtlDlg::OnOptions(AWEvent* event) { manager->ShowOptDlg(); } -void CtlDlg::OnControls(AWEvent* event) { manager->ShowCtlDlg(); } -void CtlDlg::OnMod(AWEvent* event) { manager->ShowModDlg(); } - -// +--------------------------------------------------------------------+ - -void -CtlDlg::OnApply(AWEvent* event) -{ - if (manager) - manager->ApplyOptions(); -} - -void -CtlDlg::OnCancel(AWEvent* event) -{ - if (manager) - manager->CancelOptions(); -} - -// +--------------------------------------------------------------------+ - -void -CtlDlg::Apply() -{ - if (closed) return; - - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - KeyMap& keymap = stars->GetKeyMap(); - - keymap.Bind(KEY_CONTROL_MODEL, control_model, 0); - - keymap.Bind(KEY_JOY_SELECT, joy_select, 0); - keymap.Bind(KEY_JOY_RUDDER, joy_rudder, 0); - keymap.Bind(KEY_JOY_THROTTLE, joy_throttle, 0); - keymap.Bind(KEY_JOY_SENSE, joy_sensitivity, 0); - - keymap.Bind(KEY_MOUSE_SELECT, mouse_select, 0); - keymap.Bind(KEY_MOUSE_SENSE, mouse_sensitivity, 0); - keymap.Bind(KEY_MOUSE_INVERT, mouse_invert, 0); - - keymap.SaveKeyMap("key.cfg", 256); - - stars->MapKeys(); - Ship::SetControlModel(control_model); - } - - closed = true; -} - -void -CtlDlg::Cancel() -{ - closed = true; -} diff --git a/Stars45/CtlDlg.h b/Stars45/CtlDlg.h deleted file mode 100644 index 9406b1c..0000000 --- a/Stars45/CtlDlg.h +++ /dev/null @@ -1,118 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Control Options (keyboard/joystick) Dialog Active Window class -*/ - -#ifndef CtlDlg_h -#define CtlDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class BaseScreen; -class MenuScreen; -class GameScreen; - -// +--------------------------------------------------------------------+ - -class CtlDlg : public FormWindow -{ -public: - CtlDlg(Screen* s, FormDef& def, BaseScreen* mgr); - virtual ~CtlDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnCommand(AWEvent* event); - virtual void OnCategory(AWEvent* event); - - virtual void OnControlModel(AWEvent* event); - - virtual void OnJoySelect(AWEvent* event); - virtual void OnJoyThrottle(AWEvent* event); - virtual void OnJoyRudder(AWEvent* event); - virtual void OnJoySensitivity(AWEvent* event); - virtual void OnJoyAxis(AWEvent* event); - - virtual void OnMouseSelect(AWEvent* event); - virtual void OnMouseSensitivity(AWEvent* event); - virtual void OnMouseInvert(AWEvent* event); - - virtual void Apply(); - virtual void Cancel(); - - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - - virtual void OnAudio(AWEvent* event); - virtual void OnVideo(AWEvent* event); - virtual void OnOptions(AWEvent* event); - virtual void OnControls(AWEvent* event); - virtual void OnMod(AWEvent* event); - -protected: - void ShowCategory(); - void UpdateCategory(); - - BaseScreen* manager; - - Button* category[4]; - ListBox* commands; - int command_index; - - ComboBox* control_model_combo; - - ComboBox* joy_select_combo; - ComboBox* joy_throttle_combo; - ComboBox* joy_rudder_combo; - Slider* joy_sensitivity_slider; - Button* joy_axis_button; - - ComboBox* mouse_select_combo; - Slider* mouse_sensitivity_slider; - Button* mouse_invert_checkbox; - - Button* aud_btn; - Button* vid_btn; - Button* opt_btn; - Button* ctl_btn; - Button* mod_btn; - - Button* apply; - Button* cancel; - - int selected_category; - int control_model; - - int joy_select; - int joy_throttle; - int joy_rudder; - int joy_sensitivity; - - int mouse_select; - int mouse_sensitivity; - int mouse_invert; - - bool closed; -}; - -#endif // CtlDlg_h - diff --git a/Stars45/D3DXImage.cpp b/Stars45/D3DXImage.cpp deleted file mode 100644 index 9ab9779..0000000 --- a/Stars45/D3DXImage.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - D3DX image file loader -*/ - - -#include "D3DXImage.h" -#include "VideoDX9.h" - -// +--------------------------------------------------------------------+ - -D3DXImage::D3DXImage() -: width(0), height(0), format(0), image(0) -{ } - -D3DXImage::D3DXImage(WORD w, WORD h, DWORD* img) -{ - ZeroMemory(this, sizeof(D3DXImage)); - - width = w; - height = h; - - int pixels = width * height; - - image = new DWORD [pixels]; - - if (image && pixels) { - for (int i = 0; i < pixels; i++) - image[i] = img[i]; - } -} - -D3DXImage::~D3DXImage() -{ - delete [] image; -} - -// +--------------------------------------------------------------------+ - -bool D3DXImage::Load(char *filename) -{ - bool success = false; - FILE* f; - - fopen_s(&f, filename,"rb"); - if (f == NULL) - return success; - - int len = 0; - BYTE* buf = 0; - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - buf = new BYTE[len]; - - if (buf) { - fread(buf, len, 1, f); - fclose(f); - - success = LoadBuffer(buf, len); - } - - return success; -} - -// +--------------------------------------------------------------------+ - -bool D3DXImage::LoadBuffer(BYTE* buf, int len) -{ - bool success = false; - HRESULT hr = E_FAIL; - D3DXIMAGE_INFO info; - - if (buf == NULL) - return success; - - hr = D3DXGetImageInfoFromFileInMemory(buf, len, &info); - - if (FAILED(hr)) - return success; - - width = info.Width; - height = info.Height; - format = info.Format; - - if (image) { - delete [] image; - image = 0; - } - - IDirect3DSurface9* surf = 0; - IDirect3DDevice9* dev = VideoDX9::GetD3DDevice9(); - - - hr = dev->CreateOffscreenPlainSurface( width, - height, - D3DFMT_A8R8G8B8, - D3DPOOL_SYSTEMMEM, - &surf, - NULL); - - if (FAILED(hr)) - return success; - - hr = D3DXLoadSurfaceFromFileInMemory( surf, // dest surface - NULL, // dest palette (none) - NULL, // dest rect (entire image) - buf, // memory file - len, // size of data - NULL, // source rect (entire image) - D3DX_DEFAULT, // filter operation - 0, // color key (none) - NULL); // image info - - if (SUCCEEDED(hr)) { - D3DLOCKED_RECT locked_rect; - hr = surf->LockRect(&locked_rect, NULL, D3DLOCK_READONLY); - - if (SUCCEEDED(hr)) { - // copy surface into image - image = new DWORD[width*height]; - if (image) { - for (DWORD i = 0; i < height; i++) { - BYTE* dst = (BYTE*) (image + i * width); - BYTE* src = (BYTE*) locked_rect.pBits + i * locked_rect.Pitch; - - CopyMemory(dst, src, width * sizeof(DWORD)); - } - - success = true; - } - - surf->UnlockRect(); - } - } - - surf->Release(); - surf = 0; - - return success; -} - -// +--------------------------------------------------------------------+ - -bool D3DXImage::Save(char *filename) -{ - bool success = false; - HRESULT hr = E_FAIL; - - if (!image || !width || !height) - return success; - - FILE* f; - fopen_s(&f, filename,"wb"); - if (f == NULL) - return success; - - IDirect3DSurface9* surf = 0; - IDirect3DDevice9* dev = VideoDX9::GetD3DDevice9(); - - hr = dev->CreateOffscreenPlainSurface( width, - height, - D3DFMT_A8R8G8B8, - D3DPOOL_SYSTEMMEM, - &surf, - NULL); - - - if (SUCCEEDED(hr)) { - D3DLOCKED_RECT locked_rect; - hr = surf->LockRect(&locked_rect, NULL, 0); - - if (SUCCEEDED(hr)) { - // copy image into surface - for (DWORD i = 0; i < height; i++) { - BYTE* src = (BYTE*) (image + i * width); - BYTE* dst = (BYTE*) locked_rect.pBits + i * locked_rect.Pitch; - - CopyMemory(dst, src, width * sizeof(DWORD)); - } - - surf->UnlockRect(); - - ID3DXBuffer* buffer = 0; - D3DXIMAGE_FILEFORMAT imgfmt = D3DXIFF_PNG; - - if (strstr(filename, ".jpg") || strstr(filename, ".JPG")) - imgfmt = D3DXIFF_JPG; - - else if (strstr(filename, ".bmp") || strstr(filename, ".BMP")) - imgfmt = D3DXIFF_BMP; - - hr = D3DXSaveSurfaceToFileInMemory(&buffer, // destination - imgfmt, // type of file - surf, // image to save - NULL, // palette - NULL); // source rect (entire image) - - if (SUCCEEDED(hr)) { - fwrite(buffer->GetBufferPointer(), buffer->GetBufferSize(), 1, f); - success = true; - } - } - } - - surf->Release(); - surf = 0; - fclose(f); - return success; -} - diff --git a/Stars45/D3DXImage.h b/Stars45/D3DXImage.h deleted file mode 100644 index 8abc1e2..0000000 --- a/Stars45/D3DXImage.h +++ /dev/null @@ -1,42 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - D3DX image file loader -*/ - -#ifndef D3DXImage_h -#define D3DXImage_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -struct D3DXImage -{ - static const char* TYPENAME() { return "D3DXImage"; } - - D3DXImage(); - D3DXImage(WORD w, WORD h, DWORD* img); - ~D3DXImage(); - - bool Load(char *filename); - bool Save(char *filename); - - bool LoadBuffer(BYTE* buf, int len); - - DWORD* image; - DWORD width; - DWORD height; - DWORD format; -}; - -// +--------------------------------------------------------------------+ - -#endif // D3DXImage_h diff --git a/Stars45/DataLoader.cpp b/Stars45/DataLoader.cpp deleted file mode 100644 index 22ac803..0000000 --- a/Stars45/DataLoader.cpp +++ /dev/null @@ -1,1015 +0,0 @@ -/* 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 "DataLoader.h" -#include "Archive.h" -#include "Color.h" -#include "D3DXImage.h" -#include "Bitmap.h" -#include "Bmp.h" -#include "Pcx.h" -#include "Sound.h" -#include "Video.h" -#include "Wave.h" - -// +------------------------------------------------------------------+ - -static DataLoader* def_loader = 0; -DataLoader* DataLoader::loader = 0; - -static List archives; - -// +--------------------------------------------------------------------+ - -DataLoader::DataLoader() - : datapath(""), video(0), use_file_system(true), enable_media(true) -{ } - -// +--------------------------------------------------------------------+ - -void -DataLoader::UseVideo(Video* v) -{ - video = v; -} - -// +--------------------------------------------------------------------+ - -void -DataLoader::Initialize() -{ - def_loader = new DataLoader; - loader = def_loader; - - archives.destroy(); -} - -void -DataLoader::Close() -{ - archives.destroy(); - Bitmap::ClearCache(); - - delete def_loader; - def_loader = 0; - loader = 0; -} - -void -DataLoader::Reset() -{ - Close(); -} - -// +--------------------------------------------------------------------+ - -void -DataLoader::UseFileSystem(bool use) -{ - use_file_system = use; -} - -void -DataLoader::EnableMedia(bool enable) -{ - enable_media = enable; -} - -// +--------------------------------------------------------------------+ - -int -DataLoader::EnableDatafile(const char* name) -{ - int status = DATAFILE_NOTEXIST; - - FILE* f; - fopen_s(&f, name, "rb"); - - if (f) { - ::fclose(f); - - DataArchive* a = new DataArchive(name); - - if (a && a->NumFiles() >= 1) { - status = DATAFILE_OK; - - bool found = false; - ListIter iter = archives; - while (++iter && !found) { - DataArchive* archive = iter.value(); - if (!strcmp(archive->Name(), name)) { - found = true; - } - } - - if (!found) - archives.append(a); - } - else { - Print(" WARNING: invalid data file '%s'\n", name); - status = DATAFILE_INVALID; - - delete a; - } - - loader = this; - } - else { - Print(" WARNING: could not open datafile '%s'\n", name); - status = DATAFILE_NOTEXIST; - } - - return status; -} - -int -DataLoader::DisableDatafile(const char* name) -{ - ListIter iter = archives; - while (++iter) { - DataArchive* a = iter.value(); - if (!strcmp(a->Name(), name)) { - delete iter.removeItem(); - return DATAFILE_OK; - } - } - - return DATAFILE_NOTEXIST; -} - -// +--------------------------------------------------------------------+ - -void -DataLoader::SetDataPath(const char* path) -{ - if (path) - datapath = path; - else - datapath = ""; -} - -// +--------------------------------------------------------------------+ - -bool -DataLoader::FindFile(const char* name) -{ - // assemble file name: - char filename[1024]; - strcpy_s(filename, datapath); - strcat_s(filename, name); - - // first check current directory: - if (use_file_system) { - FILE* f; - ::fopen_s(&f, filename, "rb"); - - if (f) { - ::fclose(f); - return true; - } - } - - // then check datafiles, from last to first: - int narchives = archives.size(); - for (int i = 0; i < narchives; i++) { - DataArchive* a = archives[narchives-1-i]; - if (a->FindEntry(filename) > -1) { - return true; - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -int -DataLoader::ListFiles(const char* filter, List& list, bool recurse) -{ - list.destroy(); - - ListFileSystem(filter, list, datapath, recurse); - - // then check datafile(s): - int narchives = archives.size(); - for (int i = 0; i < narchives; i++) { - DataArchive* a = archives[narchives-1-i]; - ListArchiveFiles(a->Name(), filter, list); - } - - return list.size(); -} - -int -DataLoader::ListArchiveFiles(const char* archive_name, const char* filter, List &list) -{ - int pathlen = datapath.length(); - DataArchive* a = 0; - - if (archive_name) { - int narchives = archives.size(); - for (int i = 0; i < narchives && !a; i++) { - a = archives[narchives-1-i]; - - if (_stricmp(a->Name(), archive_name)) - a = 0; - } - } - - if (!a) { - ListFileSystem(filter, list, datapath, true); - return list.size(); - } - - if (!strcmp(filter, "*.*")) { - int count = a->NumFiles(); - for (int n = 0; n < count; n++) { - DataEntry* entry = a->GetFile(n); - Text entry_name = entry->name; - entry_name.setSensitive(false); - - if (entry_name.contains(datapath)) { - Text fname = entry_name(pathlen, 1000); - - if (!list.contains(&fname)) - list.append(new Text(fname)); - } - } - } - else { - char data_filter[256]; - ZeroMemory(data_filter, 256); - - const char* pf = filter; - char* pdf = data_filter; - - while (*pf) { - if (*pf != '*') - *pdf++ = *pf; - pf++; - } - - int count = a->NumFiles(); - for (int n = 0; n < count; n++) { - DataEntry* entry = a->GetFile(n); - Text entry_name = entry->name; - entry_name.setSensitive(false); - - if (entry_name.contains(datapath) && entry_name.contains(data_filter)) { - Text fname = entry_name(pathlen, 1000); - - if (!list.contains(&fname)) - list.append(new Text(fname)); - } - } - } - - return list.size(); -} - -// +--------------------------------------------------------------------+ - -void -DataLoader::ListFileSystem(const char* filter, List& list, Text base_path, bool recurse) -{ - if (use_file_system) { - char data_filter[256]; - ZeroMemory(data_filter, 256); - - const char* pf = filter; - char* pdf = data_filter; - - while (*pf) { - if (*pf != '*') - *pdf++ = *pf; - pf++; - } - - int pathlen = base_path.length(); - - // assemble win32 find filter: - char win32_filter[1024]; - strcpy_s(win32_filter, datapath); - - if (recurse) - strcat_s(win32_filter, "*.*"); - else - strcat_s(win32_filter, filter); - - // first check current directory: - WIN32_FIND_DATA data; - HANDLE hFind = FindFirstFile(win32_filter, &data); - - if (hFind != INVALID_HANDLE_VALUE) { - do { - if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { - if (recurse && data.cFileName[0] != '.') { - Text old_datapath = datapath; - - Text newpath = datapath; - newpath += data.cFileName; - newpath += "/"; - datapath = newpath; - - ListFileSystem(filter, list, base_path, recurse); - - datapath = old_datapath; - } - } - else { - if (!strcmp(filter, "*.*") || strstr(data.cFileName, data_filter)) { - Text full_name = datapath; - full_name += data.cFileName; - - list.append(new Text(full_name(pathlen, 1000))); - } - } - } - while (FindNextFile(hFind, &data)); - } - } -} - -// +--------------------------------------------------------------------+ - -int -DataLoader::LoadBuffer(const char* name, BYTE*& buf, bool null_terminate, bool optional) -{ - buf = 0; - - // assemble file name: - char filename[1024]; - strcpy_s(filename, datapath); - strcat_s(filename, name); - - if (use_file_system) { - // first check current directory: - FILE* f; - ::fopen_s(&f, filename, "rb"); - - if (f) { - ::fseek(f, 0, SEEK_END); - int len = ftell(f); - ::fseek(f, 0, SEEK_SET); - - if (null_terminate) { - buf = new BYTE[len+1]; - if (buf) - buf[len] = 0; - } - - else { - buf = new BYTE[len]; - } - - if (buf) - ::fread(buf, len, 1, f); - - ::fclose(f); - - return len; - } - } - - // then check datafile(s): - int narchives = archives.size(); - - // vox files are usually in their own archive, - // so check there first - if (narchives > 1 && strstr(filename, "Vox")) { - for (int i = 0; i < narchives; i++) { - DataArchive* a = archives[narchives-1-i]; - if (strstr(a->Name(), "vox")) { - int index = a->FindEntry(filename); - if (index > -1) - return a->ExpandEntry(index, buf, null_terminate); - } - } - } - - for (int i = 0; i < narchives; i++) { - DataArchive* a = archives[narchives-1-i]; - int index = a->FindEntry(filename); - if (index > -1) - return a->ExpandEntry(index, buf, null_terminate); - } - - if (!optional) - Print("WARNING - DataLoader could not load buffer '%s'\n", filename); - return 0; -} - -// +--------------------------------------------------------------------+ - -int -DataLoader::LoadPartialFile(const char* name, BYTE*& buf, int max_load, bool optional) -{ - buf = 0; - - // assemble file name: - char filename[1024]; - strcpy_s(filename, datapath); - strcat_s(filename, name); - - // first check current directory: - FILE* f; - ::fopen_s(&f, filename, "rb"); - - if (f) { - ::fseek(f, 0, SEEK_END); - int len = ftell(f); - ::fseek(f, 0, SEEK_SET); - - if (len > max_load) { - len = max_load; - } - - buf = new BYTE[len]; - - if (buf) - ::fread(buf, len, 1, f); - - ::fclose(f); - - return len; - } - - if (!optional) - Print("WARNING - DataLoader could not load partial file '%s'\n", filename); - return 0; -} - -int -DataLoader::fread(void* buffer, size_t size, size_t count, BYTE*& stream) -{ - CopyMemory(buffer, stream, size*count); - stream += size*count; - - return size*count; -} - -// +--------------------------------------------------------------------+ - -void -DataLoader::ReleaseBuffer(BYTE*& buf) -{ - delete [] buf; - buf = 0; -} - -// +--------------------------------------------------------------------+ - -int -DataLoader::CacheBitmap(const char* name, Bitmap*& bitmap, int type, bool optional) -{ - int result = 0; - - // search cache: - bitmap = Bitmap::CheckCache(name); - if (bitmap) return 1; - - // not in cache yet: - bitmap = new Bitmap; - - if (bitmap) - result = LoadBitmap(name, *bitmap, type, optional); - - if (result && bitmap) - Bitmap::AddToCache(bitmap); - - return result; -} - -// +--------------------------------------------------------------------+ - -int -DataLoader::LoadBitmap(const char* name, Bitmap& bitmap, int type, bool optional) -{ - if (!enable_media) - return 0; - - int result = LoadIndexed(name, bitmap, type); - - // check for a matching high color bitmap: - if (result == 1) { - int hi_result = LoadHiColor(name, bitmap, type); - - if (hi_result == 2) - result = 3; - } - - bitmap.SetFilename(name); - - if (!result && !optional) - Print("WARNING - DataLoader could not load bitmap '%s%s'\n", datapath.data(), name); - - return result; -} - -// +--------------------------------------------------------------------+ - -int -DataLoader::LoadTexture(const char* name, Bitmap*& bitmap, int type, bool preload_cache, bool optional) -{ - if (!enable_media) - return 0; - - int result = 0; - - // assemble file name: - char filename[256]; - strcpy_s(filename, datapath); - strcat_s(filename, name); - - // search cache: - bitmap = Bitmap::CheckCache(filename); - if (bitmap) return 1; - - // not in cache yet: - bitmap = new Bitmap; - - if (bitmap) { - result = LoadHiColor(name, *bitmap, type); - - if (!result) { - result = LoadIndexed(name, *bitmap, type); - } - - bitmap->SetFilename(filename); - - if (result) { - bitmap->MakeTexture(); - Bitmap::AddToCache(bitmap); - } - else { - delete bitmap; - bitmap = 0; - - if (!optional) - Print("WARNING - DataLoader could not load texture '%s%s'\n", datapath.data(), name); - } - } - else if (!optional) { - Print("WARNING - DataLoader could not allocate texture '%s%s'\n", datapath.data(), name); - } - - return result; -} - -// +--------------------------------------------------------------------+ - -int -DataLoader::LoadIndexed(const char* name, Bitmap& bitmap, int type) -{ - if (!enable_media) - return 0; - - int result = 0; - PcxImage pcx; - D3DXImage d3dx; - bool pcx_file = strstr(name, ".pcx") || strstr(name, ".PCX"); - - // assemble file name: - char filename[256]; - strcpy_s(filename, datapath); - strcat_s(filename, name); - - // first try to load from current directory: - bool loaded = false; - - if (use_file_system) { - if (pcx_file) - loaded = pcx.Load(filename) == PCX_OK; - - else - loaded = d3dx.Load(filename); - } - - if (!loaded) { - // then check datafile: - int len = 0; - BYTE* tmp_buf = 0; - - int narchives = archives.size(); - for (int i = 0; i < narchives; i++) { - DataArchive* a = archives[narchives-1-i]; - int index = a->FindEntry(filename); - if (index > -1) { - len = a->ExpandEntry(index, tmp_buf); - - if (pcx_file) - pcx.LoadBuffer(tmp_buf, len); - - else - d3dx.LoadBuffer(tmp_buf, len); - - ReleaseBuffer(tmp_buf); - break; - } - } - } - - // now copy the image into the bitmap: - if (pcx_file) { - if (pcx.bitmap) { - bitmap.CopyImage(pcx.width, pcx.height, pcx.bitmap, type); - result = 1; - } - - else if (pcx.himap) { - bitmap.CopyHighColorImage(pcx.width, pcx.height, pcx.himap, type); - result = 2; - } - - if (result == 2) - LoadAlpha(name, bitmap, type); - } - - else { - if (d3dx.image) { - bitmap.CopyHighColorImage(d3dx.width, d3dx.height, d3dx.image, type); - result = 2; - } - - if (result == 2) { - LoadAlpha(name, bitmap, type); - } - } - - return result; -} - -int -DataLoader::LoadHiColor(const char* name, Bitmap& bitmap, int type) -{ - if (!enable_media) - return 0; - - int result = 0; - PcxImage pcx; - D3DXImage d3dx; - bool pcx_file = strstr(name, ".pcx") || strstr(name, ".PCX"); - bool bmp_file = strstr(name, ".bmp") || strstr(name, ".BMP"); - bool png_file = strstr(name, ".png") || strstr(name, ".PNG"); - - // check for a matching high color bitmap: - char filename[256]; - char name2[256]; - strcpy_s(name2, name); - - char* dot = strrchr(name2, '.'); - if (dot && pcx_file) - strcpy(dot, "+.pcx"); - else if (dot && bmp_file) - strcpy(dot, "+.bmp"); - else if (dot && png_file) - strcpy(dot, "+.png"); - else - return result; - - strcpy_s(filename, datapath); - strcat_s(filename, name2); - - // first try to load from current directory: - bool loaded = false; - - if (use_file_system) { - if (pcx_file) - loaded = pcx.Load(filename) == PCX_OK; - - else - loaded = d3dx.Load(filename); - } - - if (!loaded) { - // then check datafile: - int len = 0; - BYTE* tmp_buf = 0; - - int narchives = archives.size(); - for (int i = 0; i < narchives; i++) { - DataArchive* a = archives[narchives-1-i]; - int index = a->FindEntry(filename); - if (index > -1) { - len = a->ExpandEntry(index, tmp_buf); - - if (pcx_file) - pcx.LoadBuffer(tmp_buf, len); - else - d3dx.LoadBuffer(tmp_buf, len); - - ReleaseBuffer(tmp_buf); - break; - } - } - } - - // now copy the image into the bitmap: - if (pcx_file && pcx.himap) { - bitmap.CopyHighColorImage(pcx.width, pcx.height, pcx.himap, type); - result = 2; - } - - else if (d3dx.image) { - bitmap.CopyHighColorImage(d3dx.width, d3dx.height, d3dx.image, type); - result = 2; - } - - if (result == 2) - LoadAlpha(name, bitmap, type); - - return result; -} - -int -DataLoader::LoadAlpha(const char* name, Bitmap& bitmap, int type) -{ - if (!enable_media) - return 0; - - PcxImage pcx; - D3DXImage d3dx; - bool pcx_file = strstr(name, ".pcx") || strstr(name, ".PCX"); - bool bmp_file = strstr(name, ".bmp") || strstr(name, ".BMP"); - bool png_file = strstr(name, ".png") || strstr(name, ".PNG"); - bool tga_file = strstr(name, ".tga") || strstr(name, ".TGA"); - - // check for an associated alpha-only (grayscale) bitmap: - char filename[256]; - char name2[256]; - strcpy_s(name2, name); - char* dot = strrchr(name2, '.'); - if (dot && pcx_file) - strcpy(dot, "@.pcx"); - else if (dot && bmp_file) - strcpy(dot, "@.bmp"); - else if (dot && png_file) - strcpy(dot, "@.png"); - else if (dot && tga_file) - strcpy(dot, "@.tga"); - else - return 0; - - strcpy_s(filename, datapath); - strcat_s(filename, name2); - - // first try to load from current directory: - bool loaded = false; - - if (use_file_system) { - if (pcx_file) - loaded = pcx.Load(filename) == PCX_OK; - - else - loaded = d3dx.Load(filename); - } - - if (!loaded) { - // then check datafile: - int len = 0; - BYTE* tmp_buf = 0; - - int narchives = archives.size(); - for (int i = 0; i < narchives; i++) { - DataArchive* a = archives[narchives-1-i]; - int index = a->FindEntry(filename); - if (index > -1) { - len = a->ExpandEntry(index, tmp_buf); - - if (pcx_file) - pcx.LoadBuffer(tmp_buf, len); - else - d3dx.LoadBuffer(tmp_buf, len); - - ReleaseBuffer(tmp_buf); - break; - } - } - } - - // now copy the alpha values into the bitmap: - if (pcx_file && pcx.bitmap) { - bitmap.CopyAlphaImage(pcx.width, pcx.height, pcx.bitmap); - } - else if (pcx_file && pcx.himap) { - bitmap.CopyAlphaRedChannel(pcx.width, pcx.height, pcx.himap); - } - else if (d3dx.image) { - bitmap.CopyAlphaRedChannel(d3dx.width, d3dx.height, d3dx.image); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -int -DataLoader::LoadSound(const char* name, Sound*& snd, DWORD flags, bool optional) -{ - if (!enable_media) - return 0; - - if (strstr(name, ".ogg")) - return LoadStream(name, snd, optional); - - int result = 0; - - WAVE_HEADER head; - WAVE_FMT fmt; - WAVE_FACT fact; - WAVE_DATA data; - WAVEFORMATEX wfex; - LPBYTE wave; - - LPBYTE buf; - LPBYTE p; - int len; - - ZeroMemory(&head, sizeof(head)); - ZeroMemory(&fmt, sizeof(fmt)); - ZeroMemory(&fact, sizeof(fact)); - ZeroMemory(&data, sizeof(data)); - - len = LoadBuffer(name, buf, false, optional); - - if (len > sizeof(head)) { - CopyMemory(&head, buf, sizeof(head)); - - if (head.RIFF == MAKEFOURCC('R', 'I', 'F', 'F') && - head.WAVE == MAKEFOURCC('W', 'A', 'V', 'E')) { - - p = buf + sizeof(WAVE_HEADER); - - do { - DWORD chunk_id = *((LPDWORD) p); - - switch (chunk_id) { - case MAKEFOURCC('f', 'm', 't', ' '): - CopyMemory(&fmt, p, sizeof(fmt)); - p += fmt.chunk_size + 8; - break; - - case MAKEFOURCC('f', 'a', 'c', 't'): - CopyMemory(&fact, p, sizeof(fact)); - p += fact.chunk_size + 8; - break; - - case MAKEFOURCC('s', 'm', 'p', 'l'): - CopyMemory(&fact, p, sizeof(fact)); - p += fact.chunk_size + 8; - break; - - case MAKEFOURCC('d', 'a', 't', 'a'): - CopyMemory(&data, p, sizeof(data)); - p += 8; - break; - - default: - ReleaseBuffer(buf); - return result; - } - } - while (data.chunk_size == 0); - - wfex.wFormatTag = fmt.wFormatTag; - wfex.nChannels = fmt.nChannels; - wfex.nSamplesPerSec = fmt.nSamplesPerSec; - wfex.nAvgBytesPerSec = fmt.nAvgBytesPerSec; - wfex.nBlockAlign = fmt.nBlockAlign; - wfex.wBitsPerSample = fmt.wBitsPerSample; - wfex.cbSize = 0; - wave = p; - - snd = Sound::Create(flags, &wfex, data.chunk_size, wave); - - if (snd) - result = data.chunk_size; - } - } - - ReleaseBuffer(buf); - return result; -} - -int -DataLoader::LoadStream(const char* name, Sound*& snd, bool optional) -{ - if (!enable_media) - return 0; - - if (!name) - return 0; - - int namelen = strlen(name); - - if (namelen < 5) - return 0; - - if ((name[namelen-3] == 'o' || name[namelen-3] == 'O') && - (name[namelen-2] == 'g' || name[namelen-2] == 'G') && - (name[namelen-1] == 'g' || name[namelen-1] == 'G')) { - - return LoadOggStream(name, snd); - } - - int result = 0; - - WAVE_HEADER head; - WAVE_FMT fmt; - WAVE_FACT fact; - WAVE_DATA data; - WAVEFORMATEX wfex; - - LPBYTE buf; - LPBYTE p; - int len; - - ZeroMemory(&head, sizeof(head)); - ZeroMemory(&fmt, sizeof(fmt)); - ZeroMemory(&fact, sizeof(fact)); - ZeroMemory(&data, sizeof(data)); - - len = LoadPartialFile(name, buf, 4096, optional); - - if (len > sizeof(head)) { - CopyMemory(&head, buf, sizeof(head)); - - if (head.RIFF == MAKEFOURCC('R', 'I', 'F', 'F') && - head.WAVE == MAKEFOURCC('W', 'A', 'V', 'E')) { - - p = buf + sizeof(WAVE_HEADER); - - do { - DWORD chunk_id = *((LPDWORD) p); - - switch (chunk_id) { - case MAKEFOURCC('f', 'm', 't', ' '): - CopyMemory(&fmt, p, sizeof(fmt)); - p += fmt.chunk_size + 8; - break; - - case MAKEFOURCC('f', 'a', 'c', 't'): - CopyMemory(&fact, p, sizeof(fact)); - p += fact.chunk_size + 8; - break; - - case MAKEFOURCC('s', 'm', 'p', 'l'): - CopyMemory(&fact, p, sizeof(fact)); - p += fact.chunk_size + 8; - break; - - case MAKEFOURCC('d', 'a', 't', 'a'): - CopyMemory(&data, p, sizeof(data)); - p += 8; - break; - - default: - ReleaseBuffer(buf); - return result; - } - } - while (data.chunk_size == 0); - - wfex.wFormatTag = fmt.wFormatTag; - wfex.nChannels = fmt.nChannels; - wfex.nSamplesPerSec = fmt.nSamplesPerSec; - wfex.nAvgBytesPerSec = fmt.nAvgBytesPerSec; - wfex.nBlockAlign = fmt.nBlockAlign; - wfex.wBitsPerSample = fmt.wBitsPerSample; - wfex.cbSize = 0; - - snd = Sound::Create(Sound::STREAMED, &wfex); - - if (snd) { - // assemble file name: - char filename[1024]; - strcpy_s(filename, datapath); - strcat_s(filename, name); - - snd->StreamFile(filename, p - buf); - - result = data.chunk_size; - } - } - } - - ReleaseBuffer(buf); - return result; -} - -int -DataLoader::LoadOggStream(const char* name, Sound*& snd) -{ - if (!enable_media) - return 0; - - snd = Sound::CreateOggStream(name); - - return snd != 0; -} diff --git a/Stars45/DataLoader.h b/Stars45/DataLoader.h deleted file mode 100644 index 0331dcb..0000000 --- a/Stars45/DataLoader.h +++ /dev/null @@ -1,85 +0,0 @@ -/* 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 - -*/ - -#ifndef DataLoader_h -#define DataLoader_h - -#include "Types.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Bitmap; -class Sound; -class Video; - -// +--------------------------------------------------------------------+ - -class DataLoader -{ -public: - static const char* TYPENAME() { return "DataLoader"; } - - enum { DATAFILE_OK, DATAFILE_INVALID, DATAFILE_NOTEXIST }; - - DataLoader(); - - static DataLoader* GetLoader() { return loader; } - static void Initialize(); - static void Close(); - - void Reset(); - void UseFileSystem(bool use=true); - void UseVideo(Video* v); - void EnableMedia(bool enable=true); - - int EnableDatafile(const char* name); - int DisableDatafile(const char* name); - - void SetDataPath(const char* path); - const char* GetDataPath() const { return datapath; } - - bool IsFileSystemEnabled() const { return use_file_system; } - bool IsMediaLoadEnabled() const { return enable_media; } - - bool FindFile(const char* fname); - int ListFiles(const char* filter, List& list, bool recurse=false); - int ListArchiveFiles(const char* archive, const char* filter, List& list); - int LoadBuffer(const char* name, BYTE*& buf, bool null_terminate=false, bool optional=false); - int LoadBitmap(const char* name, Bitmap& bmp, int type=0, bool optional=false); - int CacheBitmap(const char* name, Bitmap*& bmp, int type=0, bool optional=false); - int LoadTexture(const char* name, Bitmap*& bmp, int type=0, bool preload_cache=false, bool optional=false); - int LoadSound(const char* fname, Sound*& snd, DWORD flags=0, bool optional=false); - int LoadStream(const char* fname, Sound*& snd, bool optional=false); - - void ReleaseBuffer(BYTE*& buf); - int fread(void* buffer, size_t size, size_t count, BYTE*& stream); - -private: - int LoadIndexed(const char* name, Bitmap& bmp, int type); - int LoadHiColor(const char* name, Bitmap& bmp, int type); - int LoadAlpha( const char* name, Bitmap& bmp, int type); - - void ListFileSystem(const char* filter, List& list, Text base_path, bool recurse); - int LoadPartialFile(const char* fname, BYTE*& buf, int max_load, bool optional=false); - int LoadOggStream(const char* fname, Sound*& snd); - - Text datapath; - Video* video; - bool use_file_system; - bool enable_media; - - static DataLoader* loader; -}; - -// +--------------------------------------------------------------------+ - -#endif // DataLoader_h - diff --git a/Stars45/DebriefDlg.cpp b/Stars45/DebriefDlg.cpp deleted file mode 100644 index d4977ab..0000000 --- a/Stars45/DebriefDlg.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Debriefing Dialog Active Window class -*/ - -#include "DebriefDlg.h" -#include "PlanScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Element.h" -#include "Instruction.h" -#include "Mission.h" -#include "Sim.h" -#include "SimEvent.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "StarSystem.h" -#include "FormatUtil.h" -#include "Player.h" -#include "Campaign.h" - -#include "NetLobby.h" -#include "HttpServer.h" - -#include "Clock.h" -#include "ContentBundle.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "ParseUtil.h" -#include "Panic.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(DebriefDlg, OnClose); -DEF_MAP_CLIENT(DebriefDlg, OnUnit); - -// +--------------------------------------------------------------------+ - -DebriefDlg::DebriefDlg(Screen* s, FormDef& def, PlanScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -close_btn(0), campaign(0), mission(0), -unit_index(0), info(0), sim(0), ship(0) -{ - campaign = Campaign::GetCampaign(); - - if (campaign) - mission = campaign->GetMission(); - - Init(def); -} - -DebriefDlg::~DebriefDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -DebriefDlg::RegisterControls() -{ - mission_name = FindControl(200); - mission_system = FindControl(202); - mission_sector = FindControl(204); - mission_time_start = FindControl(206); - - objectives = FindControl(210); - situation = FindControl(240); - mission_score = FindControl(211); - unit_list = (ListBox*) FindControl(320); - summary_list = (ListBox*) FindControl(330); - event_list = (ListBox*) FindControl(340); - - if (unit_list) - REGISTER_CLIENT(EID_SELECT, unit_list, DebriefDlg, OnUnit); - - close_btn = (Button*) FindControl(1); - - if (close_btn) - REGISTER_CLIENT(EID_CLICK, close_btn, DebriefDlg, OnClose); -} - -// +--------------------------------------------------------------------+ - -void -DebriefDlg::Show() -{ - FormWindow::Show(); - Clock::GetInstance()->SetTimeCompression(1.0); - - mission = 0; - campaign = Campaign::GetCampaign(); - sim = Sim::GetSim(); - - if (sim) - ship = sim->GetPlayerShip(); - - if (campaign) - mission = campaign->GetMission(); - - if (mission_name) { - if (mission) - mission_name->SetText(mission->Name()); - else - mission_name->SetText(ContentBundle::GetInstance()->GetText("DebriefDlg.mission-name")); - } - - if (mission_system) { - mission_system->SetText(""); - - if (mission) { - StarSystem* sys = mission->GetStarSystem(); - - if (sys) - mission_system->SetText(sys->Name()); - } - } - - if (mission_sector) { - mission_sector->SetText(""); - - if (mission) { - MissionElement* elem = mission->GetElements()[0]; - - if (elem) - mission_sector->SetText(elem->Region()); - } - } - - if (mission_time_start) { - if (mission) { - char txt[32]; - FormatDayTime(txt, mission->Start()); - mission_time_start->SetText(txt); - } - } - - if (objectives) { - bool found_objectives = false; - - if (sim && sim->GetPlayerElement()) { - Text text; - Element* elem = sim->GetPlayerElement(); - - for (int i = 0; i < elem->NumObjectives(); i++) { - Instruction* obj = elem->GetObjective(i); - text += Text("* ") + obj->GetDescription() + Text("\n"); - - found_objectives = true; - } - - objectives->SetText(text); - } - - if (!found_objectives) { - if (mission) - objectives->SetText(mission->Objective()); - else - objectives->SetText(ContentBundle::GetInstance()->GetText("DebriefDlg.unspecified")); - } - } - - if (situation) { - if (mission) - situation->SetText(mission->Situation()); - else - situation->SetText(ContentBundle::GetInstance()->GetText("DebriefDlg.unknown")); - } - - if (mission_score) { - mission_score->SetText(ContentBundle::GetInstance()->GetText("DebriefDlg.no-stats")); - - if (ship) { - for (int i = 0; i < ShipStats::NumStats(); i++) { - ShipStats* stats = ShipStats::GetStats(i); - if (stats && !strcmp(ship->Name(), stats->GetName())) { - stats->Summarize(); - - Player* player = Player::GetCurrentPlayer(); - int points = stats->GetPoints() + stats->GetCommandPoints(); - - if (player && sim) - points = player->GetMissionPoints(stats, sim->StartTime()) + stats->GetCommandPoints(); - - char score[32]; - sprintf_s(score, "%d %s", points, ContentBundle::GetInstance()->GetText("DebriefDlg.points").data()); - mission_score->SetText(score); - break; - } - } - } - } - - DrawUnits(); -} - -// +--------------------------------------------------------------------+ - -void -DebriefDlg::DrawUnits() -{ - if (mission) { - if (unit_list) { - unit_list->ClearItems(); - - int seln = -1; - bool netgame = false; - - if (sim && sim->IsNetGame()) - netgame = true; - - for (int i = 0; i < ShipStats::NumStats(); i++) { - ShipStats* stats = ShipStats::GetStats(i); - stats->Summarize(); - - if (netgame || (stats->GetIFF() == mission->Team() && - !strcmp(stats->GetRegion(), mission->GetRegion()))) { - int n = unit_list->AddItemWithData(" ", i) - 1; - unit_list->SetItemText(n, 1, stats->GetName()); - unit_list->SetItemText(n, 2, stats->GetRole()); - unit_list->SetItemText(n, 3, stats->GetType()); - - if (ship && !strcmp(ship->Name(), stats->GetName())) - seln = n; - } - } - - if (seln >= 0) { - unit_list->SetSelected(seln); - OnUnit(0); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -DebriefDlg::ExecFrame() -{ - if (unit_list && unit_list->NumItems() && unit_list->GetSelCount() < 1) { - unit_list->SetSelected(0); - OnUnit(0); - } - - if (Keyboard::KeyDown(VK_RETURN)) { - OnClose(0); - } -} - -// +--------------------------------------------------------------------+ - -void -DebriefDlg::OnUnit(AWEvent* event) -{ - if (!unit_list || !event_list || !summary_list) - return; - - summary_list->ClearItems(); - event_list->ClearItems(); - - int seln = unit_list->GetSelection(); - int unit = unit_list->GetItemData(seln); - - ShipStats* stats = ShipStats::GetStats(unit); - if (stats) { - stats->Summarize(); - - char txt[64]; - int i = 0; - - sprintf_s(txt, "%d", stats->GetGunShots()); - summary_list->AddItem("Guns Fired: "); - summary_list->SetItemText(i++, 1, txt); - - sprintf_s(txt, "%d", stats->GetGunHits()); - summary_list->AddItem("Gun Hits: "); - summary_list->SetItemText(i++, 1, txt); - - sprintf_s(txt, "%d", stats->GetGunKills()); - summary_list->AddItem("Gun Kills: "); - summary_list->SetItemText(i++, 1, txt); - - // one line spacer: - summary_list->AddItem(" "); - i++; - - sprintf_s(txt, "%d", stats->GetMissileShots()); - summary_list->AddItem("Missiles Fired: "); - summary_list->SetItemText(i++, 1, txt); - - sprintf_s(txt, "%d", stats->GetMissileHits()); - summary_list->AddItem("Missile Hits: "); - summary_list->SetItemText(i++, 1, txt); - - sprintf_s(txt, "%d", stats->GetMissileKills()); - summary_list->AddItem("Missile Kills: "); - summary_list->SetItemText(i++, 1, txt); - - i = 0; - ListIter iter = stats->GetEvents(); - while (++iter) { - SimEvent* event = iter.value(); - - char txt[64]; - int time = event->GetTime(); - - if (time > 24 * 60 * 60) - FormatDayTime(txt, time); - else - FormatTime(txt, time); - - event_list->AddItem(txt); - event_list->SetItemText(i, 1, event->GetEventDesc()); - - if (event->GetTarget()) - event_list->SetItemText(i, 2, event->GetTarget()); - - i++; - } - } -} - -// +--------------------------------------------------------------------+ - -void -DebriefDlg::OnClose(AWEvent* event) -{ - Sim* sim = Sim::GetSim(); - - sim->CommitMission(); - sim->UnloadMission(); - - NetLobby* lobby = NetLobby::GetInstance(); - if (lobby && lobby->IsHost()) { - lobby->SelectMission(0); - lobby->ExecFrame(); - } - - Player* player = Player::GetCurrentPlayer(); - if (player && player->ShowAward()) { - manager->ShowAwardDlg(); - } - - else { - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - Mouse::Show(false); - - Campaign* campaign = Campaign::GetCampaign(); - if (campaign && campaign->GetCampaignId() < Campaign::SINGLE_MISSIONS) - stars->SetGameMode(Starshatter::CMPN_MODE); - else - stars->SetGameMode(Starshatter::MENU_MODE); - } - - else { - Panic::Panic("DebriefDlg::OnClose() - Game instance not found"); - } - } -} diff --git a/Stars45/DebriefDlg.h b/Stars45/DebriefDlg.h deleted file mode 100644 index 5636a4c..0000000 --- a/Stars45/DebriefDlg.h +++ /dev/null @@ -1,80 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Debriefing Dialog Active Window class -*/ - -#ifndef DebriefDlg_h -#define DebriefDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class PlanScreen; -class Campaign; -class Mission; -class MissionInfo; -class Sim; -class Ship; - -// +--------------------------------------------------------------------+ - -class DebriefDlg : public FormWindow -{ -public: - DebriefDlg(Screen* s, FormDef& def, PlanScreen* mgr); - virtual ~DebriefDlg(); - - virtual void RegisterControls(); - virtual void ExecFrame(); - virtual void Show(); - - // Operations: - virtual void OnClose(AWEvent* event); - virtual void OnUnit(AWEvent* event); - -protected: - virtual void DrawUnits(); - - PlanScreen* manager; - Button* close_btn; - - ActiveWindow* mission_name; - ActiveWindow* mission_system; - ActiveWindow* mission_sector; - ActiveWindow* mission_time_start; - - ActiveWindow* objectives; - ActiveWindow* situation; - ActiveWindow* mission_score; - - ListBox* unit_list; - ListBox* summary_list; - ListBox* event_list; - - Campaign* campaign; - Mission* mission; - MissionInfo* info; - int unit_index; - - Sim* sim; - Ship* ship; -}; - -#endif // DebriefDlg_h - diff --git a/Stars45/Debris.cpp b/Stars45/Debris.cpp deleted file mode 100644 index 952c133..0000000 --- a/Stars45/Debris.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Debris Sprite animation class -*/ - -#include "Debris.h" -#include "Shot.h" -#include "Explosion.h" -#include "Sim.h" -#include "StarSystem.h" -#include "Terrain.h" - -#include "Solid.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Clock.h" -#include "Random.h" - -// +--------------------------------------------------------------------+ - -Debris::Debris(Model* model, const Vec3& pos, const Vec3& vel, double m) -: SimObject("Debris", SimObject::SIM_DEBRIS) -{ - MoveTo(pos); - - velocity = vel; - mass = (float) m; - integrity = mass * 10.0f; - life = 300; - - Solid* solid = new Solid; - - if (solid) { - solid->UseModel(model); - solid->MoveTo(pos); - - rep = solid; - - radius = solid->Radius(); - } - - Point torque = RandomVector(Mass()/2); - - if (Mass() < 10) - torque *= (rand() / 3200); - else if (Mass() > 10e3) - torque *= 0.25; - else if (Mass() > 10e6) - torque *= 0.005; - - ApplyTorque(torque); -} - -// +--------------------------------------------------------------------+ - -int -Debris::HitBy(Shot* shot, Point& impact) -{ - if (!shot->IsArmed()) return 0; - - const int HIT_NOTHING = 0; - const int HIT_HULL = 1; - - Point hull_impact; - int hit_type = HIT_NOTHING; - bool hit_hull = true; - Point shot_loc = shot->Location(); - Point delta = shot_loc - Location(); - double dlen = delta.length(); - double dscale = 1; - float scale = 1.0f; - Sim* sim = Sim::GetSim(); - - // MISSILE PROCESSING ------------------------------------------------ - - if (shot->IsMissile()) { - if (dlen < Radius()) { - hull_impact = impact = shot_loc; - sim->CreateExplosion(impact, Velocity(), Explosion::HULL_FLASH, 0.3f * scale, scale, region, this); - sim->CreateExplosion(impact, Point(), Explosion::SHOT_BLAST, 2.0f, scale, region); - hit_type = HIT_HULL; - } - } - - // ENERGY WEP PROCESSING --------------------------------------------- - - else { - - Solid* solid = (Solid*) rep; - - Point shot_loc = shot->Location(); - Point shot_vpn = shot_loc - shot->Origin(); - double shot_len = shot_vpn.Normalize(); - if (shot_len == 0) shot_len = 1000; - - // impact: - if (solid) { - if (solid->CheckRayIntersection(shot->Origin(), shot_vpn, shot_len, impact)) { - // trim beam shots to impact point: - if (shot->IsBeam()) - shot->SetBeamPoints(shot->Origin(), impact); - - hull_impact = impact; - - if (shot->IsBeam()) - sim->CreateExplosion(impact, Velocity(), Explosion::BEAM_FLASH, 0.30f * scale, scale, region, this); - else - sim->CreateExplosion(impact, Velocity(), Explosion::HULL_FLASH, 0.30f * scale, scale, region, this); - - Point burst_vel = hull_impact - Location(); - burst_vel.Normalize(); - burst_vel *= Radius() * 0.5; - burst_vel += Velocity(); - - sim->CreateExplosion(hull_impact, burst_vel, Explosion::HULL_BURST, 0.50f * scale, scale, region, this); - - hit_type = HIT_HULL; - hit_hull = true; - } - } - - else { - if (dlen < Radius()) { - hull_impact = impact = shot_loc; - - if (shot->IsBeam()) - sim->CreateExplosion(impact, Velocity(), Explosion::BEAM_FLASH, 0.30f * scale, scale, region, this); - else - sim->CreateExplosion(impact, Velocity(), Explosion::HULL_FLASH, 0.30f * scale, scale, region, this); - - hit_type = HIT_HULL; - } - } - } - - // DAMAGE RESOLUTION ------------------------------------------------- - - if (hit_type != HIT_NOTHING) { - double effective_damage = shot->Damage() * dscale; - - if (shot->IsBeam()) { - effective_damage *= Clock::GetInstance()->Delta(); - } - else { - ApplyTorque(shot->Velocity() * (float) effective_damage * 1e-6f); - } - - if (effective_damage > 0) - Physical::InflictDamage(effective_damage); - } - - return hit_type; -} - -// +--------------------------------------------------------------------+ - -void -Debris::ExecFrame(double seconds) -{ - if (GetRegion()->Type() == SimRegion::AIR_SPACE) { - if (AltitudeAGL() < Radius()) { - velocity = Point(); - arcade_velocity = Point(); - - Terrain* terrain = region->GetTerrain(); - - if (terrain) { - Point loc = Location(); - MoveTo(Point(loc.x, terrain->Height(loc.x, loc.z), loc.z)); - } - } - else { - if (mass > 100) { - Orbital* primary = GetRegion()->GetOrbitalRegion()->Primary(); - - const double GRAV = 6.673e-11; - double m0 = primary->Mass(); - double r = primary->Radius(); - - SetDrag(0.001); - SetGravity(6 * GRAV * m0 / (r*r)); // accentuate gravity - SetBaseDensity(1.0f); - } - - AeroFrame(seconds); - } - } - else { - Physical::ExecFrame(seconds); - } -} - -// +--------------------------------------------------------------------+ - -double -Debris::AltitudeAGL() const -{ - Point loc = Location(); - double altitude_agl = loc.y; - - Terrain* terrain = region->GetTerrain(); - - if (terrain) - altitude_agl -= terrain->Height(loc.x, loc.z); - - if (!_finite(altitude_agl)) - altitude_agl = 0; - - return altitude_agl; -} \ No newline at end of file diff --git a/Stars45/Debris.h b/Stars45/Debris.h deleted file mode 100644 index 7c544b1..0000000 --- a/Stars45/Debris.h +++ /dev/null @@ -1,42 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Debris Sprite class -*/ - -#ifndef Debris_h -#define Debris_h - -#include "Types.h" -#include "Geometry.h" -#include "SimObject.h" - -// +--------------------------------------------------------------------+ - -class Solid; -class Model; -class Shot; - -// +--------------------------------------------------------------------+ - -class Debris : public SimObject -{ -public: - Debris(Model* model, const Vec3& pos, const Vec3& vel, double mass); - - void SetLife(int seconds) { life = seconds; } - virtual int HitBy(Shot* shot, Point& impact); - - virtual void ExecFrame(double seconds); - virtual double AltitudeAGL() const; -}; - -#endif // Debris_h - diff --git a/Stars45/DetailSet.cpp b/Stars45/DetailSet.cpp deleted file mode 100644 index 6edaec4..0000000 --- a/Stars45/DetailSet.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Level of Detail manager class -*/ - -#include "DetailSet.h" -#include "Random.h" -#include "Video.h" - -// +--------------------------------------------------------------------+ - -SimRegion* DetailSet::ref_rgn = 0; -Point DetailSet::ref_loc; - -// +--------------------------------------------------------------------+ - -DetailSet::DetailSet() -{ - for (int i = 0; i < MAX_DETAIL; i++) - rad[i] = 0; - - index = -1; - levels = 0; - rgn = 0; -} - -DetailSet::~DetailSet() -{ - Destroy(); -} - -// +--------------------------------------------------------------------+ - -int -DetailSet::DefineLevel(double r, Graphic* g, Point* o, Point* spin_rate) -{ - if (levels < MAX_DETAIL && rep[levels].size() == 0) { - rad[levels] = r; - - if (g) - rep[levels].append(g); - - if (o) - off[levels].append(o); - - else if (g) - off[levels].append(new Point(0,0,0)); - - if (rate.size() == 0) { - if (spin_rate) { - rate.append(spin_rate); - - // randomize the initial orientation: - Point* initial_spin = new Point(); - if (spin_rate->x != 0) initial_spin->x = Random(-PI, PI); - if (spin_rate->y != 0) initial_spin->y = Random(-PI, PI); - if (spin_rate->z != 0) initial_spin->z = Random(-PI, PI); - - spin.append(initial_spin); - } - else { - rate.append(new Point()); - spin.append(new Point()); - } - } - else { - if (spin_rate) - rate[ rep[levels].size() - 1 ] = spin_rate; - } - - levels++; - } - - return levels-1; -} - -void -DetailSet::AddToLevel(int level, Graphic* g, Point* offset, Point* spin_rate) -{ - if (g && level >= 0 && level < levels) { - rep[level].append(g); - - if (!offset) - offset = new Point(0,0,0); - - off[level].append(offset); - - if (spin_rate) { - int nrep = rep[level].size(); - if (nrep > rate.size()) - rate.append(spin_rate); - else - rate[ nrep-1 ] = spin_rate; - } - - if (spin.size() < rep[level].size()) { - Point* initial_spin = new Point(); - - if (spin_rate) { - // randomize the initial orientation: - if (spin_rate->x != 0) initial_spin->x = Random(-PI, PI); - if (spin_rate->y != 0) initial_spin->y = Random(-PI, PI); - if (spin_rate->z != 0) initial_spin->z = Random(-PI, PI); - } - - spin.append(initial_spin); - } - } -} - -int -DetailSet::NumModels(int level) const -{ - if (level >= 0 && level < levels) - return rep[level].size(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -DetailSet::ExecFrame(double seconds) -{ - for (int i = 0; i < spin.size() && i < rate.size(); i++) - (*spin[i]) += (*rate[i]) * seconds; -} - -// +--------------------------------------------------------------------+ - -void -DetailSet::SetLocation(SimRegion* r, const Point& p) -{ - rgn = r; - loc = p; -} - -// +--------------------------------------------------------------------+ - -void -DetailSet::SetReference(SimRegion* r, const Point& p) -{ - ref_rgn = r; - ref_loc = p; -} - -// +--------------------------------------------------------------------+ - -int -DetailSet::GetDetailLevel() -{ - index = 0; - - if (rgn == ref_rgn) { - double screen_width = Video::GetInstance()->Width(); - Point delta = loc - ref_loc; - double distance = delta.length(); - - for (int i = 1; i < levels && rad[i] > 0; i++) { - double apparent_feature_size = (rad[i] * screen_width) / distance; - - if (apparent_feature_size > 0.4) - index = i; - } - } - - return index; -} - -// +--------------------------------------------------------------------+ - -Graphic* -DetailSet::GetRep(int level, int n) -{ - if (level >= 0 && level < levels && n >= 0 && n < rep[level].size()) - return rep[level].at(n); - - return 0; -} - -Point -DetailSet::GetOffset(int level, int n) -{ - if (level >= 0 && level < levels && n >= 0 && n < off[level].size()) - return *(off[level].at(n)); - - return Point(); -} - -Point -DetailSet::GetSpin(int level, int n) -{ - if (n >= 0 && n < spin.size()) - return *(spin.at(n)); - - return Point(); -} - -// +--------------------------------------------------------------------+ - -void -DetailSet::Destroy() -{ - for (int i = 0; i < levels; i++) { - ListIter iter = rep[i]; - - while (++iter) { - Graphic* g = iter.removeItem(); - g->Destroy(); // this will delete the object (g) - } - - off[i].destroy(); - } - - rate.destroy(); - spin.destroy(); -} diff --git a/Stars45/DetailSet.h b/Stars45/DetailSet.h deleted file mode 100644 index 1e6887c..0000000 --- a/Stars45/DetailSet.h +++ /dev/null @@ -1,72 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Level of Detail Manger class -*/ - -#ifndef DetailSet_h -#define DetailSet_h - -#include "Types.h" -#include "Geometry.h" -#include "Graphic.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Sim; -class SimRegion; - -// +--------------------------------------------------------------------+ - -class DetailSet -{ -public: - enum { MAX_DETAIL = 4 }; - - DetailSet(); - virtual ~DetailSet(); - - int DefineLevel(double r, Graphic* g=0, Point* offset=0, Point* spin=0); - void AddToLevel(int level, Graphic* g, Point* offset=0, Point* spin=0); - int NumLevels() const { return levels; } - int NumModels(int level) const; - - void ExecFrame(double seconds); - void SetLocation(SimRegion* rgn, const Point& loc); - static void SetReference(SimRegion* rgn, const Point& loc); - - int GetDetailLevel(); - Graphic* GetRep(int level, int n=0); - Point GetOffset(int level, int n=0); - Point GetSpin(int level, int n=0); - void Destroy(); - -protected: - List rep[MAX_DETAIL]; - List off[MAX_DETAIL]; - double rad[MAX_DETAIL]; - - List spin; - List rate; - - int index; - int levels; - SimRegion* rgn; - Point loc; - - static SimRegion* ref_rgn; - static Point ref_loc; -}; - -// +--------------------------------------------------------------------+ - -#endif // DetailSet_h - diff --git a/Stars45/Director.h b/Stars45/Director.h deleted file mode 100644 index dbed513..0000000 --- a/Stars45/Director.h +++ /dev/null @@ -1,43 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract Director (AI or Human Input) for Physical Objects -*/ - -#ifndef Director_h -#define Director_h - -#include "Types.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Physical; - -// +--------------------------------------------------------------------+ - -class Director -{ -public: - Director() { } - virtual ~Director() { } - - // accessors: - virtual int Type() const { return 0; } - virtual int Subframe() const { return 0; } - - // operations - virtual void ExecFrame(double factor) { } -}; - -// +--------------------------------------------------------------------+ - -#endif // Director_h - diff --git a/Stars45/DisplayView.cpp b/Stars45/DisplayView.cpp deleted file mode 100644 index 89d019d..0000000 --- a/Stars45/DisplayView.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Quantum Destination HUD Overlay -*/ - -#include "DisplayView.h" -#include "QuantumDrive.h" -#include "HUDView.h" -#include "Ship.h" -#include "Element.h" -#include "Sim.h" -#include "StarSystem.h" -#include "FormatUtil.h" - -#include "Color.h" -#include "Window.h" -#include "Video.h" -#include "Screen.h" -#include "DataLoader.h" -#include "Scene.h" -#include "Font.h" -#include "FontMgr.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Clock.h" -#include "Menu.h" - -// +====================================================================+ - -class DisplayElement -{ -public: - static const char* TYPENAME() { return "DisplayElement"; } - - DisplayElement() : image(0), font(0), blend(0), hold(0), fade_in(0), fade_out(0) { } - - Text text; - Bitmap* image; - Font* font; - Color color; - Rect rect; - int blend; - double hold; - double fade_in; - double fade_out; -}; - -// +====================================================================+ - -DisplayView* display_view = 0; - -DisplayView::DisplayView(Window* c) -: View(c), width(0), height(0), xcenter(0), ycenter(0) -{ - display_view = this; - DisplayView::OnWindowMove(); -} - -DisplayView::~DisplayView() -{ - if (display_view == this) - display_view = 0; - - elements.destroy(); -} - -DisplayView* -DisplayView::GetInstance() -{ - if (display_view == 0) - display_view = new DisplayView(0); - - return display_view; -} - -void -DisplayView::OnWindowMove() -{ - if (window) { - width = window->Width(); - height = window->Height(); - xcenter = (width / 2.0) - 0.5; - ycenter = (height / 2.0) + 0.5; - } -} - -// +--------------------------------------------------------------------+ - -void -DisplayView::Refresh() -{ - ListIter iter = elements; - while (++iter) { - DisplayElement* elem = iter.value(); - - // convert relative rect to window rect: - Rect elem_rect = elem->rect; - if (elem_rect.x == 0 && elem_rect.y == 0 && elem_rect.w == 0 && elem_rect.h == 0) { - // stretch to fit - elem_rect.w = width; - elem_rect.h = height; - } - else if (elem_rect.w < 0 && elem_rect.h < 0) { - // center image in window - elem_rect.w *= -1; - elem_rect.h *= -1; - - elem_rect.x = (width - elem_rect.w)/2; - elem_rect.y = (height - elem_rect.h)/2; - } - else { - // offset from right or bottom - if (elem_rect.x < 0) elem_rect.x += width; - if (elem_rect.y < 0) elem_rect.y += height; - } - - // compute current fade, - // assumes fades are 1 second or less: - double fade = 0; - if (elem->fade_in > 0) fade = 1 - elem->fade_in; - else if (elem->hold > 0) fade = 1; - else if (elem->fade_out > 0) fade = elem->fade_out; - - // draw text: - if (elem->text.length() && elem->font) { - elem->font->SetColor(elem->color); - elem->font->SetAlpha(fade); - window->SetFont(elem->font); - window->DrawText(elem->text, elem->text.length(), elem_rect, DT_WORDBREAK); - } - - // draw image: - else if (elem->image) { - window->FadeBitmap( elem_rect.x, - elem_rect.y, - elem_rect.x + elem_rect.w, - elem_rect.y + elem_rect.h, - elem->image, - elem->color * fade, - elem->blend ); - - } - } -} - -// +--------------------------------------------------------------------+ - -void -DisplayView::ExecFrame() -{ - double seconds = Clock::GetInstance()->GuiDelta(); - - ListIter iter = elements; - while (++iter) { - DisplayElement* elem = iter.value(); - - if (elem->fade_in > 0) - elem->fade_in -= seconds; - - else if (elem->hold > 0) - elem->hold -= seconds; - - else if (elem->fade_out > 0) - elem->fade_out -= seconds; - - else - delete iter.removeItem(); - } -} - -// +--------------------------------------------------------------------+ - -void -DisplayView::ClearDisplay() -{ - elements.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -DisplayView::AddText( const char* text, -Font* font, -Color color, -const Rect& rect, -double hold, -double fade_in, -double fade_out) -{ - DisplayElement* elem = new DisplayElement; - - if (fade_in == 0 && fade_out == 0 && hold == 0) - hold = 300; - - elem->text = text; - elem->font = font; - elem->color = color; - elem->rect = rect; - elem->hold = hold; - elem->fade_in = fade_in; - elem->fade_out = fade_out; - - elements.append(elem); -} - -void -DisplayView::AddImage(Bitmap* bmp, -Color color, -int blend, -const Rect& rect, -double hold, -double fade_in, -double fade_out) -{ - DisplayElement* elem = new DisplayElement; - - if (fade_in == 0 && fade_out == 0 && hold == 0) - hold = 300; - - elem->image = bmp; - elem->rect = rect; - elem->color = color; - elem->blend = blend; - elem->hold = hold; - elem->fade_in = fade_in; - elem->fade_out = fade_out; - - elements.append(elem); -} diff --git a/Stars45/DisplayView.h b/Stars45/DisplayView.h deleted file mode 100644 index a929970..0000000 --- a/Stars45/DisplayView.h +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Radio Communications HUD Overlay -*/ - -#ifndef DisplayView_h -#define DisplayView_h - -#include "Types.h" -#include "View.h" -#include "SimObject.h" -#include "Color.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Bitmap; -class DisplayElement; -class Font; - -// +--------------------------------------------------------------------+ - -class DisplayView : public View -{ -public: - DisplayView(Window* c); - virtual ~DisplayView(); - - // Operations: - virtual void Refresh(); - virtual void OnWindowMove(); - virtual void ExecFrame(); - virtual void ClearDisplay(); - - virtual void AddText(const char* txt, - Font* font, - Color color, - const Rect& rect, - double hold = 1e9, - double fade_in = 0, - double fade_out = 0); - - virtual void AddImage(Bitmap* bmp, - Color color, - int blend, - const Rect& rect, - double hold = 1e9, - double fade_in = 0, - double fade_out = 0); - - static DisplayView* GetInstance(); - -protected: - int width, height; - double xcenter, ycenter; - - List - elements; -}; - -#endif // DisplayView_h - diff --git a/Stars45/Drive.cpp b/Stars45/Drive.cpp deleted file mode 100644 index bf1966c..0000000 --- a/Stars45/Drive.cpp +++ /dev/null @@ -1,500 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon class -*/ - -#define NOMINMAX - -#include - -#include "Drive.h" -#include "Power.h" -#include "Ship.h" -#include "Sim.h" -#include "DriveSprite.h" -#include "CameraDirector.h" -#include "AudioConfig.h" - -#include "Light.h" -#include "Bitmap.h" -#include "Sound.h" -#include "DataLoader.h" -#include "Bolt.h" -#include "Solid.h" -#include "Game.h" -#include "ContentBundle.h" - -// +--------------------------------------------------------------------+ - -static int drive_value[] = { - 1, 1, 1, 1, 1, 1, 1, 1 -}; - -static float drive_light[] = { - 10.0f, 100.0f, 5.0f, 1.0e3f, 100.0f, 10.0f, 0.0f, 0.0f -}; - -Bitmap* drive_flare_bitmap[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -Bitmap* drive_trail_bitmap[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -Bitmap* drive_glow_bitmap[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -static Sound* sound_resource[3] = { 0, 0, 0 }; - -#define CLAMP(x, a, b) if (x < (a)) x = (a); else if (x > (b)) x = (b); - -// +----------------------------------------------------------------------+ - -DrivePort::DrivePort(const Point& l, float s) - : loc(l), flare(0), trail(0), scale(s) -{ } - -DrivePort::~DrivePort() -{ - GRAPHIC_DESTROY(flare); - GRAPHIC_DESTROY(trail); -} - -// +----------------------------------------------------------------------+ - -Drive::Drive(SUBTYPE drive_type, float max_thrust, float max_aug, bool show) - : System(DRIVE, drive_type, "Drive", drive_value[drive_type], - max_thrust*2, max_thrust*2, max_thrust*2), - thrust(max_thrust), augmenter(max_aug), scale(0.0f), - throttle(0.0f), augmenter_throttle(0.0f), intensity(0.0f), - sound(0), burner_sound(0), show_trail(show) -{ - power_flags = POWER_WATTS; - - switch (drive_type) { - default: - case PLASMA: name = ContentBundle::GetInstance()->GetText("sys.drive.plasma"); break; - case FUSION: name = ContentBundle::GetInstance()->GetText("sys.drive.fusion"); break; - case GREEN: name = ContentBundle::GetInstance()->GetText("sys.drive.green"); break; - case RED: name = ContentBundle::GetInstance()->GetText("sys.drive.red"); break; - case BLUE: name = ContentBundle::GetInstance()->GetText("sys.drive.blue"); break; - case YELLOW: name = ContentBundle::GetInstance()->GetText("sys.drive.yellow"); break; - case STEALTH: name = ContentBundle::GetInstance()->GetText("sys.drive.stealth"); break; - } - - abrv = ContentBundle::GetInstance()->GetText("sys.drive.abrv"); - - emcon_power[0] = 0; - emcon_power[1] = 50; - emcon_power[2] = 100; -} - -// +----------------------------------------------------------------------+ - -Drive::Drive(const Drive& d) - : System(d), thrust(d.thrust), augmenter(d.augmenter), scale(d.scale), - throttle(0.0f), augmenter_throttle(0.0f), intensity(0.0f), - sound(0), burner_sound(0), show_trail(d.show_trail) -{ - power_flags = POWER_WATTS; - - Mount(d); - - if (subtype != Drive::STEALTH) { - for (int i = 0; i < d.ports.size(); i++) { - DrivePort* p = d.ports[i]; - CreatePort(p->loc, p->scale); - } - } -} - -// +--------------------------------------------------------------------+ - -Drive::~Drive() -{ - if (sound) { - sound->Stop(); - sound->Release(); - sound = 0; - } - - if (burner_sound) { - burner_sound->Stop(); - burner_sound->Release(); - burner_sound = 0; - } - - ports.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -Drive::Initialize() -{ - static int initialized = 0; - if (initialized) return; - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Drive/"); - loader->LoadTexture("Drive0.pcx", drive_flare_bitmap[0], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Drive1.pcx", drive_flare_bitmap[1], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Drive2.pcx", drive_flare_bitmap[2], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Drive3.pcx", drive_flare_bitmap[3], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Drive4.pcx", drive_flare_bitmap[4], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Drive5.pcx", drive_flare_bitmap[5], Bitmap::BMP_TRANSLUCENT); - - loader->LoadTexture("Trail0.pcx", drive_trail_bitmap[0], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Trail1.pcx", drive_trail_bitmap[1], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Trail2.pcx", drive_trail_bitmap[2], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Trail3.pcx", drive_trail_bitmap[3], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Trail4.pcx", drive_trail_bitmap[4], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Trail5.pcx", drive_trail_bitmap[5], Bitmap::BMP_TRANSLUCENT); - - loader->LoadTexture("Glow0.pcx", drive_glow_bitmap[0], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Glow1.pcx", drive_glow_bitmap[1], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Glow2.pcx", drive_glow_bitmap[2], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Glow3.pcx", drive_glow_bitmap[3], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Glow4.pcx", drive_glow_bitmap[4], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("Glow5.pcx", drive_glow_bitmap[5], Bitmap::BMP_TRANSLUCENT); - - const int SOUND_FLAGS = Sound::LOCALIZED | - Sound::LOC_3D | - Sound::LOOP | - Sound::LOCKED; - - loader->SetDataPath("Sounds/"); - loader->LoadSound("engine.wav", sound_resource[0], SOUND_FLAGS); - loader->LoadSound("burner2.wav", sound_resource[1], SOUND_FLAGS); - loader->LoadSound("rumble.wav", sound_resource[2], SOUND_FLAGS); - loader->SetDataPath(0); - - if (sound_resource[0]) - sound_resource[0]->SetMaxDistance(30.0e3f); - - if (sound_resource[1]) - sound_resource[1]->SetMaxDistance(30.0e3f); - - if (sound_resource[2]) - sound_resource[2]->SetMaxDistance(50.0e3f); - - initialized = 1; -} - -// +--------------------------------------------------------------------+ - -void -Drive::Close() -{ - for (int i = 0; i < 3; i++) { - delete sound_resource[i]; - sound_resource[i] = 0; - } -} - -// +--------------------------------------------------------------------+ - -void -Drive::StartFrame() -{ -} - -// +--------------------------------------------------------------------+ - -void -Drive::AddPort(const Point& loc, float flare_scale) -{ - if (flare_scale == 0) flare_scale = scale; - DrivePort* port = new DrivePort(loc, flare_scale); - ports.append(port); -} - -// +--------------------------------------------------------------------+ - -void -Drive::CreatePort(const Point& loc, float flare_scale) -{ - Bitmap* flare_bmp = drive_flare_bitmap[subtype]; - Bitmap* trail_bmp = drive_trail_bitmap[subtype]; - Bitmap* glow_bmp = 0; - - if (flare_scale <= 0) - flare_scale = scale; - - if (augmenter <= 0) - glow_bmp = drive_glow_bitmap[subtype]; - - if (subtype != Drive::STEALTH && flare_scale > 0) { - DrivePort* port = new DrivePort(loc, flare_scale); - - if (flare_bmp) { - DriveSprite* flare_rep = new DriveSprite(flare_bmp, glow_bmp); - flare_rep->Scale(flare_scale * 1.5); - flare_rep->SetShade(0); - port->flare = flare_rep; - } - - if (trail_bmp && show_trail) { - Bolt* trail_rep = new Bolt(flare_scale * 30, flare_scale * 8, trail_bmp, true); - port->trail = trail_rep; - } - - ports.append(port); - } -} - -// +--------------------------------------------------------------------+ - -void -Drive::Orient(const Physical* rep) -{ - System::Orient(rep); - - const Matrix& orientation = rep->Cam().Orientation(); - Point ship_loc = rep->Location(); - - for (int i = 0; i < ports.size(); i++) { - DrivePort* p = ports[i]; - - Point projector = (p->loc * orientation) + ship_loc; - - if (p->flare) { - p->flare->MoveTo(projector); - p->flare->SetFront(rep->Cam().vpn() * -10 * p->scale); - } - - if (p->trail) { - if (intensity > 0.5) { - double len = -60 * p->scale * intensity; - - if (augmenter > 0 && augmenter_throttle > 0) - len += len * augmenter_throttle; - - p->trail->Show(); - p->trail->SetEndPoints(projector, projector + rep->Cam().vpn() * len); - } - else { - p->trail->Hide(); - } - } - } -} - -// +--------------------------------------------------------------------+ - -static double drive_seconds=0; - -void -Drive::SetThrottle(double t, bool aug) -{ - double spool = 1.2 * drive_seconds; - double throttle_request = t / 100; - - if (throttle < throttle_request) { - if (throttle_request-throttle < spool) { - throttle = (float) throttle_request; - } - else { - throttle += (float) spool; - } - } - - else if (throttle > throttle_request) { - if (throttle - throttle_request < spool) { - throttle = (float) throttle_request; - } - else { - throttle -= (float) spool; - } - } - - if (throttle < 0.5) - aug = false; - - if (aug && augmenter_throttle < 1) { - augmenter_throttle += (float) spool; - - if (augmenter_throttle > 1) - augmenter_throttle = 1.0f; - } - else if (!aug && augmenter_throttle > 0) { - augmenter_throttle -= (float) spool; - - if (augmenter_throttle < 0) - augmenter_throttle = 0.0f; - } -} - -// +----------------------------------------------------------------------+ - -double -Drive::GetRequest(double seconds) const -{ - if (!power_on) return 0; - - double t_factor = std::max(throttle + 0.5 * augmenter_throttle, 0.3); - - return t_factor * power_level * sink_rate * seconds; -} - -bool -Drive::IsAugmenterOn() const -{ - return augmenter > 0 && - augmenter_throttle > 0.05 && - IsPowerOn() && - status > CRITICAL; -} - -// +--------------------------------------------------------------------+ - -int -Drive::NumEngines() const -{ - return ports.size(); -} - -DriveSprite* -Drive::GetFlare(int port) const -{ - if (port >= 0 && port < ports.size()) { - return ports[port]->flare; - } - - return 0; -} - -Bolt* -Drive::GetTrail(int port) const -{ - if (port >= 0 && port < ports.size()) { - return ports[port]->trail; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -float -Drive::Thrust(double seconds) -{ - drive_seconds = seconds; - - float eff = (energy/capacity) * availability * 100.0f; - float output = throttle * thrust * eff; - bool aug_on = IsAugmenterOn(); - - if (aug_on) { - output += augmenter * augmenter_throttle * eff; - - // augmenter burns extra fuel: - PowerSource* reac = ship->Reactors()[source_index]; - reac->SetCapacity(reac->GetCapacity() - (0.1 * drive_seconds)); - } - - energy = 0.0f; - - if (output < 0 || GetPowerLevel() < 0.01) - output = 0.0f; - - int vol = -10000; - int vol_aug = -10000; - double fraction = output / thrust; - - for (int i = 0; i < ports.size(); i++) { - DrivePort* p = ports[i]; - - if (p->flare) { - if (i == 0) { - if (fraction > 0) - intensity += (float) seconds; - else - intensity -= (float) seconds; - - // capture volume based on actual output: - CLAMP(intensity, 0.0f, 1.0f); - - if (intensity > 0.25) { - vol = (int) ((intensity - 1.0) * 10000.0); - CLAMP(vol, -10000, -1500); - - if (aug_on && intensity > 0.5) { - vol_aug = (int) ((5 * augmenter_throttle - 1.0) * 10000.0); - CLAMP(vol_aug, -10000, -1000); - } - } - } - - p->flare->SetShade(intensity); - } - - if (p->trail) { - p->trail->SetShade(intensity); - } - } - - CameraDirector* cam_dir = CameraDirector::GetInstance(); - - // no sound when paused! - if (!Game::GetInstance()->Paused() && subtype != STEALTH && cam_dir && cam_dir->GetCamera()) { - if (ship && ship->GetRegion() == Sim::GetSim()->GetActiveRegion()) { - if (!sound) { - int sound_index = 0; - if (thrust > 100) - sound_index = 2; - - if (sound_resource[sound_index]) - sound = sound_resource[sound_index]->Duplicate(); - } - - if (aug_on && !burner_sound) { - if (sound_resource[1]) - burner_sound = sound_resource[1]->Duplicate(); - } - - Point cam_loc = cam_dir->GetCamera()->Pos(); - double dist = (ship->Location() - cam_loc).length(); - - if (sound && dist < sound->GetMaxDistance()) { - long max_vol = AudioConfig::EfxVolume(); - - if (vol > max_vol) - vol = max_vol; - - if (sound) { - sound->SetLocation(ship->Location()); - sound->SetVolume(vol); - sound->Play(); - } - - if (burner_sound) { - if (vol_aug > max_vol) - vol_aug = max_vol; - - burner_sound->SetLocation(ship->Location()); - burner_sound->SetVolume(vol_aug); - burner_sound->Play(); - } - } - else { - if (sound && sound->IsPlaying()) - sound->Stop(); - - if (burner_sound && burner_sound->IsPlaying()) - burner_sound->Stop(); - } - } - else { - if (sound && sound->IsPlaying()) - sound->Stop(); - - if (burner_sound && burner_sound->IsPlaying()) - burner_sound->Stop(); - } - } - - return output; -} diff --git a/Stars45/Drive.h b/Stars45/Drive.h deleted file mode 100644 index b47c10e..0000000 --- a/Stars45/Drive.h +++ /dev/null @@ -1,92 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Conventional Drive (system) class -*/ - -#ifndef Drive_h -#define Drive_h - -#include "Types.h" -#include "System.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Bolt; -class DriveSprite; -class Light; -class Sound; -class Ship; - -// +--------------------------------------------------------------------+ - -struct DrivePort { - static const char* TYPENAME() { return "DrivePort"; } - - DrivePort(const Point& l, float s); - ~DrivePort(); - - Point loc; - float scale; - - DriveSprite* flare; - Bolt* trail; -}; - -// +--------------------------------------------------------------------+ - -class Drive : public System -{ -public: - enum SUBTYPE { PLASMA, FUSION, GREEN, RED, BLUE, YELLOW, STEALTH }; - enum Constants { MAX_ENGINES=16 }; - - Drive(SUBTYPE s, float max_thrust, float max_aug, bool show_trail=true); - Drive(const Drive& rhs); - virtual ~Drive(); - - static void Initialize(); - static void Close(); - static void StartFrame(); - - float Thrust(double seconds); - float MaxThrust() const { return thrust; } - float MaxAugmenter() const { return augmenter; } - int NumEngines() const; - DriveSprite* GetFlare(int port) const; - Bolt* GetTrail(int port) const; - bool IsAugmenterOn() const; - - virtual void AddPort(const Point& loc, float flare_scale=0); - virtual void CreatePort(const Point& loc, float flare_scale); - - virtual void Orient(const Physical* rep); - - void SetThrottle(double t, bool aug=false); - virtual double GetRequest(double seconds) const; - -protected: - float thrust; - float augmenter; - float scale; - float throttle; - float augmenter_throttle; - float intensity; - - List ports; - - Sound* sound; - Sound* burner_sound; - bool show_trail; -}; - -#endif // Drive_h - diff --git a/Stars45/DriveSprite.cpp b/Stars45/DriveSprite.cpp deleted file mode 100644 index 804ef4b..0000000 --- a/Stars45/DriveSprite.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Sprite for rendering drive flares. Remains visible at extreme ranges. -*/ - -#include "DriveSprite.h" - -#include "Bitmap.h" -#include "Camera.h" -#include "Scene.h" -#include "Video.h" - -// +--------------------------------------------------------------------+ - -DriveSprite::DriveSprite() - : Sprite(), glow(0), effective_radius(0), front(0,0,0), bias(0) -{ luminous = true; } - -DriveSprite::DriveSprite(Bitmap* animation, Bitmap* g) - : Sprite(animation), glow(g), effective_radius(0), front(0,0,0), bias(0) -{ luminous = true; } - -DriveSprite::DriveSprite(Bitmap* animation, int length, int repeat, int share) - : Sprite(animation, length, repeat, share), glow(0), effective_radius(0), - front(0,0,0), bias(0) -{ luminous = true; } - -DriveSprite::~DriveSprite() -{ } - -// +--------------------------------------------------------------------+ - -void -DriveSprite::SetFront(const Vec3& f) -{ - front = f; - front.Normalize(); -} - -void -DriveSprite::SetBias(DWORD b) -{ - bias = b; -} - -// +--------------------------------------------------------------------+ - -void -DriveSprite::Render(Video* video, DWORD flags) -{ - if (!video || ((flags & RENDER_ADDITIVE) == 0)) - return; - - if (shade > 0 && !hidden && (life > 0 || loop)) { - const Camera* cam = video->GetCamera(); - bool z_disable = false; - - if (bias) - video->SetRenderState(Video::Z_BIAS, bias); - - if (front.length()) { - Point test = loc; - - if (scene && cam) { - Vec3 dir = front; - - double intensity = cam->vpn() * dir * -1; - double distance = Point(cam->Pos() - test).length(); - - if (intensity > 0.05) { - if (!scene->IsLightObscured(cam->Pos(), test, 8)) { - video->SetRenderState(Video::Z_ENABLE, false); - z_disable = true; - - if (glow) { - intensity = pow(intensity, 3); - - if (distance > 5e3) - intensity *= (1 - (distance-5e3)/45e3); - - if (intensity > 0) { - Bitmap* tmp_frame = frames; - double tmp_shade = shade; - int tmp_w = w; - int tmp_h = h; - - if (glow->Width() != frames->Width()) { - double wscale = glow->Width() / frames->Width(); - double hscale = glow->Height() / frames->Height(); - - w = (int) (w * wscale); - h = (int) (h * hscale); - } - - shade = intensity; - frames = glow; - - Sprite::Render(video, flags); - - frames = tmp_frame; - shade = tmp_shade; - w = tmp_w; - h = tmp_h; - } - } - } - } - } - } - - if (effective_radius-radius > 0.1) { - double scale_up = effective_radius / radius; - int tmp_w = w; - int tmp_h = h; - - w = (int) (w * scale_up); - h = (int) (h * scale_up); - - Sprite::Render(video, flags); - - w = tmp_w; - h = tmp_h; - } - - else { - Sprite::Render(video, flags); - } - - if (bias) video->SetRenderState(Video::Z_BIAS, 0); - if (z_disable) video->SetRenderState(Video::Z_ENABLE, true); - } -} - diff --git a/Stars45/DriveSprite.h b/Stars45/DriveSprite.h deleted file mode 100644 index 76c8bfb..0000000 --- a/Stars45/DriveSprite.h +++ /dev/null @@ -1,46 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Specialized Drive Sprite Object -*/ - -#ifndef DriveSprite_h -#define DriveSprite_h - -#include "Types.h" -#include "Geometry.h" -#include "Sprite.h" - -// +--------------------------------------------------------------------+ - -class DriveSprite : public Sprite -{ -public: - DriveSprite(); - DriveSprite(Bitmap* animation, Bitmap* glow); - DriveSprite(Bitmap* animation, int length=1, int repeat=1, int share=1); - virtual ~DriveSprite(); - - // operations - virtual void Render(Video* video, DWORD flags); - virtual void SetFront(const Vec3& f); - virtual void SetBias(DWORD b); - -protected: - double effective_radius; - Vec3 front; - Bitmap* glow; - DWORD bias; -}; - -// +--------------------------------------------------------------------+ - -#endif // DriveSprite_h - diff --git a/Stars45/Drone.cpp b/Stars45/Drone.cpp deleted file mode 100644 index b568987..0000000 --- a/Stars45/Drone.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Laser and Missile class -*/ - -#include "Drone.h" -#include "Weapon.h" -#include "Ship.h" -#include "Sim.h" -#include "Explosion.h" - -#include "Clock.h" -#include "Bolt.h" -#include "Sprite.h" -#include "Solid.h" -#include "Light.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Sound.h" - -// +--------------------------------------------------------------------+ - -Drone::Drone(const Point& pos, const Camera& shot_cam, WeaponDesign* dsn, const Ship* ship) - : Shot(pos, shot_cam, dsn, ship), - decoy_type(0), iff_code(0) -{ - obj_type = SimObject::SIM_DRONE; - - if (dsn) { - decoy_type = dsn->decoy_type; - probe = dsn->probe; - integrity = dsn->integrity; - sprintf_s(name, "Drone %04d", Identity()); - } -} - -// +--------------------------------------------------------------------+ - -Drone::~Drone() -{ -} - -// +--------------------------------------------------------------------+ - -void -Drone::SeekTarget(SimObject* target, System* sub) -{ - if (!probe) - Shot::SeekTarget(target, sub); -} - -// +--------------------------------------------------------------------+ - -void -Drone::ExecFrame(double seconds) -{ - Shot::ExecFrame(seconds); -} - -// +--------------------------------------------------------------------+ - -void -Drone::Disarm() -{ - Shot::Disarm(); -} - -// +--------------------------------------------------------------------+ - -void -Drone::Destroy() -{ - Shot::Destroy(); -} - -// +--------------------------------------------------------------------+ - -double -Drone::PCS() const -{ - if (decoy_type == 0 && !probe) - return 10e3; - - return 0; -} - -double -Drone::ACS() const -{ - if (decoy_type == 0 && !probe) - return 1e3; - - return 0; -} - -// +--------------------------------------------------------------------+ - -const char* -Drone::ClassName() const -{ - return Ship::ClassName(decoy_type); -} - -int -Drone::Class() const -{ - return decoy_type; -} - -// +--------------------------------------------------------------------+ - -int -Drone::HitBy(Shot* shot, Point& impact) -{ - if (life == 0 || !shot->IsArmed()) return 0; - - const int HIT_NOTHING = 0; - const int HIT_HULL = 1; - - Point hull_impact; - int hit_type = HIT_NOTHING; - Point shot_loc = shot->Location(); - Point shot_org = shot->Origin(); - Point delta = shot_loc - Location(); - double dlen = delta.length(); - double dscale = 1; - float scale = design->explosion_scale; - Sim* sim = Sim::GetSim(); - - if (scale <= 0) - scale = design->scale; - - // MISSILE PROCESSING ------------------------------------------------ - - if (shot->IsMissile()) { - if (dlen < 10 * Radius()) { - hull_impact = impact = shot_loc; - sim->CreateExplosion(impact, Velocity(), Explosion::HULL_FLASH, 0.3f * scale, scale, region); - sim->CreateExplosion(impact, Point(), Explosion::SHOT_BLAST, 2.0f, scale, region); - hit_type = HIT_HULL; - } - } - - // ENERGY WEP PROCESSING --------------------------------------------- - - else { - if (shot->IsBeam()) { - // check right angle spherical distance: - Point d0 = Location() - shot_org; - Point w = shot_loc - shot_org; w.Normalize(); - Point test = shot_org + w * (d0 * w); - Point d1 = test - Location(); - double dlen = d1.length(); // distance of point from line - - if (dlen < 2*Radius()) { - hull_impact = impact = test; - shot->SetBeamPoints(shot_org, impact); - sim->CreateExplosion(impact, Velocity(), Explosion::BEAM_FLASH, 0.30f * scale, scale, region); - hit_type = HIT_HULL; - } - } - else if (dlen < 2*Radius()) { - hull_impact = impact = shot_loc; - sim->CreateExplosion(impact, Velocity(), Explosion::HULL_FLASH, 0.30f * scale, scale, region); - hit_type = HIT_HULL; - } - } - - // DAMAGE RESOLUTION ------------------------------------------------- - - if (hit_type != HIT_NOTHING) { - double effective_damage = shot->Damage() * dscale; - - if (shot->IsBeam()) { - effective_damage *= Clock::GetInstance()->Delta(); - } - else { - ApplyTorque(shot->Velocity() * (float) effective_damage * 1e-6f); - } - - if (effective_damage > 0) - Physical::InflictDamage(effective_damage); - } - - return hit_type; -} diff --git a/Stars45/Drone.h b/Stars45/Drone.h deleted file mode 100644 index d6b89a1..0000000 --- a/Stars45/Drone.h +++ /dev/null @@ -1,68 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Decoy / Weapons Drone class -*/ - -#ifndef Drone_h -#define Drone_h - -#include "Types.h" -#include "Geometry.h" -#include "Shot.h" - -// +--------------------------------------------------------------------+ - -class Camera; -class Ship; -class Trail; -class System; -class WeaponDesign; -class Sprite3D; -class Sound; - -// +--------------------------------------------------------------------+ - -class Drone : public Shot -{ -public: - static const char* TYPENAME() { return "Drone"; } - - Drone(const Point& pos, const Camera& cam, WeaponDesign* design, const Ship* ship=0); - virtual ~Drone(); - - virtual void SeekTarget(SimObject* target, System* sub=0); - virtual void ExecFrame(double factor); - - virtual bool IsDrone() const { return true; } - virtual bool IsDecoy() const { return decoy_type != 0; } - virtual bool IsProbe() const { return probe?true:false; } - - virtual void Disarm(); - virtual void Destroy(); - - // SENSORS AND VISIBILITY: - virtual double PCS() const; - virtual double ACS() const; - virtual const char* ClassName() const; - virtual int Class() const; - - // DAMAGE RESOLUTION: - void SetLife(int seconds) { life = seconds; } - virtual int HitBy(Shot* shot, Point& impact); - -protected: - int iff_code; - int decoy_type; - int probe; -}; - -#endif // Drone_h - diff --git a/Stars45/DropShipAI.cpp b/Stars45/DropShipAI.cpp deleted file mode 100644 index bc563fc..0000000 --- a/Stars45/DropShipAI.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Drop Ship (orbit/surface and surface/orbit) AI class -*/ - -#include "DropShipAI.h" -#include "TacticalAI.h" -#include "Ship.h" -#include "ShipCtrl.h" -#include "Drive.h" -#include "Sim.h" -#include "StarSystem.h" -#include "KeyMap.h" - -#include "Game.h" - -// +----------------------------------------------------------------------+ - -DropShipAI::DropShipAI(Ship* s) - : ShipAI(s) -{ - seek_gain = 20; - seek_damp = 0.5; - - delete tactical; - tactical = 0; -} - -DropShipAI::~DropShipAI() -{ -} - -// +--------------------------------------------------------------------+ - -void -DropShipAI::FindObjective() -{ - distance = 0; - - if (!ship) return; - - Sim* sim = Sim::GetSim(); - SimRegion* self_rgn = ship->GetRegion(); - - // if making orbit, go up: - if (self_rgn->Type() == Sim::AIR_SPACE) { - obj_w = self->Location() + Point(0, 1e3, 0); - } - - // if breaking orbit, head for terrain region: - else { - SimRegion* dst_rgn = sim->FindNearestTerrainRegion(ship); - Point dst = dst_rgn->GetOrbitalRegion()->Location() - - self_rgn->GetOrbitalRegion()->Location() + - Point(0, 0, -1e6); - - obj_w = dst.OtherHand(); - } - - // distance from self to navpt: - distance = Point(obj_w - self->Location()).length(); - - // transform into camera coords: - objective = Transform(obj_w); - objective.Normalize(); -} - -// +--------------------------------------------------------------------+ - -void -DropShipAI::Navigator() -{ - accumulator.Clear(); - magnitude = 0; - - if (other) - ship->SetFLCSMode(Ship::FLCS_AUTO); - else - ship->SetFLCSMode(Ship::FLCS_MANUAL); - - Accumulate(AvoidCollision()); - Accumulate(Seek(objective)); - - // are we being asked to flee? - if (fabs(accumulator.yaw) == 1.0 && accumulator.pitch == 0.0) { - accumulator.pitch = -0.7f; - accumulator.yaw *= 0.25f; - } - - self->ApplyRoll((float) (accumulator.yaw * -0.4)); - self->ApplyYaw((float) (accumulator.yaw * 0.2)); - - if (fabs(accumulator.yaw) > 0.5 && fabs(accumulator.pitch) < 0.1) - accumulator.pitch -= 0.1f; - - if (accumulator.pitch != 0) - self->ApplyPitch((float) accumulator.pitch); - - // if not turning, roll to orient with world coords: - if (fabs(accumulator.yaw) < 0.1) { - Point vrt = ((Camera*) &(self->Cam()))->vrt(); - double deflection = vrt.y; - if (deflection != 0) { - double theta = asin(deflection/vrt.length()); - self->ApplyRoll(-theta); - } - } - - ship->SetThrottle(100); - ship->ExecFLCSFrame(); -} - diff --git a/Stars45/DropShipAI.h b/Stars45/DropShipAI.h deleted file mode 100644 index 0cacffc..0000000 --- a/Stars45/DropShipAI.h +++ /dev/null @@ -1,46 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Drop Ship (orbit/surface and surface/orbit) AI class -*/ - -#ifndef DropShipAI_h -#define DropShipAI_h - -#include "Types.h" -#include "Geometry.h" -#include "System.h" -#include "ShipAI.h" - -// +--------------------------------------------------------------------+ - -class Ship; - -// +--------------------------------------------------------------------+ - -class DropShipAI : public ShipAI -{ -public: - DropShipAI(Ship* s); - virtual ~DropShipAI(); - - enum { DIR_TYPE = 2001 }; - virtual int Type() const { return DIR_TYPE; } - -protected: - // accumulate behaviors: - virtual void Navigator(); - virtual void FindObjective(); -}; - -// +--------------------------------------------------------------------+ - -#endif // DropShipAI_h - diff --git a/Stars45/EditBox.cpp b/Stars45/EditBox.cpp deleted file mode 100644 index cf08a4b..0000000 --- a/Stars45/EditBox.cpp +++ /dev/null @@ -1,448 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - EditBox ActiveWindow class -*/ - -#include "EditBox.h" -#include "FormWindow.h" -#include "Video.h" -#include "Font.h" -#include "Keyboard.h" -#include "Mouse.h" - -// +--------------------------------------------------------------------+ - -static int old_cursor; - -// +--------------------------------------------------------------------+ - -EditBox::EditBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid) - : ScrollWindow(p->GetScreen(), ax, ay, aw, ah, aid, 0, p), caret_x(0), caret_y(0) -{ - sel_start = 0; - sel_length = 0; - h_offset = 0; - pass_char = 0; - - selected_color = Color::Yellow; - - char buf[32]; - sprintf_s(buf, "EditBox %d", id); - desc = buf; -} - -EditBox::EditBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid) - : ScrollWindow(s, ax, ay, aw, ah, aid), caret_x(0), caret_y(0) -{ - sel_start = 0; - sel_length = 0; - h_offset = 0; - pass_char = 0; - - selected_color = Color::Yellow; - - char buf[32]; - sprintf_s(buf, "EditBox %d", id); - desc = buf; -} - -EditBox::~EditBox() -{ -} - -// +--------------------------------------------------------------------+ - -void -EditBox::DrawContent(const Rect& ctrl_rect) -{ - int h = rect.h; - - if (line_height < 1) - line_height = GetFont()->Height(); - page_size = h / (line_height + leading); -} - -// +--------------------------------------------------------------------+ - -void -EditBox::DrawTabbedText() -{ - if (font && text.length()) { - int border_size = 4; - - if (style & WIN_RAISED_FRAME && style & WIN_SUNK_FRAME) - border_size = 8; - - Rect label_rect = rect; - - label_rect.x = border_size; - label_rect.y = border_size; - label_rect.w -= border_size * 2; - label_rect.h -= border_size * 2; - - if (focus) - font->SetCaretIndex(sel_start); - - // if displaying in password mode, create a display string - // containing the proper number of password chars: - Text s = text; - if (pass_char) - s = Text(pass_char, text.length()); - - // no tabs set: - if (tab[0] == 0) { - DWORD text_flags = DT_WORDBREAK | text_align; - - if (single_line) - text_flags = text_flags | DT_SINGLELINE; - - if (style & WIN_TEXT_SHADOW) { - label_rect.x++; - label_rect.y++; - - font->SetColor(back_color); - DrawText(s.data() + h_offset, 0, label_rect, text_flags); - - label_rect.x--; - label_rect.y--; - } - - font->SetColor(fore_color); - DrawText(s.data() + h_offset, 0, label_rect, text_flags); - } - - // use tabs: - else { - } - - font->SetCaretIndex(-1); - } - else { - caret_x = 2; - caret_y = 3; - } -} - -// +--------------------------------------------------------------------+ - -Color EditBox::GetSelectedColor() -{ - return selected_color; -} - -void EditBox::SetSelectedColor(Color c) -{ - if (selected_color != c) { - selected_color = c; - } -} - -Text EditBox::GetSelText() -{ - if (sel_start == 0 && sel_length == text.length()) - return text; - - Text selection; - char* buf = new char[sel_length+1]; - - if (buf) { - for (int i = 0; i < sel_length; i++) - buf[i] = text[(int) (sel_start + i)]; - - buf[sel_length] = 0; - - selection = buf; - delete [] buf; - } - - return selection; -} - -void EditBox::SetSelStart(int n) -{ - if (n >= 0 && n <= text.length()) - sel_start = n; -} - -void EditBox::SetSelLength(int n) -{ - if (n <= text.length() - sel_start) - sel_length = n; -} - -void EditBox::EnsureCaretVisible() -{ - if (!single_line) { - h_offset = 0; - return; - } - - if (sel_start < 0) { - sel_start = 0; - h_offset = 0; - } - - else if (sel_start > h_offset) { - int x_caret; - bool moved; - - do { - x_caret = 0; - moved = false; - - if (pass_char) { - Text pass = Text(pass_char, sel_start-h_offset); - x_caret += font->StringWidth(pass.data(), pass.length()); - } - else { - Text sub = text.substring(h_offset, sel_start-h_offset); - x_caret += font->StringWidth(sub.data(), sub.length()); - } - - if (x_caret >= Width()-4) { - if (h_offset < text.length()) { - h_offset++; - moved = true; - } - } - } - while (moved); - } - - else { - h_offset = sel_start; - } -} - -bool EditBox::CanScroll(int dir, int nlines) -{ - return false; -} - -void EditBox::Scroll(int direction, int nlines) -{ - scrolling = SCROLL_NONE; -} - -void EditBox::ScrollTo(int index) -{ -} - -int EditBox::GetPageCount() -{ - return 1; -} - -int EditBox::GetPageSize() -{ - return page_size; -} - -// +--------------------------------------------------------------------+ - -void EditBox::SetFocus() -{ - ActiveWindow::SetFocus(); - - sel_start = text.length(); - sel_length = 0; -} - -void EditBox::KillFocus() -{ - ActiveWindow::KillFocus(); -} - -// +--------------------------------------------------------------------+ - -int EditBox::CaretFromPoint(int x, int y) const -{ - return 0; -} - -// +--------------------------------------------------------------------+ - -int EditBox::OnMouseMove(int x, int y) -{ - return ActiveWindow::OnMouseMove(x,y); -} - -// +--------------------------------------------------------------------+ - -int EditBox::OnLButtonDown(int x, int y) -{ - return ActiveWindow::OnLButtonDown(x,y); -} - -// +--------------------------------------------------------------------+ - -int EditBox::OnLButtonUp(int x, int y) -{ - return ActiveWindow::OnLButtonUp(x,y); -} - -// +--------------------------------------------------------------------+ - -int EditBox::OnClick() -{ - int fire_click = !scrolling; - - if (scrolling == SCROLL_THUMB) - scrolling = SCROLL_NONE; - - if (fire_click) - return ActiveWindow::OnClick(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -void EditBox::Insert(char c) -{ - if (single_line && c == '\n') - return; - - if (sel_start < text.length()) { - if (sel_start == 0) { - text = Text(c) + text; - sel_start = 1; - } - else { - Text t1 = text.substring(0, sel_start); - Text t2 = text.substring(sel_start, text.length()-sel_start); - text = t1 + Text(c) + t2; - sel_start++; - } - } - else { - text += c; - sel_start = text.length(); - } - - EnsureCaretVisible(); -} - -void EditBox::Insert(const char* s) -{ -} - -void EditBox::Delete() -{ - if (sel_start < text.length()) { - if (sel_start == 0) { - text = text.substring(1, text.length()-1); - } - else { - Text t1 = text.substring(0, sel_start); - Text t2 = text.substring(sel_start+1, text.length()-sel_start-1); - text = t1 + t2; - } - } - - EnsureCaretVisible(); -} - -void EditBox::Backspace() -{ - if (sel_start > 0) { - if (sel_start == text.length()) { - text = text.substring(0, sel_start-1); - } - else { - Text t1 = text.substring(0, sel_start-1); - Text t2 = text.substring(sel_start, text.length()-sel_start); - text = t1 + t2; - } - - sel_start--; - EnsureCaretVisible(); - } -} - -int EditBox::OnKeyDown(int vk, int flags) -{ - if (vk >= 'A' && vk <= 'Z') { - if (flags & 1) - Insert((char) vk); - else - Insert((char) tolower(vk)); - } - else { - switch (vk) { - case VK_LEFT: - if (sel_start > 0) sel_start--; - EnsureCaretVisible(); - break; - - case VK_RIGHT: - if (sel_start < text.length()) sel_start++; - EnsureCaretVisible(); - break; - - case VK_HOME: - sel_start = 0; - EnsureCaretVisible(); - break; - - case VK_END: - sel_start = text.length(); - EnsureCaretVisible(); - break; - - case VK_DELETE: Delete(); break; - case VK_BACK: Backspace(); break; - - case VK_SPACE: Insert(' '); break; - case VK_RETURN: Insert('\n'); break; - - case VK_NUMPAD0: Insert('0'); break; - case VK_NUMPAD1: Insert('1'); break; - case VK_NUMPAD2: Insert('2'); break; - case VK_NUMPAD3: Insert('3'); break; - case VK_NUMPAD4: Insert('4'); break; - case VK_NUMPAD5: Insert('5'); break; - case VK_NUMPAD6: Insert('6'); break; - case VK_NUMPAD7: Insert('7'); break; - case VK_NUMPAD8: Insert('8'); break; - case VK_NUMPAD9: Insert('9'); break; - case VK_DECIMAL: Insert('.'); break; - case VK_ADD: Insert('+'); break; - case VK_SUBTRACT: Insert('-'); break; - case VK_MULTIPLY: Insert('*'); break; - case VK_DIVIDE: Insert('/'); break; - - case '0': if (flags & 1) Insert(')'); else Insert('0'); break; - case '1': if (flags & 1) Insert('!'); else Insert('1'); break; - case '2': if (flags & 1) Insert('@'); else Insert('2'); break; - case '3': if (flags & 1) Insert('#'); else Insert('3'); break; - case '4': if (flags & 1) Insert('$'); else Insert('4'); break; - case '5': if (flags & 1) Insert('%'); else Insert('5'); break; - case '6': if (flags & 1) Insert('^'); else Insert('6'); break; - case '7': if (flags & 1) Insert('&'); else Insert('7'); break; - case '8': if (flags & 1) Insert('*'); else Insert('8'); break; - case '9': if (flags & 1) Insert('('); else Insert('9'); break; - case 186: if (flags & 1) Insert(':'); else Insert(';'); break; - case 187: if (flags & 1) Insert('+'); else Insert('='); break; - case 188: if (flags & 1) Insert('<'); else Insert(','); break; - case 189: if (flags & 1) Insert('_'); else Insert('-'); break; - case 190: if (flags & 1) Insert('>'); else Insert('.'); break; - case 191: if (flags & 1) Insert('?'); else Insert('/'); break; - case 192: if (flags & 1) Insert('~'); else Insert('`'); break; - case 219: if (flags & 1) Insert('{'); else Insert('['); break; - case 221: if (flags & 1) Insert('}'); else Insert(']'); break; - case 220: if (flags & 1) Insert('|'); else Insert('\\'); break; - case 222: if (flags & 1) Insert('"'); else Insert('\''); break; - } - } - - return ActiveWindow::OnKeyDown(vk, flags); -} diff --git a/Stars45/EditBox.h b/Stars45/EditBox.h deleted file mode 100644 index c0ffa37..0000000 --- a/Stars45/EditBox.h +++ /dev/null @@ -1,91 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - EditBox ActiveWindow class -*/ - -#ifndef EditBox_h -#define EditBox_h - -#include "Types.h" -#include "ScrollWindow.h" - -// +--------------------------------------------------------------------+ - -class EditBox : public ScrollWindow -{ -public: - static const char* TYPENAME() { return "EditBox"; } - - enum ALIGN { EDIT_ALIGN_LEFT = DT_LEFT, - EDIT_ALIGN_CENTER = DT_CENTER, - EDIT_ALIGN_RIGHT = DT_RIGHT - }; - - EditBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid); - EditBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid); - virtual ~EditBox(); - - // Operations: - virtual void DrawContent(const Rect& ctrl_rect); - virtual void DrawTabbedText(); - - // Event Target Interface: - virtual void SetFocus(); - virtual void KillFocus(); - - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnClick(); - - virtual int OnKeyDown(int vk, int flags); - - // ScrollWindow Interface: - virtual bool CanScroll(int direction, int nlines=1); - virtual void Scroll(int direction, int nlines=1); - virtual void ScrollTo(int index); - virtual int GetPageCount(); - virtual int GetPageSize(); - - Color GetSelectedColor(); - void SetSelectedColor(Color c); - - int GetSelStart() { return sel_start; } - int GetSelLength() { return sel_length; } - Text GetSelText(); - - void SetSelStart(int n); - void SetSelLength(int n); - - char GetPasswordChar() { return pass_char; } - void SetPasswordChar(char c) { pass_char = c; } - -protected: - void Insert(char c); - void Insert(const char* s); - void Delete(); - void Backspace(); - int CaretFromPoint(int x, int y) const; - void EnsureCaretVisible(); - - int sel_start; - int sel_length; - int h_offset; - int caret_x; - int caret_y; - - char pass_char; - - Color selected_color; -}; - -#endif // EditBox_h - diff --git a/Stars45/Element.cpp b/Stars45/Element.cpp deleted file mode 100644 index 9223cbf..0000000 --- a/Stars45/Element.cpp +++ /dev/null @@ -1,665 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Package Element (e.g. Flight) class implementation -*/ - -#include "Element.h" -#include "Instruction.h" -#include "RadioMessage.h" -#include "RadioHandler.h" -#include "Sim.h" -#include "Ship.h" -#include "NetUtil.h" - -#include "Game.h" - -// +----------------------------------------------------------------------+ - -static int id_key = 1000; - -Element::Element(const char* call_sign, int a_iff, int a_type) - : id(id_key++), name(call_sign), type(a_type), iff(a_iff), - player(0), command_ai(1), commander(0), assignment(0), carrier(0), - combat_group(0), combat_unit(0), launch_time(0), hold_time(0), - zone_lock(0), respawns(0), count(0), rogue(false), playable(true), intel(0) -{ - if (!call_sign) { - char buf[32]; - sprintf_s(buf, "Pkg %d", id); - name = buf; - } - - SetLoadout(0); -} - -Element::~Element() -{ - flight_plan.destroy(); - objectives.destroy(); - instructions.destroy(); - - for (int i = 0; i < ships.size(); i++) - ships[i]->SetElement(0); - - respawns = 0; -} - -// +----------------------------------------------------------------------+ - -int -Element::AddShip(Ship* ship, int index) -{ - if (ship && !ships.contains(ship)) { - Observe(ship); - - if (index < 0) { - ships.append(ship); - index = ships.size(); - } - else { - ships.insert(ship, index-1); - } - - ship->SetElement(this); - - if (respawns < ship->RespawnCount()) - respawns = ship->RespawnCount(); - } - - return index; -} - -void -Element::DelShip(Ship* ship) -{ - if (ship && ships.contains(ship)) { - ships.remove(ship); - ship->SetElement(0); - - if (ships.isEmpty()) - respawns = ship->RespawnCount(); - } -} - -Ship* -Element::GetShip(int index) -{ - if (index >= 1 && index <= ships.size()) - return ships[index-1]; - - return 0; -} - -int -Element::GetShipClass() -{ - if (ships.size()) - return ships[0]->Class(); - - return 0; -} - -int -Element::FindIndex(const Ship* s) -{ - return ships.index(s) + 1; -} - -bool -Element::Contains(const Ship* s) -{ - return ships.contains(s); -} - -bool -Element::IsActive() const -{ - bool active = false; - - for (int i = 0; i < ships.size() && !active; i++) { - Ship* s = ships[i]; - if (s->Life() && s->MissionClock()) - active = true; - } - - return active; -} - -bool -Element::IsFinished() const -{ - bool finished = false; - - if (launch_time > 0 && respawns < 1) { - finished = true; - - if (ships.size() > 0) { - for (int i = 0; i < ships.size() && finished; i++) { - Ship* s = ships[i]; - if (s->RespawnCount() > 0 || - s->MissionClock() == 0 || - s->Life() && !s->GetInbound()) - finished = false; - } - } - } - - return finished; -} - -bool -Element::IsNetObserver() const -{ - bool observer = !IsSquadron(); - - for (int i = 0; i < ships.size() && observer; i++) { - Ship* s = ships[i]; - - if (!s->IsNetObserver()) - observer = false; - } - - return observer; -} - -bool -Element::IsSquadron() const -{ - return count > 0; -} - -bool -Element::IsStatic() const -{ - if (IsSquadron() || IsFinished()) - return false; - - const Ship* s = ships.at(0); - if (s && s->IsStatic()) - return true; - - return false; -} - -// +----------------------------------------------------------------------+ - -bool -Element::IsHostileTo(const Ship* s) const -{ - if (iff <= 0 || iff >= 100 || !s || launch_time == 0 || IsFinished()) - return false; - - if (IsSquadron()) - return false; - - if (s->IsRogue()) - return true; - - int s_iff = s->GetIFF(); - - if (s_iff <= 0 || s_iff >= 100 || s_iff == iff) - return false; - - if (ships.size() > 0 && ships[0]->GetRegion() != s->GetRegion()) - return false; - - return true; -} - -bool -Element::IsHostileTo(int iff_code) const -{ - if (iff <= 0 || iff >= 100 || launch_time == 0 || IsFinished()) - return false; - - if (IsSquadron()) - return false; - - if (iff_code <= 0 || iff_code >= 100 || iff_code == iff) - return false; - - return true; -} - -bool -Element::IsObjectiveTargetOf(const Ship* s) const -{ - if (!s || launch_time == 0 || IsFinished()) - return false; - - const char* e_name = Name().data(); - int e_len = Name().length(); - - Instruction* orders = s->GetRadioOrders(); - if (orders && orders->Action() > Instruction::SWEEP) { - const char* o_name = orders->TargetName(); - int o_len = 0; - - if (o_name && *o_name) - o_len = strlen(o_name); - - if (e_len < o_len) - o_len = e_len; - - if (!strncmp(e_name, o_name, o_len)) - return true; - } - - Element* elem = s->GetElement(); - if (elem) { - for (int i = 0; i < elem->NumObjectives(); i++) { - Instruction* obj = elem->GetObjective(i); - - if (obj) { - const char* o_name = obj->TargetName(); - int o_len = 0; - - if (o_name && *o_name) - o_len = strlen(o_name); - - if (e_len < o_len) - o_len = e_len; - - if (!strncmp(e_name, o_name, o_len)) - return true; - } - } - } - - return false; -} - -// +----------------------------------------------------------------------+ - -void -Element::SetLaunchTime(DWORD t) -{ - if (launch_time == 0 || t == 0) - launch_time = t; -} - -double -Element::GetHoldTime() -{ - return hold_time; -} - -void -Element::SetHoldTime(double t) -{ - if (t >= 0) - hold_time = t; -} - -bool -Element::GetZoneLock() -{ - return zone_lock; -} - -void -Element::SetZoneLock(bool z) -{ - zone_lock = z; -} - -void -Element::SetLoadout(int* l) -{ - if (l) { - CopyMemory(load, l, sizeof(load)); - } - else { - for (int i = 0; i < 16; i++) - load[i] = -1; - } -} - -// +----------------------------------------------------------------------+ - -bool -Element::Update(SimObject* obj) -{ - // false alarm, keep watching: - if (obj->Life() != 0) { - ::Print("Element (%s) false update on (%s) life = %f\n", Name().data(), obj->Name(), obj->Life()); - return false; - } - - Ship* s = (Ship*) obj; - ships.remove(s); - - if (ships.isEmpty()) - respawns = s->RespawnCount(); - - return SimObserver::Update(obj); -} - -const char* -Element::GetObserverName() const -{ - return (const char*) (Text("Element ") + Name()); -} - -// +----------------------------------------------------------------------+ - -void -Element::AddNavPoint(Instruction* pt, Instruction* afterPoint, bool send) -{ - if (pt && !flight_plan.contains(pt)) { - int index = -1; - - if (afterPoint) { - index = flight_plan.index(afterPoint); - - if (index > -1) - flight_plan.insert(pt, index+1); - else - flight_plan.append(pt); - } - - else { - flight_plan.append(pt); - } - - if (send) { - NetUtil::SendNavData(true, this, index, pt); - } - } -} - -void -Element::DelNavPoint(Instruction* pt, bool send) -{ - // XXX MEMORY LEAK - // This is a small memory leak, but I'm not sure if it is - // safe to delete the navpoint when removing it from the - // flight plan. Other ships in the element might have - // pointers to the object...? - - if (pt) { - int index = flight_plan.index(pt); - flight_plan.remove(pt); - - if (send) { - NetUtil::SendNavDelete(this, index); - } - } -} - -// +----------------------------------------------------------------------+ - -void -Element::ClearFlightPlan(bool send) -{ - hold_time = 0; - flight_plan.destroy(); - objectives.destroy(); - instructions.destroy(); - - if (send) { - NetUtil::SendNavDelete(this, -1); - } -} - -// +----------------------------------------------------------------------+ - -Instruction* -Element::GetNextNavPoint() -{ - if (hold_time <= 0 && flight_plan.size() > 0) { - ListIter iter = flight_plan; - while (++iter) { - Instruction* navpt = iter.value(); - - if (navpt->Status() == Instruction::COMPLETE && navpt->HoldTime() > 0) - return navpt; - - if (navpt->Status() <= Instruction::ACTIVE) - return navpt; - } - } - - return 0; -} - -// +----------------------------------------------------------------------+ - -int -Element::GetNavIndex(const Instruction* n) -{ - int index = 0; - - if (flight_plan.size() > 0) { - ListIter navpt = flight_plan; - while (++navpt) { - index++; - if (navpt.value() == n) - return index; - } - } - - return 0; -} - -// +----------------------------------------------------------------------+ - -List& -Element::GetFlightPlan() -{ - return flight_plan; -} - -int -Element::FlightPlanLength() -{ - return flight_plan.size(); -} - -// +----------------------------------------------------------------------+ - -void -Element::ClearObjectives() -{ - objectives.destroy(); -} - -void -Element::AddObjective(Instruction* obj) -{ - objectives.append(obj); -} - -Instruction* -Element::GetObjective(int index) -{ - if (objectives.isEmpty()) - return 0; - - if (index < 0) - index = 0; - - else if (index >= objectives.size()) - index = index % objectives.size(); - - return objectives.at(index); -} - -Instruction* -Element::GetTargetObjective() -{ - for (int i = 0; i < objectives.size(); i++) { - Instruction* obj = objectives[i]; - - if (obj->Status() <= Instruction::ACTIVE) { - switch (obj->Action()) { - case Instruction::INTERCEPT: - case Instruction::STRIKE: - case Instruction::ASSAULT: - case Instruction::SWEEP: - case Instruction::PATROL: - case Instruction::RECON: - case Instruction::ESCORT: - case Instruction::DEFEND: - return obj; - - default: - break; - } - } - } - - return 0; -} - -// +----------------------------------------------------------------------+ - -void -Element::ClearInstructions() -{ - instructions.clear(); -} - -void -Element::AddInstruction(const char* instr) -{ - instructions.append(new Text(instr)); -} - -Text -Element::GetInstruction(int index) -{ - if (instructions.isEmpty()) - return Text(); - - if (index < 0) - index = 0; - - if (index >= instructions.size()) - index = index % instructions.size(); - - return *instructions.at(index); -} - -// +----------------------------------------------------------------------+ - -void -Element::ResumeAssignment() -{ - SetAssignment(0); - - if (objectives.isEmpty()) - return; - - Instruction* objective = 0; - - for (int i = 0; i < objectives.size() && !objective; i++) { - Instruction* instr = objectives[i]; - - if (instr->Status() <= Instruction::ACTIVE) { - switch (instr->Action()) { - case Instruction::INTERCEPT: - case Instruction::STRIKE: - case Instruction::ASSAULT: - objective = instr; - break; - } - } - } - - if (objective) { - Sim* sim = Sim::GetSim(); - - ListIter iter = sim->GetElements(); - while (++iter) { - Element* elem = iter.value(); - SimObject* tgt = objective->GetTarget(); - - if (tgt && tgt->Type() == SimObject::SIM_SHIP && elem->Contains((const Ship*) tgt)) { - SetAssignment(elem); - return; - } - } - } -} - -// +----------------------------------------------------------------------+ - -void -Element::HandleRadioMessage(RadioMessage* msg) -{ - if (!msg) return; - - static RadioHandler rh; - - // if this is a message from within the element, - // then all ships should report in. Otherwise, - // just the leader will acknowledge the message. - int full_report = ships.contains(msg->Sender()); - int reported = false; - - ListIter s = ships; - while (++s) { - if (rh.ProcessMessage(msg, s.value())) { - if (full_report) { - if (s.value() != msg->Sender()) - rh.AcknowledgeMessage(msg, s.value()); - } - - else if (!reported) { - rh.AcknowledgeMessage(msg, s.value()); - reported = true; - } - } - } -} - -// +----------------------------------------------------------------------+ - -bool -Element::CanCommand(Element* e) -{ - while (e) { - if (e->commander == this) - return true; - e = e->commander; - } - - return false; -} - -// +----------------------------------------------------------------------+ - -void -Element::ExecFrame(double seconds) -{ - if (hold_time > 0) { - hold_time -= seconds; - return; - } - - ListIter iter = flight_plan; - while (++iter) { - Instruction* instr = iter.value(); - - if (instr->Status() == Instruction::COMPLETE && instr->HoldTime() > 0) - instr->SetHoldTime(instr->HoldTime() - seconds); - } -} - -// +----------------------------------------------------------------------+ - -void -Element::SetIFF(int iff) -{ - for (int i = 0; i < ships.size(); i++) - ships[i]->SetIFF(iff); -} diff --git a/Stars45/Element.h b/Stars45/Element.h deleted file mode 100644 index ddb2c1d..0000000 --- a/Stars45/Element.h +++ /dev/null @@ -1,171 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Package Element (e.g. Flight) class -*/ - -#ifndef Element_h -#define Element_h - -#include "Types.h" -#include "Geometry.h" -#include "SimObject.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class Instruction; -class RadioMessage; - -class CombatGroup; -class CombatUnit; - -// +--------------------------------------------------------------------+ - -class Element : public SimObserver -{ -public: - // CONSTRUCTORS: - Element(const char* call_sign, int iff, int type=0 /*PATROL*/); - virtual ~Element(); - - int operator == (const Element& e) const { return id == e.id; } - - // GENERAL ACCESSORS: - int Identity() const { return id; } - int Type() const { return type; } - const Text& Name() const { return name; } - void SetName(const char* s) { name = s; } - virtual int GetIFF() const { return iff; } - int Player() const { return player; } - void SetPlayer(int p) { player = p; } - DWORD GetLaunchTime() const { return launch_time; } - void SetLaunchTime(DWORD t); - int IntelLevel() const { return intel; } - void SetIntelLevel(int i) { intel = i; } - - // ELEMENT COMPONENTS: - int NumShips() const { return ships.size(); } - int AddShip(Ship*, int index=-1); - void DelShip(Ship*); - Ship* GetShip(int index); - int GetShipClass(); - int FindIndex(const Ship* s); - bool Contains(const Ship* s); - bool IsActive() const; - bool IsFinished() const; - bool IsNetObserver() const; - bool IsSquadron() const; - bool IsStatic() const; - bool IsHostileTo(const Ship* s) const; - bool IsHostileTo(int iff_code) const; - bool IsObjectiveTargetOf(const Ship* s) const; - bool IsRogue() const { return rogue; } - bool IsPlayable() const { return playable; } - int* Loadout() { return load; } - - void SetRogue(bool r) { rogue = r; } - void SetPlayable(bool p) { playable = p; } - void SetLoadout(int* l); - virtual void SetIFF(int iff); - - virtual void ExecFrame(double seconds); - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - // OBJECTIVES: - void ClearObjectives(); - void AddObjective(Instruction* obj); - Instruction* GetObjective(int index); - Instruction* GetTargetObjective(); - int NumObjectives() const { return objectives.size(); } - - void ClearInstructions(); - void AddInstruction(const char* instr); - Text GetInstruction(int index); - int NumInstructions() const { return instructions.size(); } - - // ORDERS AND NAVIGATION: - double GetHoldTime(); - void SetHoldTime(double t); - bool GetZoneLock(); - void SetZoneLock(bool z); - void AddNavPoint(Instruction* pt, Instruction* afterPoint=0, bool send=true); - void DelNavPoint(Instruction* pt, bool send=true); - void ClearFlightPlan(bool send=true); - Instruction* GetNextNavPoint(); - int GetNavIndex(const Instruction* n); - List& GetFlightPlan(); - int FlightPlanLength(); - virtual void HandleRadioMessage(RadioMessage* msg); - - // CHAIN OF COMMAND: - Element* GetCommander() const { return commander; } - void SetCommander(Element* e) { commander = e; } - Element* GetAssignment() const { return assignment; } - void SetAssignment(Element* e) { assignment = e; } - void ResumeAssignment(); - bool CanCommand(Element* e); - Ship* GetCarrier() const { return carrier; } - void SetCarrier(Ship* c) { carrier = c; } - int GetCommandAILevel() const { return command_ai; } - void SetCommandAILevel(int n) { command_ai = n; } - const Text& GetSquadron() const { return squadron; } - void SetSquadron(const char* s) { squadron = s; } - - // DYNAMIC CAMPAIGN: - CombatGroup* GetCombatGroup() { return combat_group; } - void SetCombatGroup(CombatGroup* g) { combat_group = g; } - CombatUnit* GetCombatUnit() { return combat_unit; } - void SetCombatUnit(CombatUnit* u) { combat_unit = u; } - - // SQUADRON STUFF: - int GetCount() const { return count; } - void SetCount(int n) { count = n; } - -protected: - int id; - int iff; - int type; - int player; - int command_ai; - int respawns; - int intel; - Text name; - - // squadron elements only: - int count; - - List ships; - List ship_names; - List instructions; - List objectives; - List flight_plan; - - Element* commander; - Element* assignment; - Ship* carrier; - Text squadron; - - CombatGroup* combat_group; - CombatUnit* combat_unit; - DWORD launch_time; - double hold_time; - - bool rogue; - bool playable; - bool zone_lock; - int load[16]; -}; - -#endif // Element_h - diff --git a/Stars45/Encrypt.cpp b/Stars45/Encrypt.cpp deleted file mode 100644 index 44d07ca..0000000 --- a/Stars45/Encrypt.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simple Encryption / Decryption class -*/ - - -#include "Encrypt.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -static long k[4] = { - 0x3B398E26, - 0x40C29501, - 0x614D7630, - 0x7F59409A -}; - -static void encypher(long* v) -{ - DWORD y=v[0]; - DWORD z=v[1]; - DWORD sum=0; - DWORD delta=0x9e3779b9; // a key schedule constant - DWORD n=32; // num iterations - - while (n-->0) { // basic cycle start - sum += delta; - y += (z<<4)+k[0] ^ z+sum ^ (z>>5)+k[1]; - z += (y<<4)+k[2] ^ y+sum ^ (y>>5)+k[3]; - } - - v[0]=y; - v[1]=z; -} - -static void decypher(long* v) -{ - DWORD y=v[0]; - DWORD z=v[1]; - DWORD sum=0; - DWORD delta=0x9e3779b9; // a key schedule constant - DWORD n=32; // num iterations - - sum=delta<<5; - - while (n-->0) { - z-= (y<<4)+k[2] ^ y+sum ^ (y>>5)+k[3]; - y-= (z<<4)+k[0] ^ z+sum ^ (z>>5)+k[1]; - sum-=delta; - } - - v[0]=y; - v[1]=z; -} - -// +-------------------------------------------------------------------+ - -Text -Encryption::Encrypt(Text block) -{ - int len = block.length(); - - if (len < 1) - return Text(); - - // pad to eight byte chunks - if (len & 0x7) { - len /= 8; - len *= 8; - len += 8; - } - - BYTE* work = new BYTE[len]; - ZeroMemory(work, len); - CopyMemory(work, block.data(), block.length()); - - long* v = (long*) work; - for (int i = 0; i < len/8; i++) { - encypher(v); - v += 2; - } - - Text cypher((const char*) work, len); - delete [] work; - return cypher; -} - -// +-------------------------------------------------------------------+ - -Text -Encryption::Decrypt(Text block) -{ - int len = block.length(); - - if (len & 0x7) { - Print("WARNING: attempt to decrypt odd length block (len=%d)\n", len); - return Text(); - } - - BYTE* work = new BYTE[len]; - CopyMemory(work, block.data(), len); - - long* v = (long*) work; - for (int i = 0; i < len/8; i++) { - decypher(v); - v += 2; - } - - Text clear((const char*) work, len); - delete [] work; - return clear; -} - -// +-------------------------------------------------------------------+ - -static const char* codes = "abcdefghijklmnop"; - -Text -Encryption::Encode(Text block) -{ - int len = block.length() * 2; - char* work = new char[len + 1]; - - for (int i = 0; i < block.length(); i++) { - BYTE b = (BYTE) (block.data()[i]); - work[2*i] = codes[b>>4 & 0xf]; - work[2*i+1] = codes[b & 0xf]; - } - - work[len] = 0; - - Text code(work, len); - delete [] work; - return code; -} - -// +-------------------------------------------------------------------+ - -Text -Encryption::Decode(Text block) -{ - int len = block.length() / 2; - char* work = new char[len + 1]; - - for (int i = 0; i < len; i++) { - char u = block[2*i]; - char l = block[2*i + 1]; - - work[i] = (u - codes[0]) << 4 | - (l - codes[0]); - } - - work[len] = 0; - - Text clear(work, len); - delete [] work; - return clear; -} - diff --git a/Stars45/Encrypt.h b/Stars45/Encrypt.h deleted file mode 100644 index be925d8..0000000 --- a/Stars45/Encrypt.h +++ /dev/null @@ -1,37 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simple Encryption / Decryption class -*/ - - -#ifndef Encrypt_h -#define Encrypt_h - -#include "Types.h" -#include "Text.h" - -// +-------------------------------------------------------------------+ - -class Encryption -{ -public: - // private key encryption / decryption of - // arbitrary blocks of data - static Text Encrypt(Text block); - static Text Decrypt(Text block); - - // encode / decode binary blocks into - // ascii strings for use in text files - static Text Encode(Text block); - static Text Decode(Text block); -}; - -#endif // Encrypt_h \ No newline at end of file diff --git a/Stars45/EngDlg.cpp b/Stars45/EngDlg.cpp deleted file mode 100644 index 7df1f9f..0000000 --- a/Stars45/EngDlg.cpp +++ /dev/null @@ -1,1042 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Engineering (Power/Maint) Dialog Active Window class -*/ - -#include "EngDlg.h" -#include "GameScreen.h" -#include "Ship.h" -#include "Power.h" -#include "Component.h" -#include "Sim.h" - -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Mouse.h" -#include "Keyboard.h" -#include "Game.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(EngDlg, OnSource); -DEF_MAP_CLIENT(EngDlg, OnClient); -DEF_MAP_CLIENT(EngDlg, OnRouteStart); -DEF_MAP_CLIENT(EngDlg, OnRouteComplete); -DEF_MAP_CLIENT(EngDlg, OnPowerOff); -DEF_MAP_CLIENT(EngDlg, OnPowerOn); -DEF_MAP_CLIENT(EngDlg, OnOverride); -DEF_MAP_CLIENT(EngDlg, OnPowerLevel); -DEF_MAP_CLIENT(EngDlg, OnComponent); -DEF_MAP_CLIENT(EngDlg, OnAutoRepair); -DEF_MAP_CLIENT(EngDlg, OnRepair); -DEF_MAP_CLIENT(EngDlg, OnReplace); -DEF_MAP_CLIENT(EngDlg, OnQueue); -DEF_MAP_CLIENT(EngDlg, OnPriorityIncrease); -DEF_MAP_CLIENT(EngDlg, OnPriorityDecrease); -DEF_MAP_CLIENT(EngDlg, OnClose); - -// +--------------------------------------------------------------------+ - -EngDlg::EngDlg(Screen* s, FormDef& def, GameScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -ship(0), route_source(0), selected_source(0), -selected_repair(0), selected_component(0) -{ - Init(def); -} - -EngDlg::~EngDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::RegisterControls() -{ - for (int i = 0; i < 4; i++) { - sources[i] = (Button*) FindControl(201 + i); - REGISTER_CLIENT(EID_CLICK, sources[i], EngDlg, OnSource); - - source_levels[i] = (Slider*) FindControl(211 + i); - - clients[i] = (ListBox*) FindControl(301 + i); - - if (clients[i]) { - clients[i]->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - clients[i]->SetSortColumn(0); - - REGISTER_CLIENT(EID_SELECT, clients[i], EngDlg, OnClient); - REGISTER_CLIENT(EID_DRAG_START, clients[i], EngDlg, OnRouteStart); - REGISTER_CLIENT(EID_DRAG_DROP, clients[i], EngDlg, OnRouteComplete); - } - } - - close_btn = (Button*) FindControl(1); - selected_name = (ActiveWindow*) FindControl(401); - power_off = (Button*) FindControl(402); - power_on = (Button*) FindControl(403); - override = (Button*) FindControl(410); - power_level = (Slider*) FindControl(404); - capacity = (Slider*) FindControl(405); - - if (close_btn) - REGISTER_CLIENT(EID_CLICK, close_btn, EngDlg, OnClose); - - if (power_off) - REGISTER_CLIENT(EID_CLICK, power_off, EngDlg, OnPowerOff); - - if (power_on) - REGISTER_CLIENT(EID_CLICK, power_on, EngDlg, OnPowerOn); - - if (override) - REGISTER_CLIENT(EID_CLICK, override, EngDlg, OnOverride); - - if (power_level) - REGISTER_CLIENT(EID_CLICK, power_level, EngDlg, OnPowerLevel); - - components = (ListBox*) FindControl(501); - - if (components) { - components->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - components->SetSortColumn(0); - REGISTER_CLIENT(EID_SELECT, components, EngDlg, OnComponent); - } - - auto_repair = (Button*) FindControl(700); - repair = (Button*) FindControl(502); - replace = (Button*) FindControl(503); - repair_time = FindControl(512); - replace_time = FindControl(513); - priority_increase = (Button*) FindControl(602); - priority_decrease = (Button*) FindControl(603); - - if (auto_repair) - REGISTER_CLIENT(EID_CLICK, auto_repair, EngDlg, OnAutoRepair); - - if (repair) - REGISTER_CLIENT(EID_CLICK, repair, EngDlg, OnRepair); - - if (replace) - REGISTER_CLIENT(EID_CLICK, replace, EngDlg, OnReplace); - - if (repair_time) - repair_time->Hide(); - - if (replace_time) - replace_time->Hide(); - - if (priority_increase) { - char up_arrow[2]; - up_arrow[0] = Font::ARROW_UP; - up_arrow[1] = 0; - priority_increase->SetText(up_arrow); - - REGISTER_CLIENT(EID_CLICK, priority_increase, EngDlg, OnPriorityIncrease); - } - - if (priority_decrease) { - char dn_arrow[2]; - dn_arrow[0] = Font::ARROW_DOWN; - dn_arrow[1] = 0; - priority_decrease->SetText(dn_arrow); - - REGISTER_CLIENT(EID_CLICK, priority_decrease, EngDlg, OnPriorityDecrease); - } - - repair_queue = (ListBox*) FindControl(601); - - if (repair_queue) { - repair_queue->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - REGISTER_CLIENT(EID_SELECT, repair_queue, EngDlg, OnQueue); - } -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::Show() -{ - FormWindow::Show(); - - if (ship) { - int nsources = ship->Reactors().size(); - - for (int i = 0; i < 4; i++) { - if (i >= nsources) { - sources[i]->Hide(); - source_levels[i]->Hide(); - clients[i]->Hide(); - } - } - } -} - -void -EngDlg::Hide() -{ - FormWindow::Hide(); -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::SetShip(Ship* s) -{ - if (IsShown() && ship != s) { - selected_source = 0; - selected_repair = 0; - selected_component = 0; - selected_clients.clear(); - - ship = s; - - UpdateRouteTables(); - ExecFrame(); - } - - // make sure we clear the ship, even if not shown: - else if (!s) { - ship = 0; - } -} - -void -EngDlg::UpdateRouteTables() -{ - for (int i = 0; i < 4; i++) - clients[i]->ClearSelection(); - - if (components) - components->ClearItems(); - - if (priority_increase) - priority_increase->SetEnabled(false); - - if (priority_decrease) - priority_decrease->SetEnabled(false); - - if (ship) { - for (int i = 0; i < 4; i++) { - if (sources[i]) - sources[i]->Hide(); - - if (source_levels[i]) - source_levels[i]->Hide(); - - if (clients[i]) { - clients[i]->ClearItems(); - clients[i]->Hide(); - } - } - - int reactor_index = 0; - ListIter reactor_iter = ship->Reactors(); - - while (++reactor_iter) { - PowerSource* reactor = reactor_iter.value(); - - if (sources[reactor_index] && clients[reactor_index]) { - sources[reactor_index]->SetText(ContentBundle::GetInstance()->GetText(reactor->Abbreviation())); - sources[reactor_index]->Show(); - - source_levels[reactor_index]->Show(); - source_levels[reactor_index]->SetValue((int) reactor->GetPowerLevel()); - - clients[reactor_index]->Show(); - - int index = 0; - ListIter client = reactor->Clients(); - while (++client) { - char abrv[64], num[20]; - FormatNumber(num, client->GetPowerLevel()); - strcpy_s(abrv, ContentBundle::GetInstance()->GetText(client->Name())); - - clients[reactor_index]->AddItemWithData(ContentBundle::GetInstance()->GetText(abrv), index); - clients[reactor_index]->SetItemText(index, 1, num); - clients[reactor_index]->SetItemData(index, 1, (DWORD) client->GetPowerLevel()); - - index++; - } - - clients[reactor_index]->SortItems(); - } - - reactor->RouteScanned(); - reactor_index++; - } - } -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::ExecFrame() -{ - if (IsShown()) - UpdateSelection(); -} - -void -EngDlg::UpdateSelection() -{ - if (!ship) return; - - char num[20]; - int nsources = ship->Reactors().size(); - - // update the route tables: - for (int source_index = 0; source_index < nsources; source_index++) { - PowerSource* reac = ship->Reactors()[source_index]; - - if (reac->RouteChanged()) - UpdateRouteTables(); - - Color c(62,106,151); - - if (reac->IsPowerOn()) { - switch (reac->Status()) { - default: - case System::NOMINAL: break; - case System::DEGRADED: c = Color::Yellow; break; - case System::CRITICAL: c = Color::BrightRed; break; - case System::DESTROYED: c = Color::DarkRed; break; - } - } - else { - c = Color::Gray; - } - - sources[source_index]->SetBackColor(c); - source_levels[source_index]->SetEnabled(reac->IsPowerOn()); - source_levels[source_index]->SetValue((int) reac->GetPowerLevel()); - - ListBox* client_list = clients[source_index]; - - for (int i = 0; i < client_list->NumItems(); i++) { - int index = client_list->GetItemData(i); - - System* client = reac->Clients()[index]; - FormatNumber(num, client->GetPowerLevel()); - client_list->SetItemText(i, 1, num); - client_list->SetItemData(i, 1, (DWORD) client->GetPowerLevel()); - - if (client->IsPowerOn()) { - Color c; - - switch (client->Status()) { - default: - case System::NOMINAL: c = Color::White; break; - case System::DEGRADED: c = Color::Yellow; break; - case System::CRITICAL: c = Color::BrightRed; break; - case System::DESTROYED: c = Color::DarkRed; break; - } - - client_list->SetItemColor(i, c); - } - else { - client_list->SetItemColor(i, Color::Gray); - } - - } - } - - // update the detail info: - if (selected_source) { - selected_name->SetText(ContentBundle::GetInstance()->GetText(selected_source->Name())); - power_off->SetEnabled(true); - power_on->SetEnabled(true); - override->SetEnabled(true); - if (override->GetButtonState() != 2) - override->SetButtonState(selected_source->GetPowerLevel() > 100 ? 1 : 0); - power_level->SetEnabled(selected_source->IsPowerOn()); - power_level->SetValue((int) selected_source->GetPowerLevel()); - - if (selected_source->Safety() < 100) { - power_level->SetMarker((int) selected_source->Safety(), 0); - power_level->SetMarker((int) selected_source->Safety(), 1); - } - else { - power_level->SetMarker(-1, 0); - power_level->SetMarker(-1, 1); - } - - capacity->SetEnabled(true); - capacity->SetValue((int) selected_source->Charge()); - - if (selected_source->IsPowerOn()) { - if (power_on->GetButtonState() != 2) - power_on->SetButtonState(1); - if (power_off->GetButtonState() != 2) - power_off->SetButtonState(0); - } - else { - if (power_on->GetButtonState() != 2) - power_on->SetButtonState(0); - if (power_off->GetButtonState() != 2) - power_off->SetButtonState(1); - } - - if (components) { - for (int i = 0; i < components->NumItems(); i++) { - int index = components->GetItemData(i); - - Component* comp = selected_source->GetComponents()[index]; - - Text stat = "OK"; - Color c; - - switch (comp->Status()) { - case Component::DESTROYED: - case Component::CRITICAL: stat = "FAIL"; c = Color::BrightRed; break; - case Component::DEGRADED: stat = "WARN"; c = Color::Yellow; break; - case Component::NOMINAL: stat = "OK"; c = Color::White; break; - case Component::REPLACE: - case Component::REPAIR: stat = "MAINT"; c = Color::Cyan; break; - } - - stat = ContentBundle::GetInstance()->GetText(Text("EngDlg.") + stat); - components->SetItemText(i, 1, stat); - components->SetItemData(i, 1, (int) comp->Status()); - - FormatNumber(num, comp->SpareCount()); - components->SetItemText(i, 2, num); - components->SetItemData(i, 2, comp->SpareCount()); - components->SetItemColor(i, c); - } - } - } - - else if (selected_clients.size() == 1) { - System* sink = selected_clients[0]; - - selected_name->SetText(ContentBundle::GetInstance()->GetText(sink->Name())); - power_off->SetEnabled(true); - power_on->SetEnabled(true); - override->SetEnabled(true); - if (override->GetButtonState() != 2) - override->SetButtonState(sink->GetPowerLevel() > 100 ? 1 : 0); - power_level->SetEnabled(sink->IsPowerOn()); - power_level->SetValue((int) sink->GetPowerLevel()); - - if (sink->Safety() < 100) { - power_level->SetMarker((int) sink->Safety(), 0); - power_level->SetMarker((int) sink->Safety(), 1); - } - else { - power_level->SetMarker(-1, 0); - power_level->SetMarker(-1, 1); - } - - capacity->SetEnabled(true); - capacity->SetValue((int) sink->Charge()); - - if (sink->IsPowerOn()) { - if (power_on->GetButtonState() != 2) - power_on->SetButtonState(1); - if (power_off->GetButtonState() != 2) - power_off->SetButtonState(0); - } - else { - if (power_on->GetButtonState() != 2) - power_on->SetButtonState(0); - if (power_off->GetButtonState() != 2) - power_off->SetButtonState(1); - } - - if (components) { - for (int i = 0; i < components->NumItems(); i++) { - int index = components->GetItemData(i); - - Component* comp = sink->GetComponents()[index]; - - Text stat = "OK"; - Color c; - - switch (comp->Status()) { - case Component::DESTROYED: - case Component::CRITICAL: stat = "FAIL"; c = Color::BrightRed; break; - case Component::DEGRADED: stat = "WARN"; c = Color::Yellow; break; - case Component::NOMINAL: stat = "OK"; c = Color::White; break; - case Component::REPLACE: - case Component::REPAIR: stat = "MAINT"; c = Color::Cyan; break; - } - - stat = ContentBundle::GetInstance()->GetText(Text("EngDlg.") + stat); - components->SetItemText(i, 1, stat); - components->SetItemData(i, 1, (int) comp->Status()); - - FormatNumber(num, comp->SpareCount()); - components->SetItemText(i, 2, num); - components->SetItemData(i, 2, comp->SpareCount()); - components->SetItemColor(i, c); - } - } - } - - else if (selected_clients.size() > 1) { - System* sink = selected_clients[0]; - - selected_name->SetText(ContentBundle::GetInstance()->GetText("[Multiple]")); - power_off->SetEnabled(true); - power_on->SetEnabled(true); - override->SetEnabled(true); - if (override->GetButtonState() != 2) - override->SetButtonState(sink->GetPowerLevel() > 100 ? 1 : 0); - power_level->SetEnabled(true); - power_level->SetValue((int) sink->GetPowerLevel()); - - if (sink->Safety() < 100) { - power_level->SetMarker((int) sink->Safety(), 0); - power_level->SetMarker((int) sink->Safety(), 1); - } - else { - power_level->SetMarker(-1, 0); - power_level->SetMarker(-1, 1); - } - - capacity->SetEnabled(true); - capacity->SetValue((int) sink->Charge()); - - if (sink->IsPowerOn()) { - if (power_on->GetButtonState() != 2) - power_on->SetButtonState(1); - if (power_off->GetButtonState() != 2) - power_off->SetButtonState(0); - } - else { - if (power_on->GetButtonState() != 2) - power_on->SetButtonState(0); - if (power_off->GetButtonState() != 2) - power_off->SetButtonState(1); - } - } - - else { - selected_name->SetText(ContentBundle::GetInstance()->GetText("No Selection")); - power_off->SetEnabled(false); - power_off->SetButtonState(0); - power_on->SetEnabled(false); - power_on->SetButtonState(0); - override->SetEnabled(false); - override->SetButtonState(0); - power_level->SetEnabled(false); - power_level->SetValue(0); - power_level->SetMarker(-1, 0); - power_level->SetMarker(-1, 1); - capacity->SetEnabled(false); - capacity->SetValue(0); - } - - // display the repair queue: - if (repair_queue) { - // if adding to the queue, dump and reload: - if (repair_queue->NumItems() < ship->RepairQueue().size()) { - repair_queue->ClearItems(); - - int i = 0; - ListIter iter = ship->RepairQueue(); - while (++iter) { - double time_remaining = 0; - char etr[20]; - - System* sys = iter.value(); - - ListIter comp = sys->GetComponents(); - while (++comp) { - Component* c = comp.value(); - if (c->TimeRemaining() > time_remaining) - time_remaining = c->TimeRemaining(); - } - - FormatTime(etr, (int) (time_remaining / ship->RepairSpeed())); - repair_queue->AddItem(ContentBundle::GetInstance()->GetText(sys->Name())); - repair_queue->SetItemText(i, 1, etr); - i++; - } - } - - // otherwise, update in place: - else { - while (repair_queue->NumItems() > ship->RepairQueue().size()) - repair_queue->RemoveItem(0); - - bool found = false; - - for (int i = 0; i < repair_queue->NumItems(); i++) { - double time_remaining = 0; - char etr[20]; - - System* sys = ship->RepairQueue().at(i); - - ListIter comp = sys->GetComponents(); - while (++comp) { - Component* c = comp.value(); - if (c->TimeRemaining() > time_remaining) - time_remaining = c->TimeRemaining(); - } - - FormatTime(etr, (int) time_remaining); - repair_queue->SetItemText(i, sys->Name()); - repair_queue->SetItemText(i, 1, etr); - - if (sys == selected_repair) { - found = true; - - if (!Mouse::LButton()) - repair_queue->SetSelected(i); - } - } - - if (!found) - selected_repair = 0; - } - } - - if (auto_repair && auto_repair->GetButtonState() != 2) - auto_repair->SetButtonState(ship->AutoRepair() ? 1 : 0); -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::OnSource(AWEvent* event) -{ - selected_source = 0; - selected_clients.clear(); - selected_component = 0; - - if (!ship) return; - - int source_index = -1; - - for (int i = 0; i < 4; i++) - if (event->window == sources[i]) - source_index = i; - - // found the source list: - if (source_index >= 0) { - selected_source = ship->Reactors()[source_index]; - } - - for (int i = 0; i < 4; i++) { - clients[i]->ClearSelection(); - } - - if (components) { - components->ClearItems(); - - if (repair) repair->SetEnabled(false); - if (replace) replace->SetEnabled(false); - if (repair_time) repair_time->Hide(); - if (replace_time) replace_time->Hide(); - - if (selected_source && selected_source->GetComponents().size()) { - int index = 0; - ListIter comp = selected_source->GetComponents(); - while (++comp) - components->AddItemWithData(ContentBundle::GetInstance()->GetText(comp->Abbreviation()), index++); - } - } -} - -void -EngDlg::OnClient(AWEvent* event) -{ - selected_source = 0; - selected_clients.clear(); - selected_component = 0; - - if (!ship) return; - - int source_index = -1; - - for (int i = 0; i < 4; i++) { - if (event->window == clients[i]) - source_index = i; - else - clients[i]->ClearSelection(); - } - - // found the source list: - if (source_index >= 0) { - // find the power source: - PowerSource* src = ship->Reactors()[source_index]; - - // build a list of the clients to be manipulated: - List& client_list = src->Clients(); - for (int i = 0; i < clients[source_index]->NumItems(); i++) { - if (clients[source_index]->IsSelected(i)) { - int index = clients[source_index]->GetItemData(i); - selected_clients.append(client_list[index]); - } - } - } - - if (components) { - components->ClearItems(); - - if (repair) repair->SetEnabled(false); - if (replace) replace->SetEnabled(false); - if (repair_time) repair_time->Hide(); - if (replace_time) replace_time->Hide(); - - if (selected_clients.size() == 1) { - System* sink = selected_clients[0]; - - if (sink->GetComponents().size()) { - int index = 0; - ListIter comp = sink->GetComponents(); - while (++comp) - components->AddItemWithData(ContentBundle::GetInstance()->GetText(comp->Abbreviation()), index++); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::OnRouteStart(AWEvent* event) -{ - if (!ship) return; - - int source_index = -1; - - for (int i = 0; i < 4; i++) - if (event->window == clients[i]) - source_index = i; - - // found the source list: - if (source_index >= 0) { - // remember the power source: - route_source = ship->Reactors()[source_index]; - route_list.clear(); - - // build a list of the clients to be moved: - List& rsc = route_source->Clients(); - for (int i = 0; i < clients[source_index]->NumItems(); i++) { - if (clients[source_index]->IsSelected(i)) { - int index = clients[source_index]->GetItemData(i); - route_list.append(rsc[index]); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::OnRouteComplete(AWEvent* event) -{ - if (!ship || !route_source) return; - - int dest_index = -1; - - for (int i = 0; i < 4; i++) - if (event->window == clients[i]) - dest_index = i; - - // found the destination list, copy the clients over: - if (dest_index >= 0) { - PowerSource* route_dest = ship->Reactors()[dest_index]; - - if (!route_dest) - return; - - ListIter iter = route_list; - while (++iter) { - System* client = iter.value(); - - route_source->RemoveClient(client); - route_dest->AddClient(client); - } - } -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::OnPowerOff(AWEvent* event) -{ - if (selected_source) { - selected_source->PowerOff(); - - power_off->SetButtonState(1); - power_on->SetButtonState(0); - override->SetButtonState(0); - } - - else if (selected_clients.size() > 0) { - ListIter iter = selected_clients; - while (++iter) - iter->PowerOff(); - - power_off->SetButtonState(1); - power_on->SetButtonState(0); - override->SetButtonState(0); - } -} - -void -EngDlg::OnPowerOn(AWEvent* event) -{ - if (selected_source) { - selected_source->PowerOn(); - - power_off->SetButtonState(0); - power_on->SetButtonState(1); - override->SetButtonState(0); - } - - else if (selected_clients.size() > 0) { - ListIter iter = selected_clients; - while (++iter) - iter->PowerOn(); - - power_off->SetButtonState(0); - power_on->SetButtonState(1); - override->SetButtonState(0); - } -} - -void -EngDlg::OnOverride(AWEvent* event) -{ - bool over = false; - - if (override->GetButtonState() > 0) - over = true; - - if (selected_source) { - selected_source->SetOverride(over); - } - - else if (selected_clients.size() > 0) { - ListIter iter = selected_clients; - while (++iter) - iter->SetOverride(over); - } - - if (over) { - power_off->SetButtonState(0); - power_on->SetButtonState(1); - } -} - -void -EngDlg::OnPowerLevel(AWEvent* event) -{ - int level = power_level->GetValue(); - - if (level < 0) - level = 0; - else if (level > 100) - level = 100; - - if (selected_source) - selected_source->SetPowerLevel(level); - - else if (selected_clients.size() > 0) { - ListIter iter = selected_clients; - while (++iter) - iter->SetPowerLevel(level); - } - - if (override) - override->SetButtonState(0); -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::OnComponent(AWEvent* event) -{ - selected_component = 0; - - if (repair) repair->SetEnabled(false); - if (replace) replace->SetEnabled(false); - if (repair_time) repair_time->Hide(); - if (replace_time) replace_time->Hide(); - - // find index of selected component: - int component_index = -1; - - if (components) { - int n = components->GetSelection(); - if (n >= 0) - component_index = components->GetItemData(n); - } - - // now examine the component info: - if (component_index >= 0) { - repair->SetEnabled(true); - - if (selected_source) { - List& comps = selected_source->GetComponents(); - selected_component = comps[component_index]; - - if (repair_time) { - char t[32]; - int s = (int) (selected_component->RepairTime() / - ship->RepairSpeed()); - FormatTime(t, s); - repair_time->SetText(t); - repair_time->Show(); - } - - if (selected_component->SpareCount() > 0) { - if (replace) replace->SetEnabled(true); - - if (replace_time) { - char t[32]; - int s = (int) (selected_component->ReplaceTime() / - ship->RepairSpeed()); - FormatTime(t, s); - replace_time->SetText(t); - replace_time->Show(); - } - } - } - else if (selected_clients.size() > 0) { - List& comps = selected_clients[0]->GetComponents(); - selected_component = comps[component_index]; - - if (repair_time) { - char t[32]; - int s = (int) (selected_component->RepairTime() / - ship->RepairSpeed()); - FormatTime(t, s); - repair_time->SetText(t); - repair_time->Show(); - } - - if (selected_component->SpareCount() > 0) { - if (replace) replace->SetEnabled(true); - - if (replace_time) { - char t[32]; - int s = (int) (selected_component->ReplaceTime() / - ship->RepairSpeed()); - FormatTime(t, s); - replace_time->SetText(t); - replace_time->Show(); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::OnAutoRepair(AWEvent* event) -{ - if (ship) - ship->EnableRepair(auto_repair->GetButtonState() > 0); -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::OnRepair(AWEvent* event) -{ - if (selected_component) { - selected_component->Repair(); - - if (ship) - ship->RepairSystem(selected_component->GetSystem()); - } -} - -void -EngDlg::OnReplace(AWEvent* event) -{ - if (selected_component) { - selected_component->Replace(); - - if (ship) - ship->RepairSystem(selected_component->GetSystem()); - } -} - -void -EngDlg::OnQueue(AWEvent* event) -{ - selected_repair = 0; - - if (priority_increase) priority_increase->SetEnabled(false); - if (priority_decrease) priority_decrease->SetEnabled(false); - - if (repair_queue) { - int n = repair_queue->GetSelection(); - - if (n >= 0) - selected_repair = ship->RepairQueue().at(n); - } - - if (!selected_repair) - return; - - selected_clients.clear(); - selected_clients.append(selected_repair); - - if (components) { - components->ClearItems(); - - if (repair) repair->SetEnabled(false); - if (replace) replace->SetEnabled(false); - if (repair_time) repair_time->Hide(); - if (replace_time) replace_time->Hide(); - - if (selected_repair->GetComponents().size()) { - int index = 0; - ListIter comp = selected_repair->GetComponents(); - while (++comp) - components->AddItemWithData(ContentBundle::GetInstance()->GetText(comp->Abbreviation()), index++); - } - } - - if (priority_increase) priority_increase->SetEnabled(true); - if (priority_decrease) priority_decrease->SetEnabled(true); -} - -void -EngDlg::OnPriorityIncrease(AWEvent* event) -{ - if (ship && repair_queue) - ship->IncreaseRepairPriority(repair_queue->GetSelection()); -} - -void -EngDlg::OnPriorityDecrease(AWEvent* event) -{ - if (ship && repair_queue) - ship->DecreaseRepairPriority(repair_queue->GetSelection()); -} - -// +--------------------------------------------------------------------+ - -void -EngDlg::OnClose(AWEvent* event) -{ - if (manager) - manager->CloseTopmost(); -} - - - diff --git a/Stars45/EngDlg.h b/Stars45/EngDlg.h deleted file mode 100644 index ae2eedf..0000000 --- a/Stars45/EngDlg.h +++ /dev/null @@ -1,105 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Engineering (Power/Maint) Dialog Active Window class -*/ - -#ifndef EngDlg_h -#define EngDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class GameScreen; -class Ship; -class PowerSource; -class System; -class Component; - -class PowerClient; - -// +--------------------------------------------------------------------+ - -class EngDlg : public FormWindow -{ -public: - EngDlg(Screen* s, FormDef& def, GameScreen* mgr); - virtual ~EngDlg(); - - virtual void Show(); - virtual void Hide(); - virtual void RegisterControls(); - - // Operations: - virtual void OnSource(AWEvent* event); - virtual void OnClient(AWEvent* event); - virtual void OnRouteStart(AWEvent* event); - virtual void OnRouteComplete(AWEvent* event); - virtual void OnPowerOff(AWEvent* event); - virtual void OnPowerOn(AWEvent* event); - virtual void OnOverride(AWEvent* event); - virtual void OnPowerLevel(AWEvent* event); - virtual void OnComponent(AWEvent* event); - virtual void OnAutoRepair(AWEvent* event); - virtual void OnRepair(AWEvent* event); - virtual void OnReplace(AWEvent* event); - virtual void OnQueue(AWEvent* event); - virtual void OnPriorityIncrease(AWEvent* event); - virtual void OnPriorityDecrease(AWEvent* event); - virtual void OnClose(AWEvent* event); - - virtual void ExecFrame(); - void UpdateRouteTables(); - void UpdateSelection(); - void SetShip(Ship* s); - -protected: - Ship* ship; - GameScreen* manager; - - Button* close_btn; - Button* sources[4]; - Slider* source_levels[4]; - ListBox* clients[4]; - ListBox* components; - ListBox* repair_queue; - ActiveWindow* selected_name; - Button* power_off; - Button* power_on; - Button* override; - Slider* power_level; - Slider* capacity; - Button* auto_repair; - Button* repair; - Button* replace; - ActiveWindow* repair_time; - ActiveWindow* replace_time; - Button* priority_increase; - Button* priority_decrease; - - PowerSource* route_source; - List route_list; - - PowerSource* selected_source; - List selected_clients; - - System* selected_repair; - Component* selected_component; -}; - -#endif // EngDlg_h - diff --git a/Stars45/EventDispatch.cpp b/Stars45/EventDispatch.cpp deleted file mode 100644 index 0a9b95c..0000000 --- a/Stars45/EventDispatch.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* 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 "EventDispatch.h" -#include "Mouse.h" -#include "Keyboard.h" - -// +--------------------------------------------------------------------+ - -int GetKeyPlus(int& key, int& shift); - -// +--------------------------------------------------------------------+ - -EventDispatch* EventDispatch::dispatcher = 0; - -// +--------------------------------------------------------------------+ - -EventDispatch::EventDispatch() - : capture(0), current(0), focus(0), click_tgt(0), - mouse_x(0), mouse_y(0), mouse_l(0), mouse_r(0) -{ } - -EventDispatch::~EventDispatch() -{ } - -// +--------------------------------------------------------------------+ - -void -EventDispatch::Create() -{ - dispatcher = new EventDispatch; -} - -// +--------------------------------------------------------------------+ - -void -EventDispatch::Close() -{ - delete dispatcher; - dispatcher = 0; -} - -// +--------------------------------------------------------------------+ - -void -EventDispatch::Dispatch() -{ - int ml = Mouse::LButton(); - int mr = Mouse::RButton(); - int mx = Mouse::X(); - int my = Mouse::Y(); - int mw = Mouse::Wheel(); - - EventTarget* mouse_tgt = capture; - EventTarget* key_tgt = focus; - EventTarget* do_click = 0; - - if (!mouse_tgt) { - ListIter iter = clients; - while (++iter) { - EventTarget* test = iter.value(); - if (test->IsFormActive()) { - if (test->TargetRect().Contains(mx,my)) - mouse_tgt = test; - - if (test->HasFocus()) - key_tgt = test; - } - } - } - - // Mouse Events: - - if (mouse_tgt != current) { - if (current && current->IsEnabled() && current->IsVisible()) - current->OnMouseExit(mx,my); - - current = mouse_tgt; - - if (current && current->IsEnabled() && current->IsVisible()) - current->OnMouseEnter(mx,my); - } - - if (mouse_tgt && mouse_tgt->IsEnabled()) { - if (mx != mouse_x || my != mouse_y) - mouse_tgt->OnMouseMove(mx,my); - - if (mw != 0) - mouse_tgt->OnMouseWheel(mw); - - if (ml != mouse_l) { - if (ml) { - mouse_tgt->OnLButtonDown(mx,my); - click_tgt = mouse_tgt; - } - else { - mouse_tgt->OnLButtonUp(mx,my); - - if (click_tgt == mouse_tgt) { - if (click_tgt->TargetRect().Contains(mx,my)) - do_click = click_tgt; - click_tgt = 0; - } - } - } - - if (mr != mouse_r) { - if (mr) - mouse_tgt->OnRButtonDown(mx,my); - else - mouse_tgt->OnRButtonUp(mx,my); - } - } - - mouse_l = ml; - mouse_r = mr; - mouse_x = mx; - mouse_y = my; - - // Keyboard Events: - - if (click_tgt && click_tgt != key_tgt) { - if (key_tgt) key_tgt->KillFocus(); - key_tgt = click_tgt; - - if (key_tgt != focus) { - if (focus) focus->KillFocus(); - - if (key_tgt && key_tgt->IsEnabled() && key_tgt->IsVisible()) - focus = key_tgt; - else - key_tgt = 0; - - if (focus) focus->SetFocus(); - } - } - - if (key_tgt && key_tgt->IsEnabled()) { - int key = 0; - int shift = 0; - - while (GetKeyPlus(key, shift)) { - if (key == VK_ESCAPE) { - key_tgt->KillFocus(); - focus = 0; - break; - } - - else if (key == VK_TAB && focus) { - int key_index = clients.index(focus) + 1; - - if (shift & 1) key_index -= 2; - - if (key_index >= clients.size()) - key_index = 0; - else if (key_index < 0) - key_index = clients.size()-1; - - if (focus) focus->KillFocus(); - focus = clients[key_index]; - if (focus) focus->SetFocus(); - - break; - } - - key_tgt->OnKeyDown(key, shift); - } - } - - if (do_click) - do_click->OnClick(); -} - -// +--------------------------------------------------------------------+ - -void -EventDispatch::MouseEnter(EventTarget* mouse_tgt) -{ - if (mouse_tgt != current) { - if (current) current->OnMouseExit(0,0); - current = mouse_tgt; - if (current) current->OnMouseEnter(0,0); - } -} - -// +--------------------------------------------------------------------+ - -void -EventDispatch::Register(EventTarget* tgt) -{ - if (!clients.contains(tgt)) - clients.append(tgt); -} - -// +--------------------------------------------------------------------+ - -void -EventDispatch::Unregister(EventTarget* tgt) -{ - clients.remove(tgt); - - if (capture == tgt) capture = 0; - if (current == tgt) current = 0; - if (focus == tgt) focus = 0; - if (click_tgt == tgt) click_tgt = 0; -} - -// +--------------------------------------------------------------------+ - -EventTarget* -EventDispatch::GetCapture() -{ - return capture; -} - -int -EventDispatch::CaptureMouse(EventTarget* tgt) -{ - if (tgt) { - capture = tgt; - return 1; - } - - return 0; -} - -int -EventDispatch::ReleaseMouse(EventTarget* tgt) -{ - if (capture == tgt) { - capture = 0; - return 1; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -EventTarget* -EventDispatch::GetFocus() -{ - return focus; -} - -void -EventDispatch::SetFocus(EventTarget* tgt) -{ - if (focus != tgt) { - if (focus) - focus->KillFocus(); - - focus = tgt; - - if (focus && focus->IsEnabled() && focus->IsVisible()) - focus->SetFocus(); - } -} - -void -EventDispatch::KillFocus(EventTarget* tgt) -{ - if (focus && focus == tgt) { - focus = 0; - tgt->KillFocus(); - } -} diff --git a/Stars45/EventDispatch.h b/Stars45/EventDispatch.h deleted file mode 100644 index 29b48a0..0000000 --- a/Stars45/EventDispatch.h +++ /dev/null @@ -1,61 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Event Dispatch class -*/ - -#ifndef EventDispatch_h -#define EventDispatch_h - -#include "Types.h" -#include "EventTarget.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class EventDispatch -{ -public: - static const char* TYPENAME() { return "EventDispatch"; } - - EventDispatch(); - virtual ~EventDispatch(); - - static void Create(); - static void Close(); - static EventDispatch* GetInstance() { return dispatcher; } - - virtual void Dispatch(); - virtual void Register(EventTarget* tgt); - virtual void Unregister(EventTarget* tgt); - - virtual EventTarget* GetCapture(); - virtual int CaptureMouse(EventTarget* tgt); - virtual int ReleaseMouse(EventTarget* tgt); - - virtual EventTarget* GetFocus(); - virtual void SetFocus(EventTarget* tgt); - virtual void KillFocus(EventTarget* tgt); - - virtual void MouseEnter(EventTarget* tgt); - -protected: - int mouse_x, mouse_y, mouse_l, mouse_r; - List clients; - EventTarget* capture; - EventTarget* current; - EventTarget* focus; - EventTarget* click_tgt; - - static EventDispatch* dispatcher; -}; - -#endif // EventDispatch_h - diff --git a/Stars45/EventTarget.h b/Stars45/EventTarget.h deleted file mode 100644 index 0c56944..0000000 --- a/Stars45/EventTarget.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Event Target interface class -*/ - -#ifndef EventTarget_h -#define EventTarget_h - -#include "Types.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class EventTarget -{ -public: - static const char* TYPENAME() { return "EventTarget"; } - - virtual ~EventTarget() { } - - int operator == (const EventTarget& t) const { return this == &t; } - - virtual int OnMouseMove(int x, int y) { return 0; } - virtual int OnLButtonDown(int x, int y) { return 0; } - virtual int OnLButtonUp(int x, int y) { return 0; } - virtual int OnClick() { return 0; } - virtual int OnSelect() { return 0; } - virtual int OnRButtonDown(int x, int y) { return 0; } - virtual int OnRButtonUp(int x, int y) { return 0; } - virtual int OnMouseEnter(int x, int y) { return 0; } - virtual int OnMouseExit(int x, int y) { return 0; } - virtual int OnMouseWheel(int wheel) { return 0; } - - virtual int OnKeyDown(int vk, int flags) { return 0; } - - virtual void SetFocus() { } - virtual void KillFocus() { } - virtual bool HasFocus() const { return false; } - - virtual bool IsEnabled() const { return true; } - virtual bool IsVisible() const { return true; } - virtual bool IsFormActive() const { return true; } - - virtual Rect TargetRect() const { return Rect(); } - - virtual const char* GetDescription() const { return "EventTarget"; } -}; - -#endif // EventTarget_h - diff --git a/Stars45/ExceptionHandler.cpp b/Stars45/ExceptionHandler.cpp deleted file mode 100644 index d93a88f..0000000 --- a/Stars45/ExceptionHandler.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/* 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 - -*/ - -#define NOMINMAX - -#include - -#include -#include - -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -class ExceptionHandler -{ -public: - ExceptionHandler(); - ~ExceptionHandler(); - -private: - static LPTOP_LEVEL_EXCEPTION_FILTER old_filter; - - static LONG WINAPI ExceptionFilter(EXCEPTION_POINTERS* info); - - static void PrintReport(EXCEPTION_POINTERS* info); - - // Helper functions - static const char* GetExceptionString(DWORD dwCode); - static BOOL GetLogicalAddress(VOID* addr, char* module, int len, - DWORD& section, DWORD& offset); - - static BOOL InitImageHelp(); - static void ImageStackTrace(CONTEXT* context); - static void IntelStackTrace(CONTEXT* context); - - - // Make typedefs for some IMAGEHLP.DLL functions so that we can use them - // with GetProcAddress - typedef BOOL (__stdcall * SYMINITIALIZEPROC)(HANDLE, LPSTR, BOOL); - typedef BOOL (__stdcall * SYMCLEANUPPROC)(HANDLE); - - typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)(HANDLE, DWORD); - typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)(HANDLE, DWORD); - typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL); - - typedef BOOL (__stdcall * STACKWALKPROC)(DWORD, - HANDLE, - HANDLE, - LPSTACKFRAME, - LPVOID, - PREAD_PROCESS_MEMORY_ROUTINE, - PFUNCTION_TABLE_ACCESS_ROUTINE, - PGET_MODULE_BASE_ROUTINE, - PTRANSLATE_ADDRESS_ROUTINE); - - static SYMINITIALIZEPROC SymInitialize; - static SYMCLEANUPPROC SymCleanup; - static STACKWALKPROC StackTrace; - static SYMFUNCTIONTABLEACCESSPROC SymFunctionTableAccess; - static SYMGETMODULEBASEPROC SymGetModuleBase; - static SYMGETSYMFROMADDRPROC SymGetSymFromAddr; -}; - -// +--------------------------------------------------------------------+ - -LPTOP_LEVEL_EXCEPTION_FILTER ExceptionHandler::old_filter = 0; - -ExceptionHandler::SYMINITIALIZEPROC ExceptionHandler::SymInitialize = 0; -ExceptionHandler::SYMCLEANUPPROC ExceptionHandler::SymCleanup = 0; -ExceptionHandler::STACKWALKPROC ExceptionHandler::StackTrace = 0; - -ExceptionHandler::SYMFUNCTIONTABLEACCESSPROC -ExceptionHandler::SymFunctionTableAccess = 0; - -ExceptionHandler::SYMGETMODULEBASEPROC -ExceptionHandler::SymGetModuleBase = 0; - -ExceptionHandler::SYMGETSYMFROMADDRPROC -ExceptionHandler::SymGetSymFromAddr = 0; - -ExceptionHandler global_exception_handler; - - -// +--------------------------------------------------------------------+ - -ExceptionHandler::ExceptionHandler() -{ - old_filter = SetUnhandledExceptionFilter(ExceptionFilter); -} - -ExceptionHandler::~ExceptionHandler() -{ - SetUnhandledExceptionFilter(old_filter); -} - -// +--------------------------------------------------------------------+ - -static bool in_filter = false; - -LONG WINAPI -ExceptionHandler::ExceptionFilter(EXCEPTION_POINTERS* info) -{ - if (in_filter) { - Print("\n\n*********************************************\n"); - Print("SECOND EXCEPTION CAUGHT: TERMINATING.\n"); - Print("*********************************************\n"); - } - - else { - in_filter = true; - PrintReport(info); - in_filter = false; - } - - if (old_filter) - return old_filter(info); - else - return EXCEPTION_CONTINUE_SEARCH; -} - -// +--------------------------------------------------------------------+ - -void -ExceptionHandler::PrintReport(EXCEPTION_POINTERS* info) -{ - EXCEPTION_RECORD* record = info->ExceptionRecord; - CONTEXT* context = info->ContextRecord; - DWORD code = record->ExceptionCode; - - Print("\n*********************************************\n"); - Print("FATAL EXCEPTION:\n"); - - Print("\nRegisters:\n"); - Print("EAX: %08x\n", context->Eax); - Print("EBX: %08x\n", context->Ebx); - Print("ECX: %08x\n", context->Ecx); - Print("EDX: %08x\n", context->Edx); - Print("EDI: %08x\n", context->Edi); - Print("ESI: %08x\n", context->Esi); - Print("EBP: %08x\n", context->Ebp); - Print("\n"); - Print("CS:EIP: %04x:%08x\n", context->SegCs, context->Eip); - Print("SS:ESP: %04x:%08x\n", context->SegSs, context->Esp); - Print("DS: %04x\n", context->SegDs); - Print("ES: %04x\n", context->SegEs); - Print("FS: %04x\n", context->SegFs); - Print("GS: %04x\n", context->SegGs); - Print("Flags: %08x\n", context->EFlags ); - Print("\n"); - - Print("Exception Code: %08x %s\n",code, GetExceptionString(code)); - Print("Exception Addr: %08x \n", record->ExceptionAddress); - - if (code == EXCEPTION_ACCESS_VIOLATION && record->NumberParameters >= 2) { - if (record->ExceptionInformation[0]) - Print(" Program attempted to WRITE to address 0x%08x\n", record->ExceptionInformation[1]); - else - Print(" Program attempted to READ from address 0x%08x\n", record->ExceptionInformation[1]); - } - - if (InitImageHelp()) { - ImageStackTrace(context); - SymCleanup(GetCurrentProcess()); - } - else { - IntelStackTrace(context); - } - - Print("\n*********************************************\nPROGRAM TERMINATED.\n"); -} - -// +--------------------------------------------------------------------+ - -const char* -ExceptionHandler::GetExceptionString(DWORD code) -{ -#define EXCEPTION( x ) case EXCEPTION_##x: return #x; - - switch (code) { - EXCEPTION( ACCESS_VIOLATION ) - EXCEPTION( DATATYPE_MISALIGNMENT ) - EXCEPTION( BREAKPOINT ) - EXCEPTION( SINGLE_STEP ) - EXCEPTION( ARRAY_BOUNDS_EXCEEDED ) - EXCEPTION( FLT_DENORMAL_OPERAND ) - EXCEPTION( FLT_DIVIDE_BY_ZERO ) - EXCEPTION( FLT_INEXACT_RESULT ) - EXCEPTION( FLT_INVALID_OPERATION ) - EXCEPTION( FLT_OVERFLOW ) - EXCEPTION( FLT_STACK_CHECK ) - EXCEPTION( FLT_UNDERFLOW ) - EXCEPTION( INT_DIVIDE_BY_ZERO ) - EXCEPTION( INT_OVERFLOW ) - EXCEPTION( PRIV_INSTRUCTION ) - EXCEPTION( IN_PAGE_ERROR ) - EXCEPTION( ILLEGAL_INSTRUCTION ) - EXCEPTION( NONCONTINUABLE_EXCEPTION ) - EXCEPTION( STACK_OVERFLOW ) - EXCEPTION( INVALID_DISPOSITION ) - EXCEPTION( GUARD_PAGE ) - EXCEPTION( INVALID_HANDLE ) - } - - static char buffer[512] = { 0 }; - - FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, - GetModuleHandle("NTDLL.DLL"), - code, 0, buffer, sizeof(buffer), 0 ); - - return buffer; -} - -// +--------------------------------------------------------------------+ - -BOOL -ExceptionHandler::GetLogicalAddress(void* addr, char* mod_name, int len, DWORD& section, DWORD& offset) -{ - MEMORY_BASIC_INFORMATION mbi; - - if (!VirtualQuery(addr, &mbi, sizeof(mbi))) - return FALSE; - - DWORD hMod = (DWORD)mbi.AllocationBase; - - if (!GetModuleFileName((HMODULE)hMod, mod_name, len)) - return FALSE; - - PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER) hMod; - PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew); - PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr ); - - DWORD rva = (DWORD)addr - hMod; // RVA is offset from module load address - - // Iterate through the section table, looking for the one that encompasses - // the linear address. - for (unsigned i = 0; i < pNtHdr->FileHeader.NumberOfSections; i++, pSection++ ) { - DWORD sectionStart = pSection->VirtualAddress; - DWORD sectionEnd = sectionStart - + std::max(pSection->SizeOfRawData, pSection->Misc.VirtualSize); - - // Is the address in this section??? - if ((rva >= sectionStart) && (rva <= sectionEnd)) { - // Yes, address is in the section. Calculate section and offset, - // and store in the "section" & "offset" params, which were - // passed by reference. - section = i+1; - offset = rva - sectionStart; - return TRUE; - } - } - - return FALSE; // Should never get here! -} - -// +--------------------------------------------------------------------+ - -void -ExceptionHandler::IntelStackTrace(CONTEXT* context) -{ - Print("\nStack Trace (Intel):\n"); - Print("Address Frame Logical addr Module\n"); - - DWORD pc = context->Eip; - DWORD* pFrame; - DWORD* pPrevFrame; - - pFrame = (DWORD*)context->Ebp; - - do { - char mod_name[256] = { 0 }; - DWORD section = 0, offset = 0; - - GetLogicalAddress((void*)pc, mod_name, 256, section, offset); - - Print("%08X %08X %04X:%08X %s\n", - pc, pFrame, section, offset, mod_name); - - pc = pFrame[1]; - pPrevFrame = pFrame; - pFrame = (PDWORD)pFrame[0]; // proceed to next higher frame on stack - - if ((DWORD)pFrame & 3) // Frame pointer must be aligned on a - break; // DWORD boundary. Bail if not so. - - if (pFrame <= pPrevFrame) - break; - - // Can two DWORDs be read from the supposed frame address? - if (IsBadWritePtr(pFrame, sizeof(PVOID)*2)) - break; - - } - while ( 1 ); -} - -// +--------------------------------------------------------------------+ - -void ExceptionHandler::ImageStackTrace(CONTEXT* context) -{ - Print("\nStack Trace (Symbolic):\n"); - Print("Address Frame\n"); - - // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag - STACKFRAME sf; - memset(&sf, 0, sizeof(sf)); - - // Initialize the STACKFRAME structure for the first call. This is only - // necessary for Intel CPUs, and isn't mentioned in the documentation. - sf.AddrPC.Offset = context->Eip; - sf.AddrPC.Mode = AddrModeFlat; - sf.AddrStack.Offset = context->Esp; - sf.AddrStack.Mode = AddrModeFlat; - sf.AddrFrame.Offset = context->Ebp; - sf.AddrFrame.Mode = AddrModeFlat; - - while ( 1 ) { - if (!StackTrace( IMAGE_FILE_MACHINE_I386, - GetCurrentProcess(), - GetCurrentThread(), - &sf, - context, - 0, - SymFunctionTableAccess, - SymGetModuleBase, - 0)) - break; - - if (sf.AddrFrame.Offset == 0) // Basic sanity check to make sure - break; // the frame is OK. Bail if not. - - Print("%08x %08x ", sf.AddrPC.Offset, sf.AddrFrame.Offset); - - // IMAGEHLP is wacky, and requires you to pass in a pointer to an - // IMAGEHLP_SYMBOL structure. The problem is that this structure is - // variable length. That is, you determine how big the structure is - // at runtime. This means that you can't use sizeof(struct). - // So...make a buffer that's big enough, and make a pointer - // to the buffer. We also need to initialize not one, but TWO - // members of the structure before it can be used. - - BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 512]; - PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)symbolBuffer; - pSymbol->SizeOfStruct = sizeof(symbolBuffer); - pSymbol->MaxNameLength = 512; - - DWORD symDisplacement = 0; // Displacement of the input address, - // relative to the start of the symbol - - if (SymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset, - &symDisplacement, pSymbol)) { - Print("%-40s [%04X]\n", pSymbol->Name, symDisplacement); - } - else { - char mod_name[256] = { 0 }; - DWORD section = 0, offset = 0; - - GetLogicalAddress((PVOID)sf.AddrPC.Offset, - mod_name, 256, section, offset ); - - Print("%04X:%08X %s\n", section, offset, mod_name); - } - } -} - -// +--------------------------------------------------------------------+ - -BOOL -ExceptionHandler::InitImageHelp() -{ - Print("\n"); - - HMODULE h = LoadLibrary("IMAGEHLP.DLL"); - if (!h) { - Print("--- could not load IMAGEHLP.DLL (%08x) ---\n", GetLastError()); - return FALSE; - } - - SymInitialize = (SYMINITIALIZEPROC) GetProcAddress(h, "SymInitialize"); - if (!SymInitialize) { - Print("--- could not find SymInitialize ---\n"); - return FALSE; - } - - SymCleanup = (SYMCLEANUPPROC) GetProcAddress(h, "SymCleanup"); - if (!SymCleanup) { - Print("--- could not find SymCleanup ---\n"); - return FALSE; - } - - StackTrace = (STACKWALKPROC) GetProcAddress(h, "StackWalk"); - if (!StackTrace) { - Print("--- could not find StackWalk ---\n"); - return FALSE; - } - - SymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) - GetProcAddress(h, "SymFunctionTableAccess"); - - if (!SymFunctionTableAccess) { - Print("--- could not find SymFunctionTableAccess ---\n"); - return FALSE; - } - - SymGetModuleBase = (SYMGETMODULEBASEPROC) GetProcAddress(h, "SymGetModuleBase"); - if (!SymGetModuleBase) { - Print("--- could not find SymGetModuleBase ---\n"); - return FALSE; - } - - SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC) GetProcAddress(h, "SymGetSymFromAddr"); - if (!SymGetSymFromAddr) { - Print("--- could not find SymGetSymFromAddr ---\n"); - return FALSE; - } - - if (!SymInitialize(GetCurrentProcess(), 0, TRUE)) { - Print("--- could not Initialize IMAGEHLP.DLL (%08x) ---\n", GetLastError()); - return FALSE; - } - - Print("Loaded IMAGEHLP.DLL\n"); - return TRUE; -} - diff --git a/Stars45/ExitDlg.cpp b/Stars45/ExitDlg.cpp deleted file mode 100644 index 5d42448..0000000 --- a/Stars45/ExitDlg.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "ExitDlg.h" -#include "MenuScreen.h" -#include "MusicDirector.h" -#include "Starshatter.h" -#include "FormatUtil.h" - -#include "Clock.h" -#include "Keyboard.h" -#include "Button.h" -#include "RichTextBox.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(ExitDlg, OnApply); -DEF_MAP_CLIENT(ExitDlg, OnCancel); - -// +--------------------------------------------------------------------+ - -ExitDlg::ExitDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), -manager(mgr), exit_latch(false), -credits(0), apply(0), cancel(0), -def_rect(def.GetRect()) -{ - Init(def); -} - -ExitDlg::~ExitDlg() -{ -} - -void -ExitDlg::RegisterControls() -{ - if (apply) - return; - - credits = (RichTextBox*) FindControl(201); - - apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, apply, ExitDlg, OnApply); - - cancel = (Button*) FindControl(2); - REGISTER_CLIENT(EID_CLICK, cancel, ExitDlg, OnCancel); -} - -// +--------------------------------------------------------------------+ - -void -ExitDlg::ExecFrame() -{ - if (credits && credits->GetLineCount() > 0) { - credits->SmoothScroll(ScrollWindow::SCROLL_DOWN, Clock::GetInstance()->GuiDelta()); - - if (credits->GetTopIndex() >= credits->GetLineCount()-1) { - credits->ScrollTo(0); - } - } - - if (Keyboard::KeyDown(VK_RETURN)) { - OnApply(0); - } - - if (Keyboard::KeyDown(VK_ESCAPE)) { - if (!exit_latch) - OnCancel(0); - } - else { - exit_latch = false; - } -} - -// +--------------------------------------------------------------------+ - -void -ExitDlg::Show() -{ - if (!IsShown()) { - Rect r = def_rect; - - if (r.w > screen->Width()) { - int extra = r.w - screen->Width(); - r.w -= extra; - } - - if (r.h > screen->Height()) { - int extra = r.h - screen->Height(); - r.h -= extra; - } - - r.x = (screen->Width() - r.w) / 2; - r.y = (screen->Height() - r.h) / 2; - - MoveTo(r); - - exit_latch = true; - Button::PlaySound(Button::SND_CONFIRM); - MusicDirector::SetMode(MusicDirector::CREDITS); - - DataLoader* loader = DataLoader::GetLoader(); - BYTE* block = 0; - - loader->SetDataPath(0); - loader->LoadBuffer("credits.txt", block, true); - - if (block && credits) { - credits->SetText((const char*) block); - } - - loader->ReleaseBuffer(block); - } - - FormWindow::Show(); -} - -// +--------------------------------------------------------------------+ - -void -ExitDlg::OnApply(AWEvent* event) -{ - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - ::Print("Exit Confirmed.\n"); - stars->Exit(); - } -} - -void -ExitDlg::OnCancel(AWEvent* event) -{ - manager->ShowMenuDlg(); - MusicDirector::SetMode(MusicDirector::MENU); -} - -// +--------------------------------------------------------------------+ diff --git a/Stars45/ExitDlg.h b/Stars45/ExitDlg.h deleted file mode 100644 index 46d5552..0000000 --- a/Stars45/ExitDlg.h +++ /dev/null @@ -1,59 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Navigation Active Window class -*/ - -#ifndef ExitDlg_h -#define ExitDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; - -// +--------------------------------------------------------------------+ - -class ExitDlg : public FormWindow -{ -public: - ExitDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~ExitDlg(); - - virtual void RegisterControls(); - virtual void Show(); - - // Operations: - virtual void ExecFrame(); - - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - -protected: - MenuScreen* manager; - - RichTextBox* credits; - Button* apply; - Button* cancel; - Rect def_rect; - - bool exit_latch; -}; - -#endif // ExitDlg_h - diff --git a/Stars45/Explosion.cpp b/Stars45/Explosion.cpp deleted file mode 100644 index 9a47b0b..0000000 --- a/Stars45/Explosion.cpp +++ /dev/null @@ -1,609 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Explosion Sprite animation class -*/ - -#include "Explosion.h" -#include "QuantumFlash.h" -#include "Particles.h" -#include "Ship.h" -#include "Sim.h" -#include "CameraDirector.h" -#include "AudioConfig.h" - -#include "Light.h" -#include "Sprite.h" -#include "Solid.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Game.h" -#include "Scene.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ - -const int MAX_EXPLOSION_TYPES = 32; - -static float lifetimes[MAX_EXPLOSION_TYPES]; -static float scales[MAX_EXPLOSION_TYPES]; -static Bitmap* bitmaps[MAX_EXPLOSION_TYPES]; -static Bitmap* particle_bitmaps[MAX_EXPLOSION_TYPES]; -static int part_frames[MAX_EXPLOSION_TYPES]; -static int lengths[MAX_EXPLOSION_TYPES]; -static float light_levels[MAX_EXPLOSION_TYPES]; -static float light_decays[MAX_EXPLOSION_TYPES]; -static Color light_colors[MAX_EXPLOSION_TYPES]; -static int num_parts[MAX_EXPLOSION_TYPES]; -static int part_types[MAX_EXPLOSION_TYPES]; -static float part_speeds[MAX_EXPLOSION_TYPES]; -static float part_drags[MAX_EXPLOSION_TYPES]; -static float part_scales[MAX_EXPLOSION_TYPES]; -static float part_blooms[MAX_EXPLOSION_TYPES]; -static float part_rates[MAX_EXPLOSION_TYPES]; -static float part_decays[MAX_EXPLOSION_TYPES]; -static bool part_trails[MAX_EXPLOSION_TYPES]; -static int part_alphas[MAX_EXPLOSION_TYPES]; -static Sound* sounds[MAX_EXPLOSION_TYPES]; -static bool recycles[MAX_EXPLOSION_TYPES]; - -// +--------------------------------------------------------------------+ - -Explosion::Explosion(int t, const Vec3& pos, const Vec3& vel, -float exp_scale, float part_scale, -SimRegion* rgn, SimObject* src) -: SimObject("Explosion", t), type(t), particles(0), source(src) -{ - Observe(source); - - MoveTo(pos); - velocity = vel; - drag = 0.3f; - rep = 0; - light = 0; - life = 0; - - if (type == QUANTUM_FLASH) { - life = 1.1; - - QuantumFlash* q = new QuantumFlash(); - rep = q; - - light = new Light(1e9, 0.66f); - light->SetColor(Color(180, 200, 255)); - } - - else if (type >= 0 && type < MAX_EXPLOSION_TYPES) { - life = lifetimes[type]; - - if (source) { - Matrix src_orient = source->Cam().Orientation(); - src_orient.Transpose(); - mount_rel = (pos - source->Location()) * src_orient; - } - - if (lengths[type] > 0) { - int repeat = (lengths[type] == 1); - Sprite* s = new Sprite(bitmaps[type], lengths[type], repeat); - s->Scale(exp_scale * scales[type]); - s->SetAngle(PI * rand()/16384.0); - s->SetLuminous(true); - rep = s; - } - - if (light_levels[type] > 0) { - light = new Light(light_levels[type], light_decays[type]); - light->SetColor(light_colors[type]); - } - - if (num_parts[type] > 0) { - particles = new Particles(particle_bitmaps[type], - num_parts[type], - pos, - Vec3(0.0f, 0.0f, 0.0f), - part_speeds[type] * part_scale, - part_drags[type], - part_scales[type] * part_scale, - part_blooms[type] * part_scale, - part_decays[type], - part_rates[type], - recycles[type], - part_trails[type], - (rgn && rgn->IsAirSpace()), - part_alphas[type], - part_frames[type]); - } - } - - if (rep) - rep->MoveTo(pos); - - if (light) - light->MoveTo(pos); -} - -// +--------------------------------------------------------------------+ - -Explosion::~Explosion() -{ - GRAPHIC_DESTROY(particles); -} - -// +--------------------------------------------------------------------+ - -bool -Explosion::Update(SimObject* obj) -{ - if (obj == source) { - source = 0; - - if (life < 0 || life > 4) - life = 4; - - if (particles) - particles->StopEmitting(); - } - - return SimObserver::Update(obj); -} - -const char* -Explosion::GetObserverName() const -{ - static char name[128]; - if (source) - sprintf_s(name, "Explosion(%s)", source->Name()); - else - sprintf_s(name, "Explosion"); - return name; -} - -// +--------------------------------------------------------------------+ - -void -Explosion::Initialize() -{ - static int initialized = 0; - if (initialized) return; - - ZeroMemory(lifetimes, sizeof(lifetimes)); - ZeroMemory(scales, sizeof(scales)); - ZeroMemory(bitmaps, sizeof(bitmaps)); - ZeroMemory(particle_bitmaps, sizeof(particle_bitmaps)); - ZeroMemory(lengths, sizeof(lengths)); - ZeroMemory(light_levels, sizeof(light_levels)); - ZeroMemory(light_decays, sizeof(light_decays)); - ZeroMemory(light_colors, sizeof(light_colors)); - ZeroMemory(num_parts, sizeof(num_parts)); - ZeroMemory(part_types, sizeof(part_types)); - ZeroMemory(part_speeds, sizeof(part_speeds)); - ZeroMemory(part_drags, sizeof(part_drags)); - ZeroMemory(part_scales, sizeof(part_scales)); - ZeroMemory(part_blooms, sizeof(part_blooms)); - ZeroMemory(part_decays, sizeof(part_decays)); - ZeroMemory(part_rates, sizeof(part_rates)); - ZeroMemory(part_trails, sizeof(part_trails)); - ZeroMemory(part_alphas, sizeof(part_alphas)); - ZeroMemory(sounds, sizeof(sounds)); - ZeroMemory(recycles, sizeof(recycles)); - - const char* filename = "Explosions.def"; - Print("Loading Explosion Defs '%s'\n", filename); - - // Load Design File: - DataLoader* loader = DataLoader::GetLoader(); - BYTE* block; - - loader->SetDataPath("Explosions/"); - int blocklen = loader->LoadBuffer(filename, block, true); - 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() != "EXPLOSION") { - Print("ERROR: invalid explosion def file '%s'\n", filename); - exit(-4); - } - } - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "explosion") { - - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: explosion structure missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - int type = -1; - char type_name[32]; - char bitmap[32]; - char particle_bitmap[32]; - char sound_file[32]; - float lifetime = 0.0f; - float scale = 1.0f; - int length = 0; - float light_level = 0.0f; - float light_decay = 1.0f; - Color light_color; - int num_part = 0; - int part_type = 0; - float part_speed = 0.0f; - float part_drag = 1.0f; - float part_scale = 1.0f; - float part_bloom = 0.0f; - float part_decay = 100.0f; - float part_rate = 1.0f; - bool part_trail = true; - bool continuous = false; - int part_alpha = 4; - int part_nframes = 1; - float sound_min_dist = 1.0f; - float sound_max_dist = 1.0e5f; - - type_name[0] = 0; - bitmap[0] = 0; - particle_bitmap[0] = 0; - sound_file[0] = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - - if (pdef->name()->value() == "type") { - if (pdef->term()->isText()) { - GetDefText(type_name, pdef, filename); - - const char* names[15] = { - "SHIELD_FLASH", - "HULL_FLASH", - "BEAM_FLASH", - "SHOT_BLAST", - "HULL_BURST", - "HULL_FIRE", - "PLASMA_LEAK", - "SMOKE_TRAIL", - "SMALL_FIRE", - "SMALL_EXPLOSION", - "LARGE_EXPLOSION", - "LARGE_BURST", - "NUKE_EXPLOSION", - "QUANTUM_FLASH", - "HYPER_FLASH" - }; - - for (int n = 0; n < 15; n++) - if (!_stricmp(type_name, names[n])) - type = n + 1; - } - - else if (pdef->term()->isNumber()) { - GetDefNumber(type, pdef, filename); - - if (type < 0 || type >= MAX_EXPLOSION_TYPES) { - ::Print("Warning - invalid explosion type %d ignored\n", type); - } - } - - else { - ::Print("Warning - weird explosion type:\n"); - pdef->print(); - } - } - - else if (pdef->name()->value() == "image" || - pdef->name()->value() == "bitmap") - GetDefText(bitmap, pdef, filename); - - else if (pdef->name()->value() == "particles" || - pdef->name()->value() == "particle_bitmap") - GetDefText(particle_bitmap, pdef, filename); - - else if (pdef->name()->value() == "sound") - GetDefText(sound_file, pdef, filename); - - else if (pdef->name()->value() == "lifetime") - GetDefNumber(lifetime, pdef, filename); - - else if (pdef->name()->value() == "scale") - GetDefNumber(scale, pdef, filename); - - else if (pdef->name()->value() == "length") - GetDefNumber(length, pdef, filename); - - else if (pdef->name()->value() == "light_level") - GetDefNumber(light_level, pdef, filename); - - else if (pdef->name()->value() == "light_decay") - GetDefNumber(light_decay, pdef, filename); - - else if (pdef->name()->value() == "light_color") - GetDefColor(light_color, pdef, filename); - - else if (pdef->name()->value() == "num_parts") - GetDefNumber(num_part, pdef, filename); - - else if (pdef->name()->value() == "part_frames") - GetDefNumber(part_nframes, pdef, filename); - - else if (pdef->name()->value() == "part_type") - GetDefNumber(part_type, pdef, filename); - - else if (pdef->name()->value() == "part_speed") - GetDefNumber(part_speed, pdef, filename); - - else if (pdef->name()->value() == "part_drag") - GetDefNumber(part_drag, pdef, filename); - - else if (pdef->name()->value() == "part_scale") - GetDefNumber(part_scale, pdef, filename); - - else if (pdef->name()->value() == "part_bloom") - GetDefNumber(part_bloom, pdef, filename); - - else if (pdef->name()->value() == "part_decay") - GetDefNumber(part_decay, pdef, filename); - - else if (pdef->name()->value() == "part_rate") - GetDefNumber(part_rate, pdef, filename); - - else if (pdef->name()->value() == "part_trail") - GetDefBool(part_trail, pdef, filename); - - else if (pdef->name()->value() == "part_alpha") - GetDefNumber(part_alpha, pdef, filename); - - else if (pdef->name()->value() == "continuous") - GetDefBool(continuous, pdef, filename); - - else if (pdef->name()->value() == "sound_min_dist") - GetDefNumber(sound_min_dist, pdef, filename); - - else if (pdef->name()->value() == "sound_max_dist") - GetDefNumber(sound_max_dist, pdef, filename); - - else { - Print("WARNING: parameter '%s' ignored in '%s'\n", - pdef->name()->value().data(), filename); - } - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - val->elements()->at(i)->print(); - } - } - - if (type >= 0 && type < MAX_EXPLOSION_TYPES) { - if (part_alpha > 2) - part_alpha = 4; - - lengths[type] = length; - lifetimes[type] = lifetime; - scales[type] = scale; - light_levels[type] = light_level; - light_decays[type] = light_decay; - light_colors[type] = light_color; - num_parts[type] = num_part; - part_types[type] = part_type; - part_speeds[type] = part_speed; - part_drags[type] = part_drag; - part_scales[type] = part_scale; - part_blooms[type] = part_bloom; - part_frames[type] = part_nframes; - part_decays[type] = part_decay; - part_rates[type] = part_rate; - part_trails[type] = part_trail; - part_alphas[type] = part_alpha; - recycles[type] = continuous; - - if (length > 0) { - bitmaps[type] = new Bitmap[length]; - - if (length > 1) { - for (int n = 0; n < length; n++) { - char img_name[64]; - sprintf_s(img_name, "%s%02d.pcx", bitmap, n); - loader->LoadBitmap(img_name, bitmaps[type][n], Bitmap::BMP_TRANSLUCENT); - } - } - - else { - loader->LoadBitmap(bitmap, bitmaps[type][0], Bitmap::BMP_TRANSLUCENT); - } - } - - if (particle_bitmap[0]) { - particle_bitmaps[type] = new Bitmap[part_nframes]; - - if (part_nframes > 1) { - for (int i = 0; i < part_nframes; i++) { - char fname[64]; - sprintf_s(fname, "%s%02d.pcx", particle_bitmap, i); - loader->LoadBitmap(fname, particle_bitmaps[type][i], Bitmap::BMP_TRANSLUCENT); - particle_bitmaps[type][i].MakeTexture(); - } - } - - else { - loader->LoadBitmap(particle_bitmap, particle_bitmaps[type][0], Bitmap::BMP_TRANSLUCENT); - particle_bitmaps[type][0].MakeTexture(); - } - } - - if (sound_file[0]) { - loader->SetDataPath("Sounds/"); - loader->LoadSound(sound_file, sounds[type], Sound::LOCALIZED | Sound::LOC_3D); - loader->SetDataPath("Explosions/"); - - if (sounds[type]) { - sounds[type]->SetMinDistance(sound_min_dist); - sounds[type]->SetMaxDistance(sound_max_dist); - } - } - } - } - } - - else - Print("WARNING: unknown definition '%s' in '%s'\n", - def->name()->value().data(), filename); - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - } - } - } - while (term); - - loader->ReleaseBuffer(block); - loader->SetDataPath(0); - initialized = 1; -} - -// +--------------------------------------------------------------------+ - -void -Explosion::Close() -{ - for (int t = 0; t < MAX_EXPLOSION_TYPES; t++) { - if (lengths[t] && bitmaps[t]) { - for (int i = 0; i < lengths[t]; i++) - bitmaps[t][i].ClearImage(); - delete [] bitmaps[t]; - } - - if (particle_bitmaps[t]) { - for (int i = 0; i < part_frames[t]; i++) - particle_bitmaps[t][i].ClearImage(); - delete [] particle_bitmaps[t]; - } - - delete sounds[t]; - } -} - -// +--------------------------------------------------------------------+ - -void -Explosion::ExecFrame(double seconds) -{ - if (source) { - const Matrix& orientation = source->Cam().Orientation(); - MoveTo((mount_rel * orientation) + source->Location()); - - if (rep) rep->Show(); - - if (particles) particles->Show(); - - if (source == Sim::GetSim()->GetPlayerShip()) { - Ship* ship = (Ship*) source; - if (CameraDirector::GetCameraMode() == CameraDirector::MODE_COCKPIT && - !ship->IsDying()) { - if (rep) rep->Hide(); - if (particles) particles->Hide(); - } - } - } - - life -= seconds; - - if (rep) { - rep->MoveTo(Location()); - - if (rep->Life() == 0) { - rep = 0; // about to be GC'd - } - - else if (rep->IsSprite()) { - Sprite* s = (Sprite*) rep; - s->SetAngle(s->Angle() + seconds * 0.5); - } - - else if (type == QUANTUM_FLASH) { - QuantumFlash* q = (QuantumFlash*) rep; - q->SetShade(q->Shade() - seconds); - } - } - - if (light) { - light->Update(); - - if (light->Life() == 0) - light = 0; // about to be GC'd - } - - if (particles) { - particles->MoveTo(Location()); - particles->ExecFrame(seconds); - } - - if (source && source->Life() == 0) - life = 0; -} - -// +--------------------------------------------------------------------+ - -void -Explosion::Activate(Scene& scene) -{ - bool filter = false; - - CameraDirector* cam_dir = CameraDirector::GetInstance(); - if (cam_dir && cam_dir->GetCamera()) { - if (Point(cam_dir->GetCamera()->Pos() - Location()).length() < 100) - filter = true; - } - - if (rep && !filter) - scene.AddGraphic(rep); - - if (light) - scene.AddLight(light); - - if (particles && !filter) - scene.AddGraphic(particles); - - if (sounds[obj_type]) { - Sound* sound = sounds[obj_type]->Duplicate(); - - // fire and forget: - if (sound) { - sound->SetLocation(Location()); - sound->SetVolume(AudioConfig::EfxVolume()); - sound->Play(); - } - } - - active = true; -} - -void -Explosion::Deactivate(Scene& scene) -{ - SimObject::Deactivate(scene); - - if (particles) - scene.DelGraphic(particles); -} - -// +--------------------------------------------------------------------+ - diff --git a/Stars45/Explosion.h b/Stars45/Explosion.h deleted file mode 100644 index f8dfc19..0000000 --- a/Stars45/Explosion.h +++ /dev/null @@ -1,83 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Explosion Sprite class -*/ - -#ifndef Explosion_h -#define Explosion_h - -#include "Types.h" -#include "Geometry.h" -#include "SimObject.h" -#include "Sound.h" - -// +--------------------------------------------------------------------+ - -class Solid; -class Particles; -class System; - -// +--------------------------------------------------------------------+ - -class Explosion : public SimObject, -public SimObserver -{ -public: - static const char* TYPENAME() { return "Explosion"; } - - enum Type { SHIELD_FLASH = 1, - HULL_FLASH = 2, - BEAM_FLASH = 3, - SHOT_BLAST = 4, - HULL_BURST = 5, - HULL_FIRE = 6, - PLASMA_LEAK = 7, - SMOKE_TRAIL = 8, - SMALL_FIRE = 9, - SMALL_EXPLOSION = 10, - LARGE_EXPLOSION = 11, - LARGE_BURST = 12, - NUKE_EXPLOSION = 13, - QUANTUM_FLASH = 14, - HYPER_FLASH = 15 - }; - - Explosion(int type, const Vec3& pos, const Vec3& vel, - float exp_scale, float part_scale, - SimRegion* rgn=0, SimObject* source=0); - virtual ~Explosion(); - - static void Initialize(); - static void Close(); - - virtual void ExecFrame(double seconds); - Particles* GetParticles() { return particles; } - - virtual void Activate(Scene& scene); - virtual void Deactivate(Scene& scene); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - -protected: - int type; - Particles* particles; - - float scale; - float scale1; - float scale2; - - SimObject* source; - Point mount_rel; -}; - -#endif // Explosion_h - diff --git a/Stars45/FadeView.cpp b/Stars45/FadeView.cpp deleted file mode 100644 index 7abb3bc..0000000 --- a/Stars45/FadeView.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Fading Bitmap "billboard" Image View class -*/ - -#include "FadeView.h" -#include "Color.h" -#include "Window.h" -#include "Video.h" -#include "Screen.h" -#include "Clock.h" - -// +--------------------------------------------------------------------+ - -FadeView::FadeView(Window* c, double in, double out, double hold) -: View(c), -fade_in(in), -fade_out(out), -hold_time(hold), -step_time(0), -fast(1) -{ - state = StateStart; -} - -FadeView::~FadeView() -{ } - -// +--------------------------------------------------------------------+ - -void FadeView::FastFade(int fade_fast) { fast = fade_fast; } -void FadeView::FadeIn(double in) { fade_in = in; } -void FadeView::FadeOut(double out) { fade_out = out; } -void FadeView::StopHold() -{ - //Print(" FadeView::StopHold()\n"); - hold_time = 0; -} - -// +--------------------------------------------------------------------+ - -void -FadeView::Refresh() -{ - double msec = Clock::GetInstance()->GuiDelta(); - - switch (state) { - case StateStart: - if (fade_in) { - //Print(" * FadeView: %f, %f, %f\n", fade_in, fade_out, hold_time); - Color::SetFade(0); - //Print(" 1. FadeView SetFade to 0 (%6.1f)\n", time); - } - - step_time = 0; - state = State2; - break; - - case State2: - if (fade_in) { - Color::SetFade(0); - //Print(" 1. FadeView SetFade to 0 (%6.1f)\n", time); - } - - step_time = 0; - state = StateIn; - break; - - case StateIn: - if (step_time < fade_in) { - double fade = step_time / fade_in; - Color::SetFade(fade); - //Print(" 2. FadeView SetFade to %3d (%6.1f) %6.1f\n", (int) (fade * 100), time, step_time); - step_time += msec; - } - else { - Color::SetFade(1); - //Print(" 2. FadeView SetFade to %3d (%6.1f) %6.1f => HOLDING\n", 100, time, step_time); - step_time = 0; - state = StateHold; - } - break; - - case StateHold: - if (step_time < hold_time) { - step_time += msec; - //Print(" 3. FadeView holding at %3d (%6.1f) %6.1f\n", 100, time, step_time); - } - else { - //Print(" 3. FadeView HOLD COMPLETE (%6.1f) %6.1f\n", time, step_time); - step_time = 0; - state = StateOut; - } - break; - - case StateOut: - if (fade_out > 0) { - if (step_time < fade_out) { - double fade = 1 - step_time / fade_out; - Color::SetFade(fade); - //Print(" 4. FadeView SetFade to %3d (%6.1f) %6.1f\n", (int) (fade*100), time, step_time); - step_time += msec; - } - else { - Color::SetFade(0); - //Print(" 4. FadeView SetFade to %3d (%6.1f) %6.1f\n", 0, time, step_time); - step_time = 0; - state = StateDone; - } - } - else { - Color::SetFade(1); - //Print(" 4. FadeView SetFade to %3d (%6.1f) %6.1f\n", 0, time, step_time); - step_time = 0; - state = StateDone; - } - break; - - default: - case StateDone: - //Print(" 5. FadeView done (%6.1f) %6.1f\n", time, step_time); - break; - } -} - diff --git a/Stars45/FadeView.h b/Stars45/FadeView.h deleted file mode 100644 index d3e3925..0000000 --- a/Stars45/FadeView.h +++ /dev/null @@ -1,54 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Non-rendering view class that controls the fade level (fade-in/fade-out) -*/ - -#ifndef FadeView_h -#define FadeView_h - -#include "Types.h" -#include "View.h" - -// +--------------------------------------------------------------------+ - -class FadeView : public View -{ -public: - static const char* TYPENAME() { return "FadeView"; } - - enum FadeState { StateStart, State2, StateIn, StateHold, StateOut, StateDone }; - - FadeView(Window* c, double fade_in=1, double fade_out=1, double hold_time=4); - virtual ~FadeView(); - - // Operations: - virtual void Refresh(); - virtual bool Done() const { return state == StateDone; } - virtual bool Holding() const { return state == StateHold; } - - // Control: - virtual void FastFade(int fade_fast); - virtual void FadeIn(double fade_in); - virtual void FadeOut(double fade_out); - virtual void StopHold(); - -protected: - double fade_in; - double fade_out; - double hold_time; - double step_time; - - int fast; - FadeState state; -}; - -#endif // FadeView_h - diff --git a/Stars45/Farcaster.cpp b/Stars45/Farcaster.cpp deleted file mode 100644 index bb1194e..0000000 --- a/Stars45/Farcaster.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "Farcaster.h" -#include "QuantumDrive.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Explosion.h" -#include "Sim.h" -#include "Element.h" -#include "Instruction.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Solid.h" -#include "Light.h" -#include "Sound.h" -#include "DataLoader.h" - -// +======================================================================+ - -Farcaster::Farcaster(double cap, double rate) - : System(FARCASTER, 0, "Farcaster", 1, (float) cap, (float) cap, (float) rate), - ship(0), dest(0), jumpship(0), cycle_time(10), - active_state(QuantumDrive::ACTIVE_READY), warp_fov(1), no_dest(false) -{ - name = ContentBundle::GetInstance()->GetText("sys.farcaster"); - abrv = ContentBundle::GetInstance()->GetText("sys.farcaster.abrv"); -} - -// +----------------------------------------------------------------------+ - -Farcaster::Farcaster(const Farcaster& s) - : System(s), - ship(0), dest(0), start_rel(s.start_rel), - end_rel(s.end_rel), jumpship(0), cycle_time(s.cycle_time), - active_state(QuantumDrive::ACTIVE_READY), warp_fov(1), no_dest(false) -{ - Mount(s); - SetAbbreviation(s.Abbreviation()); - - for (int i = 0; i < NUM_APPROACH_PTS; i++) - approach_rel[i] = s.approach_rel[i]; -} - -// +--------------------------------------------------------------------+ - -Farcaster::~Farcaster() -{ -} - -// +--------------------------------------------------------------------+ - -void -Farcaster::ExecFrame(double seconds) -{ - System::ExecFrame(seconds); - - if (ship && !no_dest) { - if (!dest) { - Element* elem = ship->GetElement(); - - if (elem->NumObjectives()) { - Sim* sim = Sim::GetSim(); - Instruction* obj = elem->GetObjective(0); - - if (obj) - dest = sim->FindShip(obj->TargetName()); - } - - if (!dest) - no_dest = true; - } - else { - if (dest->IsDying() || dest->IsDead()) { - dest = 0; - no_dest = true; - } - } - } - - // if no destination, show red nav lights: - if (no_dest) - energy = 0.0f; - - if (active_state == QuantumDrive::ACTIVE_READY && energy >= capacity && - ship && ship->GetRegion() && dest && dest->GetRegion()) { - SimRegion* rgn = ship->GetRegion(); - SimRegion* dst = dest->GetRegion(); - ListIter s_iter = rgn->Ships(); - - jumpship = 0; - - while (++s_iter) { - Ship* s = s_iter.value(); - - if (s == ship || s->IsStatic() || s->WarpFactor() > 1) - continue; - - Point delta = s->Location() - ship->Location(); - - // activate: - if (delta.length() < 1000) { - active_state = QuantumDrive::ACTIVE_PREWARP; - jumpship = s; - Observe(jumpship); - break; - } - } - } - - if (active_state == QuantumDrive::ACTIVE_READY) - return; - - if (ship) { - bool warping = false; - - if (active_state == QuantumDrive::ACTIVE_PREWARP) { - if (warp_fov < 5000) { - warp_fov *= 1.5; - } - else { - Jump(); - } - - warping = true; - } - - else if (active_state == QuantumDrive::ACTIVE_POSTWARP) { - if (warp_fov > 1) { - warp_fov *= 0.75; - } - else { - warp_fov = 1; - active_state = QuantumDrive::ACTIVE_READY; - } - - warping = true; - } - - if (jumpship) { - if (warping) { - jumpship->SetWarp(warp_fov); - - SimRegion* r = ship->GetRegion(); - ListIter neighbor = r->Ships(); - - while (++neighbor) { - if (neighbor->IsDropship()) { - Ship* s = neighbor.value(); - Point delta = s->Location() - ship->Location(); - - if (delta.length() < 5e3) - s->SetWarp(warp_fov); - } - } - } - else { - warp_fov = 1; - jumpship->SetWarp(warp_fov); - } - } - } -} - -void -Farcaster::Jump() -{ - Sim* sim = Sim::GetSim(); - SimRegion* rgn = ship->GetRegion(); - SimRegion* dst = dest->GetRegion(); - - sim->CreateExplosion(jumpship->Location(), Point(0,0,0), - Explosion::QUANTUM_FLASH, 1.0f, 0, rgn); - sim->RequestHyperJump(jumpship, dst, dest->Location().OtherHand(), 0, ship, dest); - - energy = 0.0f; - - Farcaster* f = dest->GetFarcaster(); - if (f) f->Arrive(jumpship); - - active_state = QuantumDrive::ACTIVE_READY; - warp_fov = 1; - jumpship = 0; -} - -void -Farcaster::Arrive(Ship* s) -{ - energy = 0.0f; - - active_state = QuantumDrive::ACTIVE_POSTWARP; - warp_fov = 5000; - jumpship = s; - - if (jumpship && jumpship->Velocity().length() < 500) { - jumpship->SetVelocity(jumpship->Heading() * 500); - } -} - -// +----------------------------------------------------------------------+ - -void -Farcaster::SetApproachPoint(int i, Point loc) -{ - if (i >= 0 && i < NUM_APPROACH_PTS) - approach_rel[i] = loc; -} - -void -Farcaster::SetStartPoint(Point loc) -{ - start_rel = loc; -} - -void -Farcaster::SetEndPoint(Point loc) -{ - end_rel = loc; -} - -// +----------------------------------------------------------------------+ - -void -Farcaster::SetCycleTime(double t) -{ - cycle_time = t; -} - -// +----------------------------------------------------------------------+ - -void -Farcaster::Orient(const Physical* rep) -{ - System::Orient(rep); - - Matrix orientation = rep->Cam().Orientation(); - Point loc = rep->Location(); - - start_point = (start_rel * orientation) + loc; - end_point = (end_rel * orientation) + loc; - - for (int i = 0; i < NUM_APPROACH_PTS; i++) - approach_point[i] = (approach_rel[i] * orientation) + loc; -} - -// +----------------------------------------------------------------------+ - -bool -Farcaster::Update(SimObject* obj) -{ - if (obj == jumpship) { - jumpship->SetWarp(1); - - SimRegion* r = ship->GetRegion(); - ListIter neighbor = r->Ships(); - - while (++neighbor) { - if (neighbor->IsDropship()) { - Ship* s = neighbor.value(); - Point delta = s->Location() - ship->Location(); - - if (delta.length() < 5e3) - s->SetWarp(1); - } - } - - jumpship = 0; - } - - return SimObserver::Update(obj); -} - -const char* -Farcaster::GetObserverName() const -{ - return Name(); -} diff --git a/Stars45/Farcaster.h b/Stars45/Farcaster.h deleted file mode 100644 index 9168a90..0000000 --- a/Stars45/Farcaster.h +++ /dev/null @@ -1,91 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#ifndef Farcaster_h -#define Farcaster_h - -#include "Types.h" -#include "Geometry.h" -#include "System.h" -#include "SimObject.h" -#include "Text.h" - -// +----------------------------------------------------------------------+ - -class Ship; -class ShipDesign; -class Farcaster; - -// +----------------------------------------------------------------------+ - -class Farcaster : public System, public SimObserver -{ -public: - Farcaster(double capacity, double sink_rate); - Farcaster(const Farcaster& rhs); - virtual ~Farcaster(); - - enum CONSTANTS { NUM_APPROACH_PTS = 4 }; - - virtual void ExecFrame(double seconds); - void SetShip(Ship* s) { ship = s; } - void SetDest(Ship* d) { dest = d; } - - Point ApproachPoint(int i) const { return approach_point[i]; } - Point StartPoint() const { return start_point; } - Point EndPoint() const { return end_point; } - - virtual void SetApproachPoint(int i, Point loc); - virtual void SetStartPoint(Point loc); - virtual void SetEndPoint(Point loc); - virtual void SetCycleTime(double time); - - virtual void Orient(const Physical* rep); - - // SimObserver: - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - // accessors: - const Ship* GetShip() const { return ship; } - const Ship* GetDest() const { return dest; } - - int ActiveState() const { return active_state; } - double WarpFactor() const { return warp_fov; } - -protected: - virtual void Jump(); - virtual void Arrive(Ship* s); - - Ship* ship; - Ship* dest; - Ship* jumpship; - - Point start_rel; - Point end_rel; - Point approach_rel[NUM_APPROACH_PTS]; - - Point start_point; - Point end_point; - Point approach_point[NUM_APPROACH_PTS]; - - double cycle_time; - int active_state; - double warp_fov; - - bool no_dest; -}; - -// +----------------------------------------------------------------------+ - -#endif // Farcaster_h - diff --git a/Stars45/FighterAI.cpp b/Stars45/FighterAI.cpp deleted file mode 100644 index 4160174..0000000 --- a/Stars45/FighterAI.cpp +++ /dev/null @@ -1,1832 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Fighter (low-level) Artificial Intelligence class -*/ - -#include "FighterAI.h" -#include "FighterTacticalAI.h" -#include "Ship.h" -#include "Shot.h" -#include "Sensor.h" -#include "Element.h" -#include "ShipDesign.h" -#include "Instruction.h" -#include "Weapon.h" -#include "WeaponGroup.h" -#include "Drive.h" -#include "QuantumDrive.h" -#include "Farcaster.h" -#include "FlightComp.h" -#include "FlightDeck.h" -#include "Hangar.h" -#include "Sim.h" -#include "StarSystem.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" - -#include "Clock.h" -#include "ContentBundle.h" - -static const double TIME_TO_DOCK = 30; - -// +----------------------------------------------------------------------+ - -FighterAI::FighterAI(SimObject* s) -: ShipAI(s), brakes(0), drop_state(0), jink_time(0), evading(false), -decoy_missile(0), missile_time(0), terrain_warning(false), inbound(0), -rtb_code(0), form_up(false), over_threshold(false), time_to_dock(0), -go_manual(false) -{ - ai_type = FIGHTER; - seek_gain = 22; - seek_damp = 0.55; - brakes = 0; - z_shift = 0; - - tactical = new FighterTacticalAI(this); -} - - -// +--------------------------------------------------------------------+ - -FighterAI::~FighterAI() -{ } - -// +--------------------------------------------------------------------+ - -static double frame_time = 0; - -void -FighterAI::ExecFrame(double s) -{ - if (!ship) return; - - evading = false; - inbound = ship->GetInbound(); - missile_time -= s; - - int order = 0; - - if (navpt) - order = navpt->Action(); - - if (inbound) { - form_up = false; - rtb_code = 1; - - // CHEAT LANDING: - if (inbound->Final() && time_to_dock > 0) { - FlightDeck* deck = inbound->GetDeck(); - if (deck) { - Point dst = deck->EndPoint(); - Point approach = deck->StartPoint() - dst; - - const Ship* carrier = deck->GetCarrier(); - - Camera landing_cam; - landing_cam.Clone(carrier->Cam()); - landing_cam.Yaw(deck->Azimuth()); - - if (time_to_dock > TIME_TO_DOCK/2) { - double lr, lp, lw; - double sr, sp, sw; - - landing_cam.Orientation().ComputeEulerAngles(lr, lp, lw); - ship->Cam().Orientation().ComputeEulerAngles(sr, sp, sw); - - double nr = sr + s*(lr-sr); - double np = sp + s*(lp-sp); - double nw = sw + s*(lw-sw)*0.5; - - Camera work; - work.Aim(nr,np,nw); - landing_cam.Clone(work); - } - - ship->CloneCam(landing_cam); - ship->MoveTo(dst + approach * (time_to_dock / TIME_TO_DOCK)); - ship->SetVelocity(carrier->Velocity() + ship->Heading() * 50); - ship->SetThrottle(50); - ship->ExecFLCSFrame(); - - time_to_dock -= s; - - if (time_to_dock <= 0) { - deck->Dock(ship); - time_to_dock = 0; - } - - return; - } - } - - else if (ship->GetFlightPhase() == Ship::DOCKING) { - // deal with (pathological) moving carrier deck: - - FlightDeck* deck = inbound->GetDeck(); - if (deck) { - Point dst = deck->EndPoint(); - - if (ship->IsAirborne()) { - double alt = dst.y; - dst = ship->Location(); - dst.y = alt; - } - - const Ship* carrier = deck->GetCarrier(); - - Camera landing_cam; - landing_cam.Clone(carrier->Cam()); - landing_cam.Yaw(deck->Azimuth()); - - ship->CloneCam(landing_cam); - ship->MoveTo(dst); - - if (!ship->IsAirborne()) { - ship->SetVelocity(carrier->Velocity()); - } - else { - Point taxi(landing_cam.vpn()); - ship->SetVelocity(taxi * 95); - } - - ship->SetThrottle(0); - ship->ExecFLCSFrame(); - } - - return; - } - } - else { - Instruction* orders = ship->GetRadioOrders(); - - if (orders && - (orders->Action() == RadioMessage::WEP_HOLD || - orders->Action() == RadioMessage::FORM_UP)) { - form_up = true; - rtb_code = 0; - } - else { - form_up = false; - } - } - - if (!target && order != Instruction::STRIKE) - ship->SetSensorMode(Sensor::STD); - - ShipAI::ExecFrame(s); // this must be the last line of this method - - // IT IS NOT SAFE TO PLACE CODE HERE - // if this class decides to break orbit, - // this object will be deleted during - // ShipAI::ExecFrame() (which calls - // FighterAI::Navigator() - see below) -} - -// +--------------------------------------------------------------------+ - -void -FighterAI::FindObjective() -{ - distance = 0; - - // ALWAYS complete initial launch navpt: - if (!navpt) { - navpt = ship->GetNextNavPoint(); - if (navpt && (navpt->Action() != Instruction::LAUNCH || navpt->Status() == Instruction::COMPLETE)) - navpt = 0; - } - - if (navpt && navpt->Action() == Instruction::LAUNCH) { - if (navpt->Status() != Instruction::COMPLETE) { - FindObjectiveNavPoint(); - - // transform into camera coords: - objective = Transform(obj_w); - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.launch")); - return; - } - else { - navpt = 0; - } - } - - // runway takeoff: - else if (takeoff) { - obj_w = ship->Location() + ship->Heading() * 10e3; - obj_w.y = ship->Location().y + 2e3; - - // transform into camera coords: - objective = Transform(obj_w); - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.takeoff")); - return; - } - - // approaching a carrier or runway: - else if (inbound) { - FlightDeck* deck = inbound->GetDeck(); - - if (!deck) { - objective = Point(); - return; - } - - // initial approach - if (inbound->Approach() > 0 || !inbound->Cleared()) { - obj_w = deck->ApproachPoint(inbound->Approach()) + inbound->Offset(); - - distance = (obj_w - ship->Location()).length(); - - // transform into camera coords: - objective = Transform(obj_w); - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.inbound")); - - return; - } - - // final approach - else { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.finals")); - - obj_w = deck->StartPoint(); - if (inbound->Final()) { - obj_w = deck->EndPoint(); - - if (deck->OverThreshold(ship)) { - obj_w = deck->MountLocation(); - over_threshold = true; - } - } - - distance = (obj_w - ship->Location()).length(); - - // transform into camera coords: - objective = Transform(obj_w); - - return; - } - } - - // not inbound yet, check for RTB order: - else { - Instruction* orders = (Instruction*) ship->GetRadioOrders(); - int action = 0; - - if (orders) - action = orders->Action(); - - if (navpt && !action) { - FindObjectiveNavPoint(); - if (distance < 5e3) { - action = navpt->Action(); - } - } - - if (action == RadioMessage::RTB || - action == RadioMessage::DOCK_WITH) { - - Ship* controller = ship->GetController(); - - if (orders && orders->Action() == RadioMessage::DOCK_WITH && orders->GetTarget()) { - controller = (Ship*) orders->GetTarget(); - } - - else if (navpt && navpt->Action() == RadioMessage::DOCK_WITH && navpt->GetTarget()) { - controller = (Ship*) navpt->GetTarget(); - } - - ReturnToBase(controller); - - if (rtb_code) - return; - } - } - - ShipAI::FindObjective(); -} - -void -FighterAI::ReturnToBase(Ship* controller) -{ - rtb_code = 0; - - if (controller) { - SimRegion* self_rgn = ship->GetRegion(); - SimRegion* rtb_rgn = controller->GetRegion(); - - if (self_rgn && !rtb_rgn) { - rtb_rgn = self_rgn; - } - - if (self_rgn && rtb_rgn && self_rgn != rtb_rgn) { - // is the carrier in orbit above us - // (or on the ground below us)? - - if (rtb_rgn->GetOrbitalRegion()->Primary() == - self_rgn->GetOrbitalRegion()->Primary()) { - - Point npt = rtb_rgn->Location() - self_rgn->Location(); - obj_w = npt.OtherHand(); - - // distance from self to navpt: - distance = Point(obj_w - ship->Location()).length(); - - // transform into camera coords: - objective = Transform(obj_w); - - if (rtb_rgn->IsAirSpace()) { - drop_state = -1; - } - else if (rtb_rgn->IsOrbital()) { - drop_state = 1; - } - - rtb_code = 2; - } - - // try to find a jumpgate that will take us home: - else { - QuantumDrive* qdrive = ship->GetQuantumDrive(); - bool use_farcaster = !qdrive || - !qdrive->IsPowerOn() || - qdrive->Status() < System::DEGRADED; - - if (use_farcaster) { - if (!farcaster) { - ListIter s = self_rgn->Ships(); - while (++s && !farcaster) { - if (s->GetFarcaster()) { - const Ship* dest = s->GetFarcaster()->GetDest(); - if (dest && dest->GetRegion() == rtb_rgn) { - farcaster = s->GetFarcaster(); - } - } - } - } - - if (farcaster) { - Point apt = farcaster->ApproachPoint(0); - Point npt = farcaster->StartPoint(); - double r1 = (ship->Location() - npt).length(); - - if (r1 > 50e3) { - obj_w = apt; - distance = r1; - objective = Transform(obj_w); - } - - else { - double r2 = (ship->Location() - apt).length(); - double r3 = (npt - apt).length(); - - if (r1+r2 < 1.2*r3) { - obj_w = npt; - distance = r1; - objective = Transform(obj_w); - } - else { - obj_w = apt; - distance = r2; - objective = Transform(obj_w); - } - } - - rtb_code = 3; - } - - // can't find a way back home, ignore the RTB order: - else { - ship->ClearRadioOrders(); - rtb_code = 0; - return; - } - } - else if (qdrive) { - if (qdrive->ActiveState() == QuantumDrive::ACTIVE_READY) { - qdrive->SetDestination(rtb_rgn, controller->Location()); - qdrive->Engage(); - } - - rtb_code = 3; - } - } - } - - else { - obj_w = controller->Location(); - - distance = (obj_w - ship->Location()).length(); - - // transform into camera coords: - objective = Transform(obj_w); - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.return-to-base")); - - rtb_code = 1; - } - } -} - -// +--------------------------------------------------------------------+ - -void -FighterAI::FindObjectiveNavPoint() -{ - SimRegion* self_rgn = ship->GetRegion(); - SimRegion* nav_rgn = navpt->Region(); - - if (self_rgn && !nav_rgn) { - nav_rgn = self_rgn; - navpt->SetRegion(nav_rgn); - } - - if (self_rgn && nav_rgn && self_rgn != nav_rgn) { - if (nav_rgn->GetOrbitalRegion()->Primary() == - self_rgn->GetOrbitalRegion()->Primary()) { - - Point npt = nav_rgn->Location() - self_rgn->Location(); - obj_w = npt.OtherHand(); - - // distance from self to navpt: - distance = Point(obj_w - ship->Location()).length(); - - // transform into camera coords: - objective = Transform(obj_w); - - if (nav_rgn->IsAirSpace()) { - drop_state = -1; - } - else if (nav_rgn->IsOrbital()) { - drop_state = 1; - } - - return; - } - - else { - QuantumDrive* q = ship->GetQuantumDrive(); - - if (q) { - if (q->ActiveState() == QuantumDrive::ACTIVE_READY) { - q->SetDestination(navpt->Region(), navpt->Location()); - q->Engage(); - return; - } - } - } - } - - ShipAI::FindObjectiveNavPoint(); -} - -// +--------------------------------------------------------------------+ - -Point -FighterAI::ClosingVelocity() -{ - if (ship) { - WeaponDesign* wep_design = ship->GetPrimaryDesign(); - - if (target && wep_design) { - Point aim_vec = ship->Heading(); - aim_vec.Normalize(); - - Point shot_vel = ship->Velocity() + aim_vec * wep_design->speed; - return shot_vel - target->Velocity(); - } - - else if (target) { - return ship->Velocity() - target->Velocity(); - } - - else { - return ship->Velocity(); - } - } - - return Point(1,0,0); -} - -// +--------------------------------------------------------------------+ - -void -FighterAI::Navigator() -{ - go_manual = false; - - if (takeoff) { - accumulator.Clear(); - magnitude = 0; - brakes = 0; - z_shift = 0; - - Accumulate(SeekTarget()); - HelmControl(); - ThrottleControl(); - ship->ExecFLCSFrame(); - return; - } - - Element* elem = ship->GetElement(); - - if (elem) { - Ship* lead = elem->GetShip(1); - - if (lead && lead != ship) { - if (lead->IsDropping() && !ship->IsDropping()) { - ship->DropOrbit(); - // careful: this object has just been deleted! - return; - } - - if (lead->IsAttaining() && !ship->IsAttaining()) { - ship->MakeOrbit(); - // careful: this object has just been deleted! - return; - } - } - - else { - if (drop_state < 0) { - ship->DropOrbit(); - // careful: this object has just been deleted! - return; - } - - if (drop_state > 0) { - ship->MakeOrbit(); - // careful: this object has just been deleted! - return; - } - } - } - - int order = 0; - - if (navpt) - order = navpt->Action(); - - if (rtb_code == 1 && navpt && navpt->Status() < Instruction::SKIPPED && - !inbound && distance < 35e3) { // (this should be distance to the ship) - - if (order == Instruction::RTB) { - Ship* controller = ship->GetController(); - Hangar* hangar = controller ? controller->GetHangar() : 0; - - if (hangar && hangar->CanStow(ship)) { - for (int i = 0; i < elem->NumShips(); i++) { - Ship* s = elem->GetShip(i+1); - - if (s && s->GetDirector() && s->GetDirector()->Type() >= ShipAI::FIGHTER) - RadioTraffic::SendQuickMessage(s, RadioMessage::CALL_INBOUND); - } - - if (element_index == 1) - ship->SetNavptStatus(navpt, Instruction::COMPLETE); - } - - else { - if (element_index == 1) { - ::Print("WARNING: FighterAI NAVPT RTB, but no controller or hangar found for ship '%s'\n", ship->Name()); - ship->SetNavptStatus(navpt, Instruction::SKIPPED); - } - } - } - - else { - Ship* dock_target = (Ship*) navpt->GetTarget(); - if (dock_target) { - for (int i = 0; i < elem->NumShips(); i++) { - Ship* s = elem->GetShip(i+1); - - if (s) { - RadioMessage* msg = new RadioMessage(dock_target, s, RadioMessage::CALL_INBOUND); - RadioTraffic::Transmit(msg); - } - } - - if (element_index == 1) - ship->SetNavptStatus(navpt, Instruction::COMPLETE); - } - - else { - if (element_index == 1) { - ::Print("WARNING: FighterAI NAVPT DOCK, but no dock target found for ship '%s'\n", ship->Name()); - ship->SetNavptStatus(navpt, Instruction::SKIPPED); - } - } - } - } - - if (target) - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-target")); - - accumulator.Clear(); - magnitude = 0; - brakes = 0; - z_shift = 0; - - hold = false; - if ((ship->GetElement() && ship->GetElement()->GetHoldTime() > 0) || - (navpt && navpt->Status() == Instruction::COMPLETE && navpt->HoldTime() > 0)) - hold = true; - - if (ship->MissionClock() < 10000) { - if (ship->IsAirborne()) - Accumulate(SeekTarget()); - } - - else if ((farcaster && distance < 20e3) || (inbound && inbound->Final())) { - Accumulate(SeekTarget()); - } - - else { - if (!ship->IsAirborne() || ship->AltitudeAGL() > 100) - ship->RaiseGear(); - - Accumulate(AvoidTerrain()); - Steer avoid = AvoidCollision(); - - if (other && inbound && inbound->GetDeck() && inbound->Cleared()) { - if (other != (SimObject*) inbound->GetDeck()->GetCarrier()) - Accumulate(avoid); - } - else { - Accumulate(avoid); - } - - if (!too_close && !hold && !terrain_warning) { - Accumulate(SeekTarget()); - Accumulate(EvadeThreat()); - } - } - - HelmControl(); - ThrottleControl(); - FireControl(); - AdjustDefenses(); - - ship->ExecFLCSFrame(); -} - -// +--------------------------------------------------------------------+ - -void -FighterAI::HelmControl() -{ - Camera* cam = ((Camera*) &(ship->Cam())); - Point vrt = cam->vrt(); - double deflection = vrt.y; - double theta = 0; - bool formation = element_index > 1; - bool station_keeping = distance < 0; - bool inverted = cam->vup().y < -0.5; - Ship* ward = ship->GetWard(); - - if (takeoff || inbound || station_keeping) - formation = false; - - if (takeoff || navpt || farcaster || patrol || inbound || rtb_code || target || ward || threat || formation) { - // are we being asked to flee? - if (fabs(accumulator.yaw) == 1.0 && accumulator.pitch == 0.0) { - accumulator.pitch = -0.7f; - accumulator.yaw *= 0.25f; - - if (ship->IsAirborne() && ship->GetFlightModel() == 0) - accumulator.pitch = -0.45f; - - // low ai -> lower turning rate - accumulator.pitch += 0.1f * (2-ai_level); - } - - ship->ApplyRoll((float) (accumulator.yaw * -0.7)); - ship->ApplyYaw((float) (accumulator.yaw * 0.2)); - - if (fabs(accumulator.yaw) > 0.5 && fabs(accumulator.pitch) < 0.1) - accumulator.pitch -= 0.1f; - - ship->ApplyPitch((float) accumulator.pitch); - } - - else { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.station-keeping")); - station_keeping = true; - - // go into a slow orbit if airborne: - if (ship->IsAirborne() && ship->Class() < Ship::LCA) { - accumulator.brake = 0.2; - accumulator.stop = 0; - - double compass_pitch = ship->CompassPitch(); - double desired_bank = -PI/4; - double current_bank = asin(deflection); - double theta = desired_bank - current_bank; - ship->ApplyRoll(theta); - - double coord_pitch = compass_pitch - 0.2 * fabs(current_bank); - ship->ApplyPitch(coord_pitch); - } - else { - accumulator.brake = 1; - accumulator.stop = 1; - } - } - - // if not turning, roll to orient with world coords: - if (ship->Design()->auto_roll > 0) { - if (fabs(accumulator.pitch) < 0.1 && fabs(accumulator.yaw) < 0.25) { - // zolon spiral behavior: - if (ship->Design()->auto_roll > 1) { - if ((element_index + (ship->MissionClock()>>10)) & 0x4) - ship->ApplyRoll( 0.60); - else - ship->ApplyRoll(-0.35); - } - - // normal behavior - roll to upright: - else if (fabs(deflection) > 0.1 || inverted) { - double theta = asin(deflection/vrt.length()) * 0.5; - ship->ApplyRoll(-theta); - } - } - } - - // if not otherwise occupied, pitch to orient with world coords: - if (station_keeping && (!ship->IsAirborne() || ship->Class() < Ship::LCA)) { - Point heading = ship->Heading(); - double pitch_deflection = heading.y; - - if (fabs(pitch_deflection) > 0.05) { - double rho = asin(pitch_deflection) * 3; - ship->ApplyPitch(rho); - } - } - - ship->SetTransX(0); - ship->SetTransY(0); - ship->SetTransZ(z_shift * ship->Design()->trans_z); - ship->SetFLCSMode(go_manual ? Ship::FLCS_MANUAL : Ship::FLCS_AUTO); -} - -void -FighterAI::ThrottleControl() -{ - Element* elem = ship->GetElement(); - double ship_speed = ship->Velocity() * ship->Heading(); - double desired = 1000; - bool formation = element_index > 1; - bool station_keeping = distance < 0; - bool augmenter = false; - Ship* ward = ship->GetWard(); - - if (inbound || station_keeping) - formation = false; - - // LAUNCH / TAKEOFF - if (ship->MissionClock() < 10000) { - formation = false; - throttle = 100; - brakes = 0; - } - - // STATION KEEPING - else if (station_keeping) { - // go into a slow orbit if airborne: - if (ship->IsAirborne() && ship->Class() < Ship::LCA) { - throttle = 30; - brakes = 0; - } - else { - throttle = 0; - brakes = 1; - } - } - - // TRY TO STAY AIRBORNE, YES? - else if (ship->IsAirborne() && ship_speed < 250 && ship->Class() < Ship::LCA) { - throttle = 100; - brakes = 0; - - if (ship_speed < 200) - augmenter = true; - } - - // INBOUND - else if (inbound) { - double carrier_speed = inbound->GetDeck()->GetCarrier()->Velocity().length(); - desired = 250 + carrier_speed; - - if (distance > 25.0e3) - desired = 750 + carrier_speed; - - else if (ship->IsAirborne()) - desired = 300; - - else if (inbound->Final()) - desired = 75 + carrier_speed; - - throttle = 0; - - // holding short? - if (inbound->Approach() == 0 && !inbound->Cleared() && - distance < 2000 && !ship->IsAirborne()) - desired = 0; - - if (ship_speed > desired+5) - brakes = 0.25; - - else if (ship->IsAirborne() || Ship::GetFlightModel() > 0) { - throttle = old_throttle + 1; - } - - else if (ship_speed < 0.85 * desired) { - throttle = 100; - - if (ship_speed < 0 && ship->GetFuelLevel() > 10) - augmenter = true; - } - - else if (ship_speed < desired-5) { - throttle = 30; - } - } - - else if (rtb_code || farcaster) { - desired = 750; - - if (threat || threat_missile) { - throttle = 100; - - if (!threat_missile && ship->GetFuelLevel() > 15) - augmenter = true; - } - - else { - throttle = 0; - - if (ship_speed > desired+5) - brakes = 0.25; - - else if (Ship::GetFlightModel() > 0) { - throttle = old_throttle + 1; - } - - else if (ship_speed < 0.85 * desired) { - throttle = 100; - - if (ship_speed < 0 && ship->GetFuelLevel() > 10) - augmenter = true; - } - - else if (ship_speed < desired-5) { - throttle = 30; - } - } - } - - // RUN AWAY!!! - else if (evading) { - throttle = 100; - - if (!threat_missile && ship->GetFuelLevel() > 15) - augmenter = true; - } - - // PATROL AND FORMATION - else if (!navpt && !target && !ward) { - if (!elem || !formation) { // element lead - if (patrol) { - desired = 250; - - if (distance > 10e3) - desired = 750; - - if (ship_speed > desired+5) { - brakes = 0.25; - throttle = old_throttle - 5; - } - - else if (ship_speed < 0.85 * desired) { - throttle = 100; - - if (ship_speed < 0 && ship->GetFuelLevel() > 10) - augmenter = true; - } - - else if (ship_speed < desired-5) - throttle = old_throttle + 5; - } - - else { - throttle = 35; - - if (threat) - throttle = 100; - - brakes = accumulator.brake; - - if (brakes > 0.1) - throttle = 0; - } - } - - else { // wingman - Ship* lead = elem->GetShip(1); - double zone = ship->Radius() * 3; - - if (lead) - desired = lead->Velocity() * lead->Heading(); - - if (fabs(slot_dist) < distance/4) // try to prevent porpoising - throttle = old_throttle; - - else if (slot_dist > zone*2) { - throttle = 100; - - if (objective.z > 10e3 && ship_speed < desired && ship->GetFuelLevel() > 25) - augmenter = true; - } - - else if (slot_dist > zone) - throttle = lead->Throttle() + 10; - - else if (slot_dist < -zone*2) { - throttle = old_throttle - 10; - brakes = 1; - } - - else if (slot_dist < -zone) { - throttle = old_throttle; - brakes = 0.5; - } - - else if (lead) { - double lv = lead->Velocity().length(); - double sv = ship_speed; - double dv = lv-sv; - double dt = 0; - - if (dv > 0) dt = dv * 1e-5 * frame_time; - else if (dv < 0) dt = dv * 1e-2 * frame_time; - - throttle = old_throttle + dt; - } - - else { - throttle = old_throttle; - } - } - } - - // TARGET/WARD/NAVPOINT SEEKING - else { - throttle = old_throttle; - - if (target) { - desired = 1250; - - if (ai_level < 1) { - throttle = 70; - } - - else if (ship->IsAirborne()) { - throttle = 100; - - if (!threat_missile && fabs(objective.z) > 6e3 && ship->GetFuelLevel() > 25) - augmenter = true; - } - - else { - throttle = 100; - - if (objective.z > 20e3 && ship_speed < desired && ship->GetFuelLevel() > 35) - augmenter = true; - - else if (objective.z > 0 && objective.z < 10e3) - throttle = 50; - } - } - - else if (ward) { - double d = (ship->Location() - ward->Location()).length(); - - if (d > 5000) { - if (ai_level < 1) - throttle = 50; - else - throttle = 80; - } - else { - double speed = ward->Velocity().length(); - - if (speed > 0) { - if (ship_speed > speed) { - throttle = old_throttle - 5; - brakes = 0.25; - } - else if (ship_speed < speed - 10) { - throttle = old_throttle + 1; - } - } - } - } - - else if (navpt) { - desired = navpt->Speed(); - - if (hold) { - // go into a slow orbit if airborne: - if (ship->IsAirborne() && ship->Class() < Ship::LCA) { - throttle = 25; - brakes = 0; - } - else { - throttle = 0; - brakes = 1; - } - } - - else if (desired > 0) { - if (ship_speed > desired) { - throttle = old_throttle - 5; - brakes = 0.25; - } - - else if (ship_speed < 0.85 * desired) { - throttle = 100; - - if ((ship->IsAirborne() || ship_speed < 0.35 * desired) && ship->GetFuelLevel() > 30) - augmenter = true; - } - - else if (ship_speed < desired - 10) { - throttle = old_throttle + 1; - } - - else if (Ship::GetFlightModel() > 0) { - throttle = old_throttle; - } - } - } - - else { - throttle = 0; - brakes = 1; - } - } - - if (ship->IsAirborne() && throttle < 20 && ship->Class() < Ship::LCA) - throttle = 20; - else if (ship->Design()->auto_roll > 1 && throttle < 5) - throttle = 5; - else if (throttle < 0) - throttle = 0; - - old_throttle = throttle; - ship->SetThrottle((int) throttle); - ship->SetAugmenter(augmenter); - - if (accumulator.stop && ship->GetFLCS() != 0) - ship->GetFLCS()->FullStop(); - - else if (ship_speed > 1 && brakes > 0) - ship->SetTransY(-brakes * ship->Design()->trans_y); - - else if (throttle > 10 && (ship->GetEMCON() < 2 || ship->GetFuelLevel() < 10)) - ship->SetTransY(ship->Design()->trans_y); -} - -// +--------------------------------------------------------------------+ - -Steer -FighterAI::AvoidTerrain() -{ - Steer avoid; - - terrain_warning = false; - - if (!ship || !ship->GetRegion() || !ship->GetRegion()->IsActive() || - (navpt && navpt->Action() == Instruction::LAUNCH)) - return avoid; - - if (ship->IsAirborne() && ship->GetFlightPhase() == Ship::ACTIVE) { - // too high? - if (ship->AltitudeMSL() > 25e3) { - if (!navpt || (navpt->Region() == ship->GetRegion() && navpt->Location().z < 27e3)) { - terrain_warning = true; - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.too-high")); - - // where will we be? - Point selfpt = ship->Location() + ship->Velocity() + Point(0, -15e3, 0); - - // transform into camera coords: - Point obj = Transform(selfpt); - - // head down! - avoid = Seek(obj); - } - } - - // too low? - else if (ship->AltitudeAGL() < 2500) { - terrain_warning = true; - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.too-low")); - - // way too low? - if (ship->AltitudeAGL() < 1500) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.way-too-low")); - target = 0; - drop_time = 5; - } - - // where will we be? - Point selfpt = ship->Location() + ship->Velocity() + Point(0, 10e3, 0); - - // transform into camera coords: - Point obj = Transform(selfpt); - - // pull up! - avoid = Seek(obj); - } - } - - return avoid; -} - -// +--------------------------------------------------------------------+ - -Steer -FighterAI::SeekTarget() -{ - if (ship->GetFlightPhase() < Ship::ACTIVE) - return Seek(objective); - - Ship* ward = ship->GetWard(); - - if ((!target && !ward && !navpt && !farcaster && !patrol && !inbound && !rtb_code) || ship->MissionClock() < 10000) { - if (element_index > 1) { - // break formation if threatened: - if (threat_missile) - return Steer(); - - else if (threat && !form_up) - return Steer(); - - // otherwise, keep in formation: - return SeekFormationSlot(); - } - else { - return Steer(); - } - } - - if (patrol) { - Steer result = Seek(objective); - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-patrol-point")); - - if (distance < 10 * self->Radius()) { - patrol = 0; - result.brake = 1; - result.stop = 1; - } - - return result; - } - - if (inbound) { - Steer result = Seek(objective); - - if (over_threshold && objective.z < 0) { - result = Steer(); - result.brake = 1; - result.stop = 1; - } - else { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-inbound")); - - // approach legs: - if (inbound->Approach() > 0) { - if (distance < 20 * self->Radius()) - inbound->SetApproach(inbound->Approach() - 1); - } - - // marshall point and finals: - else { - if (inbound->Cleared() && distance < 10 * self->Radius()) { - if (!inbound->Final()) { - time_to_dock = TIME_TO_DOCK; - - FlightDeck* deck = inbound->GetDeck(); - if (deck) { - double total_dist = Point(deck->EndPoint() - deck->StartPoint()).length(); - double current_dist = Point(deck->EndPoint() - ship->Location()).length(); - - time_to_dock *= (current_dist / total_dist); - } - - RadioTraffic::SendQuickMessage(ship, RadioMessage::CALL_FINALS); - } - - inbound->SetFinal(true); - ship->LowerGear(); - result.brake = 1; - result.stop = 1; - } - - else if (!inbound->Cleared() && distance < 2000) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.hold-final")); - result = Steer(); - result.brake = 1; - result.stop = 1; - } - } - } - - return result; - } - - else if (rtb_code) { - return Seek(objective); - } - - SimObject* tgt = target; - - if (ward && !tgt) - tgt = ward; - - if (tgt && too_close == tgt->Identity()) { - drop_time = 4; - return Steer(); - } - - else if (navpt && navpt->Action() == Instruction::LAUNCH) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.launch")); - return Seek(objective); - } - - else if (farcaster) { - // wingmen should - if (element_index > 1) - return SeekFormationSlot(); - - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-farcaster")); - return Seek(objective); - } - - else if (drop_time > 0) { - return Steer(); - } - - if (tgt) { - double basis = self->Radius() + tgt->Radius(); - double gap = distance - basis; - - // target behind: - if (objective.z < 0) { - // leave some room for an attack run: - if (gap < 8000) { - Steer s; - - s.pitch = -0.1; - if (objective.x > 0) s.yaw = 0.1; - else s.yaw = -0.1; - - return s; - } - - // start the attack run: - else { - return Seek(objective); - } - } - - // target in front: - else { - if (tgt->Type() == SimObject::SIM_SHIP) { - Ship* tgt_ship = (Ship*) tgt; - - // capital target strike: - if (tgt_ship->IsStatic()) { - if (gap < 2500) - return Flee(objective); - } - - else if (tgt_ship->IsStarship()) { - if (gap < 1000) - return Flee(objective); - - else if (ship->GetFlightModel() == Ship::FM_STANDARD && gap < 20e3) - go_manual = true; - } - } - - // fighter melee: - if (tgt->Velocity() * ship->Velocity() < 0) { - // head-to-head pass: - if (gap < 1250) - return Flee(objective); - } - - else if (gap < 250) { - return Steer(); - } - - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-target")); - return Seek(objective); - } - } - - if (navpt) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-navpt")); - } - - return Seek(objective); -} - -// +--------------------------------------------------------------------+ - -Steer -FighterAI::SeekFormationSlot() -{ - Steer s; - - // advance memory pipeline: - az[2] = az[1]; az[1] = az[0]; - el[2] = el[1]; el[1] = el[0]; - - Element* elem = ship->GetElement(); - Ship* lead = elem->GetShip(1); - - if (lead) { - SimRegion* self_rgn = ship->GetRegion(); - SimRegion* lead_rgn = lead->GetRegion(); - - if (self_rgn != lead_rgn) { - QuantumDrive* qdrive = ship->GetQuantumDrive(); - bool use_farcaster = !qdrive || - !qdrive->IsPowerOn() || - qdrive->Status() < System::DEGRADED; - - if (use_farcaster) { - FindObjectiveFarcaster(self_rgn, lead_rgn); - } - - else if (qdrive) { - if (qdrive->ActiveState() == QuantumDrive::ACTIVE_READY) { - qdrive->SetDestination(lead_rgn, lead->Location()); - qdrive->Engage(); - } - } - } - } - - // do station keeping? - if (distance < ship->Radius() * 10 && lead->Velocity().length() < 50) { - distance = -1; - return s; - } - - // approach - if (objective.z > ship->Radius() * -4) { - az[0] = atan2(fabs(objective.x), objective.z) * 50; - el[0] = atan2(fabs(objective.y), objective.z) * 50; - - if (objective.x < 0) az[0] = -az[0]; - if (objective.y > 0) el[0] = -el[0]; - - s.yaw = az[0] - seek_damp * (az[1] + az[2] * 0.5); - s.pitch = el[0] - seek_damp * (el[1] + el[2] * 0.5); - } - - // reverse - else { - if (objective.x > 0) s.yaw = 1.0f; - else s.yaw = -1.0f; - - s.pitch = -objective.y * 0.5f; - } - - seeking = 1; - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-formation")); - - return s; -} - -// +--------------------------------------------------------------------+ - -Steer -FighterAI::Seek(const Point& point) -{ - Steer s; - - // advance memory pipeline: - az[2] = az[1]; az[1] = az[0]; - el[2] = el[1]; el[1] = el[0]; - - // approach - if (point.z > 0.0f) { - az[0] = atan2(fabs(point.x), point.z) * seek_gain; - el[0] = atan2(fabs(point.y), point.z) * seek_gain; - - if (point.x < 0) az[0] = -az[0]; - if (point.y > 0) el[0] = -el[0]; - - s.yaw = az[0] - seek_damp * (az[1] + az[2] * 0.5); - s.pitch = el[0] - seek_damp * (el[1] + el[2] * 0.5); - - // pull up: - if (ship->IsAirborne() && point.y > 5e3) - s.pitch = -1.0f; - } - - // reverse - else { - if (ship->IsAirborne()) { - // pull up: - if (point.y > 5e3) { - s.pitch = -1.0f; - } - - // head down: - else if (point.y < -5e3) { - s.pitch = 1.0f; - } - - // level turn: - else { - if (point.x > 0) s.yaw = 1.0f; - else s.yaw = -1.0f; - - s.brake = 0.5f; - } - } - - else { - if (point.x > 0) s.yaw = 1.0f; - else s.yaw = -1.0f; - } - } - - seeking = 1; - - return s; -} - -// +--------------------------------------------------------------------+ - -Steer -FighterAI::EvadeThreat() -{ - // MISSILE THREAT REACTION: - if (threat_missile) { - evading = true; - SetTarget(0); - drop_time = 3 * (3-ai_level); - - // dropped a decoy for this missile yet? - if (decoy_missile != threat_missile) { - ship->FireDecoy(); - decoy_missile = threat_missile; - } - - // beam the missile - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.evade-missile")); - - Point beam_line = threat_missile->Velocity().cross(Point(0,1,0)); - beam_line.Normalize(); - beam_line *= 1e6; - - Point evade_p; - Point evade_w1 = threat_missile->Location() + beam_line; - Point evade_w2 = threat_missile->Location() - beam_line; - - double d1 = Point(evade_w1 - ship->Location()).length(); - double d2 = Point(evade_w2 - ship->Location()).length(); - - if (d1 > d2) - evade_p = Transform(evade_w1); - else - evade_p = Transform(evade_w2); - - return Seek(evade_p); - } - - // GENERAL THREAT EVASION: - if (threat && !form_up) { - double threat_range = 20e3; - - Ship* threat_ship = (Ship*) threat; - double threat_dist = Point(threat->Location() - ship->Location()).length(); - - if (threat_ship->IsStarship()) { - threat_range = CalcDefensePerimeter(threat_ship); - } - - if (threat_dist <= threat_range) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.evade-threat")); - - if (ship->IsAirborne()) { - evading = true; - Point beam_line = threat->Velocity().cross(Point(0,1,0)); - beam_line.Normalize(); - beam_line *= threat_range; - - Point evade_w = threat->Location() + beam_line; - Point evade_p = Transform(evade_w); - - return Seek(evade_p); - } - - else if (threat_ship->IsStarship()) { - evading = true; - - if (target == threat_ship && threat_dist < threat_range / 4) { - SetTarget(0); - drop_time = 5; - } - - if (!target) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.evade-starship")); - - // flee for three seconds: - if ((ship->MissionClock() & 3) != 3) { - return Flee(Transform(threat->Location())); - } - - // jink for one second: - else { - if (Clock::GetInstance()->GameTime() - jink_time > 1500) { - jink_time = Clock::GetInstance()->GameTime(); - jink = Point(rand() - 16384, - rand() - 16384, - rand() - 16384) * 15e3; - } - - Point evade_w = ship->Location() + jink; - Point evade_p = Transform(evade_w); - - return Seek(evade_p); - } - } - - else { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.evade-and-seek")); - - // seek for three seconds: - if ((ship->MissionClock() & 3) < 3) { - return Steer(); // no evasion - } - - // jink for one second: - else { - if (Clock::GetInstance()->GameTime() - jink_time > 1000) { - jink_time = Clock::GetInstance()->GameTime(); - jink = Point(rand() - 16384, - rand() - 16384, - rand() - 16384); - } - - Point evade_w = target->Location() + jink; - Point evade_p = Transform(evade_w); - - return Seek(evade_p); - } - } - } - - else { - evading = true; - - if (target != nullptr) { - if (target == threat) { - if (target->Type() == SimObject::SIM_SHIP) { - Ship* tgt_ship = (Ship*) target; - if (tgt_ship->GetTrigger(0)) { - SetTarget(0); - drop_time = 3; - } - } - } - - else if (target && threat_dist < threat_range / 2) { - SetTarget(0); - drop_time = 3; - } - } - - if (target) - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.evade-and-seek")); - else - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.random-evade")); - - // beam the threat - Point beam_line = threat->Velocity().cross(Point(0,1,0)); - beam_line.Normalize(); - beam_line *= 1e6; - - Point evade_p; - Point evade_w1 = threat->Location() + beam_line; - Point evade_w2 = threat->Location() - beam_line; - - double d1 = Point(evade_w1 - ship->Location()).length(); - double d2 = Point(evade_w2 - ship->Location()).length(); - - if (d1 > d2) - evade_p = Transform(evade_w1); - else - evade_p = Transform(evade_w2); - - if (!target) { - DWORD jink_rate = 400 + 200 * (3-ai_level); - - if (Clock::GetInstance()->GameTime() - jink_time > jink_rate) { - jink_time = Clock::GetInstance()->GameTime(); - jink = Point(rand() - 16384, - rand() - 16384, - rand() - 16384) * 2000; - } - - evade_p += jink; - } - - Steer steer = Seek(evade_p); - - if (target) - return steer / 4; - - return steer; - } - } - } - - return Steer(); -} - -// +--------------------------------------------------------------------+ - -void -FighterAI::FireControl() -{ - // if nothing to shoot at, forget it: - if (!target || target->Integrity() < 1) - return; - - // if the objective is a navpt or landing bay (not a target), then don't shoot! - if (inbound || farcaster || navpt && navpt->Action() < Instruction::DEFEND) - return; - - // object behind us, or too close: - if (objective.z < 0 || distance < 4 * self->Radius()) - return; - - // compute the firing cone: - double cross_section = 2 * target->Radius() / distance; - double gun_basket = cross_section * 2; - - Weapon* primary = ship->GetPrimary(); - Weapon* secondary = ship->GetSecondary(); - const WeaponDesign* dsgn_primary = 0; - const WeaponDesign* dsgn_secondary = 0; - bool use_primary = true; - Ship* tgt_ship = 0; - - if (target->Type() == SimObject::SIM_SHIP) { - tgt_ship = (Ship*) target; - - if (tgt_ship->InTransition()) - return; - } - - if (primary) { - dsgn_primary = primary->Design(); - - if (dsgn_primary->aim_az_max > 5*DEGREES && distance > dsgn_primary->max_range/2) - gun_basket = cross_section * 4; - - gun_basket *= (3-ai_level); - - if (tgt_ship) { - if (!primary->CanTarget(tgt_ship->Class())) - use_primary = false; - - /*** XXX NEED TO SUBTARGET SYSTEMS IF TARGET IS STARSHIP... - else if (tgt_ship->ShieldStrength() > 10) - use_primary = false; - ***/ - } - - if (use_primary) { - // is target in the basket? - double dx = fabs(objective.x / distance); - double dy = fabs(objective.y / distance); - - if (primary->GetFiringOrders() == Weapon::MANUAL && - dx < gun_basket && dy < gun_basket && - distance > dsgn_primary->min_range && - distance < dsgn_primary->max_range && - !primary->IsBlockedFriendly()) - { - ship->FirePrimary(); - } - } - } - - if (secondary && secondary->GetFiringOrders() == Weapon::MANUAL) { - dsgn_secondary = secondary->Design(); - - if (missile_time <= 0 && secondary->Ammo() && !secondary->IsBlockedFriendly()) { - if (secondary->Locked() || !dsgn_secondary->self_aiming) { - // is target in basket? - Point tgt = AimTransform(target->Location()); - double tgt_range = tgt.Normalize(); - - int factor = 2-ai_level; - double s_range = 0.5 + 0.2 * factor; - double s_basket = 0.3 + 0.2 * factor; - double extra_time = 10 * factor * factor + 5; - - if (!dsgn_secondary->self_aiming) - s_basket *= 0.33; - - if (tgt_ship) { - if (tgt_ship->Class() == Ship::MINE) { - extra_time = 10; - s_range = 0.75; - } - - else if (!tgt_ship->IsDropship()) { - extra_time = 0.5 * factor + 0.5; - s_range = 0.9; - } - } - - // is target in decent range? - if (tgt_range < secondary->Design()->max_range * s_range) { - double dx = fabs(tgt.x); - double dy = fabs(tgt.y); - - if (dx < s_basket && dy < s_basket && tgt.z > 0) { - if (ship->FireSecondary()) { - missile_time = secondary->Design()->salvo_delay + extra_time; - - if (Clock::GetInstance()->GameTime() - last_call_time > 6000) { - // call fox: - int call = RadioMessage::FOX_3; // A2A - - if (secondary->CanTarget(Ship::GROUND_UNITS)) // AGM - call = RadioMessage::FOX_1; - - else if (secondary->CanTarget(Ship::DESTROYER)) // ASM - call = RadioMessage::FOX_2; - - RadioTraffic::SendQuickMessage(ship, call); - last_call_time = Clock::GetInstance()->GameTime(); - } - } - } - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -double -FighterAI::CalcDefensePerimeter(Ship* starship) -{ - double perimeter = 15e3; - - if (starship) { - ListIter g_iter = starship->Weapons(); - while (++g_iter) { - WeaponGroup* group = g_iter.value(); - - ListIter w_iter = group->GetWeapons(); - while (++w_iter) { - Weapon* weapon = w_iter.value(); - - if (weapon->Ammo() && - weapon->GetTarget() == ship && - !weapon->IsBlockedFriendly()) { - - double range = weapon->Design()->max_range * 1.2; - if (range > perimeter) - perimeter = range; - } - } - } - } - - return perimeter; -} - - - diff --git a/Stars45/FighterAI.h b/Stars45/FighterAI.h deleted file mode 100644 index 37da3cf..0000000 --- a/Stars45/FighterAI.h +++ /dev/null @@ -1,84 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Fighter (low-level) Artifical Intelligence class -*/ - -#ifndef FighterAI_h -#define FighterAI_h - -#include "Types.h" -#include "ShipAI.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class Shot; -class InboundSlot; - -// +--------------------------------------------------------------------+ - -class FighterAI : public ShipAI -{ -public: - FighterAI(SimObject* s); - virtual ~FighterAI(); - - virtual void ExecFrame(double seconds); - virtual int Subframe() const { return true; } - - // convert the goal point from world to local coords: - virtual void FindObjective(); - virtual void FindObjectiveNavPoint(); - -protected: - // behaviors: - virtual Steer AvoidTerrain(); - virtual Steer SeekTarget(); - virtual Steer EvadeThreat(); - virtual Point ClosingVelocity(); - - // accumulate behaviors: - virtual void Navigator(); - - // steering functions: - virtual Steer Seek(const Point& point); - virtual Steer SeekFormationSlot(); - - // fire on target if appropriate: - virtual void FireControl(); - virtual void HelmControl(); - virtual void ThrottleControl(); - - virtual double CalcDefensePerimeter(Ship* starship); - virtual void ReturnToBase(Ship* controller); - - Shot* decoy_missile; - double missile_time; - int terrain_warning; - int drop_state; - char dir_info[32]; - double brakes; - double z_shift; - double time_to_dock; - InboundSlot* inbound; - int rtb_code; - bool evading; - DWORD jink_time; - Point jink; - bool over_threshold; - bool form_up; - bool go_manual; -}; - -// +--------------------------------------------------------------------+ - -#endif // FighterAI_h - diff --git a/Stars45/FighterTacticalAI.cpp b/Stars45/FighterTacticalAI.cpp deleted file mode 100644 index 433b3a9..0000000 --- a/Stars45/FighterTacticalAI.cpp +++ /dev/null @@ -1,561 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Fighter-specific mid-level (tactical) AI class -*/ - -#include "FighterTacticalAI.h" -#include "ShipAI.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Shot.h" -#include "Element.h" -#include "Instruction.h" -#include "RadioMessage.h" -#include "Sensor.h" -#include "Contact.h" -#include "WeaponGroup.h" -#include "Drive.h" -#include "Sim.h" -#include "StarSystem.h" - -#include "Clock.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ - -const int WINCHESTER_FIGHTER = 0; -const int WINCHESTER_ASSAULT = 1; -const int WINCHESTER_STRIKE = 2; -const int WINCHESTER_STATIC = 3; - -// +----------------------------------------------------------------------+ - -FighterTacticalAI::FighterTacticalAI(ShipAI* ai) -: TacticalAI(ai), secondary_selection_time(0) -{ - for (int i = 0; i < 4; i++) - winchester[i] = false; - - ai_level = ai->GetAILevel(); - - switch (ai_level) { - default: - case 2: THREAT_REACTION_TIME = 1000; break; - case 1: THREAT_REACTION_TIME = 3000; break; - case 0: THREAT_REACTION_TIME = 6000; break; - } -} - - -// +--------------------------------------------------------------------+ - -FighterTacticalAI::~FighterTacticalAI() -{ } - -// +--------------------------------------------------------------------+ - -bool -FighterTacticalAI::CheckFlightPlan() -{ - navpt = ship->GetNextNavPoint(); - - int order = Instruction::PATROL; - roe = FLEXIBLE; - - if (navpt) { - order = navpt->Action(); - - switch (order) { - case Instruction::LAUNCH: - case Instruction::DOCK: - case Instruction::RTB: roe = NONE; - break; - - case Instruction::VECTOR: - roe = SELF_DEFENSIVE; - if (element_index > 1) - roe = DEFENSIVE; - break; - - case Instruction::DEFEND: - case Instruction::ESCORT: roe = DEFENSIVE; - break; - - case Instruction::INTERCEPT: - if (element_index > 1) - roe = DEFENSIVE; - else - roe = DIRECTED; - break; - - case Instruction::RECON: - case Instruction::STRIKE: - case Instruction::ASSAULT: roe = DIRECTED; - break; - - case Instruction::PATROL: - case Instruction::SWEEP: roe = FLEXIBLE; - break; - - default: break; - } - - if (order == Instruction::STRIKE) { - ship->SetSensorMode(Sensor::GM); - - if (IsStrikeComplete(navpt)) { - ship->SetNavptStatus(navpt, Instruction::COMPLETE); - } - } - - else if (order == Instruction::ASSAULT) { - if (ship->GetSensorMode() == Sensor::GM) - ship->SetSensorMode(Sensor::STD); - - if (IsStrikeComplete(navpt)) { - ship->SetNavptStatus(navpt, Instruction::COMPLETE); - } - } - - else { - if (ship->GetSensorMode() == Sensor::GM) - ship->SetSensorMode(Sensor::STD); - } - } - - switch (roe) { - case NONE: ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.none")); break; - case SELF_DEFENSIVE: ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.self-defensive")); break; - case DEFENSIVE: ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.defensive")); break; - case DIRECTED: ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.directed")); break; - case FLEXIBLE: ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.flexible")); break; - default: ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.default")); break; - } - - return (navpt != 0); -} - -// +--------------------------------------------------------------------+ - -void -FighterTacticalAI::SelectTarget() -{ - TacticalAI::SelectTarget(); - - SimObject* target = ship_ai->GetTarget(); - - if (target && (target->Type() == SimObject::SIM_SHIP) && - (Clock::GetInstance()->GameTime() - secondary_selection_time) > THREAT_REACTION_TIME) { - SelectSecondaryForTarget((Ship*) target); - secondary_selection_time = Clock::GetInstance()->GameTime(); - } -} - -// +--------------------------------------------------------------------+ - -void -FighterTacticalAI::SelectTargetDirected(Ship* tgt) -{ - Ship* potential_target = tgt; - - if (!tgt) { - // try to target one of the element's objectives - // (if it shows up in the contact list) - - Element* elem = ship->GetElement(); - - if (elem) { - Instruction* objective = elem->GetTargetObjective(); - - if (objective) { - SimObject* obj_sim_obj = objective->GetTarget(); - Ship* obj_tgt = 0; - - if (obj_sim_obj && obj_sim_obj->Type() == SimObject::SIM_SHIP) - obj_tgt = (Ship*) obj_sim_obj; - - if (obj_tgt && ship->FindContact(obj_tgt)) - potential_target = obj_tgt; - } - } - } - - if (!CanTarget(potential_target)) - potential_target = 0; - - ship_ai->SetTarget(potential_target); - SelectSecondaryForTarget(potential_target); -} - -// +--------------------------------------------------------------------+ - -void -FighterTacticalAI::SelectTargetOpportunity() -{ - // NON-COMBATANTS do not pick targets of opportunity: - if (ship->GetIFF() == 0) - return; - - Ship* potential_target = 0; - Shot* current_shot_target = 0; - - // pick the closest combatant ship with a different IFF code: - double target_dist = 1.0e15; - double min_dist = 5.0e3; - - // FIGHTERS are primarily anti-air platforms, but may - // also attack smaller starships: - - Ship* ward = 0; - if (element_index > 1) - ward = ship->GetLeader(); - - // commit range for patrol/sweep is 80 Km - // (about 2 minutes for a fighter at max speed) - if (roe == FLEXIBLE || roe == AGRESSIVE) - target_dist = ship->Design()->commit_range; - - if (roe < FLEXIBLE) - target_dist = 0.5 * ship->Design()->commit_range; - - int class_limit = Ship::LCA; - - if (ship->Class() == Ship::ATTACK) - class_limit = Ship::DESTROYER; - - ListIter c_iter = ship->ContactList(); - while (++c_iter) { - Contact* contact = c_iter.value(); - Ship* c_ship = contact->GetShip(); - Shot* c_shot = contact->GetShot(); - int c_iff = contact->GetIFF(ship); - bool rogue = false; - - if (c_ship) - rogue = c_ship->IsRogue(); - - if (!rogue && (c_iff <= 0 || c_iff == ship->GetIFF() || c_iff == 1000)) - continue; - - // reasonable target? - if (c_ship && c_ship->Class() <= class_limit && !c_ship->InTransition()) { - if (!rogue) { - SimObject* ttgt = c_ship->GetTarget(); - - // if we are self-defensive, is this contact engaging us? - if (roe == SELF_DEFENSIVE && ttgt != ship) - continue; - - // if we are defending, is this contact engaging us or our ward? - if (roe == DEFENSIVE && ttgt != ship && ttgt != ward) - continue; - } - - // found an enemy, check distance: - double dist = (ship->Location() - c_ship->Location()).length(); - - if (dist < 0.75 * target_dist) { - - // if on patrol, check target distance from navpoint: - if (roe == FLEXIBLE && navpt) { - double ndist = (navpt->Location().OtherHand() - c_ship->Location()).length(); - if (ndist > 80e3) - continue; - } - - potential_target = c_ship; - target_dist = dist; - } - } - - else if (c_shot && c_shot->IsDrone()) { - // found an enemy shot, do we have enough time to engage? - if (c_shot->GetEta() < 10) - continue; - - // found an enemy shot, check distance: - double dist = (ship->Location() - c_shot->Location()).length(); - - if (!current_shot_target) { - current_shot_target = c_shot; - target_dist = dist; - } - - // is this shot a better target than the one we've found? - else { - Ship* ward = ship_ai->GetWard(); - - if ((c_shot->IsTracking(ward) && !current_shot_target->IsTracking(ward)) || - (dist < target_dist)) { - current_shot_target = c_shot; - target_dist = dist; - } - } - } - } - - if (current_shot_target) { - ship_ai->SetTarget(current_shot_target); - } - else { - ship_ai->SetTarget(potential_target); - SelectSecondaryForTarget(potential_target); - } -} - -// +--------------------------------------------------------------------+ - -int -FighterTacticalAI::ListSecondariesForTarget(Ship* tgt, List& weps) -{ - weps.clear(); - - if (tgt) { - ListIter iter = ship->Weapons(); - while (++iter) { - WeaponGroup* w = iter.value(); - - if (w->Ammo() && w->CanTarget(tgt->Class())) - weps.append(w); - } - } - - return weps.size(); -} - -void -FighterTacticalAI::SelectSecondaryForTarget(Ship* tgt) -{ - if (tgt) { - int wix = WINCHESTER_FIGHTER; - - if (tgt->IsGroundUnit()) wix = WINCHESTER_STRIKE; - else if (tgt->IsStatic()) wix = WINCHESTER_STATIC; - else if (tgt->IsStarship()) wix = WINCHESTER_ASSAULT; - - WeaponGroup* best = 0; - List weps; - - if (ListSecondariesForTarget(tgt, weps)) { - winchester[wix] = false; - - // select best weapon for the job: - double range = (ship->Location() - tgt->Location()).length(); - double best_range = 0; - double best_damage = 0; - - ListIter iter = weps; - while (++iter) { - WeaponGroup* w = iter.value(); - - if (!best) { - best = w; - - WeaponDesign* d = best->GetDesign(); - best_range = d->max_range; - best_damage = d->damage * d->ripple_count; - - if (best_range < range) - best = 0; - } - - else { - WeaponDesign* d = w->GetDesign(); - double w_range = d->max_range; - double w_damage = d->damage * d->ripple_count; - - if (w_range > range) { - if (w_range < best_range || w_damage > best_damage) - best = w; - } - } - } - - // now cycle weapons until you pick the best one: - WeaponGroup* current_missile = ship->GetSecondaryGroup(); - - if (current_missile && best && current_missile != best) { - ship->CycleSecondary(); - WeaponGroup* m = ship->GetSecondaryGroup(); - - while (m != current_missile && m != best) { - ship->CycleSecondary(); - m = ship->GetSecondaryGroup(); - } - } - } - - else { - winchester[wix] = true; - - // if we have NO weapons that can hit this target, - // just drop it: - - Weapon* primary = ship->GetPrimary(); - if (!primary || !primary->CanTarget(tgt->Class())) { - ship_ai->DropTarget(3); - ship->DropTarget(); - } - } - - if (tgt->IsGroundUnit()) - ship->SetSensorMode(Sensor::GM); - - else if (ship->GetSensorMode() == Sensor::GM) - ship->SetSensorMode(Sensor::STD); - } -} - -// +--------------------------------------------------------------------+ - -void -FighterTacticalAI::FindFormationSlot(int formation) -{ - // find the formation delta: - int s = element_index - 1; - Point delta(5*s, 0, -5*s); - - // diamond: - if (formation == Instruction::DIAMOND) { - switch (element_index) { - case 2: delta = Point( 12, -1, -10); break; - case 3: delta = Point(-12, -1, -10); break; - case 4: delta = Point( 0, -2, -20); break; - } - } - - // spread: - if (formation == Instruction::SPREAD) { - switch (element_index) { - case 2: delta = Point( 15, 0, 0); break; - case 3: delta = Point(-15, 0, 0); break; - case 4: delta = Point(-30, 0, 0); break; - } - } - - // box: - if (formation == Instruction::BOX) { - switch (element_index) { - case 2: delta = Point(15, 0, 0); break; - case 3: delta = Point( 0, -2, -20); break; - case 4: delta = Point(15, -2, -20); break; - } - } - - // trail: - if (formation == Instruction::TRAIL) { - delta = Point(0, s, -20*s); - } - - ship_ai->SetFormationDelta(delta * ship->Radius() * 2); -} - -// +--------------------------------------------------------------------+ - -void -FighterTacticalAI::FindThreat() -{ - // pick the closest contact on Threat Warning System: - Ship* threat_ship = 0; - Shot* threat_missile = 0; - double threat_dist = 1e9; - - ListIter c_iter = ship->ContactList(); - - while (++c_iter) { - Contact* contact = c_iter.value(); - - if (contact->Threat(ship) && - (Clock::GetInstance()->GameTime() - contact->AcquisitionTime()) > THREAT_REACTION_TIME) { - - double rng = contact->Range(ship); - - if (contact->GetShot()) { - threat_missile = contact->GetShot(); - } - - else if (rng < threat_dist && contact->GetShip()) { - Ship* candidate = contact->GetShip(); - - if (candidate->InTransition()) - continue; - - if (candidate->IsStarship() && rng < 50e3) { - threat_ship = candidate; - threat_dist = rng; - } - - else if (candidate->IsDropship() && rng < 25e3) { - threat_ship = candidate; - threat_dist = rng; - } - - // static and ground units: - else if (rng < 30e3) { - threat_ship = candidate; - threat_dist = rng; - } - } - } - } - - ship_ai->SetThreat(threat_ship); - ship_ai->SetThreatMissile(threat_missile); -} - -// +--------------------------------------------------------------------+ - -bool -FighterTacticalAI::IsStrikeComplete(Instruction* instr) -{ - // wingmen can not call a halt to a strike: - if (!ship || element_index > 1) - return false; - - // if there's nothing to shoot at, we must be done: - if (!instr || !instr->GetTarget() || instr->GetTarget()->Life() == 0 || - instr->GetTarget()->Type() != SimObject::SIM_SHIP) - return true; - - // break off strike only when ALL weapons are expended: - // (remember to check all relevant wingmen) - Element* element = ship->GetElement(); - Ship* target = (Ship*) instr->GetTarget(); - - if (!element) - return true; - - for (int i = 0; i < element->NumShips(); i++) { - Ship* s = element->GetShip(i+1); - - if (!s || s->Integrity() < 25) // || (s->Location() - target->Location()).length() > 250e3) - continue; - - ListIter g_iter = s->Weapons(); - while (++g_iter) { - WeaponGroup* w = g_iter.value(); - - if (w->Ammo() && w->CanTarget(target->Class())) { - ListIter w_iter = w->GetWeapons(); - - while (++w_iter) { - Weapon* weapon = w_iter.value(); - - if (weapon->Status() > System::CRITICAL) - return false; - } - } - } - } - - // still here? we must be done! - return true; -} \ No newline at end of file diff --git a/Stars45/FighterTacticalAI.h b/Stars45/FighterTacticalAI.h deleted file mode 100644 index 7d8ba71..0000000 --- a/Stars45/FighterTacticalAI.h +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Fighter-specific mid-level (tactical) AI -*/ - -#ifndef FighterTacticalAI_h -#define FighterTacticalAI_h - -#include "Types.h" -#include "TacticalAI.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class WeaponGroup; - -// +--------------------------------------------------------------------+ - -class FighterTacticalAI : public TacticalAI -{ -public: - FighterTacticalAI(ShipAI* ai); - virtual ~FighterTacticalAI(); - -protected: - virtual bool CheckFlightPlan(); - virtual bool IsStrikeComplete(Instruction* instr=0); - - virtual void SelectTarget(); - virtual void SelectTargetDirected(Ship* tgt=0); - virtual void SelectTargetOpportunity(); - virtual void FindFormationSlot(int formation); - virtual void FindThreat(); - - virtual void SelectSecondaryForTarget(Ship* tgt); - virtual int ListSecondariesForTarget(Ship* tgt, List& weps); - - bool winchester[4]; - DWORD THREAT_REACTION_TIME; - DWORD secondary_selection_time; - int ai_level; -}; - -// +--------------------------------------------------------------------+ - -#endif // FighterTacticalAI_h - diff --git a/Stars45/FirstTimeDlg.cpp b/Stars45/FirstTimeDlg.cpp deleted file mode 100644 index 4376243..0000000 --- a/Stars45/FirstTimeDlg.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "FirstTimeDlg.h" -#include "Player.h" -#include "MenuScreen.h" -#include "Ship.h" -#include "Starshatter.h" -#include "KeyMap.h" -#include "Random.h" - -#include "DataLoader.h" -#include "Button.h" -#include "EditBox.h" -#include "ComboBox.h" -#include "Video.h" -#include "Keyboard.h" -#include "MachineInfo.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(FirstTimeDlg, OnApply); - -// +--------------------------------------------------------------------+ - -FirstTimeDlg::FirstTimeDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr) -{ - Init(def); -} - -FirstTimeDlg::~FirstTimeDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -FirstTimeDlg::RegisterControls() -{ - edt_name = (EditBox*) FindControl(200); - cmb_playstyle = (ComboBox*) FindControl(201); - cmb_experience = (ComboBox*) FindControl(202); - - btn_apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, btn_apply, FirstTimeDlg, OnApply); -} - -// +--------------------------------------------------------------------+ - -void -FirstTimeDlg::Show() -{ - if (!IsShown()) - FormWindow::Show(); - - if (edt_name) - edt_name->SetText("Noobie"); -} - -// +--------------------------------------------------------------------+ - -void -FirstTimeDlg::ExecFrame() -{ -} - -// +--------------------------------------------------------------------+ - -void -FirstTimeDlg::OnApply(AWEvent* event) -{ - Starshatter* stars = Starshatter::GetInstance(); - Player* player = Player::GetCurrentPlayer(); - - if (player) { - if (edt_name) { - char password[16]; - sprintf_s(password, "%08x", (DWORD) Random(0, 2e9)); - - player->SetName(edt_name->GetText()); - player->SetPassword(password); - } - - if (cmb_playstyle) { - // ARCADE: - if (cmb_playstyle->GetSelectedIndex() == 0) { - player->SetFlightModel(2); - player->SetLandingModel(1); - player->SetHUDMode(0); - player->SetGunsight(1); - - if (stars) { - KeyMap& keymap = stars->GetKeyMap(); - - keymap.Bind(KEY_CONTROL_MODEL, 1, 0); - keymap.SaveKeyMap("key.cfg", 256); - - stars->MapKeys(); - } - - Ship::SetControlModel(1); - } - - // HARDCORE: - else { - player->SetFlightModel(0); - player->SetLandingModel(0); - player->SetHUDMode(0); - player->SetGunsight(0); - - if (stars) { - KeyMap& keymap = stars->GetKeyMap(); - - keymap.Bind(KEY_CONTROL_MODEL, 0, 0); - keymap.SaveKeyMap("key.cfg", 256); - - stars->MapKeys(); - } - - Ship::SetControlModel(0); - } - } - - if (cmb_experience && cmb_experience->GetSelectedIndex() > 0) { - player->SetRank(2); // Lieutenant - player->SetTrained(255); // Fully Trained - } - - Player::Save(); - } - - manager->ShowMenuDlg(); -} diff --git a/Stars45/FirstTimeDlg.h b/Stars45/FirstTimeDlg.h deleted file mode 100644 index 60c735c..0000000 --- a/Stars45/FirstTimeDlg.h +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef FirstTimeDlg_h -#define FirstTimeDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; - -// +--------------------------------------------------------------------+ - -class FirstTimeDlg : public FormWindow -{ -public: - FirstTimeDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~FirstTimeDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnApply(AWEvent* event); - -protected: - MenuScreen* manager; - - EditBox* edt_name; - ComboBox* cmb_playstyle; - ComboBox* cmb_experience; - - Button* btn_apply; -}; - -#endif // FirstTimeDlg_h - diff --git a/Stars45/Fix.cpp b/Stars45/Fix.cpp deleted file mode 100644 index 67b3782..0000000 --- a/Stars45/Fix.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Fixed point number class with 16 bits of fractional precision -*/ - -#include "Fix.h" - -// +--------------------------------------------------------------------+ - -const fix fix::one = fix(1); -const fix fix::two = fix(2); -const fix fix::three = fix(3); -const fix fix::five = fix(5); -const fix fix::ten = fix(10); diff --git a/Stars45/Fix.h b/Stars45/Fix.h deleted file mode 100644 index de8e01d..0000000 --- a/Stars45/Fix.h +++ /dev/null @@ -1,120 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Fixed point number class with 16 bits of fractional precision -*/ - -#ifndef Fix_h -#define Fix_h - -// +--------------------------------------------------------------------+ - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -const double fix_sixty_five=65536.0; - -inline int fast_f2i(double d) -{ - return static_cast(d); -} - -// +--------------------------------------------------------------------+ - -class fix -{ -public: - static const char* TYPENAME() { return "fix"; } - - enum FixDef { Precision=16, IntMask=0xffff0000, FractMask=0x0000ffff }; - static const fix one; - static const fix two; - static const fix three; - static const fix five; - static const fix ten; - - fix() : val(0) { } - fix(int n) : val(n<(d * fix_sixty_five)) { } - fix(const fix& f) : val(f.val) { } - - // conversion operators: - operator int () const { return (val>>Precision); } - operator float () const { return ((float) val) / ((float) fix_sixty_five); } - operator double() const { return ((double) val) / fix_sixty_five; } - - // assignment operators: - fix& operator=(const fix& f) { val=f.val; return *this; } - fix& operator=(int n) { val=(n<(d * fix_sixty_five); return *this; } - - // comparison operators: - int operator==(const fix& f) const { return val==f.val; } - int operator!=(const fix& f) const { return val!=f.val; } - int operator<=(const fix& f) const { return val<=f.val; } - int operator>=(const fix& f) const { return val>=f.val; } - int operator< (const fix& f) const { return val< f.val; } - int operator> (const fix& f) const { return val> f.val; } - - // arithmetic operators: - fix operator+(const fix& f) const { fix r; r.val = val+f.val; return r; } - fix operator-(const fix& f) const { fix r; r.val = val-f.val; return r; } - fix operator*(const fix& f) const { - fix r; - r.val = (val * f.val) >> Precision; - return r; } - fix operator/(const fix& f) const { - fix r; - r.val = (val << Precision) / f.val; - return r; } - fix& operator+=(const fix& f) { val+=f.val; return *this; } - fix& operator-=(const fix& f) { val-=f.val; return *this; } - fix& operator*=(const fix& f) { - val = (val * f.val) >> Precision; - return *this; } - fix& operator/=(const fix& f) { - val = (val << Precision) / f.val; - return *this; } - - fix operator+(int n) const { fix r; r.val = val+(n<(d); return *this; } - fix& operator/=(double d) { val/=static_cast(d); return *this; } - - // misc. functions: - fix truncate() const { fix r; r.val = val&IntMask; return r; } - fix fraction() const { fix r; r.val = val-truncate().val; return r; } - fix floor() const { fix r; r.val = val&IntMask; return r; } - fix ceil() const { fix r; r.val = (val+FractMask)&IntMask; return r; } - fix adjust_up() const { fix r; r.val = val+FractMask; return r; } - fix adjust_down() const { fix r; r.val = val-FractMask; return r; } - - fix muldiv(const fix& num, const fix& den) const { return (*this) * num / den; } - - // data: - long val; -}; - -#endif // Fix_h - diff --git a/Stars45/FlightComp.cpp b/Stars45/FlightComp.cpp deleted file mode 100644 index bbb38b6..0000000 --- a/Stars45/FlightComp.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Flight Computer System class -*/ - -#include "FlightComp.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Thruster.h" - -// +----------------------------------------------------------------------+ - -FlightComp::FlightComp(int comp_type, const char* comp_name) -: Computer(comp_type, comp_name), mode(0), vlimit(0.0f), -trans_x_limit(0.0f), trans_y_limit(0.0f), trans_z_limit(0.0f), -throttle(0.0f), halt(0) -{ } - -// +----------------------------------------------------------------------+ - -FlightComp::FlightComp(const Computer& c) -: Computer(c), mode(0), vlimit(0.0f), -trans_x_limit(0.0f), trans_y_limit(0.0f), trans_z_limit(0.0f), -throttle(0.0f), halt(0) -{ } - -// +--------------------------------------------------------------------+ - -FlightComp::~FlightComp() -{ } - -// +--------------------------------------------------------------------+ - -void -FlightComp::SetTransLimit(double x, double y, double z) -{ - trans_x_limit = 0.0f; - trans_y_limit = 0.0f; - trans_z_limit = 0.0f; - - if (x >= 0) trans_x_limit = (float) x; - if (y >= 0) trans_y_limit = (float) y; - if (z >= 0) trans_z_limit = (float) z; -} - -// +--------------------------------------------------------------------+ - -void -FlightComp::ExecSubFrame() -{ - if (ship) { - ExecThrottle(); - ExecTrans(); - } -} - -// +--------------------------------------------------------------------+ - -void -FlightComp::ExecThrottle() -{ - throttle = (float) ship->Throttle(); - - if (throttle > 5) - halt = false; -} - -// +--------------------------------------------------------------------+ - -void -FlightComp::ExecTrans() -{ - double tx = ship->TransX(); - double ty = ship->TransY(); - double tz = ship->TransZ(); - - double trans_x = tx; - double trans_y = ty; - double trans_z = tz; - - bool flcs_operative = false; - - if (IsPowerOn()) - flcs_operative = Status() == System::NOMINAL || - Status() == System::DEGRADED; - - // ---------------------------------------------------------- - // FIGHTER FLCS AUTO MODE - // ---------------------------------------------------------- - - if (mode == Ship::FLCS_AUTO) { - // auto thrust to align flight path with orientation: - if (tx == 0) { - if (flcs_operative) - trans_x = (ship->Velocity() * ship->BeamLine() * -200); - - else - trans_x = 0; - } - - // manual thrust up to vlimit/2: - else { - double vfwd = ship->BeamLine() * ship->Velocity(); - - if (fabs(vfwd)>= vlimit) { - if (trans_x > 0 && vfwd > 0) - trans_x = 0; - - else if (trans_x < 0 && vfwd < 0) - trans_x = 0; - } - } - - if (halt && flcs_operative) { - if (ty == 0) { - double vfwd = ship->Heading() * ship->Velocity(); - double vmag = fabs(vfwd); - - if (vmag > 0) { - if (vfwd > 0) - trans_y = -trans_y_limit; - else - trans_y = trans_y_limit; - - if (vfwd < vlimit/2) - trans_y *= (vmag/(vlimit/2)); - } - } - } - - - // auto thrust to align flight path with orientation: - if (tz == 0) { - if (flcs_operative) - trans_z = (ship->Velocity() * ship->LiftLine() * -200); - - else - trans_z = 0; - } - - // manual thrust up to vlimit/2: - else { - double vfwd = ship->LiftLine() * ship->Velocity(); - - if (fabs(vfwd) >= vlimit) { - if (trans_z > 0 && vfwd > 0) - trans_z = 0; - - else if (trans_z < 0 && vfwd < 0) - trans_z = 0; - } - } - } - - // ---------------------------------------------------------- - // STARSHIP HELM MODE - // ---------------------------------------------------------- - - else if (mode == Ship::FLCS_HELM) { - if (flcs_operative) { - double compass_heading = ship->CompassHeading(); - double compass_pitch = ship->CompassPitch(); - // rotate helm into compass orientation: - double helm = ship->GetHelmHeading() - compass_heading; - - if (helm > PI) - helm -= 2*PI; - else if (helm < -PI) - helm += 2*PI; - - // turn to align with helm heading: - if (helm != 0) - ship->ApplyYaw(helm); - - // pitch to align with helm pitch: - if (compass_pitch != ship->GetHelmPitch()) - ship->ApplyPitch(compass_pitch - ship->GetHelmPitch()); - - // roll to align with world coordinates: - if (ship->Design()->auto_roll > 0) { - Point vrt = ship->Cam().vrt(); - double deflection = vrt.y; - - if (fabs(helm) < PI/16 || ship->Design()->turn_bank < 0.01) { - if (ship->Design()->auto_roll > 1) { - ship->ApplyRoll(0.5); - } - else if (deflection != 0) { - double theta = asin(deflection); - ship->ApplyRoll(-theta); - } - } - - // else roll through turn maneuvers: - else { - double desired_bank = ship->Design()->turn_bank; - - if (helm >= 0) - desired_bank = -desired_bank; - - double current_bank = asin(deflection); - double theta = desired_bank - current_bank; - ship->ApplyRoll(theta); - - // coordinate the turn: - if (current_bank < 0 && desired_bank < 0 || - current_bank > 0 && desired_bank > 0) { - - double coord_pitch = compass_pitch - - ship->GetHelmPitch() - - fabs(helm) * fabs(current_bank); - ship->ApplyPitch(coord_pitch); - } - } - } - } - - // flcs inoperative, set helm heading based on actual compass heading: - else { - ship->SetHelmHeading(ship->CompassHeading()); - ship->SetHelmPitch(ship->CompassPitch()); - } - - // auto thrust to align flight path with helm order: - if (tx == 0) { - if (flcs_operative) - trans_x = (ship->Velocity() * ship->BeamLine() * ship->Mass() * -1); - - else - trans_x = 0; - } - - // manual thrust up to vlimit/2: - else { - double vfwd = ship->BeamLine() * ship->Velocity(); - - if (fabs(vfwd) >= vlimit/2) { - if (trans_x > 0 && vfwd > 0) - trans_x = 0; - - else if (trans_x < 0 && vfwd < 0) - trans_x = 0; - } - } - - if (trans_y == 0 && halt) { - double vfwd = ship->Heading() * ship->Velocity(); - double vdesired = 0; - - if (vfwd > vdesired) { - trans_y = -trans_y_limit; - - if (!flcs_operative) - trans_y = 0; - - double vdelta = vfwd-vdesired; - if (vdelta < vlimit/2) - trans_y *= (vdelta/(vlimit/2)); - } - } - - - - // auto thrust to align flight path with helm order: - if (tz == 0) { - if (flcs_operative) - trans_z = (ship->Velocity() * ship->LiftLine() * ship->Mass() * -1); - - else - trans_z = 0; - } - - // manual thrust up to vlimit/2: - else { - double vfwd = ship->LiftLine() * ship->Velocity(); - - if (fabs(vfwd) > vlimit/2) { - if (trans_z > 0 && vfwd > 0) - trans_z = 0; - - else if (trans_z < 0 && vfwd < 0) - trans_z = 0; - } - } - } - - if (ship->GetThruster()) { - ship->GetThruster()->ExecTrans(trans_x, trans_y, trans_z); - } - else { - ship->SetTransX(trans_x); - ship->SetTransY(trans_y); - ship->SetTransZ(trans_z); - } -} diff --git a/Stars45/FlightComp.h b/Stars45/FlightComp.h deleted file mode 100644 index 07797a2..0000000 --- a/Stars45/FlightComp.h +++ /dev/null @@ -1,62 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Flight Computer systems class -*/ - -#ifndef FLIGHT_COMP_H -#define FLIGHT_COMP_H - -#include "Types.h" -#include "Computer.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Ship; - -// +--------------------------------------------------------------------+ - -class FlightComp : public Computer -{ -public: - enum CompType { AVIONICS=1, FLIGHT, TACTICAL }; - - FlightComp(int comp_type, const char* comp_name); - FlightComp(const Computer& rhs); - virtual ~FlightComp(); - - virtual void ExecSubFrame(); - - int Mode() const { return mode; } - double Throttle() const { return throttle; } - - void SetMode(int m) { mode = m; } - void SetVelocityLimit(double v) { vlimit = (float) v; } - void SetTransLimit(double x, double y, double z); - - void FullStop() { halt = true; } - -protected: - virtual void ExecTrans(); - virtual void ExecThrottle(); - - int mode; - int halt; - float throttle; - - float vlimit; - float trans_x_limit; - float trans_y_limit; - float trans_z_limit; -}; - -#endif // FLIGHT_COMP_H - diff --git a/Stars45/FlightDeck.cpp b/Stars45/FlightDeck.cpp deleted file mode 100644 index 8b2d070..0000000 --- a/Stars45/FlightDeck.cpp +++ /dev/null @@ -1,1185 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Everything needed to launch and recover space craft... -*/ - -#include "FlightDeck.h" -#include "Ship.h" -#include "ShipCtrl.h" -#include "ShipDesign.h" -#include "Element.h" -#include "Mission.h" -#include "MissionEvent.h" -#include "Drive.h" -#include "Sim.h" -#include "Instruction.h" -#include "Hoop.h" -#include "LandingGear.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "SimEvent.h" -#include "AudioConfig.h" -#include "CameraDirector.h" -#include "Combatant.h" -#include "CombatGroup.h" -#include "CombatUnit.h" - -#include "NetData.h" -#include "NetUtil.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Solid.h" -#include "Light.h" -#include "Sound.h" -#include "DataLoader.h" - -static Sound* tire_sound = 0; -static Sound* catapult_sound = 0; - -// +======================================================================+ - -class FlightDeckSlot -{ -public: - FlightDeckSlot() : ship(0), state(0), sequence(0), time(0), filter(0xf) { } - int operator == (const FlightDeckSlot& that) const { return this == &that; } - - Ship* ship; - Point spot_rel; - Point spot_loc; - - int state; - int sequence; - double time; - double clearance; - DWORD filter; -}; - -// +======================================================================+ - -InboundSlot::InboundSlot(Ship* s, FlightDeck* d, int squad, int index) -: ship(s), deck(d), squadron(squad), slot(index), cleared(0), final(0), approach(0) -{ - if (ship) - Observe(ship); - - if (deck && deck->GetCarrier()) - Observe((SimObject*) deck->GetCarrier()); -} - -int InboundSlot::operator < (const InboundSlot& that) const -{ - double dthis = 0; - double dthat = 0; - - if (ship == that.ship) { - return false; - } - - if (cleared && !that.cleared) { - return true; - } - - if (!cleared && that.cleared) { - return false; - } - - if (ship && deck && that.ship) { - dthis = Point(ship->Location() - deck->MountLocation()).length(); - dthat = Point(that.ship->Location() - deck->MountLocation()).length(); - } - - if (dthis == dthat) { - return (DWORD) this < (DWORD) &that; - } - - return dthis < dthat; -} - -int InboundSlot::operator <= (const InboundSlot& that) const -{ - double dthis = 0; - double dthat = 0; - - if (ship == that.ship) - return true; - - if (cleared && !that.cleared) - return true; - - if (!cleared && that.cleared) - return false; - - if (ship && deck && that.ship) { - dthis = Point(ship->Location() - deck->MountLocation()).length(); - dthat = Point(that.ship->Location() - deck->MountLocation()).length(); - } - - return dthis <= dthat; -} - -int InboundSlot::operator == (const InboundSlot& that) const -{ - return this == &that; -} - -void InboundSlot::Clear(bool c) -{ - if (ship) - cleared = c; -} - -double InboundSlot::Distance() -{ - if (ship && deck) { - return Point(ship->Location() - deck->MountLocation()).length(); - } - - return 1e9; -} - -// +----------------------------------------------------------------------+ - -bool -InboundSlot::Update(SimObject* obj) -{ - if (obj->Type() == SimObject::SIM_SHIP) { - Ship* s = (Ship*) obj; - - if (s == ship) { - ship = 0; - } - - // Actually, this can't happen. The flight deck - // owns the slot. When the carrier is destroyed, - // the flight decks and slots are destroyed before - // the carrier updates the observers. - - // I'm leaving this block in, just in case. - - else if (deck && s == deck->GetCarrier()) { - ship = 0; - deck = 0; - } - } - - return SimObserver::Update(obj); -} - -const char* -InboundSlot::GetObserverName() const -{ - return "InboundSlot"; -} - -// +======================================================================+ - -FlightDeck::FlightDeck() -: System(FLIGHT_DECK, FLIGHT_DECK_LAUNCH, "Flight Deck", 1, 1), -carrier(0), index(0), num_slots(0), slots(0), cycle_time(5), num_hoops(0), hoops(0), -azimuth(0), light(0), num_catsounds(0), num_approach_pts(0) -{ - name = ContentBundle::GetInstance()->GetText("sys.flight-deck"); - abrv = ContentBundle::GetInstance()->GetText("sys.flight-deck.abrv"); -} - -// +----------------------------------------------------------------------+ - -FlightDeck::FlightDeck(const FlightDeck& s) -: System(s), -carrier(0), index(0), start_rel(s.start_rel), -end_rel(s.end_rel), cam_rel(s.cam_rel), -cycle_time(s.cycle_time), -num_slots(s.num_slots), slots(0), -num_hoops(0), hoops(0), azimuth(s.azimuth), light(0), -num_catsounds(0), num_approach_pts(s.num_approach_pts) -{ - Mount(s); - - slots = new FlightDeckSlot[num_slots]; - for (int i = 0; i < num_slots; i++) { - slots[i].spot_rel = s.slots[i].spot_rel; - slots[i].filter = s.slots[i].filter; - } - - for (int i = 0; i < NUM_APPROACH_PTS; i++) - approach_rel[i] = s.approach_rel[i]; - - for (int i = 0; i < 2; i++) - runway_rel[i] = s.runway_rel[i]; - - if (s.light) { - light = new Light(*s.light); - } -} - -// +--------------------------------------------------------------------+ - -FlightDeck::~FlightDeck() -{ - if (hoops && num_hoops) { - for (int i = 0; i < num_hoops; i++) { - Hoop* h = &hoops[i]; - Scene* scene = h->GetScene(); - if (scene) - scene->DelGraphic(h); - } - } - - delete [] slots; - delete [] hoops; - - LIGHT_DESTROY(light); - - recovery_queue.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -FlightDeck::Initialize() -{ - static int initialized = 0; - if (initialized) return; - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Sounds/"); - - const int SOUND_FLAGS = Sound::LOCALIZED | - Sound::LOC_3D; - - loader->LoadSound("Tires.wav", tire_sound, SOUND_FLAGS); - loader->LoadSound("Catapult.wav", catapult_sound, SOUND_FLAGS); - loader->SetDataPath(0); - - if (tire_sound) - tire_sound->SetMaxDistance(2.5e3f); - - if (catapult_sound) - catapult_sound->SetMaxDistance(0.5e3f); - - initialized = 1; -} - -// +--------------------------------------------------------------------+ - -void -FlightDeck::Close() -{ - delete tire_sound; - delete catapult_sound; - - tire_sound = 0; - catapult_sound = 0; -} - -// +--------------------------------------------------------------------+ - -void -FlightDeck::ExecFrame(double seconds) -{ - System::ExecFrame(seconds); - - bool advance_queue = false; - long max_vol = AudioConfig::EfxVolume(); - long volume = -1000; - Sim* sim = Sim::GetSim(); - - if (volume > max_vol) - volume = max_vol; - - // update ship status: - for (int i = 0; i < num_slots; i++) { - FlightDeckSlot* slot = &slots[i]; - Ship* slot_ship = 0; - - if (slot->ship == 0) { - slot->state = CLEAR; - } - else { - slot_ship = slot->ship; - slot_ship->SetThrottle(0); - } - - switch (slot->state) { - case CLEAR: - if (slot->time > 0) { - slot->time -= seconds; - } - else if (IsRecoveryDeck()) { - GrantClearance(); - } - break; - - case READY: { - Camera c; - c.Clone(carrier->Cam()); - c.Yaw(azimuth); - - if (slot_ship) { - slot_ship->CloneCam(c); - slot_ship->MoveTo(slot->spot_loc); - slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance); - slot_ship->SetVelocity(carrier->Velocity()); - } - slot->time = 0; - } - break; - - case QUEUED: - if (slot->time > 0) { - Camera c; - c.Clone(carrier->Cam()); - c.Yaw(azimuth); - - slot->time -= seconds; - if (slot_ship) { - slot_ship->CloneCam(c); - slot_ship->MoveTo(slot->spot_loc); - slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance); - slot_ship->SetFlightPhase(Ship::ALERT); - } - } - - if (slot->sequence == 1 && slot->time <= 0) { - bool clear_for_launch = true; - for (int i = 0; i < num_slots; i++) - if (slots[i].state == LOCKED) - clear_for_launch = false; - - if (clear_for_launch) { - slot->sequence = 0; - slot->state = LOCKED; - slot->time = cycle_time; - if (slot_ship) - slot_ship->SetFlightPhase(Ship::LOCKED); - num_catsounds = 0; - - advance_queue = true; - } - } - break; - - case LOCKED: - if (slot->time > 0) { - slot->time -= seconds; - - if (slot_ship) { - double ct4 = cycle_time/4; - - double dx = start_rel.x - slot->spot_rel.x; - double dy = start_rel.z - slot->spot_rel.z; - double dyaw = atan2(dx,dy) - azimuth; - - Camera c; - c.Clone(carrier->Cam()); - c.Yaw(azimuth); - - // rotate: - if (slot->time > 3*ct4) { - double step = 1 - (slot->time - 3*ct4) / ct4; - c.Yaw(dyaw * step); - slot_ship->CloneCam(c); - slot_ship->MoveTo(slot->spot_loc); - slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance); - - if (carrier->IsGroundUnit()) { - slot_ship->SetThrottle(25); - } - - else if (num_catsounds < 1) { - if (catapult_sound) { - Sound* sound = catapult_sound->Duplicate(); - sound->SetLocation(slot_ship->Location()); - sound->SetVolume(volume); - sound->Play(); - } - num_catsounds = 1; - } - } - - // translate: - else if (slot->time > 2*ct4) { - double step = (slot->time - 2*ct4) / ct4; - - Point loc = start_point + - (slot->spot_loc - start_point) * step; - - c.Yaw(dyaw); - slot_ship->CloneCam(c); - slot_ship->MoveTo(loc); - slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance); - - if (carrier->IsGroundUnit()) { - slot_ship->SetThrottle(25); - } - - else if (num_catsounds < 2) { - if (catapult_sound) { - Sound* sound = catapult_sound->Duplicate(); - sound->SetLocation(slot_ship->Location()); - sound->SetVolume(volume); - sound->Play(); - } - num_catsounds = 2; - } - } - - // rotate: - else if (slot->time > ct4) { - double step = (slot->time - ct4) / ct4; - c.Yaw(dyaw*step); - slot_ship->CloneCam(c); - slot_ship->MoveTo(start_point); - slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance); - - if (carrier->IsGroundUnit()) { - slot_ship->SetThrottle(25); - } - - else if (num_catsounds < 3) { - if (catapult_sound) { - Sound* sound = catapult_sound->Duplicate(); - sound->SetLocation(slot_ship->Location()); - sound->SetVolume(volume); - sound->Play(); - } - num_catsounds = 3; - } - } - - // wait: - else { - slot_ship->SetThrottle(100); - slot_ship->CloneCam(c); - slot_ship->MoveTo(start_point); - slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance); - } - - slot_ship->SetFlightPhase(Ship::LOCKED); - } - } - else { - slot->state = LAUNCH; - slot->time = 0; - - } - break; - - case LAUNCH: - LaunchShip(slot_ship); - break; - - case DOCKING: - if (slot_ship && !slot_ship->IsAirborne()) { - // do arresting gear stuff: - if (slot_ship->GetFlightModel() == Ship::FM_ARCADE) - slot_ship->ArcadeStop(); - - slot_ship->SetVelocity(carrier->Velocity()); - } - - if (slot->time > 0) { - slot->time -= seconds; - } - else { - if (slot_ship) { - slot_ship->SetFlightPhase(Ship::DOCKED); - slot_ship->Stow(); - - NetUtil::SendObjKill(slot_ship, carrier, NetObjKill::KILL_DOCK, index); - } - - Clear(i); - } - break; - - default: - break; - } - } - - if (advance_queue) { - for (int i = 0; i < num_slots; i++) { - FlightDeckSlot* slot = &slots[i]; - if (slot->state == QUEUED && slot->sequence > 1) - slot->sequence--; - } - } -} - -bool -FlightDeck::LaunchShip(Ship* slot_ship) -{ - FlightDeckSlot* slot = 0; - Sim* sim = Sim::GetSim(); - - if (slot_ship) { - for (int i = 0; i < num_slots; i++) { - if (slots[i].ship == slot_ship) - slot = &(slots[i]); - } - - // only suggest a launch point if no flight plan has been filed... - if (slot_ship->GetElement()->FlightPlanLength() == 0) { - Point departure = end_point; - departure = departure.OtherHand(); - - Instruction* launch_point = new - Instruction(carrier->GetRegion(), departure, Instruction::LAUNCH); - launch_point->SetSpeed(350); - - slot_ship->SetLaunchPoint(launch_point); - } - - if (!slot_ship->IsAirborne()) { - Point cat; - if (fabs(azimuth) < 5*DEGREES) { - cat = carrier->Heading() * 300; - } - else { - Camera c; - c.Clone(carrier->Cam()); - c.Yaw(azimuth); - cat = c.vpn() * 300; - } - - slot_ship->SetVelocity(carrier->Velocity() + cat); - slot_ship->SetFlightPhase(Ship::LAUNCH); - } - else { - slot_ship->SetFlightPhase(Ship::TAKEOFF); - } - - Director* dir = slot_ship->GetDirector(); - if (dir && dir->Type() == ShipCtrl::DIR_TYPE) { - ShipCtrl* ctrl = (ShipCtrl*) dir; - ctrl->Launch(); - } - - ShipStats* c = ShipStats::Find(carrier->Name()); - if (c) c->AddEvent(SimEvent::LAUNCH_SHIP, slot_ship->Name()); - - ShipStats* stats = ShipStats::Find(slot_ship->Name()); - if (stats) { - stats->SetRegion(carrier->GetRegion()->Name()); - stats->SetType(slot_ship->Design()->name); - - if (slot_ship->GetElement()) { - Element* elem = slot_ship->GetElement(); - stats->SetRole(Mission::RoleName(elem->Type())); - stats->SetCombatGroup(elem->GetCombatGroup()); - stats->SetCombatUnit(elem->GetCombatUnit()); - stats->SetElementIndex(slot_ship->GetElementIndex()); - } - - stats->SetIFF(slot_ship->GetIFF()); - stats->AddEvent(SimEvent::LAUNCH, carrier->Name()); - - if (slot_ship == sim->GetPlayerShip()) - stats->SetPlayer(true); - } - - sim->ProcessEventTrigger(MissionEvent::TRIGGER_LAUNCH, 0, slot_ship->Name()); - - if (slot) { - slot->ship = 0; - slot->state = CLEAR; - slot->sequence = 0; - slot->time = 0; - } - - return true; - } - - return false; -} - -// +----------------------------------------------------------------------+ - -void -FlightDeck::SetLight(double l) -{ - LIGHT_DESTROY(light); - light = new Light((float) l); -} - -void -FlightDeck::SetApproachPoint(int i, Point loc) -{ - if (i >= 0 && i < NUM_APPROACH_PTS) { - approach_rel[i] = loc; - - if (i >= num_approach_pts) - num_approach_pts = i+1; - } -} - -void -FlightDeck::SetRunwayPoint(int i, Point loc) -{ - if (i >= 0 && i < 2) - runway_rel[i] = loc; -} - -void -FlightDeck::SetStartPoint(Point loc) -{ - start_rel = loc; -} - -void -FlightDeck::SetEndPoint(Point loc) -{ - end_rel = loc; -} - -void -FlightDeck::SetCamLoc(Point loc) -{ - cam_rel = loc; -} - -// +----------------------------------------------------------------------+ - -void -FlightDeck::AddSlot(const Point& spot, DWORD filter) -{ - if (!slots) - slots = new FlightDeckSlot[10]; - - slots[num_slots].spot_rel = spot; - slots[num_slots].filter = filter; - num_slots++; -} - -// +----------------------------------------------------------------------+ - -void -FlightDeck::SetCycleTime(double t) -{ - cycle_time = t; -} - -// +----------------------------------------------------------------------+ - -void -FlightDeck::Orient(const Physical* rep) -{ - System::Orient(rep); - - Matrix orientation = rep->Cam().Orientation(); - Point loc = rep->Location(); - - start_point = (start_rel * orientation) + loc; - end_point = (end_rel * orientation) + loc; - cam_loc = (cam_rel * orientation) + loc; - - for (int i = 0; i < num_approach_pts; i++) - approach_point[i] = (approach_rel[i] * orientation) + loc; - - for (int i = 0; i < num_slots; i++) - slots[i].spot_loc = (slots[i].spot_rel * orientation) + loc; - - if (IsRecoveryDeck()) { - if (carrier->IsAirborne()) { - runway_point[0] = (runway_rel[0] * orientation) + loc; - runway_point[1] = (runway_rel[1] * orientation) + loc; - } - - if (num_hoops < 1) { - num_hoops = 4; - hoops = new Hoop[num_hoops]; - } - - Point hoop_vec = start_point - end_point; - double hoop_d = hoop_vec.Normalize() / num_hoops; - - orientation.Yaw(azimuth); - - for (int i = 0; i < num_hoops; i++) { - hoops[i].MoveTo(end_point + hoop_vec * (i+1) * hoop_d); - hoops[i].SetOrientation(orientation); - } - } - - if (light) - light->MoveTo(mount_loc); -} - -// +----------------------------------------------------------------------+ - -int -FlightDeck::SpaceLeft(int type) const -{ - int space_left = 0; - - for (int i = 0; i < num_slots; i++) - if (slots[i].ship == 0 && (slots[i].filter & type)) - space_left++; - - return space_left; -} - -// +----------------------------------------------------------------------+ - -bool -FlightDeck::Spot(Ship* s, int& index) -{ - if (!s) - return false; - - if (index < 0) { - for (int i = 0; i < num_slots; i++) { - if (slots[i].ship == 0 && (slots[i].filter & s->Class())) { - index = i; - break; - } - } - } - - if (index >= 0 && index < num_slots && slots[index].ship == 0) { - slots[index].state = READY; - slots[index].ship = s; - slots[index].clearance = 0; - - if (s->GetGear()) - slots[index].clearance = s->GetGear()->GetClearance(); - - if (IsRecoveryDeck() && !s->IsAirborne()) { - s->SetVelocity(s->Velocity() * 0.01); // hit the brakes! - } - - if (!IsRecoveryDeck()) { - Camera work; - work.Clone(carrier->Cam()); - work.Yaw(azimuth); - - s->CloneCam(work); - s->MoveTo(slots[index].spot_loc); - - LandingGear* g = s->GetGear(); - if (g) { - g->SetState(LandingGear::GEAR_DOWN); - g->ExecFrame(0); - s->TranslateBy(carrier->Cam().vup() * slots[index].clearance); - } - - s->SetFlightPhase(Ship::ALERT); - } - - s->SetCarrier(carrier, this); - Observe(s); - - return true; - } - - return false; -} - -bool -FlightDeck::Clear(int index) -{ - if (index >= 0 && index < num_slots && slots[index].ship != 0) { - Ship* s = slots[index].ship; - - slots[index].ship = 0; - slots[index].time = cycle_time; - slots[index].state = CLEAR; - - ListIter iter = recovery_queue; - while (++iter) { - if (iter->GetShip() == s) { - delete iter.removeItem(); // ??? SHOULD DELETE HERE ??? - break; - } - } - - return true; - } - - return false; -} - -// +----------------------------------------------------------------------+ - -bool -FlightDeck::Launch(int index) -{ - if (subtype == FLIGHT_DECK_LAUNCH && index >= 0 && index < num_slots) { - FlightDeckSlot* slot = &slots[index]; - - if (slot->ship && slot->state == READY) { - int last = 0; - FlightDeckSlot* last_slot = 0; - FlightDeckSlot* lock_slot = 0; - - for (int i = 0; i < num_slots; i++) { - FlightDeckSlot* s = &slots[i]; - - if (s->state == QUEUED && s->sequence > last) { - last = s->sequence; - last_slot = s; - } - - else if (s->state == LOCKED) { - lock_slot = s; - } - } - - // queue the slot for launch: - slot->state = QUEUED; - slot->sequence = last + 1; - slot->time = 0; - - if (last_slot) - slot->time = last_slot->time + cycle_time; - - else if (lock_slot) - slot->time = lock_slot->time; - - return true; - } - } - - return false; -} - -// +----------------------------------------------------------------------+ - -bool -FlightDeck::Recover(Ship* s) -{ - if (s && subtype == FLIGHT_DECK_RECOVERY) { - if (OverThreshold(s)) { - if (s->GetFlightPhase() < Ship::RECOVERY) { - s->SetFlightPhase(Ship::RECOVERY); - s->SetCarrier(carrier, this); // let ship know which flight deck it's in (needed for dock cam) - } - - // are we there yet? - if (s->GetFlightPhase() >= Ship::ACTIVE && s->GetFlightPhase() < Ship::DOCKING) { - if (slots[0].ship == 0) { // only need to ask this on approach - double dock_distance = (s->Location() - MountLocation()).length(); - - if (s->IsAirborne()) { - double altitude = s->Location().y - MountLocation().y; - if (dock_distance < Radius()*3 && altitude < s->Radius()) - Dock(s); - } - else { - if (dock_distance < s->Radius()) - Dock(s); - } - } - } - - return true; - } - else { - if (s->GetFlightPhase() == Ship::RECOVERY) - s->SetFlightPhase(Ship::ACTIVE); - } - } - - return false; -} - -bool -FlightDeck::Dock(Ship* s) -{ - if (s && subtype == FLIGHT_DECK_RECOVERY && slots[0].time <= 0) { - int index = 0; - if (Spot(s, index)) { - s->SetFlightPhase(Ship::DOCKING); - s->SetCarrier(carrier, this); - - // hard landings? - if (Ship::GetLandingModel() == 0) { - double base_damage = s->Design()->integrity; - - // did player do something stupid? - if (s->GetGear() && !s->IsGearDown()) { - Print("FlightDeck::Dock(%s) Belly landing!\n", s->Name()); - s->InflictDamage(0.5 * base_damage); - } - - double docking_deflection = fabs(carrier->Cam().vup().y - s->Cam().vup().y); - - if (docking_deflection > 0.35) { - Print("Landing upside down? y = %.3f\n", docking_deflection); - s->InflictDamage(0.8 * base_damage); - } - - // did incoming ship exceed safe landing parameters? - if (s->IsAirborne()) { - if (s->Velocity().y < -20) { - Print("FlightDeck::Dock(%s) Slammed it!\n", s->Name()); - s->InflictDamage(0.1 * base_damage); - } - } - - // did incoming ship exceed safe docking speed? - else { - Point delta_v = s->Velocity() - carrier->Velocity(); - double excess = (delta_v.length() - 100); - - if (excess > 0) - s->InflictDamage(excess); - } - } - - if (s->IsAirborne()) { - if (s == Sim::GetSim()->GetPlayerShip() && tire_sound) { - Sound* sound = tire_sound->Duplicate(); - sound->Play(); - } - } - - if (s->GetDrive()) - s->GetDrive()->PowerOff(); - - slots[index].state = DOCKING; - slots[index].time = 5; - - if (s->IsAirborne()) - slots[index].time = 7.5; - return true; - } - } - - return false; -} - -int -FlightDeck::Inbound(InboundSlot*& s) -{ - if (s && s->GetShip()) { - Ship* inbound = s->GetShip(); - - if (recovery_queue.contains(s)) { - InboundSlot* orig = s; - s = recovery_queue.find(s); - delete orig; - } - else { - recovery_queue.append(s); - Observe(s->GetShip()); - } - - inbound->SetInbound(s); - - // find the best initial approach point for this ship: - double current_distance = 1e9; - for (int i = 0; i < num_approach_pts; i++) { - double distance = Point(inbound->Location() - approach_point[i]).length(); - if (distance < current_distance) { - current_distance = distance; - s->SetApproach(i); - } - } - - Point offset(rand()-16000, rand()-16000, rand()-16000); - offset.Normalize(); - offset *= 200; - - s->SetOffset(offset); - - // *** DEBUG *** - // PrintQueue(); - - // if the new guy is first in line, and the deck is almost ready, - // go ahead and clear him for approach now - recovery_queue.sort(); - if (recovery_queue[0] == s && !s->Cleared() && slots[0].time <= 3) - s->Clear(); - - return recovery_queue.index(s) + 1; - } - - return 0; -} - -void -FlightDeck::GrantClearance() -{ - if (recovery_queue.size() > 0) { - if (recovery_queue[0]->Cleared() && recovery_queue[0]->Distance() > 45e3) { - recovery_queue[0]->Clear(false); - } - - if (!recovery_queue[0]->Cleared()) { - recovery_queue.sort(); - - if (recovery_queue[0]->Distance() < 35e3) { - recovery_queue[0]->Clear(); - - Ship* dst = recovery_queue[0]->GetShip(); - - RadioMessage* clearance = new RadioMessage(dst, carrier, RadioMessage::CALL_CLEARANCE); - clearance->SetInfo(Text("for final approach to ") + Name()); - RadioTraffic::Transmit(clearance); - } - } - } -} - -// +----------------------------------------------------------------------+ - -void -FlightDeck::PrintQueue() -{ - Print("\nRecovery Queue for %s\n", Name()); - if (recovery_queue.size() < 1) { - Print(" (empty)\n\n"); - return; - } - - for (int i = 0; i < recovery_queue.size(); i++) { - InboundSlot* s = recovery_queue.at(i); - - if (!s) { - Print(" %2d. null\n", i); - } - else if (!s->GetShip()) { - Print(" %2d. ship is null\n", i); - } - else { - double d = Point(s->GetShip()->Location() - MountLocation()).length(); - Print(" %2d. %c %-20s %8d km\n", i, s->Cleared()?'*':' ', s->GetShip()->Name(), (int) (d/1000)); - } - } - - Print("\n"); -} - -// +----------------------------------------------------------------------+ - -Ship* -FlightDeck::GetShip(int index) const -{ - if (index >= 0 && index < num_slots) - return slots[index].ship; - - return 0; -} - -double -FlightDeck::TimeRemaining(int index) const -{ - if (index >= 0 && index < num_slots) - return slots[index].time; - - return 0; -} - - -int -FlightDeck::State(int index) const -{ - if (index >= 0 && index < num_slots) - return slots[index].state; - - return 0; -} - -int -FlightDeck::Sequence(int index) const -{ - if (index >= 0 && index < num_slots) - return slots[index].sequence; - - return 0; -} - -// +----------------------------------------------------------------------+ - -bool -FlightDeck::Update(SimObject* obj) -{ - if (obj->Type() == SimObject::SIM_SHIP) { - Ship* s = (Ship*) obj; - - ListIter iter = recovery_queue; - while (++iter) { - InboundSlot* recovery_slot = iter.value(); - - if (recovery_slot->GetShip() == s || recovery_slot->GetShip() == 0) { - delete iter.removeItem(); - } - } - - for (int i = 0; i < num_slots; i++) { - FlightDeckSlot* slot = &slots[i]; - - if (slot->ship == s) { - slot->ship = 0; - slot->state = 0; - slot->sequence = 0; - slot->time = 0; - break; - } - } - } - - return SimObserver::Update(obj); -} - -const char* -FlightDeck::GetObserverName() const -{ - return Name(); -} - -// +----------------------------------------------------------------------+ - -bool -FlightDeck::OverThreshold(Ship* s) const -{ - if (carrier->IsAirborne()) { - if (s->AltitudeAGL() > s->Radius() * 4) - return false; - - const Point& sloc = s->Location(); - - // is ship between the markers? - double distance = 1e9; - - Point d0 = runway_point[0] - sloc; - Point d1 = runway_point[1] - sloc; - double d = d0 * d1; - bool between = (d0 * d1) < 0; - - if (between) { - // distance from point to line: - Point src = runway_point[0]; - Point dir = runway_point[1] - src; - Point w = (sloc - src).cross(dir); - - distance = w.length() / dir.length(); - } - - return distance < Radius(); - } - - else { - return (s->Location() - MountLocation()).length() < (s->Radius() + Radius()); - } -} - -// +----------------------------------------------------------------------+ - -bool -FlightDeck::ContainsPoint(const Point& p) const -{ - return (p - MountLocation()).length() < Radius(); -} diff --git a/Stars45/FlightDeck.h b/Stars45/FlightDeck.h deleted file mode 100644 index b3988c8..0000000 --- a/Stars45/FlightDeck.h +++ /dev/null @@ -1,194 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Everything needed to launch and recover space craft - - See Also: Hangar -*/ - -#ifndef FlightDeck_h -#define FlightDeck_h - -#include "Types.h" -#include "Geometry.h" -#include "System.h" -#include "SimObject.h" -#include "Text.h" - -// +----------------------------------------------------------------------+ - -class Hoop; -class Light; -class Ship; -class ShipDesign; -class FlightDeck; -class FlightDeckSlot; -class InboundSlot; - -// +======================================================================+ - -class InboundSlot : public SimObserver -{ -public: - static const char* TYPENAME() { return "InboundSlot"; } - - InboundSlot() : ship(0), deck(0), squadron(0), slot(0), cleared(0), final(0), approach(0) { } - InboundSlot(Ship* s, FlightDeck* d, int squad, int index); - - int operator < (const InboundSlot& that) const; - int operator <= (const InboundSlot& that) const; - int operator == (const InboundSlot& that) const; - - // SimObserver: - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - Ship* GetShip() { return ship; } - FlightDeck* GetDeck() { return deck; } - int Squadron() { return squadron; } - int Index() { return slot; } - int Cleared() { return cleared; } - int Final() { return final; } - int Approach() { return approach; } - Point Offset() { return offset; } - double Distance(); - - void SetApproach(int a) { approach = a; } - void SetOffset(const Point& p) { offset = p; } - void SetFinal(int f) { final = f; } - void Clear(bool clear=true); - -private: - Ship* ship; - FlightDeck* deck; - int squadron; - int slot; - int cleared; - int final; - int approach; - Point offset; -}; - -// +----------------------------------------------------------------------+ - -class FlightDeck : public System, public SimObserver -{ -public: - static const char* TYPENAME() { return "FlightDeck"; } - - FlightDeck(); - FlightDeck(const FlightDeck& rhs); - virtual ~FlightDeck(); - - enum FLIGHT_DECK_MODE { FLIGHT_DECK_LAUNCH, FLIGHT_DECK_RECOVERY }; - enum FLIGHT_SLOT_STATE { CLEAR, READY, QUEUED, LOCKED, LAUNCH, DOCKING }; - enum CONSTANTS { NUM_APPROACH_PTS = 8 }; - - static void Initialize(); - static void Close(); - - virtual void ExecFrame(double seconds); - void SetCarrier(Ship* s) { ship = carrier = s; } - void SetIndex(int n) { index = n; } - - virtual int SpaceLeft(int type) const; - - virtual bool Spot(Ship* s, int& index); - virtual bool Clear(int index); - virtual bool Launch(int index); - virtual bool LaunchShip(Ship* s); - virtual bool Recover(Ship* s); - virtual bool Dock(Ship* s); - virtual int Inbound(InboundSlot*& s); - virtual void GrantClearance(); - - virtual void AddSlot(const Point& loc, DWORD filter=0xf); - - virtual bool IsLaunchDeck() const { return subtype == FLIGHT_DECK_LAUNCH; } - virtual void SetLaunchDeck() { subtype = FLIGHT_DECK_LAUNCH; } - virtual bool IsRecoveryDeck() const { return subtype == FLIGHT_DECK_RECOVERY; } - virtual void SetRecoveryDeck() { subtype = FLIGHT_DECK_RECOVERY; } - - Point BoundingBox() const { return box; } - Point ApproachPoint(int i) const { return approach_point[i]; } - Point RunwayPoint(int i) const { return runway_point[i]; } - Point StartPoint() const { return start_point; } - Point EndPoint() const { return end_point; } - Point CamLoc() const { return cam_loc; } - double Azimuth() const { return azimuth; } - - virtual void SetBoundingBox(Point dimensions) { box = dimensions; } - virtual void SetApproachPoint(int i, Point loc); - virtual void SetRunwayPoint(int i, Point loc); - virtual void SetStartPoint(Point loc); - virtual void SetEndPoint(Point loc); - virtual void SetCamLoc(Point loc); - virtual void SetCycleTime(double time); - virtual void SetAzimuth(double az) { azimuth = az; } - virtual void SetLight(double l); - - virtual void Orient(const Physical* rep); - - // SimObserver: - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - // accessors: - int NumSlots() const { return num_slots; } - double TimeRemaining(int index) const; - int State(int index) const; - int Sequence(int index) const; - const Ship* GetCarrier() const { return carrier; } - int GetIndex() const { return index; } - Ship* GetShip(int index) const; - int NumHoops() const { return num_hoops; } - Hoop* GetHoops() const { return hoops; } - Light* GetLight() { return light; } - - List& GetRecoveryQueue() { return recovery_queue; } - void PrintQueue(); - - bool OverThreshold(Ship* s) const; - bool ContainsPoint(const Point& p) const; - -protected: - Ship* carrier; - int index; - int num_slots; - FlightDeckSlot* slots; - - Point box; - Point start_rel; - Point end_rel; - Point cam_rel; - Point approach_rel[NUM_APPROACH_PTS]; - Point runway_rel[2]; - - Point start_point; - Point end_point; - Point cam_loc; - Point approach_point[NUM_APPROACH_PTS]; - Point runway_point[2]; - - double azimuth; - double cycle_time; - - int num_approach_pts; - int num_catsounds; - int num_hoops; - Hoop* hoops; - Light* light; - List recovery_queue; -}; - -// +----------------------------------------------------------------------+ - -#endif // FlightDeck_h - diff --git a/Stars45/FlightPlanner.cpp b/Stars45/FlightPlanner.cpp deleted file mode 100644 index e8d11c8..0000000 --- a/Stars45/FlightPlanner.cpp +++ /dev/null @@ -1,370 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Flight Planning class for creating navpoint routes for fighter elements. - Used both by the CarrierAI class and the Flight Dialog. -*/ - -#include "FlightPlanner.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Element.h" -#include "Instruction.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "Hangar.h" -#include "FlightDeck.h" -#include "Mission.h" -#include "Contact.h" -#include "Sim.h" -#include "StarSystem.h" -#include "Callsign.h" - -#include "Game.h" -#include "Random.h" - -// +----------------------------------------------------------------------+ - -FlightPlanner::FlightPlanner(Ship* s) -: sim(0), ship(s) -{ - sim = Sim::GetSim(); - - patrol_range = (float) (250e3 + 10e3 * (int) Random(0, 8.9)); -} - -FlightPlanner::~FlightPlanner() -{ } - -// +--------------------------------------------------------------------+ - -void -FlightPlanner::CreatePatrolRoute(Element* elem, int index) -{ - RLoc rloc; - Vec3 dummy(0,0,0); - Point loc = ship->Location(); - double zone = ship->CompassHeading(); - Instruction* instr = 0; - - if (ship->IsAirborne()) - loc.y += 8e3; - else - loc.y += 1e3; - - loc = loc.OtherHand(); - - if (index > 2) - zone += 170*DEGREES; - else if (index > 1) - zone += -90*DEGREES; - else if (index > 0) - zone += 90*DEGREES; - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(loc); - rloc.SetDistance(30e3); - rloc.SetDistanceVar(0); - rloc.SetAzimuth(-10*DEGREES + zone); - rloc.SetAzimuthVar(0); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::VECTOR); - instr->SetSpeed(750); - instr->GetRLoc() = rloc; - - elem->AddNavPoint(instr); - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(loc); - if (ship->IsAirborne()) - rloc.SetDistance(140e3); - else - rloc.SetDistance(220e3); - rloc.SetDistanceVar(50e3); - rloc.SetAzimuth(-20*DEGREES + zone); - rloc.SetAzimuthVar(15*DEGREES); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::PATROL); - instr->SetSpeed(500); - instr->GetRLoc() = rloc; - - elem->AddNavPoint(instr); - - rloc.SetReferenceLoc(&instr->GetRLoc()); - rloc.SetDistance(120e3); - rloc.SetDistanceVar(30e3); - rloc.SetAzimuth(60*DEGREES + zone); - rloc.SetAzimuthVar(20*DEGREES); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::PATROL); - instr->SetSpeed(350); - instr->GetRLoc() = rloc; - - elem->AddNavPoint(instr); - - rloc.SetReferenceLoc(&instr->GetRLoc()); - rloc.SetDistance(120e3); - rloc.SetDistanceVar(30e3); - rloc.SetAzimuth(120*DEGREES + zone); - rloc.SetAzimuthVar(20*DEGREES); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::PATROL); - instr->SetSpeed(350); - instr->GetRLoc() = rloc; - - elem->AddNavPoint(instr); - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(loc); - rloc.SetDistance(40e3); - rloc.SetDistanceVar(0); - rloc.SetAzimuth(180*DEGREES + ship->CompassHeading()); - rloc.SetAzimuthVar(0*DEGREES); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::RTB); - instr->SetSpeed(500); - instr->GetRLoc() = rloc; - - elem->AddNavPoint(instr); -} - -// +--------------------------------------------------------------------+ - -void -FlightPlanner::CreateStrikeRoute(Element* elem, Element* target) -{ - if (!elem) return; - - RLoc rloc; - Vec3 dummy(0,0,0); - Point loc = ship->Location(); - double head = ship->CompassHeading() + 15*DEGREES; - double dist = 30e3; - Instruction* instr = 0; - Ship* tgt_ship = 0; - - if (ship->IsAirborne()) - loc += ship->Cam().vup() * 8e3; - else - loc += ship->Cam().vup() * 1e3; - - loc = loc.OtherHand(); - - if (target) - tgt_ship = target->GetShip(1); - - if (tgt_ship) { - double range = Point(tgt_ship->Location() - ship->Location()).length(); - - if (range < 100e3) - dist = 20e3; - } - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(loc); - rloc.SetDistance(dist); - rloc.SetDistanceVar(0); - rloc.SetAzimuth(head); - rloc.SetAzimuthVar(2*DEGREES); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::VECTOR); - instr->SetSpeed(750); - instr->GetRLoc() = rloc; - - elem->AddNavPoint(instr); - - if (tgt_ship) { - Ship* tgt_ship = target->GetShip(1); - Point tgt = tgt_ship->Location() + tgt_ship->Velocity() * 10; - Point mid = ship->Location() + (tgt - ship->Location()) * 0.5; - double beam = tgt_ship->CompassHeading() + 90*DEGREES; - - if (tgt_ship->IsAirborne()) - tgt += tgt_ship->Cam().vup() * 8e3; - else - tgt += tgt_ship->Cam().vup() * 1e3; - - tgt = tgt.OtherHand(); - mid = mid.OtherHand(); - - if (tgt_ship && tgt_ship->IsStarship()) { - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(tgt); - rloc.SetDistance(60e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(beam); - rloc.SetAzimuthVar(5*DEGREES); - - instr = new Instruction(tgt_ship->GetRegion(), dummy, Instruction::ASSAULT); - instr->SetSpeed(750); - instr->GetRLoc() = rloc; - instr->SetTarget(target->Name()); - instr->SetFormation(Instruction::TRAIL); - - elem->AddNavPoint(instr); - } - - if (tgt_ship && tgt_ship->IsStatic()) { - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(mid); - rloc.SetDistance(60e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(beam); - rloc.SetAzimuthVar(15*DEGREES); - - instr = new Instruction(tgt_ship->GetRegion(), dummy, Instruction::VECTOR); - instr->SetSpeed(750); - instr->GetRLoc() = rloc; - - elem->AddNavPoint(instr); - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(tgt); - rloc.SetDistance(40e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(beam); - rloc.SetAzimuthVar(5*DEGREES); - - int action = Instruction::ASSAULT; - - if (tgt_ship->IsGroundUnit()) - action = Instruction::STRIKE; - - instr = new Instruction(tgt_ship->GetRegion(), dummy, action); - instr->SetSpeed(750); - instr->GetRLoc() = rloc; - instr->SetTarget(target->Name()); - instr->SetFormation(Instruction::TRAIL); - - elem->AddNavPoint(instr); - } - - else if (tgt_ship && tgt_ship->IsDropship()) { - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(tgt); - rloc.SetDistance(60e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(tgt_ship->CompassHeading()); - rloc.SetAzimuthVar(20*DEGREES); - - instr = new Instruction(tgt_ship->GetRegion(), dummy, Instruction::INTERCEPT); - instr->SetSpeed(750); - instr->GetRLoc() = rloc; - instr->SetTarget(target->Name()); - instr->SetFormation(Instruction::SPREAD); - - elem->AddNavPoint(instr); - } - } - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(loc); - rloc.SetDistance(40e3); - rloc.SetDistanceVar(0); - rloc.SetAzimuth(180*DEGREES + ship->CompassHeading()); - rloc.SetAzimuthVar(0*DEGREES); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::RTB); - instr->SetSpeed(500); - instr->GetRLoc() = rloc; - - elem->AddNavPoint(instr); -} - -// +--------------------------------------------------------------------+ - -void -FlightPlanner::CreateEscortRoute(Element* elem, Element* ward) -{ - if (!elem) return; - - RLoc rloc; - Vec3 dummy(0,0,0); - Point loc = ship->Location(); - double head = ship->CompassHeading(); - Instruction* instr = 0; - - if (ship->IsAirborne()) - loc += ship->Cam().vup() * 8e3; - else - loc += ship->Cam().vup() * 1e3; - - loc = loc.OtherHand(); - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(loc); - rloc.SetDistance(30e3); - rloc.SetDistanceVar(0); - rloc.SetAzimuth(head); - rloc.SetAzimuthVar(0); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::VECTOR); - instr->SetSpeed(750); - instr->GetRLoc() = rloc; - - elem->AddNavPoint(instr); - - if (ward && ward->GetShip(1)) { - // follow ward's flight plan: - if (ward->GetFlightPlan().size()) { - ListIter iter = ward->GetFlightPlan(); - - while (++iter) { - Instruction* ward_instr = iter.value(); - - if (ward_instr->Action() != Instruction::RTB) { - rloc.SetReferenceLoc(&ward_instr->GetRLoc()); - rloc.SetDistance(25e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(0); - rloc.SetAzimuthVar(90*DEGREES); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::ESCORT); - instr->SetSpeed(350); - instr->GetRLoc() = rloc; - instr->SetTarget(ward->Name()); - - elem->AddNavPoint(instr); - } - } - } - - // if ward has no flight plan, just go to a point nearby: - else { - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(ward->GetShip(1)->Location()); - rloc.SetDistance(25e3); - rloc.SetDistanceVar(5e3); - rloc.SetAzimuth(0); - rloc.SetAzimuthVar(90*DEGREES); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::DEFEND); - instr->SetSpeed(500); - instr->GetRLoc() = rloc; - instr->SetTarget(ward->Name()); - instr->SetHoldTime(15 * 60); // fifteen minutes - - elem->AddNavPoint(instr); - } - } - - rloc.SetReferenceLoc(0); - rloc.SetBaseLocation(loc); - rloc.SetDistance(40e3); - rloc.SetDistanceVar(0); - rloc.SetAzimuth(180*DEGREES + ship->CompassHeading()); - rloc.SetAzimuthVar(0*DEGREES); - - instr = new Instruction(ship->GetRegion(), dummy, Instruction::RTB); - instr->SetSpeed(500); - instr->GetRLoc() = rloc; - - elem->AddNavPoint(instr); -} diff --git a/Stars45/FlightPlanner.h b/Stars45/FlightPlanner.h deleted file mode 100644 index cef9a79..0000000 --- a/Stars45/FlightPlanner.h +++ /dev/null @@ -1,50 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Flight Planning class for creating navpoint routes for fighter elements. - Used both by the CarrierAI class and the Flight Dialog. -*/ - -#ifndef FlightPlanner_h -#define FlightPlanner_h - -#include "Types.h" -#include "Director.h" - -// +--------------------------------------------------------------------+ - -class Sim; -class Ship; -class ShipAI; -class Instruction; -class Hangar; -class Element; - -// +--------------------------------------------------------------------+ - -class FlightPlanner -{ -public: - FlightPlanner(Ship* s); - virtual ~FlightPlanner(); - - virtual void CreatePatrolRoute(Element* elem, int index); - virtual void CreateStrikeRoute(Element* strike, Element* target); - virtual void CreateEscortRoute(Element* escort, Element* ward); - - Sim* sim; - Ship* ship; - float patrol_range; -}; - -// +--------------------------------------------------------------------+ - -#endif // FlightPlanner_h - diff --git a/Stars45/FltDlg.cpp b/Stars45/FltDlg.cpp deleted file mode 100644 index 5c3fe1b..0000000 --- a/Stars45/FltDlg.cpp +++ /dev/null @@ -1,1084 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "FltDlg.h" -#include "GameScreen.h" -#include "Sim.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Hangar.h" -#include "FlightDeck.h" -#include "Element.h" -#include "CombatGroup.h" -#include "Mission.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "Instruction.h" -#include "FlightPlanner.h" -#include "NetUtil.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Button.h" -#include "ListBox.h" -#include "ComboBox.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: -DEF_MAP_CLIENT(FltDlg, OnFilter); -DEF_MAP_CLIENT(FltDlg, OnPackage); -DEF_MAP_CLIENT(FltDlg, OnAlert); -DEF_MAP_CLIENT(FltDlg, OnLaunch); -DEF_MAP_CLIENT(FltDlg, OnStandDown); -DEF_MAP_CLIENT(FltDlg, OnRecall); -DEF_MAP_CLIENT(FltDlg, OnClose); -DEF_MAP_CLIENT(FltDlg, OnMissionType); - -// +--------------------------------------------------------------------+ - -static const ShipDesign* design = 0; - -// +--------------------------------------------------------------------+ - -FltDlg::FltDlg(Screen* s, FormDef& def, GameScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -ship(0), filter_list(0), hangar_list(0), -package_btn(0), alert_btn(0), launch_btn(0), stand_btn(0), recall_btn(0), -mission_type(-1), flight_planner(0), patrol_pattern(0) -{ - Init(def); -} - -FltDlg::~FltDlg() -{ - delete flight_planner; -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::RegisterControls() -{ - filter_list = (ComboBox*) FindControl(101); - hangar_list = (ListBox*) FindControl(102); - package_btn = (Button*) FindControl(110); - alert_btn = (Button*) FindControl(111); - launch_btn = (Button*) FindControl(112); - stand_btn = (Button*) FindControl(113); - recall_btn = (Button*) FindControl(114); - close_btn = (Button*) FindControl(1); - - if (filter_list) - REGISTER_CLIENT(EID_SELECT, filter_list, FltDlg, OnFilter); - - if (package_btn) - REGISTER_CLIENT(EID_CLICK, package_btn, FltDlg, OnPackage); - - if (alert_btn) - REGISTER_CLIENT(EID_CLICK, alert_btn, FltDlg, OnAlert); - - if (launch_btn) - REGISTER_CLIENT(EID_CLICK, launch_btn, FltDlg, OnLaunch); - - if (stand_btn) - REGISTER_CLIENT(EID_CLICK, stand_btn, FltDlg, OnStandDown); - - if (recall_btn) - REGISTER_CLIENT(EID_CLICK, recall_btn, FltDlg, OnRecall); - - if (close_btn) - REGISTER_CLIENT(EID_CLICK, close_btn, FltDlg, OnClose); - - for (int i = 0; i < 6; i++) { - mission_btn[i] = (Button*) FindControl(210 + i); - if (mission_btn[i]) - REGISTER_CLIENT(EID_CLICK, mission_btn[i], FltDlg, OnMissionType); - } - - objective_list = (ListBox*) FindControl(221); - loadout_list = (ListBox*) FindControl(222); -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::SetShip(Ship* s) -{ - if (ship != s) { - ship = s; - - delete flight_planner; - flight_planner = 0; - - if (filter_list) { - filter_list->ClearItems(); - - if (ship) { - int nsquadrons = 0; - int nslots = 0; - Hangar* hangar = ship->GetHangar(); - - if (hangar) { - nsquadrons = hangar->NumSquadrons(); - - for (int i = 0; i < nsquadrons; i++) { - char filter[64]; - sprintf_s(filter, "%s %s", - hangar->SquadronDesign(i)->abrv, - hangar->SquadronName(i).data()); - - filter_list->AddItem(filter); - } - - filter_list->AddItem(ContentBundle::GetInstance()->GetText("FltDlg.PENDING")); - filter_list->AddItem(ContentBundle::GetInstance()->GetText("FltDlg.ACTIVE")); - } - - flight_planner = new FlightPlanner(ship); - } - - OnFilter(0); - } - } -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::ExecFrame() -{ - if (!ship || !ship->GetHangar()) { - manager->HideFltDlg(); - } - else { - UpdateSelection(); - UpdateObjective(); - } -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::UpdateSelection() -{ - if (!filter_list || !hangar_list || !ship) return; - - design = 0; - - bool package = false; - bool alert = false; - bool launch = false; - bool stand = false; - bool recall = false; - - Hangar* hangar = ship->GetHangar(); - int seln = filter_list->GetSelectedIndex(); - char txt[32]; - int item; - - // selected squadron: - if (seln < hangar->NumSquadrons()) { - int nslots = hangar->SquadronSize(seln); - - for (item = 0; item < hangar_list->NumItems(); item++) { - int i = hangar_list->GetItemData(item); - const HangarSlot* s = hangar->GetSlot(seln, i); - - if (hangar->GetState(s) == Hangar::UNAVAIL) - hangar_list->SetItemColor(item, Color::DarkGray); - else if (hangar->GetState(s) == Hangar::MAINT) - hangar_list->SetItemColor(item, Color::Gray); - else - hangar_list->SetItemColor(item, Color::White); - - if (hangar->GetState(s) > Hangar::STORAGE) { - if (hangar->GetShip(s)) - hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name()); - else if (hangar->GetPackageElement(s)) - hangar_list->SetItemText(item, 1, hangar->GetPackageElement(s)->Name()); - else - hangar_list->SetItemText(item, 1, hangar->SquadronName(seln)); - - if (hangar->GetPackageElement(s)) - hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type())); - else - hangar_list->SetItemText(item, 3, "--"); - - } - else { - hangar_list->SetItemText(item, 1, "--"); - hangar_list->SetItemText(item, 3, "--"); - } - - hangar_list->SetItemText(item, 2, hangar->StatusName(s)); - - if (hangar->GetState(s) >= Hangar::ACTIVE) { - FormatTime(txt, hangar->GetShip(s)->MissionClock() / 1000); - hangar_list->SetItemText(item, 4, txt); - } - - else if (hangar->GetState(s) == Hangar::MAINT || - hangar->GetState(s) > Hangar::STORAGE) { - FormatTime(txt, hangar->TimeRemaining(s)); - hangar_list->SetItemText(item, 4, txt); - } - - else { - hangar_list->SetItemText(item, 4, ""); - } - - if (hangar_list->IsSelected(item)) { - if (!design) design = hangar->GetDesign(s); - - switch (hangar->GetState(s)) { - case Hangar::STORAGE: alert = true; break; - case Hangar::ALERT: launch = true; - stand = true; break; - case Hangar::QUEUED: stand = true; break; - case Hangar::ACTIVE: recall = true; break; - } - } - } - } - - // selected pending filter: - else if (seln == hangar->NumSquadrons()) { - for (item = 0; item < hangar_list->NumItems(); item++) { - int f = hangar_list->GetItemData(item, 1); - int i = hangar_list->GetItemData(item, 2); - - int squadron = -1; - int slot = -1; - const HangarSlot* s = 0; - - FlightDeck* deck = ship->GetFlightDeck(f); - - if (deck->IsLaunchDeck()) { - int state = deck->State(i); - int seq = deck->Sequence(i); - double time = deck->TimeRemaining(i); - Ship* deckship = deck->GetShip(i); - - if (deckship) { - hangar_list->SetItemText(item, 1, deckship->Name()); - - for (int a = 0; !s && a < hangar->NumSquadrons(); a++) { - for (int b = 0; !s && b < hangar->SquadronSize(a); b++) { - const HangarSlot* test = hangar->GetSlot(a,b); - if (hangar->GetShip(test) == deckship) { - s = test; - squadron = a; - slot = b; - } - } - } - - if (s) { - hangar_list->SetItemText(item, 2, hangar->StatusName(s)); - if (hangar->GetPackageElement(s)) - hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type())); - } - } - else { - hangar_list->SetItemText(item, 1, "--"); - hangar_list->SetItemText(item, 2, ContentBundle::GetInstance()->GetText("FltDlg.Open")); - } - - FormatTime(txt, time); - hangar_list->SetItemText(item, 4, txt); - hangar_list->SetItemData(item, 3, squadron); - hangar_list->SetItemData(item, 4, slot); - - if (hangar_list->IsSelected(item) && s) { - if (!design) design = hangar->GetDesign(s); - - switch (hangar->GetState(s)) { - case Hangar::ALERT: launch = true; - stand = true; break; - case Hangar::QUEUED: stand = true; break; - } - } - } - } - } - - // selected active filter: - else if (seln == hangar->NumSquadrons()+1) { - int last_index = -1; - - for (item = 0; item < hangar_list->NumItems(); item++) { - int squadron = hangar_list->GetItemData(item, 1); - int slot = hangar_list->GetItemData(item, 2); - - int nslots = hangar->SquadronSize(squadron); - - if (slot >= 0 && slot < nslots) { - const HangarSlot* s = hangar->GetSlot(squadron, slot); - - if (hangar->GetState(s) > Hangar::STORAGE) { - if (hangar->GetShip(s)) - hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name()); - else if (hangar->GetPackageElement(s)) - hangar_list->SetItemText(item, 1, hangar->GetPackageElement(s)->Name()); - else - hangar_list->SetItemText(item, 1, hangar->SquadronName(squadron)); - - if (hangar->GetPackageElement(s)) - hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type())); - else - hangar_list->SetItemText(item, 3, "--"); - - hangar_list->SetItemText(item, 2, hangar->StatusName(s)); - - FormatTime(txt, hangar->GetShip(s)->MissionClock() / 1000); - hangar_list->SetItemText(item, 4, txt); - - if (last_index < (int) hangar_list->GetItemData(item)) - last_index = (int) hangar_list->GetItemData(item); - } - else { - hangar_list->RemoveItem(item); - item--; - } - } - else { - hangar_list->RemoveItem(item); - item--; - } - } - - for (int i = 0; i < hangar->NumSquadrons(); i++) { - int nslots = hangar->SquadronSize(i); - - for (int j = 0; j < nslots; j++) { - const HangarSlot* s = hangar->GetSlot(i, j); - - if (hangar->GetState(s) >= Hangar::ACTIVE) { - bool found = false; - - for (int n = 0; !found && n < hangar_list->NumItems(); n++) { - if (hangar_list->GetItemData(n, 1) == (DWORD) i && - hangar_list->GetItemData(n, 2) == (DWORD) j) - found = true; - } - - if (!found) { - last_index++; - - char txt[32]; - sprintf_s(txt, "%2d ", last_index+1); - hangar_list->AddItemWithData(txt, last_index); // use data for sort - - if (hangar->GetShip(s)) - hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name()); - - hangar_list->SetItemText(item, 2, hangar->StatusName(s)); - - if (hangar->GetPackageElement(s)) - hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type())); - - FormatTime(txt, hangar->GetShip(s)->MissionClock() / 1000); - hangar_list->SetItemText(item, 4, txt); - - hangar_list->SetItemData(item, 1, i); - hangar_list->SetItemData(item, 2, j); - - item++; - } - } - } - } - - if (hangar_list->GetSelCount() > 0) - recall = true; - } - - if (package_btn) { - bool pkg_ok = alert && mission_type > -1; - - if (pkg_ok && mission_type > 0) { - pkg_ok = objective_list && - objective_list->GetSelCount() > 0; - - if (pkg_ok) { - int obj_index = objective_list->GetSelection(); - DWORD obj_data = objective_list->GetItemData(obj_index, 2); - - if (obj_data > 1e9) - pkg_ok = false; - } - } - - package_btn->SetEnabled(pkg_ok); - } - - if (alert_btn) { - alert_btn->SetEnabled(alert); - - for (int i = 0; i < 6; i++) - if (mission_btn[i]) - mission_btn[i]->SetEnabled(alert); - } - - if (launch_btn) - launch_btn->SetEnabled(launch); - - if (stand_btn) - stand_btn->SetEnabled(stand); - - if (recall_btn) - recall_btn->SetEnabled(recall); -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::UpdateObjective() -{ - if (!objective_list || mission_type < 0 || !ship) return; - - Sim* sim = Sim::GetSim(); - char txt[32]; - - for (int item = 0; item < objective_list->NumItems(); item++) { - const char* obj_name = objective_list->GetItemText(item); - - Element* elem = sim->FindElement(obj_name); - - // if element has expired, remove it from the objective list - if (!elem || !elem->IsActive() || elem->IsFinished()) { - objective_list->RemoveItem(item); - item--; - } - - // otherwise, the element is still active, so update range/region - else { - Ship* s = elem->GetShip(1); - double r = 0; - bool con = false; - - if (s) { - Point s_loc = s->Location() + s->GetRegion()->Location(); - Point h_loc = ship->Location() + ship->GetRegion()->Location(); - - r = (s_loc - h_loc).length(); - - con = ship->FindContact(s) != 0; - - if (con) { - FormatNumber(txt, r); - } - else { - strcpy_s(txt, ContentBundle::GetInstance()->GetText("FltDlg.Unknown").data()); - r = 2e9; - } - } - - objective_list->SetItemText(item, 1, s->GetRegion()->Name()); - - objective_list->SetItemText(item, 2, txt); - objective_list->SetItemData(item, 2, (DWORD) r); - } - } -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::Show() -{ - if (shown) return; - - FormWindow::Show(); - UpdateSelection(); - UpdateObjective(); -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::Hide() -{ - FormWindow::Hide(); -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::OnFilter(AWEvent* event) -{ - if (!filter_list || !hangar_list) return; - - int seln = filter_list->GetSelectedIndex(); - - hangar_list->ClearItems(); - - if (!ship) return; - - Hangar* hangar = ship->GetHangar(); - - // selected squadron: - if (seln < hangar->NumSquadrons()) { - int nslots = hangar->SquadronSize(seln); - - for (int i = 0; i < nslots; i++) { - char txt[32]; - sprintf_s(txt, " %2d ", i+1); - - const HangarSlot* s = hangar->GetSlot(seln, i); - hangar_list->AddItemWithData(txt, i); - - hangar_list->SetItemText(i, 1, "--"); - hangar_list->SetItemText(i, 2, hangar->StatusName(s)); - - FormatTime(txt, hangar->TimeRemaining(s)); - hangar_list->SetItemText(i, 4, txt); - } - } - - // selected pending filter: - else if (seln == hangar->NumSquadrons()) { - int item = 0; - - for (int f = 0; f < ship->NumFlightDecks(); f++) { - FlightDeck* deck = ship->GetFlightDeck(f); - - if (deck->IsLaunchDeck()) { - for (int i = 0; i < deck->NumSlots(); i++) { - int state = deck->State(i); - int seq = deck->Sequence(i); - double time = deck->TimeRemaining(i); - Ship* deckship = deck->GetShip(i); - - int squadron = -1; - int slot = -1; - - char txt[32]; - sprintf_s(txt, "%d-%d ", f+1, i+1); - - hangar_list->AddItemWithData(txt, item); // use data for sort - - if (deckship) { - hangar_list->SetItemText(item, 1, deckship->Name()); - - const HangarSlot* s = 0; - - for (int a = 0; !s && a < hangar->NumSquadrons(); a++) { - for (int b = 0; !s && b < hangar->SquadronSize(a); b++) { - const HangarSlot* test = hangar->GetSlot(a, b); - if (hangar->GetShip(test) == deckship) { - s = test; - squadron = a; - slot = b; - } - } - } - - if (s) { - hangar_list->SetItemText(item, 2, hangar->StatusName(s)); - if (hangar->GetPackageElement(s)) - hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type())); - } - } - else { - hangar_list->SetItemText(item, 1, "--"); - hangar_list->SetItemText(item, 2, ContentBundle::GetInstance()->GetText("FltDlg.Open")); - } - - - FormatTime(txt, time); - hangar_list->SetItemText(item, 4, txt); - - hangar_list->SetItemData(item, 1, f); - hangar_list->SetItemData(item, 2, i); - hangar_list->SetItemData(item, 3, squadron); - hangar_list->SetItemData(item, 4, slot); - - item++; - } - } - } - } - - // selected active filter: - else if (seln == hangar->NumSquadrons()+1) { - int item = 0; - - for (int i = 0; i < hangar->NumSquadrons(); i++) { - int nslots = hangar->SquadronSize(i); - - for (int j = 0; j < nslots; j++) { - const HangarSlot* s = hangar->GetSlot(i,j); - - if (hangar->GetState(s) >= Hangar::ACTIVE) { - char txt[32]; - sprintf_s(txt, " %2d ", item+1); - - hangar_list->AddItemWithData(txt, item); // use data for sort - - if (hangar->GetShip(s)) - hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name()); - - hangar_list->SetItemText(item, 2, hangar->StatusName(s)); - - if (hangar->GetPackageElement(s)) - hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type())); - - FormatTime(txt, hangar->TimeRemaining(s)); - hangar_list->SetItemText(item, 4, txt); - - hangar_list->SetItemData(item, 1, i); - hangar_list->SetItemData(item, 2, j); - - item++; - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::OnPackage(AWEvent* event) -{ - if (!filter_list || !hangar_list || !ship) return; - - int code = Mission::PATROL; - - switch (mission_type) { - case 0: code = Mission::PATROL; break; - case 1: code = Mission::INTERCEPT; break; - case 2: code = Mission::ASSAULT; break; - case 3: code = Mission::STRIKE; break; - case 4: code = Mission::ESCORT; break; - case 5: code = Mission::INTEL; break; - } - - int squad = filter_list->GetSelectedIndex(); - Hangar* hangar = ship->GetHangar(); - Sim* sim = Sim::GetSim(); - const char* call = sim->FindAvailCallsign(ship->GetIFF()); - Element* elem = sim->CreateElement(call, ship->GetIFF(), code); - Element* tgt = 0; - FlightDeck* deck = 0; - int queue = 1000; - int* load = 0; - - elem->SetSquadron(hangar->SquadronName(squad)); - elem->SetCarrier(ship); - - if (objective_list) { - int index = objective_list->GetListIndex(); - Text target = objective_list->GetItemText(index); - - Instruction* objective = new Instruction(code, target.data()); - elem->AddObjective(objective); - - tgt = sim->FindElement(target.data()); - } - - if (loadout_list && design) { - int index = loadout_list->GetListIndex(); - Text loadname = loadout_list->GetItemText(index); - - ListIter sl = (List&) design->loadouts; - while (++sl && !load) { - if (sl->name == loadname) { - load = sl->load; - elem->SetLoadout(load); - } - } - } - - for (int i = 0; i < ship->NumFlightDecks(); i++) { - FlightDeck* d = ship->GetFlightDeck(i); - - if (d && d->IsLaunchDeck()) { - int dq = hangar->PreflightQueue(d); - - if (dq < queue) { - queue = dq; - deck = d; - } - } - } - - int npackage = 0; - int slots[4]; - - for (int i = 0; i < 4; i++) - slots[i] = -1; - - for (int i = 0; i < hangar_list->NumItems(); i++) { - if (hangar_list->IsSelected(i)) { - int nslot = hangar_list->GetItemData(i); - hangar->GotoAlert(squad, nslot, deck, elem, load, true); - slots[npackage] = nslot; - hangar_list->SetSelected(i, false); - npackage++; - - if (npackage >= 4) - break; - } - } - - NetUtil::SendElemCreate(elem, squad, slots, false); - - if (flight_planner) { - switch (mission_type) { - case 0: - default: - flight_planner->CreatePatrolRoute(elem, patrol_pattern++); - break; - - case 1: - case 2: - case 3: - if (tgt) - flight_planner->CreateStrikeRoute(elem, tgt); - else - flight_planner->CreatePatrolRoute(elem, patrol_pattern++); - break; - - case 4: - if (tgt) - flight_planner->CreateEscortRoute(elem, tgt); - else - flight_planner->CreatePatrolRoute(elem, patrol_pattern++); - break; - } - - if (patrol_pattern < 0 || patrol_pattern > 3) - patrol_pattern = 0; - } -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::OnAlert(AWEvent* event) -{ - if (!filter_list || !hangar_list || !ship) return; - - int squad = filter_list->GetSelectedIndex(); - Hangar* hangar = ship->GetHangar(); - Sim* sim = Sim::GetSim(); - const char* call = sim->FindAvailCallsign(ship->GetIFF()); - Element* elem = sim->CreateElement(call, ship->GetIFF()); - FlightDeck* deck = 0; - int queue = 1000; - const int* load = 0; - - elem->SetSquadron(hangar->SquadronName(squad)); - elem->SetCarrier(ship); - - for (int i = 0; i < ship->NumFlightDecks(); i++) { - FlightDeck* d = ship->GetFlightDeck(i); - - if (d && d->IsLaunchDeck()) { - int dq = hangar->PreflightQueue(d); - - if (dq < queue) { - queue = dq; - deck = d; - } - } - } - - int nalert = 0; - int slots[4]; - - for (int i = 0; i < 4; i++) - slots[i] = -1; - - for (int i = 0; i < hangar_list->NumItems(); i++) { - if (hangar_list->IsSelected(i)) { - int nslot = hangar_list->GetItemData(i); - slots[nalert] = nslot; - - if (!load) { - const HangarSlot* hangar_slot = hangar->GetSlot(squad, nslot); - if (hangar_slot) { - load = hangar->GetLoadout(hangar_slot); - elem->SetLoadout((int*) load); - } - } - - hangar->GotoAlert(squad, nslot, deck, elem); - hangar_list->SetSelected(i, false); - nalert++; - - if (nalert >= 4) - break; - } - } - - NetUtil::SendElemCreate(elem, squad, slots, true); -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::OnLaunch(AWEvent* event) -{ - if (!filter_list || !hangar_list || !ship) return; - - int squad = filter_list->GetSelectedIndex(); - - Hangar* hangar = ship->GetHangar(); - - // selected squadron: - if (squad < hangar->NumSquadrons()) { - for (int i = 0; i < hangar_list->NumItems(); i++) { - if (hangar_list->IsSelected(i)) { - int nslot = hangar_list->GetItemData(i); - hangar->Launch(squad, nslot); - NetUtil::SendShipLaunch(ship, squad, nslot); - } - } - } - - // selected pending filter: - else if (squad == hangar->NumSquadrons()) { - for (int item = 0; item < hangar_list->NumItems(); item++) { - if (hangar_list->IsSelected(item)) { - int squadron = hangar_list->GetItemData(item, 3); - int slot = hangar_list->GetItemData(item, 4); - - if (squadron >= 0 && slot >= 0) { - hangar->Launch(squadron, slot); - NetUtil::SendShipLaunch(ship, squadron, slot); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::OnStandDown(AWEvent* event) -{ - if (!filter_list || !hangar_list || !ship) return; - - int seln = filter_list->GetSelectedIndex(); - - Hangar* hangar = ship->GetHangar(); - - // selected squadron: - if (seln < hangar->NumSquadrons()) { - for (int i = 0; i < hangar_list->NumItems(); i++) { - if (hangar_list->IsSelected(i)) { - int nslot = hangar_list->GetItemData(i); - hangar->StandDown(seln, nslot); - } - } - } - - // selected pending filter: - else if (seln == hangar->NumSquadrons()) { - for (int item = 0; item < hangar_list->NumItems(); item++) { - if (hangar_list->IsSelected(item)) { - int squadron = hangar_list->GetItemData(item, 3); - int slot = hangar_list->GetItemData(item, 4); - - if (squadron >= 0 && slot >= 0) - hangar->StandDown(squadron, slot); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::OnRecall(AWEvent* event) -{ - if (!filter_list || !hangar_list || !ship) return; - - int seln = filter_list->GetSelectedIndex(); - - Hangar* hangar = ship->GetHangar(); - - // selected squadron: or selected active filter: - if (seln < hangar->NumSquadrons() || seln == hangar->NumSquadrons()+1) { - for (int i = 0; i < hangar_list->NumItems(); i++) { - if (hangar_list->IsSelected(i)) { - int nsquad = seln; - int nslot = hangar_list->GetItemData(i); - - if (seln > hangar->NumSquadrons()) { - nsquad = hangar_list->GetItemData(i, 1); - nslot = hangar_list->GetItemData(i, 2); - } - - const HangarSlot* slot = hangar->GetSlot(nsquad, nslot); - Ship* recall = hangar->GetShip(slot); - - if (recall) { - RadioMessage* msg = new RadioMessage(recall, ship, RadioMessage::RTB); - RadioTraffic::Transmit(msg); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::OnMissionType(AWEvent* event) -{ - mission_type = -1; - - for (int i = 0; i < 6; i++) { - if (mission_btn[i]) { - if (mission_btn[i] == event->window) { - mission_btn[i]->SetButtonState(1); - mission_type = i; - } - else { - mission_btn[i]->SetButtonState(0); - } - } - } - - if (objective_list && mission_type > -1) { - objective_list->ClearItems(); - - char txt[32]; - Sim* sim = Sim::GetSim(); - ListIter iter = sim->GetElements(); - - while (++iter) { - Element* elem = iter.value(); - - if (!elem->IsActive() || elem->IsFinished() || elem->IsSquadron()) - continue; - - CombatGroup* group = elem->GetCombatGroup(); - int iff = elem->GetIFF(); - Ship* s = elem->GetShip(1); - double r = 0; - bool con = false; - - if (iff != ship->GetIFF()) { - if (elem->IntelLevel() < Intel::LOCATED) - continue; - - if (group && group->IntelLevel() < Intel::LOCATED) - continue; - } - - if (s) { - Point s_loc = s->Location() + s->GetRegion()->Location(); - Point h_loc = ship->Location() + ship->GetRegion()->Location(); - - r = (s_loc - h_loc).length(); - - con = ship->FindContact(s) != 0; - - if (con) { - FormatNumber(txt, r); - } - else { - strcpy_s(txt, ContentBundle::GetInstance()->GetText("FltDlg.Unknown").data()); - r = 2e9; - } - } - - switch (mission_type) { - case 1: // INTERCEPT - if (iff && iff != ship->GetIFF() && s && s->IsDropship()) { - int item = objective_list->AddItem(elem->Name()) - 1; - objective_list->SetItemText(item, 1, s->GetRegion()->Name()); - - objective_list->SetItemText(item, 2, txt); - objective_list->SetItemData(item, 2, (DWORD) r); - } - break; - - case 2: // ASSAULT - if (iff && iff != ship->GetIFF() && s && (s->IsStarship() || s->IsStatic())) { - int item = objective_list->AddItem(elem->Name()) - 1; - objective_list->SetItemText(item, 1, s->GetRegion()->Name()); - - objective_list->SetItemText(item, 2, txt); - objective_list->SetItemData(item, 2, (DWORD) r); - } - break; - - case 3: // STRIKE - if (iff && iff != ship->GetIFF() && s && s->IsGroundUnit()) { - int item = objective_list->AddItem(elem->Name()) - 1; - objective_list->SetItemText(item, 1, s->GetRegion()->Name()); - - objective_list->SetItemText(item, 2, txt); - objective_list->SetItemData(item, 2, (DWORD) r); - } - break; - - case 4: // ESCORT - if ((iff == 0 || iff == ship->GetIFF()) && (!s || !s->IsStatic())) { - int item = objective_list->AddItem(elem->Name()) - 1; - - if (s) { - objective_list->SetItemText(item, 1, s->GetRegion()->Name()); - objective_list->SetItemText(item, 2, txt); - objective_list->SetItemData(item, 2, (DWORD) r); - } - - else { - objective_list->SetItemText(item, 1, "0"); - objective_list->SetItemData(item, 1, 0); - } - } - break; - - case 5: // SCOUT? - break; - - default: break; - } - } - } - - if (loadout_list && mission_type > -1) { - loadout_list->ClearItems(); - - if (design) { - ListIter sl = (List&) design->loadouts; - while (++sl) { - int item = loadout_list->AddItem(sl->name) - 1; - - char weight[32]; - sprintf_s(weight, "%d kg", (int) ((design->mass + sl->mass) * 1000)); - loadout_list->SetItemText(item, 1, weight); - loadout_list->SetItemData(item, 1, (DWORD) (sl->mass * 1000)); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -FltDlg::OnClose(AWEvent* event) -{ - if (manager) - manager->CloseTopmost(); -} - - - diff --git a/Stars45/FltDlg.h b/Stars45/FltDlg.h deleted file mode 100644 index 2b7872a..0000000 --- a/Stars45/FltDlg.h +++ /dev/null @@ -1,80 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Flight Operations Active Window class -*/ - -#ifndef FltDlg_h -#define FltDlg_h - -#include "Types.h" -#include "FormWindow.h" - -// +--------------------------------------------------------------------+ - -class FlightPlanner; -class GameScreen; -class Ship; - -// +--------------------------------------------------------------------+ - -class FltDlg : public FormWindow -{ -public: - FltDlg(Screen* s, FormDef& def, GameScreen* mgr); - virtual ~FltDlg(); - - virtual void RegisterControls(); - - // Operations: - virtual void Show(); - virtual void Hide(); - - virtual void OnFilter(AWEvent* event); - virtual void OnPackage(AWEvent* event); - virtual void OnAlert(AWEvent* event); - virtual void OnLaunch(AWEvent* event); - virtual void OnStandDown(AWEvent* event); - virtual void OnRecall(AWEvent* event); - virtual void OnClose(AWEvent* event); - virtual void OnMissionType(AWEvent* event); - - virtual void ExecFrame(); - void SetShip(Ship* s); - void UpdateSelection(); - void UpdateObjective(); - -protected: - GameScreen* manager; - - ComboBox* filter_list; - ListBox* hangar_list; - - Button* package_btn; - Button* alert_btn; - Button* launch_btn; - Button* stand_btn; - Button* recall_btn; - Button* close_btn; - - int mission_type; - Button* mission_btn[6]; - - ListBox* objective_list; - ListBox* loadout_list; - - Ship* ship; - FlightPlanner* flight_planner; - - int patrol_pattern; -}; - -#endif // FltDlg_h - diff --git a/Stars45/Font.cpp b/Stars45/Font.cpp deleted file mode 100644 index c3ba23b..0000000 --- a/Stars45/Font.cpp +++ /dev/null @@ -1,1229 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Font Resource class implementation -*/ - -#include "Font.h" -#include "Polygon.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "ParseUtil.h" -#include "Video.h" -#include "Clock.h" - -// +--------------------------------------------------------------------+ - -Font::Font() - : flags(0), height(0), baseline(0), interspace(0), spacewidth(0), - imagewidth(0), image(0), expansion(0), alpha(1), blend(Video::BLEND_ALPHA), - scale(1), material(0), vset(0), polys(0), npolys(0), - caret_index(-1), caret_x(0), caret_y(0), tgt_bitmap(0) -{ - ZeroMemory(name, sizeof(name)); - ZeroMemory(glyph, sizeof(glyph)); - ZeroMemory(kern, sizeof(kern)); -} - -Font::Font(const char* n) - : flags(0), height(0), baseline(0), interspace(0), spacewidth(4), - imagewidth(0), image(0), expansion(0), alpha(1), blend(Video::BLEND_ALPHA), - scale(1), material(0), vset(0), polys(0), npolys(0), - caret_index(-1), caret_x(0), caret_y(0), tgt_bitmap(0) -{ - ZeroMemory(glyph, sizeof(glyph)); - ZeroMemory(kern, sizeof(kern)); - CopyMemory(name, n, sizeof(name)); - - if (!Load(name)) { - flags = 0; - height = 0; - baseline = 0; - interspace = 0; - spacewidth = 0; - imagewidth = 0; - image = 0; - - ZeroMemory(glyph, sizeof(glyph)); - ZeroMemory(kern, sizeof(kern)); - } -} - -// +--------------------------------------------------------------------+ - -Font::~Font() -{ - if (image) delete [] image; - if (vset) delete vset; - if (polys) delete [] polys; - if (material) delete material; -} - -// +--------------------------------------------------------------------+ - -static char kern_tweak[256][256]; - -bool -Font::Load(const char* name) -{ - if (!name || !name[0]) - return false; - - char imgname[256]; - char defname[256]; - wsprintf(defname, "%s.def", name); - wsprintf(imgname, "%s.pcx", name); - - DataLoader* loader = DataLoader::GetLoader(); - if (!loader) - return false; - - LoadDef(defname, imgname); - - for (int i = 0; i < 256; i++) { - glyph[i].offset = GlyphOffset(i); - glyph[i].width = 0; - } - - if (loader->LoadBitmap(imgname, bitmap)) { - if (!bitmap.Pixels() && !bitmap.HiPixels()) - return false; - - scale = bitmap.Width() / 256; - imagewidth = bitmap.Width(); - if (height > bitmap.Height()) - height = bitmap.Height(); - - int imgsize = bitmap.Width() * bitmap.Height(); - image = new BYTE[imgsize]; - - if (image) { - if (bitmap.Pixels()) { - CopyMemory(image, bitmap.Pixels(), imgsize); - } - - else { - for (int i = 0; i < imgsize; i++) - image[i] = (BYTE) bitmap.HiPixels()[i].Alpha(); - } - } - - material = new Material; - material->tex_diffuse = &bitmap; - } - else { - return false; - } - - for (int i = 0; i < 256; i++) { - glyph[i].width = CalcWidth(i); - } - - color = Color::White; - - if (!(flags & (FONT_FIXED_PITCH | FONT_NO_KERN))) - AutoKern(); - - for (int i = 0; i < 256; i++) { - for (int j = 0; j < 256; j++) { - if (kern_tweak[i][j] < 100) { - kern[i][j] = kern_tweak[i][j]; - } - } - } - - return true; -} - -void -Font::LoadDef(char* defname, char* imgname) -{ - for (int i = 0; i < 256; i++) - for (int j = 0; j < 256; j++) - kern_tweak[i][j] = 111; - - DataLoader* loader = DataLoader::GetLoader(); - if (!loader) - return; - - BYTE* block; - int blocklen = loader->LoadBuffer(defname, block, true); - - if (!block || blocklen < 4) - return; - - Parser parser(new BlockReader((const char*) block, blocklen)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("WARNING: could not parse '%s'\n", defname); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "FONT") { - Print("WARNING: invalid font def file '%s'\n", defname); - return; - } - } - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value().indexOf("image") == 0) { - GetDefText(imgname, def, defname); - } - - else if (def->name()->value() == "height") { - int h=0; - GetDefNumber(h, def, defname); - - if (h >= 0 && h <= 32) - height = (BYTE) h; - } - - else if (def->name()->value() == "baseline") { - int b=0; - GetDefNumber(b, def, defname); - - if (b >= 0 && b <= 32) - baseline = (BYTE) b; - } - - else if (def->name()->value() == "flags") { - if (def->term()->isText()) { - Text buf; - GetDefText(buf, def, defname); - buf.setSensitive(false); - - flags = 0; - - if (buf.contains("caps")) - flags = flags | FONT_ALL_CAPS; - - if (buf.contains("kern")) - flags = flags | FONT_NO_KERN; - - if (buf.contains("fixed")) - flags = flags | FONT_FIXED_PITCH; - } - - else { - int f=0; - GetDefNumber(f, def, defname); - flags = (WORD) f; - } - } - - else if (def->name()->value() == "interspace") { - int n=0; - GetDefNumber(n, def, defname); - - if (n >= 0 && n <= 100) - interspace = (BYTE) n; - } - - else if (def->name()->value() == "spacewidth") { - int n=0; - GetDefNumber(n, def, defname); - - if (n >= 0 && n <= 100) - spacewidth = (BYTE) n; - } - - else if (def->name()->value() == "expansion") { - GetDefNumber(expansion, def, defname); - } - - else if (def->name()->value() == "kern") { - TermStruct* val = def->term()->isStruct(); - - char a[8], b[8]; - int k=111; - - a[0] = 0; - b[0] = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "left" || pdef->name()->value() == "a") - GetDefText(a, pdef, defname); - - else if (pdef->name()->value() == "right" || pdef->name()->value() == "b") - GetDefText(b, pdef, defname); - - else if (pdef->name()->value() == "kern" || pdef->name()->value() == "k") - GetDefNumber(k, pdef, defname); - } - } - - if (k < 100) - kern_tweak[a[0]][b[0]] = k; - } - - else { - Print("WARNING: unknown object '%s' in '%s'\n", - def->name()->value().data(), defname); - } - } - else { - Print("WARNING: term ignored in '%s'\n", defname); - term->print(); - } - } - } - while (term); - - loader->ReleaseBuffer(block); - -} - -// +--------------------------------------------------------------------+ - -static const int pipe_width = 16; -static const int char_width = 16; -static const int char_height = 16; -static const int row_items = 16; -static const int row_width = row_items * char_width; -static const int row_size = char_height * row_width; - -int -Font::GlyphOffset(BYTE c) const -{ - if (flags & FONT_ALL_CAPS) - if (islower(c)) - c = toupper(c); - - return (c/row_items * row_size * scale * scale + - c%row_items * char_width * scale); -} - -int -Font::GlyphLocationX(BYTE c) const -{ - if (flags & FONT_ALL_CAPS) - if (islower(c)) - c = toupper(c); - - return c%row_items * char_width; -} - -int -Font::GlyphLocationY(BYTE c) const -{ - if (flags & FONT_ALL_CAPS) - if (islower(c)) - c = toupper(c); - - return c/row_items * char_height; -} - -// +--------------------------------------------------------------------+ - -int -Font::CalcWidth(BYTE c) const -{ - if (c >= PIPE_NBSP && c <= ARROW_RIGHT) - return pipe_width; - - if (c >= 128 || !image) - return 0; - - // all digits should be same size: - if (isdigit(c)) - c = '0'; - - int result = 0; - int w = 16 * scale; - int h = 16 * scale; - - BYTE* src = image + GlyphOffset(c); - - for (int y = 0; y < h; y++) { - BYTE* pleft = src; - - for (int x = 0; x < w; x++) { - if (*pleft++ > 0 && x > result) - result = x; - } - - src += imagewidth; - } - - return result + 2; -} - -// +--------------------------------------------------------------------+ - -struct FontKernData -{ - double l[32]; - double r[32]; -}; - -void -Font::FindEdges(BYTE c, double* l, double* r) -{ - if (!image) - return; - - int w = glyph[c].width; - int h = height; - - if (h > 32) - h = 32; - - BYTE* src = image + GlyphOffset(c); - - for (int y = 0; y < h; y++) { - BYTE* pleft = src; - BYTE* pright = src+w-1; - - *l = -1; - *r = -1; - - for (int x = 0; x < w; x++) { - if (*l == -1 && *pleft != 0) - *l = x + 1 - (double) *pleft/255.0; - if (*r == -1 && *pright != 0) - *r = x + 1 - (double) *pright/255.0; - - pleft++; - pright--; - } - - src += imagewidth; - l++; - r++; - } -} - -static bool nokern(char c) -{ - if (c <= Font::ARROW_RIGHT) - return true; - - const char* nokernchars = "0123456789+=<>-.,:;?'\""; - - if (strchr(nokernchars, c)) - return true; - - return false; -} - -void -Font::AutoKern() -{ - FontKernData* data = new FontKernData[256]; - - if (!data) - return; - - int h = height; - if (h > 32) h = 32; - - int i, j; - - // first, compute row edges for each glyph: - - for (i = 0; i < 256; i++) { - ZeroMemory(&data[i], sizeof(FontKernData)); - - char c = i; - - if ((flags & FONT_ALL_CAPS) && islower(c)) - c = toupper(c); - - if (glyph[(BYTE) c].width > 0) { - FindEdges((BYTE) c, data[i].l, data[i].r); - } - } - - // then, compute the appropriate kern for each pair. - // use a desired average distance of one pixel, - // with a desired minimum distance of more than half a pixel: - - double desired_avg = 2.5 + expansion; - double desired_min = 1; - - for (i = 0; i < 256; i++) { - for (j = 0; j < 256; j++) { - // no kerning between digits or dashes: - if (nokern(i) || nokern(j)) { - kern[i][j] = (char) 0; - } - - else { - double delta = 0; - double avg = 0; - double min = 2500; - int n = 0; - - for (int y = 0; y < h; y++) { - if (data[i].r[y] >= 0 && data[j].l[y] >= 0) { - delta = data[i].r[y] + data[j].l[y]; - avg += delta; - if (delta < min) - min = delta; - - n++; - } - } - - if (n > 0) { - avg /= n; - - delta = desired_avg - avg; - - if (delta < desired_min - min) { - delta = ceil(desired_min - min); - - if (i == 'T' && islower(j) && !(flags & FONT_ALL_CAPS)) - delta += 1; - } - } - else { - delta = 0; - } - - kern[i][j] = (char) delta; - } - } - } - - delete [] data; -} - -// +--------------------------------------------------------------------+ - -int -Font::CharWidth(char c) const -{ - if (flags & FONT_ALL_CAPS) - if (islower(c)) - c = toupper(c); - - int result = 0; - - if (c >= PIPE_NBSP && c <= ARROW_RIGHT) - result = pipe_width; - - else if (c < 0 || isspace(c)) - result = spacewidth; - - else - result = glyph[c].width + interspace; - - return result; -} - -int -Font::SpaceWidth() const -{ - return spacewidth; -} - -int -Font::KernWidth(char a, char b) const -{ - if (flags & FONT_ALL_CAPS) { - if (islower(a)) a = toupper(a); - if (islower(b)) b = toupper(b); - } - - return kern[a][b]; -} - -void -Font::SetKern(char a, char b, int k) -{ - if (k < -100 || k > 100) - return; - - if (flags & FONT_ALL_CAPS) { - if (islower(a)) a = toupper(a); - if (islower(b)) b = toupper(b); - } - - kern[a][b] = (char) k; -} - -// +--------------------------------------------------------------------+ - -int -Font::StringWidth(const char* str, int len) const -{ - int result = 0; - - if (!str) - return result; - - if (!len) - len = strlen(str); - - const char* c = str; - for (int i = 0; i < len; i++) { - if (isspace(*c) && (*c < PIPE_NBSP || *c > ARROW_RIGHT)) - result += spacewidth; - else { - int cc = *c; - if (flags & FONT_ALL_CAPS) - if (islower(cc)) - cc = toupper(cc); - - int k = 0; - if (i < len-1) - k = kern[cc][str[i+1]]; - - result += glyph[cc].width + interspace + k; - } - c++; - } - - return result; -} - -// +--------------------------------------------------------------------+ - -void -Font::DrawText(const char* text, int count, Rect& text_rect, DWORD flags, Bitmap* tgt) -{ - Rect clip_rect = text_rect; - - if (clip_rect.w < 1 || clip_rect.h < 1) - return; - - tgt_bitmap = tgt; - - if (text && text[0]) { - if (count < 1) - count = strlen(text); - - // single line: - if (flags & DT_SINGLELINE) { - DrawTextSingle(text, count, text_rect, clip_rect, flags); - } - - // multi-line with word wrap: - else if (flags & DT_WORDBREAK) { - DrawTextWrap(text, count, text_rect, clip_rect, flags); - } - - // multi-line with clip: - else { - DrawTextMulti(text, count, text_rect, clip_rect, flags); - } - } - else { - caret_x = text_rect.x + 2; - caret_y = text_rect.y + 2; - } - - // if calc only, update the rectangle: - if (flags & DT_CALCRECT) { - text_rect.h = clip_rect.h; - text_rect.w = clip_rect.w; - } - - // otherwise, draw caret if requested: - else if (caret_index >= 0 && caret_y >= text_rect.y && caret_y <= text_rect.y + text_rect.h) {//caret_y + height < text_rect.y + text_rect.h) { - Video* video = Video::GetInstance(); - Clock* clock = Clock::GetInstance(); - - if (video && (clock->RealTime() / 500) & 1) { - float v[4]; - v[0] = (float) (caret_x + 1); - v[1] = (float) (caret_y); - v[2] = (float) (caret_x + 1); - v[3] = (float) (caret_y + height); - - video->DrawScreenLines(1, v, color, blend); - } - - caret_index = -1; - } - - tgt_bitmap = 0; -} - -// +--------------------------------------------------------------------+ - -static int find_next_word_start(const char* text, int index) -{ - // step through intra-word space: - while (text[index] && isspace(text[index]) && text[index] != '\n') - index++; - - return index; -} - -static int find_next_word_end(const char* text, int index) -{ - if (index < 0) - return index; - - // check for leading newline: - if (text[index] == '\n') - return index; - - // step through intra-word space: - while (text[index] && isspace(text[index])) - index++; - - // step through word: - while (text[index] && !isspace(text[index])) - index++; - - return index-1; -} - -// +--------------------------------------------------------------------+ - -void -Font::DrawTextSingle(const char* text, int count, const Rect& text_rect, Rect& clip_rect, DWORD flags) -{ - // parse the format flags: - bool nodraw = (flags & DT_CALCRECT) ?true:false; - - int align = DT_LEFT; - if (flags & DT_RIGHT) - align = DT_RIGHT; - else if (flags & DT_CENTER) - align = DT_CENTER; - - int max_width = 0; - - int valign = DT_TOP; - if (flags & DT_BOTTOM) valign = DT_BOTTOM; - else if (flags & DT_VCENTER) valign = DT_VCENTER; - - int xoffset = 0; - int yoffset = 0; - - int length = StringWidth(text, count); - if (length < text_rect.w) { - switch (align) { - default: - case DT_LEFT: break; - case DT_RIGHT: xoffset = text_rect.w - length; break; - case DT_CENTER: xoffset = (text_rect.w - length)/2; break; - } - } - - if (Height() < text_rect.h) { - switch (valign) { - default: - case DT_TOP: break; - case DT_BOTTOM: yoffset = text_rect.h - Height(); break; - case DT_VCENTER: yoffset = (text_rect.h - Height())/2; break; - } - } - - max_width = length; - - // if calc only, update the rectangle: - if (nodraw) { - clip_rect.h = Height(); - clip_rect.w = max_width; - } - - // otherwise, draw the string now: - else { - int x1 = text_rect.x + xoffset; - int y1 = text_rect.y + yoffset; - - DrawString(text, count, x1, y1, text_rect); - } - - if (caret_index >= 0 && caret_index <= count) { - caret_x = text_rect.x + xoffset; - caret_y = text_rect.y + yoffset; - - if (caret_index > 0) - caret_x += StringWidth(text, caret_index); - } - - else { - caret_x = text_rect.x + 0; - caret_y = text_rect.y + 0; - } -} - -// +--------------------------------------------------------------------+ - -void -Font::DrawTextWrap(const char* text, int count, const Rect& text_rect, Rect& clip_rect, DWORD flags) -{ - // parse the format flags: - bool nodraw = (flags & DT_CALCRECT) ?true:false; - - int align = DT_LEFT; - if (flags & DT_RIGHT) - align = DT_RIGHT; - else if (flags & DT_CENTER) - align = DT_CENTER; - - int nlines = 0; - int max_width = 0; - - int line_start = 0; - int line_count = 0; - int count_remaining = count; - int curr_word_end = -1; - int next_word_end = 0; - int eol_index = 0; - - int xoffset = 0; - int yoffset = 0; - - caret_x = -1; - caret_y = -1; - - // repeat for each line of text: - while (count_remaining > 0) { - int length = 0; - - // find the end of the last whole word that fits on the line: - for (;;) { - next_word_end = find_next_word_end(text, curr_word_end+1); - - if (next_word_end < 0 || next_word_end == curr_word_end) - break; - - if (text[next_word_end] == '\n') { - eol_index = curr_word_end = next_word_end; - break; - } - - int word_len = next_word_end - line_start + 1; - - length = StringWidth(text+line_start, word_len); - - if (length < text_rect.w) { - curr_word_end = next_word_end; - - // check for a newline in the next block of white space: - eol_index = 0; - const char* eol = &text[curr_word_end+1]; - while (*eol && isspace(*eol) && *eol != '\n') - eol++; - - if (*eol == '\n') { - eol_index = eol - text; - break; - } - } - else - break; - } - - line_count = curr_word_end - line_start + 1; - - if (line_count > 0) { - length = StringWidth(text+line_start, line_count); - } - - // there was a single word longer than the entire line: - else { - line_count = next_word_end - line_start + 1; - length = StringWidth(text+line_start, line_count); - curr_word_end = next_word_end; - } - - xoffset = 0; - if (length < text_rect.w) { - switch (align) { - default: - case DT_LEFT: break; - case DT_RIGHT: xoffset = text_rect.w - length; break; - case DT_CENTER: xoffset = (text_rect.w - length)/2; break; - } - } - - if (length > max_width) max_width = length; - - if (eol_index > 0) - curr_word_end = eol_index; - - int next_line_start = find_next_word_start(text, curr_word_end+1); - - if (length > 0 && !nodraw) { - int x1 = text_rect.x + xoffset; - int y1 = text_rect.y + yoffset; - - DrawString(text+line_start, line_count, x1, y1, text_rect); - - if (caret_index == line_start) { - caret_x = x1 - 2; - caret_y = y1; - } - else if (caret_index > line_start && caret_index < next_line_start) { - caret_x = text_rect.x + xoffset + StringWidth(text+line_start, caret_index-line_start) - 2; - caret_y = text_rect.y + yoffset; - } - else if (caret_index == count) { - if (text[count-1] == '\n') { - caret_x = x1 - 2; - caret_y = y1 + height; - } - else { - caret_x = text_rect.x + xoffset + StringWidth(text+line_start, caret_index-line_start) - 2; - caret_y = text_rect.y + yoffset; - } - } - } - - nlines++; - yoffset += Height(); - if (eol_index > 0) - curr_word_end = eol_index; - line_start = find_next_word_start(text, curr_word_end+1); - count_remaining = count - line_start; - } - - // if calc only, update the rectangle: - if (nodraw) { - clip_rect.h = nlines * Height(); - clip_rect.w = max_width; - } -} - -// +--------------------------------------------------------------------+ - -void -Font::DrawTextMulti(const char* text, int count, const Rect& text_rect, Rect& clip_rect, DWORD flags) -{ - // parse the format flags: - bool nodraw = (flags & DT_CALCRECT) ?true:false; - - int align = DT_LEFT; - if (flags & DT_RIGHT) - align = DT_RIGHT; - else if (flags & DT_CENTER) - align = DT_CENTER; - - int max_width = 0; - int line_start = 0; - int count_remaining = count; - - int xoffset = 0; - int yoffset = 0; - int nlines = 0; - - // repeat for each line of text: - while (count_remaining > 0) { - int length = 0; - int line_count = 0; - - // find the end of line: - while (line_count < count_remaining) { - char c = text[line_start+line_count]; - if (!c || c == '\n') - break; - - line_count++; - } - - if (line_count > 0) { - length = StringWidth(text+line_start, line_count); - } - - xoffset = 0; - if (length < text_rect.w) { - switch (align) { - default: - case DT_LEFT: break; - case DT_RIGHT: xoffset = text_rect.w - length; break; - case DT_CENTER: xoffset = (text_rect.w - length)/2; break; - } - } - - if (length > max_width) max_width = length; - - if (length && !nodraw) { - int x1 = text_rect.x + xoffset; - int y1 = text_rect.y + yoffset; - - DrawString(text+line_start, line_count, x1, y1, text_rect); - } - - nlines++; - yoffset += Height(); - - if (line_start+line_count+1 < count) { - line_start = find_next_word_start(text, line_start+line_count+1); - count_remaining = count - line_start; - } - else { - count_remaining = 0; - } - } - - // if calc only, update the rectangle: - if (nodraw) { - clip_rect.h = nlines * Height(); - clip_rect.w = max_width; - } -} - -// +--------------------------------------------------------------------+ - -int -Font::DrawString(const char* str, int len, int x1, int y1, const Rect& clip, Bitmap* tgt) -{ - Video* video = Video::GetInstance(); - int count = 0; - int maxw = clip.w; - int maxh = clip.h; - - if (len < 1 || !video) - return count; - - // vertical clip - if ((y1 < clip.y) || (y1 > clip.y + clip.h)) - return count; - - // RENDER TO BITMAP - - if (!tgt) - tgt = tgt_bitmap; - - if (tgt) { - for (int i = 0; i < len; i++) { - char c = str[i]; - - if ((flags & FONT_ALL_CAPS) && islower(c)) - c = toupper(c); - - int cw = glyph[c].width + interspace; - int ch = height; - int k = 0; - - if (i < len-1) - k = kern[c][str[i+1]]; - - // horizontal clip: - if (x1 < clip.x) { - if (isspace(c) && (c < PIPE_NBSP || c > ARROW_RIGHT)) { - x1 += spacewidth; - maxw -= spacewidth; - } - else { - x1 += cw+k; - maxw -= cw+k; - } - } - else if (x1+cw > clip.x+clip.w) { - return count; - } - else { - if (isspace(c) && (c < PIPE_NBSP || c > ARROW_RIGHT)) { - x1 += spacewidth; - maxw -= spacewidth; - } - else { - int sx = GlyphLocationX(c); - int sy = GlyphLocationY(c); - - Color* srcpix = bitmap.HiPixels(); - Color* dstpix = tgt->HiPixels(); - if (srcpix && dstpix) { - int spitch = bitmap.Width(); - int dpitch = tgt->Width(); - - Color* dst = dstpix + (y1*dpitch) + x1; - Color* src = srcpix + (sy*spitch) + sx; - - for (int i = 0; i < ch; i++) { - Color* ps = src; - Color* pd = dst; - - for (int n = 0; n < cw; n++) { - DWORD alpha = ps->Alpha(); - if (alpha) { - *pd = color.dim(alpha / 240.0); - } - ps++; - pd++; - } - - dst += dpitch; - src += spitch; - } - } - else { - // this probably won't work... - tgt->BitBlt(x1, y1, bitmap, sx, sy, cw, ch, true); - } - - x1 += cw + k; - maxw -= cw + k; - } - - count++; - } - } - return count; - } - - // RENDER TO VIDEO - - // allocate verts, if necessary - int nverts = 4*len; - if (!vset) { - vset = new VertexSet(nverts); - - if (!vset) - return false; - - vset->space = VertexSet::SCREEN_SPACE; - - for (int v = 0; v < vset->nverts; v++) { - vset->s_loc[v].z = 0.0f; - vset->rw[v] = 1.0f; - } - } - else if (vset->nverts < nverts) { - vset->Resize(nverts); - - for (int v = 0; v < vset->nverts; v++) { - vset->s_loc[v].z = 0.0f; - vset->rw[v] = 1.0f; - } - } - - if (vset->nverts < nverts) - return count; - - if (alpha < 1) - color.SetAlpha((BYTE) (alpha * 255.0f)); - else - color.SetAlpha(255); - - for (int i = 0; i < len; i++) { - char c = str[i]; - - if ((flags & FONT_ALL_CAPS) && islower(c)) - c = toupper(c); - - int cw = glyph[c].width + interspace; - int k = 0; - - if (i < len-1) - k = kern[c][str[i+1]]; - - // horizontal clip: - if (x1 < clip.x) { - if (isspace(c) && (c < PIPE_NBSP || c > ARROW_RIGHT)) { - x1 += spacewidth; - maxw -= spacewidth; - } - else { - x1 += cw+k; - maxw -= cw+k; - } - } - else if (x1+cw > clip.x+clip.w) { - break; - } - else { - if (isspace(c) && (c < PIPE_NBSP || c > ARROW_RIGHT)) { - x1 += spacewidth; - maxw -= spacewidth; - } - else { - // create four verts for this character: - int v = count*4; - double char_x = GlyphLocationX(c); - double char_y = GlyphLocationY(c); - double char_w = glyph[c].width; - double char_h = height; - - if (y1 + char_h > clip.y + clip.h) { - char_h = clip.y + clip.h - y1; - } - - vset->s_loc[v+0].x = (float) (x1 - 0.5); - vset->s_loc[v+0].y = (float) (y1 - 0.5); - vset->tu[v+0] = (float) (char_x / 256); - vset->tv[v+0] = (float) (char_y / 256); - vset->diffuse[v+0] = color.Value(); - - vset->s_loc[v+1].x = (float) (x1 + char_w - 0.5); - vset->s_loc[v+1].y = (float) (y1 - 0.5); - vset->tu[v+1] = (float) (char_x / 256 + char_w / 256); - vset->tv[v+1] = (float) (char_y / 256); - vset->diffuse[v+1] = color.Value(); - - vset->s_loc[v+2].x = (float) (x1 + char_w - 0.5); - vset->s_loc[v+2].y = (float) (y1 + char_h - 0.5); - vset->tu[v+2] = (float) (char_x / 256 + char_w / 256); - vset->tv[v+2] = (float) (char_y / 256 + char_h / 256); - vset->diffuse[v+2] = color.Value(); - - vset->s_loc[v+3].x = (float) (x1 - 0.5); - vset->s_loc[v+3].y = (float) (y1 + char_h - 0.5); - vset->tu[v+3] = (float) (char_x / 256); - vset->tv[v+3] = (float) (char_y / 256 + char_h / 256); - vset->diffuse[v+3] = color.Value(); - - x1 += cw + k; - maxw -= cw + k; - - count++; - } - } - } - - if (count) { - // this small hack is an optimization to reduce the - // size of vertex buffer needed for font rendering: - - int old_nverts = vset->nverts; - vset->nverts = 4 * count; - - // create a larger poly array, if necessary: - if (count > npolys) { - if (polys) - delete [] polys; - - npolys = count; - polys = new Poly[npolys]; - Poly* p = polys; - int index = 0; - - for (int i = 0; i < npolys; i++) { - p->nverts = 4; - p->vertex_set = vset; - p->material = material; - p->verts[0] = index++; - p->verts[1] = index++; - p->verts[2] = index++; - p->verts[3] = index++; - - p++; - } - } - - video->DrawScreenPolys(count, polys, blend); - - // remember to restore the proper size of the vertex set: - vset->nverts = old_nverts; - } - - return count; -} - diff --git a/Stars45/Font.h b/Stars45/Font.h deleted file mode 100644 index 6bc85f5..0000000 --- a/Stars45/Font.h +++ /dev/null @@ -1,142 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Font Resource class -*/ - -#ifndef Font_h -#define Font_h - -#include "Types.h" -#include "Bitmap.h" -#include "Color.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -struct Poly; -struct Material; -struct VertexSet; -class Video; - -// +--------------------------------------------------------------------+ - -struct FontChar -{ - short offset; - short width; -}; - -// +--------------------------------------------------------------------+ - -class Font -{ -public: - static const char* TYPENAME() { return "Font"; } - - enum FLAGS { FONT_FIXED_PITCH = 1, - FONT_ALL_CAPS = 2, - FONT_NO_KERN = 4 - }; - - enum CHARS { PIPE_NBSP = 16, - PIPE_VERT = 17, - PIPE_LT = 18, - PIPE_TEE = 19, - PIPE_UL = 20, - PIPE_LL = 21, - PIPE_HORZ = 22, - PIPE_PLUS = 23, - PIPE_MINUS = 24, - ARROW_UP = 25, - ARROW_DOWN = 26, - ARROW_LEFT = 27, - ARROW_RIGHT = 28 - }; - - // default constructor: - Font(); - Font(const char* name); - ~Font(); - - bool Load(const char* name); - - int CharWidth(char c) const; - int SpaceWidth() const; - int KernWidth(char left, char right) const; - int StringWidth(const char* str, int len=0) const; - - void DrawText(const char* txt, int count, Rect& txt_rect, DWORD flags, Bitmap* tgt_bitmap=0); - int DrawString( const char* txt, int len, int x1, int y1, const Rect& clip, Bitmap* tgt_bitmap=0); - - int Height() const { return height; } - int Baseline() const { return baseline; } - WORD GetFlags() const { return flags; } - void SetFlags(WORD s) { flags = s; } - Color GetColor() const { return color; } - void SetColor(const Color& c) { color = c; } - double GetExpansion() const { return expansion; } - void SetExpansion(double e) { expansion = (float) e; } - double GetAlpha() const { return alpha; } - void SetAlpha(double a) { alpha = (float) a; } - int GetBlend() const { return blend; } - void SetBlend(int b) { blend = b; } - - void SetKern(char left, char right, int k=0); - - int GetCaretIndex() const { return caret_index; } - void SetCaretIndex(int n) { caret_index = n; } - -private: - void AutoKern(); - void FindEdges(BYTE c, double* l, double* r); - int CalcWidth(BYTE c) const; - int GlyphOffset(BYTE c) const; - int GlyphLocationX(BYTE c) const; - int GlyphLocationY(BYTE c) const; - - void DrawTextSingle(const char* txt, int count, const Rect& txt_rect, Rect& clip_rect, DWORD flags); - void DrawTextWrap(const char* txt, int count, const Rect& txt_rect, Rect& clip_rect, DWORD flags); - void DrawTextMulti(const char* txt, int count, const Rect& txt_rect, Rect& clip_rect, DWORD flags); - - void LoadDef(char* defname, char* imgname); - - char name[64]; - WORD flags; - BYTE height; - BYTE baseline; - BYTE interspace; - BYTE spacewidth; - float expansion; - float alpha; - int blend; - int scale; - - int caret_index; - int caret_x; - int caret_y; - - int imagewidth; - BYTE* image; - Bitmap bitmap; - Bitmap* tgt_bitmap; - Material* material; - VertexSet* vset; - Poly* polys; - int npolys; - - FontChar glyph[256]; - Color color; - - char kern[256][256]; -}; - -#endif // Font_h - diff --git a/Stars45/FontMgr.cpp b/Stars45/FontMgr.cpp deleted file mode 100644 index 2e1529a..0000000 --- a/Stars45/FontMgr.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Font Resource Manager class implementation -*/ - -#include "FontMgr.h" - -// +--------------------------------------------------------------------+ - -List FontMgr::fonts; - -// +--------------------------------------------------------------------+ - -void -FontMgr::Close() -{ - fonts.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -FontMgr::Register(const char* name, Font* font) -{ - FontItem* item = new FontItem; - - if (item) { - item->name = name; - item->size = 0; - item->font = font; - - fonts.append(item); - } -} - -// +--------------------------------------------------------------------+ - -Font* -FontMgr::Find(const char* name) -{ - ListIter item = fonts; - while (++item) { - if (item->name == name) - return item->font; - } - - return 0; -} diff --git a/Stars45/FontMgr.h b/Stars45/FontMgr.h deleted file mode 100644 index 5b462a8..0000000 --- a/Stars45/FontMgr.h +++ /dev/null @@ -1,49 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Font Resource Manager class -*/ - -#ifndef FontMgr_h -#define FontMgr_h - -#include "Types.h" -#include "Color.h" -#include "List.h" -#include "Text.h" - -class Font; - -// +--------------------------------------------------------------------+ - -struct FontItem -{ - static const char* TYPENAME() { return "FontItem"; } - - Text name; - int size; - Font* font; -}; - -class FontMgr -{ -public: - static const char* TYPENAME() { return "FontMgr"; } - - static void Close(); - static void Register(const char* name, Font* font); - static Font* Find(const char* name); - -private: - static List fonts; -}; - -#endif // FontMgr_h - diff --git a/Stars45/FormDef.cpp b/Stars45/FormDef.cpp deleted file mode 100644 index 853003c..0000000 --- a/Stars45/FormDef.cpp +++ /dev/null @@ -1,1268 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Form and Control Definition Resources -*/ - -#include "FormDef.h" -#include "ParseUtil.h" -#include "DataLoader.h" -#include "Bitmap.h" -#include "Game.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ - -ColumnDef::ColumnDef() -: width(10), align(0), sort(0), color(Color::White), use_color(false) -{ } - -ColumnDef::ColumnDef(const char* t, int w, int a, int s) -: title(t), width(w), align(a), sort(s), -color(Color::White), use_color(false) -{ } - -// +----------------------------------------------------------------------+ - -WinDef::WinDef(DWORD a_id, DWORD a_type, const char* a_text, DWORD a_style) -: id(a_id), pid(0), type(a_type), text(a_text), style(a_style) -{ - rect = Rect(0,0,0,0); - text_align = 0; - single_line = false; - enabled = true; - transparent = false; - hide_partial = true; - back_color = Color::Gray; - base_color = Color::Gray; - fore_color = Color::Black; - fixed_width = 0; - fixed_height = 0; -} - -void WinDef::SetID(DWORD i) { id = i; } -void WinDef::SetParentID(DWORD i) { pid = i; } -void WinDef::SetType(DWORD t) { type = t; } -void WinDef::SetRect(const Rect& r) { rect = r; } -void WinDef::SetEnabled(bool e) { enabled = e; } -void WinDef::SetStyle(DWORD s) { style = s; } -void WinDef::SetFont(const char* t) { font = t; } -void WinDef::SetText(const char* t) { text = t; } -void WinDef::SetAltText(const char* t) { alt_text = t; } -void WinDef::SetTexture(const char* t) { texture = t; } -void WinDef::SetBackColor(Color c) { back_color = c; } -void WinDef::SetBaseColor(Color c) { base_color = c; } -void WinDef::SetForeColor(Color c) { fore_color = c; } -void WinDef::SetTextAlign(DWORD a) { text_align = a; } -void WinDef::SetSingleLine(bool a) { single_line = a; } -void WinDef::SetTransparent(bool t) { transparent = t; } -void WinDef::SetHidePartial(bool a) { hide_partial = a; } - -void WinDef::SetMargins(const Insets& m) { margins = m; } -void WinDef::SetTextInsets(const Insets& t) { text_insets = t; } -void WinDef::SetCellInsets(const Insets& c) { cell_insets = c; } -void WinDef::SetCells(const Rect& r) { cells = r; } - -// +----------------------------------------------------------------------+ - -#define CTRL_DEF_ANIMATED 0x0001 -#define CTRL_DEF_BORDER 0x0002 -#define CTRL_DEF_DROP_SHADOW 0x0004 -#define CTRL_DEF_INDENT 0x0008 -#define CTRL_DEF_INVERT_LABEL 0x0010 -#define CTRL_DEF_GLOW 0x0020 -#define CTRL_DEF_SIMPLE 0x0040 -#define CTRL_DEF_STICKY 0x0080 - -CtrlDef::CtrlDef(DWORD a_id, DWORD a_type, const char* a_text, DWORD a_style) -: WinDef(a_id, a_type, a_text, a_style) -{ - ctrl_flags = CTRL_DEF_ANIMATED | CTRL_DEF_BORDER | CTRL_DEF_INDENT; - bevel_width = 5; - picture_loc = 1; // North - picture_type = Bitmap::BMP_SOLID; - - active = false; - show_headings = false; - - leading = 0; - line_height = 0; - multiselect = 0; - dragdrop = 0; - orientation = 0; - scroll_bar = 1; - num_leds = 1; - - smooth_scroll = false; - - item_style = 0; - selected_style = 0; - pass_char = 0; - - items.destroy(); - - ZeroMemory(tabs, sizeof(tabs)); - ntabs = 0; -} - -CtrlDef::~CtrlDef() -{ - items.destroy(); - columns.destroy(); -} - -CtrlDef& CtrlDef::operator=(const CtrlDef& ctrl) -{ - WinDef::operator=(ctrl); - - ctrl_flags = ctrl.ctrl_flags; - bevel_width = ctrl.bevel_width; - picture_loc = ctrl.picture_loc; - picture_type = ctrl.picture_type; - - active = ctrl.active; - show_headings = ctrl.show_headings; - - leading = ctrl.leading; - line_height = ctrl.line_height; - multiselect = ctrl.multiselect; - dragdrop = ctrl.dragdrop; - orientation = ctrl.orientation; - scroll_bar = ctrl.scroll_bar; - pass_char = ctrl.pass_char; - active_color = ctrl.active_color; - border_color = ctrl.border_color; - - smooth_scroll = ctrl.smooth_scroll; - - item_style = ctrl.item_style; - selected_style = ctrl.selected_style; - pass_char = ctrl.pass_char; - - standard_image = ctrl.standard_image; - activated_image = ctrl.activated_image; - transition_image = ctrl.transition_image; - - return *this; -} - -int CtrlDef::GetOrientation() const -{ - return orientation; -} - -void CtrlDef::SetOrientation(int o) -{ - orientation = o; -} - -bool CtrlDef::GetActive() const -{ - return active; -} - -void CtrlDef::SetActive(bool c) -{ - active = c; -} - -Color CtrlDef::GetActiveColor() const -{ - return active_color; -} - -void CtrlDef::SetActiveColor(Color c) -{ - active_color = c; -} - -bool CtrlDef::GetAnimated() const -{ - return ctrl_flags & CTRL_DEF_ANIMATED; -} - -void CtrlDef::SetAnimated(bool bNewValue) -{ - if (bNewValue) - ctrl_flags |= CTRL_DEF_ANIMATED; - else - ctrl_flags &= ~CTRL_DEF_ANIMATED; -} - -short CtrlDef::GetBevelWidth() const -{ - return bevel_width; -} - -void CtrlDef::SetBevelWidth(short nNewValue) -{ - bevel_width = nNewValue; -} - -bool CtrlDef::GetBorder() const -{ - return (ctrl_flags & CTRL_DEF_BORDER)?true:false; -} - -void CtrlDef::SetBorder(bool bNewValue) -{ - if (bNewValue) - ctrl_flags |= CTRL_DEF_BORDER; - else - ctrl_flags &= ~CTRL_DEF_BORDER; -} - -Color CtrlDef::GetBorderColor() const -{ - return border_color; -} - -void CtrlDef::SetBorderColor(Color c) -{ - border_color = c; -} - -bool CtrlDef::GetDropShadow() const -{ - return (ctrl_flags & CTRL_DEF_DROP_SHADOW)?true:false; -} - -void CtrlDef::SetDropShadow(bool bNewValue) -{ - if (bNewValue) - ctrl_flags |= CTRL_DEF_DROP_SHADOW; - else - ctrl_flags &= ~CTRL_DEF_DROP_SHADOW; -} - -bool CtrlDef::GetIndent() const -{ - return (ctrl_flags & CTRL_DEF_INDENT)?true:false; -} - -void CtrlDef::SetIndent(bool bNewValue) -{ - if (bNewValue) - ctrl_flags |= CTRL_DEF_INDENT; - else - ctrl_flags &= ~CTRL_DEF_INDENT; -} - -bool CtrlDef::GetInvertLabel() const -{ - return (ctrl_flags & CTRL_DEF_INVERT_LABEL)?true:false; -} - -void CtrlDef::SetInvertLabel(bool bNewValue) -{ - if (bNewValue) - ctrl_flags |= CTRL_DEF_INVERT_LABEL; - else - ctrl_flags &= ~CTRL_DEF_INVERT_LABEL; -} - -Text CtrlDef::GetPicture() const -{ - return picture; -} - -void CtrlDef::SetPicture(const Text& img_name) -{ - picture = img_name; -} - -short CtrlDef::GetPictureLocation() const -{ - return picture_loc; -} - -void CtrlDef::SetPictureLocation(short nNewValue) -{ - picture_loc = nNewValue; -} - -short CtrlDef::GetPictureType() const -{ - return picture_type; -} - -void CtrlDef::SetPictureType(short nNewValue) -{ - picture_type = nNewValue; -} - -bool CtrlDef::GetSticky() const -{ - return (ctrl_flags & CTRL_DEF_STICKY)?true:false; -} - -void CtrlDef::SetSticky(bool bNewValue) -{ - if (bNewValue) - ctrl_flags |= CTRL_DEF_STICKY; - else - ctrl_flags &= ~CTRL_DEF_STICKY; -} - -int CtrlDef::GetNumLeds() const -{ - return num_leds; -} - -void CtrlDef::SetNumLeds(int n) -{ - if (n > 0) - num_leds = n; -} - -int CtrlDef::NumItems() const -{ - return items.size(); -} - -Text CtrlDef::GetItem(int i) const -{ - Text result; - - if (i >= 0 && i < items.size()) - result = *(items[i]); - - return result; -} - -void CtrlDef::AddItem(const char* t) -{ - items.append(new Text(t)); -} - -int CtrlDef::NumColumns() const -{ - return columns.size(); -} - -ColumnDef* CtrlDef::GetColumn(int i) const -{ - ColumnDef* result = 0; - - if (i >= 0 && i < columns.size()) - result = columns[i]; - - return result; -} - -void CtrlDef::AddColumn(const char* t, int w, int a, int s) -{ - columns.append(new ColumnDef(t,w,a,s)); -} - -int CtrlDef::NumTabs() const -{ - return ntabs; -} - -int CtrlDef::GetTab(int i) const -{ - if (i >= 0 && i < ntabs) - return tabs[i]; - return 0; -} - -void CtrlDef::SetTab(int i, int t) -{ - if (i >= 0 && i < 10) { - tabs[i] = t; - if (i >= ntabs) - ntabs = i+1; - } -} - -void CtrlDef::AddTab(int i) -{ - if (ntabs < 10) - tabs[ntabs++] = i; -} - -bool CtrlDef::GetShowHeadings() const -{ - return show_headings; -} - -void CtrlDef::SetShowHeadings(bool bNewValue) -{ - show_headings = bNewValue; -} - -int CtrlDef::GetLeading() const -{ - return leading; -} - -void CtrlDef::SetLeading(int nNewValue) -{ - leading = nNewValue; -} - -int CtrlDef::GetLineHeight() const -{ - return line_height; -} - -void CtrlDef::SetLineHeight(int nNewValue) -{ - line_height = nNewValue; -} - -int CtrlDef::GetMultiSelect() const -{ - return multiselect; -} - -void CtrlDef::SetMultiSelect(int nNewValue) -{ - multiselect = nNewValue; -} - -int CtrlDef::GetDragDrop() const -{ - return dragdrop; -} - -void CtrlDef::SetDragDrop(int nNewValue) -{ - dragdrop = nNewValue; -} - -int CtrlDef::GetScrollBarVisible() const -{ - return scroll_bar; -} - -void CtrlDef::SetScrollBarVisible(int nNewValue) -{ - scroll_bar = nNewValue; -} - -bool CtrlDef::GetSmoothScroll() const -{ - return smooth_scroll; -} - -void CtrlDef::SetSmoothScroll(bool bNewValue) -{ - smooth_scroll = bNewValue; -} - -short CtrlDef::GetItemStyle() const -{ - return item_style; -} - -void CtrlDef::SetItemStyle(short nNewValue) -{ - item_style = nNewValue; -} - -short CtrlDef::GetSelectedStyle() const -{ - return selected_style; -} - -void CtrlDef::SetSelectedStyle(short nNewValue) -{ - selected_style = nNewValue; -} - -char CtrlDef::GetPasswordChar() const -{ - return pass_char; -} - -void CtrlDef::SetPasswordChar(char nNewValue) -{ - pass_char = nNewValue; -} - -Text CtrlDef::GetStandardImage() const -{ - return standard_image; -} - -void CtrlDef::SetStandardImage(const Text& img_name) -{ - standard_image = img_name; -} - -Text CtrlDef::GetActivatedImage() const -{ - return activated_image; -} - -void CtrlDef::SetActivatedImage(const Text& img_name) -{ - activated_image = img_name; -} - -Text CtrlDef::GetTransitionImage() const -{ - return transition_image; -} - -void CtrlDef::SetTransitionImage(const Text& img_name) -{ - transition_image = img_name; -} - - -// +----------------------------------------------------------------------+ - -FormDef::FormDef(const char* a_text, DWORD a_style) -: WinDef(0, WIN_DEF_FORM, a_text, a_style) -{ -} - -FormDef::~FormDef() -{ - controls.destroy(); -} - -void FormDef::AddCtrl(CtrlDef* def) -{ - if (def) - controls.append(def); -} - -CtrlDef* FormDef::FindCtrl(BYTE ctrl_id) -{ - if (ctrl_id > 0) { - CtrlDef test(ctrl_id, 0); - return controls.find(&test); - } - - return 0; -} - -ListIter -FormDef::GetControls() const -{ - // cast away const - FormDef* f = (FormDef*) this; - return f->controls; -} - -// +----------------------------------------------------------------------+ - -static char filename[64]; -static char path_name[64]; - -void -FormDef::Load(const char* fname) -{ - sprintf_s(filename, "%s.frm", fname); - - Print("Loading Form '%s'\n", fname); - - sprintf_s(path_name, "Screens/"); - - // Load Design File: - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(path_name); - - BYTE* block; - int blocklen = loader->LoadBuffer(filename, block, true); - - if (!block || blocklen < 4) - return; - - Parser parser(new BlockReader((const char*) block, blocklen)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'\n", filename); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "FORM") { - Print("ERROR: invalid form file '%s'\n", filename); - return; - } - } - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "form") { - - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: form structure missing in '%s'\n", filename); - } - else { - FormDef* form = this; - TermStruct* val = def->term()->isStruct(); - - for (int i = 0; i < val->elements()->size(); i++) { - char buf[256]; - - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "text" || - pdef->name()->value() == "caption") { - - GetDefText(buf, pdef, filename); - form->SetText(ContentBundle::GetInstance()->GetText(buf)); - } - - else if (pdef->name()->value() == "id") { - DWORD id; - GetDefNumber(id, pdef, filename); - form->SetID(id); - } - - else if (pdef->name()->value() == "pid") { - DWORD id; - GetDefNumber(id, pdef, filename); - form->SetParentID(id); - } - - else if (pdef->name()->value() == "rect") { - Rect r; - GetDefRect(r, pdef, filename); - form->SetRect(r); - } - - else if (pdef->name()->value() == "font") { - GetDefText(buf, pdef, filename); - form->SetFont(buf); - } - - else if (pdef->name()->value() == "back_color") { - Color c; - GetDefColor(c, pdef, filename); - form->SetBackColor(c); - } - - else if (pdef->name()->value() == "base_color") { - Color c; - GetDefColor(c, pdef, filename); - form->SetBaseColor(c); - } - - else if (pdef->name()->value() == "fore_color") { - Color c; - GetDefColor(c, pdef, filename); - form->SetForeColor(c); - } - - else if (pdef->name()->value() == "margins") { - GetDefInsets(form->margins, pdef, filename); - } - - else if (pdef->name()->value() == "text_insets") { - GetDefInsets(form->text_insets, pdef, filename); - } - - else if (pdef->name()->value() == "cell_insets") { - GetDefInsets(form->cell_insets, pdef, filename); - } - - else if (pdef->name()->value() == "cells") { - GetDefRect(form->cells, pdef, filename); - } - - else if (pdef->name()->value() == "texture") { - GetDefText(buf, pdef, filename); - - if (*buf && !strchr(buf, '.')) - strcat_s(buf, ".pcx"); - - form->SetTexture(buf); - } - - else if (pdef->name()->value() == "transparent") { - bool b; - GetDefBool(b, pdef, filename); - form->SetTransparent(b); - } - - else if (pdef->name()->value() == "style") { - DWORD s; - GetDefNumber(s, pdef, filename); - form->SetStyle(s); - } - - else if (pdef->name()->value() == "align" || - pdef->name()->value() == "text_align") { - DWORD a = DT_LEFT; - - if (GetDefText(buf, pdef, filename)) { - if (!_stricmp(buf, "left")) - a = DT_LEFT; - else if (!_stricmp(buf, "right")) - a = DT_RIGHT; - else if (!_stricmp(buf, "center")) - a = DT_CENTER; - } - - else { - GetDefNumber(a, pdef, filename); - } - - form->SetTextAlign(a); - } - - // layout constraints: - - else if (pdef->name()->value() == "layout") { - - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: layout structure missing in '%s'\n", filename); - } - else { - TermStruct* val = pdef->term()->isStruct(); - ParseLayoutDef(&form->layout, val); - } - } - - // controls: - - else if (pdef->name()->value() == "defctrl") { - - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: defctrl structure missing in '%s'\n", filename); - } - else { - TermStruct* val = pdef->term()->isStruct(); - ParseCtrlDef(&form->defctrl, val); - } - } - - else if (pdef->name()->value() == "ctrl") { - - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: ctrl structure missing in '%s'\n", filename); - } - else { - CtrlDef* ctrl = new CtrlDef; - TermStruct* val = pdef->term()->isStruct(); - - form->AddCtrl(ctrl); - *ctrl = form->defctrl; // copy default params - - ParseCtrlDef(ctrl, val); - } - } - - // end of controls. - } - } // end form params - } // end form struct - } // end form - - else - Print("WARNING: unknown object '%s' in '%s'\n", - def->name()->value().data(), filename); - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - } - } - } - while (term); - - loader->ReleaseBuffer(block); - loader->SetDataPath(0); -} - -void FormDef::ParseCtrlDef(CtrlDef* ctrl, TermStruct* val) -{ - Text buf; - - ctrl->SetText(""); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "text" || - pdef->name()->value() == "caption") { - GetDefText(buf, pdef, filename); - ctrl->SetText(ContentBundle::GetInstance()->GetText(buf)); - } - - else if (pdef->name()->value() == "id") { - DWORD id; - GetDefNumber(id, pdef, filename); - ctrl->SetID(id); - } - - else if (pdef->name()->value() == "pid") { - DWORD id; - GetDefNumber(id, pdef, filename); - ctrl->SetParentID(id); - } - - else if (pdef->name()->value() == "alt") { - GetDefText(buf, pdef, filename); - ctrl->SetAltText(ContentBundle::GetInstance()->GetText(buf)); - } - - else if (pdef->name()->value() == "type") { - DWORD type = WIN_DEF_LABEL; - - GetDefText(buf, pdef, filename); - Text type_name(buf); - - if (type_name == "button") - type = WIN_DEF_BUTTON; - - else if (type_name == "combo") - type = WIN_DEF_COMBO; - - else if (type_name == "edit") - type = WIN_DEF_EDIT; - - else if (type_name == "image") - type = WIN_DEF_IMAGE; - - else if (type_name == "slider") - type = WIN_DEF_SLIDER; - - else if (type_name == "list") - type = WIN_DEF_LIST; - - else if (type_name == "rich" || type_name == "text" || type_name == "rich_text") - type = WIN_DEF_RICH; - - ctrl->SetType(type); - } - - else if (pdef->name()->value() == "rect") { - Rect r; - GetDefRect(r, pdef, filename); - ctrl->SetRect(r); - } - - else if (pdef->name()->value() == "font") { - GetDefText(buf, pdef, filename); - ctrl->SetFont(buf); - } - - else if (pdef->name()->value() == "active_color") { - Color c; - GetDefColor(c, pdef, filename); - ctrl->SetActiveColor(c); - } - - else if (pdef->name()->value() == "back_color") { - Color c; - GetDefColor(c, pdef, filename); - ctrl->SetBackColor(c); - } - - else if (pdef->name()->value() == "base_color") { - Color c; - GetDefColor(c, pdef, filename); - ctrl->SetBaseColor(c); - } - - else if (pdef->name()->value() == "border_color") { - Color c; - GetDefColor(c, pdef, filename); - ctrl->SetBorderColor(c); - } - - else if (pdef->name()->value() == "fore_color") { - Color c; - GetDefColor(c, pdef, filename); - ctrl->SetForeColor(c); - } - - else if (pdef->name()->value() == "texture") { - GetDefText(buf, pdef, filename); - - if (buf.length() > 0 && !buf.contains('.')) - buf.append(".pcx"); - - ctrl->SetTexture(buf); - } - - else if (pdef->name()->value() == "margins") { - GetDefInsets(ctrl->margins, pdef, filename); - } - - else if (pdef->name()->value() == "text_insets") { - GetDefInsets(ctrl->text_insets, pdef, filename); - } - - else if (pdef->name()->value() == "cell_insets") { - GetDefInsets(ctrl->cell_insets, pdef, filename); - } - - else if (pdef->name()->value() == "cells") { - GetDefRect(ctrl->cells, pdef, filename); - } - - else if (pdef->name()->value() == "fixed_width") { - GetDefNumber(ctrl->fixed_width, pdef, filename); - } - - else if (pdef->name()->value() == "fixed_height") { - GetDefNumber(ctrl->fixed_height, pdef, filename); - } - - else if (pdef->name()->value() == "standard_image") { - GetDefText(buf, pdef, filename); - - if (buf.length() > 0 && !buf.contains('.')) - buf.append(".pcx"); - - ctrl->SetStandardImage(buf); - } - - else if (pdef->name()->value() == "activated_image") { - GetDefText(buf, pdef, filename); - - if (buf.length() > 0 && !buf.contains('.')) - buf.append(".pcx"); - - ctrl->SetActivatedImage(buf); - } - - else if (pdef->name()->value() == "transition_image") { - GetDefText(buf, pdef, filename); - - if (buf.length() > 0 && !buf.contains('.')) - buf.append(".pcx"); - - ctrl->SetTransitionImage(buf); - } - - else if (pdef->name()->value() == "picture") { - GetDefText(buf, pdef, filename); - - if (buf.length() > 0 && !buf.contains('.')) - buf.append(".pcx"); - - ctrl->SetPicture(buf); - } - - else if (pdef->name()->value() == "enabled") { - bool e; - GetDefBool(e, pdef, filename); - ctrl->SetEnabled(e); - } - - else if (pdef->name()->value() == "item") { - GetDefText(buf, pdef, filename); - ctrl->AddItem(ContentBundle::GetInstance()->GetText(buf)); - } - - else if (pdef->name()->value() == "tab") { - int tab = 0; - GetDefNumber(tab, pdef, filename); - ctrl->AddTab(tab); - } - - else if (pdef->name()->value() == "column") { - - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: column structure missing in '%s'\n", filename); - } - else { - TermStruct* val = pdef->term()->isStruct(); - ParseColumnDef(ctrl, val); - } - } - - else if (pdef->name()->value() == "orientation") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetOrientation(n); - } - - else if (pdef->name()->value() == "leading") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetLeading(n); - } - - else if (pdef->name()->value() == "line_height") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetLineHeight(n); - } - - else if (pdef->name()->value() == "multiselect") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetMultiSelect(n); - } - - else if (pdef->name()->value() == "dragdrop") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetDragDrop(n); - } - - else if (pdef->name()->value() == "scroll_bar") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetScrollBarVisible(n); - } - - else if (pdef->name()->value() == "smooth_scroll") { - bool b; - GetDefBool(b, pdef, filename); - ctrl->SetSmoothScroll(b); - } - - else if (pdef->name()->value() == "picture_loc") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetPictureLocation((short) n); - } - - else if (pdef->name()->value() == "picture_type") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetPictureType((short) n); - } - - else if (pdef->name()->value() == "style") { - DWORD s; - GetDefNumber(s, pdef, filename); - ctrl->SetStyle(s); - } - - else if (pdef->name()->value() == "align" || - pdef->name()->value() == "text_align") { - DWORD a = DT_LEFT; - - if (GetDefText(buf, pdef, filename)) { - if (!_stricmp(buf, "left")) - a = DT_LEFT; - else if (!_stricmp(buf, "right")) - a = DT_RIGHT; - else if (!_stricmp(buf, "center")) - a = DT_CENTER; - } - - else { - GetDefNumber(a, pdef, filename); - } - - ctrl->SetTextAlign(a); - } - - else if (pdef->name()->value() == "single_line") { - bool single = false; - GetDefBool(single, pdef, filename); - ctrl->SetSingleLine(single); - } - - else if (pdef->name()->value() == "bevel_width") { - DWORD s; - GetDefNumber(s, pdef, filename); - ctrl->SetBevelWidth((short) s); - } - - else if (pdef->name()->value() == "active") { - bool b; - GetDefBool(b, pdef, filename); - ctrl->SetActive(b); - } - - else if (pdef->name()->value() == "animated") { - bool b; - GetDefBool(b, pdef, filename); - ctrl->SetAnimated(b); - } - - else if (pdef->name()->value() == "border") { - bool b; - GetDefBool(b, pdef, filename); - ctrl->SetBorder(b); - } - - else if (pdef->name()->value() == "drop_shadow") { - bool b; - GetDefBool(b, pdef, filename); - ctrl->SetDropShadow(b); - } - - else if (pdef->name()->value() == "show_headings") { - bool b; - GetDefBool(b, pdef, filename); - ctrl->SetShowHeadings(b); - } - - else if (pdef->name()->value() == "sticky") { - bool b; - GetDefBool(b, pdef, filename); - ctrl->SetSticky(b); - } - - else if (pdef->name()->value() == "transparent") { - bool b; - GetDefBool(b, pdef, filename); - ctrl->SetTransparent(b); - } - - else if (pdef->name()->value() == "hide_partial") { - bool b; - GetDefBool(b, pdef, filename); - ctrl->SetHidePartial(b); - } - - else if (pdef->name()->value() == "num_leds") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetNumLeds(n); - } - - else if (pdef->name()->value() == "item_style") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetItemStyle((short) n); - } - - else if (pdef->name()->value() == "selected_style") { - int n; - GetDefNumber(n, pdef, filename); - ctrl->SetSelectedStyle((short) n); - } - - else if (pdef->name()->value() == "password") { - Text password; - GetDefText(password, pdef, filename); - ctrl->SetPasswordChar((char) password[0]); - } - - // layout constraints: - - else if (pdef->name()->value() == "layout") { - - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: layout structure missing in '%s'\n", filename); - } - else { - TermStruct* val = pdef->term()->isStruct(); - ParseLayoutDef(&ctrl->layout, val); - } - } - } - } -} - -void FormDef::ParseColumnDef(CtrlDef* ctrl, TermStruct* val) -{ - Text text; - char buf[256]; - int width = 0; - int align = 0; - int sort = 0; - Color c; - bool use_color = false; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "text" || - pdef->name()->value() == "title") { - GetDefText(buf, pdef, filename); - text = ContentBundle::GetInstance()->GetText(buf); - } - - else if (pdef->name()->value() == "width") { - GetDefNumber(width, pdef, filename); - } - - else if (pdef->name()->value() == "align") { - align = DT_LEFT; - - if (GetDefText(buf, pdef, filename)) { - if (!_stricmp(buf, "left")) - align = DT_LEFT; - else if (!_stricmp(buf, "right")) - align = DT_RIGHT; - else if (!_stricmp(buf, "center")) - align = DT_CENTER; - } - - else { - GetDefNumber(align, pdef, filename); - } - } - - else if (pdef->name()->value() == "sort") { - GetDefNumber(sort, pdef, filename); - } - - else if (pdef->name()->value() == "color") { - GetDefColor(c, pdef, filename); - use_color = true; - } - } - } - - ctrl->AddColumn(text, width, align, sort); - - if (use_color) { - int index = ctrl->NumColumns()-1; - ColumnDef* column = ctrl->GetColumn(index); - - if (column) { - column->color = c; - column->use_color = true; - } - } -} - -void FormDef::ParseLayoutDef(LayoutDef* def, TermStruct* val) -{ - if (!def || !val) - return; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "x_mins" || - pdef->name()->value() == "cols") { - GetDefArray(def->x_mins, pdef, filename); - } - - else - if (pdef->name()->value() == "y_mins" || - pdef->name()->value() == "rows") { - GetDefArray(def->y_mins, pdef, filename); - } - - else - if (pdef->name()->value() == "x_weights" || - pdef->name()->value() == "col_wts") { - GetDefArray(def->x_weights, pdef, filename); - } - - else - if (pdef->name()->value() == "y_weights" || - pdef->name()->value() == "row_wts") { - GetDefArray(def->y_weights, pdef, filename); - } - } - } - -} - - diff --git a/Stars45/FormDef.h b/Stars45/FormDef.h deleted file mode 100644 index b5a7f15..0000000 --- a/Stars45/FormDef.h +++ /dev/null @@ -1,331 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Form and Control Definition Resources -*/ - -#ifndef FormDef_h -#define FormDef_h - -#include -#include "Types.h" -#include "Geometry.h" -#include "Color.h" -#include "Text.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class FormDef; // values defining form style and control placement -class CtrlDef; // values defining control style -class WinDef; // base class for FormDef and CtrlDef -class TermStruct; // used for parsing - -enum WinType { - WIN_DEF_FORM, - WIN_DEF_LABEL, - WIN_DEF_BUTTON, - WIN_DEF_COMBO, - WIN_DEF_EDIT, - WIN_DEF_IMAGE, - WIN_DEF_SLIDER, - WIN_DEF_LIST, - WIN_DEF_RICH -}; - -// +--------------------------------------------------------------------+ - -class ColumnDef -{ -public: - static const char* TYPENAME() { return "ColumnDef"; } - - ColumnDef(); - ColumnDef(const char* title, int width, int align, int sort); - - Text title; - int width; - int align; - int sort; - Color color; - bool use_color; -}; - -// +--------------------------------------------------------------------+ - -class LayoutDef -{ -public: - static const char* TYPENAME() { return "LayoutDef"; } - - std::vector x_mins; - std::vector y_mins; - std::vector x_weights; - std::vector y_weights; -}; - -// +--------------------------------------------------------------------+ - -class WinDef -{ - friend class FormDef; - -public: - static const char* TYPENAME() { return "WinDef"; } - - WinDef(DWORD id, DWORD type, const char* text=0, DWORD style=0); - virtual ~WinDef() { } - - int operator == (const WinDef& w) const { return id == w.id; } - - DWORD GetID() const { return id; } - void SetID(DWORD id); - DWORD GetParentID() const { return pid; } - void SetParentID(DWORD id); - DWORD GetType() const { return type; } - void SetType(DWORD type); - - void SetRect(const Rect& r); - Rect GetRect() const { return rect; } - int GetX() const { return rect.x; } - int GetY() const { return rect.y; } - int GetW() const { return rect.w; } - int GetH() const { return rect.h; } - - void SetEnabled(bool enable=true); - bool IsEnabled() const { return enabled; } - - void SetStyle(DWORD s); - DWORD GetStyle() const { return style; } - - void SetFont(const char* t); - const Text& GetFont() const { return font; } - void SetText(const char* t); - const Text& GetText() const { return text; } - void SetAltText(const char* t); - const Text& GetAltText() const { return alt_text; } - void SetTexture(const char* t); - const Text& GetTexture() const { return texture; } - - void SetBackColor(Color c); - Color GetBackColor() const { return back_color; } - void SetBaseColor(Color c); - Color GetBaseColor() const { return base_color; } - void SetForeColor(Color c); - Color GetForeColor() const { return fore_color; } - void SetSingleLine(bool a); - bool GetSingleLine() const { return single_line; } - void SetTextAlign(DWORD a); - DWORD GetTextAlign() const { return text_align; } - void SetTransparent(bool t); - bool GetTransparent() const { return transparent; } - void SetHidePartial(bool a); - bool GetHidePartial() const { return hide_partial;} - - void SetMargins(const Insets& m); - const Insets& GetMargins() const { return margins; } - void SetTextInsets(const Insets& t); - const Insets& GetTextInsets() const { return text_insets; } - void SetCellInsets(const Insets& t); - const Insets& GetCellInsets() const { return cell_insets; } - void SetCells(const Rect& r); - const Rect& GetCells() const { return cells; } - - void SetFixedWidth(int w) { fixed_width = w; } - int GetFixedWidth() const { return fixed_width; } - void SetFixedHeight(int h) { fixed_height = h; } - int GetFixedHeight() const { return fixed_height;} - - const LayoutDef& GetLayout() const { return layout; } - -protected: - DWORD id; - DWORD pid; - DWORD type; - Rect rect; - Text font; - Text text; - Text alt_text; - Text texture; - Text picture; - DWORD style; - DWORD text_align; - bool single_line; - bool enabled; - bool transparent; - bool hide_partial; - Color back_color; - Color base_color; - Color fore_color; - - Insets margins; - Insets text_insets; - Insets cell_insets; - Rect cells; - int fixed_width; - int fixed_height; - - LayoutDef layout; -}; - -// +--------------------------------------------------------------------+ - -class CtrlDef : public WinDef -{ -public: - static const char* TYPENAME() { return "CtrlDef"; } - - CtrlDef(DWORD id=0, DWORD type=WIN_DEF_LABEL, const char* text=0, DWORD style=0); - virtual ~CtrlDef(); - - virtual CtrlDef& operator=(const CtrlDef& ctrl); - - bool GetActive() const; - void SetActive(bool c); - Color GetActiveColor() const; - void SetActiveColor(Color c); - bool GetAnimated() const; - void SetAnimated(bool bNewValue); - short GetBevelWidth() const; - void SetBevelWidth(short nNewValue); - bool GetBorder() const; - void SetBorder(bool bNewValue); - Color GetBorderColor() const; - void SetBorderColor(Color c); - bool GetDropShadow() const; - void SetDropShadow(bool bNewValue); - bool GetIndent() const; - void SetIndent(bool bNewValue); - bool GetInvertLabel() const; - void SetInvertLabel(bool bNewValue); - int GetOrientation() const; - void SetOrientation(int o); - Text GetPicture() const; - void SetPicture(const Text& img_name); - short GetPictureLocation() const; - void SetPictureLocation(short nNewValue); - short GetPictureType() const; - void SetPictureType(short nNewValue); - bool GetSticky() const; - void SetSticky(bool bNewValue); - int GetNumLeds() const; - void SetNumLeds(int nNewValue); - - int NumItems() const; - Text GetItem(int i) const; - void AddItem(const char* t); - - int NumColumns() const; - ColumnDef* GetColumn(int i) const; - void AddColumn(const char* t, int w, int a, int s); - - int NumTabs() const; - int GetTab(int i) const; - void SetTab(int i, int t); - void AddTab(int i); - - bool GetShowHeadings() const; - void SetShowHeadings(bool bNewValue); - int GetLeading() const; - void SetLeading(int nNewValue); - int GetLineHeight() const; - void SetLineHeight(int nNewValue); - int GetMultiSelect() const; - void SetMultiSelect(int nNewValue); - int GetDragDrop() const; - void SetDragDrop(int nNewValue); - int GetScrollBarVisible() const; - void SetScrollBarVisible(int nNewValue); - bool GetSmoothScroll() const; - void SetSmoothScroll(bool bNewValue); - - short GetItemStyle() const; - void SetItemStyle(short nNewValue); - short GetSelectedStyle() const; - void SetSelectedStyle(short nNewValue); - - char GetPasswordChar() const; - void SetPasswordChar(char c); - - Text GetStandardImage() const; - void SetStandardImage(const Text& img_name); - Text GetActivatedImage() const; - void SetActivatedImage(const Text& img_name); - Text GetTransitionImage() const; - void SetTransitionImage(const Text& img_name); - -protected: - WORD ctrl_flags; - short bevel_width; - - Color active_color; - Color border_color; - - Text picture; - short picture_loc; - short picture_type; - - Text standard_image; - Text activated_image; - Text transition_image; - - bool active; - bool show_headings; - int leading; - int line_height; - int multiselect; - int dragdrop; - int scroll_bar; - int orientation; - int num_leds; - - short item_style; - short selected_style; - - bool smooth_scroll; - - List items; - List columns; - - int ntabs; - int tabs[10]; - char pass_char; -}; - -// +--------------------------------------------------------------------+ - -class FormDef : public WinDef -{ -public: - static const char* TYPENAME() { return "FormDef"; } - - FormDef(const char* text=0, DWORD style=0); - virtual ~FormDef(); - - void Load(const char* filename); - - void AddCtrl(CtrlDef* def); - CtrlDef* FindCtrl(BYTE ctrl_id); - - ListIter GetControls() const; - -protected: - void ParseCtrlDef(CtrlDef* ctrl, TermStruct* val); - void ParseColumnDef(CtrlDef* ctrl, TermStruct* val); - void ParseLayoutDef(LayoutDef* def, TermStruct* val); - - CtrlDef defctrl; - List controls; -}; - -// +--------------------------------------------------------------------+ - -#endif // FormDef_h - diff --git a/Stars45/FormWindow.cpp b/Stars45/FormWindow.cpp deleted file mode 100644 index e58042d..0000000 --- a/Stars45/FormWindow.cpp +++ /dev/null @@ -1,807 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Form Window class -*/ - -#include "FormWindow.h" -#include "Screen.h" -#include "DataLoader.h" -#include "Font.h" -#include "FontMgr.h" - -#include "Button.h" -#include "ComboBox.h" -#include "EditBox.h" -#include "ImageBox.h" -#include "ListBox.h" -#include "RichTextBox.h" -#include "Slider.h" - -// +--------------------------------------------------------------------+ - -FormWindow::FormWindow(Screen* screen, int ax, int ay, int aw, int ah, -DWORD aid, DWORD s, ActiveWindow* pParent) -: ActiveWindow(screen, ax, ay, aw, ah, aid, s, pParent) -{ - char buf[32]; - sprintf_s(buf, "Form %d", id); //-V576 - desc = buf; -} - -// +--------------------------------------------------------------------+ - -FormWindow::~FormWindow() -{ -} - -// +--------------------------------------------------------------------+ - -void -FormWindow::Init() -{ -} - -// +--------------------------------------------------------------------+ - -void -FormWindow::Destroy() -{ - Hide(); - children.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -FormWindow::AddControl(ActiveWindow* ctrl) -{ - if (ctrl) { - if (!children.contains(ctrl)) - children.append(ctrl); - - ctrl->SetForm(this); - - if (!shown) - ctrl->Hide(); - } -} - -// +--------------------------------------------------------------------+ - -Button* -FormWindow::CreateButton(const char* btn_text, int ax, int ay, int aw, int ah, DWORD aid, DWORD pid) -{ - Button* button = 0; - ActiveWindow* parent = this; - - if (pid) - parent = FindControl(pid); - - button = new Button(parent, ax, ay, aw, ah, aid); - - if (button) { - button->SetForm(this); - button->SetText(btn_text); - - if (!shown) - button->Hide(); - } - - return button; -} - -// +--------------------------------------------------------------------+ - -ImageBox* -FormWindow::CreateImageBox(const char* lbl_text, int ax, int ay, int aw, int ah, DWORD aid, DWORD pid) -{ - ImageBox* image = 0; - ActiveWindow* parent = this; - - if (pid) - parent = FindControl(pid); - - image = new ImageBox(parent, ax, ay, aw, ah, aid); - - if (image) { - image->SetForm(this); - image->SetText(lbl_text); - - if (!shown) - image->Hide(); - } - - return image; -} - -// +--------------------------------------------------------------------+ - -ActiveWindow* -FormWindow::CreateLabel(const char* label_text, int ax, int ay, int aw, int ah, DWORD aid, DWORD pid, DWORD astyle) -{ - ActiveWindow* label = 0; - ActiveWindow* parent = this; - - if (pid) - parent = FindControl(pid); - - label = new ActiveWindow(screen, ax, ay, aw, ah, aid, astyle, parent); - - if (label) { - label->SetForm(this); - label->SetText(label_text); - - if (!shown) - label->Hide(); - } - - return label; -} - -// +--------------------------------------------------------------------+ - -ListBox* -FormWindow::CreateListBox(const char* lbl_text, int ax, int ay, int aw, int ah, DWORD aid, DWORD pid) -{ - ListBox* list = 0; - ActiveWindow* parent = this; - - if (pid) - parent = FindControl(pid); - - list = new ListBox(parent, ax, ay, aw, ah, aid); - - if (list) { - list->SetForm(this); - - if (!shown) - list->Hide(); - } - - return list; -} - -// +--------------------------------------------------------------------+ - -ComboBox* -FormWindow::CreateComboBox(const char* lbl_text, int ax, int ay, int aw, int ah, DWORD aid, DWORD pid) -{ - ComboBox* combo = 0; - ActiveWindow* parent = this; - - if (pid) - parent = FindControl(pid); - - combo = new ComboBox(parent, ax, ay, aw, ah, aid); - - if (combo) { - combo->SetForm(this); - combo->SetLabel(lbl_text); - - if (!shown) - combo->Hide(); - } - - return combo; -} - -// +--------------------------------------------------------------------+ - -EditBox* -FormWindow::CreateEditBox(const char* lbl_text, int ax, int ay, int aw, int ah, DWORD aid, DWORD pid) -{ - EditBox* edit = 0; - ActiveWindow* parent = this; - - if (pid) - parent = FindControl(pid); - - edit = new EditBox(parent, ax, ay, aw, ah, aid); - - if (edit) { - edit->SetForm(this); - edit->SetText(lbl_text); - - if (!shown) - edit->Hide(); - } - - return edit; -} - -// +--------------------------------------------------------------------+ - -RichTextBox* -FormWindow::CreateRichTextBox(const char* label_text, int ax, int ay, int aw, int ah, DWORD aid, DWORD pid, DWORD astyle) -{ - RichTextBox* rtb = 0; - ActiveWindow* parent = this; - - if (pid) - parent = FindControl(pid); - - rtb = new RichTextBox(parent, ax, ay, aw, ah, aid, astyle); - - if (rtb) { - rtb->SetForm(this); - rtb->SetText(label_text); - - if (!shown) - rtb->Hide(); - } - - return rtb; -} - -// +--------------------------------------------------------------------+ - -Slider* -FormWindow::CreateSlider(const char* label_text, int ax, int ay, int aw, int ah, DWORD aid, DWORD pid, DWORD astyle) -{ - Slider* slider = 0; - ActiveWindow* parent = this; - - if (pid) - parent = FindControl(pid); - - slider = new Slider(parent, ax, ay, aw, ah, aid); - - if (slider) { - slider->SetForm(this); - - if (!shown) - slider->Hide(); - } - - return slider; -} - -// +--------------------------------------------------------------------+ - -void -FormWindow::Init(const FormDef& def) -{ - if (def.GetRect().w > 0 && def.GetRect().h > 0) { - // if form size is specified in def, and it is - // smaller than the current screen size, - // center the form on the display: - - Rect r = def.GetRect(); - - if (r.w < screen->Width()) { - r.x = (screen->Width() - r.w) / 2; - } - else { - r.x = 0; - r.w = screen->Width(); - } - - if (r.h < screen->Height()) { - r.y = (screen->Height() - r.h) / 2; - } - else { - r.y = 0; - r.h = screen->Height(); - } - - MoveTo(r); - } - - SetMargins(def.GetMargins()); - SetTextInsets(def.GetTextInsets()); - SetCellInsets(def.GetCellInsets()); - SetCells(def.GetCells()); - SetFixedWidth(def.GetFixedWidth()); - SetFixedHeight(def.GetFixedHeight()); - - UseLayout(def.GetLayout().x_mins, - def.GetLayout().y_mins, - def.GetLayout().x_weights, - def.GetLayout().y_weights); - - if (def.GetTexture().length() > 0) { - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Screens/"); - loader->LoadTexture(def.GetTexture(), texture); - loader->SetDataPath(""); - } - - SetBackColor(def.GetBackColor()); - SetForeColor(def.GetForeColor()); - - Font* f = FontMgr::Find(def.GetFont()); - if (f) SetFont(f); - - SetTransparent(def.GetTransparent()); - - ListIter ctrl = def.GetControls(); - while (++ctrl) { - switch (ctrl->GetType()) { - case WIN_DEF_FORM: - case WIN_DEF_LABEL: - default: - CreateDefLabel(*ctrl); - break; - - case WIN_DEF_BUTTON: - CreateDefButton(*ctrl); - break; - - case WIN_DEF_COMBO: - CreateDefCombo(*ctrl); - break; - - case WIN_DEF_IMAGE: - CreateDefImage(*ctrl); - break; - - case WIN_DEF_EDIT: - CreateDefEdit(*ctrl); - break; - - case WIN_DEF_LIST: - CreateDefList(*ctrl); - break; - - case WIN_DEF_SLIDER: - CreateDefSlider(*ctrl); - break; - - case WIN_DEF_RICH: - CreateDefRichText(*ctrl); - break; - } - } - - RegisterControls(); - DoLayout(); - CalcGrid(); -} - -// +--------------------------------------------------------------------+ - -void -FormWindow::CreateDefLabel(CtrlDef& def) -{ - ActiveWindow* ctrl = CreateLabel(def.GetText(), - def.GetX(), - def.GetY(), - def.GetW(), - def.GetH(), - def.GetID(), - def.GetParentID(), - def.GetStyle()); - - ctrl->SetAltText(def.GetAltText()); - ctrl->SetBackColor(def.GetBackColor()); - ctrl->SetForeColor(def.GetForeColor()); - ctrl->SetTextAlign(def.GetTextAlign()); - ctrl->SetSingleLine(def.GetSingleLine()); - ctrl->SetTransparent(def.GetTransparent()); - ctrl->SetHidePartial(def.GetHidePartial()); - - ctrl->SetMargins(def.GetMargins()); - ctrl->SetTextInsets(def.GetTextInsets()); - ctrl->SetCellInsets(def.GetCellInsets()); - ctrl->SetCells(def.GetCells()); - ctrl->SetFixedWidth(def.GetFixedWidth()); - ctrl->SetFixedHeight(def.GetFixedHeight()); - - ctrl->UseLayout(def.GetLayout().x_mins, - def.GetLayout().y_mins, - def.GetLayout().x_weights, - def.GetLayout().y_weights); - - if (def.GetTexture().length() > 0) { - Bitmap* ctrl_tex = 0; - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Screens/"); - loader->LoadTexture(def.GetTexture(), ctrl_tex); - loader->SetDataPath(""); - - ctrl->SetTexture(ctrl_tex); - } - - Font* f = FontMgr::Find(def.GetFont()); - if (f) ctrl->SetFont(f); -} - -void -FormWindow::CreateDefButton(CtrlDef& def) -{ - Button* ctrl = CreateButton(def.GetText(), - def.GetX(), - def.GetY(), - def.GetW(), - def.GetH(), - def.GetID(), - def.GetParentID()); - - if (def.GetStandardImage().length()) { - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Screens/"); - - Bitmap* bmp = 0; - loader->LoadTexture(def.GetStandardImage(), bmp); - ctrl->SetStandardImage(bmp); - - if (def.GetActivatedImage().length()) { - loader->LoadTexture(def.GetActivatedImage(), bmp); - ctrl->SetActivatedImage(bmp); - } - - if (def.GetTransitionImage().length()) { - loader->LoadTexture(def.GetTransitionImage(), bmp); - ctrl->SetTransitionImage(bmp); - } - - loader->SetDataPath(""); - } - - ctrl->SetAltText(def.GetAltText()); - ctrl->SetEnabled(def.IsEnabled()); - ctrl->SetBackColor(def.GetBackColor()); - ctrl->SetForeColor(def.GetForeColor()); - ctrl->SetTextAlign(def.GetTextAlign()); - ctrl->SetSingleLine(def.GetSingleLine()); - - ctrl->SetBevelWidth(def.GetBevelWidth()); - ctrl->SetDropShadow(def.GetDropShadow()); - ctrl->SetSticky(def.GetSticky()); - ctrl->SetTransparent(def.GetTransparent()); - ctrl->SetHidePartial(def.GetHidePartial()); - ctrl->SetPictureLocation(def.GetPictureLocation()); - - ctrl->SetMargins(def.GetMargins()); - ctrl->SetTextInsets(def.GetTextInsets()); - ctrl->SetCellInsets(def.GetCellInsets()); - ctrl->SetCells(def.GetCells()); - ctrl->SetFixedWidth(def.GetFixedWidth()); - ctrl->SetFixedHeight(def.GetFixedHeight()); - - if (def.GetPicture().length() > 0) { - Bitmap pict; - int type = def.GetPictureType(); - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Screens/"); - loader->LoadBitmap(def.GetPicture(), pict, type); - loader->SetDataPath(""); - - ctrl->SetPicture(pict); - } - - Font* f = FontMgr::Find(def.GetFont()); - if (f) ctrl->SetFont(f); -} - -void -FormWindow::CreateDefImage(CtrlDef& def) -{ - ImageBox* ctrl = CreateImageBox(def.GetText(), - def.GetX(), - def.GetY(), - def.GetW(), - def.GetH(), - def.GetID(), - def.GetParentID()); - - ctrl->SetAltText(def.GetAltText()); - ctrl->SetBackColor(def.GetBackColor()); - ctrl->SetForeColor(def.GetForeColor()); - ctrl->SetStyle(def.GetStyle()); - ctrl->SetTextAlign(def.GetTextAlign()); - ctrl->SetSingleLine(def.GetSingleLine()); - ctrl->SetTransparent(def.GetTransparent()); - ctrl->SetHidePartial(def.GetHidePartial()); - - ctrl->SetMargins(def.GetMargins()); - ctrl->SetTextInsets(def.GetTextInsets()); - ctrl->SetCellInsets(def.GetCellInsets()); - ctrl->SetCells(def.GetCells()); - ctrl->SetFixedWidth(def.GetFixedWidth()); - ctrl->SetFixedHeight(def.GetFixedHeight()); - - if (def.GetPicture().length() > 0) { - Bitmap picture; - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Screens/"); - loader->LoadBitmap(def.GetPicture(), picture); - loader->SetDataPath(""); - - ctrl->SetPicture(picture); - } - - Font* f = FontMgr::Find(def.GetFont()); - if (f) ctrl->SetFont(f); -} - -void -FormWindow::CreateDefList(CtrlDef& def) -{ - ListBox* ctrl = CreateListBox(def.GetText(), - def.GetX(), - def.GetY(), - def.GetW(), - def.GetH(), - def.GetID(), - def.GetParentID()); - - ctrl->SetAltText(def.GetAltText()); - ctrl->SetEnabled(def.IsEnabled()); - ctrl->SetBackColor(def.GetBackColor()); - ctrl->SetForeColor(def.GetForeColor()); - ctrl->SetStyle(def.GetStyle()); - ctrl->SetTextAlign(def.GetTextAlign()); - ctrl->SetTransparent(def.GetTransparent()); - ctrl->SetHidePartial(def.GetHidePartial()); - - ctrl->SetLineHeight(def.GetLineHeight()); - ctrl->SetShowHeadings(def.GetShowHeadings()); - ctrl->SetLeading(def.GetLeading()); - ctrl->SetMultiSelect(def.GetMultiSelect()); - ctrl->SetDragDrop(def.GetDragDrop()); - ctrl->SetScrollBarVisible(def.GetScrollBarVisible()); - ctrl->SetSmoothScroll(def.GetSmoothScroll()); - ctrl->SetItemStyle(def.GetItemStyle()); - ctrl->SetSelectedStyle(def.GetSelectedStyle()); - - ctrl->SetMargins(def.GetMargins()); - ctrl->SetTextInsets(def.GetTextInsets()); - ctrl->SetCellInsets(def.GetCellInsets()); - ctrl->SetCells(def.GetCells()); - ctrl->SetFixedWidth(def.GetFixedWidth()); - ctrl->SetFixedHeight(def.GetFixedHeight()); - - if (def.GetTexture().length() > 0) { - Bitmap* ctrl_tex = 0; - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Screens/"); - loader->LoadTexture(def.GetTexture(), ctrl_tex); - loader->SetDataPath(""); - - ctrl->SetTexture(ctrl_tex); - } - - int ncols = def.NumColumns(); - for (int i = 0; i < ncols; i++) { - ColumnDef* col = def.GetColumn(i); - ctrl->AddColumn(col->title, col->width, col->align, col->sort); - - if (col->use_color) - ctrl->SetColumnColor(i, col->color); - } - - int nitems = def.NumItems(); - for (int i = 0; i < nitems; i++) - ctrl->AddItem(def.GetItem(i)); - - Font* f = FontMgr::Find(def.GetFont()); - if (f) ctrl->SetFont(f); -} - -void -FormWindow::CreateDefCombo(CtrlDef& def) -{ - ComboBox* ctrl = CreateComboBox(def.GetText(), - def.GetX(), - def.GetY(), - def.GetW(), - def.GetH(), - def.GetID(), - def.GetParentID()); - - ctrl->SetAltText(def.GetAltText()); - ctrl->SetEnabled(def.IsEnabled()); - ctrl->SetBackColor(def.GetBackColor()); - ctrl->SetForeColor(def.GetForeColor()); - ctrl->SetTextAlign(def.GetTextAlign()); - - ctrl->SetActiveColor(def.GetActiveColor()); - ctrl->SetBorderColor(def.GetBorderColor()); - ctrl->SetBorder(def.GetBorder()); - ctrl->SetBevelWidth(def.GetBevelWidth()); - ctrl->SetTransparent(def.GetTransparent()); - ctrl->SetHidePartial(def.GetHidePartial()); - - ctrl->SetMargins(def.GetMargins()); - ctrl->SetTextInsets(def.GetTextInsets()); - ctrl->SetCellInsets(def.GetCellInsets()); - ctrl->SetCells(def.GetCells()); - ctrl->SetFixedWidth(def.GetFixedWidth()); - ctrl->SetFixedHeight(def.GetFixedHeight()); - - int nitems = def.NumItems(); - for (int i = 0; i < nitems; i++) - ctrl->AddItem(def.GetItem(i)); - - Font* f = FontMgr::Find(def.GetFont()); - if (f) ctrl->SetFont(f); -} - -void -FormWindow::CreateDefEdit(CtrlDef& def) -{ - EditBox* ctrl = CreateEditBox(def.GetText(), - def.GetX(), - def.GetY(), - def.GetW(), - def.GetH(), - def.GetID(), - def.GetParentID()); - - ctrl->SetAltText(def.GetAltText()); - ctrl->SetEnabled(def.IsEnabled()); - ctrl->SetBackColor(def.GetBackColor()); - ctrl->SetForeColor(def.GetForeColor()); - ctrl->SetStyle(def.GetStyle()); - ctrl->SetSingleLine(def.GetSingleLine()); - ctrl->SetTextAlign(def.GetTextAlign()); - ctrl->SetTransparent(def.GetTransparent()); - ctrl->SetHidePartial(def.GetHidePartial()); - ctrl->SetPasswordChar(def.GetPasswordChar()); - - ctrl->SetMargins(def.GetMargins()); - ctrl->SetTextInsets(def.GetTextInsets()); - ctrl->SetCellInsets(def.GetCellInsets()); - ctrl->SetCells(def.GetCells()); - ctrl->SetFixedWidth(def.GetFixedWidth()); - ctrl->SetFixedHeight(def.GetFixedHeight()); - - ctrl->SetLineHeight(def.GetLineHeight()); - ctrl->SetScrollBarVisible(def.GetScrollBarVisible()); - ctrl->SetSmoothScroll(def.GetSmoothScroll()); - - if (def.GetTexture().length() > 0) { - Bitmap* ctrl_tex = 0; - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Screens/"); - loader->LoadTexture(def.GetTexture(), ctrl_tex); - loader->SetDataPath(""); - - ctrl->SetTexture(ctrl_tex); - } - - Font* f = FontMgr::Find(def.GetFont()); - if (f) ctrl->SetFont(f); -} - -void -FormWindow::CreateDefSlider(CtrlDef& def) -{ - Slider* ctrl = CreateSlider(def.GetText(), - def.GetX(), - def.GetY(), - def.GetW(), - def.GetH(), - def.GetID(), - def.GetParentID()); - - - ctrl->SetAltText(def.GetAltText()); - ctrl->SetEnabled(def.IsEnabled()); - ctrl->SetBackColor(def.GetBackColor()); - ctrl->SetForeColor(def.GetForeColor()); - - ctrl->SetActive(def.GetActive()); - ctrl->SetOrientation(def.GetOrientation()); - ctrl->SetFillColor(def.GetActiveColor()); - ctrl->SetBorderColor(def.GetBorderColor()); - ctrl->SetBorder(def.GetBorder()); - ctrl->SetStyle(def.GetStyle()); - ctrl->SetTransparent(def.GetTransparent()); - ctrl->SetHidePartial(def.GetHidePartial()); - ctrl->SetNumLeds(def.GetNumLeds()); - - ctrl->SetMargins(def.GetMargins()); - ctrl->SetTextInsets(def.GetTextInsets()); - ctrl->SetCellInsets(def.GetCellInsets()); - ctrl->SetCells(def.GetCells()); - ctrl->SetFixedWidth(def.GetFixedWidth()); - ctrl->SetFixedHeight(def.GetFixedHeight()); - - Font* f = FontMgr::Find(def.GetFont()); - if (f) ctrl->SetFont(f); -} - -void -FormWindow::CreateDefRichText(CtrlDef& def) -{ - RichTextBox* ctrl = CreateRichTextBox(def.GetText(), - def.GetX(), - def.GetY(), - def.GetW(), - def.GetH(), - def.GetID(), - def.GetParentID(), - def.GetStyle()); - - ctrl->SetAltText(def.GetAltText()); - ctrl->SetBackColor(def.GetBackColor()); - ctrl->SetForeColor(def.GetForeColor()); - ctrl->SetLineHeight(def.GetLineHeight()); - ctrl->SetLeading(def.GetLeading()); - ctrl->SetScrollBarVisible(def.GetScrollBarVisible()); - ctrl->SetSmoothScroll(def.GetSmoothScroll()); - ctrl->SetTextAlign(def.GetTextAlign()); - ctrl->SetTransparent(def.GetTransparent()); - ctrl->SetHidePartial(def.GetHidePartial()); - - ctrl->SetMargins(def.GetMargins()); - ctrl->SetTextInsets(def.GetTextInsets()); - ctrl->SetCellInsets(def.GetCellInsets()); - ctrl->SetCells(def.GetCells()); - ctrl->SetFixedWidth(def.GetFixedWidth()); - ctrl->SetFixedHeight(def.GetFixedHeight()); - - if (def.GetTexture().length() > 0) { - Bitmap* ctrl_tex = 0; - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Screens/"); - loader->LoadTexture(def.GetTexture(), ctrl_tex); - loader->SetDataPath(""); - - ctrl->SetTexture(ctrl_tex); - } - - Font* f = FontMgr::Find(def.GetFont()); - if (f) ctrl->SetFont(f); - - for (int i = 0; i < def.NumTabs(); i++) - ctrl->SetTabStop(i, def.GetTab(i)); -} - -// +--------------------------------------------------------------------+ - -void -FormWindow::AdoptFormDef(const FormDef& def) -{ - Destroy(); - Init(def); -} - -// +--------------------------------------------------------------------+ - -ActiveWindow* -FormWindow::FindControl(DWORD id) -{ - return FindChild(id); -} - - -// +--------------------------------------------------------------------+ - -ActiveWindow* -FormWindow::FindControl(int x, int y) -{ - ActiveWindow* mouse_tgt = 0; - - ListIter iter = children; - while (++iter) { - ActiveWindow* test = iter.value(); - if (test->TargetRect().Contains(x,y)) { - mouse_tgt = test; - - while (test) { - test = test->FindChild(x,y); - - if (test) - mouse_tgt = test; - } - } - } - - return mouse_tgt; -} - - - diff --git a/Stars45/FormWindow.h b/Stars45/FormWindow.h deleted file mode 100644 index 23681ca..0000000 --- a/Stars45/FormWindow.h +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Form Window class (a window that manages controls) -*/ - -#ifndef FormWindow_h -#define FormWindow_h - -#include "Types.h" -#include "ActiveWindow.h" -#include "FormDef.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Button; -class ComboBox; -class EditBox; -class ImageBox; -class ListBox; -class RichTextBox; -class Slider; - -// +--------------------------------------------------------------------+ - -class FormWindow : public ActiveWindow -{ -public: - FormWindow(Screen* s, int ax, int ay, int aw, int ah, - DWORD aid=0, DWORD style=0, ActiveWindow* parent=0); - virtual ~FormWindow(); - - // operations: - virtual void Init(); - virtual void Init(const FormDef& def); - virtual void Destroy(); - virtual ActiveWindow* FindControl(DWORD id); - virtual ActiveWindow* FindControl(int x, int y); - virtual void RegisterControls() { } - - virtual void AdoptFormDef(const FormDef& def); - virtual void AddControl(ActiveWindow* ctrl); - - virtual ActiveWindow* CreateLabel( const char* text, int x, int y, int w, int h, DWORD id=0, DWORD pid=0, DWORD style=0); - virtual Button* CreateButton( const char* text, int x, int y, int w, int h, DWORD id=0, DWORD pid=0); - virtual ImageBox* CreateImageBox( const char* text, int x, int y, int w, int h, DWORD id=0, DWORD pid=0); - virtual ListBox* CreateListBox( const char* text, int x, int y, int w, int h, DWORD id=0, DWORD pid=0); - virtual ComboBox* CreateComboBox( const char* text, int x, int y, int w, int h, DWORD id=0, DWORD pid=0); - virtual EditBox* CreateEditBox( const char* text, int x, int y, int w, int h, DWORD id=0, DWORD pid=0); - virtual RichTextBox* CreateRichTextBox(const char* text, int x, int y, int w, int h, DWORD id=0, DWORD pid=0, DWORD style=0); - virtual Slider* CreateSlider( const char* text, int x, int y, int w, int h, DWORD id=0, DWORD pid=0, DWORD style=0); - - // property accessors: - ListIter Controls() { return children; } - -protected: - virtual void CreateDefLabel(CtrlDef& def); - virtual void CreateDefButton(CtrlDef& def); - virtual void CreateDefImage(CtrlDef& def); - virtual void CreateDefList(CtrlDef& def); - virtual void CreateDefCombo(CtrlDef& def); - virtual void CreateDefEdit(CtrlDef& def); - virtual void CreateDefSlider(CtrlDef& def); - virtual void CreateDefRichText(CtrlDef& def); -}; - -#endif // FormWindow_h - diff --git a/Stars45/FormatUtil.cpp b/Stars45/FormatUtil.cpp deleted file mode 100644 index fd3ce66..0000000 --- a/Stars45/FormatUtil.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ - -void FormatNumber(char* txt, double n) -{ - double a = fabs(n); - - if (a < 1e3) - sprintf(txt, "%d", (int) (n)); - - else if (a < 1e6) - sprintf(txt, "%.1f K", (n/1e3)); - - else if (a < 1e9) - sprintf(txt, "%.1f M", (n/1e6)); - - else if (a < 1e12) - sprintf(txt, "%.1f G", (n/1e9)); - - else if (a < 1e15) - sprintf(txt, "%.1f T", (n/1e12)); - - else - sprintf(txt, "%.1e", n); -} - -// +--------------------------------------------------------------------+ - -void FormatNumberExp(char* txt, double n) -{ - double a = fabs(n); - - if (a < 100e3) - sprintf(txt, "%d", (int) (n)); - - else - sprintf(txt, "%.1e", n); -} - -// +--------------------------------------------------------------------+ - -const int MINUTE = 60; -const int HOUR = 60 * MINUTE; -const int DAY = 24 * HOUR; - -void FormatTime(char* txt, double time) -{ - int t = (int) time; - - int h = (t / HOUR); - int m = ((t - h*HOUR) / MINUTE); - int s = (t - h*HOUR - m*MINUTE); - - if (h > 0) - sprintf(txt, "%02d:%02d:%02d", h,m,s); - else - sprintf(txt, "%02d:%02d", m,s); -} - -// +--------------------------------------------------------------------+ - -void FormatTimeOfDay(char* txt, double time) -{ - int t = (int) time; - - if (t >= DAY) { - int d = t / DAY; - t -= d * DAY; - } - - int h = (t / HOUR); - int m = ((t - h*HOUR) / MINUTE); - int s = (t - h*HOUR - m*MINUTE); - - sprintf(txt, "%02d:%02d:%02d", h,m,s); -} - -// +--------------------------------------------------------------------+ - -void FormatDayTime(char* txt, double time, bool short_format) -{ - int t = (int) time; - int d = 1, h = 0, m = 0, s = 0; - - if (t >= DAY) { - d = t / DAY; - t -= d * DAY; - d++; - } - - if (t >= HOUR) { - h = t / HOUR; - t -= h * HOUR; - } - - if (t >= MINUTE) { - m = t / MINUTE; - t -= m * MINUTE; - } - - s = t; - - if (short_format) - sprintf(txt, "%02d/%02d:%02d:%02d", d, h, m, s); - else - sprintf(txt, "Day %02d %02d:%02d:%02d", d, h, m, s); -} - -// +--------------------------------------------------------------------+ - -void FormatDay(char* txt, double time) -{ - int t = (int) time; - int d = 1, h = 0, m = 0, s = 0; - - if (t >= DAY) { - d = t / DAY; - t -= d * DAY; - d++; - } - - sprintf(txt, "Day %02d", d); -} - -// +--------------------------------------------------------------------+ - -void FormatPoint(char* txt, const Point& p) -{ - char x[16]; - char y[16]; - char z[16]; - - FormatNumber(x, p.x); - FormatNumber(y, p.y); - FormatNumber(z, p.z); - - sprintf(txt, "(%s, %s, %s)", x, y, z); -} - -// +--------------------------------------------------------------------+ - -Text FormatTimeString(int utc) -{ - static const char* month[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - static const char* meridian[2] = { "AM", "PM" }; - - if (utc < 1) - utc = (int) time(0); - - time_t aclock = utc; // Get time in seconds - struct tm *t = localtime(&aclock); // Convert time to struct tm form - - char buffer[256]; - sprintf(buffer, "%d %s %d, %2d:%02d:%02d %s", - t->tm_mday, month[t->tm_mon], 1900 + t->tm_year, - t->tm_hour > 12 ? t->tm_hour-12 : t->tm_hour, - t->tm_min, t->tm_sec, meridian[t->tm_hour > 12]); - - return buffer; -} - -// +--------------------------------------------------------------------+ - -static char safe_str[2048]; - -const char* SafeString(const char* s) -{ - ZeroMemory(safe_str, sizeof(safe_str)); - - if (s && *s) { - int len = strlen(s); - int n = 0; - - for (int i = 0; i < len; i++) { - char c = s[i]; - - if (c == '\n') { - safe_str[n++] = '\\'; - safe_str[n++] = 'n'; - } - - else if (c == '\t') { - safe_str[n++] = '\\'; - safe_str[n++] = 't'; - } - - else if (c == '"') { - safe_str[n++] = '\''; - } - - else if (c == '\\' && i < len-1) { - safe_str[n++] = s[i++]; - safe_str[n++] = s[i++]; - } - - else if (c < 32 || c > 126) { - // non printing characters - } - - else { - safe_str[n++] = c; - } - - if (n > 2040) - break; - } - } - - return safe_str; -} - -// +--------------------------------------------------------------------+ - -const char* SafeQuotes(const char* msg) -{ - int dst = 0; - - if (msg) { - while (*msg && dst < 254) { - if (*msg == '"') { - safe_str[dst++] = '\''; - msg++; - } - else if (isspace(*msg)) { - safe_str[dst++] = ' '; - msg++; - } - else { - safe_str[dst++] = *msg++; - } - } - } - - safe_str[dst] = 0; - return safe_str; -} - -// +--------------------------------------------------------------------+ - -Text FormatTextReplace(const char* msg, const char* tgt, const char* val) -{ - if (!msg || !tgt || !val) - return ""; - - if (!strchr(msg, *tgt)) - return msg; - - Text result; - char* buffer = new char[strlen(msg) + 1]; - const char* p = msg; - char* q = buffer; - int tgtlen = strlen(tgt); - - while (*p) { - if (!strncmp(p, tgt, tgtlen)) { - p += tgtlen; - *q = 0; - q = buffer; - - result += buffer; - result += val; - } - - else { - *q++ = *p++; - } - } - - if (q != buffer) { - *q = 0; - result += buffer; - } - - delete [] buffer; - return result; -} - -// +--------------------------------------------------------------------+ - -Text FormatTextEscape(const char* msg) -{ - if (!msg) - return ""; - - if (!strchr(msg, '\\')) - return msg; - - Text result; - char* buffer = new char[strlen(msg) + 1]; - const char* p = msg; - char* q = buffer; - - while (*p) { - if (*p == '\\') { - p++; - - if (*p == 'n') { - *q++ = '\n'; - p++; - } - - else if (*p == 't') { - *q++ = '\t'; - p++; - } - - else { - *q++ = *p++; - } - } - - else { - *q++ = *p++; - } - } - - *q = 0; - result = buffer; - delete [] buffer; - return result; -} diff --git a/Stars45/FormatUtil.h b/Stars45/FormatUtil.h deleted file mode 100644 index f0d6b42..0000000 --- a/Stars45/FormatUtil.h +++ /dev/null @@ -1,46 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Text formatting utilities -*/ - -#ifndef FormatUtil_h -#define FormatUtil_h - -#include "Types.h" -#include "Geometry.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -void FormatNumber(char* txt, double n); -void FormatNumberExp(char* txt, double n); -void FormatTime(char* txt, double seconds); -void FormatTimeOfDay(char* txt, double seconds); -void FormatDayTime(char* txt, double seconds, bool short_format=false); -void FormatDay(char* txt, double seconds); -void FormatPoint(char* txt, const Point& p); -Text FormatTimeString(int utc=0); - -const char* SafeString(const char* s); -const char* SafeQuotes(const char* s); - -// scan msg and replace all occurrences of tgt with val -// return new result, leave msg unmodified -Text FormatTextReplace(const char* msg, const char* tgt, const char* val); - -// scan msg and replace all C-style \x escape sequences -// with their single-character values, leave orig unmodified -Text FormatTextEscape(const char* msg); - -// +--------------------------------------------------------------------+ - -#endif // FormatUtil_h - diff --git a/Stars45/Galaxy.cpp b/Stars45/Galaxy.cpp deleted file mode 100644 index 1b5bb6f..0000000 --- a/Stars45/Galaxy.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Galaxy (list of star systems) for a single campaign. -*/ - -#include "Galaxy.h" -#include "StarSystem.h" -#include "Starshatter.h" - -#include "Game.h" -#include "Solid.h" -#include "Sprite.h" -#include "Light.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "ParseUtil.h" - -static Galaxy* galaxy = 0; - -// +--------------------------------------------------------------------+ - -Galaxy::Galaxy(const char* n) - : name(n), radius(10) -{ } - -// +--------------------------------------------------------------------+ - -Galaxy::~Galaxy() -{ - Print(" Destroying Galaxy %s\n", (const char*) name); - systems.destroy(); - stars.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -Galaxy::Initialize() -{ - if (galaxy) delete galaxy; - galaxy = new Galaxy("Galaxy"); - galaxy->Load(); -} - -void -Galaxy::Close() -{ - delete galaxy; - galaxy = 0; -} - -Galaxy* -Galaxy::GetInstance() -{ - return galaxy; -} - -// +--------------------------------------------------------------------+ - -void -Galaxy::Load() -{ - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Galaxy/"); - sprintf_s(filename, "%s.def", (const char*) name); - Load(filename); - - // load mod galaxies: - List mod_galaxies; - loader->SetDataPath("Mods/Galaxy/"); - loader->ListFiles("*.def", mod_galaxies); - - ListIter iter = mod_galaxies; - while (++iter) { - Text* name = iter.value(); - - if (!name->contains("/")) { - loader->SetDataPath("Mods/Galaxy/"); - Load(name->data()); - } - } -} - -void -Galaxy::Load(const char* filename) -{ - Print("\nLoading Galaxy: %s\n", filename); - - BYTE* block = 0; - DataLoader* loader = DataLoader::GetLoader(); - loader->LoadBuffer(filename, block, true); - - Parser parser(new BlockReader((const char*) block)); - - Term* term = parser.ParseTerm(); - - if (!term) { - Print("WARNING: could not parse '%s'\n", filename); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "GALAXY") { - Print("WARNING: invalid galaxy file '%s'\n", filename); - return; - } - } - - // parse the galaxy: - do { - delete term; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "radius") { - GetDefNumber(radius, def, filename); - } - - else if (def->name()->value() == "system") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: system struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - char sys_name[32]; - char classname[32]; - Vec3 sys_loc; - int sys_iff = 0; - int star_class = Star::G; - - sys_name[0] = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") - GetDefText(sys_name, pdef, filename); - - else if (pdef->name()->value() == "loc") - GetDefVec(sys_loc, pdef, filename); - - else if (pdef->name()->value() == "iff") - GetDefNumber(sys_iff, pdef, filename); - - else if (pdef->name()->value() == "class") { - GetDefText(classname, pdef, filename); - - switch (classname[0]) { - case 'O': star_class = Star::O; break; - case 'B': star_class = Star::B; break; - case 'A': star_class = Star::A; break; - case 'F': star_class = Star::F; break; - case 'G': star_class = Star::G; break; - case 'K': star_class = Star::K; break; - case 'M': star_class = Star::M; break; - case 'R': star_class = Star::RED_GIANT; break; - case 'W': star_class = Star::WHITE_DWARF; break; - case 'Z': star_class = Star::BLACK_HOLE; break; - } - } - } - } - - if (sys_name[0]) { - StarSystem* star_system = new StarSystem(sys_name, sys_loc, sys_iff, star_class); - star_system->Load(); - systems.append(star_system); - - Star* star = new Star(sys_name, sys_loc, star_class); - stars.append(star); - } - } - } - - else if (def->name()->value() == "star") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: star struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - char star_name[32]; - char classname[32]; - Vec3 star_loc; - int star_class = Star::G; - - star_name[0] = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") - GetDefText(star_name, pdef, filename); - - else if (pdef->name()->value() == "loc") - GetDefVec(star_loc, pdef, filename); - - else if (pdef->name()->value() == "class") { - GetDefText(classname, pdef, filename); - - switch (classname[0]) { - case 'O': star_class = Star::O; break; - case 'B': star_class = Star::B; break; - case 'A': star_class = Star::A; break; - case 'F': star_class = Star::F; break; - case 'G': star_class = Star::G; break; - case 'K': star_class = Star::K; break; - case 'M': star_class = Star::M; break; - case 'R': star_class = Star::RED_GIANT; break; - case 'W': star_class = Star::WHITE_DWARF; break; - case 'Z': star_class = Star::BLACK_HOLE; break; - } - } - } - } - - if (star_name[0]) { - Star* star = new Star(star_name, star_loc, star_class); - stars.append(star); - } - } - } - } - } - } - while (term); - - loader->ReleaseBuffer(block); - loader->SetDataPath(0); -} - -// +--------------------------------------------------------------------+ - -void -Galaxy::ExecFrame() -{ - ListIter sys = systems; - while (++sys) { - sys->ExecFrame(); - } -} - -// +--------------------------------------------------------------------+ - -StarSystem* -Galaxy::GetSystem(const char* name) -{ - ListIter sys = systems; - while (++sys) { - if (!strcmp(sys->Name(), name)) - return sys.value(); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -StarSystem* -Galaxy::FindSystemByRegion(const char* rgn_name) -{ - ListIter iter = systems; - while (++iter) { - StarSystem* sys = iter.value(); - if (sys->FindRegion(rgn_name)) - return sys; - } - - return 0; -} diff --git a/Stars45/Galaxy.h b/Stars45/Galaxy.h deleted file mode 100644 index 1c9c667..0000000 --- a/Stars45/Galaxy.h +++ /dev/null @@ -1,73 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Galaxy (list of star systems) for a single campaign. -*/ - -#ifndef Galaxy_h -#define Galaxy_h - -#include "Types.h" -#include "Solid.h" -#include "Bitmap.h" -#include "Geometry.h" -#include "Text.h" -#include "Term.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Star; -class StarSystem; -class Graphic; -class Light; -class Scene; - -// +--------------------------------------------------------------------+ - -class Galaxy -{ -public: - Galaxy(const char* name); - virtual ~Galaxy(); - - int operator == (const Galaxy& s) const { return name == s.name; } - - // operations: - virtual void Load(); - virtual void Load(const char* filename); - virtual void ExecFrame(); - - // accessors: - const char* Name() const { return name; } - const char* Description() const { return description; } - List& GetSystemList() { return systems; } - List& Stars() { return stars; } - double Radius() const { return radius; } - - StarSystem* GetSystem(const char* name); - StarSystem* FindSystemByRegion(const char* rgn_name); - - static void Initialize(); - static void Close(); - static Galaxy* GetInstance(); - -protected: - char filename[64]; - Text name; - Text description; - double radius; // radius in parsecs - - List systems; - List stars; -}; - -#endif // Galaxy_h - diff --git a/Stars45/Game.cpp b/Stars45/Game.cpp deleted file mode 100644 index 3b480cc..0000000 --- a/Stars45/Game.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* 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 "Game.h" -#include "Mouse.h" -#include "Universe.h" -#include "Window.h" -#include "EventDispatch.h" -#include "DataLoader.h" -#include "Panic.h" -#include "Pcx.h" -#include "Bitmap.h" -#include "MachineInfo.h" -#include "VideoSettings.h" -#include "ContentBundle.h" -#include "Clock.h" -#include "WndProc.h" -#include "SoundCard.h" - -// +--------------------------------------------------------------------+ - -Game* game = 0; - -const double MAX_FRAME_TIME_NORMAL = 1.0 / 5.0; - -// +--------------------------------------------------------------------+ - -Game::Game() - : world(0), video_factory(0), video(0), video_settings(0), soundcard(0), - screen(0), totaltime(0), - status(Game::OK), exit_code(0), window_style(0) -{ - Clock::Init(); - if (!game) { - game = this; - - active = false; - paused = false; - server = false; - show_mouse = false; - frame_number = 0; - - max_frame_length = MAX_FRAME_TIME_NORMAL; - - video_settings = new VideoSettings; - } - else - status = TOO_MANY; -} - -Game::~Game() -{ - if (game == this) - game = 0; - - Clock::Close(); - - delete world; - delete screen; - delete video_factory; - delete video; - delete soundcard; - delete video_settings; - - if (status == EXIT) - ShowStats(); -} - -// +--------------------------------------------------------------------+ - -bool -Game::Init(HINSTANCE hi, HINSTANCE hpi, LPSTR cmdline, int nCmdShow) -{ - status = OK; - - if (status == OK) { - Print(" Initializing content...\n"); - ContentBundle::GetInstance()->Init(); - - Print(" Initializing game...\n"); - if (!InitGame()) { - if (Panic::Panicked()) - Panic::Panic("Could not initialize the game."); - status = INIT_FAILED; - } - } - - return status == OK; -} - -// +--------------------------------------------------------------------+ - -bool -Game::InitGame() -{ - if (server) { - Print(" InitGame() - server mode.\n"); - } - return true; -} - -// +--------------------------------------------------------------------+ - -int -Game::Run() -{ - status = RUN; - Clock::GetInstance()->Set(); - while (status < EXIT && !Panic::Panicked()) { - GameLoop(); - } - return exit_code; -} - -// +--------------------------------------------------------------------+ - -void -Game::Exit() -{ - Print("\n\n*** Game::Exit()\n"); - status = EXIT; -} - -// +--------------------------------------------------------------------+ - -void -Game::Activate(bool f) -{ - active = f; - - if (active && video) - video->InvalidateCache(); -} - -// +--------------------------------------------------------------------+ - -void -Game::Pause(bool f) -{ - if (f) { - if (soundcard) - soundcard->Pause(); - paused = true; - } - else { - if (soundcard) - soundcard->Resume(); - paused = false; - } -} - -// +--------------------------------------------------------------------+ - -bool -Game::GameLoop() -{ - bool wait_for_windows_events = true; - - if (active && !paused) { - if (!server) { - // Route Events to EventTargets - EventDispatch* ed = EventDispatch::GetInstance(); - if (ed) - ed->Dispatch(); - } - - UpdateWorld(); - GameState(); - - if (!server) { - UpdateScreen(); - CollectStats(); - } - - wait_for_windows_events = false; - } - else if (active && paused) { - if (GetKey()=='P') - Pause(false); - } - - Clock::GetInstance()->Step(); - frame_number++; - Mouse::w = 0; - return wait_for_windows_events; -} - -// +--------------------------------------------------------------------+ - -void -Game::UpdateWorld() -{ - if (world) - world->ExecFrame(Clock::GetInstance()->Delta()); -} - -// +--------------------------------------------------------------------+ - -void -Game::GameState() -{ -} - -// +--------------------------------------------------------------------+ - -void -Game::UpdateScreen() -{ - if (!screen || !video) return; - - if (screen->Refresh()) { - video->Present(); - } - else { - Panic::Panic("Screen refresh failed."); - } -} - -// +--------------------------------------------------------------------+ - -Game* -Game::GetInstance() -{ - return game; -} - -// +--------------------------------------------------------------------+ - -void -Game::CollectStats() -{ - if (!totaltime) totaltime = Clock::GetInstance()->RealTime(); - - if (video) { - stats.nframe = video->GetStats().nframe; - stats.nverts = video->GetStats().nverts; - stats.npolys = video->GetStats().npolys; - stats.nlines = video->GetStats().nlines; - stats.ncalls += video->GetStats().ncalls; - - stats.total_verts += stats.nverts; - stats.total_polys += stats.npolys; - stats.total_lines += stats.nlines; - } -} - -// +--------------------------------------------------------------------+ - -void -Game::ShowStats() -{ - if (server) return; - - totaltime = Clock::GetInstance()->RealTime() - totaltime; - - Print("\n"); - Print("Performance Data:\n"); - Print("-----------------\n"); - - Print(" Time: %d msec\n", totaltime); - Print(" Frames: %d\n", stats.nframe); - Print(" Polys Rendered: %d\n", stats.total_polys); - Print(" Lines Rendered: %d\n", stats.total_lines); - Print(" Verts Rendered: %d\n", stats.total_verts); - Print(" Render Calls: %d\n", stats.ncalls); - Print("\n"); - - Print("Performance Statistics:\n"); - Print("-----------------------\n"); - - Print(" Frames/Second: %.2f\n", (stats.nframe * 1000.0) / totaltime); - Print(" Polys/Frame: %.2f\n", (double) stats.total_polys / (double) stats.nframe); - Print(" Polys/Call: %.2f\n", (double) stats.total_polys / (double) stats.ncalls); - Print(" Polys/Second: %.2f\n", (stats.total_polys * 1000.0) / totaltime); - Print(" Lines/Second: %.2f\n", (stats.total_lines * 1000.0) / totaltime); - Print(" Verts/Second: %.2f\n", (stats.total_verts * 1000.0) / totaltime); - - Print("\n"); -} - -// +====================================================================+ - -DWORD Game::Frame() -{ - return frame_number; -} diff --git a/Stars45/Game.h b/Stars45/Game.h deleted file mode 100644 index 0a59197..0000000 --- a/Stars45/Game.h +++ /dev/null @@ -1,117 +0,0 @@ -/* 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 - -*/ - -#ifndef Game_h -#define Game_h - -#include "Types.h" -#include "Screen.h" -#include "Video.h" -#include "VideoSettings.h" - -// +--------------------------------------------------------------------+ - -class Universe; -class Sound; -class SoundCard; -class Video; -class VideoFactory; -class Text; - -// +--------------------------------------------------------------------+ - -class Game -{ -public: - static const char* TYPENAME() { return "Game"; } - enum STATUS { OK, RUN, EXIT, INIT_FAILED, TOO_MANY }; - - Game(); - virtual ~Game(); - - // - // MAIN GAME FUNCTIONALITY: - // - - virtual bool Init(HINSTANCE hi, HINSTANCE hpi, LPSTR cmdline, int nCmdShow); - virtual int Run(); - virtual void Exit(); - virtual bool OnPaint() { return false; } - virtual bool OnHelp() { return false; } - - virtual void Activate(bool f); - virtual void Pause(bool f); - int Status() const { return status; } - - const RenderStats& GetPolyStats() { return stats; } - - // - // GENERAL GAME CLASS UTILITY METHODS: - // - - static Game* GetInstance(); - - DWORD Frame(); - - void SetMaxFrameLength(double seconds) { max_frame_length = seconds; } - double GetMaxFrameLength() { return max_frame_length; } - - bool Active() { return active; } - bool Paused() { return paused; } - bool Server() { return server; } - bool ShowMouse() { return show_mouse; } - - virtual bool GameLoop(); - virtual void UpdateWorld(); - virtual void GameState(); - virtual void UpdateScreen(); - virtual void CollectStats(); - - virtual bool InitGame(); - - virtual void ShowStats(); - -protected: - Universe* world; - VideoFactory* video_factory; - Video* video; - VideoSettings* video_settings; - SoundCard* soundcard; - Screen* screen; - - RenderStats stats; - DWORD totaltime; - - HMENU hmenu; - DWORD winstyle; - - char* app_name; - char* title_text; - char* palette_name; - - // Internal variables for the state of the app - DWORD window_style; // Saved window style for mode switches - RECT bounds_rect; // Saved window bounds for mode switches - RECT client_rect; // Saved client area size for mode switches - - int status; - int exit_code; - - bool active; - bool paused; - bool server; - bool show_mouse; - DWORD frame_number; - - double max_frame_length; -}; - -// +--------------------------------------------------------------------+ - -#endif // Game_h diff --git a/Stars45/GameScreen.cpp b/Stars45/GameScreen.cpp deleted file mode 100644 index 87ce925..0000000 --- a/Stars45/GameScreen.cpp +++ /dev/null @@ -1,1251 +0,0 @@ -/* 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 "GameScreen.h" - -#include "Sim.h" -#include "Ship.h" -#include "DisplayView.h" -#include "HUDView.h" -#include "HUDSounds.h" -#include "WepView.h" -#include "QuantumView.h" -#include "QuitView.h" -#include "RadioView.h" -#include "TacticalView.h" -#include "NavDlg.h" -#include "EngDlg.h" -#include "FltDlg.h" -#include "AudDlg.h" -#include "VidDlg.h" -#include "OptDlg.h" -#include "CtlDlg.h" -#include "KeyDlg.h" -#include "JoyDlg.h" -#include "ModDlg.h" -#include "ModInfoDlg.h" -#include "FormDef.h" -#include "Starshatter.h" -#include "CameraDirector.h" - -#include "Game.h" -#include "Video.h" -#include "Screen.h" -#include "Window.h" -#include "ActiveWindow.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "MouseController.h" -#include "CameraView.h" -#include "FadeView.h" -#include "Color.h" -#include "Bitmap.h" -#include "Font.h" -#include "FontMgr.h" -#include "EventDispatch.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -GameScreen* GameScreen::game_screen = 0; - -static MouseController* mouse_con = 0; -static bool mouse_active = false; - -// +--------------------------------------------------------------------+ - -GameScreen::GameScreen() -: screen(0), gamewin(0), -navdlg(0), wep_view(0), engdlg(0), fltdlg(0), -HUDfont(0), GUIfont(0), GUI_small_font(0), title_font(0), cam_view(0), -isShown(false), disp_view(0), hud_view(0), tac_view(0), radio_view(0), -quantum_view(0), quit_view(0), ctldlg(0), joydlg(0), keydlg(0), auddlg(0), -viddlg(0), moddlg(0), modInfoDlg(0), -flare1(0), flare2(0), flare3(0), flare4(0), -optdlg(0), cam_dir(0), sim(0) -{ - cam_dir = new CameraDirector; - sim = Sim::GetSim(); - loader = DataLoader::GetLoader(); - - // find the fonts: - HUDfont = FontMgr::Find("HUD"); - GUIfont = FontMgr::Find("GUI"); - GUI_small_font = FontMgr::Find("GUIsmall"); - title_font = FontMgr::Find("Title"); - - loader->LoadTexture("flare0+.pcx", flare1, Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("flare2.pcx", flare2, Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("flare3.pcx", flare3, Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("flare4.pcx", flare4, Bitmap::BMP_TRANSLUCENT); - - mouse_con = MouseController::GetInstance(); - game_screen = this; -} - -GameScreen::~GameScreen() -{ - TearDown(); - game_screen = 0; -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::Setup(Screen* s) -{ - if (!s) - return; - - screen = s; - - loader->UseFileSystem(true); - - // create windows - gamewin = new Window(screen, 0, 0, screen->Width(), screen->Height()); - - // attach views to windows (back to front) - // fade in: - gamewin->AddView(new FadeView(gamewin, 1, 0, 0)); - - // camera: - cam_dir = CameraDirector::GetInstance(); - cam_view = new CameraView(gamewin, cam_dir->GetCamera(), 0); - - if (cam_view) - gamewin->AddView(cam_view); - - // HUD: - hud_view = new HUDView(gamewin); - gamewin->AddView(hud_view); - - wep_view = new WepView(gamewin); - gamewin->AddView(wep_view); - - quantum_view = new QuantumView(gamewin); - gamewin->AddView(quantum_view); - - radio_view = new RadioView(gamewin); - gamewin->AddView(radio_view); - - tac_view = new TacticalView(gamewin, this); - gamewin->AddView(tac_view); - - disp_view = DisplayView::GetInstance(); - - // note: quit view must be last in chain - // so it can release window surface - quit_view = new QuitView(gamewin); - gamewin->AddView(quit_view); - - Starshatter* stars = Starshatter::GetInstance(); - - // initialize lens flare bitmaps: - if (stars->LensFlare()) { - cam_view->LensFlareElements(flare1, flare4, flare2, flare3); - cam_view->LensFlare(true); - } - - // if lens flare disabled, just create the corona: - else if (stars->Corona()) { - cam_view->LensFlareElements(flare1, 0, 0, 0); - cam_view->LensFlare(true); - } - - screen->AddWindow(gamewin); - - FormDef aud_def("AudDlg", 0); - aud_def.Load("AudDlg"); - auddlg = new AudDlg(screen, aud_def, this); - - FormDef ctl_def("CtlDlg", 0); - ctl_def.Load("CtlDlg"); - ctldlg = new CtlDlg(screen, ctl_def, this); - - FormDef opt_def("OptDlg", 0); - opt_def.Load("OptDlg"); - optdlg = new OptDlg(screen, opt_def, this); - - FormDef vid_def("VidDlg", 0); - vid_def.Load("VidDlg"); - viddlg = new VidDlg(screen, vid_def, this); - - FormDef mod_def("ModDlg", 0); - mod_def.Load("ModDlg"); - moddlg = new ModDlg(screen, mod_def, this); - - FormDef joy_def("JoyDlg", 0); - joy_def.Load("JoyDlg"); - joydlg = new JoyDlg(screen, joy_def, this); - - FormDef key_def("KeyDlg", 0); - key_def.Load("KeyDlg"); - keydlg = new KeyDlg(screen, key_def, this); - - FormDef mod_info_def("ModInfoDlg", 0); - mod_info_def.Load("ModInfoDlg"); - modInfoDlg = new ModInfoDlg(screen, mod_info_def, this); - - FormDef nav_def("NavDlg", 0); - nav_def.Load("NavDlg"); - navdlg = new NavDlg(screen, nav_def, this); - - FormDef eng_def("EngDlg", 0); - eng_def.Load("EngDlg"); - engdlg = new EngDlg(screen, eng_def, this); - - FormDef flt_def("FltDlg", 0); - flt_def.Load("FltDlg"); - fltdlg = new FltDlg(screen, flt_def, this); - - if (engdlg) engdlg->Hide(); - if (fltdlg) fltdlg->Hide(); - if (navdlg) navdlg->Hide(); - if (auddlg) auddlg->Hide(); - if (viddlg) viddlg->Hide(); - if (optdlg) optdlg->Hide(); - if (ctldlg) ctldlg->Hide(); - if (keydlg) keydlg->Hide(); - if (joydlg) joydlg->Hide(); - if (moddlg) moddlg->Hide(); - if (modInfoDlg) modInfoDlg->Hide(); - - screen->SetBackgroundColor(Color::Black); - - frame_rate = 0; - - loader->UseFileSystem(Starshatter::UseFileSystem()); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::TearDown() -{ - if (gamewin && disp_view) - gamewin->DelView(disp_view); - - if (screen) { - screen->DelWindow(engdlg); - screen->DelWindow(fltdlg); - screen->DelWindow(navdlg); - screen->DelWindow(modInfoDlg); - screen->DelWindow(auddlg); - screen->DelWindow(viddlg); - screen->DelWindow(optdlg); - screen->DelWindow(moddlg); - screen->DelWindow(ctldlg); - screen->DelWindow(keydlg); - screen->DelWindow(joydlg); - screen->DelWindow(gamewin); - } - - delete engdlg; - delete fltdlg; - delete navdlg; - delete modInfoDlg; - delete auddlg; - delete viddlg; - delete optdlg; - delete moddlg; - delete ctldlg; - delete keydlg; - delete joydlg; - delete gamewin; - delete cam_dir; - - engdlg = 0; - fltdlg = 0; - navdlg = 0; - modInfoDlg = 0; - auddlg = 0; - viddlg = 0; - optdlg = 0; - moddlg = 0; - ctldlg = 0; - keydlg = 0; - joydlg = 0; - gamewin = 0; - screen = 0; - cam_dir = 0; - cam_view = 0; - disp_view = 0; -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::FrameRate(double f) -{ - frame_rate = f; -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::SetFieldOfView(double fov) -{ - cam_view->SetFieldOfView(fov); -} - -// +--------------------------------------------------------------------+ - -double -GameScreen::GetFieldOfView() const -{ - return cam_view->GetFieldOfView(); -} - -// +--------------------------------------------------------------------+ - -Bitmap* -GameScreen::GetLensFlare(int index) -{ - switch (index) { - case 0: return flare1; - case 1: return flare2; - case 2: return flare3; - case 3: return flare4; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ExecFrame() -{ - sim = Sim::GetSim(); - - if (sim) { - cam_view->UseCamera(CameraDirector::GetInstance()->GetCamera()); - cam_view->UseScene(sim->GetScene()); - - Ship* player = sim->GetPlayerShip(); - - if (player) { - bool dialog_showing = false; - - if (hud_view) { - hud_view->UseCameraView(cam_view); - hud_view->ExecFrame(); - } - - if (quit_view && quit_view->IsMenuShown()) { - quit_view->ExecFrame(); - dialog_showing = true; - } - - if (navdlg && navdlg->IsShown()) { - navdlg->SetShip(player); - navdlg->ExecFrame(); - dialog_showing = true; - } - - if (engdlg && engdlg->IsShown()) { - engdlg->SetShip(player); - engdlg->ExecFrame(); - dialog_showing = true; - } - - if (fltdlg && fltdlg->IsShown()) { - fltdlg->SetShip(player); - fltdlg->ExecFrame(); - dialog_showing = true; - } - - if (auddlg && auddlg->IsShown()) { - auddlg->ExecFrame(); - dialog_showing = true; - } - - if (viddlg && viddlg->IsShown()) { - viddlg->ExecFrame(); - dialog_showing = true; - } - - if (optdlg && optdlg->IsShown()) { - optdlg->ExecFrame(); - dialog_showing = true; - } - - if (ctldlg && ctldlg->IsShown()) { - ctldlg->ExecFrame(); - dialog_showing = true; - } - - if (keydlg && keydlg->IsShown()) { - keydlg->ExecFrame(); - dialog_showing = true; - } - - if (joydlg && joydlg->IsShown()) { - joydlg->ExecFrame(); - dialog_showing = true; - } - - if (moddlg && moddlg->IsShown()) { - moddlg->ExecFrame(); - dialog_showing = true; - } - - if (quantum_view && !dialog_showing) { - quantum_view->ExecFrame(); - } - - if (radio_view && !dialog_showing) { - radio_view->ExecFrame(); - } - - if (wep_view && !dialog_showing) { - wep_view->ExecFrame(); - } - - if (tac_view && !dialog_showing) { - if (cam_view) - tac_view->UseProjector(cam_view->GetProjector()); - tac_view->ExecFrame(); - } - } - - if (disp_view) { - disp_view->ExecFrame(); - } - } - - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - if (stars->LensFlare()) { - cam_view->LensFlareElements(flare1, flare4, flare2, flare3); - cam_view->LensFlare(true); - } - - else if (stars->Corona()) { - cam_view->LensFlareElements(flare1, 0, 0, 0); - cam_view->LensFlare(true); - } - - else { - cam_view->LensFlare(false); - } - } -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::CycleMFDMode(int mfd) -{ - if (hud_view) - hud_view->CycleMFDMode(mfd); -} - -void -GameScreen::CycleHUDMode() -{ - if (hud_view) - hud_view->CycleHUDMode(); -} - -void -GameScreen::CycleHUDColor() -{ - if (hud_view) - hud_view->CycleHUDColor(); -} - -void -GameScreen::CycleHUDWarn() -{ - if (hud_view) - hud_view->CycleHUDWarn(); -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::CloseTopmost() -{ - bool processed = false; - - if (!gamewin) return processed; - - if (navdlg && navdlg->IsShown()) { - HideNavDlg(); - processed = true; - } - - else if (engdlg && engdlg->IsShown()) { - HideEngDlg(); - processed = true; - } - - else if (fltdlg && fltdlg->IsShown()) { - HideFltDlg(); - processed = true; - } - - else if (modInfoDlg && modInfoDlg->IsShown()) { - HideModInfoDlg(); - processed = true; - } - - else if (keydlg && keydlg->IsShown()) { - ShowCtlDlg(); - processed = true; - } - - else if (joydlg && joydlg->IsShown()) { - ShowCtlDlg(); - processed = true; - } - - else if (auddlg && auddlg->IsShown()) { - CancelOptions(); - processed = true; - } - - else if (viddlg && viddlg->IsShown()) { - CancelOptions(); - processed = true; - } - - else if (optdlg && optdlg->IsShown()) { - CancelOptions(); - processed = true; - } - - else if (moddlg && moddlg->IsShown()) { - CancelOptions(); - processed = true; - } - - else if (ctldlg && ctldlg->IsShown()) { - CancelOptions(); - processed = true; - } - - else if (quantum_view && quantum_view->IsMenuShown()) { - quantum_view->CloseMenu(); - processed = true; - } - - else if (quit_view && quit_view->IsMenuShown()) { - quit_view->CloseMenu(); - processed = true; - } - - else if (radio_view && radio_view->IsMenuShown()) { - radio_view->CloseMenu(); - processed = true; - } - - return processed; -} - -static Window* old_disp_win = 0; - -void -GameScreen::Show() -{ - if (!isShown) { - screen->AddWindow(gamewin); - isShown = true; - - if (disp_view) { - old_disp_win = disp_view->GetWindow(); - - disp_view->SetWindow(gamewin); - gamewin->AddView(disp_view); - } - } -} - -void -GameScreen::Hide() -{ - if (isShown) { - HideAll(); - - if (disp_view && gamewin) { - gamewin->DelView(disp_view); - disp_view->SetWindow(old_disp_win); - } - - if (engdlg) engdlg->SetShip(0); - if (fltdlg) fltdlg->SetShip(0); - if (navdlg) navdlg->SetShip(0); - - HUDSounds::StopSound(HUDSounds::SND_RED_ALERT); - - screen->DelWindow(gamewin); - isShown = false; - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsFormShown() const -{ - bool form_shown = false; - - if (navdlg && navdlg->IsShown()) - form_shown = true; - - else if (engdlg && engdlg->IsShown()) - form_shown = true; - - else if (fltdlg && fltdlg->IsShown()) - form_shown = true; - - else if (auddlg && auddlg->IsShown()) - form_shown = true; - - else if (viddlg && viddlg->IsShown()) - form_shown = true; - - else if (optdlg && optdlg->IsShown()) - form_shown = true; - - else if (moddlg && moddlg->IsShown()) - form_shown = true; - - else if (ctldlg && ctldlg->IsShown()) - form_shown = true; - - else if (keydlg && keydlg->IsShown()) - form_shown = true; - - else if (joydlg && joydlg->IsShown()) - form_shown = true; - - return form_shown; -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowExternal() -{ - if (!gamewin) return; - - if ((navdlg && navdlg->IsShown()) || - (engdlg && engdlg->IsShown()) || - (fltdlg && fltdlg->IsShown()) || - (auddlg && auddlg->IsShown()) || - (viddlg && viddlg->IsShown()) || - (optdlg && optdlg->IsShown()) || - (moddlg && moddlg->IsShown()) || - (ctldlg && ctldlg->IsShown()) || - (keydlg && keydlg->IsShown()) || - (joydlg && joydlg->IsShown())) - return; - - gamewin->MoveTo(Rect(0, 0, screen->Width(), screen->Height())); - screen->AddWindow(gamewin); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowNavDlg() -{ - if (!gamewin) return; - - if (navdlg && !navdlg->IsShown()) { - HideAll(); - - navdlg->SetSystem(sim->GetStarSystem()); - navdlg->SetShip(sim->GetPlayerShip()); - navdlg->Show(); - - if (mouse_con) { - mouse_active = mouse_con->Active(); - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } - else { - HideNavDlg(); - } -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::HideNavDlg() -{ - if (!gamewin) return; - - if (navdlg && navdlg->IsShown()) { - navdlg->Hide(); - - if (mouse_con) - mouse_con->SetActive(mouse_active); - - Mouse::Show(false); - screen->AddWindow(gamewin); - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsNavShown() -{ - return gamewin && navdlg && navdlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowEngDlg() -{ - if (!gamewin) return; - - if (engdlg && !engdlg->IsShown()) { - HideAll(); - - engdlg->SetShip(sim->GetPlayerShip()); - engdlg->Show(); - - if (mouse_con) { - mouse_active = mouse_con->Active(); - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } - else { - HideEngDlg(); - } -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::HideEngDlg() -{ - if (!gamewin) return; - - if (engdlg && engdlg->IsShown()) { - engdlg->Hide(); - - if (mouse_con) - mouse_con->SetActive(mouse_active); - - Mouse::Show(false); - screen->AddWindow(gamewin); - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsEngShown() -{ - return gamewin && engdlg && engdlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowFltDlg() -{ - if (!gamewin) return; - - if (fltdlg && !fltdlg->IsShown()) { - HideAll(); - - fltdlg->SetShip(sim->GetPlayerShip()); - fltdlg->Show(); - - if (mouse_con) { - mouse_active = mouse_con->Active(); - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } - else { - HideFltDlg(); - } -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::HideFltDlg() -{ - if (!gamewin) return; - - if (fltdlg && fltdlg->IsShown()) { - fltdlg->Hide(); - - if (mouse_con) - mouse_con->SetActive(mouse_active); - - Mouse::Show(false); - screen->AddWindow(gamewin); - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsFltShown() -{ - return gamewin && fltdlg && fltdlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowAudDlg() -{ - if (auddlg) { - if (quit_view) { - quit_view->CloseMenu(); - Game::GetInstance()->Pause(true); - } - - HideAll(); - - auddlg->Show(); - auddlg->SetTopMost(true); - - if (mouse_con) { - mouse_active = mouse_con->Active(); - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::HideAudDlg() -{ - if (auddlg && auddlg->IsShown()) { - auddlg->Hide(); - Mouse::Show(false); - screen->AddWindow(gamewin); - - if (quit_view) - quit_view->ShowMenu(); - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsAudShown() -{ - return auddlg && auddlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowVidDlg() -{ - if (viddlg) { - if (quit_view) { - quit_view->CloseMenu(); - Game::GetInstance()->Pause(true); - } - - HideAll(); - - viddlg->Show(); - viddlg->SetTopMost(true); - - if (mouse_con) { - mouse_active = mouse_con->Active(); - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::HideVidDlg() -{ - if (viddlg && viddlg->IsShown()) { - viddlg->Hide(); - Mouse::Show(false); - screen->AddWindow(gamewin); - - if (quit_view) - quit_view->ShowMenu(); - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsVidShown() -{ - return viddlg && viddlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowOptDlg() -{ - if (optdlg) { - if (quit_view) { - quit_view->CloseMenu(); - Game::GetInstance()->Pause(true); - } - - HideAll(); - - optdlg->Show(); - optdlg->SetTopMost(true); - - if (mouse_con) { - mouse_active = mouse_con->Active(); - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::HideOptDlg() -{ - if (optdlg && optdlg->IsShown()) { - optdlg->Hide(); - Mouse::Show(false); - screen->AddWindow(gamewin); - - if (quit_view) - quit_view->ShowMenu(); - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsOptShown() -{ - return optdlg && optdlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowModDlg() -{ - if (moddlg) { - if (quit_view) { - quit_view->CloseMenu(); - Game::GetInstance()->Pause(true); - } - - HideAll(); - - moddlg->Show(); - moddlg->SetTopMost(true); - - if (mouse_con) { - mouse_active = mouse_con->Active(); - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::HideModDlg() -{ - if (moddlg && moddlg->IsShown()) { - moddlg->Hide(); - Mouse::Show(false); - screen->AddWindow(gamewin); - - if (quit_view) - quit_view->ShowMenu(); - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsModShown() -{ - return moddlg && moddlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowModInfoDlg() -{ - if (moddlg && modInfoDlg) { - if (quit_view) { - quit_view->CloseMenu(); - Game::GetInstance()->Pause(true); - } - - HideAll(); - - moddlg->Show(); - moddlg->SetTopMost(false); - - modInfoDlg->Show(); - modInfoDlg->SetTopMost(true); - - if (mouse_con) { - mouse_active = mouse_con->Active(); - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::HideModInfoDlg() -{ - ShowModDlg(); -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsModInfoShown() -{ - return modInfoDlg && modInfoDlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowCtlDlg() -{ - if (ctldlg) { - if (quit_view) { - quit_view->CloseMenu(); - Game::GetInstance()->Pause(true); - } - - HideAll(); - - ctldlg->Show(); - ctldlg->SetTopMost(true); - - if (mouse_con) { - mouse_active = mouse_con->Active(); - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::HideCtlDlg() -{ - if (ctldlg && ctldlg->IsShown()) { - ctldlg->Hide(); - Mouse::Show(false); - screen->AddWindow(gamewin); - - if (quit_view) - quit_view->ShowMenu(); - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsCtlShown() -{ - return ctldlg && ctldlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowKeyDlg() -{ - if (keydlg) { - if (quit_view) { - quit_view->CloseMenu(); - Game::GetInstance()->Pause(true); - } - - HideAll(); - - if (ctldlg) { - ctldlg->Show(); - ctldlg->SetTopMost(false); - } - - if (keydlg) keydlg->Show(); - - if (mouse_con) { - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsKeyShown() -{ - return keydlg && keydlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowJoyDlg() -{ - if (joydlg) { - if (quit_view) { - quit_view->CloseMenu(); - Game::GetInstance()->Pause(true); - } - - HideAll(); - - if (ctldlg) { - ctldlg->Show(); - ctldlg->SetTopMost(false); - } - - if (joydlg) joydlg->Show(); - - if (mouse_con) { - mouse_con->SetActive(false); - } - - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -bool -GameScreen::IsJoyShown() -{ - return joydlg && joydlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ShowWeaponsOverlay() -{ - if (wep_view) - wep_view->CycleOverlayMode(); -} - -void -GameScreen::HideWeaponsOverlay() -{ - if (wep_view) - wep_view->SetOverlayMode(0); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::HideAll() -{ - screen->DelWindow(gamewin); - - if (engdlg) engdlg->Hide(); - if (fltdlg) fltdlg->Hide(); - if (navdlg) navdlg->Hide(); - if (auddlg) auddlg->Hide(); - if (viddlg) viddlg->Hide(); - if (optdlg) optdlg->Hide(); - if (moddlg) moddlg->Hide(); - if (modInfoDlg) modInfoDlg->Hide(); - if (ctldlg) ctldlg->Hide(); - if (keydlg) keydlg->Hide(); - if (joydlg) joydlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -void -GameScreen::ApplyOptions() -{ - if (ctldlg) ctldlg->Apply(); - if (optdlg) optdlg->Apply(); - if (auddlg) auddlg->Apply(); - if (viddlg) viddlg->Apply(); - - if (engdlg) engdlg->Hide(); - if (fltdlg) fltdlg->Hide(); - if (navdlg) navdlg->Hide(); - if (ctldlg) ctldlg->Hide(); - if (auddlg) auddlg->Hide(); - if (viddlg) viddlg->Hide(); - if (optdlg) optdlg->Hide(); - if (moddlg) moddlg->Hide(); - if (keydlg) keydlg->Hide(); - if (joydlg) joydlg->Hide(); - - Mouse::Show(false); - screen->AddWindow(gamewin); - Game::GetInstance()->Pause(false); -} - -void -GameScreen::CancelOptions() -{ - if (ctldlg) ctldlg->Cancel(); - if (optdlg) optdlg->Cancel(); - if (auddlg) auddlg->Cancel(); - if (viddlg) viddlg->Cancel(); - - if (engdlg) engdlg->Hide(); - if (fltdlg) fltdlg->Hide(); - if (navdlg) navdlg->Hide(); - if (ctldlg) ctldlg->Hide(); - if (auddlg) auddlg->Hide(); - if (viddlg) viddlg->Hide(); - if (optdlg) optdlg->Hide(); - if (moddlg) moddlg->Hide(); - if (keydlg) keydlg->Hide(); - if (joydlg) joydlg->Hide(); - - Mouse::Show(false); - screen->AddWindow(gamewin); - Game::GetInstance()->Pause(false); -} diff --git a/Stars45/GameScreen.h b/Stars45/GameScreen.h deleted file mode 100644 index 597c6d2..0000000 --- a/Stars45/GameScreen.h +++ /dev/null @@ -1,191 +0,0 @@ -/* 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 - -*/ - -#ifndef GameScreen_h -#define GameScreen_h - -#include "Types.h" -#include "Bitmap.h" -#include "Screen.h" -#include "BaseScreen.h" - -// +--------------------------------------------------------------------+ - -class Screen; -class Sim; -class Window; -class Font; - -class NavDlg; -class EngDlg; -class FltDlg; -class CtlDlg; -class JoyDlg; -class KeyDlg; -class ModDlg; -class ModInfoDlg; - -class CameraDirector; -class DisplayView; -class HUDView; -class WepView; -class QuantumView; -class QuitView; -class RadioView; -class TacticalView; -class CameraView; -class PolyRender; -class Bitmap; -class DataLoader; -class Video; -class VideoFactory; - -// +--------------------------------------------------------------------+ - -class GameScreen : public BaseScreen -{ -public: - GameScreen(); - virtual ~GameScreen(); - - virtual void Setup(Screen* screen); - virtual void TearDown(); - virtual bool CloseTopmost(); - - virtual bool IsShown() const { return isShown; } - virtual void Show(); - virtual void Hide(); - - virtual bool IsFormShown() const; - virtual void ShowExternal(); - - virtual void ShowNavDlg(); - virtual void HideNavDlg(); - virtual bool IsNavShown(); - virtual NavDlg* GetNavDlg() { return navdlg; } - - virtual void ShowEngDlg(); - virtual void HideEngDlg(); - virtual bool IsEngShown(); - virtual EngDlg* GetEngDlg() { return engdlg; } - - virtual void ShowFltDlg(); - virtual void HideFltDlg(); - virtual bool IsFltShown(); - virtual FltDlg* GetFltDlg() { return fltdlg; } - - virtual void ShowCtlDlg(); - virtual void HideCtlDlg(); - virtual bool IsCtlShown(); - - virtual void ShowJoyDlg(); - virtual bool IsJoyShown(); - - virtual void ShowKeyDlg(); - virtual bool IsKeyShown(); - - - virtual AudDlg* GetAudDlg() const { return auddlg; } - virtual VidDlg* GetVidDlg() const { return viddlg; } - virtual OptDlg* GetOptDlg() const { return optdlg; } - virtual CtlDlg* GetCtlDlg() const { return ctldlg; } - virtual JoyDlg* GetJoyDlg() const { return joydlg; } - virtual KeyDlg* GetKeyDlg() const { return keydlg; } - virtual ModDlg* GetModDlg() const { return moddlg; } - virtual ModInfoDlg* GetModInfoDlg() const { return modInfoDlg; } - - virtual void ShowAudDlg(); - virtual void HideAudDlg(); - virtual bool IsAudShown(); - - virtual void ShowVidDlg(); - virtual void HideVidDlg(); - virtual bool IsVidShown(); - - virtual void ShowOptDlg(); - virtual void HideOptDlg(); - virtual bool IsOptShown(); - - virtual void ShowModDlg(); - virtual void HideModDlg(); - virtual bool IsModShown(); - - virtual void ShowModInfoDlg(); - virtual void HideModInfoDlg(); - virtual bool IsModInfoShown(); - - virtual void ApplyOptions(); - virtual void CancelOptions(); - - virtual void ShowWeaponsOverlay(); - virtual void HideWeaponsOverlay(); - - void SetFieldOfView(double fov); - double GetFieldOfView() const; - void CycleMFDMode(int mfd); - void CycleHUDMode(); - void CycleHUDColor(); - void CycleHUDWarn(); - void FrameRate(double f); - void ExecFrame(); - - static GameScreen* GetInstance() { return game_screen; } - CameraView* GetCameraView() const { return cam_view; } - Bitmap* GetLensFlare(int index); - -private: - void HideAll(); - - Sim* sim; - Screen* screen; - - Window* gamewin; - NavDlg* navdlg; - EngDlg* engdlg; - FltDlg* fltdlg; - CtlDlg* ctldlg; - KeyDlg* keydlg; - JoyDlg* joydlg; - AudDlg* auddlg; - VidDlg* viddlg; - OptDlg* optdlg; - ModDlg* moddlg; - ModInfoDlg* modInfoDlg; - - Font* HUDfont; - Font* GUIfont; - Font* GUI_small_font; - Font* title_font; - - Bitmap* flare1; - Bitmap* flare2; - Bitmap* flare3; - Bitmap* flare4; - - CameraDirector* cam_dir; - DisplayView* disp_view; - HUDView* hud_view; - WepView* wep_view; - QuantumView* quantum_view; - QuitView* quit_view; - TacticalView* tac_view; - RadioView* radio_view; - CameraView* cam_view; - DataLoader* loader; - - double frame_rate; - bool isShown; - - static GameScreen* game_screen; -}; - -// +--------------------------------------------------------------------+ - -#endif // GameScreen_h - diff --git a/Stars45/GameWinDX9.cpp b/Stars45/GameWinDX9.cpp deleted file mode 100644 index 5d04c97..0000000 --- a/Stars45/GameWinDX9.cpp +++ /dev/null @@ -1,662 +0,0 @@ -/* 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. -*/ - -#include "GameWinDX9.h" - -#include -#include - -#include "Bitmap.h" -#include "Clock.h" -#include "Color.h" -#include "DataLoader.h" -#include "Game.h" -#include "MachineInfo.h" -#include "Panic.h" -#include "Screen.h" -#include "Types.h" -#include "Utils.h" -#include "VideoFactory.h" -#include "Video.h" - - -GameWinDX9* GameWinDX9::instance = nullptr; - - -GameWinDX9* -GameWinDX9::GetInstance() -{ - return instance; -} - - -GameWinDX9::GameWinDX9() : - max_tex_size {2048}, - screen_color {Color::Black}, - hInst{nullptr}, - hwnd{nullptr}, - is_windowed {false}, - is_active {false}, - is_device_lost {false}, - is_minimized {false}, - is_maximized {false}, - ignore_size_change {false}, - is_device_initialized {false}, - is_device_restored {false} -{ - if (instance != nullptr) - Panic::Panic("Multiple instances of GameWinDX9"); - instance = this; -} - - -GameWinDX9::~GameWinDX9() -{ - if (instance != nullptr) - instance = nullptr; -} - - -bool -GameWinDX9::Init(HINSTANCE hi, HINSTANCE hpi, LPSTR cmdline, int nCmdShow) -{ - status = OK; - hInst = hi; - - Print(" Initializing Game\n"); - - stats.Clear(); - - if (!InitApplication(hInst)) { // Initialize shared things - Panic::Panic("Could not initialize the application."); - status = INIT_FAILED; - } - - if (status == OK && !video_settings) { - Panic::Panic("No video settings specified"); - status = INIT_FAILED; - } - - if (status == OK) { - static int os_version = MachineInfo::GetPlatform(); - - if (os_version == MachineInfo::OS_WIN95 || os_version == MachineInfo::OS_WIN98) { - Panic::Panic(" Windows 95 and 98 are no longer supported. Please update to Windows XP or higher."); - status = INIT_FAILED; - } else if (os_version == MachineInfo::OS_WINNT) { - Panic::Panic(" D3D not available under WinNT 4"); - status = INIT_FAILED; - } else if (MachineInfo::GetDirectXVersion() < MachineInfo::DX_9) { - Panic::Panic(" Insufficient DirectX detected (Dx9 IS REQUIRED)"); - status = INIT_FAILED; - } - } - - if (status == OK) { - Print("\n Initializing instance...\n"); - // Perform initializations that apply to a specific instance - if (!InitInstance(hInst, nCmdShow)) { - Panic::Panic("Could not initialize the instance."); - status = INIT_FAILED; - } - } - - if (status != OK) - return false; - return Game::Init(hi, hpi, cmdline, nCmdShow); -} - - -bool -GameWinDX9::InitApplication(HINSTANCE hInstance) -{ - WNDCLASS wc; - LOGBRUSH brush = { BS_SOLID, RGB(0,0,0), 0 }; - - if (server) - brush.lbColor = RGB(255,255,255); - - // Fill in window class structure with parameters that - // describe the main window. - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC) WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(100)); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - - wc.hbrBackground = CreateBrushIndirect(&brush); - wc.lpszMenuName = app_name; - wc.lpszClassName = app_name; - - // Register the window class and return success/failure code. - if (RegisterClass(&wc) == 0) { - DWORD err = GetLastError(); - - if (err == 1410) // class already exists, this is OK - return true; - - else - Print("WARNING: Register Window Class: %08x\n", err); - } - - return true; -} - - -bool -GameWinDX9::InitInstance(HINSTANCE hInstance, int nCmdShow) -{ - hInst = hInstance; - - // center window on display: - int screenx = GetSystemMetrics(SM_CXSCREEN); - int screeny = GetSystemMetrics(SM_CYSCREEN); - int x_offset = 0; - int y_offset = 0; - int s_width = 800; - int s_height = 600; - - if (server) { - s_width = 320; - s_height = 200; - } - - else if (video_settings) { - s_width = video_settings->window_width; - s_height = video_settings->window_height; - } - - if (s_width < screenx) - x_offset = (screenx - s_width) / 2; - - if (s_height < screeny) - y_offset = (screeny - s_height) / 2; - - // Create a main window for this application instance - RECT rctmp; - rctmp.left = x_offset; - rctmp.top = y_offset; - rctmp.right = x_offset + s_width; - rctmp.bottom = y_offset + s_height; - - window_style = - WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | - WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE; - - AdjustWindowRect(&rctmp, window_style, 1); - - hwnd = CreateWindow( - app_name, // Class name - app_name, // Caption - window_style, - x_offset, // Position - y_offset, - rctmp.right - rctmp.left, // Size - rctmp.bottom - rctmp.top, - 0, // Parent window (no parent) - 0, // use class menu - hInst, // handle to window instance - 0); // no params to pass on - - // If window could not be created, return "failure" - if (!hwnd) { - Panic::Panic("Could not create window\n"); - return false; - } - - Print(" Window created.\n"); - - // Make the window visible and draw it - ShowWindow(hwnd, nCmdShow); // Show the window - UpdateWindow(hwnd); // Sends WM_PAINT message - - // Save window properties - window_style = GetWindowLong(hwnd, GWL_STYLE); - GetWindowRect(hwnd, &bounds_rect); - GetClientRect(hwnd, &client_rect); - - // Use client area to set video window size - video_settings->window_width = client_rect.right - client_rect.left; - video_settings->window_height = client_rect.bottom - client_rect.top; - - Print(" Instance initialized.\n"); - return true; -} - - -bool -GameWinDX9::InitGame() -{ - if (server) return true; - if (!SetupPalette()) { - Panic::Panic("Could not set up the palette."); - return false; - } - Print(" Palette laoded\n"); - if (!InitVideo() || !video || video->Status() != Video::VIDEO_OK) { - Panic::Panic("Could not create the Video Interface"); - return false; - } - Print(" Created video object.\n"); - Color::UseVideo(video); - screen = new Screen(video); - if (!screen) { - Panic::Panic("Could not create the Screen object."); - return false; - } - Print(" Created screen object.\n"); - if (!screen->SetBackgroundColor(Color::Black)) - Print(" WARNING: Could not set video background color to Black.\n"); - screen->ClearAllFrames(true); - Print("Established requested video parameters.\n\n"); - return Game::InitGame(); -} - - -bool -GameWinDX9::InitVideo() -{ - if (server) return true; - - // create a video factory, and video object: - video_factory = new VideoFactory(hwnd); - - if (video_factory) { - Print(" Init Video...\n"); - Print(" Request %s mode\n", video_settings->GetModeDescription()); - - video = video_factory->CreateVideo(video_settings); - - if (video) { - if (!video->IsHardware()) { - video_factory->DestroyVideo(video); - video = 0; - - Panic::Panic("3D Hardware Not Found"); - } - - // save a copy of the device-specific video settings: - else if (video->GetVideoSettings()) { - *video_settings = *video->GetVideoSettings(); - is_windowed = video_settings->IsWindowed(); - } - } - - soundcard = video_factory->CreateSoundCard(); - } - - return (video && video->Status() == Video::VIDEO_OK); -} - - -bool -GameWinDX9::ResetVideo() -{ - if (server) return true; - if (!video_factory) return InitVideo(); - - Print(" Reset Video...\n"); - Print(" Request %s mode\n", video_settings->GetModeDescription()); - - delete screen; - - if (video && !video->Reset(video_settings)) { - video_factory->DestroyVideo(video); - video = video_factory->CreateVideo(video_settings); - } - - if (!video || video->Status() != Video::VIDEO_OK) { - Panic::Panic("Could not re-create Video Interface."); - return false; - } - - Print(" Re-created video object.\n"); - - // save a copy of the device-specific video settings: - if (video->GetVideoSettings()) { - *video_settings = *video->GetVideoSettings(); - is_windowed = video_settings->IsWindowed(); - } - - Color::UseVideo(video); - - screen = new Screen(video); - if (!screen) { - Panic::Panic("Could not re-create Screen object."); - return false; - } - - Print(" Re-created screen object.\n"); - - if (!screen->SetBackgroundColor(Color::Black)) - Print(" WARNING: could not set video background color to Black\n"); - - screen->ClearAllFrames(true); - - Print(" Re-established requested video parameters.\n"); - - Bitmap::CacheUpdate(); - Print(" Refreshed texture bitmaps.\n\n"); - return true; -} - - -bool -GameWinDX9::ResizeVideo() -{ - if (!video || !video_settings) return false; - if (!is_windowed) return false; - if (ignore_size_change) return true; - - HRESULT hr = S_OK; - RECT client_old; - - client_old = client_rect; - - // Update window properties - GetWindowRect(hwnd, &bounds_rect); - GetClientRect(hwnd, &client_rect); - - if (client_old.right - client_old.left != - client_rect.right - client_rect.left || - client_old.bottom - client_old.top != - client_rect.bottom - client_rect.top) { - - // A new window size will require a new backbuffer - // size, so the 3D structures must be changed accordingly. - Pause(true); - - video_settings->is_windowed = true; - video_settings->window_width = client_rect.right - client_rect.left; - video_settings->window_height = client_rect.bottom - client_rect.top; - - ::Print("ResizeVideo() %d x %d\n", video_settings->window_width, video_settings->window_height); - - if (video) { - video->Reset(video_settings); - } - - Pause(false); - } - - // save a copy of the device-specific video settings: - if (video->GetVideoSettings()) { - *video_settings = *video->GetVideoSettings(); - is_windowed = video_settings->IsWindowed(); - } - - screen->Resize(video_settings->window_width, video_settings->window_height); - - return hr == S_OK; -} - - -bool -GameWinDX9::ToggleFullscreen() -{ - bool result = false; - - if (video && video_settings) { - Pause(true); - ignore_size_change = true; - - // Toggle the windowed state - is_windowed = !is_windowed; - video_settings->is_windowed = is_windowed; - - // Prepare window for windowed/fullscreen change - AdjustWindowForChange(); - - // Reset the 3D device - if (!video->Reset(video_settings)) { - // reset failed, try to restore... - ignore_size_change = false; - - if (!is_windowed) { - // Restore window type to windowed mode - is_windowed = !is_windowed; - video_settings->is_windowed = is_windowed; - - AdjustWindowForChange(); - - SetWindowPos(hwnd, - HWND_NOTOPMOST, - bounds_rect.left, - bounds_rect.top, - bounds_rect.right - bounds_rect.left, - bounds_rect.bottom - bounds_rect.top, - SWP_SHOWWINDOW); - } - - ::Print("Unable to toggle %s fullscreen mode.\n", is_windowed ? "into" : "out of"); - } - - else { - ignore_size_change = false; - - // When moving from fullscreen to windowed mode, it is important to - // adjust the window size after resetting the device rather than - // beforehand to ensure that you get the window size you want. For - // example, when switching from 640x480 fullscreen to windowed with - // a 1000x600 window on a 1024x768 desktop, it is impossible to set - // the window size to 1000x600 until after the display mode has - // changed to 1024x768, because windows cannot be larger than the - // desktop. - - if (is_windowed) { - SetWindowPos(hwnd, - HWND_NOTOPMOST, - bounds_rect.left, - bounds_rect.top, - bounds_rect.right - bounds_rect.left, - bounds_rect.bottom - bounds_rect.top, - SWP_SHOWWINDOW); - } - - GetClientRect(hwnd, &client_rect); // Update our copy - Pause(false); - - if (is_windowed) - screen->Resize(video_settings->window_width, - video_settings->window_height); - - else - screen->Resize(video_settings->fullscreen_mode.width, - video_settings->fullscreen_mode.height); - - result = true; - } - } - - return result; -} - - -bool -GameWinDX9::AdjustWindowForChange() -{ - if (is_windowed) { - // Set windowed-mode style - SetWindowLong(hwnd, GWL_STYLE, window_style); - if (hmenu != NULL) { - SetMenu(hwnd, hmenu); - hmenu = NULL; - } - } - else { - // Set fullscreen-mode style - SetWindowLong(hwnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE); - if (hmenu == NULL) { - hmenu = GetMenu(hwnd); - SetMenu(hwnd, NULL); - } - } - - return true; -} - - -bool -GameWinDX9::SetupPalette() -{ - if (LoadPalette(standard_palette, inverse_palette)) { - Color::SetPalette(standard_palette, 256, inverse_palette); - return true; - } - - return false; -} - - -bool -GameWinDX9::LoadPalette(PALETTEENTRY* pal, BYTE* inv) -{ - char palheader[32]; - struct { - WORD Version; - WORD NumberOfEntries; - PALETTEENTRY Entries[256]; - } Palette = { 0x300, 256 }; - - DataLoader* loader = DataLoader::GetLoader(); - BYTE* block; - char fname[256]; - sprintf_s(fname, "%s.pal", palette_name); - - if (!loader->LoadBuffer(fname, block)) { - Print(" Could not open file '%s'\n", fname); - return false; - } - - memcpy(&palheader, block, 24); - memcpy((char*) Palette.Entries, (block+24), 256*4); - - for (int i = 0; i < 256; i++) { - *pal++ = Palette.Entries[i]; - } - - loader->ReleaseBuffer(block); - - sprintf_s(fname, "%s.ipl", palette_name); - int size = loader->LoadBuffer(fname, block); - if (size < 32768) { - Print(" Could not open file '%s'\n", fname); - return false; - } - - memcpy(inv, block, 32768); - loader->ReleaseBuffer(block); - - return true; -} - - -int -GameWinDX9::Run() -{ - MSG msg; - status = RUN; - Clock::GetInstance()->Set(); - while (status < EXIT && !Panic::Panicked()) { - if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) - break; - - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else { - if (GameLoop()) - WaitMessage(); - } - } - return exit_code ? exit_code : msg.wParam; -} - - -int -GameWinDX9::MaxTexSize() const -{ - if (video) { - int max_from_video = video->MaxTexSize(); - if (max_from_video < max_tex_size) - return max_from_video; - return max_tex_size; - } - else if (Video* video = Video::GetInstance()) { - return video->MaxTexSize(); - } - return 256; -} - - -int -GameWinDX9::MaxTexAspect() const -{ - if (video) - return video->MaxTexAspect(); - else if (Video* video = Video::GetInstance()) - return video->MaxTexAspect(); - return 1; -} - - -Color -GameWinDX9::GetScreenColor() const -{ - return screen_color; -} - - -int -GameWinDX9::GetScreenWidth() const -{ - if (video) - return video->Width(); - return 0; -} - - -int -GameWinDX9::GetScreenHeight() const -{ - if (video) - return video->Height(); - return 0; -} - - -HINSTANCE -GameWinDX9::GetHINST() -{ - return hInst; -} - - -HWND -GameWinDX9::GetHWND() -{ - return hwnd; -} - - -void -GameWinDX9::SetMaxTexSize(int n) -{ - if (n >= 64 && n <= 4096) - max_tex_size = n; -} - - -void -GameWinDX9::SetScreenColor(Color c) -{ - screen_color = c; - if (screen) - screen->SetBackgroundColor(c); -} diff --git a/Stars45/GameWinDX9.h b/Stars45/GameWinDX9.h deleted file mode 100644 index 43fc71d..0000000 --- a/Stars45/GameWinDX9.h +++ /dev/null @@ -1,79 +0,0 @@ -/* 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. -*/ - -#ifndef GameWinDX9_h -#define GameWinDX9_h - -#include "Color.h" -#include "Game.h" -#include "Types.h" -#include "WndProc.h" - - -class GameWinDX9 : public Game -{ -public: - static GameWinDX9* GetInstance(); - - GameWinDX9(); - virtual ~GameWinDX9(); - - virtual bool Init(HINSTANCE hi, HINSTANCE hpi, LPSTR cmdline, int nCmdShow); - virtual bool InitApplication(HINSTANCE hInstance); - virtual bool InitInstance(HINSTANCE hInstance, int nCmdShow); - virtual bool InitGame(); - - virtual bool InitVideo(); - virtual bool ResizeVideo(); - virtual bool ResetVideo(); - virtual bool ToggleFullscreen(); - virtual bool AdjustWindowForChange(); - - virtual bool SetupPalette(); - virtual bool LoadPalette(PALETTEENTRY* pal, BYTE* inv); - - virtual int Run() override; - - int MaxTexSize() const; - int MaxTexAspect() const; - Color GetScreenColor() const; - int GetScreenWidth() const; - int GetScreenHeight() const; - - HINSTANCE GetHINST(); - HWND GetHWND(); - - void SetMaxTexSize(int n); - void SetScreenColor(Color c); - - -protected: - friend LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM uParam, LPARAM lParam); - - PALETTEENTRY standard_palette[256]; - BYTE inverse_palette[32768]; - - int max_tex_size; - Color screen_color; - - HINSTANCE hInst; - HWND hwnd; - - bool is_windowed; - bool is_active; - bool is_device_lost; - bool is_minimized; - bool is_maximized; - bool ignore_size_change; - bool is_device_initialized; - bool is_device_restored; - -private: - static GameWinDX9* instance; -}; - - -#endif // GameWinDX9_h diff --git a/Stars45/Geometry.cpp b/Stars45/Geometry.cpp deleted file mode 100644 index 60b5c4d..0000000 --- a/Stars45/Geometry.cpp +++ /dev/null @@ -1,696 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Geometric Utilities -*/ - -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -void Rect::Inflate(int dx, int dy) -{ - x -= dx; - w += dx*2; - y -= dy; - h += dy*2; -} - -void Rect::Deflate(int dx, int dy) -{ - x += dx; - w -= dx*2; - y += dy; - h -= dy*2; -} - -void Rect::Inset(int l, int r, int t, int b) -{ - x += l; - y += t; - w -= l + r; - h -= t + b; -} - -int Rect::Contains(int ax, int ay) const -{ - if (ax < x) return 0; - if (ax > x+w) return 0; - if (ay < y) return 0; - if (ay > y+h) return 0; - - return 1; -} - -// +--------------------------------------------------------------------+ - -double -Point::Normalize() -{ - double scale = 1.0; - double len = length(); - - if (len) - scale /= len; - - x *= scale; - y *= scale; - z *= scale; - - return len; -} - -// +--------------------------------------------------------------------+ - -void -Point::SetElement(int i, double v) -{ - switch (i) { - case 0: x = v; break; - case 1: y = v; break; - case 2: z = v; break; - default: break; - } -} - -// +--------------------------------------------------------------------+ - -Point -Point::operator*(const Matrix& m) const -{ - Point result; - - result.x = (m.elem[0][0] * x) + (m.elem[1][0] * y) + (m.elem[2][0] * z); - result.y = (m.elem[0][1] * x) + (m.elem[1][1] * y) + (m.elem[2][1] * z); - result.z = (m.elem[0][2] * x) + (m.elem[1][2] * y) + (m.elem[2][2] * z); - - return result; -} - -// +--------------------------------------------------------------------+ - -double ClosestApproachTime(const Point& loc1, const Point& vel1, -const Point& loc2, const Point& vel2) -{ - double t = 0; - - Point D = loc1-loc2; - Point Dv = vel1-vel2; - - if (Dv.x || Dv.y || Dv.z) - t = -1 * (Dv*D) / (Dv*Dv); - - return t; -} - -// +--------------------------------------------------------------------+ - -float -Vec2::Normalize() -{ - float scale = 1.0f; - float len = length(); - - if (len) - scale /= len; - - x *= scale; - y *= scale; - - return len; -} - -// +--------------------------------------------------------------------+ - -float -Vec3::Normalize() -{ - float scale = 1.0f; - float len = length(); - - if (len) - scale /= len; - - x *= scale; - y *= scale; - z *= scale; - - return len; -} - -// +--------------------------------------------------------------------+ - -Vec3 -Vec3::operator*(const Matrix& m) const -{ - Vec3 result; - - result.x = (float) ((m.elem[0][0] * x) + (m.elem[1][0] * y) + (m.elem[2][0] * z)); - result.y = (float) ((m.elem[0][1] * x) + (m.elem[1][1] * y) + (m.elem[2][1] * z)); - result.z = (float) ((m.elem[0][2] * x) + (m.elem[1][2] * y) + (m.elem[2][2] * z)); - - return result; -} - -// +--------------------------------------------------------------------+ - -double ClosestApproachTime(const Vec3& loc1, const Vec3& vel1, -const Vec3& loc2, const Vec3& vel2) -{ - double t = 0; - - Point D = loc1-loc2; - Point Dv = vel1-vel2; - - if (Dv.x || Dv.y || Dv.z) - t = -1 * (Dv*D) / (Dv*Dv); - - return t; -} - -// +--------------------------------------------------------------------+ - -double -Quaternion::Normalize() -{ - double scale = 1.0; - double len = length(); - - if (len) - scale /= len; - - x *= scale; - y *= scale; - z *= scale; - w *= scale; - - return len; -} - -// +--------------------------------------------------------------------+ - -Matrix::Matrix() -{ - Identity(); -} - -Matrix::Matrix(const Matrix& m) -{ - CopyMemory(elem, m.elem, sizeof(elem)); -} - -Matrix::Matrix(const Point& vrt, const Point& vup, const Point& vpn) -{ - elem[0][0] = vrt.x; - elem[0][1] = vrt.y; - elem[0][2] = vrt.z; - - elem[1][0] = vup.x; - elem[1][1] = vup.y; - elem[1][2] = vup.z; - - elem[2][0] = vpn.x; - elem[2][1] = vpn.y; - elem[2][2] = vpn.z; -} - -// +--------------------------------------------------------------------+ - -Matrix& -Matrix::operator =(const Matrix& m) -{ - CopyMemory(elem, m.elem, sizeof(elem)); - - return *this; -} - -// +--------------------------------------------------------------------+ - -Matrix& -Matrix::operator*=(const Matrix& m) -{ - return *this = *this * m; -} - -// +--------------------------------------------------------------------+ - -void -Matrix::Identity() -{ - elem[0][0] = 1; - elem[0][1] = 0; - elem[0][2] = 0; - - elem[1][0] = 0; - elem[1][1] = 1; - elem[1][2] = 0; - - elem[2][0] = 0; - elem[2][1] = 0; - elem[2][2] = 1; -} - -// +--------------------------------------------------------------------+ - -inline void swap_elem(double& a, double& b) { double t=a; a=b; b=t; } - -void -Matrix::Transpose() -{ - swap_elem(elem[0][1], elem[1][0]); - swap_elem(elem[0][2], elem[2][0]); - swap_elem(elem[1][2], elem[2][1]); -} - -// +--------------------------------------------------------------------+ - -void -Matrix::Rotate(double roll, double pitch, double yaw) -{ - double e[3][3]; - CopyMemory(e, elem, sizeof(elem)); - - double sr = sin(roll); - double cr = cos(roll); - double sp = sin(pitch); - double cp = cos(pitch); - double sy = sin(yaw); - double cy = cos(yaw); - - double a,b,c; - - a = cy*cr; - b = cy*sr; - c = -sy; - - elem[0][0] = a*e[0][0] + b*e[1][0] + c*e[2][0]; - elem[0][1] = a*e[0][1] + b*e[1][1] + c*e[2][1]; - elem[0][2] = a*e[0][2] + b*e[1][2] + c*e[2][2]; - - a = cp*-sr + sp*sy*cr; - b = cp* cr + sp*sy*sr; - c = sp*cy; - - elem[1][0] = a*e[0][0] + b*e[1][0] + c*e[2][0]; - elem[1][1] = a*e[0][1] + b*e[1][1] + c*e[2][1]; - elem[1][2] = a*e[0][2] + b*e[1][2] + c*e[2][2]; - - a = -sp*-sr + cp*sy*cr; - b = -sp* cr + cp*sy*sr; - c = cp*cy; - - elem[2][0] = a*e[0][0] + b*e[1][0] + c*e[2][0]; - elem[2][1] = a*e[0][1] + b*e[1][1] + c*e[2][1]; - elem[2][2] = a*e[0][2] + b*e[1][2] + c*e[2][2]; -} - -// +--------------------------------------------------------------------+ - -void -Matrix::Roll(double roll) -{ - double s = sin(roll); - double c = cos(roll); - - double e00 = elem[0][0]; - double e01 = elem[0][1]; - double e02 = elem[0][2]; - double e10 = elem[1][0]; - double e11 = elem[1][1]; - double e12 = elem[1][2]; - - elem[0][0] = c*e00 + s*e10; - elem[0][1] = c*e01 + s*e11; - elem[0][2] = c*e02 + s*e12; - - elem[1][0] = -s*e00 + c*e10; - elem[1][1] = -s*e01 + c*e11; - elem[1][2] = -s*e02 + c*e12; -} - -// +--------------------------------------------------------------------+ - -void -Matrix::Pitch(double pitch) -{ - double s = sin(pitch); - double c = cos(pitch); - - double e10 = elem[1][0]; - double e11 = elem[1][1]; - double e12 = elem[1][2]; - double e20 = elem[2][0]; - double e21 = elem[2][1]; - double e22 = elem[2][2]; - - elem[1][0] = c*e10 + s*e20; - elem[1][1] = c*e11 + s*e21; - elem[1][2] = c*e12 + s*e22; - - elem[2][0] = -s*e10 + c*e20; - elem[2][1] = -s*e11 + c*e21; - elem[2][2] = -s*e12 + c*e22; -} - -// +--------------------------------------------------------------------+ - -void -Matrix::Yaw(double yaw) -{ - double s = sin(yaw); - double c = cos(yaw); - - double e00 = elem[0][0]; - double e01 = elem[0][1]; - double e02 = elem[0][2]; - double e20 = elem[2][0]; - double e21 = elem[2][1]; - double e22 = elem[2][2]; - - elem[0][0] = c*e00 - s*e20; - elem[0][1] = c*e01 - s*e21; - elem[0][2] = c*e02 - s*e22; - - elem[2][0] = s*e00 + c*e20; - elem[2][1] = s*e01 + c*e21; - elem[2][2] = s*e02 + c*e22; -} - -// +--------------------------------------------------------------------+ - -inline int sign(double d) { return (d >= 0); } - -void -Matrix::ComputeEulerAngles(double& roll, double& pitch, double& yaw) const -{ - double cy; - - yaw = asin(-elem[0][2]); - cy = cos(yaw); - roll = asin(elem[0][1] / cy); - pitch = asin(elem[1][2] / cy); - - if (sign(cos(roll)*cy) != sign(elem[0][0])) - roll = PI - roll; - - if (sign(cos(pitch)*cy) != sign(elem[2][2])) - pitch = PI - pitch; -} - -// +--------------------------------------------------------------------+ - -Matrix -Matrix::operator*(const Matrix& m) const -{ - Matrix r; - - r.elem[0][0] = elem[0][0]*m.elem[0][0] + elem[0][1]*m.elem[1][0] + elem[0][2]*m.elem[2][0]; - r.elem[0][1] = elem[0][0]*m.elem[0][1] + elem[0][1]*m.elem[1][1] + elem[0][2]*m.elem[2][1]; - r.elem[0][2] = elem[0][0]*m.elem[0][2] + elem[0][1]*m.elem[1][2] + elem[0][2]*m.elem[2][2]; - - r.elem[1][0] = elem[1][0]*m.elem[0][0] + elem[1][1]*m.elem[1][0] + elem[1][2]*m.elem[2][0]; - r.elem[1][1] = elem[1][0]*m.elem[0][1] + elem[1][1]*m.elem[1][1] + elem[1][2]*m.elem[2][1]; - r.elem[1][2] = elem[1][0]*m.elem[0][2] + elem[1][1]*m.elem[1][2] + elem[1][2]*m.elem[2][2]; - - r.elem[2][0] = elem[2][0]*m.elem[0][0] + elem[2][1]*m.elem[1][0] + elem[2][2]*m.elem[2][0]; - r.elem[2][1] = elem[2][0]*m.elem[0][1] + elem[2][1]*m.elem[1][1] + elem[2][2]*m.elem[2][1]; - r.elem[2][2] = elem[2][0]*m.elem[0][2] + elem[2][1]*m.elem[1][2] + elem[2][2]*m.elem[2][2]; - - return r; -} - -// +--------------------------------------------------------------------+ - -Point -Matrix::operator*(const Point& p) const -{ - Point result; - - result.x = (elem[0][0] * p.x) + (elem[0][1] * p.y) + (elem[0][2] * p.z); - result.y = (elem[1][0] * p.x) + (elem[1][1] * p.y) + (elem[1][2] * p.z); - result.z = (elem[2][0] * p.x) + (elem[2][1] * p.y) + (elem[2][2] * p.z); - - return result; -} - -// +--------------------------------------------------------------------+ - -Vec3 -Matrix::operator*(const Vec3& v) const -{ - Vec3 result; - - result.x = (float) ((elem[0][0] * v.x) + (elem[0][1] * v.y) + (elem[0][2] * v.z)); - result.y = (float) ((elem[1][0] * v.x) + (elem[1][1] * v.y) + (elem[1][2] * v.z)); - result.z = (float) ((elem[2][0] * v.x) + (elem[2][1] * v.y) + (elem[2][2] * v.z)); - - return result; -} - -// +--------------------------------------------------------------------+ - -double -Matrix::Cofactor(int i, int j) const -{ - int i1=0; - int i2=2; - int j1=0; - int j2=2; - - if (i==0) i1=1; else if (i==2) i2=1; - if (j==0) j1=1; else if (j==2) j2=1; - - double factor = elem[i1][j1]*elem[i2][j2] - elem[i1][j2]*elem[i2][j1]; - - if ((i+j) & 1) - factor *= -1; - - return factor; -} - -// +--------------------------------------------------------------------+ - -void -Matrix::Invert() -{ - double f[3][3]; - int i, j; - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - f[i][j] = Cofactor(j,i); - - double det = elem[0][0] * f[0][0] + - elem[0][1] * f[1][0] + - elem[0][2] * f[2][0]; - - if (det != 0) { - double inv = 1/det; - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - elem[i][j] = f[i][j] * inv; - } -} - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -Plane::Plane() -: distance(0.0f) -{ } - -Plane::Plane(const Point& p0, const Point& p1, const Point& p2) -{ - Point d1 = p1 - p0; - Point d2 = p2 - p0; - - normal = (Vec3) d1.cross(d2); - normal.Normalize(); - - distance = (float) (normal * p0); -} - -Plane::Plane(const Vec3& v0, const Vec3& v1, const Vec3& v2) -{ - Vec3 d1 = v1 - v0; - Vec3 d2 = v2 - v0; - - normal = d1.cross(d2); - normal.Normalize(); - - distance = normal * v0; -} - -void Plane::Rotate(const Vec3& v0, const Matrix& m) -{ - normal = normal * m; - distance = normal * v0; -} - -void Plane::Translate(const Vec3& v0) -{ - distance = normal * v0; -} - -// +--------------------------------------------------------------------+ -// 3-D dot product. - -double DotProduct(const Point& a, const Point& b) -{ - return (a.x * b.x) + (a.y * b.y) + (a.z * b.z); -} - -// +--------------------------------------------------------------------+ -// 3-D cross product. - -void CrossProduct(const Point& a, const Point& b, Point& out) -{ - out.x = (a.y * b.z) - (a.z * b.y); - out.y = (a.z * b.x) - (a.x * b.z); - out.z = (a.x * b.y) - (a.y * b.x); -} - -// +--------------------------------------------------------------------+ -// Concatenate two 3x3 matrices. - -void MConcat(double in1[3][3], double in2[3][3], double out[3][3]) -{ - int i, j; - - for (i=0 ; i<3 ; i++) { - for (j=0 ; j<3 ; j++) { - out[i][j] = in1[i][0] * in2[0][j] + - in1[i][1] * in2[1][j] + - in1[i][2] * in2[2][j]; - } - } -} - -/* GRAPHICS GEMS II ---------------------------------------------------- -* -* lines_intersect: AUTHOR: Mukesh Prasad -* -* This function computes whether two line segments, -* respectively joining the input points (x1,y1) -- (x2,y2) -* and the input points (x3,y3) -- (x4,y4) intersect. -* If the lines intersect, the output variables x, y are -* set to coordinates of the point of intersection. -* -* All values are in integers. The returned value is rounded -* to the nearest integer point. -* -* If non-integral grid points are relevant, the function -* can easily be transformed by substituting floating point -* calculations instead of integer calculations. -* -* Entry -* x1, y1, x2, y2 Coordinates of endpoints of one segment. -* x3, y3, x4, y4 Coordinates of endpoints of other segment. -* -* Exit -* x, y Coordinates of intersection point. -* -* The value returned by the function is one of: -* -* DONT_INTERSECT 0 -* DO_INTERSECT 1 -* COLLINEAR 2 -* -* Error conditions: -* -* Depending upon the possible ranges, and particularly on 16-bit -* computers, care should be taken to protect from overflow. -* -* In the following code, 'long' values have been used for this -* purpose, instead of 'int'. -* -*/ - -#define DONT_INTERSECT 0 -#define DO_INTERSECT 1 -#define COLLINEAR 2 - -inline int SAME_SIGNS(double a, double b) -{ - return ((a>=0 && b>=0) || (a<0 && b<0)); -} - -int -lines_intersect( -/* 1st line segment */ double x1, double y1, double x2, double y2, -/* 2nd line segment */ double x3, double y3, double x4, double y4, -/* pt of intersect */ double& ix, double& iy) -{ - double a1, a2, b1, b2, c1, c2; /* Coefficients of line eqns. */ - double r1, r2, r3, r4; /* 'Sign' values */ - double denom, offset, num; /* Intermediate values */ - - /* Compute a1, b1, c1, where line joining points 1 and 2 - * is "a1 x + b1 y + c1 = 0". */ - - a1 = y2 - y1; - b1 = x1 - x2; - c1 = x2 * y1 - x1 * y2; - - /* Compute r3 and r4. */ - - r3 = a1 * x3 + b1 * y3 + c1; - r4 = a1 * x4 + b1 * y4 + c1; - - /* Check signs of r3 and r4. If both point 3 and point 4 lie on - * same side of line 1, the line segments do not intersect. */ - - if ( r3 != 0 && - r4 != 0 && - SAME_SIGNS( r3, r4 )) - return ( DONT_INTERSECT ); - - /* Compute a2, b2, c2 */ - - a2 = y4 - y3; - b2 = x3 - x4; - c2 = x4 * y3 - x3 * y4; - - /* Compute r1 and r2 */ - - r1 = a2 * x1 + b2 * y1 + c2; - r2 = a2 * x2 + b2 * y2 + c2; - - /* Check signs of r1 and r2. If both point 1 and point 2 lie - * on same side of second line segment, the line segments do - * not intersect. */ - - if ( r1 != 0 && - r2 != 0 && - SAME_SIGNS( r1, r2 )) - return ( DONT_INTERSECT ); - - /* Line segments intersect: compute intersection point. */ - - denom = a1 * b2 - a2 * b1; - if ( denom == 0 ) - return ( DONT_INTERSECT ); - offset = denom < 0 ? - denom / 2 : denom / 2; - - /* The denom/2 is to get rounding instead of truncating. It - * is added or subtracted to the numerator, depending upon the - * sign of the numerator. */ - - num = b1 * c2 - b2 * c1; - ix = ( num < 0 ? num - offset : num + offset ) / denom; - - num = a2 * c1 - a1 * c2; - iy = ( num < 0 ? num - offset : num + offset ) / denom; - - return ( DO_INTERSECT ); -} - diff --git a/Stars45/Geometry.h b/Stars45/Geometry.h deleted file mode 100644 index 7170c6c..0000000 --- a/Stars45/Geometry.h +++ /dev/null @@ -1,303 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Geometric classes: Rect, Vec3, Point, Matrix, Plane -*/ - -#ifndef Geometry_h -#define Geometry_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -struct Rect; -struct Insets; -struct Matrix; -struct Vec3; -struct Point; -struct Quaternion; -struct Plane; - -#ifndef PI -const double PI = 3.14159265358979323846; -#endif -const double DEGREES = (PI/180); - -// +--------------------------------------------------------------------+ - -struct Rect -{ - static const char* TYPENAME() { return "Rect"; } - - Rect() : x(0), y(0), w(0), h(0) { } - Rect(int ix, int iy, int iw, int ih) : x(ix), y(iy), w(iw), h(ih) { } - - int operator==(const Rect& r) const { return x==r.x && y==r.y && w==r.w && h==r.h; } - int operator!=(const Rect& r) const { return x!=r.x || y!=r.y || w!=r.w || h!=r.h; } - - void Inflate(int dw, int dh); - void Deflate(int dw, int dh); - void Inset(int left, int right, int top, int bottom); - int Contains(int x, int y) const; - - int x, y, w, h; -}; - -// +--------------------------------------------------------------------+ - -struct Insets -{ - Insets() : left(0), right(0), top(0), bottom(0) { } - Insets(WORD l, WORD r, WORD t, WORD b) : left(l), right(r), top(t), bottom(b) { } - - WORD left; - WORD right; - WORD top; - WORD bottom; -}; - -// +--------------------------------------------------------------------+ - -struct Matrix -{ - static const char* TYPENAME() { return "Matrix"; } - - Matrix(); - Matrix(const Matrix& m); - Matrix(const Point& vrt, const Point& vup, const Point& vpn); - - Matrix& operator = (const Matrix& m); - Matrix& operator *= (const Matrix& m); - - double operator() (int i, int j) const { return elem[i][j]; } - double& operator() (int i, int j) { return elem[i][j]; } - - void Identity(); - void Transpose(); - void Rotate(double roll, double pitch, double yaw); - void Roll(double roll); - void Pitch(double pitch); - void Yaw(double yaw); - void ComputeEulerAngles(double& roll, double& pitch, double& yaw) const; - - double Cofactor(int i, int j) const; - void Invert(); - - Matrix Inverse() const { - Matrix result(*this); - result.Invert(); - return result; - } - - Matrix operator*(const Matrix& m) const; - Point operator*(const Point & p) const; - Vec3 operator*(const Vec3& v) const; - - double elem[3][3]; - -private: - Matrix(int no_init) { } -}; - -// +--------------------------------------------------------------------+ - -struct Vec2 -{ - static const char* TYPENAME() { return "Vec2"; } - - Vec2() { } - Vec2(int ix, int iy) : x((float) ix), y((float) iy) { } - Vec2(float ix, float iy) : x(ix), y(iy) { } - Vec2(double ix, double iy) : x((float) ix), y((float) iy) { } - - operator void*() const { return (void*) (x || y); } - int operator==(const Vec2& p) const { return x==p.x && y==p.y; } - int operator!=(const Vec2& p) const { return x!=p.x || y!=p.y; } - Vec2 operator+ (const Vec2& p) const { return Vec2(x+p.x, y+p.y); } - Vec2 operator- (const Vec2& p) const { return Vec2(x-p.x, y-p.y); } - Vec2 operator- () const { return Vec2(-x, -y); } - Vec2 operator* (float s) const { return Vec2(x*s, y*s); } - Vec2 operator/ (float s) const { return Vec2(x/s, y/s); } - float operator*(const Vec2& p) const { return (x*p.x + y*p.y); } - - Vec2& operator= (const Vec2& p) { x =p.x; y =p.y; return *this; } - Vec2& operator+=(const Vec2& p) { x+=p.x; y+=p.y; return *this; } - Vec2& operator-=(const Vec2& p) { x-=p.x; y-=p.y; return *this; } - Vec2& operator*=(float s) { x*=s; y*=s; return *this; } - Vec2& operator/=(float s) { x/=s; y/=s; return *this; } - - float length() const { return (float) sqrt(x*x+y*y); } - float Normalize(); - float dot(const Vec2& p) const { return (x*p.x + y*p.y); } - Vec2 normal() const { return Vec2(-y, x); } - - float x, y; -}; - -// +--------------------------------------------------------------------+ - -struct Vec3 -{ - static const char* TYPENAME() { return "Vec3"; } - - Vec3() { } - Vec3(int ix, int iy, int iz) : x((float) ix), y((float) iy), z((float) iz) { } - Vec3(float ix, float iy, float iz) : x(ix), y(iy), z(iz) { } - Vec3(double ix, double iy, double iz) : x((float) ix), y((float) iy), z((float) iz) { } - - operator void*() const { return (void*) (x || y || z); } - int operator==(const Vec3& p) const { return x==p.x && y==p.y && z==p.z; } - int operator!=(const Vec3& p) const { return x!=p.x || y!=p.y || z!=p.z; } - Vec3 operator+ (const Vec3& p) const { return Vec3(x+p.x, y+p.y, z+p.z); } - Vec3 operator- (const Vec3& p) const { return Vec3(x-p.x, y-p.y, z-p.z); } - Vec3 operator- () const { return Vec3(-x, -y, -z); } - Vec3 operator* (float s) const { return Vec3(x*s, y*s, z*s); } - Vec3 operator/ (float s) const { return Vec3(x/s, y/s, z/s); } - float operator* (const Vec3& p) const { return (x*p.x + y*p.y + z*p.z); } - Vec3 operator* (const Matrix&) const; - - Vec3& operator= (const Vec3& p) { x =p.x; y =p.y; z =p.z; return *this; } - Vec3& operator+=(const Vec3& p) { x+=p.x; y+=p.y; z+=p.z; return *this; } - Vec3& operator-=(const Vec3& p) { x-=p.x; y-=p.y; z-=p.z; return *this; } - Vec3& operator*=(float s) { x*=s; y*=s; z*=s; return *this; } - Vec3& operator/=(float s) { x/=s; y/=s; z/=s; return *this; } - - void SwapYZ() { float t = y; y = z; z = t; } - float length() const { return (float) sqrt(x*x+y*y+z*z); } - float Normalize(); - - float dot(const Vec3& p) const { return (x*p.x + y*p.y + z*p.z); } - Vec3 cross(const Vec3& v) const { return Vec3((y*v.z) - (z*v.y), - (z*v.x) - (x*v.z), - (x*v.y) - (y*v.x)); } - - float x, y, z; -}; - -double ClosestApproachTime(const Vec3& loc1, const Vec3& vel1, -const Vec3& loc2, const Vec3& vel2); - -// +--------------------------------------------------------------------+ - -struct Point -{ - static const char* TYPENAME() { return "Point"; } - - Point() : x(0), y(0), z(0) { } - Point(double ix, double iy, double iz) : x(ix), y(iy), z(iz) { } - Point(const Point& p) : x(p.x), y(p.y), z(p.z) { } - Point(const Vec3& v) : x(v.x), y(v.y), z(v.z) { } - - operator Vec3() const { return Vec3((float) x, (float) y, (float) z); } - - operator void*() const { return (void*) (x || y || z); } - int operator==(const Point& p) const { return x==p.x && y==p.y && z==p.z; } - int operator!=(const Point& p) const { return x!=p.x || y!=p.y || z!=p.z; } - Point operator+ (const Point& p) const { return Point(x+p.x, y+p.y, z+p.z); } - Point operator- (const Point& p) const { return Point(x-p.x, y-p.y, z-p.z); } - Point operator- () const { return Point(-x, -y, -z); } - Point operator* (double s) const { return Point(x*s, y*s, z*s); } - Point operator/ (double s) const { return Point(x/s, y/s, z/s); } - double operator*(const Point& p) const { return (x*p.x + y*p.y + z*p.z); } - Point operator* (const Matrix& m) const; - - Point& operator= (const Point& p) { x =p.x; y =p.y; z =p.z; return *this; } - Point& operator+=(const Point& p) { x+=p.x; y+=p.y; z+=p.z; return *this; } - Point& operator-=(const Point& p) { x-=p.x; y-=p.y; z-=p.z; return *this; } - Point& operator*=(double s) { x*=s; y*=s; z*=s; return *this; } - Point& operator/=(double s) { x/=s; y/=s; z/=s; return *this; } - - double length() const { return sqrt(x*x+y*y+z*z); } - double Normalize(); - void SwapYZ() { double t = y; y = z; z = t; } - Point OtherHand() const { return Point(-x, z, y); } - - void SetElement(int i, double v); - - double dot(const Point& p) const { return (x*p.x + y*p.y + z*p.z); } - Point cross(const Point& p) const { return Point((y*p.z) - (z*p.y), - (z*p.x) - (x*p.z), - (x*p.y) - (y*p.x)); } - - double x, y, z; -}; - -double ClosestApproachTime(const Point& loc1, const Point& vel1, -const Point& loc2, const Point& vel2); - -// +--------------------------------------------------------------------+ - -struct Quaternion -{ - static const char* TYPENAME() { return "Quaternion"; } - - Quaternion() : x(0), y(0), z(0), w(0) { } - Quaternion(double ix, - double iy, - double iz, - double iw) : x(ix), y(iy), z(iz), w(iw) { } - Quaternion(const Quaternion& q) : x(q.x), y(q.y), z(q.z), w(q.w) { } - - int operator==(const Quaternion& q) const { return x==q.x && y==q.y && z==q.z && w==q.w; } - int operator!=(const Quaternion& q) const { return x!=q.x || y!=q.y || z!=q.z || w!=q.w; } - - Quaternion operator+ (const Quaternion& q) const { return Quaternion(x+q.x, y+q.y, z+q.z, w+q.w); } - Quaternion operator- (const Quaternion& q) const { return Quaternion(x-q.x, y-q.y, z-q.z, w-q.w); } - Quaternion operator- () const { return Quaternion(-x, -y, -z, -w); } - Quaternion operator* (double s) const { return Quaternion(x*s, y*s, z*s, w*s); } - Quaternion operator/ (double s) const { return Quaternion(x/s, y/s, z/s, w/s); } - - Quaternion& operator= (const Quaternion& q) { x =q.x; y =q.y; z =q.z; w =q.w; return *this; } - Quaternion& operator+=(const Quaternion& q) { x+=q.x; y+=q.y; z+=q.z; w+=q.w; return *this; } - Quaternion& operator-=(const Quaternion& q) { x-=q.x; y-=q.y; z-=q.z; w-=q.w; return *this; } - Quaternion& operator*=(double s) { x*=s; y*=s; z*=s; w*=s; return *this; } - Quaternion& operator/=(double s) { x/=s; y/=s; z/=s; w/=s; return *this; } - - double length() const { return sqrt(x*x + y*y + z*z + w*w); } - double Normalize(); - - double x, y, z, w; -}; - -// +--------------------------------------------------------------------+ - -struct Plane -{ - static const char* TYPENAME() { return "Plane"; } - - Plane(); - Plane(const Point& p0, const Point& p1, const Point& p2); - Plane(const Vec3& v0, const Vec3& v1, const Vec3& v2); - - void Rotate(const Vec3& v0, const Matrix& m); - void Translate(const Vec3& v0); - - float distance; - Vec3 normal; -}; - -// +--------------------------------------------------------------------+ - -double DotProduct(const Point& a, const Point& b); -void CrossProduct(const Point& a, const Point& b, Point& out); -void MConcat(double in1[3][3], double in2[3][3], double out[3][3]); - -// +--------------------------------------------------------------------+ - -int lines_intersect( -/* 1st line segment */ double x1, double y1, double x2, double y2, -/* 2nd line segment */ double x3, double y3, double x4, double y4, -/* intersect point */ double& x, double& y); - -// +--------------------------------------------------------------------+ - -#endif // Geometry_h - diff --git a/Stars45/Graphic.cpp b/Stars45/Graphic.cpp deleted file mode 100644 index ff8115b..0000000 --- a/Stars45/Graphic.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract 3D Graphic Object -*/ - -#include "Graphic.h" -#include "Scene.h" -#include "Projector.h" - -// +--------------------------------------------------------------------+ - -int Graphic::id_key = 1; - -// +--------------------------------------------------------------------+ - -Graphic::Graphic() - : id(id_key++), visible(true), loc(0.0f, 0.0f, 0.0f), - radius(0.0f), infinite(0), foreground(0), hidden(0), life(-1), - trans(false), shadow(false), luminous(false), depth(0.0f), scene(0) -{ - screen_rect.x = 0; - screen_rect.y = 0; - screen_rect.w = 0; - screen_rect.h = 0; - - ZeroMemory(name, sizeof(name)); - strcpy_s(name, "Graphic"); -} - -// +--------------------------------------------------------------------+ - -Graphic::~Graphic() -{ } - -int -Graphic::operator < (const Graphic& g) const -{ - if (!infinite && g.infinite) - return 1; - - else if (infinite && !g.infinite) - return 0; - - double za = fabs(Depth()); - double zb = fabs(g.Depth()); - - return (za < zb); -} - -int -Graphic::operator <= (const Graphic& g) const -{ - if (!infinite && g.infinite) - return 1; - - else if (infinite && !g.infinite) - return 0; - - double za = fabs(Depth()); - double zb = fabs(g.Depth()); - - return (za <= zb); -} - -// +--------------------------------------------------------------------+ - -void -Graphic::SetInfinite(bool b) -{ - infinite = (BYTE) b; - - if (infinite) - depth = 1.0e9f; -} - -// +--------------------------------------------------------------------+ - -int -Graphic::Nearer(Graphic* a, Graphic* b) -{ - if (a->depth < b->depth) return -1; - else if (a->depth == b->depth) return 0; - else return 1; -} - -// +--------------------------------------------------------------------+ - -int -Graphic::Farther(Graphic* a, Graphic* b) -{ - if (a->depth > b->depth) return -1; - else if (a->depth == b->depth) return 0; - else return 1; -} - -// +--------------------------------------------------------------------+ - -void -Graphic::Destroy() -{ - if (scene) - scene->DelGraphic(this); - - delete this; -} - -// +--------------------------------------------------------------------+ - -int -Graphic::CollidesWith(Graphic& o) -{ - Point delta_loc = loc - o.loc; - - // bounding spheres test: - if (delta_loc.length() > radius + o.radius) - return 0; - - return 1; -} - -// +--------------------------------------------------------------------+ - -int -Graphic::CheckRayIntersection(Point Q, Point w, double len, Point& ipt, -bool treat_translucent_polys_as_solid) -{ - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Graphic::ProjectScreenRect(Projector* p) -{ - screen_rect.x = 2000; - screen_rect.y = 2000; - screen_rect.w = 0; - screen_rect.h = 0; -} - -// +--------------------------------------------------------------------+ - -bool -Graphic::CheckVisibility(Projector& projector) -{ - if (projector.IsVisible( Location(), Radius()) && - projector.ApparentRadius(Location(), Radius()) > 1) { - - visible = true; - } - else { - visible = false; - screen_rect.x = 2000; - screen_rect.y = 2000; - screen_rect.w = 0; - screen_rect.h = 0; - } - - return visible; -} diff --git a/Stars45/Graphic.h b/Stars45/Graphic.h deleted file mode 100644 index fac4f59..0000000 --- a/Stars45/Graphic.h +++ /dev/null @@ -1,138 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract 3D Graphic Object -*/ - -#ifndef Graphic_h -#define Graphic_h - -#include "Geometry.h" -#include "Color.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -#define GRAPHIC_DESTROY(x) if (x) { x->Destroy(); x = 0; } //-V571 - -// +--------------------------------------------------------------------+ - -class Projector; -class Light; -class Scene; -class Video; - -// +--------------------------------------------------------------------+ - -class Graphic -{ -public: - static const char* TYPENAME() { return "Graphic"; } - - enum TYPE { OTHER, SOLID, SPRITE, BOLT, QUAD }; - - enum RENDER_FLAGS { - RENDER_SOLID = 0x0001, - RENDER_ALPHA = 0x0002, - RENDER_ADDITIVE = 0x0004, - RENDER_FIRST_LIGHT = 0x1000, - RENDER_ADD_LIGHT = 0x2000 - }; - - Graphic(); - virtual ~Graphic(); - - int operator == (const Graphic& g) const { return id == g.id; } - int operator < (const Graphic& g) const; - int operator <= (const Graphic& g) const; - - // operations - virtual void Render(Video* video, DWORD flags) { } - virtual void Update() { } - virtual void SetOrientation(const Matrix& o) { } - - virtual int CollidesWith(Graphic& o); - - // accessors / mutators - int Identity() const { return id; } - const char* Name() const { return name; } - bool IsVisible() const { return visible; } - void SetVisible(bool v) { visible = v; } - float Radius() const { return radius; } - - Point Location() const { return loc; } - virtual void MoveTo(const Point& p) { loc = p; } - virtual void TranslateBy(const Point& ref) { loc = loc - ref; } - - virtual float Depth() const { return depth; } - virtual void SetDepth(float d) { depth = d; } - static int Nearer(Graphic* a, Graphic* b); - static int Farther(Graphic* a, Graphic* b); - - virtual int IsInfinite() const { return infinite; } - virtual void SetInfinite(bool b); - virtual int IsForeground() const { return foreground; } - virtual void SetForeground(bool f){ foreground = f; } - virtual int IsBackground() const { return background; } - virtual void SetBackground(bool b){ background = b; } - - virtual int Hidden() const { return hidden; } - virtual int Life() const { return life; } - virtual void Destroy(); - virtual void Hide() { hidden = true; } - virtual void Show() { hidden = false; } - virtual bool Luminous() const { return luminous;} - virtual void SetLuminous(bool l) { luminous = l; } - virtual bool Translucent() const { return trans; } - virtual bool CastsShadow() const { return shadow; } - virtual void SetShadow(bool s) { shadow = s; } - - virtual bool IsSolid() const { return false; } - virtual bool IsSprite() const { return false; } - virtual bool IsBolt() const { return false; } - virtual bool IsQuad() const { return false; } - - virtual void ProjectScreenRect(Projector* p); - const Rect& ScreenRect() const { return screen_rect; } - virtual Scene* GetScene() const { return scene; } - virtual void SetScene(Scene*s) { scene = s; } - - virtual int CheckRayIntersection(Point pt, Point vpn, double len, Point& ipt, - bool treat_translucent_polys_as_solid=true); - - virtual bool CheckVisibility(Projector& projector); - -protected: - static int id_key; - - int id; - Point loc; - float depth; - float radius; - int life; - - bool visible; - bool infinite; - bool foreground; - bool background; - bool hidden; - bool trans; - bool shadow; - bool luminous; - - Rect screen_rect; - Scene* scene; - char name[32]; -}; - -// +--------------------------------------------------------------------+ - -#endif // Graphic_h - diff --git a/Stars45/Grid.cpp b/Stars45/Grid.cpp deleted file mode 100644 index f65b483..0000000 --- a/Stars45/Grid.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Tactical Grid class -*/ - -#include "Grid.h" - -#include "Game.h" -#include "Video.h" -#include "Window.h" - -static const Color DARK_LINE( 8, 8, 8); -static const Color LITE_LINE(16, 16, 16); - -// +--------------------------------------------------------------------+ - -Grid::Grid(int asize, int astep) -: size(asize), step(astep), drawn(0) -{ - radius = (float) (size * 1.414); -} - -Grid::~Grid() -{ } - -// +--------------------------------------------------------------------+ - -int Grid::CollidesWith(Graphic& o) { return 0; } - -// +--------------------------------------------------------------------+ - -void Grid::Render(Video* video, DWORD flags) -{ - if (!video || hidden) return; - - int c = 0; - Color line; - - for (int i = 0; i <= size; i += step) { - Point p1( i, 0, -size); p1 += Location(); - Point p2( i, 0, size); p2 += Location(); - Point p3(-i, 0, -size); p3 += Location(); - Point p4(-i, 0, size); p4 += Location(); - - if (c) line = DARK_LINE; - else line = LITE_LINE; - - DrawLine(video, p1,p2,line); - DrawLine(video, p3,p4,line); - - c++; - if (c > 3) c = 0; - } - - c = 0; - - for (int i = 0; i <= size; i += step) { - Point p1(-size, 0, i); p1 += Location(); - Point p2( size, 0, i); p2 += Location(); - Point p3(-size, 0, -i); p3 += Location(); - Point p4( size, 0, -i); p4 += Location(); - - if (c) line = DARK_LINE; - else line = LITE_LINE; - - DrawLine(video, p1,p2,line); - DrawLine(video, p3,p4,line); - - c++; - if (c > 3) c = 0; - } -} - -void Grid::DrawLine(Video* video, Point& p1, Point& p2, Color grid_color) -{ - Vec3 v[2]; - - v[0] = p1; - v[1] = p2; - - video->DrawLines(1, v, grid_color, Video::BLEND_ADDITIVE); -} diff --git a/Stars45/Grid.h b/Stars45/Grid.h deleted file mode 100644 index eb426bb..0000000 --- a/Stars45/Grid.h +++ /dev/null @@ -1,49 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Tactical Grid -*/ - -#ifndef Grid_h -#define Grid_h - -#include "Types.h" -#include "Graphic.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Window; -class Projector; -class PolyRender; - -// +--------------------------------------------------------------------+ - -class Grid : public Graphic -{ -public: - Grid(int size, int step); - virtual ~Grid(); - - virtual void Render(Video* video, DWORD flags); - virtual int CollidesWith(Graphic& o); - -protected: - virtual void DrawLine(Video* video, Point& p1, Point& p2, Color c); - - int size; - int step; - int drawn; -}; - -// +--------------------------------------------------------------------+ - -#endif // Grid_h - diff --git a/Stars45/GroundAI.cpp b/Stars45/GroundAI.cpp deleted file mode 100644 index 4435742..0000000 --- a/Stars45/GroundAI.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Low-Level Artificial Intelligence class for Ground Units -*/ - -#include "GroundAI.h" -#include "SteerAI.h" -#include "System.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Shield.h" -#include "Sim.h" -#include "Player.h" -#include "CarrierAI.h" -#include "Contact.h" -#include "Weapon.h" -#include "WeaponGroup.h" - -#include "Clock.h" -#include "Physical.h" - -// +----------------------------------------------------------------------+ - -GroundAI::GroundAI(SimObject* s) -: ship((Ship*) s), target(0), subtarget(0), exec_time(0), carrier_ai(0) -{ - Sim* sim = Sim::GetSim(); - Ship* pship = sim->GetPlayerShip(); - int player_team = 1; - int ai_level = 1; - - if (pship) - player_team = pship->GetIFF(); - - Player* player = Player::GetCurrentPlayer(); - if (player) { - if (ship && ship->GetIFF() && ship->GetIFF() != player_team) { - ai_level = player->AILevel(); - } - else if (player->AILevel() == 0) { - ai_level = 1; - } - } - - // evil alien ships are *always* smart: - if (ship && ship->GetIFF() > 1 && ship->Design()->auto_roll > 1) { - ai_level = 2; - } - - if (ship && ship->GetHangar() && ship->GetCommandAILevel() > 0) - carrier_ai = new CarrierAI(ship, ai_level); -} - - -// +--------------------------------------------------------------------+ - -GroundAI::~GroundAI() -{ - delete carrier_ai; -} - -// +--------------------------------------------------------------------+ - -void -GroundAI::SetTarget(SimObject* targ, System* sub) -{ - if (target != targ) { - target = targ; - - if (target) - Observe(target); - } - - subtarget = sub; -} - -// +--------------------------------------------------------------------+ - -bool -GroundAI::Update(SimObject* obj) -{ - if (obj == target) { - target = 0; - subtarget = 0; - } - - return SimObserver::Update(obj); -} - -const char* -GroundAI::GetObserverName() const -{ - static char name[64]; - sprintf_s(name, "GroundAI(%s)", ship->Name()); - return name; -} - -// +--------------------------------------------------------------------+ - -void -GroundAI::SelectTarget() -{ - SimObject* potential_target = 0; - - // pick the closest combatant ship with a different IFF code: - double target_dist = 1.0e15; - - Ship* current_ship_target = 0; - - ListIter c_iter = ship->ContactList(); - while (++c_iter) { - Contact* contact = c_iter.value(); - int c_iff = contact->GetIFF(ship); - Ship* c_ship = contact->GetShip(); - Shot* c_shot = contact->GetShot(); - bool rogue = false; - - if (c_ship) - rogue = c_ship->IsRogue(); - - if (rogue || c_iff > 0 && c_iff != ship->GetIFF() && c_iff < 1000) { - if (c_ship && !c_ship->InTransition()) { - // found an enemy, check distance: - double dist = (ship->Location() - c_ship->Location()).length(); - - if (!current_ship_target || (c_ship->Class() <= current_ship_target->Class() && - dist < target_dist)) { - current_ship_target = c_ship; - target_dist = dist; - } - } - } - - potential_target = current_ship_target; - } - - SetTarget(potential_target); -} - -// +--------------------------------------------------------------------+ - -int -GroundAI::Type() const -{ - return SteerAI::GROUND; -} - -// +--------------------------------------------------------------------+ - -void -GroundAI::ExecFrame(double secs) -{ - const int exec_period = 1000; - - if ((int) Clock::GetInstance()->GameTime() - exec_time > exec_period) { - exec_time = (int) Clock::GetInstance()->GameTime(); - SelectTarget(); - } - - if (ship) { - Shield* shield = ship->GetShield(); - - if (shield) - shield->SetPowerLevel(100); - - ListIter iter = ship->Weapons(); - while (++iter) { - WeaponGroup* group = (WeaponGroup*) iter.value(); - - if (group->NumWeapons() > 1 && group->CanTarget(Ship::DROPSHIPS)) - group->SetFiringOrders(Weapon::POINT_DEFENSE); - else - group->SetFiringOrders(Weapon::AUTO); - - group->SetTarget((Ship*) target, 0); - } - - if (carrier_ai) - carrier_ai->ExecFrame(secs); - } -} diff --git a/Stars45/GroundAI.h b/Stars45/GroundAI.h deleted file mode 100644 index ca135ef..0000000 --- a/Stars45/GroundAI.h +++ /dev/null @@ -1,60 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Ground Unit (low-level) Artifical Intelligence class -*/ - -#ifndef GroundAI_h -#define GroundAI_h - -#include "Types.h" -#include "SimObject.h" -#include "Director.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class System; -class CarrierAI; - -// +--------------------------------------------------------------------+ - -class GroundAI : public Director, -public SimObserver -{ -public: - GroundAI(SimObject* self); - virtual ~GroundAI(); - - virtual void ExecFrame(double seconds); - virtual void SetTarget(SimObject* targ, System* sub=0); - virtual SimObject* GetTarget() const { return target; } - virtual System* GetSubTarget() const { return subtarget; } - virtual int Type() const; - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - -protected: - virtual void SelectTarget(); - - Ship* ship; - SimObject* target; - System* subtarget; - double exec_time; - CarrierAI* carrier_ai; -}; - - -// +--------------------------------------------------------------------+ - -#endif // GroundAI_h - diff --git a/Stars45/HUDSounds.cpp b/Stars45/HUDSounds.cpp deleted file mode 100644 index 3dcab0b..0000000 --- a/Stars45/HUDSounds.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - HUDSounds singleton class utility implementation -*/ - -#include "HUDSounds.h" -#include "AudioConfig.h" - -#include "Sound.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -static Sound* mfd_mode = 0; -static Sound* nav_mode = 0; -static Sound* wep_mode = 0; -static Sound* wep_disp = 0; -static Sound* hud_mode = 0; -static Sound* hud_widget = 0; -static Sound* shield_level = 0; -static Sound* red_alert = 0; -static Sound* tac_accept = 0; -static Sound* tac_reject = 0; - -// +--------------------------------------------------------------------+ - -static void LoadInterfaceSound(DataLoader* loader, const char* wave, Sound*& s) -{ - loader->LoadSound(wave, s, 0, true); // optional sound effect -} - -void -HUDSounds::Initialize() -{ - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Sounds/"); - - LoadInterfaceSound(loader, "mfd_mode.wav", mfd_mode); - LoadInterfaceSound(loader, "nav_mode.wav", nav_mode); - LoadInterfaceSound(loader, "wep_mode.wav", wep_mode); - LoadInterfaceSound(loader, "wep_disp.wav", wep_disp); - LoadInterfaceSound(loader, "hud_mode.wav", hud_mode); - LoadInterfaceSound(loader, "hud_widget.wav", hud_widget); - LoadInterfaceSound(loader, "shield_level.wav", shield_level); - LoadInterfaceSound(loader, "alarm.wav", red_alert); - LoadInterfaceSound(loader, "tac_accept.wav", tac_accept); - LoadInterfaceSound(loader, "tac_reject.wav", tac_reject); - - if (red_alert) - red_alert->SetFlags(Sound::AMBIENT | Sound::LOOP | Sound::LOCKED); - - loader->SetDataPath(0); -} - -// +--------------------------------------------------------------------+ - -void -HUDSounds::Close() -{ - delete mfd_mode; - delete nav_mode; - delete wep_mode; - delete wep_disp; - delete hud_mode; - delete hud_widget; - delete shield_level; - delete red_alert; - delete tac_accept; - delete tac_reject; -} - -void HUDSounds::PlaySound(int n) -{ - Sound* sound = 0; - - switch (n) { - default: - case SND_MFD_MODE: if (mfd_mode) sound = mfd_mode->Duplicate(); break; - case SND_NAV_MODE: if (nav_mode) sound = nav_mode->Duplicate(); break; - case SND_WEP_MODE: if (wep_mode) sound = wep_mode->Duplicate(); break; - case SND_WEP_DISP: if (wep_disp) sound = wep_disp->Duplicate(); break; - case SND_HUD_MODE: if (hud_mode) sound = hud_mode->Duplicate(); break; - case SND_HUD_WIDGET: if (hud_widget) sound = hud_widget->Duplicate(); break; - case SND_SHIELD_LEVEL: if (shield_level) sound = shield_level->Duplicate(); break; - case SND_TAC_ACCEPT: if (tac_accept) sound = tac_accept->Duplicate(); break; - case SND_TAC_REJECT: if (tac_reject) sound = tac_reject->Duplicate(); break; - - // RED ALERT IS A SPECIAL CASE! - case SND_RED_ALERT: - if (red_alert) { - sound = red_alert; - } - break; - } - - if (sound && !sound->IsPlaying()) { - int gui_volume = AudioConfig::GuiVolume(); - sound->SetVolume(gui_volume); - sound->Play(); - } -} - -void HUDSounds::StopSound(int n) -{ - if (n == SND_RED_ALERT && red_alert) { - red_alert->Stop(); - } -} diff --git a/Stars45/HUDSounds.h b/Stars45/HUDSounds.h deleted file mode 100644 index bc10ce2..0000000 --- a/Stars45/HUDSounds.h +++ /dev/null @@ -1,45 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - HUDSounds singleton class utility -*/ - -#ifndef HUDSounds_h -#define HUDSounds_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class HUDSounds -{ -public: - enum SOUNDS { - SND_MFD_MODE, - SND_NAV_MODE, - SND_WEP_MODE, - SND_WEP_DISP, - SND_HUD_MODE, - SND_HUD_WIDGET, - SND_SHIELD_LEVEL, - SND_RED_ALERT, - SND_TAC_ACCEPT, - SND_TAC_REJECT - }; - - static void Initialize(); - static void Close(); - - static void PlaySound(int n); - static void StopSound(int n); -}; - -#endif // HUDSounds_h - diff --git a/Stars45/HUDView.cpp b/Stars45/HUDView.cpp deleted file mode 100644 index c280333..0000000 --- a/Stars45/HUDView.cpp +++ /dev/null @@ -1,4373 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Heads Up Display -*/ - -#include "HUDView.h" -#include "HUDSounds.h" -#include "Ship.h" -#include "Element.h" -#include "Computer.h" -#include "Drive.h" -#include "Instruction.h" -#include "NavSystem.h" -#include "Power.h" -#include "Shield.h" -#include "Sensor.h" -#include "Contact.h" -#include "ShipDesign.h" -#include "Shot.h" -#include "Drone.h" -#include "Thruster.h" -#include "Weapon.h" -#include "WeaponGroup.h" -#include "FlightDeck.h" -#include "SteerAI.h" -#include "Sim.h" -#include "StarSystem.h" -#include "Starshatter.h" -#include "CameraDirector.h" -#include "Mfd.h" -#include "RadioView.h" -#include "FormatUtil.h" -#include "Hoop.h" -#include "QuantumDrive.h" -#include "KeyMap.h" -#include "AudioConfig.h" -#include "Player.h" - -#include "NetGame.h" -#include "NetPlayer.h" - -#include "Color.h" -#include "CameraView.h" -#include "Screen.h" -#include "DataLoader.h" -#include "Scene.h" -#include "FontMgr.h" -#include "Graphic.h" -#include "Sprite.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "MouseController.h" -#include "Polygon.h" -#include "Sound.h" -#include "Game.h" -#include "Clock.h" -#include "GameWinDX9.h" -#include "ContentBundle.h" -#include "Window.h" - -static Bitmap hud_left_air; -static Bitmap hud_right_air; -static Bitmap hud_left_fighter; -static Bitmap hud_right_fighter; -static Bitmap hud_left_starship; -static Bitmap hud_right_starship; -static Bitmap instr_left; -static Bitmap instr_right; -static Bitmap warn_left; -static Bitmap warn_right; -static Bitmap lead; -static Bitmap cross; -static Bitmap cross1; -static Bitmap cross2; -static Bitmap cross3; -static Bitmap cross4; -static Bitmap fpm; -static Bitmap hpm; -static Bitmap pitch_ladder_pos; -static Bitmap pitch_ladder_neg; -static Bitmap chase_left; -static Bitmap chase_right; -static Bitmap chase_top; -static Bitmap chase_bottom; -static Bitmap icon_ship; -static Bitmap icon_target; - -static BYTE* hud_left_shade_air = 0; -static BYTE* hud_right_shade_air = 0; -static BYTE* hud_left_shade_fighter = 0; -static BYTE* hud_right_shade_fighter = 0; -static BYTE* hud_left_shade_starship = 0; -static BYTE* hud_right_shade_starship = 0; -static BYTE* instr_left_shade = 0; -static BYTE* instr_right_shade = 0; -static BYTE* warn_left_shade = 0; -static BYTE* warn_right_shade = 0; -static BYTE* lead_shade = 0; -static BYTE* cross_shade = 0; -static BYTE* cross1_shade = 0; -static BYTE* cross2_shade = 0; -static BYTE* cross3_shade = 0; -static BYTE* cross4_shade = 0; -static BYTE* fpm_shade = 0; -static BYTE* hpm_shade = 0; -static BYTE* pitch_ladder_pos_shade = 0; -static BYTE* pitch_ladder_neg_shade = 0; -static BYTE* chase_left_shade = 0; -static BYTE* chase_right_shade = 0; -static BYTE* chase_top_shade = 0; -static BYTE* chase_bottom_shade = 0; -static BYTE* icon_ship_shade = 0; -static BYTE* icon_target_shade = 0; - -static Sprite* hud_left_sprite = 0; -static Sprite* hud_right_sprite = 0; -static Sprite* fpm_sprite = 0; -static Sprite* hpm_sprite = 0; -static Sprite* lead_sprite = 0; -static Sprite* aim_sprite = 0; -static Sprite* tgt1_sprite = 0; -static Sprite* tgt2_sprite = 0; -static Sprite* tgt3_sprite = 0; -static Sprite* tgt4_sprite = 0; -static Sprite* chase_sprite = 0; -static Sprite* instr_left_sprite = 0; -static Sprite* instr_right_sprite = 0; -static Sprite* warn_left_sprite = 0; -static Sprite* warn_right_sprite = 0; -static Sprite* icon_ship_sprite = 0; -static Sprite* icon_target_sprite = 0; - -static Sound* missile_lock_sound; - -const int NUM_HUD_COLORS = 4; - -Color standard_hud_colors[NUM_HUD_COLORS] = { - Color(130,190,140), // green - Color(130,200,220), // cyan - Color(250,170, 80), // orange - // Color(220,220,100), // yellow - Color( 16, 16, 16) // dark gray -}; - -Color standard_txt_colors[NUM_HUD_COLORS] = { - Color(150,200,170), // green w/ green gray - Color(220,220,180), // cyan w/ light yellow - Color(220,220, 80), // orange w/ yellow - // Color(180,200,220), // yellow w/ white - Color( 32, 32, 32) // dark gray -}; - -Color night_vision_colors[NUM_HUD_COLORS] = { - Color( 20, 80, 20), // green - Color( 30, 80, 80), // cyan - Color( 80, 80, 20), // yellow - // Color(180,200,220), // not used - Color( 0, 0, 0) // no night vision -}; - -static Font* hud_font = 0; -static Font* big_font = 0; - -static bool mouse_in = false; -static int mouse_latch = 0; -static int mouse_index = -1; - -static int ship_status = System::NOMINAL; -static int tgt_status = System::NOMINAL; - -// +--------------------------------------------------------------------+ - -enum TXT { - MAX_CONTACT = 50, - - TXT_CAUTION_TXT = 0, - TXT_LAST_CAUTION = 23, - TXT_CAM_ANGLE, - TXT_CAM_MODE, - TXT_PAUSED, - TXT_GEAR_DOWN, - - TXT_HUD_MODE, - TXT_PRIMARY_WEP, - TXT_SECONDARY_WEP, - TXT_DECOY, - TXT_SHIELD, - TXT_AUTO, - TXT_SHOOT, - TXT_NAV_INDEX, - TXT_NAV_ACTION, - TXT_NAV_FORMATION, - TXT_NAV_SPEED, - TXT_NAV_ETR, - TXT_NAV_HOLD, - - TXT_SPEED, - TXT_RANGE, - TXT_CLOSING_SPEED, - TXT_THREAT_WARN, - TXT_COMPASS, - TXT_HEADING, - TXT_PITCH, - TXT_ALTITUDE, - TXT_GFORCE, - TXT_MISSILE_T1, - TXT_MISSILE_T2, - TXT_ICON_SHIP_TYPE, - TXT_ICON_TARGET_TYPE, - TXT_TARGET_NAME, - TXT_TARGET_DESIGN, - TXT_TARGET_SHIELD, - TXT_TARGET_HULL, - TXT_TARGET_SUB, - TXT_TARGET_ETA, - - TXT_MSG_1, - TXT_MSG_2, - TXT_MSG_3, - TXT_MSG_4, - TXT_MSG_5, - TXT_MSG_6, - - TXT_NAV_PT, - TXT_SELF, - TXT_SELF_NAME, - TXT_CONTACT_NAME, - TXT_CONTACT_INFO = TXT_CONTACT_NAME + MAX_CONTACT, - TXT_LAST = TXT_CONTACT_INFO + MAX_CONTACT, - - TXT_LAST_ACTIVE = TXT_NAV_HOLD, - TXT_INSTR_PAGE = TXT_CAUTION_TXT + 6, -}; - -static HUDText hud_text[TXT_LAST]; - -void -HUDView::DrawHUDText(int index, const char* txt, Rect& rect, int align, int upcase, bool box) -{ - if (index < 0 || index >= TXT_LAST) - return; - - HUDText& ht = hud_text[index]; - Color hc = ht.color; - - char txt_buf[256]; - int n = strlen(txt); - - if (n > 250) n = 250; - - int i; - for (i = 0; i < n; i++) { - if (upcase && islower(txt[i])) - txt_buf[i] = toupper(txt[i]); - else - txt_buf[i] = txt[i]; - } - - txt_buf[i] = 0; - - if (box) { - ht.font->DrawText(txt_buf, n, rect, DT_LEFT | DT_SINGLELINE | DT_CALCRECT); - - if ((align & DT_CENTER) != 0) { - int cx = width/2; - rect.x = cx - rect.w/2; - } - } - - if (!cockpit_hud_texture && rect.Contains(Mouse::X(), Mouse::Y())) { - mouse_in = true; - - if (index <= TXT_LAST_ACTIVE) - hc = Color::White; - - if (Mouse::LButton() && !mouse_latch) { - mouse_latch = 2; - mouse_index = index; - } - } - - if (cockpit_hud_texture && - index >= TXT_HUD_MODE && - index <= TXT_TARGET_ETA && - ht.font != big_font) { - - Sprite* s = hud_sprite[0]; - - int cx = (int) s->Location().x; - int cy = (int) s->Location().y; - int w2 = s->Width() / 2; - int h2 = s->Height() / 2; - - Rect txt_rect(rect); - txt_rect.x -= (cx-w2); - txt_rect.y -= (cy-h2); - - if (index == TXT_ICON_SHIP_TYPE) - txt_rect = Rect(0, 500, 128, 12); - - else if (index == TXT_ICON_TARGET_TYPE) - txt_rect = Rect(128, 500, 128, 12); - - ht.font->SetColor(hc); - ht.font->DrawText(txt_buf, n, txt_rect, align | DT_SINGLELINE, cockpit_hud_texture); - ht.hidden = false; - } - else { - ht.font->SetColor(hc); - ht.font->DrawText(txt_buf, n, rect, align | DT_SINGLELINE); - ht.rect = rect; - ht.hidden = false; - - if (box) { - rect.Inflate(3,2); - rect.h--; - window->DrawRect(rect, hud_color); - } - } -} - -void -HUDView::HideHUDText(int index) -{ - if (index >= TXT_LAST) - return; - - hud_text[index].hidden = true; -} - -// +--------------------------------------------------------------------+ - -HUDView* HUDView::hud_view = 0; -bool HUDView::arcade = false; -bool HUDView::show_fps = false; -int HUDView::def_color_set = 1; -int HUDView::gunsight = 1; - -// +--------------------------------------------------------------------+ - -HUDView::HUDView(Window* c) -: View(c), projector(0), camview(0), -sim(0), ship(0), target(0), mode(HUD_MODE_TAC), -tactical(0), overlay(0), cockpit_hud_texture(0), -threat(0), active_region(0), transition(false), docking(false), -az_ring(0), az_pointer(0), el_ring(0), el_pointer(0), compass_scale(1), -show_warn(false), show_inst(false), inst_page(0) -{ - hud_view = this; - - sim = Sim::GetSim(); - - if (sim) - sim->ShowGrid(false); - - int i; - - width = window->Width(); - height = window->Height(); - xcenter = (width / 2.0) - 0.5; - ycenter = (height / 2.0) + 0.5; - - PrepareBitmap("HUDleftA.pcx", hud_left_air, hud_left_shade_air); - PrepareBitmap("HUDrightA.pcx", hud_right_air, hud_right_shade_air); - PrepareBitmap("HUDleft.pcx", hud_left_fighter, hud_left_shade_fighter); - PrepareBitmap("HUDright.pcx", hud_right_fighter, hud_right_shade_fighter); - PrepareBitmap("HUDleft1.pcx", hud_left_starship, hud_left_shade_starship); - PrepareBitmap("HUDright1.pcx", hud_right_starship, hud_right_shade_starship); - PrepareBitmap("INSTR_left.pcx", instr_left, instr_left_shade); - PrepareBitmap("INSTR_right.pcx", instr_right, instr_right_shade); - PrepareBitmap("CAUTION_left.pcx", warn_left, warn_left_shade); - PrepareBitmap("CAUTION_right.pcx", warn_right, warn_right_shade); - PrepareBitmap("hud_icon.pcx", icon_ship, icon_ship_shade); - PrepareBitmap("hud_icon.pcx", icon_target, icon_target_shade); - - PrepareBitmap("lead.pcx", lead, lead_shade); - PrepareBitmap("cross.pcx", cross, cross_shade); - PrepareBitmap("cross1.pcx", cross1, cross1_shade); - PrepareBitmap("cross2.pcx", cross2, cross2_shade); - PrepareBitmap("cross3.pcx", cross3, cross3_shade); - PrepareBitmap("cross4.pcx", cross4, cross4_shade); - PrepareBitmap("fpm.pcx", fpm, fpm_shade); - PrepareBitmap("hpm.pcx", hpm, hpm_shade); - PrepareBitmap("chase_l.pcx", chase_left, chase_left_shade); - PrepareBitmap("chase_r.pcx", chase_right, chase_right_shade); - PrepareBitmap("chase_t.pcx", chase_top, chase_top_shade); - PrepareBitmap("chase_b.pcx", chase_bottom, chase_bottom_shade); - PrepareBitmap("ladder1.pcx", pitch_ladder_pos, - pitch_ladder_pos_shade); - PrepareBitmap("ladder2.pcx", pitch_ladder_neg, - pitch_ladder_neg_shade); - - hud_left_air.SetType(Bitmap::BMP_TRANSLUCENT); - hud_right_air.SetType(Bitmap::BMP_TRANSLUCENT); - hud_left_fighter.SetType(Bitmap::BMP_TRANSLUCENT); - hud_right_fighter.SetType(Bitmap::BMP_TRANSLUCENT); - hud_left_starship.SetType(Bitmap::BMP_TRANSLUCENT); - hud_right_starship.SetType(Bitmap::BMP_TRANSLUCENT); - instr_left.SetType(Bitmap::BMP_TRANSLUCENT); - instr_right.SetType(Bitmap::BMP_TRANSLUCENT); - warn_left.SetType(Bitmap::BMP_TRANSLUCENT); - warn_right.SetType(Bitmap::BMP_TRANSLUCENT); - icon_ship.SetType(Bitmap::BMP_TRANSLUCENT); - icon_target.SetType(Bitmap::BMP_TRANSLUCENT); - fpm.SetType(Bitmap::BMP_TRANSLUCENT); - hpm.SetType(Bitmap::BMP_TRANSLUCENT); - lead.SetType(Bitmap::BMP_TRANSLUCENT); - cross.SetType(Bitmap::BMP_TRANSLUCENT); - cross1.SetType(Bitmap::BMP_TRANSLUCENT); - cross2.SetType(Bitmap::BMP_TRANSLUCENT); - cross3.SetType(Bitmap::BMP_TRANSLUCENT); - cross4.SetType(Bitmap::BMP_TRANSLUCENT); - chase_left.SetType(Bitmap::BMP_TRANSLUCENT); - chase_right.SetType(Bitmap::BMP_TRANSLUCENT); - chase_top.SetType(Bitmap::BMP_TRANSLUCENT); - chase_bottom.SetType(Bitmap::BMP_TRANSLUCENT); - pitch_ladder_pos.SetType(Bitmap::BMP_TRANSLUCENT); - pitch_ladder_neg.SetType(Bitmap::BMP_TRANSLUCENT); - - hud_left_sprite = new Sprite(&hud_left_fighter); - hud_right_sprite = new Sprite(&hud_right_fighter); - instr_left_sprite = new Sprite(&instr_left); - instr_right_sprite = new Sprite(&instr_right); - warn_left_sprite = new Sprite(&warn_left); - warn_right_sprite = new Sprite(&warn_right); - icon_ship_sprite = new Sprite(&icon_ship); - icon_target_sprite = new Sprite(&icon_target); - fpm_sprite = new Sprite(&fpm); - hpm_sprite = new Sprite(&hpm); - lead_sprite = new Sprite(&lead); - aim_sprite = new Sprite(&cross); - tgt1_sprite = new Sprite(&cross1); - tgt2_sprite = new Sprite(&cross2); - tgt3_sprite = new Sprite(&cross3); - tgt4_sprite = new Sprite(&cross4); - chase_sprite = new Sprite(&chase_left); - - ZeroMemory(hud_sprite, sizeof(hud_sprite)); - - hud_sprite[ 0] = hud_left_sprite; - hud_sprite[ 1] = hud_right_sprite; - hud_sprite[ 2] = instr_left_sprite; - hud_sprite[ 3] = instr_right_sprite; - hud_sprite[ 4] = warn_left_sprite; - hud_sprite[ 5] = warn_right_sprite; - hud_sprite[ 6] = icon_ship_sprite; - hud_sprite[ 7] = icon_target_sprite; - hud_sprite[ 8] = fpm_sprite; - hud_sprite[ 9] = hpm_sprite; - hud_sprite[10] = lead_sprite; - hud_sprite[11] = aim_sprite; - hud_sprite[12] = tgt1_sprite; - hud_sprite[13] = tgt2_sprite; - hud_sprite[14] = tgt3_sprite; - hud_sprite[15] = tgt4_sprite; - hud_sprite[16] = chase_sprite; - - double pitch_ladder_UV[8] = { 0.125,0.0625, 0.875,0.0625, 0.875,0, 0.125,0 }; - double UV[8]; - - for (i = 0; i < 15; i++) { - pitch_ladder[i] = new Sprite(&pitch_ladder_pos); - - CopyMemory(UV, pitch_ladder_UV, sizeof(UV)); - UV[1] = UV[3] = (pitch_ladder_UV[1] * (i )); - UV[5] = UV[7] = (pitch_ladder_UV[1] * (i+1)); - - pitch_ladder[i]->Reshape(192, 16); - pitch_ladder[i]->SetTexCoords(UV); - pitch_ladder[i]->SetBlendMode(2); - pitch_ladder[i]->Hide(); - } - - // zero mark at i=15 - { - pitch_ladder[i] = new Sprite(&pitch_ladder_pos); - - UV[0] = UV[6] = 0; - UV[2] = UV[4] = 1; - UV[1] = UV[3] = (pitch_ladder_UV[1] * (i+1)); - UV[5] = UV[7] = (pitch_ladder_UV[1] * (i )); - - pitch_ladder[i]->Reshape(256, 16); - pitch_ladder[i]->SetTexCoords(UV); - pitch_ladder[i]->SetBlendMode(2); - pitch_ladder[i]->Hide(); - } - - for (i = 16; i < 31; i++) { - pitch_ladder[i] = new Sprite(&pitch_ladder_neg); - - CopyMemory(UV, pitch_ladder_UV, sizeof(UV)); - UV[1] = UV[3] = (pitch_ladder_UV[1] * (30 - i )); - UV[5] = UV[7] = (pitch_ladder_UV[1] * (30 - i+1)); - - pitch_ladder[i]->Reshape(192, 16); - pitch_ladder[i]->SetTexCoords(UV); - pitch_ladder[i]->SetBlendMode(2); - pitch_ladder[i]->Hide(); - } - - for (i = 0; i < 3; i++) - mfd[i] = new MFD(window, i); - - mfd[0]->SetRect(Rect( 8, height - 136, 128, 128)); - mfd[1]->SetRect(Rect(width - 136, height - 136, 128, 128)); - mfd[2]->SetRect(Rect( 8, 8, 128, 128)); - - hud_left_sprite->MoveTo( Point(width/2-128, height/2, 1)); - hud_right_sprite->MoveTo(Point(width/2+128, height/2, 1)); - hud_left_sprite->SetBlendMode(2); - hud_left_sprite->SetFilter(0); - hud_right_sprite->SetBlendMode(2); - hud_right_sprite->SetFilter(0); - - instr_left_sprite->MoveTo( Point(width/2-128, height-128, 1)); - instr_right_sprite->MoveTo(Point(width/2+128, height-128, 1)); - instr_left_sprite->SetBlendMode(2); - instr_left_sprite->SetFilter(0); - instr_right_sprite->SetBlendMode(2); - instr_right_sprite->SetFilter(0); - - warn_left_sprite->MoveTo( Point(width/2-128, height-128, 1)); - warn_right_sprite->MoveTo(Point(width/2+128, height-128, 1)); - warn_left_sprite->SetBlendMode(2); - warn_left_sprite->SetFilter(0); - warn_right_sprite->SetBlendMode(2); - warn_right_sprite->SetFilter(0); - - icon_ship_sprite->MoveTo( Point( 184, height-72, 1)); - icon_target_sprite->MoveTo(Point(width - 184, height-72, 1)); - icon_ship_sprite->SetBlendMode(2); - icon_ship_sprite->SetFilter(0); - icon_target_sprite->SetBlendMode(2); - icon_target_sprite->SetFilter(0); - - fpm_sprite->MoveTo(Point(width/2, height/2, 1)); - hpm_sprite->MoveTo(Point(width/2, height/2, 1)); - lead_sprite->MoveTo(Point(width/2, height/2, 1)); - aim_sprite->MoveTo(Point(width/2, height/2, 1)); - tgt1_sprite->MoveTo(Point(width/2, height/2, 1)); - tgt2_sprite->MoveTo(Point(width/2, height/2, 1)); - tgt3_sprite->MoveTo(Point(width/2, height/2, 1)); - tgt4_sprite->MoveTo(Point(width/2, height/2, 1)); - - fpm_sprite->SetBlendMode(2); - hpm_sprite->SetBlendMode(2); - lead_sprite->SetBlendMode(2); - aim_sprite->SetBlendMode(2); - tgt1_sprite->SetBlendMode(2); - tgt2_sprite->SetBlendMode(2); - tgt3_sprite->SetBlendMode(2); - tgt4_sprite->SetBlendMode(2); - chase_sprite->SetBlendMode(2); - - fpm_sprite->SetFilter(0); - hpm_sprite->SetFilter(0); - lead_sprite->SetFilter(0); - aim_sprite->SetFilter(0); - tgt1_sprite->SetFilter(0); - tgt2_sprite->SetFilter(0); - tgt3_sprite->SetFilter(0); - tgt4_sprite->SetFilter(0); - chase_sprite->SetFilter(0); - - lead_sprite->Hide(); - aim_sprite->Hide(); - tgt1_sprite->Hide(); - tgt2_sprite->Hide(); - tgt3_sprite->Hide(); - tgt4_sprite->Hide(); - chase_sprite->Hide(); - - aw = chase_left.Width() / 2; - ah = chase_left.Height() / 2; - - mfd[0]->SetMode(MFD::MFD_MODE_SHIP); - mfd[1]->SetMode(MFD::MFD_MODE_FOV); - mfd[2]->SetMode(MFD::MFD_MODE_GAME); - - hud_font = FontMgr::Find("HUD"); - big_font = FontMgr::Find("GUI"); - - for (i = 0; i < TXT_LAST; i++) { - hud_text[i].font = hud_font; - } - - hud_text[TXT_THREAT_WARN].font = big_font; - hud_text[TXT_SHOOT].font = big_font; - hud_text[TXT_AUTO].font = big_font; - - SetHUDColorSet(def_color_set); - MFD::SetColor(standard_hud_colors[color]); - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("HUD/"); - - az_ring = new Solid; - az_pointer = new Solid; - el_ring = new Solid; - el_pointer = new Solid; - - az_ring->Load("CompassRing.mag", compass_scale); - az_pointer->Load("CompassPointer.mag", compass_scale); - el_ring->Load("PitchRing.mag", compass_scale); - el_pointer->Load("CompassPointer.mag", compass_scale); - - loader->SetDataPath("Sounds/"); - loader->LoadSound("MissileLock.wav", missile_lock_sound, Sound::LOOP | Sound::LOCKED); - - loader->SetDataPath(0); - - for (i = 0; i < MAX_MSG; i++) - msg_time[i] = 0; -} - -HUDView::~HUDView() -{ - HideCompass(); - - if (missile_lock_sound) { - missile_lock_sound->Stop(); - missile_lock_sound->Release(); - missile_lock_sound = 0; - } - - for (int i = 0; i < 3; i++) { - delete mfd[i]; - mfd[i] = 0; - } - - for (int i = 0; i < 32; i++) { - GRAPHIC_DESTROY(hud_sprite[i]); - } - - fpm.ClearImage(); - hpm.ClearImage(); - lead.ClearImage(); - cross.ClearImage(); - cross1.ClearImage(); - cross2.ClearImage(); - cross3.ClearImage(); - cross4.ClearImage(); - hud_left_air.ClearImage(); - hud_right_air.ClearImage(); - hud_left_fighter.ClearImage(); - hud_right_fighter.ClearImage(); - hud_left_starship.ClearImage(); - hud_right_starship.ClearImage(); - instr_left.ClearImage(); - instr_right.ClearImage(); - warn_left.ClearImage(); - warn_right.ClearImage(); - icon_ship.ClearImage(); - icon_target.ClearImage(); - chase_left.ClearImage(); - chase_right.ClearImage(); - chase_top.ClearImage(); - chase_bottom.ClearImage(); - pitch_ladder_pos.ClearImage(); - pitch_ladder_neg.ClearImage(); - - delete [] fpm_shade; - delete [] hpm_shade; - delete [] lead_shade; - delete [] cross_shade; - delete [] cross1_shade; - delete [] cross2_shade; - delete [] cross3_shade; - delete [] cross4_shade; - delete [] hud_left_shade_air; - delete [] hud_right_shade_air; - delete [] hud_left_shade_fighter; - delete [] hud_right_shade_fighter; - delete [] hud_left_shade_starship; - delete [] hud_right_shade_starship; - delete [] instr_left_shade; - delete [] instr_right_shade; - delete [] warn_left_shade; - delete [] warn_right_shade; - delete [] icon_ship_shade; - delete [] icon_target_shade; - delete [] chase_left_shade; - delete [] chase_right_shade; - delete [] chase_top_shade; - delete [] chase_bottom_shade; - delete [] pitch_ladder_pos_shade; - delete [] pitch_ladder_neg_shade; - - delete az_ring; - delete az_pointer; - delete el_ring; - delete el_pointer; - - fpm_shade = 0; - hpm_shade = 0; - cross_shade = 0; - cross1_shade = 0; - cross2_shade = 0; - cross3_shade = 0; - cross4_shade = 0; - hud_left_shade_air = 0; - hud_right_shade_air = 0; - hud_left_shade_fighter = 0; - hud_right_shade_fighter = 0; - hud_left_shade_starship = 0; - hud_right_shade_starship = 0; - instr_left_shade = 0; - instr_right_shade = 0; - warn_left_shade = 0; - warn_right_shade = 0; - icon_ship_shade = 0; - icon_target_shade = 0; - chase_left_shade = 0; - chase_right_shade = 0; - chase_top_shade = 0; - chase_bottom_shade = 0; - pitch_ladder_pos_shade = 0; - pitch_ladder_neg_shade = 0; - - az_ring = 0; - az_pointer = 0; - el_ring = 0; - el_pointer = 0; - - hud_view = 0; -} - -void -HUDView::OnWindowMove() -{ - width = window->Width(); - height = window->Height(); - xcenter = (width / 2.0) - 0.5; - ycenter = (height / 2.0) + 0.5; - - mfd[0]->SetRect(Rect( 8, height - 136, 128, 128)); - mfd[1]->SetRect(Rect(width - 136, height - 136, 128, 128)); - mfd[2]->SetRect(Rect( 8, 8, 128, 128)); - - hud_left_sprite->MoveTo( Point(width/2-128, height/2, 1)); - hud_right_sprite->MoveTo(Point(width/2+128, height/2, 1)); - - instr_left_sprite->MoveTo( Point(width/2-128, height-128, 1)); - instr_right_sprite->MoveTo(Point(width/2+128, height-128, 1)); - warn_left_sprite->MoveTo( Point(width/2-128, height-128, 1)); - warn_right_sprite->MoveTo(Point(width/2+128, height-128, 1)); - icon_ship_sprite->MoveTo( Point( 184, height-72, 1)); - icon_target_sprite->MoveTo(Point(width - 184, height-72, 1)); - - for (int i = 0; i < TXT_LAST; i++) { - hud_text[i].font = hud_font; - hud_text[i].color = standard_txt_colors[color]; - } - - if (big_font) { - hud_text[TXT_THREAT_WARN].font = big_font; - hud_text[TXT_SHOOT].font = big_font; - hud_text[TXT_AUTO].font = big_font; - } - - MFD::SetColor(standard_hud_colors[color]); - - int cx = width/2; - int cy = height/2; -} - -// +--------------------------------------------------------------------+ - -void -HUDView::SetTacticalMode(int mode) -{ - if (tactical != mode) { - tactical = mode; - - if (tactical) { - hud_left_sprite->Hide(); - hud_right_sprite->Hide(); - - for (int i = 0; i < 31; i++) - pitch_ladder[i]->Hide(); - } - else if (GameWinDX9::GetInstance()->MaxTexSize() > 128) { - hud_left_sprite->Show(); - hud_right_sprite->Show(); - } - } -} - -void -HUDView::SetOverlayMode(int mode) -{ - if (overlay != mode) { - overlay = mode; - } -} - -// +--------------------------------------------------------------------+ - -bool -HUDView::Update(SimObject* obj) -{ - if (obj == ship) { - if (target) - SetTarget(0); - - ship = 0; - - for (int i = 0; i < 3; i++) - mfd[i]->SetShip(ship); - } - - if (obj == target) { - target = 0; - PrepareBitmap("hud_icon.pcx", icon_target, icon_target_shade); - ColorizeBitmap(icon_target, icon_target_shade, txt_color); - } - - return SimObserver::Update(obj); -} - -const char* -HUDView::GetObserverName() const -{ - return "HUDView"; -} - -// +--------------------------------------------------------------------+ - -void -HUDView::UseCameraView(CameraView* v) -{ - if (v && camview != v) { - camview = v; - - for (int i = 0; i < 3; i++) - mfd[i]->UseCameraView(camview); - - projector = camview->GetProjector(); - } -} - -// +--------------------------------------------------------------------+ - -Color -HUDView::MarkerColor(Contact* contact) -{ - Color c(80,80,80); - - if (contact) { - Sim* sim = Sim::GetSim(); - Ship* ship = sim->GetPlayerShip(); - - int c_iff = contact->GetIFF(ship); - - c = Ship::IFFColor(c_iff) * contact->Age(); - - if (contact->GetShot() && contact->Threat(ship)) { - if ((Clock::GetInstance()->RealTime()/500) & 1) - c = c * 2; - else - c = c * 0.5; - } - } - - return c; -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawContactMarkers() -{ - threat = 0; - - for (int i = 0; i < MAX_CONTACT; i++) { - HideHUDText(TXT_CONTACT_NAME+i); - HideHUDText(TXT_CONTACT_INFO+i); - } - - - if (!ship) - return; - - int index = 0; - ListIter contact = ship->ContactList(); - - // draw own sensor contacts: - while (++contact) { - Contact* c = contact.value(); - - // draw track ladder: - if (c->TrackLength() > 0 && c->GetShip() != ship) { - DrawTrack(c); - } - - DrawContact(c, index++); - } - - Color c = ship->MarkerColor(); - - // draw own ship track ladder: - if (CameraDirector::GetCameraMode() == CameraDirector::MODE_ORBIT && ship->TrackLength() > 0) { - int ctl = ship->TrackLength(); - - Point t1 = ship->Location(); - Point t2 = ship->TrackPoint(0); - - if (t1 != t2) - DrawTrackSegment(t1, t2, c); - - for (int i = 0; i < ctl-1; i++) { - t1 = ship->TrackPoint(i); - t2 = ship->TrackPoint(i+1); - - if (t1 != t2) - DrawTrackSegment(t1, t2, c * ((double) (ctl-i)/ (double) ctl)); - } - } - - // draw own ship marker: - Point mark_pt = ship->Location(); - projector->Transform(mark_pt); - - // clip: - if (CameraDirector::GetCameraMode() == CameraDirector::MODE_ORBIT && mark_pt.z > 1.0) { - projector->Project(mark_pt); - - int x = (int) mark_pt.x; - int y = (int) mark_pt.y; - - if (x > 4 && x < width-4 && - y > 4 && y < height-4) { - - DrawDiamond(x,y,5,c); - - if (tactical) { - Rect self_rect(x+8, y-4, 200, 12); - DrawHUDText(TXT_SELF, ship->Name(), self_rect, DT_LEFT, HUD_MIXED_CASE); - - if (NetGame::GetInstance()) { - Player* p = Player::GetCurrentPlayer(); - if (p) { - Rect net_name_rect(x+8, y+6, 120, 12); - DrawHUDText(TXT_SELF_NAME, p->Name(), net_name_rect, DT_LEFT, HUD_MIXED_CASE); - } - } - } - } - } - - // draw life bars on targeted ship: - if (target && target->Type() == SimObject::SIM_SHIP && target->Rep()) { - Ship* tgt_ship = (Ship*) target; - if (tgt_ship == nullptr) { - Print(" Null Pointer in HUDView::DrawContactMarkers(). Please investigate."); - return; - } - Graphic* g = tgt_ship->Rep(); - Rect r = g->ScreenRect(); - - Point mark_pt; - - if (tgt_ship) - mark_pt = tgt_ship->Location(); - - projector->Transform(mark_pt); - - // clip: - if (mark_pt.z > 1.0) { - projector->Project(mark_pt); - - int x = (int) mark_pt.x; - int y = r.y; - - if (y >= 2000) - y = (int) mark_pt.y; - - if (x > 4 && x < width-4 && - y > 4 && y < height-4) { - - const int BAR_LENGTH = 40; - - // life bars: - int sx = x - BAR_LENGTH/2; - int sy = y - 8; - - double hull_strength = tgt_ship->Integrity() / tgt_ship->Design()->integrity; - - int hw = (int) (BAR_LENGTH * hull_strength); - int sw = (int) (BAR_LENGTH * (tgt_ship->ShieldStrength() / 100.0)); - - System::STATUS s = System::NOMINAL; - - if (hull_strength < 0.30) s = System::CRITICAL; - else if (hull_strength < 0.60) s = System::DEGRADED; - - Color hc = GetStatusColor(s); - Color sc = hud_color; - - window->FillRect(sx, sy, sx+hw, sy+1, hc); - window->FillRect(sx, sy+3, sx+sw, sy+4, sc); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawContact(Contact* contact, int index) -{ - if (index >= MAX_CONTACT) return; - - Color c = MarkerColor(contact); - int c_iff = contact->GetIFF(ship); - Ship* c_ship = contact->GetShip(); - Shot* c_shot = contact->GetShot(); - Point mark_pt = contact->Location(); - double distance = 0; - - if (!c_ship && !c_shot || c_ship == ship) - return; - - if (c_ship && c_ship->GetFlightPhase() < Ship::ACTIVE) - return; - - if (c_ship) { - mark_pt = c_ship->Location(); - - if (c_ship->IsGroundUnit()) - mark_pt += Point(0,150,0); - } - else { - mark_pt = c_shot->Location(); - } - - projector->Transform(mark_pt); - - // clip: - if (mark_pt.z > 1.0) { - distance = mark_pt.length(); - - projector->Project(mark_pt); - - int x = (int) mark_pt.x; - int y = (int) mark_pt.y; - - if (x > 4 && x < width-4 && - y > 4 && y < height-4) { - - DrawDiamond(x,y,3,c); - - if (contact->Threat(ship)) { - if (c_ship) { - window->DrawEllipse(x-6, y-6, x+6, y+6, c); - } - else { - DrawDiamond(x,y,7,c); - } - } - - bool name_crowded = false; - - if (x < width-8) { - char code = *(ContentBundle::GetInstance()->GetText("HUDView.symbol.fighter").data()); - - if (c_ship) { - if (c_ship->Class() > Ship::LCA) - code = *(ContentBundle::GetInstance()->GetText("HUDView.symbol.starship").data()); - } - - else if (c_shot) { - code = *(ContentBundle::GetInstance()->GetText("HUDView.symbol.torpedo").data()); - } - - Sensor* sensor = ship->GetSensor(); - double limit = 75e3; - - if (sensor) - limit = sensor->GetBeamRange(); - - double range = contact->Range(ship, limit); - - char contact_buf[256]; - Rect contact_rect(x+8, y-4, 120, 12); - - if (range == 0) { - sprintf_s(contact_buf, "%c *", code); - } - else { - bool mega = false; - - if (range > 999e3) { - range /= 1e6; - mega = true; - } - else if (range < 1e3) - range = 1; - else - range /= 1000; - - if (arcade) { - if (c_ship) - strcpy_s(contact_buf, c_ship->Name()); - else if (!mega) - sprintf_s(contact_buf, "%c %d", code, (int) range); - else - sprintf_s(contact_buf, "%c %.1f M", code, range); - } - else { - char closing = '+'; - Point delta_v; - - if (c_ship) - delta_v = ship->Velocity() - c_ship->Velocity(); - else if (c_shot) - delta_v = ship->Velocity() - c_shot->Velocity(); - - if (delta_v * ship->Velocity() < 0) // losing ground - closing = '-'; - - if (!mega) - sprintf_s(contact_buf, "%c %d%c", code, (int) range, closing); - else - sprintf_s(contact_buf, "%c %.1f M", code, range); - } - } - - if (!IsNameCrowded(x, y)) { - DrawHUDText(TXT_CONTACT_INFO+index, contact_buf, contact_rect, DT_LEFT, HUD_MIXED_CASE); - - if (c_shot || (c_ship && (c_ship->IsDropship() || c_ship->IsStatic()))) - name_crowded = distance > 50e3; - } - else { - name_crowded = true; - } - } - - bool name_drawn = false; - if (NetGame::GetInstance() && c_ship) { - NetPlayer* netp = NetGame::GetInstance()->FindPlayerByObjID(c_ship->GetObjID()); - if (netp && strcmp(netp->Name(), "Server A.I. Ship")) { - Rect contact_rect(x+8, y+6, 120, 12); - DrawHUDText(TXT_CONTACT_NAME+index, netp->Name(), contact_rect, DT_LEFT, HUD_MIXED_CASE); - name_drawn = true; - } - } - - if (!name_drawn && !name_crowded && c_ship && c_iff < 10 && !arcade) { - Rect contact_rect(x+8, y+6, 120, 12); - DrawHUDText(TXT_CONTACT_NAME+index, c_ship->Name(), contact_rect, DT_LEFT, HUD_MIXED_CASE); - } - } - } - - if (contact->Threat(ship) && !ship->IsStarship()) { - if (threat < 1 && c_ship && !c_ship->IsStarship()) - threat = 1; - - if (c_shot) - threat = 2; - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawTrackSegment(Point& t1, Point& t2, Color c) -{ - int x1, y1, x2, y2; - - projector->Transform(t1); - projector->Transform(t2); - - const double CLIP_Z = 0.1; - - if (t1.z < CLIP_Z && t2.z < CLIP_Z) - return; - - if (t1.z < CLIP_Z && t2.z >= CLIP_Z) { - double dx = t2.x - t1.x; - double dy = t2.y - t1.y; - double s = (CLIP_Z - t1.z) / (t2.z - t1.z); - - t1.x += dx * s; - t1.y += dy * s; - t1.z = CLIP_Z; - } - - else if (t2.z < CLIP_Z && t1.z >= CLIP_Z) { - double dx = t1.x - t2.x; - double dy = t1.y - t2.y; - double s = (CLIP_Z - t2.z) / (t1.z - t2.z); - - t2.x += dx * s; - t2.y += dy * s; - t2.z = CLIP_Z; - } - - if (t1.z >= CLIP_Z && t2.z >= CLIP_Z) { - projector->Project(t1, false); - projector->Project(t2, false); - - x1 = (int) t1.x; - y1 = (int) t1.y; - x2 = (int) t2.x; - y2 = (int) t2.y; - - if (window->ClipLine(x1,y1,x2,y2)) - window->DrawLine(x1,y1,x2,y2,c); - } -} - -void -HUDView::DrawTrack(Contact* contact) -{ - Ship* c_ship = contact->GetShip(); - - if (c_ship && c_ship->GetFlightPhase() < Ship::ACTIVE) - return; - - int ctl = contact->TrackLength(); - Color c = MarkerColor(contact); - - Point t1 = contact->Location(); - Point t2 = contact->TrackPoint(0); - - if (t1 != t2) - DrawTrackSegment(t1, t2, c); - - for (int i = 0; i < ctl-1; i++) { - t1 = contact->TrackPoint(i); - t2 = contact->TrackPoint(i+1); - - if (t1 != t2) - DrawTrackSegment(t1, t2, c * ((double) (ctl-i)/ (double) ctl)); - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawRect(SimObject* targ) -{ - Graphic* g = targ->Rep(); - Rect r = g->ScreenRect(); - Color c; - - if (targ->Type() == SimObject::SIM_SHIP) - c = ((Ship*) targ)->MarkerColor(); - else - c = ((Shot*) targ)->MarkerColor(); - - if (r.w > 0 && r.h > 0) { - if (r.w < 8) { - r.x -= (8-r.w)/2; - r.w = 8; - } - - if (r.h < 8) { - r.y -= (8-r.h)/2; - r.h = 8; - } - } - - else { - Point mark_pt = targ->Location(); - projector->Transform(mark_pt); - - // clip: - if (mark_pt.z < 1.0) - return; - - projector->Project(mark_pt); - - int x = (int) mark_pt.x; - int y = (int) mark_pt.y; - - if (x < 4 || x > width-4 || y < 4 || y > height-4) - return; - - r.x = x-4; - r.y = y-4; - r.w = 8; - r.h = 8; - } - - // horizontal - window->DrawLine(r.x, r.y, r.x+8, r.y, c); - window->DrawLine(r.x+r.w-8, r.y, r.x+r.w, r.y, c); - window->DrawLine(r.x, r.y+r.h, r.x+8, r.y+r.h, c); - window->DrawLine(r.x+r.w-8, r.y+r.h, r.x+r.w, r.y+r.h, c); - // vertical - window->DrawLine(r.x, r.y, r.x, r.y+8, c); - window->DrawLine(r.x, r.y+r.h-8, r.x, r.y+r.h, c); - window->DrawLine(r.x+r.w, r.y, r.x+r.w, r.y+8, c); - window->DrawLine(r.x+r.w, r.y+r.h-8, r.x+r.w, r.y+r.h, c); -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawBars() -{ - fpm_sprite->Hide(); - hpm_sprite->Hide(); - lead_sprite->Hide(); - aim_sprite->Hide(); - tgt1_sprite->Hide(); - tgt2_sprite->Hide(); - tgt3_sprite->Hide(); - tgt4_sprite->Hide(); - chase_sprite->Hide(); - - for (int i = 0; i < 31; i++) - pitch_ladder[i]->Hide(); - - const int bar_width = 256; - const int bar_height = 192; - const int box_width = 120; - - int cx = width/2; - int cy = height/2; - int l = cx - bar_width/2; - int r = cx + bar_width/2; - int t = cy - bar_height/2; - int b = cy + bar_height/2; - int align = DT_LEFT; - - if (Game::GetInstance()->Paused()) - { - Rect pause_rect = Rect(cx - 128, cy - 60, 256, 12); - DrawHUDText(TXT_PAUSED, ContentBundle::GetInstance()->GetText("HUDView.PAUSED"), pause_rect, DT_CENTER); - } - - if (ship) { - DrawContactMarkers(); - - char txt[256]; - double speed = ship->Velocity().length(); - - if (ship->Velocity() * ship->Heading() < 0) - speed = -speed; - - FormatNumber(txt, speed); - - if (tactical) { - l = box_width + 16; - r = width - box_width - 16; - } - - Rect speed_rect(l-box_width-8, cy-5, box_width, 12); - - align = (tactical) ? DT_LEFT : DT_RIGHT; - DrawHUDText(TXT_SPEED, txt, speed_rect, align); - - // upper left hud quadrant (airborne fighters) - if (ship->IsAirborne()) { - double alt_msl = ship->AltitudeMSL(); - double alt_agl = ship->AltitudeAGL(); - - if (alt_agl <= 1000) - sprintf_s(txt, "R %4d", (int) alt_agl); - else - FormatNumber(txt, alt_msl); - - speed_rect.y -= 20; - - if (arcade) { - char arcade_txt[32]; - sprintf_s(arcade_txt, "%s %s", ContentBundle::GetInstance()->GetText("HUDView.altitude").data(), txt); - align = (tactical) ? DT_LEFT : DT_RIGHT; - DrawHUDText(TXT_ALTITUDE, arcade_txt, speed_rect, align); - } - else { - align = (tactical) ? DT_LEFT : DT_RIGHT; - DrawHUDText(TXT_ALTITUDE, txt, speed_rect, align); - } - - if (!arcade) { - sprintf_s(txt, "%.1f G", ship->GForce()); - speed_rect.y -= 20; - - align = (tactical) ? DT_LEFT : DT_RIGHT; - DrawHUDText(TXT_GFORCE, txt, speed_rect, align); - - speed_rect.y += 40; - } - } - - // upper left hud quadrant (starships) - else if (ship->IsStarship() && ship->GetFLCSMode() == Ship::FLCS_HELM && !arcade) { - sprintf_s(txt, "%s: %.1f", ContentBundle::GetInstance()->GetText("HUDView.Pitch").data(), ship->GetHelmPitch()/DEGREES); - speed_rect.y -= 50; - - align = (tactical) ? DT_LEFT : DT_RIGHT; - DrawHUDText(TXT_PITCH, txt, speed_rect, align); - - speed_rect.y -= 10; - int heading_degrees = (int) (ship->GetHelmHeading()/DEGREES); - if (heading_degrees < 0) heading_degrees += 360; - sprintf_s(txt, "%s: %03d", ContentBundle::GetInstance()->GetText("HUDView.Heading").data(), heading_degrees); - DrawHUDText(TXT_HEADING, txt, speed_rect, align); - - speed_rect.y += 60; - } - - // per user request, all ships should show compass heading - if (!tactical && !arcade) { - Rect heading_rect(l, t+5, bar_width, 12); - int heading_degrees = (int) (ship->CompassHeading()/DEGREES); - if (heading_degrees < 0) heading_degrees += 360; - sprintf_s(txt, "%d", heading_degrees); - DrawHUDText(TXT_COMPASS, txt, heading_rect, DT_CENTER); - } - - switch (mode) { - case HUD_MODE_TAC: strcpy_s(txt, ContentBundle::GetInstance()->GetText("HUDView.mode.tactical").data()); break; - case HUD_MODE_NAV: strcpy_s(txt, ContentBundle::GetInstance()->GetText("HUDView.mode.navigation").data()); break; - case HUD_MODE_ILS: strcpy_s(txt, ContentBundle::GetInstance()->GetText("HUDView.mode.landing").data()); break; - } - - if (tactical) { - speed_rect.y += 76; - align = DT_LEFT; - } - else { - speed_rect.y = cy+76; - align = DT_RIGHT; - } - - DrawHUDText(TXT_HUD_MODE, txt, speed_rect, align); - - // landing gear: - if (ship->IsGearDown()) { - const char* gear_down = ContentBundle::GetInstance()->GetText("HUDView.gear-down"); - - Rect gear_rect(l, b+20, box_width, 12); - DrawHUDText(TXT_GEAR_DOWN, gear_down, gear_rect, DT_CENTER, HUD_UPPER_CASE, true); - } - - // sensor/missile lock warnings and quantum drive countdown: - QuantumDrive* quantum = ship->GetQuantumDrive(); - - if (threat || (quantum && quantum->JumpTime() > 0)) { - const char* threat_warn = ContentBundle::GetInstance()->GetText("HUDView.threat-warn"); - bool show_msg = true; - - if (quantum && quantum->JumpTime() > 0) { - static char buf[64]; - sprintf_s(buf, "%s: %d", ContentBundle::GetInstance()->GetText("HUDView.quantum-jump").data(), (int) quantum->JumpTime()); - threat_warn = buf; - } - - else if (threat > 1) { - threat_warn = ContentBundle::GetInstance()->GetText("HUDView.missile-warn"); - show_msg = ((Clock::GetInstance()->RealTime()/500) & 1) != 0; - } - - if (show_msg) { - Rect lock_rect(l, t-25, box_width, 12); - DrawHUDText(TXT_THREAT_WARN, threat_warn, lock_rect, DT_CENTER, HUD_MIXED_CASE, true); - } - } - - if (ship->CanTimeSkip()) { - Rect auto_rect(l, t-40, box_width, 12); - DrawHUDText(TXT_AUTO, ContentBundle::GetInstance()->GetText("HUDView.AUTO"), auto_rect, DT_CENTER, HUD_MIXED_CASE, true); - } - - if (mode == HUD_MODE_NAV) { - Instruction* next = ship->GetNextNavPoint(); - - if (next) { - double distance = ship->RangeToNavPoint(next); - FormatNumber(txt, distance); - - Rect range_rect(r-20, cy-5, box_width, 12); - DrawHUDText(TXT_RANGE, txt, range_rect, DT_RIGHT); - range_rect.Inflate(2,2); - } - } - - // lower left hud quadrant - else if (mode == HUD_MODE_TAC) { - speed_rect.x = l-box_width-8; - speed_rect.y = cy-5 +20; - speed_rect.w = box_width; - align = (tactical) ? DT_LEFT : DT_RIGHT; - - if (!arcade && ship->GetPrimary() && !ship->IsNetObserver()) - DrawHUDText(TXT_PRIMARY_WEP, ship->GetPrimary()->Abbreviation(), speed_rect, align); - - WeaponGroup* missile = ship->GetSecondaryGroup(); - - if (missile && missile->Ammo() > 0 && !ship->IsNetObserver()) { - if (!arcade) { - speed_rect.y = cy-5 +30; - sprintf_s(txt, "%s %d", missile->Name(), missile->Ammo()); - DrawHUDText(TXT_SECONDARY_WEP, txt, speed_rect, align); - } - - // missile range indicator - if (missile->GetSelected()->Locked()) { - Rect shoot_rect(l, b+5, box_width, 12); - DrawHUDText(TXT_SHOOT, ContentBundle::GetInstance()->GetText("HUDView.SHOOT"), shoot_rect, DT_CENTER, HUD_MIXED_CASE, true); - } - } - - if (!arcade && !ship->IsNetObserver()) { - if (ship->GetShield()) { - speed_rect.y = cy-5+40; - sprintf_s(txt, "%s - %03d +", ContentBundle::GetInstance()->GetText("HUDView.SHIELD").data(), ship->ShieldStrength()); - DrawHUDText(TXT_SHIELD, txt, speed_rect, align); - } - else if (ship->GetDecoy()) { - speed_rect.y = cy-5+40; - sprintf_s(txt, "%s %d", ContentBundle::GetInstance()->GetText("HUDView.DECOY").data(), ship->GetDecoy()->Ammo()); - DrawHUDText(TXT_DECOY, txt, speed_rect, align); - } - - - Rect eta_rect = speed_rect; - eta_rect.y += 10; - - align = DT_RIGHT; - - if (tactical) { - eta_rect.x = 8; - align = DT_LEFT; - } - - for (int i = 0; i < 2; i++) { - int eta = ship->GetMissileEta(i); - if (eta > 0) { - int minutes = (eta/60) % 60; - int seconds = (eta ) % 60; - - char eta_buf[16]; - sprintf_s(eta_buf, "T %d:%02d", minutes, seconds); - DrawHUDText(TXT_MISSILE_T1+i, eta_buf, eta_rect, align); - eta_rect.y += 10; - } - } - } - - NetGame* netgame = NetGame::GetInstance(); - if (netgame && !netgame->IsActive()) { - Rect shoot_rect(l, b+5, box_width, 12); - DrawHUDText(TXT_SHOOT, ContentBundle::GetInstance()->GetText("HUDView.NET-GAME-OVER"), shoot_rect, DT_CENTER, HUD_MIXED_CASE, true); - } - - else if (ship->IsNetObserver()) { - Rect shoot_rect(l, b+5, box_width, 12); - DrawHUDText(TXT_SHOOT, ContentBundle::GetInstance()->GetText("HUDView.OBSERVER"), shoot_rect, DT_CENTER, HUD_MIXED_CASE, true); - } - - DrawTarget(); - } - - else if (mode == HUD_MODE_ILS) { - DrawTarget(); - } - - DrawNavInfo(); - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawFPM() -{ - fpm_sprite->Hide(); - - if (ship->Velocity().length() > 50) { - double xtarg = xcenter; - double ytarg = ycenter; - - Point svel = ship->Velocity(); - svel.Normalize(); - - Point tloc = ship->Location() + svel * 1e8; - // Translate into camera relative: - projector->Transform(tloc); - - int behind = tloc.z < 0; - - if (behind) - return; - - // Project into screen coordinates: - projector->Project(tloc); - - xtarg = tloc.x; - ytarg = tloc.y; - - fpm_sprite->Show(); - fpm_sprite->MoveTo(Point(xtarg, ytarg, 1)); - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawPitchLadder() -{ - for (int i = 0; i < 31; i++) - pitch_ladder[i]->Hide(); - - if (ship->IsAirborne() && GameWinDX9::GetInstance()->MaxTexSize() > 128) { - double xtarg = xcenter; - double ytarg = ycenter; - - Point uvec = Point(0,1,0); - Point svel = ship->Velocity(); - - if (svel.length() == 0) - svel = ship->Heading(); - - if (svel.x == 0 && svel.z == 0) - return; - - svel.y = 0; - svel.Normalize(); - - Point gloc = ship->Location(); - gloc.y = 0; - - const double baseline = 1e9; - const double clip_angle = 20*DEGREES; - - Point tloc = gloc + svel * baseline; - - // Translate into camera relative: - projector->Transform(tloc); - - // Project into screen coordinates: - projector->Project(tloc); - - xtarg = tloc.x; - ytarg = tloc.y; - - // compute roll angle: - double roll_angle = 0; - double pitch_angle = 0; - - Point heading = ship->Heading(); - heading.Normalize(); - - if (heading.x != 0 || heading.z != 0) { - Point gheading = heading; - gheading.y = 0; - gheading.Normalize(); - - double dot = gheading * heading; - - if (heading.y < 0) dot = -dot; - - pitch_angle = acos(dot); - - if (pitch_angle > PI/2) - pitch_angle -= PI; - - double s0 = sin(pitch_angle); - double c0 = cos(pitch_angle); - double s1 = sin(pitch_angle + 10*DEGREES); - double c1 = cos(pitch_angle + 10*DEGREES); - - tloc = gloc + (svel * baseline * c0) + (uvec * baseline * s0); - projector->Transform(tloc); - - double x0 = tloc.x; - double y0 = tloc.y; - - tloc = gloc + (svel * baseline * c1) + (uvec * baseline * s1); - projector->Transform(tloc); - - double x1 = tloc.x; - double y1 = tloc.y; - - double dx = x1-x0; - double dy = y1-y0; - - roll_angle = atan2(-dy,dx) + PI/2; - } - - const double alias_limit = 0.1*DEGREES; - - if (fabs(roll_angle) <= alias_limit) { - if (roll_angle > 0) - roll_angle = alias_limit; - else - roll_angle = -alias_limit; - } - - else if (fabs(roll_angle-PI) <= alias_limit) { - roll_angle = PI - alias_limit; - } - - if (fabs(pitch_angle) <= clip_angle) { - pitch_ladder[15]->Show(); - pitch_ladder[15]->MoveTo(Point(xtarg, ytarg, 1)); - pitch_ladder[15]->SetAngle(roll_angle); - } - - for (int i = 1; i <= 15; i++) { - double angle = i * 5 * DEGREES; - - if (i > 12) - angle = (60 + (i-12)*10) * DEGREES; - - double s = sin(angle); - double c = cos(angle); - - if (fabs(pitch_angle - angle) <= clip_angle) { - // positive angle: - tloc = gloc + (svel * baseline * c) + (uvec * baseline * s); - projector->Transform(tloc); - - if (tloc.z > 0) { - projector->Project(tloc); - pitch_ladder[15-i]->Show(); - pitch_ladder[15-i]->MoveTo(Point(tloc.x, tloc.y, 1)); - pitch_ladder[15-i]->SetAngle(roll_angle); - } - } - - if (fabs(pitch_angle + angle) <= clip_angle) { - // negative angle: - tloc = gloc + (svel * baseline * c) + (uvec * -baseline * s); - projector->Transform(tloc); - - if (tloc.z > 0) { - projector->Project(tloc); - pitch_ladder[15+i]->Show(); - pitch_ladder[15+i]->MoveTo(Point(tloc.x, tloc.y, 1)); - pitch_ladder[15+i]->SetAngle(roll_angle); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawHPM() -{ - hpm_sprite->Hide(); - - if (!ship) - return; - - double xtarg = xcenter; - double ytarg = ycenter; - - double az = ship->GetHelmHeading() - PI; - double el = ship->GetHelmPitch(); - - Point hvec = Point(sin(az), sin(el), cos(az)); - hvec.Normalize(); - - Point tloc = ship->Location() + hvec * 1e8; - // Translate into camera relative: - projector->Transform(tloc); - - int behind = tloc.z < 0; - - if (behind) - return; - - // Project into screen coordinates: - projector->Project(tloc); - - xtarg = tloc.x; - ytarg = tloc.y; - - hpm_sprite->Show(); - hpm_sprite->MoveTo(Point(xtarg, ytarg, 1)); -} - -// +--------------------------------------------------------------------+ - -void -HUDView::HideCompass() -{ - az_ring->Hide(); - az_pointer->Hide(); - el_ring->Hide(); - el_pointer->Hide(); - - Scene* scene = az_ring->GetScene(); - if (scene) { - scene->DelGraphic(az_ring); - scene->DelGraphic(az_pointer); - scene->DelGraphic(el_ring); - scene->DelGraphic(el_pointer); - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawCompass() -{ - if (!ship || !ship->Rep()) - return; - - Solid* solid = (Solid*) ship->Rep(); - Point loc = solid->Location(); - - az_ring->MoveTo(loc); - az_pointer->MoveTo(loc); - el_ring->MoveTo(loc); - el_pointer->MoveTo(loc); - - double helm_heading = ship->GetHelmHeading(); - double helm_pitch = ship->GetHelmPitch(); - double curr_heading = ship->CompassHeading(); - double curr_pitch = ship->CompassPitch(); - - bool show_az = fabs(helm_heading - curr_heading) > 5*DEGREES; - bool show_el = fabs(helm_pitch - curr_pitch) > 5*DEGREES; - - Scene* scene = camview->GetScene(); - - if (show_az || show_el) { - scene->AddGraphic(az_ring); - az_ring->Show(); - - if (show_el || fabs(helm_pitch) > 5 * DEGREES) { - scene->AddGraphic(el_ring); - Matrix ring_orient; - ring_orient.Yaw(helm_heading + PI); - el_ring->SetOrientation(ring_orient); - el_ring->Show(); - - scene->AddGraphic(el_pointer); - Matrix pointer_orient; - pointer_orient.Yaw(helm_heading + PI); - pointer_orient.Pitch(-helm_pitch); - pointer_orient.Roll(PI/2); - el_pointer->SetOrientation(pointer_orient); - el_pointer->Show(); - } - else { - scene->AddGraphic(az_pointer); - Matrix pointer_orient; - pointer_orient.Yaw(helm_heading + PI); - - az_pointer->SetOrientation(pointer_orient); - az_pointer->Show(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawLCOS(SimObject* targ, double dist) -{ - lead_sprite->Hide(); - aim_sprite->Hide(); - chase_sprite->Hide(); - - double xtarg = xcenter; - double ytarg = ycenter; - - Weapon* prim = ship->GetPrimary(); - if (!prim) return; - - Point tloc = targ->Location(); - // Translate into camera relative: - projector->Transform(tloc); - - int behind = tloc.z < 0; - - if (behind) - tloc.z = -tloc.z; - - // Project into screen coordinates: - projector->Project(tloc); - - // DRAW THE OFFSCREEN CHASE INDICATOR: - if (behind || - tloc.x <= 0 || tloc.x >= width-1 || - tloc.y <= 0 || tloc.y >= height-1) { - - // Left side: - if (tloc.x <= 0 || (behind && tloc.x < width/2)) { - if (tloc.y < ah) tloc.y = ah; - else if (tloc.y >= height-ah) tloc.y = height-1-ah; - - chase_sprite->Show(); - chase_sprite->SetAnimation(&chase_left); - chase_sprite->MoveTo(Point(aw, tloc.y, 1)); - } - - // Right side: - else if (tloc.x >= width-1 || behind) { - if (tloc.y < ah) tloc.y = ah; - else if (tloc.y >= height-ah) tloc.y = height-1-ah; - - chase_sprite->Show(); - chase_sprite->SetAnimation(&chase_right); - chase_sprite->MoveTo(Point(width-1-aw, tloc.y, 1)); - } - else { - if (tloc.x < aw) tloc.x = aw; - else if (tloc.x >= width-aw) tloc.x = width-1-aw; - - // Top edge: - if (tloc.y <= 0) { - chase_sprite->Show(); - chase_sprite->SetAnimation(&chase_top); - chase_sprite->MoveTo(Point(tloc.x, ah, 1)); - } - - // Bottom edge: - else if (tloc.y >= height-1) { - chase_sprite->Show(); - chase_sprite->SetAnimation(&chase_bottom); - chase_sprite->MoveTo(Point(tloc.x, height-1-ah, 1)); - } - } - } - - // DRAW THE LCOS: - else { - if (!ship->IsStarship()) { - Point aim_vec = ship->Heading(); - aim_vec.Normalize(); - - // shot speed is relative to ship speed: - Point shot_vel = ship->Velocity() + aim_vec * prim->Design()->speed; - double shot_speed = shot_vel.length(); - - // time for shot to reach target - double time = dist / shot_speed; - - // LCOS (Lead Computing Optical Sight) - if (gunsight == 0) { - // where the shot will be when it is the same distance - // away from the ship as the target: - Point impact = ship->Location() + (shot_vel * time); - - // where the target will be when the shot reaches it: - Point targ_vel = targ->Velocity(); - Point dest = targ->Location() + (targ_vel * time); - Point delta = impact - dest; - - // draw the gun sight here in 3d world coordinates: - Point sight = targ->Location() + delta; - - // Project into screen coordinates: - projector->Transform(sight); - projector->Project(sight); - - xtarg = sight.x; - ytarg = sight.y; - - aim_sprite->Show(); - aim_sprite->MoveTo(Point(xtarg, ytarg, 1)); - } - - // Wing Commander style lead indicator - else { - // where the target will be when the shot reaches it: - Point targ_vel = targ->Velocity() - ship->Velocity(); - Point dest = targ->Location() + (targ_vel * time); - - // Translate into camera relative: - projector->Transform(dest); - projector->Project(dest); - - xtarg = dest.x; - ytarg = dest.y; - - lead_sprite->Show(); - lead_sprite->MoveTo(Point(xtarg, ytarg, 1)); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawTarget() -{ - const int bar_width = 256; - const int bar_height = 192; - const int box_width = 120; - - SimObject* old_target = target; - - if (mode == HUD_MODE_ILS) { - Ship* controller = ship->GetController(); - if (controller && !target) - target = controller; - } - - if (target && target->Rep()) { - Sensor* sensor = ship->GetSensor(); - Contact* contact = 0; - - if (sensor && target->Type() == SimObject::SIM_SHIP) { - contact = sensor->FindContact((Ship*) target); - } - - int cx = width/2; - int cy = height/2; - int l = cx - bar_width/2; - int r = cx + bar_width/2; - int t = cy - bar_height/2; - int b = cy + bar_height/2; - Point delta = target->Location() - ship->Location(); - double distance = delta.length(); - Point delta_v = ship->Velocity() - target->Velocity(); - double speed = delta_v.length(); - char txt[256]; - - if (mode == HUD_MODE_ILS && ship->GetInbound() && ship->GetInbound()->GetDeck()) { - delta = ship->GetInbound()->GetDeck()->EndPoint() - ship->Location(); - distance = delta.length(); - } - - if (delta * ship->Velocity() > 0) { // in front - if (delta_v * ship->Velocity() < 0) // losing ground - speed = -speed; - } - else { // behind - if (delta_v * ship->Velocity() > 0) // passing - speed = -speed; - } - - Rect range_rect(r-20, cy-5, box_width, 12); - - if (tactical) - range_rect.x = width - range_rect.w - 8; - - if (contact) { - Sensor* sensor = ship->GetSensor(); - double limit = 75e3; - - if (sensor) - limit = sensor->GetBeamRange(); - - distance = contact->Range(ship, limit); - - if (!contact->ActLock() && !contact->PasLock()) { - strcpy_s(txt, ContentBundle::GetInstance()->GetText("HUDView.No-Range").data()); - speed = 0; - } - else { - FormatNumber(txt, distance); - } - } - - else { - FormatNumber(txt, distance); - } - - DrawHUDText(TXT_RANGE, txt, range_rect, DT_RIGHT); - - if (arcade) { - target = old_target; - return; - } - - range_rect.y += 18; - FormatNumber(txt, speed); - DrawHUDText(TXT_CLOSING_SPEED, txt, range_rect, DT_RIGHT); - - // target info: - if (!tactical) { - range_rect.y = cy-76; - } - - else { - range_rect.x = width - 2*box_width - 8; - range_rect.y = cy-76; - range_rect.w = 2*box_width; - } - - DrawHUDText(TXT_TARGET_NAME, target->Name(), range_rect, DT_RIGHT); - - if (target->Type() == SimObject::SIM_SHIP) { - Ship* tgt_ship = (Ship*) target; - - range_rect.y += 10; - DrawHUDText(TXT_TARGET_DESIGN, tgt_ship->Design()->display_name, range_rect, DT_RIGHT); - - if (mode != HUD_MODE_ILS) { - if (tgt_ship->IsStarship()) { - range_rect.y += 10; - sprintf_s(txt, "%s %03d", ContentBundle::GetInstance()->GetText("HUDView.symbol.shield").data(), (int) tgt_ship->ShieldStrength()); - DrawHUDText(TXT_TARGET_SHIELD, txt, range_rect, DT_RIGHT); - } - - range_rect.y += 10; - sprintf_s(txt, "%s %03d", ContentBundle::GetInstance()->GetText("HUDView.symbol.hull").data(), (int) (tgt_ship->Integrity() / tgt_ship->Design()->integrity * 100)); - DrawHUDText(TXT_TARGET_HULL, txt, range_rect, DT_RIGHT); - - System* sys = ship->GetSubTarget(); - if (sys) { - Color stat = hud_color; - static DWORD blink = Clock::GetInstance()->RealTime(); - - int blink_delta = Clock::GetInstance()->RealTime() - blink; - sprintf_s(txt, "%s %03d", sys->Abbreviation(), (int) sys->Availability()); - - switch (sys->Status()) { - case System::DEGRADED: stat = Color(255,255, 0); break; - case System::CRITICAL: - case System::DESTROYED: stat = Color(255, 0, 0); break; - case System::MAINT: - if (blink_delta < 250) - stat = Color(8,8,8); - break; - } - - if (blink_delta > 500) - blink = Clock::GetInstance()->RealTime(); - - range_rect.y += 10; - DrawHUDText(TXT_TARGET_SUB, txt, range_rect, DT_RIGHT); - } - } - } - - else if (target->Type() == SimObject::SIM_DRONE) { - Drone* tgt_drone = (Drone*) target; - - range_rect.y += 10; - DrawHUDText(TXT_TARGET_DESIGN, tgt_drone->DesignName(), range_rect, DT_RIGHT); - - range_rect.y += 10; - int eta = tgt_drone->GetEta(); - - if (eta > 0) { - int minutes = (eta/60) % 60; - int seconds = (eta ) % 60; - - char eta_buf[16]; - sprintf_s(eta_buf, "T %d:%02d", minutes, seconds); - DrawHUDText(TXT_TARGET_ETA, eta_buf, range_rect, DT_RIGHT); - } - } - } - - target = old_target; -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawNavInfo() -{ - const int bar_width = 256; - const int bar_height = 192; - const int box_width = 120; - - if (arcade) { - if (ship->IsAutoNavEngaged()) { - Rect info_rect(width/2-box_width, height/2+bar_height, box_width*2, 12); - - if (big_font) - hud_text[TXT_NAV_INDEX].font = big_font; - - DrawHUDText(TXT_NAV_INDEX, ContentBundle::GetInstance()->GetText("HUDView.Auto-Nav"), info_rect, DT_CENTER); - } - - return; - } - - hud_text[TXT_NAV_INDEX].font = hud_font; - - Instruction* navpt = ship->GetNextNavPoint(); - - if (navpt) { - int cx = width/2; - int cy = height/2; - int l = cx - bar_width/2; - int r = cx + bar_width/2; - int t = cy - bar_height/2; - int b = cy + bar_height/2; - - int index = ship->GetNavIndex(navpt); - double distance = ship->RangeToNavPoint(navpt); - double speed = ship->Velocity().length(); - int etr = 0; - char txt[256]; - - if (speed > 10) - etr = (int) (distance/speed); - - Rect info_rect(r-20, cy+32, box_width, 12); - - if (tactical) - info_rect.x = width - info_rect.w - 8; - - if (ship->IsAutoNavEngaged()) - sprintf_s(txt, "%s %d", ContentBundle::GetInstance()->GetText("HUDView.Auto-Nav").data(), index); - else - sprintf_s(txt, "%s %d", ContentBundle::GetInstance()->GetText("HUDView.Nav").data(), index); - DrawHUDText(TXT_NAV_INDEX, txt, info_rect, DT_RIGHT); - - info_rect.y += 10; - if (navpt->Action()) - DrawHUDText(TXT_NAV_ACTION, Instruction::ActionName(navpt->Action()), info_rect, DT_RIGHT); - - info_rect.y += 10; - FormatNumber(txt, navpt->Speed()); - DrawHUDText(TXT_NAV_SPEED, txt, info_rect, DT_RIGHT); - - if (etr > 3600) { - info_rect.y += 10; - sprintf_s(txt, "%s XX:XX", ContentBundle::GetInstance()->GetText("HUDView.time-enroute").data()); - DrawHUDText(TXT_NAV_ETR, txt, info_rect, DT_RIGHT); - } - else if (etr > 0) { - info_rect.y += 10; - - int minutes = (etr/60) % 60; - int seconds = (etr ) % 60; - sprintf_s(txt, "%s %2d:%02d", ContentBundle::GetInstance()->GetText("HUDView.time-enroute").data(), minutes, seconds); - DrawHUDText(TXT_NAV_ETR, txt, info_rect, DT_RIGHT); - } - - if (navpt->HoldTime() > 0) { - info_rect.y += 10; - - int hold = (int) navpt->HoldTime(); - int minutes = (hold/60) % 60; - int seconds = (hold ) % 60; - sprintf_s(txt, "%s %2d:%02d", ContentBundle::GetInstance()->GetText("HUDView.HOLD").data(), minutes, seconds); - DrawHUDText(TXT_NAV_HOLD, txt, info_rect, DT_RIGHT); - } - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawSight() -{ - if (target && target->Rep()) { - Point delta = target->Location() - ship->Location(); - double distance = delta.length(); - - // draw LCOS on target: - if (!tactical) - DrawLCOS(target, distance); - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawDesignators() -{ - double xtarg = xcenter; - double ytarg = ycenter; - SimObject* t1 = 0; - SimObject* t2 = 0; - SimObject* t3 = 0; - Sprite* sprite = 0; - - tgt1_sprite->Hide(); - tgt2_sprite->Hide(); - tgt3_sprite->Hide(); - tgt4_sprite->Hide(); - - // fighters just show primary target: - if (ship->IsDropship()) { - SimObject* t = ship->GetTarget(); - System* s = ship->GetSubTarget(); - - if (t) { - Point tloc = t->Location(); - if (s) { - tloc = s->MountLocation(); - } - else if (t->Type() == SimObject::SIM_SHIP) { - Ship* tgt_ship = (Ship*) t; - - if (tgt_ship->IsGroundUnit()) - tloc += Point(0,150,0); - } - - projector->Transform(tloc); - - if (tloc.z > 0) { - projector->Project(tloc); - - xtarg = tloc.x; - ytarg = tloc.y; - - if (xtarg>0 && xtarg0 && ytargLocation() - ship->Location()).length(); - - // use out-of-range crosshair if out of range: - if (!ship->GetPrimaryDesign() || ship->GetPrimaryDesign()->max_range < range) { - tgt4_sprite->Show(); - tgt4_sprite->MoveTo(Point(xtarg, ytarg, 1)); - } - - // else, use in-range primary crosshair: - else { - tgt1_sprite->Show(); - tgt1_sprite->MoveTo(Point(xtarg, ytarg, 1)); - } - } - } - } - } - - // starships show up to three targets: - else { - ListIter w = ship->Weapons(); - while (!t3 && ++w) { - SimObject* t = w->GetTarget(); - System* s = w->GetSubTarget(); - - if (w->Contains(ship->GetPrimary())) { - if (t == 0) t = ship->GetTarget(); - t1 = t; - sprite = tgt1_sprite; - } - - else if (t && w->Contains(ship->GetSecondary())) { - t2 = t; - sprite = tgt2_sprite; - - if (t2 == t1) - continue; // don't overlap target designators - } - - else if (t) { - t3 = t; - sprite = tgt3_sprite; - - if (t3 == t1 || t3 == t2) - continue; // don't overlap target designators - } - - if (t) { - Point tloc = t->Location(); - - if (s) - tloc = s->MountLocation(); - - projector->Transform(tloc); - - if (tloc.z > 0) { - projector->Project(tloc); - - xtarg = tloc.x; - ytarg = tloc.y; - - if (xtarg>0 && xtarg0 && ytargLocation() - ship->Location()).length(); - - // flip to out-of-range crosshair - if (sprite == tgt1_sprite) { - if (!ship->GetPrimaryDesign() || ship->GetPrimaryDesign()->max_range < range) { - sprite = tgt4_sprite; - } - } - - sprite->Show(); - sprite->MoveTo(Point(xtarg, ytarg, 1)); - } - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -Color -HUDView::GetStatusColor(System::STATUS status) -{ - Color sc; - - switch (status) { - default: - case System::NOMINAL: sc = Color( 32,192, 32); break; - case System::DEGRADED: sc = Color(255,255, 0); break; - case System::CRITICAL: sc = Color(255, 0, 0); break; - case System::DESTROYED: sc = Color( 0, 0, 0); break; - } - - return sc; -} - -void -HUDView::SetStatusColor(System::STATUS status) -{ - switch (status) { - default: - case System::NOMINAL: status_color = txt_color; break; - case System::DEGRADED: status_color = Color(255,255, 0); break; - case System::CRITICAL: status_color = Color(255, 0, 0); break; - case System::DESTROYED: status_color = Color( 0, 0, 0); break; - } -} - -// +--------------------------------------------------------------------+ - -static int GetReactorStatus(Ship* ship) -{ - if (!ship || ship->Reactors().size() < 1) - return -1; - - int status = System::NOMINAL; - bool maint = false; - - ListIter iter = ship->Reactors(); - while (++iter) { - PowerSource* s = iter.value(); - - if (s->Status() < status) - status = s->Status(); - } - - if (maint && status == System::NOMINAL) - status = System::MAINT; - - return status; -} - -static int GetDriveStatus(Ship* ship) -{ - if (!ship || ship->Drives().size() < 1) - return -1; - - int status = System::NOMINAL; - bool maint = false; - - ListIter iter = ship->Drives(); - while (++iter) { - Drive* s = iter.value(); - - if (s->Status() < status) - status = s->Status(); - - else if (s->Status() == System::MAINT) - maint = true; - } - - if (maint && status == System::NOMINAL) - status = System::MAINT; - - return status; -} - -static int GetQuantumStatus(Ship* ship) -{ - if (!ship || ship->GetQuantumDrive() == 0) - return -1; - - QuantumDrive* s = ship->GetQuantumDrive(); - return s->Status(); -} - -static int GetThrusterStatus(Ship* ship) -{ - if (!ship || ship->GetThruster() == 0) - return -1; - - Thruster* s = ship->GetThruster(); - return s->Status(); -} - -static int GetShieldStatus(Ship* ship) -{ - if (!ship) - return -1; - - Shield* s = ship->GetShield(); - Weapon* d = ship->GetDecoy(); - - if (!s && !d) - return -1; - - int status = System::NOMINAL; - bool maint = false; - - if (s) { - if (s->Status() < status) - status = s->Status(); - - else if (s->Status() == System::MAINT) - maint = true; - } - - if (d) { - if (d->Status() < status) - status = d->Status(); - - else if (d->Status() == System::MAINT) - maint = true; - } - - if (maint && status == System::NOMINAL) - status = System::MAINT; - - return status; -} - -static int GetWeaponStatus(Ship* ship, int index) -{ - if (!ship || ship->Weapons().size() <= index) - return -1; - - WeaponGroup* group = ship->Weapons().at(index); - - int status = System::NOMINAL; - bool maint = false; - - ListIter iter = group->GetWeapons(); - while (++iter) { - Weapon* s = iter.value(); - - if (s->Status() < status) - status = s->Status(); - - else if (s->Status() == System::MAINT) - maint = true; - } - - if (maint && status == System::NOMINAL) - status = System::MAINT; - - return status; -} - -static int GetSensorStatus(Ship* ship) -{ - if (!ship || ship->GetSensor() == 0) - return -1; - - Sensor* s = ship->GetSensor(); - Weapon* p = ship->GetProbeLauncher(); - - int status = s->Status(); - bool maint = s->Status() == System::MAINT; - - if (p) { - if (p->Status() < status) - status = p->Status(); - - else if (p->Status() == System::MAINT) - maint = true; - } - - if (maint && status == System::NOMINAL) - status = System::MAINT; - - return status; -} - -static int GetComputerStatus(Ship* ship) -{ - if (!ship || ship->Computers().size() < 1) - return -1; - - int status = System::NOMINAL; - bool maint = false; - - ListIter iter = ship->Computers(); - while (++iter) { - Computer* s = iter.value(); - - if (s->Status() < status) - status = s->Status(); - - else if (s->Status() == System::MAINT) - maint = true; - } - - if (ship->GetNavSystem()) { - NavSystem* s = ship->GetNavSystem(); - - if (s->Status() < status) - status = s->Status(); - - else if (s->Status() == System::MAINT) - maint = true; - } - - if (maint && status == System::NOMINAL) - status = System::MAINT; - - return status; -} - -static int GetFlightDeckStatus(Ship* ship) -{ - if (!ship || ship->FlightDecks().size() < 1) - return -1; - - int status = System::NOMINAL; - bool maint = false; - - ListIter iter = ship->FlightDecks(); - while (++iter) { - FlightDeck* s = iter.value(); - - if (s->Status() < status) - status = s->Status(); - - else if (s->Status() == System::MAINT) - maint = true; - } - - if (maint && status == System::NOMINAL) - status = System::MAINT; - - return status; -} - -void -HUDView::DrawWarningPanel() -{ - int box_width = 75; - int box_height = 17; - int row_height = 28; - int box_left = width/2 - box_width*2; - - if (cockpit_hud_texture) { - box_left = 275; - box_height = 18; - row_height = 18; - } - - if (ship) { - if (GameWinDX9::GetInstance()->MaxTexSize() > 128) { - warn_left_sprite->Show(); - warn_right_sprite->Show(); - } - - int x = box_left; - int y = cockpit_hud_texture ? 410 : height-97; - int c = cockpit_hud_texture ? 3 : 4; - - static DWORD blink = Clock::GetInstance()->RealTime(); - - for (int index = 0; index < 12; index++) { - int stat = -1; - Text abrv = ContentBundle::GetInstance()->GetText("HUDView.UNKNOWN"); - - switch (index) { - case 0: stat = GetReactorStatus(ship); abrv = ContentBundle::GetInstance()->GetText("HUDView.REACTOR"); break; - case 1: stat = GetDriveStatus(ship); abrv = ContentBundle::GetInstance()->GetText("HUDView.DRIVE"); break; - case 2: stat = GetQuantumStatus(ship); abrv = ContentBundle::GetInstance()->GetText("HUDView.QUANTUM"); break; - case 3: stat = GetShieldStatus(ship); abrv = ContentBundle::GetInstance()->GetText("HUDView.SHIELD"); - if (ship->GetShield() == 0 && ship->GetDecoy()) - abrv = ContentBundle::GetInstance()->GetText("HUDView.DECOY"); - break; - - case 4: - case 5: - case 6: - case 7: stat = GetWeaponStatus(ship, index-4); - if (stat >= 0) { - WeaponGroup* g = ship->Weapons().at(index-4); - abrv = g->Name(); - } - break; - - case 8: stat = GetSensorStatus(ship); abrv = ContentBundle::GetInstance()->GetText("HUDView.SENSOR"); break; - case 9: stat = GetComputerStatus(ship); abrv = ContentBundle::GetInstance()->GetText("HUDView.COMPUTER"); break; - case 10: stat = GetThrusterStatus(ship); abrv = ContentBundle::GetInstance()->GetText("HUDView.THRUSTER"); break; - case 11: stat = GetFlightDeckStatus(ship);abrv = ContentBundle::GetInstance()->GetText("HUDView.FLTDECK"); break; - } - - Rect warn_rect(x, y, box_width, box_height); - - if (cockpit_hud_texture) - cockpit_hud_texture->DrawRect(warn_rect, Color::DarkGray); - - if (stat >= 0) { - SetStatusColor((System::STATUS) stat); - Color tc = status_color; - - if (stat != System::NOMINAL) { - if (Clock::GetInstance()->RealTime() - blink < 250) { - tc = cockpit_hud_texture ? txt_color : Color(8,8,8); - } - } - - if (cockpit_hud_texture) { - if (tc != txt_color) { - Rect r2 = warn_rect; - r2.Inset(1,1,1,1); - cockpit_hud_texture->FillRect(r2, tc); - tc = Color::Black; - } - - warn_rect.y += 4; - - hud_font->SetColor(tc); - hud_font->DrawText(abrv, -1, - warn_rect, - DT_CENTER | DT_SINGLELINE, - cockpit_hud_texture); - - warn_rect.y -= 4; - } - else { - DrawHUDText(TXT_CAUTION_TXT + index, - abrv, - warn_rect, - DT_CENTER); - - hud_text[TXT_CAUTION_TXT + index].color = tc; - } - } - - x += box_width; - - if (--c <= 0) { - c = cockpit_hud_texture ? 3 : 4; - x = box_left; - y += row_height; - } - } - - if (Clock::GetInstance()->RealTime() - blink > 500) - blink = Clock::GetInstance()->RealTime(); - - // reset for next time - SetStatusColor(System::NOMINAL); - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawInstructions() -{ - if (!ship) return; - - if (GameWinDX9::GetInstance()->MaxTexSize() > 128) { - instr_left_sprite->Show(); - instr_right_sprite->Show(); - } - - int ninst = 0; - int nobj = 0; - Element* elem = ship->GetElement(); - - if (elem) { - ninst = elem->NumInstructions(); - nobj = elem->NumObjectives(); - } - - Rect r = Rect(width/2 - 143, height - 105, 290, 17); - - if (ninst) { - int npages = ninst/6 + (ninst%6 ? 1 : 0); - - if (inst_page >= npages) - inst_page = npages-1; - else if (inst_page < 0) - inst_page = 0; - - int first = inst_page * 6; - int last = first + 6; - if (last > ninst) last = ninst; - - int n = TXT_CAUTION_TXT; - - for (int i = first; i < last; i++) { - hud_text[n].color = standard_txt_colors[color]; - DrawHUDText(n++, FormatInstruction(elem->GetInstruction(i)), r, DT_LEFT, HUD_MIXED_CASE); - r.y += 14; - } - - char page[32]; - sprintf_s(page, "%d / %d", inst_page+1, npages); - r = Rect(width/2 + 40, height-16, 110, 16); - DrawHUDText(TXT_INSTR_PAGE, page, r, DT_CENTER, HUD_MIXED_CASE); - } - - else if (nobj) { - int n = TXT_CAUTION_TXT; - - for (int i = 0; i < nobj; i++) { - char desc[256]; - sprintf_s(desc, "* %s", elem->GetObjective(i)->GetShortDescription()); - hud_text[n].color = standard_txt_colors[color]; - DrawHUDText(n++, desc, r, DT_LEFT, HUD_MIXED_CASE); - r.y += 14; - } - } - - else { - hud_text[TXT_CAUTION_TXT].color = standard_txt_colors[color]; - DrawHUDText(TXT_CAUTION_TXT, ContentBundle::GetInstance()->GetText("HUDView.No-Instructions"), r, DT_LEFT, HUD_MIXED_CASE); - } -} - -// +--------------------------------------------------------------------+ - -const char* -HUDView::FormatInstruction(Text instr) -{ - if (!instr.contains('$')) - return (const char*) instr; - - static char result[256]; - - const char* s = (const char*) instr; - char* d = result; - - KeyMap& keymap = Starshatter::GetInstance()->GetKeyMap(); - - while (*s) { - if (*s == '$') { - s++; - char action[32]; - char* a = action; - while (*s && (isupper(*s) || isdigit(*s) || *s == '_')) *a++ = *s++; - *a = 0; - - int act = KeyMap::GetKeyAction(action); - int key = keymap.FindMapIndex(act); - const char* s2 = keymap.DescribeKey(key); - - if (!s2) s2 = action; - while (*s2) *d++ = *s2++; - } - else { - *d++ = *s++; - } - } - - *d = 0; - - return result; -} - -// +--------------------------------------------------------------------+ - -void -HUDView::CycleInstructions(int direction) -{ - if (direction > 0) - inst_page++; - else - inst_page--; -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawMessages() -{ - int message_queue_empty = true; - - // age messages: - for (int i = 0; i < MAX_MSG; i++) { - if (msg_time[i] > 0) { - msg_time[i] -= Clock::GetInstance()->GuiDelta(); - - if (msg_time[i] <= 0) { - msg_time[i] = 0; - msg_text[i] = ""; - } - - message_queue_empty = false; - } - } - - if (!message_queue_empty) { - // advance message pipeline: - for (int i = 0; i < MAX_MSG; i++) { - if (msg_time[0] == 0) { - for (int j = 0; j < MAX_MSG-1; j++) { - msg_time[j] = msg_time[j+1]; - msg_text[j] = msg_text[j+1]; - } - - msg_time[MAX_MSG-1] = 0; - msg_text[MAX_MSG-1] = ""; - } - } - - // draw messages: - for (int i = 0; i < MAX_MSG; i++) { - int index = TXT_MSG_1 + i; - - if (msg_time[i] > 0) { - Rect msg_rect(10, 95 + i*10, width-20, 12); - DrawHUDText(index, msg_text[i], msg_rect, DT_LEFT, HUD_MIXED_CASE); - if (msg_time[i] > 1) - hud_text[index].color = txt_color; - else - hud_text[index].color = txt_color.dim(0.5 + 0.5*msg_time[i]); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawNav() -{ - if (!sim) - return; - - active_region = sim->GetActiveRegion(); - - if (ship) { - int nav_index = 1; - Instruction* next = ship->GetNextNavPoint(); - - if (mode == HUD_MODE_NAV) { - if (next && next->Action() == Instruction::LAUNCH) - DrawNavPoint(*next, 0, true); - - ListIter navpt = ship->GetFlightPlan(); - while (++navpt) { - DrawNavPoint(*navpt.value(), nav_index++, (navpt.value() == next)); - } - } - else if (next) { - DrawNavPoint(*next, 0, true); - } - } -} - -void -HUDView::DrawILS() -{ - if (ship) { - bool hoops_drawn = false; - bool same_sector = false; - - InboundSlot* inbound = ship->GetInbound(); - if (inbound) { - FlightDeck* fd = inbound->GetDeck(); - - if (fd && fd->IsRecoveryDeck() && fd->GetCarrier()) { - if (fd->GetCarrier()->GetRegion() == ship->GetRegion()) - same_sector = true; - - if (same_sector && mode == HUD_MODE_ILS && !transition && !docking) { - Point dst = fd->MountLocation(); - projector->Transform(dst); - - if (dst.z > 1.0) { - projector->Project(dst); - - int x = (int) dst.x; - int y = (int) dst.y; - - if (x > 4 && x < width-4 && - y > 4 && y < height-4) { - - window->DrawLine(x-6, y-6, x+6, y+6, hud_color); - window->DrawLine(x+6, y-6, x-6, y+6, hud_color); - } - } - } - - // draw the hoops for this flight deck: - Scene* scene = camview->GetScene(); - for (int h = 0; h < fd->NumHoops(); h++) { - Hoop* hoop = fd->GetHoops() + h; - if (hoop && scene) { - if (same_sector && mode == HUD_MODE_ILS && !transition && !docking) { - scene->AddGraphic(hoop); - hoop->Show(); - - hoops_drawn = true; - } - else { - hoop->Hide(); - scene->DelGraphic(hoop); - } - } - } - } - } - - if (!hoops_drawn) { - ListIter iter = ship->GetRegion()->Carriers(); - while (++iter) { - Ship* carrier = iter.value(); - - bool ours = (carrier->GetIFF() == ship->GetIFF()) || - (carrier->GetIFF() == 0); - - for (int i = 0; i < carrier->NumFlightDecks(); i++) { - FlightDeck* fd = carrier->GetFlightDeck(i); - - if (fd && fd->IsRecoveryDeck()) { - if (mode == HUD_MODE_ILS && ours && !transition && !docking) { - Point dst = fd->MountLocation(); - projector->Transform(dst); - - if (dst.z > 1.0) { - projector->Project(dst); - - int x = (int) dst.x; - int y = (int) dst.y; - - if (x > 4 && x < width-4 && - y > 4 && y < height-4) { - - window->DrawLine(x-6, y-6, x+6, y+6, hud_color); - window->DrawLine(x+6, y-6, x-6, y+6, hud_color); - } - } - } - - // draw the hoops for this flight deck: - Scene* scene = camview->GetScene(); - for (int h = 0; h < fd->NumHoops(); h++) { - Hoop* hoop = fd->GetHoops() + h; - if (hoop && scene) { - if (mode == HUD_MODE_ILS && ours && !transition && !docking) { - hoop->Show(); - if (!hoop->GetScene()) - scene->AddGraphic(hoop); - } - else { - hoop->Hide(); - if (hoop->GetScene()) - scene->DelGraphic(hoop); - } - } - } - } - } - } - } - } -} - -void -HUDView::DrawObjective() -{ - if (ship && ship->GetDirector() && ship->GetDirector()->Type() >= SteerAI::SEEKER) { - SteerAI* steer = (SteerAI*) ship->GetDirector(); - Point obj = steer->GetObjective(); - projector->Transform(obj); - - if (obj.z > 1.0) { - projector->Project(obj); - - int x = (int) obj.x; - int y = (int) obj.y; - - if (x > 4 && x < width-4 && - y > 4 && y < height-4) { - - Color c = Color::Cyan; - window->DrawRect(x-6, y-6, x+6, y+6, c); - window->DrawLine(x-6, y-6, x+6, y+6, c); - window->DrawLine(x+6, y-6, x-6, y+6, c); - } - } - - if (steer->GetOther()) { - obj = steer->GetOther()->Location(); - projector->Transform(obj); - - if (obj.z > 1.0) { - projector->Project(obj); - - int x = (int) obj.x; - int y = (int) obj.y; - - if (x > 4 && x < width-4 && - y > 4 && y < height-4) { - - Color c = Color::Orange; - window->DrawRect(x-6, y-6, x+6, y+6, c); - window->DrawLine(x-6, y-6, x+6, y+6, c); - window->DrawLine(x+6, y-6, x-6, y+6, c); - } - } - } - } - /***/ -} - -void -HUDView::DrawNavPoint(Instruction& navpt, int index, int next) -{ - if (index >= 15 || !navpt.Region()) return; - - // transform from starsystem to world coordinates: - Point npt = navpt.Region()->Location() + navpt.Location(); - - if (active_region) - npt -= active_region->Location(); - - npt = npt.OtherHand(); - - // transform from world to camera: - projector->Transform(npt); - - // clip: - if (npt.z > 1.0) { - - // project: - projector->Project(npt); - - int x = (int) npt.x; - int y = (int) npt.y; - - // clip: - if (x > 4 && x < width-4 && - y > 4 && y < height-4) { - - Color c = Color::White; - if (navpt.Status() > Instruction::ACTIVE && navpt.HoldTime() <= 0) - c = Color::DarkGray; - - // draw: - if (next) - window->DrawEllipse(x-6, y-6, x+5, y+5, c); - - window->DrawLine(x-6, y-6, x+6, y+6, c); - window->DrawLine(x+6, y-6, x-6, y+6, c); - - if (index > 0) { - char npt_buf[32]; - Rect npt_rect(x+10, y-4, 200, 12); - - if (navpt.Status() == Instruction::COMPLETE && navpt.HoldTime() > 0) { - char hold_time[32]; - FormatTime(hold_time, navpt.HoldTime()); - sprintf_s(npt_buf, "%d %s", index, hold_time); - } - else { - sprintf_s(npt_buf, "%d", index); - } - - DrawHUDText(TXT_NAV_PT + index, npt_buf, npt_rect, DT_LEFT); - } - } - } - - if (next && mode == HUD_MODE_NAV && navpt.Region() == ship->GetRegion()) { - - // Translate into camera relative: - Point tloc = navpt.Location().OtherHand(); - projector->Transform(tloc); - - int behind = tloc.z < 0; - - if (behind) - tloc.z = -tloc.z; - - // Project into screen coordinates: - projector->Project(tloc); - - // DRAW THE OFFSCREEN CHASE INDICATOR: - if (behind || - tloc.x <= 0 || tloc.x >= width-1 || - tloc.y <= 0 || tloc.y >= height-1) { - - // Left side: - if (tloc.x <= 0 || (behind && tloc.x < width/2)) { - if (tloc.y < ah) tloc.y = ah; - else if (tloc.y >= height-ah) tloc.y = height-1-ah; - - chase_sprite->Show(); - chase_sprite->SetAnimation(&chase_left); - chase_sprite->MoveTo(Point(aw, tloc.y, 1)); - } - - // Right side: - else if (tloc.x >= width-1 || behind) { - if (tloc.y < ah) tloc.y = ah; - else if (tloc.y >= height-ah) tloc.y = height-1-ah; - - chase_sprite->Show(); - chase_sprite->SetAnimation(&chase_right); - chase_sprite->MoveTo(Point(width-1-aw, tloc.y, 1)); - } - else { - if (tloc.x < aw) tloc.x = aw; - else if (tloc.x >= width-aw) tloc.x = width-1-aw; - - // Top edge: - if (tloc.y <= 0) { - chase_sprite->Show(); - chase_sprite->SetAnimation(&chase_top); - chase_sprite->MoveTo(Point(tloc.x, ah, 1)); - } - - // Bottom edge: - else if (tloc.y >= height-1) { - chase_sprite->Show(); - chase_sprite->SetAnimation(&chase_bottom); - chase_sprite->MoveTo(Point(tloc.x, height-1-ah, 1)); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::SetShip(Ship* s) -{ - if (ship != s) { - double new_scale = 1; - - ship_status = -1; - ship = s; - - if (ship) { - if (ship->Life() == 0 || ship->IsDying() || ship->IsDead()) { - ship = 0; - } - else { - Observe(ship); - new_scale = 1.1 * ship->Radius() / 64; - - if (ship->Design()->hud_icon.Width()) { - TransferBitmap(ship->Design()->hud_icon, icon_ship, icon_ship_shade); - ColorizeBitmap(icon_ship, icon_ship_shade, txt_color); - } - } - } - - if (az_ring) { - az_ring->Rescale(1/compass_scale); - az_ring->Rescale(new_scale); - } - - if (az_pointer) { - az_pointer->Rescale(1/compass_scale); - az_pointer->Rescale(new_scale); - } - - if (el_ring) { - el_ring->Rescale(1/compass_scale); - el_ring->Rescale(new_scale); - } - - if (el_pointer) { - el_pointer->Rescale(1/compass_scale); - el_pointer->Rescale(new_scale); - } - - compass_scale = new_scale; - inst_page = 0; - - if (ship && ship->GetElement() && ship->GetElement()->NumInstructions() > 0) - if (!show_inst) - CycleHUDInst(); - } - - else if (ship && ship->Design()->hud_icon.Width()) { - bool update = false; - System::STATUS s = System::NOMINAL; - int integrity = (int) (ship->Integrity() / ship->Design()->integrity * 100); - - if (integrity < 30) s = System::CRITICAL; - else if (integrity < 60) s = System::DEGRADED; - - if (s != ship_status) { - ship_status = s; - update = true; - } - - if (update) { - SetStatusColor((System::STATUS) ship_status); - ColorizeBitmap(icon_ship, icon_ship_shade, status_color); - } - } - - if (ship && ship->Cockpit()) { - Solid* cockpit = (Solid*) ship->Cockpit(); - - bool change = false; - - if (cockpit->Hidden()) { - if (cockpit_hud_texture) - change = true; - - cockpit_hud_texture = 0; - } - else { - if (!cockpit_hud_texture) - change = true; - - Model* cockpit_model = cockpit->GetModel(); - Material* hud_material = 0; - - if (cockpit_model) { - hud_material = (Material*) cockpit_model->FindMaterial("HUD"); - if (hud_material) { - cockpit_hud_texture = hud_material->tex_emissive; - } - } - } - - if (change) { - SetHUDColorSet(color); - } - } -} - -void -HUDView::SetTarget(SimObject* t) -{ - bool update = false; - - if (target != t) { - tgt_status = -1; - target = t; - if (target) Observe(target); - update = true; - } - - if (target && target->Type() == SimObject::SIM_SHIP) { - System::STATUS s = System::NOMINAL; - Ship* tship = (Ship*) target; - int integrity = (int) (tship->Integrity() / tship->Design()->integrity * 100); - - if (integrity < 30) s = System::CRITICAL; - else if (integrity < 60) s = System::DEGRADED; - - if (s != tgt_status) { - tgt_status = s; - update = true; - } - } - - if (update) { - if (target && target->Type() == SimObject::SIM_SHIP) { - Ship* tship = (Ship*) target; - TransferBitmap(tship->Design()->hud_icon, icon_target, icon_target_shade); - } - else { - PrepareBitmap("hud_icon.pcx", icon_target, icon_target_shade); - } - - SetStatusColor((System::STATUS) tgt_status); - ColorizeBitmap(icon_target, icon_target_shade, status_color); - } -} - -// +--------------------------------------------------------------------+ - -MFD* -HUDView::GetMFD(int n) const -{ - if (n >= 0 && n < 3) - return mfd[n]; - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -HUDView::Refresh() -{ - sim = Sim::GetSim(); - mouse_in = false; - - if (!sim || !camview || !projector) { - return; - } - - if (Mouse::LButton() == 0) { - mouse_latch = 0; - mouse_index = -1; - } - - int mouse_index_old = mouse_index; - - SetShip(sim->GetPlayerShip()); - - if (mode == HUD_MODE_OFF) { - if (cockpit_hud_texture) { - cockpit_hud_texture->FillRect(0,0,512,256,Color::Black); - } - - sim->ShowGrid(false); - return; - } - - if (cockpit_hud_texture && cockpit_hud_texture->Width() == 512) { - Bitmap* hud_bmp = 0; - - if (hud_sprite[0]) { - hud_bmp = hud_sprite[0]->Frame(); - int bmp_w = hud_bmp->Width(); - int bmp_h = hud_bmp->Height(); - - cockpit_hud_texture->BitBlt( 0, 0, *hud_bmp, 0, 0, bmp_w, bmp_h); - } - - if (hud_sprite[1]) { - hud_bmp = hud_sprite[1]->Frame(); - int bmp_w = hud_bmp->Width(); - int bmp_h = hud_bmp->Height(); - - cockpit_hud_texture->BitBlt(256, 0, *hud_bmp, 0, 0, bmp_w, bmp_h); - } - - if (hud_sprite[6]) { - if (hud_sprite[6]->Hidden()) { - cockpit_hud_texture->FillRect(0,384,128,512,Color::Black); - } - else { - hud_bmp = hud_sprite[6]->Frame(); - int bmp_w = hud_bmp->Width(); - int bmp_h = hud_bmp->Height(); - - cockpit_hud_texture->BitBlt(0,384, *hud_bmp, 0, 0, bmp_w, bmp_h); - } - } - - if (hud_sprite[7]) { - if (hud_sprite[7]->Hidden()) { - cockpit_hud_texture->FillRect(128,384,256,512,Color::Black); - } - else { - hud_bmp = hud_sprite[7]->Frame(); - int bmp_w = hud_bmp->Width(); - int bmp_h = hud_bmp->Height(); - - cockpit_hud_texture->BitBlt(128,384, *hud_bmp, 0, 0, bmp_w, bmp_h); - } - } - - for (int i = 8; i < 32; i++) { - if (hud_sprite[i] && !hud_sprite[i]->Hidden()) { - Sprite* s = hud_sprite[i]; - - int cx = (int) s->Location().x; - int cy = (int) s->Location().y; - int w2 = s->Width() / 2; - int h2 = s->Height() / 2; - - window->DrawBitmap(cx-w2, cy-h2, cx+w2, cy+h2, s->Frame(), Video::BLEND_ALPHA); - } - } - } - else { - for (int i = 0; i < 32; i++) { - if (hud_sprite[i] && !hud_sprite[i]->Hidden()) { - Sprite* s = hud_sprite[i]; - - int cx = (int) s->Location().x; - int cy = (int) s->Location().y; - int w2 = s->Width() / 2; - int h2 = s->Height() / 2; - - window->DrawBitmap(cx-w2, cy-h2, cx+w2, cy+h2, s->Frame(), Video::BLEND_ALPHA); - } - } - - Video* video = Video::GetInstance(); - - for (int i = 0; i < 31; i++) { - Sprite* s = pitch_ladder[i]; - - if (s && !s->Hidden()) { - s->Render2D(video); - } - } - } - - //DrawStarSystem(); - DrawMessages(); - - if (ship) { - // no hud in transition: - if (ship->InTransition()) { - transition = true; - HideAll(); - return; - } - - else if (transition) { - transition = false; - RestoreHUD(); - } - - CameraDirector* cam_dir = CameraDirector::GetInstance(); - - // everything is off during docking, except the final message: - if (cam_dir && cam_dir->GetMode() == CameraDirector::MODE_DOCKING) { - docking = true; - HideAll(); - - if (ship->GetFlightPhase() == Ship::DOCKING) { - Rect dock_rect(width/2-100, height/6, 200, 20); - - if (ship->IsAirborne()) - DrawHUDText(TXT_AUTO, ContentBundle::GetInstance()->GetText("HUDView.SUCCESSFUL-LANDING"), dock_rect, DT_CENTER); - else - DrawHUDText(TXT_AUTO, ContentBundle::GetInstance()->GetText("HUDView.DOCKING-COMPLETE"), dock_rect, DT_CENTER); - } - return; - } - else if (docking) { - docking = false; - RestoreHUD(); - } - - // go to NAV mode during autopilot: - if (ship->GetNavSystem() && ship->GetNavSystem()->AutoNavEngaged() && !arcade) - mode = HUD_MODE_NAV; - - SetTarget(ship->GetTarget()); - - // internal view of HUD reticule - if (CameraDirector::GetCameraMode() <= CameraDirector::MODE_CHASE) - SetTacticalMode(0); - - // external view - else - SetTacticalMode(!cockpit_hud_texture); - - sim->ShowGrid(tactical && - !ship->IsAirborne() && - CameraDirector::GetCameraMode() != CameraDirector::MODE_VIRTUAL); - - // draw HUD bars: - DrawBars(); - - if (missile_lock_sound) { - if (threat > 1) { - long max_vol = AudioConfig::WrnVolume(); - long volume = -1500; - - if (volume > max_vol) - volume = max_vol; - - missile_lock_sound->SetVolume(volume); - missile_lock_sound->Play(); - } - else { - missile_lock_sound->Stop(); - } - } - - DrawNav(); - DrawILS(); - - // FOR DEBUG PURPOSES ONLY: - // DrawObjective(); - - if (!overlay) { - Rect fov_rect(0, 10, width, 10); - int fov_degrees = 180 - 2 * (int)(projector->XAngle()*180/PI); - - if (fov_degrees > 90) - DrawHUDText(TXT_CAM_ANGLE, ContentBundle::GetInstance()->GetText("HUDView.Wide-Angle"), fov_rect, DT_CENTER); - - fov_rect.y = 20; - DrawHUDText(TXT_CAM_MODE, CameraDirector::GetModeName(), fov_rect, DT_CENTER); - } - - DrawMFDs(); - - instr_left_sprite->Hide(); - instr_right_sprite->Hide(); - warn_left_sprite->Hide(); - warn_right_sprite->Hide(); - - if (cockpit_hud_texture) - cockpit_hud_texture->FillRect(256,384,512,512,Color::Black); - - if (show_inst) { - DrawInstructions(); - } - - else if (!arcade) { - if (ship->MasterCaution() && !show_warn) - ShowHUDWarn(); - - if (show_warn) - DrawWarningPanel(); - } - - if (width > 640 || (!show_inst && !show_warn)) { - Rect icon_rect(120, height-24, 128, 16); - - if (ship) - DrawHUDText(TXT_ICON_SHIP_TYPE, ship->DesignName(), icon_rect, DT_CENTER); - - icon_rect.x = width - 248; - - if (target && target->Type() == SimObject::SIM_SHIP) { - Ship* tship = (Ship*) target; - DrawHUDText(TXT_ICON_TARGET_TYPE, tship->DesignName(), icon_rect, DT_CENTER); - } - } - } - else { - if (target) { - SetTarget(0); - } - } - - // latch mouse down to prevent dragging into a control: - if (Mouse::LButton() == 1) - mouse_latch = 1; - - if (mouse_index > -1 && mouse_index_old != mouse_index) - MouseFrame(); -} - -void -HUDView::DrawMFDs() -{ - for (int i = 0; i < 3; i++) { - mfd[i]->Show(); - mfd[i]->SetShip(ship); - mfd[i]->SetCockpitHUDTexture(cockpit_hud_texture); - mfd[i]->Draw(); - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::DrawStarSystem() -{ - if (sim && sim->GetStarSystem()) { - StarSystem* sys = sim->GetStarSystem(); - - ListIter iter = sys->Bodies(); - while (++iter) { - OrbitalBody* body = iter.value(); - DrawOrbitalBody(body); - } - } -} - -void -HUDView::DrawOrbitalBody(OrbitalBody* body) -{ - if (body) { - Point p = body->Rep()->Location(); - - projector->Transform(p); - - if (p.z > 100) { - float r = (float) body->Radius(); - r = projector->ProjectRadius(p, r); - projector->Project(p, false); - - window->DrawEllipse((int) (p.x-r), - (int) (p.y-r), - (int) (p.x+r), - (int) (p.y+r), - Color::Cyan); - } - - ListIter iter = body->Satellites(); - while (++iter) { - OrbitalBody* body = iter.value(); - DrawOrbitalBody(body); - } - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::ExecFrame() -{ - // update the position of HUD elements that are - // part of the 3D scene (like fpm and lcos sprites) - HideCompass(); - - if (ship && !transition && !docking && mode != HUD_MODE_OFF) { - Player* p = Player::GetCurrentPlayer(); - gunsight = p->Gunsight(); - - if (ship->IsStarship()) { - if (tactical) { - hud_left_sprite->Hide(); - hud_right_sprite->Hide(); - } - - else if (hud_left_sprite->Frame() != &hud_left_starship) { - hud_left_sprite->SetAnimation(&hud_left_starship); - hud_right_sprite->SetAnimation(&hud_right_starship); - - hud_left_sprite->MoveTo( Point(width/2-128, height/2, 1)); - hud_right_sprite->MoveTo(Point(width/2+128, height/2, 1)); - } - } - - else if (!ship->IsStarship()) { - if (ship->IsAirborne() && hud_left_sprite->Frame() != &hud_left_air) { - hud_left_sprite->SetAnimation(&hud_left_air); - hud_right_sprite->SetAnimation(&hud_right_air); - } - - else if (!ship->IsAirborne() && hud_left_sprite->Frame() != &hud_left_fighter) { - hud_left_sprite->SetAnimation(&hud_left_fighter); - hud_right_sprite->SetAnimation(&hud_right_fighter); - } - } - - if (!tactical) { - if (GameWinDX9::GetInstance()->MaxTexSize() > 128) { - hud_left_sprite->Show(); - hud_right_sprite->Show(); - } - - if (!arcade) - DrawFPM(); - - if (ship->IsStarship() && ship->GetFLCSMode() == Ship::FLCS_HELM) - DrawHPM(); - else if (!arcade) - DrawPitchLadder(); - } - - else { - if (ship->IsStarship() && ship->GetFLCSMode() == Ship::FLCS_HELM) - DrawCompass(); - } - - if (mode == HUD_MODE_TAC) { - DrawSight(); - DrawDesignators(); - } - - if (width > 640 || (!show_inst && !show_warn)) { - icon_ship_sprite->Show(); - icon_target_sprite->Show(); - } - else { - icon_ship_sprite->Hide(); - icon_target_sprite->Hide(); - } - } - - // if the hud is off or prohibited, - // hide all of the sprites: - - else { - hud_left_sprite->Hide(); - hud_right_sprite->Hide(); - instr_left_sprite->Hide(); - instr_right_sprite->Hide(); - warn_left_sprite->Hide(); - warn_right_sprite->Hide(); - icon_ship_sprite->Hide(); - icon_target_sprite->Hide(); - fpm_sprite->Hide(); - hpm_sprite->Hide(); - lead_sprite->Hide(); - aim_sprite->Hide(); - tgt1_sprite->Hide(); - tgt2_sprite->Hide(); - tgt3_sprite->Hide(); - tgt4_sprite->Hide(); - chase_sprite->Hide(); - - for (int i = 0; i < 3; i++) - mfd[i]->Hide(); - - for (int i = 0; i < 31; i++) - pitch_ladder[i]->Hide(); - - DrawILS(); - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::CycleMFDMode(int mfd_index) -{ - if (mfd_index < 0 || mfd_index > 2) return; - - int m = mfd[mfd_index]->GetMode(); - m++; - - if (mfd_index == 2) { - if (m > MFD::MFD_MODE_SHIP) - m = MFD::MFD_MODE_OFF; - } - else { - if (m > MFD::MFD_MODE_3D) - m = MFD::MFD_MODE_OFF; - - if (m == MFD::MFD_MODE_GAME) - m++; - - if (mfd_index != 0 && m == MFD::MFD_MODE_SHIP) - m++; - } - - mfd[mfd_index]->SetMode(m); - HUDSounds::PlaySound(HUDSounds::SND_MFD_MODE); -} - -// +--------------------------------------------------------------------+ - -void -HUDView::ShowHUDWarn() -{ - if (!show_warn) { - show_warn = true; - - if (ship && ship->HullStrength() <= 40) { - // TOO OBNOXIOUS!! - HUDSounds::PlaySound(HUDSounds::SND_RED_ALERT); - } - } -} - -void -HUDView::ShowHUDInst() -{ - show_inst = true; -} - -// +--------------------------------------------------------------------+ - -void -HUDView::HideHUDWarn() -{ - show_warn = false; - - if (ship) { - ship->ClearCaution(); - HUDSounds::StopSound(HUDSounds::SND_RED_ALERT); - } -} - -void -HUDView::HideHUDInst() -{ - show_inst = false; -} - -// +--------------------------------------------------------------------+ - -void -HUDView::CycleHUDWarn() -{ - HUDSounds::PlaySound(HUDSounds::SND_HUD_WIDGET); - show_warn = !show_warn; - - if (ship && !show_warn) { - ship->ClearCaution(); - HUDSounds::StopSound(HUDSounds::SND_RED_ALERT); - } -} - -void -HUDView::CycleHUDInst() -{ - show_inst = !show_inst; - HUDSounds::PlaySound(HUDSounds::SND_HUD_WIDGET); -} - -// +--------------------------------------------------------------------+ - -void -HUDView::SetHUDMode(int m) -{ - if (mode != m) { - mode = m; - - if (mode > HUD_MODE_ILS || mode < HUD_MODE_OFF) - mode = HUD_MODE_OFF; - - if (ship && !ship->IsDropship() && mode == HUD_MODE_ILS) - mode = HUD_MODE_OFF; - - RestoreHUD(); - } -} - -void -HUDView::CycleHUDMode() -{ - mode++; - - if (arcade && mode != HUD_MODE_TAC) - mode = HUD_MODE_OFF; - - else if (mode > HUD_MODE_ILS || mode < HUD_MODE_OFF) - mode = HUD_MODE_OFF; - - else if (!ship->IsDropship() && mode == HUD_MODE_ILS) - mode = HUD_MODE_OFF; - - RestoreHUD(); - HUDSounds::PlaySound(HUDSounds::SND_HUD_MODE); -} - -void -HUDView::RestoreHUD() -{ - if (mode == HUD_MODE_OFF) { - HideAll(); - } - else { - for (int i = 0; i < 3; i++) - mfd[i]->Show(); - - if (width > 640 || (!show_inst && !show_warn)) { - icon_ship_sprite->Show(); - icon_target_sprite->Show(); - } - else { - icon_ship_sprite->Hide(); - icon_target_sprite->Hide(); - } - - if (!tactical && GameWinDX9::GetInstance()->MaxTexSize() > 128) { - hud_left_sprite->Show(); - hud_right_sprite->Show(); - } - - fpm_sprite->Show(); - - if (ship && ship->IsStarship()) - hpm_sprite->Show(); - - if (gunsight == 0) - aim_sprite->Show(); - else - lead_sprite->Show(); - } -} - -void -HUDView::HideAll() -{ - for (int i = 0; i < 3; i++) - mfd[i]->Hide(); - - hud_left_sprite->Hide(); - hud_right_sprite->Hide(); - instr_left_sprite->Hide(); - instr_right_sprite->Hide(); - warn_left_sprite->Hide(); - warn_right_sprite->Hide(); - icon_ship_sprite->Hide(); - icon_target_sprite->Hide(); - fpm_sprite->Hide(); - hpm_sprite->Hide(); - lead_sprite->Hide(); - aim_sprite->Hide(); - tgt1_sprite->Hide(); - tgt2_sprite->Hide(); - tgt3_sprite->Hide(); - tgt4_sprite->Hide(); - chase_sprite->Hide(); - - sim->ShowGrid(false); - - for (int i = 0; i < 31; i++) - pitch_ladder[i]->Hide(); - - if (missile_lock_sound) - missile_lock_sound->Stop(); - - HideCompass(); - DrawILS(); - Mouse::Show(false); -} - -// +--------------------------------------------------------------------+ - -Color -HUDView::Ambient() const -{ - if (!sim || !ship || mode == HUD_MODE_OFF) - return Color::Black; - - SimRegion* rgn = sim->GetActiveRegion(); - - if (!rgn || !rgn->IsAirSpace()) - return Color::Black; - - Color c = sim->GetStarSystem()->Ambient(); - - if (c.Red() > 32 || c.Green() > 32 || c.Blue() > 32) - return Color::Black; - - // if we get this far, the night-vision aid is on - return night_vision_colors[color]; -} - -Color -HUDView::CycleHUDColor() -{ - HUDSounds::PlaySound(HUDSounds::SND_HUD_MODE); - SetHUDColorSet(color+1); - return hud_color; -} - -void -HUDView::SetHUDColorSet(int c) -{ - color = c; - if (color > NUM_HUD_COLORS-1) color = 0; - hud_color = standard_hud_colors[color]; - txt_color = standard_txt_colors[color]; - - ColorizeBitmap(fpm, fpm_shade, hud_color, true); - ColorizeBitmap(hpm, hpm_shade, hud_color, true); - ColorizeBitmap(lead, lead_shade, txt_color * 1.25, true); - ColorizeBitmap(cross, cross_shade, hud_color, true); - ColorizeBitmap(cross1, cross1_shade, hud_color, true); - ColorizeBitmap(cross2, cross2_shade, hud_color, true); - ColorizeBitmap(cross3, cross3_shade, hud_color, true); - ColorizeBitmap(cross4, cross4_shade, hud_color, true); - - if (GameWinDX9::GetInstance()->MaxTexSize() > 128) { - ColorizeBitmap(hud_left_air, hud_left_shade_air, hud_color); - ColorizeBitmap(hud_right_air, hud_right_shade_air, hud_color); - ColorizeBitmap(hud_left_fighter, hud_left_shade_fighter, hud_color); - ColorizeBitmap(hud_right_fighter, hud_right_shade_fighter, hud_color); - ColorizeBitmap(hud_left_starship, hud_left_shade_starship, hud_color); - ColorizeBitmap(hud_right_starship, hud_right_shade_starship, hud_color); - - ColorizeBitmap(instr_left, instr_left_shade, hud_color); - ColorizeBitmap(instr_right, instr_right_shade, hud_color); - ColorizeBitmap(warn_left, warn_left_shade, hud_color); - ColorizeBitmap(warn_right, warn_right_shade, hud_color); - - ColorizeBitmap(pitch_ladder_pos, pitch_ladder_pos_shade, hud_color); - ColorizeBitmap(pitch_ladder_neg, pitch_ladder_neg_shade, hud_color); - } - - ColorizeBitmap(icon_ship, icon_ship_shade, txt_color); - ColorizeBitmap(icon_target, icon_target_shade, txt_color); - - ColorizeBitmap(chase_left, chase_left_shade, hud_color, true); - ColorizeBitmap(chase_right, chase_right_shade, hud_color, true); - ColorizeBitmap(chase_top, chase_top_shade, hud_color, true); - ColorizeBitmap(chase_bottom, chase_bottom_shade, hud_color, true); - - MFD::SetColor(hud_color); - Hoop::SetColor(hud_color); - - for (int i = 0; i < 3; i++) - mfd[i]->SetText3DColor(txt_color); - - Font* font = FontMgr::Find("HUD"); - if (font) - font->SetColor(txt_color); - - for (int i = 0; i < TXT_LAST; i++) - hud_text[i].color = txt_color; -} - -// +--------------------------------------------------------------------+ - -void -HUDView::Message(const char* fmt, ...) -{ - if (fmt) { - char msg[512]; - vsprintf(msg, fmt, (char *)(&fmt+1)); - - char* newline = strchr(msg, '\n'); - if (newline) - *newline = 0; - - Print("%s\n", msg); - - if (hud_view) { - int index = -1; - - for (int i = 0; i < MAX_MSG; i++) { - if (hud_view->msg_time[i] <= 0) { - index = i; - break; - } - } - - // no space; advance pipeline: - if (index < 0) { - for (int i = 0; i < MAX_MSG-1; i++) { - hud_view->msg_text[i] = hud_view->msg_text[i+1]; - hud_view->msg_time[i] = hud_view->msg_time[i+1]; - } - - index = MAX_MSG-1; - } - - hud_view->msg_text[index] = msg; - hud_view->msg_time[index] = 10; - } - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::ClearMessages() -{ - if (hud_view) { - for (int i = 0; i < MAX_MSG-1; i++) { - hud_view->msg_text[i] = Text(); - hud_view->msg_time[i] = 0; - } - } -} - -// +--------------------------------------------------------------------+ - -void -HUDView::PrepareBitmap(const char* name, Bitmap& img, BYTE*& shades) -{ - delete [] shades; - shades = 0; - - DataLoader* loader = DataLoader::GetLoader(); - - loader->SetDataPath("HUD/"); - int loaded = loader->LoadBitmap(name, img, Bitmap::BMP_TRANSPARENT); - loader->SetDataPath(0); - - if (!loaded) - return; - - int w = img.Width(); - int h = img.Height(); - - shades = new BYTE[w*h]; - - for (int y = 0; y < h; y++) - for (int x = 0; x < w; x++) - shades[y*w+x] = (BYTE) (img.GetColor(x,y).Red() * 0.66); -} - -void -HUDView::TransferBitmap(const Bitmap& src, Bitmap& img, BYTE*& shades) -{ - delete [] shades; - shades = 0; - - if (src.Width() != img.Width() || src.Height() != img.Height()) - return; - - img.CopyBitmap(src); - img.SetType(Bitmap::BMP_TRANSLUCENT); - - int w = img.Width(); - int h = img.Height(); - - shades = new BYTE[w*h]; - - for (int y = 0; y < h; y++) - for (int x = 0; x < w; x++) - shades[y*w+x] = (BYTE) (img.GetColor(x,y).Red() * 0.5); -} - -void -HUDView::ColorizeBitmap(Bitmap& img, BYTE* shades, Color color, bool force_alpha) -{ - if (!shades) return; - - int max_tex_size = GameWinDX9::GetInstance()->MaxTexSize(); - - if (max_tex_size < 128) - GameWinDX9::GetInstance()->SetMaxTexSize(128); - - if (hud_view && hud_view->cockpit_hud_texture && !force_alpha) { - img.FillColor(Color::Black); - Color* dst = img.HiPixels(); - BYTE* src = shades; - - for (int y = 0; y < img.Height(); y++) { - for (int x = 0; x < img.Width(); x++) { - if (*src) - *dst = color.dim(*src/200.0); - else - *dst = Color::Black; - - dst++; - src++; - } - } - img.MakeTexture(); - } - else { - img.FillColor(color); - img.CopyAlphaImage(img.Width(), img.Height(), shades); - img.MakeTexture(); - } - - if (max_tex_size < 128) - GameWinDX9::GetInstance()->SetMaxTexSize(max_tex_size); -} - -// +--------------------------------------------------------------------+ - -void -HUDView::MouseFrame() -{ - MouseController* ctrl = MouseController::GetInstance(); - if (ctrl && ctrl->Active()) - return; - - if (mouse_index >= TXT_CAUTION_TXT && mouse_index <= TXT_LAST_CAUTION) { - if (show_inst) { - if (mouse_index == TXT_INSTR_PAGE) { - if (Mouse::X() > width/2 + 125) - CycleInstructions(1); - else if (Mouse::X() < width/2 + 65) - CycleInstructions(-1); - } - else - show_inst = false; - } - else { - CycleHUDWarn(); - } - return; - } - - Starshatter* stars = Starshatter::GetInstance(); - if (mouse_index == TXT_PAUSED) - stars->Pause(!Game::GetInstance()->Paused()); - - if (mouse_index == TXT_GEAR_DOWN) - ship->ToggleGear(); - - if (mouse_index == TXT_HUD_MODE) { - CycleHUDMode(); - - if (mode == HUD_MODE_OFF) - CycleHUDMode(); - } - - if (mouse_index == TXT_PRIMARY_WEP) { - HUDSounds::PlaySound(HUDSounds::SND_WEP_MODE); - ship->CyclePrimary(); - } - - if (mouse_index == TXT_SECONDARY_WEP) { - HUDSounds::PlaySound(HUDSounds::SND_WEP_MODE); - ship->CycleSecondary(); - } - - if (mouse_index == TXT_DECOY) - ship->FireDecoy(); - - if (mouse_index == TXT_SHIELD) { - Shield* shield = ship->GetShield(); - - if (shield) { - double level = shield->GetPowerLevel(); - - const Rect& r = hud_text[TXT_SHIELD].rect; - if (Mouse::X() < r.x + r.w * 0.75) - shield->SetPowerLevel(level - 10); - else - shield->SetPowerLevel(level + 10); - - HUDSounds::PlaySound(HUDSounds::SND_SHIELD_LEVEL); - } - } - - if (mouse_index == TXT_AUTO) - ship->TimeSkip(); - - if (mouse_index >= TXT_NAV_INDEX && mouse_index <= TXT_NAV_ETR) { - ship->SetAutoNav(!ship->IsAutoNavEngaged()); - SetHUDMode(HUD_MODE_TAC); - } -} - -// +--------------------------------------------------------------------+ - -bool -HUDView::IsMouseLatched() -{ - bool result = mouse_in; - - if (!result) { - HUDView* hud = HUDView::GetInstance(); - - for (int i = 0; i < 3; i++) - result = result || hud->mfd[i]->IsMouseLatched(); - } - - return result; -} - -// +--------------------------------------------------------------------+ - -bool -HUDView::IsNameCrowded(int x, int y) -{ - for (int i = 0; i < MAX_CONTACT; i++) { - HUDText& test = hud_text[TXT_CONTACT_NAME + i]; - - if (!test.hidden) { - Rect r = test.rect; - - int dx = r.x - x; - int dy = r.y - y; - int d = dx*dx + dy*dy; - - if (d <= 400) - return true; - } - - test = hud_text[TXT_CONTACT_INFO + i]; - - if (!test.hidden) { - Rect r = test.rect; - - int dx = r.x - x; - int dy = r.y - y; - int d = dx*dx + dy*dy; - - if (d <= 400) - return true; - } - } - - return false; -} - -void -HUDView::DrawDiamond(int x, int y, int r, Color c) -{ - POINT diamond[4]; - - diamond[0].x = x; - diamond[0].y = y-r; - - diamond[1].x = x+r; - diamond[1].y = y; - - diamond[2].x = x; - diamond[2].y = y+r; - - diamond[3].x = x-r; - diamond[3].y = y; - - window->DrawPoly(4, diamond, c); -} diff --git a/Stars45/HUDView.h b/Stars45/HUDView.h deleted file mode 100644 index 4274ac9..0000000 --- a/Stars45/HUDView.h +++ /dev/null @@ -1,217 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Heads Up Display -*/ - -#ifndef HUDView_h -#define HUDView_h - -#include "Types.h" -#include "View.h" -#include "Bitmap.h" -#include "Font.h" -#include "System.h" -#include "SimObject.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Graphic; -class Sprite; -class Solid; -class Ship; -class Contact; -class Physical; -class OrbitalBody; -class OrbitalRegion; -class Instruction; -class CameraView; -class Projector; -class MFD; - -// +--------------------------------------------------------------------+ - -class HUDView : public View, -public SimObserver -{ -public: - HUDView(Window* c); - virtual ~HUDView(); - - enum HUDModes { HUD_MODE_OFF, HUD_MODE_TAC, HUD_MODE_NAV, HUD_MODE_ILS }; - - // Operations: - virtual void Refresh(); - virtual void OnWindowMove(); - virtual void ExecFrame(); - virtual void UseCameraView(CameraView* v); - - virtual Ship* GetShip() const { return ship; } - virtual SimObject* GetTarget() const { return target; } - virtual void SetShip(Ship* s); - virtual void SetTarget(SimObject* t); - virtual MFD* GetMFD(int n) const; - - virtual void HideAll(); - virtual void DrawBars(); - virtual void DrawNav(); - virtual void DrawILS(); - virtual void DrawObjective(); - virtual void DrawNavInfo(); - virtual void DrawNavPoint(Instruction& navpt, int index, int next); - virtual void DrawContactMarkers(); - virtual void DrawContact(Contact* c, int index); - virtual void DrawTrack(Contact* c); - virtual void DrawTrackSegment(Point& t1, Point& t2, Color c); - virtual void DrawRect(SimObject* targ); - virtual void DrawTarget(); - virtual void DrawSight(); - virtual void DrawLCOS(SimObject* targ, double dist); - virtual void DrawDesignators(); - virtual void DrawFPM(); - virtual void DrawHPM(); - virtual void DrawCompass(); - virtual void HideCompass(); - virtual void DrawPitchLadder(); - virtual void DrawStarSystem(); - - virtual void DrawMFDs(); - virtual void DrawWarningPanel(); - virtual void DrawInstructions(); - virtual void DrawMessages(); - - virtual void MouseFrame(); - - virtual int GetHUDMode() const { return mode; } - virtual int GetTacticalMode() const { return tactical; } - virtual void SetTacticalMode(int mode=1); - virtual int GetOverlayMode() const { return overlay; } - virtual void SetOverlayMode(int mode=1); - - virtual void SetHUDMode(int mode); - virtual void CycleHUDMode(); - virtual Color CycleHUDColor(); - virtual void SetHUDColorSet(int c); - virtual int GetHUDColorSet() const { return color; } - virtual Color GetHUDColor() const { return hud_color; } - virtual Color GetTextColor() const { return txt_color; } - virtual Color Ambient() const; - virtual void ShowHUDWarn(); - virtual void ShowHUDInst(); - virtual void HideHUDWarn(); - virtual void HideHUDInst(); - virtual void CycleHUDWarn(); - virtual void CycleHUDInst(); - virtual void CycleMFDMode(int mfd); - virtual void CycleInstructions(int direction); - virtual void RestoreHUD(); - - virtual void TargetOff() { target = 0; } - static Color MarkerColor(Contact* targ); - - static bool IsNameCrowded(int x, int y); - static bool IsMouseLatched(); - static HUDView* GetInstance() { return hud_view; } - static void Message(const char* fmt, ...); - static void ClearMessages(); - static void PrepareBitmap(const char* name, Bitmap& img, BYTE*& shades); - static void TransferBitmap(const Bitmap& src, Bitmap& img, BYTE*& shades); - static void ColorizeBitmap(Bitmap& img, BYTE* shades, Color color, bool force_alpha=false); - - static int GetGunsight() { return gunsight; } - static void SetGunsight(int s) { gunsight = s; } - static bool IsArcade() { return arcade; } - static void SetArcade(bool a) { arcade = a; } - static int DefaultColorSet() { return def_color_set; } - static void SetDefaultColorSet(int c) { def_color_set = c; } - static Color GetStatusColor(System::STATUS status); - static bool ShowFPS() { return show_fps; } - static void ShowFPS(bool f) { show_fps = f; } - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - -protected: - const char* FormatInstruction(Text instr); - void SetStatusColor(System::STATUS status); - - enum HUD_CASE { HUD_MIXED_CASE, HUD_UPPER_CASE }; - - void DrawDiamond(int x, int y, int r, Color c); - void DrawHUDText(int index, const char* txt, Rect& rect, int align, int upcase=HUD_UPPER_CASE, bool box=false); - void HideHUDText(int index); - - void DrawOrbitalBody(OrbitalBody* body); - - Projector* projector; - CameraView* camview; - - int width, height, aw, ah; - double xcenter, ycenter; - - Sim* sim; - Ship* ship; - SimObject* target; - - SimRegion* active_region; - - Bitmap* cockpit_hud_texture; - - Color hud_color; - Color txt_color; - Color status_color; - - bool show_warn; - bool show_inst; - int inst_page; - int threat; - - int mode; - int color; - int tactical; - int overlay; - int transition; - int docking; - - MFD* mfd[3]; - - Sprite* pitch_ladder[31]; - Sprite* hud_sprite[32]; - - Solid* az_ring; - Solid* az_pointer; - Solid* el_ring; - Solid* el_pointer; - double compass_scale; - - enum { MAX_MSG = 6 }; - Text msg_text[MAX_MSG]; - double msg_time[MAX_MSG]; - - static HUDView* hud_view; - static bool arcade; - static bool show_fps; - static int gunsight; - static int def_color_set; -}; - - -// +--------------------------------------------------------------------+ - -struct HUDText { - Font* font; - Color color; - Rect rect; - bool hidden; -}; - -#endif // HUDView_h - diff --git a/Stars45/Hangar.cpp b/Stars45/Hangar.cpp deleted file mode 100644 index 7e7f7d8..0000000 --- a/Stars45/Hangar.cpp +++ /dev/null @@ -1,932 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Everything needed to store and maintain space craft - - See Also: FlightDeck -*/ - -#include "Hangar.h" -#include "FlightDeck.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Sim.h" -#include "Instruction.h" -#include "Element.h" -#include "Mission.h" -#include "RadioMessage.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatGroup.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Random.h" - -// +======================================================================+ - -class HangarSlot -{ - friend class Hangar; - -public: - static const char* TYPENAME() { return "HangarSlot"; } - - HangarSlot(); - ~HangarSlot(); - int operator == (const HangarSlot& that) const { return this == &that; } - -private: - Text squadron; - CombatGroup* group; - Ship* ship; - int iff; - const ShipDesign* design; - FlightDeck* deck; - int slot; - int state; - double time; - Element* package; - bool alert_hold; - int loadout[16]; -}; - -// +--------------------------------------------------------------------+ - -HangarSlot::HangarSlot() - : ship(0), group(0), design(0), deck(0), slot(0), - state(0), time(0), package(0), alert_hold(false) -{ - for (int i = 0; i < 16; i++) - loadout[i] = -1; -} - -HangarSlot::~HangarSlot() -{ -} - -// +======================================================================+ - -Hangar::Hangar() - : ship(0), nsquadrons(0), last_patrol_launch(0) -{ - ZeroMemory(nslots, sizeof(nslots)); - ZeroMemory(squadrons, sizeof(squadrons)); -} - -// +----------------------------------------------------------------------+ - -Hangar::Hangar(const Hangar& s) - : ship(0), nsquadrons(s.nsquadrons), last_patrol_launch(s.last_patrol_launch) -{ - ZeroMemory(nslots, sizeof(nslots)); - ZeroMemory(squadrons, sizeof(squadrons)); -} - -// +--------------------------------------------------------------------+ - -Hangar::~Hangar() -{ - for (int i = 0; i < MAX_SQUADRONS; i++) - delete [] squadrons[i]; -} - -// +--------------------------------------------------------------------+ - -void -Hangar::ExecFrame(double seconds) -{ - for (int n = 0; n < nsquadrons; n++) { - if (squadrons[n] && nslots[n] > 0) { - for (int i = 0; i < nslots[n]; i++) { - HangarSlot* slot = &squadrons[n][i]; - - switch (slot->state) { - case UNAVAIL: - case STORAGE: - case APPROACH: - break; - - case ACTIVE: - if (slot->ship && slot->ship->GetFlightPhase() == Ship::APPROACH) - slot->state = APPROACH; - break; - - case MAINT: - if (slot->time > 0) { - slot->time -= seconds; - } - else { - slot->time = 0; - slot->state = STORAGE; - } - break; - - - case PREP: - if (slot->time > 0) { - slot->time -= seconds; - } - else { - slot->time = 0; - FinishPrep(slot); - } - break; - - case ALERT: - if (slot->time > 0) { - slot->time -= seconds; - } - else if (slot->deck) { - slot->time = 0; - - // if package has specific objective, launch as soon as possible: - if (!slot->alert_hold) - slot->deck->Launch(slot->slot); - - switch (slot->deck->State(slot->slot)) { - case FlightDeck::READY: slot->state = ALERT; break; - case FlightDeck::QUEUED: slot->state = QUEUED; break; - case FlightDeck::LOCKED: slot->state = LOCKED; break; - case FlightDeck::LAUNCH: slot->state = LAUNCH; break; - default: slot->state = STORAGE; break; - } - } - break; - - case QUEUED: - case LOCKED: - if (slot->deck) { - switch (slot->deck->State(slot->slot)) { - case FlightDeck::READY: slot->state = ALERT; break; - case FlightDeck::QUEUED: slot->state = QUEUED; break; - case FlightDeck::LOCKED: slot->state = LOCKED; break; - case FlightDeck::LAUNCH: slot->state = LAUNCH; break; - default: slot->state = STORAGE; break; - } - - slot->time = slot->deck->TimeRemaining(slot->slot); - } - break; - - case LAUNCH: - if (slot->deck) { - slot->time = slot->deck->TimeRemaining(slot->slot); - - if (slot->ship && slot->ship->GetFlightPhase() > Ship::LAUNCH) { - slot->state = ACTIVE; - slot->time = 0; - } - } - break; - - case RECOVERY: - break; - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -bool -Hangar::FinishPrep(HangarSlot* slot) -{ - if (slot->deck->SpaceLeft(slot->design->type)) { - Sim* sim = Sim::GetSim(); - - Text ship_name = slot->squadron; - - slot->ship = sim->CreateShip(ship_name, "", - (ShipDesign*) slot->design, - ship->GetRegion()->Name(), - Point(0, 0, 0), - slot->iff, - ship->GetCommandAILevel(), - slot->loadout); - - Observe(slot->ship); - - if (slot->package) { - slot->package->SetCommander(ship->GetElement()); - slot->package->AddShip(slot->ship); - - if (slot->group) { - slot->package->SetCombatGroup(slot->group); - slot->package->SetCombatUnit(slot->group->GetNextUnit()); - } - - char name[64]; - sprintf_s(name, "%s %d", - (const char*) slot->package->Name(), - slot->ship->GetElementIndex()); - slot->ship->SetName(name); - } - - slot->slot = -1; // take first available slot - if (slot->deck->Spot(slot->ship, slot->slot)) { - slot->state = ALERT; - return true; - } - - Print("WARNING: Could not spot alert ship - carrier: '%s' ship '%s'\n", - ship->Name(), slot->ship->Name()); - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -Hangar::Update(SimObject* obj) -{ - bool found = false; - - for (int n = 0; !found && n < nsquadrons; n++) { - if (squadrons[n] && nslots[n] > 0) { - for (int i = 0; !found && i < nslots[n]; i++) { - HangarSlot* slot = &squadrons[n][i]; - - if (slot->ship == obj) { - // was ship destroyed in combat, - // or did it just dock here? - if (slot->state != MAINT) { - slot->state = UNAVAIL; - slot->ship = 0; - slot->deck = 0; - slot->time = 0; - slot->package = 0; - } - - found = true; - } - } - } - } - - return SimObserver::Update(obj); -} - -const char* -Hangar::GetObserverName() const -{ - static char name[64]; - if (ship) - sprintf_s(name, "Hangar(%s)", ship->Name()); - else - sprintf_s(name, "Hangar"); - return name; -} - -// +--------------------------------------------------------------------+ - -bool -Hangar::CreateSquadron(Text squadron, CombatGroup* group, -const ShipDesign* design, int count, int iff, -int* def_load, int maint_count, int dead_count) -{ - if (nsquadrons < MAX_SQUADRONS && count > 0) { - HangarSlot* s = new HangarSlot[count]; - - for (int i = 0; i < count; i++) { - s[i].squadron = squadron; - s[i].group = group; - s[i].design = design; - s[i].iff = iff; - - if (def_load) - CopyMemory(s[i].loadout, def_load, sizeof(s[i].loadout)); - } - - squadrons[nsquadrons] = s; - nslots[nsquadrons] = count; - names[nsquadrons] = squadron; - - int i = count-1; - while (dead_count-- > 0) - s[i--].state = UNAVAIL; - - while (maint_count-- > 0) { - s[i].state = MAINT; - s[i--].time = 600 + rand() / 15; - } - - nsquadrons++; - return true; - } - - return false; -} - -bool -Hangar::GotoActiveFlight(int squadron, int slot_index, Element* elem, int* loadout) -{ - if (elem && squadron < nsquadrons && slot_index < nslots[squadron]) { - HangarSlot* slot = &(squadrons[squadron][slot_index]); - - if (slot->state == STORAGE) { - slot->deck = 0; - slot->state = ACTIVE; - slot->time = 0; - slot->package = elem; - slot->alert_hold = false; - - if (loadout) - CopyMemory(slot->loadout, loadout, sizeof(slot->loadout)); - - Sim* sim = Sim::GetSim(); - - Text ship_name = slot->squadron; - - slot->ship = sim->CreateShip(ship_name, "", - (ShipDesign*) slot->design, - ship->GetRegion()->Name(), - ship->Location() + RandomPoint(), - slot->iff, - ship->GetCommandAILevel(), - slot->loadout); - - if (slot->ship) { - Observe(slot->ship); - - elem->SetCommander(ship->GetElement()); - elem->AddShip(slot->ship); - - if (slot->group) { - elem->SetCombatGroup(slot->group); - elem->SetCombatUnit(slot->group->GetNextUnit()); - } - - char name[64]; - sprintf_s(name, "%s %d", - (const char*) elem->Name(), - slot->ship->GetElementIndex()); - - slot->ship->SetName(name); - } - - return true; - } - } - - return false; -} - -bool -Hangar::GotoAlert(int squadron, int slot, FlightDeck* d, Element* elem, int* loadout, bool pkg, bool expedite) -{ - if (squadron < nsquadrons && slot < nslots[squadron]) { - HangarSlot* s = &(squadrons[squadron][slot]); - - if (s->state == STORAGE) { - s->deck = d; - s->state = PREP; - s->time = expedite ? 3 : s->design->prep_time; - s->package = elem; - s->alert_hold = !pkg; - - if (loadout) - CopyMemory(s->loadout, loadout, sizeof(s->loadout)); - - if (expedite) - FinishPrep(s); - - return true; - } - } - - return false; -} - -bool -Hangar::Launch(int squadron, int slot) -{ - if (squadron < nsquadrons && slot < nslots[squadron]) { - HangarSlot* s = &(squadrons[squadron][slot]); - - if (s->state == ALERT && s->deck) - return s->deck->Launch(s->slot); - } - - return false; -} - -bool -Hangar::StandDown(int squadron, int slot) -{ - if (squadron < nsquadrons && slot < nslots[squadron]) { - HangarSlot* s = &(squadrons[squadron][slot]); - - Element* package = 0; - bool clear_slot = false; - - if (s->state == ALERT && s->deck) { - if (s->deck->Clear(s->slot)) { - if (s->ship) { - Sim* sim = Sim::GetSim(); - - if (s->package) { - package = s->package; - package->DelShip(s->ship); - } - - sim->DestroyShip(s->ship); - } - - clear_slot = true; - } - } - - else if (s->state == PREP) { - clear_slot = true; - package = s->package; - } - - if (clear_slot) { - s->state = STORAGE; - s->deck = 0; - s->slot = 0; - s->ship = 0; - s->package = 0; - - if (package) { - int npkg = 0; - for (int i = 0; i < nslots[squadron]; i++) { - if (squadrons[squadron][i].package == package) - npkg++; - } - - if (npkg == 0) { - Sim::GetSim()->DestroyElement(package); - } - } - - return true; - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -Hangar::CanStow(Ship* incoming) -{ - int squadron = -1; - int slot = -1; - - if (FindSlot(incoming, squadron, slot)) - return true; - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -Hangar::Stow(Ship* incoming) -{ - int squadron = -1; - int slot = -1; - - if (FindSlot(incoming, squadron, slot)) { - HangarSlot* s = &(squadrons[squadron][slot]); - s->state = MAINT; - s->design = incoming->Design(); - s->time = 2400; - s->package = 0; // XXX MEMORY LEAK? - - // extra maintenance time? - if (incoming->Integrity() < incoming->Design()->integrity) { - double damage = 100 * ((double) incoming->Design()->integrity - (double) incoming->Integrity()) / (double) incoming->Design()->integrity; - - if (damage < 10) s->time *= 1.2; - else if (damage < 25) s->time *= 2; - else if (damage < 50) s->time *= 4; - else s->time *= 10; - } - - // quicker turnaround during network play: - Sim* sim = Sim::GetSim(); - if (sim && sim->IsNetGame()) - s->time /= 40; - - return true; - } - - return false; -} - -bool -Hangar::FindSlot(Ship* test, int& squadron, int& slot, int desired_state) -{ - if (test) { - // if test is already inbound to this carrier, - // keep the inbound squadron and slot selections: - if (desired_state == UNAVAIL && test->GetInbound()) { - InboundSlot* inbound = test->GetInbound(); - FlightDeck* deck = inbound->GetDeck(); - - if (deck && deck->GetCarrier() == ship && deck->IsPowerOn()) { - squadron = inbound->Squadron(); - slot = inbound->Index(); - return true; - } - } - - int avail_squadron = -1; - int avail_slot = -1; - - for (int i = 0; i < nsquadrons; i++) { - if (squadron < 0 || squadron == i) { - for (int j = 0; j < nslots[i]; j++) { - HangarSlot* s = &(squadrons[i][j]); - if (s->ship == test) { - squadron = i; - slot = j; - return true; - } - - else if (avail_slot < 0 && s->ship == 0) { - if ((desired_state > STORAGE && s->state == STORAGE) || - (desired_state < STORAGE && s->state == UNAVAIL)) { - avail_squadron = i; - avail_slot = j; - } - } - } - } - } - - if (avail_squadron >= 0 && avail_slot >= 0) { - squadron = avail_squadron; - slot = avail_slot; - - if (desired_state > STORAGE) { - HangarSlot* s = &(squadrons[squadron][slot]); - - s->ship = test; - s->design = test->Design(); - s->state = desired_state; - s->deck = 0; - s->slot = 0; - s->package = test->GetElement(); - s->time = 0; - - Observe(s->ship); - } - - return true; - } - } - - return false; -} - -bool -Hangar::FindSquadronAndSlot(Ship* test, int& squadron, int& slot) -{ - if (test) { - for (int i = 0; i < nsquadrons; i++) { - if (squadron < 0 || squadron == i) { - for (int j = 0; j < nslots[i]; j++) { - HangarSlot* s = &(squadrons[i][j]); - if (s->ship == test) { - squadron = i; - slot = j; - return true; - } - } - } - } - } - - return false; -} - - -bool -Hangar::FindAvailSlot(const ShipDesign* design, int& squadron, int& slot) -{ - if (design) { - for (int i = 0; i < nsquadrons; i++) { - if (nslots[i] > 0 && squadrons[i]->design == design) { - for (int j = 0; j < nslots[i]; j++) { - HangarSlot* s = &(squadrons[i][j]); - - if (s->state == STORAGE) { - squadron = i; - slot = j; - return true; - } - } - } - } - } - - return false; -} - -bool -Hangar::Ready(int squadron, int slot, FlightDeck* d) -{ - if (squadron < 0 || squadron >= nsquadrons || slot < 0 || slot >= nslots[squadron] || !d) - return false; - - HangarSlot* s = &(squadrons[squadron][slot]); - - s->time = 3; // 5; - s->deck = d; - s->slot = -1; // take first available slot - - if (d->Spot(s->ship, s->slot)) { - s->state = ALERT; - s->alert_hold = false; - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -Text -Hangar::SquadronName(int n) const -{ - if (n >= 0 && n < nsquadrons) - return names[n]; - - return ContentBundle::GetInstance()->GetText("Unknown"); -} - -int -Hangar::SquadronSize(int n) const -{ - if (n >= 0 && n < nsquadrons) - return nslots[n]; - - return 0; -} - -int -Hangar::SquadronIFF(int n) const -{ - if (n >= 0 && n < nsquadrons) - return squadrons[n]->iff; - - return 0; -} - -const ShipDesign* -Hangar::SquadronDesign(int n) const -{ - if (n >= 0 && n < nsquadrons && nslots[n]) - return squadrons[n]->design; - - return 0; -} - -const HangarSlot* -Hangar::GetSlot(int i, int j) const -{ - if (i >= 0 && i < nsquadrons) - if (j >= 0 && j < nslots[i]) - return squadrons[i] + j; - - return 0; -} - -// +--------------------------------------------------------------------+ - -Ship* -Hangar::GetShip(const HangarSlot* s) const -{ - if (s) return s->ship; - return 0; -} - -const ShipDesign* -Hangar::GetDesign(const HangarSlot* s) const -{ - if (s) return s->design; - return 0; -} - -FlightDeck* -Hangar::GetFlightDeck(const HangarSlot* s) const -{ - if (s) return s->deck; - return 0; -} - -int -Hangar::GetFlightDeckSlot(const HangarSlot* s) const -{ - if (s) return s->slot; - return 0; -} - -int -Hangar::GetState(const HangarSlot* s) const -{ - if (s) return s->state; - return 0; -} - -double -Hangar::TimeRemaining(const HangarSlot* s) const -{ - if (s) return s->time; - return 0; -} - -Element* -Hangar::GetPackageElement(const HangarSlot* s) const -{ - if (s) return s->package; - return 0; -} - -const int* -Hangar::GetLoadout(const HangarSlot* s) const -{ - if (s) return s->loadout; - return 0; -} - -Text -Hangar::StatusName(const HangarSlot* s) const -{ - switch (s->state) { - default: - case UNAVAIL: return ContentBundle::GetInstance()->GetText("hangar.UNAVAIL"); - case MAINT: return ContentBundle::GetInstance()->GetText("hangar.MAINT"); - case STORAGE: return ContentBundle::GetInstance()->GetText("hangar.STORAGE"); - case PREP: return ContentBundle::GetInstance()->GetText("hangar.PREP"); - case ALERT: return ContentBundle::GetInstance()->GetText("hangar.ALERT"); - case QUEUED: { - Text state = ContentBundle::GetInstance()->GetText("hangar.QUEUED"); - char seq[8]; - sprintf_s(seq, " %d", s->deck->Sequence(s->slot)); - return state + seq; - } - case LOCKED: return ContentBundle::GetInstance()->GetText("hangar.LOCKED"); - case LAUNCH: return ContentBundle::GetInstance()->GetText("hangar.LAUNCH"); - case ACTIVE: return ContentBundle::GetInstance()->GetText("hangar.ACTIVE"); - case APPROACH: return ContentBundle::GetInstance()->GetText("hangar.APPROACH"); - case RECOVERY: return ContentBundle::GetInstance()->GetText("hangar.RECOVERY"); - } -} - -// +--------------------------------------------------------------------+ - -int -Hangar::PreflightQueue(FlightDeck* d) const -{ - int result = 0; - - for (int n = 0; n < nsquadrons; n++) { - if (squadrons[n] && nslots[n] > 0) { - for (int i = 0; i < nslots[n]; i++) { - HangarSlot* slot = &squadrons[n][i]; - - if (slot->deck == d) - result++; - } - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -int -Hangar::NumShipsReady(int n) const -{ - int result = 0; - - if (n >= 0 && n < nsquadrons && squadrons[n] && nslots[n] > 0) { - for (int i = 0; i < nslots[n]; i++) { - HangarSlot* slot = &squadrons[n][i]; - - if (slot->state == STORAGE) - result++; - } - } - - return result; -} - -int -Hangar::NumShipsMaint(int n) const -{ - int result = 0; - - if (n >= 0 && n < nsquadrons && squadrons[n] && nslots[n] > 0) { - for (int i = 0; i < nslots[n]; i++) { - HangarSlot* slot = &squadrons[n][i]; - - if (slot->state == MAINT) - result++; - } - } - - return result; -} - -int -Hangar::NumShipsDead(int n) const -{ - int result = 0; - - if (n >= 0 && n < nsquadrons && squadrons[n] && nslots[n] > 0) { - for (int i = 0; i < nslots[n]; i++) { - HangarSlot* slot = &squadrons[n][i]; - - if (slot->state == UNAVAIL) - result++; - } - } - - return result; -} - -int -Hangar::NumSlotsEmpty() const -{ - int result = 0; - - for (int n = 0; n < nsquadrons; n++) { - if (squadrons[n] && nslots[n] > 0) { - for (int i = 0; i < nslots[n]; i++) { - HangarSlot* slot = &squadrons[n][i]; - - if (slot->state == UNAVAIL) - result++; - } - } - } - - return result; -} - -int -Hangar::GetActiveElements(List& active_list) -{ - active_list.clear(); - - for (int n = 0; n < nsquadrons; n++) { - if (squadrons[n] && nslots[n] > 0) { - for (int i = 0; i < nslots[n]; i++) { - HangarSlot* slot = &squadrons[n][i]; - - if (slot->package != 0 && !active_list.contains(slot->package)) - active_list.append(slot->package); - } - } - } - - return active_list.size(); -} - -// +--------------------------------------------------------------------+ - -DWORD -Hangar::GetLastPatrolLaunch() const -{ - return last_patrol_launch; -} - -void -Hangar::SetLastPatrolLaunch(DWORD t) -{ - last_patrol_launch = t; -} - -// +--------------------------------------------------------------------+ - -void -Hangar::SetAllIFF(int iff) -{ - for (int n = 0; n < nsquadrons; n++) { - if (squadrons[n] && nslots[n] > 0) { - for (int i = 0; i < nslots[n]; i++) { - HangarSlot* slot = &squadrons[n][i]; - - if (slot->ship) - slot->ship->SetIFF(iff); - } - } - } -} diff --git a/Stars45/Hangar.h b/Stars45/Hangar.h deleted file mode 100644 index 41f7892..0000000 --- a/Stars45/Hangar.h +++ /dev/null @@ -1,126 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Everything needed to store and maintain space craft - - See Also: FlightDeck -*/ - -#ifndef Hangar_h -#define Hangar_h - -#include "Types.h" -#include "Geometry.h" -#include "SimObject.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class ShipDesign; -class FlightDeck; -class FlightDeckSlot; -class Element; -class HangarSlot; -class InboundSlot; -class CombatGroup; - -// +--------------------------------------------------------------------+ - -class Hangar : public SimObserver -{ -public: - Hangar(); - Hangar(const Hangar& rhs); - virtual ~Hangar(); - - enum HANGAR_STATE { UNAVAIL = -2, - MAINT = -1, - STORAGE = 0, - PREP, - ALERT, - QUEUED, - LOCKED, - LAUNCH, - ACTIVE, - APPROACH, - RECOVERY - }; - - enum CONSTANTS { MAX_SQUADRONS=10 }; - - virtual void ExecFrame(double seconds); - void SetShip(Ship* s) { ship = s; } - - virtual bool CreateSquadron(Text squadron, CombatGroup* g, - const ShipDesign* design, int count, int iff=-1, - int* def_load=0, int maint_count=0, int dead_count=0); - - // used only by net client to expedite creation of already active ships: - virtual bool GotoActiveFlight(int squadron, int slot, Element* elem, int* loadout); - - virtual bool GotoAlert(int squadron, int slot, FlightDeck* d, Element* elem=0, int* loadout=0, bool pkg=false, bool expedite=false); - virtual bool Ready(int squadron, int slot, FlightDeck* d); - virtual bool Launch(int squadron, int slot); - virtual bool StandDown(int squadron, int slot); - virtual bool CanStow(Ship* s); - virtual bool Stow(Ship* s); - virtual bool FindSlot(Ship* s, int& squadron, int& slot, int state=UNAVAIL); - virtual bool FindSquadronAndSlot(Ship* s, int& squadron, int& slot); - virtual bool FindAvailSlot(const ShipDesign* s, int& squadron, int& slot); - virtual bool FinishPrep(HangarSlot* slot); - virtual void SetAllIFF(int iff); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - // accessors: - int NumSquadrons() const { return nsquadrons; } - Text SquadronName(int n) const; - int SquadronSize(int n) const; - int SquadronIFF(int n) const; - const ShipDesign* SquadronDesign(int n) const; - - int NumShipsReady(int squadron) const; - int NumShipsMaint(int squadron) const; - int NumShipsDead(int squadron) const; - int NumSlotsEmpty() const; - - int GetActiveElements(List& active_list); - - const HangarSlot* GetSlot(int squadron, int index) const; - Ship* GetShip(const HangarSlot* s) const; - const ShipDesign* GetDesign(const HangarSlot* s) const; - FlightDeck* GetFlightDeck(const HangarSlot* s) const; - int GetFlightDeckSlot(const HangarSlot* s) const; - int GetState(const HangarSlot* s) const; - double TimeRemaining(const HangarSlot* s) const; - Element* GetPackageElement(const HangarSlot* s) const; - const int* GetLoadout(const HangarSlot* s) const; - Text StatusName(const HangarSlot* s) const; - - int PreflightQueue(FlightDeck* d) const; - DWORD GetLastPatrolLaunch() const; - void SetLastPatrolLaunch(DWORD t); - -protected: - Ship* ship; - int nsquadrons; - int nslots[MAX_SQUADRONS]; - Text names[MAX_SQUADRONS]; - HangarSlot* squadrons[MAX_SQUADRONS]; - DWORD last_patrol_launch; -}; - -// +--------------------------------------------------------------------+ - - -#endif // Hangar_h - diff --git a/Stars45/HardPoint.cpp b/Stars45/HardPoint.cpp deleted file mode 100644 index 2fa15f0..0000000 --- a/Stars45/HardPoint.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - HardPoint class -*/ - -#include "HardPoint.h" -#include "Weapon.h" -#include "WeaponDesign.h" -#include "Shot.h" -#include "Ship.h" -#include "Sim.h" - -// +----------------------------------------------------------------------+ - -HardPoint::HardPoint(Vec3 muzzle_loc, double az, double el) -: aim_azimuth((float) az), aim_elevation((float) el), muzzle(muzzle_loc) -{ - ZeroMemory(designs, sizeof(designs)); -} - -// +----------------------------------------------------------------------+ - -HardPoint::HardPoint(const HardPoint& h) -: aim_azimuth(h.aim_azimuth), aim_elevation(h.aim_elevation), muzzle(h.muzzle), -mount_rel(h.mount_rel), radius(h.radius), hull_factor(h.hull_factor) -{ - CopyMemory(designs, h.designs, sizeof(designs)); -} - -// +--------------------------------------------------------------------+ - -HardPoint::~HardPoint() -{ -} - -// +--------------------------------------------------------------------+ - -void -HardPoint::Mount(Point loc, float rad, float hull) -{ - mount_rel = loc; - radius = rad; - hull_factor = hull; -} - -// +--------------------------------------------------------------------+ - -void -HardPoint::AddDesign(WeaponDesign* d) -{ - for (int i = 0; i < MAX_DESIGNS; i++) { - if (!designs[i]) { - designs[i] = d; - return; - } - } -} - -// +--------------------------------------------------------------------+ - -Weapon* -HardPoint::CreateWeapon(int type_index) -{ - if (type_index >= 0 && type_index < MAX_DESIGNS && designs[type_index]) { - Vec3 zero_pt = Vec3(0.0f, 0.0f, 0.0f); - Vec3* muzzle_pt = &zero_pt; - - if (designs[type_index]->turret.length() == 0) - muzzle_pt = &muzzle; - - Weapon* missile = new Weapon(designs[type_index], - 1, - muzzle_pt, - aim_azimuth, - aim_elevation); - missile->SetAbbreviation(GetAbbreviation()); - missile->Mount(mount_rel, radius, hull_factor); - return missile; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -double -HardPoint::GetCarryMass(int type_index) -{ - if (type_index >= 0 && type_index < MAX_DESIGNS && designs[type_index]) - return designs[type_index]->carry_mass; - - return 0; -} - diff --git a/Stars45/HardPoint.h b/Stars45/HardPoint.h deleted file mode 100644 index 3fbeda4..0000000 --- a/Stars45/HardPoint.h +++ /dev/null @@ -1,81 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Hard Point (gun or missile launcher) class -*/ - -#ifndef HardPoint_h -#define HardPoint_h - -#include "Types.h" -#include "Geometry.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Weapon; -class WeaponDesign; - -// +--------------------------------------------------------------------+ - -class HardPoint -{ -public: - static const char* TYPENAME() { return "HardPoint"; } - - enum CONSTANTS { MAX_DESIGNS=8 }; - - HardPoint(Vec3 muzzle, double az=0, double el=0); - HardPoint(const HardPoint& rhs); - virtual ~HardPoint(); - - int operator==(const HardPoint& w) const { return this == &w; } - - virtual void AddDesign(WeaponDesign* dsn); - virtual Weapon* CreateWeapon(int type_index=0); - virtual double GetCarryMass(int type_index=0); - WeaponDesign* GetWeaponDesign(int n) { return designs[n]; } - - virtual void Mount(Point loc, float rad, float hull=0.5f); - Point MountLocation() const { return mount_rel; } - double Radius() const { return radius; } - double HullProtection() const { return hull_factor; } - - virtual const char* GetName() const { return name; } - virtual void SetName(const char* s) { name = s; } - virtual const char* GetAbbreviation() const { return abrv; } - virtual void SetAbbreviation(const char* s) { abrv = s; } - virtual const char* GetDesign() const { return sys_dsn; } - virtual void SetDesign(const char* s) { sys_dsn = s; } - - virtual double GetAzimuth() const { return aim_azimuth; } - virtual void SetAzimuth(double a) { aim_azimuth = (float) a; } - virtual double GetElevation() const { return aim_elevation; } - virtual void SetElevation(double e) { aim_elevation = (float) e; } - -protected: - // Displayable name: - Text name; - Text abrv; - Text sys_dsn; - - WeaponDesign* designs[MAX_DESIGNS]; - Vec3 muzzle; - float aim_azimuth; - float aim_elevation; - - // Mounting: - Point mount_rel; // object space - float radius; - float hull_factor; -}; - -#endif // HardPoint_h - diff --git a/Stars45/Hoop.cpp b/Stars45/Hoop.cpp deleted file mode 100644 index cfd2a65..0000000 --- a/Stars45/Hoop.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ILS Hoop (HUD display) class -*/ - -#include "Hoop.h" - -#include "Game.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Window.h" - -static Color ils_color; - -// +--------------------------------------------------------------------+ - -Hoop::Hoop() -: width(360), height(180), mtl(0) -{ - foreground = 1; - radius = (float) width; - - DataLoader* loader = DataLoader::GetLoader(); - - loader->SetDataPath("HUD/"); - loader->LoadTexture("ILS.pcx", hoop_texture, Bitmap::BMP_TRANSLUCENT); - loader->SetDataPath(0); - - CreatePolys(); -} - -Hoop::~Hoop() -{ } - -// +--------------------------------------------------------------------+ - -void Hoop::SetColor(Color c) -{ - ils_color = c; -} - -// +--------------------------------------------------------------------+ - -void -Hoop::CreatePolys() -{ - Material* mtl = new Material; - - mtl->tex_diffuse = hoop_texture; - mtl->blend = Material::MTL_ADDITIVE; - - int w = width /2; - int h = height/2; - - model = new Model; - own_model = 1; - - Surface* surface = new Surface; - - surface->SetName("hoop"); - surface->CreateVerts(4); - surface->CreatePolys(2); - - VertexSet* vset = surface->GetVertexSet(); - Poly* polys = surface->GetPolys(); - - ZeroMemory(polys, sizeof(Poly) * 2); - - for (int i = 0; i < 4; i++) { - int x = w; - int y = h; - float u = 0; - float v = 0; - - if (i == 0 || i == 3) - x = -x; - else - u = 1; - - if (i < 2) - y = -y; - else - v = 1; - - vset->loc[i] = Vec3(x, y, 0); - vset->nrm[i] = Vec3(0, 0, 0); - - vset->tu[i] = u; - vset->tv[i] = v; - } - - for (int i = 0; i < 2; i++) { - Poly& poly = polys[i]; - - poly.nverts = 4; - poly.vertex_set = vset; - poly.material = mtl; - - poly.verts[0] = i ? 3 : 0; - poly.verts[1] = i ? 2 : 1; - poly.verts[2] = i ? 1 : 2; - poly.verts[3] = i ? 0 : 3; - - poly.plane = Plane(vset->loc[poly.verts[0]], - vset->loc[poly.verts[2]], - vset->loc[poly.verts[1]]); - - surface->AddIndices(6); - } - - // then assign them to cohesive segments: - Segment* segment = new Segment; - segment->npolys = 2; - segment->polys = &polys[0]; - segment->material = segment->polys->material; - - surface->GetSegments().append(segment); - - model->AddSurface(surface); - - - SetLuminous(true); -} - -// +--------------------------------------------------------------------+ - -void -Hoop::Update() -{ - if (mtl) - mtl->Ke = ils_color; - - if (model && luminous) { - ListIter s_iter = model->GetSurfaces(); - while (++s_iter) { - Surface* surface = s_iter.value(); - VertexSet* vset = surface->GetVertexSet(); - - for (int i = 0; i < vset->nverts; i++) { - vset->diffuse[i] = ils_color.Value(); - } - } - - InvalidateSurfaceData(); - } -} diff --git a/Stars45/Hoop.h b/Stars45/Hoop.h deleted file mode 100644 index 9577b29..0000000 --- a/Stars45/Hoop.h +++ /dev/null @@ -1,44 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ILS Hoop (HUD display) class -*/ - -#ifndef Hoop_h -#define Hoop_h - -#include "Types.h" -#include "Solid.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Hoop : public Solid -{ -public: - Hoop(); - virtual ~Hoop(); - - virtual void Update(); - static void SetColor(Color c); - -protected: - virtual void CreatePolys(); - - Bitmap* hoop_texture; - Material* mtl; - int width; - int height; -}; - -// +--------------------------------------------------------------------+ - -#endif // Hoop_h - diff --git a/Stars45/IA3D.H b/Stars45/IA3D.H deleted file mode 100644 index 9e4e319..0000000 --- a/Stars45/IA3D.H +++ /dev/null @@ -1,128 +0,0 @@ -/*--------------------------------------------------------------------- -* -* ia3d.h -* -*--------------------------------------------------------------------- -* -* $Id: ia3d.h%v 1.1 1996/09/02 10:50:35 mike Exp mike $ -* -*--------------------------------------------------------------------- -* -* ia3d header file. It's the part the outside world needs to see. -* -*--------------------------------------------------------------------- -* -* AUREAL SEMICONDUCTOR, INC. PROPRIETARY AND CONFIDENTIAL -* Copyright (c) 1996 Aureal Semiconductor, Inc. - All rights -* reserved. -* -*--------------------------------------------------------------------- -*/ - - -#ifndef _IA3D_H_ -#define _IA3D_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - - // A3d Class ID! {D8F1EEE0-F634-11cf-8700-00A0245D918B} - DEFINE_GUID(CLSID_A3d, - 0xd8f1eee0, 0xf634, 0x11cf, 0x87, 0x0, 0x0, 0xa0, 0x24, 0x5d, 0x91, 0x8b); - - // A3d Interface ID! {D8F1EEE1-F634-11cf-8700-00A0245D918B} - DEFINE_GUID(IID_IA3d, - 0xd8f1eee1, 0xf634, 0x11cf, 0x87, 0x0, 0x0, 0xa0, 0x24, 0x5d, 0x91, 0x8b); - - - // Bits for manipulating output modes - - // Values for bOutputMode -#define OUTPUT_MODE_STEREO 0x00000001 -#define OUTPUT_MODE_QUAD 0x00000002 - - // Values for FrontXtalkMode and bRearXtalkMode -#define OUTPUT_HEADPHONES 0x00000001 // headphones -#define OUTPUT_SPEAKERS_WIDE 0x00000002 -#define OUTPUT_SPEAKERS_NARROW 0x00000003 - - // Values for Resource Management Mode -#define A3D_RESOURCE_MODE_OFF 0x00000000 -#define A3D_RESOURCE_MODE_NOTIFY 0x00000001 -#define A3D_RESOURCE_MODE_DYNAMIC 0x00000002 - - // Declare the IA3d Interface. It's not very complex at all. - -#undef INTERFACE -#define INTERFACE IA3d - - typedef struct IA3d *LPIA3D; - - DECLARE_INTERFACE_(IA3d, IUnknown) - { - // IUnknown - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - - // IA3d - STDMETHOD(SetOutputMode)(THIS_ DWORD dwFrontXtalkMode, DWORD dwBackXtalkMode, DWORD dwQuadMode) PURE; - STDMETHOD(GetOutputMode)(THIS_ DWORD *lpdwFrontXtalkMode, DWORD *lpdwBackXtalkMode, DWORD *lpdwQuadMode) PURE; - - STDMETHOD(SetResourceManagerMode) (THIS_ DWORD ) PURE; - STDMETHOD(GetResourceManagerMode) (THIS_ DWORD *) PURE; - - STDMETHOD(SetHFAbsorbFactor)(THIS_ FLOAT ) PURE; - STDMETHOD(GetHFAbsorbFactor)(THIS_ FLOAT *) PURE; - - }; - - - - - // The library function that gets things going. It returns an interface - // pointer to DirectSound. - -#define A3D_OK 1 // A3dCreate returns this upon detection of A3D enabled hardware. - - _declspec (dllexport) HRESULT WINAPI - A3dCreate(GUID * lpGUID, LPDIRECTSOUND * ppDS, IUnknown FAR *pUnkOuter ); - - // Usefull Macros for C folks. - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IA3d_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IA3d_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IA3d_Release(p) (p)->lpVtbl->Release(p) -#define IA3d_SetOutputMode(p,a,b,c) (p)->lpVtbl->SetOutputMode(p,a,b,c) -#define IA3d_GetOutputMode(p,a,b,c) (p)->lpVtbl->GetOutputMode(p,a,b,c) -#define IA3d_SetResourceManagerMode(p,a) (p)->lpVtbl->SetResourceManagerMode(p,a) -#define IA3d_GetResourceManagerMode(p,a) (p)->lpVtbl->GetResourceManagerMode(p,a) -#define IA3d_SetHFAbsorbFactor(p,a) (p)->lpVtbl->SetHFAbsorbFactor(p,a) -#define IA3d_GetHFAbsorbFactor(p,a) (p)->lpVtbl->GetHFAbsorbFactor(p,a) - - -#else -#define IA3d_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IA3d_AddRef(p) (p)->AddRef() -#define IA3d_Release(p) (p)->Release() -#define IA3d_SetOutputMode(p,a,b,c) (p)->SetOutputMode(a,b,c) -#define IA3d_GetOutputMode(p,a,b,c) (p)->GetOutputMode(a,b,c) -#define IA3d_SetResourceManagerMode(p,a) (p)->SetResourceManagerMode(a) -#define IA3d_GetResourceManagerMode(p,a) (p)->GetResourceManagerMode(a) -#define IA3d_SetHFAbsorbFactor(p,a) (p)->SetHFAbsorbFactor(a) -#define IA3d_GetHFAbsorbFactor(p,a) (p)->GetHFAbsorbFactor(a) - -#endif - - - -#ifdef __cplusplus -}; -#endif - - - -#endif // _IA3D_H_ diff --git a/Stars45/ImageBox.cpp b/Stars45/ImageBox.cpp deleted file mode 100644 index 0821ee1..0000000 --- a/Stars45/ImageBox.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ImageBox class -*/ - -#include "ImageBox.h" -#include "Video.h" -#include "Bitmap.h" -#include "Font.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -ImageBox::ImageBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid) -: ActiveWindow(p->GetScreen(), ax, ay, aw, ah, aid, 0, p), blend_mode(Video::BLEND_ALPHA) -{ - picture_loc = 1; - text_align = DT_CENTER; - - char buf[32]; - sprintf_s(buf, "ImageBox %d", id); //-V576 - desc = buf; -} - -ImageBox::ImageBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid) -: ActiveWindow(s, ax, ay, aw, ah, aid, 0, 0), blend_mode(Video::BLEND_ALPHA) -{ - picture_loc = 1; - text_align = DT_CENTER; - - char buf[32]; - sprintf_s(buf, "ImageBox %d", id); //-V576 - desc = buf; -} - -// +--------------------------------------------------------------------+ - -ImageBox::~ImageBox() -{ } - -// +--------------------------------------------------------------------+ - -void -ImageBox::Draw() -{ - if (!shown) - return; - - int x = 0; - int y = 0; - int w = rect.w; - int h = rect.h; - int img_w = picture.Width(); - int img_h = picture.Height(); - - Rect box_rect(x,y,w,h); - - // draw the picture (if any) - if (picture.Width()) { - Rect irect = CalcPictureRect(); - DrawBitmap(irect.x, - irect.y, - irect.x + irect.w, - irect.y + irect.h, - &picture, - blend_mode); - } - - // draw the border: - DrawStyleRect(0, 0, w, h, style); - - // draw text here: - if (font && text.length()) { - int border_size = 4; - - if (style & WIN_RAISED_FRAME && style & WIN_SUNK_FRAME) - border_size = 8; - - Rect label_rect = CalcLabelRect(img_w,img_h); - int vert_space = label_rect.h; - int horz_space = label_rect.w; - - DrawText(text.data(), 0, label_rect, DT_CALCRECT | DT_WORDBREAK | DT_CENTER); - vert_space = (vert_space - label_rect.h)/2; - - label_rect.w = horz_space; - - if (vert_space > 0) - label_rect.y += vert_space; - - Color fore = ShadeColor(fore_color, 1); - font->SetColor(fore); - DrawText(text.data(), 0, label_rect, DT_WORDBREAK | DT_CENTER); - } -} - -void -ImageBox::DrawTabbedText() -{ - if (!shown) - return; - - int x = 0; - int y = 0; - int w = rect.w; - int h = rect.h; - int img_w = picture.Width(); - int img_h = picture.Height(); - - Rect box_rect(x,y,w,h); - - // draw the picture (if any) - if (picture.Width()) { - Rect irect = CalcPictureRect(); - DrawBitmap(irect.x, - irect.y, - irect.x + irect.w, - irect.y + irect.h, - &picture, - Video::BLEND_ALPHA); - } - - ActiveWindow::DrawTabbedText(); -} - -Rect ImageBox::CalcLabelRect(int img_w, int img_h) -{ - // fit the text in the bevel: - Rect label_rect; - label_rect.x = 0; - label_rect.y = 0; - label_rect.w = rect.w; - label_rect.h = rect.h; - - label_rect.Deflate(2,2); - - // and around the picture, if any: - if (img_h != 0) { - switch (picture_loc) { - default: - case 0: // the four corner positions - case 2: // and the center position - case 4: // don't affect the text position - case 6: - case 8: - break; - - case 1: // north - label_rect.y += img_h; - label_rect.h -= img_h; - break; - - case 3: // west - label_rect.x += img_w; - label_rect.w -= img_w; - break; - - case 5: // east - label_rect.w -= img_w; - break; - - case 7: // south - label_rect.h -= img_h; - break; - } - } - - return label_rect; -} - -// +--------------------------------------------------------------------+ - -Rect -ImageBox::CalcPictureRect() -{ - if (target_rect.w > 0 && target_rect.h > 0) - return target_rect; - - int w = rect.w; - int h = rect.h; - int img_w = picture.Width(); - int img_h = picture.Height(); - - if (img_h > h) img_h = h-2; - if (img_w > w) img_w = w-2; - - int img_x_offset = 0; - int img_y_offset = 0; - - switch (picture_loc) { - default: - // TOP ROW: - case 0: break; - - case 1: img_x_offset = (w/2-img_w/2); - break; - - case 2: img_x_offset = w - img_w; - break; - - // MIDDLE ROW: - case 3: img_y_offset = (h/2-img_h/2); - break; - case 4: img_x_offset = (w/2-img_w/2); - img_y_offset = (h/2-img_h/2); - break; - case 5: img_x_offset = w - img_w; - img_y_offset = (h/2-img_h/2); - break; - - // BOTTOM ROW: - case 6: - img_y_offset = h - img_h; - break; - case 7: img_x_offset = (w/2-img_w/2); - img_y_offset = h - img_h; - break; - case 8: img_x_offset = w - img_w; - img_y_offset = h - img_h; - break; - } - - Rect img_rect; - img_rect.x = img_x_offset; - img_rect.y = img_y_offset; - img_rect.w = img_w; - img_rect.h = img_h; - - return img_rect; -} - -// +--------------------------------------------------------------------+ - -int ImageBox::OnMouseMove(int x, int y) -{ - return ActiveWindow::OnMouseMove(x,y); -} - -int ImageBox::OnLButtonDown(int x, int y) -{ - return ActiveWindow::OnLButtonDown(x,y); -} - -int ImageBox::OnLButtonUp(int x, int y) -{ - return ActiveWindow::OnLButtonUp(x,y); -} - -int ImageBox::OnClick() -{ - return ActiveWindow::OnClick(); -} - -int ImageBox::OnMouseEnter(int mx, int my) -{ - return ActiveWindow::OnMouseEnter(mx, my); -} - -int ImageBox::OnMouseExit(int mx, int my) -{ - return ActiveWindow::OnMouseExit(mx, my); -} - -// +--------------------------------------------------------------------+ - -void ImageBox::GetPicture(Bitmap& img) const -{ - img.CopyBitmap(picture); -} - -void ImageBox::SetPicture(const Bitmap& img) -{ - picture.CopyBitmap(img); - picture.AutoMask(); - picture.MakeTexture(); -} - -int ImageBox::GetPictureLocation() const -{ - return picture_loc; -} - -void ImageBox::SetPictureLocation(int n) -{ - if (picture_loc != n && n >= 0 && n <= 8) { - picture_loc = n; - } -} diff --git a/Stars45/ImageBox.h b/Stars45/ImageBox.h deleted file mode 100644 index 24e2e53..0000000 --- a/Stars45/ImageBox.h +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ImageBox class -*/ - -#ifndef ImageBox_h -#define ImageBox_h - -#include "Types.h" -#include "ActiveWindow.h" -#include "Bitmap.h" - -// +--------------------------------------------------------------------+ - -class ImageBox : public ActiveWindow -{ -public: - ImageBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD id=0); - ImageBox(Screen* s, int ax, int ay, int aw, int ah, DWORD id=0); - virtual ~ImageBox(); - - // Operations: - virtual void Draw(); - - // Event Target Interface: - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnClick(); - virtual int OnMouseEnter(int x, int y); - virtual int OnMouseExit(int x, int y); - - // Property accessors: - int GetBlendMode() const { return blend_mode; } - void SetBlendMode(int blend) { blend_mode = blend; } - bool GetBorder() const { return border; } - void SetBorder(bool bNewValue) { border = bNewValue; } - Color GetBorderColor() const { return border_color; } - void SetBorderColor(Color c) { border_color = c; } - void GetPicture(Bitmap& img) const; - void SetPicture(const Bitmap& img); - int GetPictureLocation() const; - void SetPictureLocation(int nNewValue); - Rect GetTargetRect() const { return target_rect; } - void SetTargetRect(const Rect& r) { target_rect = r; } - -protected: - virtual void DrawTabbedText(); - - Rect CalcLabelRect(int img_w, int img_h); - Rect CalcPictureRect(); - - bool border; - Color border_color; - Bitmap picture; - int picture_loc; - int blend_mode; - Rect target_rect; -}; - -#endif // ImageBox_h - diff --git a/Stars45/ImgView.cpp b/Stars45/ImgView.cpp deleted file mode 100644 index e2c8bba..0000000 --- a/Stars45/ImgView.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Bitmap "billboard" Image View class -*/ - -#include "ImgView.h" -#include "Color.h" -#include "Window.h" -#include "Video.h" -#include "Bitmap.h" -#include "Screen.h" - -// +--------------------------------------------------------------------+ - -ImgView::ImgView(Window* c, Bitmap* bmp) -: View(c), img(bmp), width(0), height(0), x_offset(0), y_offset(0), -blend(Video::BLEND_SOLID) -{ - if (img) { - width = img->Width(); - height = img->Height(); - } - - if (width < c->Width()) - x_offset = (c->Width() - width) / 2; - - if (height < c->Height()) - y_offset = (c->Height() - height) / 2; -} - -ImgView::~ImgView() -{ -} - -// +--------------------------------------------------------------------+ - -void -ImgView::Refresh() -{ - if (img && width > 0 && height > 0) - window->DrawBitmap(x_offset, - y_offset, - x_offset + width, - y_offset + height, - img, - blend); -} - -// +--------------------------------------------------------------------+ - -void -ImgView::SetPicture(Bitmap* bmp) -{ - img = bmp; - width = 0; - height = 0; - x_offset = 0; - y_offset = 0; - - if (img) { - width = img->Width(); - height = img->Height(); - } - - if (window) { - x_offset = (window->Width() - width) / 2; - y_offset = (window->Height() - height) / 2; - } -} diff --git a/Stars45/ImgView.h b/Stars45/ImgView.h deleted file mode 100644 index d000abf..0000000 --- a/Stars45/ImgView.h +++ /dev/null @@ -1,50 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Bitmap "Billboard" View class -*/ - -#ifndef ImgView_h -#define ImgView_h - -#include "Types.h" -#include "View.h" - -// +--------------------------------------------------------------------+ - -class Bitmap; - -// +--------------------------------------------------------------------+ - -class ImgView : public View -{ -public: - static const char* TYPENAME() { return "ImgView"; } - - ImgView(Window* c, Bitmap* bmp); - virtual ~ImgView(); - - // Operations: - virtual void Refresh(); - - virtual Bitmap* GetPicture() const { return img; } - virtual void SetPicture(Bitmap* bmp); - virtual int GetBlend() const { return blend; } - virtual void SetBlend(int b) { blend = b; } - -protected: - Bitmap* img; - int x_offset, y_offset; - int width, height; - int blend; -}; - -#endif // ImgView_h - diff --git a/Stars45/Instruction.cpp b/Stars45/Instruction.cpp deleted file mode 100644 index 18ef168..0000000 --- a/Stars45/Instruction.cpp +++ /dev/null @@ -1,568 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Navigation Point class implementation -*/ - -#include "Instruction.h" -#include "Element.h" -#include "RadioMessage.h" -#include "Ship.h" -#include "Sim.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Text.h" - -// +----------------------------------------------------------------------+ - -Instruction::Instruction(int act, const char* tgt) -: region(0), action(act), formation(0), tgt_name(tgt), -status(PENDING), speed(0), target(0), emcon(0), wep_free(0), -priority(PRIMARY), farcast(0), hold_time(0) -{ } - -Instruction::Instruction(const char* rgn, Point loc, int act) -: region(0), action(act), formation(0), -status(PENDING), speed(0), target(0), emcon(0), wep_free(0), -priority(PRIMARY), farcast(0), hold_time(0) -{ - rgn_name = rgn; - rloc.SetBaseLocation(loc); - rloc.SetDistance(0); -} - -Instruction::Instruction(SimRegion* rgn, Point loc, int act) -: region(rgn), action(act), formation(0), -status(PENDING), speed(0), target(0), emcon(0), wep_free(0), -priority(PRIMARY), farcast(0), hold_time(0) -{ - rgn_name = region->Name(); - rloc.SetBaseLocation(loc); - rloc.SetDistance(0); -} - -Instruction::Instruction(const Instruction& instr) -: region(instr.region), rgn_name(instr.rgn_name), -rloc(instr.rloc), action(instr.action), -formation(instr.formation), status(instr.status), speed(instr.speed), -target(0), tgt_name(instr.tgt_name), tgt_desc(instr.tgt_desc), -emcon(instr.emcon), wep_free(instr.wep_free), -priority(instr.priority), farcast(instr.farcast), -hold_time(instr.hold_time) -{ - SetTarget(instr.target); -} - -Instruction::~Instruction() -{ } - -// +--------------------------------------------------------------------+ - -Instruction& -Instruction::operator = (const Instruction& n) -{ - rgn_name = n.rgn_name; - region = n.region; - rloc = n.rloc; - action = n.action; - formation = n.formation; - status = n.status; - speed = n.speed; - - tgt_name = n.tgt_name; - tgt_desc = n.tgt_desc; - target = 0; - emcon = n.emcon; - wep_free = n.wep_free; - priority = n.priority; - farcast = n.farcast; - hold_time = n.hold_time; - - SetTarget(n.target); - return *this; -} - -// +--------------------------------------------------------------------+ - -Point -Instruction::Location() const -{ - Instruction* pThis = (Instruction*) this; - return pThis->rloc.Location(); -} - -void -Instruction::SetLocation(const Point& l) -{ - rloc.SetBaseLocation(l); - rloc.SetReferenceLoc(0); - rloc.SetDistance(0); -} - -// +----------------------------------------------------------------------+ - -SimObject* -Instruction::GetTarget() -{ - if (!target && tgt_name.length() > 0) { - Sim* sim = Sim::GetSim(); - - if (sim) { - Ship* s = sim->FindShip(tgt_name, rgn_name); - - if (s) { - target = s; - Observe(target); - } - } - } - - return target; -} - -void -Instruction::SetTarget(const char* n) -{ - if (n && *n && tgt_name != n) { - tgt_name = n; - tgt_desc = n; - - if (target) - target = 0; - } -} - -void -Instruction::SetTarget(SimObject* s) -{ - if (s && target != s) { - tgt_name = s->Name(); - target = s; - Observe(target); - } -} - -void -Instruction::SetTargetDesc(const char* d) -{ - if (d && *d) - tgt_desc = d; -} - -void -Instruction::ClearTarget() -{ - if (target) { - target = 0; - tgt_name = ""; - tgt_desc = ""; - } -} - -// +----------------------------------------------------------------------+ - -bool -Instruction::Update(SimObject* obj) -{ - if (target == obj) - target = 0; - - return SimObserver::Update(obj); -} - -const char* -Instruction::GetObserverName() const -{ - return "Instruction"; -} - -// +----------------------------------------------------------------------+ - -void -Instruction::Evaluate(Ship* ship) -{ - Sim* sim = Sim::GetSim(); - - switch (action) { - case VECTOR: - break; - - case LAUNCH: - if (ship->GetFlightPhase() == Ship::ACTIVE) - SetStatus(COMPLETE); - break; - - case DOCK: - case RTB: - if (sim->GetPlayerShip() == ship && - (ship->GetFlightPhase() == Ship::DOCKING || - ship->GetFlightPhase() == Ship::DOCKED)) - SetStatus(COMPLETE); - else if (ship->Integrity() < 1) - SetStatus(FAILED); - break; - - case DEFEND: - case ESCORT: - { - bool found = false; - bool safe = true; - - ListIter iter = sim->GetElements(); - while (++iter && !found) { - Element* e = iter.value(); - - if (e->IsFinished() || e->IsSquadron()) - continue; - - if (e->Name() == tgt_name || - (e->GetCommander() && e->GetCommander()->Name() == tgt_name)) { - - found = true; - - for (int i = 0; i < e->NumShips(); i++) { - Ship* s = e->GetShip(i+1); - - if (s && s->Integrity() < 1) - SetStatus(FAILED); - } - - if (status == PENDING) { - // if the element had a flight plan, and all nav points - // have been addressed, then the element is safe - if (e->FlightPlanLength() > 0) { - if (e->GetNextNavPoint() == 0) - SetStatus(COMPLETE); - else - safe = false; - } - } - } - } - - if (status == PENDING && safe && - sim->GetPlayerShip() == ship && - (ship->GetFlightPhase() == Ship::DOCKING || - ship->GetFlightPhase() == Ship::DOCKED)) { - SetStatus(COMPLETE); - } - } - break; - - case PATROL: - case SWEEP: - { - Sim* sim = Sim::GetSim(); - bool alive = false; - - ListIter iter = sim->GetElements(); - while (++iter) { - Element* e = iter.value(); - - if (e->IsFinished() || e->IsSquadron()) - continue; - - if (e->GetIFF() && e->GetIFF() != ship->GetIFF()) { - for (int i = 0; i < e->NumShips(); i++) { - Ship* s = e->GetShip(i+1); - - if (s && s->Integrity() >= 1) - alive = true; - } - } - } - - if (status == PENDING && !alive) { - SetStatus(COMPLETE); - } - } - break; - - case INTERCEPT: - case STRIKE: - case ASSAULT: - { - Sim* sim = Sim::GetSim(); - bool alive = false; - - ListIter iter = sim->GetElements(); - while (++iter) { - Element* e = iter.value(); - - if (e->IsFinished() || e->IsSquadron()) - continue; - - if (e->Name() == tgt_name) { - for (int i = 0; i < e->NumShips(); i++) { - Ship* s = e->GetShip(i+1); - - if (s && s->Integrity() >= 1) - alive = true; - } - } - } - - if (status == PENDING && !alive) { - SetStatus(COMPLETE); - } - } - break; - - case RECON: - break; - - default: - break; - } -} - -void -Instruction::SetStatus(int s) -{ - status = s; -} - -// +----------------------------------------------------------------------+ - -const char* -Instruction::GetShortDescription() const -{ - static char desc[256]; - - switch (action) { - case VECTOR: - if (farcast) - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.farcast").data(), rgn_name.data()); - else - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.vector").data(), rgn_name.data()); - break; - - case LAUNCH: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.launch").data(), tgt_name.data()); - break; - - case DOCK: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.dock").data(), tgt_name.data()); - break; - - case RTB: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.return-to-base").data()); - break; - - case DEFEND: - if (priority == PRIMARY) { - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.defend").data(), ActionName(action), tgt_desc.data()); - } - else { - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.protect").data(), tgt_desc.data()); - } - break; - - case ESCORT: - if (priority == PRIMARY) { - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.escort").data(), ActionName(action), tgt_desc.data()); - } - else { - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.protect").data(), tgt_desc.data()); - } - break; - - case PATROL: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.patrol").data(), - tgt_desc.data(), - rgn_name.data()); - break; - - case SWEEP: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.sweep").data(), - tgt_desc.data(), - rgn_name.data()); - break; - - case INTERCEPT: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.intercept").data(), tgt_desc.data()); - break; - - case STRIKE: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.strike").data(), tgt_desc.data()); - break; - - case ASSAULT: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.assault").data(), tgt_desc.data()); - break; - - case RECON: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.short.recon").data(), tgt_desc.data()); - break; - - default: - sprintf_s(desc, "%s", ActionName(action)); - break; - } - - if (status != PENDING) { - strcat_s(desc, " - "); - strcat_s(desc, ContentBundle::GetInstance()->GetText(StatusName(status))); - } - - return desc; -} - -// +----------------------------------------------------------------------+ - -const char* -Instruction::GetDescription() const -{ - static char desc[1024]; - - switch (action) { - case VECTOR: - if (farcast) - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.farcast").data(), rgn_name.data()); - else - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.vector").data(), rgn_name.data()); - break; - - case LAUNCH: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.launch").data(), tgt_name.data()); - break; - - case DOCK: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.dock").data(), tgt_name.data()); - break; - - case RTB: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.return-to-base").data()); - break; - - case DEFEND: - if (priority == PRIMARY) { - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.defend").data(), ActionName(action), tgt_desc.data()); - } - else { - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.protect").data(), tgt_desc.data()); - } - break; - - case ESCORT: - if (priority == PRIMARY) { - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.escort").data(), ActionName(action), tgt_desc.data()); - } - else { - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.protect").data(), tgt_desc.data()); - } - break; - - case PATROL: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.patrol").data(), - tgt_desc.data(), - rgn_name.data()); - break; - - case SWEEP: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.sweep").data(), - tgt_desc.data(), - rgn_name.data()); - break; - - case INTERCEPT: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.intercept").data(), tgt_desc.data()); - break; - - case STRIKE: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.strike").data(), tgt_desc.data()); - break; - - case ASSAULT: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.assault").data(), tgt_desc.data()); - break; - - case RECON: - sprintf_s(desc, ContentBundle::GetInstance()->GetText("instr.long.recon").data(), tgt_desc.data()); - break; - - default: - sprintf_s(desc, "%s", ActionName(action)); - break; - } - - if (status != PENDING) { - strcat_s(desc, " - "); - strcat_s(desc, ContentBundle::GetInstance()->GetText(StatusName(status))); - } - - return desc; -} - -// +----------------------------------------------------------------------+ - -const char* -Instruction::ActionName(int a) -{ - switch (a) { - case VECTOR: return "Vector"; - case LAUNCH: return "Launch"; - case DOCK: return "Dock"; - case RTB: return "RTB"; - - case DEFEND: return "Defend"; - case ESCORT: return "Escort"; - case PATROL: return "Patrol"; - case SWEEP: return "Sweep"; - case INTERCEPT: return "Intercept"; - case STRIKE: return "Strike"; - case ASSAULT: return "Assault"; - case RECON: return "Recon"; - - default: return "Unknown"; - } -} - -const char* -Instruction::StatusName(int s) -{ - switch (s) { - case PENDING: return "Pending"; - case ACTIVE: return "Active"; - case SKIPPED: return "Skipped"; - case ABORTED: return "Aborted"; - case FAILED: return "Failed"; - case COMPLETE: return "Complete"; - - default: return "Unknown"; - } -} - -const char* -Instruction::FormationName(int f) -{ - switch (f) { - case DIAMOND: return "Diamond"; - case SPREAD: return "Spread"; - case BOX: return "Box"; - case TRAIL: return "Trail"; - - default: return "Unknown"; - } -} - -const char* -Instruction::PriorityName(int p) -{ - switch (p) { - case PRIMARY: return "Primary"; - case SECONDARY: return "Secondary"; - case BONUS: return "Bonus"; - - default: return "Unknown"; - } -} - diff --git a/Stars45/Instruction.h b/Stars45/Instruction.h deleted file mode 100644 index d1ca0eb..0000000 --- a/Stars45/Instruction.h +++ /dev/null @@ -1,165 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Instruction (NavPoint / Order / Objective) class declaration -*/ - -#ifndef Instruction_h -#define Instruction_h - -#include "Types.h" -#include "Geometry.h" -#include "SimObject.h" -#include "Text.h" -#include "RLoc.h" - -// +--------------------------------------------------------------------+ - -class Ship; - -// +--------------------------------------------------------------------+ - -class Instruction : public SimObserver -{ -public: - static const char* TYPENAME() { return "Instruction"; } - - enum ACTION - { - VECTOR, - LAUNCH, - DOCK, - RTB, - - DEFEND, - ESCORT, - PATROL, - SWEEP, - INTERCEPT, - STRIKE, // ground attack - ASSAULT, // starship attack - RECON, - - //RECALL, - //DEPLOY, - - NUM_ACTIONS - }; - - enum STATUS - { - PENDING, - ACTIVE, - SKIPPED, - ABORTED, - FAILED, - COMPLETE, - - NUM_STATUS - }; - - enum FORMATION - { - DIAMOND, - SPREAD, - BOX, - TRAIL, - - NUM_FORMATIONS - }; - - enum PRIORITY - { - PRIMARY = 1, - SECONDARY, - BONUS - }; - - Instruction(int action, const char* tgt); - Instruction(const char* rgn, Point loc, int act=VECTOR); - Instruction(SimRegion* rgn, Point loc, int act=VECTOR); - Instruction(const Instruction& instr); - virtual ~Instruction(); - - Instruction& operator = (const Instruction& n); - - // accessors: - static const char* ActionName(int a); - static const char* StatusName(int s); - static const char* FormationName(int f); - static const char* PriorityName(int p); - - const char* RegionName() const { return rgn_name; } - SimRegion* Region() const { return region; } - Point Location() const; - RLoc& GetRLoc() { return rloc; } - int Action() const { return action; } - int Status() const { return status; } - int Formation() const { return formation; } - int Speed() const { return speed; } - int EMCON() const { return emcon; } - int WeaponsFree() const { return wep_free; } - int Priority() const { return priority; } - int Farcast() const { return farcast; } - double HoldTime() const { return hold_time; } - - const char* TargetName() const { return tgt_name; } - const char* TargetDesc() const { return tgt_desc; } - SimObject* GetTarget(); - - void Evaluate(Ship* s); - const char* GetShortDescription() const; - const char* GetDescription() const; - - // mutators: - void SetRegion(SimRegion* r) { region = r; } - void SetLocation(const Point& l); - void SetAction(int s) { action = s; } - void SetStatus(int s); - void SetFormation(int s) { formation = s; } - void SetSpeed(int s) { speed = s; } - void SetEMCON(int e) { emcon = e; } - void SetWeaponsFree(int f) { wep_free = f; } - void SetPriority(int p) { priority = p; } - void SetFarcast(int f) { farcast = f; } - void SetHoldTime(double t) { hold_time = t; } - - void SetTarget(const char* n); - void SetTarget(SimObject* s); - void SetTargetDesc(const char* d); - void ClearTarget(); - - virtual bool Update(SimObject* s); - virtual const char* GetObserverName() const; - -protected: - Text rgn_name; - SimRegion* region; - RLoc rloc; - int action; - int formation; - int status; - int speed; - - Text tgt_name; - Text tgt_desc; - SimObject* target; - int emcon; - int wep_free; - int priority; - int farcast; - - double hold_time; -}; - -// +--------------------------------------------------------------------+ - -#endif // Instruction_h - diff --git a/Stars45/Intel.cpp b/Stars45/Intel.cpp deleted file mode 100644 index 51b1806..0000000 --- a/Stars45/Intel.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - An element in the dynamic campaign -*/ - -#include "Intel.h" - -#include "Game.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -static const char* intel_name[] = { - "", - "Reserve", - "Secret", - "Known", - "Located", - "Tracked", -}; - -const char* -Intel::NameFromIntel(int intel) -{ - return intel_name[intel]; -} - -int -Intel::IntelFromName(const char* type_name) -{ - for (int i = RESERVE; i <= TRACKED; i++) - if (!_stricmp(type_name, intel_name[i])) - return i; - - return 0; -} diff --git a/Stars45/Intel.h b/Stars45/Intel.h deleted file mode 100644 index 5ed1675..0000000 --- a/Stars45/Intel.h +++ /dev/null @@ -1,36 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#ifndef Intel_h -#define Intel_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class Intel -{ -public: - enum INTEL_TYPE { - RESERVE = 1, // out-system reserve: this group is not even here - SECRET, // enemy is completely unaware of this group - KNOWN, // enemy knows this group is in the system - LOCATED, // enemy has located at least the lead ship - TRACKED // enemy is tracking all elements - }; - - static int IntelFromName(const char* name); - static const char* NameFromIntel(int intel); -}; - -#endif // Intel_h - diff --git a/Stars45/JoyDlg.cpp b/Stars45/JoyDlg.cpp deleted file mode 100644 index b0ac318..0000000 --- a/Stars45/JoyDlg.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "JoyDlg.h" -#include "KeyMap.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "FormatUtil.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "ListBox.h" -#include "ComboBox.h" -#include "Button.h" -#include "Joystick.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(JoyDlg, OnApply); -DEF_MAP_CLIENT(JoyDlg, OnCancel); -DEF_MAP_CLIENT(JoyDlg, OnAxis); - -static const char* joy_axis_names[] = { - "JoyDlg.axis.0", - "JoyDlg.axis.1", - "JoyDlg.axis.2", - "JoyDlg.axis.3", - "JoyDlg.axis.4", - "JoyDlg.axis.5", - "JoyDlg.axis.6", - "JoyDlg.axis.7" -}; - -static int selected_axis = -1; -static int sample_axis = -1; -static int samples[8]; - -static int map_axis[4]; - -// +--------------------------------------------------------------------+ - -JoyDlg::JoyDlg(Screen* s, FormDef& def, BaseScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -apply(0), cancel(0), message(0) -{ - Init(def); -} - -JoyDlg::~JoyDlg() -{ -} - -void -JoyDlg::RegisterControls() -{ - if (apply) - return; - - for (int i = 0; i < 4; i++) { - axis_button[i] = (Button*) FindControl(201 + i); - invert_checkbox[i] = (Button*) FindControl(301 + i); - - if (axis_button[i]) - REGISTER_CLIENT(EID_CLICK, axis_button[i], JoyDlg, OnAxis); - } - - message = FindControl(11); - - apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, apply, JoyDlg, OnApply); - - cancel = (Button*) FindControl(2); - REGISTER_CLIENT(EID_CLICK, cancel, JoyDlg, OnCancel); -} - -// +--------------------------------------------------------------------+ - -void -JoyDlg::ExecFrame() -{ - if (selected_axis >= 0 && selected_axis < 4) { - Joystick* joystick = Joystick::GetInstance(); - if (joystick) { - joystick->Acquire(); - - int delta = 1000; - - for (int i = 0; i < 8; i++) { - int a = Joystick::ReadRawAxis(i + KEY_JOY_AXIS_X); - - int d = a - samples[i]; - if (d < 0) d = -d; - - if (d > delta && samples[i] < 1e6) { - delta = d; - sample_axis = i; - } - - samples[i] = a; - } - - Button* b = axis_button[selected_axis]; - - if (sample_axis >= 0) { - b->SetText(ContentBundle::GetInstance()->GetText(joy_axis_names[sample_axis])); - map_axis[selected_axis] = sample_axis; - } - - else - b->SetText(ContentBundle::GetInstance()->GetText("JoyDlg.select")); - } - } -} - -// +--------------------------------------------------------------------+ - -void -JoyDlg::Show() -{ - FormWindow::Show(); - - for (int i = 0; i < 4; i++) { - Button* b = axis_button[i]; - if (b) { - int map = Joystick::GetAxisMap(i) - KEY_JOY_AXIS_X; - int inv = Joystick::GetAxisInv(i); - - if (map >= 0 && map < 8) { - b->SetText(ContentBundle::GetInstance()->GetText(joy_axis_names[map])); - map_axis[i] = map; - } - else { - b->SetText(ContentBundle::GetInstance()->GetText("JoyDlg.unmapped")); - } - - b->SetButtonState(0); - - invert_checkbox[i]->SetButtonState(inv ? 1 : 0); - } - } - - SetFocus(); -} - -// +--------------------------------------------------------------------+ - -void -JoyDlg::OnAxis(AWEvent* event) -{ - for (int i = 0; i < 4; i++) { - int map = map_axis[i]; - Text name = ContentBundle::GetInstance()->GetText("JoyDlg.unmapped"); - Button* b = axis_button[i]; - - if (map >= 0 && map < 8) - name = ContentBundle::GetInstance()->GetText(joy_axis_names[map]); - - if (b) { - if (b == event->window) { - if (selected_axis == i) { - b->SetText(name); - b->SetButtonState(0); - selected_axis = -1; - } - else { - b->SetText(ContentBundle::GetInstance()->GetText("JoyDlg.select")); - b->SetButtonState(1); - selected_axis = i; - } - } - else { - b->SetText(name); - b->SetButtonState(0); - } - } - } - - for (int i = 0; i < 8; i++) { - samples[i] = 10000000; - } -} - -// +--------------------------------------------------------------------+ - -void -JoyDlg::OnApply(AWEvent* event) -{ - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - KeyMap& keymap = stars->GetKeyMap(); - - keymap.Bind(KEY_AXIS_YAW, map_axis[0]+KEY_JOY_AXIS_X, 0); - keymap.Bind(KEY_AXIS_PITCH, map_axis[1]+KEY_JOY_AXIS_X, 0); - keymap.Bind(KEY_AXIS_ROLL, map_axis[2]+KEY_JOY_AXIS_X, 0); - keymap.Bind(KEY_AXIS_THROTTLE, map_axis[3]+KEY_JOY_AXIS_X, 0); - - keymap.Bind(KEY_AXIS_YAW_INVERT, invert_checkbox[0]->GetButtonState(), 0); - keymap.Bind(KEY_AXIS_PITCH_INVERT, invert_checkbox[1]->GetButtonState(), 0); - keymap.Bind(KEY_AXIS_ROLL_INVERT, invert_checkbox[2]->GetButtonState(), 0); - keymap.Bind(KEY_AXIS_THROTTLE_INVERT, invert_checkbox[3]->GetButtonState(), 0); - - keymap.SaveKeyMap("key.cfg", 256); - - stars->MapKeys(); - } - - if (manager) - manager->ShowCtlDlg(); -} - -void -JoyDlg::OnCancel(AWEvent* event) -{ - if (manager) - manager->ShowCtlDlg(); -} - -// +--------------------------------------------------------------------+ diff --git a/Stars45/JoyDlg.h b/Stars45/JoyDlg.h deleted file mode 100644 index 83ceda9..0000000 --- a/Stars45/JoyDlg.h +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Navigation Active Window class -*/ - -#ifndef JoyDlg_h -#define JoyDlg_h - -#include "Types.h" -#include "FormWindow.h" - -// +--------------------------------------------------------------------+ - -class BaseScreen; - -// +--------------------------------------------------------------------+ - -class JoyDlg : public FormWindow -{ -public: - JoyDlg(Screen* s, FormDef& def, BaseScreen* mgr); - virtual ~JoyDlg(); - - virtual void RegisterControls(); - virtual void Show(); - - // Operations: - virtual void ExecFrame(); - - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - - virtual void OnAxis(AWEvent* event); - -protected: - BaseScreen* manager; - - ActiveWindow* message; - Button* axis_button[4]; - Button* invert_checkbox[4]; - - Button* apply; - Button* cancel; -}; - -#endif // JoyDlg_h - diff --git a/Stars45/Joystick.cpp b/Stars45/Joystick.cpp deleted file mode 100644 index 8b1a2ee..0000000 --- a/Stars45/Joystick.cpp +++ /dev/null @@ -1,914 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Joystick Input class -*/ - -#include "GameWinDX9.h" -#include "Joystick.h" -#include "MachineInfo.h" -#include "Types.h" - -#define DIRECTINPUT_VERSION 0x0800 - -#include - -#define JOY_POVUPRIGHT 4500 -#define JOY_POVDNRIGHT 13500 -#define JOY_POVDNLEFT 22500 -#define JOY_POVUPLEFT 31500 - -// +--------------------------------------------------------------------+ -// DIRECT INPUT SUPPORT - -const int MAX_DEVICES = 8; - -static LPDIRECTINPUT7 pdi = 0; -static LPDIRECTINPUTDEVICE7 pdev = 0; -static DIDEVICEINSTANCE devices[MAX_DEVICES]; -static int ndev = 0; -static int idev = -1; -static int strikes = 3; - -static Joystick* joystick = 0; - -void DirectInputError(const char* msg, HRESULT err); -const char* DIErrStr(HRESULT hr); -void ReleaseDirectInput(); - -// +--------------------------------------------------------------------+ - -Joystick::Joystick() -: x(0), y(0), z(0), p(0), r(0), w(0), t(0) -{ - if (!joystick) - joystick = this; - - select = 1; - rudder = 0; - throttle = 1; - sensitivity = 25; - dead_zone = 100; - - for (int i = 0; i < MotionController::MaxActions; i++) - action[i] = false; - - for (int i = 0; i < KEY_MAP_SIZE; i++) - map[i] = 0; - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - hat[i][j] = false; - } - } - - map_axis[0] = KEY_JOY_AXIS_X; - map_axis[1] = KEY_JOY_AXIS_Y; - map_axis[2] = KEY_JOY_AXIS_RZ; - map_axis[3] = KEY_JOY_AXIS_S0; - - inv_axis[0] = false; - inv_axis[1] = false; - inv_axis[2] = false; - inv_axis[3] = false; - - if (MachineInfo::GetDirectXVersion() < MachineInfo::DX_7) { - Print("Joystick: DI7 not found, using multimedia library\n"); - pdi = 0; - pdev = 0; - } - - else if (!pdi) { - HRESULT hr = DirectInput8Create(GameWinDX9::GetInstance()->GetHINST(), - DIRECTINPUT_VERSION, - IID_IDirectInput7, - (void**)&pdi, - NULL); - if FAILED(hr) { - DirectInputError("Failed to initialize DI7", hr); - pdi = 0; - pdev = 0; - } - else { - Print("Joystick: initialized DI7 pdi = %08x\n", (DWORD) pdi); - } - } -} - -Joystick::~Joystick() -{ - ReleaseDirectInput(); - joystick = 0; -} - -void ReleaseDirectInput() -{ - if (pdev) { - pdev->Unacquire(); - pdev->Release(); - pdev = 0; - } - - if (pdi) { - pdi->Release(); - pdi = 0; - } -} - -Joystick* Joystick::GetInstance() -{ - return joystick; -} - -// +--------------------------------------------------------------------+ - -void -Joystick::MapKeys(KeyMapEntry* mapping, int nkeys) -{ - ZeroMemory(map, sizeof(map)); - - for (int i = 0; i < nkeys; i++) { - KeyMapEntry k = mapping[i]; - - if (k.act >= KEY_MAP_FIRST && k.act < KEY_MAP_LAST) { - if (k.act == KEY_JOY_SENSE) - sensitivity = k.key; - - else if (k.act == KEY_JOY_DEAD_ZONE) - dead_zone = k.key; - - else if (k.act == KEY_JOY_SWAP) - swapped = k.key; - - else if (k.act == KEY_JOY_RUDDER) - rudder = k.key; - - else if (k.act == KEY_JOY_THROTTLE) - throttle = k.key; - - else if (k.act == KEY_JOY_SELECT) - select = k.key; - - - else if (k.act == KEY_AXIS_YAW) - map_axis[0] = k.key; - - else if (k.act == KEY_AXIS_PITCH) - map_axis[1] = k.key; - - else if (k.act == KEY_AXIS_ROLL) - map_axis[2] = k.key; - - else if (k.act == KEY_AXIS_THROTTLE) - map_axis[3] = k.key; - - - else if (k.act == KEY_AXIS_YAW_INVERT) - inv_axis[0] = k.key ? true : false; - - else if (k.act == KEY_AXIS_PITCH_INVERT) - inv_axis[1] = k.key ? true : false; - - else if (k.act == KEY_AXIS_ROLL_INVERT) - inv_axis[2] = k.key ? true : false; - - else if (k.act == KEY_AXIS_THROTTLE_INVERT) - inv_axis[3] = k.key ? true : false; - - else if (k.key >= KEY_JOY_1 && k.key <= KEY_JOY_32) - map[k.act] = k.key; - - else if (k.alt >= KEY_JOY_1 && k.alt <= KEY_JOY_32) - map[k.act] = k.alt; - - else if (k.joy >= KEY_JOY_1 && k.joy <= KEY_JOY_32) - map[k.act] = k.joy; - - else if (k.key >= KEY_POV_0_UP && k.key <= KEY_POV_3_RIGHT) - map[k.act] = k.key; - - else if (k.alt >= KEY_POV_0_UP && k.alt <= KEY_POV_3_RIGHT) - map[k.act] = k.alt; - - else if (k.joy >= KEY_POV_0_UP && k.joy <= KEY_POV_3_RIGHT) - map[k.act] = k.joy; - } - } -} - -// +--------------------------------------------------------------------+ - -static inline double sqr(double a) { return a*a; } - -BOOL FAR PASCAL EnumJoystick(LPCDIDEVICEINSTANCE pdinst, LPVOID pvSelect) -{ - CopyMemory(&devices[ndev++], pdinst, pdinst->dwSize); - - ::Print("EnumJoystick %d: '%s'\n", ndev, pdinst->tszInstanceName); - ::Print(" guid: {%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x} \n", - (DWORD) pdinst->guidInstance.Data1, - (WORD) pdinst->guidInstance.Data2, - (WORD) pdinst->guidInstance.Data3, - (BYTE) pdinst->guidInstance.Data4[0], - (BYTE) pdinst->guidInstance.Data4[1], - (BYTE) pdinst->guidInstance.Data4[2], - (BYTE) pdinst->guidInstance.Data4[3], - (BYTE) pdinst->guidInstance.Data4[4], - (BYTE) pdinst->guidInstance.Data4[5]); - - if (ndev < MAX_DEVICES) - return DIENUM_CONTINUE; - - return DIENUM_STOP; -} - -bool CreateDevice(int select) -{ - if (!pdi || ndev < select) - return false; - - LPCDIDEVICEINSTANCE pdinst = &devices[select-1]; - - ::Print("Joystick CreateDevice(%d)\n", select); - ::Print(" name: %s\n\n", pdinst->tszInstanceName); - - // release current device before trying to get another: - if (pdev) { - pdev->Unacquire(); - pdev->Release(); - pdev = 0; - } - - HRESULT hr = DI_OK; - // Create the DirectInput joystick device: - hr = pdi->CreateDeviceEx(pdinst->guidInstance, - IID_IDirectInputDevice7, - (void**)&pdev, - NULL); - - if (hr != DI_OK || pdev == 0) { - DirectInputError("Create Device Ex failed", hr); - return false; - } - - // Set the data format: - hr = pdev->SetDataFormat(&c_dfDIJoystick); - - if (hr != DI_OK) { - DirectInputError("Set Data Format failed", hr); - pdev->Release(); - pdev = 0; - return false; - } - - // Set the coop level: - hr = pdev->SetCooperativeLevel(GameWinDX9::GetInstance()->GetHWND(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); - - if (hr != DI_OK) { - DirectInputError("Set Cooperative Level failed", hr); - pdev->Release(); - return false; - } - - // Set data ranges - DIPROPRANGE diprg; - diprg.lMin = -32768; - diprg.lMax = +32768; - - diprg.diph.dwSize = sizeof(diprg); - diprg.diph.dwHeaderSize = sizeof(diprg.diph); - diprg.diph.dwObj = DIJOFS_X; - diprg.diph.dwHow = DIPH_BYOFFSET; - pdev->SetProperty(DIPROP_RANGE, &diprg.diph); - - diprg.diph.dwObj = DIJOFS_Y; - pdev->SetProperty(DIPROP_RANGE, &diprg.diph); - - diprg.diph.dwObj = DIJOFS_Z; - pdev->SetProperty(DIPROP_RANGE, &diprg.diph); - - diprg.diph.dwObj = DIJOFS_RX; - pdev->SetProperty(DIPROP_RANGE, &diprg.diph); - - diprg.diph.dwObj = DIJOFS_RY; - pdev->SetProperty(DIPROP_RANGE, &diprg.diph); - - diprg.diph.dwObj = DIJOFS_RZ; - pdev->SetProperty(DIPROP_RANGE, &diprg.diph); - - diprg.diph.dwObj = DIJOFS_SLIDER(0); - pdev->SetProperty(DIPROP_RANGE, &diprg.diph); - - diprg.diph.dwObj = DIJOFS_SLIDER(1); - pdev->SetProperty(DIPROP_RANGE, &diprg.diph); - - ::Print("Created joystick %d (pdev = %08x)\n", select, (DWORD) pdev); - idev = select; - return true; -} - -void -Joystick::EnumerateDevices() -{ - if (!pdi) { - Print("Joystick: no DI7, unable to enumerate devices\n"); - ndev = 0; - } - - else if (ndev < 1) { - Print("Joystick: preparing to enumerate devices\n"); - - ndev = 0; - HRESULT hr = - pdi->EnumDevices(DI8DEVTYPE_JOYSTICK, - EnumJoystick, - (LPVOID) 0, - DIEDFL_ATTACHEDONLY); - - if (FAILED(hr)) { - DirectInputError("Failed to enumerate devices", hr); - ReleaseDirectInput(); - } - - else if (ndev < 1) { - Print("Joystick: no devices found\n"); - ReleaseDirectInput(); - } - } -} - -int -Joystick::NumDevices() -{ - return ndev; -} - -const char* -Joystick::GetDeviceName(int i) -{ - if (i >= 0 && i < ndev) - return devices[i].tszInstanceName; - - return 0; -} - -// +--------------------------------------------------------------------+ - -static DIJOYSTATE joystate; -static JOYINFOEX joyinfo; - -int -Joystick::ReadRawAxis(int a) -{ - if (!joystick) - return 0; - - int result = 0; - - if (pdev) { - switch (a) { - case KEY_JOY_AXIS_X: result = joystate.lX; break; - case KEY_JOY_AXIS_Y: result = joystate.lY; break; - case KEY_JOY_AXIS_Z: result = joystate.lZ; break; - case KEY_JOY_AXIS_RX: result = joystate.lRx; break; - case KEY_JOY_AXIS_RY: result = joystate.lRy; break; - case KEY_JOY_AXIS_RZ: result = joystate.lRz; break; - case KEY_JOY_AXIS_S0: result = joystate.rglSlider[0]; break; - case KEY_JOY_AXIS_S1: result = joystate.rglSlider[1]; break; - } - } - - else { - switch (a) { - case KEY_JOY_AXIS_X: - if (joyinfo.dwFlags & JOY_RETURNX) - result = joyinfo.dwXpos; - break; - - case KEY_JOY_AXIS_Y: - if (joyinfo.dwFlags & JOY_RETURNY) - result = joyinfo.dwYpos; - break; - - case KEY_JOY_AXIS_Z: - if (joyinfo.dwFlags & JOY_RETURNZ) - result = joyinfo.dwZpos; - break; - - case KEY_JOY_AXIS_RZ: - if (joyinfo.dwFlags & JOY_RETURNR) - result = joyinfo.dwRpos; - break; - } - } - - return result; -} - -double -Joystick::ReadAxisDI(int a) -{ - if (a < 0 || a > 3) - return 0; - - double result = 0; - - switch (map_axis[a]) { - case KEY_JOY_AXIS_X: result = joystate.lX; break; - case KEY_JOY_AXIS_Y: result = joystate.lY; break; - case KEY_JOY_AXIS_Z: result = joystate.lZ; break; - case KEY_JOY_AXIS_RX: result = joystate.lRx; break; - case KEY_JOY_AXIS_RY: result = joystate.lRy; break; - case KEY_JOY_AXIS_RZ: result = joystate.lRz; break; - case KEY_JOY_AXIS_S0: result = joystate.rglSlider[0]; break; - case KEY_JOY_AXIS_S1: result = joystate.rglSlider[1]; break; - } - - if (a < 3) { - // ignore small movements: - if (result > dead_zone) result -= dead_zone; - else if (result < -dead_zone) result += dead_zone; - else result = 0; - - double scale = 1.0 / (32768.0-dead_zone); - - if (result >= 0) - result = sqr(result * scale); - else - result = sqr(result * scale) * -1.0; - - if (inv_axis[a]) - result = -result; - } - else { - result = (result+32768.0) / 65536.0; - - if (inv_axis[a]) - result = 1 - result; - } - - - return result; -} - -double -Joystick::ReadAxisMM(int a) -{ - if (a < 0 || a > 3) - return 0; - - double result = 0; - - switch (map_axis[a]) { - case KEY_JOY_AXIS_X: - if (joyinfo.dwFlags & JOY_RETURNX) - result = joyinfo.dwXpos - 32768; - break; - - case KEY_JOY_AXIS_Y: - if (joyinfo.dwFlags & JOY_RETURNY) - result = joyinfo.dwYpos - 32768; - break; - - case KEY_JOY_AXIS_Z: - if (joyinfo.dwFlags & JOY_RETURNZ) - result = joyinfo.dwZpos - 32768; - break; - - case KEY_JOY_AXIS_RZ: - if (joyinfo.dwFlags & JOY_RETURNR) - result = joyinfo.dwRpos - 32768; - break; - } - - if (a < 3) { - // ignore small movements: - if (result > dead_zone) result -= dead_zone; - else if (result < -dead_zone) result += dead_zone; - else result = 0; - - double scale = 1.0 / (32768.0-dead_zone); - - if (result >= 0) - result = sqr(result * scale); - else - result = sqr(result * scale) * -1.0; - - if (inv_axis[a]) - result = -result; - } - else { - result = (result+32768.0) / 65536.0; - - if (inv_axis[a]) - result = 1 - result; - } - - return result; -} - -// +--------------------------------------------------------------------+ - -void -Joystick::Acquire() -{ - t = x = y = z = p = r = w = 0; - for (int i = 0; i < MotionController::MaxActions; i++) - action[i] = false; - - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - hat[i][j] = false; - - if (select == 0) - return; - - //============================================================ - // - // FIRST TRY DIRECT INPUT - - bool acquired = false; - - if (pdi) { - if (idev != select) { - if (ndev < 1) - EnumerateDevices(); - - if (CreateDevice(select) && pdev) - pdev->Acquire(); - } - - if (pdev) { - HRESULT hr = 0; - - hr = pdev->Poll(); - hr = pdev->GetDeviceState(sizeof(joystate), &joystate); - - if (hr == DIERR_INPUTLOST) { - pdev->Acquire(); - - hr = pdev->Poll(); - hr = pdev->GetDeviceState(sizeof(joystate), &joystate); - - if (FAILED(hr)) { - strikes--; - ::Print("Joystick could not re-acquire joystick (%08x)\n", hr); - - // give up before you hurt yourself: - if (strikes <= 0) { - ReleaseDirectInput(); - ndev = 0; - select = 0; - } - - return; - } - } - - for (int i = 0; i < 32; i++) - action[i] = (joystate.rgbButtons[i] & 0x80) != 0; - - double joy_x = ReadAxisDI(0); - double joy_y = ReadAxisDI(1); - double joy_r = rudder ? ReadAxisDI(2) : 0; - double joy_t = throttle ? ReadAxisDI(3) : 0; - - int joy_p = joystate.rgdwPOV[0]; - - ProcessAxes(joy_x, joy_y, joy_r, joy_t); - - for (int i = 0; i < 4; i++) - ProcessHat(i, joystate.rgdwPOV[i]); - - acquired = true; - } - } - - //============================================================ - // - // THEN TRY WINDOWS MULTIMEDIA LIBRARY - - if (!acquired) { - memset(&joyinfo, 0, sizeof(JOYINFOEX)); - joyinfo.dwSize = sizeof(JOYINFOEX); - joyinfo.dwFlags = JOY_RETURNALL; - - HRESULT hr = 0; - - if (select == 1) - hr = joyGetPosEx(JOYSTICKID1, &joyinfo); - - else if (select == 2) - hr = joyGetPosEx(JOYSTICKID2, &joyinfo); - - if (hr != 0) { - Print("\nJoystick::Acquire() joyGetPosEx %d failed (err=%08x)\n\n", select, hr); - select = 0; - } - - action[0] = (joyinfo.dwButtons & JOY_BUTTON1) ? true : false; - action[1] = (joyinfo.dwButtons & JOY_BUTTON2) ? true : false; - action[2] = (joyinfo.dwButtons & JOY_BUTTON3) ? true : false; - action[3] = (joyinfo.dwButtons & JOY_BUTTON4) ? true : false; - - double joy_x = ReadAxisMM(0); - double joy_y = ReadAxisMM(1); - double joy_r = rudder ? ReadAxisMM(2) : 0; - double joy_t = throttle ? ReadAxisMM(3) : 0; - - ProcessAxes(joy_x, joy_y, joy_r, joy_t); - ProcessHat(0, joyinfo.dwPOV); - } - - // lateral translations: - if (KeyDownMap(KEY_PLUS_Y)) y = 1; - else if (KeyDownMap(KEY_MINUS_Y)) y = -1; - - if (KeyDownMap(KEY_PLUS_Z)) z = 1; - else if (KeyDownMap(KEY_MINUS_Z)) z = -1; - - if (KeyDownMap(KEY_MINUS_X)) x = -1; - else if (KeyDownMap(KEY_PLUS_X)) x = 1; - - // button-based turns: - const double steps=10; - static double p1=0, r1=0, w1=0; - - // if roll and yaw are swapped -------------------------- - if (swapped) { - // yaw: - if (KeyDownMap(KEY_ROLL_LEFT)) { if (w1 3) return; - - if (LOWORD(joy_pov) == 0xFFFF) - return; - - switch (joy_pov) { - case JOY_POVFORWARD: hat[i][0] = true; break; - case JOY_POVBACKWARD: hat[i][1] = true; break; - case JOY_POVLEFT: hat[i][2] = true; break; - case JOY_POVRIGHT: hat[i][3] = true; break; - - case JOY_POVUPRIGHT: hat[i][0] = true; - hat[i][3] = true; break; - - case JOY_POVDNRIGHT: hat[i][1] = true; - hat[i][3] = true; break; - - case JOY_POVDNLEFT: hat[i][1] = true; - hat[i][2] = true; break; - - case JOY_POVUPLEFT: hat[i][0] = true; - hat[i][2] = true; break; - - default: break; - } -} - -// +--------------------------------------------------------------------+ - -bool Joystick::KeyDown(int key) -{ - if (!joystick) - return false; - - if (key >= KEY_JOY_1 && key <= KEY_JOY_32) - return joystick->action[key - KEY_JOY_1]; - - else if (key >= KEY_POV_0_UP && key <= KEY_POV_0_RIGHT) - return joystick->hat[0][key - KEY_POV_0_UP]; - - else if (key >= KEY_POV_1_UP && key <= KEY_POV_1_RIGHT) - return joystick->hat[1][key - KEY_POV_1_UP]; - - else if (key >= KEY_POV_2_UP && key <= KEY_POV_2_RIGHT) - return joystick->hat[2][key - KEY_POV_2_UP]; - - else if (key >= KEY_POV_3_UP && key <= KEY_POV_3_RIGHT) - return joystick->hat[3][key - KEY_POV_3_UP]; - - return false; -} - -// +--------------------------------------------------------------------+ - -bool Joystick::KeyDownMap(int key) -{ - if (!joystick) - return false; - - if (key >= KEY_MAP_FIRST && key <= KEY_MAP_LAST && joystick->map[key]) - return KeyDown(joystick->map[key]); - - return false; -} - -// +--------------------------------------------------------------------+ - -int Joystick::GetAxisMap(int n) -{ - if (!joystick || n < 0 || n > 3) - return -1; - - return joystick->map_axis[n]; -} - -int Joystick::GetAxisInv(int n) -{ - if (!joystick || n < 0 || n > 3) - return -1; - - return joystick->inv_axis[n]; -} - -// +--------------------------------------------------------------------+ - -void -DirectInputError(const char* msg, HRESULT err) -{ - static int report = 50; - if (report > 0) - report--; - else - return; - - Print(" DirectInput7: %s. [%s]\n", msg, DIErrStr(err)); -} - -static char errstrbuf[128]; - -const char* DIErrStr(HRESULT hr) -{ - auto casted = static_cast(hr); - switch (casted) { - default: - sprintf_s(errstrbuf, "Unrecognized error value = %08x.", casted); - return errstrbuf; - - case DI_OK: - return "No error."; - - case DI_BUFFEROVERFLOW: - return "The device buffer overflowed and some input was lost. This value is equal to the S_FALSE standard COM return value."; - case DI_DOWNLOADSKIPPED: - return "The parameters of the effect were successfully updated, but the effect could not be downloaded because the associated device was not acquired in exclusive mode."; - case DI_EFFECTRESTARTED: - return "The effect was stopped, the parameters were updated, and the effect was restarted."; - case DI_POLLEDDEVICE: - return "The device is a polled device. As a result, device buffering does not collect any data and event notifications is not signaled until the IDirectInputDevice7::Poll method is called."; - case DI_TRUNCATED: - return "The parameters of the effect were successfully updated, but some of them were beyond the capabilities of the device and were truncated to the nearest supported value."; - case DI_TRUNCATEDANDRESTARTED: - return "Equal to DI_EFFECTRESTARTED | DI_TRUNCATED"; - case DIERR_ACQUIRED: - return "The operation cannot be performed while the device is acquired."; - case DIERR_ALREADYINITIALIZED: - return "This object is already initialized"; - case DIERR_BADDRIVERVER: - return "The object could not be created due to an incompatible driver version or mismatched or incomplete driver components."; - case DIERR_BETADIRECTINPUTVERSION: - return "The application was written for an unsupported prerelease version of DirectInput."; - case DIERR_DEVICEFULL: - return "The device is full."; - case DIERR_DEVICENOTREG: - return "The device or device instance is not registered with DirectInput. This value is equal to the REGDB_E_CLASSNOTREG standard COM return value."; - case DIERR_EFFECTPLAYING: - return "The parameters were updated in memory but were not downloaded to the device because the device does not support updating an effect while it is still playing."; - case DIERR_HASEFFECTS: - return "The device cannot be reinitialized because there are still effects attached to it."; - case DIERR_GENERIC: - return "An undetermined error occurred inside the DirectInput subsystem. This value is equal to the E_FAIL standard COM return value."; - case DIERR_HANDLEEXISTS: - return "The device already has an event notification associated with it. This value is equal to the E_ACCESSDENIED standard COM return value."; - case DIERR_INCOMPLETEEFFECT: - return "The effect could not be downloaded because essential information is missing. For example, no axes have been associated with the effect, or no type-specific information has been supplied."; - case DIERR_INPUTLOST: - return "Access to the input device has been lost. It must be reacquired."; - case DIERR_INVALIDPARAM: - return "An invalid parameter was passed to the returning function, or the object was not in a state that permitted the function to be called. This value is equal to the E_INVALIDARG standard COM return value."; - case DIERR_MOREDATA: - return "Not all the requested information fit into the buffer."; - case DIERR_NOAGGREGATION: - return "This object does not support aggregation."; - case DIERR_NOINTERFACE: - return "The specified interface is not supported by the object. This value is equal to the E_NOINTERFACE standard COM return value."; - case DIERR_NOTACQUIRED: - return "The operation cannot be performed unless the device is acquired."; - case DIERR_NOTBUFFERED: - return "The device is not buffered. Set the DIPROP_BUFFERSIZE property to enable buffering."; - case DIERR_NOTDOWNLOADED: - return "The effect is not downloaded."; - case DIERR_NOTEXCLUSIVEACQUIRED: - return "The operation cannot be performed unless the device is acquired in DISCL_EXCLUSIVE mode."; - case DIERR_NOTFOUND: - return "The requested object does not exist."; - case DIERR_NOTINITIALIZED: - return "This object has not been initialized."; - case DIERR_OLDDIRECTINPUTVERSION: - return "The application requires a newer version of DirectInput."; - case DIERR_OUTOFMEMORY: - return "The DirectInput subsystem could not allocate sufficient memory to complete the call. This value is equal to the E_OUTOFMEMORY standard COM return value."; - case DIERR_REPORTFULL: - return "More information was requested to be sent than can be sent to the device."; - case DIERR_UNPLUGGED: - return "The operation could not be completed because the device is not plugged in."; - case DIERR_UNSUPPORTED: - return "The function called is not supported at this time. This value is equal to the E_NOTIMPL standard COM return value."; - } -} - diff --git a/Stars45/Joystick.h b/Stars45/Joystick.h deleted file mode 100644 index 5e645c8..0000000 --- a/Stars45/Joystick.h +++ /dev/null @@ -1,82 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Joystick Input class -*/ - -#ifndef Joystick_h -#define Joystick_h - -#include "MotionController.h" -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class Joystick : public MotionController -{ -public: - static const char* TYPENAME() { return "Joystick"; } - - Joystick(); - virtual ~Joystick(); - - // setup - virtual void MapKeys(KeyMapEntry* mapping, int nkeys); - - // sample the physical device - virtual void Acquire(); - - // translations - virtual double X() { return x; } - virtual double Y() { return y; } - virtual double Z() { return z; } - - // rotations - virtual double Pitch() { return p; } - virtual double Roll() { return r; } - virtual double Yaw() { return w; } - virtual int Center() { return 0; } - - // throttle - virtual double Throttle() { return t; } - virtual void SetThrottle(double throttle) { t = throttle; } - - // actions - virtual int Action(int n) { return action[n]; } - virtual int ActionMap(int n) { return KeyDownMap(n); } - - static bool KeyDown(int key); - static bool KeyDownMap(int key); - - static Joystick* GetInstance(); - static void EnumerateDevices(); - static int NumDevices(); - static const char* GetDeviceName(int i); - - static int ReadRawAxis(int axis); - static int GetAxisMap(int n); - static int GetAxisInv(int n); - -protected: - double ReadAxisDI(int axis); - double ReadAxisMM(int axis); - void ProcessAxes(double joy_x, double joy_y, double joy_r, double joy_t); - void ProcessHat(int i, DWORD joy_pov); - - double x,y,z,p,r,w,t; - bool action[MotionController::MaxActions]; - bool hat[4][4]; - int map[KEY_MAP_SIZE]; - int map_axis[4]; - bool inv_axis[4]; -}; - -#endif // Joystick_h - diff --git a/Stars45/KeyDlg.cpp b/Stars45/KeyDlg.cpp deleted file mode 100644 index cbd7c68..0000000 --- a/Stars45/KeyDlg.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "KeyDlg.h" -#include "KeyMap.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "FormatUtil.h" - -#include "Game.h" -#include "ListBox.h" -#include "ComboBox.h" -#include "Button.h" -#include "Joystick.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(KeyDlg, OnApply); -DEF_MAP_CLIENT(KeyDlg, OnCancel); -DEF_MAP_CLIENT(KeyDlg, OnClear); - -// +--------------------------------------------------------------------+ - -KeyDlg::KeyDlg(Screen* s, FormDef& def, BaseScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -key_key(0), key_shift(0), key_joy(0), key_clear(0), -command(0), current_key(0), new_key(0), clear(0), -apply(0), cancel(0) -{ - Init(def); -} - -KeyDlg::~KeyDlg() -{ -} - -void -KeyDlg::RegisterControls() -{ - if (apply) - return; - - command = FindControl(201); - current_key = FindControl(202); - new_key = FindControl(203); - - clear = (Button*) FindControl(300); - REGISTER_CLIENT(EID_CLICK, clear, KeyDlg, OnClear); - - apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, apply, KeyDlg, OnApply); - - cancel = (Button*) FindControl(2); - REGISTER_CLIENT(EID_CLICK, cancel, KeyDlg, OnCancel); -} - -// +--------------------------------------------------------------------+ - -void -KeyDlg::ExecFrame() -{ - int key = 0; - int shift = 0; - int joy = 0; - Joystick* joystick = Joystick::GetInstance(); - - if (joystick) joystick->Acquire(); - - for (int i = 0; i < 256; i++) { - int vk = KeyMap::GetMappableVKey(i); - - if (vk >= KEY_JOY_1 && vk <= KEY_JOY_16) { - if (joystick && joystick->KeyDown(vk)) - joy = vk; - } - - else if (vk >= KEY_POV_0_UP && vk <= KEY_POV_3_RIGHT) { - if (joystick && joystick->KeyDown(vk)) - joy = vk; - } - - else if (GetAsyncKeyState(vk)) { - if (vk == VK_SHIFT || vk == VK_MENU) - shift = vk; - else - key = vk; - } - } - - if (key) { - key_key = key; - key_shift = shift; - - new_key->SetText(KeyMap::DescribeKey(key, shift, joy)); - } - - else if (joy) { - key_joy = joy; - new_key->SetText(KeyMap::DescribeKey(key, shift, joy)); - } -} - -// +--------------------------------------------------------------------+ - -void -KeyDlg::Show() -{ - FormWindow::Show(); - - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - KeyMap& keymap = stars->GetKeyMap(); - - if (command) - command->SetText(keymap.DescribeAction(key_index)); - - if (current_key) - current_key->SetText(keymap.DescribeKey(key_index)); - } - - key_clear = false; - new_key->SetText(""); - SetFocus(); -} - -// +--------------------------------------------------------------------+ - -void -KeyDlg::SetKeyMapIndex(int i) -{ - key_index = i; - key_key = 0; - key_shift = 0; -} - -// +--------------------------------------------------------------------+ - -void -KeyDlg::OnClear(AWEvent* event) -{ - key_clear = true; - - key_key = 0; - key_shift = 0; - key_joy = 0; -} - -// +--------------------------------------------------------------------+ - -void -KeyDlg::OnApply(AWEvent* event) -{ - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - KeyMap& keymap = stars->GetKeyMap(); - KeyMapEntry* map = keymap.GetKeyMap(key_index); - - if (key_clear) { - map->key = 0; - map->alt = 0; - map->joy = 0; - } - - if (key_key) { - map->key = key_key; - map->alt = key_shift; - } - - if (key_joy) { - map->joy = key_joy; - } - } - - if (manager) - manager->ShowCtlDlg(); -} - -void -KeyDlg::OnCancel(AWEvent* event) -{ - if (manager) - manager->ShowCtlDlg(); -} - -// +--------------------------------------------------------------------+ diff --git a/Stars45/KeyDlg.h b/Stars45/KeyDlg.h deleted file mode 100644 index 198f3ab..0000000 --- a/Stars45/KeyDlg.h +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Navigation Active Window class -*/ - -#ifndef KeyDlg_h -#define KeyDlg_h - -#include "Types.h" -#include "FormWindow.h" - -// +--------------------------------------------------------------------+ - -class BaseScreen; - -// +--------------------------------------------------------------------+ - -class KeyDlg : public FormWindow -{ -public: - KeyDlg(Screen* s, FormDef& def, BaseScreen* mgr); - virtual ~KeyDlg(); - - virtual void RegisterControls(); - virtual void Show(); - - // Operations: - virtual void ExecFrame(); - - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnClear(AWEvent* event); - - int GetKeyMapIndex() const { return key_index; } - void SetKeyMapIndex(int i); - -protected: - BaseScreen* manager; - - int key_index; - int key_key; - int key_shift; - int key_joy; - int key_clear; - - Button* clear; - Button* apply; - Button* cancel; - - ActiveWindow* command; - ActiveWindow* current_key; - ActiveWindow* new_key; -}; - -#endif // KeyDlg_h - diff --git a/Stars45/KeyMap.cpp b/Stars45/KeyMap.cpp deleted file mode 100644 index 6c5e2ab..0000000 --- a/Stars45/KeyMap.cpp +++ /dev/null @@ -1,825 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon class -*/ - -#include "Keyboard.h" -#include "KeyMap.h" -#include "Game.h" -#include "Ship.h" - -// +----------------------------------------------------------------------+ - -struct KeyName -{ - int category; - int key; - const char* name; - const char* desc; -}; - -static KeyName key_action_table[] = { - { KeyMap::KEY_FLIGHT, KEY_PLUS_X, "KEY_PLUS_X", "Translate Right" }, - { KeyMap::KEY_FLIGHT, KEY_MINUS_X, "KEY_MINUS_X", "Translate Left" }, - { KeyMap::KEY_FLIGHT, KEY_PLUS_Y, "KEY_PLUS_Y", "Translate Forward" }, - { KeyMap::KEY_FLIGHT, KEY_MINUS_Y, "KEY_MINUS_Y", "Translate Aft" }, - { KeyMap::KEY_FLIGHT, KEY_PLUS_Z, "KEY_PLUS_Z", "Translate Up" }, - { KeyMap::KEY_FLIGHT, KEY_MINUS_Z, "KEY_MINUS_Z", "Translate Down" }, - - { KeyMap::KEY_FLIGHT, KEY_PITCH_UP, "KEY_PITCH_UP", "Pitch Up" }, - { KeyMap::KEY_FLIGHT, KEY_PITCH_DOWN, "KEY_PITCH_DOWN", "Pitch Down" }, - { KeyMap::KEY_FLIGHT, KEY_YAW_LEFT, "KEY_YAW_LEFT", "Yaw Left" }, - { KeyMap::KEY_FLIGHT, KEY_YAW_RIGHT, "KEY_YAW_RIGHT", "Yaw Right" }, - { KeyMap::KEY_FLIGHT, KEY_ROLL_LEFT, "KEY_ROLL_LEFT", "Roll Left" }, - { KeyMap::KEY_FLIGHT, KEY_ROLL_RIGHT, "KEY_ROLL_RIGHT", "Roll Right" }, - { KeyMap::KEY_FLIGHT, KEY_CENTER, "KEY_CENTER", "Center" }, - { KeyMap::KEY_FLIGHT, KEY_ROLL_ENABLE, "KEY_ROLL_ENABLE", "Roll Enable" }, - { KeyMap::KEY_FLIGHT, KEY_SWAP_ROLL_YAW, "KEY_SWAP_ROLL_YAW", "Swap Ctrl Axes" }, - - { KeyMap::KEY_WEAPONS, KEY_ACTION_0, "KEY_ACTION_0", "Fire Primary" }, - { KeyMap::KEY_WEAPONS, KEY_ACTION_1, "KEY_ACTION_1", "Fire Secondary" }, - { KeyMap::KEY_WEAPONS, KEY_ACTION_2, "KEY_ACTION_2", "Action 2" }, - { KeyMap::KEY_WEAPONS, KEY_ACTION_3, "KEY_ACTION_3", "Action 3" }, - - { KeyMap::KEY_FLIGHT, KEY_CONTROL_MODEL, "KEY_CONTROL_MODEL" }, - - { KeyMap::KEY_FLIGHT, KEY_MOUSE_SELECT, "KEY_MOUSE_SELECT" }, - { KeyMap::KEY_FLIGHT, KEY_MOUSE_SENSE, "KEY_MOUSE_SENSE" }, - { KeyMap::KEY_FLIGHT, KEY_MOUSE_SWAP, "KEY_MOUSE_SWAP" }, - { KeyMap::KEY_FLIGHT, KEY_MOUSE_INVERT, "KEY_MOUSE_INVERT" }, - { KeyMap::KEY_FLIGHT, KEY_MOUSE_ACTIVE, "KEY_MOUSE_ACTIVE", "Toggle Mouse Ctrl" }, - - { KeyMap::KEY_FLIGHT, KEY_JOY_SELECT, "KEY_JOY_SELECT" }, - { KeyMap::KEY_FLIGHT, KEY_JOY_RUDDER, "KEY_JOY_RUDDER" }, - { KeyMap::KEY_FLIGHT, KEY_JOY_THROTTLE, "KEY_JOY_THROTTLE" }, - { KeyMap::KEY_FLIGHT, KEY_JOY_SENSE, "KEY_JOY_SENSE" }, - { KeyMap::KEY_FLIGHT, KEY_JOY_DEAD_ZONE, "KEY_JOY_DEAD_ZONE" }, - { KeyMap::KEY_FLIGHT, KEY_JOY_SWAP, "KEY_JOY_SWAP" }, - - { KeyMap::KEY_FLIGHT, KEY_AXIS_YAW, "KEY_AXIS_YAW" }, - { KeyMap::KEY_FLIGHT, KEY_AXIS_PITCH, "KEY_AXIS_PITCH" }, - { KeyMap::KEY_FLIGHT, KEY_AXIS_ROLL, "KEY_AXIS_ROLL" }, - { KeyMap::KEY_FLIGHT, KEY_AXIS_THROTTLE, "KEY_AXIS_THROTTLE" }, - { KeyMap::KEY_FLIGHT, KEY_AXIS_YAW_INVERT, "KEY_AXIS_YAW_INVERT" }, - { KeyMap::KEY_FLIGHT, KEY_AXIS_PITCH_INVERT, "KEY_AXIS_PITCH_INVERT" }, - { KeyMap::KEY_FLIGHT, KEY_AXIS_ROLL_INVERT, "KEY_AXIS_ROLL_INVERT" }, - { KeyMap::KEY_FLIGHT, KEY_AXIS_THROTTLE_INVERT, "KEY_AXIS_THROTTLE_INVERT" }, - - { KeyMap::KEY_MISC, KEY_EXIT, "KEY_EXIT", "Exit" }, - { KeyMap::KEY_MISC, KEY_PAUSE, "KEY_PAUSE", "Pause" }, - // { KeyMap::KEY_VIEW, KEY_NEXT_VIEW, "KEY_NEXT_VIEW", "Next View" }, - { KeyMap::KEY_VIEW, KEY_TARGET_PADLOCK, "KEY_TARGET_PADLOCK","Padlock Target" }, - { KeyMap::KEY_VIEW, KEY_THREAT_PADLOCK, "KEY_THREAT_PADLOCK","Padlock Threat" }, - { KeyMap::KEY_WEAPONS, KEY_LOCK_TARGET, "KEY_LOCK_TARGET", "Lock Target" }, - { KeyMap::KEY_WEAPONS, KEY_LOCK_THREAT, "KEY_LOCK_THREAT", "Lock Threat" }, - { KeyMap::KEY_WEAPONS, KEY_LOCK_CLOSEST_SHIP, "KEY_LOCK_CLOSEST_SHIP", "Lock Closest Ship" }, - { KeyMap::KEY_WEAPONS, KEY_LOCK_CLOSEST_THREAT, "KEY_LOCK_CLOSEST_THREAT", "Lock Closest Threat" }, - { KeyMap::KEY_WEAPONS, KEY_LOCK_HOSTILE_SHIP, "KEY_LOCK_HOSTILE_SHIP", "Lock Hostile Ship" }, - { KeyMap::KEY_WEAPONS, KEY_LOCK_HOSTILE_THREAT, "KEY_LOCK_HOSTILE_THREAT", "Lock Hostile Threat" }, - { KeyMap::KEY_WEAPONS, KEY_CYCLE_SUBTARGET, "KEY_CYCLE_SUBTARGET", "Target Subsystem" }, - { KeyMap::KEY_WEAPONS, KEY_PREV_SUBTARGET, "KEY_PREV_SUBTARGET", "Previous Subsystem" }, - { KeyMap::KEY_FLIGHT, KEY_AUTO_NAV, "KEY_AUTO_NAV", "Autonav" }, - { KeyMap::KEY_MISC, KEY_TIME_COMPRESS, "KEY_TIME_COMPRESS", "Compress Time" }, - { KeyMap::KEY_MISC, KEY_TIME_EXPAND, "KEY_TIME_EXPAND", "Expand Time" }, - { KeyMap::KEY_MISC, KEY_TIME_SKIP, "KEY_TIME_SKIP", "Skip to Next Event" }, - - { KeyMap::KEY_FLIGHT, KEY_THROTTLE_UP, "KEY_THROTTLE_UP", "Throttle Up" }, - { KeyMap::KEY_FLIGHT, KEY_THROTTLE_DOWN, "KEY_THROTTLE_DOWN", "Throttle Down" }, - { KeyMap::KEY_FLIGHT, KEY_THROTTLE_ZERO, "KEY_THROTTLE_ZERO", "All Stop" }, - { KeyMap::KEY_FLIGHT, KEY_THROTTLE_FULL, "KEY_THROTTLE_FULL", "Full Throttle" }, - { KeyMap::KEY_FLIGHT, KEY_AUGMENTER, "KEY_AUGMENTER", "Augmenter" }, - { KeyMap::KEY_FLIGHT, KEY_FLCS_MODE_AUTO, "KEY_FLCS_MODE_AUTO","FLCS Mode Toggle" }, - { KeyMap::KEY_FLIGHT, KEY_COMMAND_MODE, "KEY_COMMAND_MODE", "CMD Mode Toggle" }, - { KeyMap::KEY_FLIGHT, KEY_DROP_ORBIT, "KEY_DROP_ORBIT", "Break Orbit" }, - { KeyMap::KEY_FLIGHT, KEY_GEAR_TOGGLE, "KEY_GEAR_TOGGLE", "Landing Gear" }, - { KeyMap::KEY_FLIGHT, KEY_NAVLIGHT_TOGGLE, "KEY_NAVLIGHT_TOGGLE","Nav Lights" }, - - { KeyMap::KEY_WEAPONS, KEY_CYCLE_PRIMARY, "KEY_CYCLE_PRIMARY", "Cycle Primary" }, - { KeyMap::KEY_WEAPONS, KEY_CYCLE_SECONDARY, "KEY_CYCLE_SECONDARY", "Cycle Secondary" }, - - { KeyMap::KEY_VIEW, KEY_HUD_INST, "KEY_HUD_INST", "Instr. Display" }, - { KeyMap::KEY_VIEW, KEY_CAM_BRIDGE, "KEY_CAM_BRIDGE", "Bridge Cam" }, - { KeyMap::KEY_VIEW, KEY_CAM_VIRT, "KEY_CAM_VIRT", "Virtual Cockpit" }, - { KeyMap::KEY_VIEW, KEY_CAM_CHASE, "KEY_CAM_CHASE", "Chase Cam" }, - { KeyMap::KEY_VIEW, KEY_CAM_DROP, "KEY_CAM_DROP", "Drop Cam" }, - { KeyMap::KEY_VIEW, KEY_CAM_EXTERN, "KEY_CAM_EXTERN", "Orbit Cam" }, - { KeyMap::KEY_MISC, KEY_HUD_MODE, "KEY_HUD_MODE", "HUD Mode" }, - { KeyMap::KEY_MISC, KEY_HUD_COLOR, "KEY_HUD_COLOR", "HUD Color" }, - { KeyMap::KEY_MISC, KEY_HUD_WARN, "KEY_HUD_WARN", "Master Caution" }, - { KeyMap::KEY_MISC, KEY_NAV_DLG, "KEY_NAV_DLG", "NAV Window" }, - { KeyMap::KEY_MISC, KEY_WEP_DLG, "KEY_WEP_DLG", "TAC Overlay" }, - { KeyMap::KEY_MISC, KEY_FLT_DLG, "KEY_FLT_DLG", "FLT Window" }, - { KeyMap::KEY_MISC, KEY_ENG_DLG, "KEY_ENG_DLG", "ENG Window" }, - - { KeyMap::KEY_VIEW, KEY_ZOOM_WIDE, "KEY_ZOOM_WIDE", "Toggle Wide Angle" }, - { KeyMap::KEY_VIEW, KEY_ZOOM_IN, "KEY_ZOOM_IN", "Zoom In" }, - { KeyMap::KEY_VIEW, KEY_ZOOM_OUT, "KEY_ZOOM_OUT", "Zoom Out" }, - - { KeyMap::KEY_VIEW, KEY_CAM_VIRT_PLUS_AZ, "KEY_CAM_VIRT_PLUS_AZ", "Look Left" }, - { KeyMap::KEY_VIEW, KEY_CAM_VIRT_MINUS_AZ, "KEY_CAM_VIRT_MINUS_AZ", "Look Right" }, - { KeyMap::KEY_VIEW, KEY_CAM_VIRT_PLUS_EL, "KEY_CAM_VIRT_PLUS_EL", "Look Up" }, - { KeyMap::KEY_VIEW, KEY_CAM_VIRT_MINUS_EL, "KEY_CAM_VIRT_MINUS_EL", "Look Down" }, - { KeyMap::KEY_VIEW, KEY_CAM_CYCLE_OBJECT, "KEY_CAM_CYCLE_OBJECT", "View Next Object" }, - { KeyMap::KEY_VIEW, KEY_CAM_EXT_PLUS_AZ, "KEY_CAM_EXT_PLUS_AZ", "View Spin Left" }, - { KeyMap::KEY_VIEW, KEY_CAM_EXT_MINUS_AZ, "KEY_CAM_EXT_MINUS_AZ", "View Spin Right" }, - { KeyMap::KEY_VIEW, KEY_CAM_EXT_PLUS_EL, "KEY_CAM_EXT_PLUS_EL", "View Raise" }, - { KeyMap::KEY_VIEW, KEY_CAM_EXT_MINUS_EL, "KEY_CAM_EXT_MINUS_EL", "View Lower" }, - { KeyMap::KEY_VIEW, KEY_CAM_EXT_PLUS_RANGE, "KEY_CAM_EXT_PLUS_RANGE", "View Farther" }, - { KeyMap::KEY_VIEW, KEY_CAM_EXT_MINUS_RANGE,"KEY_CAM_EXT_MINUS_RANGE", "View Closer" }, - { KeyMap::KEY_VIEW, KEY_CAM_VIEW_SELECTION, "KEY_CAM_VIEW_SELECTION", "View Selection" }, - - { KeyMap::KEY_WEAPONS, KEY_TARGET_SELECTION, "KEY_TARGET_SELECTION", "Target Selection" }, - { KeyMap::KEY_MISC, KEY_RADIO_MENU, "KEY_RADIO_MENU", "Radio Call" }, - { KeyMap::KEY_MISC, KEY_QUANTUM_MENU, "KEY_QUANTUM_MENU", "Quantum Drive" }, - - { KeyMap::KEY_MISC, KEY_MFD1, "KEY_MFD1", "MFD 1" }, - { KeyMap::KEY_MISC, KEY_MFD2, "KEY_MFD2", "MFD 2" }, - { KeyMap::KEY_MISC, KEY_MFD3, "KEY_MFD3", "MFD 3" }, - { KeyMap::KEY_MISC, KEY_MFD4, "KEY_MFD4", "MFD 4" }, - { KeyMap::KEY_MISC, KEY_SELF_DESTRUCT, "KEY_SELF_DESTRUCT", "Self Destruct" }, - - { KeyMap::KEY_MISC, KEY_COMM_ATTACK_TGT, "KEY_COMM_ATTACK_TGT", "'Attack Tgt'" }, - { KeyMap::KEY_MISC, KEY_COMM_ESCORT_TGT, "KEY_COMM_ESCORT_TGT", "'Escort Tgt'" }, - { KeyMap::KEY_MISC, KEY_COMM_WEP_FREE, "KEY_COMM_WEP_FREE", "'Break & Attack'" }, - { KeyMap::KEY_MISC, KEY_COMM_WEP_HOLD, "KEY_COMM_WEP_HOLD", "'Form Up'" }, - { KeyMap::KEY_MISC, KEY_COMM_COVER_ME, "KEY_COMM_COVER_ME", "'Help Me Out!'" }, - { KeyMap::KEY_MISC, KEY_COMM_SKIP_NAV, "KEY_COMM_SKIP_NAV", "'Skip Navpoint'" }, - { KeyMap::KEY_MISC, KEY_COMM_RETURN_TO_BASE,"KEY_COMM_RETURN_TO_BASE", "'Return to Base'" }, - { KeyMap::KEY_MISC, KEY_COMM_CALL_INBOUND, "KEY_COMM_CALL_INBOUND", "'Call Inbound'" }, - { KeyMap::KEY_MISC, KEY_COMM_REQUEST_PICTURE, "KEY_COMM_REQUEST_PICTURE", "'Request Picture'" }, - { KeyMap::KEY_MISC, KEY_COMM_REQUEST_SUPPORT, "KEY_COMM_REQUEST_SUPPORT", "'Request Support'" }, - { KeyMap::KEY_MISC, KEY_CHAT_BROADCAST, "KEY_CHAT_BROADCAST", "Chat Broadcast" }, - { KeyMap::KEY_MISC, KEY_CHAT_TEAM, "KEY_CHAT_TEAM", "Chat Team" }, - { KeyMap::KEY_MISC, KEY_CHAT_WING, "KEY_CHAT_WING", "Chat Wingman" }, - { KeyMap::KEY_MISC, KEY_CHAT_UNIT, "KEY_CHAT_UNIT", "Chat Unit" }, - - { KeyMap::KEY_WEAPONS, KEY_SHIELDS_UP, "KEY_SHIELDS_UP", "Raise Shields" }, - { KeyMap::KEY_WEAPONS, KEY_SHIELDS_DOWN, "KEY_SHIELDS_DOWN", "Lower Shields" }, - { KeyMap::KEY_WEAPONS, KEY_SHIELDS_FULL, "KEY_SHIELDS_FULL", "Full Shields" }, - { KeyMap::KEY_WEAPONS, KEY_SHIELDS_ZERO, "KEY_SHIELDS_ZERO", "Zero Shields" }, - - { KeyMap::KEY_WEAPONS, KEY_SENSOR_MODE, "KEY_SENSOR_MODE", "Sensor Mode" }, - { KeyMap::KEY_WEAPONS, KEY_SENSOR_GROUND_MODE, "KEY_SENSOR_GROUND_MODE", "Sensor AGM" }, - { KeyMap::KEY_WEAPONS, KEY_SENSOR_BEAM, "KEY_SENSOR_BEAM", "Sensor Sweep Angle" }, - { KeyMap::KEY_WEAPONS, KEY_SENSOR_RANGE_PLUS, "KEY_SENSOR_RANGE_PLUS", "Inc Sensor Range" }, - { KeyMap::KEY_WEAPONS, KEY_SENSOR_RANGE_MINUS, "KEY_SENSOR_RANGE_MINUS", "Dec Sensor Range" }, - { KeyMap::KEY_WEAPONS, KEY_EMCON_PLUS, "KEY_EMCON_PLUS", "Inc EMCON Level" }, - { KeyMap::KEY_WEAPONS, KEY_EMCON_MINUS, "KEY_EMCON_MINUS", "Dec EMCON Level" }, - - { KeyMap::KEY_WEAPONS, KEY_DECOY, "KEY_DECOY", "Launch Decoy" }, - { KeyMap::KEY_WEAPONS, KEY_LAUNCH_PROBE, "KEY_LAUNCH_PROBE", "Launch Probe" }, - -}; - -static KeyName key_key_table[] = { - { 0, VK_ESCAPE, "VK_ESCAPE", "Escape" }, - { 0, VK_UP, "VK_UP", "Up" }, - { 0, VK_DOWN, "VK_DOWN", "Down" }, - { 0, VK_LEFT, "VK_LEFT", "Left" }, - { 0, VK_RIGHT, "VK_RIGHT", "Right" }, - { 0, VK_NEXT, "VK_NEXT", "Pg Down" }, - { 0, VK_PRIOR, "VK_PRIOR", "Pg Up" }, - { 0, VK_ADD, "VK_ADD", "+" }, - { 0, VK_SUBTRACT, "VK_SUBTRACT", "-" }, - { 0, VK_MULTIPLY, "VK_MULTIPLY", "*" }, - { 0, VK_DIVIDE, "VK_DIVIDE", "/" }, - { 0, VK_SPACE, "VK_SPACE", "Space" }, - { 0, VK_TAB, "VK_TAB", "Tab" }, - { 0, VK_RETURN, "VK_RETURN", "Enter" }, - { 0, VK_HOME, "VK_HOME", "Home" }, - { 0, VK_END, "VK_END", "End" }, - { 0, VK_SHIFT, "VK_SHIFT", "Shift" }, - { 0, VK_CONTROL, "VK_CONTROL", "Ctrl" }, - { 0, VK_MENU, "VK_MENU", "Alt" }, - - { 0, VK_DECIMAL, "VK_DECIMAL", "." }, - { 0, VK_SEPARATOR, "VK_SEPARATOR", "Separator" }, - { 0, VK_PAUSE, "VK_PAUSE", "Pause" }, - { 0, VK_BACK, "VK_BACK", "Backspace" }, - { 0, VK_INSERT, "VK_INSERT", "Insert" }, - { 0, VK_DELETE, "VK_DELETE", "Delete" }, - { 0, 20, "CAP", "CapsLock" }, - { 0, 144, "NUM", "NumLock" }, - { 0, 145, "SCROLL", "Scroll" }, - { 0, 44, "PRINT", "PrintScr" }, - - { 0, VK_NUMPAD0, "VK_NUMPAD0", "Num 0" }, - { 0, VK_NUMPAD1, "VK_NUMPAD1", "Num 1" }, - { 0, VK_NUMPAD2, "VK_NUMPAD2", "Num 2" }, - { 0, VK_NUMPAD3, "VK_NUMPAD3", "Num 3" }, - { 0, VK_NUMPAD4, "VK_NUMPAD4", "Num 4" }, - { 0, VK_NUMPAD5, "VK_NUMPAD5", "Num 5" }, - { 0, VK_NUMPAD6, "VK_NUMPAD6", "Num 6" }, - { 0, VK_NUMPAD7, "VK_NUMPAD7", "Num 7" }, - { 0, VK_NUMPAD8, "VK_NUMPAD8", "Num 8" }, - { 0, VK_NUMPAD9, "VK_NUMPAD9", "Num 9" }, - - { 0, VK_F1, "VK_F1", "F1" }, - { 0, VK_F2, "VK_F2", "F2" }, - { 0, VK_F3, "VK_F3", "F3" }, - { 0, VK_F4, "VK_F4", "F4" }, - { 0, VK_F5, "VK_F5", "F5" }, - { 0, VK_F6, "VK_F6", "F6" }, - { 0, VK_F7, "VK_F7", "F7" }, - { 0, VK_F8, "VK_F8", "F8" }, - { 0, VK_F9, "VK_F9", "F9" }, - { 0, VK_F10, "VK_F10", "F10" }, - { 0, VK_F11, "VK_F11", "F11" }, - { 0, VK_F12, "VK_F12", "F12" }, - - { 0, KEY_JOY_1, "KEY_JOY_1", "Joy 1" }, - { 0, KEY_JOY_2, "KEY_JOY_2", "Joy 2" }, - { 0, KEY_JOY_3, "KEY_JOY_3", "Joy 3" }, - { 0, KEY_JOY_4, "KEY_JOY_4", "Joy 4" }, - { 0, KEY_JOY_5, "KEY_JOY_5", "Joy 5" }, - { 0, KEY_JOY_6, "KEY_JOY_6", "Joy 6" }, - { 0, KEY_JOY_7, "KEY_JOY_7", "Joy 7" }, - { 0, KEY_JOY_8, "KEY_JOY_8", "Joy 8" }, - { 0, KEY_JOY_9, "KEY_JOY_9", "Joy 9" }, - { 0, KEY_JOY_10, "KEY_JOY_10", "Joy 10" }, - { 0, KEY_JOY_11, "KEY_JOY_11", "Joy 11" }, - { 0, KEY_JOY_12, "KEY_JOY_12", "Joy 12" }, - { 0, KEY_JOY_13, "KEY_JOY_13", "Joy 13" }, - { 0, KEY_JOY_14, "KEY_JOY_14", "Joy 14" }, - { 0, KEY_JOY_15, "KEY_JOY_15", "Joy 15" }, - { 0, KEY_JOY_16, "KEY_JOY_16", "Joy 16" }, - - { 0, KEY_POV_0_UP, "KEY_POV_0_UP", "Hat 1 Up" }, - { 0, KEY_POV_0_DOWN, "KEY_POV_0_DOWN", "Hat 1 Down" }, - { 0, KEY_POV_0_LEFT, "KEY_POV_0_LEFT", "Hat 1 Left" }, - { 0, KEY_POV_0_RIGHT, "KEY_POV_0_RIGHT", "Hat 1 Right" }, - { 0, KEY_POV_1_UP, "KEY_POV_1_UP", "Hat 2 Up" }, - { 0, KEY_POV_1_DOWN, "KEY_POV_1_DOWN", "Hat 2 Down" }, - { 0, KEY_POV_1_LEFT, "KEY_POV_1_LEFT", "Hat 2 Left" }, - { 0, KEY_POV_1_RIGHT, "KEY_POV_1_RIGHT", "Hat 2 Right" }, - { 0, KEY_POV_2_UP, "KEY_POV_2_UP", "Hat 3 Up" }, - { 0, KEY_POV_2_DOWN, "KEY_POV_2_DOWN", "Hat 3 Down" }, - { 0, KEY_POV_2_LEFT, "KEY_POV_2_LEFT", "Hat 3 Left" }, - { 0, KEY_POV_2_RIGHT, "KEY_POV_2_RIGHT", "Hat 3 Right" }, - { 0, KEY_POV_3_UP, "KEY_POV_3_UP", "Hat 4 Up" }, - { 0, KEY_POV_3_DOWN, "KEY_POV_3_DOWN", "Hat 4 Down" }, - { 0, KEY_POV_3_LEFT, "KEY_POV_3_LEFT", "Hat 4 Left" }, - { 0, KEY_POV_3_RIGHT, "KEY_POV_3_RIGHT", "Hat 4 Right" }, - - { 0, 186, ";", ";" }, - { 0, 188, ",", "<" }, - { 0, 190, ".", ">" }, - { 0, 191, "/", "/" }, - { 0, 192, "~", "~" }, - { 0, 219, "[", "[" }, - { 0, 220, "\\", "\\" }, - { 0, 221, "]", "]" }, - { 0, 222, "'", "'" }, - - { 0, '0', "0", "0" }, - { 0, '1', "1", "1" }, - { 0, '2', "2", "2" }, - { 0, '3', "3", "3" }, - { 0, '4', "4", "4" }, - { 0, '5', "5", "5" }, - { 0, '6', "6", "6" }, - { 0, '7', "7", "7" }, - { 0, '8', "8", "8" }, - { 0, '9', "9", "9" }, - - { 0, 'A', "A", "A" }, - { 0, 'B', "B", "B" }, - { 0, 'C', "C", "C" }, - { 0, 'D', "D", "D" }, - { 0, 'E', "E", "E" }, - { 0, 'F', "F", "F" }, - { 0, 'G', "G", "G" }, - { 0, 'H', "H", "H" }, - { 0, 'I', "I", "I" }, - { 0, 'J', "J", "J" }, - { 0, 'K', "K", "K" }, - { 0, 'L', "L", "L" }, - { 0, 'M', "M", "M" }, - { 0, 'N', "N", "N" }, - { 0, 'O', "O", "O" }, - { 0, 'P', "P", "P" }, - { 0, 'Q', "Q", "Q" }, - { 0, 'R', "R", "R" }, - { 0, 'S', "S", "S" }, - { 0, 'T', "T", "T" }, - { 0, 'U', "U", "U" }, - { 0, 'V', "V", "V" }, - { 0, 'W', "W", "W" }, - { 0, 'X', "X", "X" }, - { 0, 'Y', "Y", "Y" }, - { 0, 'Z', "Z", "Z" }, - -}; - -// +----------------------------------------------------------------------+ - -int KeyMap::GetKeyAction(const char* act_str) -{ - if (!act_str) return -1; - - int nactions = sizeof(key_action_table) / sizeof(KeyName); - - for (int i = 0; i < nactions; i++) - if (!_stricmp(act_str, key_action_table[i].name)) - return key_action_table[i].key; - - return -1; -} - -// +----------------------------------------------------------------------+ - -int KeyMap::GetKeyActionIndex(int act) -{ - int nactions = sizeof(key_action_table) / sizeof(KeyName); - - for (int i = 0; i < nactions; i++) - if (key_action_table[i].key == act) - return i; - - return -1; -} - -// +----------------------------------------------------------------------+ - -int KeyMap::GetKeyKey(const char* key_str) -{ - if (!key_str) return 0; - - if (*key_str == '=') { - int value = 0; - sscanf_s(key_str, "=%d", &value); - return value; - } - - int nkeys = sizeof(key_key_table) / sizeof(KeyName); - - for (int i = 0; i < nkeys; i++) - if (!_stricmp(key_str, key_key_table[i].name)) - return key_key_table[i].key; - - return 0; -} - -// +----------------------------------------------------------------------+ - -int KeyMap::GetKeyKeyIndex(int key) -{ - int nkeys = sizeof(key_key_table) / sizeof(KeyName); - - for (int i = 0; i < nkeys; i++) - if (key_key_table[i].key == key) - return i; - - return -1; -} - -// +----------------------------------------------------------------------+ - - -KeyMap::KeyMap() -: nkeys(0) -{ - int n = BuildDefaultKeyMap(); - DefaultKeyMap(n); -} - -KeyMap::~KeyMap() -{ } - -// +----------------------------------------------------------------------+ - -int -KeyMap::BuildDefaultKeyMap() -{ - int i = 0; - - defmap[i++] = KeyMapEntry(KEY_PITCH_UP, VK_DOWN); - defmap[i++] = KeyMapEntry(KEY_PITCH_DOWN, VK_UP); - defmap[i++] = KeyMapEntry(KEY_YAW_LEFT, VK_LEFT); - defmap[i++] = KeyMapEntry(KEY_YAW_RIGHT, VK_RIGHT); - defmap[i++] = KeyMapEntry(KEY_ROLL_LEFT, VK_NUMPAD7); - defmap[i++] = KeyMapEntry(KEY_ROLL_RIGHT, VK_NUMPAD9); - - defmap[i++] = KeyMapEntry(KEY_PLUS_X, 190, 0, KEY_POV_0_RIGHT); // . - defmap[i++] = KeyMapEntry(KEY_MINUS_X, 188, 0, KEY_POV_0_LEFT); // , - defmap[i++] = KeyMapEntry(KEY_PLUS_Y, VK_HOME); - defmap[i++] = KeyMapEntry(KEY_MINUS_Y, VK_END); - defmap[i++] = KeyMapEntry(KEY_PLUS_Z, VK_PRIOR, 0, KEY_POV_0_UP); - defmap[i++] = KeyMapEntry(KEY_MINUS_Z, VK_NEXT, 0, KEY_POV_0_DOWN); - - defmap[i++] = KeyMapEntry(KEY_ACTION_0, VK_CONTROL, 0, KEY_JOY_1); - defmap[i++] = KeyMapEntry(KEY_ACTION_1, VK_SPACE, 0, KEY_JOY_2); - - - defmap[i++] = KeyMapEntry(KEY_THROTTLE_UP, 'A'); - defmap[i++] = KeyMapEntry(KEY_THROTTLE_DOWN, 'Z'); - defmap[i++] = KeyMapEntry(KEY_THROTTLE_FULL, 'A', VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_THROTTLE_ZERO, 'Z', VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_AUGMENTER, VK_TAB); - defmap[i++] = KeyMapEntry(KEY_FLCS_MODE_AUTO, 'M'); - defmap[i++] = KeyMapEntry(KEY_COMMAND_MODE, 'M', VK_SHIFT); - - defmap[i++] = KeyMapEntry(KEY_CYCLE_PRIMARY, VK_BACK, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CYCLE_SECONDARY, VK_BACK); - defmap[i++] = KeyMapEntry(KEY_LOCK_TARGET, 'T', 0, KEY_JOY_3); - defmap[i++] = KeyMapEntry(KEY_LOCK_THREAT, 'T', VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_LOCK_CLOSEST_SHIP, 'U'); - defmap[i++] = KeyMapEntry(KEY_LOCK_CLOSEST_THREAT, 'U', VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_LOCK_HOSTILE_SHIP, 'Y'); - defmap[i++] = KeyMapEntry(KEY_LOCK_HOSTILE_THREAT, 'Y', VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CYCLE_SUBTARGET, 186); - defmap[i++] = KeyMapEntry(KEY_PREV_SUBTARGET, 186, VK_SHIFT); - - defmap[i++] = KeyMapEntry(KEY_DECOY, 'D', 0, KEY_JOY_4); - defmap[i++] = KeyMapEntry(KEY_GEAR_TOGGLE, 'G'); - defmap[i++] = KeyMapEntry(KEY_NAVLIGHT_TOGGLE, 'L'); - - defmap[i++] = KeyMapEntry(KEY_AUTO_NAV, 'N', VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_DROP_ORBIT, 'O'); - - defmap[i++] = KeyMapEntry(KEY_SHIELDS_UP, 'S'); - defmap[i++] = KeyMapEntry(KEY_SHIELDS_DOWN, 'X'); - defmap[i++] = KeyMapEntry(KEY_SHIELDS_FULL, 'S', VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_SHIELDS_ZERO, 'X', VK_SHIFT); - - defmap[i++] = KeyMapEntry(KEY_SENSOR_MODE, VK_F5); - defmap[i++] = KeyMapEntry(KEY_SENSOR_GROUND_MODE, VK_F5, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_LAUNCH_PROBE, VK_F6); - defmap[i++] = KeyMapEntry(KEY_SENSOR_RANGE_MINUS, VK_F7); - defmap[i++] = KeyMapEntry(KEY_SENSOR_RANGE_PLUS, VK_F8); - defmap[i++] = KeyMapEntry(KEY_EMCON_MINUS, VK_F9); - defmap[i++] = KeyMapEntry(KEY_EMCON_PLUS, VK_F10); - - defmap[i++] = KeyMapEntry(KEY_EXIT, VK_ESCAPE); - defmap[i++] = KeyMapEntry(KEY_PAUSE, VK_PAUSE); - // defmap[i++] = KeyMapEntry(KEY_NEXT_VIEW, VK_TAB); - defmap[i++] = KeyMapEntry(KEY_TIME_EXPAND, VK_DELETE); - defmap[i++] = KeyMapEntry(KEY_TIME_COMPRESS, VK_INSERT); - defmap[i++] = KeyMapEntry(KEY_TIME_SKIP, VK_INSERT, VK_SHIFT); - - defmap[i++] = KeyMapEntry(KEY_CAM_BRIDGE, VK_F1); - defmap[i++] = KeyMapEntry(KEY_CAM_VIRT, VK_F1, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CAM_CHASE, VK_F2); - defmap[i++] = KeyMapEntry(KEY_CAM_DROP, VK_F2, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CAM_EXTERN, VK_F3); - defmap[i++] = KeyMapEntry(KEY_TARGET_PADLOCK, VK_F4); - - defmap[i++] = KeyMapEntry(KEY_ZOOM_WIDE, 'K'); - defmap[i++] = KeyMapEntry(KEY_HUD_MODE, 'H'); - defmap[i++] = KeyMapEntry(KEY_HUD_COLOR, 'H', VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_HUD_WARN, 'C'); - defmap[i++] = KeyMapEntry(KEY_HUD_INST, 'I'); - defmap[i++] = KeyMapEntry(KEY_NAV_DLG, 'N'); - defmap[i++] = KeyMapEntry(KEY_WEP_DLG, 'W'); - defmap[i++] = KeyMapEntry(KEY_ENG_DLG, 'E'); - defmap[i++] = KeyMapEntry(KEY_FLT_DLG, 'F'); - defmap[i++] = KeyMapEntry(KEY_RADIO_MENU, 'R'); - defmap[i++] = KeyMapEntry(KEY_QUANTUM_MENU, 'Q'); - - defmap[i++] = KeyMapEntry(KEY_MFD1, 219); // [ - defmap[i++] = KeyMapEntry(KEY_MFD2, 221); // ] - defmap[i++] = KeyMapEntry(KEY_SELF_DESTRUCT, VK_ESCAPE, VK_SHIFT); - - defmap[i++] = KeyMapEntry(KEY_CAM_CYCLE_OBJECT, VK_TAB, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CAM_EXT_PLUS_AZ, VK_LEFT, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CAM_EXT_MINUS_AZ, VK_RIGHT, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CAM_EXT_PLUS_EL, VK_UP, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CAM_EXT_MINUS_EL, VK_DOWN, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CAM_EXT_PLUS_RANGE, VK_SUBTRACT); - defmap[i++] = KeyMapEntry(KEY_CAM_EXT_MINUS_RANGE, VK_ADD); - defmap[i++] = KeyMapEntry(KEY_CAM_VIEW_SELECTION, 'V'); - defmap[i++] = KeyMapEntry(KEY_CAM_VIRT_PLUS_AZ, VK_LEFT, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CAM_VIRT_MINUS_AZ, VK_RIGHT, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CAM_VIRT_PLUS_EL, VK_DOWN, VK_SHIFT); - defmap[i++] = KeyMapEntry(KEY_CAM_VIRT_MINUS_EL, VK_UP, VK_SHIFT); - - defmap[i++] = KeyMapEntry(KEY_SWAP_ROLL_YAW, 'J'); - - defmap[i++] = KeyMapEntry(KEY_COMM_ATTACK_TGT, 'A', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_COMM_ESCORT_TGT, 'E', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_COMM_WEP_FREE, 'B', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_COMM_WEP_HOLD, 'F', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_COMM_COVER_ME, 'H', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_COMM_SKIP_NAV, 'N', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_COMM_RETURN_TO_BASE, 'R', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_COMM_CALL_INBOUND, 'I', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_COMM_REQUEST_PICTURE,'P', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_COMM_REQUEST_SUPPORT,'S', VK_MENU); - - defmap[i++] = KeyMapEntry(KEY_CHAT_BROADCAST, '1', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_CHAT_TEAM, '2', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_CHAT_WING, '3', VK_MENU); - defmap[i++] = KeyMapEntry(KEY_CHAT_UNIT, '4', VK_MENU); - - defmap[i++] = KeyMapEntry(KEY_CONTROL_MODEL, 0); - - defmap[i++] = KeyMapEntry(KEY_JOY_SELECT, 1); - defmap[i++] = KeyMapEntry(KEY_JOY_RUDDER, 0); - defmap[i++] = KeyMapEntry(KEY_JOY_THROTTLE, 1); - defmap[i++] = KeyMapEntry(KEY_JOY_SENSE, 1); - defmap[i++] = KeyMapEntry(KEY_JOY_DEAD_ZONE, 500); - - defmap[i++] = KeyMapEntry(KEY_MOUSE_SELECT, 1); - defmap[i++] = KeyMapEntry(KEY_MOUSE_SENSE, 10); - defmap[i++] = KeyMapEntry(KEY_MOUSE_ACTIVE, 192); // ~ key - - /*** For Debug Convenience Only: ***/ - defmap[i++] = KeyMapEntry(KEY_INC_STARDATE, VK_F11); - defmap[i++] = KeyMapEntry(KEY_DEC_STARDATE, VK_F11, VK_SHIFT); - /***/ - - return i; -} - -// +----------------------------------------------------------------------+ - -int -KeyMap::DefaultKeyMap(int max_keys) -{ - for (int i = 0; i < max_keys; i++) - map[i] = defmap[i]; - - nkeys = max_keys; - return nkeys; -} - -void -KeyMap::Bind(int a, int k, int s) -{ - if (!a) return; - - for (int i = 0; i < nkeys; i++) { - if (map[i].act == a) { - map[i].key = k; - map[i].alt = s; - - return; - } - } - - map[nkeys++] = KeyMapEntry(a, k, s); -} - -// +----------------------------------------------------------------------+ - -int -KeyMap::LoadKeyMap(const char* filename, int max_keys) -{ - FILE* f; - fopen_s(&f, filename, "rb"); - - if (!f) return nkeys; - - char line[256]; - - while (fgets(line, sizeof(line), f)) { - int act = -1, key = -1, alt = 0, joy = -1; - char act_str[128], key_str[128], alt_str[128], joy_str[128]; - - ZeroMemory(act_str, sizeof(act_str)); - ZeroMemory(key_str, sizeof(key_str)); - ZeroMemory(alt_str, sizeof(alt_str)); - ZeroMemory(joy_str, sizeof(joy_str)); - - sscanf(line, "%s %s %s %s", act_str, key_str, alt_str, joy_str); - - act = GetKeyAction(act_str); - key = GetKeyKey(key_str); - alt = GetKeyKey(alt_str); - joy = GetKeyKey(joy_str); - - if (act != -1 && key != -1) { - if (act == KEY_CONTROL_MODEL) - Ship::SetControlModel(key); - - int mapped = false; - - for (int i = 0; i < max_keys && !mapped; i++) { - if (map[i].act == act) { - Print(" Remapping: '%s' => %s(%d) %s(%d) %s(%d)\n", - act_str, key_str, key, alt_str, alt, joy_str, joy); - - map[i] = KeyMapEntry(act, key, alt, joy); - mapped = true; - } - } - - if (!mapped) { - Print(" Mapping: '%s' => %s(%d) %s(%d) %s(%d)\n", - act_str, key_str, key, alt_str, alt, joy_str, joy); - map[nkeys++] = KeyMapEntry(act, key, alt, joy); - } - } - - if (nkeys >= max_keys-1) { - Print(" Too many keys in configuration...\n"); - break; - } - } - - fclose(f); - return nkeys; -} - -// +----------------------------------------------------------------------+ - -int -KeyMap::SaveKeyMap(const char* filename, int max_keys) -{ - FILE* f; - fopen_s(&f, filename, "wb"); - if (!f) return 0; - - for (int i = 0; i < nkeys; i++) { - if (map[i].act >= KEY_CONTROL_MODEL && - map[i].act <= KEY_AXIS_THROTTLE_INVERT) { - - int a = GetKeyActionIndex(map[i].act); - - fprintf(f, "%-24s =%d\n", key_action_table[a].name, map[i].key); - } - - else if (map[i] != defmap[i]) { - int a = GetKeyActionIndex(map[i].act); - int k = GetKeyKeyIndex(map[i].key); - int s = GetKeyKeyIndex(map[i].alt); - int j = GetKeyKeyIndex(map[i].joy); - - if (a > -1) { - if (j > -1) { - if (s > -1) { - fprintf(f, "%-24s %-16s %-16s %-16s\n", - key_action_table[a].name, - key_key_table[ k].name, - key_key_table[ s].name, - key_key_table[ j].name); - } - else if (k > -1) { - fprintf(f, "%-24s %-16s %-16s %-16s\n", - key_action_table[a].name, - key_key_table[ k].name, - "null", - key_key_table[ j].name); - } - else { - fprintf(f, "%-24s %-16s %-16s %-16s\n", - key_action_table[a].name, - "null", - "null", - key_key_table[ j].name); - } - } - else if (s > -1) { - fprintf(f, "%-24s %-16s %-16s\n", - key_action_table[a].name, - key_key_table[ k].name, - key_key_table[ s].name); - } - else if (k > -1) { - fprintf(f, "%-24s %-16s\n", - key_action_table[a].name, - key_key_table[ k].name); - } - } - } - } - - fclose(f); - return nkeys; -} - -// +----------------------------------------------------------------------+ - -int -KeyMap::GetCategory(int n) -{ - int nactions = sizeof(key_action_table) / sizeof(KeyName); - - for (int i = 0; i < nactions; i++) { - if (map[n].act == key_action_table[i].key) { - return key_action_table[i].category; - } - } - - return KEY_MISC; -} - -// +----------------------------------------------------------------------+ - -int -KeyMap::FindMapIndex(int act) -{ - for (int n = 0; n < nkeys; n++) - if (map[n].act == act) - return n; - return -1; -} - -// +----------------------------------------------------------------------+ - -const char* -KeyMap::DescribeAction(int n) -{ - int nactions = sizeof(key_action_table) / sizeof(KeyName); - - for (int i = 0; i < nactions; i++) { - if (map[n].act == key_action_table[i].key) { - if (key_action_table[i].desc) - return key_action_table[i].desc; - - return key_action_table[i].name; - } - } - - return 0; -} - -// +----------------------------------------------------------------------+ - -static char key_desc[32]; - -const char* -KeyMap::DescribeKey(int n) -{ - if (n >= 0 && n < 256) - return DescribeKey(map[n].key, map[n].alt, map[n].joy); - - return 0; -} - -const char* -KeyMap::DescribeKey(int vk, int shift, int j) -{ - const char* key = 0; - const char* alt = 0; - const char* joy = 0; - - int nkeys = sizeof(key_key_table) / sizeof(KeyName); - - for (int i = 0; i < nkeys; i++) { - if (vk > 0 && vk == key_key_table[i].key) { - if (key_key_table[i].desc) - key = key_key_table[i].desc; - else - key = key_key_table[i].name; - } - - if (shift > 0 && shift == key_key_table[i].key) { - if (key_key_table[i].desc) - alt = key_key_table[i].desc; - else - alt = key_key_table[i].name; - } - - if (j > 0 && j == key_key_table[i].key) { - if (key_key_table[i].desc) - joy = key_key_table[i].desc; - else - joy = key_key_table[i].name; - } - } - - if (key) { - if (alt) { - sprintf_s(key_desc, "%s+%s", alt, key); - } - else { - strcpy_s(key_desc, key); - } - - if (joy) { - strcat_s(key_desc, ", "); - strcat_s(key_desc, joy); - } - } - - else if (joy) { - strcpy_s(key_desc, joy); - } - - else { - sprintf_s(key_desc, "%d", vk); - } - - return key_desc; -} - -int -KeyMap::GetMappableVKey(int n) -{ - int nkeys = sizeof(key_key_table) / sizeof(KeyName); - - if (n >= 0 && n < nkeys) { - return key_key_table[n].key; - } - - return 0; -} \ No newline at end of file diff --git a/Stars45/KeyMap.h b/Stars45/KeyMap.h deleted file mode 100644 index 1ec7bbc..0000000 --- a/Stars45/KeyMap.h +++ /dev/null @@ -1,180 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Keyboard Mapping -*/ - -#ifndef KeyMap_h -#define KeyMap_h - -#include "Types.h" -#include "Geometry.h" -#include "MotionController.h" - -// +--------------------------------------------------------------------+ - -class KeyMap -{ -public: - KeyMap(); - virtual ~KeyMap(); - - int DefaultKeyMap(int max_keys = 256); - int LoadKeyMap(const char* filename, int max_keys = 256); - int SaveKeyMap(const char* filename, int max_keys = 256); - - enum KEY_CATEGORY { KEY_FLIGHT, KEY_WEAPONS, KEY_VIEW, KEY_MISC }; - - int GetCategory(int i); - const char* DescribeAction(int i); - const char* DescribeKey(int i); - int FindMapIndex(int act); - - static const char* DescribeKey(int vk, int shift, int joy); - static int GetMappableVKey(int n); - - int GetNumKeys() { return nkeys; } - KeyMapEntry* GetMapping() { return map; } - KeyMapEntry* GetKeyMap(int i) { return &map[i]; } - KeyMapEntry* GetDefault(int i) { return &defmap[i]; } - - void Bind(int a, int k, int s); - - static int GetKeyAction(const char* act_str); - static int GetKeyActionIndex(int act); - static int GetKeyKey(const char* key_str); - static int GetKeyKeyIndex(int key); - -protected: - int BuildDefaultKeyMap(); - - KeyMapEntry map[256]; - KeyMapEntry defmap[256]; - int nkeys; -}; - -// +--------------------------------------------------------------------+ - - -const int KEY_EXIT = 0 + KEY_USER_BASE; -const int KEY_PAUSE = 1 + KEY_USER_BASE; -const int KEY_NEXT_VIEW = 2 + KEY_USER_BASE; -const int KEY_TARGET_PADLOCK = 3 + KEY_USER_BASE; -const int KEY_THREAT_PADLOCK = 4 + KEY_USER_BASE; -const int KEY_LOCK_TARGET = 5 + KEY_USER_BASE; -const int KEY_LOCK_THREAT = 6 + KEY_USER_BASE; -const int KEY_AUTO_NAV = 7 + KEY_USER_BASE; -const int KEY_TIME_COMPRESS = 8 + KEY_USER_BASE; -const int KEY_TIME_EXPAND = 9 + KEY_USER_BASE; -const int KEY_TIME_SKIP = 10 + KEY_USER_BASE; - -const int KEY_SWAP_ROLL_YAW = 11 + KEY_USER_BASE; - -const int KEY_THROTTLE_UP = 15 + KEY_USER_BASE; -const int KEY_THROTTLE_DOWN = 16 + KEY_USER_BASE; -const int KEY_THROTTLE_ZERO = 17 + KEY_USER_BASE; -const int KEY_THROTTLE_FULL = 18 + KEY_USER_BASE; -const int KEY_CYCLE_PRIMARY = 19 + KEY_USER_BASE; -const int KEY_CYCLE_SECONDARY = 20 + KEY_USER_BASE; -const int KEY_FLCS_MODE_AUTO = 21 + KEY_USER_BASE; -const int KEY_DROP_ORBIT = 22 + KEY_USER_BASE; - -const int KEY_HUD_INST = 23 + KEY_USER_BASE; -const int KEY_CAM_BRIDGE = 24 + KEY_USER_BASE; -const int KEY_CAM_CHASE = 25 + KEY_USER_BASE; -const int KEY_CAM_EXTERN = 26 + KEY_USER_BASE; -const int KEY_HUD_MODE = 27 + KEY_USER_BASE; -const int KEY_HUD_COLOR = 28 + KEY_USER_BASE; -const int KEY_HUD_WARN = 29 + KEY_USER_BASE; -const int KEY_NAV_DLG = 30 + KEY_USER_BASE; -const int KEY_WEP_DLG = 31 + KEY_USER_BASE; -const int KEY_FLT_DLG = 32 + KEY_USER_BASE; -const int KEY_ENG_DLG = 33 + KEY_USER_BASE; - -const int KEY_ZOOM_WIDE = 34 + KEY_USER_BASE; -const int KEY_ZOOM_IN = 35 + KEY_USER_BASE; -const int KEY_ZOOM_OUT = 36 + KEY_USER_BASE; -const int KEY_CAM_CYCLE_OBJECT = 37 + KEY_USER_BASE; -const int KEY_CAM_EXT_PLUS_AZ = 38 + KEY_USER_BASE; -const int KEY_CAM_EXT_MINUS_AZ = 39 + KEY_USER_BASE; -const int KEY_CAM_EXT_PLUS_EL = 40 + KEY_USER_BASE; -const int KEY_CAM_EXT_MINUS_EL = 41 + KEY_USER_BASE; -const int KEY_CAM_EXT_PLUS_RANGE = 42 + KEY_USER_BASE; -const int KEY_CAM_EXT_MINUS_RANGE = 43 + KEY_USER_BASE; -const int KEY_CAM_VIEW_SELECTION = 44 + KEY_USER_BASE; -const int KEY_CAM_DROP = 45 + KEY_USER_BASE; - -const int KEY_TARGET_SELECTION = 50 + KEY_USER_BASE; -const int KEY_RADIO_MENU = 51 + KEY_USER_BASE; -const int KEY_QUANTUM_MENU = 52 + KEY_USER_BASE; -const int KEY_MFD1 = 53 + KEY_USER_BASE; -const int KEY_MFD2 = 54 + KEY_USER_BASE; -const int KEY_MFD3 = 55 + KEY_USER_BASE; -const int KEY_MFD4 = 56 + KEY_USER_BASE; - -const int KEY_SENSOR_MODE = 60 + KEY_USER_BASE; -const int KEY_SENSOR_GROUND_MODE = 61 + KEY_USER_BASE; -const int KEY_SENSOR_BEAM = 62 + KEY_USER_BASE; -const int KEY_SENSOR_RANGE_PLUS = 63 + KEY_USER_BASE; -const int KEY_SENSOR_RANGE_MINUS = 64 + KEY_USER_BASE; -const int KEY_EMCON_PLUS = 65 + KEY_USER_BASE; -const int KEY_EMCON_MINUS = 66 + KEY_USER_BASE; - -const int KEY_SHIELDS_UP = 67 + KEY_USER_BASE; -const int KEY_SHIELDS_DOWN = 68 + KEY_USER_BASE; -const int KEY_SHIELDS_FULL = 69 + KEY_USER_BASE; -const int KEY_SHIELDS_ZERO = 70 + KEY_USER_BASE; -const int KEY_DECOY = 71 + KEY_USER_BASE; -const int KEY_ECM_TOGGLE = 72 + KEY_USER_BASE; -const int KEY_LAUNCH_PROBE = 73 + KEY_USER_BASE; -const int KEY_GEAR_TOGGLE = 74 + KEY_USER_BASE; - -const int KEY_LOCK_CLOSEST_SHIP = 75 + KEY_USER_BASE; -const int KEY_LOCK_CLOSEST_THREAT = 76 + KEY_USER_BASE; -const int KEY_LOCK_HOSTILE_SHIP = 77 + KEY_USER_BASE; -const int KEY_LOCK_HOSTILE_THREAT = 78 + KEY_USER_BASE; -const int KEY_CYCLE_SUBTARGET = 79 + KEY_USER_BASE; -const int KEY_PREV_SUBTARGET = 80 + KEY_USER_BASE; - -const int KEY_AUGMENTER = 81 + KEY_USER_BASE; -const int KEY_NAVLIGHT_TOGGLE = 82 + KEY_USER_BASE; - -const int KEY_CAM_VIRT = 85 + KEY_USER_BASE; -const int KEY_CAM_VIRT_PLUS_AZ = 86 + KEY_USER_BASE; -const int KEY_CAM_VIRT_MINUS_AZ = 87 + KEY_USER_BASE; -const int KEY_CAM_VIRT_PLUS_EL = 88 + KEY_USER_BASE; -const int KEY_CAM_VIRT_MINUS_EL = 89 + KEY_USER_BASE; - -const int KEY_COMM_ATTACK_TGT = 90 + KEY_USER_BASE; -const int KEY_COMM_ESCORT_TGT = 91 + KEY_USER_BASE; -const int KEY_COMM_WEP_FREE = 92 + KEY_USER_BASE; -const int KEY_COMM_WEP_HOLD = 93 + KEY_USER_BASE; -const int KEY_COMM_COVER_ME = 94 + KEY_USER_BASE; -const int KEY_COMM_SKIP_NAV = 95 + KEY_USER_BASE; -const int KEY_COMM_RETURN_TO_BASE = 96 + KEY_USER_BASE; -const int KEY_COMM_CALL_INBOUND = 97 + KEY_USER_BASE; -const int KEY_COMM_REQUEST_PICTURE = 98 + KEY_USER_BASE; -const int KEY_COMM_REQUEST_SUPPORT = 99 + KEY_USER_BASE; - -const int KEY_CHAT_BROADCAST = 100 + KEY_USER_BASE; -const int KEY_CHAT_TEAM = 101 + KEY_USER_BASE; -const int KEY_CHAT_WING = 102 + KEY_USER_BASE; -const int KEY_CHAT_UNIT = 103 + KEY_USER_BASE; - -const int KEY_COMMAND_MODE = 104 + KEY_USER_BASE; -const int KEY_SELF_DESTRUCT = 105 + KEY_USER_BASE; - -/*** For Debug Convenience Only: ***/ -const int KEY_INC_STARDATE = 120 + KEY_USER_BASE; -const int KEY_DEC_STARDATE = 121 + KEY_USER_BASE; -/***/ - -#endif // KeyMap_h - diff --git a/Stars45/Keyboard.cpp b/Stars45/Keyboard.cpp deleted file mode 100644 index 63b93e9..0000000 --- a/Stars45/Keyboard.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Keyboard Input class -*/ - -#include "Keyboard.h" -#include "Game.h" - -// +--------------------------------------------------------------------+ - -static Keyboard* instance = 0; -int Keyboard::map[KEY_MAP_SIZE]; -int Keyboard::alt[KEY_MAP_SIZE]; - -Keyboard::Keyboard() -: x(0), y(0), z(0), p(0), r(0), w(0), c(0), p1(0), r1(0), w1(0), t(0) -{ - instance = this; - sensitivity = 25; - dead_zone = 100; - - for (int i = 0; i < MotionController::MaxActions; i++) - action[i] = 0; - - memset(map, 0, sizeof(map)); - memset(alt, 0, sizeof(alt)); - - map[KEY_PLUS_X] = 'R'; - map[KEY_MINUS_X] = 'E'; - map[KEY_PLUS_Y] = VK_HOME; - map[KEY_MINUS_Y] = VK_END; - map[KEY_PLUS_Z] = VK_PRIOR; // page up - map[KEY_MINUS_Z] = VK_NEXT; // page down - - map[KEY_PITCH_UP] = VK_DOWN; - map[KEY_PITCH_DOWN] = VK_UP; - map[KEY_YAW_LEFT] = VK_LEFT; - map[KEY_YAW_RIGHT] = VK_RIGHT; - map[KEY_ROLL_ENABLE] = 0; // used to be VK_CONTROL; -} - -Keyboard::~Keyboard() -{ - instance = 0; -} - -Keyboard* -Keyboard::GetInstance() -{ - return instance; -} - -// +--------------------------------------------------------------------+ - -void -Keyboard::MapKeys(KeyMapEntry* mapping, int nkeys) -{ - for (int i = 0; i < nkeys; i++) { - KeyMapEntry k = mapping[i]; - - if (k.act >= KEY_MAP_FIRST && k.act <= KEY_MAP_LAST) { - if (k.key == 0 || k.key > VK_MBUTTON && k.key < KEY_JOY_1) { - map[k.act] = k.key; - alt[k.act] = k.alt; - } - } - } -} - -// +--------------------------------------------------------------------+ - -bool Keyboard::KeyDown(int key) -{ - if (key) { - short k = GetAsyncKeyState(key); - return (k<0)||(k&1); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -bool Keyboard::KeyDownMap(int key) -{ - if (key >= KEY_MAP_FIRST && key <= KEY_MAP_LAST && map[key]) { - short k = GetAsyncKeyState(map[key]); - short a = -1; - - if (alt[key] > 0 && alt[key] < KEY_JOY_1) { - a = GetAsyncKeyState(alt[key]); - } - else { - a = !GetAsyncKeyState(VK_SHIFT) && - !GetAsyncKeyState(VK_MENU); - } - - return ((k<0)||(k&1)) && ((a<0)||(a&1)); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Keyboard::FlushKeys() -{ - for (int i = 0; i < 255; i++) - GetAsyncKeyState(i); -} - -// +--------------------------------------------------------------------+ - -static inline double sqr(double a) { return a; } //*a; } - -void -Keyboard::Acquire() -{ - t = x = y = z = p = r = w = c = 0; - - for (int i = 0; i < MotionController::MaxActions; i++) - action[i] = 0; - - int speed = 10; - - // lateral translations: - if (KeyDownMap(KEY_PLUS_Y)) y = 1; - else if (KeyDownMap(KEY_MINUS_Y)) y = -1; - - if (KeyDownMap(KEY_PLUS_Z)) z = 1; - else if (KeyDownMap(KEY_MINUS_Z)) z = -1; - - if (KeyDownMap(KEY_MINUS_X)) x = -1; - else if (KeyDownMap(KEY_PLUS_X)) x = 1; - - const double steps=10; - - // if roll and yaw are swapped -------------------------- - if (swapped) { - // yaw: - if (KeyDownMap(KEY_ROLL_LEFT)) { if (w1GetText("sys.landing-gear"); - abrv = ContentBundle::GetInstance()->GetText("sys.landing-gear.abrv"); - - for (int i = 0; i < MAX_GEAR; i++) { - models[i] = 0; - gear[i] = 0; - } -} - -// +----------------------------------------------------------------------+ - -LandingGear::LandingGear(const LandingGear& g) -: System(g), state(GEAR_UP), transit(0), ngear(g.ngear), clearance(0) -{ - Mount(g); - SetAbbreviation(g.Abbreviation()); - int i; - - for (i = 0; i < ngear; i++) { - models[i] = 0; - gear[i] = new Solid; - start[i] = g.start[i]; - end[i] = g.end[i]; - - gear[i]->UseModel(g.models[i]); - - if (clearance > end[i].y) - clearance = end[i].y; - } - - while (i < MAX_GEAR) { - models[i] = 0; - gear[i] = 0; - i++; - } - - clearance += mount_rel.y; -} - -// +--------------------------------------------------------------------+ - -LandingGear::~LandingGear() -{ - for (int i = 0; i < MAX_GEAR; i++) { - delete models[i]; - - if (gear[i]) { - Solid* g = gear[i]; - - if (g->GetScene()) - g->GetScene()->DelGraphic(g); - delete g; - } - } -} - -// +--------------------------------------------------------------------+ - -void -LandingGear::Initialize() -{ - if (!gear_transit_sound) { - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Sounds/"); - loader->LoadSound("GearTransit.wav", gear_transit_sound); - } -} - -// +--------------------------------------------------------------------+ - -void -LandingGear::Close() -{ - delete gear_transit_sound; - gear_transit_sound = 0; -} - -// +--------------------------------------------------------------------+ - -int -LandingGear::AddGear(Model* m, const Point& s, const Point& e) -{ - if (ngear < MAX_GEAR) { - models[ngear] = m; - start[ngear] = s; - end[ngear] = e; - - ngear++; - } - - return ngear; -} - -// +--------------------------------------------------------------------+ - -void -LandingGear::SetState(GEAR_STATE s) -{ - if (state != s) { - state = s; - - if (ship && ship == Sim::GetSim()->GetPlayerShip()) { - if (state == GEAR_LOWER || state == GEAR_RAISE) { - if (gear_transit_sound) { - Sound* sound = gear_transit_sound->Duplicate(); - sound->SetVolume(AudioConfig::EfxVolume()); - sound->Play(); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -LandingGear::ExecFrame(double seconds) -{ - System::ExecFrame(seconds); - - switch (state) { - case GEAR_UP: - transit = 0; - break; - - case GEAR_DOWN: - transit = 1; - break; - - case GEAR_LOWER: - if (transit < 1) { - transit += seconds; - - Scene* s = 0; - if (ship && ship->Rep()) - s = ship->Rep()->GetScene(); - - if (s) { - for (int i = 0; i < ngear; i++) { - if (gear[i] && !gear[i]->GetScene()) { - s->AddGraphic(gear[i]); - } - } - } - } - else { - transit = 1; - state = GEAR_DOWN; - } - break; - - case GEAR_RAISE: - if (transit > 0) { - transit -= seconds; - } - else { - transit = 0; - state = GEAR_UP; - - for (int i = 0; i < ngear; i++) { - if (gear[i]) { - Scene* s = gear[i]->GetScene(); - if (s) s->DelGraphic(gear[i]); - } - } - } - break; - } -} - -// +--------------------------------------------------------------------+ - -void -LandingGear::Orient(const Physical* rep) -{ - System::Orient(rep); - - const Matrix& orientation = rep->Cam().Orientation(); - Point ship_loc = rep->Location(); - - for (int i = 0; i < ngear; i++) { - Point gloc; - if (transit < 1) gloc = start[i] + (end[i]-start[i])*transit; - else gloc = end[i]; - - Point projector = (gloc * orientation) + ship_loc; - if (gear[i]) { - gear[i]->MoveTo(projector); - gear[i]->SetOrientation(orientation); - } - } -} - -// +--------------------------------------------------------------------+ - -Solid* -LandingGear::GetGear(int index) -{ - if (index >= 0 && index < ngear) { - Solid* g = gear[index]; - return g; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -Point -LandingGear::GetGearStop(int index) -{ - if (index >= 0 && index < ngear) { - Solid* g = gear[index]; - - if (g) - return g->Location(); - } - - return Point(); -} - -// +--------------------------------------------------------------------+ - -double -LandingGear::GetTouchDown() -{ - double down = 0; - - if (ship) { - down = ship->Location().y; - - if (state != GEAR_UP) { - for (int i = 0; i < ngear; i++) { - if (gear[i]) { - Point stop = gear[i]->Location(); - - if (stop.y < down) - down = stop.y; - } - } - } - } - - return down; -} \ No newline at end of file diff --git a/Stars45/LandingGear.h b/Stars45/LandingGear.h deleted file mode 100644 index b753106..0000000 --- a/Stars45/LandingGear.h +++ /dev/null @@ -1,65 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Fighter undercarriage (landing gear) system class -*/ - -#ifndef LandingGear_h -#define LandingGear_h - -#include "Types.h" -#include "System.h" -#include "Solid.h" - -// +--------------------------------------------------------------------+ - -class Ship; - -// +--------------------------------------------------------------------+ - -class LandingGear : public System -{ -public: - enum CONSTANTS { MAX_GEAR = 4 }; - enum GEAR_STATE { GEAR_UP, GEAR_LOWER, GEAR_DOWN, GEAR_RAISE }; - - LandingGear(); - LandingGear(const LandingGear& rhs); - virtual ~LandingGear(); - - virtual int AddGear(Model* m, const Point& s, const Point& e); - virtual void ExecFrame(double seconds); - virtual void Orient(const Physical* rep); - - GEAR_STATE GetState() const { return state; } - void SetState(GEAR_STATE s); - int NumGear() const { return ngear; } - Solid* GetGear(int i); - Point GetGearStop(int i); - double GetTouchDown(); - double GetClearance() const { return clearance; } - - static void Initialize(); - static void Close(); - -protected: - GEAR_STATE state; - double transit; - double clearance; - - int ngear; - Model* models[MAX_GEAR]; - Solid* gear[MAX_GEAR]; - Point start[MAX_GEAR]; - Point end[MAX_GEAR]; -}; - -#endif // LandingGear_h - diff --git a/Stars45/Layout.cpp b/Stars45/Layout.cpp deleted file mode 100644 index 5637831..0000000 --- a/Stars45/Layout.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Layout Resource class implementation -*/ - -#include "Layout.h" - -// +--------------------------------------------------------------------+ - -Layout::Layout() -{ } - -Layout::~Layout() -{ } - -// +--------------------------------------------------------------------+ - -bool -Layout::DoLayout(ActiveWindow* panel) -{ - if (!panel || panel->GetChildren().size() < 1) - return false; - - if (cols.size() < 1 || rows.size() < 1) - return false; - - std::vector cell_x; - std::vector cell_y; - - ScaleWeights(); - CalcCells(panel->Width(), panel->Height(), cell_x, cell_y); - - ListIter iter = panel->GetChildren(); - while (++iter) { - ActiveWindow* w = iter.value(); - Rect c = w->GetCells(); - Rect r; - Rect rp = panel->GetRect(); - - if (c.x < 0) c.x = 0; - else if (c.x >= (int)cell_x.size()) c.x = cell_x.size() - 1; - if (c.y < 0) c.y = 0; - else if (c.y >= (int)cell_y.size()) c.y = cell_y.size() - 1; - if (c.x+c.w >= (int)cell_x.size()) c.w = cell_x.size() - c.x - 1; - if (c.y+c.h >= (int)cell_y.size()) c.h = cell_y.size() - c.y - 1; - - r.x = cell_x[c.x] + w->GetCellInsets().left; - r.y = cell_y[c.y] + w->GetCellInsets().top; - r.w = cell_x[c.x+c.w] - w->GetCellInsets().right - r.x; - r.h = cell_y[c.y+c.h] - w->GetCellInsets().bottom - r.y; - - r.x += panel->X(); - r.y += panel->Y(); - - if (w->GetFixedWidth() && w->GetFixedWidth() < r.w) - r.w = w->GetFixedWidth(); - - if (w->GetFixedHeight() && w->GetFixedHeight() < r.h) - r.h = w->GetFixedHeight(); - - if (w->GetID() == 330 || w->GetID() == 125) { - int y1 = r.y + r.h; - int y2 = rp.y + rp.h; - } - - if (w->GetHidePartial() && (r.x + r.w > rp.x + rp.w)) { - w->MoveTo(Rect(0,0,0,0)); - } - - else if (w->GetHidePartial() && (r.y + r.h > rp.y + rp.h)) { - w->MoveTo(Rect(0,0,0,0)); - } - - else { - w->MoveTo(r); - } - } - - return true; -} - -// +--------------------------------------------------------------------+ - -void -Layout::ScaleWeights() -{ - float total = 0; - - for (auto cwi = col_weights.begin(); cwi != col_weights.end(); ++cwi) - total += *cwi; - - if (total > 0) { - for (auto cwi = col_weights.begin(); cwi != col_weights.end(); ++cwi) - *cwi = *cwi / total; - } - - total = 0; - for (auto rwi = row_weights.begin(); rwi != row_weights.end(); ++rwi) - total += *rwi; - - if (total > 0) { - for (auto rwi = row_weights.begin(); rwi != row_weights.end(); ++rwi) - *rwi = *rwi / total; - } -} - -// +--------------------------------------------------------------------+ - -void - Layout::CalcCells(DWORD w, DWORD h, std::vector& cell_x, std::vector& cell_y) -{ - DWORD x = 0; - DWORD y = 0; - DWORD min_x = 0; - DWORD min_y = 0; - DWORD ext_x = 0; - DWORD ext_y = 0; - - for (auto cit = cols.begin(); cit != cols.end(); ++cit) - min_x += *cit; - - for (auto rit = rows.begin(); rit != rows.end(); ++rit) - min_y += *rit; - - if (min_x < w) - ext_x = w - min_x; - - if (min_y < h) - ext_y = h - min_y; - - cell_x.push_back(x); - for (auto cit = cols.begin(); cit != cols.end(); ++cit) { - x += *cit + (DWORD) (ext_x * col_weights[cit - cols.begin()]); - cell_x.push_back(x); - } - - cell_y.push_back(y); - for (auto rit = rows.begin(); rit != rows.end(); ++rit) { - y += *rit + (DWORD) (ext_y * row_weights[rit - rows.begin()]); - cell_y.push_back(y); - } -} - -// +--------------------------------------------------------------------+ - -void -Layout::Clear() -{ - cols.clear(); - rows.clear(); - - col_weights.clear(); - row_weights.clear(); -} - -void -Layout::AddCol(DWORD min_width, float col_factor) -{ - cols.push_back(min_width); - col_weights.push_back(col_factor); -} - -void -Layout::AddRow(DWORD min_height, float row_factor) -{ - rows.push_back(min_height); - row_weights.push_back(row_factor); -} - -void -Layout::SetConstraints(const std::vector& min_x, -const std::vector& min_y, -const std::vector& weight_x, -const std::vector& weight_y) -{ - Clear(); - - if (min_x.size() == weight_x.size() && min_y.size() == weight_y.size()) { - for (auto iter = min_x.begin(); iter != min_x.end(); ++iter) - cols.push_back(*iter); - - for (auto iter = min_y.begin(); iter != min_y.end(); ++iter) - rows.push_back(*iter); - - for (auto iter = weight_x.begin(); iter != weight_x.end(); ++iter) - col_weights.push_back(*iter); - - for (auto iter = weight_y.begin(); iter != weight_y.end(); ++iter) - row_weights.push_back(*iter); - } -} - -void -Layout::SetConstraints(const std::vector& min_x, -const std::vector& min_y, -const std::vector& weight_x, -const std::vector& weight_y) -{ - Clear(); - - if (min_x.size() == weight_x.size() && - min_y.size() == weight_y.size()) { - - for (auto iter = min_x.begin(); iter != min_x.end(); ++iter) - cols.push_back((DWORD) *iter); - - for (auto iter = min_y.begin(); iter != min_y.end(); ++iter) - rows.push_back((DWORD) *iter); - - for (auto iter = weight_x.begin(); iter != weight_x.end(); ++iter) - col_weights.push_back(*iter); - - for (auto iter = weight_y.begin(); iter != weight_y.end(); ++iter) - row_weights.push_back(*iter); - } -} - -void -Layout::SetConstraints(int ncols, -int nrows, -const int* min_x, -const int* min_y, -const float* weight_x, -const float* weight_y) -{ - Clear(); - - if (nrows > 0 && ncols > 0) { - int i = 0; - - for (i = 0; i < ncols; i++) { - cols.push_back(min_x[i]); - col_weights.push_back(weight_x[i]); - } - - for (i = 0; i < nrows; i++) { - rows.push_back(min_y[i]); - row_weights.push_back(weight_y[i]); - } - } -} diff --git a/Stars45/Layout.h b/Stars45/Layout.h deleted file mode 100644 index 51402d7..0000000 --- a/Stars45/Layout.h +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Layout Manager class for ActiveWindow panels -*/ - -#ifndef Layout_h -#define Layout_h - -#include "ActiveWindow.h" - -// +--------------------------------------------------------------------+ - -class Layout -{ -public: - static const char* TYPENAME() { return "Layout"; } - - Layout(); - virtual ~Layout(); - - virtual bool DoLayout(ActiveWindow* panel); - - virtual void Clear(); - virtual void AddCol(DWORD min_width, float col_factor); - virtual void AddRow(DWORD min_height, float row_factor); - - virtual void SetConstraints(const std::vector& min_x, - const std::vector& min_y, - const std::vector& weight_x, - const std::vector& weight_y); - - virtual void SetConstraints(const std::vector& min_x, - const std::vector& min_y, - const std::vector& weight_x, - const std::vector& weight_y); - - virtual void SetConstraints(int ncols, - int nrows, - const int* min_x, - const int* min_y, - const float* weight_x, - const float* weight_y); - - -protected: - virtual void ScaleWeights(); - virtual void CalcCells(DWORD w, DWORD h, std::vector& cell_x, std::vector& cell_y); - - std::vector cols; - std::vector rows; - std::vector col_weights; - std::vector row_weights; -}; - -#endif // Layout_h - diff --git a/Stars45/Light.cpp b/Stars45/Light.cpp deleted file mode 100644 index c0c3a26..0000000 --- a/Stars45/Light.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Dynamic Light Source -*/ - -#include "Light.h" -#include "Scene.h" - -// +--------------------------------------------------------------------+ - -int Light::id_key = 1; - -// +--------------------------------------------------------------------+ - -Light::Light(float l, float dl, int time) -: id(id_key++), type(LIGHT_POINT), life(time), -light(l), dldt(dl), color(255,255,255), -active(true), shadow(false), scene(0) -{ } - -// +--------------------------------------------------------------------+ - -Light::~Light() -{ } - -// +--------------------------------------------------------------------+ - -void -Light::Update() -{ - if (dldt < 1.0f) - light *= dldt; - - if (life > 0) life--; -} - -// +--------------------------------------------------------------------+ - -void -Light::Destroy() -{ - if (scene) - scene->DelLight(this); - - delete this; -} - -// +--------------------------------------------------------------------+ - -void -Light::MoveTo(const Point& dst) -{ - //if (type != LIGHT_DIRECTIONAL) - loc = dst; -} - -void -Light::TranslateBy(const Point& ref) -{ - if (type != LIGHT_DIRECTIONAL) - loc = loc - ref; -} diff --git a/Stars45/Light.h b/Stars45/Light.h deleted file mode 100644 index 2f42e91..0000000 --- a/Stars45/Light.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Dynamic Light Source -*/ - -#ifndef Light_h -#define Light_h - -#include "Geometry.h" -#include "Color.h" - -// +--------------------------------------------------------------------+ - -#define LIGHT_DESTROY(x) if (x) { x->Destroy(); x = 0; } - -// +--------------------------------------------------------------------+ - -class Scene; - -// +--------------------------------------------------------------------+ - -class Light -{ -public: - static const char* TYPENAME() { return "Light"; } - - enum TYPES { - LIGHT_POINT = 1, - LIGHT_SPOT = 2, - LIGHT_DIRECTIONAL = 3, - LIGHT_FORCE_DWORD = 0x7fffffff - }; - - Light(float l=0.0f, float dl=1.0f, int time=-1); - virtual ~Light(); - - int operator == (const Light& l) const { return id == l.id; } - - // operations - virtual void Update(); - - // accessors / mutators - int Identity() const { return id; } - Point Location() const { return loc; } - - DWORD Type() const { return type; } - void SetType(DWORD t) { type = t; } - float Intensity() const { return light; } - void SetIntensity(float f) { light = f; } - Color GetColor() const { return color; } - void SetColor(Color c) { color = c; } - bool IsActive() const { return active; } - void SetActive(bool a) { active = a; } - bool CastsShadow() const { return shadow; } - void SetShadow(bool s) { shadow = s; } - - bool IsPoint() const { return type == LIGHT_POINT; } - bool IsSpot() const { return type == LIGHT_SPOT; } - bool IsDirectional() const { return type == LIGHT_DIRECTIONAL; } - - virtual void MoveTo(const Point& dst); - virtual void TranslateBy(const Point& ref); - - virtual int Life() const { return life; } - virtual void Destroy(); - virtual Scene* GetScene() const { return scene; } - virtual void SetScene(Scene*s) { scene = s; } - -protected: - static int id_key; - - int id; - DWORD type; - Point loc; - int life; - float light; - float dldt; - Color color; - bool active; - bool shadow; - Scene* scene; -}; - -// +--------------------------------------------------------------------+ - -#endif // Light_h - diff --git a/Stars45/ListBox.cpp b/Stars45/ListBox.cpp deleted file mode 100644 index 8b4eeeb..0000000 --- a/Stars45/ListBox.cpp +++ /dev/null @@ -1,1332 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ListBox ActiveWindow class -*/ - -#include "ListBox.h" -#include "Button.h" -#include "Bitmap.h" -#include "FormWindow.h" -#include "Video.h" -#include "Font.h" -#include "Keyboard.h" -#include "Mouse.h" - -// +--------------------------------------------------------------------+ - -class ListBoxCell -{ -public: - static const char* TYPENAME() { return "ListBoxCell"; } - - ListBoxCell() : data(0), image(0) { } - - Text text; - DWORD data; - Bitmap* image; -}; - -// +--------------------------------------------------------------------+ - -class ListBoxItem -{ -public: - static const char* TYPENAME() { return "ListBoxItem"; } - - ListBoxItem() : data(0), image(0), selected(false), listbox(0), color(Color::White) { } - ~ListBoxItem() { subitems.destroy(); } - - int operator < (const ListBoxItem& item) const; - int operator <=(const ListBoxItem& item) const; - int operator ==(const ListBoxItem& item) const; - - Text text; - DWORD data; - Bitmap* image; - bool selected; - Color color; - List subitems; - - ListBox* listbox; -}; - -// +--------------------------------------------------------------------+ - -class ListBoxColumn -{ -public: - static const char* TYPENAME() { return "ListBoxColumn"; } - - ListBoxColumn() : width(0), align(0), sort(0), color(Color::White), use_color(0), percent(0) { } - - Text title; - int width; - int align; - int sort; - Color color; - int use_color; - - double percent; -}; - -// +--------------------------------------------------------------------+ - -int ListBoxItem::operator < (const ListBoxItem& item) const -{ - if (listbox && listbox == item.listbox) { - int sort_column = listbox->GetSortColumn() - 1; - int sort_criteria = listbox->GetSortCriteria(); - - if (sort_column == -1) { - switch (sort_criteria) { - case ListBox::LIST_SORT_NUMERIC_DESCENDING: - return data > item.data; - - case ListBox::LIST_SORT_ALPHA_DESCENDING: - return text > item.text; - - case ListBox::LIST_SORT_ALPHA_ASCENDING: - return text < item.text; - - case ListBox::LIST_SORT_NUMERIC_ASCENDING: - return data < item.data; - } - } - - else if (sort_column >= 0 && - sort_column <= subitems.size() && - sort_column <= item.subitems.size()) { - - switch (sort_criteria) { - case ListBox::LIST_SORT_NUMERIC_DESCENDING: - return subitems[sort_column]->data > item.subitems[sort_column]->data; - - case ListBox::LIST_SORT_ALPHA_DESCENDING: - return subitems[sort_column]->text > item.subitems[sort_column]->text; - - case ListBox::LIST_SORT_ALPHA_ASCENDING: - return subitems[sort_column]->text < item.subitems[sort_column]->text; - - case ListBox::LIST_SORT_NUMERIC_ASCENDING: - return subitems[sort_column]->data < item.subitems[sort_column]->data; - } - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -int ListBoxItem::operator <=(const ListBoxItem& item) const -{ - if (listbox && listbox == item.listbox) { - int sort_column = listbox->GetSortColumn() - 1; - int sort_criteria = listbox->GetSortCriteria(); - - if (sort_column == -1) { - switch (sort_criteria) { - case ListBox::LIST_SORT_NUMERIC_DESCENDING: - return data >= item.data; - - case ListBox::LIST_SORT_ALPHA_DESCENDING: - return text >= item.text; - - case ListBox::LIST_SORT_ALPHA_ASCENDING: - return text <= item.text; - - case ListBox::LIST_SORT_NUMERIC_ASCENDING: - return data <= item.data; - } - } - - else if (sort_column >= 0 && - sort_column <= subitems.size() && - sort_column <= item.subitems.size()) { - - switch (sort_criteria) { - case ListBox::LIST_SORT_NUMERIC_DESCENDING: - return subitems[sort_column]->data >= item.subitems[sort_column]->data; - - case ListBox::LIST_SORT_ALPHA_DESCENDING: - return subitems[sort_column]->text >= item.subitems[sort_column]->text; - - case ListBox::LIST_SORT_ALPHA_ASCENDING: - return subitems[sort_column]->text <= item.subitems[sort_column]->text; - - case ListBox::LIST_SORT_NUMERIC_ASCENDING: - return subitems[sort_column]->data <= item.subitems[sort_column]->data; - } - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -int ListBoxItem::operator == (const ListBoxItem& item) const -{ - if (listbox && listbox == item.listbox) { - int sort_column = listbox->GetSortColumn() - 1; - int sort_criteria = listbox->GetSortCriteria(); - - if (sort_column == -1) { - switch (sort_criteria) { - case ListBox::LIST_SORT_NUMERIC_DESCENDING: - return data == item.data; - - case ListBox::LIST_SORT_ALPHA_DESCENDING: - return text == item.text; - - case ListBox::LIST_SORT_ALPHA_ASCENDING: - return text == item.text; - - case ListBox::LIST_SORT_NUMERIC_ASCENDING: - return data == item.data; - } - } - - else if (sort_column >= 0 && - sort_column <= subitems.size() && - sort_column <= item.subitems.size()) { - - switch (sort_criteria) { - case ListBox::LIST_SORT_NUMERIC_DESCENDING: - return subitems[sort_column]->data == item.subitems[sort_column]->data; - - case ListBox::LIST_SORT_ALPHA_DESCENDING: - return subitems[sort_column]->text == item.subitems[sort_column]->text; - - case ListBox::LIST_SORT_ALPHA_ASCENDING: - return subitems[sort_column]->text == item.subitems[sort_column]->text; - - case ListBox::LIST_SORT_NUMERIC_ASCENDING: - return subitems[sort_column]->data == item.subitems[sort_column]->data; - } - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -static int old_cursor; - -// +--------------------------------------------------------------------+ - -ListBox::ListBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid) -: ScrollWindow(p->GetScreen(), ax, ay, aw, ah, aid, 0, p) -{ - show_headings = false; - multiselect = false; - list_index = 0; - selcount = 0; - - selected_color = Color(255, 255, 128); - - sort_column = 0; - item_style = LIST_ITEM_STYLE_PLAIN; - seln_style = LIST_ITEM_STYLE_PLAIN; - - char buf[32]; - sprintf_s(buf, "ListBox %d", id); - desc = buf; -} - -ListBox::ListBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid) -: ScrollWindow(s, ax, ay, aw, ah, aid) -{ - show_headings = false; - multiselect = false; - list_index = 0; - selcount = 0; - - selected_color = Color(255, 255, 128); - - sort_column = 0; - item_style = LIST_ITEM_STYLE_PLAIN; - seln_style = LIST_ITEM_STYLE_PLAIN; - - char buf[32]; - sprintf_s(buf, "ListBox %d", id); - desc = buf; -} - -ListBox::~ListBox() -{ - items.destroy(); - columns.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -ListBox::DrawContent(const Rect& ctrl_rect) -{ - SizeColumns(); - - Rect item_rect = ctrl_rect; - item_rect.h = line_height; - - int h = rect.h; - - // draw headings at top, if needed: - if (show_headings) { - Color save_color = back_color; - back_color = ShadeColor(back_color, 1.3); - font->SetColor(fore_color); - - int max_column = columns.size()-1; - item_rect.h += HEADING_EXTRA; - - page_size = (h-item_rect.h) / (line_height + leading); - - for (int column = 0; column <= max_column; column++) { - item_rect.w = GetColumnWidth(column); - - // draw heading button - FillRect(item_rect, back_color); - DrawStyleRect(item_rect, WIN_RAISED_FRAME); - - Rect title_rect = item_rect; - title_rect.Deflate(3,3); - - DrawText(GetColumnTitle(column), - 0, - title_rect, - DT_CENTER|DT_SINGLELINE); - - item_rect.x += item_rect.w; - } - - item_rect.y += item_rect.h; - back_color = save_color; - item_rect.h = line_height; - } - - int index = 0; - ListIter iter = items; - - while (++iter && item_rect.y < h) { - ListBoxItem* item = iter.value(); - - if (index++ >= top_index) { - // draw main item: - int column = 0; - item_rect.x = ctrl_rect.x; - item_rect.w = GetColumnWidth(column) - 2; - - if (item_rect.y + item_rect.h > h) { - item_rect.h = h - item_rect.y - 1; - } - - Color item_color = GetItemColor(index-1, 0); - - if (item->selected) { - font->SetColor(selected_color); - - if (seln_style == LIST_ITEM_STYLE_FILLED_BOX) - FillRect(item_rect, selected_color * 0.25); - - if (seln_style >= LIST_ITEM_STYLE_BOX) - DrawRect(item_rect, selected_color); - } - else { - font->SetColor(item_color); - - if (item_style == LIST_ITEM_STYLE_FILLED_BOX) - FillRect(item_rect, item_color * 0.25); - - if (item_style >= LIST_ITEM_STYLE_BOX) - DrawRect(item_rect, item_color); - } - - Rect text_rect = item_rect; - - if (item->image && item->image->Width() > 0 && item->image->Height() > 0) { - DrawBitmap(text_rect.x, text_rect.y, text_rect.x + text_rect.w, text_rect.y + line_height, item->image); - } - else { - text_rect.Deflate(2,0); - DrawText(item->text.data(), - item->text.length(), - text_rect, - GetColumnAlign(column)|DT_SINGLELINE); - } - - // draw subitems: - ListIter sub_iter = item->subitems; - while (++sub_iter) { - ListBoxCell* sub = sub_iter.value(); - - column++; - item_rect.x += item_rect.w + 2; - item_rect.w = GetColumnWidth(column) - 2; - - if (item->selected) { - if (seln_style == LIST_ITEM_STYLE_FILLED_BOX) - FillRect(item_rect, selected_color * 0.25); - - if (seln_style >= LIST_ITEM_STYLE_BOX) - DrawRect(item_rect, selected_color); - } - else { - if (item_style == LIST_ITEM_STYLE_FILLED_BOX) - FillRect(item_rect, item_color * 0.25); - - if (item_style >= LIST_ITEM_STYLE_BOX) - DrawRect(item_rect, item_color); - } - - if (item->selected) - font->SetColor(selected_color); - else - font->SetColor(GetItemColor(index-1, column)); - - Rect text_rect = item_rect; - if (sub->image && sub->image->Width() > 0 && sub->image->Height() > 0) { - DrawBitmap(text_rect.x, text_rect.y, text_rect.x + text_rect.w, text_rect.y + line_height, sub->image); - } - else { - text_rect.Deflate(2,0); - DrawText(sub->text.data(), - sub->text.length(), - text_rect, - GetColumnAlign(column)|DT_SINGLELINE); - } - } - - item_rect.y += line_height + leading; - } - } -} - -// +--------------------------------------------------------------------+ - -void -ListBox::SizeColumns() -{ - ListBoxColumn* c = columns.first(); - - if (c->percent < 0.001) { - double total = 0; - - ListIter iter = columns; - while (++iter) { - c = iter.value(); - total += c->width; - } - - iter.reset(); - while (++iter) { - c = iter.value(); - c->percent = c->width / total; - } - } - - int usable_width = rect.w; - int used = 0; - - if (IsScrollVisible()) { - usable_width -= SCROLL_WIDTH + 2; - } - else { - usable_width -= 3; - } - - for (int i = 0; i < columns.size(); i++) { - c = columns[i]; - - if (i < columns.size() - 1) - c->width = (int) (c->percent * usable_width); - else - c->width = usable_width - used; - - used += c->width; - } -} - -// +--------------------------------------------------------------------+ - -int ListBox::NumItems() -{ - return items.size(); -} - -int ListBox::NumColumns() -{ - return columns.size(); -} - -Text ListBox::GetItemText(int index) -{ - if (index >= 0 && index < items.size()) - return items[index]->text; - - return Text(); -} - -void ListBox::SetItemText(int index, const char* text) -{ - if (index >= 0 && index < items.size()) { - items[index]->text = text; - } -} - -DWORD ListBox::GetItemData(int index) -{ - if (index >= 0 && index < items.size()) - return items[index]->data; - - return 0; -} - -void ListBox::SetItemData(int index, DWORD data) -{ - if (index >= 0 && index < items.size()) { - items[index]->data = data; - } -} - -Bitmap* ListBox::GetItemImage(int index) -{ - if (index >= 0 && index < items.size()) - return items[index]->image; - - return 0; -} - -void ListBox::SetItemImage(int index, Bitmap* img) -{ - if (index >= 0 && index < items.size()) { - items[index]->image = img; - } -} - -Color ListBox::GetItemColor(int index) -{ - if (index >= 0 && index < items.size()) - return items[index]->color; - - return Color::White; -} - -void ListBox::SetItemColor(int index, Color c) -{ - if (index >= 0 && index < items.size()) { - items[index]->color = c; - } -} - -Text ListBox::GetItemText(int index, int column) -{ - if (column == 0) { - return GetItemText(index); - } - - if (index >= 0 && index < items.size()) { - ListBoxItem* item = items[index]; - - column--; - if (column >= 0 && column < item->subitems.size()) - return item->subitems[column]->text; - } - - return Text(); -} - -void ListBox::SetItemText(int index, int column, const char* text) -{ - if (column == 0) { - SetItemText(index, text); - return; - } - - if (index >= 0 && index < items.size()) { - ListBoxItem* item = items[index]; - - column--; - if (column >= 0 && column < columns.size()-1) { - while (column >= item->subitems.size()) { - ListBoxCell* cell = new ListBoxCell; - if (cell) - item->subitems.append(cell); - } - - item->subitems[column]->text = text; - } - } -} - -DWORD ListBox::GetItemData(int index, int column) -{ - if (column == 0) { - return GetItemData(index); - } - - if (index >= 0 && index < items.size()) { - ListBoxItem* item = items[index]; - - column--; - if (column >= 0 && column < item->subitems.size()) - return item->subitems[column]->data; - } - - return 0; -} - -void ListBox::SetItemData(int index, int column, DWORD data) -{ - if (column == 0) { - SetItemData(index, data); - return; - } - - if (index >= 0 && index < items.size()) { - ListBoxItem* item = items[index]; - - column--; - if (column >= 0 && column < columns.size()-1) { - while (column >= item->subitems.size()) { - ListBoxCell* cell = new ListBoxCell; - if (cell) - item->subitems.append(cell); - } - - item->subitems[column]->data = data; - } - } -} - -Bitmap* ListBox::GetItemImage(int index, int column) -{ - if (column == 0) { - return GetItemImage(index); - } - - if (index >= 0 && index < items.size()) { - ListBoxItem* item = items[index]; - - column--; - if (column >= 0 && column < item->subitems.size()) - return item->subitems[column]->image; - } - - return 0; -} - -void ListBox::SetItemImage(int index, int column, Bitmap* img) -{ - if (column == 0) { - SetItemImage(index, img); - return; - } - - if (index >= 0 && index < items.size()) { - ListBoxItem* item = items[index]; - - column--; - if (column >= 0 && column < columns.size()-1) { - while (column >= item->subitems.size()) { - ListBoxCell* cell = new ListBoxCell; - if (cell) - item->subitems.append(cell); - } - - item->subitems[column]->image = img; - } - } -} - -int ListBox::AddItem(const char* text) -{ - ListBoxItem* item = new ListBoxItem; - - if (item) { - item->text = text; - item->color = fore_color; - item->listbox = this; - - items.append(item); - - line_count = items.size(); - list_index = items.size()-1; - } - - return list_index+1; -} - -int ListBox::AddItemWithData(const char* text, int data) -{ - ListBoxItem* item = new ListBoxItem; - - if (item) { - item->text = text; - item->data = data; - item->color = fore_color; - item->listbox = this; - - items.append(item); - - line_count = items.size(); - list_index = items.size()-1; - } - - return list_index+1; -} - -int ListBox::AddImage(Bitmap* img) -{ - ListBoxItem* item = new ListBoxItem; - - if (item) { - item->image = img; - item->color = fore_color; - item->listbox = this; - - items.append(item); - - line_count = items.size(); - list_index = items.size()-1; - } - - return list_index+1; -} - -void ListBox::InsertItem(int index, const char* text) -{ - if (index >=0 && index < items.size()) { - ListBoxItem* item = new ListBoxItem; - - if (item) { - item->text = text; - item->color = fore_color; - item->listbox = this; - - list_index = index; - items.insert(item, list_index); - line_count = items.size(); - } - } -} - -void ListBox::InsertItemWithData(int index, const char* text, int data) -{ - if (index >=0 && index < items.size()) { - ListBoxItem* item = new ListBoxItem; - - if (item) { - item->text = text; - item->data = data; - item->color = fore_color; - item->listbox = this; - - list_index = index; - items.insert(item, list_index); - line_count = items.size(); - } - } -} - -void ListBox::ClearItems() -{ - items.destroy(); - selcount = 0; - top_index = 0; - list_index = 0; - line_count = 0; -} - -void ListBox::RemoveItem(int index) -{ - if (index >= 0 && index < items.size()) { - if (items[index]->selected) - selcount--; - items.removeIndex(index); - line_count = items.size(); - } -} - -void ListBox::RemoveSelectedItems() -{ - if (selcount) { - ListIter item = items; - while (++item) { - if (item->selected) { - delete item.removeItem(); - } - } - - line_count = items.size(); - selcount = 0; - } -} - -void ListBox::AddColumn(const char* title, int width, int align, int sort) -{ - ListBoxColumn* column = new ListBoxColumn; - - if (column) { - column->title = title; - column->width = width; - column->align = align; - column->sort = sort; - - columns.append(column); - } -} - -Text ListBox::GetColumnTitle(int index) -{ - if (index >= 0 && index < columns.size()) - return columns[index]->title; - - return Text(); -} - -void ListBox::SetColumnTitle(int index, const char* title) -{ - if (index >= 0 && index < columns.size()) { - columns[index]->title = title; - } -} - -int ListBox::GetColumnWidth(int index) -{ - if (index >= 0 && index < columns.size()) - return columns[index]->width; - - return 0; -} - -void ListBox::SetColumnWidth(int index, int width) -{ - if (index >= 0 && index < columns.size()) { - columns[index]->width = width; - } -} - -int ListBox::GetColumnAlign(int index) -{ - if (index >= 0 && index < columns.size()) - return columns[index]->align; - - return 0; -} - -void ListBox::SetColumnAlign(int index, int align) -{ - if (index >= 0 && index < columns.size()) { - columns[index]->align = align; - } -} - -int ListBox::GetColumnSort(int index) -{ - if (index >= 0 && index < columns.size()) - return columns[index]->sort; - - return 0; -} - -void ListBox::SetColumnSort(int index, int sort) -{ - if (index >= 0 && index < columns.size()) { - columns[index]->sort = sort; - } -} - -Color ListBox::GetColumnColor(int index) -{ - if (index >= 0 && index < columns.size()) - return columns[index]->color; - - return Color::White; -} - -void ListBox::SetColumnColor(int index, Color c) -{ - if (index >= 0 && index < columns.size()) { - columns[index]->color = c; - columns[index]->use_color = true; - } -} - -Color ListBox::GetItemColor(int index, int column) -{ - Color c = Color::White; - - if (index >= 0 && index < items.size()) - c = items[index]->color; - - if (column >= 0 && column < columns.size()) { - if (columns[column]->use_color) - c = columns[column]->color; - } - - return c; -} - -int ListBox::GetMultiSelect() -{ - return multiselect; -} - -void ListBox::SetMultiSelect(int nNewValue) -{ - if (multiselect != nNewValue && (nNewValue == 0 || nNewValue == 1)) { - multiselect = nNewValue; - ClearSelection(); - } -} - -bool ListBox::GetShowHeadings() -{ - return show_headings; -} - -void ListBox::SetShowHeadings(bool nNewValue) -{ - if (show_headings != nNewValue) { - show_headings = nNewValue; - } -} - -Color ListBox::GetSelectedColor() -{ - return selected_color; -} - -void ListBox::SetSelectedColor(Color c) -{ - if (selected_color != c) { - selected_color = c; - } -} - -int ListBox::GetItemStyle() const -{ - return item_style; -} - -void ListBox::SetItemStyle(int style) -{ - if (style >= LIST_ITEM_STYLE_PLAIN && style <= LIST_ITEM_STYLE_FILLED_BOX) { - item_style = style; - } -} - -int ListBox::GetSelectedStyle() const -{ - return seln_style; -} - -void ListBox::SetSelectedStyle(int style) -{ - if (style >= LIST_ITEM_STYLE_PLAIN && style <= LIST_ITEM_STYLE_FILLED_BOX) { - seln_style = style; - } -} - -bool ListBox::IsSelected(int index) -{ - if (index >= 0 && index < items.size()) - return items[index]->selected; - - return false; -} - -void ListBox::SetSelected(int index, bool bNewValue) -{ - if (index >= 0 && index < items.size()) { - if (!multiselect) - ClearSelection(); - - if (items[index]->selected != bNewValue) { - items[index]->selected = bNewValue; - - if (bNewValue) { - list_index = index; - selcount++; - } - else { - selcount--; - } - } - } -} - -void ListBox::ClearSelection() -{ - ListIter item = items; - while (++item) - item->selected = false; - - selcount = 0; -} - -int ListBox::GetListIndex() -{ - return list_index; -} - -int ListBox::GetLineCount() -{ - line_count = items.size(); - return line_count; -} - -int ListBox::GetSelCount() -{ - return selcount; -} - -int ListBox::GetSelection() -{ - for (int i = 0; i < items.size(); i++) - if (items[i]->selected) - return i; - - return -1; -} - -Text ListBox::GetSelectedItem() -{ - int n = GetSelection(); - return GetItemText(n); -} - -// +--------------------------------------------------------------------+ - -int ListBox::GetSortColumn() -{ - return sort_column; -} - -void ListBox::SetSortColumn(int col_index) -{ - if (col_index >= 0 && col_index <= columns.size()) - sort_column = col_index; -} - -int ListBox::GetSortCriteria() -{ - return GetColumnSort(sort_column); -} - -void ListBox::SetSortCriteria(SORT sort) -{ - SetColumnSort(sort_column, sort); -} - -// +--------------------------------------------------------------------+ - -void ListBox::SortItems() -{ - if (sort_column >=0 && sort_column <= columns.size()) - items.sort(); -} - -// +--------------------------------------------------------------------+ - -int ListBox::IndexFromPoint(int x, int y) const -{ - int sel_index = -1; - - if (show_headings) - sel_index = top_index + (y - (line_height+HEADING_EXTRA)) / (line_height + leading); - - else - sel_index = top_index + y / (line_height + leading); - - return sel_index; -} - -// +--------------------------------------------------------------------+ - -int ListBox::OnMouseMove(int x, int y) -{ - bool dirty = false; - - if (captured) { - ActiveWindow* test = GetCapture(); - - if (test != this) { - captured = false; - dirty = true; - } - - else { - if (selecting && !dragging) { - if (dragdrop && (x < rect.x || - x > rect.x+rect.w || - y < rect.y || - y > rect.y+rect.h)) { - - dragging = true; - OnDragStart(x,y); - } - } - - if (scrolling == SCROLL_THUMB) { - mouse_y = y - rect.y - TRACK_START; - - int dest = (int) ((double) mouse_y/track_length * (items.size()-1)); - ScrollTo(dest); - dirty = true; - } - } - } - - return ActiveWindow::OnMouseMove(x,y); -} - -// +--------------------------------------------------------------------+ - -static bool preselected = false; - -int ListBox::OnLButtonDown(int x, int y) -{ - if (!captured) - captured = SetCapture(); - - mouse_x = x - rect.x; - mouse_y = y - rect.y; - - int x_scroll_bar = rect.w; - - if (IsScrollVisible()) - x_scroll_bar -= SCROLL_WIDTH; - - if (mouse_x < x_scroll_bar) { - scrolling = SCROLL_NONE; - - if (show_headings && mouse_y < line_height+BORDER_WIDTH+EXTRA_WIDTH) { - int next_col_start = 0; - int max_column = columns.size()-1; - int column; - - for (column = 0; column < max_column; column++) { - next_col_start += GetColumnWidth(column); - - if (mouse_x < next_col_start) - break; - } - - sort_column = column; - - int& sort_criteria = columns[sort_column]->sort; - - if (sort_criteria != LIST_SORT_NEVER) { - if (!sort_criteria) - sort_criteria = LIST_SORT_ALPHA_DESCENDING; - else - sort_criteria = -sort_criteria; - - SortItems(); - } - } - - else { - selecting = true; - } - } - - else { - selecting = false; - - if (mouse_y < TRACK_START) { - scrolling = SCROLL_UP; - Scroll(scrolling, 1); - Button::PlaySound(Button::SND_LIST_SCROLL); - } - - else if (mouse_y > rect.h-TRACK_START) { - scrolling = SCROLL_DOWN; - if (top_index < items.size()-1) - top_index++; - Button::PlaySound(Button::SND_LIST_SCROLL); - } - - else if (mouse_y < thumb_pos) { - scrolling = SCROLL_PAGE_UP; - Scroll(scrolling, page_size); - Button::PlaySound(Button::SND_LIST_SCROLL); - } - - else if (mouse_y > thumb_pos+THUMB_HEIGHT) { - scrolling = SCROLL_PAGE_DOWN; - Scroll(scrolling, page_size); - Button::PlaySound(Button::SND_LIST_SCROLL); - } - - else { - scrolling = SCROLL_THUMB; - } - } - - if (selecting) { - list_index = IndexFromPoint(mouse_x, mouse_y); - preselected = IsSelected(list_index); - if (!multiselect || !Keyboard::KeyDown(VK_SHIFT)) - ClearSelection(); - SetSelected(list_index); - EnsureVisible(list_index); - Button::PlaySound(Button::SND_LIST_SELECT); - } - - return ActiveWindow::OnLButtonDown(x,y); -} - -// +--------------------------------------------------------------------+ - -int ListBox::OnLButtonUp(int x, int y) -{ - if (captured) { - mouse_x = x-rect.x; - mouse_y = y-rect.y; - - if (dragging) { - if (mouse_x < 0 || mouse_x > rect.w || mouse_y < 0 || mouse_y > rect.h) { - FormWindow* parent_form = (FormWindow*) form; - - if (parent_form) { - ActiveWindow* drop_target = parent_form->FindControl(x,y); - - if (drop_target && drop_target->IsEnabled() && drop_target->IsShown()) - drop_target->OnDragDrop(x,y,this); - } - } - } - else if (preselected) { - if (multiselect && Keyboard::KeyDown(VK_SHIFT)) { - SetSelected(list_index, false); - Button::PlaySound(Button::SND_LIST_SELECT); - } - } - - ReleaseCapture(); - captured = false; - - Mouse::SetCursor((Mouse::CURSOR) old_cursor); - } - - dragging = false; - selecting = false; - - return ActiveWindow::OnLButtonUp(x,y); -} - -// +--------------------------------------------------------------------+ - -int ListBox::OnMouseWheel(int wheel) -{ - return ScrollWindow::OnMouseWheel(wheel); -} - -// +--------------------------------------------------------------------+ - -int ListBox::OnClick() -{ - int fire_select = !scrolling; - - if (scrolling == SCROLL_THUMB) - scrolling = SCROLL_NONE; - - if (fire_select) - return ActiveWindow::OnSelect(); - else - return ActiveWindow::OnClick(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -int ListBox::OnKeyDown(int vk, int flags) -{ - if (selcount == 1 && list_index >= 0 && list_index < items.size()) { - ListBoxItem* item = items[list_index]; - - if (vk == VK_DOWN) { - if (list_index < items.size() - 1) { - item->selected = false; - list_index++; - item = items[list_index]; - item->selected = true; - OnClick(); - return ActiveWindow::OnKeyDown(vk, flags); - } - } - - else if (vk == VK_UP) { - if (list_index > 0) { - item->selected = false; - list_index--; - item = items[list_index]; - item->selected = true; - OnClick(); - return ActiveWindow::OnKeyDown(vk, flags); - } - } - } - - return ScrollWindow::OnKeyDown(vk, flags); -} - -// +--------------------------------------------------------------------+ - -int ListBox::OnDragStart(int x, int y) -{ - old_cursor = Mouse::SetCursor(Mouse::DRAG); - return ActiveWindow::OnDragStart(x,y); -} - -// +--------------------------------------------------------------------+ - -int ListBox::OnDragDrop(int x, int y, ActiveWindow* source) -{ - if (!dragdrop) return 0; - - ListBox* drag_source = (ListBox*) source; - - if (drag_source) { - int max_col = NumColumns(); - - if (max_col != drag_source->NumColumns()) - max_col = 0; - - for (int i = 0; i < drag_source->NumItems(); i++) { - if (drag_source->IsSelected(i)) { - AddItemWithData(drag_source->GetItemText(i), - drag_source->GetItemData(i)); - - for (int c = 1; c < max_col; c++) { - SetItemText(list_index, c, drag_source->GetItemText(i,c)); - SetItemData(list_index, c, drag_source->GetItemData(i,c)); - } - - if (!multiselect) - ClearSelection(); - - items[list_index]->selected = true; - selcount++; - } - } - - drag_source->RemoveSelectedItems(); - Button::PlaySound(Button::SND_LIST_DROP); - } - - return ActiveWindow::OnDragDrop(x,y,source); -} diff --git a/Stars45/ListBox.h b/Stars45/ListBox.h deleted file mode 100644 index 6d94d74..0000000 --- a/Stars45/ListBox.h +++ /dev/null @@ -1,169 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ListBox ActiveWindow class -*/ - -#ifndef ListBox_h -#define ListBox_h - -#include "Types.h" -#include "ScrollWindow.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Bitmap; -class ListBox; -class ListBoxCell; -class ListBoxItem; -class ListBoxColumn; - -// +--------------------------------------------------------------------+ - -class ListBox : public ScrollWindow -{ -public: - enum SORT { LIST_SORT_NUMERIC_DESCENDING = -2, - LIST_SORT_ALPHA_DESCENDING, - LIST_SORT_NONE, - LIST_SORT_ALPHA_ASCENDING, - LIST_SORT_NUMERIC_ASCENDING, - LIST_SORT_NEVER - }; - - enum ALIGN { LIST_ALIGN_LEFT = DT_LEFT, - LIST_ALIGN_CENTER = DT_CENTER, - LIST_ALIGN_RIGHT = DT_RIGHT - }; - - enum STYLE { LIST_ITEM_STYLE_PLAIN, - LIST_ITEM_STYLE_BOX, - LIST_ITEM_STYLE_FILLED_BOX - }; - - ListBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid); - ListBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid); - virtual ~ListBox(); - - // Operations: - virtual void DrawContent(const Rect& ctrl_rect); - - // Event Target Interface: - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnMouseWheel(int wheel); - virtual int OnClick(); - - virtual int OnKeyDown(int vk, int flags); - - // pseudo-events: - virtual int OnDragStart(int x, int y); - virtual int OnDragDrop(int x, int y, ActiveWindow* source); - - // Property accessors: - int NumItems(); - int NumColumns(); - - Text GetItemText(int index); - void SetItemText(int index, const char* text); - DWORD GetItemData(int index); - void SetItemData(int index, DWORD data); - Bitmap* GetItemImage(int index); - void SetItemImage(int index, Bitmap* img); - Color GetItemColor(int index); - void SetItemColor(int index, Color c); - - Text GetItemText(int index, int column); - void SetItemText(int index, int column, const char* text); - DWORD GetItemData(int index, int column); - void SetItemData(int index, int column, DWORD data); - Bitmap* GetItemImage(int index, int column); - void SetItemImage(int index, int column, Bitmap* img); - - int AddItem(const char* text); - int AddImage(Bitmap* img); - int AddItemWithData(const char* text, int data); - void InsertItem(int index, const char* text); - void InsertItemWithData(int index, const char* text, int data); - void ClearItems(); - void RemoveItem(int index); - void RemoveSelectedItems(); - - void AddColumn(const char* title, - int width, - int align = ListBox::LIST_ALIGN_LEFT, - int sort = ListBox::LIST_SORT_NONE); - - Text GetColumnTitle(int index); - void SetColumnTitle(int index, const char* title); - int GetColumnWidth(int index); - void SetColumnWidth(int index, int width); - int GetColumnAlign(int index); - void SetColumnAlign(int index, int align); - int GetColumnSort(int index); - void SetColumnSort(int index, int sort); - Color GetColumnColor(int index); - void SetColumnColor(int index, Color c); - - Color GetItemColor(int index, int column); - - int GetMultiSelect(); - void SetMultiSelect(int nNewValue); - bool GetShowHeadings(); - void SetShowHeadings(bool nNewValue); - Color GetSelectedColor(); - void SetSelectedColor(Color c); - - int GetItemStyle() const; - void SetItemStyle(int style); - int GetSelectedStyle() const; - void SetSelectedStyle(int style); - - bool IsSelected(int index); - void SetSelected(int index, bool bNewValue=true); - void ClearSelection(); - - int GetSortColumn(); - void SetSortColumn(int col_index); - int GetSortCriteria(); - void SetSortCriteria(SORT sort); - void SortItems(); - void SizeColumns(); - - // read-only: - virtual int GetListIndex(); - virtual int GetLineCount(); - virtual int GetSelCount(); - virtual int GetSelection(); - virtual Text GetSelectedItem(); - -protected: - int IndexFromPoint(int x, int y) const; - - // properties: - List items; - List columns; - - bool show_headings; - int multiselect; - int list_index; - int selcount; - - Color selected_color; - - int sort_column; - int item_style; - int seln_style; -}; - -#endif // ListBox_h - diff --git a/Stars45/LoadDlg.cpp b/Stars45/LoadDlg.cpp deleted file mode 100644 index 1138fec..0000000 --- a/Stars45/LoadDlg.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Loading progress dialog box -*/ - - -#include "LoadDlg.h" -#include "Starshatter.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ListBox.h" -#include "ComboBox.h" -#include "Slider.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ - -LoadDlg::LoadDlg(Screen* s, FormDef& def) -: FormWindow(s, 0, 0, s->Width(), s->Height()), -progress(0), activity(0) -{ - Init(def); -} - -LoadDlg::~LoadDlg() -{ -} - -void -LoadDlg::RegisterControls() -{ - title = FindControl(100); - activity = FindControl(101); - progress = (Slider*) FindControl(102); -} - -// +--------------------------------------------------------------------+ - -void -LoadDlg::ExecFrame() -{ - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - if (title) { - if (stars->GetGameMode() == Starshatter::CLOD_MODE || - stars->GetGameMode() == Starshatter::CMPN_MODE) - title->SetText(ContentBundle::GetInstance()->GetText("LoadDlg.campaign")); - - else if (stars->GetGameMode() == Starshatter::MENU_MODE) - title->SetText(ContentBundle::GetInstance()->GetText("LoadDlg.tac-ref")); - - else - title->SetText(ContentBundle::GetInstance()->GetText("LoadDlg.mission")); - } - - activity->SetText(stars->GetLoadActivity()); - progress->SetValue(stars->GetLoadProgress()); - } -} - -// +--------------------------------------------------------------------+ - diff --git a/Stars45/LoadDlg.h b/Stars45/LoadDlg.h deleted file mode 100644 index 8b79e28..0000000 --- a/Stars45/LoadDlg.h +++ /dev/null @@ -1,40 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Loading progress dialog box -*/ - -#ifndef LoadDlg_h -#define LoadDlg_h - -#include "Types.h" -#include "FormWindow.h" - -// +--------------------------------------------------------------------+ - -class LoadDlg : public FormWindow -{ -public: - LoadDlg(Screen* s, FormDef& def); - virtual ~LoadDlg(); - - virtual void RegisterControls(); - - // Operations: - virtual void ExecFrame(); - -protected: - ActiveWindow* title; - ActiveWindow* activity; - Slider* progress; -}; - -#endif // LoadDlg_h - diff --git a/Stars45/LoadScreen.cpp b/Stars45/LoadScreen.cpp deleted file mode 100644 index 60972e2..0000000 --- a/Stars45/LoadScreen.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* 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 "LoadScreen.h" -#include "LoadDlg.h" -#include "CmpLoadDlg.h" -#include "Starshatter.h" - -#include "GameWinDX9.h" -#include "Video.h" -#include "Screen.h" -#include "FormDef.h" -#include "Window.h" -#include "ActiveWindow.h" -#include "Mouse.h" -#include "Color.h" -#include "Bitmap.h" -#include "Font.h" -#include "FontMgr.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -LoadScreen::LoadScreen() -: screen(0), load_dlg(0), cmp_load_dlg(0), isShown(false) -{ } - -LoadScreen::~LoadScreen() -{ - TearDown(); -} - -// +--------------------------------------------------------------------+ - -void -LoadScreen::Setup(Screen* s) -{ - if (!s) - return; - - screen = s; - - DataLoader* loader = DataLoader::GetLoader(); - loader->UseFileSystem(true); - - // create windows - FormDef load_def("LoadDlg", 0); - load_def.Load("LoadDlg"); - load_dlg = new LoadDlg(screen, load_def); - - FormDef cmp_load_def("CmpLoadDlg", 0); - cmp_load_def.Load("CmpLoadDlg"); - cmp_load_dlg = new CmpLoadDlg(screen, cmp_load_def); - - loader->UseFileSystem(Starshatter::UseFileSystem()); - ShowLoadDlg(); -} - -// +--------------------------------------------------------------------+ - -void -LoadScreen::TearDown() -{ - if (screen) { - if (load_dlg) screen->DelWindow(load_dlg); - if (cmp_load_dlg) screen->DelWindow(cmp_load_dlg); - } - - delete load_dlg; - delete cmp_load_dlg; - - load_dlg = 0; - cmp_load_dlg = 0; - screen = 0; -} - -// +--------------------------------------------------------------------+ - -void -LoadScreen::ExecFrame() -{ - GameWinDX9::GetInstance()->SetScreenColor(Color::Black); - - if (load_dlg && load_dlg->IsShown()) - load_dlg->ExecFrame(); - - if (cmp_load_dlg && cmp_load_dlg->IsShown()) - cmp_load_dlg->ExecFrame(); -} - -// +--------------------------------------------------------------------+ - -bool -LoadScreen::CloseTopmost() -{ - return false; -} - -void -LoadScreen::Show() -{ - if (!isShown) { - ShowLoadDlg(); - isShown = true; - } -} - -void -LoadScreen::Hide() -{ - if (isShown) { - HideLoadDlg(); - isShown = false; - } -} - -// +--------------------------------------------------------------------+ - -void -LoadScreen::ShowLoadDlg() -{ - if (load_dlg) load_dlg->Hide(); - if (cmp_load_dlg) cmp_load_dlg->Hide(); - - Starshatter* stars = Starshatter::GetInstance(); - - // show campaign load dialog if available and loading campaign - if (stars && cmp_load_dlg) { - if (stars->GetGameMode() == Starshatter::CLOD_MODE || - stars->GetGameMode() == Starshatter::CMPN_MODE) { - cmp_load_dlg->Show(); - Mouse::Show(false); - return; - } - } - - // otherwise, show regular load dialog - if (load_dlg) { - load_dlg->Show(); - Mouse::Show(false); - } -} - -// +--------------------------------------------------------------------+ - -void -LoadScreen::HideLoadDlg() -{ - if (load_dlg && load_dlg->IsShown()) - load_dlg->Hide(); - - if (cmp_load_dlg && cmp_load_dlg->IsShown()) - cmp_load_dlg->Hide(); -} diff --git a/Stars45/LoadScreen.h b/Stars45/LoadScreen.h deleted file mode 100644 index 349703b..0000000 --- a/Stars45/LoadScreen.h +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 - -*/ - -#ifndef LoadScreen_h -#define LoadScreen_h - -#include "Types.h" -#include "Bitmap.h" -#include "Screen.h" - -// +--------------------------------------------------------------------+ - -class LoadDlg; -class CmpLoadDlg; - -class Bitmap; -class DataLoader; -class Font; -class Screen; -class Video; -class VideoFactory; - -// +--------------------------------------------------------------------+ - -class LoadScreen -{ -public: - LoadScreen(); - virtual ~LoadScreen(); - - virtual void Setup(Screen* screen); - virtual void TearDown(); - virtual bool CloseTopmost(); - - virtual bool IsShown() const { return isShown; } - virtual void Show(); - virtual void Hide(); - - virtual void ShowLoadDlg(); - virtual void HideLoadDlg(); - virtual LoadDlg* GetLoadDlg() { return load_dlg; } - virtual CmpLoadDlg* GetCmpLoadDlg() { return cmp_load_dlg; } - - virtual void ExecFrame(); - -private: - Screen* screen; - LoadDlg* load_dlg; - CmpLoadDlg* cmp_load_dlg; - - bool isShown; -}; - -// +--------------------------------------------------------------------+ - -#endif // LoadScreen_h - diff --git a/Stars45/Locale_ss.cpp b/Stars45/Locale_ss.cpp deleted file mode 100644 index 427753c..0000000 --- a/Stars45/Locale_ss.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - 3D Locale (Polygon) Object -*/ - -#include "Locale_ss.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -static List locales; - -// +--------------------------------------------------------------------+ - -Locale::Locale(const char* l, const char* c, const char* v) -{ - ZeroMemory(this, sizeof(Locale)); - if (l && *l) { - strncpy_s(language, l, 6); - char* p = language; - while (*p) { - *p = tolower(*p); - p++; - } - } - - if (c && *c) { - strncpy_s(country, c, 6); - char* p = country; - while (*p) { - *p = toupper(*p); - p++; - } - } - - if (v && *v) { - strncpy_s(variant, v, 6); - char* p = variant; - while (*p) { - *p = tolower(*p); - p++; - } - } - - locales.append(this); -} - -// +--------------------------------------------------------------------+ - -Locale::~Locale() -{ - locales.remove(this); -} - -// +--------------------------------------------------------------------+ - -int -Locale::operator == (const Locale& that) const -{ - if (this == &that) return 1; - - return !_stricmp(language, that.language) && - !_stricmp(country, that.country) && - !_stricmp(variant, that.variant); -} - -// +--------------------------------------------------------------------+ - -Locale* -Locale::ParseLocale(const char* str) -{ - if (str && *str) { - int i = 0; - char s1[4]; - char s2[4]; - char s3[4]; - - while (*str && *str != '_' && i < 3) { - s1[i] = *str++; - i++; - } - s1[i] = 0; - i = 0; - - if (*str == '_') - str++; - - while (*str && *str != '_' && i < 3) { - s2[i] = *str++; - i++; - } - s2[i] = 0; - i = 0; - - if (*str == '_') - str++; - - while (*str && *str != '_' && i < 3) { - s3[i] = *str++; - i++; - } - s3[i] = 0; - i = 0; - - return CreateLocale(s1, s2, s3); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -Locale* -Locale::CreateLocale(const char* l, const char* c, const char* v) -{ - ListIter iter = locales; - while (++iter) { - Locale* loc = iter.value(); - if (!_stricmp(l, loc->GetLanguage())) { - if (c && *c) { - if (!_stricmp(c, loc->GetCountry())) { - if (v && *v) { - if (!_stricmp(v, loc->GetVariant())) { - return loc; - } - } - else { - return loc; - } - } - } - else { - return loc; - } - } - } - - if (l[0]) { - if (c[0]) { - if (v[0]) { - return new Locale(l, c, v); - } - return new Locale(l, c); - } - return new Locale(l); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -const List& -Locale::GetAllLocales() -{ - return locales; -} - -// +--------------------------------------------------------------------+ - -const Text -Locale::GetFullCode() const -{ - Text result = language; - if (*country) { - result.append("_"); - result.append(country); - - if (*variant) { - result.append("_"); - result.append(variant); - } - } - return result; -} - -// +--------------------------------------------------------------------+ - -static const char* languages[] = { - "en", "English", - "fr", "French", - "de", "German", - "it", "Italian", - "pt", "Portuguese", - "ru", "Russian", - "es", "Spanish" -}; - -static const char* countries[] = { - "US", "USA", - "CA", "Canada", - "FR", "France", - "DE", "Germany", - "IT", "Italy", - "PT", "Portugal", - "RU", "Russia", - "ES", "Spain", - "UK", "United Kingdom" -}; - -const Text -Locale::GetDisplayName() const -{ - Text result; - if (*language) { - for (int i = 0; i < 14; i += 2) { - if (!_stricmp(language, languages[i])) { - result = languages[i+1]; - break; - } - } - - if (*country) { - for (int i = 0; i < 18; i += 2) { - if (!_stricmp(country, countries[i])) { - result.append(" - "); - result.append(countries[i+1]); - break; - } - } - } - - } - return result; -} - diff --git a/Stars45/Locale_ss.h b/Stars45/Locale_ss.h deleted file mode 100644 index be161ff..0000000 --- a/Stars45/Locale_ss.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Description of locale by ISO language, country, and variant -*/ - -#ifndef Locale_h -#define Locale_h - -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Locale -{ -public: - static const char* TYPENAME() { return "Locale"; } - - Locale(const char* language, const char* country=0, const char* variant=0); - ~Locale(); - - int operator == (const Locale& that) const; - - // Operations: - static const List& GetAllLocales(); - static Locale* ParseLocale(const char* str); - - // Property accessors: - const char* GetLanguage() const { return language; } - const char* GetCountry() const { return country; } - const char* GetVariant() const { return variant; } - const Text GetFullCode() const; - const Text GetDisplayName() const; - - -protected: - static Locale* CreateLocale(const char* language, const char* country=0, const char* variant=0); - char language[8]; - char country[8]; - char variant[8]; -}; - -#endif // Locale_h - diff --git a/Stars45/MCIWave.cpp b/Stars45/MCIWave.cpp deleted file mode 100644 index a8c0a0b..0000000 --- a/Stars45/MCIWave.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - MCI Wave Output stuff -*/ - -#include "Types.h" -#include "GameWinDX9.h" -#include "Utils.h" - -// +----------------------------------------------------------------------+ - -const int MCI_MAX_STR = 128; -static char ret_str[MCI_MAX_STR]; -static char err_str[MCI_MAX_STR]; -static MCIERROR mci_err; -static MMRESULT wav_err; - -static int mci_send_string(const char* cmd_str) -{ - mci_err = mciSendString(cmd_str, ret_str, sizeof(ret_str), GameWinDX9::GetInstance()->GetHWND()); - if (mci_err) { - if (mciGetErrorString(mci_err, err_str, sizeof(err_str))) - Print("Error (%s): '%s'\n", cmd_str, err_str); - else - Print("Error (%s): %d - UNKNOWN\n", cmd_str, mci_err); - return 0; - } - - return 1; -} - -// +--------------------------------------------------------------------+ - -static void print_wav_error() -{ - waveOutGetErrorText(wav_err, err_str, MCI_MAX_STR); - Print(err_str); -} - -// +--------------------------------------------------------------------+ - -int load_wave_file(const char* fname, LPWAVEHDR hdr, LPWAVEFORMATEX format) -{ - HMMIO hmmio; /* file handle for open file */ - MMCKINFO mmckinfoParent; /* parent chunk information structure */ - MMCKINFO mmckinfoSubchunk; /* subchunk information structure */ - DWORD dwFmtSize; /* size of "fmt" chunk */ - DWORD dwDataSize; /* size of "data" chunk */ - - /* - * Open the given file for reading with buffered I/O - * using the default internal buffer. - */ - hmmio = mmioOpen((LPSTR) fname, NULL, MMIO_READ | MMIO_ALLOCBUF); - - if (hmmio == NULL) { - Print("load_wave_file(): '%s' - Failed to open file.\n", fname); - return 0; - } - - /* - * Locate a "RIFF" chunk with a "WAVE" form type - * to make sure the file is a WAVE file. - */ - mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); - if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, NULL, MMIO_FINDRIFF)) { - Print("load_wave_file(): '%s' - This is not a WAVE file.\n", fname); - mmioClose(hmmio, 0); - return 0; - } - - /* - * Find the "fmt " chunk (form type "fmt "); it must be - * a subchunk of the "RIFF" parent chunk. - */ - mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' '); - if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK)) { - Print("load_wave_file(): '%s' - WAVE file has no \"fmt\" chunk\n", fname); - mmioClose(hmmio, 0); - return 0; - } - - /* - * Get the size of the "fmt " chunk--allocate and lock memory for it. - */ - dwFmtSize = mmckinfoSubchunk.cksize; - - /* Read the "fmt " chunk. */ - if (mmioRead(hmmio, (HPSTR) format, dwFmtSize) != (LRESULT)dwFmtSize) { - Print("load_wave_file(): '%s' - Failed to read format chunk.\n", fname); - mmioClose(hmmio, 0); - return 0; - } - - /* Ascend out of the "fmt " subchunk. */ - mmioAscend(hmmio, &mmckinfoSubchunk, 0); - - /* - * Find the data subchunk. The current file position - * should be at the beginning of the data chunk. - */ - mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); - if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK)) { - Print("load_wave_file(): '%s' - WAVE file has no data chunk.\n", fname); - mmioClose(hmmio, 0); - return 0; - } - - /* Get the size of the data subchunk. */ - dwDataSize = mmckinfoSubchunk.cksize; - if (dwDataSize == 0L) { - Print("load_wave_file(): '%s' - The data chunk contains no data.\n", fname); - mmioClose(hmmio, 0); - return 0; - } - - // allocate the data block: - hdr->lpData = (LPSTR) new BYTE[dwDataSize]; - hdr->dwBufferLength = dwDataSize; - - /* Read the waveform data subchunk. */ - if (mmioRead(hmmio, (HPSTR) hdr->lpData, dwDataSize) != (LRESULT)dwDataSize) { - Print("load_wave_file(): '%s' - Failed to read data chunk.\n", fname); - mmioClose(hmmio, 0); - return 0; - } - - /* Close the file. */ - mmioClose(hmmio, 0); - - return 1; -} - -// +--------------------------------------------------------------------+ - -void delete_wave_file(LPWAVEHDR hdr, LPWAVEFORMATEX format) -{ - if (hdr) { - delete hdr->lpData; - hdr->lpData = 0; - } -} diff --git a/Stars45/MCIWave.h b/Stars45/MCIWave.h deleted file mode 100644 index bef5ae2..0000000 --- a/Stars45/MCIWave.h +++ /dev/null @@ -1,24 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - MCI Wave Output stuff -*/ - -#ifndef MCI_WAVE_H -#define MCI_WAVE_H - -// +--------------------------------------------------------------------+ - -int load_wave_file(const char* fname, LPWAVEHDR hdr, LPWAVEFORMATEX format); -void delete_wave_file(LPWAVEHDR hdr, LPWAVEFORMATEX format); - -// +--------------------------------------------------------------------+ - -#endif diff --git a/Stars45/MachineInfo.cpp b/Stars45/MachineInfo.cpp deleted file mode 100644 index 64552ba..0000000 --- a/Stars45/MachineInfo.cpp +++ /dev/null @@ -1,823 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Collect and Display Machine, OS, and Driver Information -*/ - -#include - -#include "MachineInfo.h" -#include "Utils.h" - -#define DIRECTINPUT_VERSION 0x0700 - -#include -#include -#include -#include -#include - -// +--------------------------------------------------------------------+ - -static int cpu_class=-1; -static int cpu_speed=-1; -static int platform=-1; -static int dx_version=-1; -static int total_ram=-1; - -static OSVERSIONINFO os_ver = { sizeof(OSVERSIONINFO) }; -static SYSTEM_INFO cpu_info; -static MEMORYSTATUS mem_info = { sizeof(MEMORYSTATUS) }; - -// +--------------------------------------------------------------------+ - -const char* -MachineInfo::GetShortDescription() -{ - static char desc[256]; - - static const char* cpu_names[] = { - "8088", - "8086", - "80286", - "80386", - "80486", - "Pentium", - "Pentium II", - "Pentium 3", - "Pentium 4" - }; - - static const char* os_names[] = { - "DOS", - "Windows 95", - "Windows 98", - "Windows NT", - "Windows 2000", - "Windows XP", - "Windows XP x64", - "Windows Vista", - "Windows Seven", - "Future Windows" - }; - - int cpu_index = GetCpuClass(); - if (cpu_index < 0) cpu_index = 0; - else if (cpu_index > 8) cpu_index = 8; - - int os_index = GetPlatform(); - if (os_index < 0) os_index = 0; - - sprintf_s(desc, "%s %d MHz %d MB RAM %s", - cpu_names[cpu_index], - GetCpuSpeed(), - GetTotalRam(), - os_names[os_index]); - - return desc; -} - -// +--------------------------------------------------------------------+ - -static void DescribeCpuMake(); -static void DescribeOwner95(); -static void DescribeOwnerNT(); -static void DescribeDrivers95(const char* sType); -static void DescribeDriversNT(const char* sType); -static void DescribeDriverVersion(const char* file); -static void DescribeDXVersion(const char* component); - -// wait for at least target_time, -// return the exact amount of time actually waited: - -static double SpinWait(double target_time) -{ - double actual_time = 0; - - LARGE_INTEGER ifreq; - LARGE_INTEGER cnt1; - LARGE_INTEGER cnt2; - - QueryPerformanceFrequency(&ifreq); - double freq = (double) ifreq.QuadPart; - - QueryPerformanceCounter(&cnt1); - - do { - QueryPerformanceCounter(&cnt2); - - double delta = (double) (cnt2.QuadPart - cnt1.QuadPart); - actual_time = delta / freq; - } - while (actual_time < target_time); - - return actual_time; -} - -static double CalcCpuSpeed() -{ - const auto before = std::chrono::high_resolution_clock::now(); - - double seconds = SpinWait(0.1); - - const auto after = std::chrono::high_resolution_clock::now(); - const std::chrono::duration diff = after - before; - double clocks = diff.count(); - - return (clocks/seconds); -} - -/**************************************************************************** -* -* GetDXVersion -* -* This function returns -* 0 Insufficient DirectX installed -* 9 At least DirectX 9 installed. -* -****************************************************************************/ - -DWORD GetDXVersion() -{ - HRESULT hr = 0; - HINSTANCE DDHinst = 0; - LPDIRECT3D9 d3d9 = 0; - OSVERSIONINFO osVer = { sizeof(OSVERSIONINFO) }; - - // First get the windows platform - - if (!GetVersionEx(&osVer)) - return 0; - - // NT versions do not support DirectX 9 - if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT) { - if (osVer.dwMajorVersion <= 4) - return 0; - } - - DDHinst = LoadLibrary("D3D9.DLL"); - if (DDHinst == 0) { - return 0; - } - - FreeLibrary(DDHinst); - return 9; -} - - -// +--------------------------------------------------------------------+ - -int -MachineInfo::GetCpuClass() -{ - if (cpu_class < 0) { - GetSystemInfo(&cpu_info); - - if (cpu_info.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL || - cpu_info.dwProcessorType < PROCESSOR_INTEL_PENTIUM) - Print("INCOMPATIBLE CPU TYPE!\n"); - - if (GetPlatform() < OS_WINNT) - cpu_class = CPU_P5; - - else - cpu_class = cpu_info.wProcessorLevel; - } - - return cpu_class; -} - -// +--------------------------------------------------------------------+ - -int -MachineInfo::GetCpuSpeed() -{ - if (cpu_speed < 0) { - cpu_speed = (int) (CalcCpuSpeed() / 1e6); - } - - return cpu_speed; -} - -// +--------------------------------------------------------------------+ - -int -MachineInfo::GetTotalRam() -{ - if (total_ram < 0) { - GlobalMemoryStatus(&mem_info); - total_ram = (int) (mem_info.dwTotalPhys/(1024*1024)) + 1; - } - - return total_ram; -} - -// +--------------------------------------------------------------------+ - -int -MachineInfo::GetPlatform() -{ - if (platform < 0) { - GetVersionEx(&os_ver); - - switch (os_ver.dwPlatformId) { - default: - case VER_PLATFORM_WIN32s: - case VER_PLATFORM_WIN32_WINDOWS: { - char msg[256]; - sprintf_s(msg, "Invalid Operating System Platform: %d\n", os_ver.dwPlatformId); //-V576 - Print(msg); - } - break; - - case VER_PLATFORM_WIN32_NT: - if (os_ver.dwMajorVersion == 4) - platform = OS_WINNT; - else if (os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 0) - platform = OS_WIN2K; - else if (os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 1) - platform = OS_WINXP; - else if (os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 2) - platform = OS_WINXP64; - else if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 0) - platform = OS_WINVISTA; - else if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 1) - platform = OS_WINSEVEN; - else if (os_ver.dwMajorVersion >= 6) - platform = OS_WINFUTURE; - - else { - platform = OS_INVALID; - - Print("Invalid Operating System Platform (NT-series): %d.%d\n", os_ver.dwMajorVersion, os_ver.dwMinorVersion); - } - - break; - } - } - - return platform; -} - -// +--------------------------------------------------------------------+ - -int -MachineInfo::GetDirectXVersion() -{ - if (dx_version < 0) { - dx_version = GetDXVersion(); - } - - return dx_version; -} - -// +--------------------------------------------------------------------+ - -void -MachineInfo::DescribeMachine() -{ - GetPlatform(); - GetCpuClass(); - - Print("+====================================================================+\n"); - Print("| |\n"); - - char txt[256]; - - switch (platform) { - case OS_WIN95: - sprintf_s(txt, "Windows 95 version %d.%d.%d %s", //-V576 - os_ver.dwMajorVersion, - os_ver.dwMinorVersion, - LOWORD(os_ver.dwBuildNumber), - os_ver.szCSDVersion); - break; - - case OS_WIN98: - sprintf_s(txt, "Windows 98 version %d.%d.%d %s", //-V576 - os_ver.dwMajorVersion, - os_ver.dwMinorVersion, - LOWORD(os_ver.dwBuildNumber), - os_ver.szCSDVersion); - break; - - case OS_WINNT: - sprintf_s(txt, "Windows NT %d.%d (Build %d) %s", //-V576 - os_ver.dwMajorVersion, - os_ver.dwMinorVersion, - os_ver.dwBuildNumber, - os_ver.szCSDVersion); - break; - - case OS_WIN2K: - sprintf_s(txt, "Windows 2000 %d.%d (Build %d) %s", //-V576 - os_ver.dwMajorVersion, - os_ver.dwMinorVersion, - os_ver.dwBuildNumber, - os_ver.szCSDVersion); - - case OS_WINXP: - sprintf_s(txt, "Windows XP %d.%d (Build %d) %s", //-V576 - os_ver.dwMajorVersion, - os_ver.dwMinorVersion, - os_ver.dwBuildNumber, - os_ver.szCSDVersion); - break; - case OS_WINXP64: - sprintf_s(txt, "Windows XP x64 %d.%d (Build %d) %s", //-V576 - os_ver.dwMajorVersion, - os_ver.dwMinorVersion, - os_ver.dwBuildNumber, - os_ver.szCSDVersion); - break; - case OS_WINVISTA: - sprintf_s(txt, "Windows Vista %d.%d (Build %d) %s", //-V576 - os_ver.dwMajorVersion, - os_ver.dwMinorVersion, - os_ver.dwBuildNumber, - os_ver.szCSDVersion); - break; - case OS_WINSEVEN: - sprintf_s(txt, "Windows 7 %d.%d (Build %d) %s", //-V576 - os_ver.dwMajorVersion, - os_ver.dwMinorVersion, - os_ver.dwBuildNumber, - os_ver.szCSDVersion); - break; - case OS_WINFUTURE: - sprintf_s(txt, "Windows from the future %d.%d (Build %d) %s", //-V576 - os_ver.dwMajorVersion, - os_ver.dwMinorVersion, - os_ver.dwBuildNumber, - os_ver.szCSDVersion); - break; - - default: - sprintf_s(txt, "Unknown Operating System Platform"); - break; - } - - Print("| %-66s |\n", txt); - Print("| |\n"); - - if (platform == OS_WIN95 || platform == OS_WIN98) - DescribeOwner95(); - else - DescribeOwnerNT(); - - sprintf_s(txt, "CPUs Detected: %d CPU Level: %d.%d.%d CPU Speed: %d", //-V576 - cpu_info.dwNumberOfProcessors, - cpu_info.wProcessorLevel, - cpu_info.wProcessorRevision >> 8, - cpu_info.wProcessorRevision & 0xff, - GetCpuSpeed() + 1); - - Print("| %-66s |\n", txt); - DescribeCpuMake(); - - GlobalMemoryStatus(&mem_info); - total_ram = (int) (mem_info.dwTotalPhys/(1024*1024)) + 1; - int swap_max = (int) (mem_info.dwTotalPageFile/(1024*1024)); - int swap_avail = (int) (mem_info.dwAvailPageFile/(1024*1024)); - - sprintf_s(txt, "%d MB RAM %d MB Max Swap %d MB Avail Swap", - total_ram, swap_max, swap_avail); - - - Print("| %-66s |\n", txt); - - Print("| |\n"); - Print("| DirectX %d installed. |\n", - GetDirectXVersion()); - DescribeDXVersion("DDRAW"); - DescribeDXVersion("D3DIM"); - DescribeDXVersion("DINPUT"); - DescribeDXVersion("DPLAY"); - DescribeDXVersion("DSOUND"); - DescribeDXVersion("DMUSIC"); - DescribeDXVersion("DSHOW"); - Print("| |\n"); - - - if (platform == OS_WIN95 || platform == OS_WIN98) { - DescribeDrivers95("Display"); - DescribeDrivers95("Media"); - DescribeDrivers95("Monitor"); - DescribeDrivers95("Multimedia"); - } - else { - DescribeDriversNT(""); - } - - Print("+====================================================================+\n"); - Print("\n"); -} - -// +--------------------------------------------------------------------+ - -static void DescribeCpuMake() -{ - HKEY hkWin; - char sProcessor[256] = ""; - char sMMXInfo[256] = ""; - char sVendor[256] = ""; - DWORD dwSize; - - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, - "Hardware\\Description\\System\\CentralProcessor\\0", - 0, - KEY_READ, - &hkWin) == ERROR_SUCCESS) { - - dwSize = 256; - RegQueryValueEx(hkWin, - "Identifier", - NULL, - NULL, - (LPBYTE) sProcessor, - &dwSize); - - dwSize = 256; - RegQueryValueEx(hkWin, - "MMXIdentifier", - NULL, - NULL, - (LPBYTE) sMMXInfo, - &dwSize); - - dwSize = 256; - RegQueryValueEx(hkWin, - "VendorIdentifier", - NULL, - NULL, - (LPBYTE) sVendor, - &dwSize); - - RegCloseKey(hkWin); - } - - if (sProcessor[0]) Print("| %-66s |\n", sProcessor); - if (sMMXInfo[0]) Print("| %-66s |\n", sMMXInfo); - if (sVendor[0]) Print("| %-66s |\n", sVendor); - - if (sProcessor[0] || sMMXInfo[0] || sVendor[0]) - Print("| |\n"); -} - -// +--------------------------------------------------------------------+ - -static void DescribeOwner95() -{ - HKEY hkWin; - char sRegisteredOwner[256] = ""; - char sRegisteredOrganization[256] = ""; - DWORD dwSize; - - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, - "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", - 0, - KEY_READ, - &hkWin) == ERROR_SUCCESS) { - - dwSize = 256; - RegQueryValueEx(hkWin, - "RegisteredOwner", - NULL, - NULL, - (LPBYTE) sRegisteredOwner, - &dwSize); - - dwSize = 256; - RegQueryValueEx(hkWin, - "RegisteredOrganization", - NULL, - NULL, - (LPBYTE) sRegisteredOrganization, - &dwSize); - - RegCloseKey(hkWin); - } - else { - Print("Could not access registered owner\n"); - } - - if (sRegisteredOwner[0]) { - char txt[256]; - sprintf_s(txt, "Registered Owner: %s, %s", sRegisteredOwner, sRegisteredOrganization); - Print("| %-66s |\n", txt); - Print("| |\n"); - } -} - -static void DescribeOwnerNT() -{ - HKEY hkWin; - char sRegisteredOwner[256] = ""; - char sRegisteredOrganization[256] = ""; - DWORD dwSize; - - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, - "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", - 0, - KEY_READ, - &hkWin) == ERROR_SUCCESS) { - - dwSize = 256; - RegQueryValueEx(hkWin, - "RegisteredOwner", - NULL, - NULL, - (LPBYTE) sRegisteredOwner, - &dwSize); - - dwSize = 256; - RegQueryValueEx(hkWin, - "RegisteredOrganization", - NULL, - NULL, - (LPBYTE) sRegisteredOrganization, - &dwSize); - - RegCloseKey(hkWin); - } - else { - Print("Could not access registered owner\n"); - } - - if (sRegisteredOwner[0]) { - char txt[256]; - sprintf_s(txt, "Registered Owner: %s, %s", sRegisteredOwner, sRegisteredOrganization); - Print("| %-66s |\n", txt); - Print("| |\n"); - } -} - -// +--------------------------------------------------------------------+ - -static void DescribeDrivers95(const char* sType) -{ - HKEY hkWin, hkSub; - int nKey = 0; - char sKey[256]; - char sSub[256]; - char sDriver[256]; - char txt[256]; - DWORD dwSize; - int worked; - - // describe the video driver(s): - do { - worked = 0; - - sprintf_s(sKey, "System\\CurrentControlSet\\Services\\Class\\%s\\%04X", sType, nKey); - sprintf_s(sSub, "System\\CurrentControlSet\\Services\\Class\\%s\\%04X\\DEFAULT", sType, nKey); - - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, - sKey, - 0, - KEY_READ, - &hkWin) == ERROR_SUCCESS) { - - dwSize = 256; - RegQueryValueEx(hkWin, - "DriverDesc", - NULL, - NULL, - (LPBYTE) sDriver, - &dwSize); - - if (sDriver[0]) { - sprintf_s(txt, "* %s", sDriver); - Print("| %-66s |\n", txt); - worked = 1; - } - - // try to find the driver file name: - if (worked) { - ZeroMemory(sDriver, sizeof(sDriver)); - - dwSize = 256; - DWORD err = RegQueryValueEx(hkWin, "Driver", NULL, NULL, (LPBYTE) sDriver, &dwSize); - - if (err != ERROR_SUCCESS) { - dwSize = 256; - err = RegQueryValueEx(hkWin, "DeviceDriver", NULL, NULL, (LPBYTE) sDriver, &dwSize); - } - - if (err != ERROR_SUCCESS) { - dwSize = 256; - err = RegQueryValueEx(hkWin, "drv", NULL, NULL, (LPBYTE) sDriver, &dwSize); - } - - if (err != ERROR_SUCCESS) { - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, - sSub, - 0, - KEY_READ, - &hkSub) == ERROR_SUCCESS) { - - dwSize = 256; - err = RegQueryValueEx(hkSub, "drv", NULL, NULL, (LPBYTE) sDriver, &dwSize); - - RegCloseKey(hkSub); - } - } - - // if we found it, try to display version info: - if (err == ERROR_SUCCESS) { - DescribeDriverVersion(sDriver); - } - - Print("| |\n"); - } - - RegCloseKey(hkWin); - } - - nKey++; - } - while (worked); -} - -static void DescribeDriversNT(const char* sType) -{ - Print("| |\n"); - - HKEY hkWin; - char sVideo[256] = ""; - char sDriver[256] = ""; - DWORD dwSize = 0; - - // find the pointer to the video driver: - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, - "HARDWARE\\DEVICEMAP\\VIDEO", - 0, - KEY_READ, - &hkWin) == ERROR_SUCCESS) { - - dwSize = 256; - RegQueryValueEx(hkWin, - "\\Device\\Video0", - NULL, - NULL, - (LPBYTE) sVideo, - &dwSize); - - RegCloseKey(hkWin); - } - - // follow the pointer and get the driver description: - if (dwSize && sVideo[0]) { - const char* sLeader = "\\REGISTRY\\Machine\\"; - int nLeader = strlen(sLeader); - - if (_strnicmp(sVideo, sLeader, nLeader) == 0) { - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, - sVideo + nLeader, - 0, - KEY_READ, - &hkWin) == ERROR_SUCCESS) { - - dwSize = 256; - RegQueryValueEx(hkWin, - "Device Description", - NULL, - NULL, - (LPBYTE) sDriver, - &dwSize); - - RegCloseKey(hkWin); - } - } - } - - if (sDriver[0]) { - Print("| %-66s |\n", sDriver); - Print("| |\n"); - } -} - -// +--------------------------------------------------------------------+ - -static char sTranslation[16]; - -static void GetTranslation(const LPBYTE pBlock) -{ - LPBYTE sData = NULL; - UINT lenData = 0; - - if (VerQueryValue(pBlock, "\\VarFileInfo\\Translation", - (LPVOID*) &sData, &lenData)) { - - if (lenData && sData) { - sprintf_s(sTranslation, "%02X%02X%02X%02X", sData[1], sData[0], sData[3], sData[2]); - } - } -} - -void DisplayVersionString(const LPBYTE pBlock, LPTSTR sSection) -{ - char txt[256]; - char sFullSection[256]; - - sprintf_s(sFullSection, "\\StringFileInfo\\%s\\%s", sTranslation, sSection); - - LPBYTE sData = NULL; - UINT lenData = 0; - DWORD dwErr = 0; - - if (VerQueryValue(pBlock, sFullSection, (LPVOID*) &sData, &lenData)) { - if (lenData && sData) { - sprintf_s(txt, "%-16s %s", sSection, sData); - Print("| %-60s |\n", txt); - } - } -} - -static void DescribeDriverVersion(const char* file) -{ - DWORD dwHandle = 0; - TCHAR szFile[512]; - - strcpy_s(szFile, file); - - int nBytes = GetFileVersionInfoSize(szFile, &dwHandle); - - if (nBytes <= 0) { - char szWinDir[256]; - GetSystemDirectory(szWinDir, 256); - sprintf_s(szFile, "%s\\%s", szWinDir, file); - - nBytes = GetFileVersionInfoSize(szFile, &dwHandle); - - if (nBytes <= 0) - return; - } - - LPBYTE pBlock = new BYTE[nBytes]; - - if (pBlock && GetFileVersionInfo(szFile, dwHandle, nBytes, (LPVOID) pBlock)) { - GetTranslation(pBlock); - DisplayVersionString(pBlock, "CompanyName"); - // DisplayVersionString(pBlock, "FileDescription"); - DisplayVersionString(pBlock, "FileVersion"); - // DisplayVersionString(pBlock, "InternalName"); - // DisplayVersionString(pBlock, "LegalCopyright"); - // DisplayVersionString(pBlock, "OriginalFilename"); - // DisplayVersionString(pBlock, "ProductName"); - // DisplayVersionString(pBlock, "ProductVersion"); - // DisplayVersionString(pBlock, "Comments"); - // DisplayVersionString(pBlock, "LegalTrademarks"); - // DisplayVersionString(pBlock, "PrivateBuild"); - // DisplayVersionString(pBlock, "SpecialBuild"); - } - - delete [] pBlock; -} - -static void DescribeDXVersion(const char* component) -{ - DWORD dwHandle = 0; - char szFile[512]; - char szWinDir[512]; - - GetSystemDirectory(szWinDir, 512); - - sprintf_s(szFile, "%s\\%s.dll", szWinDir, component); - - int nBytes = GetFileVersionInfoSize(szFile, &dwHandle); - - if (nBytes <= 0) { - return; - } - - LPBYTE pBlock = new BYTE[nBytes]; - - if (pBlock && GetFileVersionInfo(szFile, dwHandle, nBytes, (LPVOID) pBlock)) { - GetTranslation(pBlock); - - char txt[256]; - char sFullSection[256]; - LPBYTE sData = NULL; - UINT lenData = 0; - DWORD dwErr = 0; - - sprintf_s(sFullSection, "\\StringFileInfo\\%s\\FileVersion", sTranslation); - - if (VerQueryValue(pBlock, sFullSection, (LPVOID*) &sData, &lenData)) { - if (lenData && sData) { - sprintf_s(txt, "%-8s%s", component, sData); - Print("| %-64s |\n", txt); - } - } - } - - delete [] pBlock; -} \ No newline at end of file diff --git a/Stars45/MachineInfo.h b/Stars45/MachineInfo.h deleted file mode 100644 index 01e4bda..0000000 --- a/Stars45/MachineInfo.h +++ /dev/null @@ -1,41 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Collect and Display Machine, OS, and Driver Information -*/ - -#ifndef MachineInfo_h -#define MachineInfo_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class MachineInfo -{ -public: - enum { CPU_INVALID, CPU_P5=5, CPU_P6=6, CPU_P7=7, CPU_PLUS }; - enum { OS_INVALID, OS_WIN95, OS_WIN98, OS_WINNT, OS_WIN2K, OS_WINXP, OS_WINXP64, OS_WINVISTA, OS_WINSEVEN, OS_WINFUTURE }; - enum { DX_NONE, DX_3=3, DX_5=5, DX_6=6, DX_7=7, DX_8=8, DX_9=9, DX_PLUS }; - - static int GetCpuClass(); - static int GetCpuSpeed(); - static int GetTotalRam(); - static int GetPlatform(); - static int GetDirectXVersion(); - - static void DescribeMachine(); - - static const char* GetShortDescription(); -}; - -// +--------------------------------------------------------------------+ - -#endif // MachineInfo_h \ No newline at end of file diff --git a/Stars45/Main.cpp b/Stars45/Main.cpp deleted file mode 100644 index a71476d..0000000 --- a/Stars45/Main.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* 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 "StarServer.h" -#include "HUDView.h" -#include "Utils.h" - -#include "NetHost.h" -#include "NetAddr.h" -#include "NetLayer.h" -#include "NetBrokerClient.h" -#include "NetClient.h" -#include "HttpClient.h" - -#include "Color.h" -#include "DataLoader.h" -#include "Pcx.h" -#include "MachineInfo.h" -#include "Encrypt.h" -#include "FormatUtil.h" -#include "Panic.h" -#include "ParseUtil.h" -#include "Random.h" -#include "VersionInfo.h" - -// +--------------------------------------------------------------------+ -// WinMain -// +--------------------------------------------------------------------+ - -extern int VD3D_describe_things; -int dump_missions = 0; - -static void PrintLogHeader() -{ - Text sTime = FormatTimeString(); - - Print("+====================================================================+\n"); - Print("| STARSHATTER %-25s%29s |\n", versionInfo, sTime.data()); - - MachineInfo::DescribeMachine(); -} - -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - LPSTR lpCmdLine, int nCmdShow) -{ - int result = 0; - int test_mode = 0; - int do_server = 0; - - if (strstr(lpCmdLine, "-server")) - AssignErrLog(fopen("serverlog.txt", "wb")); - else - AssignErrLog(fopen("errlog.txt", "wb")); - - PrintLogHeader(); - - if (strstr(lpCmdLine, "-test")) { - Print(" Request TEST mode\n"); - test_mode = 1; - } - - if (strstr(lpCmdLine, "-fps")) { - HUDView::ShowFPS(true); - } - - if (strstr(lpCmdLine, "-dump")) { - Print(" Request dump dynamic missions\n"); - dump_missions = 1; - } - - if (strstr(lpCmdLine, "-lan")) { - Print(" Request LAN ONLY mode\n"); - NetBrokerClient::Disable(); - } - - if (strstr(lpCmdLine, "-server")) { - do_server = 1; - Print(" Request Standalone Server Mode\n"); - } - - char* d3dinfo = strstr(lpCmdLine, "-d3d"); - if (d3dinfo) { - int n = d3dinfo[4] - '0'; - - if (n >= 0 && n <= 5) - VD3D_describe_things = n; - - Print(" D3D Info Level: %d\n", VD3D_describe_things); - } - else { - VD3D_describe_things = 0; - } - - try { - NetLayer net; - - if (do_server) { - StarServer* server = new StarServer(); - - if (server->Init(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) - result = server->Run(); - - Print("\n+====================================================================+\n"); - Print(" Begin Shutdown...\n"); - - delete server; - } - - else { - Starshatter* stars = 0; - - stars = new Starshatter; - stars->SetTestMode(test_mode); - - if (stars->Init(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) - result = stars->Run(); - - Print("\n+====================================================================+\n"); - Print(" Begin Shutdown...\n"); - - delete stars; - } - - Token::close(); - - if (Panic::Panicked()) - MessageBox(0, Panic::Message(), "Starshatter - Error", MB_OK); - } - - catch (const char* msg) { - Print(" FATAL EXCEPTION: '%s'\n", msg); - } - /* } */ - - Print("+====================================================================+\n"); - Print(" END OF LINE.\n"); - - CloseErrLog(); - - return result; -} - - diff --git a/Stars45/MapView.cpp b/Stars45/MapView.cpp deleted file mode 100644 index dc992d1..0000000 --- a/Stars45/MapView.cpp +++ /dev/null @@ -1,3482 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Star Map class -*/ - -#include "MapView.h" - -#include "Galaxy.h" -#include "StarSystem.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Instruction.h" -#include "Element.h" -#include "NavAI.h" -#include "Weapon.h" -#include "Sim.h" -#include "Mission.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "Contact.h" -#include "MenuView.h" - -#include "NetLobby.h" -#include "NetUtil.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "EventDispatch.h" -#include "Video.h" -#include "Button.h" -#include "Bitmap.h" -#include "Font.h" -#include "FontMgr.h" -#include "Mouse.h" -#include "FormatUtil.h" -#include "Menu.h" - -// +--------------------------------------------------------------------+ - -// Supported Selection Modes: - -const int SELECT_NONE = -1; -const int SELECT_SYSTEM = 0; -const int SELECT_PLANET = 1; -const int SELECT_REGION = 2; -const int SELECT_STATION = 3; -const int SELECT_STARSHIP = 4; -const int SELECT_FIGHTER = 5; -const int SELECT_NAVPT = 6; - -const int VIEW_GALAXY = 0; -const int VIEW_SYSTEM = 1; -const int VIEW_REGION = 2; - -// +--------------------------------------------------------------------+ - -MapView::MapView(Window* win) -: View(win) -, system(0), zoom(1.1), offset_x(0), offset_y(0), ship(0), campaign(0) -, captured(false), dragging(false), adding_navpt(false) -, moving_navpt(false), moving_elem(false) -, view_mode(VIEW_SYSTEM), seln_mode(SELECT_REGION), ship_filter(0xffffffff) -, current_star(0), current_planet(0), current_region(0) -, current_ship(0), current_elem(0), current_navpt(0), mission(0) -, scrolling(0), scroll_x(0), scroll_y(0), click_x(0), click_y(0) -, active_menu(0), map_menu(0), map_system_menu(0), map_sector_menu(0) -, ship_menu(0), editor(false) -, nav_menu(0), action_menu(0), objective_menu(0), formation_menu(0), speed_menu(0) -, hold_menu(0), farcast_menu(0), menu_view(0) -{ - for (int i = 0; i < 3; i++) { - view_zoom[i] = zoom; - view_offset_x[i] = offset_x; - view_offset_y[i] = offset_y; - } - - menu_view = new MenuView(window); - - title_font = FontMgr::Find("Limerick12"); - font = FontMgr::Find("Verdana"); - - active_window = (ActiveWindow*) window; - - if (active_window) - active_window->AddView(this); -} - -// +--------------------------------------------------------------------+ - -MapView::~MapView() -{ - ClearMenu(); - galaxy_image.ClearImage(); - - delete menu_view; -} - -// +--------------------------------------------------------------------+ - -void -MapView::OnWindowMove() -{ - if (menu_view) - menu_view->OnWindowMove(); -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetGalaxy(List& g) -{ - system_list.clear(); - system_list.append(g); - - if (system_list.size() > 0) { - SetSystem(system_list[0]); - } -} - -void -MapView::SetSystem(StarSystem* s) -{ - if (system != s) { - system = s; - - // forget invalid selection: - current_star = 0; - current_planet = 0; - current_region = 0; - current_ship = 0; - current_elem = 0; - current_navpt = 0; - - // flush old object pointers: - stars.clear(); - planets.clear(); - regions.clear(); - - // insert objects from star system: - if (system) { - ListIter star = system->Bodies(); - while (++star) { - switch (star->Type()) { - case Orbital::STAR: stars.append(star.value()); - break; - case Orbital::PLANET: - case Orbital::MOON: planets.append(star.value()); - break; - } - } - - ListIter planet = star->Satellites(); - while (++planet) { - planets.append(planet.value()); - - ListIter moon = planet->Satellites(); - while (++moon) { - planets.append(moon.value()); - } - } - - ListIter rgn = system->AllRegions(); - while (++rgn) - regions.append(rgn.value()); - - // sort region list by distance from the star: - regions.sort(); - } - - BuildMenu(); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetShip(Ship* s) -{ - if (ship != s) { - ship = s; - - // forget invalid selection: - current_star = 0; - current_planet = 0; - current_region = 0; - current_ship = 0; - current_elem = 0; - current_navpt = 0; - - if (ship && system_list.size() > 0) { - SimRegion* rgn = ship->GetRegion(); - - if (rgn && rgn->System()) { - system = 0; - SetSystem(rgn->System()); - } - } - - BuildMenu(); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetMission(Mission* m) -{ - if (mission != m) { - mission = m; - - // forget invalid selection: - current_star = 0; - current_planet = 0; - current_region = 0; - current_ship = 0; - current_elem = 0; - current_navpt = 0; - - if (mission && system_list.size() > 0) { - system = 0; - SetSystem(mission->GetStarSystem()); - } - - BuildMenu(); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetCampaign(Campaign* c) -{ - if (campaign != c) { - campaign = c; - - // forget invalid selection: - current_star = 0; - current_planet = 0; - current_region = 0; - current_ship = 0; - current_elem = 0; - current_navpt = 0; - - if (campaign) - SetGalaxy(campaign->GetSystemList()); - } -} - -// +--------------------------------------------------------------------+ - -enum MapView_MENU { - MAP_SYSTEM = 1000, - MAP_SECTOR = 2000, - MAP_SHIP = 3000, - MAP_NAV = 4000, - MAP_ADDNAV = 4001, - MAP_DELETE = 4002, - MAP_CLEAR = 4003, - MAP_ACTION = 5000, - MAP_FORMATION = 6000, - MAP_SPEED = 7000, - MAP_HOLD = 8000, - MAP_FARCAST = 8500, - MAP_OBJECTIVE = 9000 -}; - -void -MapView::BuildMenu() -{ - ClearMenu(); - - map_system_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.STARSYSTEM")); - - if (system_list.size() > 0) { - int i = 0; - ListIter iter = system_list; - while (++iter) { - StarSystem* s = iter.value(); - map_system_menu->AddItem(s->Name(), MAP_SYSTEM + i); - i++; - } - } - - else if (system) { - map_system_menu->AddItem(system->Name(), MAP_SYSTEM); - } - - map_sector_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.SECTOR")); - for (int i = 0; i < regions.size(); i++) { - Orbital* rgn = regions[i]; - map_sector_menu->AddItem(rgn->Name(), MAP_SECTOR + i); - } - - map_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.MAP")); - map_menu->AddMenu("System", map_system_menu); - map_menu->AddMenu("Sector", map_sector_menu); - - if (ship || mission) { - ship_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.SHIP")); - ship_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Starsystem"), map_system_menu); - ship_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Sector"), map_sector_menu); - - ship_menu->AddItem("", 0); - ship_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Add-Nav"), MAP_ADDNAV); - ship_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Clear-All"), MAP_CLEAR); - - action_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.ACTION")); - for (int i = 0; i < Instruction::NUM_ACTIONS; i++) { - action_menu->AddItem(ContentBundle::GetInstance()->GetText(Text("MapView.item.") + Instruction::ActionName(i)), MAP_ACTION + i); - } - - formation_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.FORMATION")); - for (int i = 0; i < Instruction::NUM_FORMATIONS; i++) { - formation_menu->AddItem(ContentBundle::GetInstance()->GetText(Text("MapView.item.") + Instruction::FormationName(i)), MAP_FORMATION + i); - } - - speed_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.SPEED")); - speed_menu->AddItem("250", MAP_SPEED + 0); - speed_menu->AddItem("500", MAP_SPEED + 1); - speed_menu->AddItem("750", MAP_SPEED + 2); - speed_menu->AddItem("1000", MAP_SPEED + 3); - - hold_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.HOLD")); - hold_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.None"), MAP_HOLD + 0); - hold_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.1-Minute"), MAP_HOLD + 1); - hold_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.5-Minutes"), MAP_HOLD + 2); - hold_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.10-Minutes"), MAP_HOLD + 3); - hold_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.15-Minutes"), MAP_HOLD + 4); - - farcast_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.FARCAST")); - farcast_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Use-Quantum"), MAP_FARCAST + 0); - farcast_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Use-Farcast"), MAP_FARCAST + 1); - - objective_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.OBJECTIVE")); - - nav_menu = new Menu(ContentBundle::GetInstance()->GetText("MapView.menu.NAVPT")); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Action"), action_menu); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Objective"), objective_menu); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Formation"), formation_menu); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Speed"), speed_menu); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Hold"), hold_menu); - nav_menu->AddMenu(ContentBundle::GetInstance()->GetText("MapView.item.Farcast"), farcast_menu); - nav_menu->AddItem("", 0); - nav_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Add-Nav"), MAP_ADDNAV); - nav_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.Del-Nav"), MAP_DELETE); - } - - else if (campaign) { - ship_menu = 0; - speed_menu = 0; - hold_menu = 0; - farcast_menu = 0; - objective_menu = 0; - formation_menu = 0; - nav_menu = 0; - } - - active_menu = map_menu; -} - -// +--------------------------------------------------------------------+ - -void -MapView::ClearMenu() -{ - delete map_menu; - delete map_system_menu; - delete map_sector_menu; - delete ship_menu; - delete nav_menu; - delete action_menu; - delete objective_menu; - delete formation_menu; - delete speed_menu; - delete hold_menu; - delete farcast_menu; - - map_menu = 0; - map_system_menu = 0; - map_sector_menu = 0; - ship_menu = 0; - nav_menu = 0; - action_menu = 0; - objective_menu = 0; - formation_menu = 0; - speed_menu = 0; - hold_menu = 0; - farcast_menu = 0; -} - -// +--------------------------------------------------------------------+ - -void -MapView::ProcessMenuItem(int action) -{ - bool send_nav_data = false; - bool can_command = true; - - if (ship && current_ship && ship != current_ship) { - if (ship->GetElement() && current_ship->GetElement()) { - if (!ship->GetElement()->CanCommand(current_ship->GetElement())) { - can_command = false; - } - } - } - - else if (current_elem && NetLobby::GetInstance()) { - can_command = false; - } - - if (action >= MAP_OBJECTIVE) { - int index = action - MAP_OBJECTIVE; - - if (current_navpt && can_command) { - current_navpt->SetTarget(objective_menu->GetItem(index)->GetText()); - send_nav_data = true; - } - } - - else if (action >= MAP_FARCAST) { - if (current_navpt && can_command) { - current_navpt->SetFarcast(action - MAP_FARCAST); - send_nav_data = true; - } - } - - else if (action >= MAP_HOLD) { - int hold_time = 0; - switch (action) { - default: - case MAP_HOLD + 0: hold_time = 0; break; - case MAP_HOLD + 1: hold_time = 60; break; - case MAP_HOLD + 2: hold_time = 300; break; - case MAP_HOLD + 3: hold_time = 600; break; - case MAP_HOLD + 4: hold_time = 900; break; - } - - if (current_navpt && can_command) { - current_navpt->SetHoldTime(hold_time); - send_nav_data = true; - } - } - - else if (action >= MAP_SPEED) { - if (current_navpt && can_command) { - current_navpt->SetSpeed((action - MAP_SPEED + 1) * 250); - send_nav_data = true; - } - } - - else if (action >= MAP_FORMATION) { - if (current_navpt && can_command) { - current_navpt->SetFormation(action - MAP_FORMATION); - send_nav_data = true; - } - } - - else if (action >= MAP_ACTION) { - if (current_navpt && can_command) { - current_navpt->SetAction(action - MAP_ACTION); - SelectNavpt(current_navpt); - send_nav_data = true; - } - } - - else if (action == MAP_ADDNAV) { - Text rgn_name = regions[current_region]->Name(); - Instruction* prior = current_navpt; - Instruction* n = 0; - - if (current_ship && can_command) { - Sim* sim = Sim::GetSim(); - SimRegion* rgn = sim->FindRegion(rgn_name); - Point init_pt; - - if (rgn) { - if (rgn->IsAirSpace()) - init_pt.z = 10e3; - - n = new Instruction(rgn, init_pt); - } - else { - n = new Instruction(rgn_name, init_pt); - } - - n->SetSpeed(500); - - if (prior) { - n->SetAction(prior->Action()); - n->SetFormation(prior->Formation()); - n->SetSpeed(prior->Speed()); - n->SetTarget(prior->GetTarget()); - } - - current_ship->AddNavPoint(n, prior); - } - - else if (current_elem && can_command) { - Point init_pt; - - if (regions[current_region]->Type() == Orbital::TERRAIN) - init_pt.z = 10e3; - - n = new Instruction(rgn_name, init_pt); - n->SetSpeed(500); - - if (prior) { - n->SetAction(prior->Action()); - n->SetFormation(prior->Formation()); - n->SetSpeed(prior->Speed()); - n->SetTarget(prior->GetTarget()); - } - - current_elem->AddNavPoint(n, prior); - } - - if (can_command) { - current_navpt = n; - current_status = Instruction::PENDING; - adding_navpt = true; - captured = SetCapture(); - } - } - - else if (action == MAP_DELETE) { - if (current_navpt && can_command) { - if (current_ship) - current_ship->DelNavPoint(current_navpt); - else if (current_elem && can_command) - current_elem->DelNavPoint(current_navpt); - - SelectNavpt(0); - } - } - - else if (action == MAP_CLEAR) { - if (current_ship && can_command) - current_ship->ClearFlightPlan(); - else if (current_elem && can_command) - current_elem->ClearFlightPlan(); - - SelectNavpt(0); - } - - else if (action >= MAP_NAV) { - } - - else if (action >= MAP_SHIP) { - } - - else if (action >= MAP_SECTOR) { - int index = action - MAP_SECTOR; - - if (index < regions.size()) - current_region = index; - - if (view_mode == VIEW_SYSTEM) { - Orbital* s = regions[current_region]; - SetupScroll(s); - } - } - - else if (system_list.size() > 0 && action >= MAP_SYSTEM) { - int index = action - MAP_SYSTEM; - - if (index < system_list.size()) - SetSystem(system_list[index]); - } - - else { - } - - Sim* sim = Sim::GetSim(); - if (send_nav_data && sim) { - Ship* s = current_ship; - - if (s && s->GetElement()) { - Element* elem = s->GetElement(); - int index = elem->GetNavIndex(current_navpt); - - if (index >= 0) - NetUtil::SendNavData(false, elem, index-1, current_navpt); - } - } -} - -// +--------------------------------------------------------------------+ - -bool -MapView::SetCapture() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - return dispatch->CaptureMouse(this) ? true : false; - - return 0; -} - -// +--------------------------------------------------------------------+ - -bool -MapView::ReleaseCapture() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - return dispatch->ReleaseMouse(this) ? true : false; - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetViewMode(int mode) -{ - if (mode >= 0 && mode < 3) { - // save state: - view_zoom[view_mode] = zoom; - view_offset_x[view_mode] = offset_x; - view_offset_y[view_mode] = offset_y; - - // switch mode: - view_mode = mode; - - // restore state: - - if (view_mode == VIEW_GALAXY) { - zoom = 1; - offset_x = 0; - offset_y = 0; - } - else { - zoom = view_zoom[view_mode]; - offset_x = view_offset_x[view_mode]; - offset_y = view_offset_y[view_mode]; - } - - scrolling = 0; - scroll_x = 0; - scroll_y = 0; - } -} - -// +--------------------------------------------------------------------+ - -bool -MapView::Update(SimObject* obj) -{ - if (obj == current_ship) { - current_ship = 0; - active_menu = map_menu; - } - - return SimObserver::Update(obj); -} - -// +--------------------------------------------------------------------+ - -void -MapView::SelectShip(Ship* selship) -{ - if (selship != current_ship) { - current_ship = selship; - - if (current_ship) { - if (current_ship->Life() == 0 || current_ship->IsDying() || current_ship->IsDead()) { - current_ship = 0; - } - else { - Observe(current_ship); - } - } - } - - SelectNavpt(0); -} - -// +--------------------------------------------------------------------+ - -void -MapView::SelectElem(MissionElement* elem) -{ - if (elem != current_elem) { - current_elem = elem; - - if (current_elem) { - if (current_elem->IsStarship()) { - ship_menu->GetItem(3)->SetEnabled(true); - } - - else if (current_elem->IsDropship()) { - ship_menu->GetItem(3)->SetEnabled(true); - } - - else { - ship_menu->GetItem(3)->SetEnabled(false); - } - } - } - - SelectNavpt(0); -} - -// +--------------------------------------------------------------------+ - -void -MapView::SelectNavpt(Instruction* navpt) -{ - current_navpt = navpt; - - if (current_navpt) { - current_status = current_navpt->Status(); - - List ships; - objective_menu->ClearItems(); - - switch (current_navpt->Action()) { - case Instruction::VECTOR: - case Instruction::LAUNCH: - case Instruction::PATROL: - case Instruction::SWEEP: - case Instruction::RECON: - objective_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.not-available"), 0); - objective_menu->GetItem(0)->SetEnabled(false); - break; - - case Instruction::DOCK: - FindShips(true, true, true, false, ships); - break; - - case Instruction::DEFEND: - FindShips(true, true, true, false, ships); - break; - - case Instruction::ESCORT: - FindShips(true, false, true, true, ships); - break; - - case Instruction::INTERCEPT: - FindShips(false, false, false, true, ships); - break; - - case Instruction::ASSAULT: - FindShips(false, false, true, false, ships); - break; - - case Instruction::STRIKE: - FindShips(false, true, false, false, ships); - break; - } - - for (int i = 0; i < ships.size(); i++) - objective_menu->AddItem(ships[i]->data(), MAP_OBJECTIVE + i); - - ships.destroy(); - } - else { - objective_menu->ClearItems(); - objective_menu->AddItem(ContentBundle::GetInstance()->GetText("MapView.item.not-available"), 0); - objective_menu->GetItem(0)->SetEnabled(false); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::FindShips(bool friendly, bool station, bool starship, bool dropship, -List& result) -{ - if (mission) { - for (int i = 0; i < mission->GetElements().size(); i++) { - MissionElement* elem = mission->GetElements().at(i); - - if (elem->IsSquadron()) continue; - if (!station && elem->IsStatic()) continue; - if (!starship && elem->IsStarship()) continue; - if (!dropship && elem->IsDropship()) continue; - - if (!editor && friendly && elem->GetIFF() > 0 && elem->GetIFF() != mission->Team()) - continue; - - if (!editor && !friendly && (elem->GetIFF() == 0 || elem->GetIFF() == mission->Team())) - continue; - - result.append(new Text(elem->Name())); - } - } - - else if (ship) { - Sim* sim = Sim::GetSim(); - - if (sim) { - for (int r = 0; r < sim->GetRegions().size(); r++) { - SimRegion* rgn = sim->GetRegions().at(r); - - for (int i = 0; i < rgn->Ships().size(); i++) { - Ship* s = rgn->Ships().at(i); - - if (!station && s->IsStatic()) continue; - if (!starship && s->IsStarship()) continue; - if (!dropship && s->IsDropship()) continue; - - if (friendly && s->GetIFF() > 0 && s->GetIFF() != ship->GetIFF()) - continue; - - if (!friendly && (s->GetIFF() == 0 || s->GetIFF() == ship->GetIFF())) - continue; - - result.append(new Text(s->Name())); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetSelectionMode(int mode) -{ - if (mode <= SELECT_NONE) { - seln_mode = SELECT_NONE; - return; - } - - if (mode != seln_mode && mode <= SELECT_FIGHTER) { - seln_mode = mode; - - // when changing mode, - // select the item closest to the current center: - if (system && view_mode == VIEW_SYSTEM) - SelectAt(rect.x + rect.w/2, - rect.y + rect.h/2); - } -} - -void -MapView::SetSelection(int index) -{ - if (scrolling) return; - Orbital* s = 0; - - switch (seln_mode) { - case SELECT_SYSTEM: - if (index < system_list.size()) - SetSystem(system_list[index]); - s = stars[current_star]; - break; - - default: - case SELECT_PLANET: - if (index < planets.size()) - current_planet = index; - s = planets[current_planet]; - break; - - case SELECT_REGION: - if (index < regions.size()) - current_region = index; - s = regions[current_region]; - break; - - case SELECT_STATION: - { - if (mission) { - MissionElement* selected_elem = 0; - - ListIter elem = mission->GetElements(); - while (++elem) { - if (elem->IsStatic()) { - if (elem->Identity() == index) { - selected_elem = elem.value(); - break; - } - } - } - - SelectElem(selected_elem); - - if (selected_elem && regions.size()) { - ListIter rgn = regions; - while (++rgn) { - if (!_stricmp(selected_elem->Region(), rgn->Name())) { - Orbital* elem_region = rgn.value(); - current_region = regions.index(elem_region); - } - } - } - } - - else { - Ship* selship = 0; - - if (ship) { - SimRegion* simrgn = ship->GetRegion(); - if (simrgn) { - ListIter s = simrgn->Ships(); - while (++s) { - if (s->IsStatic()) { - if (s->Identity() == index) { - selship = s.value(); - break; - } - } - } - } - } - - SelectShip(selship); - - if (selship) { - s = selship->GetRegion()->GetOrbitalRegion(); - current_region = regions.index(s); - } - } - } - break; - - case SELECT_STARSHIP: - { - if (mission) { - MissionElement* selected_elem = 0; - - ListIter elem = mission->GetElements(); - while (++elem) { - if (elem->IsStarship()) { - if (elem->Identity() == index) { - selected_elem = elem.value(); - break; - } - } - } - - SelectElem(selected_elem); - - if (selected_elem && regions.size()) { - ListIter rgn = regions; - while (++rgn) { - if (!_stricmp(selected_elem->Region(), rgn->Name())) { - Orbital* elem_region = rgn.value(); - current_region = regions.index(elem_region); - } - } - } - } - - else { - Ship* selship = 0; - - if (ship) { - SimRegion* simrgn = ship->GetRegion(); - if (simrgn) { - ListIter s = simrgn->Ships(); - while (++s) { - if (s->IsStarship()) { - if (s->Identity() == index) { - selship = s.value(); - break; - } - } - } - } - } - - SelectShip(selship); - - if (selship) { - s = selship->GetRegion()->GetOrbitalRegion(); - current_region = regions.index(s); - } - } - } - break; - - case SELECT_FIGHTER: - { - if (mission) { - MissionElement* selected_elem = 0; - - ListIter elem = mission->GetElements(); - while (++elem) { - if (elem->IsDropship() && !elem->IsSquadron()) { - if (elem->Identity() == index) { - selected_elem = elem.value(); - break; - } - } - } - - SelectElem(selected_elem); - - if (selected_elem && regions.size()) { - ListIter rgn = regions; - while (++rgn) { - if (!_stricmp(selected_elem->Region(), rgn->Name())) { - Orbital* elem_region = rgn.value(); - current_region = regions.index(elem_region); - } - } - } - } - - else { - Ship* selship = 0; - - if (ship) { - SimRegion* simrgn = ship->GetRegion(); - if (simrgn) { - ListIter s = simrgn->Ships(); - while (++s) { - if (s->IsDropship()) { - if (s->Identity() == index) { - selship = s.value(); - break; - } - } - } - } - } - - SelectShip(selship); - - if (selship) { - s = selship->GetRegion()->GetOrbitalRegion(); - current_region = regions.index(s); - } - } - } - break; - } - - SetupScroll(s); -} - -void -MapView::SetSelectedShip(Ship* ship) -{ - if (scrolling) return; - Orbital* s = 0; - Ship* selship = 0; - - - switch (seln_mode) { - case SELECT_SYSTEM: - case SELECT_PLANET: - case SELECT_REGION: - default: - break; - - case SELECT_STATION: - case SELECT_STARSHIP: - case SELECT_FIGHTER: - { - if (ship) { - SimRegion* simrgn = ship->GetRegion(); - - if (simrgn && simrgn->NumShips()) { - selship = simrgn->Ships().find(ship); - } - } - - SelectShip(selship); - } - break; - } - - if (selship) - SetupScroll(s); -} - -void -MapView::SetSelectedElem(MissionElement* elem) -{ - if (scrolling) return; - Orbital* s = 0; - - switch (seln_mode) { - case SELECT_SYSTEM: - case SELECT_PLANET: - case SELECT_REGION: - default: - break; - - case SELECT_STATION: - case SELECT_STARSHIP: - case SELECT_FIGHTER: - { - SelectElem(elem); - } - break; - } - - if (current_elem) - SetupScroll(s); -} - -void -MapView::SetupScroll(Orbital* s) -{ - switch (view_mode) { - case VIEW_GALAXY: - zoom = 1; - offset_x = 0; - offset_y = 0; - scrolling = 0; - break; - - case VIEW_SYSTEM: - if (s == 0) { - offset_x = 0; - offset_y = 0; - scrolling = 0; - } - else { - scroll_x = (offset_x + s->Location().x) / 5.0; - scroll_y = (offset_y + s->Location().y) / 5.0; - scrolling = 5; - } - break; - - case VIEW_REGION: - if (current_navpt) { - // don't move the map - scrolling = 0; - } - else if (current_ship) { - Point sloc = current_ship->Location().OtherHand(); - - if (!IsVisible(sloc)) { - scroll_x = (offset_x + sloc.x) / 5.0; - scroll_y = (offset_y + sloc.y) / 5.0; - scrolling = 5; - } - else { - scroll_x = 0; - scroll_y = 0; - scrolling = 0; - } - } - else if (current_elem) { - Point sloc = current_elem->Location(); - - if (!IsVisible(sloc)) { - scroll_x = (offset_x + sloc.x) / 5.0; - scroll_y = (offset_y + sloc.y) / 5.0; - scrolling = 5; - } - else { - scroll_x = 0; - scroll_y = 0; - scrolling = 0; - } - } - else { - offset_x = 0; - offset_y = 0; - scrolling = 0; - } - break; - } -} - -bool -MapView::IsVisible(const Point& loc) -{ - if (view_mode == VIEW_REGION) { - double scale = c/r; - double ox = offset_x * scale; - double oy = offset_y * scale; - double sx = loc.x * scale; - double sy = loc.y * scale; - double cx = rect.w/2; - double cy = rect.h/2; - - int test_x = (int) (cx + sx + ox); - int test_y = (int) (cy + sy + oy); - - bool visible = test_x >= 0 && test_x < rect.w && - test_y >= 0 && test_y < rect.h; - - return visible; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetRegion(OrbitalRegion* rgn) -{ - if (scrolling || rgn == 0) return; - - int index = regions.index(rgn); - - if (index < 0 || index == current_region || index >= regions.size()) - return; - - current_region = index; - Orbital* s = regions[current_region]; - - if (!s) - return; - - switch (view_mode) { - case VIEW_GALAXY: - case VIEW_SYSTEM: - scroll_x = (offset_x + s->Location().x) / 5.0; - scroll_y = (offset_y + s->Location().y) / 5.0; - scrolling = 5; - break; - - case VIEW_REGION: - offset_x = 0; - offset_y = 0; - scrolling = 0; - break; - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::SetRegionByName(const char* rgn_name) -{ - OrbitalRegion* rgn = 0; - - for (int i = 0; i < regions.size(); i++) { - Orbital* r = regions[i]; - if (!strcmp(rgn_name, r->Name())) { - rgn = (OrbitalRegion*) r; - break; - } - } - - SetRegion(rgn); -} - -// +--------------------------------------------------------------------+ - -void -MapView::SelectAt(int x, int y) -{ - if (scrolling) return; - if (c == 0) return; - if (seln_mode < 0) return; - - Orbital* s = 0; - - double scale = r/c; - double cx = rect.w/2; - double cy = rect.h/2; - double test_x = (x - rect.x - cx) * scale - offset_x; - double test_y = (y - rect.y - cy) * scale - offset_y; - double dist = 1.0e20; - int closest = 0; - - if (view_mode == VIEW_GALAXY) { - c = (cx>cy) ? cx : cy; - r = 10; - - Galaxy* g = Galaxy::GetInstance(); - if (g) - r = g->Radius(); - - StarSystem* closest_system = 0; - - // draw the list of systems, and their connections: - ListIter iter = system_list; - while (++iter) { - StarSystem* s = iter.value(); - - double dx = (s->Location().x - test_x); - double dy = (s->Location().y - test_y); - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - closest_system = s; - } - } - - if (closest_system) - SetSystem(closest_system); - } - - else if (view_mode == VIEW_SYSTEM) { - switch (seln_mode) { - case SELECT_SYSTEM: { - if (stars.isEmpty()) return; - int index = 0; - ListIter star = stars; - while (++star) { - double dx = (star->Location().x - test_x); - double dy = (star->Location().y - test_y); - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - closest = index; - } - - index++; - } - - current_star = closest; - } - s = stars[current_star]; - break; - - case SELECT_PLANET: { - if (planets.isEmpty()) return; - int index = 0; - ListIter planet = planets; - while (++planet) { - double dx = (planet->Location().x - test_x); - double dy = (planet->Location().y - test_y); - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - closest = index; - } - - index++; - } - - current_planet = closest; - } - s = planets[current_planet]; - break; - - default: - case SELECT_REGION: { - if (regions.isEmpty()) return; - int index = 0; - ListIter region = regions; - while (++region) { - double dx = (region->Location().x - test_x); - double dy = (region->Location().y - test_y); - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - closest = index; - } - - index++; - } - - current_region = closest; - } - s = regions[current_region]; - break; - } - } - - else if (view_mode == VIEW_REGION) { - dist = 5.0e3; - - if (mission) { - Orbital* rgn = regions[current_region]; - MissionElement* sel_elem = 0; - Instruction* sel_nav = 0; - - if (!rgn) return; - - // check nav points: - ListIter elem = mission->GetElements(); - while (++elem) { - MissionElement* e = elem.value(); - - if (!e->IsSquadron() && (editor || e->GetIFF() == mission->Team())) { - ListIter navpt = e->NavList(); - while (++navpt) { - Instruction* n = navpt.value(); - - if (!_stricmp(n->RegionName(), rgn->Name())) { - Point nloc = n->Location(); - double dx = nloc.x - test_x; - double dy = nloc.y - test_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - sel_nav = n; - sel_elem = e; - } - } - } - } - } - - if (sel_nav) { - SelectElem(sel_elem); - SelectNavpt(sel_nav); - } - - // check elements: - else { - elem.reset(); - while (++elem) { - MissionElement* e = elem.value(); - - if (e->Region() == rgn->Name() && !e->IsSquadron()) { - Point sloc = e->Location(); - double dx = sloc.x - test_x; - double dy = sloc.y - test_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - sel_elem = e; - } - } - } - - SelectElem(sel_elem); - - if (sel_elem) - s = rgn; - } - } - else if (ship) { - Sim* sim = Sim::GetSim(); - Orbital* rgn = regions[current_region]; - SimRegion* simrgn = 0; - Ship* sel_ship = 0; - Instruction* sel_nav = 0; - - if (sim && rgn) - simrgn = sim->FindRegion(rgn->Name()); - - // check nav points: - if (simrgn) { - for (int r = 0; r < sim->GetRegions().size(); r++) { - SimRegion* simrgn = sim->GetRegions().at(r); - - for (int i = 0; i < simrgn->Ships().size(); i++) { - Ship* s = simrgn->Ships().at(i); - - if (s->GetIFF() == ship->GetIFF() && s->GetElementIndex() == 1) { - ListIter navpt = s->GetFlightPlan(); - while (++navpt) { - Instruction* n = navpt.value(); - - if (!_stricmp(n->RegionName(), rgn->Name())) { - Point nloc = n->Location(); - double dx = nloc.x - test_x; - double dy = nloc.y - test_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - sel_nav = n; - sel_ship = s; - } - } - } - } - } - } - } - - if (sel_nav) { - SelectShip(sel_ship); - SelectNavpt(sel_nav); - } - - // check ships: - else if (simrgn->NumShips()) { - ListIter ship = simrgn->Ships(); - while (++ship) { - Ship* s = ship.value(); - - if (!IsClutter(*s)) { - Point sloc = s->Location().OtherHand(); - double dx = sloc.x - test_x; - double dy = sloc.y - test_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < dist) { - dist = d; - sel_ship = s; - } - } - } - - SelectShip(sel_ship); - } - else { - SelectShip(0); - SelectNavpt(0); - } - } - } - - if (s) - SetupScroll(s); -} - -// +--------------------------------------------------------------------+ - -Orbital* -MapView::GetSelection() -{ - Orbital* s = 0; - - switch (seln_mode) { - case SELECT_SYSTEM: - if (current_star < stars.size()) - s = stars[current_star]; - break; - - default: - case SELECT_PLANET: - if (current_planet < planets.size()) - s = planets[current_planet]; - break; - - case SELECT_REGION: - if (current_region < regions.size()) - s = regions[current_region]; - break; - - case SELECT_STATION: - case SELECT_STARSHIP: - case SELECT_FIGHTER: - break; - } - - return s; -} - -Ship* -MapView::GetSelectedShip() -{ - return current_ship; -} - -MissionElement* -MapView::GetSelectedElem() -{ - return current_elem; -} - -// +--------------------------------------------------------------------+ - -int -MapView::GetSelectionIndex() -{ - int s = 0; - - switch (seln_mode) { - case SELECT_SYSTEM: s = current_star; break; - default: - case SELECT_PLANET: s = current_planet; break; - case SELECT_REGION: s = current_region; break; - - case SELECT_STATION: - case SELECT_STARSHIP: - case SELECT_FIGHTER: - { - s = -1; - Sim* sim = Sim::GetSim(); - Orbital* rgn = regions[current_region]; - SimRegion* simrgn = 0; - - if (sim && rgn) - simrgn = sim->FindRegion(rgn->Name()); - - if (simrgn) { - if (current_ship && simrgn->NumShips()) { - s = simrgn->Ships().index(current_ship); - } - } - } - break; - } - - return s; -} - -void -MapView::DrawTabbedText(Font* font, const char* text) -{ - if (font && text && *text) { - Rect label_rect; - - label_rect.w = rect.w; - label_rect.h = rect.h; - - label_rect.Inset(8,8,8,8); - - DWORD text_flags = DT_WORDBREAK | DT_LEFT; - - active_window->SetFont(font); - active_window->DrawText(text, 0, label_rect, text_flags); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::Refresh() -{ - rect = window->GetRect(); - - if (!system) { - DrawGrid(); - DrawTabbedText(title_font, ContentBundle::GetInstance()->GetText("MapView.item.no-system")); - return; - } - - if (font) - font->SetColor(Color::White); - - if (scrolling) { - offset_x -= scroll_x; - offset_y -= scroll_y; - scrolling--; - } - - rect.w -= 2; - rect.h -= 2; - - switch (view_mode) { - case VIEW_GALAXY: DrawGalaxy(); break; - case VIEW_SYSTEM: DrawSystem(); break; - case VIEW_REGION: DrawRegion(); break; - default: DrawGrid(); break; - } - - rect.w += 2; - rect.h += 2; - - if (menu_view) { - if (current_navpt) { - active_menu = nav_menu; - } - else if (current_ship) { - if (current_ship->GetIFF() == ship->GetIFF()) - active_menu = ship_menu; - else - active_menu = map_menu; - } - else if (current_elem) { - if (editor || current_elem->GetIFF() == mission->Team()) - active_menu = ship_menu; - else - active_menu = map_menu; - } - else { - active_menu = map_menu; - } - - menu_view->SetBackColor(Color::Gray); - menu_view->SetTextColor(Color::White); - menu_view->SetMenu(active_menu); - menu_view->DoMouseFrame(); - - if (menu_view->GetAction()) { - ProcessMenuItem(menu_view->GetAction()); - } - - menu_view->Refresh(); - } - - DrawTitle(); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawTitle() -{ - title_font->SetColor(active_window->GetForeColor()); - DrawTabbedText(title_font, title); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawGalaxy() -{ - title = ContentBundle::GetInstance()->GetText("MapView.title.Galaxy"); - DrawGrid(); - - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cx>cy) ? cx : cy; - r = 10; // * zoom; - - Galaxy* g = Galaxy::GetInstance(); - if (g) - r = g->Radius(); // * zoom; - - double scale = c/r; - double ox = 0; - double oy = 0; - - // compute offset: - ListIter iter = system_list; - while (++iter) { - StarSystem* s = iter.value(); - - if (system == s) { - if (fabs(s->Location().x) > 10 || fabs(s->Location().y) > 10) { - int sx = (int) s->Location().x; - int sy = (int) s->Location().y; - - sx -= sx % 10; - sy -= sy % 10; - - ox = sx * -scale; - oy = sy * -scale; - } - } - } - - // draw the list of systems, and their connections: - iter.reset(); - while (++iter) { - StarSystem* s = iter.value(); - - int sx = (int) (cx + ox + s->Location().x * scale); - int sy = (int) (cy + oy + s->Location().y * scale); - - if (sx < 4 || sx > rect.w-4 || sy < 4 || sy > rect.h-4) - continue; - - window->DrawEllipse(sx-7, sy-7, sx+7, sy+7, Ship::IFFColor(s->Affiliation())); - - if (s == system) { - window->DrawLine(0, sy, rect.w, sy, Color::Gray, Video::BLEND_ADDITIVE); - window->DrawLine(sx, 0, sx, rect.h, Color::Gray, Video::BLEND_ADDITIVE); - } - - ListIter iter2 = system_list; - while (++iter2) { - StarSystem* s2 = iter2.value(); - - if (s != s2 && s->HasLinkTo(s2)) { - int ax = sx; - int ay = sy; - - int bx = (int) (cx + ox + s2->Location().x * scale); - int by = (int) (cy + oy + s2->Location().y * scale); - - if (ax == bx) { - if (ay < by) { - ay += 8; by -= 8; - } - else { - ay -= 8; by += 8; - } - } - - else if (ay == by) { - if (ax < bx) { - ax += 8; bx -= 8; - } - else { - ax -= 8; bx += 8; - } - } - - else { - Point d = Point(bx, by, 0) - Point(ax, ay, 0); - d.Normalize(); - - ax += (int) (8 * d.x); - ay += (int) (8 * d.y); - - bx -= (int) (8 * d.x); - by -= (int) (8 * d.y); - } - - window->DrawLine(ax, ay, bx, by, Color(120,120,120), Video::BLEND_ADDITIVE); - } - } - } - - // finally draw all the stars in the galaxy: - if (g) { - ListIter iter = g->Stars(); - while (++iter) { - Star* s = iter.value(); - - int sx = (int) (cx + ox + s->Location().x * scale); - int sy = (int) (cy + oy + s->Location().y * scale); - int sr = s->GetSize(); - - if (sx < 4 || sx > rect.w-4 || sy < 4 || sy > rect.h-4) - continue; - - window->FillEllipse(sx-sr, sy-sr, sx+sr, sy+sr, s->GetColor()); - - if (!strncmp(s->Name(), "GSC", 3)) - font->SetColor(Color(100,100,100)); - else - font->SetColor(Color::White); - - Rect name_rect(sx-60, sy+8, 120, 20); - active_window->SetFont(font); - active_window->DrawText(s->Name(), 0, name_rect, DT_SINGLELINE | DT_CENTER); - } - } - - font->SetColor(Color::White); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawSystem() -{ - Text caption = ContentBundle::GetInstance()->GetText("MapView.title.Starsystem"); - caption += " "; - caption += system->Name(); - - if (current_ship) { - caption += "\n"; - caption += ContentBundle::GetInstance()->GetText("MapView.title.Ship"); - caption += " "; - caption += current_ship->Name(); - } - else if (current_elem) { - caption += "\n"; - caption += ContentBundle::GetInstance()->GetText("MapView.title.Ship"); - caption += " "; - caption += current_elem->Name(); - } - - title = caption; - - ListIter star = system->Bodies(); - while (++star) { - int p_orb = 1; - - ListIter planet = star->Satellites(); - while (++planet) { - DrawOrbital(*planet, p_orb++); - - int m_orb = 1; - - ListIter moon = planet->Satellites(); - while (++moon) { - DrawOrbital(*moon, m_orb++); - - ListIter region = moon->Regions(); - while (++region) { - DrawOrbital(*region, 1); - } - } - - ListIter region = planet->Regions(); - while (++region) { - DrawOrbital(*region, 1); - } - } - - ListIter region = star->Regions(); - while (++region) { - DrawOrbital(*region, 1); - } - - DrawOrbital(*star, 0); - } - - char r_txt[32]; - FormatNumber(r_txt, system->Radius() * zoom); - char resolution[64]; - sprintf_s(resolution, "%s: %s", ContentBundle::GetInstance()->GetText("MapView.info.Resolution").data(), r_txt); - - active_window->SetFont(font); - Rect text_rect(4, 4, rect.w - 8, 24); - active_window->DrawText(resolution, -1, text_rect, DT_SINGLELINE|DT_RIGHT); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawRegion() -{ - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - - Text caption = ContentBundle::GetInstance()->GetText("MapView.title.Sector"); - caption += " "; - caption += rgn->Name(); - - if (current_ship) { - caption += "\n"; - caption += ContentBundle::GetInstance()->GetText("MapView.title.Ship"); - caption += " "; - caption += current_ship->Name(); - } - else if (current_elem) { - caption += "\n"; - caption += ContentBundle::GetInstance()->GetText("MapView.title.Ship"); - caption += " "; - caption += current_elem->Name(); - } - - title = caption; - - double cx = rect.w/2; - double cy = rect.h/2; - - int size = (int) rgn->Radius(); - int step = (int) rgn->GridSpace(); - - c = (cxRadius() * zoom; - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - int left = (int) (-size * scale + ox + cx); - int right = (int) ( size * scale + ox + cx); - int top = (int) (-size * scale + oy + cy); - int bottom = (int) ( size * scale + oy + cy); - - Color major(48,48,48); - Color minor(24,24,24); - - int x,y; - int tick = 0; - - for (x = 0; x <= size; x += step) { - int lx = (int) (x * scale + ox + cx); - if (!tick) - window->DrawLine(lx, top, lx, bottom, major, Video::BLEND_ADDITIVE); - else - window->DrawLine(lx, top, lx, bottom, minor, Video::BLEND_ADDITIVE); - - lx = (int) (-x * scale + ox + cx); - if (!tick) - window->DrawLine(lx, top, lx, bottom, major, Video::BLEND_ADDITIVE); - else - window->DrawLine(lx, top, lx, bottom, minor, Video::BLEND_ADDITIVE); - - if (++tick > 3) tick = 0; - } - - tick = 0; - - for (y = 0; y <= size; y += step) { - int ly = (int) (y * scale + oy + cy); - if (!tick) - window->DrawLine(left, ly, right, ly, major, Video::BLEND_ADDITIVE); - else - window->DrawLine(left, ly, right, ly, minor, Video::BLEND_ADDITIVE); - - ly = (int) (-y * scale + oy + cy); - if (!tick) - window->DrawLine(left, ly, right, ly, major, Video::BLEND_ADDITIVE); - else - window->DrawLine(left, ly, right, ly, minor, Video::BLEND_ADDITIVE); - - if (++tick > 3) tick = 0; - } - - int rep = 3; - if (r > 70e3) rep = 2; - if (r > 250e3) rep = 1; - - if (campaign && rgn) { - // draw the combatants in this region: - ListIter iter = campaign->GetCombatants(); - while (++iter) { - Combatant* combatant = iter.value(); - DrawCombatGroup(combatant->GetForce(), rep); - } - } - - else if (mission && rgn) { - // draw the elements in this region: - ListIter elem = mission->GetElements(); - while (++elem) - if (!elem->IsSquadron()) - DrawElem(*elem, (elem.value() == current_elem), rep); - } - - else if (ship) { - // draw the ships in this region: - Sim* sim = Sim::GetSim(); - SimRegion* simrgn = 0; - - if (sim && rgn) - simrgn = sim->FindRegion(rgn->Name()); - - // this algorithm uses the allied track list for the region, - // even if this ship is in a different region. a previous - // version used the ship's own contact list, which only shows - // ships in the player's region. this way is less "realistic" - // but more fun for managing large battles. - - if (simrgn) { - ListIter c = simrgn->TrackList(ship->GetIFF()); - while (++c) { - Contact* contact = c.value(); - Ship* s = contact->GetShip(); - - if (s && (s->Class() & ship_filter) && !IsClutter(*s) && s != ship) - DrawShip(*s, (s == current_ship), rep); - } - - ListIter s_iter = simrgn->Ships(); - while (++s_iter) { - Ship* s = s_iter.value(); - - if (s && (s->IsStatic()) && !IsClutter(*s) && - (s->GetIFF() == ship->GetIFF() || s->GetIFF() == 0)) - DrawShip(*s, (s == current_ship), rep); - } - - // draw nav routes for allied ships not in the region: - ListIter r_iter = sim->GetRegions(); - while (++r_iter) { - SimRegion* r = r_iter.value(); - - if (r != simrgn) { - ListIter s_iter = r->Ships(); - while (++s_iter) { - Ship* s = s_iter.value(); - - if (s && !s->IsStatic() && !IsClutter(*s) && - (s->GetIFF() == ship->GetIFF() || s->GetIFF() == 0)) { - DrawNavRoute(simrgn->GetOrbitalRegion(), - s->GetFlightPlan(), - s->MarkerColor(), - s, 0); - } - } - } - } - } - - // draw our own ship: - DrawShip(*ship, (ship == current_ship), rep); - } - - char r_txt[32]; - FormatNumber(r_txt, r*2); - char resolution[64]; - sprintf_s(resolution, "%s: %s", ContentBundle::GetInstance()->GetText("MapView.info.Resolution").data(), r_txt); - - active_window->SetFont(font); - Rect text_rect(4, 4, rect.w - 8, 24); - active_window->DrawText(resolution, -1, text_rect, DT_SINGLELINE|DT_RIGHT); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawGrid() -{ - int grid_step = rect.w/8; - int cx = rect.w/2; - int cy = rect.h/2; - - Color c(32,32,32); - - window->DrawLine(0, cy, rect.w, cy, c, Video::BLEND_ADDITIVE); - window->DrawLine(cx, 0, cx, rect.h, c, Video::BLEND_ADDITIVE); - - for (int i = 1; i < 4; i++) { - window->DrawLine(0, cy + (i*grid_step), rect.w, cy + (i*grid_step), c, Video::BLEND_ADDITIVE); - window->DrawLine(0, cy - (i*grid_step), rect.w, cy - (i*grid_step), c, Video::BLEND_ADDITIVE); - window->DrawLine(cx + (i*grid_step), 0, cx + (i*grid_step), rect.h, c, Video::BLEND_ADDITIVE); - window->DrawLine(cx - (i*grid_step), 0, cx - (i*grid_step), rect.h, c, Video::BLEND_ADDITIVE); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawOrbital(Orbital& body, int index) -{ - int type = body.Type(); - - if (type == Orbital::NOTHING) - return; - - int x1, y1, x2, y2; - Rect label_rect; - int label_w = 64; - int label_h = 18; - - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cxRadius() * zoom; - - if ((r > 300e9) && (type > Orbital::PLANET)) - return; - - double xscale = cx / r; - double yscale = cy / r * 0.75; - - double ox = offset_x * xscale; - double oy = offset_y * yscale; - - double bo_x = body.Orbit() * xscale; - double bo_y = body.Orbit() * yscale; - double br = body.Radius() * yscale; - double bx = body.Location().x * xscale; - double by = body.Location().y * yscale; - - double px = 0; - double py = 0; - - if (body.Primary()) { - double min_pr = GetMinRadius(body.Primary()->Type()); - - if (index) { - if (min_pr < 4) - min_pr = 4; - - min_pr *= (index+1); - } - - double min_x = min_pr * xscale / yscale; - double min_y = min_pr; - - if (bo_x < min_x) - bo_x = min_x; - - if (bo_y < min_y) - bo_y = min_y; - - px = body.Primary()->Location().x * xscale; - py = body.Primary()->Location().y * yscale; - } - - if (type == Orbital::TERRAIN) - bo_x = bo_y; - - int ipx = (int) (cx + px + ox); - int ipy = (int) (cy + py + oy); - int ibo_x = (int) bo_x; - int ibo_y = (int) bo_y; - - x1 = ipx - ibo_x; - y1 = ipy - ibo_y; - x2 = ipx + ibo_x; - y2 = ipy + ibo_y; - - if (type != Orbital::TERRAIN) { - double a = x2-x1; - double b = rect.w*32; - - if (a < b) - window->DrawEllipse(x1, y1, x2, y2, Color(64,64,64), Video::BLEND_ADDITIVE); - } - - // show body's location on possibly magnified orbit - bx = px + bo_x * cos(body.Phase()); - by = py + bo_y * sin(body.Phase()); - - double min_br = GetMinRadius(type); - if (br < min_br) br = min_br; - - Color color; - - switch (type) { - case Orbital::STAR: color = Color(248, 248, 128); break; - case Orbital::PLANET: color = Color( 64, 64, 192); break; - case Orbital::MOON: color = Color( 32, 192, 96); break; - case Orbital::REGION: color = Color(255, 255, 255); break; - case Orbital::TERRAIN: color = Color( 16, 128, 48); break; - } - - int icx = (int) (cx + bx + ox); - int icy = (int) (cy + by + oy); - int ibr = (int) br; - - x1 = icx - ibr; - y1 = icy - ibr; - x2 = icx + ibr; - y2 = icy + ibr; - - if (type < Orbital::REGION) { - if (body.GetMapIcon().Width() > 64) { - Bitmap* map_icon = (Bitmap*) &body.GetMapIcon(); - - if (type == Orbital::STAR) - window->DrawBitmap(x1,y1,x2,y2, map_icon, Video::BLEND_ADDITIVE); - else - window->DrawBitmap(x1,y1,x2,y2, map_icon, Video::BLEND_ALPHA); - } - else { - window->FillEllipse(x1, y1, x2, y2, color); - } - } - else { - window->DrawRect(x1, y1, x2, y2, color); - - if (campaign) { - ListIter iter = campaign->GetCombatants(); - while (++iter) { - Combatant* combatant = iter.value(); - - if (ibr >= 4 || combatant->GetIFF() == 1) - DrawCombatantSystem(combatant, &body, icx, icy, ibr); - } - } - } - - if (type == Orbital::STAR || bo_y > label_h) { - label_rect.x = x1 - label_w + (int) br; - label_rect.y = y1 - label_h; - label_rect.w = label_w * 2; - label_rect.h = label_h; - - active_window->SetFont(font); - active_window->DrawText(body.Name(), -1, label_rect, DT_SINGLELINE|DT_CENTER); - } -} - -// +--------------------------------------------------------------------+ - -double -MapView::GetMinRadius(int type) -{ - switch (type) { - case Orbital::STAR: return 8; - case Orbital::PLANET: return 4; - case Orbital::MOON: return 2; - case Orbital::REGION: return 2; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -static void -ColorizeBitmap(Bitmap& img, Color color) -{ - int w = img.Width(); - int h = img.Height(); - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - Color c = img.GetColor(x, y); - - if (c != Color::Black && c != Color::White) { - img.SetColor(x,y,color.ShadeColor(c.Blue()/2)); - } - } - } - - img.AutoMask(); -} - -static POINT shipshape1[] = { {6,0}, {-6,4}, {-6,-4} }; -static POINT shipshape2[] = { {8,0}, { 4,4}, {-8,4}, {-8,-4}, {4,-4} }; -static POINT shipshape3[] = { {8,8}, {-8,8}, {-8,-8}, {8,-8} }; - -void -MapView::DrawShip(Ship& s, bool current, int rep) -{ - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - if (!rgn) return; - - int x1, y1, x2, y2; - POINT shiploc; - Point sloc = s.Location().OtherHand(); - - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cxRadius() * zoom; - - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - double rlx = 0; - double rly = 0; - - int sprite_width = 10; - - window->SetFont(font); - - // draw ship icon: - if (rep && view_mode == VIEW_REGION && rgn == s.GetRegion()->GetOrbitalRegion()) { - double sx = (sloc.x + rlx) * scale; - double sy = (sloc.y + rly) * scale; - - shiploc.x = (int) (cx + sx + ox); - shiploc.y = (int) (cy + sy + oy); - - bool ship_visible = shiploc.x >= 0 && shiploc.x < rect.w && - shiploc.y >= 0 && shiploc.y < rect.h; - - if (ship_visible) { - if (rep < 3) { - window->FillRect(shiploc.x-2, shiploc.y-2, shiploc.x+2, shiploc.y+2, s.MarkerColor()); - sprite_width = 2; - - if (&s == ship || !IsCrowded(s)) - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, s.Name()); - } - else { - Point heading = s.Heading().OtherHand(); - heading.z = 0; - heading.Normalize(); - - double theta = 0; - - if (heading.y > 0) - theta = acos(heading.x); - else - theta = -acos(heading.x); - - const double THETA_SLICE = 4 / PI; - const double THETA_OFFSET = PI + THETA_SLICE/2; - - int sprite_index = (int) ((theta + THETA_OFFSET) * THETA_SLICE); - int nsprites = s.Design()->map_sprites.size(); - - if (nsprites) { - if (sprite_index < 0 || sprite_index >= nsprites) - sprite_index = sprite_index % nsprites; - - Bitmap* map_sprite = s.Design()->map_sprites[sprite_index]; - - Bitmap bmp; - bmp.CopyBitmap(*map_sprite); - ColorizeBitmap(bmp, s.MarkerColor()); - sprite_width = bmp.Width()/2; - int h = bmp.Height()/2; - - window->DrawBitmap(shiploc.x-sprite_width, - shiploc.y-h, - shiploc.x+sprite_width, - shiploc.y+h, - &bmp, - Video::BLEND_ALPHA); - } - - else { - theta -= PI/2; - - if (s.IsStatic()) { - window->FillRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, s.MarkerColor()); - window->DrawRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, Color::White); - } - else if (s.IsStarship()) { - window->FillRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, s.MarkerColor()); - window->DrawRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, Color::White); - } - else { - window->FillRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, s.MarkerColor()); - window->DrawRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, Color::White); - } - } - - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, s.Name()); - } - } - } - - // draw nav route: - // draw current ship marker: - if (current && Text(s.GetRegion()->Name()) == regions[current_region]->Name()) { - x1 = (int) (shiploc.x - sprite_width - 1); - x2 = (int) (shiploc.x + sprite_width + 1); - y1 = (int) (shiploc.y - sprite_width - 1); - y2 = (int) (shiploc.y + sprite_width + 1); - - window->DrawRect(x1, y1, x2, y2, Color::White); - } - - // only see routes for your own team: - if (s.GetIFF() == 0 || ship && s.GetIFF() == ship->GetIFF()) { - DrawNavRoute(rgn, s.GetFlightPlan(), s.MarkerColor(), &s, 0); - } -} - -void -MapView::DrawElem(MissionElement& s, bool current, int rep) -{ - if (!mission) return; - - bool visible = editor || - s.GetIFF() == 0 || - s.GetIFF() == mission->Team() || - s.IntelLevel() > Intel::KNOWN; - - if (!visible) return; - - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - - if (!rgn) return; - - int x1, y1, x2, y2; - POINT shiploc; - - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cxRadius() * zoom; - - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - double rlx = 0; - double rly = 0; - - int sprite_width = 10; - - window->SetFont(font); - - // draw ship icon: - if (!_stricmp(s.Region(), rgn->Name())) { - double sx = (s.Location().x + rlx) * scale; - double sy = (s.Location().y + rly) * scale; - - shiploc.x = (int) (cx + sx + ox); - shiploc.y = (int) (cy + sy + oy); - - bool ship_visible = shiploc.x >= 0 && shiploc.x < rect.w && - shiploc.y >= 0 && shiploc.y < rect.h; - - if (ship_visible) { - if (rep < 3) { - window->FillRect(shiploc.x-2, shiploc.y-2, shiploc.x+2, shiploc.y+2, s.MarkerColor()); - sprite_width = 2; - - if (!IsCrowded(s)) - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, s.Name()); - } - else { - double theta = s.Heading(); - - const double THETA_SLICE = 4 / PI; - const double THETA_OFFSET = PI / 2; - - int sprite_index = (int) ((theta + THETA_OFFSET) * THETA_SLICE); - int nsprites = 0; - - if (s.GetDesign()) - nsprites = s.GetDesign()->map_sprites.size(); - - if (nsprites > 0) { - if (sprite_index < 0 || sprite_index >= nsprites) - sprite_index = sprite_index % nsprites; - - Bitmap* map_sprite = s.GetDesign()->map_sprites[sprite_index]; - - Bitmap bmp; - bmp.CopyBitmap(*map_sprite); - ColorizeBitmap(bmp, s.MarkerColor()); - sprite_width = bmp.Width()/2; - int h = bmp.Height()/2; - - window->DrawBitmap(shiploc.x-sprite_width, - shiploc.y-h, - shiploc.x+sprite_width, - shiploc.y+h, - &bmp, - Video::BLEND_ALPHA); - } - - else { - theta -= PI/2; - - if (s.IsStatic()) { - window->FillRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, s.MarkerColor()); - window->DrawRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, Color::White); - } - else if (s.IsStarship()) { - window->FillRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, s.MarkerColor()); - window->DrawRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, Color::White); - } - else { - window->FillRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, s.MarkerColor()); - window->DrawRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, Color::White); - } - } - - char label[64]; - - if (s.Count() > 1) - sprintf_s(label, "%s x %d", (const char*) s.Name(), s.Count()); - else - strcpy_s(label, (const char*) s.Name()); - - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, label); - } - } - } - - // draw nav route: - // draw current ship marker: - if (current && s.Region() == regions[current_region]->Name()) { - x1 = (int) (shiploc.x - sprite_width - 1); - x2 = (int) (shiploc.x + sprite_width + 1); - y1 = (int) (shiploc.y - sprite_width - 1); - y2 = (int) (shiploc.y + sprite_width + 1); - - window->DrawRect(x1, y1, x2, y2, Color::White); - } - - // only see routes for your own team: - if (editor || s.GetIFF() == 0 || mission && s.GetIFF() == mission->Team()) { - DrawNavRoute(rgn, s.NavList(), s.MarkerColor(), 0, &s); - } -} - -void -MapView::DrawNavRoute(OrbitalRegion* rgn, -List& s_route, -Color s_marker, -Ship* ship, -MissionElement* elem) -{ - int x1, y1, x2, y2; - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cxRadius() * zoom; - - if (view_mode == VIEW_REGION) { - if (!rgn) return; - r = rgn->Radius() * zoom; - } - - double scale = c/r; - double ox = offset_x * scale; - double oy = offset_y * scale; - - Point old_loc; - double old_x = 0; - double old_y = 0; - bool old_in = false; - - Point first_loc; - int first_x = 0; - int first_y = 0; - bool first_in = false; - - bool draw_route = true; - bool draw_bold = false; - - if (ship && ship->GetElementIndex() > 1) - draw_route = false; - - if (ship && ship == current_ship) { - s_marker = s_marker * 1.5; - draw_bold = true; - } - - else if (elem && elem == current_elem) { - s_marker = s_marker * 1.5; - draw_bold = true; - } - - for (int i = 0; i < s_route.size(); i++) { - Instruction* navpt = s_route[i]; - - if (!_stricmp(navpt->RegionName(), rgn->Name())) { - double nav_x = navpt->Location().x * scale; - double nav_y = navpt->Location().y * scale; - - int isx = (int) (cx + nav_x + ox); - int isy = (int) (cy + nav_y + oy); - - if (old_in && draw_route) { - int iox = (int) (cx + old_x + ox); - int ioy = (int) (cy + old_y + oy); - window->DrawLine(iox, ioy, isx, isy, s_marker); - - int x1 = (iox-isx); - int y1 = (ioy-isy); - - if (draw_bold) { - if (x1 > y1) { - window->DrawLine(iox, ioy+1, isx, isy+1, s_marker); - } - else { - window->DrawLine(iox+1, ioy, isx+1, isy, s_marker); - } - } - - if ((x1*x1 + y1*y1) > 2000) { - double dist = Point(navpt->Location() - old_loc).length(); - - int imx = (int) (cx + (old_x+nav_x)/2 + ox); - int imy = (int) (cy + (old_y+nav_y)/2 + oy); - - char dist_txt[32]; - FormatNumber(dist_txt, dist); - font->SetColor(Color::Gray); - window->SetFont(font); - window->Print(imx-20, imy-6, dist_txt); - font->SetColor(Color::White); - } - } - - x1 = isx - 3; - y1 = isy - 3; - x2 = isx + 3; - y2 = isy + 3; - - Color c = Color::White; - if (navpt->Status() > Instruction::ACTIVE) { - c = Color::Gray; - } - else if (!first_in) { - first_in = true; - first_loc = navpt->Location(); - first_x = isx; - first_y = isy; - } - - if (draw_route) { - window->DrawLine(x1, y1, x2, y2, c); - window->DrawLine(x1, y2, x2, y1, c); - - if (navpt == current_navpt) - window->DrawRect(x1-2, y1-2, x2+2, y2+2, c); - - char buf[256]; - sprintf_s(buf, "%d", i+1); - window->SetFont(font); - window->Print(x2+3, y1, buf); - - if (navpt == current_navpt) { - if (navpt->TargetName() && strlen(navpt->TargetName())) { - sprintf_s(buf, "%s %s", ContentBundle::GetInstance()->GetText(Text("MapView.item.") + Instruction::ActionName(navpt->Action())).data(), navpt->TargetName()); - window->Print(x2+3, y1+10, buf); - } - else { - sprintf_s(buf, "%s", ContentBundle::GetInstance()->GetText(Text("MapView.item.") + Instruction::ActionName(navpt->Action())).data()); - window->Print(x2+3, y1+10, buf); - } - - sprintf_s(buf, "%s", ContentBundle::GetInstance()->GetText(Text("MapView.item.") + Instruction::FormationName(navpt->Formation())).data()); - window->Print(x2+3, y1+20, buf); - - sprintf_s(buf, "%d", navpt->Speed()); - window->Print(x2+3, y1+30, buf); - - if (navpt->HoldTime()) { - char hold_time[32]; - FormatTime(hold_time, navpt->HoldTime()); - - sprintf_s(buf, "%s %s", ContentBundle::GetInstance()->GetText("MapView.item.Hold").data(), hold_time); - window->Print(x2+3, y1+40, buf); - } - } - } - - old_loc = navpt->Location(); - old_x = nav_x; - old_y = nav_y; - old_in = true; - } - - else { - old_loc = navpt->Location(); - old_x = 0; - old_y = 0; - old_in = false; - } - } - - // if the ship and the first active navpoint are both in the region, - // draw a line from the ship to the first active navpoint: - - if (first_in) { - old_in = false; - - if (ship && ship->GetRegion()) { - old_in = (ship->GetRegion()->GetOrbitalRegion() == rgn); - - if (old_in) { - old_loc = ship->Location().OtherHand(); - old_x = old_loc.x * scale; - old_y = old_loc.y * scale; - } - } - - else if (elem) { - old_in = (elem->Region() == rgn->Name()) ? true : false; - - if (old_in) { - old_loc = elem->Location(); - old_x = old_loc.x * scale; - old_y = old_loc.y * scale; - } - } - - if (old_in) { - int iox = (int) (cx + old_x + ox); - int ioy = (int) (cy + old_y + oy); - window->DrawLine(iox, ioy, first_x, first_y, s_marker); - - int x1 = (iox-first_x); - int y1 = (ioy-first_y); - - if (draw_bold) { - if (x1 > y1) { - window->DrawLine(iox, ioy+1, first_x, first_y+1, s_marker); - } - else { - window->DrawLine(iox+1, ioy, first_x+1, first_y, s_marker); - } - } - - if ((x1*x1 + y1*y1) > 2000) { - double dist = Point(first_loc - old_loc).length(); - double nav_x = first_loc.x * scale; - double nav_y = first_loc.y * scale; - - int imx = (int) (cx + (old_x+nav_x)/2 + ox); - int imy = (int) (cy + (old_y+nav_y)/2 + oy); - - char dist_txt[32]; - FormatNumber(dist_txt, dist); - font->SetColor(Color::Gray); - window->SetFont(font); - window->Print(imx-20, imy-6, dist_txt); - font->SetColor(Color::White); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawCombatantSystem(Combatant* c, Orbital* rgn, int x, int y, int r) -{ - int team = c->GetIFF(); - int x1 = 0; - int x2 = 0; - int y1 = y - r; - int a = 0; - - switch (team) { - case 0: x1 = x - 64; - x2 = x + 64; - y1 = y + r + 4; - a = DT_CENTER; - break; - - case 1: x1 = x - 200; - x2 = x - r - 4; - a = DT_RIGHT; - break; - - default: x1 = x + r + 4; - x2 = x + 200; - a = DT_LEFT; - break; - } - - DrawCombatGroupSystem(c->GetForce(), rgn, x1, x2, y1, a); -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawCombatGroupSystem(CombatGroup* group, Orbital* rgn, int x1, int x2, int& y, int a) -{ - if (!group || group->IsReserve() || group->CalcValue() < 1) - return; - - char txt[80]; - - if (group->GetRegion() == rgn->Name()) { - switch (group->Type()) { - case CombatGroup::CARRIER_GROUP: - case CombatGroup::BATTLE_GROUP: - case CombatGroup::DESTROYER_SQUADRON: - { - sprintf_s(txt, "%s '%s'", group->GetShortDescription(), group->Name().data()); - active_window->SetFont(font); - Rect text_rect(x1, y, x2 - x1, 12); - active_window->DrawText(txt, 0, text_rect, a); - y += 10; - break; - } - case CombatGroup::BATTALION: - case CombatGroup::STATION: - case CombatGroup::STARBASE: - - case CombatGroup::MINEFIELD: - case CombatGroup::BATTERY: - case CombatGroup::MISSILE: - { - active_window->SetFont(font); - Rect text_rect(x1, y, x2 - x1, 12); - active_window->DrawText(group->GetShortDescription(), 0, text_rect, a); - y += 10; - break; - } - default: - break; - } - } - - ListIter iter = group->GetComponents(); - while (++iter) { - CombatGroup* g = iter.value(); - DrawCombatGroupSystem(g, rgn, x1, x2, y, a); - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::DrawCombatGroup(CombatGroup* group, int rep) -{ - // does group even exist yet? - if (!group || group->IsReserve() || group->CalcValue() < 1) - return; - - // is group a squadron? don't draw squadrons on map: - if (group->Type() >= CombatGroup::WING && group->Type() < CombatGroup::FLEET) - return; - - // has group been discovered yet? - CombatGroup* player_group = campaign->GetPlayerGroup(); - if (group->GetIFF() && player_group && player_group->GetIFF() != group->GetIFF()) - if (group->IntelLevel() <= Intel::KNOWN) - return; - - // has group been destroyed already? - if (group->CalcValue() < 1) - return; - - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - if (!rgn) return; - - POINT shiploc; - - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cxRadius() * zoom; - - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - double rlx = 0; - double rly = 0; - - int sprite_width = 10; - - if (group->GetUnits().size() > 0) { - CombatUnit* unit = 0; - - for (int i = 0; i < group->GetUnits().size(); i++) { - unit = group->GetUnits().at(i); - - if (unit->Count() - unit->DeadCount() > 0) - break; - } - - // draw unit icon: - if (unit->GetRegion() == rgn->Name() && unit->Type() > Ship::LCA && unit->Count() > 0) { - double sx = (unit->Location().x + rlx) * scale; - double sy = (unit->Location().y + rly) * scale; - - shiploc.x = (int) (cx + sx + ox); - shiploc.y = (int) (cy + sy + oy); - - bool ship_visible = shiploc.x >= 0 && shiploc.x < rect.w && - shiploc.y >= 0 && shiploc.y < rect.h; - - if (ship_visible) { - if (rep < 3) { - window->FillRect(shiploc.x-2, shiploc.y-2, shiploc.x+2, shiploc.y+2, unit->MarkerColor()); - sprite_width = 2; - - char buf[256]; - sprintf_s(buf, "%s", unit->Name().data()); - window->SetFont(font); - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, buf); - } - else { - int sprite_index = 2; - int nsprites = 0; - - if (unit->GetDesign()) - nsprites = unit->GetDesign()->map_sprites.size(); - - if (nsprites) { - if (sprite_index >= nsprites) - sprite_index = sprite_index % nsprites; - - Bitmap* map_sprite = unit->GetDesign()->map_sprites[sprite_index]; - - Bitmap bmp; - bmp.CopyBitmap(*map_sprite); - ColorizeBitmap(bmp, unit->MarkerColor()); - sprite_width = bmp.Width()/2; - int h = bmp.Height()/2; - - window->DrawBitmap(shiploc.x-sprite_width, - shiploc.y-h, - shiploc.x+sprite_width, - shiploc.y+h, - &bmp, - Video::BLEND_ALPHA); - } - - else { - if (unit->IsStatic()) { - window->FillRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, unit->MarkerColor()); - window->DrawRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, Color::White); - } - else if (unit->IsStarship()) { - window->FillRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, unit->MarkerColor()); - window->DrawRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, Color::White); - } - else { - window->FillRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, unit->MarkerColor()); - window->DrawRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, Color::White); - } - } - - char label[128]; - strcpy_s(label, unit->GetDescription()); - window->SetFont(font); - window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, label); - } - } - } - } - - // recurse - ListIter iter = group->GetComponents(); - while (++iter) { - CombatGroup* g = iter.value(); - DrawCombatGroup(g, rep); - } -} - -// +--------------------------------------------------------------------+ - -bool -MapView::IsClutter(Ship& test) -{ - // get leader: - Ship* lead = test.GetLeader(); - - if (lead == &test) // this is the leader: - return false; - - // too close? - if (lead) { - POINT testloc, leadloc; - - GetShipLoc(test, testloc); - GetShipLoc(*lead, leadloc); - - double dx = testloc.x - leadloc.x; - double dy = testloc.y - leadloc.y; - double d = dx*dx + dy*dy; - - if (d <= 64) - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -MapView::IsCrowded(Ship& test) -{ - POINT testloc, refloc; - Sim* sim = Sim::GetSim(); - Orbital* rgn = regions[current_region]; - SimRegion* simrgn = sim->FindRegion(rgn->Name()); - - if (simrgn) { - GetShipLoc(test, testloc); - - ListIter s = simrgn->Ships(); - while (++s) { - Ship* ref = s.value(); - - // too close? - if (ref && ref != &test) { - GetShipLoc(*ref, refloc); - - double dx = testloc.x - refloc.x; - double dy = testloc.y - refloc.y; - double d = dx*dx + dy*dy; - - if (d <= 64) - return true; - } - } - } - - return false; -} - -void -MapView::GetShipLoc(Ship& s, POINT& shiploc) -{ - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cxRadius() * zoom; - - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - - if (view_mode == VIEW_REGION) { - if (!rgn) return; - r = rgn->Radius() * zoom; - } - - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - double rlx = 0; - double rly = 0; - - if (view_mode == VIEW_SYSTEM) { - rgn = system->ActiveRegion(); - - if (rgn) { - rlx = rgn->Location().x; - rly = rgn->Location().y; - } - } - - if (view_mode == VIEW_SYSTEM || - (view_mode == VIEW_REGION && rgn == s.GetRegion()->GetOrbitalRegion())) { - double sx = (s.Location().x + rlx) * scale; - double sy = (s.Location().y + rly) * scale; - - shiploc.x = (int) (cx + sx + ox); - shiploc.y = (int) (cy + sy + oy); - } - else { - shiploc.x = -1; - shiploc.y = -1; - } -} - -// +--------------------------------------------------------------------+ - -bool -MapView::IsCrowded(MissionElement& test) -{ - POINT testloc, refloc; - Sim* sim = Sim::GetSim(); - Orbital* rgn = regions[current_region]; - - if (mission) { - GetElemLoc(test, testloc); - - ListIter s = mission->GetElements(); - while (++s) { - MissionElement* ref = s.value(); - - if (ref && ref != &test && !_stricmp(ref->Region(), rgn->Name())) { - GetElemLoc(*ref, refloc); - - double dx = testloc.x - refloc.x; - double dy = testloc.y - refloc.y; - double d = dx*dx + dy*dy; - - if (d <= 64) - return true; - } - } - } - - return false; -} - -void -MapView::GetElemLoc(MissionElement& s, POINT& shiploc) -{ - double cx = rect.w/2; - double cy = rect.h/2; - - c = (cxRadius() * zoom; - - OrbitalRegion* rgn = (OrbitalRegion*) regions[current_region]; - - if (view_mode == VIEW_REGION) { - if (!rgn) return; - r = rgn->Radius() * zoom; - } - - double scale = c/r; - - double ox = offset_x * scale; - double oy = offset_y * scale; - - double rlx = 0; - double rly = 0; - - if (view_mode == VIEW_SYSTEM) { - rgn = system->ActiveRegion(); - - if (rgn) { - rlx = rgn->Location().x; - rly = rgn->Location().y; - } - } - - if (view_mode == VIEW_SYSTEM || - (view_mode == VIEW_REGION && !_stricmp(s.Region(), rgn->Name()))) { - double sx = (s.Location().x + rlx) * scale; - double sy = (s.Location().y + rly) * scale; - - shiploc.x = (int) (cx + sx + ox); - shiploc.y = (int) (cy + sy + oy); - } - else { - shiploc.x = -1; - shiploc.y = -1; - } -} - -// +--------------------------------------------------------------------+ - -OrbitalRegion* -MapView::GetRegion() const -{ - OrbitalRegion* result = 0; - - if (current_region < regions.size()) - result = (OrbitalRegion*) regions[current_region]; - - return result; -} - -// +--------------------------------------------------------------------+ - -void -MapView::ZoomIn() -{ - zoom *= 0.9; - - if (view_mode == VIEW_SYSTEM) { - if (system && zoom * system->Radius() < 2e6) { - zoom = 2e6 / system->Radius(); - } - } - else if (view_mode == VIEW_REGION) { - OrbitalRegion* rgn = GetRegion(); - if (rgn && zoom * rgn->Radius() < 1e3) { - zoom = 1e3 / rgn->Radius(); - } - } -} - -void -MapView::ZoomOut() -{ - zoom *= 1.1; - - if (view_mode == VIEW_SYSTEM) { - if (system && zoom * system->Radius() > 500e9) { - zoom = 500e9 / system->Radius(); - } - } - else if (view_mode == VIEW_REGION) { - OrbitalRegion* rgn = GetRegion(); - if (rgn && zoom * rgn->Radius() > 1e6) { - zoom = 1e6 / rgn->Radius(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -MapView::OnShow() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - dispatch->Register(this); -} - -void -MapView::OnHide() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - dispatch->Unregister(this); - - if (captured) { - ReleaseCapture(); - captured = false; - Mouse::Show(true); - } - - dragging = false; -} - -// +--------------------------------------------------------------------+ - -bool -MapView::IsEnabled() const -{ - if (active_window) - return active_window->IsEnabled(); - - return false; -} - -bool -MapView::IsVisible() const -{ - if (active_window) - return active_window->IsVisible(); - - return false; -} - -bool -MapView::IsFormActive() const -{ - if (active_window) - return active_window->IsFormActive(); - - return false; -} - -Rect -MapView::TargetRect() const -{ - if (active_window) - return active_window->TargetRect(); - - return Rect(); -} - -// +--------------------------------------------------------------------+ - -int -MapView::OnMouseMove(int x, int y) -{ - if (captured) { - EventTarget* test = 0; - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch) - test = dispatch->GetCapture(); - - if (test != this) { - captured = false; - Mouse::Show(true); - } - - else { - if (dragging) { - int delta_x = x - mouse_x; - int delta_y = y - mouse_y; - - offset_x += delta_x * r / c; - offset_y += delta_y * r / c; - - Mouse::SetCursorPos(mouse_x, mouse_y); - } - - else if (view_mode == VIEW_REGION) { - double scale = r/c; - click_x = (x - rect.x - rect.w/2) * scale - offset_x; - click_y = (y - rect.y - rect.h/2) * scale - offset_y; - - if ((adding_navpt || moving_navpt) && current_navpt) { - Point loc = current_navpt->Location(); - loc.x = click_x; - loc.y = click_y; - current_navpt->SetLocation(loc); - current_navpt->SetStatus(current_status); - } - - else if (editor && moving_elem && current_elem) { - Point loc = current_elem->Location(); - loc.x = click_x; - loc.y = click_y; - current_elem->SetLocation(loc); - } - } - } - } - - return active_window->OnMouseMove(x,y); -} - -// +--------------------------------------------------------------------+ - -int -MapView::OnRButtonDown(int x, int y) -{ - if (!captured) - captured = SetCapture(); - - if (captured) { - dragging = true; - mouse_x = x; - mouse_y = y; - Mouse::Show(false); - } - - return active_window->OnRButtonDown(x, y); -} - -// +--------------------------------------------------------------------+ - -int -MapView::OnRButtonUp(int x, int y) -{ - if (captured) { - ReleaseCapture(); - captured = false; - Mouse::Show(true); - } - - dragging = false; - - return active_window->OnRButtonUp(x, y); -} - -// +--------------------------------------------------------------------+ - -int MapView::OnClick() -{ - return active_window->OnClick(); -} - -int MapView::OnLButtonDown(int x, int y) -{ - if (menu_view && menu_view->IsShown()) { - // ignore this event... - } - else { - if (!captured) - captured = SetCapture(); - - if (view_mode == VIEW_REGION) { - double scale = r/c; - click_x = (x - rect.x - rect.w/2) * scale - offset_x; - click_y = (y - rect.y - rect.h/2) * scale - offset_y; - - if (current_navpt) { - Point nloc = current_navpt->Location(); - double dx = nloc.x - click_x; - double dy = nloc.y - click_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < 5e3) { - moving_navpt = true; - - if (ship && current_ship && ship != current_ship) { - if (ship->GetElement() && current_ship->GetElement()) { - if (!ship->GetElement()->CanCommand(current_ship->GetElement())) { - moving_navpt = false; - } - } - } - else if (current_elem && NetLobby::GetInstance()) { - moving_navpt = false; - } - } - } - - else if (editor && current_elem) { - Point nloc = current_elem->Location(); - double dx = nloc.x - click_x; - double dy = nloc.y - click_y; - double d = sqrt(dx*dx + dy*dy); - - if (d < 5e3) { - moving_elem = true; - - if (current_elem && NetLobby::GetInstance()) { - moving_elem = false; - } - } - } - } - } - - return active_window->OnLButtonDown(x,y); -} - -int MapView::OnLButtonUp(int x, int y) -{ - bool process_event = false; - - if (captured) { - process_event = true; - ReleaseCapture(); - captured = false; - Mouse::Show(true); - } - - if (process_event && !adding_navpt) { - if (!moving_navpt && !moving_elem) { - Button::PlaySound(); - } - - if (view_mode == VIEW_REGION) { - double scale = r/c; - click_x = (x - rect.x - rect.w/2) * scale - offset_x; - click_y = (y - rect.y - rect.h/2) * scale - offset_y; - - if (!scrolling) - SelectAt(x,y); - - active_window->ClientEvent(EID_MAP_CLICK, x, y); - } - - else if (!scrolling) { - SelectAt(x,y); - - active_window->ClientEvent(EID_MAP_CLICK, x, y); - } - } - - if ((adding_navpt || moving_navpt) && current_navpt) { - current_navpt->SetStatus(current_status); - - Sim* sim = Sim::GetSim(); - if (sim) { - Ship* s = current_ship; - - if (s && s->GetElement()) { - Element* elem = s->GetElement(); - int index = elem->GetNavIndex(current_navpt); - - if (index >= 0) - NetUtil::SendNavData(false, elem, index-1, current_navpt); - } - } - } - - adding_navpt = false; - moving_navpt = false; - moving_elem = false; - - return active_window->OnLButtonUp(x,y); -} - - diff --git a/Stars45/MapView.h b/Stars45/MapView.h deleted file mode 100644 index 0e8d599..0000000 --- a/Stars45/MapView.h +++ /dev/null @@ -1,222 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Star Map class -*/ - -#ifndef MapView_h -#define MapView_h - -#include "Types.h" -#include "SimObject.h" -#include "View.h" -#include "EventTarget.h" -#include "Bitmap.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class ActiveWindow; -class StarSystem; -class Orbital; -class OrbitalRegion; -class Ship; -class Instruction; -class Mission; -class MissionElement; -class Campaign; -class Combatant; -class CombatGroup; -class Menu; -class MenuItem; -class MenuView; -class Font; - -const int EID_MAP_CLICK = 1000; - -// +--------------------------------------------------------------------+ - -class MapView : public View, -public EventTarget, -public SimObserver -{ -public: - MapView(Window* win); - virtual ~MapView(); - - // Operations: - virtual void Refresh(); - virtual void OnWindowMove(); - virtual void OnShow(); - virtual void OnHide(); - - virtual void DrawTitle(); - virtual void DrawGalaxy(); - virtual void DrawSystem(); - virtual void DrawRegion(); - - virtual void DrawGrid(); - virtual void DrawOrbital(Orbital& orbital, int index); - virtual void DrawShip(Ship& ship, bool current=false, int rep=3); - virtual void DrawElem(MissionElement& elem, bool current=false, int rep=3); - virtual void DrawNavRoute(OrbitalRegion* rgn, - List& route, - Color smarker, - Ship* ship=0, - MissionElement* elem=0); - - virtual void DrawCombatantSystem(Combatant* c, Orbital* rgn, int x, int y, int r); - virtual void DrawCombatGroupSystem(CombatGroup* g, Orbital* rgn, int x1, int x2, int& y, int a); - virtual void DrawCombatGroup(CombatGroup* g, int rep=3); - - virtual int GetViewMode() const { return view_mode; } - virtual void SetViewMode(int mode); - virtual void SetSelectionMode(int mode); - virtual int GetSelectionMode() const { return seln_mode; } - virtual void SetSelection(int index); - virtual void SetSelectedShip(Ship* ship); - virtual void SetSelectedElem(MissionElement* elem); - virtual void SetRegion(OrbitalRegion* rgn); - virtual void SetRegionByName(const char* rgn_name); - virtual void SelectAt(int x, int y); - virtual Orbital* GetSelection(); - virtual Ship* GetSelectedShip(); - virtual MissionElement* GetSelectedElem(); - virtual int GetSelectionIndex(); - virtual void SetShipFilter(DWORD f) { ship_filter = f; } - - // Event Target Interface: - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnClick(); - virtual int OnRButtonDown(int x, int y); - virtual int OnRButtonUp(int x, int y); - - virtual bool IsEnabled() const; - virtual bool IsVisible() const; - virtual bool IsFormActive() const; - virtual Rect TargetRect() const; - - void ZoomIn(); - void ZoomOut(); - - void SetGalaxy(List& systems); - void SetSystem(StarSystem* s); - void SetMission(Mission* m); - void SetShip(Ship* s); - void SetCampaign(Campaign* c); - - bool IsVisible(const Point& loc); - - // accessors: - virtual void GetClickLoc(double& x, double& y) { x = click_x; y = click_y; } - List& GetGalaxy() { return system_list; } - StarSystem* GetSystem() const { return system; } - OrbitalRegion* GetRegion() const; - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const { return "MapWin"; } - - bool GetEditorMode() const { return editor; } - void SetEditorMode(bool b) { editor = b; } - -protected: - virtual void BuildMenu(); - virtual void ClearMenu(); - virtual void ProcessMenuItem(int action); - virtual bool SetCapture(); - virtual bool ReleaseCapture(); - - virtual void DrawTabbedText(Font* font, const char* text); - - bool IsClutter(Ship& s); - bool IsCrowded(Ship& s); - bool IsCrowded(MissionElement& elem); - void GetShipLoc(Ship& s, POINT& loc); - void GetElemLoc(MissionElement& s, POINT& loc); - void SelectShip(Ship* selship); - void SelectElem(MissionElement* selelem); - void SelectNavpt(Instruction* navpt); - void FindShips(bool friendly, bool station, bool starship, bool dropship, - List& result); - void SetupScroll(Orbital* s); - - double GetMinRadius(int type); - - Text title; - Rect rect; - Campaign* campaign; - Mission* mission; - List system_list; - StarSystem* system; - List stars; - List planets; - List regions; - Ship* ship; - Bitmap galaxy_image; - bool editor; - - int current_star; - int current_planet; - int current_region; - Ship* current_ship; - MissionElement* current_elem; - Instruction* current_navpt; - int current_status; - - int view_mode; - int seln_mode; - bool captured; - bool dragging; - bool adding_navpt; - bool moving_navpt; - bool moving_elem; - int scrolling; - int mouse_x; - int mouse_y; - DWORD ship_filter; - - double zoom; - double view_zoom[3]; - double offset_x; - double offset_y; - double view_offset_x[3]; - double view_offset_y[3]; - double c, r; - double scroll_x; - double scroll_y; - double click_x; - double click_y; - - Font* font; - Font* title_font; - - ActiveWindow* active_window; - Menu* active_menu; - - Menu* map_menu; - Menu* map_system_menu; - Menu* map_sector_menu; - Menu* ship_menu; - Menu* nav_menu; - Menu* action_menu; - Menu* objective_menu; - Menu* formation_menu; - Menu* speed_menu; - Menu* hold_menu; - Menu* farcast_menu; - - MenuView* menu_view; -}; - -#endif // MapView_h - diff --git a/Stars45/Menu.cpp b/Stars45/Menu.cpp deleted file mode 100644 index 35f5715..0000000 --- a/Stars45/Menu.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simple menu hierarchy class -*/ - -#include "Menu.h" - -// +--------------------------------------------------------------------+ - -void -Menu::AddItem(Text label, DWORD value, bool enabled) -{ - MenuItem* item = new MenuItem(label, value, enabled); - - if (item) { - item->menu = this; - items.append(item); - } -} - -void -Menu::AddItem(MenuItem* item) -{ - if (item->submenu) - item->submenu->SetParent(this); - item->menu = this; - items.append(item); -} - -void -Menu::AddMenu(Text label, Menu* menu, DWORD value) -{ - MenuItem* item = new MenuItem(label, value); - - if (item) { - item->menu = this; - item->submenu = menu; - menu->parent = this; - - items.append(item); - } -} - -MenuItem* -Menu::GetItem(int index) -{ - if (index >= 0 && index < items.size()) - return items[index]; - - return 0; -} - -void -Menu::SetItem(int index, MenuItem* item) -{ - if (item && index >= 0 && index < items.size()) - items[index] = item; -} - -int -Menu::NumItems() const -{ - return items.size(); -} - -void -Menu::ClearItems() -{ - items.destroy(); -} - - -// +--------------------------------------------------------------------+ - -MenuItem::MenuItem(Text label, DWORD value, bool e) -: text(label), data(value), enabled(e), submenu(0), selected(0) -{ } - -MenuItem::~MenuItem() -{ } - -// +--------------------------------------------------------------------+ - -Menu* -MenuHistory::GetCurrent() -{ - int n = history.size(); - - if (n) - return history[n-1]; - - return 0; -} - -Menu* -MenuHistory::GetLevel(int n) -{ - if (n >= 0 && n < history.size()) - return history[n]; - - return 0; -} - -Menu* -MenuHistory::Find(const char* title) -{ - for (int i = 0; i < history.size(); i++) - if (history[i]->GetTitle() == title) - return history[i]; - - return 0; -} - -void -MenuHistory::Pop() -{ - int n = history.size(); - - if (n) - history.removeIndex(n-1); -} - -void -MenuHistory::Push(Menu* menu) -{ - history.append(menu); -} - -void -MenuHistory::Clear() -{ - history.clear(); -} diff --git a/Stars45/Menu.h b/Stars45/Menu.h deleted file mode 100644 index b74099f..0000000 --- a/Stars45/Menu.h +++ /dev/null @@ -1,123 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simple menu hierarchy class -*/ - -#ifndef Menu_h -#define Menu_h - -#include "Types.h" -#include "List.h" -#include "Text.h" - -// +-------------------------------------------------------------------+ - -class Menu; -class MenuItem; -class MenuHistory; - -// +-------------------------------------------------------------------+ - -class Menu -{ -public: - static const char* TYPENAME() { return "Menu"; } - - Menu() { } - Menu(Text t) : title(t) { } - virtual ~Menu() { items.destroy(); } - - virtual Text GetTitle() const { return title; } - virtual void SetTitle(Text t) { title = t; } - virtual Menu* GetParent() const { return parent; } - virtual void SetParent(Menu* p) { parent = p; } - - virtual void AddItem(Text label, DWORD value=0, bool enabled=true); - virtual void AddItem(MenuItem* item); - virtual void AddMenu(Text label, Menu* menu, DWORD value=0); - virtual MenuItem* GetItem(int index); - virtual void SetItem(int index, MenuItem* item); - virtual int NumItems() const; - virtual void ClearItems(); - - ListIter GetItems() { return items; } - -protected: - Text title; - List items; - Menu* parent; - - friend class MenuItem; -}; - -// +-------------------------------------------------------------------+ - -class MenuItem -{ -public: - static const char* TYPENAME() { return "MenuItem"; } - - MenuItem(Text label, DWORD value=0, bool enabled=true); - virtual ~MenuItem(); - - virtual Text GetText() const { return text; } - virtual void SetText(Text t) { text = t; } - - virtual DWORD GetData() const { return data; } - virtual void SetData(DWORD d) { data = d; } - - virtual int GetEnabled() const { return enabled; } - virtual void SetEnabled(int e) { enabled = e; } - - virtual int GetSelected() const { return selected; } - virtual void SetSelected(int s) { selected = s; } - - virtual Menu* GetMenu() const { return menu; } - virtual void SetMenu(Menu* m) { menu = m; } - - virtual Menu* GetSubmenu() const { return submenu; } - virtual void SetSubmenu(Menu* s) { submenu = s; } - -protected: - Text text; - DWORD data; - int enabled; - int selected; - - Menu* menu; - Menu* submenu; - - friend class Menu; -}; - -// +-------------------------------------------------------------------+ - -class MenuHistory -{ -public: - static const char* TYPENAME() { return "MenuHistory"; } - - MenuHistory() { } - virtual ~MenuHistory() { history.clear(); } - - virtual Menu* GetCurrent(); - virtual Menu* GetLevel(int n); - virtual Menu* Find(const char* title); - virtual void Pop(); - virtual void Push(Menu* menu); - virtual void Clear(); - -private: - List history; -}; - -#endif // Menu_h - diff --git a/Stars45/MenuDlg.cpp b/Stars45/MenuDlg.cpp deleted file mode 100644 index 36dce15..0000000 --- a/Stars45/MenuDlg.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "MenuDlg.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "Campaign.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "VersionInfo.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(MenuDlg, OnStart); -DEF_MAP_CLIENT(MenuDlg, OnCampaign); -DEF_MAP_CLIENT(MenuDlg, OnMission); -DEF_MAP_CLIENT(MenuDlg, OnPlayer); -DEF_MAP_CLIENT(MenuDlg, OnMultiplayer); -DEF_MAP_CLIENT(MenuDlg, OnMod); -DEF_MAP_CLIENT(MenuDlg, OnTacReference); -DEF_MAP_CLIENT(MenuDlg, OnVideo); -DEF_MAP_CLIENT(MenuDlg, OnOptions); -DEF_MAP_CLIENT(MenuDlg, OnControls); -DEF_MAP_CLIENT(MenuDlg, OnQuit); -DEF_MAP_CLIENT(MenuDlg, OnButtonEnter); -DEF_MAP_CLIENT(MenuDlg, OnButtonExit); - -// +--------------------------------------------------------------------+ - -MenuDlg::MenuDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), -manager(mgr), btn_start(0), -btn_campaign(0), btn_mission(0), btn_player(0), btn_multi(0), -btn_mod(0), btn_tac(0), -btn_options(0), btn_controls(0), btn_quit(0), -version(0), description(0), stars(0), campaign(0) -{ - stars = Starshatter::GetInstance(); - campaign = Campaign::GetCampaign(); - - Init(def); -} - -MenuDlg::~MenuDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MenuDlg::RegisterControls() -{ - if (btn_start) - return; - - btn_start = (Button*) FindControl(120); - btn_campaign = (Button*) FindControl(101); - btn_mission = (Button*) FindControl(102); - btn_player = (Button*) FindControl(103); - btn_multi = (Button*) FindControl(104); - btn_video = (Button*) FindControl(111); - btn_options = (Button*) FindControl(112); - btn_controls = (Button*) FindControl(113); - btn_quit = (Button*) FindControl(114); - btn_mod = (Button*) FindControl(115); - btn_tac = (Button*) FindControl(116); - - if (btn_start) { - REGISTER_CLIENT(EID_CLICK, btn_start, MenuDlg, OnStart); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_start, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_start, MenuDlg, OnButtonExit); - } - - if (btn_campaign) { - REGISTER_CLIENT(EID_CLICK, btn_campaign, MenuDlg, OnCampaign); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_campaign, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_campaign, MenuDlg, OnButtonExit); - } - - if (btn_mission) { - REGISTER_CLIENT(EID_CLICK, btn_mission, MenuDlg, OnMission); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_mission, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_mission, MenuDlg, OnButtonExit); - } - - if (btn_player) { - REGISTER_CLIENT(EID_CLICK, btn_player, MenuDlg, OnPlayer); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_player, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_player, MenuDlg, OnButtonExit); - } - - if (btn_multi) { - REGISTER_CLIENT(EID_CLICK, btn_multi, MenuDlg, OnMultiplayer); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_multi, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_multi, MenuDlg, OnButtonExit); - } - - if (btn_video) { - REGISTER_CLIENT(EID_CLICK, btn_video, MenuDlg, OnVideo); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_video, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_video, MenuDlg, OnButtonExit); - } - - if (btn_options) { - REGISTER_CLIENT(EID_CLICK, btn_options, MenuDlg, OnOptions); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_options, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_options, MenuDlg, OnButtonExit); - } - - if (btn_controls) { - REGISTER_CLIENT(EID_CLICK, btn_controls, MenuDlg, OnControls); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_controls, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_controls, MenuDlg, OnButtonExit); - } - - if (btn_mod) { - REGISTER_CLIENT(EID_CLICK, btn_mod, MenuDlg, OnMod); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_mod, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_mod, MenuDlg, OnButtonExit); - } - - if (btn_tac) { - REGISTER_CLIENT(EID_CLICK, btn_tac, MenuDlg, OnTacReference); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_tac, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_tac, MenuDlg, OnButtonExit); - } - - if (btn_quit) { - REGISTER_CLIENT(EID_CLICK, btn_quit, MenuDlg, OnQuit); - REGISTER_CLIENT(EID_MOUSE_ENTER, btn_quit, MenuDlg, OnButtonEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, btn_quit, MenuDlg, OnButtonExit); - } - - version = FindControl(100); - - if (version) { - version->SetText(versionInfo); - } - - description = FindControl(202); -} - -// +--------------------------------------------------------------------+ - -void -MenuDlg::Show() -{ - FormWindow::Show(); - - if (btn_multi && Starshatter::UseFileSystem()) - btn_multi->SetEnabled(false); -} - -void -MenuDlg::ExecFrame() -{ -} - -// +--------------------------------------------------------------------+ - -void -MenuDlg::OnStart(AWEvent* event) -{ - if (description) description->SetText(""); - stars->StartOrResumeGame(); -} - -void -MenuDlg::OnCampaign(AWEvent* event) -{ - if (description) description->SetText(""); - manager->ShowCmpSelectDlg(); -} - -void -MenuDlg::OnMission(AWEvent* event) -{ - if (description) description->SetText(""); - manager->ShowMsnSelectDlg(); -} - -void -MenuDlg::OnPlayer(AWEvent* event) -{ - if (description) description->SetText(""); - manager->ShowPlayerDlg(); -} - -void -MenuDlg::OnMultiplayer(AWEvent* event) -{ - if (description) description->SetText(""); - manager->ShowNetClientDlg(); -} - -void -MenuDlg::OnVideo(AWEvent* event) -{ - if (description) description->SetText(""); - manager->ShowVidDlg(); -} - -void -MenuDlg::OnOptions(AWEvent* event) -{ - if (description) description->SetText(""); - manager->ShowOptDlg(); -} - -void -MenuDlg::OnControls(AWEvent* event) -{ - if (description) description->SetText(""); - manager->ShowCtlDlg(); -} - -void -MenuDlg::OnMod(AWEvent* event) -{ - if (description) description->SetText(""); - manager->ShowModDlg(); -} - -void -MenuDlg::OnTacReference(AWEvent* event) -{ - if (description) description->SetText(""); - stars->OpenTacticalReference(); -} - -void -MenuDlg::OnQuit(AWEvent* event) -{ - if (description) description->SetText(""); - manager->ShowExitDlg(); -} - -// +--------------------------------------------------------------------+ - -void -MenuDlg::OnButtonEnter(AWEvent* event) -{ - ActiveWindow* src = event->window; - - if (src && description) - description->SetText(src->GetAltText()); -} - -void -MenuDlg::OnButtonExit(AWEvent* event) -{ - if (description) - description->SetText(""); -} diff --git a/Stars45/MenuDlg.h b/Stars45/MenuDlg.h deleted file mode 100644 index f380acc..0000000 --- a/Stars45/MenuDlg.h +++ /dev/null @@ -1,85 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef MenuDlg_h -#define MenuDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class Campaign; -class Starshatter; - -// +--------------------------------------------------------------------+ - -class MenuDlg : public FormWindow -{ -public: - MenuDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~MenuDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnStart(AWEvent* event); - virtual void OnCampaign(AWEvent* event); - virtual void OnMission(AWEvent* event); - virtual void OnPlayer(AWEvent* event); - virtual void OnMultiplayer(AWEvent* event); - virtual void OnMod(AWEvent* event); - virtual void OnTacReference(AWEvent* event); - - virtual void OnVideo(AWEvent* event); - virtual void OnOptions(AWEvent* event); - virtual void OnControls(AWEvent* event); - virtual void OnQuit(AWEvent* event); - - virtual void OnButtonEnter(AWEvent* event); - virtual void OnButtonExit(AWEvent* event); - -protected: - MenuScreen* manager; - - Button* btn_start; - Button* btn_campaign; - Button* btn_mission; - Button* btn_player; - Button* btn_multi; - Button* btn_mod; - Button* btn_tac; - - Button* btn_video; - Button* btn_options; - Button* btn_controls; - Button* btn_quit; - - ActiveWindow* version; - ActiveWindow* description; - - Starshatter* stars; - Campaign* campaign; -}; - -#endif // MenuDlg_h - diff --git a/Stars45/MenuScreen.cpp b/Stars45/MenuScreen.cpp deleted file mode 100644 index f45d2c5..0000000 --- a/Stars45/MenuScreen.cpp +++ /dev/null @@ -1,1073 +0,0 @@ -/* 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 "MenuScreen.h" - -#include "FormDef.h" -#include "MenuDlg.h" - -#include "ExitDlg.h" -#include "AudDlg.h" -#include "VidDlg.h" -#include "OptDlg.h" -#include "CtlDlg.h" -#include "JoyDlg.h" -#include "KeyDlg.h" -#include "ConfirmDlg.h" -#include "PlayerDlg.h" -#include "ModDlg.h" -#include "ModInfoDlg.h" -#include "MsnSelectDlg.h" -#include "MsnEditDlg.h" -#include "MsnElemDlg.h" -#include "MsnEventDlg.h" -#include "MsnEditNavDlg.h" -#include "FirstTimeDlg.h" -#include "AwardShowDlg.h" -#include "LoadDlg.h" -#include "TacRefDlg.h" - -#include "CmpSelectDlg.h" -#include "NetClientDlg.h" -#include "NetLobbyDlg.h" -#include "NetServerDlg.h" -#include "NetUnitDlg.h" -#include "NetAddrDlg.h" -#include "NetPassDlg.h" - -#include "Starshatter.h" -#include "Player.h" -#include "NetLobby.h" -#include "NetClientConfig.h" -#include "NetServerConfig.h" - -#include "GameWinDX9.h" -#include "Video.h" -#include "Screen.h" -#include "ActiveWindow.h" -#include "Mouse.h" -#include "Keyboard.h" -#include "FadeView.h" -#include "Color.h" -#include "Bitmap.h" -#include "Font.h" -#include "FontMgr.h" -#include "EventDispatch.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -MenuScreen::MenuScreen() -: screen(0), menudlg(0), -fadewin(0), fadeview(0), exitdlg(0), -auddlg(0), viddlg(0), optdlg(0), ctldlg(0), joydlg(0), keydlg(0), -playdlg(0), confirmdlg(0), firstdlg(0), awarddlg(0), cmpSelectDlg(0), -msnSelectDlg(0), modDlg(0), modInfoDlg(0), -msnEditDlg(0), msnElemDlg(0), msnEventDlg(0), msnEditNavDlg(0), -netClientDlg(0), netAddrDlg(0), netPassDlg(0), netLobbyDlg(0), netServerDlg(0), -netUnitDlg(0), loadDlg(0), tacRefDlg(0), current_dlg(0), isShown(false) -{ - loader = DataLoader::GetLoader(); -} - -MenuScreen::~MenuScreen() -{ - TearDown(); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::Setup(Screen* s) -{ - if (!s) - return; - - screen = s; - - Color::SetFade(0); - - // create windows - - loader->UseFileSystem(true); - - FormDef menu_def("MenuDlg", 0); - menu_def.Load("MenuDlg"); - menudlg = new MenuDlg(screen, menu_def, this); - - FormDef exit_def("ExitDlg", 0); - exit_def.Load("ExitDlg"); - exitdlg = new ExitDlg(screen, exit_def, this); - - FormDef aud_def("AudDlg", 0); - aud_def.Load("AudDlg"); - auddlg = new AudDlg(screen, aud_def, this); - - FormDef ctl_def("CtlDlg", 0); - ctl_def.Load("CtlDlg"); - ctldlg = new CtlDlg(screen, ctl_def, this); - - FormDef opt_def("OptDlg", 0); - opt_def.Load("OptDlg"); - optdlg = new OptDlg(screen, opt_def, this); - - FormDef vid_def("VidDlg", 0); - vid_def.Load("VidDlg"); - viddlg = new VidDlg(screen, vid_def, this); - - FormDef mod_def("ModDlg", 0); - mod_def.Load("ModDlg"); - modDlg = new ModDlg(screen, mod_def, this); - - FormDef tac_ref_def("TacRefDlg", 0); - tac_ref_def.Load("TacRefDlg"); - tacRefDlg = new TacRefDlg(screen, tac_ref_def, this); - - FormDef cmp_sel_def("CmpSelectDlg", 0); - cmp_sel_def.Load("CmpSelectDlg"); - cmpSelectDlg = new CmpSelectDlg(screen, cmp_sel_def, this); - - FormDef net_lobby_def("NetLobbyDlg", 0); - net_lobby_def.Load("NetLobbyDlg"); - netLobbyDlg = new NetLobbyDlg(screen, net_lobby_def, this); - - FormDef net_client_def("NetClientDlg", 0); - net_client_def.Load("NetClientDlg"); - netClientDlg = new NetClientDlg(screen, net_client_def, this); - - FormDef net_server_def("NetServerDlg", 0); - net_server_def.Load("NetServerDlg"); - netServerDlg = new NetServerDlg(screen, net_server_def, this); - - FormDef net_unit_def("NetUnitDlg", 0); - net_unit_def.Load("NetUnitDlg"); - netUnitDlg = new NetUnitDlg(screen, net_unit_def, this); - - FormDef net_addr_def("NetAddrDlg", 0); - net_addr_def.Load("NetAddrDlg"); - netAddrDlg = new NetAddrDlg(screen, net_addr_def, this); - - FormDef net_pass_def("NetPassDlg", 0); - net_pass_def.Load("NetPassDlg"); - netPassDlg = new NetPassDlg(screen, net_pass_def, this); - - FormDef msn_edit_def("MsnEditDlg", 0); - msn_edit_def.Load("MsnEditDlg"); - msnEditDlg = new MsnEditDlg(screen, msn_edit_def, this); - - FormDef msn_nav_def("MsnEditNavDlg", 0); - msn_nav_def.Load("MsnEditNavDlg"); - msnEditNavDlg = new MsnEditNavDlg(screen, msn_nav_def, this); - - FormDef msn_elem_def("MsnElemDlg", 0); - msn_elem_def.Load("MsnElemDlg"); - msnElemDlg = new MsnElemDlg(screen, msn_elem_def, this); - - FormDef msn_event_def("MsnEventDlg", 0); - msn_event_def.Load("MsnEventDlg"); - msnEventDlg = new MsnEventDlg(screen, msn_event_def, this); - - FormDef msn_def("MsnSelectDlg", 0); - msn_def.Load("MsnSelectDlg"); - msnSelectDlg = new MsnSelectDlg(screen, msn_def, this); - - FormDef player_def("PlayerDlg", 0); - player_def.Load("PlayerDlg"); - playdlg = new PlayerDlg(screen, player_def, this); - - FormDef award_def("AwardDlg", 0); - award_def.Load("AwardDlg"); - awarddlg = new AwardShowDlg(screen, award_def, this); - - FormDef joy_def("JoyDlg", 0); - joy_def.Load("JoyDlg"); - joydlg = new JoyDlg(screen, joy_def, this); - - FormDef key_def("KeyDlg", 0); - key_def.Load("KeyDlg"); - keydlg = new KeyDlg(screen, key_def, this); - - FormDef first_def("FirstTimeDlg", 0); - first_def.Load("FirstTimeDlg"); - firstdlg = new FirstTimeDlg(screen, first_def, this); - - FormDef mod_info_def("ModInfoDlg", 0); - mod_info_def.Load("ModInfoDlg"); - modInfoDlg = new ModInfoDlg(screen, mod_info_def, this); - - FormDef confirm_def("ConfirmDlg", 0); - confirm_def.Load("ConfirmDlg"); - confirmdlg = new ConfirmDlg(screen, confirm_def, this); - - FormDef load_def("LoadDlg", 0); - load_def.Load("LoadDlg"); - loadDlg = new LoadDlg(screen, load_def); - - fadewin = new Window(screen, 0, 0, 1, 1); - fadeview = new FadeView(fadewin, 2, 0, 0); - fadewin->AddView(fadeview); - screen->AddWindow(fadewin); - - loader->UseFileSystem(Starshatter::UseFileSystem()); - - ShowMenuDlg(); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::TearDown() -{ - if (screen) { - if (menudlg) screen->DelWindow(menudlg); - if (netClientDlg) screen->DelWindow(netClientDlg); - if (netAddrDlg) screen->DelWindow(netAddrDlg); - if (netPassDlg) screen->DelWindow(netPassDlg); - if (netLobbyDlg) screen->DelWindow(netLobbyDlg); - if (netServerDlg) screen->DelWindow(netServerDlg); - if (netUnitDlg) screen->DelWindow(netUnitDlg); - - if (cmpSelectDlg) screen->DelWindow(cmpSelectDlg); - if (awarddlg) screen->DelWindow(awarddlg); - if (firstdlg) screen->DelWindow(firstdlg); - if (msnSelectDlg) screen->DelWindow(msnSelectDlg); - if (msnEditDlg) screen->DelWindow(msnEditDlg); - if (msnElemDlg) screen->DelWindow(msnElemDlg); - if (msnEventDlg) screen->DelWindow(msnEventDlg); - if (msnEditNavDlg) screen->DelWindow(msnEditNavDlg); - if (tacRefDlg) screen->DelWindow(tacRefDlg); - if (loadDlg) screen->DelWindow(loadDlg); - - if (auddlg) screen->DelWindow(auddlg); - if (viddlg) screen->DelWindow(viddlg); - if (optdlg) screen->DelWindow(optdlg); - if (ctldlg) screen->DelWindow(ctldlg); - if (modDlg) screen->DelWindow(modDlg); - if (modInfoDlg) screen->DelWindow(modInfoDlg); - if (joydlg) screen->DelWindow(joydlg); - if (keydlg) screen->DelWindow(keydlg); - if (exitdlg) screen->DelWindow(exitdlg); - if (playdlg) screen->DelWindow(playdlg); - if (confirmdlg) screen->DelWindow(confirmdlg); - if (fadewin) screen->DelWindow(fadewin); - } - - delete menudlg; - delete fadewin; - delete exitdlg; - delete auddlg; - delete viddlg; - delete optdlg; - delete ctldlg; - delete modDlg; - delete modInfoDlg; - delete joydlg; - delete keydlg; - delete playdlg; - delete confirmdlg; - - delete netClientDlg; - delete netAddrDlg; - delete netPassDlg; - delete netLobbyDlg; - delete netServerDlg; - delete netUnitDlg; - delete msnSelectDlg; - delete msnEditDlg; - delete msnElemDlg; - delete msnEventDlg; - delete msnEditNavDlg; - delete tacRefDlg; - delete loadDlg; - delete firstdlg; - delete awarddlg; - delete cmpSelectDlg; - - screen = 0; - fadewin = 0; - fadeview = 0; - menudlg = 0; - exitdlg = 0; - playdlg = 0; - confirmdlg = 0; - msnSelectDlg = 0; - msnEditDlg = 0; - msnElemDlg = 0; - msnEventDlg = 0; - msnEditNavDlg = 0; - cmpSelectDlg = 0; - awarddlg = 0; - firstdlg = 0; - netClientDlg = 0; - netAddrDlg = 0; - netPassDlg = 0; - netLobbyDlg = 0; - netServerDlg = 0; - netUnitDlg = 0; - loadDlg = 0; - tacRefDlg = 0; - - auddlg = 0; - viddlg = 0; - optdlg = 0; - ctldlg = 0; - modDlg = 0; - modInfoDlg = 0; - joydlg = 0; - keydlg = 0; - - screen = 0; -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ExecFrame() -{ - GameWinDX9::GetInstance()->SetScreenColor(Color::Black); - - if (menudlg && menudlg->IsShown()) - menudlg->ExecFrame(); - - if (exitdlg && exitdlg->IsShown()) - exitdlg->ExecFrame(); - - if (joydlg && joydlg->IsShown()) - joydlg->ExecFrame(); - - if (keydlg && keydlg->IsShown()) - keydlg->ExecFrame(); - - if (ctldlg && ctldlg->IsShown()) - ctldlg->ExecFrame(); - - if (optdlg && optdlg->IsShown()) - optdlg->ExecFrame(); - - if (auddlg && auddlg->IsShown()) - auddlg->ExecFrame(); - - if (viddlg && viddlg->IsShown()) - viddlg->ExecFrame(); - - if (confirmdlg && confirmdlg->IsShown()) - confirmdlg->ExecFrame(); - - if (playdlg && playdlg->IsShown()) - playdlg->ExecFrame(); - - if (msnSelectDlg && msnSelectDlg->IsShown()) - msnSelectDlg->ExecFrame(); - - if (msnEditNavDlg && msnEditNavDlg->IsShown()) - msnEditNavDlg->ExecFrame(); - - if (firstdlg && firstdlg->IsShown()) - firstdlg->ExecFrame(); - - if (awarddlg && awarddlg->IsShown()) - awarddlg->ExecFrame(); - - if (cmpSelectDlg && cmpSelectDlg->IsShown()) - cmpSelectDlg->ExecFrame(); - - if (netClientDlg && netClientDlg->IsShown()) - netClientDlg->ExecFrame(); - - if (netAddrDlg && netAddrDlg->IsShown()) - netAddrDlg->ExecFrame(); - - if (netPassDlg && netPassDlg->IsShown()) - netPassDlg->ExecFrame(); - - if (netLobbyDlg && netLobbyDlg->IsShown()) - netLobbyDlg->ExecFrame(); - - if (netServerDlg && netServerDlg->IsShown()) - netServerDlg->ExecFrame(); - - if (netUnitDlg && netUnitDlg->IsShown()) - netUnitDlg->ExecFrame(); - - if (loadDlg && loadDlg->IsShown()) - loadDlg->ExecFrame(); - - if (tacRefDlg && tacRefDlg->IsShown()) - tacRefDlg->ExecFrame(); -} - -// +--------------------------------------------------------------------+ - -bool -MenuScreen::CloseTopmost() -{ - bool processed = false; - if (joydlg && joydlg->IsShown()) { - ShowCtlDlg(); - processed = true; - } - - else if (keydlg && keydlg->IsShown()) { - ShowCtlDlg(); - processed = true; - } - - else if (msnElemDlg && msnElemDlg->IsShown()) { - HideMsnElemDlg(); - processed = true; - } - - else if (msnEventDlg && msnEventDlg->IsShown()) { - HideMsnEventDlg(); - processed = true; - } - - else if (netAddrDlg && netAddrDlg->IsShown()) { - ShowNetClientDlg(); - processed = true; - } - - else if (netPassDlg && netPassDlg->IsShown()) { - ShowNetClientDlg(); - processed = true; - } - - else if (netServerDlg && netServerDlg->IsShown()) { - ShowNetClientDlg(); - processed = true; - } - - else if (netUnitDlg && netUnitDlg->IsShown()) { - netUnitDlg->OnCancel(0); - processed = true; - } - - else if (netLobbyDlg && netLobbyDlg->IsShown()) { - netLobbyDlg->OnCancel(0); - processed = true; - } - - else if (netClientDlg && netClientDlg->IsShown()) { - netClientDlg->OnCancel(0); - processed = true; - } - - else if (exitdlg && exitdlg->IsShown()) { - // key_exit is handled in the exit dlg... - } - - else if (cmpSelectDlg && cmpSelectDlg->IsShown()) { - if (cmpSelectDlg->CanClose()) - ShowMenuDlg(); - - processed = true; - } - - else if (menudlg && !menudlg->IsShown()) { - ShowMenuDlg(); - processed = true; - } - - return processed; -} - -void -MenuScreen::Show() -{ - if (!isShown) { - Starshatter* stars = Starshatter::GetInstance(); - NetLobby* lobby = NetLobby::GetInstance(); - - if (lobby) { - ShowNetLobbyDlg(); - } - else if (current_dlg == msnSelectDlg) { - ShowMsnSelectDlg(); - } - else { - if (Player::ConfigExists()) { - ShowMenuDlg(); - } - - else { - ShowFirstTimeDlg(); - } - } - - isShown = true; - } -} - -void -MenuScreen::Hide() -{ - if (isShown) { - HideAll(); - isShown = false; - } -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowMenuDlg() -{ - HideAll(); - if (menudlg) { - menudlg->Show(); - menudlg->SetTopMost(true); - } - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowCmpSelectDlg() -{ - HideAll(); - current_dlg = cmpSelectDlg; - if (cmpSelectDlg) - cmpSelectDlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowMsnSelectDlg() -{ - HideAll(); - current_dlg = msnSelectDlg; - - if (msnSelectDlg) - msnSelectDlg->Show(); - - if (msnEditNavDlg) - msnEditNavDlg->SetMission(0); - - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowModDlg() -{ - if (modDlg) { - HideAll(); - modDlg->Show(); - modDlg->SetTopMost(true); - Mouse::Show(true); - } - else { - ShowMsnSelectDlg(); - } -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowModInfoDlg() -{ - if (modDlg && modInfoDlg) { - HideAll(); - modDlg->Show(); - modDlg->SetTopMost(false); - modInfoDlg->Show(); - Mouse::Show(true); - } - else { - ShowMsnSelectDlg(); - } -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowMsnEditDlg() -{ - if (msnEditDlg) { - bool nav_shown = false; - if (msnEditNavDlg && msnEditNavDlg->IsShown()) - nav_shown = true; - - HideAll(); - - if (nav_shown) { - msnEditNavDlg->Show(); - msnEditNavDlg->SetTopMost(true); - } - else { - msnEditDlg->Show(); - msnEditDlg->SetTopMost(true); - } - - Mouse::Show(true); - } - else { - ShowMsnSelectDlg(); - } -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowMsnElemDlg() -{ - if (msnElemDlg) { - if (msnEditDlg && msnEditDlg->IsShown()) - msnEditDlg->SetTopMost(false); - - if (msnEditNavDlg && msnEditNavDlg->IsShown()) - msnEditNavDlg->SetTopMost(false); - - msnElemDlg->Show(); - msnElemDlg->SetTopMost(true); - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowMsnEventDlg() -{ - if (msnEventDlg) { - if (msnEditDlg && msnEditDlg->IsShown()) - msnEditDlg->SetTopMost(false); - - if (msnEditNavDlg && msnEditNavDlg->IsShown()) - msnEditNavDlg->SetTopMost(false); - - msnEventDlg->Show(); - msnEventDlg->SetTopMost(true); - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowNavDlg() -{ - if (msnEditNavDlg && !msnEditNavDlg->IsShown()) { - HideAll(); - msnEditNavDlg->Show(); - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowFirstTimeDlg() -{ - HideAll(); - if (menudlg && firstdlg) { - menudlg->Show(); - menudlg->SetTopMost(false); - - firstdlg->Show(); - firstdlg->SetTopMost(true); - } - - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowPlayerDlg() -{ - if (playdlg) { - HideAll(); - playdlg->Show(); - } - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowAwardDlg() -{ - if (awarddlg) { - HideAll(); - awarddlg->Show(); - } - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowTacRefDlg() -{ - if (tacRefDlg) { - HideAll(); - tacRefDlg->Show(); - } - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowNetClientDlg() -{ - if (netClientDlg) { - HideAll(); - netClientDlg->Show(); - netClientDlg->SetTopMost(true); - } - - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowNetAddrDlg() -{ - if (netAddrDlg) { - if (netClientDlg) { - netClientDlg->Show(); - netClientDlg->SetTopMost(false); - } - - netAddrDlg->Show(); - } - - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowNetPassDlg() -{ - if (netPassDlg) { - ShowNetClientDlg(); - if (netClientDlg) - netClientDlg->SetTopMost(false); - - netPassDlg->Show(); - } - - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowNetLobbyDlg() -{ - if (netLobbyDlg) { - HideAll(); - netLobbyDlg->Show(); - netLobbyDlg->SetTopMost(true); - } - - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowNetServerDlg() -{ - if (netServerDlg) { - netServerDlg->Show(); - netServerDlg->SetTopMost(true); - } - - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowNetUnitDlg() -{ - if (netUnitDlg) { - HideAll(); - netUnitDlg->Show(); - netUnitDlg->SetTopMost(true); - } - - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowAudDlg() -{ - HideAll(); - if (auddlg) - auddlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowVidDlg() -{ - HideAll(); - if (viddlg) - viddlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowOptDlg() -{ - HideAll(); - if (optdlg) - optdlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowCtlDlg() -{ - HideAll(); - if (ctldlg) { - ctldlg->Show(); - ctldlg->SetTopMost(true); - } - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowJoyDlg() -{ - HideAll(); - if (ctldlg) { - ctldlg->Show(); - ctldlg->SetTopMost(false); - } - - if (joydlg) - joydlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowKeyDlg() -{ - HideAll(); - - if (ctldlg) { - ctldlg->Show(); - ctldlg->SetTopMost(false); - } - - if (keydlg) - keydlg->Show(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowConfirmDlg() -{ - if (confirmdlg) { - if (msnSelectDlg && msnSelectDlg->IsShown()) - msnSelectDlg->SetTopMost(false); - - if (playdlg && playdlg->IsShown()) - playdlg->SetTopMost(false); - - confirmdlg->Show(); - confirmdlg->SetTopMost(true); - Mouse::Show(true); - } -} - -void -MenuScreen::HideConfirmDlg() -{ - if (confirmdlg) - confirmdlg->Hide(); - - if (msnSelectDlg && msnSelectDlg->IsShown()) - msnSelectDlg->SetTopMost(true); - - if (playdlg && playdlg->IsShown()) - playdlg->SetTopMost(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowLoadDlg() -{ - if (loadDlg) { - if (menudlg && menudlg->IsShown()) - menudlg->SetTopMost(false); - - loadDlg->Show(); - loadDlg->SetTopMost(true); - Mouse::Show(true); - } -} - -void -MenuScreen::HideLoadDlg() -{ - if (loadDlg) - loadDlg->Hide(); - - if (menudlg && menudlg->IsShown()) - menudlg->SetTopMost(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ShowExitDlg() -{ - HideAll(); - - if (menudlg) { - menudlg->Show(); - menudlg->SetTopMost(false); - } - - if (exitdlg) - exitdlg->Show(); - else - Starshatter::GetInstance()->Exit(); - - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::HideNavDlg() -{ - if (msnEditNavDlg) - msnEditNavDlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::HideMsnElemDlg() -{ - if (msnElemDlg) - msnElemDlg->Hide(); - - if (msnEditDlg && msnEditDlg->IsShown()) - msnEditDlg->SetTopMost(true); - - if (msnEditNavDlg && msnEditNavDlg->IsShown()) - msnEditNavDlg->SetTopMost(true); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::HideMsnEventDlg() -{ - if (msnEventDlg) - msnEventDlg->Hide(); - - if (msnEditDlg && msnEditDlg->IsShown()) - msnEditDlg->SetTopMost(true); - - if (msnEditNavDlg && msnEditNavDlg->IsShown()) - msnEditNavDlg->SetTopMost(true); -} - -// +--------------------------------------------------------------------+ - -bool -MenuScreen::IsNavShown() -{ - return msnEditNavDlg && msnEditNavDlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::HideAll() -{ - Keyboard::FlushKeys(); - - current_dlg = 0; - - if (menudlg) menudlg->Hide(); - if (exitdlg) exitdlg->Hide(); - if (auddlg) auddlg->Hide(); - if (viddlg) viddlg->Hide(); - if (ctldlg) ctldlg->Hide(); - if (optdlg) optdlg->Hide(); - if (joydlg) joydlg->Hide(); - if (keydlg) keydlg->Hide(); - if (playdlg) playdlg->Hide(); - if (confirmdlg) confirmdlg->Hide(); - if (modDlg) modDlg->Hide(); - if (modInfoDlg) modInfoDlg->Hide(); - if (msnSelectDlg) msnSelectDlg->Hide(); - if (msnEditDlg) msnEditDlg->Hide(); - if (msnElemDlg) msnElemDlg->Hide(); - if (msnEventDlg) msnEventDlg->Hide(); - if (msnEditNavDlg) msnEditNavDlg->Hide(); - if (netClientDlg) netClientDlg->Hide(); - if (netAddrDlg) netAddrDlg->Hide(); - if (netPassDlg) netPassDlg->Hide(); - if (netLobbyDlg) netLobbyDlg->Hide(); - if (netServerDlg) netServerDlg->Hide(); - if (netUnitDlg) netUnitDlg->Hide(); - if (firstdlg) firstdlg->Hide(); - if (awarddlg) awarddlg->Hide(); - if (cmpSelectDlg) cmpSelectDlg->Hide(); - if (tacRefDlg) tacRefDlg->Hide(); - if (loadDlg) loadDlg->Hide(); -} - -// +--------------------------------------------------------------------+ - -void -MenuScreen::ApplyOptions() -{ - if (ctldlg) ctldlg->Apply(); - if (optdlg) optdlg->Apply(); - if (auddlg) auddlg->Apply(); - if (viddlg) viddlg->Apply(); - if (modDlg) modDlg->Apply(); - - ShowMenuDlg(); -} - -void -MenuScreen::CancelOptions() -{ - if (ctldlg) ctldlg->Cancel(); - if (optdlg) optdlg->Cancel(); - if (auddlg) auddlg->Cancel(); - if (viddlg) viddlg->Cancel(); - if (modDlg) modDlg->Cancel(); - - ShowMenuDlg(); -} diff --git a/Stars45/MenuScreen.h b/Stars45/MenuScreen.h deleted file mode 100644 index 6642e16..0000000 --- a/Stars45/MenuScreen.h +++ /dev/null @@ -1,198 +0,0 @@ -/* 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 - -*/ - -#ifndef MenuScreen_h -#define MenuScreen_h - -#include "Types.h" -#include "Bitmap.h" -#include "Screen.h" -#include "BaseScreen.h" - -// +--------------------------------------------------------------------+ - -class MenuDlg; -class AudDlg; -class VidDlg; -class OptDlg; -class CtlDlg; -class JoyDlg; -class KeyDlg; -class ExitDlg; -class ConfirmDlg; - -class FirstTimeDlg; -class PlayerDlg; -class AwardShowDlg; - -class MsnSelectDlg; -class CmpSelectDlg; -class ModDlg; -class ModInfoDlg; -class MsnEditDlg; -class MsnElemDlg; -class MsnEventDlg; - -class NetClientDlg; -class NetAddrDlg; -class NetPassDlg; -class NetLobbyDlg; -class NetServerDlg; -class NetUnitDlg; - -class LoadDlg; -class TacRefDlg; - -class ActiveWindow; -class Bitmap; -class DataLoader; -class FadeView; -class Font; -class FormWindow; -class Screen; -class Video; -class VideoFactory; -class Window; - -// +--------------------------------------------------------------------+ - -class MenuScreen : public BaseScreen -{ -public: - MenuScreen(); - virtual ~MenuScreen(); - - virtual void Setup(Screen* screen); - virtual void TearDown(); - virtual bool CloseTopmost(); - - virtual bool IsShown() const { return isShown; } - virtual void Show(); - virtual void Hide(); - - virtual void ExecFrame(); - - virtual void ShowMenuDlg(); - virtual void ShowCmpSelectDlg(); - virtual void ShowMsnSelectDlg(); - virtual void ShowModDlg(); - virtual void ShowModInfoDlg(); - virtual void ShowMsnEditDlg(); - virtual void ShowNetClientDlg(); - virtual void ShowNetAddrDlg(); - virtual void ShowNetPassDlg(); - virtual void ShowNetLobbyDlg(); - virtual void ShowNetServerDlg(); - virtual void ShowNetUnitDlg(); - virtual void ShowFirstTimeDlg(); - virtual void ShowPlayerDlg(); - virtual void ShowTacRefDlg(); - virtual void ShowAwardDlg(); - virtual void ShowAudDlg(); - virtual void ShowVidDlg(); - virtual void ShowOptDlg(); - virtual void ShowCtlDlg(); - virtual void ShowJoyDlg(); - virtual void ShowKeyDlg(); - virtual void ShowExitDlg(); - virtual void ShowConfirmDlg(); - virtual void HideConfirmDlg(); - virtual void ShowLoadDlg(); - virtual void HideLoadDlg(); - - // base screen interface: - virtual void ShowMsnElemDlg(); - virtual void HideMsnElemDlg(); - virtual MsnElemDlg* GetMsnElemDlg() { return msnElemDlg; } - - virtual void ShowMsnEventDlg(); - virtual void HideMsnEventDlg(); - virtual MsnEventDlg* GetMsnEventDlg() { return msnEventDlg; } - - virtual void ShowNavDlg(); - virtual void HideNavDlg(); - virtual bool IsNavShown(); - virtual NavDlg* GetNavDlg() { return msnEditNavDlg; } - - virtual MsnSelectDlg* GetMsnSelectDlg() const { return msnSelectDlg; } - virtual ModDlg* GetModDlg() const { return modDlg; } - virtual ModInfoDlg* GetModInfoDlg() const { return modInfoDlg; } - virtual MsnEditDlg* GetMsnEditDlg() const { return msnEditDlg; } - virtual NetClientDlg* GetNetClientDlg() const { return netClientDlg; } - virtual NetAddrDlg* GetNetAddrDlg() const { return netAddrDlg; } - virtual NetPassDlg* GetNetPassDlg() const { return netPassDlg; } - virtual NetLobbyDlg* GetNetLobbyDlg() const { return netLobbyDlg; } - virtual NetServerDlg* GetNetServerDlg() const { return netServerDlg; } - virtual NetUnitDlg* GetNetUnitDlg() const { return netUnitDlg; } - virtual LoadDlg* GetLoadDlg() const { return loadDlg; } - virtual TacRefDlg* GetTacRefDlg() const { return tacRefDlg; } - - virtual AudDlg* GetAudDlg() const { return auddlg; } - virtual VidDlg* GetVidDlg() const { return viddlg; } - virtual OptDlg* GetOptDlg() const { return optdlg; } - virtual CtlDlg* GetCtlDlg() const { return ctldlg; } - virtual JoyDlg* GetJoyDlg() const { return joydlg; } - virtual KeyDlg* GetKeyDlg() const { return keydlg; } - virtual ExitDlg* GetExitDlg() const { return exitdlg; } - virtual FirstTimeDlg* GetFirstTimeDlg() const { return firstdlg; } - virtual PlayerDlg* GetPlayerDlg() const { return playdlg; } - virtual AwardShowDlg* GetAwardDlg() const { return awarddlg; } - virtual ConfirmDlg* GetConfirmDlg() const { return confirmdlg; } - - virtual void ApplyOptions(); - virtual void CancelOptions(); - -private: - void HideAll(); - - Screen* screen; - MenuDlg* menudlg; - - Window* fadewin; - FadeView* fadeview; - ExitDlg* exitdlg; - AudDlg* auddlg; - VidDlg* viddlg; - OptDlg* optdlg; - CtlDlg* ctldlg; - JoyDlg* joydlg; - KeyDlg* keydlg; - ConfirmDlg* confirmdlg; - PlayerDlg* playdlg; - AwardShowDlg* awarddlg; - ModDlg* modDlg; - ModInfoDlg* modInfoDlg; - MsnSelectDlg* msnSelectDlg; - MsnEditDlg* msnEditDlg; - MsnElemDlg* msnElemDlg; - MsnEventDlg* msnEventDlg; - NavDlg* msnEditNavDlg; - LoadDlg* loadDlg; - TacRefDlg* tacRefDlg; - - CmpSelectDlg* cmpSelectDlg; - FirstTimeDlg* firstdlg; - NetClientDlg* netClientDlg; - NetAddrDlg* netAddrDlg; - NetPassDlg* netPassDlg; - NetLobbyDlg* netLobbyDlg; - NetServerDlg* netServerDlg; - NetUnitDlg* netUnitDlg; - - FormWindow* current_dlg; - DataLoader* loader; - - int wc, hc; - bool isShown; -}; - -// +--------------------------------------------------------------------+ - -#endif // MenuScreen_h - diff --git a/Stars45/MenuView.cpp b/Stars45/MenuView.cpp deleted file mode 100644 index 6c4d26e..0000000 --- a/Stars45/MenuView.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - -*/ - -#include "MenuView.h" - -#include "Color.h" -#include "Window.h" -#include "Video.h" -#include "DataLoader.h" -#include "Scene.h" -#include "FontMgr.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "MouseController.h" -#include "Menu.h" -#include "Button.h" -#include "Clock.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ - -MenuView::MenuView(Window* c) -: View(c), -mouse_down(0), right_down(0), shift_down(0), show_menu(false), -action(0), menu(0), menu_item(0), selected(0), -text_color(Color::White), back_color(Color::Black) -{ - right_start.x = 0; - right_start.y = 0; - - OnWindowMove(); -} - -MenuView::~MenuView() -{ -} - -// +--------------------------------------------------------------------+ - -void -MenuView::OnWindowMove() -{ - offset.x = window->X(); - offset.y = window->Y(); - width = window->Width(); - height = window->Height(); -} - -// +--------------------------------------------------------------------+ - -void -MenuView::Refresh() -{ - if (show_menu) - DrawMenu(); -} - -// +--------------------------------------------------------------------+ - -void -MenuView::DoMouseFrame() -{ - static DWORD rbutton_latch = 0; - - action = 0; - - if (Mouse::RButton()) { - MouseController* mouse_con = MouseController::GetInstance(); - if (!right_down && (!mouse_con || !mouse_con->Active())) { - rbutton_latch = Clock::GetInstance()->RealTime(); - right_down = true; - show_menu = false; - } - } - else { - if (right_down && (Clock::GetInstance()->RealTime() - rbutton_latch < 250)) { - right_start.x = Mouse::X() - offset.x; - right_start.y = Mouse::Y() - offset.y; - show_menu = true; - Button::PlaySound(Button::SND_MENU_OPEN); - } - - right_down = false; - } - - MouseController* mouse_con = MouseController::GetInstance(); - - if (!mouse_con || !mouse_con->Active()) { - if (Mouse::LButton()) { - if (!mouse_down) - shift_down = Keyboard::KeyDown(VK_SHIFT); - - mouse_down = true; - } - - else if (mouse_down) { - int mouse_x = Mouse::X() - offset.x; - int mouse_y = Mouse::Y() - offset.y; - int keep_menu = false; - - if (show_menu) { - keep_menu = ProcessMenuItem(); - Mouse::Show(true); - } - - mouse_down = false; - - if (!keep_menu) { - ClearMenuSelection(menu); - show_menu = false; - } - } - } -} - -// +--------------------------------------------------------------------+ - -int -MenuView::ProcessMenuItem() -{ - if (!menu_item || !menu_item->GetEnabled()) - return false; - - if (menu_item->GetSubmenu()) { - ListIter item = menu_item->GetMenu()->GetItems(); - while (++item) - if (item.value() == menu_item) - item->SetSelected(2); - else - item->SetSelected(0); - - Button::PlaySound(Button::SND_MENU_OPEN); - return true; // keep menu showing - } - - action = menu_item->GetData(); - Button::PlaySound(Button::SND_MENU_SELECT); - return false; -} - -// +--------------------------------------------------------------------+ - -void -MenuView::DrawMenu() -{ - menu_item = 0; - - if (menu) { - int mx = right_start.x - 2; - int my = right_start.y - 2; - - DrawMenu(mx, my, menu); - } -} - -void -MenuView::DrawMenu(int mx, int my, Menu* m) -{ - if (m) { - MenuItem* locked_item = 0; - Menu* submenu = 0; - int subx = 0; - int suby = 0; - Font* font = FontMgr::Find("HUD"); - - Rect menu_rect(mx, my, 100, m->NumItems() * 10 + 6); - - int max_width = 0; - int max_height = 0; - int extra_width = 16; - - ListIter item = m->GetItems(); - while (++item) { - menu_rect.w = width/2; - - if (item->GetText().length()) { - window->SetFont(font); - window->DrawText(item->GetText(), 0, menu_rect, DT_LEFT|DT_SINGLELINE|DT_CALCRECT); - if (menu_rect.w > max_width) - max_width = menu_rect.w; - max_height += 11; - - if (item->GetSubmenu()) - extra_width = 28; - - if (item->GetSelected() > 1) - locked_item = item.value(); - } - else { - max_height += 4; - } - } - - menu_rect.h = max_height + 6; - menu_rect.w = max_width + extra_width; - - if (menu_rect.x + menu_rect.w >= width) - menu_rect.x = width - menu_rect.w - 2; - - if (menu_rect.y + menu_rect.h >= height) - menu_rect.y = height - menu_rect.h - 2; - - window->FillRect(menu_rect, back_color * 0.2); - window->DrawRect(menu_rect, back_color); - - Rect item_rect = menu_rect; - - item_rect.x += 4; - item_rect.y += 3; - item_rect.w -= 8; - item_rect.h = 12; - - item.reset(); - while (++item) { - int line_height = 0; - - if (item->GetText().length()) { - Rect fill_rect = item_rect; - fill_rect.Inflate(2,-1); - fill_rect.y -= 1; - - int mx = Mouse::X() - offset.x; - int my = Mouse::Y() - offset.y; - - // is this item picked? - if (menu_rect.Contains(mx, my)) { - if (my >= fill_rect.y && my <= fill_rect.y+fill_rect.h) { - if (Mouse::LButton()) { - menu_item = item.value(); - item->SetSelected(2); - if (locked_item && locked_item->GetMenu() == m) - locked_item->SetSelected(0); - locked_item = menu_item; - } - else if (!locked_item || locked_item->GetMenu() != m) { - item->SetSelected(true); - menu_item = item.value(); - } - - if (menu_item && menu_item != selected) { - selected = menu_item; - Button::PlaySound(Button::SND_MENU_HILITE); - } - } - else if (item.value() != locked_item) { - item->SetSelected(false); - } - } - - if (item->GetSelected()) { - window->FillRect(fill_rect, back_color * 0.35); - window->DrawRect(fill_rect, back_color * 0.75); - - if (item->GetSubmenu()) { - submenu = item->GetSubmenu(); - subx = menu_rect.x + max_width + extra_width; - suby = fill_rect.y - 3; - } - } - - if (item->GetEnabled()) - font->SetColor(text_color); - else - font->SetColor(text_color * 0.33); - - window->SetFont(font); - window->DrawText(item->GetText(), 0, item_rect, DT_LEFT|DT_SINGLELINE); - line_height = 11; - } - else { - window->DrawLine(item_rect.x, - item_rect.y + 2, - item_rect.x + max_width + extra_width - 8, - item_rect.y + 2, - back_color); - line_height = 4; - } - - if (item->GetSubmenu()) { - int left = item_rect.x + max_width + 10; - int top = item_rect.y + 1; - - // draw the arrow: - POINT arrow[3]; - - arrow[0].x = left; - arrow[0].y = top; - arrow[1].x = left + 8; - arrow[1].y = top + 4; - arrow[2].x = left; - arrow[2].y = top + 8; - - window->FillPoly(3, arrow, back_color); - } - - item_rect.y += line_height; - } - - if (submenu) { - if (subx + 60 > width) - subx = menu_rect.x - 60; - - DrawMenu(subx, suby, submenu); - } - } -} - -// +--------------------------------------------------------------------+ - -void -MenuView::ClearMenuSelection(Menu* menu) -{ - if (menu) { - ListIter item = menu->GetItems(); - while (++item) { - item->SetSelected(0); - if (item->GetSubmenu()) - ClearMenuSelection(item->GetSubmenu()); - } - } -} diff --git a/Stars45/MenuView.h b/Stars45/MenuView.h deleted file mode 100644 index f5890b2..0000000 --- a/Stars45/MenuView.h +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for displaying right-click context menus -*/ - -#ifndef MenuView_h -#define MenuView_h - -#include "Types.h" -#include "View.h" -#include "Bitmap.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Menu; -class MenuItem; - -// +--------------------------------------------------------------------+ - -class MenuView : public View -{ -public: - MenuView(Window* c); - virtual ~MenuView(); - - // Operations: - virtual void Refresh(); - virtual void OnWindowMove(); - virtual void DoMouseFrame(); - virtual void DrawMenu(); - virtual void DrawMenu(int x, int y, Menu* menu); - virtual int ProcessMenuItem(); - virtual void ClearMenuSelection(Menu* menu); - - virtual bool IsShown() { return show_menu != 0; } - virtual int GetAction() { return action; } - virtual Menu* GetMenu() { return menu; } - virtual void SetMenu(Menu* m) { menu = m; } - virtual MenuItem* GetMenuItem() { return menu_item; } - - virtual Color GetBackColor() { return back_color; } - virtual void SetBackColor(Color c) { back_color = c; } - virtual Color GetTextColor() { return text_color; } - virtual void SetTextColor(Color c) { text_color = c; } - -protected: - int width, height; - - int shift_down; - int mouse_down; - int right_down; - int show_menu; - POINT right_start; - POINT offset; - - int action; - Menu* menu; - MenuItem* menu_item; - MenuItem* selected; - - Color back_color; - Color text_color; -}; - -#endif // MenuView_h - diff --git a/Stars45/Mfd.cpp b/Stars45/Mfd.cpp deleted file mode 100644 index f79f2af..0000000 --- a/Stars45/Mfd.cpp +++ /dev/null @@ -1,1405 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Class for all Multi Function Displays -*/ - -#include "Mfd.h" -#include "HUDView.h" -#include "Ship.h" -#include "NavSystem.h" -#include "Power.h" -#include "Shield.h" -#include "Sensor.h" -#include "Contact.h" -#include "ShipDesign.h" -#include "Shot.h" -#include "Weapon.h" -#include "WeaponGroup.h" -#include "Sim.h" -#include "StarSystem.h" -#include "Starshatter.h" -#include "Drive.h" -#include "QuantumDrive.h" -#include "Power.h" -#include "Instruction.h" - -#include "NetGame.h" - -#include "CameraView.h" -#include "Color.h" -#include "Font.h" -#include "FontMgr.h" -#include "Window.h" -#include "Video.h" -#include "Screen.h" -#include "DataLoader.h" -#include "Scene.h" -#include "Graphic.h" -#include "Sprite.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Game.h" -#include "Clock.h" -#include "ContentBundle.h" - -static Bitmap sensor_fov; -static Bitmap sensor_fwd; -static Bitmap sensor_hsd; -static Bitmap sensor_3d; - -static BYTE* sensor_fov_shade; -static BYTE* sensor_fwd_shade; -static BYTE* sensor_hsd_shade; -static BYTE* sensor_3d_shade; - -static Color hud_color = Color::Black; -static Color txt_color = Color::Black; - -// +--------------------------------------------------------------------+ - -MFD::MFD(Window* c, int n) -: window(c), rect(0,0,0,0), index(n), mode(MFD_MODE_OFF), sprite(0), -ship(0), hidden(true), camview(0), lines(0), mouse_latch(0), mouse_in(false), -cockpit_hud_texture(0) -{ - sprite = new Sprite(&sensor_fov); - - sprite->SetBlendMode(2); - sprite->SetFilter(0); - sprite->Hide(); - - Font* font = FontMgr::Find("HUD"); - - for (int i = 0; i < TXT_LAST; i++) { - mfd_text[i].font = font; - mfd_text[i].color = Color::White; - mfd_text[i].hidden = true; - } -} - -MFD::~MFD() -{ - GRAPHIC_DESTROY(sprite); -} - -// +--------------------------------------------------------------------+ - -void -MFD::Initialize() -{ - static int initialized = 0; - if (initialized) return; - - HUDView::PrepareBitmap("sensor_fov.pcx", sensor_fov, sensor_fov_shade); - HUDView::PrepareBitmap("sensor_fwd.pcx", sensor_fwd, sensor_fwd_shade); - HUDView::PrepareBitmap("sensor_hsd.pcx", sensor_hsd, sensor_hsd_shade); - HUDView::PrepareBitmap("sensor_3d.pcx", sensor_3d, sensor_3d_shade); - - sensor_fov.SetType(Bitmap::BMP_TRANSLUCENT); - sensor_fwd.SetType(Bitmap::BMP_TRANSLUCENT); - sensor_hsd.SetType(Bitmap::BMP_TRANSLUCENT); - sensor_3d.SetType(Bitmap::BMP_TRANSLUCENT); - - initialized = 1; -} - -void -MFD::Close() -{ - sensor_fov.ClearImage(); - sensor_fwd.ClearImage(); - sensor_hsd.ClearImage(); - sensor_3d.ClearImage(); - - delete [] sensor_fov_shade; - delete [] sensor_fwd_shade; - delete [] sensor_hsd_shade; - delete [] sensor_3d_shade; -} - -// +--------------------------------------------------------------------+ - -void -MFD::UseCameraView(CameraView* v) -{ - if (v && !camview) { - camview = v; - } -} - -void -MFD::SetColor(Color c) -{ - HUDView* hud = HUDView::GetInstance(); - - if (hud) { - hud_color = hud->GetHUDColor(); - txt_color = hud->GetTextColor(); - } - else { - hud_color = c; - txt_color = c; - } - - HUDView::ColorizeBitmap(sensor_fov, sensor_fov_shade, c); - HUDView::ColorizeBitmap(sensor_fwd, sensor_fwd_shade, c); - HUDView::ColorizeBitmap(sensor_hsd, sensor_hsd_shade, c); - HUDView::ColorizeBitmap(sensor_3d, sensor_3d_shade, c); -} - -void -MFD::SetText3DColor(Color c) -{ - for (int i = 0; i < TXT_LAST; i++) - mfd_text[i].color = c; -} - -// +--------------------------------------------------------------------+ - -void -MFD::Show() -{ - switch (mode) { - case MFD_MODE_FOV: - case MFD_MODE_HSD: - case MFD_MODE_3D: - if (sprite) - sprite->Show(); - break; - } - - hidden = false; -} - -void -MFD::Hide() -{ - if (sprite) - sprite->Hide(); - - for (int i = 0; i < TXT_LAST; i++) - HideMFDText(i); - - hidden = true; -} - -// +--------------------------------------------------------------------+ - -void -MFD::SetRect(const Rect& r) -{ - rect = r; - - if (sprite) - sprite->MoveTo(Point(rect.x + sprite->Width()/2, - rect.y + sprite->Height()/2, - 1)); -} - -// +--------------------------------------------------------------------+ - -void -MFD::SetMode(int m) -{ - if (m < MFD_MODE_OFF || m > MFD_MODE_3D) - mode = MFD_MODE_OFF; - else - mode = m; - - sprite->Hide(); - - for (int i = 0; i < TXT_LAST; i++) - HideMFDText(i); - - switch (mode) { - case MFD_MODE_GAME: - case MFD_MODE_SHIP: - lines = 0; - break; - - case MFD_MODE_FOV: - sprite->SetAnimation(&sensor_fov); - sprite->Show(); - sprite->Reshape(sensor_fov.Width()-8, 16); - break; - case MFD_MODE_HSD: - sprite->SetAnimation(&sensor_hsd); - sprite->Show(); - sprite->Reshape(sensor_hsd.Width()-8, 16); - break; - case MFD_MODE_3D: - sprite->SetAnimation(&sensor_3d); - sprite->Show(); - sprite->Reshape(sensor_3d.Width()-8, 16); - break; - } -} - -// +--------------------------------------------------------------------+ - -void -MFD::Draw() -{ - mouse_in = false; - - if (Mouse::LButton() == 0) - mouse_latch = 0; - - if (rect.Contains(Mouse::X(), Mouse::Y())) - mouse_in = true; - - // click to turn on MFD when off: - if (mode < MFD_MODE_FOV && Mouse::LButton() && !mouse_latch) { - mouse_latch = 1; - if (mouse_in) { - HUDView* hud = HUDView::GetInstance(); - if (hud) - hud->CycleMFDMode(index); - } - } - - for (int i = 0; i < TXT_LAST; i++) - HideMFDText(i); - - if (hidden || mode < MFD_MODE_FOV) { - if (cockpit_hud_texture) { - int x1 = index*128; - int y1 = 256; - int x2 = x1 + 128; - int y2 = y1 + 128; - - cockpit_hud_texture->FillRect(x1, y1, x2, y2, Color::Black); - } - - if (hidden) - return; - } - - if (sprite && !sprite->Hidden()) { - if (cockpit_hud_texture) { - int x1 = index*128; - int y1 = 256; - int w = sprite->Width(); - int h = sprite->Height(); - - cockpit_hud_texture->BitBlt(x1, y1, *sprite->Frame(), 0,0,w,h); - } - else { - int cx = rect.x + rect.w/2; - int cy = rect.y + rect.h/2; - int w2 = sprite->Width()/2; - int h2 = sprite->Height()/2; - - window->DrawBitmap(cx-w2, cy-h2, cx+w2, cy+h2, sprite->Frame(), Video::BLEND_ALPHA); - } - } - - switch (mode) { - default: - case MFD_MODE_OFF: break; - case MFD_MODE_GAME: DrawGameMFD(); break; - case MFD_MODE_SHIP: DrawStatusMFD(); break; - - // sensor sub-modes: - case MFD_MODE_FOV: DrawSensorMFD(); break; - case MFD_MODE_HSD: DrawHSD(); break; - case MFD_MODE_3D: Draw3D(); break; - } -} - -// +--------------------------------------------------------------------+ - -void -MFD::DrawSensorLabels(const char* mfd_mode) -{ - Sensor* sensor = ship->GetSensor(); - char mode_buf[8] = " "; - int scan_r = rect.w; - int scan_x = rect.x; - int scan_y = rect.y; - - switch (sensor->GetMode()) { - case Sensor::PAS: strcpy_s(mode_buf, ContentBundle::GetInstance()->GetText("MFD.mode.passive").data()); break; - case Sensor::STD: strcpy_s(mode_buf, ContentBundle::GetInstance()->GetText("MFD.mode.standard").data()); break; - case Sensor::ACM: strcpy_s(mode_buf, ContentBundle::GetInstance()->GetText("MFD.mode.auto-combat").data()); break; - case Sensor::GM: strcpy_s(mode_buf, ContentBundle::GetInstance()->GetText("MFD.mode.ground").data()); break; - case Sensor::PST: strcpy_s(mode_buf, ContentBundle::GetInstance()->GetText("MFD.mode.passive").data()); break; - case Sensor::CST: strcpy_s(mode_buf, ContentBundle::GetInstance()->GetText("MFD.mode.combined").data()); break; - default: break; - } - - Rect mode_rect(scan_x+2, scan_y+2, 40, 12); - DrawMFDText(0, mode_buf, mode_rect, DT_LEFT); - - char range_txt[12]; - double beam_range = sensor->GetBeamRange() + 1; - if (beam_range >= 1e6) - sprintf_s(range_txt, "-%dM+", (int) (beam_range / 1e6)); - else - sprintf_s(range_txt, "-%3d+", (int) (beam_range / 1e3)); - - Rect range_rect(scan_x+2, scan_y+scan_r-12, 40, 12); - DrawMFDText(1, range_txt, range_rect, DT_LEFT); - - Rect disp_rect(scan_x+scan_r-41, scan_y+2, 40, 12); - DrawMFDText(2, mfd_mode, disp_rect, DT_RIGHT); - - Rect probe_rect(scan_x+scan_r-41, scan_y+scan_r-12, 40, 12); - - if (ship->GetProbeLauncher()) { - char probes[32]; - sprintf_s(probes, "%s %02d", ContentBundle::GetInstance()->GetText("MFD.probe").data(), ship->GetProbeLauncher()->Ammo()); - DrawMFDText(3, probes, probe_rect, DT_RIGHT); - } - else { - HideMFDText(3); - } - - if (Mouse::LButton() && !mouse_latch) { - mouse_latch = 1; - - if (mode_rect.Contains(Mouse::X(), Mouse::Y())) { - if (sensor->GetMode() < Sensor::PST) { - int sensor_mode = sensor->GetMode() + 1; - if (sensor_mode > Sensor::GM) - sensor_mode = Sensor::PAS; - - sensor->SetMode((Sensor::Mode) sensor_mode); - } - } - - else if (range_rect.Contains(Mouse::X(), Mouse::Y())) { - if (Mouse::X() > range_rect.x+range_rect.w/2) - sensor->IncreaseRange(); - else - sensor->DecreaseRange(); - } - - else if (disp_rect.Contains(Mouse::X(), Mouse::Y())) { - HUDView* hud = HUDView::GetInstance(); - if (hud) - hud->CycleMFDMode(index); - } - - else if (probe_rect.Contains(Mouse::X(), Mouse::Y())) { - ship->LaunchProbe(); - } - } -} - -// +--------------------------------------------------------------------+ - -// AZIMUTH-ELEVATION ANGULAR SCANNER - -void -MFD::DrawSensorMFD() -{ - int scan_r = rect.w; - int scan_x = cockpit_hud_texture ? (index*128) : rect.x; - int scan_y = cockpit_hud_texture ? 256 : rect.y; - int r = scan_r / 2; - - double xctr = (scan_r / 2.0) - 0.5; - double yctr = (scan_r / 2.0) + 0.5; - - Sensor* sensor = ship->GetSensor(); - if (!sensor) { - DrawMFDText(0, ContentBundle::GetInstance()->GetText("MFD.inactive").data(), rect, DT_CENTER); - return; - } - - int w = sprite->Width(); - int h = sprite->Height(); - - if (w < sprite->Frame()->Width()) - w += 2; - - if (h < sprite->Frame()->Height()) - h += 16; - - sprite->Reshape(w, h); - sprite->Show(); - - if (h < sprite->Frame()->Height()) - return; - - double sweep_scale = r / (PI/2); - - if (sensor->GetBeamLimit() > 90*DEGREES) - sweep_scale = (double) r / (90*DEGREES); - - int az = (int) (sensor->GetBeamLimit() * sweep_scale); - int el = az; - int xc = (int) (scan_x + xctr); - int yc = (int) (scan_y + yctr); - - if (mode == MFD_MODE_FOV) { - if (sensor->GetMode() < Sensor::GM) { - if (cockpit_hud_texture) - cockpit_hud_texture->DrawEllipse(xc-az, yc-el, xc+az, yc+el, hud_color); - else - window->DrawEllipse(xc-az, yc-el, xc+az, yc+el, hud_color); - } - } - else { - char az_txt[8]; - sprintf_s(az_txt, "%d", (int) (sensor->GetBeamLimit() / DEGREES)); - - Rect az_rect(scan_x+2, scan_y+scan_r-12, 32, 12); - DrawMFDText(1, az_txt, az_rect, DT_LEFT); - - az_rect.x = scan_x + (scan_r/2) - (az_rect.w/2); - DrawMFDText(2, "0", az_rect, DT_CENTER); - - az_rect.x = scan_x + scan_r - az_rect.w - 2; - DrawMFDText(3, az_txt, az_rect, DT_RIGHT); - } - - // draw next nav point: - Instruction* navpt = ship->GetNextNavPoint(); - if (navpt && navpt->Region() == ship->GetRegion()) { - const Camera* cam = &ship->Cam(); - - // translate: - Point pt = navpt->Location().OtherHand() - ship->Location(); - - // rotate: - double tx = pt * cam->vrt(); - double ty = pt * cam->vup(); - double tz = pt * cam->vpn(); - - if (tz > 1.0) { - // convert to spherical coords: - double rng = pt.length(); - double az = asin(fabs(tx) / rng); - double el = asin(fabs(ty) / rng); - - if (tx < 0) az = -az; - if (ty < 0) el = -el; - - if (fabs(az) < 90*DEGREES) { - az *= sweep_scale; - el *= sweep_scale; - - int x = (int) (r + az); - int y = (int) (r - el); - - // clip again: - if (x > 0 && x < scan_r && - y > 0 && y < scan_r) { - - // draw: - int xc = scan_x + x; - int yc = scan_y + y; - - if (cockpit_hud_texture) { - cockpit_hud_texture->DrawLine(xc-2, yc-2, xc+2, yc+2, Color::White); - cockpit_hud_texture->DrawLine(xc-2, yc+2, xc+2, yc-2, Color::White); - } - else { - window->DrawLine(xc-2, yc-2, xc+2, yc+2, Color::White); - window->DrawLine(xc-2, yc+2, xc+2, yc-2, Color::White); - } - } - } - } - } - - int num_contacts = ship->NumContacts(); - ListIter iter = ship->ContactList(); - - while (++iter) { - Contact* contact = iter.value(); - Ship* c_ship = contact->GetShip(); - double az, el, rng; - bool aft = false; - - if (c_ship == ship) continue; - - contact->GetBearing(ship, az, el, rng); - - // clip (is in-front): - if (fabs(az) < 90*DEGREES) { - az *= sweep_scale; - el *= sweep_scale; - } - - // rear anulus: - else { - double len = sqrt(az*az + el*el); - - if (len > 1e-6) { - az = r * az/len; - el = r * el/len; - } - else { - az = -r; - el = 0; - } - - aft = true; - } - - int x = (int) (r + az); - int y = (int) (r - el); - - // clip again: - if (x < 0 || x > scan_r) continue; - if (y < 0 || y > scan_r) continue; - - // draw: - Color mark = HUDView::MarkerColor(contact); - - if (aft) - mark = mark * 0.75; - - int xc = scan_x + x; - int yc = scan_y + y; - int size = 1; - - if (c_ship && c_ship == ship->GetTarget()) - size = 2; - - if (cockpit_hud_texture) - cockpit_hud_texture->FillRect(xc-size, yc-size, xc+size, yc+size, mark); - else - window->FillRect(xc-size, yc-size, xc+size, yc+size, mark); - - if (contact->Threat(ship)) { - if (c_ship) { - if (cockpit_hud_texture) - cockpit_hud_texture->DrawEllipse(xc-4, yc-4, xc+3, yc+3, mark); - else - window->DrawEllipse(xc-4, yc-4, xc+3, yc+3, mark); - } - else { - if (cockpit_hud_texture) { - cockpit_hud_texture->DrawLine(xc, yc-5, xc+5, yc, mark); - cockpit_hud_texture->DrawLine(xc+5, yc, xc, yc+5, mark); - cockpit_hud_texture->DrawLine(xc, yc+5, xc-5, yc, mark); - cockpit_hud_texture->DrawLine(xc-5, yc, xc, yc-5, mark); - } - else { - window->DrawLine(xc, yc-5, xc+5, yc, mark); - window->DrawLine(xc+5, yc, xc, yc+5, mark); - window->DrawLine(xc, yc+5, xc-5, yc, mark); - window->DrawLine(xc-5, yc, xc, yc-5, mark); - } - } - } - } - - DrawSensorLabels(ContentBundle::GetInstance()->GetText("MFD.mode.field-of-view").data()); -} - -// +--------------------------------------------------------------------+ - -// HORIZONTAL SITUATION DISPLAY - -void -MFD::DrawHSD() -{ - int scan_r = rect.w; - int scan_x = cockpit_hud_texture ? (index*128) : rect.x; - int scan_y = cockpit_hud_texture ? 256 : rect.y; - int r = scan_r / 2 - 4; - - double xctr = (scan_r / 2.0) - 0.5; - double yctr = (scan_r / 2.0) + 0.5; - - int xc = (int) xctr + scan_x; - int yc = (int) yctr + scan_y; - - Sensor* sensor = ship->GetSensor(); - if (!sensor) { - DrawMFDText(0, ContentBundle::GetInstance()->GetText("MFD.inactive").data(), rect, DT_CENTER); - return; - } - - int w = sprite->Width(); - int h = sprite->Height(); - - if (w < sprite->Frame()->Width()) - w += 2; - - if (h < sprite->Frame()->Height()) - h += 16; - - sprite->Reshape(w, h); - sprite->Show(); - - if (h < sprite->Frame()->Height()) - return; - - if (sensor->GetMode() < Sensor::PST) { - double s = sin(sensor->GetBeamLimit()); - double c = cos(sensor->GetBeamLimit()); - - int x0 = (int) (0.1*r*s); - int y0 = (int) (0.1*r*c); - int x1 = (int) (1.0*r*s); - int y1 = (int) (1.0*r*c); - - if (cockpit_hud_texture) { - cockpit_hud_texture->DrawLine(xc-x0, yc-y0, xc-x1, yc-y1, hud_color); - cockpit_hud_texture->DrawLine(xc+x0, yc-y0, xc+x1, yc-y1, hud_color); - } - else { - window->DrawLine(xc-x0, yc-y0, xc-x1, yc-y1, hud_color); - window->DrawLine(xc+x0, yc-y0, xc+x1, yc-y1, hud_color); - } - } - - double rscale = (double) r/(sensor->GetBeamRange()); - - Camera hsd_cam = ship->Cam(); - Point look = ship->Location() + ship->Heading() * 1000; - look.y = ship->Location().y; - - hsd_cam.LookAt(look); - - // draw tick marks on range rings: - for (int dir = 0; dir < 4; dir++) { - Point tick; - - switch (dir) { - case 0: tick = Point( 0, 0, 1000); break; - case 1: tick = Point( 1000, 0, 0); break; - case 2: tick = Point( 0, 0, -1000); break; - case 3: tick = Point(-1000, 0, 0); break; - } - - double tx = tick * hsd_cam.vrt(); - double tz = tick * hsd_cam.vpn(); - double az = asin(fabs(tx) / 1000); - - if (tx < 0) az = -az; - - if (tz < 0) - if (az < 0) az = -PI - az; - else az = PI - az; - - for (double range = 0.3; range < 1; range += 0.3) { - int x0 = (int) (sin(az) * r * range); - int y0 = (int) (cos(az) * r * range); - int x1 = (int) (sin(az) * r * (range + 0.1)); - int y1 = (int) (cos(az) * r * (range + 0.1)); - - if (cockpit_hud_texture) { - cockpit_hud_texture->DrawLine(xc+x0, yc-y0, xc+x1, yc-y1, hud_color); - } - else { - window->DrawLine(xc+x0, yc-y0, xc+x1, yc-y1, hud_color); - } - } - } - - // draw next nav point: - Instruction* navpt = ship->GetNextNavPoint(); - if (navpt && navpt->Region() == ship->GetRegion()) { - const Camera* cam = &hsd_cam; - - // translate: - Point pt = navpt->Location().OtherHand() - ship->Location(); - - // rotate: - double tx = pt * cam->vrt(); - double ty = pt * cam->vup(); - double tz = pt * cam->vpn(); - - // convert to spherical coords: - double rng = pt.length(); - double az = asin(fabs(tx) / rng); - - if (rng > sensor->GetBeamRange()) - rng = sensor->GetBeamRange(); - - if (tx < 0) - az = -az; - - if (tz < 0) - if (az < 0) - az = -PI - az; - else - az = PI - az; - - // draw: - int x = (int) (xc + sin(az) * rng * rscale); - int y = (int) (yc - cos(az) * rng * rscale); - - if (cockpit_hud_texture) { - cockpit_hud_texture->DrawLine(x-2, y-2, x+2, y+2, Color::White); - cockpit_hud_texture->DrawLine(x-2, y+2, x+2, y-2, Color::White); - } - else { - window->DrawLine(x-2, y-2, x+2, y+2, Color::White); - window->DrawLine(x-2, y+2, x+2, y-2, Color::White); - } - } - - // draw contact markers: - double limit = sensor->GetBeamRange(); - ListIter contact = ship->ContactList(); - - while (++contact) { - Ship* c_ship = contact->GetShip(); - if (c_ship == ship) continue; - - // translate: - Point targ_pt = contact->Location() - hsd_cam.Pos(); - - // rotate: - double tx = targ_pt * hsd_cam.vrt(); - double rg = contact->Range(ship, limit); - double true_range = targ_pt.length(); - double az = asin(fabs(tx) / true_range); - - // clip: - if (rg > limit || rg <= 0) - continue; - - if (tx < 0) - az = -az; - - if (!contact->InFront(ship)) - if (az < 0) - az = -PI - az; - else - az = PI - az; - - // draw: - int x = (int) (xc + sin(az) * rg * rscale); - int y = (int) (yc - cos(az) * rg * rscale); - int size = 2; - - // clip again: - if (x < scan_x || y < scan_y) - continue; - - if (c_ship && c_ship == ship->GetTarget()) - size = 3; - - Color mark = HUDView::MarkerColor(contact.value()); - if (cockpit_hud_texture) { - cockpit_hud_texture->FillRect(x-size, y-size, x+size, y+size, mark); - } - else { - window->FillRect(x-size, y-size, x+size, y+size, mark); - } - - if (contact->Threat(ship)) { - if (c_ship) { - if (cockpit_hud_texture) { - cockpit_hud_texture->DrawEllipse(x-4, y-4, x+3, y+3, mark); - } - else { - window->DrawEllipse(x-4, y-4, x+3, y+3, mark); - } - } - else { - if (cockpit_hud_texture) { - cockpit_hud_texture->DrawLine(x, y-5, x+5, y, mark); - cockpit_hud_texture->DrawLine(x+5, y, x, y+5, mark); - cockpit_hud_texture->DrawLine(x, y+5, x-5, y, mark); - cockpit_hud_texture->DrawLine(x-5, y, x, y-5, mark); - } - else { - window->DrawLine(x, y-5, x+5, y, mark); - window->DrawLine(x+5, y, x, y+5, mark); - window->DrawLine(x, y+5, x-5, y, mark); - window->DrawLine(x-5, y, x, y-5, mark); - } - } - } - } - - DrawSensorLabels(ContentBundle::GetInstance()->GetText("MFD.mode.horizontal").data()); -} - -// +--------------------------------------------------------------------+ - -// ELITE-STYLE 3D RADAR - -void -MFD::Draw3D() -{ - int scan_r = rect.w; - int scan_x = cockpit_hud_texture ? (index*128) : rect.x; - int scan_y = cockpit_hud_texture ? 256 : rect.y; - int r = scan_r / 2 - 4; - - double xctr = (scan_r / 2.0) - 0.5; - double yctr = (scan_r / 2.0) + 0.5; - - int xc = (int) xctr + scan_x; - int yc = (int) yctr + scan_y; - - Sensor* sensor = ship->GetSensor(); - if (!sensor) { - DrawMFDText(0, ContentBundle::GetInstance()->GetText("MFD.inactive").data(), rect, DT_CENTER); - return; - } - - int w = sprite->Width(); - int h = sprite->Height(); - - if (w < sprite->Frame()->Width()) - w += 2; - - if (h < sprite->Frame()->Height()) - h += 16; - - sprite->Reshape(w, h); - sprite->Show(); - - if (h < sprite->Frame()->Height()) - return; - - double rscale = (double) r/(sensor->GetBeamRange()); - - Camera hsd_cam = ship->Cam(); - - if (ship->IsStarship()) { - Point look = ship->Location() + ship->Heading() * 1000; - look.y = ship->Location().y; - - hsd_cam.LookAt(look); - } - - - // draw next nav point: - Instruction* navpt = ship->GetNextNavPoint(); - if (navpt && navpt->Region() == ship->GetRegion()) { - const Camera* cam = &hsd_cam; - - // translate: - Point pt = navpt->Location().OtherHand() - ship->Location(); - - // rotate: - double tx = pt * cam->vrt(); - double ty = pt * cam->vup(); - double tz = pt * cam->vpn(); - - // convert to cylindrical coords: - double rng = pt.length(); - double az = asin(fabs(tx) / rng); - - if (rng > sensor->GetBeamRange()) - rng = sensor->GetBeamRange(); - - if (tx < 0) - az = -az; - - if (tz < 0) { - if (az < 0) - az = -PI - az; - else - az = PI - az; - } - - // accentuate vertical: - if (ty > 10) - ty = log10(ty-9) * r/8; - - else if (ty < -10) - ty = -log10(9-ty) * r/8; - - else - ty = 0; - - // draw: - int x = (int) (sin(az) * rng * rscale); - int y = (int) (cos(az) * rng * rscale/2); - int z = (int) (ty); - - int x0 = xc+x; - int y0 = yc-y-z; - - if (cockpit_hud_texture) { - cockpit_hud_texture->DrawLine(x0-2, y0-2, x0+2, y0+2, Color::White); - cockpit_hud_texture->DrawLine(x0-2, y0+2, x0+2, y0-2, Color::White); - } - else { - window->DrawLine(x0-2, y0-2, x0+2, y0+2, Color::White); - window->DrawLine(x0-2, y0+2, x0+2, y0-2, Color::White); - } - - if (cockpit_hud_texture) { - if (z > 0) - cockpit_hud_texture->DrawLine(x0, y0+1, x0, y0+z, Color::White); - else if (z < 0) - cockpit_hud_texture->DrawLine(x0, y0+z, x0, y0-1, Color::White); - } - else { - if (z > 0) - window->DrawLine(x0, y0+1, x0, y0+z, Color::White); - else if (z < 0) - window->DrawLine(x0, y0+z, x0, y0-1, Color::White); - } - } - - - // draw contact markers: - double limit = sensor->GetBeamRange(); - ListIter contact = ship->ContactList(); - - while (++contact) { - Ship* c_ship = contact->GetShip(); - if (c_ship == ship) continue; - - // translate: - Point targ_pt = contact->Location() - hsd_cam.Pos(); - - // rotate: - double tx = targ_pt * hsd_cam.vrt(); - double ty = targ_pt * hsd_cam.vup(); - double rg = contact->Range(ship, limit); - double true_range = targ_pt.length(); - double az = asin(fabs(tx) / true_range); - - // clip: - if (rg > limit || rg <= 0) - continue; - - if (tx < 0) - az = -az; - - if (!contact->InFront(ship)) - if (az < 0) - az = -PI - az; - else - az = PI - az; - - // accentuate vertical: - ty *= 4; - - // draw: - int x = (int) (sin(az) * rg * rscale); - int y = (int) (cos(az) * rg * rscale/2); - int z = (int) (ty * rscale/2); - int size = 1; - - int x0 = xc+x; - int y0 = yc-y-z; - - if (c_ship && c_ship == ship->GetTarget()) - size = 2; - - Color mark = HUDView::MarkerColor(contact.value()); - - if (cockpit_hud_texture) { - cockpit_hud_texture->FillRect(x0-size, y0-size, x0+size, y0+size, mark); - - if (contact->Threat(ship)) { - if (c_ship) { - cockpit_hud_texture->DrawEllipse(x0-4, y0-4, x0+3, y0+3, mark); - } - else { - cockpit_hud_texture->DrawLine(x0, y0-5, x0+5, y0, mark); - cockpit_hud_texture->DrawLine(x0+5, y0, x0, y0+5, mark); - cockpit_hud_texture->DrawLine(x0, y0+5, x0-5, y0, mark); - cockpit_hud_texture->DrawLine(x0-5, y0, x0, y0-5, mark); - } - } - - if (z > 0) - cockpit_hud_texture->FillRect(x0-1, y0+size, x0, y0+z, mark); - else if (z < 0) - cockpit_hud_texture->FillRect(x0-1, y0+z, x0, y0-size, mark); - } - else { - window->FillRect(x0-size, y0-size, x0+size, y0+size, mark); - - if (contact->Threat(ship)) { - if (c_ship) { - window->DrawEllipse(x0-4, y0-4, x0+3, y0+3, mark); - } - else { - window->DrawLine(x0, y0-5, x0+5, y0, mark); - window->DrawLine(x0+5, y0, x0, y0+5, mark); - window->DrawLine(x0, y0+5, x0-5, y0, mark); - window->DrawLine(x0-5, y0, x0, y0-5, mark); - } - } - - if (z > 0) - window->FillRect(x0-1, y0+size, x0, y0+z, mark); - else if (z < 0) - window->FillRect(x0-1, y0+z, x0, y0-size, mark); - } - } - - DrawSensorLabels(ContentBundle::GetInstance()->GetText("MFD.mode.3D").data()); -} - -// +--------------------------------------------------------------------+ - -// GROUND MAP - -void -MFD::DrawMap() -{ - Rect text_rect(rect.x, rect.y, rect.w, 12); - DrawMFDText(0, ContentBundle::GetInstance()->GetText("MFD.mode.ground").data(), text_rect, DT_CENTER); -} - -// +--------------------------------------------------------------------+ - -void -MFD::DrawGauge(int x, int y, int percent) -{ - if (cockpit_hud_texture) { - x += this->index * 128 - this->rect.x; - y += 256 - this->rect.y; - cockpit_hud_texture->DrawRect(x, y, x+53, y+8, Color::DarkGray); - } - else { - window->DrawRect(x, y, x+53, y+8, Color::DarkGray); - } - - if (percent < 3) return; - if (percent > 100) percent = 100; - - percent /= 2; - - if (cockpit_hud_texture) - cockpit_hud_texture->FillRect(x+2, y+2, x+2+percent, y+7, Color::Gray); - else - window->FillRect(x+2, y+2, x+2+percent, y+7, Color::Gray); -} - -void -MFD::DrawGameMFD() -{ - if (lines < 10) lines++; - - char txt[64]; - Rect txt_rect(rect.x, rect.y, rect.w, 12); - - int t = 0; - - if (!HUDView::IsArcade() && HUDView::ShowFPS()) { - sprintf_s(txt, "FPS: %6.2f", Clock::GetInstance()->Rate()); - DrawMFDText(t++, txt, txt_rect, DT_LEFT); - txt_rect.y += 10; - - if (lines <= 1) return; - - Starshatter* game = Starshatter::GetInstance(); - sprintf_s(txt, "Polys: %d", game->GetPolyStats().npolys); - DrawMFDText(t++, txt, txt_rect, DT_LEFT); - txt_rect.y += 10; - } - - if (ship) { - DrawMFDText(t++, ship->Name(), txt_rect, DT_LEFT); - txt_rect.y += 10; - } - - if (lines <= 2) return; - - int hours = (Clock::GetInstance()->GameTime() / 3600000) ; - int minutes = (Clock::GetInstance()->GameTime() / 60000) % 60; - int seconds = (Clock::GetInstance()->GameTime() / 1000) % 60; - - if (ship) { - DWORD clock = ship->MissionClock(); - - hours = (clock / 3600000) ; - minutes = (clock / 60000) % 60; - seconds = (clock / 1000) % 60; - } - - if (static_cast(Clock::GetInstance()->TimeCompression()) != 1) - sprintf_s(txt, "%02d:%02d:%02d x%.1f", hours, minutes, seconds, Clock::GetInstance()->TimeCompression()); //-V576 - else - sprintf_s(txt, "%02d:%02d:%02d", hours, minutes, seconds); - - DrawMFDText(t++, txt, txt_rect, DT_LEFT); - txt_rect.y += 10; - - if (HUDView::IsArcade() || lines <= 3) return; - - DrawMFDText(t++, ship->GetRegion()->Name(), txt_rect, DT_LEFT); - txt_rect.y += 10; - - if (lines <= 4) return; - - if (ship) { - switch (ship->GetFlightPhase()) { - case Ship::DOCKED: DrawMFDText(t++, ContentBundle::GetInstance()->GetText("MFD.phase.DOCKED").data(), txt_rect, DT_LEFT); break; - case Ship::ALERT: DrawMFDText(t++, ContentBundle::GetInstance()->GetText("MFD.phase.ALERT").data(), txt_rect, DT_LEFT); break; - case Ship::LOCKED: DrawMFDText(t++, ContentBundle::GetInstance()->GetText("MFD.phase.LOCKED").data(), txt_rect, DT_LEFT); break; - case Ship::LAUNCH: DrawMFDText(t++, ContentBundle::GetInstance()->GetText("MFD.phase.LAUNCH").data(), txt_rect, DT_LEFT); break; - case Ship::TAKEOFF: DrawMFDText(t++, ContentBundle::GetInstance()->GetText("MFD.phase.TAKEOFF").data(), txt_rect, DT_LEFT); break; - case Ship::ACTIVE: DrawMFDText(t++, ContentBundle::GetInstance()->GetText("MFD.phase.ACTIVE").data(), txt_rect, DT_LEFT); break; - case Ship::APPROACH: DrawMFDText(t++, ContentBundle::GetInstance()->GetText("MFD.phase.APPROACH").data(), txt_rect, DT_LEFT); break; - case Ship::RECOVERY: DrawMFDText(t++, ContentBundle::GetInstance()->GetText("MFD.phase.RECOVERY").data(), txt_rect, DT_LEFT); break; - case Ship::DOCKING: DrawMFDText(t++, ContentBundle::GetInstance()->GetText("MFD.phase.DOCKING").data(), txt_rect, DT_LEFT); break; - } - } -} - -void -MFD::DrawStatusMFD() -{ - if (lines < 10) lines++; - - Rect status_rect(rect.x, rect.y, rect.w, 12); - int row = 0; - char txt[32]; - - if (ship) { - if (status_rect.y > 320 && !ship->IsStarship()) - status_rect.y += 32; - - Drive* drive = ship->GetDrive(); - if (drive) { - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.THRUST").data(), status_rect, DT_LEFT); - DrawGauge(status_rect.x+70, status_rect.y, (int) ship->Throttle()); - status_rect.y += 10; - } - - if (lines <= 1) return; - - if (ship->Reactors().size() > 0) { - PowerSource* reactor = ship->Reactors()[0]; - if (reactor) { - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.FUEL").data(), status_rect, DT_LEFT); - DrawGauge(status_rect.x+70, status_rect.y, reactor->Charge()); - status_rect.y += 10; - } - } - - if (lines <= 2) return; - - QuantumDrive* quantum_drive = ship->GetQuantumDrive(); - if (quantum_drive) { - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.QUANTUM").data(), status_rect, DT_LEFT); - DrawGauge(status_rect.x+70, status_rect.y, (int) quantum_drive->Charge()); - status_rect.y += 10; - } - - if (lines <= 3) return; - - double hull = ship->Integrity() / ship->Design()->integrity * 100; - int hull_status = System::CRITICAL; - - if (hull > 66) - hull_status = System::NOMINAL; - else if (hull > 33) - hull_status = System::DEGRADED; - - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.HULL").data(), status_rect, DT_LEFT); - DrawGauge(status_rect.x+70, status_rect.y, (int) hull); - status_rect.y += 10; - - if (lines <= 4) return; - - Shield* shield = ship->GetShield(); - if (shield) { - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.SHIELD").data(), status_rect, DT_LEFT); - DrawGauge(status_rect.x+70, status_rect.y, ship->ShieldStrength()); - status_rect.y += 10; - } - - if (lines <= 5) return; - - Weapon* primary = ship->GetPrimary(); - if (primary) { - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.GUNS").data(), status_rect, DT_LEFT); - DrawGauge(status_rect.x+70, status_rect.y, primary->Charge()); - status_rect.y += 10; - } - - if (lines <= 6) return; - - if (HUDView::IsArcade()) { - for (int i = 0; i < ship->Weapons().size() && i < 4; i++) { - WeaponGroup* w = ship->Weapons().at(i); - - if (w->IsMissile()) { - char ammo[8]; - - if (ship->GetSecondaryGroup() == w) - sprintf_s(ammo, "%d *", w->Ammo()); - else - sprintf_s(ammo, "%d", w->Ammo()); - - DrawMFDText(row++, (const char*) w->GetDesign()->name, status_rect, DT_LEFT); - status_rect.x += 70; - DrawMFDText(row++, ammo, status_rect, DT_LEFT); - status_rect.x -= 70; - status_rect.y += 10; - } - } - - if (ship->GetDecoy()) { - char ammo[8]; - sprintf_s(ammo, "%d", ship->GetDecoy()->Ammo()); - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.DECOY").data(), status_rect, DT_LEFT); - status_rect.x += 70; - DrawMFDText(row++, ammo, status_rect, DT_LEFT); - status_rect.x -= 70; - status_rect.y += 10; - } - - if (NetGame::GetInstance()) { - char lives[8]; - sprintf_s(lives, "%d", ship->RespawnCount() + 1); - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.LIVES").data(), status_rect, DT_LEFT); - status_rect.x += 70; - DrawMFDText(row++, lives, status_rect, DT_LEFT); - status_rect.x -= 70; - status_rect.y += 10; - } - - return; - } - - Sensor* sensor = ship->GetSensor(); - if (sensor) { - if (ship->GetFlightPhase() != Ship::ACTIVE) { - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.SENSOR").data(), status_rect, DT_LEFT); - status_rect.x += 70; - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.OFFLINE").data(), status_rect, DT_LEFT); - status_rect.x -= 70; - status_rect.y += 10; - } - - else { - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.EMCON").data(), status_rect, DT_LEFT); - status_rect.x += 70; - - sprintf_s(txt, "%s %d", ContentBundle::GetInstance()->GetText("MFD.status.MODE").data(), ship->GetEMCON()); - - if (!sensor->IsPowerOn() || sensor->GetEnergy() == 0) { - if (!Game::GetInstance()->Paused() && (Clock::GetInstance()->RealTime()/1000) & 2) - strcpy_s(txt, ContentBundle::GetInstance()->GetText("MFD.status.SENSOR-OFF").data()); - } - - DrawMFDText(row++, txt, status_rect, DT_LEFT); - status_rect.x -= 70; - status_rect.y += 10; - } - } - - if (lines <= 7) return; - - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.SYSTEMS").data(), status_rect, DT_LEFT); - status_rect.x += 70; - DrawMFDText(row++, ship->GetDirectorInfo(), status_rect, DT_LEFT); - - if (NetGame::GetInstance()) { - char lives[8]; - sprintf_s(lives, "%d", ship->RespawnCount() + 1); - status_rect.x -= 70; - status_rect.y += 10; - DrawMFDText(row++, ContentBundle::GetInstance()->GetText("MFD.status.LIVES").data(), status_rect, DT_LEFT); - status_rect.x += 70; - DrawMFDText(row++, lives, status_rect, DT_LEFT); - } - } -} - -// +--------------------------------------------------------------------+ - -void -MFD::SetStatusColor(int status) -{ - Color status_color; - - switch (status) { - default: - case System::NOMINAL: status_color = txt_color; break; - case System::DEGRADED: status_color = Color(255,255, 0); break; - case System::CRITICAL: status_color = Color(255, 0, 0); break; - case System::DESTROYED: status_color = Color( 0, 0, 0); break; - } -} - -// +--------------------------------------------------------------------+ - -bool MFD::IsMouseLatched() const -{ - return mouse_in; -} - -// +--------------------------------------------------------------------+ - -void MFD::DrawMFDText(int index, const char* txt, Rect& txt_rect, int align, int status) -{ - if (index >= MFD::TXT_LAST) { - Print("MFD DrawMFDText() invalid mfd_text index %d '%s'\n", index, txt); - } - else { - HUDText& mt = mfd_text[index]; - Color mc = mt.color; - - switch (status) { - default: - case System::NOMINAL: mc = txt_color; break; - case System::DEGRADED: mc = Color(255,255, 0); break; - case System::CRITICAL: mc = Color(255, 0, 0); break; - case System::DESTROYED: mc = Color( 0, 0, 0); break; - } - - char txt_buf[256]; - int n = strlen(txt); - - if (n > 250) n = 250; - int i; - - for (i = 0; i < n; i++) { - if (islower(txt[i])) - txt_buf[i] = toupper(txt[i]); - else - txt_buf[i] = txt[i]; - } - - txt_buf[i] = 0; - - - if (cockpit_hud_texture) { - Rect hud_rect(txt_rect); - - hud_rect.x = txt_rect.x + this->index * 128 - this->rect.x; - hud_rect.y = txt_rect.y + 256 - this->rect.y; - - mt.font->SetColor(mc); - mt.font->DrawText(txt_buf, 0, hud_rect, align | DT_SINGLELINE, cockpit_hud_texture); - mt.rect = rect; - mt.hidden = false; - } - else { - if (txt_rect.Contains(Mouse::X(), Mouse::Y())) - mc = Color::White; - - mt.font->SetColor(mc); - mt.font->DrawText(txt_buf, 0, txt_rect, align | DT_SINGLELINE); - mt.rect = rect; - mt.hidden = false; - } - - } -} - -void MFD::HideMFDText(int index) -{ - if (index >= MFD::TXT_LAST) - Print("MFD HideMFDText() invalid mfd_text index %d\n", index); - else - mfd_text[index].hidden = true; -} - - - - diff --git a/Stars45/Mfd.h b/Stars45/Mfd.h deleted file mode 100644 index 66bfe85..0000000 --- a/Stars45/Mfd.h +++ /dev/null @@ -1,103 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Class for all Multi Function Displays -*/ - -#ifndef MFD_h -#define MFD_h - -#include "Types.h" -#include "Geometry.h" -#include "Color.h" -#include "HUDView.h" - -// +--------------------------------------------------------------------+ - -class Contact; -class Ship; -class Sprite; -class Window; - -// +--------------------------------------------------------------------+ - -class MFD -{ -public: - enum Modes { MFD_MODE_OFF, MFD_MODE_GAME, MFD_MODE_SHIP, - MFD_MODE_FOV, /*MFD_MODE_FWD, MFD_MODE_MAP,*/ - MFD_MODE_HSD, MFD_MODE_3D - }; - - MFD(Window* c, int index); - virtual ~MFD(); - - int operator == (const MFD& that) const { return this == &that; } - - static void Initialize(); - static void Close(); - static void SetColor(Color c); - - // Operations: - virtual void Draw(); - virtual void DrawGameMFD(); - virtual void DrawStatusMFD(); - virtual void DrawSensorMFD(); - virtual void DrawHSD(); - virtual void Draw3D(); - virtual void DrawSensorLabels(const char* mfd_mode); - virtual void DrawMap(); - virtual void DrawGauge(int x, int y, int percent); - virtual void SetStatusColor(int status); - - virtual void SetWindow(Window* w) { window = w; } - virtual Window* GetWindow() { return window; } - virtual void SetRect(const Rect& r); - virtual const Rect& GetRect() const { return rect; } - virtual void SetMode(int m); - virtual int GetMode() const { return mode; } - virtual Sprite* GetSprite() { return sprite; } - - virtual void SetShip(Ship* s) { ship = s; } - virtual Ship* GetShip() { return ship; } - - virtual void Show(); - virtual void Hide(); - - virtual void UseCameraView(CameraView* v); - void DrawMFDText(int index, const char* txt, Rect& r, int align, int status=-1); - void HideMFDText(int index); - void SetText3DColor(Color c); - void SetCockpitHUDTexture(Bitmap* bmp) { cockpit_hud_texture = bmp; } - - bool IsMouseLatched() const; - -protected: - - enum { TXT_LAST=20 }; - - Window* window; - Rect rect; - int index; - int mode; - int lines; - Sprite* sprite; - bool hidden; - Ship* ship; - HUDText mfd_text[TXT_LAST]; - CameraView* camview; - Bitmap* cockpit_hud_texture; - - int mouse_latch; - bool mouse_in; -}; - -#endif // MFD_h - diff --git a/Stars45/Mission.cpp b/Stars45/Mission.cpp deleted file mode 100644 index 64d5948..0000000 --- a/Stars45/Mission.cpp +++ /dev/null @@ -1,2160 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission classes -*/ - -#include "Mission.h" -#include "MissionEvent.h" -#include "StarSystem.h" -#include "Galaxy.h" -#include "Starshatter.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Element.h" -#include "Instruction.h" -#include "WeaponDesign.h" -#include "Sim.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "ParseUtil.h" -#include "FormatUtil.h" -#include "Random.h" -#include "Skin.h" - -// +--------------------------------------------------------------------+ - -Mission::Mission(int identity, const char* fname, const char* pname) -: id(identity), type(0), team(1), ok(false), active(false), complete(false), -star_system(0), start(33 * 3600), stardate(0), target(0), ward(0), -current(0), degrees(false) -{ - objective = ContentBundle::GetInstance()->GetText("Mission.unspecified"); - sitrep = ContentBundle::GetInstance()->GetText("Mission.unknown"); - - if (fname) - strcpy_s(filename, fname); - else - ZeroMemory(filename, sizeof(filename)); - - if (pname) - strcpy_s(path, pname); - else - strcpy_s(path, "Missions/"); -} - -Mission::~Mission() -{ - ::Print("Mission::~Mission() id = %d name = '%s'\n", id, name.data()); - elements.destroy(); - events.destroy(); -} - -// +--------------------------------------------------------------------+ - -const char* -Mission::Subtitles() const -{ - return subtitles; -} - -// +--------------------------------------------------------------------+ - -void -Mission::AddElement(MissionElement* elem) -{ - if (elem) - elements.append(elem); -} - -// +--------------------------------------------------------------------+ - -MissionElement* -Mission::FindElement(const char* name) -{ - ListIter iter = elements; - while (++iter) { - MissionElement* elem = iter.value(); - - if (elem->Name() == name) - return elem; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Mission::IncreaseElemPriority(int elem_index) -{ - if (elem_index > 0 && elem_index < elements.size()) { - MissionElement* elem1 = elements.at(elem_index-1); - MissionElement* elem2 = elements.at(elem_index); - - elements.at(elem_index-1) = elem2; - elements.at(elem_index) = elem1; - } -} - -void -Mission::DecreaseElemPriority(int elem_index) -{ - if (elem_index >= 0 && elem_index < elements.size()-1) { - MissionElement* elem1 = elements.at(elem_index); - MissionElement* elem2 = elements.at(elem_index+1); - - elements.at(elem_index) = elem2; - elements.at(elem_index+1) = elem1; - } -} - -// +--------------------------------------------------------------------+ - -void -Mission::IncreaseEventPriority(int event_index) -{ - if (event_index > 0 && event_index < events.size()) { - MissionEvent* event1 = events.at(event_index-1); - MissionEvent* event2 = events.at(event_index); - - events.at(event_index-1) = event2; - events.at(event_index) = event1; - } -} - -void -Mission::DecreaseEventPriority(int event_index) -{ - if (event_index >= 0 && event_index < events.size()-1) { - MissionEvent* event1 = events.at(event_index); - MissionEvent* event2 = events.at(event_index+1); - - events.at(event_index) = event2; - events.at(event_index+1) = event1; - } -} - -// +--------------------------------------------------------------------+ - -void -Mission::SetStarSystem(StarSystem* s) -{ - if (star_system != s) { - star_system = s; - - if (!system_list.contains(s)) - system_list.append(s); - } -} - -void -Mission::ClearSystemList() -{ - star_system = 0; - system_list.clear(); -} - -// +--------------------------------------------------------------------+ - -void -Mission::SetPlayer(MissionElement* player_element) -{ - ListIter elem = elements; - while (++elem) { - MissionElement* element = elem.value(); - if (element == player_element) - element->player = 1; - else - element->player = 0; - } -} - -MissionElement* -Mission::GetPlayer() -{ - MissionElement* p = 0; - - ListIter elem = elements; - while (++elem) { - if (elem->player > 0) - p = elem.value(); - } - - return p; -} - -// +--------------------------------------------------------------------+ - -MissionEvent* -Mission::FindEvent(int event_type) const -{ - Mission* pThis = (Mission*) this; - ListIter iter = pThis->events; - while (++iter) { - MissionEvent* event = iter.value(); - - if (event->Event() == event_type) - return event; - } - - return 0; -} - -void -Mission::AddEvent(MissionEvent* event) -{ - if (event) - events.append(event); -} - -// +--------------------------------------------------------------------+ - -bool -Mission::Load(const char* fname, const char* pname) -{ - ok = false; - - if (fname) - strcpy_s(filename, fname); - - if (pname) - strcpy_s(path, pname); - - if (!filename[0]) { - Print("\nCan't Load Mission, script unspecified.\n"); - return ok; - } - - // wipe existing mission before attempting to load... - elements.destroy(); - events.destroy(); - - Print("\nLoad Mission: '%s'\n", filename); - - DataLoader* loader = DataLoader::GetLoader(); - bool old_fs = loader->IsFileSystemEnabled(); - BYTE* block = 0; - - loader->UseFileSystem(true); - loader->SetDataPath(path); - loader->LoadBuffer(filename, block, true); - loader->SetDataPath(0); - loader->UseFileSystem(old_fs); - - ok = ParseMission((const char*) block); - - loader->ReleaseBuffer(block); - Print("Mission Loaded.\n\n"); - - if (ok) - Validate(); - - return ok; -} - -// +--------------------------------------------------------------------+ - -bool -Mission::ParseMission(const char* block) -{ - Parser parser(new BlockReader(block)); - Term* term = parser.ParseTerm(); - char err[256]; - - if (!term) { - sprintf_s(err, "ERROR: could not parse '%s'\n", filename); - AddError(err); - return ok; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "MISSION") { - sprintf_s(err, "ERROR: invalid mission file '%s'\n", filename); - AddError(err); - term->print(10); - return ok; - } - } - - ok = true; - - char target_name[256]; - char ward_name[256]; - - target_name[0] = 0; - ward_name[0] = 0; - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - Text defname = def->name()->value(); - defname.setSensitive(false); - - if (defname == "name") { - GetDefText(name, def, filename); - name = ContentBundle::GetInstance()->GetText(name); - } - - else if (defname == "desc") { - GetDefText(desc, def, filename); - if (desc.length() > 0 && desc.length() < 32) - desc = ContentBundle::GetInstance()->GetText(desc); - } - - else if (defname == "type") { - char typestr[64]; - GetDefText(typestr, def, filename); - type = TypeFromName(typestr); - } - - else if (defname == "system") { - char sysname[64]; - GetDefText(sysname, def, filename); - - Galaxy* galaxy = Galaxy::GetInstance(); - - if (galaxy) { - SetStarSystem(galaxy->GetSystem(sysname)); - } - } - - else if (defname == "degrees") - GetDefBool(degrees, def, filename); - - else if (defname == "region") - GetDefText(region, def, filename); - - else if (defname == "objective") { - GetDefText(objective, def, filename); - if (objective.length() > 0 && objective.length() < 32) - objective = ContentBundle::GetInstance()->GetText(objective); - } - - else if (defname == "sitrep") { - GetDefText(sitrep, def, filename); - if (sitrep.length() > 0 && sitrep.length() < 32) - sitrep = ContentBundle::GetInstance()->GetText(sitrep); - } - - else if (defname == "subtitles") { - Text subtitles_path; - DataLoader* loader = DataLoader::GetLoader(); - BYTE* block = 0; - - GetDefText(subtitles_path, def, filename); - loader->SetDataPath(0); - loader->LoadBuffer(subtitles_path, block, true); - - subtitles = Text("\n") + (const char*) block; - - loader->ReleaseBuffer(block); - } - - else if (defname == "start") - GetDefTime(start, def, filename); - - else if (defname == "stardate") - GetDefNumber(stardate, def, filename); - - else if (defname == "team") - GetDefNumber(team, def, filename); - - else if (defname == "target") - GetDefText(target_name, def, filename); - - else if (defname == "ward") - GetDefText(ward_name, def, filename); - - else if ((defname == "element") || - (defname == "ship") || - (defname == "station")) { - - if (!def->term() || !def->term()->isStruct()) { - sprintf_s(err, "ERROR: element struct missing in '%s'\n", filename); - AddError(err); - } - else { - TermStruct* val = def->term()->isStruct(); - MissionElement* elem = ParseElement(val); - AddElement(elem); - } - } - - else if (defname == "event") { - if (!def->term() || !def->term()->isStruct()) { - sprintf_s(err, "ERROR: event struct missing in '%s'\n", filename); - AddError(err); - } - else { - TermStruct* val = def->term()->isStruct(); - MissionEvent* event = ParseEvent(val); - AddEvent(event); - } - } - } // def - } // term - } - while (term); - - if (ok) { - if (target_name[0]) - target = FindElement(target_name); - - if (ward_name[0]) - ward = FindElement(ward_name); - } - - return ok; -} - -// +--------------------------------------------------------------------+ - -bool -Mission::Save() -{ - Validate(); - - if (!filename[0] || !path[0]) { - AddError(ContentBundle::GetInstance()->GetText("Mission.error.no-file")); - return ok; - } - - Text content = Serialize(); - - if (content.length() < 8) { - AddError(ContentBundle::GetInstance()->GetText("Mission.error.no-serial")); - return ok; - } - - if (!_stricmp(path, "mods/missions/")) { - CreateDirectory("Mods", 0); - CreateDirectory("Mods/Missions", 0); - } - - else if (!_stricmp(path, "multiplayer/")) { - CreateDirectory("Multiplayer", 0); - } - - char fname[256]; - sprintf_s(fname, "%s%s", path, filename); - FILE* f; - fopen_s(&f, fname, "wb"); - if (f) { - fwrite(content.data(), content.length(), 1, f); - fclose(f); - } - - return ok; -} - -// +--------------------------------------------------------------------+ - -void -Mission::Validate() -{ - char err[256]; - - ok = true; - - if (elements.isEmpty()) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.no-elem").data(), filename); - AddError(err); - } - else { - bool found_player = false; - - for (int i = 0; i < elements.size(); i++) { - MissionElement* elem = elements.at(i); - - if (elem->Name().length() < 1) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.unnamed-elem").data(), filename); - AddError(err); - } - - if (elem->Player() > 0) { - if (!found_player) { - found_player = true; - - if (elem->Region() != GetRegion()) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.wrong-sector").data(), - elem->Name().data(), - GetRegion()); - AddError(err); - } - } - else { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.extra-player").data(), - elem->Name().data(), - filename); - AddError(err); - } - } - } - - if (!found_player) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.no-player").data(), filename); - AddError(err); - } - } -} - -void -Mission::AddError(Text err) -{ - ::Print(err); - errmsg += err; - - ok = false; -} - -// +--------------------------------------------------------------------+ - -#define MSN_CHECK(x) if (!_stricmp(n, #x)) result = Mission::x; - -int -Mission::TypeFromName(const char* n) -{ - int result = -1; - - MSN_CHECK(PATROL) - else MSN_CHECK(SWEEP) - else MSN_CHECK(INTERCEPT) - else MSN_CHECK(AIR_PATROL) - else MSN_CHECK(AIR_SWEEP) - else MSN_CHECK(AIR_INTERCEPT) - else MSN_CHECK(STRIKE) - else MSN_CHECK(ASSAULT) - else MSN_CHECK(DEFEND) - else MSN_CHECK(ESCORT) - else MSN_CHECK(ESCORT_FREIGHT) - else MSN_CHECK(ESCORT_SHUTTLE) - else MSN_CHECK(ESCORT_STRIKE) - else MSN_CHECK(INTEL) - else MSN_CHECK(SCOUT) - else MSN_CHECK(RECON) - else MSN_CHECK(BLOCKADE) - else MSN_CHECK(FLEET) - else MSN_CHECK(BOMBARDMENT) - else MSN_CHECK(FLIGHT_OPS) - else MSN_CHECK(TRANSPORT) - else MSN_CHECK(CARGO) - else MSN_CHECK(TRAINING) - else MSN_CHECK(OTHER) - - if (result < PATROL) { - for (int i = PATROL; i <= OTHER && result < PATROL; i++) { - if (!_stricmp(n, RoleName(i))) { - result = i; - } - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -static int elem_id = 351; - -MissionElement* -Mission::ParseElement(TermStruct* val) -{ - Text design; - Text skin_name; - Text role_name; - int deck = 1; - char err[256]; - - MissionElement* element = new MissionElement(); - element->rgn_name = region; - element->elem_id = elem_id++; - - current = element; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") - GetDefText(element->name, pdef, filename); - - else if (defname == "carrier") - GetDefText(element->carrier, pdef, filename); - - else if (defname == "commander") - GetDefText(element->commander, pdef, filename); - - else if (defname == "squadron") - GetDefText(element->squadron, pdef, filename); - - else if (defname == "path") - GetDefText(element->path, pdef, filename); - - else if (defname == "design") { - GetDefText(design, pdef, filename); - element->design = ShipDesign::Get(design, element->path); - - if (!element->design) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.unknown-ship").data(), design.data(), filename); - AddError(err); - } - } - - else if (defname == "skin") { - if (!element->design) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.out-of-order").data(), filename); - AddError(err); - } - - else if (pdef->term()->isText()) { - GetDefText(skin_name, pdef, filename); - element->skin = element->design->FindSkin(skin_name); - } - - else if (pdef->term()->isStruct()) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.bad-skin").data(), filename); - AddError(err); - } - } - - else if (defname == "mission") { - GetDefText(role_name, pdef, filename); - element->mission_role = TypeFromName(role_name); - } - - else if (defname == "intel") { - GetDefText(role_name, pdef, filename); - element->intel = Intel::IntelFromName(role_name); - } - - else if (defname == "loc") { - Vec3 loc; - GetDefVec(loc, pdef, filename); - element->SetLocation(loc); - } - - else if (defname == "rloc") { - if (pdef->term()->isStruct()) { - RLoc* rloc = ParseRLoc(pdef->term()->isStruct()); - element->SetRLoc(*rloc); - delete rloc; - } - } - - else if (defname.indexOf("head") == 0) { - if (pdef->term()->isArray()) { - Vec3 head; - GetDefVec(head, pdef, filename); - if (degrees) head.z *= (float) DEGREES; - element->heading = head.z; - } - else if (pdef->term()->isNumber()) { - double heading = 0; - GetDefNumber(heading, pdef, filename); - if (degrees) heading *= DEGREES; - element->heading = heading; - } - } - - else if (defname == "region" || defname == "rgn") - GetDefText(element->rgn_name, pdef, filename); - - else if (defname == "iff") - GetDefNumber(element->IFF_code, pdef, filename); - - else if (defname == "count") - GetDefNumber(element->count, pdef, filename); - - else if (defname == "maint_count") - GetDefNumber(element->maint_count, pdef, filename); - - else if (defname == "dead_count") - GetDefNumber(element->dead_count, pdef, filename); - - else if (defname == "player") - GetDefNumber(element->player, pdef, filename); - - else if (defname == "alert") - GetDefBool(element->alert, pdef, filename); - - else if (defname == "playable") - GetDefBool(element->playable, pdef, filename); - - else if (defname == "rogue") - GetDefBool(element->rogue, pdef, filename); - - else if (defname == "invulnerable") - GetDefBool(element->invulnerable, pdef, filename); - - else if (defname == "command_ai") - GetDefNumber(element->command_ai, pdef, filename); - - else if (defname.indexOf("respawn") == 0) - GetDefNumber(element->respawns, pdef, filename); - - else if (defname.indexOf("hold") == 0) - GetDefNumber(element->hold_time, pdef, filename); - - else if (defname.indexOf("zone") == 0) { - if (pdef->term() && pdef->term()->isBool()) { - bool locked = false; - GetDefBool(locked, pdef, filename); - element->zone_lock = locked; - } - else { - GetDefNumber(element->zone_lock, pdef, filename); - } - } - - else if (defname == "objective") { - if (!pdef->term() || !pdef->term()->isStruct()) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.no-objective").data(), element->name.data(), filename); - AddError(err); - } - else { - TermStruct* val = pdef->term()->isStruct(); - Instruction* obj = ParseInstruction(val, element); - element->objectives.append(obj); - } - } - - else if (defname == "instr") { - Text* obj = new Text; - if (GetDefText(*obj, pdef, filename)) - element->instructions.append(obj); - else - delete obj; - } - - else if (defname == "ship") { - if (!pdef->term() || !pdef->term()->isStruct()) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.no-ship").data(), element->name.data(), filename); - AddError(err); - } - else { - TermStruct* val = pdef->term()->isStruct(); - MissionShip* s = ParseShip(val, element); - element->ships.append(s); - - if (s->Integrity() < 0 && element->design) - s->SetIntegrity(element->design->integrity); - } - } - - else if (defname == "order" || defname == "navpt") { - if (!pdef->term() || !pdef->term()->isStruct()) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.no-navpt").data(), element->name.data(), filename); - AddError(err); - } - else { - TermStruct* val = pdef->term()->isStruct(); - Instruction* npt = ParseInstruction(val, element); - element->navlist.append(npt); - } - } - - else if (defname == "loadout") { - if (!pdef->term() || !pdef->term()->isStruct()) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.no-loadout").data(), element->name.data(), filename); - AddError(err); - } - else { - TermStruct* val = pdef->term()->isStruct(); - ParseLoadout(val, element); - } - } - } - } - - if (element->name.length() < 1) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.unnamed-elem").data(), filename); - AddError(err); - } - - else if (element->design == 0) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.unknown-ship").data(), element->name.data(), filename); - AddError(err); - } - - current = 0; - - return element; -} - -MissionEvent* -Mission::ParseEvent(TermStruct* val) -{ - MissionEvent* event = new MissionEvent; - Text event_name; - Text trigger_name; - static int event_id = 1; - static double event_time = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "event") { - GetDefText(event_name, pdef, filename); - event->event = MissionEvent::EventForName(event_name); - } - - else if (defname == "trigger") { - GetDefText(trigger_name, pdef, filename); - event->trigger = MissionEvent::TriggerForName(trigger_name); - } - - else if (defname == "id") - GetDefNumber(event_id, pdef, filename); - - else if (defname == "time") - GetDefNumber(event_time, pdef, filename); - - else if (defname == "delay") - GetDefNumber(event->delay, pdef, filename); - - else if (defname == "event_param" || defname == "param" || defname == "color") { - ZeroMemory(event->event_param, sizeof(event->event_param)); - - if (pdef->term()->isNumber()) { - GetDefNumber(event->event_param[0], pdef, filename); - event->event_nparams = 1; - } - - else if (pdef->term()->isArray()) { - std::vector plist; - GetDefArray(plist, pdef, filename); - - for (int i = 0; i < 10 && i < (int)plist.size(); i++) { - float f = plist[i]; - event->event_param[i] = (int) f; - event->event_nparams = i + 1; - } - } - } - - else if (defname == "trigger_param") { - ZeroMemory(event->trigger_param, sizeof(event->trigger_param)); - - if (pdef->term()->isNumber()) { - GetDefNumber(event->trigger_param[0], pdef, filename); - event->trigger_nparams = 1; - } - - else if (pdef->term()->isArray()) { - std::vector plist; - GetDefArray(plist, pdef, filename); - - for (int i = 0; i < 10 && i < (int)plist.size(); i++) { - float f = plist[i]; - event->trigger_param[i] = (int) f; - event->trigger_nparams = i + 1; - } - } - } - - else if (defname == "event_ship" || defname == "ship") - GetDefText(event->event_ship, pdef, filename); - - else if (defname == "event_source" || defname == "source" || defname == "font") - GetDefText(event->event_source, pdef, filename); - - else if (defname == "event_target" || defname == "target" || defname == "image") - GetDefText(event->event_target, pdef, filename); - - else if (defname == "event_message" || defname == "message") { - Text raw_msg; - GetDefText(raw_msg, pdef, filename); - raw_msg = ContentBundle::GetInstance()->GetText(raw_msg); - event->event_message = FormatTextEscape(raw_msg); - } - - else if (defname == "event_chance" || defname == "chance") - GetDefNumber(event->event_chance, pdef, filename); - - else if (defname == "event_sound" || defname == "sound") - GetDefText(event->event_sound, pdef, filename); - - else if (defname == "loc" || defname == "vec" || defname == "fade") - GetDefVec(event->event_point, pdef, filename); - - else if (defname == "rect") - GetDefRect(event->event_rect, pdef, filename); - - else if (defname == "trigger_ship") - GetDefText(event->trigger_ship, pdef, filename); - - else if (defname == "trigger_target") - GetDefText(event->trigger_target, pdef, filename); - } - } - - event->id = event_id++; - event->time = event_time; - return event; -} - -MissionShip* -Mission::ParseShip(TermStruct* val, MissionElement* element) -{ - MissionShip* msn_ship = new MissionShip; - - Text name; - Text skin_name; - Text regnum; - Text region; - char err[256]; - Vec3 loc(-1.0e9f, -1.0e9f, -1.0e9f); - Vec3 vel(-1.0e9f, -1.0e9f, -1.0e9f); - int respawns = -1; - double heading = -1e9; - double integrity = -1; - int ammo[16]; - int fuel[4]; - int i; - - for (i = 0; i < 16; i++) - ammo[i] = -10; - - for (i = 0; i < 4; i++) - fuel[i] = -10; - - for (i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") - GetDefText(name, pdef, filename); - - else if (defname == "skin") { - if (!element || !element->design) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.out-of-order").data(), filename); - AddError(err); - } - - else if (pdef->term()->isText()) { - GetDefText(skin_name, pdef, filename); - msn_ship->skin = element->design->FindSkin(skin_name); - } - - else if (pdef->term()->isStruct()) { - sprintf_s(err, ContentBundle::GetInstance()->GetText("Mission.error.bad-skin").data(), filename); - AddError(err); - } - } - - else if (defname == "regnum") - GetDefText(regnum, pdef, filename); - - else if (defname == "region") - GetDefText(region, pdef, filename); - - else if (defname == "loc") - GetDefVec(loc, pdef, filename); - - else if (defname == "velocity") - GetDefVec(vel, pdef, filename); - - else if (defname == "respawns") - GetDefNumber(respawns, pdef, filename); - - else if (defname == "heading") { - if (pdef->term()->isArray()) { - Vec3 h; - GetDefVec(h, pdef, filename); - if (degrees) h.z *= (float) DEGREES; - heading = h.z; - } - else if (pdef->term()->isNumber()) { - double h = 0; - GetDefNumber(h, pdef, filename); - if (degrees) h *= DEGREES; - heading = h; - } - } - - else if (defname == "integrity") - GetDefNumber(integrity, pdef, filename); - - else if (defname == "ammo") - GetDefArray(ammo, 16, pdef, filename); - - else if (defname == "fuel") - GetDefArray(fuel, 4, pdef, filename); - } - } - - msn_ship->SetName(name); - msn_ship->SetRegNum(regnum); - msn_ship->SetRegion(region); - msn_ship->SetIntegrity(integrity); - - if (loc.x > -1e9) - msn_ship->SetLocation(loc); - - if (vel.x > -1e9) - msn_ship->SetVelocity(vel); - - if (respawns > -1) - msn_ship->SetRespawns(respawns); - - if (heading > -1e9) - msn_ship->SetHeading(heading); - - if (ammo[0] > -10) - msn_ship->SetAmmo(ammo); - - if (fuel[0] > -10) - msn_ship->SetFuel(fuel); - - return msn_ship; -} - -Instruction* -Mission::ParseInstruction(TermStruct* val, MissionElement* element) -{ - int order = Instruction::VECTOR; - int status = Instruction::PENDING; - int formation = 0; - int speed = 0; - int priority = 1; - int farcast = 0; - int hold = 0; - int emcon = 0; - Vec3 loc(0,0,0); - RLoc* rloc = 0; - Text order_name; - Text status_name; - Text order_rgn_name; - Text tgt_name; - Text tgt_desc; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "cmd") { - GetDefText(order_name, pdef, filename); - - for (int cmd = 0; cmd < Instruction::NUM_ACTIONS; cmd++) - if (!_stricmp(order_name, Instruction::ActionName(cmd))) - order = cmd; - } - - else if (defname == "status") { - GetDefText(status_name, pdef, filename); - - for (int n = 0; n < Instruction::NUM_STATUS; n++) - if (!_stricmp(status_name, Instruction::StatusName(n))) - status = n; - } - - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - } - - else if (defname == "rloc") { - if (pdef->term()->isStruct()) - rloc = ParseRLoc(pdef->term()->isStruct()); - } - - else if (defname == "rgn") { - GetDefText(order_rgn_name, pdef, filename); - } - else if (defname == "speed") { - GetDefNumber(speed, pdef, filename); - } - else if (defname == "formation") { - GetDefNumber(formation, pdef, filename); - } - else if (defname == "emcon") { - GetDefNumber(emcon, pdef, filename); - } - else if (defname == "priority") { - GetDefNumber(priority, pdef, filename); - } - else if (defname == "farcast") { - if (pdef->term()->isBool()) { - bool f = false; - GetDefBool(f, pdef, filename); - farcast = f; - } - else { - GetDefNumber(farcast, pdef, filename); - } - } - else if (defname == "tgt") { - GetDefText(tgt_name, pdef, filename); - } - else if (defname == "tgt_desc") { - GetDefText(tgt_desc, pdef, filename); - } - else if (defname.indexOf("hold") == 0) { - GetDefNumber(hold, pdef, filename); - } - } - } - - Text rgn; - - if (order_rgn_name.length() > 0) - rgn = order_rgn_name; - - else if (element->navlist.size() > 0) - rgn = element->navlist[element->navlist.size()-1]->RegionName(); - - else - rgn = region; - - if (tgt_desc.length() && tgt_name.length()) - tgt_desc = tgt_desc + " " + tgt_name; - - Instruction* instr = new Instruction(rgn, loc, order); - - instr->SetStatus(status); - instr->SetEMCON(emcon); - instr->SetFormation(formation); - instr->SetSpeed(speed); - instr->SetTarget(tgt_name); - instr->SetTargetDesc(tgt_desc); - instr->SetPriority(priority-1); - instr->SetFarcast(farcast); - instr->SetHoldTime(hold); - - if (rloc) { - instr->GetRLoc() = *rloc; - delete rloc; - } - - return instr; -} - -void -Mission::ParseLoadout(TermStruct* val, MissionElement* element) -{ - int ship = -1; - int stations[16]; - Text name; - - ZeroMemory(stations, sizeof(stations)); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "ship") { - GetDefNumber(ship, pdef, filename); - } - else if (defname == "name") { - GetDefText(name, pdef, filename); - } - else if (defname == "stations") { - GetDefArray(stations, 16, pdef, filename); - } - } - } - - MissionLoad* load = new MissionLoad(ship); - - if (name.length()) - load->SetName(name); - - for (int i = 0; i < 16; i++) - load->SetStation(i, stations[i]); - - element->loadouts.append(load); -} - -RLoc* -Mission::ParseRLoc(TermStruct* val) -{ - Vec3 base_loc; - RLoc* rloc = new RLoc; - RLoc* ref = 0; - - double dex = 0; - double dex_var = 5e3; - double az = 0; - double az_var = PI; - double el = 0; - double el_var = 0.1; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "dex") { - GetDefNumber(dex, pdef, filename); - rloc->SetDistance(dex); - } - else if (defname == "dex_var") { - GetDefNumber(dex_var, pdef, filename); - rloc->SetDistanceVar(dex_var); - } - else if (defname == "az") { - GetDefNumber(az, pdef, filename); - if (degrees) az *= DEGREES; - rloc->SetAzimuth(az); - } - else if (defname == "az_var") { - GetDefNumber(az_var, pdef, filename); - if (degrees) az_var *= DEGREES; - rloc->SetAzimuthVar(az_var); - } - else if (defname == "el") { - GetDefNumber(el, pdef, filename); - if (degrees) el *= DEGREES; - rloc->SetElevation(el); - } - else if (defname == "el_var") { - GetDefNumber(el_var, pdef, filename); - if (degrees) el_var *= DEGREES; - rloc->SetElevationVar(el_var); - } - else if (defname == "loc") { - GetDefVec(base_loc, pdef, filename); - rloc->SetBaseLocation(base_loc); - } - - else if (defname == "ref") { - Text refstr; - GetDefText(refstr, pdef, filename); - - int sep = refstr.indexOf(':'); - - if (sep >= 0) { - Text elem_name = refstr.substring(0, sep); - Text nav_name = refstr.substring(sep+1, refstr.length()); - MissionElement* elem = 0; - - if (elem_name == "this") - elem = current; - else - elem = FindElement(elem_name); - - if (elem && elem->NavList().size() > 0) { - int index = atoi(nav_name)-1; - if (index < 0) - index = 0; - else if (index >= elem->NavList().size()) - index = elem->NavList().size()-1; - - ref = &elem->NavList()[index]->GetRLoc(); - rloc->SetReferenceLoc(ref); - } - else { - ::Print("Warning: no ref found for rloc '%s' in elem '%s'\n", refstr.data(), current->Name().data()); - rloc->SetBaseLocation(RandomPoint()); - } - } - else { - MissionElement* elem = 0; - - if (refstr == "this") - elem = current; - else - elem = FindElement(refstr); - - if (elem) { - ref = &elem->GetRLoc(); - rloc->SetReferenceLoc(ref); - } - else { - ::Print("Warning: no ref found for rloc '%s' in elem '%s'\n", refstr.data(), current->Name().data()); - rloc->SetBaseLocation(RandomPoint()); - } - } - } - } - } - - return rloc; -} - -const char* -Mission::RoleName(int role) -{ - switch (role) { - case PATROL: return "Patrol"; - case SWEEP: return "Sweep"; - case INTERCEPT: return "Intercept"; - case AIR_PATROL: return "Airborne Patrol"; - case AIR_SWEEP: return "Airborne Sweep"; - case AIR_INTERCEPT: return "Airborne Intercept"; - case STRIKE: return "Strike"; - case ASSAULT: return "Assault"; - case DEFEND: return "Defend"; - case ESCORT: return "Escort"; - case ESCORT_FREIGHT: return "Freight Escort"; - case ESCORT_SHUTTLE: return "Shuttle Escort"; - case ESCORT_STRIKE: return "Strike Escort"; - case INTEL: return "Intel"; - case SCOUT: return "Scout"; - case RECON: return "Recon"; - case BLOCKADE: return "Blockade"; - case FLEET: return "Fleet"; - case BOMBARDMENT: return "Attack"; - case FLIGHT_OPS: return "Flight Ops"; - case TRANSPORT: return "Transport"; - case CARGO: return "Cargo"; - case TRAINING: return "Training"; - default: - case OTHER: return "Misc"; - } -} - -// +--------------------------------------------------------------------+ - -Text -Mission::Serialize(const char* player_elem, int player_index) -{ - Text s = "MISSION\n\nname: \""; - s += SafeString(Name()); - - if (desc.length()) { - s += "\"\ndesc: \""; - s += SafeString(desc); - } - - s += "\"\ntype: \""; - s += SafeString(TypeName()); - - ListIter sys_iter = system_list; - while (++sys_iter) { - StarSystem* sys = sys_iter.value(); - - if (sys != star_system) { - s += "\"\nsystem: \""; - s += sys->Name(); - } - } - - s += "\"\nsystem: \""; - if (GetStarSystem()) - s += SafeString(GetStarSystem()->Name()); - else - s += "null"; - - ListIter iter = GetElements(); - - Sim* sim = Sim::GetSim(); - if (sim && sim->GetElements().size() > 0) - iter = sim->GetMissionElements(); - - s += "\"\n"; - - bool region_set = false; - if (player_elem && *player_elem) { - // set the mission region to that of the active player - while (++iter) { - MissionElement* e = iter.value(); - if (e->Name() == player_elem) { - char buf[32]; - sprintf_s(buf, "team: %d\n", e->GetIFF()); - s += buf; - - s += "region: \""; - s += SafeString(e->Region()); - s += "\"\n\n"; - - region_set = true; - break; - } - } - - iter.reset(); - } - - if (!region_set) { - s += "region: \""; - s += SafeString(GetRegion()); - s += "\"\n\n"; - } - - if (Objective() && *Objective()) { - s += "objective: \""; - s += SafeString(Objective()); - s += "\"\n\n"; - } - - if (Situation() && *Situation()) { - s += "sitrep: \""; - s += SafeString(Situation()); - s += "\"\n\n"; - } - - char buffer[256]; - FormatTime(buffer, Start()); - - s += "start: \""; - s += buffer; - s += "\"\n\n"; - s += "degrees: true\n\n"; - - while (++iter) { - MissionElement* elem = iter.value(); - - s += "element: {\n"; - s += " name: \""; - s += SafeString(elem->Name()); - s += "\"\n"; - - if (elem->Path().length()) { - s += " path: \""; - s += SafeString(elem->Path()); - s += "\"\n"; - } - - if (elem->GetDesign()) { - s += " design: \""; - s += SafeString(elem->GetDesign()->name); - s += "\"\n"; - } - - if (elem->GetSkin()) { - s += " skin: \""; - s += SafeString(elem->GetSkin()->Name()); - s += "\"\n"; - } - - if (elem->Squadron().length()) { - s += " squadron: \""; - s += SafeString(elem->Squadron()); - s += "\"\n"; - } - - if (elem->Carrier().length()) { - s += " carrier: \""; - s += SafeString(elem->Carrier()); - s += "\"\n"; - } - - if (elem->Commander().length()) { - s += " commander: \""; - s += SafeString(elem->Commander()); - s += "\"\n"; - } - - s += " mission: \""; - s += elem->RoleName(); - s += "\"\n\n"; - - if (elem->IntelLevel()) { - s += " intel: \""; - s += Intel::NameFromIntel(elem->IntelLevel()); - s += "\"\n"; - } - - sprintf_s(buffer, " count: %d\n", elem->Count()); - s += buffer; - - if (elem->MaintCount()) { - sprintf_s(buffer, " maint_count: %d\n", elem->MaintCount()); - s += buffer; - } - - if (elem->DeadCount()) { - sprintf_s(buffer, " dead_count: %d\n", elem->DeadCount()); - s += buffer; - } - - if (elem->RespawnCount()) { - sprintf_s(buffer, " respawn_count: %d\n", elem->RespawnCount()); - s += buffer; - } - - if (elem->HoldTime()) { - sprintf_s(buffer, " hold_time: %d\n", elem->HoldTime()); - s += buffer; - } - - if (elem->ZoneLock()) { - sprintf_s(buffer, " zone_lock: %d\n", elem->ZoneLock()); - s += buffer; - } - - if (elem->IsAlert()) { - s += " alert: true\n"; - } - - if (!elem->IsSquadron()) { - sprintf_s(buffer, " command_ai:%d\n", elem->CommandAI()); - s += buffer; - } - - sprintf_s(buffer, " iff: %d\n", elem->GetIFF()); - s += buffer; - - if (player_elem) { - if (elem->Name() == player_elem) { - if (player_index < 1) - player_index = 1; - - sprintf_s(buffer, " player: %d\n", player_index); - s += buffer; - } - } - - else { - if (elem->Player()) { - sprintf_s(buffer, " player: %d\n", elem->Player()); - s += buffer; - } - } - - if (!elem->IsSquadron()) { - if (elem->IsPlayable()) - s += " playable: true\n"; - else - s += " playable: false\n"; - } - - - s += " region: \""; - s += elem->Region(); - s += "\"\n"; - - sprintf_s(buffer, " loc: (%.0f, %.0f, %.0f)\n", - elem->Location().x, - elem->Location().y, - elem->Location().z); - s += buffer; - - if (elem->Heading() != 0) { - sprintf_s(buffer, " head: %d\n", (int) (elem->Heading()/DEGREES)); - s += buffer; - } - - if (elem->Loadouts().size()) { - s += "\n"; - - ListIter load_iter = elem->Loadouts(); - while (++load_iter) { - MissionLoad* load = load_iter.value(); - - sprintf_s(buffer, " loadout: { ship: %d, ", load->GetShip()); - s += buffer; - - if (load->GetName().length()) { - s += "name: \""; - s += SafeString(load->GetName()); - s += "\" }\n"; - } - else { - s += "stations: ("; - - for (int i = 0; i < 16; i++) { - sprintf_s(buffer, "%d", load->GetStation(i)); - s += buffer; - - if (i < 15) - s += ", "; - } - - s += ") }\n"; - } - } - } - - if (elem->Objectives().size()) { - s += "\n"; - - ListIter obj_iter = elem->Objectives(); - while (++obj_iter) { - Instruction* inst = obj_iter.value(); - - s += " objective: { cmd: "; - s += Instruction::ActionName(inst->Action()); - s += ", tgt: \""; - s += SafeString(inst->TargetName()); - s += "\" }\n"; - } - } - - if (elem->NavList().size()) { - s += "\n"; - - ListIter nav_iter = elem->NavList(); - while (++nav_iter) { - Instruction* inst = nav_iter.value(); - - s += " navpt: { cmd: "; - s += Instruction::ActionName(inst->Action()); - s += ", status: "; - s += Instruction::StatusName(inst->Status()); - - if (inst->TargetName() && *inst->TargetName()) { - s += ", tgt: \""; - s += SafeString(inst->TargetName()); - s += "\""; - } - - sprintf_s(buffer, ", loc: (%.0f, %.0f, %.0f), speed: %d", - inst->Location().x, - inst->Location().y, - inst->Location().z, - inst->Speed()); - s += buffer; - - if (inst->RegionName() && *inst->RegionName()) { - s += ", rgn: \""; - s += inst->RegionName(); - s += "\""; - } - - if (inst->HoldTime()) { - sprintf_s(buffer, ", hold: %d", (int) inst->HoldTime()); - s += buffer; - } - - if (inst->Farcast()) { - s += ", farcast: true"; - } - - if (inst->Formation() > Instruction::DIAMOND) { - sprintf_s(buffer, ", formation: %d", (int) inst->Formation()); - s += buffer; - } - - if (inst->Priority() > Instruction::PRIMARY) { - sprintf_s(buffer, ", priority: %d", (int) inst->Priority()); - s += buffer; - } - - s += " }\n"; - } - } - - if (elem->Instructions().size()) { - s += "\n"; - - ListIter i_iter = elem->Instructions(); - while (++i_iter) { - s += " instr: \""; - s += SafeString(*i_iter.value()); - s += "\"\n"; - } - } - - if (elem->Ships().size()) { - ListIter s_iter = elem->Ships(); - while (++s_iter) { - MissionShip* ship = s_iter.value(); - - s += "\n ship: {\n"; - - if (ship->Name().length()) { - s += " name: \""; - s += SafeString(ship->Name()); - s += "\"\n"; - } - - if (ship->RegNum().length()) { - s += " regnum: \""; - s += SafeString(ship->RegNum()); - s += "\"\n"; - } - - if (ship->Region().length()) { - s += " region: \""; - s += SafeString(ship->Region()); - s += "\"\n"; - } - - if (fabs(ship->Location().x) < 1e9) { - sprintf_s(buffer, " loc: (%.0f, %.0f, %.0f),\n", - ship->Location().x, - ship->Location().y, - ship->Location().z); - s += buffer; - } - - if (fabs(ship->Velocity().x) < 1e9) { - sprintf_s(buffer, " velocity: (%.1f, %.1f, %.1f),\n", - ship->Velocity().x, - ship->Velocity().y, - ship->Velocity().z); - s += buffer; - } - - if (ship->Respawns() > -1) { - sprintf_s(buffer, " respawns: %d,\n", ship->Respawns()); - s += buffer; - } - - if (ship->Heading() > -1e9) { - sprintf_s(buffer, " heading: %d,\n", (int) (ship->Heading()/DEGREES)); - s += buffer; - } - - if (ship->Integrity() > -1) { - sprintf_s(buffer, " integrity: %d,\n", (int) ship->Integrity()); - s += buffer; - } - - if (ship->Decoys() > -1) { - sprintf_s(buffer, " decoys: %d,\n", ship->Decoys()); - s += buffer; - } - - if (ship->Probes() > -1) { - sprintf_s(buffer, " probes: %d,\n", ship->Probes()); - s += buffer; - } - - if (ship->Ammo()[0] > -10) { - s += "\n ammo: ("; - - for (int i = 0; i < 16; i++) { - sprintf_s(buffer, "%d", ship->Ammo()[i]); - s += buffer; - - if (i < 15) - s += ", "; - } - - s += ")\n"; - } - - if (ship->Fuel()[0] > -10) { - s += "\n fuel: ("; - - for (int i = 0; i < 4; i++) { - sprintf_s(buffer, "%d", ship->Fuel()[i]); - s += buffer; - - if (i < 3) - s += ", "; - } - - s += ")\n"; - } - - s += " }\n"; - } - } - - s += "}\n\n"; - } - - ListIter iter2 = GetEvents(); - while (++iter2) { - MissionEvent* event = iter2.value(); - - s += "event: {\n"; - - s += " id: "; - sprintf_s(buffer, "%d", event->EventID()); - s += buffer; - s += ",\n time: "; - sprintf_s(buffer, "%.1f", event->Time()); - s += buffer; - s += ",\n delay: "; - sprintf_s(buffer, "%.1f", event->Delay()); - s += buffer; - s += ",\n event: "; - s += event->EventName(); - s += "\n"; - - if (event->EventShip().length()) { - s += " event_ship: \""; - s += SafeString(event->EventShip()); - s += "\"\n"; - } - - if (event->EventSource().length()) { - s += " event_source: \""; - s += SafeString(event->EventSource()); - s += "\"\n"; - } - - if (event->EventTarget().length()) { - s += " event_target: \""; - s += SafeString(event->EventTarget()); - s += "\"\n"; - } - - if (event->EventSound().length()) { - s += " event_sound: \""; - s += SafeString(event->EventSound()); - s += "\"\n"; - } - - if (event->EventMessage().length()) { - s += " event_message: \""; - s += SafeString(event->EventMessage()); - s += "\"\n"; - } - - if (event->EventParam()) { - sprintf_s(buffer, "%d", event->EventParam()); - s += " event_param: "; - s += buffer; - s += "\n"; - } - - if (event->EventChance()) { - sprintf_s(buffer, "%d", event->EventChance()); - s += " event_chance: "; - s += buffer; - s += "\n"; - } - - s += " trigger: \""; - s += event->TriggerName(); - s += "\"\n"; - - if (event->TriggerShip().length()) { - s += " trigger_ship: \""; - s += SafeString(event->TriggerShip()); - s += "\"\n"; - } - - if (event->TriggerTarget().length()) { - s += " trigger_target: \""; - s += SafeString(event->TriggerTarget()); - s += "\"\n"; - } - - Text param_str = event->TriggerParamStr(); - - if (param_str.length()) { - s += " trigger_param: "; - s += param_str; - s += "\n"; - } - - s += "}\n\n"; - } - - s += "// EOF\n"; - - return s; -} - -// +====================================================================+ - -static int elem_idkey = 1; - -MissionElement::MissionElement() -: id (elem_idkey++), -elem_id(0), design(0), skin(0), count(1), maint_count(0), dead_count(0), -IFF_code(0), player(0), alert(false), playable(false), rogue(false), invulnerable(false), -respawns(0), hold_time(0), zone_lock(0), heading(0), mission_role(Mission::OTHER), -intel(Intel::SECRET), command_ai(1), combat_group(0), combat_unit(0) -{ -} - -MissionElement::~MissionElement() -{ - ships.destroy(); - objectives.destroy(); - instructions.destroy(); - navlist.destroy(); - loadouts.destroy(); -} - -Text -MissionElement::Abbreviation() const -{ - if (design) - return design->abrv; - - return "UNK"; -} - -Text -MissionElement::GetShipName(int index) const -{ - if (index < 0 || index >= ships.size()) { - if (count > 1) { - char sname[256]; - sprintf_s(sname, "%s %d", (const char*) name, index+1); - return sname; - } - else { - return name; - } - } - - return ships.at(index)->Name(); -} - -Text -MissionElement::GetRegistry(int index) const -{ - if (index < 0 || index >= ships.size()) { - return Text(); - } - - return ships.at(index)->RegNum(); -} - -Text -MissionElement::RoleName() const -{ - return Mission::RoleName(mission_role); -} - -Color -MissionElement::MarkerColor() const -{ - return Ship::IFFColor(IFF_code); -} - -bool -MissionElement::IsStatic() const -{ - int design_type = 0; - if (GetDesign()) - design_type = GetDesign()->type; - - return design_type >= Ship::STATION; -} - -bool -MissionElement::IsGroundUnit() const -{ - int design_type = 0; - if (GetDesign()) - design_type = GetDesign()->type; - - return (design_type & Ship::GROUND_UNITS) ? true : false; -} - -bool -MissionElement::IsStarship() const -{ - int design_type = 0; - if (GetDesign()) - design_type = GetDesign()->type; - - return (design_type & Ship::STARSHIPS) ? true : false; -} - -bool -MissionElement::IsDropship() const -{ - int design_type = 0; - if (GetDesign()) - design_type = GetDesign()->type; - - return (design_type & Ship::DROPSHIPS) ? true : false; -} - -bool -MissionElement::IsCarrier() const -{ - const ShipDesign* design = GetDesign(); - if (design && design->flight_decks.size() > 0) - return true; - - return false; -} - -bool -MissionElement::IsSquadron() const -{ - if (carrier.length() > 0) - return true; - - return false; -} - -// +--------------------------------------------------------------------+ - -Point -MissionElement::Location() const -{ - MissionElement* pThis = (MissionElement*) this; - return pThis->rloc.Location(); -} - -void -MissionElement::SetLocation(const Point& l) -{ - rloc.SetBaseLocation(l); - rloc.SetReferenceLoc(0); - rloc.SetDistance(0); -} - -void -MissionElement::SetRLoc(const RLoc& r) -{ - rloc = r; -} - -// +----------------------------------------------------------------------+ - -void -MissionElement::AddNavPoint(Instruction* pt, Instruction* afterPoint) -{ - if (pt && !navlist.contains(pt)) { - if (afterPoint) { - int index = navlist.index(afterPoint); - - if (index > -1) - navlist.insert(pt, index+1); - else - navlist.append(pt); - } - - else { - navlist.append(pt); - } - } -} - -void -MissionElement::DelNavPoint(Instruction* pt) -{ - if (pt) - delete navlist.remove(pt); -} - -void -MissionElement::ClearFlightPlan() -{ - navlist.destroy(); -} - -// +----------------------------------------------------------------------+ - -int -MissionElement::GetNavIndex(const Instruction* n) -{ - int index = 0; - - if (navlist.size() > 0) { - ListIter navpt = navlist; - while (++navpt) { - index++; - if (navpt.value() == n) - return index; - } - } - - return 0; -} - -// +====================================================================+ - -MissionLoad::MissionLoad(int s, const char* n) -: ship(s) -{ - for (int i = 0; i < 16; i++) - load[i] = -1; // default: no weapon mounted - - if (n) - name = n; -} - -MissionLoad::~MissionLoad() -{ -} - -// +--------------------------------------------------------------------+ - -int -MissionLoad::GetShip() const -{ - return ship; -} - -void -MissionLoad::SetShip(int s) -{ - ship = s; -} - -Text -MissionLoad::GetName() const -{ - return name; -} - -void -MissionLoad::SetName(Text n) -{ - name = n; -} - -int* -MissionLoad::GetStations() -{ - return load; -} - -int -MissionLoad::GetStation(int index) -{ - if (index >= 0 && index < 16) - return load[index]; - - return 0; -} - -void -MissionLoad::SetStation(int index, int selection) -{ - if (index >= 0 && index < 16) - load[index] = selection; -} - - -// +====================================================================+ - -MissionShip::MissionShip() -: loc(-1e9, -1e9, -1e9), respawns(0), heading(0), integrity(100), -decoys(-10), probes(-10), skin(0) -{ - for (int i = 0; i < 16; i++) - ammo[i] = -10; - - for (int i = 0; i < 4; i++) - fuel[i] = -10; -} - -void -MissionShip::SetAmmo(const int* a) -{ - if (a) { - for (int i = 0; i < 16; i++) - ammo[i] = a[i]; - } -} - -void -MissionShip::SetFuel(const int* f) -{ - if (f) { - for (int i = 0; i < 4; i++) - fuel[i] = f[i]; - } -} diff --git a/Stars45/Mission.h b/Stars45/Mission.h deleted file mode 100644 index 956bb5b..0000000 --- a/Stars45/Mission.h +++ /dev/null @@ -1,425 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simulation Universe and Region classes -*/ - -#ifndef Mission_h -#define Mission_h - -#include "Types.h" -#include "Intel.h" -#include "RLoc.h" -#include "Universe.h" -#include "Scene.h" -#include "Skin.h" -#include "Physical.h" -#include "Geometry.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Mission; -class MissionElement; -class MissionLoad; -class MissionEvent; -class MissionShip; - -class CombatGroup; -class CombatUnit; - -class Ship; -class System; -class Element; -class ShipDesign; -class WeaponDesign; -class StarSystem; -class Instruction; - -class Term; -class TermArray; -class TermStruct; - -// +--------------------------------------------------------------------+ - -class Mission -{ -public: - static const char* TYPENAME() { return "Mission"; } - - enum TYPE - { - PATROL, - SWEEP, - INTERCEPT, - AIR_PATROL, - AIR_SWEEP, - AIR_INTERCEPT, - STRIKE, // ground attack - ASSAULT, // starship attack - DEFEND, - ESCORT, - ESCORT_FREIGHT, - ESCORT_SHUTTLE, - ESCORT_STRIKE, - INTEL, - SCOUT, - RECON, - BLOCKADE, - FLEET, - BOMBARDMENT, - FLIGHT_OPS, - TRANSPORT, - CARGO, - TRAINING, - OTHER - }; - - Mission(int id, const char* filename=0, const char* path=0); - virtual ~Mission(); - - int operator == (const Mission& m) const { return id == m.id; } - - virtual void Validate(); - virtual bool Load(const char* filename=0, const char* path=0); - virtual bool Save(); - virtual bool ParseMission(const char* buffer); - virtual void SetPlayer(MissionElement* player_element); - virtual MissionElement* GetPlayer(); - - // accessors/mutators: - int Identity() const { return id; } - const char* FileName() const { return filename; } - const char* Name() const { return name; } - const char* Description() const { return desc; } - const char* Situation() const { return sitrep; } - const char* Objective() const { return objective; } - const char* Subtitles() const; - int Start() const { return start; } - double Stardate() const { return stardate; } - int Type() const { return type; } - const char* TypeName() const { return RoleName(type); } - int Team() const { return team; } - bool IsOK() const { return ok; } - bool IsActive() const { return active; } - bool IsComplete() const { return complete; } - - StarSystem* GetStarSystem() const { return star_system; } - List& GetSystemList() { return system_list; } - const char* GetRegion() const { return region; } - - List& GetElements() { return elements; } - virtual MissionElement* FindElement(const char* name); - virtual void AddElement(MissionElement* elem); - - List& GetEvents() { return events; } - MissionEvent* FindEvent(int event_type) const; - virtual void AddEvent(MissionEvent* event); - - MissionElement* GetTarget() const { return target; } - MissionElement* GetWard() const { return ward; } - - void SetName(const char* n) { name = n; } - void SetDescription(const char* d) { desc = d; } - void SetSituation(const char* sit) { sitrep = sit; } - void SetObjective(const char* obj) { objective = obj; } - void SetStart(int s) { start = s; } - void SetType(int t) { type = t; } - void SetTeam(int iff) { team = iff; } - void SetStarSystem(StarSystem* s); - void SetRegion(const char* rgn) { region = rgn; } - void SetOK(bool a) { ok = a; } - void SetActive(bool a) { active = a; } - void SetComplete(bool c) { complete = c; } - void SetTarget(MissionElement* t) { target = t; } - void SetWard(MissionElement* w) { ward = w; } - - void ClearSystemList(); - - void IncreaseElemPriority(int index); - void DecreaseElemPriority(int index); - void IncreaseEventPriority(int index); - void DecreaseEventPriority(int index); - - static const char* RoleName(int role); - static int TypeFromName(const char* n); - - Text ErrorMessage() const { return errmsg; } - void AddError(Text err); - - Text Serialize(const char* player_elem=0, int player_index=0); - -protected: - MissionElement* ParseElement(TermStruct* val); - MissionEvent* ParseEvent(TermStruct* val); - MissionShip* ParseShip(TermStruct* val, MissionElement* element); - Instruction* ParseInstruction(TermStruct* val, MissionElement* element); - void ParseLoadout(TermStruct* val, MissionElement* element); - RLoc* ParseRLoc(TermStruct* val); - - int id; - char filename[64]; - char path[64]; - Text region; - Text name; - Text desc; - int type; - int team; - int start; - double stardate; - bool ok; - bool active; - bool complete; - bool degrees; - Text objective; - Text sitrep; - Text errmsg; - Text subtitles; - StarSystem* star_system; - List system_list; - - List elements; - List events; - - MissionElement* target; - MissionElement* ward; - MissionElement* current; -}; - -// +--------------------------------------------------------------------+ - -class MissionElement -{ - friend class Mission; - -public: - static const char* TYPENAME() { return "MissionElement"; } - - MissionElement(); - ~MissionElement(); - - int operator == (const MissionElement& r) const { return id == r.id; } - - int Identity() const { return id; } - const Text& Name() const { return name; } - Text Abbreviation() const; - const Text& Carrier() const { return carrier; } - const Text& Commander() const { return commander; } - const Text& Squadron() const { return squadron; } - const Text& Path() const { return path; } - int ElementID() const { return elem_id; } - const ShipDesign* GetDesign() const { return design; } - const Skin* GetSkin() const { return skin; } - int Count() const { return count; } - int MaintCount() const { return maint_count; } - int DeadCount() const { return dead_count; } - int GetIFF() const { return IFF_code; } - int IntelLevel() const { return intel; } - int MissionRole() const { return mission_role; } - int Player() const { return player; } - Text RoleName() const; - Color MarkerColor() const; - bool IsStarship() const; - bool IsDropship() const; - bool IsStatic() const; - bool IsGroundUnit() const; - bool IsSquadron() const; - bool IsCarrier() const; - bool IsAlert() const { return alert; } - bool IsPlayable() const { return playable; } - bool IsRogue() const { return rogue; } - bool IsInvulnerable() const { return invulnerable; } - int RespawnCount() const { return respawns; } - int HoldTime() const { return hold_time; } - int CommandAI() const { return command_ai; } - int ZoneLock() const { return zone_lock; } - - const Text& Region() const { return rgn_name; } - Point Location() const; - RLoc& GetRLoc() { return rloc; } - double Heading() const { return heading; } - - Text GetShipName(int n) const; - Text GetRegistry(int n) const; - - List& Objectives() { return objectives; } - List& Instructions() { return instructions; } - List& NavList() { return navlist; } - List& Loadouts() { return loadouts; } - List& Ships() { return ships; } - - void SetName(const char* n) { name = n; } - void SetCarrier(const char* c) { carrier = c; } - void SetCommander(const char* c) { commander = c; } - void SetSquadron(const char* s) { squadron = s; } - void SetPath(const char* p) { path = p; } - void SetElementID(int id) { elem_id = id; } - void SetDesign(const ShipDesign* d){ design = d; } - void SetSkin(const Skin* s) { skin = s; } - void SetCount(int n) { count = n; } - void SetMaintCount(int n) { maint_count = n; } - void SetDeadCount(int n) { dead_count = n; } - void SetIFF(int iff) { IFF_code = iff; } - void SetIntelLevel(int i) { intel = i; } - void SetMissionRole(int r) { mission_role = r; } - void SetPlayer(int p) { player = p; } - void SetPlayable(bool p) { playable = p; } - void SetRogue(bool r) { rogue = r; } - void SetInvulnerable(bool n) { invulnerable = n; } - void SetAlert(bool a) { alert = a; } - void SetCommandAI(int a) { command_ai = a; } - void SetRegion(const char* rgn) { rgn_name = rgn; } - void SetLocation(const Point& p); - void SetRLoc(const RLoc& r); - void SetHeading(double h) { heading = h; } - void SetRespawnCount(int r) { respawns = r; } - void SetHoldTime(int t) { hold_time = t; } - void SetZoneLock(int z) { zone_lock = z; } - - void AddNavPoint(Instruction* pt, Instruction* afterPoint=0); - void DelNavPoint(Instruction* pt); - void ClearFlightPlan(); - int GetNavIndex(const Instruction* n); - - void AddObjective(Instruction* obj) { objectives.append(obj); } - void AddInstruction(const char* i) { instructions.append(new Text(i)); } - - CombatGroup* GetCombatGroup() { return combat_group; } - void SetCombatGroup(CombatGroup* g) { combat_group = g; } - CombatUnit* GetCombatUnit() { return combat_unit; } - void SetCombatUnit(CombatUnit* u) { combat_unit = u; } - -protected: - int id; - Text name; - Text carrier; - Text commander; - Text squadron; - Text path; - int elem_id; - const ShipDesign* design; - const Skin* skin; - int count; - int maint_count; - int dead_count; - int IFF_code; - int mission_role; - int intel; - int respawns; - int hold_time; - int zone_lock; - int player; - int command_ai; - bool alert; - bool playable; - bool rogue; - bool invulnerable; - - Text rgn_name; - RLoc rloc; - double heading; - - CombatGroup* combat_group; - CombatUnit* combat_unit; - - List objectives; - List instructions; - List navlist; - List loadouts; - List ships; -}; - -// +--------------------------------------------------------------------+ - -class MissionLoad -{ - friend class Mission; - -public: - static const char* TYPENAME() { return "MissionLoad"; } - - MissionLoad(int ship=-1, const char* name=0); - ~MissionLoad(); - - int GetShip() const; - void SetShip(int ship); - - Text GetName() const; - void SetName(Text name); - - int* GetStations(); - int GetStation(int index); - void SetStation(int index, int selection); - -protected: - int ship; - Text name; - int load[16]; -}; - -// +--------------------------------------------------------------------+ - -class MissionShip -{ - friend class Mission; - -public: - static const char* TYPENAME() { return "MissionShip"; } - - MissionShip(); - ~MissionShip() { } - - const Text& Name() const { return name; } - const Text& RegNum() const { return regnum; } - const Text& Region() const { return region; } - const Skin* GetSkin() const { return skin; } - const Point& Location() const { return loc; } - const Point& Velocity() const { return velocity; } - int Respawns() const { return respawns; } - double Heading() const { return heading; } - double Integrity() const { return integrity; } - int Decoys() const { return decoys; } - int Probes() const { return probes; } - const int* Ammo() const { return ammo; } - const int* Fuel() const { return fuel; } - - void SetName(const char* n) { name = n; } - void SetRegNum(const char* n) { regnum = n; } - void SetRegion(const char* n) { region = n; } - void SetSkin(const Skin* s) { skin = s; } - void SetLocation(const Point& p) { loc = p; } - void SetVelocity(const Point& p) { velocity = p; } - void SetRespawns(int r) { respawns = r; } - void SetHeading(double h) { heading = h; } - void SetIntegrity(double n) { integrity = n; } - void SetDecoys(int d) { decoys = d; } - void SetProbes(int p) { probes = p; } - void SetAmmo(const int* a); - void SetFuel(const int* f); - -protected: - Text name; - Text regnum; - Text region; - const Skin* skin; - Point loc; - Point velocity; - int respawns; - double heading; - double integrity; - int decoys; - int probes; - int ammo[16]; - int fuel[4]; -}; - -#endif // Mission_h - diff --git a/Stars45/MissionEvent.cpp b/Stars45/MissionEvent.cpp deleted file mode 100644 index 24da372..0000000 --- a/Stars45/MissionEvent.cpp +++ /dev/null @@ -1,872 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Events for mission scripting -*/ - -#include "MissionEvent.h" -#include "Mission.h" -#include "StarSystem.h" -#include "Galaxy.h" -#include "Starshatter.h" -#include "StarServer.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Element.h" -#include "DisplayView.h" -#include "HUDView.h" -#include "Instruction.h" -#include "QuantumDrive.h" -#include "Sim.h" -#include "AudioConfig.h" -#include "CameraDirector.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "Weapon.h" -#include "WeaponGroup.h" -#include "Player.h" -#include "Campaign.h" -#include "CombatGroup.h" - -#include "NetData.h" -#include "NetUtil.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Font.h" -#include "FontMgr.h" -#include "Sound.h" -#include "ParseUtil.h" -#include "FormatUtil.h" -#include "Random.h" - -const char* FormatGameTime(); - -// +--------------------------------------------------------------------+ - -MissionEvent::MissionEvent() -: id(0), status(PENDING), time(0), delay(0), event(0), event_nparams(0), -event_chance(100), trigger(0), trigger_nparams(0), sound(0) -{ - ZeroMemory(event_param, sizeof(event_param)); - ZeroMemory(trigger_param, sizeof(trigger_param)); -} - -MissionEvent::~MissionEvent() -{ - if (sound) { - sound->Stop(); - sound->Release(); - } -} - -// +--------------------------------------------------------------------+ - -void -MissionEvent::ExecFrame(double seconds) -{ - Sim* sim = Sim::GetSim(); - - if (!sim) { - status = PENDING; - return; - } - - if (status == PENDING) - CheckTrigger(); - - if (status == ACTIVE) { - if (delay > 0) - delay -= seconds; - - else - Execute(); - } -} - -// +--------------------------------------------------------------------+ - -void -MissionEvent::Activate() -{ - if (status == PENDING) { - if (event_chance > 0 && event_chance < 100) { - if (Random(0, 100) < event_chance) - status = ACTIVE; - else - status = SKIPPED; - } - - else { - status = ACTIVE; - } - - if (status == SKIPPED) { - Sim::GetSim()->ProcessEventTrigger(TRIGGER_SKIPPED, id); - } - } -} - -void -MissionEvent::Skip() -{ - if (status == PENDING) { - status = SKIPPED; - } -} - -// +--------------------------------------------------------------------+ - -bool -MissionEvent::CheckTrigger() -{ - Sim* sim = Sim::GetSim(); - - if (time > 0 && time > sim->MissionClock()) - return false; - - switch (trigger) { - case TRIGGER_TIME: { - if (time <= sim->MissionClock()) - Activate(); - } - break; - - case TRIGGER_DAMAGE: { - Ship* ship = sim->FindShip(trigger_ship); - if (ship) { - double damage = 100.0 * (ship->Design()->integrity - ship->Integrity()) / - (ship->Design()->integrity); - - if (damage >= trigger_param[0]) - Activate(); - } - } - break; - - case TRIGGER_DETECT: { - Ship* ship = sim->FindShip(trigger_ship); - Ship* tgt = sim->FindShip(trigger_target); - - if (ship && tgt) { - if (ship->FindContact(tgt)) - Activate(); - } - else { - Skip(); - } - } - break; - - case TRIGGER_RANGE: { - Ship* ship = sim->FindShip(trigger_ship); - Ship* tgt = sim->FindShip(trigger_target); - - if (ship && tgt) { - double range = (ship->Location() - tgt->Location()).length(); - double min_range = 0; - double max_range = 1e12; - - if (trigger_param[0] > 0) - min_range = trigger_param[0]; - else - max_range = -trigger_param[0]; - - if (range < min_range || range > max_range) - Activate(); - } - else { - Skip(); - } - } - break; - - case TRIGGER_SHIPS_LEFT: { - int alive = 0; - int count = 0; - int iff = -1; - int nparams = NumTriggerParams(); - - if (nparams > 0) count = TriggerParam(0); - if (nparams > 1) iff = TriggerParam(1); - - ListIter iter = sim->GetRegions(); - while (++iter) { - SimRegion* rgn = iter.value(); - - ListIter s_iter = rgn->Ships(); - while (++s_iter) { - Ship* ship = s_iter.value(); - - if (ship->Type() >= Ship::STATION) - continue; - - if (ship->Life() == 0 && ship->RespawnCount() < 1) - continue; - - if (iff < 0 || ship->GetIFF() == iff) - alive++; - } - } - - if (alive <= count) - Activate(); - } - break; - - case TRIGGER_EVENT_ALL: { - bool all = true; - int nparams = NumTriggerParams(); - for (int i = 0; all && i < nparams; i++) { - int trigger_id = TriggerParam(i); - - ListIter iter = sim->GetEvents(); - while (++iter) { - MissionEvent* e = iter.value(); - if (e->EventID() == trigger_id) { - if (e->Status() != COMPLETE) - all = false; - break; - } - - else if (e->EventID() == -trigger_id) { - if (e->Status() == COMPLETE) - all = false; - break; - } - } - } - - if (all) - Activate(); - } - break; - - case TRIGGER_EVENT_ANY: { - bool any = false; - int nparams = NumTriggerParams(); - for (int i = 0; !any && i < nparams; i++) { - int trigger_id = TriggerParam(i); - - ListIter iter = sim->GetEvents(); - while (++iter) { - MissionEvent* e = iter.value(); - if (e->EventID() == trigger_id) { - if (e->Status() == COMPLETE) - any = true; - break; - } - } - } - - if (any) - Activate(); - } - break; - } - - return status == ACTIVE; -} - -// +--------------------------------------------------------------------+ - -void -MissionEvent::Execute(bool silent) -{ - Starshatter* stars = Starshatter::GetInstance(); - HUDView* hud = HUDView::GetInstance(); - Sim* sim = Sim::GetSim(); - Ship* player = sim->GetPlayerShip(); - Ship* ship = 0; - Ship* src = 0; - Ship* tgt = 0; - Element* elem = 0; - int pan = 0; - bool end_mission = false; - - if (event_ship.length()) - ship = sim->FindShip(event_ship); - else - ship = player; - - if (event_source.length()) - src = sim->FindShip(event_source); - - if (event_target.length()) - tgt = sim->FindShip(event_target); - - if (ship) - elem = ship->GetElement(); - - else if (event_ship.length()) { - elem = sim->FindElement(event_ship); - - if (elem) - ship = elem->GetShip(1); - } - - // expire the delay, if any remains - delay = 0; - - // fire the event action - switch (event) { - case MESSAGE: - if (event_message.length() > 0) { - if (ship) { - RadioMessage* msg = new RadioMessage(ship, src, event_param[0]); - msg->SetInfo(event_message); - msg->SetChannel(ship->GetIFF()); - if (tgt) - msg->AddTarget(tgt); - RadioTraffic::Transmit(msg); - } - - else if (elem) { - RadioMessage* msg = new RadioMessage(elem, src, event_param[0]); - msg->SetInfo(event_message); - msg->SetChannel(elem->GetIFF()); - if (tgt) - msg->AddTarget(tgt); - RadioTraffic::Transmit(msg); - } - } - - if (event_sound.length() > 0) { - pan = event_param[0]; - } - break; - - case OBJECTIVE: - if (elem) { - if (event_param[0]) { - elem->ClearInstructions(); - elem->ClearObjectives(); - } - - Instruction* obj = new Instruction(event_param[0], 0); - obj->SetTarget(event_target); - elem->AddObjective(obj); - - if (elem->Contains(player)) { - HUDView* hud = HUDView::GetInstance(); - - if (hud) - hud->ShowHUDInst(); - } - } - break; - - case INSTRUCTION: - if (elem) { - if (event_param[0]) - elem->ClearInstructions(); - - elem->AddInstruction(event_message); - - if (elem->Contains(player) && event_message.length() > 0) { - HUDView* hud = HUDView::GetInstance(); - - if (hud) - hud->ShowHUDInst(); - } - } - break; - - case IFF: - if (elem) { - elem->SetIFF(event_param[0]); - } - - else if (ship) { - ship->SetIFF(event_param[0]); - } - break; - - case DAMAGE: - if (ship) { - ship->InflictDamage(event_param[0]); - - if (ship->Integrity() < 1) { - NetUtil::SendObjKill(ship, 0, NetObjKill::KILL_MISC); - ship->DeathSpiral(); - Print(" %s Killed By Scripted Event %d (%s)\n", (const char*) ship->Name(), id, FormatGameTime()); - } - } - else { - Print(" EVENT %d: Could not apply damage to ship '%s' (not found).\n", id, (const char*) event_ship); - } - break; - - case JUMP: - if (ship) { - SimRegion* rgn = sim->FindRegion(event_target); - - if (rgn && ship->GetRegion() != rgn) { - if (rgn->IsOrbital()) { - QuantumDrive* quantum_drive = ship->GetQuantumDrive(); - if (quantum_drive) { - quantum_drive->SetDestination(rgn, Point(0,0,0)); - quantum_drive->Engage(true); // request immediate jump - } - - else if (ship->IsAirborne()) { - ship->MakeOrbit(); - } - } - - else { - ship->DropOrbit(); - } - } - - } - break; - - case HOLD: - if (elem) - elem->SetHoldTime(event_param[0]); - break; - - case SKIP: { - for (int i = 0; i < event_nparams; i++) { - int skip_id = event_param[i]; - - ListIter iter = sim->GetEvents(); - while (++iter) { - MissionEvent* e = iter.value(); - if (e->EventID() == skip_id) { - if (e->status != COMPLETE) - e->status = SKIPPED; - } - } - } - } - break; - - case END_MISSION: - Print(" END MISSION By Scripted Event %d (%s)\n", id, FormatGameTime()); - end_mission = true; - break; - - // - // NOTE: CUTSCENE EVENTS DO NOT APPLY IN MULTIPLAYER - // - case BEGIN_SCENE: - Print(" ------------------------------------\n"); - Print(" Begin Cutscene '%s'\n", event_message.data()); - stars->BeginCutscene(); - break; - - case END_SCENE: - Print(" End Cutscene '%s'\n", event_message.data()); - Print(" ------------------------------------\n"); - stars->EndCutscene(); - break; - - case CAMERA: - if (stars->InCutscene()) { - CameraDirector* cam_dir = CameraDirector::GetInstance(); - - if (!cam_dir->GetShip()) - cam_dir->SetShip(player); - - switch (event_param[0]) { - case 1: - if (cam_dir->GetMode() != CameraDirector::MODE_COCKPIT) - cam_dir->SetMode(CameraDirector::MODE_COCKPIT, event_rect.x); - break; - - case 2: - if (cam_dir->GetMode() != CameraDirector::MODE_CHASE) - cam_dir->SetMode(CameraDirector::MODE_CHASE, event_rect.x); - break; - - case 3: - if (cam_dir->GetMode() != CameraDirector::MODE_ORBIT) - cam_dir->SetMode(CameraDirector::MODE_ORBIT, event_rect.x); - break; - - case 4: - if (cam_dir->GetMode() != CameraDirector::MODE_TARGET) - cam_dir->SetMode(CameraDirector::MODE_TARGET, event_rect.x); - break; - } - - if (event_target.length()) { - ::Print("Mission Event %d: setting camera target to %s\n", id, (const char*) event_target); - Ship* s_tgt = 0; - - if (event_target.indexOf("body:") < 0) - s_tgt = sim->FindShip(event_target); - - if (s_tgt) { - ::Print(" found ship %s\n", s_tgt->Name()); - cam_dir->SetViewOrbital(0); - - if (cam_dir->GetViewObject() != s_tgt) { - - if (event_param[0] == 6) { - s_tgt->DropCam(event_param[1], event_param[2]); - cam_dir->SetShip(s_tgt); - cam_dir->SetMode(CameraDirector::MODE_DROP, 0); - } - else { - Ship* cam_ship = cam_dir->GetShip(); - - if (cam_ship && cam_ship->IsDropCam()) { - cam_ship->CompleteTransition(); - } - - if (cam_dir->GetShip() != sim->GetPlayerShip()) - cam_dir->SetShip(sim->GetPlayerShip()); - cam_dir->SetViewObject(s_tgt, true); // immediate, no transition - } - } - } - - else { - const char* body_name = event_target.data(); - - if (!strncmp(body_name, "body:", 5)) - body_name += 5; - - Orbital* orb = sim->FindOrbitalBody(body_name); - - if (orb) { - ::Print(" found body %s\n", orb->Name()); - cam_dir->SetViewOrbital(orb); - } - } - } - - if (event_param[0] == 3) { - cam_dir->SetOrbitPoint(event_point.x, event_point.y, event_point.z); - } - - else if (event_param[0] == 5) { - cam_dir->SetOrbitRates(event_point.x, event_point.y, event_point.z); - } - } - break; - - case VOLUME: - if (stars->InCutscene()) { - AudioConfig* audio_cfg = AudioConfig::GetInstance(); - - audio_cfg->SetEfxVolume(event_param[0]); - audio_cfg->SetWrnVolume(event_param[0]); - } - break; - - case DISPLAY: - if (stars->InCutscene()) { - DisplayView* disp_view = DisplayView::GetInstance(); - - if (disp_view) { - Color color; - color.Set(event_param[0]); - - if (event_message.length() && event_source.length()) { - - if (event_message.contains('$')) { - Campaign* campaign = Campaign::GetCampaign(); - Player* user = Player::GetCurrentPlayer(); - CombatGroup* group = campaign->GetPlayerGroup(); - - if (user) { - event_message = FormatTextReplace(event_message, "$NAME", user->Name().data()); - event_message = FormatTextReplace(event_message, "$RANK", Player::RankName(user->Rank())); - } - - if (group) { - event_message = FormatTextReplace(event_message, "$GROUP", group->GetDescription()); - } - - if (event_message.contains("$TIME")) { - char timestr[32]; - FormatDayTime(timestr, campaign->GetTime(), true); - event_message = FormatTextReplace(event_message, "$TIME", timestr); - } - } - - disp_view->AddText( event_message, - FontMgr::Find(event_source), - color, - event_rect, - event_point.y, - event_point.x, - event_point.z); - - } - - else if (event_target.length()) { - DataLoader* loader = DataLoader::GetLoader(); - - if (loader) { - loader->SetDataPath(0); - loader->LoadBitmap(event_target, image, 0, true); - } - - if (image.Width() && image.Height()) - disp_view->AddImage( &image, - color, - Video::BLEND_ALPHA, - event_rect, - event_point.y, - event_point.x, - event_point.z); - } - } - } - break; - - case FIRE_WEAPON: - if (ship) { - // fire single weapon: - if (event_param[0] >= 0) { - ship->FireWeapon(event_param[0]); - } - - // fire all weapons: - else { - ListIter g_iter = ship->Weapons(); - while (++g_iter) { - ListIter w_iter = g_iter->GetWeapons(); - while (++w_iter) { - Weapon* w = w_iter.value(); - w->Fire(); - } - } - } - } - break; - - default: - break; - } - - sim->ProcessEventTrigger(TRIGGER_EVENT, id); - - if (!silent && !sound && event_sound.length()) { - DataLoader* loader = DataLoader::GetLoader(); - bool use_fs = loader->IsFileSystemEnabled(); - DWORD flags = pan ? Sound::LOCKED|Sound::LOCALIZED : - Sound::LOCKED|Sound::AMBIENT; - - loader->UseFileSystem(true); - loader->SetDataPath("Sounds/"); - loader->LoadSound(event_sound, sound, flags); - loader->SetDataPath(0); - - if (!sound) { - loader->SetDataPath("Mods/Sounds/"); - loader->LoadSound(event_sound, sound, flags); - loader->SetDataPath(0); - } - - if (!sound) { - loader->LoadSound(event_sound, sound, flags); - } - - loader->UseFileSystem(use_fs); - - // fire and forget: - if (sound) { - if (sound->GetFlags() & Sound::STREAMED) { - sound->SetFlags(flags | sound->GetFlags()); - sound->SetVolume(AudioConfig::VoxVolume()); - sound->Play(); - } - else { - sound->SetFlags(flags); - sound->SetVolume(AudioConfig::VoxVolume()); - sound->SetPan(pan); - sound->SetFilename(event_sound); - sound->AddToSoundCard(); - sound->Play(); - } - } - } - - status = COMPLETE; - - if (end_mission) { - StarServer* server = StarServer::GetInstance(); - - if (stars) { - stars->EndMission(); - } - - else if (server) { - // end mission event uses event_target member - // to forward server to next mission in the chain: - if (event_target.length()) - server->SetNextMission(event_target); - - server->SetGameMode(StarServer::MENU_MODE); - } - } -} - -// +--------------------------------------------------------------------+ - -Text -MissionEvent::TriggerParamStr() const -{ - - Text result; - char buffer[8]; - - if (trigger_param[0] == 0) { - // nothing - } - - else if (trigger_param[1] == 0) { - sprintf_s(buffer, "%d", trigger_param[0]); - result = buffer; - } - - else { - result = "("; - - for (int i = 0; i < 8; i++) { - if (trigger_param[i] == 0) - break; - - if (i < 7 && trigger_param[i+1] != 0) - sprintf_s(buffer, "%d, ", trigger_param[i]); - else - sprintf_s(buffer, "%d", trigger_param[i]); - - result += buffer; - } - - result += ")"; - } - - return result; -} - -// +--------------------------------------------------------------------+ - -int -MissionEvent::EventParam(int index) const -{ - if (index >= 0 && index < NumEventParams()) - return event_param[index]; - - return 0; -} - -int -MissionEvent::NumEventParams() const -{ - return event_nparams; -} - -// +--------------------------------------------------------------------+ - -int -MissionEvent::TriggerParam(int index) const -{ - if (index >= 0 && index < NumTriggerParams()) - return trigger_param[index]; - - return 0; -} - -int -MissionEvent::NumTriggerParams() const -{ - return trigger_nparams; -} - -// +--------------------------------------------------------------------+ - -static const char* event_names[] = { - "Message", - "Objective", - "Instruction", - "IFF", - "Damage", - "Jump", - "Hold", - "Skip", - "Exit", - - "BeginScene", - "Camera", - "Volume", - "Display", - "Fire", - "EndScene" -}; - -static const char* trigger_names[] = { - "Time", - "Damage", - "Destroyed", - "Jump", - "Launch", - "Dock", - "Navpoint", - "Event", - "Skipped", - "Target", - "Ships Left", - "Detect", - "Range", - "Event (ALL)", - "Event (ANY)" -}; - -const char* -MissionEvent::EventName() const -{ - return event_names[event]; -} - -const char* -MissionEvent::EventName(int n) -{ - return event_names[n]; -} - -int -MissionEvent::EventForName(const char* n) -{ - for (int i = 0; i < NUM_EVENTS; i++) - if (!_stricmp(n, event_names[i])) - return i; - - return 0; -} - -const char* -MissionEvent::TriggerName() const -{ - return trigger_names[trigger]; -} - -const char* -MissionEvent::TriggerName(int n) -{ - return trigger_names[n]; -} - -int -MissionEvent::TriggerForName(const char* n) -{ - for (int i = 0; i < NUM_TRIGGERS; i++) - if (!_stricmp(n, trigger_names[i])) - return i; - - return 0; -} \ No newline at end of file diff --git a/Stars45/MissionEvent.h b/Stars45/MissionEvent.h deleted file mode 100644 index 5fe4f10..0000000 --- a/Stars45/MissionEvent.h +++ /dev/null @@ -1,166 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Events for mission scripting -*/ - -#ifndef MissionEvent_h -#define MissionEvent_h - -#include "Types.h" -#include "List.h" -#include "Text.h" -#include "Geometry.h" -#include "Bitmap.h" - -// +--------------------------------------------------------------------+ - -class Mission; -class MissionElement; -class MissionLoad; -class MissionEvent; - -class Ship; -class System; -class Element; -class ShipDesign; -class WeaponDesign; -class StarSystem; -class Instruction; -class Sound; - -// +--------------------------------------------------------------------+ - -class MissionEvent -{ - friend class Mission; - friend class MissionTemplate; - friend class MsnEditDlg; - friend class MsnEventDlg; - -public: - static const char* TYPENAME() { return "MissionEvent"; } - - enum EVENT_TYPE { - MESSAGE, - OBJECTIVE, - INSTRUCTION, - IFF, - DAMAGE, - JUMP, - HOLD, - SKIP, - END_MISSION, - - BEGIN_SCENE, - CAMERA, - VOLUME, - DISPLAY, - FIRE_WEAPON, - END_SCENE, - - NUM_EVENTS - }; - - enum EVENT_STATUS { - PENDING, ACTIVE, COMPLETE, SKIPPED - }; - - enum EVENT_TRIGGER { - TRIGGER_TIME, TRIGGER_DAMAGE, TRIGGER_DESTROYED, - TRIGGER_JUMP, TRIGGER_LAUNCH, TRIGGER_DOCK, - TRIGGER_NAVPT, TRIGGER_EVENT, TRIGGER_SKIPPED, - TRIGGER_TARGET, TRIGGER_SHIPS_LEFT, TRIGGER_DETECT, - TRIGGER_RANGE, TRIGGER_EVENT_ALL, TRIGGER_EVENT_ANY, - NUM_TRIGGERS - }; - - MissionEvent(); - ~MissionEvent(); - - // operations: - void ExecFrame(double seconds); - void Activate(); - - virtual bool CheckTrigger(); - virtual void Execute(bool silent=false); - virtual void Skip(); - - // accessors: - int EventID() const { return id; } - int Status() const { return status; } - bool IsPending() const { return status == PENDING; } - bool IsActive() const { return status == ACTIVE; } - bool IsComplete() const { return status == COMPLETE; } - bool IsSkipped() const { return status == SKIPPED; } - - double Time() const { return time; } - double Delay() const { return delay; } - - int Event() const { return event; } - const char* EventName() const; - Text EventShip() const { return event_ship; } - Text EventSource() const { return event_source; } - Text EventTarget() const { return event_target; } - Text EventMessage() const { return event_message; } - Text EventSound() const { return event_sound; } - - int EventParam(int index=0) const; - int NumEventParams() const; - - int EventChance() const { return event_chance; } - Point EventPoint() const { return event_point; } - Rect EventRect() const { return event_rect; } - - int Trigger() const { return trigger; } - const char* TriggerName() const; - Text TriggerShip() const { return trigger_ship; } - Text TriggerTarget() const { return trigger_target; } - - Text TriggerParamStr() const; - int TriggerParam(int index=0) const; - int NumTriggerParams() const; - - static const char* EventName(int n); - static int EventForName(const char* n); - static const char* TriggerName(int n); - static int TriggerForName(const char* n); - -protected: - int id; - int status; - double time; - double delay; - - int event; - Text event_ship; - Text event_source; - Text event_target; - Text event_message; - Text event_sound; - int event_param[10]; - int event_nparams; - int event_chance; - Vec3 event_point; - Rect event_rect; - - int trigger; - Text trigger_ship; - Text trigger_target; - int trigger_param[10]; - int trigger_nparams; - - Bitmap image; - Sound* sound; -}; - - -#endif // MissionEvent_h - diff --git a/Stars45/MissionTemplate.cpp b/Stars45/MissionTemplate.cpp deleted file mode 100644 index 54efbe6..0000000 --- a/Stars45/MissionTemplate.cpp +++ /dev/null @@ -1,844 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Template classes -*/ - -#include "MissionTemplate.h" -#include "MissionEvent.h" -#include "StarSystem.h" -#include "Galaxy.h" -#include "Callsign.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "Starshatter.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Element.h" -#include "Instruction.h" -#include "Random.h" - -#include "Game.h" -#include "DataLoader.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ - -MissionTemplate::MissionTemplate(int identity, const char* fname, const char* pname) -: Mission(identity, fname, pname) -{ -} - -MissionTemplate::~MissionTemplate() -{ - callsigns.destroy(); - aliases.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -MissionTemplate::AddElement(MissionElement* elem) -{ - if (elem) { - elements.append(elem); - aliases.append(new MissionAlias(elem->Name(), elem)); - } -} - -bool -MissionTemplate::MapElement(MissionElement* elem) -{ - bool result = false; - - if (elem && !elem->GetCombatUnit()) { - if (elem->IsDropship()) { - Text callsign = MapCallsign(elem->Name(), elem->GetIFF()); - - if (callsign.length()) - elem->SetName(callsign); - } - - ListIter obj = elem->Objectives(); - while (++obj) { - Instruction* i = obj.value(); - if (strlen(i->TargetName())) { - // find a callsign, only if one already exists: - Text callsign = MapCallsign(i->TargetName(), -1); - if (callsign.length()) - i->SetTarget(callsign.data()); - } - } - - ListIter nav = elem->NavList(); - while (++nav) { - Instruction* i = nav.value(); - if (strlen(i->TargetName())) { - // find a callsign, only if one already exists: - Text callsign = MapCallsign(i->TargetName(), -1); - if (callsign.length()) - i->SetTarget(callsign.data()); - } - } - - CombatGroup* g = FindCombatGroup(elem->GetIFF(), elem->GetDesign()); - - if (g) { - CombatUnit* u = g->GetNextUnit(); - - if (u) { - elem->SetCombatGroup(g); - elem->SetCombatUnit(u); - } - } - - if (elem->GetCombatUnit()) { - MissionElement* cmdr = FindElement(elem->Commander()); - if (cmdr) - elem->SetCommander(cmdr->Name()); - - MissionElement* sqdr = FindElement(elem->Squadron()); - if (sqdr) - elem->SetSquadron(sqdr->Name()); - - if (!elem->IsDropship()) { - aliases.append(new MissionAlias(elem->Name(), elem)); - elem->SetName(elem->GetCombatUnit()->Name()); - } - - result = true; - } - } - - return result; -} - -Text -MissionTemplate::MapShip(Text name) -{ - Text result = name; - int len = name.length(); - - if (len) { - MissionElement* elem = 0; - - // single ship from an element (e.g. "Alpha 1")? - if (isdigit(name[len-1]) && isspace(name[len-2])) { - Text elem_name = name.substring(0, len-2); - - elem = FindElement(elem_name); - if (elem) - result = elem->Name() + name.substring(len-2, 2); - } - - // full element name - // (also used to try again if single-ship search fails) - if (!elem) { - elem = FindElement(name); - - if (elem) - result = elem->Name(); - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -bool -MissionTemplate::MapEvent(MissionEvent* event) -{ - bool result = false; - - if (event) { - event->event_ship = MapShip(event->event_ship); - event->event_source = MapShip(event->event_source); - event->event_target = MapShip(event->event_target); - event->trigger_ship = MapShip(event->trigger_ship); - event->trigger_target = MapShip(event->trigger_target); - - result = true; - } - - return result; -} - -// +--------------------------------------------------------------------+ - -Text -MissionTemplate::MapCallsign(const char* name, int iff) -{ - for (int i = 0; i < callsigns.size(); i++) { - if (callsigns[i]->Name() == name) - return callsigns[i]->Callsign(); - } - - if (iff >= 0) { - const char* callsign = Callsign::GetCallsign(iff); - MissionCallsign* mc = new MissionCallsign(callsign, name); - callsigns.append(mc); - - return mc->Callsign(); - } - - return name; -} - -// +--------------------------------------------------------------------+ - -static void SelectCombatGroups(CombatGroup* g, const ShipDesign* d, List& list) -{ - if (g->IntelLevel() <= Intel::RESERVE) - return; - - if (g->GetUnits().size() > 0) { - for (int i = 0; i < g->GetUnits().size(); i++) { - CombatUnit* u = g->GetUnits().at(i); - if (u->GetDesign() == d && u->Count() - u->DeadCount() > 0) { - list.append(g); - } - } - } - - ListIter subgroup = g->GetComponents(); - while (++subgroup) - SelectCombatGroups(subgroup.value(), d, list); -} - -CombatGroup* -MissionTemplate::FindCombatGroup(int iff, const ShipDesign* d) -{ - CombatGroup* result = 0; - Campaign* campaign = Campaign::GetCampaign(); - List group_list; - static int combat_group_index = 0; - - if (campaign) { - ListIter combatant = campaign->GetCombatants(); - while (++combatant) { - if (combatant->GetIFF() == iff) { - ::SelectCombatGroups(combatant->GetForce(), d, group_list); - } - } - - if (group_list.size() > 0) - result = group_list[combat_group_index++ % group_list.size()]; - } - - return result; -} - -// +--------------------------------------------------------------------+ - -MissionElement* -MissionTemplate::FindElement(const char* n) -{ - Text name = n; - - ListIter c_iter = callsigns; - while (++c_iter) { - MissionCallsign* c = c_iter.value(); - if (c->Name() == name) { - name = c->Callsign(); - break; - } - } - - ListIter a_iter = aliases; - while (++a_iter) { - MissionAlias* a = a_iter.value(); - if (a->Name() == name) - return a->Element(); - } - - ListIter e_iter = elements; - while (++e_iter) { - MissionElement* elem = e_iter.value(); - if (elem->Name() == name) - return elem; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -bool -MissionTemplate::Load(const char* fname, const char* pname) -{ - ok = false; - - if (fname) - strcpy_s(filename, fname); - - if (pname) - strcpy_s(path, pname); - - if (!filename[0]) { - Print("\nCan't Load Mission Template, script unspecified.\n"); - return ok; - } - - Print("\nLoad Mission Template: '%s'\n", filename); - - int max_ships = (int) 1e6; - - DataLoader* loader = DataLoader::GetLoader(); - bool old_fs = loader->IsFileSystemEnabled(); - BYTE* block = 0; - - loader->UseFileSystem(true); - loader->SetDataPath(path); - loader->LoadBuffer(filename, block, true); - loader->SetDataPath(0); - loader->UseFileSystem(old_fs); - - Parser parser(new BlockReader((const char*) block)); - - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'\n", filename); - return ok; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "MISSION_TEMPLATE") { - Print("ERROR: invalid MISSION TEMPLATE file '%s'\n", filename); - term->print(10); - return ok; - } - } - - ok = true; - - char target_name[256]; - char ward_name[256]; - - target_name[0] = 0; - ward_name[0] = 0; - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - Text defname = def->name()->value(); - - if (defname == "name") - GetDefText(name, def, filename); - - else if (defname == "type") { - char typestr[64]; - GetDefText(typestr, def, filename); - type = TypeFromName(typestr); - } - - else if (defname == "system") { - char sysname[64]; - GetDefText(sysname, def, filename); - - Campaign* campaign = Campaign::GetCampaign(); - - if (campaign) { - Galaxy* galaxy = Galaxy::GetInstance(); - - if (galaxy) { - star_system = galaxy->GetSystem(sysname); - } - } - } - - else if (defname == "degrees") - GetDefBool(degrees, def, filename); - - else if (defname == "region") - GetDefText(region, def, filename); - - else if (defname == "objective") - GetDefText(objective, def, filename); - - else if (defname == "sitrep") - GetDefText(sitrep, def, filename); - - else if (defname == "start") - GetDefTime(start, def, filename); - - else if (defname == "team") - GetDefNumber(team, def, filename); - - else if (defname == "target") - GetDefText(target_name, def, filename); - - else if (defname == "ward") - GetDefText(ward_name, def, filename); - - else if ((defname == "alias")) { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: alias struct missing in '%s'\n", filename); - ok = false; - } - else { - TermStruct* val = def->term()->isStruct(); - ParseAlias(val); - } - } - - else if ((defname == "callsign")) { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: callsign struct missing in '%s'\n", filename); - ok = false; - } - else { - TermStruct* val = def->term()->isStruct(); - ParseCallsign(val); - } - } - - else if (defname == "optional") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: optional group struct missing in '%s'\n", filename); - ok = false; - } - else { - TermStruct* val = def->term()->isStruct(); - ParseOptional(val); - } - } - - else if (defname == "element") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: element struct missing in '%s'\n", filename); - ok = false; - } - else { - TermStruct* val = def->term()->isStruct(); - MissionElement* elem = ParseElement(val); - if (MapElement(elem)) { - AddElement(elem); - } - else { - Print("WARNING: failed to map element %s '%s' in '%s'\n", - elem->GetDesign() ? elem->GetDesign()->name : "NO DSN", - elem->Name().data(), - filename); - val->print(); - Print("\n"); - delete elem; - ok = false; - } - } - } - - else if (defname == "event") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: event struct missing in '%s'\n", filename); - ok = false; - } - else { - TermStruct* val = def->term()->isStruct(); - MissionEvent* event = ParseEvent(val); - - if (MapEvent(event)) - AddEvent(event); - } - } - } // def - } // term - } - while (term); - - loader->ReleaseBuffer(block); - - if (ok) { - CheckObjectives(); - - if (target_name[0]) - target = FindElement(target_name); - - if (ward_name[0]) - ward = FindElement(ward_name); - - Print("Mission Template Loaded.\n\n"); - } - - return ok; -} - -// +--------------------------------------------------------------------+ - -void -MissionTemplate::ParseAlias(TermStruct* val) -{ - Text name; - Text design; - Text code; - Text elem_name; - int iff = -1; - int player = 0; - RLoc* rloc = 0; - bool use_loc = false; - Vec3 loc; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") - GetDefText(name, pdef, filename); - - else if (defname == "elem") - GetDefText(elem_name, pdef, filename); - - else if (defname == "code") - GetDefText(code, pdef, filename); - - else if (defname == "design") - GetDefText(design, pdef, filename); - - else if (defname == "iff") - GetDefNumber(iff, pdef, filename); - - else if (defname == "loc") { - loc; - GetDefVec(loc, pdef, filename); - use_loc = true; - } - - else if (defname == "rloc") { - if (pdef->term()->isStruct()) { - rloc = ParseRLoc(pdef->term()->isStruct()); - } - } - - else if (defname == "player") { - GetDefNumber(player, pdef, filename); - - if (player && !code.length()) - code = "player"; - } - } - } - - MissionElement* elem = 0; - - // now find element and create alias: - if (name.length()) { - for (int i = 0; i < aliases.size(); i++) - if (aliases[i]->Name() == name) - return; - - // by element name? - if (elem_name.length()) { - elem = FindElement(elem_name); - } - - // by special code? - else if (code.length()) { - code.toLower(); - Campaign* campaign = Campaign::GetCampaign(); - - if (code == "player") { - for (int i = 0; !elem && i < elements.size(); i++) { - MissionElement* e = elements[i]; - if (e->Player() > 0) { - elem = e; - } - } - } - - else if (campaign && code == "player_carrier") { - CombatGroup* player_group = campaign->GetPlayerGroup(); - - if (player_group) { - CombatGroup* carrier = player_group->FindCarrier(); - - if (carrier) { - elem = FindElement(carrier->Name()); - } - } - } - - else if (campaign && code == "player_squadron") { - CombatGroup* player_group = player_squadron; - - if (!player_group) - player_group = campaign->GetPlayerGroup(); - - if (player_group && - (player_group->Type() == CombatGroup::INTERCEPT_SQUADRON || - player_group->Type() == CombatGroup::FIGHTER_SQUADRON || - player_group->Type() == CombatGroup::ATTACK_SQUADRON)) { - elem = FindElement(player_group->Name()); - } - } - - else if (campaign && code == "strike_target") { - CombatGroup* player_group = campaign->GetPlayerGroup(); - - if (player_group) { - CombatGroup* strike_target = campaign->FindStrikeTarget(player_group->GetIFF(), player_group); - - if (strike_target) { - elem = FindElement(strike_target->Name()); - } - } - } - } - - // by design and team? - else { - MissionElement* first_match = 0; - - for (int i = 0; !elem && i < elements.size(); i++) { - MissionElement* e = elements[i]; - if (e->GetIFF() == iff && design == e->GetDesign()->name) { - // do we already have an alias for this element? - bool found = false; - for (int a = 0; !found && a < aliases.size(); a++) - if (aliases[a]->Element() == e) - found = true; - - if (!found) - elem = e; - - else if (!first_match) - first_match = e; - } - } - - if (first_match && !elem) - elem = first_match; - } - - if (elem) { - if (rloc) elem->SetRLoc(*rloc); - else if (use_loc) elem->SetLocation(loc); - - delete rloc; - - aliases.append(new MissionAlias(name, elem)); - } - else { - ::Print("WARNING: Could not resolve mission alias '%s'\n", (const char*) name); - ok = false; - } - } - - if (!elem || !ok) return; - - // re-parse the struct, dealing with stuff - // that needs to be attached to the element: - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "objective") { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: order struct missing for element '%s' in '%s'\n", (const char*) elem->Name(), filename); - ok = false; - } - else { - TermStruct* val = pdef->term()->isStruct(); - Instruction* obj = ParseInstruction(val, elem); - elem->Objectives().append(obj); - } - } - - else if (defname == "instr") { - Text* obj = new Text; - if (GetDefText(*obj, pdef, filename)) - elem->Instructions().append(obj); - } - - else if (defname == "order" || defname == "navpt") { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: order struct missing for element '%s' in '%s'\n", (const char*) elem->Name(), filename); - ok = false; - } - else { - TermStruct* val = pdef->term()->isStruct(); - Instruction* npt = ParseInstruction(val, elem); - elem->NavList().append(npt); - } - } - - else if (defname == "loadout") { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: loadout struct missing for element '%s' in '%s'\n", (const char*) elem->Name(), filename); - ok = false; - } - else { - TermStruct* val = pdef->term()->isStruct(); - ParseLoadout(val, elem); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MissionTemplate::ParseCallsign(TermStruct* val) -{ - Text name; - int iff = -1; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") - GetDefText(name, pdef, filename); - - else if (defname == "iff") - GetDefNumber(iff, pdef, filename); - } - } - - if (name.length() > 0 && iff >= 0) - MapCallsign(name, iff); -} - -// +--------------------------------------------------------------------+ - -bool -MissionTemplate::ParseOptional(TermStruct* val) -{ - int n = 0; - int min = 0; - int max = 1000; - int skip = 0; - int total = val->elements()->size(); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "min") { - GetDefNumber(min, pdef, filename); - total--; - } - - else if (defname == "max") { - GetDefNumber(max, pdef, filename); - total--; - } - - - else if ((defname == "optional")) { - bool select; - - if (n >= max) - select = false; - else if (total - n - skip <= min) - select = true; - else - select = RandomChance(); - - if (select) { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: optional group struct missing in '%s'\n", filename); - ok = false; - skip++; - } - else { - TermStruct* val = pdef->term()->isStruct(); - if (ParseOptional(val)) - n++; - else - skip++; - } - } - else { - skip++; - } - } - - else if (defname == "element") { - bool select; - - if (n >= max) - select = false; - else if (total - n - skip <= min) - select = true; - else - select = RandomChance(); - - if (select) { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: element struct missing in '%s'\n", filename); - ok = false; - skip++; - } - else { - TermStruct* es = pdef->term()->isStruct(); - MissionElement* elem = ParseElement(es); - if (MapElement(elem)) { - AddElement(elem); - n++; - } - else { - delete elem; - skip++; - } - } - } - else { - skip++; - } - } - } - } - - return n > 0 && n >= min; -} - -// +--------------------------------------------------------------------+ - -void -MissionTemplate::CheckObjectives() -{ - ListIter iter = elements; - while (++iter) { - MissionElement* elem = iter.value(); - - ListIter obj = elem->Objectives(); - while (++obj) { - Instruction* o = obj.value(); - Text tgt = o->TargetName(); - - MissionElement* tgt_elem = 0; - - if (tgt.length()) { - tgt_elem = FindElement(tgt); - - if (!tgt_elem) - obj.removeItem(); - else - o->SetTarget(tgt_elem->Name()); - } - } - } -} diff --git a/Stars45/MissionTemplate.h b/Stars45/MissionTemplate.h deleted file mode 100644 index 44ef0ca..0000000 --- a/Stars45/MissionTemplate.h +++ /dev/null @@ -1,116 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simulation Universe and Region classes -*/ - -#ifndef MissionTemplate_h -#define MissionTemplate_h - -#include "Types.h" -#include "Mission.h" - -// +--------------------------------------------------------------------+ - -class MissionTemplate; -class MissionAlias; -class MissionCallsign; -class MissionEvent; - -// +--------------------------------------------------------------------+ - -class MissionTemplate : public Mission -{ -public: - static const char* TYPENAME() { return "MissionTemplate"; } - - MissionTemplate(int id, const char* filename=0, const char* path=0); - virtual ~MissionTemplate(); - - virtual bool Load(const char* filename=0, const char* path=0); - - // accessors/mutators: - virtual MissionElement* FindElement(const char* name); - virtual void AddElement(MissionElement* elem); - virtual bool MapElement(MissionElement* elem); - virtual Text MapShip(Text name); - virtual CombatGroup* GetPlayerSquadron() const { return player_squadron; } - virtual void SetPlayerSquadron(CombatGroup* ps) { player_squadron = ps; } - virtual Text MapCallsign(const char* name, int iff); - virtual bool MapEvent(MissionEvent* event); - - -protected: - CombatGroup* FindCombatGroup(int iff, const ShipDesign* dsn); - void ParseAlias(TermStruct* val); - void ParseCallsign(TermStruct* val); - bool ParseOptional(TermStruct* val); - void CheckObjectives(); - - List aliases; - List callsigns; - CombatGroup* player_squadron; -}; - -// +--------------------------------------------------------------------+ - -class MissionAlias -{ - friend class MissionTemplate; - -public: - static const char* TYPENAME() { return "MissionAlias"; } - - MissionAlias() : elem(0) { } - MissionAlias(const char* n, MissionElement* e) : name(n), elem(e) { } - virtual ~MissionAlias() { } - - int operator == (const MissionAlias& a) const { return name == a.name; } - - Text Name() const { return name; } - MissionElement* Element() const { return elem; } - - void SetName(const char* n) { name = n; } - void SetElement(MissionElement* e) { elem = e; } - -protected: - Text name; - MissionElement* elem; -}; - -// +--------------------------------------------------------------------+ - -class MissionCallsign -{ - friend class MissionTemplate; - -public: - static const char* TYPENAME() { return "MissionCallsign"; } - - MissionCallsign() { } - MissionCallsign(const char* c, const char* n) : call(c), name(n) { } - virtual ~MissionCallsign() { } - - int operator == (const MissionCallsign& a)const { return call == a.call; } - - Text Callsign() const { return call; } - Text Name() const { return name; } - - void SetCallsign(const char* c) { call = c; } - void SetName(const char* n) { name = n; } - -protected: - Text call; - Text name; -}; - - -#endif // MissionTemplate_h - diff --git a/Stars45/ModConfig.cpp b/Stars45/ModConfig.cpp deleted file mode 100644 index 3cc433e..0000000 --- a/Stars45/ModConfig.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mod file deployment configuration and manager -*/ - - -#include "ModConfig.h" -#include "ModInfo.h" -#include "Campaign.h" -#include "ShipDesign.h" -#include "WeaponDesign.h" -#include "Starshatter.h" -#include "ParseUtil.h" -#include "DataLoader.h" -#include "ContentBundle.h" - -// +-------------------------------------------------------------------+ - -static ModConfig* mod_config = 0; - -// +-------------------------------------------------------------------+ - -ModConfig::ModConfig() -{ - mod_config = this; - - Load(); - FindMods(); - Deploy(); -} - -ModConfig::~ModConfig() -{ - if (mod_config == this) - mod_config = 0; - - Undeploy(); - - enabled.destroy(); - disabled.destroy(); - mods.destroy(); -} - -// +-------------------------------------------------------------------+ - -void -ModConfig::Initialize() -{ - mod_config = new ModConfig; -} - -void -ModConfig::Close() -{ - delete mod_config; - mod_config = 0; -} - -// +-------------------------------------------------------------------+ - -ModConfig* -ModConfig::GetInstance() -{ - return mod_config; -} - -// +-------------------------------------------------------------------+ - -void -ModConfig::Load() -{ - // read the config file: - BYTE* block = 0; - int blocklen = 0; - - char filename[64]; - strcpy_s(filename, "mod.cfg"); - - FILE* f; - ::fopen_s(&f, 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); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "MOD_CONFIG") { - Print("WARNING: invalid '%s' file. No mods deployed\n", filename); - return; - } - } - - enabled.destroy(); - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - Text name; - GetDefText(name, def, filename); - enabled.append(new Text(name)); - } - } - } - while (term); - - delete [] block; -} - -void -ModConfig::Save() -{ - FILE* f; - fopen_s(&f, "mod.cfg", "wb"); - if (f) { - fprintf(f, "MOD_CONFIG\n\n"); - - ListIter iter = enabled; - while (++iter) { - Text* name = iter.value(); - fprintf(f, "mod: \"%s\"\n", name->data()); - } - - fclose(f); - } -} - -void -ModConfig::FindMods() -{ - disabled.destroy(); - - DataLoader* loader = DataLoader::GetLoader(); - - if (loader) { - loader->UseFileSystem(true); - loader->ListFiles("*.dat", disabled, true); - loader->UseFileSystem(Starshatter::UseFileSystem()); - - ListIter iter = disabled; - while (++iter) { - Text* name = iter.value(); - name->setSensitive(false); - - if (*name == "shatter.dat" || - *name == "beta.dat" || - *name == "start.dat" || - *name == "irunin.dat" || - *name == "vox.dat" || - name->contains("uninstall") || - enabled.contains(name)) - delete iter.removeItem(); - } - } -} - -// +-------------------------------------------------------------------+ - -ModInfo* -ModConfig::GetModInfo(const char* filename) -{ - for (int i = 0; i < mods.size(); i++) { - ModInfo* mod_info = mods[i]; - - if (mod_info->Filename() == filename && mod_info->IsEnabled()) - return mod_info; - } - - return NULL; -} - -// +-------------------------------------------------------------------+ - -bool -ModConfig::IsDeployed(const char* name) -{ - for (int i = 0; i < mods.size(); i++) { - ModInfo* mod_info = mods[i]; - - if (mod_info->Name() == name && mod_info->IsEnabled()) - return true; - } - - return false; -} - -// +-------------------------------------------------------------------+ - -void -ModConfig::Deploy() -{ - Save(); - - if (enabled.size() < 1) - return; - - Print("\nDEPLOYING MODS\n--------------\n"); - - int i = 1; - ListIter iter = enabled; - while (++iter) { - Text* name = iter.value(); - - if (IsDeployed(name->data())) { - Print(" %d. %s is already deployed (skipping)\n", i++, name->data()); - continue; - } - - Print(" %d. %s\n", i++, name->data()); - - ModInfo* mod_info = new ModInfo; - - if (mod_info->Load(name->data()) && mod_info->Enable()) { - mods.append(mod_info); - } - else { - Print(" Could not deploy '%s' - disabling\n", name->data()); - - delete mod_info; - iter.removeItem(); - disabled.append(name); - } - } - - Print("\n"); - ContentBundle::GetInstance()->UseLocale(nullptr); -} - -void -ModConfig::Undeploy() -{ - Print("UNDEPLOYING MODS\n"); - mods.destroy(); - - ShipDesign::ClearModCatalog(); - WeaponDesign::ClearModCatalog(); -} - -void -ModConfig::Redeploy() -{ - Undeploy(); - Deploy(); - - Campaign::Close(); - Campaign::Initialize(); - Campaign::SelectCampaign("Single Missions"); -} - -// +-------------------------------------------------------------------+ - -void -ModConfig::EnableMod(const char* name) -{ - if (!name || !*name) - return; - - Text* mod_name; - - ListIter iter = disabled; - while (++iter) { - Text* t = iter.value(); - - if (*t == name) { - mod_name = t; - iter.removeItem(); - break; - } - } - - if (mod_name) { - enabled.append(mod_name); - - if (!IsDeployed(*mod_name)) { - ModInfo* mod_info = new ModInfo; - - if (mod_info->Load(*mod_name) && mod_info->Enable()) { - mods.append(mod_info); - } - } - } -} - -void -ModConfig::DisableMod(const char* name) -{ - if (!name || !*name) - return; - - Text* mod_name; - - ListIter iter = enabled; - while (++iter) { - Text* t = iter.value(); - - if (*t == name) { - mod_name = t; - iter.removeItem(); - break; - } - } - - if (mod_name) { - disabled.append(mod_name); - - ListIter iter = mods; - while (++iter) { - ModInfo* mod_info = iter.value(); - if (mod_info->Name() == *mod_name) { - delete iter.removeItem(); - break; - } - } - } -} - -// +-------------------------------------------------------------------+ - -void -ModConfig::IncreaseModPriority(int mod_index) -{ - if (mod_index > 0 && mod_index < enabled.size()) { - Text* mod1 = enabled.at(mod_index-1); - Text* mod2 = enabled.at(mod_index); - - enabled.at(mod_index-1) = mod2; - enabled.at(mod_index) = mod1; - } -} - -void -ModConfig::DecreaseModPriority(int mod_index) -{ - if (mod_index >= 0 && mod_index < enabled.size()-1) { - Text* mod1 = enabled.at(mod_index); - Text* mod2 = enabled.at(mod_index+1); - - enabled.at(mod_index) = mod2; - enabled.at(mod_index+1) = mod1; - } -} - diff --git a/Stars45/ModConfig.h b/Stars45/ModConfig.h deleted file mode 100644 index 5b57589..0000000 --- a/Stars45/ModConfig.h +++ /dev/null @@ -1,74 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mod file deployment configuration and manager -*/ - - -#ifndef ModConfig_h -#define ModConfig_h - -#include "Types.h" -#include "Bitmap.h" -#include "Text.h" -#include "List.h" - -// +-------------------------------------------------------------------+ - -class ModConfig; -class ModInfo; -class ModCampaign; - -// +-------------------------------------------------------------------+ - -class ModConfig -{ -public: - static const char* TYPENAME() { return "ModConfig"; } - - ModConfig(); - ~ModConfig(); - - int operator == (const ModConfig& cfg) const { return this == &cfg; } - - static void Initialize(); - static void Close(); - static ModConfig* GetInstance(); - - void Load(); - void Save(); - void FindMods(); - - bool IsDeployed(const char* name); - void Deploy(); - void Undeploy(); - void Redeploy(); - - // these methods change the configuration only - // you must Redeploy() to have them take effect: - - void EnableMod(const char* name); - void DisableMod(const char* name); - void IncreaseModPriority(int mod_index); - void DecreaseModPriority(int mod_index); - - List& EnabledMods() { return enabled; } - List& DisabledMods() { return disabled; } - List& GetModInfoList() { return mods; } - - ModInfo* GetModInfo(const char* filename); - -private: - List enabled; - List disabled; - List mods; -}; - -#endif // ModConfig_h \ No newline at end of file diff --git a/Stars45/ModDlg.cpp b/Stars45/ModDlg.cpp deleted file mode 100644 index 45323a3..0000000 --- a/Stars45/ModDlg.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mod Config Dialog Active Window class -*/ - -#include "ModDlg.h" -#include "ModInfoDlg.h" -#include "BaseScreen.h" -#include "ModConfig.h" - -#include "Clock.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(ModDlg, OnIncrease); -DEF_MAP_CLIENT(ModDlg, OnDecrease); -DEF_MAP_CLIENT(ModDlg, OnEnable); -DEF_MAP_CLIENT(ModDlg, OnDisable); -DEF_MAP_CLIENT(ModDlg, OnSelectEnabled); -DEF_MAP_CLIENT(ModDlg, OnSelectDisabled); -DEF_MAP_CLIENT(ModDlg, OnAccept); -DEF_MAP_CLIENT(ModDlg, OnCancel); -DEF_MAP_CLIENT(ModDlg, OnAudio); -DEF_MAP_CLIENT(ModDlg, OnVideo); -DEF_MAP_CLIENT(ModDlg, OnOptions); -DEF_MAP_CLIENT(ModDlg, OnControls); -DEF_MAP_CLIENT(ModDlg, OnMod); - -// +--------------------------------------------------------------------+ - -ModDlg::ModDlg(Screen* s, FormDef& def, BaseScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -lst_disabled(0), lst_enabled(0), btn_enable(0), btn_disable(0), -btn_increase(0), btn_decrease(0), btn_accept(0), btn_cancel(0), -aud_btn(0), vid_btn(0), ctl_btn(0), opt_btn(0), mod_btn(0), -config(0), changed(false) -{ - config = ModConfig::GetInstance(); - Init(def); -} - -ModDlg::~ModDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -ModDlg::RegisterControls() -{ - btn_accept = (Button*) FindControl( 1); - btn_cancel = (Button*) FindControl( 2); - btn_enable = (Button*) FindControl(301); - btn_disable = (Button*) FindControl(302); - btn_increase = (Button*) FindControl(303); - btn_decrease = (Button*) FindControl(304); - - lst_disabled = (ListBox*) FindControl(201); - lst_enabled = (ListBox*) FindControl(202); - - if (btn_accept) - REGISTER_CLIENT(EID_CLICK, btn_accept, ModDlg, OnAccept); - - if (btn_cancel) - REGISTER_CLIENT(EID_CLICK, btn_cancel, ModDlg, OnCancel); - - if (lst_enabled) - REGISTER_CLIENT(EID_SELECT, lst_enabled, ModDlg, OnSelectEnabled); - - if (lst_disabled) - REGISTER_CLIENT(EID_SELECT, lst_disabled, ModDlg, OnSelectDisabled); - - if (btn_enable) { - REGISTER_CLIENT(EID_CLICK, btn_enable, ModDlg, OnEnable); - btn_enable->SetEnabled(false); - } - - if (btn_disable) { - REGISTER_CLIENT(EID_CLICK, btn_disable, ModDlg, OnDisable); - btn_disable->SetEnabled(false); - } - - if (btn_increase) { - char up_arrow[2]; - up_arrow[0] = Font::ARROW_UP; - up_arrow[1] = 0; - btn_increase->SetText(up_arrow); - btn_increase->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_increase, ModDlg, OnIncrease); - } - - if (btn_decrease) { - char dn_arrow[2]; - dn_arrow[0] = Font::ARROW_DOWN; - dn_arrow[1] = 0; - btn_decrease->SetText(dn_arrow); - btn_decrease->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_decrease, ModDlg, OnDecrease); - } - - vid_btn = (Button*) FindControl(901); - REGISTER_CLIENT(EID_CLICK, vid_btn, ModDlg, OnVideo); - - aud_btn = (Button*) FindControl(902); - REGISTER_CLIENT(EID_CLICK, aud_btn, ModDlg, OnAudio); - - ctl_btn = (Button*) FindControl(903); - REGISTER_CLIENT(EID_CLICK, ctl_btn, ModDlg, OnControls); - - opt_btn = (Button*) FindControl(904); - REGISTER_CLIENT(EID_CLICK, opt_btn, ModDlg, OnOptions); - - mod_btn = (Button*) FindControl(905); - if (mod_btn) - REGISTER_CLIENT(EID_CLICK, mod_btn, ModDlg, OnMod); -} - -// +--------------------------------------------------------------------+ - -void -ModDlg::Show() -{ - FormWindow::Show(); - UpdateLists(); - - if (vid_btn) vid_btn->SetButtonState(0); - if (aud_btn) aud_btn->SetButtonState(0); - if (ctl_btn) ctl_btn->SetButtonState(0); - if (opt_btn) opt_btn->SetButtonState(0); - if (mod_btn) mod_btn->SetButtonState(1); -} - -void -ModDlg::UpdateLists() -{ - config = ModConfig::GetInstance(); - - if (config && lst_disabled && lst_enabled) { - lst_disabled->ClearItems(); - lst_enabled->ClearItems(); - - ListIter iter_d = config->DisabledMods(); - while (++iter_d) { - Text* t = iter_d.value(); - lst_disabled->AddItem(*t); - } - - ListIter iter_e = config->EnabledMods(); - while (++iter_e) { - Text* t = iter_e.value(); - lst_enabled->AddItem(*t); - } - } - - if (btn_disable) - btn_disable->SetEnabled(false); - - if (btn_enable) - btn_enable->SetEnabled(false); - - if (btn_increase) - btn_increase->SetEnabled(false); - - if (btn_decrease) - btn_decrease->SetEnabled(false); -} - -// +--------------------------------------------------------------------+ - -void -ModDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - if (btn_accept && btn_accept->IsEnabled()) - OnAccept(0); - } -} - -// +--------------------------------------------------------------------+ - -void -ModDlg::OnSelectEnabled(AWEvent* event) -{ - static DWORD click_time = 0; - - if (lst_enabled) { - if (btn_disable) - btn_disable->SetEnabled(lst_enabled->GetSelCount() == 1); - - if (btn_increase) - btn_increase->SetEnabled(lst_enabled->GetSelection() > 0); - - if (btn_decrease) - btn_decrease->SetEnabled(lst_enabled->GetSelection() < lst_enabled->NumItems() - 1); - - // double-click: - if (Clock::GetInstance()->RealTime() - click_time < 350) { - if (lst_enabled->GetSelCount() == 1) { - int index = lst_enabled->GetSelection(); - Text mod_name = lst_enabled->GetItemText(index); - ModInfo* mod_info = config->GetModInfo(mod_name); - ModInfoDlg* mod_info_dlg = manager->GetModInfoDlg(); - - if (mod_info && mod_info_dlg) { - mod_info_dlg->SetModInfo(mod_info); - manager->ShowModInfoDlg(); - } - } - } - } - - click_time = Clock::GetInstance()->RealTime(); -} - -void -ModDlg::OnSelectDisabled(AWEvent* event) -{ - if (btn_enable && lst_disabled) { - btn_enable->SetEnabled(lst_disabled->GetSelCount() == 1); - } -} - -void -ModDlg::OnEnable(AWEvent* event) -{ - int index = lst_disabled->GetSelection(); - Text mod_name = lst_disabled->GetItemText(index); - - config->EnableMod(mod_name); - changed = true; - - UpdateLists(); - - ModInfo* mod_info = config->GetModInfo(mod_name); - ModInfoDlg* mod_info_dlg = manager->GetModInfoDlg(); - - if (mod_info && mod_info_dlg) { - mod_info_dlg->SetModInfo(mod_info); - manager->ShowModInfoDlg(); - } -} - -void -ModDlg::OnDisable(AWEvent* event) -{ - int index = lst_enabled->GetSelection(); - Text mod_name = lst_enabled->GetItemText(index); - - config->DisableMod(mod_name); - changed = true; - - UpdateLists(); -} - -void -ModDlg::OnIncrease(AWEvent* event) -{ - int index = lst_enabled->GetSelection(); - config->IncreaseModPriority(index--); - - UpdateLists(); - lst_enabled->SetSelected(index); - btn_disable->SetEnabled(true); - btn_increase->SetEnabled(index > 0); - btn_decrease->SetEnabled(index < lst_enabled->NumItems()-1); -} - -void -ModDlg::OnDecrease(AWEvent* event) -{ - int index = lst_enabled->GetSelection(); - config->DecreaseModPriority(index++); - - UpdateLists(); - lst_enabled->SetSelected(index); - btn_disable->SetEnabled(true); - btn_increase->SetEnabled(index > 0); - btn_decrease->SetEnabled(index < lst_enabled->NumItems()-1); -} - -// +--------------------------------------------------------------------+ - -void ModDlg::OnAudio(AWEvent* event) { manager->ShowAudDlg(); } -void ModDlg::OnVideo(AWEvent* event) { manager->ShowVidDlg(); } -void ModDlg::OnOptions(AWEvent* event) { manager->ShowOptDlg(); } -void ModDlg::OnControls(AWEvent* event) { manager->ShowCtlDlg(); } -void ModDlg::OnMod(AWEvent* event) { manager->ShowModDlg(); } - -// +--------------------------------------------------------------------+ - -void -ModDlg::Apply() -{ - if (changed) { - config->Save(); - config->FindMods(); - config->Redeploy(); - changed = false; - } -} - -void -ModDlg::Cancel() -{ - if (changed) { - config->Load(); - config->FindMods(); - config->Redeploy(); - changed = false; - } -} - -// +--------------------------------------------------------------------+ - -void -ModDlg::OnAccept(AWEvent* event) -{ - manager->ApplyOptions(); -} - -void -ModDlg::OnCancel(AWEvent* event) -{ - manager->CancelOptions(); -} diff --git a/Stars45/ModDlg.h b/Stars45/ModDlg.h deleted file mode 100644 index 1ebdf87..0000000 --- a/Stars45/ModDlg.h +++ /dev/null @@ -1,93 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mod Config Dialog Active Window class -*/ - -#ifndef ModDlg_h -#define ModDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class BaseScreen; -class Campaign; -class ModConfig; - -// +--------------------------------------------------------------------+ - -class ModDlg : public FormWindow -{ -public: - ModDlg(Screen* s, FormDef& def, BaseScreen* mgr); - virtual ~ModDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - - virtual void OnIncrease(AWEvent* event); - virtual void OnDecrease(AWEvent* event); - - virtual void OnSelectEnabled(AWEvent* event); - virtual void OnSelectDisabled(AWEvent* event); - - virtual void OnEnable(AWEvent* event); - virtual void OnDisable(AWEvent* event); - - virtual void OnAccept(AWEvent* event); - virtual void OnCancel(AWEvent* event); - - virtual void Apply(); - virtual void Cancel(); - - virtual void OnAudio(AWEvent* event); - virtual void OnVideo(AWEvent* event); - virtual void OnOptions(AWEvent* event); - virtual void OnControls(AWEvent* event); - virtual void OnMod(AWEvent* event); - -protected: - void UpdateLists(); - - BaseScreen* manager; - - ListBox* lst_disabled; - ListBox* lst_enabled; - - Button* btn_accept; - Button* btn_cancel; - Button* btn_enable; - Button* btn_disable; - Button* btn_increase; - Button* btn_decrease; - - Button* aud_btn; - Button* vid_btn; - Button* opt_btn; - Button* ctl_btn; - Button* mod_btn; - - ModConfig* config; - bool changed; -}; - -#endif // ModDlg_h - diff --git a/Stars45/ModInfo.cpp b/Stars45/ModInfo.cpp deleted file mode 100644 index 0c75ed1..0000000 --- a/Stars45/ModInfo.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Information block for describing and deploying third party mods -*/ - - -#include "ModInfo.h" -#include "Campaign.h" -#include "ShipDesign.h" -#include "ParseUtil.h" - -#include "Archive.h" -#include "DataLoader.h" -#include "Pcx.h" -#include "Bitmap.h" - -// +-------------------------------------------------------------------+ - -ModInfo::ModInfo() -: logo(0), distribute(false), enabled(false), catalog(0) -{ } - -ModInfo::ModInfo(const char* fname) -: logo(0), distribute(false), enabled(false), catalog(0) -{ - if (fname && *fname) { - Load(fname); - } -} - -ModInfo::ModInfo(const char* n, const char* v, const char* u) -: name(n), logo(0), version(v), url(u), distribute(false), enabled(false), catalog(0) -{ } - -ModInfo::~ModInfo() -{ - if (enabled) - Disable(); - - delete logo; - delete catalog; - campaigns.destroy(); -} - -// +-------------------------------------------------------------------+ - -bool -ModInfo::Load(const char* fname) -{ - bool ok = false; - - filename = fname; - DataArchive a(filename); - - int n = a.FindEntry("mod_info.def"); - if (n > -1) { - BYTE* buf = 0; - int len = a.ExpandEntry(n, buf, true); - - if (len > 0 && buf != 0) { - ok = ParseModInfo((const char*) buf); - delete [] buf; - } - } - - if (logoname.length()) { - PcxImage pcx; - - logo = new Bitmap; - - n = a.FindEntry(logoname); - if (n > -1) { - BYTE* buf = 0; - int len = a.ExpandEntry(n, buf, true); - - pcx.LoadBuffer(buf, len); - delete [] buf; - } - - // now copy the image into the bitmap: - if (pcx.bitmap) { - logo->CopyImage(pcx.width, pcx.height, pcx.bitmap); - } - - else if (pcx.himap) { - logo->CopyHighColorImage(pcx.width, pcx.height, pcx.himap); - } - - else { - logo->ClearImage(); - } - } - - return ok; -} - -bool -ModInfo::ParseModInfo(const char* block) -{ - bool ok = false; - Parser parser(new BlockReader(block)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'\n", filename.data()); - return ok; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "MOD_INFO") { - Print("ERROR: invalid mod_info file '%s'\n", filename.data()); - term->print(10); - return ok; - } - } - - ok = true; - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - Text defname = def->name()->value(); - - if (defname == "name") - GetDefText(name, def, filename); - - else if (defname == "desc" || defname == "description") - GetDefText(desc, def, filename); - - else if (defname == "author") - GetDefText(author, def, filename); - - else if (defname == "url") - GetDefText(url, def, filename); - - else if (defname == "copyright") - GetDefText(copyright, def, filename); - - else if (defname == "logo") - GetDefText(logoname, def, filename); - - else if (defname == "version") { - if (def->term()) { - if (def->term()->isNumber()) { - int v = 0; - char buf[32]; - GetDefNumber(v, def, filename); - sprintf_s(buf, "%d", v); - - version = buf; - } - - else if (def->term()->isText()) { - GetDefText(version, def, filename); - } - } - } - - else if (defname == "distribute") - GetDefBool(distribute, def, filename); - - else if (defname == "campaign") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: campaign structure missing in mod_info.def for '%s'\n", name.data()); - } - else { - TermStruct* val = def->term()->isStruct(); - - ModCampaign* c = new ModCampaign; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - defname = pdef->name()->value(); - - if (defname == "name") { - GetDefText(c->name, pdef, filename); - } - - else if (defname == "path") { - GetDefText(c->path, pdef, filename); - } - - else if (defname == "dynamic") { - GetDefBool(c->dynamic, pdef, filename); - } - } - } - - if (c->name.length() && c->path.length()) - campaigns.append(c); - else - delete c; - } - } - - else if (defname == "catalog") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: catalog structure missing in mod_info.def for '%s'\n", name.data()); - } - else { - TermStruct* val = def->term()->isStruct(); - - ModCatalog* c = new ModCatalog; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - defname = pdef->name()->value(); - - if (defname == "file") { - GetDefText(c->file, pdef, filename); - } - - else if (defname == "path") { - GetDefText(c->path, pdef, filename); - - char last_char = c->path[c->path.length()-1]; - - if (last_char != '/' && last_char != '\\') - c->path += "/"; - } - } - } - - if (c->file.length() && c->path.length() && !catalog) - catalog = c; - else - delete c; - } - } - } // def - } // term - } - while (term); - - return ok; -} - -// +-------------------------------------------------------------------+ - -bool -ModInfo::Enable() -{ - DataLoader* loader = DataLoader::GetLoader(); - - if (loader && !enabled) { - loader->EnableDatafile(filename); - enabled = true; - - if (catalog) - ShipDesign::LoadCatalog(catalog->Path(), catalog->File(), true); - - ShipDesign::LoadSkins("/Mods/Skins/", filename); - - for (int i = 0; i < campaigns.size(); i++) { - ModCampaign* c = campaigns[i]; - Campaign::CreateCustomCampaign(c->Name(), c->Path()); - } - } - - return enabled; -} - -bool -ModInfo::Disable() -{ - DataLoader* loader = DataLoader::GetLoader(); - - if (loader) { - loader->DisableDatafile(filename); - enabled = false; - } - - return !enabled; -} - -// +-------------------------------------------------------------------+ diff --git a/Stars45/ModInfo.h b/Stars45/ModInfo.h deleted file mode 100644 index 3ee2054..0000000 --- a/Stars45/ModInfo.h +++ /dev/null @@ -1,121 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Information block for describing and deploying third party mods -*/ - - -#ifndef ModInfo_h -#define ModInfo_h - -#include "Types.h" -#include "Bitmap.h" -#include "Text.h" -#include "List.h" - -// +-------------------------------------------------------------------+ - -class ModInfo; -class ModCampaign; -class ModCatalog; - -// +-------------------------------------------------------------------+ - -class ModInfo -{ -public: - static const char* TYPENAME() { return "ModInfo"; } - - ModInfo(); - ModInfo(const char* filename); - ModInfo(const char* name, const char* version, const char* url); - ~ModInfo(); - - int operator == (const ModInfo& m) const { return name.length() && name == m.name; } - - const Text& Name() const { return name; } - const Text& Description() const { return desc; } - const Text& Author() const { return author; } - const Text& URL() const { return url; } - const Text& Filename() const { return filename; } - const Text& Copyright() const { return copyright; } - Bitmap* LogoImage() const { return logo; } - const Text& Version() const { return version; } - bool Distribute() const { return distribute; } - bool IsEnabled() const { return enabled; } - - List& GetCampaigns() { return campaigns; } - - bool Load(const char* filename); - bool ParseModInfo(const char* buffer); - - bool Enable(); - bool Disable(); - -private: - Text name; - Text desc; - Text author; - Text url; - Text filename; - Text copyright; - Bitmap* logo; - Text logoname; - Text version; - bool distribute; - bool enabled; - - List campaigns; - ModCatalog* catalog; -}; - -// +-------------------------------------------------------------------+ - -class ModCampaign -{ - friend class ModInfo; - -public: - static const char* TYPENAME() { return "ModCampaign"; } - - ModCampaign() : dynamic(false) { } - ~ModCampaign() { } - - const Text& Name() const { return name; } - const Text& Path() const { return path; } - bool IsDynamic() const { return dynamic; } - -private: - Text name; - Text path; - bool dynamic; -}; - -// +-------------------------------------------------------------------+ - -class ModCatalog -{ - friend class ModInfo; - -public: - static const char* TYPENAME() { return "ModCatalog"; } - - ModCatalog() { } - ~ModCatalog() { } - - const Text& File() const { return file; } - const Text& Path() const { return path; } - -private: - Text file; - Text path; -}; - -#endif // ModInfo_h \ No newline at end of file diff --git a/Stars45/ModInfoDlg.cpp b/Stars45/ModInfoDlg.cpp deleted file mode 100644 index cebdc54..0000000 --- a/Stars45/ModInfoDlg.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mod Config Dialog Active Window class -*/ - -#include "ModInfoDlg.h" -#include "BaseScreen.h" -#include "ModConfig.h" -#include "ModInfo.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "ImageBox.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(ModInfoDlg, OnAccept); - -// +--------------------------------------------------------------------+ - -ModInfoDlg::ModInfoDlg(Screen* s, FormDef& def, BaseScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -btn_accept(0), mod_info(0) -{ - Init(def); -} - -ModInfoDlg::~ModInfoDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -ModInfoDlg::RegisterControls() -{ - btn_accept = (Button*) FindControl( 1); - - if (btn_accept) - REGISTER_CLIENT(EID_CLICK, btn_accept, ModInfoDlg, OnAccept); - - lbl_name = FindControl(101); - lbl_desc = FindControl(102); - lbl_copy = FindControl(103); - - img_logo = (ImageBox*) FindControl(200); - - if (img_logo) { - img_logo->GetPicture(bmp_default); - img_logo->SetBlendMode(Video::BLEND_SOLID); - } -} - -// +--------------------------------------------------------------------+ - -void -ModInfoDlg::Show() -{ - FormWindow::Show(); -} - -// +--------------------------------------------------------------------+ - -void -ModInfoDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - if (btn_accept && btn_accept->IsEnabled()) - OnAccept(0); - } -} - -// +--------------------------------------------------------------------+ - -void -ModInfoDlg::SetModInfo(ModInfo* info) -{ - mod_info = info; - - if (mod_info) { - if (lbl_name) lbl_name->SetText(mod_info->Name()); - if (lbl_desc) lbl_desc->SetText(mod_info->Description()); - if (lbl_copy) lbl_copy->SetText(mod_info->Copyright()); - - if (img_logo && mod_info->LogoImage() && mod_info->LogoImage()->Width() > 32) - img_logo->SetPicture(*mod_info->LogoImage()); - else if (img_logo) - img_logo->SetPicture(bmp_default); - } -} - -// +--------------------------------------------------------------------+ - -void -ModInfoDlg::OnAccept(AWEvent* event) -{ - manager->ShowModDlg(); -} diff --git a/Stars45/ModInfoDlg.h b/Stars45/ModInfoDlg.h deleted file mode 100644 index 656e012..0000000 --- a/Stars45/ModInfoDlg.h +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mod Info Splash Dialog Active Window class -*/ - -#ifndef ModInfoDlg_h -#define ModInfoDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class BaseScreen; -class ModConfig; -class ModInfo; - -// +--------------------------------------------------------------------+ - -class ModInfoDlg : public FormWindow -{ -public: - ModInfoDlg(Screen* s, FormDef& def, BaseScreen* mgr); - virtual ~ModInfoDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void SetModInfo(ModInfo* info); - virtual void OnAccept(AWEvent* event); - -protected: - BaseScreen* manager; - - ActiveWindow* lbl_name; - ActiveWindow* lbl_desc; - ActiveWindow* lbl_copy; - ImageBox* img_logo; - - Button* btn_accept; - - ModInfo* mod_info; - - Bitmap bmp_default; -}; - -#endif // ModInfoDlg_h - diff --git a/Stars45/MotionController.h b/Stars45/MotionController.h deleted file mode 100644 index 11c0977..0000000 --- a/Stars45/MotionController.h +++ /dev/null @@ -1,230 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract MotionController class (hides details of Joystick, Keyboard, etc.) -*/ - -#ifndef MoCon_h -#define MoCon_h - -// +--------------------------------------------------------------------+ - -struct KeyMapEntry -{ - static const char* TYPENAME() { return "KeyMapEntry"; } - - KeyMapEntry() : act(0), key(0), alt(0), joy(0) { } - KeyMapEntry(int a, int k, int s=0, int j=0) : act(a), key(k), alt(s), joy(j) { } - - int operator==(const KeyMapEntry& k) const { return act==k.act && key==k.key && alt==k.alt && joy==k.joy; } - int operator!=(const KeyMapEntry& k) const { return !(*this==k); } - - int act; - int key; - int alt; - int joy; -}; - -// +--------------------------------------------------------------------+ - -const int KEY_MAP_SIZE = 256; -const int KEY_BASE_SIZE = 64; -const int KEY_USER_SIZE = KEY_MAP_SIZE - KEY_BASE_SIZE; - -const int KEY_MAP_BASE = 0; -const int KEY_MAP_END = KEY_MAP_BASE + KEY_BASE_SIZE - 1; - -const int KEY_USER_BASE = KEY_MAP_END + 1; -const int KEY_USER_END = KEY_USER_BASE + KEY_USER_SIZE - 1; - -const int KEY_MAP_FIRST = KEY_MAP_BASE; -const int KEY_MAP_LAST = KEY_MAP_BASE + KEY_MAP_SIZE - 1; - -// MAP NAMES: - -const int KEY_PLUS_X = 1; -const int KEY_MINUS_X = 2; -const int KEY_PLUS_Y = 3; -const int KEY_MINUS_Y = 4; -const int KEY_PLUS_Z = 5; -const int KEY_MINUS_Z = 6; - -const int KEY_PITCH_UP = 7; -const int KEY_PITCH_DOWN = 8; -const int KEY_YAW_LEFT = 9; -const int KEY_YAW_RIGHT = 10; -const int KEY_ROLL_LEFT = 11; -const int KEY_ROLL_RIGHT = 12; -const int KEY_CENTER = 13; -const int KEY_ROLL_ENABLE = 14; - -const int KEY_ACTION_0 = 15; -const int KEY_ACTION_1 = 16; -const int KEY_ACTION_2 = 17; -const int KEY_ACTION_3 = 18; - -const int KEY_CONTROL_MODEL = 19; -const int KEY_MOUSE_SELECT = 20; -const int KEY_MOUSE_SENSE = 21; -const int KEY_MOUSE_SWAP = 22; -const int KEY_MOUSE_INVERT = 23; -const int KEY_MOUSE_ACTIVE = 24; - -const int KEY_JOY_SELECT = 25; -const int KEY_JOY_THROTTLE = 26; -const int KEY_JOY_RUDDER = 27; -const int KEY_JOY_SENSE = 28; -const int KEY_JOY_DEAD_ZONE = 29; -const int KEY_JOY_SWAP = 30; - -const int KEY_AXIS_YAW = 32; -const int KEY_AXIS_PITCH = 33; -const int KEY_AXIS_ROLL = 34; -const int KEY_AXIS_THROTTLE = 35; - -const int KEY_AXIS_YAW_INVERT = 38; -const int KEY_AXIS_PITCH_INVERT = 39; -const int KEY_AXIS_ROLL_INVERT = 40; -const int KEY_AXIS_THROTTLE_INVERT = 41; - - -// CONTROL VALUES: - -// joystick buttons and switches must use -// ids greater than 255 so they don't interfere -// with extended ascii numbers for keyboard keys - -const int KEY_JOY_AXIS_X = 0x1A0; -const int KEY_JOY_AXIS_Y = 0x1A1; -const int KEY_JOY_AXIS_Z = 0x1A2; -const int KEY_JOY_AXIS_RX = 0x1A3; -const int KEY_JOY_AXIS_RY = 0x1A4; -const int KEY_JOY_AXIS_RZ = 0x1A5; -const int KEY_JOY_AXIS_S0 = 0x1A6; -const int KEY_JOY_AXIS_S1 = 0x1A7; - -const int KEY_JOY_1 = 0x1C1; -const int KEY_JOY_2 = 0x1C2; -const int KEY_JOY_3 = 0x1C3; -const int KEY_JOY_4 = 0x1C4; -const int KEY_JOY_5 = 0x1C5; -const int KEY_JOY_6 = 0x1C6; -const int KEY_JOY_7 = 0x1C7; -const int KEY_JOY_8 = 0x1C8; -const int KEY_JOY_9 = 0x1C9; -const int KEY_JOY_10 = 0x1CA; -const int KEY_JOY_11 = 0x1CB; -const int KEY_JOY_12 = 0x1CC; -const int KEY_JOY_13 = 0x1CD; -const int KEY_JOY_14 = 0x1CE; -const int KEY_JOY_15 = 0x1CF; -const int KEY_JOY_16 = 0x1D0; - -const int KEY_JOY_32 = 0x1E0; - -const int KEY_POV_0_UP = 0x1F0; -const int KEY_POV_0_DOWN = 0x1F1; -const int KEY_POV_0_LEFT = 0x1F2; -const int KEY_POV_0_RIGHT = 0x1F3; - -const int KEY_POV_1_UP = 0x1F4; -const int KEY_POV_1_DOWN = 0x1F5; -const int KEY_POV_1_LEFT = 0x1F6; -const int KEY_POV_1_RIGHT = 0x1F7; - -const int KEY_POV_2_UP = 0x1F8; -const int KEY_POV_2_DOWN = 0x1F9; -const int KEY_POV_2_LEFT = 0x1FA; -const int KEY_POV_2_RIGHT = 0x1FB; - -const int KEY_POV_3_UP = 0x1FC; -const int KEY_POV_3_DOWN = 0x1FD; -const int KEY_POV_3_LEFT = 0x1FE; -const int KEY_POV_3_RIGHT = 0x1FF; - -// +--------------------------------------------------------------------+ - -class MotionController -{ -public: - static const char* TYPENAME() { return "MotionController"; } - - MotionController() - : status(StatusOK), sensitivity(1), dead_zone(0), - swapped(0), inverted(0), rudder(0), throttle(0), select(0) { } - - virtual ~MotionController() { } - - enum StatusValue { StatusOK, StatusErr, StatusBadParm }; - enum ActionValue { MaxActions = 32 }; - - StatusValue Status() const { return status; } - int Sensitivity() const { return sensitivity; } - int DeadZone() const { return dead_zone; } - int Swapped() const { return swapped; } - int Inverted() const { return inverted; } - int RudderEnabled() const { return rudder; } - int ThrottleEnabled() const { return throttle; } - int Selector() const { return select; } - - - // setup: - virtual void SetSensitivity(int sense, int dead) - { - if (sense > 0) sensitivity = sense; - if (dead > 0) dead_zone = dead; - } - - virtual void SetSelector(int sel) { select = sel; } - virtual void SetRudderEnabled(int rud) { rudder = rud; } - virtual void SetThrottleEnabled(int t) { throttle = t; } - - virtual void SwapYawRoll(int swap) { swapped = swap; } - virtual int GetSwapYawRoll() { return swapped; } - virtual void InvertPitch(int inv) { inverted = inv; } - virtual int GetInverted() { return inverted; } - - virtual void MapKeys(KeyMapEntry* mapping, int nkeys) { } - - // sample the physical device - virtual void Acquire() { } - - // translations - virtual double X() { return 0; } - virtual double Y() { return 0; } - virtual double Z() { return 0; } - - // rotations - virtual double Pitch() { return 0; } - virtual double Roll() { return 0; } - virtual double Yaw() { return 0; } - virtual int Center() { return 0; } - - // throttle - virtual double Throttle() { return 0; } - virtual void SetThrottle(double t) { } - - // actions - virtual int Action(int n) { return 0; } - virtual int ActionMap(int n) { return 0; } - -protected: - StatusValue status; - int sensitivity; - int dead_zone; - int swapped; - int inverted; - int rudder; - int throttle; - int select; -}; - -#endif // MoCon_h - diff --git a/Stars45/Mouse.cpp b/Stars45/Mouse.cpp deleted file mode 100644 index c772bc2..0000000 --- a/Stars45/Mouse.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mouse class -*/ - -#include "Mouse.h" -#include "DataLoader.h" -#include "Window.h" -#include "Screen.h" -#include "Bitmap.h" -#include "Video.h" - -// +--------------------------------------------------------------------+ - -int Mouse::show = 1; -int Mouse::cursor = Mouse::ARROW; - -int Mouse::x = 320; -int Mouse::y = 240; -int Mouse::l = 0; -int Mouse::m = 0; -int Mouse::r = 0; -int Mouse::w = 0; - -Bitmap* Mouse::image[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -int Mouse::hotspot[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -Window* Mouse::window = 0; - -// +--------------------------------------------------------------------+ - -void Mouse::Create(Screen* screen) -{ - if (screen) { - delete window; - window = new Window(screen, 0, 0, screen->Width(), screen->Height()); - } -} - -// +--------------------------------------------------------------------+ - -void Mouse::Resize(Screen* screen) -{ - if (screen) { - delete window; - window = new Window(screen, 0, 0, screen->Width(), screen->Height()); - } -} - -// +--------------------------------------------------------------------+ - -void Mouse::Close() -{ - for (int i = 0; i < 8; i++) { - delete image[i]; - image[i] = 0; - } - - delete window; - window = 0; - - show = 0; - cursor = ARROW; -} - -// +--------------------------------------------------------------------+ - -void -Mouse::SetCursorPos(int ax, int ay) -{ - POINT p; - int dx = 0; - int dy = 0; - - ::GetCursorPos(&p); - - dx = p.x - x; - dy = p.y - y; - - x = ax; - y = ay; - - ::SetCursorPos(x+dx,y+dy); -} - -// +--------------------------------------------------------------------+ - -int -Mouse::SetCursor(CURSOR c) -{ - int old = cursor; - cursor = c; - return old; -} - -// +--------------------------------------------------------------------+ - -int -Mouse::LoadCursor(CURSOR c, const char* name, HOTSPOT hs) -{ - int result = 0; - - delete image[c]; - image[c] = 0; - - if (name && *name) { - image[c] = new Bitmap; - result = DataLoader::GetLoader()->LoadBitmap(name, *image[c], Bitmap::BMP_TRANSPARENT); - - if (result) { - Bitmap* bmp = image[c]; - - if (bmp && bmp->HiPixels()) - image[c]->CopyAlphaRedChannel(image[c]->Width(), image[c]->Height(), (LPDWORD) image[c]->HiPixels()); - - hotspot[c] = hs; - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -void -Mouse::Show(int s) -{ - show = s; -} - -// +--------------------------------------------------------------------+ - -void -Mouse::Paint() -{ - if (!show || !window) return; - - // draw using bitmap: - if (image[cursor]) { - int w2 = image[cursor]->Width()/2; - int h2 = image[cursor]->Height()/2; - - if (hotspot[cursor] == HOTSPOT_NW) - window->DrawBitmap(x, y, x+w2*2, y+h2*2, image[cursor], Video::BLEND_ALPHA); - else - window->DrawBitmap(x-w2, y-h2, x+w2, y+h2, image[cursor], Video::BLEND_ALPHA); - } - - // draw using primitives: - /*** -else { - switch (cursor) { - case ARROW: - case CROSS: - case USER1: - case USER2: - case USER3: - default: - window->DrawLine(x-7, y, x+8, y, Color::White); - window->DrawLine(x, y-7, x, y+8, Color::White); - break; - - case WAIT: - window->DrawLine(x-7, y-7, x+8, y-7, Color::White); - window->DrawLine(x-7, y-7, x+8, y+8, Color::White); - window->DrawLine(x-7, y+8, x+8, y-7, Color::White); - window->DrawLine(x-7, y+8, x+8, y+8, Color::White); - break; - - case NOT: - window->DrawEllipse(x-7,y-7,x+8,y+8, Color::White); - window->DrawLine( x-7,y-7,x+8,y+8, Color::White); - break; - - case DRAG: - window->DrawRect(x-7, y-6, x+8, y-3, Color::White); - window->DrawRect(x-7, y-1, x+8, y+2, Color::White); - window->DrawRect(x-7, y+4, x+8, y+7, Color::White); - break; - } -} -***/ -} diff --git a/Stars45/Mouse.h b/Stars45/Mouse.h deleted file mode 100644 index e9f6a18..0000000 --- a/Stars45/Mouse.h +++ /dev/null @@ -1,74 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mouse class -*/ - -#ifndef Mouse_h -#define Mouse_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class Bitmap; -class Screen; -class Window; - -// +--------------------------------------------------------------------+ - -class Mouse -{ - friend LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); - friend class Game; - -public: - static const char* TYPENAME() { return "Mouse"; } - - enum CURSOR { ARROW, CROSS, WAIT, NOT, DRAG, USER1, USER2, USER3 }; - enum HOTSPOT { HOTSPOT_CTR, HOTSPOT_NW }; - - static int X() { return x; } - static int Y() { return y; } - static int LButton() { return l; } - static int MButton() { return m; } - static int RButton() { return r; } - static int Wheel() { return w; } - - static void Paint(); - - static void SetCursorPos(int x, int y); - static void Show(int s=1); - static int SetCursor(CURSOR c); - static int LoadCursor(CURSOR c, const char* name, HOTSPOT hs = HOTSPOT_CTR); - - static void Create(Screen* screen); - static void Resize(Screen* screen); - static void Close(); - -private: - static int show; - static int cursor; - - static int x; - static int y; - static int l; - static int m; - static int r; - static int w; - - static Bitmap* image[8]; - static int hotspot[8]; - - static Window* window; -}; - -#endif // Mouse_h - diff --git a/Stars45/MouseController.cpp b/Stars45/MouseController.cpp deleted file mode 100644 index 75fd0f5..0000000 --- a/Stars45/MouseController.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - MouseController Input class -*/ - -#include "MouseController.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Clock.h" -#include "Video.h" - -// +--------------------------------------------------------------------+ - -static MouseController* instance = 0; -static DWORD rbutton_latch = 0; -static DWORD mbutton_latch = 0; -static DWORD active_latch = 0; - -// +--------------------------------------------------------------------+ - -MouseController::MouseController() -: p(0), r(0), w(0), dx(0), dy(0), t(0) -{ - instance = this; - select = 0; - sensitivity = 10; - swapped = 0; - active = false; - - active_key = 20; // caps lock - - rbutton_latch = 0; - - for (int i = 0; i < MotionController::MaxActions; i++) - action[i] = 0; -} - -MouseController::~MouseController() -{ - instance = 0; -} - -MouseController* -MouseController::GetInstance() -{ - return instance; -} - -// +--------------------------------------------------------------------+ - -void -MouseController::MapKeys(KeyMapEntry* mapping, int nkeys) -{ - for (int i = 0; i < nkeys; i++) { - KeyMapEntry k = mapping[i]; - - if (k.act >= KEY_MAP_FIRST && k.act <= KEY_MAP_LAST) { - - if (k.act == KEY_MOUSE_SENSE) - sensitivity = k.key; - - else if (k.act == KEY_MOUSE_SWAP) - swapped = k.key; - - else if (k.act == KEY_MOUSE_INVERT) - inverted = k.key; - - else if (k.act == KEY_MOUSE_SELECT) - select = k.key; - - else if (k.act == KEY_MOUSE_ACTIVE) - active_key = k.key; - } - } -} - -// +--------------------------------------------------------------------+ - -static inline double sqr(double a) { return a*a; } - -void -MouseController::Acquire() -{ - p = r = w = 0; - action[0] = 0; - action[1] = 0; - action[2] = 0; - action[3] = 0; - - if (active_key && Keyboard::KeyDown(active_key)) { - active_latch = 1; - } - else { - if (active_latch) { - active_latch = 0; - active = !active; - } - } - - if (!select || !active) - return; - - action[0] = Mouse::LButton(); - - int roll_enable = 0; - - if (Mouse::RButton()) { - roll_enable = 1; - - if (!rbutton_latch) - rbutton_latch = Clock::GetInstance()->RealTime(); - } - else { - if (rbutton_latch) { - rbutton_latch = Clock::GetInstance()->RealTime() - rbutton_latch; - if (rbutton_latch < 250) - action[1] = 1; - } - - rbutton_latch = 0; - } - - if (Mouse::MButton()) { - if (!mbutton_latch) - mbutton_latch = Clock::GetInstance()->RealTime(); - } - else { - if (mbutton_latch) { - action[3] = 1; - } - - mbutton_latch = 0; - } - - double step = 0; - int cx = Video::GetInstance()->Width()/2; - int cy = Video::GetInstance()->Height()/2; - - dx += Mouse::X() - cx; - dy += Mouse::Y() - cy; - - step = fabs(dx)/cx; - - if (roll_enable || select == 1) - step *= 3 * sensitivity; - else - step *= step * sensitivity/4; - - if (roll_enable) { - if (dx > 0) - r = -step; - else if (dx < 0) - r = step; - } - else { - if (dx > 0) - w = step; - else if (dx < 0) - w = -step; - } - - step = fabs(dy)/cy; - - if (select == 1) - step *= 2 * sensitivity; - else - step *= step * sensitivity/4; - - if (inverted) { - step *= -1; - } - - if (dy > 0) - p = step; - else if (dy < 0) - p = -step; - - if (select == 1) { - ::SetCursorPos(cx, cy); - - double drain = cx * 4 * Clock::GetInstance()->Delta(); - - if (dx > drain) { - dx -= drain; - } - else if (dx < -drain) { - dx += drain; - } - else { - dx = 0; - } - - if (dy > drain) { - dy -= drain; - } - else if (dy < -drain) { - dy += drain; - } - else { - dy = 0; - } - } - else { - dx = 0; - dy = 0; - } - - if (Mouse::Wheel() > 0) { - if (t < 0.25) - t += 0.025; - else - t += 0.1; - - if (t > 1) t = 1; - } - - else if (Mouse::Wheel() < 0) { - if (t < 0.25) - t -= 0.025; - else - t -= 0.1; - - if (t < 0) t = 0; - } -} - -// +--------------------------------------------------------------------+ - -int -MouseController::ActionMap(int n) -{ - if (n >= KEY_ACTION_0 && n <= KEY_ACTION_3) - return action[n - KEY_ACTION_0]; - - return 0; -} - diff --git a/Stars45/MouseController.h b/Stars45/MouseController.h deleted file mode 100644 index 7d66329..0000000 --- a/Stars45/MouseController.h +++ /dev/null @@ -1,69 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Joystick Input class -*/ - -#ifndef MouseController_h -#define MouseController_h - -#include "MotionController.h" - -// +--------------------------------------------------------------------+ - -class MouseController : public MotionController -{ -public: - static const char* TYPENAME() { return "MouseController"; } - - MouseController(); - virtual ~MouseController(); - - // setup - virtual void MapKeys(KeyMapEntry* mapping, int nkeys); - - // sample the physical device - virtual void Acquire(); - - // translations - virtual double X() { return 0; } - virtual double Y() { return 0; } - virtual double Z() { return 0; } - - // rotations - virtual double Pitch() { if (active) return p; return 0; } - virtual double Roll() { if (active) return r; return 0; } - virtual double Yaw() { if (active) return w; return 0; } - virtual int Center() { return 0; } - - // throttle - virtual double Throttle() { if (active) return t; return 0; } - virtual void SetThrottle(double throttle) { t = throttle; } - - // actions - virtual int Action(int n) { return action[n]; } - virtual int ActionMap(int n); - - // actively sampling? - virtual bool Active() { return active; } - virtual void SetActive(bool a) { active = a; } - - static MouseController* GetInstance(); - -protected: - double p,r,w, dx, dy, t; - int action[MotionController::MaxActions]; - int map[32]; - bool active; - int active_key; -}; - -#endif // MouseController_h - diff --git a/Stars45/MsnDlg.cpp b/Stars45/MsnDlg.cpp deleted file mode 100644 index 4d2bfba..0000000 --- a/Stars45/MsnDlg.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#include "MsnDlg.h" -#include "PlanScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Mission.h" -#include "Instruction.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "StarSystem.h" - -#include "NetLobby.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "FormWindow.h" -#include "FormatUtil.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "Panic.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ - -MsnDlg::MsnDlg(PlanScreen* mgr) -: plan_screen(mgr), -commit(0), cancel(0), campaign(0), mission(0), -pkg_index(-1), info(0) -{ - campaign = Campaign::GetCampaign(); - - if (campaign) - mission = campaign->GetMission(); - - mission_name = 0; - mission_system = 0; - mission_sector = 0; - mission_time_start = 0; - mission_time_target = 0; - mission_time_target_label = 0; - - sit_button = 0; - pkg_button = 0; - nav_button = 0; - wep_button = 0; - commit = 0; - cancel = 0; -} - -MsnDlg::~MsnDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MsnDlg::RegisterMsnControls(FormWindow* win) -{ - mission_name = win->FindControl(200); - mission_system = win->FindControl(202); - mission_sector = win->FindControl(204); - mission_time_start = win->FindControl(206); - mission_time_target = win->FindControl(208); - mission_time_target_label = win->FindControl(207); - - sit_button = (Button*) win->FindControl(900); - pkg_button = (Button*) win->FindControl(901); - nav_button = (Button*) win->FindControl(902); - wep_button = (Button*) win->FindControl(903); - commit = (Button*) win->FindControl(1); - cancel = (Button*) win->FindControl(2); -} - -// +--------------------------------------------------------------------+ - -void -MsnDlg::ShowMsnDlg() -{ - campaign = Campaign::GetCampaign(); - - mission = 0; - pkg_index = -1; - - if (campaign) { - mission = campaign->GetMission(); - - if (!mission) - ::Print("ERROR - MsnDlg::Show() no mission.\n"); - else - ::Print("MsnDlg::Show() mission id = %d name = '%s'\n", - mission->Identity(), - mission->Name()); - } - else { - ::Print("ERROR - MsnDlg::Show() no campaign.\n"); - } - - if (mission_name) { - if (mission) - mission_name->SetText(mission->Name()); - else - mission_name->SetText(ContentBundle::GetInstance()->GetText("MsnDlg.no-mission")); - } - - if (mission_system) { - mission_system->SetText(""); - - if (mission) { - StarSystem* sys = mission->GetStarSystem(); - - if (sys) - mission_system->SetText(sys->Name()); - } - } - - if (mission_sector) { - mission_sector->SetText(""); - - if (mission) { - mission_sector->SetText(mission->GetRegion()); - } - } - - if (mission_time_start) { - if (mission) { - char txt[32]; - FormatDayTime(txt, mission->Start()); - mission_time_start->SetText(txt); - } - } - - if (mission_time_target) { - int time_on_target = CalcTimeOnTarget(); - - if (time_on_target) { - char txt[32]; - FormatDayTime(txt, time_on_target); - mission_time_target->SetText(txt); - mission_time_target_label->SetText(ContentBundle::GetInstance()->GetText("MsnDlg.target")); - } - else { - mission_time_target->SetText(""); - mission_time_target_label->SetText(""); - } - } - - - if (sit_button) { - sit_button->SetButtonState(plan_screen->IsMsnObjShown()); - sit_button->SetEnabled(true); - } - - if (pkg_button) { - pkg_button->SetButtonState(plan_screen->IsMsnPkgShown()); - pkg_button->SetEnabled(true); - } - - if (nav_button) { - nav_button->SetButtonState(plan_screen->IsNavShown()); - nav_button->SetEnabled(true); - } - - if (wep_button) { - wep_button->SetButtonState(plan_screen->IsMsnWepShown()); - wep_button->SetEnabled(true); - } - - bool mission_ok = true; - - if (!mission || !mission->IsOK()) { - mission_ok = false; - - if (sit_button) sit_button->SetEnabled(false); - if (pkg_button) pkg_button->SetEnabled(false); - if (nav_button) nav_button->SetEnabled(false); - if (wep_button) wep_button->SetEnabled(false); - } - else { - MissionElement* player_elem = mission->GetPlayer(); - - if (wep_button && player_elem) - wep_button->SetEnabled(player_elem->Loadouts().size() > 0); - } - - if (wep_button && NetLobby::GetInstance()) - wep_button->SetEnabled(false); - - commit->SetEnabled(mission_ok); - cancel->SetEnabled(true); -} - -// +--------------------------------------------------------------------+ - -int -MsnDlg::CalcTimeOnTarget() -{ - if (mission) { - MissionElement* element = mission->GetElements()[0]; - if (element) { - Point loc = element->Location(); - loc.SwapYZ(); // navpts use Z for altitude, element loc uses Y for altitude. - - int mission_time = mission->Start(); - - int i = 0; - ListIter navpt = element->NavList(); - while (++navpt) { - int action = navpt->Action(); - - double dist = Point(loc - navpt->Location()).length(); - - int etr = 0; - - if (navpt->Speed() > 0) - etr = (int) (dist / navpt->Speed()); - else - etr = (int) (dist / 500); - - mission_time += etr; - - loc = navpt->Location(); - i++; - - if (action >= Instruction::ESCORT) { // this is the target! - return mission_time; - } - } - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -MsnDlg::OnTabButton(AWEvent* event) -{ - if (event->window == sit_button) { - plan_screen->ShowMsnObjDlg(); - } - - if (event->window == pkg_button) { - plan_screen->ShowMsnPkgDlg(); - } - - if (event->window == nav_button) { - plan_screen->ShowNavDlg(); - } - - if (event->window == wep_button) { - plan_screen->ShowMsnWepDlg(); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnDlg::OnCommit(AWEvent* event) -{ - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - Mouse::Show(false); - stars->SetGameMode(Starshatter::LOAD_MODE); - } - - else - Panic::Panic("MsnDlg::OnCommit() - Game instance not found"); -} - -void -MsnDlg::OnCancel(AWEvent* event) -{ - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - Mouse::Show(false); - - if (campaign && (campaign->IsDynamic() || campaign->IsTraining())) - stars->SetGameMode(Starshatter::CMPN_MODE); - else - stars->SetGameMode(Starshatter::MENU_MODE); - } - - else - Panic::Panic("MsnDlg::OnCancel() - Game instance not found"); -} diff --git a/Stars45/MsnDlg.h b/Stars45/MsnDlg.h deleted file mode 100644 index 44b3231..0000000 --- a/Stars45/MsnDlg.h +++ /dev/null @@ -1,72 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#ifndef MsnDlg_h -#define MsnDlg_h - -#include "Types.h" -#include "Bitmap.h" -#include "Button.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class FormWindow; -class PlanScreen; -class Campaign; -class Mission; -class MissionInfo; - -// +--------------------------------------------------------------------+ - -class MsnDlg -{ -public: - MsnDlg(PlanScreen* mgr); - virtual ~MsnDlg(); - - void RegisterMsnControls(FormWindow* win); - void ShowMsnDlg(); - - // Operations: - virtual void OnCommit(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnTabButton(AWEvent* event); - -protected: - virtual int CalcTimeOnTarget(); - - PlanScreen* plan_screen; - Button* commit; - Button* cancel; - Button* sit_button; - Button* pkg_button; - Button* nav_button; - Button* wep_button; - - ActiveWindow* mission_name; - ActiveWindow* mission_system; - ActiveWindow* mission_sector; - ActiveWindow* mission_time_start; - ActiveWindow* mission_time_target; - ActiveWindow* mission_time_target_label; - - Campaign* campaign; - Mission* mission; - MissionInfo* info; - int pkg_index; -}; - -#endif // MsnDlg_h - diff --git a/Stars45/MsnEditDlg.cpp b/Stars45/MsnEditDlg.cpp deleted file mode 100644 index 13f5cf7..0000000 --- a/Stars45/MsnEditDlg.cpp +++ /dev/null @@ -1,895 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Editor Dialog Active Window class -*/ - -#include "MsnEditDlg.h" -#include "MsnElemDlg.h" -#include "MsnEventDlg.h" -#include "NavDlg.h" -#include "MenuScreen.h" -#include "Campaign.h" -#include "Mission.h" -#include "MissionEvent.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "StarSystem.h" -#include "Galaxy.h" - -#include "Clock.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "EditBox.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" -#include "Random.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(MsnEditDlg, OnAccept); -DEF_MAP_CLIENT(MsnEditDlg, OnCancel); -DEF_MAP_CLIENT(MsnEditDlg, OnTabButton); -DEF_MAP_CLIENT(MsnEditDlg, OnSystemSelect); -DEF_MAP_CLIENT(MsnEditDlg, OnElemAdd); -DEF_MAP_CLIENT(MsnEditDlg, OnElemEdit); -DEF_MAP_CLIENT(MsnEditDlg, OnElemDel); -DEF_MAP_CLIENT(MsnEditDlg, OnElemSelect); -DEF_MAP_CLIENT(MsnEditDlg, OnElemInc); -DEF_MAP_CLIENT(MsnEditDlg, OnElemDec); -DEF_MAP_CLIENT(MsnEditDlg, OnEventAdd); -DEF_MAP_CLIENT(MsnEditDlg, OnEventEdit); -DEF_MAP_CLIENT(MsnEditDlg, OnEventDel); -DEF_MAP_CLIENT(MsnEditDlg, OnEventSelect); -DEF_MAP_CLIENT(MsnEditDlg, OnEventInc); -DEF_MAP_CLIENT(MsnEditDlg, OnEventDec); - -// +--------------------------------------------------------------------+ - -MsnEditDlg::MsnEditDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -btn_accept(0), btn_cancel(0), -btn_elem_add(0), btn_elem_edit(0), btn_elem_del(0), btn_elem_inc(0), btn_elem_dec(0), -btn_event_add(0), btn_event_edit(0), btn_event_del(0), btn_event_inc(0), btn_event_dec(0), -btn_sit(0), btn_pkg(0), btn_map(0), -txt_name(0), cmb_type(0), cmb_system(0), cmb_region(0), -txt_description(0), txt_situation(0), txt_objective(0), -lst_elem(0), lst_event(0), mission(0), mission_info(0), current_tab(0), -exit_latch(true) -{ - Init(def); -} - -MsnEditDlg::~MsnEditDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::SetMission(Mission* m) -{ - mission = m; - current_tab = 0; -} - -void -MsnEditDlg::SetMissionInfo(MissionInfo* m) -{ - mission_info = m; - current_tab = 0; -} - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::RegisterControls() -{ - btn_accept = (Button*) FindControl( 1); - btn_cancel = (Button*) FindControl( 2); - btn_sit = (Button*) FindControl(301); - btn_pkg = (Button*) FindControl(302); - btn_map = (Button*) FindControl(303); - - btn_elem_add = (Button*) FindControl(501); - btn_elem_edit = (Button*) FindControl(505); - btn_elem_del = (Button*) FindControl(502); - btn_elem_inc = (Button*) FindControl(503); - btn_elem_dec = (Button*) FindControl(504); - - btn_event_add = (Button*) FindControl(511); - btn_event_edit = (Button*) FindControl(515); - btn_event_del = (Button*) FindControl(512); - btn_event_inc = (Button*) FindControl(513); - btn_event_dec = (Button*) FindControl(514); - - txt_name = (EditBox*) FindControl(201); - cmb_type = (ComboBox*) FindControl(202); - cmb_system = (ComboBox*) FindControl(203); - cmb_region = (ComboBox*) FindControl(204); - - txt_description= (EditBox*) FindControl(410); - txt_situation = (EditBox*) FindControl(411); - txt_objective = (EditBox*) FindControl(412); - - lst_elem = (ListBox*) FindControl(510); - lst_event = (ListBox*) FindControl(520); - - if (btn_accept) - REGISTER_CLIENT(EID_CLICK, btn_accept, MsnEditDlg, OnAccept); - - if (btn_cancel) - REGISTER_CLIENT(EID_CLICK, btn_cancel, MsnEditDlg, OnCancel); - - if (btn_elem_add) - REGISTER_CLIENT(EID_CLICK, btn_elem_add, MsnEditDlg, OnElemAdd); - - if (btn_elem_edit) - REGISTER_CLIENT(EID_CLICK, btn_elem_edit, MsnEditDlg, OnElemEdit); - - if (btn_elem_del) - REGISTER_CLIENT(EID_CLICK, btn_elem_del, MsnEditDlg, OnElemDel); - - if (btn_elem_inc) { - char up_arrow[2]; - up_arrow[0] = Font::ARROW_UP; - up_arrow[1] = 0; - btn_elem_inc->SetText(up_arrow); - btn_elem_inc->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_elem_inc, MsnEditDlg, OnElemInc); - } - - if (btn_elem_dec) { - char dn_arrow[2]; - dn_arrow[0] = Font::ARROW_DOWN; - dn_arrow[1] = 0; - btn_elem_dec->SetText(dn_arrow); - btn_elem_dec->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_elem_dec, MsnEditDlg, OnElemDec); - } - - if (btn_event_add) - REGISTER_CLIENT(EID_CLICK, btn_event_add, MsnEditDlg, OnEventAdd); - - if (btn_event_edit) - REGISTER_CLIENT(EID_CLICK, btn_event_edit, MsnEditDlg, OnEventEdit); - - if (btn_event_del) - REGISTER_CLIENT(EID_CLICK, btn_event_del, MsnEditDlg, OnEventDel); - - if (btn_event_inc) { - char up_arrow[2]; - up_arrow[0] = Font::ARROW_UP; - up_arrow[1] = 0; - btn_event_inc->SetText(up_arrow); - btn_event_inc->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_event_inc, MsnEditDlg, OnEventInc); - } - - if (btn_event_dec) { - char dn_arrow[2]; - dn_arrow[0] = Font::ARROW_DOWN; - dn_arrow[1] = 0; - btn_event_dec->SetText(dn_arrow); - btn_event_dec->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_event_dec, MsnEditDlg, OnEventDec); - } - - if (btn_sit) - REGISTER_CLIENT(EID_CLICK, btn_sit, MsnEditDlg, OnTabButton); - - if (btn_pkg) - REGISTER_CLIENT(EID_CLICK, btn_pkg, MsnEditDlg, OnTabButton); - - if (btn_map) - REGISTER_CLIENT(EID_CLICK, btn_map, MsnEditDlg, OnTabButton); - - if (cmb_system) - REGISTER_CLIENT(EID_SELECT, cmb_system, MsnEditDlg, OnSystemSelect); - - if (lst_elem) - REGISTER_CLIENT(EID_SELECT, lst_elem, MsnEditDlg, OnElemSelect); - - if (lst_event) - REGISTER_CLIENT(EID_SELECT, lst_event, MsnEditDlg, OnEventSelect); -} - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::Show() -{ - FormWindow::Show(); - - if (!txt_name || !cmb_type) return; - - txt_name->SetText(""); - - if (cmb_system) { - cmb_system->ClearItems(); - - Galaxy* galaxy = Galaxy::GetInstance(); - ListIter iter = galaxy->GetSystemList(); - while (++iter) { - cmb_system->AddItem(iter->Name()); - } - } - - if (mission) { - int i; - - txt_name->SetText(mission->Name()); - cmb_type->SetSelection(mission->Type()); - - StarSystem* sys = mission->GetStarSystem(); - if (sys && cmb_system && cmb_region) { - for (i = 0; i < cmb_system->NumItems(); i++) { - if (!strcmp(cmb_system->GetItem(i), sys->Name())) { - cmb_system->SetSelection(i); - break; - } - } - - cmb_region->ClearItems(); - int sel_rgn = 0; - - List regions; - regions.append(sys->AllRegions()); - regions.sort(); - - i = 0; - ListIter iter = regions; - while (++iter) { - OrbitalRegion* region = iter.value(); - cmb_region->AddItem(region->Name()); - - if (!strcmp(mission->GetRegion(), region->Name())) { - sel_rgn = i; - } - - i++; - } - - cmb_region->SetSelection(sel_rgn); - } - - if (txt_description && mission_info) - txt_description->SetText(mission_info->description); - - if (txt_situation) - txt_situation->SetText(mission->Situation()); - - if (txt_objective) - txt_objective->SetText(mission->Objective()); - - DrawPackages(); - } - - ShowTab(current_tab); - - exit_latch = true; -} - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::DrawPackages() -{ - bool elem_del = false; - bool elem_edit = false; - bool elem_inc = false; - bool elem_dec = false; - - bool event_del = false; - bool event_edit = false; - bool event_inc = false; - bool event_dec = false; - - if (mission) { - if (lst_elem) { - bool cleared = false; - int index = lst_elem->GetSelection(); - - if (lst_elem->NumItems() != mission->GetElements().size()) { - if (lst_elem->NumItems() < mission->GetElements().size()) - index = lst_elem->NumItems(); - - lst_elem->ClearItems(); - cleared = true; - } - - int i = 0; - ListIter elem = mission->GetElements(); - while (++elem) { - char txt[256]; - - sprintf_s(txt, "%d", elem->Identity()); - - if (cleared) { - lst_elem->AddItemWithData(txt, elem->ElementID()); - } - else { - lst_elem->SetItemText(i, txt); - lst_elem->SetItemData(i, elem->ElementID()); - } - - sprintf_s(txt, "%d", elem->GetIFF()); - lst_elem->SetItemText(i, 1, txt); - lst_elem->SetItemText(i, 2, elem->Name()); - lst_elem->SetItemText(i, 4, elem->RoleName()); - lst_elem->SetItemText(i, 5, elem->Region()); - - const ShipDesign* design = elem->GetDesign(); - - if (design) { - if (elem->Count() > 1) - sprintf_s(txt, "%d %s", elem->Count(), design->abrv); - else - sprintf_s(txt, "%s %s", design->abrv, design->name); - } - else { - sprintf_s(txt, "%s", ContentBundle::GetInstance()->GetText("MsnDlg.undefined").data()); - } - - lst_elem->SetItemText(i, 3, txt); - - i++; - } - - int nitems = lst_elem->NumItems(); - if (nitems) { - if (index >= nitems) - index = nitems - 1; - - if (index >= 0) { - lst_elem->SetSelected(index); - elem_del = true; - elem_edit = true; - elem_inc = index > 0; - elem_dec = index < nitems-1; - } - } - } - - if (lst_event) { - bool cleared = false; - int index = lst_event->GetSelection(); - - if (lst_event->NumItems() != mission->GetEvents().size()) { - if (lst_event->NumItems() < mission->GetEvents().size()) - index = lst_event->NumItems(); - - lst_event->ClearItems(); - cleared = true; - } - - int i = 0; - ListIter event = mission->GetEvents(); - while (++event) { - char txt[256]; - - sprintf_s(txt, "%d", event->EventID()); - if (cleared) { - lst_event->AddItemWithData(txt, event->EventID()); - } - else { - lst_event->SetItemText(i, txt); - lst_event->SetItemData(i, event->EventID()); - } - - if (event->Time()) { - FormatTime(txt, event->Time()); - } - else if (event->Delay()) { - txt[0] = '+'; - txt[1] = ' '; - FormatTime(txt+2, event->Delay()); - } - else { - strcpy_s(txt, " "); - } - - lst_event->SetItemText(i, 1, txt); - lst_event->SetItemText(i, 2, event->EventName()); - lst_event->SetItemText(i, 3, event->EventShip()); - lst_event->SetItemText(i, 4, event->EventMessage()); - - i++; - } - - int nitems = lst_event->NumItems(); - if (nitems) { - if (index >= nitems) - index = nitems - 1; - - if (index >= 0) { - lst_event->SetSelected(index); - event_del = true; - event_edit = true; - event_inc = index > 0; - event_dec = index < nitems-1; - } - } - } - } - - if (btn_elem_del) btn_elem_del->SetEnabled(elem_del); - if (btn_elem_edit) btn_elem_edit->SetEnabled(elem_edit); - if (btn_elem_inc) btn_elem_inc->SetEnabled(elem_inc); - if (btn_elem_dec) btn_elem_dec->SetEnabled(elem_del); - - if (btn_event_del) btn_event_del->SetEnabled(event_del); - if (btn_event_edit) btn_event_edit->SetEnabled(event_edit); - if (btn_event_inc) btn_event_inc->SetEnabled(event_inc); - if (btn_event_dec) btn_event_dec->SetEnabled(event_dec); -} - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - if (!exit_latch && btn_accept && btn_accept->IsEnabled()) - OnAccept(0); - } - - else if (Keyboard::KeyDown(VK_ESCAPE)) { - if (!exit_latch) - OnCancel(0); - } - - else { - exit_latch = false; - } -} - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::ScrapeForm() -{ - if (mission) { - if (txt_name) { - mission->SetName(txt_name->GetText()); - } - - if (cmb_type) { - mission->SetType(cmb_type->GetSelectedIndex()); - - if (mission_info) - mission_info->type = cmb_type->GetSelectedIndex(); - } - - Galaxy* galaxy = Galaxy::GetInstance(); - StarSystem* system = 0; - - if (galaxy && cmb_system) - system = galaxy->GetSystem(cmb_system->GetSelectedItem()); - - if (system) { - mission->ClearSystemList(); - mission->SetStarSystem(system); - - if (mission_info) - mission_info->system = system->Name(); - } - - if (cmb_region) { - mission->SetRegion(cmb_region->GetSelectedItem()); - - if (mission_info) - mission_info->region = cmb_region->GetSelectedItem(); - } - - if (txt_description && mission_info) { - mission_info->description = txt_description->GetText(); - mission->SetDescription(txt_description->GetText()); - } - - if (txt_situation) - mission->SetSituation(txt_situation->GetText()); - - if (txt_objective) - mission->SetObjective(txt_objective->GetText()); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::ShowTab(int tab) -{ - current_tab = tab; - - if (current_tab < 0 || current_tab > 2) - current_tab = 0; - - if (btn_sit) btn_sit->SetButtonState(tab == 0 ? 1 : 0); - if (btn_pkg) btn_pkg->SetButtonState(tab == 1 ? 1 : 0); - if (btn_map) btn_map->SetButtonState(tab == 2 ? 1 : 0); - - DWORD low = 400 + tab*100; - DWORD high = low + 100; - - ListIter iter = Controls(); - while (++iter) { - ActiveWindow* a = iter.value(); - - if (a->GetID() < 400) - a->Show(); - - else if (a->GetID() >= low && a->GetID() < high) - a->Show(); - - else - a->Hide(); - } - - if (tab == 2) { - NavDlg* navdlg = manager->GetNavDlg(); - - if (navdlg) { - navdlg->SetMission(mission); - navdlg->SetEditorMode(true); - } - - manager->ShowNavDlg(); - } - else { - manager->HideNavDlg(); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::OnTabButton(AWEvent* event) -{ - if (!event) return; - - if (event->window == btn_sit) - ShowTab(0); - - else if (event->window == btn_pkg) - ShowTab(1); - - else if (event->window == btn_map) - ShowTab(2); -} - -void -MsnEditDlg::OnSystemSelect(AWEvent* event) -{ - StarSystem* sys = 0; - - if (cmb_system) { - const char* name = cmb_system->GetSelectedItem(); - - Galaxy* galaxy = Galaxy::GetInstance(); - ListIter iter = galaxy->GetSystemList(); - while (++iter) { - StarSystem* s = iter.value(); - - if (!strcmp(s->Name(), name)) { - sys = s; - break; - } - } - } - - if (sys && cmb_region) { - cmb_region->ClearItems(); - - List regions; - regions.append(sys->AllRegions()); - regions.sort(); - - ListIter iter = regions; - while (++iter) { - OrbitalRegion* region = iter.value(); - cmb_region->AddItem(region->Name()); - } - } - - ScrapeForm(); - - NavDlg* navdlg = manager->GetNavDlg(); - - if (navdlg) - navdlg->SetMission(mission); -} - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::OnElemSelect(AWEvent* event) -{ - static DWORD click_time = 0; - - if (lst_elem && mission) { - int selection = lst_elem->GetSelection(); - - if (btn_elem_edit) - btn_elem_edit->SetEnabled(selection >= 0); - - if (btn_elem_del) - btn_elem_del->SetEnabled(selection >= 0); - - if (btn_elem_inc) - btn_elem_inc->SetEnabled(selection > 0); - - if (btn_elem_dec) - btn_elem_dec->SetEnabled(selection >= 0 && selection < lst_elem->NumItems() - 1); - - // double-click: - if (Clock::GetInstance()->RealTime() - click_time < 350) { - if (lst_elem->GetSelCount() == 1) { - int index = lst_elem->GetSelection(); - MissionElement* elem = mission->GetElements().at(index); - MsnElemDlg* msn_elem_dlg = manager->GetMsnElemDlg(); - - if (elem && msn_elem_dlg) { - ScrapeForm(); - msn_elem_dlg->SetMission(mission); - msn_elem_dlg->SetMissionElement(elem); - manager->ShowMsnElemDlg(); - } - } - } - } - - click_time = Clock::GetInstance()->RealTime(); -} - -void -MsnEditDlg::OnElemInc(AWEvent* event) -{ - int index = lst_elem->GetSelection(); - mission->IncreaseElemPriority(index--); - - DrawPackages(); - lst_elem->SetSelected(index); - btn_elem_edit->SetEnabled(true); - btn_elem_del->SetEnabled(true); - btn_elem_inc->SetEnabled(index > 0); - btn_elem_dec->SetEnabled(index >= 0 && index < lst_elem->NumItems()-1); -} - -void -MsnEditDlg::OnElemDec(AWEvent* event) -{ - int index = lst_elem->GetSelection(); - mission->DecreaseElemPriority(index++); - - DrawPackages(); - lst_elem->SetSelected(index); - btn_elem_edit->SetEnabled(true); - btn_elem_del->SetEnabled(true); - btn_elem_inc->SetEnabled(index > 0); - btn_elem_dec->SetEnabled(index >= 0 && index < lst_elem->NumItems()-1); -} - - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::OnElemAdd(AWEvent* event) -{ - if (lst_elem && mission) { - List& elements = mission->GetElements(); - MissionElement* elem = new MissionElement; - - if (elements.size() > 0) - elem->SetLocation(RandomPoint()); - - if (cmb_region) - elem->SetRegion(cmb_region->GetSelectedItem()); - - elements.append(elem); - DrawPackages(); - - MsnElemDlg* msn_elem_dlg = manager->GetMsnElemDlg(); - - if (msn_elem_dlg) { - ScrapeForm(); - msn_elem_dlg->SetMission(mission); - msn_elem_dlg->SetMissionElement(elem); - manager->ShowMsnElemDlg(); - } - } -} - -void -MsnEditDlg::OnElemDel(AWEvent* event) -{ - if (lst_elem && mission) { - List& elements = mission->GetElements(); - delete elements.removeIndex(lst_elem->GetSelection()); - DrawPackages(); - } -} - -void -MsnEditDlg::OnElemEdit(AWEvent* event) -{ - if (lst_elem && mission && lst_elem->GetSelCount() == 1) { - int index = lst_elem->GetSelection(); - MissionElement* elem = mission->GetElements().at(index); - MsnElemDlg* msn_elem_dlg = manager->GetMsnElemDlg(); - - if (elem && msn_elem_dlg) { - ScrapeForm(); - msn_elem_dlg->SetMission(mission); - msn_elem_dlg->SetMissionElement(elem); - manager->ShowMsnElemDlg(); - } - } -} - - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::OnEventSelect(AWEvent* event) -{ - static DWORD click_time = 0; - - if (lst_event && mission) { - int selection = lst_event->GetSelection(); - - if (btn_event_edit) - btn_event_edit->SetEnabled(selection >= 0); - - if (btn_event_del) - btn_event_del->SetEnabled(selection >= 0); - - if (btn_event_inc) - btn_event_inc->SetEnabled(selection > 0); - - if (btn_event_dec) - btn_event_dec->SetEnabled(selection >= 0 && selection < lst_event->NumItems() - 1); - - // double-click: - if (Clock::GetInstance()->RealTime() - click_time < 350) { - if (lst_event->GetSelCount() == 1) { - int index = lst_event->GetSelection(); - MissionEvent* event = mission->GetEvents().at(index); - MsnEventDlg* msn_event_dlg = manager->GetMsnEventDlg(); - - if (event && msn_event_dlg) { - ScrapeForm(); - msn_event_dlg->SetMission(mission); - msn_event_dlg->SetMissionEvent(event); - manager->ShowMsnEventDlg(); - } - } - } - } - - click_time = Clock::GetInstance()->RealTime(); -} - -void -MsnEditDlg::OnEventInc(AWEvent* event) -{ - int index = lst_event->GetSelection(); - mission->IncreaseEventPriority(index--); - - DrawPackages(); - lst_event->SetSelected(index); - btn_event_edit->SetEnabled(true); - btn_event_del->SetEnabled(true); - btn_event_inc->SetEnabled(index > 0); - btn_event_dec->SetEnabled(index >= 0 && index < lst_event->NumItems()-1); -} - -void -MsnEditDlg::OnEventDec(AWEvent* event) -{ - int index = lst_event->GetSelection(); - mission->DecreaseEventPriority(index++); - - DrawPackages(); - lst_event->SetSelected(index); - btn_event_edit->SetEnabled(true); - btn_event_del->SetEnabled(true); - btn_event_inc->SetEnabled(index > 0); - btn_event_dec->SetEnabled(index >= 0 && index < lst_event->NumItems()-1); -} - - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::OnEventAdd(AWEvent* event) -{ - if (lst_event && mission) { - List& events = mission->GetEvents(); - MissionEvent* event = new MissionEvent; - - int id = 1; - for (int i = 0; i < events.size(); i++) { - MissionEvent* e = events[i]; - if (e->EventID() >= id) - id = e->EventID() + 1; - } - - event->id = id; - - events.append(event); - DrawPackages(); - - MsnEventDlg* msn_event_dlg = manager->GetMsnEventDlg(); - - if (msn_event_dlg) { - ScrapeForm(); - msn_event_dlg->SetMission(mission); - msn_event_dlg->SetMissionEvent(event); - manager->ShowMsnEventDlg(); - } - } -} - -void -MsnEditDlg::OnEventDel(AWEvent* event) -{ - if (lst_event && mission) { - List& events = mission->GetEvents(); - delete events.removeIndex(lst_event->GetSelection()); - DrawPackages(); - } -} - -void -MsnEditDlg::OnEventEdit(AWEvent* event) -{ - if (lst_event && mission && lst_event->GetSelCount() == 1) { - int index = lst_event->GetSelection(); - MissionEvent* event = mission->GetEvents().at(index); - MsnEventDlg* msn_event_dlg = manager->GetMsnEventDlg(); - - if (event && msn_event_dlg) { - ScrapeForm(); - msn_event_dlg->SetMission(mission); - msn_event_dlg->SetMissionEvent(event); - manager->ShowMsnEventDlg(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnEditDlg::OnAccept(AWEvent* event) -{ - if (mission) { - ScrapeForm(); - mission_info->name = mission->Name(); - mission->Save(); - } - - manager->ShowMsnSelectDlg(); -} - -void -MsnEditDlg::OnCancel(AWEvent* event) -{ - if (mission) - mission->Load(); - - manager->ShowMsnSelectDlg(); -} diff --git a/Stars45/MsnEditDlg.h b/Stars45/MsnEditDlg.h deleted file mode 100644 index b0eaaf0..0000000 --- a/Stars45/MsnEditDlg.h +++ /dev/null @@ -1,115 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Editor Dialog Active Window class -*/ - -#ifndef MsnEditDlg_h -#define MsnEditDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class Campaign; -class Mission; -class MissionInfo; - -// +--------------------------------------------------------------------+ - -class MsnEditDlg : public FormWindow -{ -public: - friend class MsnEditNavDlg; - - MsnEditDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~MsnEditDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - virtual void ScrapeForm(); - - // Operations: - virtual void OnAccept(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnTabButton(AWEvent* event); - virtual void OnSystemSelect(AWEvent* event); - virtual void OnElemAdd(AWEvent* event); - virtual void OnElemEdit(AWEvent* event); - virtual void OnElemDel(AWEvent* event); - virtual void OnElemSelect(AWEvent* event); - virtual void OnElemInc(AWEvent* event); - virtual void OnElemDec(AWEvent* event); - virtual void OnEventAdd(AWEvent* event); - virtual void OnEventEdit(AWEvent* event); - virtual void OnEventDel(AWEvent* event); - virtual void OnEventSelect(AWEvent* event); - virtual void OnEventInc(AWEvent* event); - virtual void OnEventDec(AWEvent* event); - - virtual Mission* GetMission() const { return mission; } - virtual void SetMission(Mission* m); - virtual void SetMissionInfo(MissionInfo* m); - -protected: - virtual void DrawPackages(); - virtual void ShowTab(int tab); - - MenuScreen* manager; - - Button* btn_accept; - Button* btn_cancel; - - Button* btn_elem_add; - Button* btn_elem_edit; - Button* btn_elem_del; - Button* btn_elem_inc; - Button* btn_elem_dec; - - Button* btn_event_add; - Button* btn_event_edit; - Button* btn_event_del; - Button* btn_event_inc; - Button* btn_event_dec; - - Button* btn_sit; - Button* btn_pkg; - Button* btn_map; - - EditBox* txt_name; - ComboBox* cmb_type; - ComboBox* cmb_system; - ComboBox* cmb_region; - - EditBox* txt_description; - EditBox* txt_situation; - EditBox* txt_objective; - - ListBox* lst_elem; - ListBox* lst_event; - - Mission* mission; - MissionInfo* mission_info; - - int current_tab; - bool exit_latch; -}; - -#endif // MsnEditDlg_h - diff --git a/Stars45/MsnEditNavDlg.cpp b/Stars45/MsnEditNavDlg.cpp deleted file mode 100644 index eab1d13..0000000 --- a/Stars45/MsnEditNavDlg.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#include "MsnEditNavDlg.h" -#include "MsnEditDlg.h" -#include "MenuScreen.h" -#include "Campaign.h" -#include "Galaxy.h" -#include "Instruction.h" -#include "Mission.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "StarSystem.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: -DEF_MAP_CLIENT(MsnEditNavDlg, OnCommit); -DEF_MAP_CLIENT(MsnEditNavDlg, OnCancel); -DEF_MAP_CLIENT(MsnEditNavDlg, OnTabButton); -DEF_MAP_CLIENT(MsnEditNavDlg, OnSystemSelect); - -// +--------------------------------------------------------------------+ - -MsnEditNavDlg::MsnEditNavDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: NavDlg(s, def, mgr), menu_screen(mgr), mission_info(0), -btn_accept(0), btn_cancel(0), btn_sit(0), btn_pkg(0), btn_map(0) -{ - RegisterControls(); -} - -MsnEditNavDlg::~MsnEditNavDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MsnEditNavDlg::RegisterControls() -{ - btn_accept = (Button*) FindControl( 1); - btn_cancel = (Button*) FindControl( 2); - btn_sit = (Button*) FindControl(301); - btn_pkg = (Button*) FindControl(302); - btn_map = (Button*) FindControl(303); - - txt_name = (EditBox*) FindControl(201); - cmb_type = (ComboBox*) FindControl(202); - cmb_system = (ComboBox*) FindControl(203); - cmb_region = (ComboBox*) FindControl(204); - - if (btn_accept) - REGISTER_CLIENT(EID_CLICK, btn_accept, MsnEditNavDlg, OnCommit); - - if (btn_cancel) - REGISTER_CLIENT(EID_CLICK, btn_cancel, MsnEditNavDlg, OnCancel); - - if (btn_sit) - REGISTER_CLIENT(EID_CLICK, btn_sit, MsnEditNavDlg, OnTabButton); - - if (btn_pkg) - REGISTER_CLIENT(EID_CLICK, btn_pkg, MsnEditNavDlg, OnTabButton); - - if (btn_map) - REGISTER_CLIENT(EID_CLICK, btn_map, MsnEditNavDlg, OnTabButton); - - if (cmb_system) - REGISTER_CLIENT(EID_SELECT, cmb_system, MsnEditNavDlg, OnSystemSelect); -} - -// +--------------------------------------------------------------------+ - -void -MsnEditNavDlg::Show() -{ - bool need_tab_update = !shown; - - NavDlg::Show(); - - if (txt_name && cmb_type) { - txt_name->SetText(""); - - if (cmb_system) { - cmb_system->ClearItems(); - - Galaxy* galaxy = Galaxy::GetInstance(); - ListIter iter = galaxy->GetSystemList(); - while (++iter) { - cmb_system->AddItem(iter->Name()); - } - } - - if (mission) { - int i; - - txt_name->SetText(mission->Name()); - cmb_type->SetSelection(mission->Type()); - - StarSystem* sys = mission->GetStarSystem(); - if (sys && cmb_system && cmb_region) { - for (i = 0; i < cmb_system->NumItems(); i++) { - if (!strcmp(cmb_system->GetItem(i), sys->Name())) { - cmb_system->SetSelection(i); - break; - } - } - - cmb_region->ClearItems(); - int sel_rgn = 0; - - List regions; - regions.append(sys->AllRegions()); - regions.sort(); - - i = 0; - ListIter iter = regions; - while (++iter) { - OrbitalRegion* region = iter.value(); - cmb_region->AddItem(region->Name()); - - if (!strcmp(mission->GetRegion(), region->Name())) { - sel_rgn = i; - } - - i++; - } - - cmb_region->SetSelection(sel_rgn); - } - } - } - - if (need_tab_update) { - ShowTab(2); - } - - exit_latch = true; -} - -void -MsnEditNavDlg::SetMissionInfo(MissionInfo* m) -{ - mission_info = m; -} - -// +--------------------------------------------------------------------+ - -void -MsnEditNavDlg::ScrapeForm() -{ - if (mission) { - if (txt_name) { - mission->SetName(txt_name->GetText()); - } - - if (cmb_type) { - mission->SetType(cmb_type->GetSelectedIndex()); - - if (mission_info) - mission_info->type = cmb_type->GetSelectedIndex(); - } - - Galaxy* galaxy = Galaxy::GetInstance(); - StarSystem* system = 0; - - if (galaxy && cmb_system) - system = galaxy->GetSystem(cmb_system->GetSelectedItem()); - - if (system) { - mission->ClearSystemList(); - mission->SetStarSystem(system); - - if (mission_info) - mission_info->system = system->Name(); - } - - if (cmb_region) { - mission->SetRegion(cmb_region->GetSelectedItem()); - - if (mission_info) - mission_info->region = cmb_region->GetSelectedItem(); - } - - SetSystem(system); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnEditNavDlg::ShowTab(int tab) -{ - if (tab < 0 || tab > 2) - tab = 0; - - if (btn_sit) btn_sit->SetButtonState(tab == 0 ? 1 : 0); - if (btn_pkg) btn_pkg->SetButtonState(tab == 1 ? 1 : 0); - if (btn_map) btn_map->SetButtonState(tab == 2 ? 1 : 0); - - if (tab != 2) { - MsnEditDlg* msnEditDlg = menu_screen->GetMsnEditDlg(); - - if (msnEditDlg) - msnEditDlg->ShowTab(tab); - - menu_screen->ShowMsnEditDlg(); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnEditNavDlg::OnTabButton(AWEvent* event) -{ - if (!event) return; - - if (event->window == btn_sit) - ShowTab(0); - - else if (event->window == btn_pkg) - ShowTab(1); - - else if (event->window == btn_map) - ShowTab(2); -} - -void -MsnEditNavDlg::OnSystemSelect(AWEvent* event) -{ - StarSystem* sys = 0; - - if (cmb_system) { - const char* name = cmb_system->GetSelectedItem(); - - Galaxy* galaxy = Galaxy::GetInstance(); - ListIter iter = galaxy->GetSystemList(); - while (++iter) { - StarSystem* s = iter.value(); - - if (!strcmp(s->Name(), name)) { - sys = s; - break; - } - } - } - - if (sys && cmb_region) { - cmb_region->ClearItems(); - - List regions; - regions.append(sys->AllRegions()); - regions.sort(); - - ListIter iter = regions; - while (++iter) { - OrbitalRegion* region = iter.value(); - cmb_region->AddItem(region->Name()); - } - } - - ScrapeForm(); -} - - -// +--------------------------------------------------------------------+ - -void -MsnEditNavDlg::OnCommit(AWEvent* event) -{ - if (mission) { - ScrapeForm(); - - if (mission_info) - mission_info->name = mission->Name(); - - mission->Save(); - } - - menu_screen->ShowMsnSelectDlg(); -} - -void -MsnEditNavDlg::OnCancel(AWEvent* event) -{ - if (mission) - mission->Load(); - - menu_screen->ShowMsnSelectDlg(); -} diff --git a/Stars45/MsnEditNavDlg.h b/Stars45/MsnEditNavDlg.h deleted file mode 100644 index 87a9c38..0000000 --- a/Stars45/MsnEditNavDlg.h +++ /dev/null @@ -1,77 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#ifndef MsnEditNavDlg_h -#define MsnEditNavDlg_h - -#include "Types.h" -#include "NavDlg.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "EditBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class Campaign; -class Mission; -class MissionInfo; - -// +--------------------------------------------------------------------+ - -class MsnEditNavDlg : public NavDlg -{ -public: - friend class MsnEditDlg; - - MsnEditNavDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~MsnEditNavDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void SetMissionInfo(MissionInfo* m); - virtual void ScrapeForm(); - - // Operations: - virtual void OnCommit(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnTabButton(AWEvent* event); - virtual void OnSystemSelect(AWEvent* event); - -protected: - virtual void ShowTab(int tab); - - MenuScreen* menu_screen; - - Button* btn_accept; - Button* btn_cancel; - - Button* btn_sit; - Button* btn_pkg; - Button* btn_map; - - EditBox* txt_name; - ComboBox* cmb_type; - ComboBox* cmb_system; - ComboBox* cmb_region; - MissionInfo* mission_info; - - bool exit_latch; -}; - -#endif // MsnEditNavDlg_h - diff --git a/Stars45/MsnElemDlg.cpp b/Stars45/MsnElemDlg.cpp deleted file mode 100644 index 780bc72..0000000 --- a/Stars45/MsnElemDlg.cpp +++ /dev/null @@ -1,804 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mod Config Dialog Active Window class -*/ - -#include "MsnElemDlg.h" -#include "MsnEditDlg.h" -#include "MenuScreen.h" -#include "Campaign.h" -#include "Mission.h" -#include "Instruction.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "StarSystem.h" -#include "Galaxy.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "EditBox.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "Skin.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(MsnElemDlg, OnAccept); -DEF_MAP_CLIENT(MsnElemDlg, OnCancel); -DEF_MAP_CLIENT(MsnElemDlg, OnClassSelect); -DEF_MAP_CLIENT(MsnElemDlg, OnDesignSelect); -DEF_MAP_CLIENT(MsnElemDlg, OnObjectiveSelect); -DEF_MAP_CLIENT(MsnElemDlg, OnIFFChange); - -// +--------------------------------------------------------------------+ - -MsnElemDlg::MsnElemDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -btn_accept(0), btn_cancel(0), edt_name(0), cmb_class(0), cmb_design(0), -edt_size(0), edt_iff(0), cmb_role(0), cmb_region(0), cmb_skin(0), -edt_loc_x(0), edt_loc_y(0), edt_loc_z(0), cmb_heading(0), edt_hold_time(0), -btn_player(0), btn_playable(0), btn_alert(0), btn_command_ai(0), -edt_respawns(0), cmb_commander(0), cmb_carrier(0), cmb_squadron(0), -cmb_intel(0), cmb_loadout(0), cmb_objective(0), cmb_target(0), -mission(0), elem(0), exit_latch(true) -{ - Init(def); -} - -MsnElemDlg::~MsnElemDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MsnElemDlg::RegisterControls() -{ - btn_accept = (Button*) FindControl( 1); - if (btn_accept) - REGISTER_CLIENT(EID_CLICK, btn_accept, MsnElemDlg, OnAccept); - - btn_cancel = (Button*) FindControl( 2); - if (btn_accept) - REGISTER_CLIENT(EID_CLICK, btn_cancel, MsnElemDlg, OnCancel); - - edt_name = (EditBox*) FindControl(201); - cmb_class = (ComboBox*) FindControl(202); - cmb_design = (ComboBox*) FindControl(203); - cmb_skin = (ComboBox*) FindControl(213); - edt_size = (EditBox*) FindControl(204); - edt_iff = (EditBox*) FindControl(205); - cmb_role = (ComboBox*) FindControl(206); - cmb_region = (ComboBox*) FindControl(207); - edt_loc_x = (EditBox*) FindControl(208); - edt_loc_y = (EditBox*) FindControl(209); - edt_loc_z = (EditBox*) FindControl(210); - cmb_heading = (ComboBox*) FindControl(211); - edt_hold_time = (EditBox*) FindControl(212); - - btn_player = (Button*) FindControl(221); - btn_alert = (Button*) FindControl(222); - btn_playable = (Button*) FindControl(223); - btn_command_ai = (Button*) FindControl(224); - edt_respawns = (EditBox*) FindControl(225); - cmb_commander = (ComboBox*) FindControl(226); - cmb_carrier = (ComboBox*) FindControl(227); - cmb_squadron = (ComboBox*) FindControl(228); - cmb_intel = (ComboBox*) FindControl(229); - cmb_loadout = (ComboBox*) FindControl(230); - cmb_objective = (ComboBox*) FindControl(231); - cmb_target = (ComboBox*) FindControl(232); - - if (cmb_class) - REGISTER_CLIENT(EID_SELECT, cmb_class, MsnElemDlg, OnClassSelect); - - if (cmb_design) - REGISTER_CLIENT(EID_SELECT, cmb_design, MsnElemDlg, OnDesignSelect); - - if (cmb_objective) - REGISTER_CLIENT(EID_SELECT, cmb_objective, MsnElemDlg, OnObjectiveSelect); - - if (edt_iff) - REGISTER_CLIENT(EID_KILL_FOCUS, edt_iff, MsnElemDlg, OnIFFChange); -} - -// +--------------------------------------------------------------------+ - -void -MsnElemDlg::Show() -{ - FormWindow::Show(); - - if (!elem) return; - - int current_class = 0; - - if (cmb_class) { - cmb_class->ClearItems(); - - cmb_class->AddItem(Ship::ClassName(Ship::DRONE)); - cmb_class->AddItem(Ship::ClassName(Ship::FIGHTER)); - cmb_class->AddItem(Ship::ClassName(Ship::ATTACK)); - - cmb_class->AddItem(Ship::ClassName(Ship::LCA)); - cmb_class->AddItem(Ship::ClassName(Ship::COURIER)); - cmb_class->AddItem(Ship::ClassName(Ship::CARGO)); - cmb_class->AddItem(Ship::ClassName(Ship::CORVETTE)); - cmb_class->AddItem(Ship::ClassName(Ship::FREIGHTER)); - cmb_class->AddItem(Ship::ClassName(Ship::FRIGATE)); - cmb_class->AddItem(Ship::ClassName(Ship::DESTROYER)); - cmb_class->AddItem(Ship::ClassName(Ship::CRUISER)); - cmb_class->AddItem(Ship::ClassName(Ship::BATTLESHIP)); - cmb_class->AddItem(Ship::ClassName(Ship::CARRIER)); - cmb_class->AddItem(Ship::ClassName(Ship::SWACS)); - cmb_class->AddItem(Ship::ClassName(Ship::DREADNAUGHT)); - cmb_class->AddItem(Ship::ClassName(Ship::STATION)); - cmb_class->AddItem(Ship::ClassName(Ship::FARCASTER)); - - cmb_class->AddItem(Ship::ClassName(Ship::MINE)); - cmb_class->AddItem(Ship::ClassName(Ship::COMSAT)); - cmb_class->AddItem(Ship::ClassName(Ship::DEFSAT)); - - cmb_class->AddItem(Ship::ClassName(Ship::BUILDING)); - cmb_class->AddItem(Ship::ClassName(Ship::FACTORY)); - cmb_class->AddItem(Ship::ClassName(Ship::SAM)); - cmb_class->AddItem(Ship::ClassName(Ship::EWR)); - cmb_class->AddItem(Ship::ClassName(Ship::C3I)); - cmb_class->AddItem(Ship::ClassName(Ship::STARBASE)); - - const ShipDesign* design = elem->GetDesign(); - - for (int i = 0; i < cmb_class->NumItems(); i++) { - const char* cname = cmb_class->GetItem(i); - int classid = Ship::ClassForName(cname); - - if (design && classid == design->type) { - cmb_class->SetSelection(i); - current_class = classid; - break; - } - } - } - - if (cmb_design) { - OnClassSelect(0); - OnDesignSelect(0); - } - - if (cmb_role) { - cmb_role->ClearItems(); - - for (int i = Mission::PATROL; i <= Mission::OTHER; i++) { - cmb_role->AddItem(Mission::RoleName(i)); - - if (i == 0) - cmb_role->SetSelection(0); - - else if (elem->MissionRole() == i) - cmb_role->SetSelection(cmb_role->NumItems()-1); - } - } - - if (cmb_region) { - cmb_region->ClearItems(); - - if (mission) { - StarSystem* sys = mission->GetStarSystem(); - if (sys) { - List regions; - regions.append(sys->AllRegions()); - regions.sort(); - - ListIter iter = regions; - while (++iter) { - OrbitalRegion* region = iter.value(); - cmb_region->AddItem(region->Name()); - - if (!strcmp(elem->Region(), region->Name())) - cmb_region->SetSelection(cmb_region->NumItems()-1); - } - } - } - } - - char buf[64]; - - if (edt_name) edt_name->SetText(elem->Name()); - - sprintf_s(buf, "%d", elem->Count()); - if (edt_size) edt_size->SetText(buf); - - sprintf_s(buf, "%d", elem->GetIFF()); - if (edt_iff) edt_iff->SetText(buf); - - sprintf_s(buf, "%d", (int) elem->Location().x / 1000); - if (edt_loc_x) edt_loc_x->SetText(buf); - - sprintf_s(buf, "%d", (int) elem->Location().y / 1000); - if (edt_loc_y) edt_loc_y->SetText(buf); - - sprintf_s(buf, "%d", (int) elem->Location().z / 1000); - if (edt_loc_z) edt_loc_z->SetText(buf); - - sprintf_s(buf, "%d", elem->RespawnCount()); - if (edt_respawns) edt_respawns->SetText(buf); - - sprintf_s(buf, "%d", elem->HoldTime()); - if (edt_hold_time) edt_hold_time->SetText(buf); - - if (btn_player) btn_player->SetButtonState(elem->Player() > 0 ? 1 : 0); - if (btn_playable) btn_playable->SetButtonState(elem->IsPlayable() ? 1 : 0); - if (btn_alert) btn_alert->SetButtonState(elem->IsAlert() ? 1 : 0); - if (btn_command_ai) btn_command_ai->SetButtonState(elem->CommandAI()); - - UpdateTeamInfo(); - - if (cmb_intel) { - cmb_intel->ClearItems(); - - for (int i = Intel::RESERVE; i < Intel::TRACKED; i++) { - cmb_intel->AddItem(Intel::NameFromIntel(i)); - - if (i == 0) - cmb_intel->SetSelection(0); - - else if (elem->IntelLevel() == i) - cmb_intel->SetSelection(cmb_intel->NumItems()-1); - } - } - - Instruction* instr = 0; - if (elem->Objectives().size() > 0) - instr = elem->Objectives().at(0); - - if (cmb_objective) { - cmb_objective->ClearItems(); - cmb_objective->AddItem(""); - cmb_objective->SetSelection(0); - - for (int i = 0; i < Instruction::NUM_ACTIONS; i++) { - cmb_objective->AddItem(Instruction::ActionName(i)); - - if (instr && instr->Action() == i) - cmb_objective->SetSelection(i+1); - } - } - - if (cmb_target) { - OnObjectiveSelect(0); - } - - if (cmb_heading) { - double heading = elem->Heading(); - - while (heading > 2*PI) - heading -= 2*PI; - - while (heading < 0) - heading += 2*PI; - - if (heading >= PI/4 && heading < 3*PI/4) - cmb_heading->SetSelection(1); - - else if (heading >= 3*PI/4 && heading < 5*PI/4) - cmb_heading->SetSelection(2); - - else if (heading >= 5*PI/4 && heading < 7*PI/4) - cmb_heading->SetSelection(3); - - else - cmb_heading->SetSelection(0); - } - - exit_latch = true; -} - -// +--------------------------------------------------------------------+ - -void -MsnElemDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - if (!exit_latch && btn_accept && btn_accept->IsEnabled()) - OnAccept(0); - } - - else if (Keyboard::KeyDown(VK_ESCAPE)) { - if (!exit_latch) - OnCancel(0); - } - - else { - exit_latch = false; - } -} - -// +--------------------------------------------------------------------+ - -void -MsnElemDlg::SetMission(Mission* m) -{ - mission = m; -} - -void -MsnElemDlg::SetMissionElement(MissionElement* e) -{ - elem = e; -} - -// +--------------------------------------------------------------------+ - -void -MsnElemDlg::UpdateTeamInfo() -{ - if (cmb_commander) { - cmb_commander->ClearItems(); - cmb_commander->AddItem(""); - cmb_commander->SetSelection(0); - - if (mission && elem) { - ListIter iter = mission->GetElements(); - while (++iter) { - MissionElement* e = iter.value(); - - if (CanCommand(e, elem)) { - cmb_commander->AddItem(e->Name()); - - if (elem->Commander() == e->Name()) - cmb_commander->SetSelection(cmb_commander->NumItems()-1); - } - } - } - } - - if (cmb_squadron) { - cmb_squadron->ClearItems(); - cmb_squadron->AddItem(""); - cmb_squadron->SetSelection(0); - - if (mission && elem) { - ListIter iter = mission->GetElements(); - while (++iter) { - MissionElement* e = iter.value(); - - if (e->GetIFF() == elem->GetIFF() && e != elem && e->IsSquadron()) { - cmb_squadron->AddItem(e->Name()); - - if (elem->Squadron() == e->Name()) - cmb_squadron->SetSelection(cmb_squadron->NumItems()-1); - } - } - } - } - - if (cmb_carrier) { - cmb_carrier->ClearItems(); - cmb_carrier->AddItem(""); - cmb_carrier->SetSelection(0); - - if (mission && elem) { - ListIter iter = mission->GetElements(); - while (++iter) { - MissionElement* e = iter.value(); - - if (e->GetIFF() == elem->GetIFF() && e != elem && e->GetDesign() && e->GetDesign()->flight_decks.size()) { - cmb_carrier->AddItem(e->Name()); - - if (elem->Carrier() == e->Name()) - cmb_carrier->SetSelection(cmb_carrier->NumItems()-1); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnElemDlg::OnClassSelect(AWEvent* event) -{ - if (!cmb_class || !cmb_design) return; - - const char* cname = cmb_class->GetSelectedItem(); - int classid = Ship::ClassForName(cname); - - cmb_design->ClearItems(); - - List designs; - ShipDesign::GetDesignList(classid, designs); - - if (designs.size() > 0) { - const ShipDesign* design = elem->GetDesign(); - bool found = false; - - for (int i = 0; i < designs.size(); i++) { - const char* dsn = designs[i]->data(); - cmb_design->AddItem(dsn); - - if (design && !_stricmp(dsn, design->name)) { - cmb_design->SetSelection(i); - found = true; - } - } - - if (!found) - cmb_design->SetSelection(0); - } - else { - cmb_design->AddItem(""); - cmb_design->SetSelection(0); - } - - OnDesignSelect(0); -} - -// +--------------------------------------------------------------------+ - -void -MsnElemDlg::OnDesignSelect(AWEvent* event) -{ - if (!cmb_design) return; - - ShipDesign* design = 0; - - const char* dname = cmb_design->GetSelectedItem(); - int load_index = 0; - - if (dname) - design = ShipDesign::Get(dname); - - if (cmb_loadout) { - cmb_loadout->ClearItems(); - - if (design) { - MissionLoad* mload = 0; - - if (elem && elem->Loadouts().size() > 0) - mload = elem->Loadouts().at(0); - - const List& loadouts = design->loadouts; - - if (loadouts.size() > 0) { - for (int i = 0; i < loadouts.size(); i++) { - const ShipLoad* load = loadouts[i]; - if (load->name[0]) { - cmb_loadout->AddItem(load->name); - - if (mload && mload->GetName() == load->name) { - load_index = cmb_loadout->NumItems()-1; - } - } - } - } - } - - if (cmb_loadout->NumItems() < 1) - cmb_loadout->AddItem(""); - - cmb_loadout->SetSelection(load_index); - } - - if (cmb_skin) { - cmb_skin->ClearItems(); - - if (design) { - cmb_skin->AddItem(ContentBundle::GetInstance()->GetText("MsnDlg.default")); - cmb_skin->SetSelection(0); - - ListIter iter = design->skins; - - while (++iter) { - Skin* s = iter.value(); - cmb_skin->AddItem(s->Name()); - - if (elem && elem->GetSkin() && !strcmp(s->Name(), elem->GetSkin()->Name())) { - cmb_skin->SetSelection(cmb_skin->NumItems()-1); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnElemDlg::OnObjectiveSelect(AWEvent* event) -{ - if (!cmb_objective || !cmb_target) return; - - Instruction* instr = 0; - if (elem->Objectives().size() > 0) - instr = elem->Objectives().at(0); - - int objid = cmb_objective->GetSelectedIndex() - 1; - - cmb_target->ClearItems(); - cmb_target->AddItem(""); - - if (mission) { - ListIter iter = mission->GetElements(); - while (++iter) { - MissionElement* e = iter.value(); - - if (e != elem) { - bool add = false; - - if (objid < Instruction::PATROL) - add = e->GetIFF() == 0 || e->GetIFF() == elem->GetIFF(); - else - add = e->GetIFF() != elem->GetIFF(); - - if (add) { - cmb_target->AddItem(e->Name()); - - if (instr && !_stricmp(instr->TargetName(), e->Name())) - cmb_target->SetSelection(cmb_target->NumItems()-1); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnElemDlg::OnIFFChange(AWEvent* event) -{ - if (edt_iff && elem) { - int elem_iff = 0; - sscanf_s(edt_iff->GetText().data(), "%d", &elem_iff); - - if (elem->GetIFF() == elem_iff) - return; - - elem->SetIFF(elem_iff); - } - - UpdateTeamInfo(); - - if (cmb_target) - OnObjectiveSelect(0); -} - -// +--------------------------------------------------------------------+ - -void -MsnElemDlg::OnAccept(AWEvent* event) -{ - if (mission && elem) { - char buf[64]; - int val; - - if (edt_name) { - elem->SetName(edt_name->GetText()); - } - - if (edt_size) { - strcpy_s(buf, edt_size->GetText()); - - if (isdigit(*buf)) - sscanf_s(buf, "%d", &val); - else - val = 1; - - elem->SetCount(val); - } - - if (edt_iff) { - strcpy_s(buf, edt_iff->GetText()); - - if (isdigit(*buf)) - sscanf_s(buf, "%d", &val); - else - val = 1; - - elem->SetIFF(val); - } - - if (edt_loc_x && edt_loc_y && edt_loc_z) { - Point loc; - - strcpy_s(buf, edt_loc_x->GetText()); - - if (isdigit(*buf) || *buf == '-') - sscanf_s(buf, "%d", &val); - else - val = 0; - - loc.x = val * 1000; - - strcpy_s(buf, edt_loc_y->GetText()); - - if (isdigit(*buf) || *buf == '-') - sscanf_s(buf, "%d", &val); - else - val = 0; - - loc.y = val * 1000; - - strcpy_s(buf, edt_loc_z->GetText()); - - if (isdigit(*buf) || *buf == '-') - sscanf_s(buf, "%d", &val); - else - val = 0; - - loc.z = val * 1000; - - elem->SetLocation(loc); - } - - if (edt_respawns) { - strcpy_s(buf, edt_respawns->GetText()); - - if (isdigit(*buf)) - sscanf_s(buf, "%d", &val); - else - val = 0; - - elem->SetRespawnCount(val); - } - - if (edt_hold_time) { - strcpy_s(buf, edt_hold_time->GetText()); - - if (isdigit(*buf)) - sscanf_s(buf, "%d", &val); - else - val = 0; - - elem->SetHoldTime(val); - } - - if (btn_player) { - if (btn_player->GetButtonState() > 0) { - mission->SetPlayer(elem); - } - else { - elem->SetPlayer(0); - } - } - - if (btn_playable) - elem->SetPlayable(btn_playable->GetButtonState() ? true : false); - - if (btn_alert) - elem->SetAlert(btn_alert->GetButtonState() ? true : false); - - if (btn_command_ai) - elem->SetCommandAI(btn_command_ai->GetButtonState() ? 1 : 0); - - if (cmb_design) { - ShipDesign* d = ShipDesign::Get(cmb_design->GetSelectedItem()); - - if (d) { - elem->SetDesign(d); - - if (cmb_skin) { - const char* skin_name = cmb_skin->GetSelectedItem(); - - if (strcmp(skin_name, ContentBundle::GetInstance()->GetText("MsnDlg.default").data())) { - elem->SetSkin(d->FindSkin(skin_name)); - } - else { - elem->SetSkin(0); - } - } - } - } - - if (cmb_role) { - elem->SetMissionRole(cmb_role->GetSelectedIndex()); - } - - if (cmb_region) { - elem->SetRegion(cmb_region->GetSelectedItem()); - - if (elem->Player() > 0) { - mission->SetRegion(cmb_region->GetSelectedItem()); - } - } - - if (cmb_heading) { - switch (cmb_heading->GetSelectedIndex()) { - default: - case 0: elem->SetHeading(0); break; - case 1: elem->SetHeading(PI/2); break; - case 2: elem->SetHeading(PI); break; - case 3: elem->SetHeading(3*PI/2); break; - } - } - - if (cmb_commander) { - elem->SetCommander(cmb_commander->GetSelectedItem()); - } - - if (cmb_squadron) { - elem->SetSquadron(cmb_squadron->GetSelectedItem()); - } - - if (cmb_carrier) { - elem->SetCarrier(cmb_carrier->GetSelectedItem()); - } - - if (cmb_intel) { - elem->SetIntelLevel(Intel::IntelFromName(cmb_intel->GetSelectedItem())); - } - - if (cmb_loadout && cmb_loadout->NumItems()) { - elem->Loadouts().destroy(); - - const char* loadname = cmb_loadout->GetSelectedItem(); - if (loadname && *loadname) { - MissionLoad* mload = new MissionLoad(-1, cmb_loadout->GetSelectedItem()); - elem->Loadouts().append(mload); - } - } - - if (cmb_objective && cmb_target) { - List& objectives = elem->Objectives(); - objectives.destroy(); - - int action = cmb_objective->GetSelectedIndex() - 1; - const char* target = cmb_target->GetSelectedItem(); - - if (action >= Instruction::VECTOR) { - Instruction* obj = new Instruction(action, target); - objectives.append(obj); - } - } - - if (elem->Player()) { - mission->SetTeam(elem->GetIFF()); - } - } - - manager->ShowMsnEditDlg(); -} - -void -MsnElemDlg::OnCancel(AWEvent* event) -{ - manager->ShowMsnEditDlg(); -} - -bool -MsnElemDlg::CanCommand(const MissionElement* commander, -const MissionElement* subordinate) const -{ - if (mission && commander && subordinate && commander != subordinate) { - if (commander->GetIFF() != subordinate->GetIFF()) - return false; - - if (commander->IsSquadron()) - return false; - - if (commander->Commander().length() == 0) - return true; - - if (subordinate->Name() == commander->Commander()) - return false; - - MissionElement* elem = mission->FindElement(commander->Commander()); - - if (elem) - return CanCommand(elem, subordinate); - } - - return false; -} \ No newline at end of file diff --git a/Stars45/MsnElemDlg.h b/Stars45/MsnElemDlg.h deleted file mode 100644 index d433006..0000000 --- a/Stars45/MsnElemDlg.h +++ /dev/null @@ -1,98 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Editor Element Dialog Active Window class -*/ - -#ifndef MsnElemDlg_h -#define MsnElemDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class MsnEditDlg; -class Mission; -class MissionElement; - -// +--------------------------------------------------------------------+ - -class MsnElemDlg : public FormWindow -{ -public: - MsnElemDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~MsnElemDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void SetMission(Mission* elem); - virtual void SetMissionElement(MissionElement* elem); - virtual void OnAccept(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnClassSelect(AWEvent* event); - virtual void OnDesignSelect(AWEvent* event); - virtual void OnObjectiveSelect(AWEvent* event); - virtual void OnIFFChange(AWEvent* event); - - virtual void UpdateTeamInfo(); - virtual bool CanCommand(const MissionElement* commander, - const MissionElement* subordinate) const; - -protected: - MenuScreen* manager; - - EditBox* edt_name; - ComboBox* cmb_class; - ComboBox* cmb_design; - ComboBox* cmb_skin; - EditBox* edt_size; - EditBox* edt_iff; - ComboBox* cmb_role; - ComboBox* cmb_region; - EditBox* edt_loc_x; - EditBox* edt_loc_y; - EditBox* edt_loc_z; - ComboBox* cmb_heading; - EditBox* edt_hold_time; - - Button* btn_player; - Button* btn_playable; - Button* btn_alert; - Button* btn_command_ai; - EditBox* edt_respawns; - ComboBox* cmb_carrier; - ComboBox* cmb_squadron; - ComboBox* cmb_commander; - ComboBox* cmb_intel; - ComboBox* cmb_loadout; - ComboBox* cmb_objective; - ComboBox* cmb_target; - - Button* btn_accept; - Button* btn_cancel; - - Mission* mission; - MissionElement* elem; - bool exit_latch; -}; - -#endif // MsnElemDlg_h - diff --git a/Stars45/MsnEventDlg.cpp b/Stars45/MsnEventDlg.cpp deleted file mode 100644 index 57f7174..0000000 --- a/Stars45/MsnEventDlg.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mod Config Dialog Active Window class -*/ - -#include "MsnEventDlg.h" -#include "MsnEditDlg.h" -#include "MenuScreen.h" -#include "Campaign.h" -#include "Mission.h" -#include "MissionEvent.h" -#include "Instruction.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "StarSystem.h" -#include "Galaxy.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "EditBox.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(MsnEventDlg, OnEventSelect); -DEF_MAP_CLIENT(MsnEventDlg, OnAccept); -DEF_MAP_CLIENT(MsnEventDlg, OnCancel); - -// +--------------------------------------------------------------------+ - -MsnEventDlg::MsnEventDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -btn_accept(0), btn_cancel(0), mission(0), event(0) -{ - Init(def); -} - -MsnEventDlg::~MsnEventDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MsnEventDlg::RegisterControls() -{ - btn_accept = (Button*) FindControl( 1); - if (btn_accept) - REGISTER_CLIENT(EID_CLICK, btn_accept, MsnEventDlg, OnAccept); - - btn_cancel = (Button*) FindControl( 2); - if (btn_accept) - REGISTER_CLIENT(EID_CLICK, btn_cancel, MsnEventDlg, OnCancel); - - lbl_id = FindControl(201); - edt_time = (EditBox*) FindControl(202); - edt_delay = (EditBox*) FindControl(203); - cmb_event = (ComboBox*) FindControl(204); - cmb_event_ship = (ComboBox*) FindControl(205); - cmb_event_source = (ComboBox*) FindControl(206); - cmb_event_target = (ComboBox*) FindControl(207); - edt_event_param = (EditBox*) FindControl(208); - edt_event_chance = (EditBox*) FindControl(220); - edt_event_sound = (EditBox*) FindControl(209); - edt_event_message = (EditBox*) FindControl(210); - - cmb_trigger = (ComboBox*) FindControl(221); - cmb_trigger_ship = (ComboBox*) FindControl(222); - cmb_trigger_target = (ComboBox*) FindControl(223); - edt_trigger_param = (EditBox*) FindControl(224); - - if (cmb_event) - REGISTER_CLIENT(EID_SELECT, cmb_event, MsnEventDlg, OnEventSelect); -} - -// +--------------------------------------------------------------------+ - -void -MsnEventDlg::Show() -{ - FormWindow::Show(); - - if (!event) return; - - FillShipList(cmb_event_ship, event->EventShip()); - FillShipList(cmb_event_source, event->EventSource()); - - if (event->Event() == MissionEvent::JUMP) - FillRgnList(cmb_event_target, event->EventTarget()); - else - FillShipList(cmb_event_target,event->EventTarget()); - - FillShipList(cmb_trigger_ship, event->TriggerShip()); - FillShipList(cmb_trigger_target, event->TriggerTarget()); - - char buf[64]; - - sprintf_s(buf, "%d", event->EventID()); - if (lbl_id) lbl_id->SetText(buf); - - if (edt_time) { - sprintf_s(buf, "%.1f", event->Time()); - edt_time->SetText(buf); - } - - if (edt_delay) { - sprintf_s(buf, "%.1f", event->Delay()); - edt_delay->SetText(buf); - } - - if (edt_event_chance) { - sprintf_s(buf, "%d", event->EventChance()); - edt_event_chance->SetText(buf); - } - - sprintf_s(buf, "%d", event->EventParam()); - if (edt_event_param) edt_event_param->SetText(buf); - - if (edt_trigger_param) - edt_trigger_param->SetText(event->TriggerParamStr()); - - if (edt_event_message) - edt_event_message->SetText(event->EventMessage()); - - if (edt_event_sound) - edt_event_sound->SetText(event->EventSound()); - - if (cmb_event) { - cmb_event->ClearItems(); - - for (int i = 0; i < MissionEvent::NUM_EVENTS; i++) { - cmb_event->AddItem(MissionEvent::EventName(i)); - } - - cmb_event->SetSelection(event->Event()); - } - - if (cmb_trigger) { - cmb_trigger->ClearItems(); - - for (int i = 0; i < MissionEvent::NUM_TRIGGERS; i++) { - cmb_trigger->AddItem(MissionEvent::TriggerName(i)); - } - - cmb_trigger->SetSelection(event->Trigger()); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnEventDlg::FillShipList(ComboBox* cmb, const char* seln) -{ - if (!cmb) return; - cmb->ClearItems(); - - if (!mission) return; - - int index = 1; - int selected_index = 0; - cmb->AddItem(""); - - List& list = mission->GetElements(); - for (int i = 0; i < list.size(); i++) { - MissionElement* elem = list[i]; - - if (elem->IsSquadron()) - continue; - - if (elem->Count() == 1) { - cmb->AddItem(elem->Name()); - - if (elem->Name() == seln) - selected_index = index; - - index++; - } - else { - char ship_name[256]; - - for (int n = 0; n < elem->Count(); n++) { - sprintf_s(ship_name, "%s %d", elem->Name().data(), n+1); - cmb->AddItem(ship_name); - - if (!_stricmp(ship_name, seln)) - selected_index = index; - - index++; - } - } - } - - cmb->SetSelection(selected_index); -} - -void -MsnEventDlg::FillRgnList(ComboBox* cmb, const char* seln) -{ - if (!cmb) return; - cmb->ClearItems(); - - if (!mission) return; - - int selected_index = 0; - int i = 0; - - ListIter iter = mission->GetSystemList(); - while (++iter) { - StarSystem* sys = iter.value(); - - ListIter iter2 = sys->AllRegions(); - while (++iter2) { - OrbitalRegion* region = iter2.value(); - - if (!strcmp(region->Name(), seln)) - selected_index = i; - - cmb->AddItem(region->Name()); - i++; - } - } - - cmb->SetSelection(selected_index); -} - -// +--------------------------------------------------------------------+ - -void -MsnEventDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - if (btn_accept && btn_accept->IsEnabled()) - OnAccept(0); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnEventDlg::SetMission(Mission* m) -{ - mission = m; -} - -void -MsnEventDlg::SetMissionEvent(MissionEvent* e) -{ - event = e; -} - -// +--------------------------------------------------------------------+ - -void -MsnEventDlg::OnEventSelect(AWEvent* e) -{ - if (cmb_event->GetSelectedIndex() == MissionEvent::JUMP) - FillRgnList(cmb_event_target, event->EventTarget()); - - else - FillShipList(cmb_event_target, event->EventTarget()); -} - -// +--------------------------------------------------------------------+ - -void -MsnEventDlg::OnAccept(AWEvent* e) -{ - if (mission && event) { - char buf[64]; - int val; - - if (edt_time) { - strcpy_s(buf, edt_time->GetText()); - - float t = 0; - sscanf_s(buf, "%f", &t); - - event->time = t; - } - - if (edt_delay) { - strcpy_s(buf, edt_delay->GetText()); - - float t = 0; - sscanf_s(buf, "%f", &t); - - event->delay = t; - } - - if (edt_event_param) { - strcpy_s(buf, edt_event_param->GetText()); - - if (isdigit(*buf)) { - sscanf_s(buf, "%d", &val); - event->event_param[0] = val; - event->event_nparams = 1; - } - else if (*buf == '(') { - Parser parser(new BlockReader(buf)); - Term* term = parser.ParseTerm(); - - if (term && term->isArray()) { - TermArray* val = term->isArray(); - if (val) { - int nelem = val->elements()->size(); - - if (nelem > 10) - nelem = 10; - - for (int i = 0; i < nelem; i++) - event->event_param[i] = (int) (val->elements()->at(i)->isNumber()->value()); - - event->event_nparams = nelem; - } - } - } - } - - if (edt_event_chance) { - strcpy_s(buf, edt_event_chance->GetText()); - - if (isdigit(*buf)) { - sscanf_s(buf, "%d", &val); - } - else { - val = 0; - } - - event->event_chance = val; - } - - if (edt_event_message) - event->event_message = edt_event_message->GetText(); - - if (edt_event_sound) - event->event_sound = edt_event_sound->GetText(); - - if (edt_trigger_param) { - strcpy_s(buf, edt_trigger_param->GetText()); - - ZeroMemory(event->trigger_param, sizeof(event->trigger_param)); - - if (isdigit(*buf)) { - sscanf_s(buf, "%d", &val); - event->trigger_param[0] = val; - event->trigger_nparams = 1; - } - - else if (*buf == '(') { - Parser parser(new BlockReader(buf)); - Term* term = parser.ParseTerm(); - - if (term && term->isArray()) { - TermArray* val = term->isArray(); - if (val) { - int nelem = val->elements()->size(); - - if (nelem > 10) - nelem = 10; - - for (int i = 0; i < nelem; i++) - event->trigger_param[i] = (int) (val->elements()->at(i)->isNumber()->value()); - - event->trigger_nparams = nelem; - } - } - } - - } - - if (cmb_event) - event->event = cmb_event->GetSelectedIndex(); - - if (cmb_event_ship) - event->event_ship = cmb_event_ship->GetSelectedItem(); - - if (cmb_event_source) - event->event_source = cmb_event_source->GetSelectedItem(); - - if (cmb_event_target) - event->event_target = cmb_event_target->GetSelectedItem(); - - if (cmb_trigger) - event->trigger = cmb_trigger->GetSelectedIndex(); - - if (cmb_trigger_ship) - event->trigger_ship = cmb_trigger_ship->GetSelectedItem(); - - if (cmb_trigger_target) - event->trigger_target = cmb_trigger_target->GetSelectedItem(); - } - - manager->ShowMsnEditDlg(); -} - -void -MsnEventDlg::OnCancel(AWEvent* event) -{ - manager->ShowMsnEditDlg(); -} diff --git a/Stars45/MsnEventDlg.h b/Stars45/MsnEventDlg.h deleted file mode 100644 index bd3180e..0000000 --- a/Stars45/MsnEventDlg.h +++ /dev/null @@ -1,85 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Editor Element Dialog Active Window class -*/ - -#ifndef MsnEventDlg_h -#define MsnEventDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class MsnEditDlg; -class Mission; -class MissionElement; -class MissionEvent; - -// +--------------------------------------------------------------------+ - -class MsnEventDlg : public FormWindow -{ -public: - MsnEventDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~MsnEventDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void SetMission(Mission* msn); - virtual void SetMissionEvent(MissionEvent* event); - virtual void OnEventSelect(AWEvent* e); - virtual void OnAccept(AWEvent* e); - virtual void OnCancel(AWEvent* e); - -protected: - virtual void FillShipList(ComboBox* cmb, const char* seln); - virtual void FillRgnList(ComboBox* cmb, const char* seln); - - MenuScreen* manager; - - ActiveWindow* lbl_id; - EditBox* edt_time; - EditBox* edt_delay; - - ComboBox* cmb_event; - ComboBox* cmb_event_ship; - ComboBox* cmb_event_source; - ComboBox* cmb_event_target; - EditBox* edt_event_param; - EditBox* edt_event_chance; - EditBox* edt_event_sound; - EditBox* edt_event_message; - - ComboBox* cmb_trigger; - ComboBox* cmb_trigger_ship; - ComboBox* cmb_trigger_target; - EditBox* edt_trigger_param; - - Button* btn_accept; - Button* btn_cancel; - - Mission* mission; - MissionEvent* event; -}; - -#endif // MsnEventDlg_h - diff --git a/Stars45/MsnNavDlg.cpp b/Stars45/MsnNavDlg.cpp deleted file mode 100644 index 7858aaf..0000000 --- a/Stars45/MsnNavDlg.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#include "MsnNavDlg.h" -#include "PlanScreen.h" -#include "Campaign.h" -#include "Mission.h" -#include "Instruction.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "StarSystem.h" - -#include "Keyboard.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: -DEF_MAP_CLIENT(MsnNavDlg, OnCommit); -DEF_MAP_CLIENT(MsnNavDlg, OnCancel); -DEF_MAP_CLIENT(MsnNavDlg, OnTabButton); - -// +--------------------------------------------------------------------+ - -MsnNavDlg::MsnNavDlg(Screen* s, FormDef& def, PlanScreen* mgr) -: NavDlg(s, def, mgr), MsnDlg(mgr) -{ - RegisterControls(); -} - -MsnNavDlg::~MsnNavDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MsnNavDlg::RegisterControls() -{ - RegisterMsnControls(this); - - if (commit) - REGISTER_CLIENT(EID_CLICK, commit, MsnNavDlg, OnCommit); - - if (cancel) - REGISTER_CLIENT(EID_CLICK, cancel, MsnNavDlg, OnCancel); - - if (sit_button) - REGISTER_CLIENT(EID_CLICK, sit_button, MsnNavDlg, OnTabButton); - - if (pkg_button) - REGISTER_CLIENT(EID_CLICK, pkg_button, MsnNavDlg, OnTabButton); - - if (nav_button) - REGISTER_CLIENT(EID_CLICK, nav_button, MsnNavDlg, OnTabButton); - - if (wep_button) - REGISTER_CLIENT(EID_CLICK, wep_button, MsnNavDlg, OnTabButton); -} - -// +--------------------------------------------------------------------+ - -void -MsnNavDlg::Show() -{ - NavDlg::Show(); - ShowMsnDlg(); -} - -void -MsnNavDlg::ExecFrame() -{ - NavDlg::ExecFrame(); - - if (Keyboard::KeyDown(VK_RETURN)) { - OnCommit(0); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnNavDlg::OnCommit(AWEvent* event) -{ - MsnDlg::OnCommit(event); - NavDlg::OnCommit(event); -} - -void -MsnNavDlg::OnCancel(AWEvent* event) -{ - MsnDlg::OnCancel(event); - NavDlg::OnCancel(event); -} diff --git a/Stars45/MsnNavDlg.h b/Stars45/MsnNavDlg.h deleted file mode 100644 index a5d60ab..0000000 --- a/Stars45/MsnNavDlg.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#ifndef MsnNavDlg_h -#define MsnNavDlg_h - -#include "Types.h" -#include "MsnDlg.h" -#include "NavDlg.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class PlanScreen; -class Campaign; -class Mission; -class MissionInfo; - -// +--------------------------------------------------------------------+ - -class MsnNavDlg : public NavDlg, -public MsnDlg -{ -public: - MsnNavDlg(Screen* s, FormDef& def, PlanScreen* mgr); - virtual ~MsnNavDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnCommit(AWEvent* event); - virtual void OnCancel(AWEvent* event); -}; - -#endif // MsnNavDlg_h - diff --git a/Stars45/MsnObjDlg.cpp b/Stars45/MsnObjDlg.cpp deleted file mode 100644 index 384f83e..0000000 --- a/Stars45/MsnObjDlg.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#include "MsnObjDlg.h" -#include "PlanScreen.h" -#include "Campaign.h" -#include "Mission.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "ShipSolid.h" -#include "StarSystem.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Mouse.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "ParseUtil.h" -#include "FormatUtil.h" -#include "Light.h" -#include "Solid.h" -#include "Keyboard.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: -DEF_MAP_CLIENT(MsnObjDlg, OnCommit); -DEF_MAP_CLIENT(MsnObjDlg, OnCancel); -DEF_MAP_CLIENT(MsnObjDlg, OnTabButton); -DEF_MAP_CLIENT(MsnObjDlg, OnSkin); - -// +--------------------------------------------------------------------+ - -MsnObjDlg::MsnObjDlg(Screen* s, FormDef& def, PlanScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), MsnDlg(mgr), -objectives(0), sitrep(0), beauty(0), camview(0), player_desc(0), -ship(0) -{ - campaign = Campaign::GetCampaign(); - - if (campaign) - mission = campaign->GetMission(); - - Init(def); -} - -MsnObjDlg::~MsnObjDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MsnObjDlg::RegisterControls() -{ - objectives = FindControl(400); - sitrep = FindControl(401); - beauty = FindControl(300); - player_desc = FindControl(301); - cmb_skin = (ComboBox*) FindControl(302); - - RegisterMsnControls(this); - - if (commit) - REGISTER_CLIENT(EID_CLICK, commit, MsnObjDlg, OnCommit); - - if (cancel) - REGISTER_CLIENT(EID_CLICK, cancel, MsnObjDlg, OnCancel); - - if (sit_button) - REGISTER_CLIENT(EID_CLICK, sit_button, MsnObjDlg, OnTabButton); - - if (pkg_button) - REGISTER_CLIENT(EID_CLICK, pkg_button, MsnObjDlg, OnTabButton); - - if (nav_button) - REGISTER_CLIENT(EID_CLICK, nav_button, MsnObjDlg, OnTabButton); - - if (wep_button) - REGISTER_CLIENT(EID_CLICK, wep_button, MsnObjDlg, OnTabButton); - - if (cmb_skin) { - REGISTER_CLIENT(EID_SELECT, cmb_skin, MsnObjDlg, OnSkin); - } - - if (beauty) { - scene.SetAmbient(Color(72,75,78)); - - Point light_pos(3e6, 5e6, 4e6); - - Light* main_light = new Light(1.2f); - main_light->MoveTo(light_pos); - main_light->SetType(Light::LIGHT_DIRECTIONAL); - main_light->SetColor(Color::White); - main_light->SetShadow(true); - - scene.AddLight(main_light); - - Light* back_light = new Light(0.35f); - back_light->MoveTo(light_pos * -1); - back_light->SetType(Light::LIGHT_DIRECTIONAL); - back_light->SetColor(Color::White); - back_light->SetShadow(false); - - scene.AddLight(back_light); - - camview = new CameraView(beauty, &cam, &scene); - camview->SetProjectionType(Video::PROJECTION_PERSPECTIVE); - camview->SetFieldOfView(2); - - beauty->AddView(camview); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnObjDlg::Show() -{ - bool update_scene = !shown; - - FormWindow::Show(); - ShowMsnDlg(); - - if (objectives) { - if (mission) { - if (mission->IsOK()) - objectives->SetText(mission->Objective()); - else - objectives->SetText(""); - } - else { - objectives->SetText(ContentBundle::GetInstance()->GetText("MsnDlg.no-mission")); - } - } - - if (sitrep) { - if (mission) { - if (mission->IsOK()) - sitrep->SetText(mission->Situation()); - else - sitrep->SetText(ContentBundle::GetInstance()->GetText("MsnDlg.found-errors") + - mission->ErrorMessage()); - } - else { - sitrep->SetText(ContentBundle::GetInstance()->GetText("MsnDlg.no-mission")); - } - } - - if (cmb_skin) { - cmb_skin->ClearItems(); - cmb_skin->Hide(); - } - - if (beauty) { - if (mission && mission->IsOK()) { - MissionElement* elem = mission->GetPlayer(); - - if (elem) { - const ShipDesign* design = elem->GetDesign(); - - if (design && camview && update_scene) { - double az = -PI/6; - double el = PI/8; - double zoom = 1.8; - - scene.Graphics().clear(); - - if (elem->IsStarship()) { - az = -PI/8; - el = PI/12; - zoom = 1.7; - } - - if (design->beauty_cam.z > 0) { - az = design->beauty_cam.x; - el = design->beauty_cam.y; - zoom = design->beauty_cam.z; - } - - double r = design->radius; - double x = zoom * r * sin(az) * cos(el); - double y = zoom * r * cos(az) * cos(el); - double z = zoom * r * sin(el); - - cam.LookAt(Point(0,0,r/5), Point(x,z,y), Point(0,1,0)); - - int n = design->lod_levels; - - if (n >= 1) { - Model* model = design->models[n-1].at(0); - - if (model) { - ship = new ShipSolid(0); - ship->UseModel(model); - ship->CreateShadows(1); - ship->SetSkin(elem->GetSkin()); - - Matrix o; - o.Pitch( 3 * DEGREES); - o.Roll( 13 * DEGREES); - - ship->SetOrientation(o); - - scene.Graphics().append(ship); - } - } - } - - if (cmb_skin && design && design->skins.size()) { - cmb_skin->Show(); - cmb_skin->AddItem(ContentBundle::GetInstance()->GetText("MsnDlg.default")); - cmb_skin->SetSelection(0); - ListIter iter = ((ShipDesign*) design)->skins; - - while (++iter) { - Skin* s = iter.value(); - cmb_skin->AddItem(s->Name()); - - if (elem && elem->GetSkin() && !strcmp(s->Name(), elem->GetSkin()->Name())) { - cmb_skin->SetSelection(cmb_skin->NumItems()-1); - } - } - } - } - } - } - - if (player_desc) { - player_desc->SetText(""); - - if (mission && mission->IsOK()) { - MissionElement* elem = mission->GetPlayer(); - - if (elem) { - const ShipDesign* design = elem->GetDesign(); - - if (design) { - char txt[256]; - - if (design->type <= Ship::ATTACK) - sprintf_s(txt, "%s %s", design->abrv, design->display_name); - else - sprintf_s(txt, "%s %s", design->abrv, elem->Name().data()); - - player_desc->SetText(txt); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnObjDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnCommit(0); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnObjDlg::OnSkin(AWEvent* event) -{ - Text skin_name = cmb_skin->GetSelectedItem(); - - if (mission && mission->IsOK()) { - MissionElement* elem = mission->GetPlayer(); - - if (elem) { - const ShipDesign* design = elem->GetDesign(); - - if (design) { - const Skin* skin = design->FindSkin(skin_name); - - elem->SetSkin(skin); - - if (ship) - ship->SetSkin(skin); - } - } - } -} - -void -MsnObjDlg::OnCommit(AWEvent* event) -{ - MsnDlg::OnCommit(event); -} - -void -MsnObjDlg::OnCancel(AWEvent* event) -{ - MsnDlg::OnCancel(event); -} - -void -MsnObjDlg::OnTabButton(AWEvent* event) -{ - MsnDlg::OnTabButton(event); -} diff --git a/Stars45/MsnObjDlg.h b/Stars45/MsnObjDlg.h deleted file mode 100644 index d3ff7a1..0000000 --- a/Stars45/MsnObjDlg.h +++ /dev/null @@ -1,67 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#ifndef MsnObjDlg_h -#define MsnObjDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "MsnDlg.h" -#include "Bitmap.h" -#include "Button.h" -#include "CameraView.h" -#include "Scene.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class PlanScreen; -class Campaign; -class Mission; -class MissionInfo; -class ShipSolid; - -// +--------------------------------------------------------------------+ - -class MsnObjDlg : public FormWindow, -public MsnDlg -{ -public: - MsnObjDlg(Screen* s, FormDef& def, PlanScreen* mgr); - virtual ~MsnObjDlg(); - - virtual void RegisterControls(); - virtual void ExecFrame(); - virtual void Show(); - - // Operations: - virtual void OnCommit(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnTabButton(AWEvent* event); - virtual void OnSkin(AWEvent* event); - -protected: - ActiveWindow* objectives; - ActiveWindow* sitrep; - ActiveWindow* player_desc; - ActiveWindow* beauty; - ComboBox* cmb_skin; - CameraView* camview; - Scene scene; - Camera cam; - ShipSolid* ship; -}; - -#endif // MsnObjDlg_h - diff --git a/Stars45/MsnPkgDlg.cpp b/Stars45/MsnPkgDlg.cpp deleted file mode 100644 index 6616fd2..0000000 --- a/Stars45/MsnPkgDlg.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#include "MsnPkgDlg.h" -#include "PlanScreen.h" -#include "Campaign.h" -#include "Mission.h" -#include "Instruction.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "StarSystem.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Mouse.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "ParseUtil.h" -#include "FormatUtil.h" -#include "Keyboard.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: -DEF_MAP_CLIENT(MsnPkgDlg, OnPackage); -DEF_MAP_CLIENT(MsnPkgDlg, OnCommit); -DEF_MAP_CLIENT(MsnPkgDlg, OnCancel); -DEF_MAP_CLIENT(MsnPkgDlg, OnTabButton); - -// +--------------------------------------------------------------------+ - -MsnPkgDlg::MsnPkgDlg(Screen* s, FormDef& def, PlanScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), MsnDlg(mgr) -{ - campaign = Campaign::GetCampaign(); - - if (campaign) - mission = campaign->GetMission(); - - Init(def); -} - -MsnPkgDlg::~MsnPkgDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MsnPkgDlg::RegisterControls() -{ - pkg_list = (ListBox*) FindControl(320); - nav_list = (ListBox*) FindControl(330); - - for (int i = 0; i < 5; i++) - threat[i] = FindControl(251 + i); - - RegisterMsnControls(this); - - if (pkg_list) - REGISTER_CLIENT(EID_SELECT, pkg_list, MsnPkgDlg, OnPackage); - - if (commit) - REGISTER_CLIENT(EID_CLICK, commit, MsnPkgDlg, OnCommit); - - if (cancel) - REGISTER_CLIENT(EID_CLICK, cancel, MsnPkgDlg, OnCancel); - - if (sit_button) - REGISTER_CLIENT(EID_CLICK, sit_button, MsnPkgDlg, OnTabButton); - - if (pkg_button) - REGISTER_CLIENT(EID_CLICK, pkg_button, MsnPkgDlg, OnTabButton); - - if (nav_button) - REGISTER_CLIENT(EID_CLICK, nav_button, MsnPkgDlg, OnTabButton); - - if (wep_button) - REGISTER_CLIENT(EID_CLICK, wep_button, MsnPkgDlg, OnTabButton); -} - -// +--------------------------------------------------------------------+ - -void -MsnPkgDlg::Show() -{ - FormWindow::Show(); - ShowMsnDlg(); - - DrawPackages(); - DrawNavPlan(); - DrawThreats(); -} - -// +--------------------------------------------------------------------+ - -void -MsnPkgDlg::DrawPackages() -{ - if (mission) { - if (pkg_list) { - pkg_list->ClearItems(); - - int i = 0; - int elem_index = 0; - ListIter elem = mission->GetElements(); - while (++elem) { - // display this element? - if (elem->GetIFF() == mission->Team() && - !elem->IsSquadron() && - elem->Region() == mission->GetRegion() && - elem->GetDesign()->type < Ship::STATION) { - - char txt[256]; - - if (elem->Player() > 0) { - sprintf_s(txt, "==>"); - if (pkg_index < 0) - pkg_index = elem_index; - } - else { - strcpy_s(txt, " "); - } - - pkg_list->AddItemWithData(txt, elem->ElementID()); - pkg_list->SetItemText(i, 1, elem->Name()); - pkg_list->SetItemText(i, 2, elem->RoleName()); - - const ShipDesign* design = elem->GetDesign(); - - if (elem->Count() > 1) - sprintf_s(txt, "%d %s", elem->Count(), design->abrv); - else - sprintf_s(txt, "%s %s", design->abrv, design->name); - pkg_list->SetItemText(i, 3, txt); - - i++; - } - - elem_index++; - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnPkgDlg::DrawNavPlan() -{ - if (mission) { - if (pkg_index < 0 || pkg_index >= mission->GetElements().size()) - pkg_index = 0; - - MissionElement* element = mission->GetElements()[pkg_index]; - if (nav_list && element) { - nav_list->ClearItems(); - - Point loc = element->Location(); - int i = 0; - - ListIter navpt = element->NavList(); - while (++navpt) { - char txt[256]; - sprintf_s(txt, "%d", i + 1); - - nav_list->AddItem(txt); - nav_list->SetItemText(i, 1, Instruction::ActionName(navpt->Action())); - nav_list->SetItemText(i, 2, navpt->RegionName()); - - double dist = Point(loc - navpt->Location()).length(); - FormatNumber(txt, dist); - nav_list->SetItemText(i, 3, txt); - - sprintf_s(txt, "%d", navpt->Speed()); - nav_list->SetItemText(i, 4, txt); - - loc = navpt->Location(); - i++; - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnPkgDlg::DrawThreats() -{ - for (int i = 0; i < 5; i++) - if (threat[i]) - threat[i]->SetText(""); - - if (!mission) return; - - MissionElement* player = mission->GetPlayer(); - - if (!player) return; - - Text rgn0 = player->Region(); - Text rgn1; - int iff = player->GetIFF(); - - ListIter nav = player->NavList(); - while (++nav) { - if (rgn0 != nav->RegionName()) - rgn1 = nav->RegionName(); - } - - if (threat[0]) { - Point base_loc = mission->GetElements()[0]->Location(); - - int i = 0; - ListIter iter = mission->GetElements(); - while (++iter) { - MissionElement* elem = iter.value(); - - if (elem->GetIFF() == 0 || elem->GetIFF() == iff || elem->IntelLevel() <= Intel::SECRET) - continue; - - if (elem->IsSquadron()) - continue; - - if (elem->IsGroundUnit()) { - if (!elem->GetDesign() || - elem->GetDesign()->type != Ship::SAM) - continue; - - if (elem->Region() != rgn0 && - elem->Region() != rgn1) - continue; - } - - int mission_role = elem->MissionRole(); - - if (mission_role == Mission::STRIKE || - mission_role == Mission::INTEL || - mission_role >= Mission::TRANSPORT) - continue; - - char rng[32]; - char role[32]; - char txt[256]; - - if (mission_role == Mission::SWEEP || - mission_role == Mission::INTERCEPT || - mission_role == Mission::FLEET || - mission_role == Mission::BOMBARDMENT) - strcpy_s(role, ContentBundle::GetInstance()->GetText("MsnDlg.ATTACK").data()); - else - strcpy_s(role, ContentBundle::GetInstance()->GetText("MsnDlg.PATROL").data()); - - double dist = Point(base_loc - elem->Location()).length(); - FormatNumber(rng, dist); - - sprintf_s(txt, "%s - %d %s - %s", role, - elem->Count(), - elem->GetDesign()->abrv, - rng); - if (threat[i]) - threat[i]->SetText(txt); - - i++; - - if (i >= 5) - break; - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnPkgDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnCommit(0); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnPkgDlg::OnPackage(AWEvent* event) -{ - if (!pkg_list || !mission) - return; - - int seln = pkg_list->GetListIndex(); - int pkg = pkg_list->GetItemData(seln); - - int i = 0; - ListIter elem = mission->GetElements(); - while (++elem) { - if (elem->ElementID() == pkg) { - pkg_index = i; - //mission->SetPlayer(elem.value()); - } - - i++; - } - - //DrawPackages(); - DrawNavPlan(); -} - -// +--------------------------------------------------------------------+ - -void -MsnPkgDlg::OnCommit(AWEvent* event) -{ - MsnDlg::OnCommit(event); -} - -void -MsnPkgDlg::OnCancel(AWEvent* event) -{ - MsnDlg::OnCancel(event); -} - -void -MsnPkgDlg::OnTabButton(AWEvent* event) -{ - MsnDlg::OnTabButton(event); -} diff --git a/Stars45/MsnPkgDlg.h b/Stars45/MsnPkgDlg.h deleted file mode 100644 index d42261d..0000000 --- a/Stars45/MsnPkgDlg.h +++ /dev/null @@ -1,65 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#ifndef MsnPkgDlg_h -#define MsnPkgDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "MsnDlg.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class PlanScreen; -class Campaign; -class Mission; -class MissionInfo; - -// +--------------------------------------------------------------------+ - -class MsnPkgDlg : public FormWindow, -public MsnDlg -{ -public: - MsnPkgDlg(Screen* s, FormDef& def, PlanScreen* mgr); - virtual ~MsnPkgDlg(); - - virtual void RegisterControls(); - virtual void ExecFrame(); - virtual void Show(); - - // Operations: - virtual void OnCommit(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnTabButton(AWEvent* event); - virtual void OnPackage(AWEvent* event); - -protected: - virtual void DrawPackages(); - virtual void DrawNavPlan(); - virtual void DrawThreats(); - - ListBox* pkg_list; - ListBox* nav_list; - - ActiveWindow* threat[5]; -}; - -#endif // MsnPkgDlg_h - diff --git a/Stars45/MsnSelectDlg.cpp b/Stars45/MsnSelectDlg.cpp deleted file mode 100644 index fdd6b06..0000000 --- a/Stars45/MsnSelectDlg.cpp +++ /dev/null @@ -1,498 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Select Dialog Active Window class -*/ - -#include "MsnSelectDlg.h" -#include "MsnEditDlg.h" -#include "MsnEditNavDlg.h" -#include "ConfirmDlg.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Mission.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(MsnSelectDlg, OnAccept); -DEF_MAP_CLIENT(MsnSelectDlg, OnCancel); -DEF_MAP_CLIENT(MsnSelectDlg, OnMod); -DEF_MAP_CLIENT(MsnSelectDlg, OnNew); -DEF_MAP_CLIENT(MsnSelectDlg, OnEdit); -DEF_MAP_CLIENT(MsnSelectDlg, OnDel); -DEF_MAP_CLIENT(MsnSelectDlg, OnDelConfirm); -DEF_MAP_CLIENT(MsnSelectDlg, OnCampaignSelect); -DEF_MAP_CLIENT(MsnSelectDlg, OnMissionSelect); - -// +--------------------------------------------------------------------+ - -static Mission* edit_mission; - -// +--------------------------------------------------------------------+ - -MsnSelectDlg::MsnSelectDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -cmb_campaigns(0), lst_campaigns(0), lst_missions(0), -btn_accept(0), btn_cancel(0), btn_mod(0), -btn_new(0), btn_edit(0), btn_del(0), editable(false), -description(0), stars(0), campaign(0), -selected_mission(-1), mission_id(0) -{ - stars = Starshatter::GetInstance(); - campaign = Campaign::GetCampaign(); - edit_mission = 0; - - Init(def); -} - -MsnSelectDlg::~MsnSelectDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MsnSelectDlg::RegisterControls() -{ - btn_accept = (Button*) FindControl( 1); - btn_cancel = (Button*) FindControl( 2); - - if (btn_accept) { - btn_accept->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_accept, MsnSelectDlg, OnAccept); - } - - if (btn_cancel) { - REGISTER_CLIENT(EID_CLICK, btn_cancel, MsnSelectDlg, OnCancel); - } - - btn_mod = (Button*) FindControl(300); - btn_new = (Button*) FindControl(301); - btn_edit = (Button*) FindControl(302); - btn_del = (Button*) FindControl(303); - - if (btn_mod) - REGISTER_CLIENT(EID_CLICK, btn_mod, MsnSelectDlg, OnMod); - - if (btn_new) - REGISTER_CLIENT(EID_CLICK, btn_new, MsnSelectDlg, OnNew); - - if (btn_edit) - REGISTER_CLIENT(EID_CLICK, btn_edit, MsnSelectDlg, OnEdit); - - if (btn_del) { - REGISTER_CLIENT(EID_CLICK, btn_del, MsnSelectDlg, OnDel); - REGISTER_CLIENT(EID_USER_1, btn_del, MsnSelectDlg, OnDelConfirm); - } - - description = FindControl(200); - - cmb_campaigns = (ComboBox*) FindControl(201); - lst_campaigns = (ListBox*) FindControl(203); - lst_missions = (ListBox*) FindControl(202); - - if (cmb_campaigns) { - REGISTER_CLIENT(EID_SELECT, cmb_campaigns, MsnSelectDlg, OnCampaignSelect); - } - - if (lst_campaigns) { - REGISTER_CLIENT(EID_SELECT, lst_campaigns, MsnSelectDlg, OnCampaignSelect); - - lst_campaigns->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - lst_campaigns->SetLeading(4); - } - - if (lst_missions) { - REGISTER_CLIENT(EID_SELECT, lst_missions, MsnSelectDlg, OnMissionSelect); - - lst_missions->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - lst_missions->SetLeading(4); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnSelectDlg::Show() -{ - FormWindow::Show(); - campaign = Campaign::GetCampaign(); - - if (cmb_campaigns) { - int n = 0; - cmb_campaigns->ClearItems(); - ListIter iter = Campaign::GetAllCampaigns(); - while (++iter) { - Campaign* c = iter.value(); - - if (c->GetCampaignId() >= Campaign::SINGLE_MISSIONS) { - cmb_campaigns->AddItem(c->Name()); - - if (campaign->GetCampaignId() < Campaign::SINGLE_MISSIONS) { - campaign = Campaign::SelectCampaign(c->Name()); - cmb_campaigns->SetSelection(n); - } - - else if (campaign->GetCampaignId() == c->GetCampaignId()) { - cmb_campaigns->SetSelection(n); - } - - n++; - } - } - } - - else if (lst_campaigns) { - int n = 0; - lst_campaigns->ClearItems(); - ListIter iter = Campaign::GetAllCampaigns(); - while (++iter) { - Campaign* c = iter.value(); - - if (c->GetCampaignId() >= Campaign::SINGLE_MISSIONS) { - lst_campaigns->AddItem(c->Name()); - - if (campaign->GetCampaignId() < Campaign::SINGLE_MISSIONS) { - campaign = Campaign::SelectCampaign(c->Name()); - lst_campaigns->SetSelected(n); - } - - else if (campaign->GetCampaignId() == c->GetCampaignId()) { - lst_campaigns->SetSelected(n); - } - - n++; - } - } - } - - if (campaign) { - int id = campaign->GetCampaignId(); - editable = (id >= Campaign::MULTIPLAYER_MISSIONS && - id <= Campaign::CUSTOM_MISSIONS); - - if (btn_new) btn_new->SetEnabled(editable); - if (btn_edit) btn_edit->SetEnabled(false); - if (btn_del) btn_del->SetEnabled(false); - } - - if (description) - description->SetText(ContentBundle::GetInstance()->GetText("MsnSelectDlg.choose")); - - if (lst_missions) { - lst_missions->ClearItems(); - - if (campaign) { - ListIter iter = campaign->GetMissionList(); - while (++iter) { - MissionInfo* info = iter.value(); - Mission* m = info->mission; - - lst_missions->AddItem(info->name); - - if (m && m == edit_mission) { - lst_missions->SetSelected(lst_missions->NumItems()-1); - } - } - - if (selected_mission >= 0 && lst_missions->GetSelCount() == 0) { - lst_missions->SetSelected(selected_mission); - } - } - - OnMissionSelect(0); - edit_mission = 0; - } -} - -// +--------------------------------------------------------------------+ - -void -MsnSelectDlg::OnCampaignSelect(AWEvent* event) -{ - const char* selected_campaign = 0; - - if (cmb_campaigns) - selected_campaign = cmb_campaigns->GetSelectedItem(); - else if (lst_campaigns) - selected_campaign = lst_campaigns->GetSelectedItem(); - - Campaign* c = Campaign::SelectCampaign(selected_campaign); - - if (c) { - campaign = c; - - if (cmb_campaigns) { - cmb_campaigns->ClearItems(); - - ListIter iter = campaign->GetMissionList(); - while (++iter) { - cmb_campaigns->AddItem(iter->name); - } - } - - else if (lst_missions) { - lst_missions->ClearItems(); - - ListIter iter = campaign->GetMissionList(); - while (++iter) { - lst_missions->AddItem(iter->name); - } - - lst_missions->ScrollTo(0); - } - - if (btn_accept) - btn_accept->SetEnabled(false); - - if (description) - description->SetText(ContentBundle::GetInstance()->GetText("MsnSelectDlg.choose")); - - int id = c->GetCampaignId(); - editable = (id >= Campaign::MULTIPLAYER_MISSIONS && - id <= Campaign::CUSTOM_MISSIONS); - - if (btn_new) btn_new->SetEnabled(editable); - if (btn_edit) btn_edit->SetEnabled(false); - if (btn_del) btn_del->SetEnabled(false); - } -} - -void -MsnSelectDlg::OnMissionSelect(AWEvent* event) -{ - selected_mission = -1; - - for (int i = 0; i < lst_missions->NumItems(); i++) - if (lst_missions->IsSelected(i)) - selected_mission = i; - - if (btn_accept && description && campaign) { - List& mission_info_list = campaign->GetMissionList(); - - if (selected_mission >= 0 && selected_mission < mission_info_list.size()) { - MissionInfo* info = mission_info_list[selected_mission]; - mission_id = info->id; - - char time_buf[32]; - FormatDayTime(time_buf, info->start); - - Text d(""); - d += info->name; - d += "\n\n"; - d += ContentBundle::GetInstance()->GetText("MsnSelectDlg.mission-type"); - d += "\n\t"; - d += Mission::RoleName(info->type); - d += "\n\n"; - d += ContentBundle::GetInstance()->GetText("MsnSelectDlg.scenario"); - d += "\n\t"; - d += info->description; - d += "\n\n"; - d += ContentBundle::GetInstance()->GetText("MsnSelectDlg.location"); - d += "\n\t"; - d += info->region; - d += " "; - d += ContentBundle::GetInstance()->GetText("MsnSelectDlg.sector"); - d += " / "; - d += info->system; - d += " "; - d += ContentBundle::GetInstance()->GetText("MsnSelectDlg.system"); - d += "\n\n"; - d += ContentBundle::GetInstance()->GetText("MsnSelectDlg.start-time"); - d += "\n\t"; - d += time_buf; - - description->SetText(d); - btn_accept->SetEnabled(true); - - if (btn_edit) btn_edit->SetEnabled(editable); - if (btn_del) btn_del->SetEnabled(editable); - } - - else { - description->SetText(ContentBundle::GetInstance()->GetText("MsnSelectDlg.choose")); - btn_accept->SetEnabled(false); - - if (btn_edit) btn_edit->SetEnabled(false); - if (btn_del) btn_del->SetEnabled(false); - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnSelectDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - if (btn_accept && btn_accept->IsEnabled()) - OnAccept(0); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnSelectDlg::OnMod(AWEvent* event) -{ -} - -void -MsnSelectDlg::OnNew(AWEvent* event) -{ - const char* cname = 0; - - if (cmb_campaigns) - cname = cmb_campaigns->GetSelectedItem(); - else if (lst_campaigns) - cname = lst_campaigns->GetSelectedItem(); - - Campaign* c = Campaign::SelectCampaign(cname); - if (!c) return; - - MissionInfo* info = c->CreateNewMission(); - if (!info || !info->mission) - return; - - mission_id = info->id; - - MsnEditDlg* editor = manager->GetMsnEditDlg(); - - if (editor) { - edit_mission = info->mission; - - editor->SetMissionInfo(info); - editor->SetMission(info->mission); - manager->ShowMsnEditDlg(); - } - - MsnEditNavDlg* navdlg = (MsnEditNavDlg*) manager->GetNavDlg(); - - if (navdlg) { - navdlg->SetMission(info->mission); - navdlg->SetMissionInfo(info); - } -} - -void -MsnSelectDlg::OnEdit(AWEvent* event) -{ - const char* cname = 0; - - if (cmb_campaigns) - cname = cmb_campaigns->GetSelectedItem(); - else if (lst_campaigns) - cname = lst_campaigns->GetSelectedItem(); - - Campaign* c = Campaign::SelectCampaign(cname); - if (!c) return; - - Mission* m = c->GetMission(mission_id); - if (!m) return; - - MsnEditDlg* editor = manager->GetMsnEditDlg(); - - if (editor) { - edit_mission = m; - - editor->SetMissionInfo(c->GetMissionInfo(mission_id)); - editor->SetMission(m); - manager->ShowMsnEditDlg(); - } -} - -void -MsnSelectDlg::OnDel(AWEvent* event) -{ - const char* cname = 0; - - if (cmb_campaigns) - cname = cmb_campaigns->GetSelectedItem(); - else if (lst_campaigns) - cname = lst_campaigns->GetSelectedItem(); - - Campaign* c = Campaign::SelectCampaign(cname); - if (!c) return; - - Mission* m = c->GetMission(mission_id); - if (!m) return; - - ConfirmDlg* confirm = manager->GetConfirmDlg(); - if (confirm) { - char msg[256]; - sprintf_s(msg, ContentBundle::GetInstance()->GetText("MsnSelectDlg.are-you-sure").data(), m->Name()); - confirm->SetMessage(msg); - confirm->SetTitle(ContentBundle::GetInstance()->GetText("MsnSelectDlg.confirm-delete")); - confirm->SetParentControl(btn_del); - - manager->ShowConfirmDlg(); - } - - else { - OnDelConfirm(event); - } -} - -void -MsnSelectDlg::OnDelConfirm(AWEvent* event) -{ - const char* cname = 0; - - if (cmb_campaigns) - cname = cmb_campaigns->GetSelectedItem(); - else if (lst_campaigns) - cname = lst_campaigns->GetSelectedItem(); - - Campaign* c = Campaign::SelectCampaign(cname); - if (!c) return; - - edit_mission = 0; - c->DeleteMission(mission_id); - Show(); -} - -// +--------------------------------------------------------------------+ - -void -MsnSelectDlg::OnAccept(AWEvent* event) -{ - if (selected_mission >= 0) { - Mouse::Show(false); - - int id = campaign->GetMissionList()[selected_mission]->id; - campaign->SetMissionId(id); - campaign->ReloadMission(id); - - stars->SetGameMode(Starshatter::PREP_MODE); - } -} - -void -MsnSelectDlg::OnCancel(AWEvent* event) -{ - manager->ShowMenuDlg(); -} - -// +--------------------------------------------------------------------+ diff --git a/Stars45/MsnSelectDlg.h b/Stars45/MsnSelectDlg.h deleted file mode 100644 index 6fbc298..0000000 --- a/Stars45/MsnSelectDlg.h +++ /dev/null @@ -1,80 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Select Dialog Active Window class -*/ - -#ifndef MsnSelectDlg_h -#define MsnSelectDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class Campaign; -class Starshatter; - -// +--------------------------------------------------------------------+ - -class MsnSelectDlg : public FormWindow -{ -public: - MsnSelectDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~MsnSelectDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnCampaignSelect(AWEvent* event); - virtual void OnMissionSelect(AWEvent* event); - - virtual void OnMod(AWEvent* event); - virtual void OnNew(AWEvent* event); - virtual void OnEdit(AWEvent* event); - virtual void OnDel(AWEvent* event); - virtual void OnDelConfirm(AWEvent* event); - virtual void OnAccept(AWEvent* event); - virtual void OnCancel(AWEvent* event); - -protected: - MenuScreen* manager; - - Button* btn_mod; - Button* btn_new; - Button* btn_edit; - Button* btn_del; - Button* btn_accept; - Button* btn_cancel; - - ComboBox* cmb_campaigns; - ListBox* lst_campaigns; - ListBox* lst_missions; - - ActiveWindow* description; - - Starshatter* stars; - Campaign* campaign; - int selected_mission; - int mission_id; - bool editable; -}; - -#endif // MsnSelectDlg_h - diff --git a/Stars45/MsnWepDlg.cpp b/Stars45/MsnWepDlg.cpp deleted file mode 100644 index 2249d48..0000000 --- a/Stars45/MsnWepDlg.cpp +++ /dev/null @@ -1,515 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#include "MsnWepDlg.h" -#include "PlanScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Mission.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "WeaponDesign.h" -#include "HardPoint.h" -#include "StarSystem.h" -#include "FormatUtil.h" - -#include "Game.h" -#include "Mouse.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "ParseUtil.h" -#include "Keyboard.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: -DEF_MAP_CLIENT(MsnWepDlg, OnCommit); -DEF_MAP_CLIENT(MsnWepDlg, OnCancel); -DEF_MAP_CLIENT(MsnWepDlg, OnTabButton); -DEF_MAP_CLIENT(MsnWepDlg, OnMount); -DEF_MAP_CLIENT(MsnWepDlg, OnLoadout); - -// +--------------------------------------------------------------------+ - -MsnWepDlg::MsnWepDlg(Screen* s, FormDef& def, PlanScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), MsnDlg(mgr), -elem(0), first_station(0), beauty(0), player_desc(0) -{ - campaign = Campaign::GetCampaign(); - - if (campaign) - mission = campaign->GetMission(); - - ZeroMemory(designs, sizeof(designs)); - ZeroMemory(mounts, sizeof(mounts)); - Init(def); -} - -MsnWepDlg::~MsnWepDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -MsnWepDlg::RegisterControls() -{ - lbl_element = FindControl(601); - lbl_type = FindControl(602); - lbl_weight = FindControl(603); - loadout_list = (ListBox*) FindControl(604); - beauty = (ImageBox*) FindControl(300); - player_desc = FindControl(301); - - if (loadout_list) - REGISTER_CLIENT(EID_SELECT, loadout_list, MsnWepDlg, OnLoadout); - - for (int i = 0; i < 8; i++) { - lbl_desc[i] = FindControl(500 + i*10); - lbl_station[i] = FindControl(401 + i); - - for (int n = 0; n < 8; n++) { - btn_load[i][n] = (Button*) FindControl(500 + i*10 + n + 1); - - if (btn_load[i][n]) { - if (i == 0) { - if (n == 0) - btn_load[i][n]->GetPicture(led_off); - else if (n == 1) - btn_load[i][n]->GetPicture(led_on); - } - - btn_load[i][n]->SetPicture(led_off); - btn_load[i][n]->SetPictureLocation(4); // centered - REGISTER_CLIENT(EID_CLICK, btn_load[i][n], MsnWepDlg, OnMount); - } - } - } - - RegisterMsnControls(this); - - if (commit) - REGISTER_CLIENT(EID_CLICK, commit, MsnWepDlg, OnCommit); - - if (cancel) - REGISTER_CLIENT(EID_CLICK, cancel, MsnWepDlg, OnCancel); - - if (sit_button) - REGISTER_CLIENT(EID_CLICK, sit_button, MsnWepDlg, OnTabButton); - - if (pkg_button) - REGISTER_CLIENT(EID_CLICK, pkg_button, MsnWepDlg, OnTabButton); - - if (nav_button) - REGISTER_CLIENT(EID_CLICK, nav_button, MsnWepDlg, OnTabButton); - - if (wep_button) - REGISTER_CLIENT(EID_CLICK, wep_button, MsnWepDlg, OnTabButton); -} - -// +--------------------------------------------------------------------+ - -void -MsnWepDlg::Show() -{ - FormWindow::Show(); - ShowMsnDlg(); - - if (mission) { - for (int i = 0; i < mission->GetElements().size(); i++) { - MissionElement* e = mission->GetElements().at(i); - if (e->Player()) { - elem = e; - break; - } - } - } - - if (elem) { - SetupControls(); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnWepDlg::SetupControls() -{ - ShipDesign* design = (ShipDesign*) elem->GetDesign(); - - if (lbl_element) - lbl_element->SetText(elem->Name()); - - if (lbl_type) - lbl_type->SetText(design->name); - - BuildLists(); - - for (int i = 0; i < 8; i++) { - if (!lbl_desc[i]) continue; - - if (designs[i]) { - lbl_desc[i]->Show(); - lbl_desc[i]->SetText(designs[i]->group + " " + designs[i]->name); - - for (int n = 0; n < 8; n++) { - if (mounts[i][n]) { - btn_load[i][n]->Show(); - btn_load[i][n]->SetPicture((loads[n]==i) ? led_on : led_off); - } - else { - btn_load[i][n]->Hide(); - } - } - } - else { - lbl_desc[i]->Hide(); - - for (int n = 0; n < 8; n++) { - btn_load[i][n]->Hide(); - } - } - } - - double loaded_mass = 0; - char weight[32]; - - if (loadout_list) { - loadout_list->ClearItems(); - - if (design) { - ListIter sl = (List&) design->loadouts; - while (++sl) { - ShipLoad* load = sl.value(); - int item = loadout_list->AddItem(load->name) - 1; - - sprintf_s(weight, "%d kg", (int) ((design->mass + load->mass) * 1000)); - loadout_list->SetItemText(item, 1, weight); - loadout_list->SetItemData(item, 1, (DWORD) (load->mass * 1000)); - - if (elem->Loadouts().size() > 0 && - elem->Loadouts().at(0)->GetName() == load->name) { - loadout_list->SetSelected(item, true); - loaded_mass = design->mass + load->mass; - } - } - } - } - - if (lbl_weight && design) { - if (loaded_mass < 1) - loaded_mass = design->mass; - - sprintf_s(weight, "%d kg", (int) (loaded_mass * 1000)); - lbl_weight->SetText(weight); - } - - if (beauty && design) { - beauty->SetPicture(design->beauty); - } - - if (player_desc && design) { - char txt[256]; - - if (design->type <= Ship::ATTACK) - sprintf_s(txt, "%s %s", design->abrv, design->display_name); - else - sprintf_s(txt, "%s %s", design->abrv, elem->Name().data()); - - player_desc->SetText(txt); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnWepDlg::BuildLists() -{ - ZeroMemory(designs, sizeof(designs)); - ZeroMemory(mounts, sizeof(mounts)); - - if (elem) { - ShipDesign* d = (ShipDesign*) elem->GetDesign(); - int nstations = d->hard_points.size(); - - first_station = (8 - nstations) / 2; - - int index = 0; - int station = first_station; - - for (int s = 0; s < 8; s++) - if (lbl_station[s]) - lbl_station[s]->SetText(""); - - ListIter iter = d->hard_points; - while (++iter) { - HardPoint* hp = iter.value(); - - if (lbl_station[station]) - lbl_station[station]->SetText(hp->GetAbbreviation()); - - for (int n = 0; n < HardPoint::MAX_DESIGNS; n++) { - WeaponDesign* wep_dsn = hp->GetWeaponDesign(n); - - if (wep_dsn) { - bool found = false; - - for (int i = 0; i < 8 && !found; i++) { - if (designs[i] == wep_dsn) { - found = true; - mounts[i][station] = true; - } - } - - if (!found) { - mounts[index][station] = true; - designs[index++] = wep_dsn; - } - } - } - - station++; - } - - if (elem->Loadouts().size()) { - MissionLoad* msn_load = elem->Loadouts().at(0); - - for (int i = 0; i < 8; i++) - loads[i] = -1; - - // map loadout: - int* loadout = 0; - if (msn_load->GetName().length()) { - ListIter sl = ((ShipDesign*) elem->GetDesign())->loadouts; - while (++sl) { - if (!_stricmp(sl->name, msn_load->GetName())) - loadout = sl->load; - } - } - else { - loadout = msn_load->GetStations(); - } - - for (int i = 0; i < nstations; i++) { - loads[i + first_station] = loadout[i]; - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnWepDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnCommit(0); - } -} - -// +--------------------------------------------------------------------+ - -int -MsnWepDlg::LoadToPointIndex(int n) -{ - int nn = n + first_station; - - if (!elem || nn < 0 || nn >= 8 || loads[nn] == -1) - return -1; - - int index = -1; - WeaponDesign* wep_design = designs[ loads[nn] ]; - ShipDesign* design = (ShipDesign*) elem->GetDesign(); - HardPoint* hard_point = design->hard_points[n]; - - for (int i = 0; i < 8 && index < 0; i++) { - if (hard_point->GetWeaponDesign(i) == wep_design) { - index = i; - } - } - - return index; -} - -int -MsnWepDlg::PointIndexToLoad(int n, int index) -{ - int nn = n + first_station; - - if (!elem || nn < 0 || nn >= 8) - return -1; - - int result = -1; - ShipDesign* design = (ShipDesign*) elem->GetDesign(); - HardPoint* hard_point = design->hard_points[n]; - WeaponDesign* wep_design = hard_point->GetWeaponDesign(index); - - for (int i = 0; i < 8 && result < 0; i++) { - if (designs[i] == wep_design) { - result = i; - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -void -MsnWepDlg::OnMount(AWEvent* event) -{ - int station = -1; - int item = -1; - - for (int i = 0; i < 8 && item < 0; i++) { - for (int n = 0; n < 8 && station < 0; n++) { - if (btn_load[i][n] == event->window) { - station = n; - item = i; - } - } - } - - if (item >= 0 && station >= 0) { - if (loads[station] == item) - item = -1; - - loads[station] = item; - - for (int n = 0; n < 8; n++) { - btn_load[n][station]->SetPicture(n == item ? led_on : led_off); - } - - if (elem) { - int nstations = elem->GetDesign()->hard_points.size(); - - if (elem->Loadouts().size() < 1) { - MissionLoad* l = new MissionLoad; - elem->Loadouts().append(l); - - for (int n = 0; n < nstations; n++) - l->SetStation(n, LoadToPointIndex(n)); - } - else { - ListIter l = elem->Loadouts(); - while (++l) { - // if the player customizes the loadout, - // tell the sim loader not to use a named - // loadout from the ship design: - l->SetName(""); - - for (int n = 0; n < nstations; n++) - l->SetStation(n, LoadToPointIndex(n)); - } - } - } - } - - if (loadout_list) - loadout_list->ClearSelection(); - - if (lbl_weight && elem) { - ShipDesign* d = (ShipDesign*) elem->GetDesign(); - int nstations = d->hard_points.size(); - double mass = d->mass; - - for (int n = 0; n < nstations; n++) { - int item = loads[n+first_station]; - mass += d->hard_points[n]->GetCarryMass(item); - } - - char weight[32]; - sprintf_s(weight, "%d kg", (int) (mass * 1000)); - lbl_weight->SetText(weight); - } -} - -// +--------------------------------------------------------------------+ - -void -MsnWepDlg::OnLoadout(AWEvent* event) -{ - if (!elem) return; - - ShipDesign* design = (ShipDesign*) elem->GetDesign(); - ShipLoad* shipload = 0; - - if (loadout_list && design) { - int index = loadout_list->GetListIndex(); - Text loadname = loadout_list->GetItemText(index); - - ListIter sl = (List&) design->loadouts; - while (++sl) { - if (sl->name == loadname) { - shipload = sl.value(); - } - } - - if (!shipload) return; - - if (lbl_weight) { - char weight[32]; - sprintf_s(weight, "%d kg", (int) ((design->mass + shipload->mass) * 1000)); - lbl_weight->SetText(weight); - } - - if (elem->Loadouts().size() < 1) { - MissionLoad* l = new MissionLoad(-1, shipload->name); - elem->Loadouts().append(l); - } - else { - ListIter l = elem->Loadouts(); - while (++l) { - // if the player chooses a std loadout, - // tell the sim loader to use a named - // loadout from the ship design: - l->SetName(shipload->name); - } - } - - int nstations = design->hard_points.size(); - int* loadout = shipload->load; - - for (int i = 0; i < 8; i++) - loads[i] = -1; - - for (int i = 0; i < nstations; i++) - loads[i + first_station] = PointIndexToLoad(i, loadout[i]); - - for (int i = 0; i < 8; i++) { - for (int n = 0; n < 8; n++) { - btn_load[i][n]->SetPicture(i == loads[n] ? led_on: led_off); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -MsnWepDlg::OnCommit(AWEvent* event) -{ - MsnDlg::OnCommit(event); -} - -void -MsnWepDlg::OnCancel(AWEvent* event) -{ - MsnDlg::OnCancel(event); -} - -void -MsnWepDlg::OnTabButton(AWEvent* event) -{ - MsnDlg::OnTabButton(event); -} diff --git a/Stars45/MsnWepDlg.h b/Stars45/MsnWepDlg.h deleted file mode 100644 index 975595b..0000000 --- a/Stars45/MsnWepDlg.h +++ /dev/null @@ -1,85 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#ifndef MsnWepDlg_h -#define MsnWepDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "MsnDlg.h" -#include "Bitmap.h" -#include "Button.h" -#include "ImageBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class PlanScreen; -class Campaign; -class Mission; -class MissionElement; -class HardPoint; -class WeaponDesign; - -// +--------------------------------------------------------------------+ - -class MsnWepDlg : public FormWindow, -public MsnDlg -{ -public: - MsnWepDlg(Screen* s, FormDef& def, PlanScreen* mgr); - virtual ~MsnWepDlg(); - - virtual void RegisterControls(); - virtual void ExecFrame(); - virtual void Show(); - - // Operations: - virtual void OnCommit(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnTabButton(AWEvent* event); - virtual void OnMount(AWEvent* event); - virtual void OnLoadout(AWEvent* event); - -protected: - virtual void SetupControls(); - virtual void BuildLists(); - virtual int LoadToPointIndex(int n); - virtual int PointIndexToLoad(int n, int index); - - ActiveWindow* lbl_element; - ActiveWindow* lbl_type; - ActiveWindow* lbl_weight; - ActiveWindow* player_desc; - ImageBox* beauty; - - ActiveWindow* lbl_station[8]; - ActiveWindow* lbl_desc[8]; - Button* btn_load[8][8]; - - ListBox* loadout_list; - - MissionElement* elem; - WeaponDesign* designs[8]; - bool mounts[8][8]; - int loads[8]; - int first_station; - - Bitmap led_off; - Bitmap led_on; -}; - -#endif // MsnWepDlg_h - diff --git a/Stars45/MultiController.cpp b/Stars45/MultiController.cpp deleted file mode 100644 index 3df791b..0000000 --- a/Stars45/MultiController.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - MultiController Input class -*/ - -#include "MultiController.h" - -// +--------------------------------------------------------------------+ - -MultiController::MultiController() -: x(0), y(0), z(0), p(0), r(0), w(0), c(0), p1(0), r1(0), w1(0), t(0) -{ - for (int i = 0; i < MotionController::MaxActions; i++) - action[i] = 0; - - nctrl = 0; - for (int i = 0; i < 4; i++) - ctrl[i] = 0; -} - -MultiController::~MultiController() -{ - for (int i = 0; i < 4; i++) - delete ctrl[i]; -} - -// +--------------------------------------------------------------------+ - -void -MultiController::AddController(MotionController* c) -{ - if (nctrl < 4 && c) - ctrl[nctrl++] = c; -} - -void -MultiController::MapKeys(KeyMapEntry* mapping, int nkeys) -{ - for (int i = 0; i < nctrl; i++) - ctrl[i]->MapKeys(mapping, nkeys); -} - -int -MultiController::GetSwapYawRoll() const -{ - if (nctrl) - return ctrl[0]->GetSwapYawRoll(); - - return 0; -} - -void -MultiController::SwapYawRoll(int swap) -{ - for (int i = 0; i < nctrl; i++) - ctrl[i]->SwapYawRoll(swap); -} - -// +--------------------------------------------------------------------+ - -inline void clamp(double& x) { if (x<-1)x=-1; else if (x>1)x=1; } - -void -MultiController::Acquire() -{ - t = x = y = z = p = r = w = c = 0; - - for (int i = 0; i < MotionController::MaxActions; i++) - action[i] = 0; - - for (int i = 0; i < nctrl; i++) { - ctrl[i]->Acquire(); - - x += ctrl[i]->X(); - y += ctrl[i]->Y(); - z += ctrl[i]->Z(); - - r += ctrl[i]->Roll(); - p += ctrl[i]->Pitch(); - w += ctrl[i]->Yaw(); - c += ctrl[i]->Center(); - t += ctrl[i]->Throttle(); - - for (int a = 0; a < MotionController::MaxActions; a++) - action[a] += ctrl[i]->Action(a); - } - - clamp(x); - clamp(y); - clamp(z); - clamp(r); - clamp(p); - clamp(w); - clamp(t); -} - -// +--------------------------------------------------------------------+ - -void -MultiController::SetThrottle(double throttle) -{ - for (int i = 0; i < nctrl; i++) - ctrl[i]->SetThrottle(throttle); -} - -// +--------------------------------------------------------------------+ - -int -MultiController::ActionMap(int key) -{ - for (int i = 0; i < nctrl; i++) { - int result = ctrl[i]->ActionMap(key); - - if (result) - return result; - } - - return 0; -} - diff --git a/Stars45/MultiController.h b/Stars45/MultiController.h deleted file mode 100644 index 455a577..0000000 --- a/Stars45/MultiController.h +++ /dev/null @@ -1,67 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ComboController Motion Controller class -*/ - -#ifndef MultiController_h -#define MultiController_h - -#include "MotionController.h" - -// +--------------------------------------------------------------------+ - -class MultiController : public MotionController -{ -public: - static const char* TYPENAME() { return "MultiController"; } - - MultiController(); - virtual ~MultiController(); - - virtual void AddController(MotionController* c); - virtual void MapKeys(KeyMapEntry* mapping, int nkeys); - virtual void SwapYawRoll(int swap); - virtual int GetSwapYawRoll() const; - - // sample the physical device - virtual void Acquire(); - - // translations - virtual double X() { return x; } - virtual double Y() { return y; } - virtual double Z() { return z; } - - // rotations - virtual double Pitch() { return p; } - virtual double Roll() { return r; } - virtual double Yaw() { return w; } - virtual int Center() { return c; } - - // throttle - virtual double Throttle() { return t; } - virtual void SetThrottle(double throttle); - - // actions - virtual int Action(int n) { return action[n]; } - virtual int ActionMap(int n); - -protected: - int nctrl; - MotionController* ctrl[4]; - - double x,y,z,p,r,w,t; - double p1, r1, w1; - int c; - int action[MotionController::MaxActions]; -}; - -#endif // MultiController_h - diff --git a/Stars45/MusicDirector.cpp b/Stars45/MusicDirector.cpp deleted file mode 100644 index b2ff7ef..0000000 --- a/Stars45/MusicDirector.cpp +++ /dev/null @@ -1,519 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Music Director class to manage selection, setup, and playback - of background music tracks for both menu and game modes -*/ - -#include - -#include "MusicDirector.h" -#include "MusicTrack.h" - -#include "Random.h" -#include "DataLoader.h" -#include "FormatUtil.h" -#include "Sound.h" - -static MusicDirector* music_director = 0; - -// +-------------------------------------------------------------------+ - -MusicDirector::MusicDirector() -: mode(0), transition(0), track(0), next_track(0), no_music(true), -hproc(0) -{ - music_director = this; - - ScanTracks(); - - if (!no_music) - StartThread(); -} - -MusicDirector::~MusicDirector() -{ - StopThread(); - - delete track; - delete next_track; - - menu_tracks.destroy(); - intro_tracks.destroy(); - brief_tracks.destroy(); - debrief_tracks.destroy(); - promote_tracks.destroy(); - flight_tracks.destroy(); - combat_tracks.destroy(); - launch_tracks.destroy(); - recovery_tracks.destroy(); - victory_tracks.destroy(); - defeat_tracks.destroy(); - credit_tracks.destroy(); - - if (this == music_director) - music_director = 0; -} - -// +--------------------------------------------------------------------+ - -void -MusicDirector::Initialize() -{ - if (music_director) delete music_director; - music_director = new MusicDirector(); -} - -void -MusicDirector::Close() -{ - delete music_director; - music_director = 0; -} - -MusicDirector* -MusicDirector::GetInstance() -{ - return music_director; -} - -// +-------------------------------------------------------------------+ - -void -MusicDirector::ExecFrame() -{ - if (no_music) return; - - const std::lock_guard lock(sync); - - if (next_track && !track) { - track = next_track; - next_track = 0; - } - - if (track) { - if (track->IsDone()) { - if (mode != NONE && mode != SHUTDOWN && next_track == 0) { - GetNextTrack(track->GetIndex()+1); - } - - delete track; - track = next_track; - next_track = 0; - } - - else if (track->IsLooped()) { - if (mode != NONE && mode != SHUTDOWN && next_track == 0) { - GetNextTrack(track->GetIndex()+1); - } - - track->FadeOut(); - track->ExecFrame(); - } - - else { - track->ExecFrame(); - } - } - - if (next_track) { - if (next_track->IsDone()) { - delete next_track; - next_track = 0; - } - - else if (next_track->IsLooped()) { - next_track->FadeOut(); - next_track->ExecFrame(); - } - - else { - next_track->ExecFrame(); - } - } -} - -// +-------------------------------------------------------------------+ - -void -MusicDirector::ScanTracks() -{ - DataLoader* loader = DataLoader::GetLoader(); - - bool old_file_system = loader->IsFileSystemEnabled(); - loader->UseFileSystem(true); - loader->SetDataPath("Music/"); - - List files; - loader->ListFiles("*.ogg", files, true); - - if (files.size() == 0) { - loader->UseFileSystem(old_file_system); - no_music = true; - return; - } - - no_music = false; - - ListIter iter = files; - while (++iter) { - Text* name = iter.value(); - Text* file = new Text("Music/"); - - name->setSensitive(false); - file->append(*name); - - if (name->indexOf("Menu") == 0) { - menu_tracks.append(file); - } - - else if (name->indexOf("Intro") == 0) { - intro_tracks.append(file); - } - - else if (name->indexOf("Brief") == 0) { - brief_tracks.append(file); - } - - else if (name->indexOf("Debrief") == 0) { - debrief_tracks.append(file); - } - - else if (name->indexOf("Promot") == 0) { - promote_tracks.append(file); - } - - else if (name->indexOf("Flight") == 0) { - flight_tracks.append(file); - } - - else if (name->indexOf("Combat") == 0) { - combat_tracks.append(file); - } - - else if (name->indexOf("Launch") == 0) { - launch_tracks.append(file); - } - - else if (name->indexOf("Recovery") == 0) { - recovery_tracks.append(file); - } - - else if (name->indexOf("Victory") == 0) { - victory_tracks.append(file); - } - - else if (name->indexOf("Defeat") == 0) { - defeat_tracks.append(file); - } - - else if (name->indexOf("Credit") == 0) { - credit_tracks.append(file); - } - - else { - menu_tracks.append(file); - } - - delete iter.removeItem(); - } - - loader->UseFileSystem(old_file_system); - - menu_tracks.sort(); - intro_tracks.sort(); - brief_tracks.sort(); - debrief_tracks.sort(); - promote_tracks.sort(); - flight_tracks.sort(); - combat_tracks.sort(); - launch_tracks.sort(); - recovery_tracks.sort(); - victory_tracks.sort(); - defeat_tracks.sort(); - credit_tracks.sort(); -} - -// +-------------------------------------------------------------------+ - -const char* -MusicDirector::GetModeName(int mode) -{ - switch (mode) { - case NONE: return "NONE"; - case MENU: return "MENU"; - case INTRO: return "INTRO"; - case BRIEFING: return "BRIEFING"; - case DEBRIEFING: return "DEBRIEFING"; - case PROMOTION: return "PROMOTION"; - case FLIGHT: return "FLIGHT"; - case COMBAT: return "COMBAT"; - case LAUNCH: return "LAUNCH"; - case RECOVERY: return "RECOVERY"; - case VICTORY: return "VICTORY"; - case DEFEAT: return "DEFEAT"; - case CREDITS: return "CREDITS"; - case SHUTDOWN: return "SHUTDOWN"; - } - - return "UNKNOWN?"; -} - -// +-------------------------------------------------------------------+ - -void -MusicDirector::SetMode(int mode) -{ - if (!music_director || music_director->no_music) return; - - const std::lock_guard lock(music_director->sync); - - // stay in intro mode until it is complete: - if (mode == MENU && (music_director->GetMode() == NONE || - music_director->GetMode() == INTRO)) - mode = INTRO; - - mode = music_director->CheckMode(mode); - - if (mode != music_director->mode) { - ::Print("MusicDirector::SetMode() old: %s new: %s\n", - GetModeName(music_director->mode), - GetModeName(mode)); - - music_director->mode = mode; - - MusicTrack* t = music_director->track; - if (t && t->GetState() && !t->IsDone()) { - if (mode == NONE || mode == SHUTDOWN) - t->SetFadeTime(0.5); - - t->FadeOut(); - } - - t = music_director->next_track; - if (t && t->GetState() && !t->IsDone()) { - if (mode == NONE || mode == SHUTDOWN) - t->SetFadeTime(0.5); - t->FadeOut(); - - delete music_director->track; - music_director->track = t; - music_director->next_track = 0; - } - - music_director->ShuffleTracks(); - music_director->GetNextTrack(0); - - if (music_director->next_track) - music_director->next_track->FadeIn(); - } -} - -int -MusicDirector::CheckMode(int req_mode) -{ - if (req_mode == RECOVERY && recovery_tracks.size() == 0) - req_mode = LAUNCH; - - if (req_mode == LAUNCH && launch_tracks.size() == 0) - req_mode = FLIGHT; - - if (req_mode == COMBAT && combat_tracks.size() == 0) - req_mode = FLIGHT; - - if (req_mode == FLIGHT && flight_tracks.size() == 0) - req_mode = NONE; - - if (req_mode == PROMOTION && promote_tracks.size() == 0) - req_mode = VICTORY; - - if (req_mode == DEBRIEFING && debrief_tracks.size() == 0) - req_mode = BRIEFING; - - if (req_mode == BRIEFING && brief_tracks.size() == 0) - req_mode = MENU; - - if (req_mode == INTRO && intro_tracks.size() == 0) - req_mode = MENU; - - if (req_mode == VICTORY && victory_tracks.size() == 0) - req_mode = MENU; - - if (req_mode == DEFEAT && defeat_tracks.size() == 0) - req_mode = MENU; - - if (req_mode == CREDITS && credit_tracks.size() == 0) - req_mode = MENU; - - if (req_mode == MENU && menu_tracks.size() == 0) - req_mode = NONE; - - return req_mode; -} - -// +-------------------------------------------------------------------+ - -bool -MusicDirector::IsNoMusic() -{ - if (music_director) - return music_director->no_music; - - return true; -} - -// +-------------------------------------------------------------------+ - -void -MusicDirector::GetNextTrack(int index) -{ - List* tracks = 0; - - switch (mode) { - case MENU: tracks = &menu_tracks; break; - case INTRO: tracks = &intro_tracks; break; - case BRIEFING: tracks = &brief_tracks; break; - case DEBRIEFING: tracks = &debrief_tracks; break; - case PROMOTION: tracks = &promote_tracks; break; - case FLIGHT: tracks = &flight_tracks; break; - case COMBAT: tracks = &combat_tracks; break; - case LAUNCH: tracks = &launch_tracks; break; - case RECOVERY: tracks = &recovery_tracks; break; - case VICTORY: tracks = &victory_tracks; break; - case DEFEAT: tracks = &defeat_tracks; break; - case CREDITS: tracks = &credit_tracks; break; - default: tracks = 0; break; - } - - if (tracks && tracks->size()) { - if (next_track) - delete next_track; - - if (index < 0 || index >= tracks->size()) { - index = 0; - - if (mode == INTRO) { - mode = MENU; - ShuffleTracks(); - tracks = &menu_tracks; - - ::Print("MusicDirector: INTRO mode complete, switching to MENU\n"); - - if (!tracks->size()) - return; - } - } - - next_track = new MusicTrack(*tracks->at(index), mode, index); - next_track->FadeIn(); - } - - else if (next_track) { - next_track->FadeOut(); - } -} - -// +-------------------------------------------------------------------+ - -void -MusicDirector::ShuffleTracks() -{ - List* tracks = 0; - - switch (mode) { - case MENU: tracks = &menu_tracks; break; - case INTRO: tracks = &intro_tracks; break; - case BRIEFING: tracks = &brief_tracks; break; - case DEBRIEFING: tracks = &debrief_tracks; break; - case PROMOTION: tracks = &promote_tracks; break; - case FLIGHT: tracks = &flight_tracks; break; - case COMBAT: tracks = &combat_tracks; break; - case LAUNCH: tracks = &launch_tracks; break; - case RECOVERY: tracks = &recovery_tracks; break; - case VICTORY: tracks = &victory_tracks; break; - case DEFEAT: tracks = &defeat_tracks; break; - case CREDITS: tracks = &credit_tracks; break; - default: tracks = 0; break; - } - - if (tracks && tracks->size() > 1) { - tracks->sort(); - - Text* t = tracks->at(0); - - if (!isdigit(*t[0])) - tracks->shuffle(); - } -} - -// +--------------------------------------------------------------------+ - -DWORD WINAPI MusicDirectorThreadProc(LPVOID link); - -void -MusicDirector::StartThread() -{ - if (hproc != 0) { - DWORD result = 0; - GetExitCodeThread(hproc, &result); - - if (result != STILL_ACTIVE) { - CloseHandle(hproc); - hproc = 0; - } - else { - return; - } - } - - if (hproc == 0) { - DWORD thread_id = 0; - hproc = CreateThread(0, 4096, MusicDirectorThreadProc, (LPVOID) this, 0, &thread_id); - - if (hproc == 0) { - static int report = 10; - if (report > 0) { - ::Print("WARNING: MusicDirector failed to create thread (err=%08x)\n", GetLastError()); - report--; - - if (report == 0) - ::Print(" Further warnings of this type will be supressed.\n"); - } - } - } -} - -void -MusicDirector::StopThread() -{ - if (hproc != 0) { - SetMode(SHUTDOWN); - WaitForSingleObject(hproc, 1500); - CloseHandle(hproc); - hproc = 0; - } -} - -DWORD WINAPI MusicDirectorThreadProc(LPVOID link) -{ - MusicDirector* dir = (MusicDirector*) link; - - if (dir) { - while (dir->GetMode() != MusicDirector::SHUTDOWN) { - dir->ExecFrame(); - Sleep(100); - } - - return 0; - } - - return (DWORD) E_POINTER; -} - diff --git a/Stars45/MusicDirector.h b/Stars45/MusicDirector.h deleted file mode 100644 index 8fc6812..0000000 --- a/Stars45/MusicDirector.h +++ /dev/null @@ -1,115 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Music Director class to manage selection, setup, and playback - of background music tracks for both menu and game modes -*/ - - -#ifndef MusicDirector_h -#define MusicDirector_h - -#include - -#include "Types.h" -#include "List.h" -#include "Text.h" - -// +-------------------------------------------------------------------+ - -class MusicTrack; - -// +-------------------------------------------------------------------+ - -class MusicDirector -{ -public: - enum MODES { - NONE, - - // menu modes: - - MENU, - INTRO, - BRIEFING, - DEBRIEFING, - PROMOTION, - VICTORY, - DEFEAT, - CREDITS, - - // in game modes: - - FLIGHT, - COMBAT, - LAUNCH, - RECOVERY, - - // special modes: - SHUTDOWN - }; - - enum TRANSITIONS { - CUT, - FADE_OUT, - FADE_IN, - FADE_BOTH, - CROSS_FADE - }; - - MusicDirector(); - ~MusicDirector(); - - // Operations: - void ExecFrame(); - void ScanTracks(); - - int CheckMode(int mode); - int GetMode() const { return mode; } - - static void Initialize(); - static void Close(); - static MusicDirector* GetInstance(); - static void SetMode(int mode); - static const char* GetModeName(int mode); - static bool IsNoMusic(); - -protected: - void StartThread(); - void StopThread(); - void GetNextTrack(int index); - void ShuffleTracks(); - - int mode; - int transition; - - MusicTrack* track; - MusicTrack* next_track; - - List menu_tracks; - List intro_tracks; - List brief_tracks; - List debrief_tracks; - List promote_tracks; - List flight_tracks; - List combat_tracks; - List launch_tracks; - List recovery_tracks; - List victory_tracks; - List defeat_tracks; - List credit_tracks; - - bool no_music; - - HANDLE hproc; - std::mutex sync; -}; - -#endif // MusicDirector_h \ No newline at end of file diff --git a/Stars45/MusicTrack.cpp b/Stars45/MusicTrack.cpp deleted file mode 100644 index cca61a5..0000000 --- a/Stars45/MusicTrack.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Music Director class to manage selection, setup, and playback - of background music tracks for both menu and game modes -*/ - - -#include "MusicTrack.h" -#include "MusicDirector.h" -#include "Starshatter.h" -#include "AudioConfig.h" - -#include "Game.h" -#include "Clock.h" -#include "Sound.h" - -// +-------------------------------------------------------------------+ - -const double FADE_TIME = 1.5; -const double SILENCE = -5000; - -// +-------------------------------------------------------------------+ - -MusicTrack::MusicTrack(const Text& txt, int m, int n) -: name(txt), sound(0), state(NONE), mode(m), index(n), -fade(0), fade_time(FADE_TIME) -{ - long max_vol = 0; - - if (mode >= MusicDirector::FLIGHT) - max_vol = AudioConfig::GameMusic(); - else - max_vol = AudioConfig::MenuMusic(); - - if (max_vol <= AudioConfig::Silence()) - return; - - name.setSensitive(false); - - if (name.contains(".ogg")) { - sound = Sound::CreateOggStream(name); - - if (name.contains("-loop")) { - sound->SetFlags(Sound::STREAMED | - Sound::OGGVORBIS | - Sound::LOOP | - Sound::LOCKED); - } - - else { - sound->SetFlags(Sound::STREAMED | - Sound::OGGVORBIS | - Sound::LOCKED); - } - - sound->SetVolume((long) SILENCE); - } -} - -MusicTrack::~MusicTrack() -{ - if (sound) { - sound->Stop(); - sound->Release(); - } -} - -// +--------------------------------------------------------------------+ - -void -MusicTrack::ExecFrame() -{ - bool music_pause = false; - - Starshatter* stars = Starshatter::GetInstance(); - if (stars) { - music_pause = (stars->GetGameMode() == Starshatter::PLAY_MODE) && - Game::GetInstance()->Paused(); - } - - if (sound && !music_pause) { - double fvol = 1; - long volume = 0; - - switch (state) { - case PLAY: - if (sound->IsReady()) - sound->Play(); - SetVolume(volume); - break; - - case FADE_IN: - if (sound->IsReady()) - sound->Play(); - - if (fade > 0) { - fvol = fade/fade_time; - volume = (long) (fvol * SILENCE); - SetVolume(volume); - } - - if (fade < 0.01) - state = PLAY; - break; - - case FADE_OUT: - if (sound->IsReady()) - sound->Play(); - - if (fade > 0) { - fvol = 1 - fade/fade_time; - volume = (long) (fvol * SILENCE); - SetVolume(volume); - } - - if (fade < 0.01) - state = STOP; - break; - - case STOP: - if (sound->IsPlaying()) { - sound->Stop(); - sound->Release(); - sound = 0; - } - break; - } - - if (fade > 0) - fade -= Clock::GetInstance()->GuiDelta(); - - if (fade < 0) - fade = 0; - } -} - -// +--------------------------------------------------------------------+ - -void -MusicTrack::Play() -{ - state = PLAY; - fade = 0; -} - -void -MusicTrack::Stop() -{ - state = STOP; - fade = 0; -} - -void -MusicTrack::FadeIn() -{ - if (state != FADE_IN && state != PLAY) { - state = FADE_IN; - fade = fade_time; - } -} - -void -MusicTrack::FadeOut() -{ - if (state != FADE_OUT && state != STOP) { - state = FADE_OUT; - fade = fade_time; - } -} - -// +--------------------------------------------------------------------+ - -int -MusicTrack::IsReady() const -{ - if (sound) - return sound->IsReady(); - - return false; -} - -int -MusicTrack::IsPlaying() const -{ - if (sound) - return sound->IsPlaying(); - - return false; -} - -int -MusicTrack::IsDone() const -{ - if (sound) - return sound->IsDone() || sound->LoopCount() >= 5; - - return true; -} - -int -MusicTrack::IsLooped() const -{ - if (sound) - return sound->IsDone() || sound->LoopCount() >= 4; - - return true; -} - -// +--------------------------------------------------------------------+ - -long -MusicTrack::GetVolume() const -{ - if (sound) - return sound->GetVolume(); - - return 0; -} - -void -MusicTrack::SetVolume(long v) -{ - if (sound) { - long max_vol = 0; - - if (mode >= MusicDirector::FLIGHT) - max_vol = AudioConfig::GameMusic(); - else - max_vol = AudioConfig::MenuMusic(); - - if (v > max_vol) - v = max_vol; - - sound->SetVolume(v); - } -} - -double -MusicTrack::GetTotalTime() const -{ - if (sound) - return sound->GetTotalTime(); - - return 0; -} - -double -MusicTrack::GetTimeRemaining() const -{ - if (sound) - return sound->GetTimeRemaining(); - - return 0; -} - -double -MusicTrack::GetTimeElapsed() const -{ - if (sound) - return sound->GetTimeElapsed(); - - return 0; -} - diff --git a/Stars45/MusicTrack.h b/Stars45/MusicTrack.h deleted file mode 100644 index 30af277..0000000 --- a/Stars45/MusicTrack.h +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - MusicTrack class -*/ - - -#ifndef MusicTrack_h -#define MusicTrack_h - -#include "Types.h" -#include "List.h" -#include "Text.h" - -// +-------------------------------------------------------------------+ - -class Sound; - -// +-------------------------------------------------------------------+ - -class MusicTrack -{ -public: - enum STATE { NONE, FADE_IN, PLAY, FADE_OUT, STOP }; - - MusicTrack(const Text& name, int mode=0, int index=0); - virtual ~MusicTrack(); - - // Operations: - virtual void ExecFrame(); - - virtual void Play(); - virtual void Stop(); - virtual void FadeIn(); - virtual void FadeOut(); - - // accessors / mutators - const Text& Name() const { return name; } - Sound* GetSound() const { return sound; } - int GetState() const { return state; } - int GetMode() const { return mode; } - int GetIndex() const { return index; } - - int IsReady() const; - int IsPlaying() const; - int IsDone() const; - int IsLooped() const; - - virtual long GetVolume() const; - virtual void SetVolume(long v); - - virtual double GetTotalTime() const; - virtual double GetTimeRemaining() const; - virtual double GetTimeElapsed() const; - - virtual double GetFadeTime() const { return fade_time; } - virtual void SetFadeTime(double t) { fade_time = t; } - -protected: - Text name; - Sound* sound; - int state; - int mode; - int index; - double fade; - double fade_time; -}; - -#endif // MusicTrack_h \ No newline at end of file diff --git a/Stars45/NPClient.h b/Stars45/NPClient.h deleted file mode 100644 index bf7925b..0000000 --- a/Stars45/NPClient.h +++ /dev/null @@ -1,190 +0,0 @@ -// ******************************************************************************* -// * -// * Module Name: -// * NPClient.h -// * -// * Doyle Nickless -- 13 Jan, 2003 -- for Eye Control Technology. -// * -// * Abstract: -// * Header for NaturalPoint Game Client API. -// * -// * Environment: -// * Microsoft Windows -- User mode -// * -// ******************************************************************************* - -#ifndef _NPCLIENT_H_DEFINED_ -#define _NPCLIENT_H_DEFINED_ - -#pragma pack( push, npclient_h ) // Save current pack value -#pragma pack(1) - -////////////////// -/// Defines ////////////////////////////////////////////////////////////////////// -///////////////// -#define VERSION_MAJOR 1 -#define VERSION_MINOR 0 -#define VERSION_BUILD 1 - -// magic to get the preprocessor to do what we want -#define lita(arg) #arg -#define xlita(arg) lita(arg) -#define cat3(w,x,z) w##.##x##.##z##\000 -#define xcat3(w,x,z) cat3(w,x,z) -#define VERSION_STRING xlita(xcat3(VERSION_MAJOR,VERSION_MINOR,VERSION_BUILD)) -// -// Versioning hasn't been worked out yet... -// -// The following is the previous spec definition of versioning info -- I can probably do -// something very similar to this -- will keep you posted. -// -// request version information using 2 messages, they cannot be expected to arrive in a specific order - so always parse using the High byte -// the messages have a NPCONTROL byte in the first parameter, and the second parameter has packed bytes. -// Message 1) (first parameter)NPCONTROL : (second parameter) (High Byte)NPVERSIONMAJOR (Low Byte) major version number data -// Message 2) (first parameter)NPCONTROL : (second parameter) (High Byte)NPVERSIONMINOR (Low Byte) minor version number data - -#define NPQUERYVERSION 1040 - -#define NPSTATUS_REMOTEACTIVE 0 -#define NPSTATUS_REMOTEDISABLED 1 - -// CONTROL DATA SUBFIELDS -#define NPVERSIONMAJOR 1 -#define NPVERSIONMINOR 2 - -// DATA FIELDS -#define NPControl 8 // indicates a control data field -// the second parameter of a message bearing control data information contains a packed data format. -// The High byte indicates what the data is, and the Low byte contains the actual data -// roll, pitch, yaw -#define NPRoll 1 // +/- 16383 (representing +/- 180) [data = input - 16383] -#define NPPitch 2 // +/- 16383 (representing +/- 180) [data = input - 16383] -#define NPYaw 4 // +/- 16383 (representing +/- 180) [data = input - 16383] - -// x, y, z - remaining 6dof coordinates -#define NPX 16 // +/- 16383 [data = input - 16383] -#define NPY 32 // +/- 16383 [data = input - 16383] -#define NPZ 64 // +/- 16383 [data = input - 16383] - -// raw object position from imager -#define NPRawX 128 // 0..25600 (actual value is multiplied x 100 to pass two decimal places of precision) [data = input / 100] -#define NPRawY 256 // 0..25600 (actual value is multiplied x 100 to pass two decimal places of precision) [data = input / 100] -#define NPRawZ 512 // 0..25600 (actual value is multiplied x 100 to pass two decimal places of precision) [data = input / 100] - -// x, y, z deltas from raw imager position -#define NPDeltaX 1024 // +/- 2560 (actual value is multiplied x 10 to pass two decimal places of precision) [data = (input / 10) - 256] -#define NPDeltaY 2048 // +/- 2560 (actual value is multiplied x 10 to pass two decimal places of precision) [data = (input / 10) - 256] -#define NPDeltaZ 4096 // +/- 2560 (actual value is multiplied x 10 to pass two decimal places of precision) [data = (input / 10) - 256] - -// raw object position from imager -#define NPSmoothX 8192 // 0..32766 (actual value is multiplied x 10 to pass one decimal place of precision) [data = input / 10] -#define NPSmoothY 16384 // 0..32766 (actual value is multiplied x 10 to pass one decimal place of precision) [data = input / 10] -#define NPSmoothZ 32768 // 0..32766 (actual value is multiplied x 10 to pass one decimal place of precision) [data = input / 10] - - -////////////////// -/// Typedefs ///////////////////////////////////////////////////////////////////// -///////////////// - -// NPESULT values are returned from the Game Client API functions. -// -typedef enum tagNPResult -{ - NP_OK = 0, - NP_ERR_DEVICE_NOT_PRESENT, - NP_ERR_UNSUPPORTED_OS, - NP_ERR_INVALID_ARG, - NP_ERR_DLL_NOT_FOUND, - NP_ERR_NO_DATA, - NP_ERR_INTERNAL_DATA - -} NPRESULT; - -typedef struct tagTrackIRSignature -{ - char DllSignature[200]; - char AppSignature[200]; - -} SIGNATUREDATA, *LPTRACKIRSIGNATURE; - -typedef struct tagTrackIRData -{ - unsigned short wNPStatus; - unsigned short wPFrameSignature; - unsigned long dwNPIOData; - - float fNPRoll; - float fNPPitch; - float fNPYaw; - float fNPX; - float fNPY; - float fNPZ; - float fNPRawX; - float fNPRawY; - float fNPRawZ; - float fNPDeltaX; - float fNPDeltaY; - float fNPDeltaZ; - float fNPSmoothX; - float fNPSmoothY; - float fNPSmoothZ; - -} TRACKIRDATA, *LPTRACKIRDATA; - - -// -// Typedef for pointer to the notify callback function that is implemented within -// the client -- this function receives head tracker reports from the game client API -// -typedef NPRESULT (__stdcall *PF_NOTIFYCALLBACK)( unsigned short, unsigned short ); - -// Typedefs for game client API functions (useful for declaring pointers to these -// functions within the client for use during GetProcAddress() ops) -// -typedef NPRESULT (__stdcall *PF_NP_REGISTERWINDOWHANDLE)( HWND ); -typedef NPRESULT (__stdcall *PF_NP_UNREGISTERWINDOWHANDLE)( void ); -typedef NPRESULT (__stdcall *PF_NP_REGISTERPROGRAMPROFILEID)( unsigned short ); -typedef NPRESULT (__stdcall *PF_NP_QUERYVERSION)( unsigned short* ); -typedef NPRESULT (__stdcall *PF_NP_REQUESTDATA)( unsigned short ); -typedef NPRESULT (__stdcall *PF_NP_GETSIGNATURE)( LPTRACKIRSIGNATURE ); -typedef NPRESULT (__stdcall *PF_NP_GETDATA)( LPTRACKIRDATA ); -typedef NPRESULT (__stdcall *PF_NP_REGISTERNOTIFY)( PF_NOTIFYCALLBACK ); -typedef NPRESULT (__stdcall *PF_NP_UNREGISTERNOTIFY)( void ); -typedef NPRESULT (__stdcall *PF_NP_STARTCURSOR)( void ); -typedef NPRESULT (__stdcall *PF_NP_STOPCURSOR)( void ); -typedef NPRESULT (__stdcall *PF_NP_RECENTER)( void ); -typedef NPRESULT (__stdcall *PF_NP_STARTDATATRANSMISSION)( void ); -typedef NPRESULT (__stdcall *PF_NP_STOPDATATRANSMISSION)( void ); - -//// Function Prototypes /////////////////////////////////////////////// -// -// Functions exported from game client API DLL ( note __stdcall calling convention -// is used for ease of interface to clients of differing implementations including -// C, C++, Pascal (Delphi) and VB. ) -// -NPRESULT __stdcall NP_RegisterWindowHandle( HWND hWnd ); -NPRESULT __stdcall NP_UnregisterWindowHandle( void ); -NPRESULT __stdcall NP_RegisterProgramProfileID( unsigned short wPPID ); -NPRESULT __stdcall NP_QueryVersion( unsigned short* pwVersion ); -NPRESULT __stdcall NP_RequestData( unsigned short wDataReq ); -NPRESULT __stdcall NP_GetSignature( LPTRACKIRSIGNATURE pSignature ); -NPRESULT __stdcall NP_GetData( LPTRACKIRDATA pTID ); -NPRESULT __stdcall NP_RegisterNotify( PF_NOTIFYCALLBACK pfNotify ); -NPRESULT __stdcall NP_UnregisterNotify( void ); -NPRESULT __stdcall NP_StartCursor( void ); -NPRESULT __stdcall NP_StopCursor( void ); -NPRESULT __stdcall NP_ReCenter( void ); -NPRESULT __stdcall NP_StartDataTransmission( void ); -NPRESULT __stdcall NP_StopDataTransmission( void ); - -///////////////////////////////////////////////////////////////////////// - -#pragma pack( pop, npclient_h ) // Ensure previous pack value is restored - -#endif // #ifdef NPCLIENT_H_DEFINED_ - -// -// *** End of file: NPClient.h *** -// - - diff --git a/Stars45/NPClientWraps.cpp b/Stars45/NPClientWraps.cpp deleted file mode 100644 index 0705696..0000000 --- a/Stars45/NPClientWraps.cpp +++ /dev/null @@ -1,256 +0,0 @@ -// ******************************************************************************* -// * -// * Module Name: -// * NPClientWraps.cpp -// * -// * Software Engineer: -// * Doyle Nickless - GoFlight Inc., for Eye Control Technology. -// * -// * Abstract: -// * This module implements the wrapper code for interfacing to the NaturalPoint -// * Game Client API. Developers of client apps can include this module into -// * their projects to simplify communication with the NaturalPoint software. -// * -// * This is necessary since the NPClient DLL is run-time linked rather than -// * load-time linked, avoiding the need to link a static library into the -// * client program (only this module is needed, and can be supplied in source -// * form.) -// * -// * Environment: -// * User mode -// * -// ******************************************************************************* -// -#include "Game.h" -#include "Text.h" - -#include "NPClient.h" -#include "NPClientWraps.h" - -///////////// -// Defines /////////////////////////////////////////////////////////////////////// -///////////// -// - -///////////////// -// Global Data /////////////////////////////////////////////////////////////////// -///////////////// -// -PF_NP_REGISTERWINDOWHANDLE gpfNP_RegisterWindowHandle = NULL; -PF_NP_UNREGISTERWINDOWHANDLE gpfNP_UnregisterWindowHandle = NULL; -PF_NP_REGISTERPROGRAMPROFILEID gpfNP_RegisterProgramProfileID = NULL; -PF_NP_QUERYVERSION gpfNP_QueryVersion = NULL; -PF_NP_REQUESTDATA gpfNP_RequestData = NULL; -PF_NP_GETSIGNATURE gpfNP_GetSignature = NULL; -PF_NP_GETDATA gpfNP_GetData = NULL; -PF_NP_STARTCURSOR gpfNP_StartCursor = NULL; -PF_NP_STOPCURSOR gpfNP_StopCursor = NULL; -PF_NP_RECENTER gpfNP_ReCenter = NULL; -PF_NP_STARTDATATRANSMISSION gpfNP_StartDataTransmission = NULL; -PF_NP_STOPDATATRANSMISSION gpfNP_StopDataTransmission = NULL; - -HMODULE ghNPClientDLL = (HMODULE)NULL; - -//////////////////////////////////////////////////// -// NaturalPoint Game Client API function wrappers ///////////////////////////// -//////////////////////////////////////////////////// -// -NPRESULT __stdcall NP_RegisterWindowHandle( HWND hWnd ) -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_RegisterWindowHandle ) - result = (*gpfNP_RegisterWindowHandle)( hWnd ); - - return result; -} // NP_RegisterWindowHandle() - - -NPRESULT __stdcall NP_UnregisterWindowHandle() -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_UnregisterWindowHandle ) - result = (*gpfNP_UnregisterWindowHandle)(); - - return result; -} // NP_UnregisterWindowHandle() - - -NPRESULT __stdcall NP_RegisterProgramProfileID( unsigned short wPPID ) -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_RegisterProgramProfileID ) - result = (*gpfNP_RegisterProgramProfileID)( wPPID ); - - return result; -} // NP_RegisterProgramProfileID() - - -NPRESULT __stdcall NP_QueryVersion( unsigned short* pwVersion ) -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_QueryVersion ) - result = (*gpfNP_QueryVersion)( pwVersion ); - - return result; -} // NP_QueryVersion() - - -NPRESULT __stdcall NP_RequestData( unsigned short wDataReq ) -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_RequestData ) - result = (*gpfNP_RequestData)( wDataReq ); - - return result; -} // NP_RequestData() - -NPRESULT __stdcall NP_GetSignature( LPTRACKIRSIGNATURE pSignature ) -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_GetSignature ) - result = (*gpfNP_GetSignature)( pSignature ); - - return result; -} // NP_GetSignature() - - -NPRESULT __stdcall NP_GetData( LPTRACKIRDATA pTID ) -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_GetData ) - result = (*gpfNP_GetData)( pTID ); - - return result; -} // NP_GetData() - - -NPRESULT __stdcall NP_StartCursor() -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_StartCursor ) - result = (*gpfNP_StartCursor)(); - - return result; -} // NP_StartCursor() - - -NPRESULT __stdcall NP_StopCursor() -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_StopCursor ) - result = (*gpfNP_StopCursor)(); - - return result; -} // NP_StopCursor() - - -NPRESULT __stdcall NP_ReCenter() -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_ReCenter ) - result = (*gpfNP_ReCenter)(); - - return result; -} // NP_ReCenter() - - -NPRESULT __stdcall NP_StartDataTransmission() -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_StartDataTransmission ) - result = (*gpfNP_StartDataTransmission)(); - - return result; -} // NP_StartDataTransmission() - - -NPRESULT __stdcall NP_StopDataTransmission() -{ - NPRESULT result = NP_ERR_DLL_NOT_FOUND; - - if( NULL != gpfNP_StopDataTransmission ) - result = (*gpfNP_StopDataTransmission)(); - - return result; -} // NP_StopDataTransmission() - - -////////////////////////////////////////////////////////////////////////////// -// NPClientInit() -- Loads the DLL and retrieves pointers to all exports -// -NPRESULT NPClient_Init( const char* csDLLPath ) -{ - NPRESULT result = NP_OK; - - Text csNPClientDLLFullPath; - - if (csDLLPath && *csDLLPath) - csNPClientDLLFullPath = Text(csDLLPath) + "\\"; - csNPClientDLLFullPath += "NPClient.dll"; - - ghNPClientDLL = ::LoadLibrary( csNPClientDLLFullPath.data() ); - - if (NULL != ghNPClientDLL) { - // verify the dll signature - gpfNP_GetSignature = (PF_NP_GETSIGNATURE)::GetProcAddress( ghNPClientDLL, "NP_GetSignature" ); - - SIGNATUREDATA pSignature; - SIGNATUREDATA verifySignature; - // init the signatures - strcpy_s(verifySignature.DllSignature, "precise head tracking\n put your head into the game\n now go look around\n\n Copyright EyeControl Technologies"); - strcpy_s(verifySignature.AppSignature, "hardware camera\n software processing data\n track user movement\n\n Copyright EyeControl Technologies"); - // query the dll and compare the results - NPRESULT vresult = NP_GetSignature( &pSignature ); - if( vresult == NP_OK ) - { - if ((strcmp(verifySignature.DllSignature,pSignature.DllSignature)==0) - && (strcmp(verifySignature.AppSignature,pSignature.AppSignature)==0)) - { - result = NP_OK; - - // Get addresses of all exported functions - gpfNP_RegisterWindowHandle = (PF_NP_REGISTERWINDOWHANDLE)::GetProcAddress( ghNPClientDLL, "NP_RegisterWindowHandle" ); - gpfNP_UnregisterWindowHandle = (PF_NP_UNREGISTERWINDOWHANDLE)::GetProcAddress( ghNPClientDLL, "NP_UnregisterWindowHandle" ); - gpfNP_RegisterProgramProfileID = (PF_NP_REGISTERPROGRAMPROFILEID)::GetProcAddress( ghNPClientDLL, "NP_RegisterProgramProfileID" ); - gpfNP_QueryVersion = (PF_NP_QUERYVERSION)::GetProcAddress( ghNPClientDLL, "NP_QueryVersion" ); - gpfNP_RequestData = (PF_NP_REQUESTDATA)::GetProcAddress( ghNPClientDLL, "NP_RequestData" ); - gpfNP_GetData = (PF_NP_GETDATA)::GetProcAddress( ghNPClientDLL, "NP_GetData" ); - gpfNP_StartCursor = (PF_NP_STARTCURSOR)::GetProcAddress( ghNPClientDLL, "NP_StartCursor" ); - gpfNP_StopCursor = (PF_NP_STOPCURSOR)::GetProcAddress( ghNPClientDLL, "NP_StopCursor" ); - gpfNP_ReCenter = (PF_NP_RECENTER)::GetProcAddress( ghNPClientDLL, "NP_ReCenter" ); - gpfNP_StartDataTransmission = (PF_NP_STARTDATATRANSMISSION)::GetProcAddress( ghNPClientDLL, "NP_StartDataTransmission" ); - gpfNP_StopDataTransmission = (PF_NP_STOPDATATRANSMISSION)::GetProcAddress( ghNPClientDLL, "NP_StopDataTransmission" ); - } - else - { - result = NP_ERR_DLL_NOT_FOUND; - } - } - else - { - result = NP_ERR_DLL_NOT_FOUND; - } - } - else - result = NP_ERR_DLL_NOT_FOUND; - - return result; - -} // NPClient_Init() - -////////////////////////////////////////////////////////////////////////////// - - - - diff --git a/Stars45/NPClientWraps.h b/Stars45/NPClientWraps.h deleted file mode 100644 index 49c0f4b..0000000 --- a/Stars45/NPClientWraps.h +++ /dev/null @@ -1,33 +0,0 @@ -// ******************************************************************************* -// * -// * Module Name: -// * NPClientWraps.h -// * -// * Software Engineer: -// * Doyle Nickless - GoFlight Inc., for Eye Control Technology. -// * -// * Abstract: -// * Header file for NPClientWraps.cpp module. -// * -// * Environment: -// * User mode -// * -// ******************************************************************************* -// -#ifndef _NPCLIENTWRAPS_H_DEFINED_ -#define _NPCLIENTWRAPS_H_DEFINED_ - -#include "NPClient.h" - -///////////// -// Defines /////////////////////////////////////////////////////////////////////// -///////////// -// - -///////////////////////// -// Function Prototypes /////////////////////////////////////////////////////////// -///////////////////////// -// -NPRESULT NPClient_Init( const char* csDLLPath ); - -#endif // #ifdef _NPCLIENTWRAPS_H_DEFINED_ diff --git a/Stars45/NavAI.cpp b/Stars45/NavAI.cpp deleted file mode 100644 index ad897d0..0000000 --- a/Stars45/NavAI.cpp +++ /dev/null @@ -1,621 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Automatic Navigator Artificial Intelligence class -*/ - -#include "NavAI.h" -#include "TacticalAI.h" -#include "Instruction.h" -#include "NavSystem.h" -#include "QuantumDrive.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "ShipCtrl.h" -#include "Drive.h" -#include "Farcaster.h" -#include "Shield.h" -#include "Sim.h" -#include "StarSystem.h" -#include "KeyMap.h" -#include "HUDView.h" -#include "HUDSounds.h" - -#include "Game.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ - -NavAI::NavAI(Ship* s) -: ShipAI(s), complete(false), brakes(0), -drop_state(0), quantum_state(0), farcaster(0), terrain_warning(false) -{ - seek_gain = 20; - seek_damp = 0.55; - - delete tactical; - tactical = 0; -} - -// +--------------------------------------------------------------------+ - -NavAI::~NavAI() -{ } - -// +--------------------------------------------------------------------+ - -void -NavAI::ExecFrame(double s) -{ - if (!ship) return; - - seconds = s; - - ship->SetDirectorInfo(" "); - - if (ship->GetFlightPhase() == Ship::TAKEOFF) - takeoff = true; - - else if (takeoff && ship->MissionClock() > 10000) - takeoff = false; - - FindObjective(); - Navigator(); - - // watch for disconnect: - if (ShipCtrl::Toggled(KEY_AUTO_NAV)) { - NavSystem* navsys = ship->GetNavSystem(); - if (navsys) { - HUDView::GetInstance()->SetHUDMode(HUDView::HUD_MODE_TAC); - navsys->DisengageAutoNav(); - - Sim* sim = Sim::GetSim(); - if (sim) { - ship->SetControls(sim->GetControls()); - return; - } - } - } - - static double time_til_change = 0.0; - - if (time_til_change < 0.001) { - if (ship->GetShield()) { - Shield* shield = ship->GetShield(); - double level = shield->GetPowerLevel(); - - if (ShipCtrl::KeyDown(KEY_SHIELDS_FULL)) { - HUDSounds::PlaySound(HUDSounds::SND_SHIELD_LEVEL); - shield->SetPowerLevel(100); - time_til_change = 0.5f; - } - - else if (ShipCtrl::KeyDown(KEY_SHIELDS_ZERO)) { - HUDSounds::PlaySound(HUDSounds::SND_SHIELD_LEVEL); - shield->SetPowerLevel(0); - time_til_change = 0.5f; - } - - else if (ShipCtrl::KeyDown(KEY_SHIELDS_UP)) { - if (level < 25) level = 25; - else if (level < 50) level = 50; - else if (level < 75) level = 75; - else level = 100; - - HUDSounds::PlaySound(HUDSounds::SND_SHIELD_LEVEL); - shield->SetPowerLevel(level); - time_til_change = 0.5f; - } - - else if (ShipCtrl::KeyDown(KEY_SHIELDS_DOWN)) { - if (level > 75) level = 75; - else if (level > 50) level = 50; - else if (level > 25) level = 25; - else level = 0; - - HUDSounds::PlaySound(HUDSounds::SND_SHIELD_LEVEL); - shield->SetPowerLevel(level); - time_til_change = 0.5f; - } - - } - } - else { - time_til_change -= seconds; - } - - if (ShipCtrl::Toggled(KEY_DECOY)) - ship->FireDecoy(); - - if (ShipCtrl::Toggled(KEY_LAUNCH_PROBE)) - ship->LaunchProbe(); - - if (ShipCtrl::Toggled(KEY_GEAR_TOGGLE)) - ship->ToggleGear(); - - if (ShipCtrl::Toggled(KEY_NAVLIGHT_TOGGLE)) - ship->ToggleNavlights(); - - if (drop_state < 0) { - ship->DropOrbit(); - return; - } - - if (drop_state > 0) { - ship->MakeOrbit(); - return; - } -} - -// +--------------------------------------------------------------------+ - -void -NavAI::FindObjective() -{ - navpt = 0; - distance = 0; - - // runway takeoff: - if (takeoff) { - obj_w = ship->Location() + ship->Heading() * 10e3; - obj_w.y = ship->Location().y + 2e3; - - // transform into camera coords: - objective = Transform(obj_w); - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.takeoff")); - return; - } - - // PART I: Find next NavPoint: - if (ship->GetNavSystem()) - navpt = ship->GetNextNavPoint(); - - complete = !navpt; - if (complete) return; - - // PART II: Compute Objective from NavPoint: - Point npt = navpt->Location(); - Sim* sim = Sim::GetSim(); - SimRegion* self_rgn = ship->GetRegion(); - SimRegion* nav_rgn = navpt->Region(); - - if (self_rgn && !nav_rgn) { - nav_rgn = self_rgn; - navpt->SetRegion(nav_rgn); - } - - if (self_rgn == nav_rgn) { - if (farcaster) { - if (farcaster->GetShip()->GetRegion() != self_rgn) - farcaster = farcaster->GetDest()->GetFarcaster(); - - obj_w = farcaster->EndPoint(); - } - - else { - obj_w = npt.OtherHand(); - } - - // distance from self to navpt: - distance = Point(obj_w - self->Location()).length(); - - // transform into camera coords: - objective = Transform(obj_w); - - if (!ship->IsStarship()) - objective.Normalize(); - - if (farcaster && distance < 1000) - farcaster = 0; - } - - // PART III: Deal with orbital transitions: - else if (ship->IsDropship()) { - if (nav_rgn->GetOrbitalRegion()->Primary() == - self_rgn->GetOrbitalRegion()->Primary()) { - - Point npt = nav_rgn->Location() - self_rgn->Location(); - obj_w = npt.OtherHand(); - - // distance from self to navpt: - distance = Point(obj_w - ship->Location()).length(); - - // transform into camera coords: - objective = Transform(obj_w); - - if (nav_rgn->IsAirSpace()) { - drop_state = -1; - } - else if (nav_rgn->IsOrbital()) { - drop_state = 1; - } - } - - // PART IIIa: Deal with farcaster jumps: - else if (nav_rgn->IsOrbital() && self_rgn->IsOrbital()) { - ListIter s = self_rgn->Ships(); - while (++s && !farcaster) { - if (s->GetFarcaster()) { - const Ship* dest = s->GetFarcaster()->GetDest(); - if (dest && dest->GetRegion() == nav_rgn) { - farcaster = s->GetFarcaster(); - } - } - } - - if (farcaster) { - Point apt = farcaster->ApproachPoint(0); - Point npt = farcaster->StartPoint(); - double r1 = (ship->Location() - npt).length(); - - if (r1 > 50e3) { - obj_w = apt; - distance = r1; - objective = Transform(obj_w); - } - - else { - double r2 = (ship->Location() - apt).length(); - double r3 = (npt - apt).length(); - - if (r1+r2 < 1.2*r3) { - obj_w = npt; - distance = r1; - objective = Transform(obj_w); - } - else { - obj_w = apt; - distance = r2; - objective = Transform(obj_w); - } - } - } - } - } - - // PART IV: Deal with quantum jumps: - else if (ship->IsStarship()) { - quantum_state = 1; - - Point npt = nav_rgn->Location() + navpt->Location(); - npt -= self_rgn->Location(); - obj_w = npt.OtherHand(); - - // distance from self to navpt: - distance = Point(obj_w - ship->Location()).length(); - - // transform into camera coords: - objective = Transform(obj_w); - } -} - -// +--------------------------------------------------------------------+ - -void -NavAI::Navigator() -{ - accumulator.Clear(); - magnitude = 0; - brakes = 0; - hold = false; - - if (navpt) { - if (navpt->Status() == Instruction::COMPLETE && navpt->HoldTime() > 0) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.auto-hold")); - hold = true; - } - else { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.auto-nav")); - } - } - else { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.auto-stop")); - } - - Accumulate(AvoidTerrain()); - Accumulate(AvoidCollision()); - - if (!hold) - accumulator = SeekTarget(); - - HelmControl(); - ThrottleControl(); -} - -// +--------------------------------------------------------------------+ - -void -NavAI::HelmControl() -{ - // ---------------------------------------------------------- - // STARSHIP HELM MODE - // ---------------------------------------------------------- - - if (ship->IsStarship()) { - ship->SetFLCSMode(Ship::FLCS_HELM); - ship->SetHelmHeading(accumulator.yaw); - - if (accumulator.pitch > 45*DEGREES) - ship->SetHelmPitch(45*DEGREES); - - else if (accumulator.pitch < -45*DEGREES) - ship->SetHelmPitch(-45*DEGREES); - - else - ship->SetHelmPitch(accumulator.pitch); - } - - // ---------------------------------------------------------- - // FIGHTER FLCS AUTO MODE - // ---------------------------------------------------------- - - else { - ship->SetFLCSMode(Ship::FLCS_AUTO); - - // are we being asked to flee? - if (fabs(accumulator.yaw) == 1.0 && accumulator.pitch == 0.0) { - accumulator.pitch = -0.7f; - accumulator.yaw *= 0.25f; - } - - self->ApplyRoll((float) (accumulator.yaw * -0.4)); - self->ApplyYaw((float) (accumulator.yaw * 0.2)); - - if (fabs(accumulator.yaw) > 0.5 && fabs(accumulator.pitch) < 0.1) - accumulator.pitch -= 0.1f; - - if (accumulator.pitch != 0) - self->ApplyPitch((float) accumulator.pitch); - - // if not turning, roll to orient with world coords: - if (fabs(accumulator.yaw) < 0.1) { - Point vrt = ((Camera*) &(self->Cam()))->vrt(); - double deflection = vrt.y; - if (deflection != 0) { - double theta = asin(deflection/vrt.length()); - self->ApplyRoll(-theta); - } - } - - if (!ship->IsAirborne() || ship->AltitudeAGL() > 100) - ship->RaiseGear(); - } - - ship->SetTransX(0); - ship->SetTransY(0); - ship->SetTransZ(0); - ship->ExecFLCSFrame(); -} - -// +--------------------------------------------------------------------+ - -void -NavAI::ThrottleControl() -{ - double ship_speed = ship->Velocity() * ship->Heading(); - bool augmenter = false; - - if (hold) { - throttle = 0; - brakes = 1; - } - - else if (navpt) { - double speed = navpt->Speed(); - - if (speed < 10) - speed = 250; - - throttle = 0; - - if (Ship::GetFlightModel() > 0) { - if (ship_speed > speed + 10) - throttle = old_throttle - 0.25; - - else if (ship_speed < speed - 10) - throttle = old_throttle + 0.25; - - else - throttle = old_throttle; - } - - else { - if (ship_speed > speed+5) - brakes = 0.25; - - else if (ship_speed < speed-5) - throttle = 50; - } - } - else { - throttle = 0; - brakes = 0.25; - } - - if (ship->IsAirborne() && ship->Class() < Ship::LCA) { - if (ship_speed < 250) { - throttle = 100; - brakes = 0; - - if (ship_speed < 200) - augmenter = true; - } - - else if (throttle < 20) { - throttle = 20; - } - } - - old_throttle = throttle; - ship->SetThrottle(throttle); - ship->SetAugmenter(augmenter); - - if (ship_speed > 1 && brakes > 0) - ship->SetTransY(-brakes * ship->Design()->trans_y); -} - -// +--------------------------------------------------------------------+ - -Steer -NavAI::SeekTarget() -{ - if (!ship) - return Steer(); - - if (takeoff) - return Seek(objective); - - if (navpt) { - if (quantum_state == 1) { - QuantumDrive* q = ship->GetQuantumDrive(); - - if (q) { - if (q->ActiveState() == QuantumDrive::ACTIVE_READY) { - q->SetDestination(navpt->Region(), navpt->Location()); - q->Engage(); - } - - else if (q->ActiveState() == QuantumDrive::ACTIVE_POSTWARP) { - quantum_state = 0; - } - } - } - - if (distance < 2 * self->Radius()) { - ship->SetNavptStatus(navpt, Instruction::COMPLETE); - - return Steer(); - } - else { - return Seek(objective); - } - } - - return Steer(); -} - -// +--------------------------------------------------------------------+ - -void -NavAI::Disengage() -{ - throttle = 0; -} - -// +--------------------------------------------------------------------+ - -Point -NavAI::Transform(const Point& point) -{ - if (ship && ship->IsStarship()) - return point - self->Location(); - - return SteerAI::Transform(point); -} - -Steer -NavAI::Seek(const Point& point) -{ - // if ship is starship, the point is in relative world coordinates - // x: distance east(-) / west(+) - // y: altitude down(-) / up(+) - // z: distance north(-) / south(+) - - if (ship && ship->IsStarship()) { - Steer result; - - result.yaw = atan2(point.x, point.z) + PI; - - double adjacent = sqrt(point.x * point.x + point.z * point.z); - if (fabs(point.y) > ship->Radius() && adjacent > ship->Radius()) - result.pitch = atan(point.y / adjacent); - - if (_isnan(result.yaw)) - result.yaw = 0; - - if (_isnan(result.pitch)) - result.pitch = 0; - - return result; - } - - return SteerAI::Seek(point); -} - -Steer -NavAI::Flee(const Point& point) -{ - if (ship && ship->IsStarship()) { - Steer result = Seek(point); - result.yaw += PI; - result.pitch *= -1; - return result; - } - - return SteerAI::Flee(point); -} - -Steer -NavAI::Avoid(const Point& point, float radius) -{ - if (ship && ship->IsStarship()) { - Steer result = Seek(point); - - if (point * ship->BeamLine() > 0) - result.yaw -= PI/2; - else - result.yaw += PI/2; - - return result; - } - - return SteerAI::Avoid(point, radius); -} - -// +--------------------------------------------------------------------+ - -Steer -NavAI::AvoidTerrain() -{ - Steer avoid; - - terrain_warning = false; - - if (!ship || !ship->GetRegion() || !ship->GetRegion()->IsActive() || - takeoff || (navpt && navpt->Action() == Instruction::LAUNCH)) - return avoid; - - if (ship->IsAirborne() && ship->GetFlightPhase() == Ship::ACTIVE) { - // too low? - if (ship->AltitudeAGL() < 1000) { - terrain_warning = true; - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.too-low")); - - // way too low? - if (ship->AltitudeAGL() < 750) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.way-too-low")); - } - - // where will we be? - Point selfpt = ship->Location() + ship->Velocity() + Point(0, 10e3, 0); - - // transform into camera coords: - Point obj = Transform(selfpt); - - // pull up! - avoid = Seek(obj); - } - } - - return avoid; -} - - - diff --git a/Stars45/NavAI.h b/Stars45/NavAI.h deleted file mode 100644 index 0eeea2e..0000000 --- a/Stars45/NavAI.h +++ /dev/null @@ -1,73 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Automatic Navigator -*/ - -#ifndef NavAI_h -#define NavAI_h - -#include "Types.h" -#include "Geometry.h" -#include "System.h" -#include "ShipAI.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Farcaster; - -// +--------------------------------------------------------------------+ - -class NavAI : public ShipAI -{ -public: - NavAI(Ship* s); - virtual ~NavAI(); - - enum { DIR_TYPE = 2000 }; - virtual int Type() const { return DIR_TYPE; } - - virtual void ExecFrame(double seconds); - virtual int Subframe() const { return true; } - void Disengage(); - bool Complete() const { return complete; } - -protected: - // behaviors: - virtual Steer SeekTarget(); - - // steering functions: - virtual Point Transform(const Point& pt); - virtual Steer Seek(const Point& point); - virtual Steer Flee(const Point& point); - virtual Steer Avoid(const Point& point, float radius); - virtual Steer AvoidTerrain(); - - // accumulate behaviors: - virtual void Navigator(); - virtual void FindObjective(); - - virtual void HelmControl(); - virtual void ThrottleControl(); - - bool complete; - int drop_state; - int quantum_state; - int terrain_warning; - double brakes; - Farcaster* farcaster; -}; - -// +--------------------------------------------------------------------+ - - -#endif // NavAI_h - diff --git a/Stars45/NavDlg.cpp b/Stars45/NavDlg.cpp deleted file mode 100644 index 8847957..0000000 --- a/Stars45/NavDlg.cpp +++ /dev/null @@ -1,1125 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "NavDlg.h" -#include "MapView.h" -#include "MsnElemDlg.h" -#include "BaseScreen.h" -#include "Element.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Sim.h" -#include "Galaxy.h" -#include "StarSystem.h" -#include "Instruction.h" -#include "NavSystem.h" -#include "FormatUtil.h" -#include "Campaign.h" -#include "Contact.h" -#include "Mission.h" - -#include "Clock.h" -#include "ContentBundle.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ListBox.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: -DEF_MAP_CLIENT(NavDlg, OnView); -DEF_MAP_CLIENT(NavDlg, OnFilter); -DEF_MAP_CLIENT(NavDlg, OnSelect); -DEF_MAP_CLIENT(NavDlg, OnCommit); -DEF_MAP_CLIENT(NavDlg, OnCancel); -DEF_MAP_CLIENT(NavDlg, OnEngage); -DEF_MAP_CLIENT(NavDlg, OnMapDown); -DEF_MAP_CLIENT(NavDlg, OnMapMove); -DEF_MAP_CLIENT(NavDlg, OnMapClick); -DEF_MAP_CLIENT(NavDlg, OnClose); - -// +--------------------------------------------------------------------+ - -static char* filter_name[] = { - "SYSTEM", "PLANET", - "SECTOR", "STATION", - "STARSHIP", "FIGHTER" -}; - -static char* commit_name = "Commit"; -static char* cancel_name = "Cancel"; - -static Color commit_color(53,159,67); -static Color cancel_color(160,8,8); - - -// Supported Selection Modes: - -const int SELECT_NONE = -1; -const int SELECT_SYSTEM = 0; -const int SELECT_PLANET = 1; -const int SELECT_REGION = 2; -const int SELECT_STATION = 3; -const int SELECT_STARSHIP = 4; -const int SELECT_FIGHTER = 5; - -const int VIEW_GALAXY = 0; -const int VIEW_SYSTEM = 1; -const int VIEW_REGION = 2; - -// +--------------------------------------------------------------------+ - -NavDlg::NavDlg(Screen* s, FormDef& def, BaseScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -loc_labels(0), dst_labels(0), loc_data(0), dst_data(0), -seln_list(0), info_list(0), seln_mode(SELECT_REGION), -nav_edit_mode(NAV_EDIT_NONE), star_map(0), map_win(0), -star_system(0), ship(0), mission(0), editor(false) -{ - Init(def); -} - -NavDlg::~NavDlg() -{ } - -void -NavDlg::RegisterControls() -{ - int i; - - map_win = FindControl(100); - - if (map_win) { - star_map = new MapView(map_win); - - REGISTER_CLIENT(EID_LBUTTON_DOWN, map_win, NavDlg, OnMapDown); - REGISTER_CLIENT(EID_MOUSE_MOVE, map_win, NavDlg, OnMapMove); - REGISTER_CLIENT(EID_MAP_CLICK, map_win, NavDlg, OnMapClick); - } - - for (i = 0; i < 3; i++) { - view_btn[i] = (Button*) FindControl(101 + i); - REGISTER_CLIENT(EID_CLICK, view_btn[i], NavDlg, OnView); - } - - close_btn = (Button*) FindControl(2); - - if (close_btn) - REGISTER_CLIENT(EID_CLICK, close_btn, NavDlg, OnClose); - - zoom_in_btn = (Button*) FindControl(110); - zoom_out_btn = (Button*) FindControl(111); - - for (i = 0; i < 6; i++) { - filter_btn[i] = (Button*) FindControl(401 + i); - REGISTER_CLIENT(EID_CLICK, filter_btn[i], NavDlg, OnFilter); - } - - commit_btn = (Button*) FindControl(1); - - if (commit_btn) { - REGISTER_CLIENT(EID_CLICK, commit_btn, NavDlg, OnEngage); - } - - loc_labels = FindControl(601); - dst_labels = FindControl(602); - loc_data = FindControl(701); - dst_data = FindControl(702); - - seln_list = (ListBox*) FindControl(801); - - if (seln_list) { - seln_list->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - REGISTER_CLIENT(EID_SELECT, seln_list, NavDlg, OnSelect); - } - - info_list = (ListBox*) FindControl(802); - - if (star_map) { - star_map->SetViewMode(VIEW_SYSTEM); - view_btn[1]->SetButtonState(1); - - star_map->SetSelectionMode(2); - } - - UpdateSelection(); -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::SetSystem(StarSystem* s) -{ - if (star_system == s) - return; - - star_system = s; - - if (star_map) { - Campaign* c = Campaign::GetCampaign(); - Sim* sim = Sim::GetSim(); - - if (sim && sim->GetSystemList().size()) { - star_map->SetGalaxy(sim->GetSystemList()); - } - else if (mission && mission->GetSystemList().size()) { - star_map->SetGalaxy(mission->GetSystemList()); - } - else if (c && c->GetSystemList().size()) { - star_map->SetGalaxy(c->GetSystemList()); - } - else { - Galaxy* g = Galaxy::GetInstance(); - if (g) - star_map->SetGalaxy(g->GetSystemList()); - } - - star_map->SetSystem(s); - } - - // flush old object pointers: - stars.clear(); - planets.clear(); - regions.clear(); - contacts.clear(); - - if (star_system) { - // insert objects from star system: - ListIter star = star_system->Bodies(); - while (++star) { - switch (star->Type()) { - case Orbital::STAR: stars.append(star.value()); - break; - case Orbital::PLANET: - case Orbital::MOON: planets.append(star.value()); - break; - } - - ListIter planet = star->Satellites(); - while (++planet) { - planets.append(planet.value()); - - ListIter moon = planet->Satellites(); - while (++moon) { - planets.append(moon.value()); - } - } - } - - ListIter rgn = star_system->AllRegions(); - while (++rgn) - regions.append(rgn.value()); - } - - // sort region list by distance from the star: - regions.sort(); -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::SetShip(Ship* s) -{ - if (ship == s) - return; - - ship = s; - - if (ship) - SetSystem(ship->GetRegion()->System()); - - if (star_map) { - Sim* sim = Sim::GetSim(); - - if (sim && sim->GetSystemList().size()) - star_map->SetGalaxy(sim->GetSystemList()); - - star_map->SetShip(ship); - - if (ship) { - star_map->SetRegion(ship->GetRegion()->GetOrbitalRegion()); - UseViewMode(VIEW_REGION); - star_map->SetSelectedShip(ship); - } - } - - for (int i = 0; i < 6; i++) - filter_btn[i]->SetButtonState(0); - - filter_btn[SELECT_REGION]->SetButtonState(1); - UseFilter(SELECT_STARSHIP); - UpdateSelection(); -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::SetMission(Mission* m) -{ - if (!m && mission == m) - return; - - if (mission == m && star_system == m->GetStarSystem()) - return; - - mission = m; - - if (mission) { - SetSystem(mission->GetStarSystem()); - } - - if (star_map) { - Campaign* c = Campaign::GetCampaign(); - Sim* sim = Sim::GetSim(); - - star_map->SetMission(0); // prevent building map menu twice - - if (sim && sim->GetSystemList().size()) { - star_map->SetGalaxy(sim->GetSystemList()); - } - else if (mission && mission->GetSystemList().size()) { - star_map->SetGalaxy(mission->GetSystemList()); - } - else if (c && c->GetSystemList().size()) { - star_map->SetGalaxy(c->GetSystemList()); - } - else { - Galaxy* g = Galaxy::GetInstance(); - if (g) - star_map->SetGalaxy(g->GetSystemList()); - } - - if (mission) { - star_map->SetMission(mission); - star_map->SetRegionByName(mission->GetRegion()); - - if (star_map->GetViewMode() == VIEW_REGION) { - ListIter elem = mission->GetElements(); - while (++elem) { - MissionElement* e = elem.value(); - - if (e->Player()) - star_map->SetSelectedElem(e); - } - } - } - } - - bool updated = false; - - if (mission) { - Orbital* rgn = 0; - rgn = mission->GetStarSystem()->FindOrbital(mission->GetRegion()); - - if (rgn) { - SelectRegion((OrbitalRegion*) rgn); - updated = true; - } - } - - if (!updated) - UpdateSelection(); -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::SetEditorMode(bool e) -{ - editor = e; - - if (star_map) - star_map->SetEditorMode(editor); -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::ExecFrame() -{ - Sim* sim = Sim::GetSim(); - - if (loc_labels && ship) { - char loc_buf[512]; - char x[16]; - char y[16]; - char z[16]; - char d[16]; - - FormatNumber(x, -ship->Location().x); - FormatNumber(y, ship->Location().z); - FormatNumber(z, ship->Location().y); - - strcpy_s(loc_buf, ContentBundle::GetInstance()->GetText("NavDlg.loc-labels").data()); - loc_labels->SetText(loc_buf); - - if (sim->GetActiveRegion()) { - sprintf_s(loc_buf, "\n%s\n%s\n%s, %s, %s", - (const char*) star_system->Name(), - (const char*) sim->GetActiveRegion()->Name(), - x, y, z); - - } - else { - sprintf_s(loc_buf, "\n%s\nPlanck Space?\n%s, %s, %s", - (const char*) star_system->Name(), x, y, z); - } - - loc_data->SetText(loc_buf); - - if (ship) { - NavSystem* navsys = ship->GetNavSystem(); - - if (ship->GetNextNavPoint() == 0 || !navsys) { - commit_btn->SetText(ContentBundle::GetInstance()->GetText("NavDlg.commit")); - commit_btn->SetBackColor(commit_color); - commit_btn->SetEnabled(false); - } - else if (navsys) { - commit_btn->SetEnabled(true); - - if (navsys->AutoNavEngaged()) { - commit_btn->SetText(ContentBundle::GetInstance()->GetText("NavDlg.cancel")); - commit_btn->SetBackColor(cancel_color); - } - else { - commit_btn->SetText(ContentBundle::GetInstance()->GetText("NavDlg.commit")); - commit_btn->SetBackColor(commit_color); - } - } - } - - if (dst_labels) { - Instruction* navpt = ship->GetNextNavPoint(); - - if (navpt && navpt->Region()) { - FormatNumber(x, navpt->Location().x); - FormatNumber(y, navpt->Location().y); - FormatNumber(z, navpt->Location().z); - - double distance = 0; - Point npt = navpt->Region()->Location() + navpt->Location(); - if (sim->GetActiveRegion()) - npt -= sim->GetActiveRegion()->Location(); - - npt = npt.OtherHand(); - - // distance from self to navpt: - distance = Point(npt - ship->Location()).length(); - FormatNumber(d, distance); - - strcpy_s(loc_buf, ContentBundle::GetInstance()->GetText("NavDlg.dst-labels").data()); - dst_labels->SetText(loc_buf); - - sprintf_s(loc_buf, "\n%s\n%s\n%s, %s, %s\n%s", - (const char*) star_system->Name(), - (const char*) navpt->Region()->Name(), - x, y, z, d); - dst_data->SetText(loc_buf); - } - else { - dst_labels->SetText(ContentBundle::GetInstance()->GetText("NavDlg.destination")); - dst_data->SetText(ContentBundle::GetInstance()->GetText("NavDlg.not-avail")); - } - } - } - - UpdateSelection(); - UpdateLists(); - - if (Keyboard::KeyDown(VK_ADD) || - (zoom_in_btn && zoom_in_btn->GetButtonState() > 0)) { - star_map->ZoomIn(); - } - else if (Keyboard::KeyDown(VK_SUBTRACT) || - (zoom_out_btn && zoom_out_btn->GetButtonState() > 0)) { - star_map->ZoomOut(); - } - - else if (star_map->TargetRect().Contains(Mouse::X(),Mouse::Y())) { - - if (Mouse::Wheel() > 0) { - star_map->ZoomIn(); - star_map->ZoomIn(); - star_map->ZoomIn(); - } - - else if (Mouse::Wheel() < 0) { - star_map->ZoomOut(); - star_map->ZoomOut(); - star_map->ZoomOut(); - } - } - - if (nav_edit_mode == NAV_EDIT_NONE) - Mouse::SetCursor(Mouse::ARROW); - else - Mouse::SetCursor(Mouse::CROSS); -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::OnView(AWEvent* event) -{ - int use_filter_mode = -1; - - view_btn[VIEW_GALAXY]->SetButtonState(0); - view_btn[VIEW_SYSTEM]->SetButtonState(0); - view_btn[VIEW_REGION]->SetButtonState(0); - - if (view_btn[0] == event->window) { - star_map->SetViewMode(VIEW_GALAXY); - view_btn[VIEW_GALAXY]->SetButtonState(1); - use_filter_mode = SELECT_SYSTEM; - } - - else if (view_btn[VIEW_SYSTEM] == event->window) { - star_map->SetViewMode(VIEW_SYSTEM); - view_btn[VIEW_SYSTEM]->SetButtonState(1); - use_filter_mode = SELECT_REGION; - } - - else if (view_btn[VIEW_REGION] == event->window) { - star_map->SetViewMode(VIEW_REGION); - view_btn[VIEW_REGION]->SetButtonState(1); - use_filter_mode = SELECT_STARSHIP; - } - - if (use_filter_mode >= 0) { - for (int i = 0; i < 6; i++) { - if (i == use_filter_mode) - filter_btn[i]->SetButtonState(1); - else - filter_btn[i]->SetButtonState(0); - } - - UseFilter(use_filter_mode); - } -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::OnFilter(AWEvent* event) -{ - int filter_index = -1; - for (int i = 0; i < 6; i++) { - if (filter_btn[i] == event->window) { - filter_index = i; - filter_btn[i]->SetButtonState(1); - } - else { - filter_btn[i]->SetButtonState(0); - } - } - - if (filter_index >= 0) - UseFilter(filter_index); -} - -void -NavDlg::UseFilter(int filter_index) -{ - seln_mode = filter_index; - - star_map->SetSelectionMode(seln_mode); - UpdateSelection(); - UpdateLists(); -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::UseViewMode(int mode) -{ - if (mode >= 0 && mode < 3) { - int use_filter_mode = -1; - - view_btn[VIEW_GALAXY]->SetButtonState(0); - view_btn[VIEW_SYSTEM]->SetButtonState(0); - view_btn[VIEW_REGION]->SetButtonState(0); - - if (mode == 0) { - star_map->SetViewMode(VIEW_GALAXY); - view_btn[VIEW_GALAXY]->SetButtonState(1); - use_filter_mode = SELECT_SYSTEM; - } - - else if (mode == 1) { - star_map->SetViewMode(VIEW_SYSTEM); - view_btn[VIEW_SYSTEM]->SetButtonState(1); - use_filter_mode = SELECT_REGION; - } - - else if (mode == 2) { - star_map->SetViewMode(VIEW_REGION); - view_btn[VIEW_REGION]->SetButtonState(1); - use_filter_mode = SELECT_STARSHIP; - } - - if (use_filter_mode >= 0) { - for (int i = 0; i < 6; i++) { - filter_btn[i]->SetButtonState(i == use_filter_mode); - } - - UseFilter(use_filter_mode); - } - } -} - -void -NavDlg::SelectStar(Orbital* star) -{ - UseViewMode(0); - - if (stars.size()) { - int sel = 0; - - ListIter iter = stars; - while (++iter) { - if (iter.value() == star) { - int old_seln_mode = seln_mode; - UseFilter(SELECT_SYSTEM); - SelectObject(sel); - UseFilter(old_seln_mode); - return; - } - - sel++; - } - } -} - -void -NavDlg::SelectPlanet(Orbital* planet) -{ - UseViewMode(1); - - if (planets.size()) { - int sel = 0; - - ListIter iter = planets; - while (++iter) { - if (iter.value() == planet) { - int old_seln_mode = seln_mode; - UseFilter(SELECT_PLANET); - SelectObject(sel); - UseFilter(old_seln_mode); - return; - } - - sel++; - } - } -} - -void -NavDlg::SelectRegion(OrbitalRegion* rgn) -{ - UseViewMode(2); - - if (regions.size()) { - int sel = 0; - - ListIter iter = regions; - while (++iter) { - if (iter.value() == rgn) { - int old_seln_mode = seln_mode; - UseFilter(SELECT_REGION); - SelectObject(sel); - UseFilter(old_seln_mode); - return; - } - - sel++; - } - } -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::OnSelect(AWEvent* event) -{ - int index = -1; - - for (int i = 0; i < seln_list->NumItems(); i++) - if (seln_list->IsSelected(i)) - index = i; - - if (index >= 0) - SelectObject(index); -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::SelectObject(int index) -{ - Text selected = seln_list->GetItemText(index); - int selection = seln_list->GetItemData(index); - - star_map->SetSelection(selection); - SetSystem(star_map->GetSystem()); -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::UpdateSelection() -{ - if (!info_list) - return; - - if (!star_map) - return; - - info_list->ClearItems(); - - Text units_km = Text(" ") + ContentBundle::GetInstance()->GetText("NavDlg.units.kilometers"); - Text units_tonnes = Text(" ") + ContentBundle::GetInstance()->GetText("NavDlg.units.tonnes"); - - if (seln_mode <= SELECT_REGION) { - Orbital* s = star_map->GetSelection(); - - if (s) { - char radius[32]; - char mass[32]; - char orbit[32]; - char period[32]; - char units[32]; - - double p = s->Period(); - - if (p < 60) { - sprintf_s(units, " %s", ContentBundle::GetInstance()->GetText("NavDlg.units.seconds").data()); - } - else if (p < 3600) { - p /= 60; - sprintf_s(units, " %s", ContentBundle::GetInstance()->GetText("NavDlg.units.minutes").data()); - } - else if (p < 24 * 3600) { - p /= 3600; - sprintf_s(units, " %s", ContentBundle::GetInstance()->GetText("NavDlg.units.hours").data()); - } - else if (p < 365.25 * 24 * 3600) { - p /= 24*3600; - sprintf_s(units, " %s", ContentBundle::GetInstance()->GetText("NavDlg.units.days").data()); - } - else { - p /= 365.25*24*3600; - sprintf_s(units, " %s", ContentBundle::GetInstance()->GetText("NavDlg.units.years").data()); - } - - FormatNumberExp(radius, s->Radius()/1000); - FormatNumberExp(mass, s->Mass()/1000); - FormatNumberExp(orbit, s->Orbit()/1000); - FormatNumberExp(period, p); - - strcat_s(radius, units_km.data()); - strcat_s(mass, units_tonnes.data()); - strcat_s(orbit, units_km.data()); - strcat_s(period, units); - - if (seln_mode >= SELECT_SYSTEM) { - info_list->AddItem(ContentBundle::GetInstance()->GetText(Text("NavDlg.filter.") + filter_name[seln_mode])); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.radius")); - if (s->Mass() > 0) - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.mass")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.orbit")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.period")); - - int row = 0; - info_list->SetItemText(row++, 1, s->Name()); - info_list->SetItemText(row++, 1, radius); - if (s->Mass() > 0) - info_list->SetItemText(row++, 1, mass); - info_list->SetItemText(row++, 1, orbit); - info_list->SetItemText(row++, 1, period); - } - } - } - - else if (seln_mode == SELECT_STATION || - seln_mode == SELECT_STARSHIP || - seln_mode == SELECT_FIGHTER) { - - Ship* sel_ship = star_map->GetSelectedShip(); - MissionElement* sel_elem = star_map->GetSelectedElem(); - - if (sel_ship) { - Text order_desc = ContentBundle::GetInstance()->GetText("NavDlg.none"); - char shield[16]; - char hull[16]; - char range[32]; - - sprintf_s(shield, "%03d", sel_ship->ShieldStrength()); - sprintf_s(hull, "%03d", sel_ship->HullStrength()); - sprintf_s(range, "%s", ContentBundle::GetInstance()->GetText("NavDlg.not-avail").data()); - - if (ship) { - FormatNumberExp(range, Point(sel_ship->Location()-ship->Location()).length()/1000); - strcat_s(range, units_km.data()); - } - - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.name")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.class")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.sector")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.shield")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.hull")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.range")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.orders")); - - int row = 0; - info_list->SetItemText(row++, 1, sel_ship->Name()); - info_list->SetItemText(row++, 1, Text(sel_ship->Abbreviation()) + Text(" ") + Text(sel_ship->Design()->display_name)); - info_list->SetItemText(row++, 1, sel_ship->GetRegion()->Name()); - info_list->SetItemText(row++, 1, shield); - info_list->SetItemText(row++, 1, hull); - info_list->SetItemText(row++, 1, range); - info_list->SetItemText(row++, 1, order_desc); - } - - else if (sel_elem) { - Text order_desc = ContentBundle::GetInstance()->GetText("NavDlg.none"); - char range[32]; - - MissionElement* self = mission->GetElements()[0]; - if (self) - FormatNumberExp(range, Point(sel_elem->Location()-self->Location()).length()/1000); - else - strcpy_s(range, "0"); - - strcat_s(range, units_km.data()); - - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.name")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.class")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.sector")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.range")); - info_list->AddItem(ContentBundle::GetInstance()->GetText("NavDlg.orders")); - - int row = 0; - info_list->SetItemText(row++, 1, sel_elem->Name()); - - if (sel_elem->GetDesign()) - info_list->SetItemText(row++, 1, sel_elem->Abbreviation() + Text(" ") + sel_elem->GetDesign()->name); - else - info_list->SetItemText(row++, 1, ContentBundle::GetInstance()->GetText("NavDlg.unknown")); - - info_list->SetItemText(row++, 1, sel_elem->Region()); - info_list->SetItemText(row++, 1, range); - info_list->SetItemText(row++, 1, order_desc); - } - } -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::UpdateLists() -{ - if (!seln_list) - return; - - int seln_index = -1; - int top_index = -1; - - if (seln_list->IsSelecting()) - seln_index = seln_list->GetListIndex(); - - top_index = seln_list->GetTopIndex(); - - seln_list->ClearItems(); - - switch (seln_mode) { - case SELECT_SYSTEM: - { - seln_list->SetColumnTitle(0, ContentBundle::GetInstance()->GetText(Text("NavDlg.filter.") + filter_name[seln_mode])); - int i = 0; - ListIter iter = star_map->GetGalaxy(); - while (++iter) - seln_list->AddItemWithData(iter->Name(), i++); - } - break; - - case SELECT_PLANET: - { - seln_list->SetColumnTitle(0, ContentBundle::GetInstance()->GetText(Text("NavDlg.filter.") + filter_name[seln_mode])); - int i = 0; - ListIter iter = planets; - while (++iter) { - if (iter->Type() == Orbital::MOON) - seln_list->AddItemWithData(Text("- ") + Text(iter->Name()), i++); - else - seln_list->AddItemWithData(iter->Name(), i++); - } - } - break; - - case SELECT_REGION: - { - seln_list->SetColumnTitle(0, ContentBundle::GetInstance()->GetText(Text("NavDlg.filter.") + filter_name[seln_mode])); - int i = 0; - ListIter iter = regions; - while (++iter) { - seln_list->AddItemWithData(iter->Name(), i++); - } - } - break; - - case SELECT_STATION: - case SELECT_STARSHIP: - case SELECT_FIGHTER: - { - seln_list->SetColumnTitle(0, ContentBundle::GetInstance()->GetText(Text("NavDlg.filter.") + filter_name[seln_mode])); - int i = 0; - - if (mission) { - ListIter elem = mission->GetElements(); - while (++elem) { - MissionElement* e = elem.value(); - bool filter_ok = - (seln_mode == SELECT_STATION && e->IsStatic()) || - (seln_mode == SELECT_STARSHIP && e->IsStarship() && !e->IsStatic()) || - (seln_mode == SELECT_FIGHTER && e->IsDropship() && !e->IsSquadron()); - - if (filter_ok) { - bool visible = editor || - e->GetIFF() == 0 || - e->GetIFF() == mission->Team() || - e->IntelLevel() > Intel::KNOWN; - - if (visible) - seln_list->AddItemWithData(e->Name(), e->Identity()); - } - } - } - - else if (ship) { - Sim* sim = Sim::GetSim(); - ListIter r_iter = sim->GetRegions(); - while (++r_iter) { - SimRegion* rgn = r_iter.value(); - - ListIter s_iter = rgn->Ships(); - while (++s_iter) { - Ship* s = s_iter.value(); - bool filter_ok = - (seln_mode == SELECT_STATION && s->IsStatic()) || - (seln_mode == SELECT_STARSHIP && s->IsStarship() && !s->IsStatic()) || - (seln_mode == SELECT_FIGHTER && s->IsDropship()); - - - if (filter_ok) { - bool visible = s->GetIFF() == 0 || - s->GetIFF() == ship->GetIFF() || - s->GetElement() && - s->GetElement()->IntelLevel() > Intel::KNOWN; - - if (visible) - seln_list->AddItemWithData(s->Name(), s->Identity()); - } - } - } - } - } - break; - - default: - break; - } - - if (top_index >= 0) - seln_list->ScrollTo(top_index); - - if (seln_index >= 0) - seln_list->SetSelected(seln_index); - - else - CoordinateSelection(); -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::OnEngage(AWEvent* event) -{ - bool hide = false; - - if (ship) { - NavSystem* navsys = ship->GetNavSystem(); - if (navsys) { - if (navsys->AutoNavEngaged()) { - navsys->DisengageAutoNav(); - commit_btn->SetText(ContentBundle::GetInstance()->GetText("NavDlg.commit")); - commit_btn->SetBackColor(commit_color); - } - else { - navsys->EngageAutoNav(); - commit_btn->SetText(ContentBundle::GetInstance()->GetText("NavDlg.cancel")); - commit_btn->SetBackColor(cancel_color); - hide = true; - } - - Sim* sim = Sim::GetSim(); - if (sim) - ship->SetControls(sim->GetControls()); - } - } - - if (manager && hide) - manager->ShowNavDlg(); // also hides -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::OnCommit(AWEvent* event) -{ - if (manager) - manager->ShowNavDlg(); // also hides -} - - -// +--------------------------------------------------------------------+ - -void -NavDlg::OnCancel(AWEvent* event) -{ - if (manager) - manager->ShowNavDlg(); // also hides -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::SetNavEditMode(int mode) -{ - if (nav_edit_mode != mode) { - if (mode != NAV_EDIT_NONE) { - int map_mode = star_map->GetSelectionMode(); - if (map_mode != -1) - seln_mode = map_mode; - - star_map->SetSelectionMode(-1); - } - else { - star_map->SetSelectionMode(seln_mode); - } - - nav_edit_mode = mode; - } -} - -int -NavDlg::GetNavEditMode() -{ - return nav_edit_mode; -} - -void -NavDlg::OnMapDown(AWEvent* event) -{ -} - -void -NavDlg::OnMapMove(AWEvent* event) -{ -} - -void -NavDlg::OnMapClick(AWEvent* event) -{ - static DWORD click_time = 0; - - SetSystem(star_map->GetSystem()); - CoordinateSelection(); - - // double-click: - if (Clock::GetInstance()->RealTime() - click_time < 350) { - MissionElement* elem = star_map->GetSelectedElem(); - MsnElemDlg* msn_elem_dlg = manager->GetMsnElemDlg(); - - if (elem && msn_elem_dlg) { - msn_elem_dlg->SetMission(mission); - msn_elem_dlg->SetMissionElement(elem); - manager->ShowMsnElemDlg(); - } - } - - click_time = Clock::GetInstance()->RealTime(); -} - -void -NavDlg::CoordinateSelection() -{ - if (!seln_list || !star_map) - return; - - switch (seln_mode) { - default: - case SELECT_SYSTEM: - case SELECT_PLANET: - case SELECT_REGION: - { - seln_list->ClearSelection(); - - Orbital* selected = star_map->GetSelection(); - - if (selected) { - for (int i = 0; i < seln_list->NumItems(); i++) { - if (seln_list->GetItemText(i) == selected->Name() || - seln_list->GetItemText(i) == Text("- ") + selected->Name()) { - seln_list->SetSelected(i, true); - } - } - } - } - break; - - case SELECT_STATION: - case SELECT_STARSHIP: - case SELECT_FIGHTER: - { - seln_list->ClearSelection(); - - Ship* selected = star_map->GetSelectedShip(); - MissionElement* elem = star_map->GetSelectedElem(); - - if (selected) { - for (int i = 0; i < seln_list->NumItems(); i++) { - if (seln_list->GetItemText(i) == selected->Name()) { - seln_list->SetSelected(i, true); - } - } - } - - else if (elem) { - for (int i = 0; i < seln_list->NumItems(); i++) { - if (seln_list->GetItemText(i) == elem->Name()) { - seln_list->SetSelected(i, true); - } - } - } - } - break; - } -} - -// +--------------------------------------------------------------------+ - -void -NavDlg::OnClose(AWEvent* event) -{ - if (manager) - manager->HideNavDlg(); -} diff --git a/Stars45/NavDlg.h b/Stars45/NavDlg.h deleted file mode 100644 index 1bc4eb7..0000000 --- a/Stars45/NavDlg.h +++ /dev/null @@ -1,118 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Navigation Active Window class -*/ - -#ifndef NavDlg_h -#define NavDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "Font.h" - -class BaseScreen; -class MapView; -class StarSystem; -class Ship; -class SimRegion; -class Orbital; -class OrbitalRegion; -class Mission; - -// +--------------------------------------------------------------------+ - -class NavDlg : public FormWindow -{ -public: - NavDlg(Screen* s, FormDef& def, BaseScreen* mgr); - virtual ~NavDlg(); - - virtual void RegisterControls(); - - // Operations: - virtual void OnView(AWEvent* event); - virtual void OnFilter(AWEvent* event); - virtual void OnSelect(AWEvent* event); - virtual void OnCommit(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnEngage(AWEvent* event); - virtual void OnMapDown(AWEvent* event); - virtual void OnMapMove(AWEvent* event); - virtual void OnMapClick(AWEvent* event); - virtual void OnClose(AWEvent* event); - - virtual void ExecFrame(); - StarSystem* GetSystem() const { return star_system; } - void SetSystem(StarSystem* s); - Mission* GetMission() const { return mission; } - void SetMission(Mission* m); - Ship* GetShip() const { return ship; } - void SetShip(Ship* s); - - bool GetEditorMode() const { return editor; } - void SetEditorMode(bool b); - - void UseViewMode(int mode); - void UseFilter(int index); - void SelectObject(int index); - void UpdateSelection(); - void UpdateLists(); - void CoordinateSelection(); - - void SelectStar(Orbital* star); - void SelectPlanet(Orbital* planet); - void SelectRegion(OrbitalRegion* rgn); - - enum NAV_EDIT_MODE { NAV_EDIT_NONE = 0, - NAV_EDIT_ADD = 1, - NAV_EDIT_DEL = 2, - NAV_EDIT_MOVE = 3 }; - - void SetNavEditMode(int mode); - int GetNavEditMode(); - -protected: - Button* view_btn[3]; - Button* filter_btn[6]; - Button* commit_btn; - Button* zoom_in_btn; - Button* zoom_out_btn; - Button* close_btn; - - MapView* star_map; - ActiveWindow* map_win; - ActiveWindow* loc_labels; - ActiveWindow* dst_labels; - ActiveWindow* loc_data; - ActiveWindow* dst_data; - - ListBox* seln_list; - ListBox* info_list; - - BaseScreen* manager; - int seln_mode; - int nav_edit_mode; - - StarSystem* star_system; - List stars; - List planets; - List regions; - List contacts; - - Ship* ship; - Mission* mission; - bool editor; -}; - -#endif // NavDlg_h - diff --git a/Stars45/NavLight.cpp b/Stars45/NavLight.cpp deleted file mode 100644 index 1be4fd5..0000000 --- a/Stars45/NavLight.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Navigation Light System class -*/ - -#include "NavLight.h" - -#include "Clock.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ - -static Bitmap* images[4]; - -// +----------------------------------------------------------------------+ - -NavLight::NavLight(double p, double s) -: System(COMPUTER, 32, "Navigation Lights", 1, 0), -period(p), nlights(0), scale(s), enable(true) -{ - name = ContentBundle::GetInstance()->GetText("sys.nav-light"); - abrv = ContentBundle::GetInstance()->GetText("sys.nav-light.abrv"); - - ZeroMemory(beacon, sizeof(beacon)); - ZeroMemory(beacon_type, sizeof(beacon_type)); - ZeroMemory(pattern, sizeof(pattern)); -} - -// +----------------------------------------------------------------------+ - -NavLight::NavLight(const NavLight& c) -: System(c), period(c.period), scale(c.scale), -nlights(0), enable(true) -{ - Mount(c); - SetAbbreviation(c.Abbreviation()); - ZeroMemory(beacon, sizeof(beacon)); - ZeroMemory(beacon_type, sizeof(beacon_type)); - - nlights = c.nlights; - - for (int i = 0; i < nlights; i++) { - loc[i] = c.loc[i]; - pattern[i] = c.pattern[i]; - beacon_type[i] = c.beacon_type[i]; - - DriveSprite* rep = new DriveSprite(images[beacon_type[i]]); - rep->Scale(c.scale); - - beacon[i] = rep; - } - - offset = rand(); -} - -// +--------------------------------------------------------------------+ - -NavLight::~NavLight() -{ - for (int i = 0; i < nlights; i++) - GRAPHIC_DESTROY(beacon[i]); -} - -// +--------------------------------------------------------------------+ - -void -NavLight::Initialize() -{ - static int initialized = 0; - if (initialized) return; - - DataLoader* loader = DataLoader::GetLoader(); - loader->LoadTexture("beacon1.pcx", images[0], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("beacon2.pcx", images[1], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("beacon3.pcx", images[2], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture("beacon4.pcx", images[3], Bitmap::BMP_TRANSLUCENT); - - initialized = 1; -} - -void -NavLight::Close() -{ -} - -// +--------------------------------------------------------------------+ - -void -NavLight::ExecFrame(double seconds) -{ - if (enable && power_on) { - double t = (Clock::GetInstance()->GameTime()+offset) / 1000.0; - DWORD n = (int) (fmod(t, period) * 32 / period); - DWORD code = 1 << n; - - for (int i = 0; i < nlights; i++) { - if (beacon[i]) { - if (pattern[i] & code) - beacon[i]->SetShade(1); - else - beacon[i]->SetShade(0); - } - } - } - else { - for (int i = 0; i < nlights; i++) { - if (beacon[i]) { - beacon[i]->SetShade(0); - } - } - } -} - -void -NavLight::Enable() -{ - enable = true; -} - -void -NavLight::Disable() -{ - enable = false; -} - -void -NavLight::AddBeacon(Point l, DWORD ptn, int t) -{ - if (nlights < MAX_LIGHTS) { - loc[nlights] = l; - pattern[nlights] = ptn; - beacon_type[nlights] = t; - - DriveSprite* rep = new DriveSprite(images[t]); - rep->Scale(scale); - - beacon[nlights] = rep; - nlights++; - } -} - -void -NavLight::SetPeriod(double p) -{ - period = p; -} - -void -NavLight::SetPattern(int index, DWORD ptn) -{ - if (index >= 0 && index < nlights) - pattern[index] = ptn; -} - -void -NavLight::SetOffset(DWORD o) -{ - offset = o; -} - -// +--------------------------------------------------------------------+ - -void -NavLight::Orient(const Physical* rep) -{ - System::Orient(rep); - - const Matrix& orientation = rep->Cam().Orientation(); - Point ship_loc = rep->Location(); - - for (int i = 0; i < nlights; i++) { - Point projector = (loc[i] * orientation) + ship_loc; - if (beacon[i]) beacon[i]->MoveTo(projector); - } -} - - diff --git a/Stars45/NavLight.h b/Stars45/NavLight.h deleted file mode 100644 index b0be265..0000000 --- a/Stars45/NavLight.h +++ /dev/null @@ -1,66 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Navigation Lights System class -*/ - -#ifndef NavLight_h -#define NavLight_h - -#include "Types.h" -#include "System.h" -#include "DriveSprite.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class NavLight : public System -{ -public: - enum Constants { MAX_LIGHTS = 8 }; - - NavLight(double period, double scale); - NavLight(const NavLight& rhs); - virtual ~NavLight(); - - static void Initialize(); - static void Close(); - - virtual void ExecFrame(double seconds); - - int NumBeacons() const { return nlights; } - Sprite* Beacon(int index) const { return beacon[index]; } - bool IsEnabled() const { return enable; } - - virtual void Enable(); - virtual void Disable(); - virtual void AddBeacon(Point loc, DWORD pattern, int type=1); - virtual void SetPeriod(double p); - virtual void SetPattern(int index, DWORD p); - virtual void SetOffset(DWORD o); - - virtual void Orient(const Physical* rep); - -protected: - double period; - double scale; - bool enable; - - int nlights; - - Point loc[MAX_LIGHTS]; - DriveSprite* beacon[MAX_LIGHTS]; - DWORD pattern[MAX_LIGHTS]; - int beacon_type[MAX_LIGHTS]; - DWORD offset; -}; - -#endif // NavLight_h - diff --git a/Stars45/NavSystem.cpp b/Stars45/NavSystem.cpp deleted file mode 100644 index da5a3d6..0000000 --- a/Stars45/NavSystem.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Navigation System class implementation -*/ - -#include "NavSystem.h" -#include "Ship.h" -#include "Sim.h" -#include "HUDSounds.h" -#include "Button.h" -#include "Game.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ - -NavSystem::NavSystem() -: System(COMPUTER, 2, "Auto Nav System", 1, 1,1,1), -autonav(0) -{ - name = ContentBundle::GetInstance()->GetText("sys.nav-system"); - abrv = ContentBundle::GetInstance()->GetText("sys.nav-system.abrv"); - - power_flags = POWER_WATTS | POWER_CRITICAL; -} - -// +----------------------------------------------------------------------+ - -NavSystem::NavSystem(const NavSystem& s) -: System(s), autonav(0) -{ - Mount(s); - - power_flags = POWER_WATTS | POWER_CRITICAL; -} - -// +--------------------------------------------------------------------+ - -NavSystem::~NavSystem() -{ } - -// +--------------------------------------------------------------------+ - -void -NavSystem::ExecFrame(double seconds) -{ - if (autonav && ship && !ship->GetNextNavPoint()) - autonav = false; - - energy = 0.0f; - System::ExecFrame(seconds); -} - -// +----------------------------------------------------------------------+ - -bool -NavSystem::AutoNavEngaged() -{ - return ship && autonav && IsPowerOn(); -} - -void -NavSystem::EngageAutoNav() -{ - if (IsPowerOn() && !autonav) { - if (!ship->GetNextNavPoint()) { - Button::PlaySound(Button::SND_REJECT); - } - else { - HUDSounds::PlaySound(HUDSounds::SND_NAV_MODE); - autonav = true; - } - } -} - -void -NavSystem::DisengageAutoNav() -{ - if (autonav) - HUDSounds::PlaySound(HUDSounds::SND_NAV_MODE); - - autonav = false; -} - -// +--------------------------------------------------------------------+ - -void -NavSystem::Distribute(double delivered_energy, double seconds) -{ - if (IsPowerOn()) { - // convert Joules to Watts: - energy = (float) (delivered_energy/seconds); - - // brown out: - if (energy < capacity*0.75f) - power_on = false; - - // spike: - else if (energy > capacity*1.5f) { - power_on = false; - ApplyDamage(50); - } - } -} - diff --git a/Stars45/NavSystem.h b/Stars45/NavSystem.h deleted file mode 100644 index 3727c19..0000000 --- a/Stars45/NavSystem.h +++ /dev/null @@ -1,54 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Nav Points and so on... -*/ - -#ifndef NavSystem_h -#define NavSystem_h - -#include "Types.h" -#include "Geometry.h" -#include "System.h" - -// +--------------------------------------------------------------------+ - -class StarSystem; -class Orbital; -class OrbitalBody; -class OrbitalRegion; -class Ship; - -// +--------------------------------------------------------------------+ - -class NavSystem : public System -{ -public: - NavSystem(); - NavSystem(const NavSystem& rhs); - virtual ~NavSystem(); - - virtual void ExecFrame(double seconds); - - virtual void Distribute(double delivered_energy, double seconds); - - bool AutoNavEngaged(); - void EngageAutoNav(); - void DisengageAutoNav(); - -protected: - bool autonav; -}; - -// +--------------------------------------------------------------------+ - - -#endif // NavSystem_h - diff --git a/Stars45/NetAddrDlg.cpp b/Stars45/NetAddrDlg.cpp deleted file mode 100644 index 6af21a3..0000000 --- a/Stars45/NetAddrDlg.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Select Dialog Active Window class -*/ - -#include "NetAddrDlg.h" -#include "MenuScreen.h" -#include "NetClientConfig.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "EditBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(NetAddrDlg, OnSave); -DEF_MAP_CLIENT(NetAddrDlg, OnCancel); - -// +--------------------------------------------------------------------+ - -NetAddrDlg::NetAddrDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -btn_save(0), btn_cancel(0), edt_name(0), edt_addr(0), edt_port(0), edt_pass(0) -{ - Init(def); -} - -NetAddrDlg::~NetAddrDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -NetAddrDlg::RegisterControls() -{ - btn_save = (Button*) FindControl(1); - btn_cancel = (Button*) FindControl(2); - - REGISTER_CLIENT(EID_CLICK, btn_save, NetAddrDlg, OnSave); - REGISTER_CLIENT(EID_CLICK, btn_cancel, NetAddrDlg, OnCancel); - - edt_name = (EditBox*) FindControl(200); - edt_addr = (EditBox*) FindControl(201); - edt_port = (EditBox*) FindControl(202); - edt_pass = (EditBox*) FindControl(203); - - if (edt_name) edt_name->SetText(""); - if (edt_addr) edt_addr->SetText(""); - if (edt_port) edt_port->SetText(""); - if (edt_pass) edt_pass->SetText(""); -} - -// +--------------------------------------------------------------------+ - -void -NetAddrDlg::Show() -{ - if (!IsShown()) { - FormWindow::Show(); - - if (edt_name) edt_name->SetText(""); - if (edt_addr) edt_addr->SetText(""); - if (edt_port) edt_port->SetText(""); - if (edt_pass) edt_pass->SetText(""); - - if (edt_name) edt_name->SetFocus(); - } -} - -// +--------------------------------------------------------------------+ - -static bool tab_latch = false; - -void -NetAddrDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnSave(0); - } -} - -// +--------------------------------------------------------------------+ - -void -NetAddrDlg::OnSave(AWEvent* event) -{ - NetClientConfig* config = NetClientConfig::GetInstance(); - - if (config && - edt_addr && edt_addr->GetText().length() > 0 && - edt_port && edt_port->GetText().length() > 0) - { - Text name; - Text addr; - Text pass; - int port; - - sscanf_s(edt_port->GetText().data(), "%d", &port); - - if (edt_name && edt_name->GetText().length() < 250) { - char buffer[256]; - strcpy_s(buffer, edt_name->GetText().data()); - char* p = strpbrk(buffer, "\n\r\t"); - if (p) *p = 0; - - name = SafeQuotes(buffer); - } - - if (edt_pass && edt_pass->GetText().length() < 250) { - char buffer[256]; - strcpy_s(buffer, edt_pass->GetText().data()); - char* p = strpbrk(buffer, "\n\r\t"); - if (p) *p = 0; - - pass = SafeQuotes(buffer); - } - - if (edt_addr && edt_addr->GetText().length() < 250) { - char buffer[256]; - strcpy_s(buffer, edt_addr->GetText().data()); - char* p = strpbrk(buffer, "\n\r\t"); - if (p) *p = 0; - - addr = SafeQuotes(buffer); - } - - config->AddServer(name, addr, port, pass, true); - config->Save(); - } - - if (manager) - manager->ShowNetClientDlg(); -} - -void -NetAddrDlg::OnCancel(AWEvent* event) -{ - if (manager) - manager->ShowNetClientDlg(); -} diff --git a/Stars45/NetAddrDlg.h b/Stars45/NetAddrDlg.h deleted file mode 100644 index ca2e6e9..0000000 --- a/Stars45/NetAddrDlg.h +++ /dev/null @@ -1,59 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Network Server Address/Port Dialog Active Window class -*/ - -#ifndef NetAddrDlg_h -#define NetAddrDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; - -// +--------------------------------------------------------------------+ - -class NetAddrDlg : public FormWindow -{ -public: - NetAddrDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~NetAddrDlg(); - - virtual void RegisterControls(); - virtual void Show(); - - // Operations: - virtual void ExecFrame(); - - virtual void OnSave(AWEvent* event); - virtual void OnCancel(AWEvent* event); - -protected: - MenuScreen* manager; - - Button* btn_save; - Button* btn_cancel; - EditBox* edt_name; - EditBox* edt_addr; - EditBox* edt_port; - EditBox* edt_pass; -}; - -#endif // NetAddrDlg_h - diff --git a/Stars45/NetAdminChat.cpp b/Stars45/NetAdminChat.cpp deleted file mode 100644 index 359173a..0000000 --- a/Stars45/NetAdminChat.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - HTTP Servlet Engine for Multiplayer Admin -*/ - - -#include "NetAdminChat.h" -#include "NetLobbyServer.h" -#include "NetServerConfig.h" -#include "NetUser.h" -#include "NetChat.h" -#include "NetUtil.h" - -#include "HttpServlet.h" -#include "NetLayer.h" -#include "FormatUtil.h" - -// +-------------------------------------------------------------------+ - -NetAdminChat::NetAdminChat() -{ } - -// +-------------------------------------------------------------------+ - -bool -NetAdminChat::DoGet(HttpRequest& request, HttpResponse& response) -{ - if (CheckUser(request, response)) { - NetLobbyServer* lobby = NetLobbyServer::GetInstance(); - - if (lobby) { - Text msg = request.GetParam("msg"); - Text act = request.GetParam("action"); - - if (msg.length()) { - lobby->AddChat(user, msg); - - if (user) - NetUtil::SendChat(0xffff, user->Name(), msg); - } - - else if (act.length()) { - if (act == "clear") - lobby->ClearChat(); - - else if (act == "save") - lobby->SaveChat(); - } - } - - response.SetStatus(HttpResponse::SC_OK); - response.AddHeader("MIME-Version", "1.0"); - response.AddHeader("Content-Type", "text/html"); - response.AddHeader("Cache-Control", "no-cache"); - response.AddHeader("Expires", "-1"); - - response.SetContent(GetHead("Chat") + - GetTitleBar(GetStatLine(), - "onLoad=\"self.focus();document.chatForm.msg.focus();\"") + - GetContent() + - GetBodyClose()); - } - - return true; -} - -// +-------------------------------------------------------------------+ - -Text -NetAdminChat::GetContent() -{ - Text content = "
\n"; - - int nchat = 0; - NetLobbyServer* lobby = NetLobbyServer::GetInstance(); - if (lobby) { - content += "\n\n"; - - ListIter iter = lobby->GetChat(); - while (++iter) { - NetChatEntry* c = iter.value(); - - content += " \n"; - } - - content += "
"; - content += FormatTimeString(c->GetTime()); - content += ""; - content += c->GetUser(); - content += ""; - content += c->GetMessage(); - content += "
\n\n"; - } - - content += "
\n
\n\ -
\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ -
    
  Refresh\ -  ·  Save  ·  Clear
\n\ -
\n\ -
\n\n"; - - content += GetCopyright(); - return content; -} diff --git a/Stars45/NetAdminChat.h b/Stars45/NetAdminChat.h deleted file mode 100644 index 2ce1fba..0000000 --- a/Stars45/NetAdminChat.h +++ /dev/null @@ -1,32 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - HTTP Servlet Engine for Multiplayer Admin -*/ - - -#ifndef NetAdminChat_h -#define NetAdminChat_h - -#include "NetAdminServer.h" - -// +-------------------------------------------------------------------+ - -class NetAdminChat : public NetAdminServlet -{ -public: - NetAdminChat(); - virtual ~NetAdminChat() { } - - virtual bool DoGet(HttpRequest& request, HttpResponse& response); - virtual Text GetContent(); -}; - -#endif // NetAdminChat_h \ No newline at end of file diff --git a/Stars45/NetAdminServer.cpp b/Stars45/NetAdminServer.cpp deleted file mode 100644 index b5efad7..0000000 --- a/Stars45/NetAdminServer.cpp +++ /dev/null @@ -1,884 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - HTTP Servlet Engine for Multiplayer Admin -*/ - - -#include "NetAdminServer.h" -#include "NetLobbyServer.h" -#include "NetServerConfig.h" -#include "NetClientConfig.h" -#include "NetAdminChat.h" -#include "NetUser.h" -#include "NetChat.h" - -#include "StarServer.h" -#include "HttpServlet.h" -#include "NetLayer.h" - -#include "DataLoader.h" -#include "FormatUtil.h" -#include "MachineInfo.h" -#include "VersionInfo.h" - -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ - -class NetAdminLogin : public NetAdminServlet -{ -public: - NetAdminLogin() { } - virtual ~NetAdminLogin() { } - - virtual bool DoGet(HttpRequest& request, HttpResponse& response) { - NetServerConfig* config = NetServerConfig::GetInstance(); - - Text admin_name = "system"; - Text admin_pass = "manager"; - - if (config) { - admin_name = config->GetAdminName(); - admin_pass = config->GetAdminPass(); - } - - Text name = request.GetParam("user"); - Text pass = request.GetParam("pass"); - - Sleep(500); - - if (CheckUser(request, response)) { - response.SetStatus(HttpResponse::SC_TEMPORARY_REDIRECT); - response.SetHeader("MIME-Version", "1.0"); - response.SetHeader("Content-Type", "text/html"); - response.SetHeader("Cache-Control", "no-cache"); - response.SetHeader("Expires", "-1"); - response.SetHeader("Location", "/home"); - - response.SetContent(GetHead("Login") + - "
You are already logged in.
" + - GetBodyClose()); - } - - else if (name == admin_name && pass == admin_pass) { - user = new NetUser(name); - user->SetAddress(request.GetClientAddr()); - - if (session) - user->SetSessionID(session->GetID()); - - admin->AddUser(user); - - response.SetStatus(HttpResponse::SC_TEMPORARY_REDIRECT); - response.SetHeader("MIME-Version", "1.0"); - response.SetHeader("Content-Type", "text/html"); - response.SetHeader("Cache-Control", "no-cache"); - response.SetHeader("Expires", "-1"); - response.SetHeader("Location", "/home"); - - response.SetContent(GetHead("Login") + - "
You have successfully logged in.
" + - GetBodyClose()); - } - - else { - response.SetStatus(HttpResponse::SC_OK); - response.SetHeader("MIME-Version", "1.0"); - response.SetHeader("Content-Type", "text/html"); - response.SetHeader("Cache-Control", "no-cache"); - response.SetHeader("Expires", "-1"); - - response.SetContent(GetHead("Login") + - GetTitleBar(0, "onLoad=\"self.focus();document.loginForm.user.focus();\"") + - GetContent() + - GetBodyClose()); - } - - return true; - } - - virtual Text GetContent() { Text content = - " \n\ - \n\ - \n\ - \n\ - \n\ -
  

\n\ - Welcome to the Starshatter Server!

\n\ - Login to access the server "; - - NetServerConfig* config = NetServerConfig::GetInstance(); - if (config) - content += config->Name(); - else - content += "server"; - - content += "
\n\ -
\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ -
Username:
Password:
 
\n\ -
\n\ -
 
\n"; - - return content; - } -}; - -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ - -class NetAdminServerMgr : public NetAdminServlet -{ -public: - NetAdminServerMgr() { } - virtual ~NetAdminServerMgr() { } - - virtual bool DoGet(HttpRequest& request, HttpResponse& response) { - if (CheckUser(request, response)) { - Text action = request.GetParam("action"); - action.setSensitive(false); - - bool completed = false; - - if (action == "restart") { - StarServer* svr = StarServer::GetInstance(); - - if (svr) { - svr->Shutdown(true); - completed = true; - - response.SetStatus(HttpResponse::SC_OK); - response.SetHeader("MIME-Version", "1.0"); - response.SetHeader("Content-Type", "text/html"); - response.SetHeader("Cache-Control", "no-cache"); - response.SetHeader("Expires", "-1"); - - response.SetContent(GetHead("Restart") + - GetTitleBar() + - "
The Starshatter Server will restart in three (3) seconds.
" + - GetBodyClose()); - } - } - - else if (action == "shutdown") { - StarServer* svr = StarServer::GetInstance(); - - if (svr) { - svr->Shutdown(false); - completed = true; - - response.SetStatus(HttpResponse::SC_OK); - response.SetHeader("MIME-Version", "1.0"); - response.SetHeader("Content-Type", "text/html"); - response.SetHeader("Cache-Control", "no-cache"); - response.SetHeader("Expires", "-1"); - - response.SetContent(GetHead("Restart") + - GetTitleBar() + - "
The Starshatter Server will shutdown in three (3) seconds.
" + - GetBodyClose()); - } - } - - if (!completed) { - response.SetStatus(HttpResponse::SC_TEMPORARY_REDIRECT); - response.SetHeader("MIME-Version", "1.0"); - response.SetHeader("Content-Type", "text/html"); - response.SetHeader("Cache-Control", "no-cache"); - response.SetHeader("Expires", "-1"); - response.SetHeader("Location", "/home"); - - response.SetContent(GetHead("Login") + - "
Unknown Action.
" + - GetBodyClose()); - } - } - - return true; - } -}; - -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ - -class NetAdminFile : public NetAdminServlet -{ -public: - NetAdminFile() { } - virtual ~NetAdminFile() { } - - virtual bool DoGet(HttpRequest& request, HttpResponse& response) { - if (!CheckUser(request, response)) - return true; - - Text content; - Text path = request.GetParam("path"); - Text name = request.GetParam("name"); - - if (name.length()) { - BYTE* buffer = 0; - DataLoader* loader = DataLoader::GetLoader(); - - if (loader) { - bool use_file_system = loader->IsFileSystemEnabled(); - - loader->UseFileSystem(true); - loader->SetDataPath(path); - int len = loader->LoadBuffer(name, buffer); - - if (len) { - content = Text((const char*) buffer, len); - } - - loader->ReleaseBuffer(buffer); - loader->SetDataPath(0); - loader->UseFileSystem(use_file_system); - } - } - - response.SetStatus(HttpResponse::SC_OK); - response.AddHeader("MIME-Version", "1.0"); - response.AddHeader("Cache-Control", "no-cache"); - response.AddHeader("Expires", "-1"); - response.AddHeader("Content-Type", "text/plain"); - response.SetContent(content); - - return true; - } -}; - -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ - -class NetAdminUserList : public NetAdminServlet -{ -public: - NetAdminUserList() { } - virtual ~NetAdminUserList() { } - - virtual bool DoGet(HttpRequest& request, HttpResponse& response) { - if (CheckUser(request, response)) { - response.SetStatus(HttpResponse::SC_OK); - response.SetHeader("MIME-Version", "1.0"); - response.SetHeader("Content-Type", "text/html"); - response.SetHeader("Cache-Control", "no-cache"); - response.SetHeader("Expires", "-1"); - - response.SetContent(GetHead("User List") + - GetTitleBar() + - GetContent() + - GetBodyClose()); - } - - return true; - } - - virtual Text GetContent() { - Text content = - "\n\ -
\n\ -\n\ - \n\ - \n\ - \n\ -
\n\ -  User List\n\ -
\n\n"; - - content += - " \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ -\n"; - - NetLobbyServer* lobby = NetLobbyServer::GetInstance(); - - if (lobby) { - ListIter u_iter = lobby->GetUsers(); - while (++u_iter) { - NetUser* u = u_iter.value(); - NetAddr a = u->GetAddress(); - - char addr_dotted[32]; - char addr_hex[16]; - char user_stats[16]; - - sprintf_s(addr_dotted, "%d.%d.%d.%d", a.B1(), a.B2(), a.B3(), a.B4()); - sprintf_s(addr_hex, "%08x", a.IPAddr()); - sprintf_s(user_stats, "%d / %d / %d", u->Missions(), u->Kills(), u->Losses()); - - content += "\n\n\ - \n"; - } - } - - content += "
 NameAddressIs HostSquadronStatsBan
 "; - content += u->Name(); - content += ""; - content += addr_dotted; - content += ""; - content += u->IsHost() ? "*" : " "; - content += ""; - content += u->Squadron(); - content += ""; - content += user_stats; - content += ""; - content += "Name()); - content += "&addr="; - content += addr_hex; - content += "\">BAN
\n\n"; - - content += "
\n\n"; - content += GetCopyright(); - return content; - } -}; - -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ - -class NetAdminBanUser : public NetAdminServlet -{ -public: - NetAdminBanUser() { } - virtual ~NetAdminBanUser() { } - - virtual bool DoGet(HttpRequest& request, HttpResponse& response) { - if (CheckUser(request, response)) { - Text name = request.GetParam("name"); - bool completed = false; - - NetLobbyServer* lobby = NetLobbyServer::GetInstance(); - - if (lobby) { - ListIter u_iter = lobby->GetUsers(); - while (++u_iter && !completed) { - NetUser* u = u_iter.value(); - - if (u->Name() == name) { - NetLobbyServer* nls = NetLobbyServer::GetInstance(); - - if (nls) { - nls->BanUser(u); - completed = true; - } - } - } - } - - response.SetStatus(HttpResponse::SC_TEMPORARY_REDIRECT); - response.SetHeader("MIME-Version", "1.0"); - response.SetHeader("Content-Type", "text/html"); - response.SetHeader("Cache-Control", "no-cache"); - response.SetHeader("Expires", "-1"); - response.SetHeader("Location", "/users"); - - response.SetContent(GetHead("User List") + - GetTitleBar() + - "
User Banned.
" + - GetBodyClose()); - } - - return true; - } -}; - -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ - -static NetAdminServer* net_Admin_server = 0; - -NetAdminServer* -NetAdminServer::GetInstance(WORD port) -{ - if (!net_Admin_server && port > 0) - net_Admin_server = new NetAdminServer(port); - - return net_Admin_server; -} - -NetAdminServer::NetAdminServer(WORD port) -: HttpServletExec(port) -{ - http_server_name = Text("Starshatter NetAdminServer ") + versionInfo; -} - -NetAdminServer::~NetAdminServer() -{ - if (net_Admin_server == this) - net_Admin_server = 0; -} - -// +--------------------------------------------------------------------+ - -HttpServlet* -NetAdminServer::GetServlet(HttpRequest& request) -{ - Text path = request.URI(); - path.setSensitive(false); - - if (path.indexOf("/login") == 0) - return new NetAdminLogin; - - if (path.indexOf("/chat") == 0) - return new NetAdminChat; - - if (path.indexOf("/server") == 0) - return new NetAdminServerMgr; - - if (path.indexOf("/file") == 0) - return new NetAdminFile; - - if (path.indexOf("/user") == 0) - return new NetAdminUserList; - - if (path.indexOf("/ban") == 0) - return new NetAdminBanUser; - - return new NetAdminServlet; -} - -// +-------------------------------------------------------------------+ - -void -NetAdminServer::AddChat(NetUser* user, const char* msg) -{ - if (user && msg && *msg) { - NetLobbyServer* lobby = NetLobbyServer::GetInstance(); - - if (lobby) - lobby->AddChat(user, msg); - } -} - -ListIter -NetAdminServer::GetChat() -{ - NetLobbyServer* lobby = NetLobbyServer::GetInstance(); - - if (lobby) - return lobby->GetChat(); - - static List idle_chatter; - return idle_chatter; -} - -// +-------------------------------------------------------------------+ - -void -NetAdminServer::AddUser(NetUser* user) -{ - if (user && !admin_users.contains(user)) - admin_users.append(user); -} - -void -NetAdminServer::DelUser(NetUser* user) -{ - if (user) { - admin_users.remove(user); - delete user; - } -} - -int -NetAdminServer::NumUsers() -{ - return admin_users.size(); -} - - -List& -NetAdminServer::GetUsers() -{ - return admin_users; -} - -bool -NetAdminServer::HasHost() -{ - bool result = false; - - NetLobbyServer* lobby = NetLobbyServer::GetInstance(); - - if (lobby) - result = lobby->HasHost(); - - return result; -} - -NetUser* -NetAdminServer::FindUserBySession(Text id) -{ - ListIter iter = admin_users; - while (++iter) { - NetUser* u = iter.value(); - if (u->GetSessionID() == id) - return u; - } - - return 0; -} - -void -NetAdminServer::DoSyncedCheck() -{ - ListIter iter = admin_users; - while (++iter) { - NetUser* u = iter.value(); - - bool found = false; - - ListIter s_iter = sessions; - while (++s_iter && !found) { - HttpSession* s = s_iter.value(); - - if (s->GetID() == u->GetSessionID()) - found = true; - } - - if (!found) - delete iter.removeItem(); - } -} - - -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ - -NetAdminServlet::NetAdminServlet() -{ - admin = NetAdminServer::GetInstance(); - user = 0; -} - -// +-------------------------------------------------------------------+ - -bool -NetAdminServlet::DoGet(HttpRequest& request, HttpResponse& response) -{ - if (CheckUser(request, response)) { - - if (request.URI() == "/home") - response.SetStatus(HttpResponse::SC_OK); - else - response.SetStatus(HttpResponse::SC_TEMPORARY_REDIRECT); - - response.SetHeader("MIME-Version", "1.0"); - response.SetHeader("Content-Type", "text/html"); - response.SetHeader("Cache-Control", "no-cache"); - response.SetHeader("Expires", "-1"); - response.SetHeader("Location", "/home"); - - response.SetContent(GetHead() + - GetTitleBar(GetStatLine()) + - GetContent() + - GetBodyClose()); - } - - return true; -} - -// +-------------------------------------------------------------------+ - -bool -NetAdminServlet::CheckUser(HttpRequest& request, HttpResponse& response) -{ - if (!user) { - if (session) - user = admin->FindUserBySession(session->GetID()); - - if (!user) { - response.SetStatus(HttpResponse::SC_TEMPORARY_REDIRECT); - response.SetHeader("MIME-Version", "1.0"); - response.SetHeader("Content-Type", "text/plain"); - response.SetHeader("Cache-Control", "no-cache"); - response.SetHeader("Expires", "-1"); - response.SetHeader("Location", "/login"); - response.SetContent("You are not logged in."); - } - } - - return user != 0; -} - -// +-------------------------------------------------------------------+ - -Text -NetAdminServlet::GetCSS() -{ - return - - "body { font-family:arial,helvetica,sans-serif; color:black; background-color:white }\n\ -a:link { text-decoration:none; font-weight:normal; font-size:10pt; color:black }\n\ -a:visited { text-decoration:none; font-weight:normal; font-size:10pt; color:black }\n\ -a:hover { text-decoration:underline; font-weight:normal; font-size:10pt; color:black }\n\ -.std { font-size:10pt }\n\ -.tiny { font-size:8pt }\n\ -.heading { font-size:14pt; font-weight:bold; background-color:#99BBEE }\n\ -.subhead { font-size:11pt; font-weight:bold }\n\ -.status { font-size:10pt; color:white }\n\ -.content { padding-right: 4pt; padding-left: 4pt; padding-bottom: 4pt; padding-top: 4pt; margin: 4pt; }\n\ -.copy { font-size:8pt; }\n\ -.top-bar { color: white; background-color: #336699 }\n\ -.top-line { color: yellow; background-color: black }\n\ -.topbarbig { line-height:24px; color:white; font-size:18px; font-weight:bold; }\n\ -.topbarsmall { line-height:18px; color:white; font-size:14px; }\n"; -} - -Text -NetAdminServlet::GetHead(const char* title) -{ - Text head = "\n\nStarshatter Server"; - - if (title && *title) { - head += " - "; - head += title; - } - - head += "\n\n\n"; - - return head; -} - -Text -NetAdminServlet::GetBody() -{ - return GetTitleBar(GetStatLine()) + - GetContent() + - GetBodyClose(); -} - -Text -NetAdminServlet::GetTitleBar(const char* statline, const char* onload) -{ - Text bar = "\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ -
 \n\ - Administration Console
\n"; - - if (statline) { - bar += ""; - } - - bar += "Starshatter Server "; - bar += versionInfo; - bar += ""; - - if (statline) { - bar += ""; - } - - bar += "\n\ -
"; - - if (statline && *statline) - bar += statline; - else - bar += " "; - - bar += "
\n\n"; - - return bar; -} - -Text -NetAdminServlet::GetStatLine() -{ - NetServerConfig* config = NetServerConfig::GetInstance(); - - Text line = - " \n\ - \n\ - \n\ - \n\ - \n\ - \n\ -
\n\ -   Connected to "; - - char buffer[256]; - sprintf_s(buffer, "%s:%d", config->Name().data(), config->GetAdminPort()); - line += buffer; - - line += "\n\ - \n\ - Server Mode: "; - - NetLobbyServer* lobby = NetLobbyServer::GetInstance(); - if (lobby) { - switch (lobby->GetStatus()) { - default: - case NetServerInfo::OFFLINE: line += "Offline"; break; - case NetServerInfo::LOBBY: line += "Lobby"; break; - case NetServerInfo::BRIEFING: line += "Briefing"; break; - case NetServerInfo::ACTIVE: line += "Active"; break; - case NetServerInfo::DEBRIEFING: line += "Debriefing"; break; - case NetServerInfo::PERSISTENT: line += "PERSISTENT"; break; - } - } - else { - line += "Unknown"; - } - - line += "\n\ - \n\ - "; - - line += FormatTimeString(); - - line += "  \n\ -
\n"; - - return line; -} - -Text -NetAdminServlet::GetContent() -{ - Text content = - "\n\ -
\n\ -\n\ - \n\ - \n\ - \n\ -
\n\ -  Game Admin Functions\n\ -
\n\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ -\n\ -
 \n\ - Lobby Chat\n\ - \n\ - Mission List\n\ -
 \n\ - View Error Log\n\ - \n\ - Player List\n\ -
 \n\ - View Server Log\n\ - \n\ - Ban List\n\ -
 
\n\n"; - - content += - " \n\ - \n\ - \n\ - \n\ -
\n\ -  Server Admin Functions\n\ -
\n\n\ -\n\ - \n\ - \n\ - \n\ - \n\ - \n\ -\n\ -
 \n\ - Restart Server\n\ - \n\ - Shutdown Server\n\ -
\n\n"; - - content += "
\n\n"; - content += GetCopyright(); - return content; -} - -Text -NetAdminServlet::GetBodyClose() -{ - return "\n\n\n\n"; -} - -Text -NetAdminServlet::GetCopyright() -{ - return "
    Copyright © 1997-2004 Destroyer Studios. All rights reserved.
"; -} diff --git a/Stars45/NetAdminServer.h b/Stars45/NetAdminServer.h deleted file mode 100644 index 804d482..0000000 --- a/Stars45/NetAdminServer.h +++ /dev/null @@ -1,90 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - HTTP Servlet Engine for Multiplayer Admin -*/ - - -#ifndef NetAdminServer_h -#define NetAdminServer_h - -#include "HttpServletExec.h" -#include "HttpServlet.h" - -// +-------------------------------------------------------------------+ - -class Mission; -class MissionElement; -class NetChatEntry; -class NetUser; - -// +-------------------------------------------------------------------+ - -class NetAdminServer : public HttpServletExec -{ -public: - virtual ~NetAdminServer(); - - int operator == (const NetAdminServer& s) const { return this == &s; } - - virtual HttpServlet* GetServlet(HttpRequest& request); - - virtual void AddUser(NetUser* user); - virtual void DelUser(NetUser* user); - virtual int NumUsers(); - virtual bool HasHost(); - virtual List& GetUsers(); - - virtual NetUser* FindUserBySession(Text id); - - virtual void AddChat(NetUser* user, const char* msg); - ListIter GetChat(); - DWORD GetStartTime() const { return start_time; } - - virtual void GameOn() { } - virtual void GameOff() { } - - // singleton locator: - static NetAdminServer* GetInstance(WORD port=0); - -protected: - NetAdminServer(WORD port); - virtual void DoSyncedCheck(); - - DWORD start_time; - List admin_users; -}; - -// +-------------------------------------------------------------------+ - -class NetAdminServlet : public HttpServlet -{ -public: - NetAdminServlet(); - virtual ~NetAdminServlet() { } - - virtual bool DoGet(HttpRequest& request, HttpResponse& response); - virtual bool CheckUser(HttpRequest& request, HttpResponse& response); - - virtual Text GetCSS(); - virtual Text GetHead(const char* title=0); - virtual Text GetBody(); - virtual Text GetTitleBar(const char* statline=0, const char* onload=0); - virtual Text GetStatLine(); - virtual Text GetCopyright(); - virtual Text GetContent(); - virtual Text GetBodyClose(); - -protected: - NetAdminServer* admin; - NetUser* user; -}; - -#endif // NetAdminServer_h \ No newline at end of file diff --git a/Stars45/NetAuth.cpp b/Stars45/NetAuth.cpp deleted file mode 100644 index f9e4d02..0000000 --- a/Stars45/NetAuth.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - This class represents a user connecting to the multiplayer lobby -*/ - - -#include "NetAuth.h" -#include "NetLobby.h" -#include "NetUser.h" -#include "ModConfig.h" -#include "ModInfo.h" -#include "Random.h" -#include "Sha1.h" - -static int auth_level = NetAuth::NET_AUTH_MINIMAL; - -// +-------------------------------------------------------------------+ - -int -NetAuth::AuthLevel() -{ - return auth_level; -} - - -void -NetAuth::SetAuthLevel(int n) -{ - if (n >= NET_AUTH_MINIMAL && n <= NET_AUTH_SECURE) - auth_level = n; -} - -// +-------------------------------------------------------------------+ - -Text -NetAuth::CreateAuthRequest(NetUser* u) -{ - Text request; - - if (u) { - u->SetAuthLevel(auth_level); - - if (auth_level == NET_AUTH_MINIMAL) { - u->SetAuthState(NET_AUTH_OK); - u->SetSalt("Very Low Sodium"); - } - - else if (auth_level == NET_AUTH_STANDARD) { - u->SetAuthState(NET_AUTH_INITIAL); - u->SetSalt("Very Low Sodium"); - - request = "level 1"; - } - - else { - char salt[33]; - - for (int i = 0; i < 32; i++) - salt[i] = (char) ('0' + (int) Random(0, 9.4)); - - salt[32] = 0; - u->SetSalt(salt); - u->SetAuthState(NET_AUTH_INITIAL); - - request = "level 2 salt "; - request += salt; - } - } - - return request; -} - -// +-------------------------------------------------------------------+ - -static Text Digest(const char* salt, const char* file) -{ - int length = 0; - int offset = 0; - char block[4096]; - char digest[64]; - - ZeroMemory(digest, sizeof(digest)); - - if (file) { - FILE* f; - fopen_s(&f, file, "rb"); - - if (f) { - SHA1 sha1; - - if (salt) { - sha1.Input(salt, strlen(salt)); - } - - fseek(f, 0, SEEK_END); - length = ftell(f); - fseek(f, 0, SEEK_SET); - - while (offset < length) { - int n = fread(block, sizeof(char), 4096, f); - sha1.Input(block, n); - offset += n; - } - - fclose(f); - - unsigned result[5]; - if (sha1.Result(result)) { - sprintf_s(digest, "SHA1_%08X_%08X_%08X_%08X_%08X", - result[0], result[1], result[2], result[3], result[4]); - } - } - } - - return digest; -} - -// +-------------------------------------------------------------------+ - -Text -NetAuth::CreateAuthResponse(int level, const char* salt) -{ - Text response; - ModConfig* config = ModConfig::GetInstance(); - - if (level == NET_AUTH_SECURE) { - response += "exe "; - response += Digest(salt, "stars.exe"); // XXX should look up name of this exe - response += " "; - - response += "dat "; - response += Digest(salt, "shatter.dat"); - response += " "; - - response += "etc "; - response += Digest(salt, "start.dat"); - response += " "; - } - - if (level >= NET_AUTH_STANDARD) { - List& mods = config->GetModInfoList(); - ListIter mod_iter = mods; - - char buffer[32]; - sprintf_s(buffer, "num %d ", mods.size()); - response += buffer; - - while (++mod_iter) { - ModInfo* info = mod_iter.value(); - - response += "mod \""; - response += info->Name(); - response += "\" ver \""; - response += info->Version(); - response += "\" "; - - if (level == NET_AUTH_SECURE) { - response += "sha "; - response += Digest(salt, info->Filename()); - response += " "; - } - } - } - - return response; -} - -// +-------------------------------------------------------------------+ - -bool -NetAuth::AuthUser(NetUser* u, Text response) -{ - bool authentic = false; - - if (auth_level == NET_AUTH_MINIMAL) { // (this case should not occur) - if (u) { - u->SetAuthLevel(auth_level); - u->SetAuthState(NET_AUTH_OK); - } - - authentic = (u != 0); - } - - else if (u) { - Text expected_response = CreateAuthResponse(auth_level, u->Salt()); - if (expected_response == response) - authentic = true; - - u->SetAuthState(authentic ? NET_AUTH_OK : NET_AUTH_FAILED); - } - - return authentic; -} - -// +-------------------------------------------------------------------+ - diff --git a/Stars45/NetAuth.h b/Stars45/NetAuth.h deleted file mode 100644 index 42103fc..0000000 --- a/Stars45/NetAuth.h +++ /dev/null @@ -1,50 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - This class authenticates a user connecting to the multiplayer lobby -*/ - - -#ifndef NetAuth_h -#define NetAuth_h - -#include "Types.h" -#include "NetAddr.h" -#include "NetLobby.h" -#include "Text.h" - -// +-------------------------------------------------------------------+ - -class NetAuth -{ -public: - enum AUTH_STATE { - NET_AUTH_INITIAL = 0, - NET_AUTH_FAILED = 1, - NET_AUTH_OK = 2 - }; - - enum AUTH_LEVEL { - NET_AUTH_MINIMAL = 0, - NET_AUTH_STANDARD = 1, - NET_AUTH_SECURE = 2 - }; - - static int AuthLevel(); - static void SetAuthLevel(int n); - - static Text CreateAuthRequest(NetUser* u); - static Text CreateAuthResponse(int level, const char* salt); - static bool AuthUser(NetUser* u, Text response); -}; - -// +-------------------------------------------------------------------+ - -#endif // NetAuth_h \ No newline at end of file diff --git a/Stars45/NetBrokerClient.cpp b/Stars45/NetBrokerClient.cpp deleted file mode 100644 index 043c580..0000000 --- a/Stars45/NetBrokerClient.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Client for Starshatter.com GameNet Broker -*/ - - -#include "NetBrokerClient.h" - -#include "HttpClient.h" -#include "HttpServlet.h" -#include "NetLayer.h" - -#include "Game.h" -#include "VersionInfo.h" - -const char* HOSTNAME = "www.starshatter.com"; -const WORD HTTPPORT = 80; - -bool NetBrokerClient::broker_available = false; -bool NetBrokerClient::broker_found = false; - -// +--------------------------------------------------------------------+ - -bool -NetBrokerClient::GameOn(const char* name, -const char* type, -const char* addr, -WORD port, -const char* password) -{ - bool result = false; - - if (!broker_available) - return result; - - Text msg; - char buffer[8]; - NetAddr broker(HOSTNAME, HTTPPORT); - - if (broker.IPAddr() == 0) - return result; - - sprintf_s(buffer, "%d", port); - - msg = "GET http://"; - msg += HOSTNAME; - msg += "/GameNet/GameOn.php?name="; - msg += HttpRequest::EncodeParam(name); - msg += "&addr="; - msg += HttpRequest::EncodeParam(addr); - msg += "&game="; - msg += HttpRequest::EncodeParam(type); - msg += "&vers="; - msg += HttpRequest::EncodeParam(versionInfo); - msg += "&port="; - msg += buffer; - msg += "&pass="; - msg += HttpRequest::EncodeParam(password); - msg += " HTTP/1.1\n\n"; - - HttpClient client(broker); - HttpRequest request(msg); - request.SetHeader("Host", HOSTNAME); - - HttpResponse* response = client.DoRequest(request); - - if (response && response->Status() == 200) { - broker_found = true; - result = true; - } - else { - ::Print("NetBrokerClient unable to contact GameNet!\n"); - - if (response) { - ::Print(" Response Status: %d\n", response->Status()); - ::Print(" Response Content: %s\n", response->Content().data()); - } - else { - ::Print(" No response.\n"); - } - - if (!broker_found) - broker_available = false; - } - - delete response; - return result; -} - -bool -NetBrokerClient::GameList(const char* type, List& server_list) -{ - bool result = false; - - if (!broker_available) - return result; - - Text msg; - NetAddr broker(HOSTNAME, HTTPPORT); - - if (broker.IPAddr() == 0) - return result; - - msg = "GET http://"; - msg += HOSTNAME; - msg += "/GameNet/GameList.php?game="; - msg += HttpRequest::EncodeParam(type); - msg += "&vers="; - msg += HttpRequest::EncodeParam(versionInfo); - msg += " HTTP/1.1\n\n"; - - HttpClient client(broker); - HttpRequest request(msg); - request.SetHeader("Host", HOSTNAME); - - HttpResponse* response = client.DoRequest(request); - - if (response && response->Status() == 200) { - result = true; - - Text name; - Text type; - Text addr; - int port; - Text pass; - Text vers; - char buff[1024]; - - const char* p = response->Content(); - - // skip size - while (*p && strncmp(p, "name:", 5)) - p++; - - while (*p) { - if (!strncmp(p, "name:", 5)) { - p += 5; - ZeroMemory(buff, sizeof(buff)); - char* d = buff; - while (*p && *p != '\n') *d++ = *p++; - if (*p) p++; - - name = buff; - } - else if (!strncmp(p, "addr:", 5)) { - p += 5; - ZeroMemory(buff, sizeof(buff)); - char* d = buff; - while (*p && *p != '\n') *d++ = *p++; - if (*p) p++; - - addr = buff; - } - else if (!strncmp(p, "port:", 5)) { - p += 5; - ZeroMemory(buff, sizeof(buff)); - char* d = buff; - while (*p && *p != '\n') *d++ = *p++; - if (*p) p++; - - sscanf_s(buff, "%d", &port); - } - else if (!strncmp(p, "pass:", 5)) { - p += 5; - ZeroMemory(buff, sizeof(buff)); - char* d = buff; - while (*p && *p != '\n') *d++ = *p++; - if (*p) p++; - - pass = buff; - } - else if (!strncmp(p, "game:", 5)) { - p += 5; - ZeroMemory(buff, sizeof(buff)); - char* d = buff; - while (*p && *p != '\n') *d++ = *p++; - if (*p) p++; - - type = buff; - type.setSensitive(false); - - if (type.contains("lan")) - type = "LAN"; - else - type = "Public"; - } - else if (!strncmp(p, "vers:", 5)) { - p += 5; - ZeroMemory(buff, sizeof(buff)); - char* d = buff; - while (*p && *p != '\n') *d++ = *p++; - if (*p) p++; - - vers = buff; - } - else if (!strncmp(p, "time:", 5)) { - while (*p && *p != '\n') p++; - if (*p) p++; - } - - else if (!strncmp(p, "###", 3)) { - NetServerInfo* server = new NetServerInfo; - server->name = name; - server->hostname = addr; - server->type = type; - server->addr = NetAddr(addr, port); - server->port = port; - server->password = pass; - server->version = vers; - server->save = false; - - server_list.append(server); - - while (*p && strncmp(p, "name:", 5)) - p++; - } - else { - while (*p && *p != '\n') p++; - if (*p) p++; - } - } - } - else if (!broker_found) { - broker_available = false; - } - - delete response; - return result; -} diff --git a/Stars45/NetBrokerClient.h b/Stars45/NetBrokerClient.h deleted file mode 100644 index e05e89d..0000000 --- a/Stars45/NetBrokerClient.h +++ /dev/null @@ -1,42 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Client for Starshatter.com GameNet Broker -*/ - - -#ifndef NetBrokerClient_h -#define NetBrokerClient_h - -#include "HttpClient.h" -#include "NetLobby.h" - -// +-------------------------------------------------------------------+ - -class NetBrokerClient -{ -public: - static void Enable() { broker_available = true; } - static void Disable() { broker_available = false; } - - static bool GameOn(const char* name, - const char* type, - const char* addr, - WORD port, - const char* password); - static bool GameList(const char* type, List& server_list); - -protected: - static bool broker_available; - static bool broker_found; -}; - - -#endif // NetBrokerClient_h \ No newline at end of file diff --git a/Stars45/NetChat.cpp b/Stars45/NetChat.cpp deleted file mode 100644 index 7c1f4d2..0000000 --- a/Stars45/NetChat.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Single chat message and sender -*/ - - -#include "NetChat.h" -#include "NetLayer.h" - -// +-------------------------------------------------------------------+ - -static int chat_id_key = 1000; - -// +-------------------------------------------------------------------+ - -NetChatEntry::NetChatEntry(const NetUser* u, const char* s) -: id(chat_id_key++), msg(s) -{ - if (u) { - user = u->Name(); - color = u->GetColor(); - } - else { - user = "unknown"; - color = Color::Gray; - } - - time = NetLayer::GetUTC(); -} - -NetChatEntry::NetChatEntry(int msg_id, const char* u, const char* s) -: id(msg_id), user(u), msg(s) -{ - color = Color::Gray; - time = NetLayer::GetUTC(); - - if (id >= chat_id_key) - chat_id_key = id + 1; -} - -NetChatEntry::~NetChatEntry() -{ } - diff --git a/Stars45/NetChat.h b/Stars45/NetChat.h deleted file mode 100644 index 97e5dd8..0000000 --- a/Stars45/NetChat.h +++ /dev/null @@ -1,51 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Single chat message and sender -*/ - - -#ifndef NetChat_h -#define NetChat_h - -#include "Types.h" -#include "NetUser.h" - -// +-------------------------------------------------------------------+ - -class NetChatEntry -{ -public: - static const char* TYPENAME() { return "NetChatEntry"; } - - NetChatEntry(const NetUser* user, const char* msg); - NetChatEntry(int id, const char* user, const char* msg); - ~NetChatEntry(); - - int operator == (const NetChatEntry& c) const { return id == c.id; } - int operator < (const NetChatEntry& c) const { return id < c.id; } - - int GetID() const { return id; } - const Text& GetUser() const { return user; } - Color GetColor() const { return color; } - const Text& GetMessage() const { return msg; } - DWORD GetTime() const { return time; } - -private: - int id; - Text user; - Text msg; - Color color; - DWORD time; -}; - -// +-------------------------------------------------------------------+ - -#endif // NetChat_h \ No newline at end of file diff --git a/Stars45/NetClientConfig.cpp b/Stars45/NetClientConfig.cpp deleted file mode 100644 index 2fd4d1b..0000000 --- a/Stars45/NetClientConfig.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/* 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 "NetClientConfig.h" -#include "NetLobbyClient.h" -#include "NetBrokerClient.h" - -#include "NetLayer.h" -#include "NetAddr.h" -#include "NetHost.h" - -#include "Token.h" -#include "Game.h" -#include "DataLoader.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ - -NetClientConfig* NetClientConfig::instance = 0; - -// +--------------------------------------------------------------------+ - -NetClientConfig::NetClientConfig() -: server_index(-1), host_request(false), conn(0) -{ - instance = this; - Load(); -} - -NetClientConfig::~NetClientConfig() -{ - Logout(); - - instance = 0; - servers.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -NetClientConfig::Initialize() -{ - if (!instance) - instance = new NetClientConfig(); -} - -void -NetClientConfig::Close() -{ - delete instance; - instance = 0; -} - -// +--------------------------------------------------------------------+ - -void -NetClientConfig::AddServer(const char* name, const char* addr, WORD port, const char* pass, bool save) -{ - if (!addr || !*addr || port < 1024 || port > 48000) - return; - - char buffer[1024]; - if (name && *name) - strcpy_s(buffer, name); - else - sprintf_s(buffer, "%s:%d", addr, port); - - NetServerInfo* server = new NetServerInfo; - server->name = buffer; - server->hostname = addr; - server->addr = NetAddr(addr, port); - server->port = port; - server->password = pass; - server->save = save; - - if (server->addr.IPAddr() == 0) { - Print("NetClientConfig::AddServer(%s, %s, %d) failed to resolve IP Addr\n", - name, addr, port); - } - - servers.append(server); -} - -void -NetClientConfig::DelServer(int index) -{ - if (index >= 0 && index < servers.size()) { - delete servers.removeIndex(index); - } -} - -// +--------------------------------------------------------------------+ - -NetServerInfo* -NetClientConfig::GetServerInfo(int n) -{ - if (n >= 0 && n < servers.size()) - return servers.at(n); - - return 0; -} - -// +--------------------------------------------------------------------+ - -NetServerInfo* -NetClientConfig::GetSelectedServer() -{ - if (server_index >= 0 && server_index < servers.size()) - return servers.at(server_index); - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -NetClientConfig::Download() -{ - Load(); - - List list; - if (NetBrokerClient::GameList("Starshatter", list)) { - servers.append(list); - } -} - -// +--------------------------------------------------------------------+ - -void -NetClientConfig::Load() -{ - server_index = -1; - - // read the config file: - BYTE* block = 0; - int blocklen = 0; - - char filename[64]; - strcpy_s(filename, "client.cfg"); - - FILE* f; - ::fopen_s(&f, 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; - - servers.destroy(); - - Parser parser(new BlockReader((const char*) block, blocklen)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'.\n", filename); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "CLIENT_CONFIG") { - 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() == "server") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: server struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - Text name; - Text addr; - Text pass; - int port; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") - GetDefText(name, pdef, filename); - else if (pdef->name()->value() == "addr") - GetDefText(addr, pdef, filename); - else if (pdef->name()->value() == "pass") - GetDefText(pass, pdef, filename); - else if (pdef->name()->value() == "port") - GetDefNumber(port, pdef, filename); - } - } - - AddServer(name, addr, (WORD) port, pass, true); - } - } - else { - Print("WARNING: unknown label '%s' in '%s'\n", - def->name()->value().data(), filename); - } - } - } - } - while (term); - - delete [] block; -} - -// +--------------------------------------------------------------------+ - -void -NetClientConfig::Save() -{ - FILE* f; - fopen_s(&f, "client.cfg", "wb"); - if (f) { - fprintf(f, "CLIENT_CONFIG\n\n"); - - ListIter iter = servers; - while (++iter) { - NetServerInfo* server = iter.value(); - - if (server->save) { - int port = (int) server->port; - fprintf(f, "server: {\n"); - fprintf(f, " name: \"%s\",\n", (const char*) server->name); - fprintf(f, " addr: \"%s\",\n", (const char*) server->hostname); - fprintf(f, " port: %d,\n", port); - - if (server->password.length()) - fprintf(f, " pass: \"%s\",\n", (const char*) server->password); - - fprintf(f, "}\n\n"); - } - } - - fclose(f); - } -} - -// +--------------------------------------------------------------------+ - -void -NetClientConfig::CreateConnection() -{ - NetServerInfo* s = GetSelectedServer(); - - if (s) { - NetAddr addr = s->addr; - - if (conn) { - if (conn->GetServerAddr().IPAddr() != addr.IPAddr() || - conn->GetServerAddr().Port() != addr.Port()) { - conn->Logout(); - DropConnection(); - } - } - - if (addr.IPAddr() && addr.Port() && !conn) { - conn = new NetLobbyClient; // (addr); - } - } - - else if (conn) { - conn->Logout(); - DropConnection(); - } -} - -NetLobbyClient* -NetClientConfig::GetConnection() -{ - return conn; -} - -bool -NetClientConfig::Login() -{ - bool result = false; - - if (!conn) - CreateConnection(); - - if (conn) - result = conn->Login(host_request); - - return result; -} - -bool -NetClientConfig::Logout() -{ - bool result = false; - - if (conn) { - result = conn->Logout(); - DropConnection(); - } - - return result; -} - -void -NetClientConfig::DropConnection() -{ - delete conn; - conn = 0; -} diff --git a/Stars45/NetClientConfig.h b/Stars45/NetClientConfig.h deleted file mode 100644 index 13a8bff..0000000 --- a/Stars45/NetClientConfig.h +++ /dev/null @@ -1,72 +0,0 @@ -/* 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 - -*/ - -#ifndef NetClientConfig_h -#define NetClientConfig_h - -#include "Types.h" -#include "Game.h" -#include "Text.h" -#include "List.h" - -#include "NetAddr.h" - -// +--------------------------------------------------------------------+ - -class NetLobbyClient; -class NetServerInfo; - -// +--------------------------------------------------------------------+ - -class NetClientConfig -{ -public: - NetClientConfig(); - ~NetClientConfig(); - - void AddServer(const char* name, - const char* addr, - WORD port, - const char* password, - bool save=false); - void DelServer(int index); - - List& GetServerList() { return servers; } - NetServerInfo* GetServerInfo(int n); - void Download(); - void Load(); - void Save(); - - void SetServerIndex(int n) { server_index = n; } - int GetServerIndex() const { return server_index; } - void SetHostRequest(bool n) { host_request = n; } - bool GetHostRequest() const { return host_request; } - NetServerInfo* GetSelectedServer(); - - void CreateConnection(); - NetLobbyClient* GetConnection(); - bool Login(); - bool Logout(); - void DropConnection(); - - static void Initialize(); - static void Close(); - static NetClientConfig* GetInstance() { return instance; } - -private: - List servers; - int server_index; - bool host_request; - - NetLobbyClient* conn; - - static NetClientConfig* instance; -}; - -#endif // NetClientConfig_h diff --git a/Stars45/NetClientDlg.cpp b/Stars45/NetClientDlg.cpp deleted file mode 100644 index 2a6ce66..0000000 --- a/Stars45/NetClientDlg.cpp +++ /dev/null @@ -1,430 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "NetClientDlg.h" -#include "NetClientConfig.h" -#include "NetLobbyClient.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "Ship.h" -#include "HUDView.h" - -#include "NetAddr.h" - -#include "DataLoader.h" -#include "ContentBundle.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "MachineInfo.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(NetClientDlg, OnSelect); -DEF_MAP_CLIENT(NetClientDlg, OnAdd); -DEF_MAP_CLIENT(NetClientDlg, OnDel); -DEF_MAP_CLIENT(NetClientDlg, OnServer); -DEF_MAP_CLIENT(NetClientDlg, OnHost); -DEF_MAP_CLIENT(NetClientDlg, OnJoin); -DEF_MAP_CLIENT(NetClientDlg, OnCancel); - -// +--------------------------------------------------------------------+ - -NetClientDlg::NetClientDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -server_index(-1), ping_index(0), hnet(0) -{ - config = NetClientConfig::GetInstance(); - Init(def); -} - -NetClientDlg::~NetClientDlg() -{ - StopNetProc(); -} - -void -NetClientDlg::StopNetProc() -{ - if (hnet != 0) { - WaitForSingleObject(hnet, 500); - CloseHandle(hnet); - hnet = 0; - } -} - -// +--------------------------------------------------------------------+ - -void -NetClientDlg::RegisterControls() -{ - btn_add = (Button*) FindControl(101); - btn_del = (Button*) FindControl(102); - lst_servers = (ListBox*) FindControl(200); - lbl_info = FindControl(210); - btn_server = (Button*) FindControl(301); - btn_host = (Button*) FindControl(302); - btn_join = (Button*) FindControl(303); - btn_cancel = (Button*) FindControl(2); - - REGISTER_CLIENT(EID_CLICK, btn_add, NetClientDlg, OnAdd); - REGISTER_CLIENT(EID_CLICK, btn_del, NetClientDlg, OnDel); - REGISTER_CLIENT(EID_SELECT, lst_servers, NetClientDlg, OnSelect); - REGISTER_CLIENT(EID_CLICK, btn_server, NetClientDlg, OnServer); - REGISTER_CLIENT(EID_CLICK, btn_host, NetClientDlg, OnHost); - REGISTER_CLIENT(EID_CLICK, btn_join, NetClientDlg, OnJoin); - REGISTER_CLIENT(EID_CLICK, btn_cancel, NetClientDlg, OnCancel); -} - -// +--------------------------------------------------------------------+ - -void -NetClientDlg::Show() -{ - int selected_index = -1; - - if (!IsShown()) { - FormWindow::Show(); - - // try to retrieve list of active servers from web broker - if (config && lst_servers) { - selected_index = config->GetServerIndex(); - lst_servers->ClearItems(); - config->Download(); - } - } - - if (config && lst_servers) { - if (lst_servers->NumItems() != config->GetServerList().size()) - ShowServers(); - else - UpdateServers(); - - if (selected_index >= 0 && selected_index < lst_servers->NumItems()) { - config->SetServerIndex(selected_index); - lst_servers->SetSelected(selected_index); - OnSelect(0); - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetClientDlg::ExecFrame() -{ - if (!config || !lst_servers) return; - - if (lst_servers->NumItems() != config->GetServerList().size()) - ShowServers(); - else - UpdateServers(); - - NetServerInfo* info = config->GetServerInfo(server_index); - - bool del_enabled = info != 0; - bool join_enabled = info != 0 && info->status > NetServerInfo::OFFLINE; - bool host_enabled = join_enabled && info->hosted == 0; - - if (btn_host) - btn_host->SetEnabled(host_enabled); - - if (btn_join) - btn_join->SetEnabled(join_enabled); - - if (btn_del) - btn_del->SetEnabled(del_enabled); -} - -// +--------------------------------------------------------------------+ - -void -NetClientDlg::ShowServers() -{ - if (!config || !lst_servers) return; - - lst_servers->ClearItems(); - lst_servers->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - lst_servers->SetLeading(2); - - int i = 0; - ListIter iter = config->GetServerList(); - while (++iter) { - NetServerInfo* info = iter.value(); - - lst_servers->AddItemWithData(info->name, (DWORD) i); - lst_servers->SetItemText(i, 1, info->type); - lst_servers->SetItemText(i, 2, info->password); - lst_servers->SetItemText(i, 3, ContentBundle::GetInstance()->GetText("NetClientDlg.offline")); - lst_servers->SetItemText(i, 4, "0"); - lst_servers->SetItemText(i, 5, ContentBundle::GetInstance()->GetText("NetClientDlg.not-avail")); - - i++; - } - - ping_index = 0; - server_index = -1; - - if (btn_host) btn_host->SetEnabled(false); - if (btn_join) btn_join->SetEnabled(false); - if (btn_del) btn_del->SetEnabled(false); -} - -void -NetClientDlg::UpdateServers() -{ - if (!config || !lst_servers || lst_servers->NumItems() < 1) return; - - if (!PingComplete()) - return; - - PingServer(ping_index); - - for (int i = 0; i < lst_servers->NumItems(); i++) { - int n = lst_servers->GetItemData(i); - - NetServerInfo* info = config->GetServerList().at(n); - lst_servers->SetItemText(i, 0, info->name); - - Text status = ContentBundle::GetInstance()->GetText("NetClientDlg.offline"); - - if (info->ping_time > 0 && info->ping_time < 10000) { - char buffer[32]; - sprintf_s(buffer, "%d ms", info->ping_time); //-V576 - lst_servers->SetItemText(i, 5, buffer); - - switch (info->status) { - default: - case NetServerInfo::OFFLINE: status = ContentBundle::GetInstance()->GetText("NetClientDlg.offline"); break; - case NetServerInfo::LOBBY: status = ContentBundle::GetInstance()->GetText("NetClientDlg.lobby"); break; - case NetServerInfo::BRIEFING: status = ContentBundle::GetInstance()->GetText("NetClientDlg.briefing"); break; - case NetServerInfo::ACTIVE: status = ContentBundle::GetInstance()->GetText("NetClientDlg.active"); break; - case NetServerInfo::DEBRIEFING: status = ContentBundle::GetInstance()->GetText("NetClientDlg.debriefing"); break; - case NetServerInfo::PERSISTENT: status = ContentBundle::GetInstance()->GetText("NetClientDlg.persistent"); break; - } - } - else { - lst_servers->SetItemText(i, 5, ContentBundle::GetInstance()->GetText("NetClientDlg.not-avail")); - } - - lst_servers->SetItemText(i, 3, status); - - char num_users[16]; - sprintf_s(num_users, "%d", info->nplayers); - lst_servers->SetItemText(i, 4, num_users); - } -} - -// +--------------------------------------------------------------------+ - -DWORD WINAPI NetClientPingProc(LPVOID link); - -void -NetClientDlg::PingServer(int n) -{ - if (hnet == 0) { - NetClientConfig* config = NetClientConfig::GetInstance(); - if (!config) return; - - NetServerInfo* info = config->GetServerInfo(n); - if (!info) return; - - // copy info from server list - ping_info = *info; - - DWORD thread_id = 0; - hnet = CreateThread(0, 4096, NetClientPingProc, (LPVOID) &ping_info, 0, &thread_id); - - if (hnet == 0) { - static int report = 10; - if (report > 0) { - ::Print("WARNING: NetClientDlg() failed to create PING thread for server '%s' (err=%08x)\n", info->name.data(), GetLastError()); - report--; - - if (report == 0) - ::Print(" Further warnings of this type will be supressed.\n"); - } - } - } -} - -bool -NetClientDlg::PingComplete() -{ - if (hnet != 0) { - DWORD result = 0; - GetExitCodeThread(hnet, &result); - - if (result != STILL_ACTIVE) { - CloseHandle(hnet); - hnet = 0; - - NetClientConfig* config = NetClientConfig::GetInstance(); - if (config) { - NetServerInfo* info = config->GetServerInfo(ping_index); - if (info) { - // copy result back into server list - info->machine_info = ping_info.machine_info; - info->gameport = ping_info.gameport; - info->status = ping_info.status; - info->nplayers = ping_info.nplayers; - info->hosted = ping_info.hosted; - info->ping_time = ping_info.ping_time; - } - } - - if (lst_servers && ping_index >= lst_servers->NumItems()-1) - ping_index = 0; - else - ping_index++; - } - } - - return !hnet; -} - -// +--------------------------------------------------------------------+ - -DWORD WINAPI NetClientPingProc(LPVOID link) -{ - NetServerInfo* info = (NetServerInfo*) link; - if (!info) { - Print("NetClientPingProc() no link\n"); - Sleep(200); - return 1; - } - - NetAddr addr = info->addr; - if (!addr.IPAddr()) { - Sleep(200); - return 1; - } - - NetLobbyClient conn(addr); - - if (conn.Ping()) { - info->machine_info = conn.GetMachineInfo(); - info->gameport = conn.GetGamePort(); - info->status = conn.GetStatus(); - info->nplayers = conn.NumUsers(); - info->hosted = conn.HasHost(); - info->ping_time = conn.GetLag(); - } - - else { - info->machine_info = Text(); - info->nplayers = 0; - info->hosted = 0; - info->status = NetServerInfo::OFFLINE; - info->ping_time = 0; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -NetClientDlg::OnAdd(AWEvent* event) -{ - manager->ShowNetAddrDlg(); -} - -void -NetClientDlg::OnDel(AWEvent* event) -{ - if (config && server_index >= 0) - config->DelServer(server_index); -} - -void -NetClientDlg::OnSelect(AWEvent* event) -{ - if (lst_servers) { - server_index = lst_servers->GetSelection(); - NetServerInfo* info = config->GetServerInfo(server_index); - - if (lbl_info) { - if (info) - lbl_info->SetText(info->machine_info); - else - lbl_info->SetText(""); - } - - if (btn_host) { - btn_host->SetEnabled(info && info->status > NetServerInfo::OFFLINE && info->hosted == 0); - } - - if (btn_join) { - btn_join->SetEnabled(info && info->status > NetServerInfo::OFFLINE); - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetClientDlg::OnServer(AWEvent* event) -{ - manager->ShowNetServerDlg(); -} - -void -NetClientDlg::OnHost(AWEvent* event) -{ - if (config) { - config->SetServerIndex(server_index); - config->SetHostRequest(true); - config->Save(); - - NetServerInfo* info = config->GetServerInfo(server_index); - if (info && info->password == "Yes") { - manager->ShowNetPassDlg(); - } - else { - manager->ShowNetLobbyDlg(); - } - } -} - -void -NetClientDlg::OnJoin(AWEvent* event) -{ - if (config) { - config->SetServerIndex(server_index); - config->SetHostRequest(false); - config->Save(); - - NetServerInfo* info = config->GetServerInfo(server_index); - if (info && info->password == "Yes") { - manager->ShowNetPassDlg(); - } - else { - manager->ShowNetLobbyDlg(); - } - } -} - -void -NetClientDlg::OnCancel(AWEvent* event) -{ - if (config) { - config->Save(); - config->SetServerIndex(-1); - } - - manager->ShowMenuDlg(); -} diff --git a/Stars45/NetClientDlg.h b/Stars45/NetClientDlg.h deleted file mode 100644 index 3506e9c..0000000 --- a/Stars45/NetClientDlg.h +++ /dev/null @@ -1,79 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef NetClientDlg_h -#define NetClientDlg_h - -#include "Types.h" -#include "NetClientConfig.h" -#include "NetLobby.h" - -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; - -// +--------------------------------------------------------------------+ - -class NetClientDlg : public FormWindow -{ -public: - NetClientDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~NetClientDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnSelect(AWEvent* event); - virtual void OnAdd(AWEvent* event); - virtual void OnDel(AWEvent* event); - virtual void OnServer(AWEvent* event); - virtual void OnHost(AWEvent* event); - virtual void OnJoin(AWEvent* event); - virtual void OnCancel(AWEvent* event); - - virtual void ShowServers(); - virtual void UpdateServers(); - virtual void PingServer(int n); - virtual bool PingComplete(); - virtual void StopNetProc(); - -protected: - MenuScreen* manager; - NetClientConfig* config; - - Button* btn_add; - Button* btn_del; - ListBox* lst_servers; - ActiveWindow* lbl_info; - int server_index; - int ping_index; - HANDLE hnet; - NetServerInfo ping_info; - - Button* btn_server; - Button* btn_host; - Button* btn_join; - Button* btn_cancel; -}; - -#endif // NetClientDlg_h - diff --git a/Stars45/NetData.cpp b/Stars45/NetData.cpp deleted file mode 100644 index 4d625b9..0000000 --- a/Stars45/NetData.cpp +++ /dev/null @@ -1,1451 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Payload structures for multiplayer network packets -*/ - -#include "NetData.h" -#include "NetLink.h" -#include "NetMsg.h" -#include "RadioMessage.h" -#include "Ship.h" -#include "Shot.h" -#include "Sim.h" -#include "Instruction.h" -#include "Weapon.h" -#include "Element.h" -#include "System.h" -#include "Power.h" -#include "Shield.h" - -#include "Game.h" - -// +--------------------------------------------------------------------+ -// DATA SIZE OFFSET -// -------- ----------------- --------- -// type: 1 0 -// size: 1 1 -// objid: 2 2 -// loc: 9 (3 x 24 bits) 4 -// vel: 6 (3 x 16 bits) 13 -// euler: 4 (3 x 10 bits) 19 -// status: 1 23 - -const int LOCATION_OFFSET = 8000000; -const int VELOCITY_OFFSET = 32000; -const double EULER_SCALE = 2*PI / (1<<10); - -BYTE* -NetObjLoc::Pack() -{ - data[ 0] = TYPE; - data[ 1] = SIZE; - - // obj id - data[ 2] = (BYTE) ((objid & 0xff00) >> 8); - data[ 3] = (BYTE) ((objid & 0x00ff) ); - - // location - DWORD x = (DWORD) (((int) location.x + LOCATION_OFFSET) & 0x00ffffff); - DWORD y = (DWORD) (((int) location.y + LOCATION_OFFSET) & 0x00ffffff); - DWORD z = (DWORD) (((int) location.z + LOCATION_OFFSET) & 0x00ffffff); - - data[ 4] = (BYTE) ((x & 0x00ff0000) >> 16); - data[ 5] = (BYTE) ((x & 0x0000ff00) >> 8); - data[ 6] = (BYTE) ((x & 0x000000ff) ); - - data[ 7] = (BYTE) ((y & 0x00ff0000) >> 16); - data[ 8] = (BYTE) ((y & 0x0000ff00) >> 8); - data[ 9] = (BYTE) ((y & 0x000000ff) ); - - data[10] = (BYTE) ((z & 0x00ff0000) >> 16); - data[11] = (BYTE) ((z & 0x0000ff00) >> 8); - data[12] = (BYTE) ((z & 0x000000ff) ); - - // velocity - WORD vx = (WORD) (((int) velocity.x + VELOCITY_OFFSET) & 0x0000ffff); - WORD vy = (WORD) (((int) velocity.y + VELOCITY_OFFSET) & 0x0000ffff); - WORD vz = (WORD) (((int) velocity.z + VELOCITY_OFFSET) & 0x0000ffff); - - data[13] = (BYTE) ((vx & 0xff00) >> 8); - data[14] = (BYTE) ((vx & 0x00ff)); - - data[15] = (BYTE) ((vy & 0xff00) >> 8); - data[16] = (BYTE) ((vy & 0x00ff)); - - data[17] = (BYTE) ((vz & 0xff00) >> 8); - data[18] = (BYTE) ((vz & 0x00ff)); - - // orientation - if (_finite(euler.x)) { - while (euler.x < 0) euler.x += 2*PI; - while (euler.x > 2*PI) euler.x -= 2*PI; - } - else { - euler.x = 0; - } - - if (_finite(euler.y)) { - while (euler.y < 0) euler.y += 2*PI; - while (euler.y > 2*PI) euler.y -= 2*PI; - } - else { - euler.y = 0; - } - - if (_finite(euler.z)) { - while (euler.z < 0) euler.z += 2*PI; - while (euler.z > 2*PI) euler.z -= 2*PI; - } - else { - euler.z = 0; - } - - WORD ox = (WORD) (((int) (euler.x / EULER_SCALE)) & 0x000003ff); - WORD oy = (WORD) (((int) (euler.y / EULER_SCALE)) & 0x000003ff); - WORD oz = (WORD) (((int) (euler.z / EULER_SCALE)) & 0x000003ff); - - DWORD o = (ox << 20) | (oy << 10) | (oz); - - data[19] = (BYTE) ((o & 0xff000000) >> 24); - data[20] = (BYTE) ((o & 0x00ff0000) >> 16); - data[21] = (BYTE) ((o & 0x0000ff00) >> 8); - data[22] = (BYTE) ((o & 0x000000ff) ); - - // status bits - data[23] = throttle << 7 | - augmenter << 6 | - gear << 5 | - (shield >> 2) & 0x1f; - - return data; -} - -bool -NetObjLoc::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[ 2] << 8) | - (data[ 3] ); - - int x = (data[ 4] << 16) | - (data[ 5] << 8) | - (data[ 6] ); - - int y = (data[ 7] << 16) | - (data[ 8] << 8) | - (data[ 9] ); - - int z = (data[10] << 16) | - (data[11] << 8) | - (data[12] ); - - int vx = (data[13] << 8) | - (data[14] ); - - int vy = (data[15] << 8) | - (data[16] ); - - int vz = (data[17] << 8) | - (data[18] ); - - DWORD o = (data[19] << 24) | - (data[20] << 16) | - (data[21] << 8) | - (data[22] ); - - WORD ox = (WORD) ((o >> 20) & 0x03ff); - WORD oy = (WORD) ((o >> 10) & 0x03ff); - WORD oz = (WORD) ((o ) & 0x03ff); - - throttle = data[23] & 0x80 ? true : false; - augmenter = data[23] & 0x40 ? true : false; - gear = data[23] & 0x20 ? true : false; - shield = (data[23] & 0x1f) << 2; - - location = Point(x -LOCATION_OFFSET, y -LOCATION_OFFSET, z -LOCATION_OFFSET); - velocity = Point(vx-VELOCITY_OFFSET, vy-VELOCITY_OFFSET, vz-VELOCITY_OFFSET); - euler = Point(ox*EULER_SCALE, oy*EULER_SCALE, oz*EULER_SCALE); - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetJoinRequest::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - for (int i = 0; i < name.length() && i < 16; i++) - data[2+i] = name[i]; - - for (int i = 0; i < pass.length() && i < 16; i++) - data[18+i] = pass[i]; - - for (int i = 0; i < elem.length() && i < 31; i++) - data[34+i] = elem[i]; - - data[65] = (BYTE) index; - - for (int i = 0; i < serno.length() && i < 60; i++) - data[66+i] = serno[i]; - - return data; -} - -bool -NetJoinRequest::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - char buf[64]; - - CopyMemory(buf, data+2, 16); - buf[16] = 0; - name = buf; - - CopyMemory(buf, data+18, 16); - buf[16] = 0; - pass = buf; - - CopyMemory(buf, data+34, 31); - buf[31] = 0; - elem = buf; - - index = data[65]; - - CopyMemory(buf, data+66, 60); - buf[61] = 0; - serno = buf; - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -NetJoinAnnounce::NetJoinAnnounce() -: index(0), integrity(0), respawns(0), decoys(0), probes(0), fuel(0), -shield(0), nid(0) -{ - ZeroMemory(ammo, sizeof(ammo)); -} - -void -NetJoinAnnounce::SetAmmo(const int* a) -{ - if (a) { - CopyMemory(ammo, a, sizeof(ammo)); - } -} - -void -NetJoinAnnounce::SetShip(Ship* s) -{ - SetName(s->Name()); - SetObjID(s->GetObjID()); - - if (s->GetElement()) { - SetElement(s->GetElement()->Name()); - SetIndex(s->GetElementIndex()); - } - - if (s->GetRegion()) - SetRegion(s->GetRegion()->Name()); - - SetLocation(s->Location()); - SetVelocity(s->Velocity()); - SetIntegrity(s->Integrity()); - SetRespawns(s->RespawnCount()); - - if (s->GetDecoy()) - SetDecoys(s->GetDecoy()->Ammo()); - - if (s->GetProbeLauncher()) - SetProbes(s->GetProbeLauncher()->Ammo()); - - if (s->Reactors().size()) - SetFuel(s->Reactors()[0]->Charge()); - - Shield* shield = s->GetShield(); - if (shield) - SetShield((int) shield->GetPowerLevel()); -} - -BYTE* -NetJoinAnnounce::Pack() -{ - ZeroMemory(data, SIZE); - - data[ 0] = TYPE; - data[ 1] = SIZE; - data[ 2] = (BYTE) ((objid & 0xff00) >> 8); - data[ 3] = (BYTE) ((objid & 0x00ff) ); - - float* f = (float*) (data + 4); - *f++ = (float) loc.x; // bytes 4 - 7 - *f++ = (float) loc.y; // bytes 8 - 11 - *f++ = (float) loc.z; // bytes 12 - 15 - *f++ = (float) integrity; // bytes 16 - 19 - - for (int i = 0; i < name.length() && i < 16; i++) - data[20+i] = name[i]; - - for (int i = 0; i < elem.length() && i < 32; i++) - data[36+i] = elem[i]; - - for (int i = 0; i < region.length() && i < 32; i++) - data[68+i] = region[i]; - - int* p = (int*) (data + 100); - *p++ = respawns; // bytes 100 - 103 - *p++ = decoys; // bytes 104 - 107 - *p++ = probes; // bytes 108 - 111 - - data[112]= (BYTE) fuel; // byte 112 - data[113]= (BYTE) shield; // byte 113 - - BYTE* a = data + 116; - for (int i = 0; i < 16; i++) { // bytes 116 - 179 - if (ammo[i] >= 0) { - *a++ = ammo[i]; - } - else { - *a++ = 255; - } - } - - data[180] = (BYTE) index; - - f = (float*) (data + 184); - *f++ = (float) velocity.x; - *f++ = (float) velocity.y; - *f++ = (float) velocity.z; - - return data; -} - -bool -NetJoinAnnounce::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - - float* f = (float*) (data + 4); - loc.x = *f++; - loc.y = *f++; - loc.z = *f++; - integrity = *f++; - - char buf[64]; - CopyMemory(buf, data+20, 16); - buf[16] = 0; - name = buf; - - CopyMemory(buf, data+36, 32); - buf[16] = 0; - elem = buf; - - CopyMemory(buf, data+68, 32); - buf[16] = 0; - region = buf; - - int* p = (int*) (data + 100); - respawns = *p++; - decoys = *p++; - probes = *p++; - - fuel = data[112]; - shield = data[113]; - - CopyMemory(ammo, data+116, 16); - - index = data[180]; - - f = (float*) (data + 184); - velocity.x = *f++; - velocity.y = *f++; - velocity.z = *f++; - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetQuitAnnounce::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - data[4] = (BYTE) (disconnected); - - return data; -} - -bool -NetQuitAnnounce::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - disconnected = data[4] ? true : false; - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetDisconnect::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - return data; -} - -bool -NetDisconnect::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetObjDamage::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - data[4] = (BYTE) ((shotid & 0xff00) >> 8); - data[5] = (BYTE) ((shotid & 0x00ff) ); - - float* p = (float*) (data + 6); - *p = damage; - - return data; -} - -bool -NetObjDamage::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - shotid = (data[4] << 8) | data[5]; - damage = *(float*) (data + 6); - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetSysDamage::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - - float* p = (float*) (data + 4); - *p = (float) damage; - - data[8] = (BYTE) (sysix+1); - data[9] = dmgtype; - - return data; -} - -bool -NetSysDamage::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - damage = *(float*) (data + 4); - sysix = data[8]; - dmgtype = data[9]; - - sysix--; - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetSysStatus::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - data[4] = (BYTE) (sysix+1); - data[5] = (BYTE) (status); - data[6] = (BYTE) (power); - data[7] = (BYTE) (reactor); - - float* f = (float*) (data + 8); - *f = (float) avail; - - return data; -} - -bool -NetSysStatus::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - sysix = data[4]; - status = data[5]; - power = data[6]; - reactor = data[7]; - - float* f = (float*) (data + 8); - avail = *f; - - sysix--; - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetObjKill::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - data[4] = (BYTE) ((kill_id & 0xff00) >> 8); - data[5] = (BYTE) ((kill_id & 0x00ff) ); - data[6] = (BYTE) killtype; - data[7] = (BYTE) respawn; - - float* f = (float*) (data + 8); - *f++ = (float) loc.x; - *f++ = (float) loc.y; - *f++ = (float) loc.z; - - data[20] = (BYTE) deck; - - return data; -} - -bool -NetObjKill::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - kill_id = (data[4] << 8) | data[5]; - killtype = data[6]; - respawn = data[7] ? true : false; - - float* f = (float*) (data + 8); - loc.x = *f++; - loc.y = *f++; - loc.z = *f++; - - deck = data[20]; - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetObjHyper::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - data[4] = (BYTE) ((fc_src & 0xff00) >> 8); - data[5] = (BYTE) ((fc_src & 0x00ff) ); - data[6] = (BYTE) ((fc_dst & 0xff00) >> 8); - data[7] = (BYTE) ((fc_dst & 0x00ff) ); - data[8] = (BYTE) transtype; - - float* f = (float*) (data + 12); - *f++ = (float) location.x; // bytes 12 - 15 - *f++ = (float) location.y; // bytes 16 - 19 - *f++ = (float) location.z; // bytes 20 - 23 - - char* p = (char*) (data + 24); - strncpy(p, region.data(), 31); - - return data; -} - -bool -NetObjHyper::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - fc_src = (data[4] << 8) | data[5]; - fc_dst = (data[6] << 8) | data[7]; - transtype = data[8]; - - float* f = (float*) (data + 12); - location.x = *f++; - location.y = *f++; - location.z = *f++; - - region = (char*) (data + 24); - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetObjTarget::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - data[4] = (BYTE) ((tgtid & 0xff00) >> 8); - data[5] = (BYTE) ((tgtid & 0x00ff) ); - data[6] = (BYTE) (sysix+1); - - return data; -} - -bool -NetObjTarget::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - tgtid = (data[4] << 8) | data[5]; - sysix = data[6]; - - sysix--; - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetObjEmcon::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - data[4] = (BYTE) (emcon); - - return data; -} - -bool -NetObjEmcon::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - emcon = data[4]; - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetWepTrigger::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - data[4] = (BYTE) ((tgtid & 0xff00) >> 8); - data[5] = (BYTE) ((tgtid & 0x00ff) ); - data[6] = (BYTE) (sysix+1); - data[7] = (BYTE) index; - data[8] = (BYTE) count; - data[9] = ((BYTE) decoy << 1) | - ((BYTE) probe ); - - return data; -} - -bool -NetWepTrigger::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - tgtid = (data[4] << 8) | data[5]; - sysix = data[6]; - index = data[7]; - count = data[8]; - decoy = (data[9] & 0x02) ? true : false; - probe = (data[9] & 0x01) ? true : false; - - sysix--; - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetWepRelease::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - data[4] = (BYTE) ((tgtid & 0xff00) >> 8); - data[5] = (BYTE) ((tgtid & 0x00ff) ); - data[6] = (BYTE) ((wepid & 0xff00) >> 8); - data[7] = (BYTE) ((wepid & 0x00ff) ); - data[8] = (BYTE) (sysix+1); - data[9] = (BYTE) index; - data[10] = ((BYTE) decoy << 1) | - ((BYTE) probe ); - - return data; -} - -bool -NetWepRelease::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - tgtid = (data[4] << 8) | data[5]; - wepid = (data[6] << 8) | data[7]; - sysix = data[8]; - index = data[9]; - decoy = (data[10] & 0x02) ? true : false; - probe = (data[10] & 0x01) ? true : false; - - sysix--; - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetWepDestroy::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - - return data; -} - -bool -NetWepDestroy::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - objid = (data[2] << 8) | data[3]; - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -NetCommMsg::~NetCommMsg() -{ - delete radio_message; -} - -void -NetCommMsg::SetRadioMessage(RadioMessage* m) -{ - radio_message = new RadioMessage(*m); -} - -BYTE* -NetCommMsg::Pack() -{ - ZeroMemory(data, SIZE); - - if (radio_message) { - length = 55 + radio_message->Info().length(); - - if (length > SIZE) - length = SIZE; - - data[0] = TYPE; - data[1] = (BYTE) length; - - if (radio_message->Sender()) { - objid = radio_message->Sender()->GetObjID(); - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - } - - if (radio_message->DestinationShip()) { - DWORD dstid = radio_message->DestinationShip()->GetObjID(); - data[4] = (BYTE) ((dstid & 0xff00) >> 8); - data[5] = (BYTE) ((dstid & 0x00ff) ); - } - - data[6] = (BYTE) radio_message->Action(); - data[7] = (BYTE) radio_message->Channel(); - - if (radio_message->TargetList().size() > 0) { - SimObject* tgt = radio_message->TargetList().at(0); - DWORD tgtid = tgt->GetObjID(); - data[8] = (BYTE) ((tgtid & 0xff00) >> 8); - data[9] = (BYTE) ((tgtid & 0x00ff) ); - } - - float* f = (float*) (data + 10); - *f++ = (float) radio_message->Location().x; // bytes 10 - 13 - *f++ = (float) radio_message->Location().y; // bytes 14 - 17 - *f++ = (float) radio_message->Location().z; // bytes 18 - 21 - - char* p = (char*) (data + 22); - - Element* dst_elem = radio_message->DestinationElem(); - if (dst_elem) - strncpy(p, dst_elem->Name().data(), 31); - - p = (char*) (data + 55); - strncpy(p, radio_message->Info().data(), 128); - - data[SIZE-1] = 0; - } - - return data; -} - -bool -NetCommMsg::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE) { - length = p[1]; - ZeroMemory(data, SIZE); - CopyMemory(data, p, length); - - DWORD dstid = 0; - DWORD tgtid = 0; - int action = 0; - int channel = 0; - Point loc; - Text elem_name; - Text info; - - objid = (data[2] << 8) | data[3]; - dstid = (data[4] << 8) | data[5]; - tgtid = (data[8] << 8) | data[9]; - action = data[6]; - channel = data[7]; - - float* f = (float*) (data + 10); - loc.x = *f++; - loc.y = *f++; - loc.z = *f++; - - elem_name = (char*) (data + 22); - - if (length > 55) - info = (char*) (data + 55); - - Sim* sim = Sim::GetSim(); - Ship* src = sim->FindShipByObjID(objid); - Ship* dst = sim->FindShipByObjID(dstid); - Element* elem = sim->FindElement(elem_name); - - delete radio_message; - if (elem) - radio_message = new RadioMessage(elem, src, action); - else - radio_message = new RadioMessage(dst, src, action); - - radio_message->SetChannel(channel); - radio_message->SetLocation(loc); - radio_message->SetInfo(info); - - if (tgtid) { - SimObject* tgt = sim->FindShipByObjID(tgtid); - - if (!tgt) - tgt = sim->FindShotByObjID(tgtid); - - if (tgt) - radio_message->AddTarget(tgt); - } - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetChatMsg::Pack() -{ - ZeroMemory(data, SIZE); - - int chatlen = text.length(); - - if (chatlen > MAX_CHAT) - chatlen = MAX_CHAT; - - length = HDR_LEN + NAME_LEN + chatlen; - - data[0] = TYPE; - data[1] = (BYTE) length; - data[2] = (BYTE) ((dstid & 0xff00) >> 8); - data[3] = (BYTE) ((dstid & 0x00ff) ); - - char* p = (char*) (data + HDR_LEN); - strncpy(p, name.data(), NAME_LEN); - - p = (char*) (data + HDR_LEN + NAME_LEN); - strncpy(p, text.data(), chatlen); - - return data; -} - -bool -NetChatMsg::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE) { - length = p[1]; - ZeroMemory(data, SIZE); - CopyMemory(data, p, length); - - dstid = (data[2] << 8) | data[3]; - - char buffer[NAME_LEN+1]; - ZeroMemory(buffer, NAME_LEN+1); - CopyMemory(buffer, data + HDR_LEN, NAME_LEN); - - name = buffer; - - if (length > HDR_LEN + NAME_LEN) - text = (char*) (data + HDR_LEN + NAME_LEN); - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -NetElemRequest::NetElemRequest() -{ } - -BYTE* -NetElemRequest::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - strncpy((char*) (data + 8), name.data(), NAME_LEN-1); - - return data; -} - -bool -NetElemRequest::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE) { - ZeroMemory(data, SIZE); - CopyMemory(data, p, SIZE); - - name = (const char*) (data + 8); - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -NetElemCreate::NetElemCreate() -: iff(0), type(0), intel(0), alert(false), in_flight(false) -{ - for (int i = 0; i < 16; i++) - load[i] = -1; -} - -void -NetElemCreate::SetLoadout(int* l) -{ - if (l) { - CopyMemory(load, l, sizeof(load)); - } - else { - for (int i = 0; i < 16; i++) - load[i] = -1; - } -} - -void -NetElemCreate::SetSlots(int* s) -{ - if (s) { - CopyMemory(slots, s, sizeof(slots)); - } - else { - for (int i = 0; i < 4; i++) - slots[i] = -1; - } -} - -BYTE* -NetElemCreate::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) iff; - data[3] = (BYTE) type; - data[4] = (BYTE) intel; - data[5] = (BYTE) obj_code; - - for (int i = 0; i < 16; i++) - data[6+i] = (BYTE) load[i]; - - strncpy((char*) (data + 22), name.data(), NAME_LEN-1); - strncpy((char*) (data + 54), commander.data(), NAME_LEN-1); - strncpy((char*) (data + 86), objective.data(), NAME_LEN-1); - strncpy((char*) (data + 118), carrier.data(), NAME_LEN-1); - - data[150] = (BYTE) squadron; - data[151] = (BYTE) slots[0]; - data[152] = (BYTE) slots[1]; - data[153] = (BYTE) slots[2]; - data[154] = (BYTE) slots[3]; - data[155] = (BYTE) alert; - data[156] = (BYTE) in_flight; - - return data; -} - -bool -NetElemCreate::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE) { - ZeroMemory(data, SIZE); - CopyMemory(data, p, SIZE); - - iff = data[2]; - type = data[3]; - intel = data[4]; - obj_code = data[5]; - - for (int i = 0; i < 16; i++) { - load[i] = data[6+i] == 255 ? -1 : data[6+i]; - } - - name = (const char*) (data + 22); - commander = (const char*) (data + 54); - objective = (const char*) (data + 86); - carrier = (const char*) (data + 118); - - squadron = data[150]; - - for (int i = 0; i < 4; i++) { - slots[i] = data[151+i]; - if (slots[i] >= 255) - slots[i] = -1; - } - - alert = data[155] ? true : false; - in_flight = data[156] ? true : false; - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetShipLaunch::Pack() -{ - ZeroMemory(data, SIZE); - - data[ 0] = TYPE; - data[ 1] = SIZE; - - DWORD* p = (DWORD*) (data + 4); - *p++ = (DWORD) objid; - *p++ = (DWORD) squadron; - *p++ = (DWORD) slot; - - return data; -} - -bool -NetShipLaunch::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE) { - ZeroMemory(data, SIZE); - CopyMemory(data, p, SIZE); - - DWORD* p = (DWORD*) (data + 4); - objid = *p++; - squadron = (int) *p++; - slot = (int) *p++; - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -NetNavData::NetNavData() -: objid(0), create(true), index(0), navpoint(0) -{ -} - -NetNavData::~NetNavData() -{ - delete navpoint; -} - -void -NetNavData::SetNavPoint(Instruction* n) -{ - if (navpoint) { - delete navpoint; - navpoint = 0; - } - - if (n) - navpoint = new Instruction(*n); -} - -BYTE* -NetNavData::Pack() -{ - ZeroMemory(data, SIZE); - - data[ 0] = TYPE; - data[ 1] = SIZE; - - data[ 2] = (BYTE) ((objid & 0xff00) >> 8); - data[ 3] = (BYTE) ((objid & 0x00ff) ); - data[ 4] = (BYTE) create; - data[ 5] = (BYTE) index; - - if (!navpoint) - return data; - - data[ 6] = (BYTE) navpoint->Action(); - data[ 7] = (BYTE) navpoint->Formation(); - data[ 8] = (BYTE) navpoint->Status(); - data[ 9] = (BYTE) navpoint->EMCON(); - data[10] = (BYTE) navpoint->WeaponsFree(); - data[11] = (BYTE) navpoint->Farcast(); - - Point loc = navpoint->Location(); - - float* f = (float*) (data + 12); - *f++ = (float) loc.x; // bytes 12 - 15 - *f++ = (float) loc.y; // bytes 16 - 19 - *f++ = (float) loc.z; // bytes 20 - 23 - *f++ = (float) navpoint->HoldTime(); // bytes 24 - 27 - *f++ = (float) navpoint->Speed(); // bytes 28 - 31 - - WORD tgtid = 0; - if (navpoint->GetTarget()) - tgtid = (WORD) navpoint->GetTarget()->GetObjID(); - - data[32] = (BYTE) ((tgtid & 0xff00) >> 8); - data[33] = (BYTE) ((tgtid & 0x00ff) ); - - strncpy((char*) (data + 34), navpoint->RegionName(), NAME_LEN-1); - strncpy((char*) (data + 66), navpoint->TargetName(), NAME_LEN-1); - strncpy((char*) (data + 98), elem.data(), NAME_LEN-1); - - return data; -} - -bool -NetNavData::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE) { - ZeroMemory(data, SIZE); - CopyMemory(data, p, SIZE); - - int action; - int formation; - int status; - int emcon; - int wep_free; - int farcast; - int speed; - float hold_time; - Point loc; - WORD tgtid = 0; - - const char* rgn_name = 0; - const char* tgt_name = 0; - - objid = (data[ 2] << 8) | - (data[ 3] ); - - tgtid = (data[32] << 8) | - (data[33] ); - - create = data[ 4] ? true : false; - index = data[ 5]; - action = data[ 6]; - formation = data[ 7]; - status = data[ 8]; - emcon = data[ 9]; - wep_free = data[10]; - farcast = data[11]; - - float* f = (float*) (data + 12); - loc.x = *f++; - loc.y = *f++; - loc.z = *f++; - hold_time = *f++; - speed = (int) *f++; - - rgn_name = (const char*) (data + 34); - tgt_name = (const char*) (data + 66); - elem = (const char*) (data + 98); - - if (navpoint) { - delete navpoint; - navpoint = 0; - } - - Sim* sim = Sim::GetSim(); - SimRegion* rgn = 0; - - if (sim) - rgn = sim->FindRegion(rgn_name); - - if (rgn) - navpoint = new Instruction(rgn, loc, action); - else - navpoint = new Instruction(rgn_name, loc, action); - - navpoint->SetFormation(formation); - navpoint->SetStatus(status); - navpoint->SetEMCON(emcon); - navpoint->SetWeaponsFree(wep_free); - navpoint->SetFarcast(farcast); - navpoint->SetHoldTime(hold_time); - navpoint->SetSpeed(speed); - navpoint->SetTarget(tgt_name); - - if (tgtid) { - Sim* sim = Sim::GetSim(); - Ship* tgt = sim->FindShipByObjID(tgtid); - - if (tgt) - navpoint->SetTarget(tgt); - } - - if (index >= 255) - index = -1; - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetNavDelete::Pack() -{ - ZeroMemory(data, SIZE); - - data[ 0] = TYPE; - data[ 1] = SIZE; - - data[ 2] = (BYTE) ((objid & 0xff00) >> 8); - data[ 3] = (BYTE) ((objid & 0x00ff) ); - data[ 4] = (BYTE) index; - - strncpy((char*) (data + 6), elem.data(), 31); - - return data; -} - -bool -NetNavDelete::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE) { - ZeroMemory(data, SIZE); - CopyMemory(data, p, SIZE); - int index = 0; - - objid = (data[ 2] << 8) | - (data[ 3] ); - - index = data[4]; - elem = (const char*) (data + 6); - - if (index >= 255) - index = -1; - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -BYTE* -NetSelfDestruct::Pack() -{ - ZeroMemory(data, SIZE); - - data[0] = TYPE; - data[1] = SIZE; - - data[2] = (BYTE) ((objid & 0xff00) >> 8); - data[3] = (BYTE) ((objid & 0x00ff) ); - - float* p = (float*) (data + 4); - *p = damage; - - return data; -} - -bool -NetSelfDestruct::Unpack(const BYTE* p) -{ - if (p && p[0] == TYPE && p[1] == SIZE) { - CopyMemory(data, p, SIZE); - - objid = (data[2] << 8) | data[3]; - damage = *(float*) (data + 4); - - return true; - } - - return false; -} diff --git a/Stars45/NetData.h b/Stars45/NetData.h deleted file mode 100644 index ebb7fd0..0000000 --- a/Stars45/NetData.h +++ /dev/null @@ -1,965 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Payload structures for multiplayer network packets -*/ - -#ifndef NetData_h -#define NetData_h - -#include "Types.h" -#include "Geometry.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -// UNRELIABLE: 0x01 - 0x0F - -const BYTE NET_PING = 0x01; -const BYTE NET_PONG = 0x02; -const BYTE NET_OBJ_LOC = 0x03; - -// RELIABLE: 0x10 - 0x7F - -const BYTE NET_JOIN_REQUEST = 0x10; -const BYTE NET_JOIN_ANNOUNCE = 0x11; -const BYTE NET_QUIT_REQUEST = 0x12; -const BYTE NET_QUIT_ANNOUNCE = 0x13; -const BYTE NET_KICK_REQUEST = 0x14; -const BYTE NET_KICK_ANNOUNCE = 0x15; -const BYTE NET_GAME_OVER = 0x16; -const BYTE NET_COMM_MESSAGE = 0x17; -const BYTE NET_CHAT_MESSAGE = 0x18; -const BYTE NET_DISCONNECT = 0x19; - -const BYTE NET_OBJ_DAMAGE = 0x20; -const BYTE NET_OBJ_KILL = 0x21; -const BYTE NET_OBJ_SPAWN = 0x22; -const BYTE NET_OBJ_HYPER = 0x23; -const BYTE NET_OBJ_TARGET = 0x24; -const BYTE NET_OBJ_EMCON = 0x25; -const BYTE NET_SYS_DAMAGE = 0x26; -const BYTE NET_SYS_STATUS = 0x27; - -const BYTE NET_ELEM_CREATE = 0x28; -const BYTE NET_SHIP_LAUNCH = 0x29; -const BYTE NET_NAV_DATA = 0x2A; -const BYTE NET_NAV_DELETE = 0x2B; -const BYTE NET_ELEM_REQUEST = 0x2C; - -const BYTE NET_WEP_TRIGGER = 0x30; -const BYTE NET_WEP_RELEASE = 0x31; -const BYTE NET_WEP_DESTROY = 0x32; - -const BYTE NET_SELF_DESTRUCT = 0x3F; - -// +--------------------------------------------------------------------+ - -class Ship; - -// +--------------------------------------------------------------------+ - -class NetData -{ -public: - static const char* TYPENAME() { return "NetData"; } - - NetData() { } - virtual ~NetData() { } - - virtual int Type() const { return 0; } - virtual int Length() const { return 0; } - virtual BYTE* Pack() { return 0; } - virtual bool Unpack(const BYTE* data) { return 0; } - - virtual DWORD GetObjID() const { return 0; } - virtual void SetObjID(DWORD o) { } -}; - -// +--------------------------------------------------------------------+ - -class NetObjLoc : public NetData -{ -public: - static const char* TYPENAME() { return "NetObjLoc"; } - - NetObjLoc() : objid(0), throttle(false), augmenter(false), shield(0) { } - NetObjLoc(DWORD oid, const Point& pos, const Point& orient, const Point& vel) : - objid(oid), location(pos), euler(orient), velocity(vel), - throttle(false), augmenter(false), gear(false), shield(0) { } - - enum { TYPE=NET_OBJ_LOC, SIZE=24 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD id) { objid = id; } - - Point GetLocation() const { return location; } - Point GetVelocity() const { return velocity; } - Point GetOrientation() const { return euler; } - bool GetThrottle() const { return throttle; } - bool GetAugmenter() const { return augmenter; } - bool GetGearDown() const { return gear; } - int GetShield() const { return shield; } - - void SetLocation(const Point& loc) { location = loc; } - void SetVelocity(const Point& v) { velocity = v; } - void SetOrientation(const Point& o) { euler = o; } - void SetThrottle(bool t) { throttle = t; } - void SetAugmenter(bool a) { augmenter = a; } - void SetGearDown(bool g) { gear = g; } - void SetShield(int s) { shield = s; } - -private: - DWORD objid; - Point location; - Point velocity; - Point euler; - bool throttle; - bool augmenter; - bool gear; - int shield; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetJoinRequest : public NetData -{ -public: - static const char* TYPENAME() { return "NetJoinRequest"; } - - NetJoinRequest() : index(0) { } - - enum { TYPE=NET_JOIN_REQUEST, SIZE=128 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - const char* GetName() const { return name; } - const char* GetPassword() const { return pass; } - const char* GetSerialNumber() const { return serno; } - const char* GetElement() const { return elem; } - int GetIndex() const { return index; } - - void SetName(const char* n) { name = n; } - void SetPassword(const char* p) { pass = p; } - void SetSerialNumber(const char* s){ serno = s; } - void SetElement(const char* n) { elem = n; } - void SetIndex(int n) { index = n; } - -private: - Text name; // callsign - Text pass; // password - Text serno; // box cdkey - Text elem; // element to join - int index; // one-based index - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetJoinAnnounce : public NetData -{ -public: - static const char* TYPENAME() { return "NetJoinAnnounce"; } - - NetJoinAnnounce(); - - enum { TYPE=NET_JOIN_ANNOUNCE, SIZE=200 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - - const char* GetName() const { return name; } - const char* GetElement() const { return elem; } - const char* GetRegion() const { return region; } - const Point& GetLocation() const { return loc; } - const Point& GetVelocity() const { return velocity; } - int GetIndex() const { return index; } - double GetIntegrity() const { return integrity; } - int GetRespawns() const { return respawns; } - int GetDecoys() const { return decoys; } - int GetProbes() const { return probes; } - int GetFuel() const { return fuel; } - int GetShield() const { return shield; } - const int* GetAmmo() const { return ammo; } - - void SetShip(Ship* s); - - void SetName(const char* n) { name = n; } - void SetElement(const char* n) { elem = n; } - void SetRegion(const char* r) { region = r; } - void SetLocation(const Point& l) { loc = l; } - void SetVelocity(const Point& v) { velocity = v; } - void SetIndex(int n) { index = n; } - void SetIntegrity(double n) { integrity = (float) n; } - void SetRespawns(int n) { respawns = n; } - void SetDecoys(int n) { decoys = n; } - void SetProbes(int n) { probes = n; } - void SetFuel(int n) { fuel = n; } - void SetShield(int n) { shield = n; } - void SetAmmo(const int* a); - - virtual DWORD GetNetID() const { return nid; } - virtual void SetNetID(DWORD n) { nid = n; } - -private: - Text name; // callsign - Text elem; // element to join - Text region; // region ship is in - Point loc; // location of ship - Point velocity; // velocity of ship - int index; // one-based index - float integrity; // hull integrity - int respawns; - int decoys; - int probes; - int fuel; - int shield; - int ammo[16]; - DWORD objid; - DWORD nid; // not sent over network - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetQuitAnnounce : public NetData -{ -public: - static const char* TYPENAME() { return "NetQuitAnnounce"; } - - NetQuitAnnounce() : objid(0), disconnected(false) { } - - enum { TYPE=NET_QUIT_ANNOUNCE, SIZE=5 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - virtual bool GetDisconnected() const { return disconnected; } - virtual void SetDisconnected(bool d) { disconnected = d; } - -private: - DWORD objid; - bool disconnected; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetDisconnect : public NetData -{ -public: - static const char* TYPENAME() { return "NetDisconnect"; } - - NetDisconnect() { } - - enum { TYPE=NET_DISCONNECT, SIZE=2 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - -private: - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetObjDamage : public NetData -{ -public: - static const char* TYPENAME() { return "NetObjDamage"; } - - NetObjDamage() : objid(0), damage(0), shotid(0) { } - - enum { TYPE=NET_OBJ_DAMAGE, SIZE=12 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - - virtual DWORD GetShotID() const { return shotid; } - virtual void SetShotID(DWORD o) { shotid = o; } - - float GetDamage() const { return damage; } - void SetDamage(float d) { damage = d; } - -private: - DWORD objid; - float damage; - DWORD shotid; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetObjKill : public NetData -{ -public: - static const char* TYPENAME() { return "NetObjKill"; } - - NetObjKill() : objid(0), kill_id(0), killtype(0), respawn(false), deck(0) { } - - enum { TYPE=NET_OBJ_KILL, SIZE=24, - KILL_MISC = 0, - KILL_PRIMARY, - KILL_SECONDARY, - KILL_COLLISION, - KILL_CRASH, - KILL_DOCK - }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - virtual DWORD GetKillerID() const { return kill_id; } - virtual void SetKillerID(DWORD o) { kill_id = o; } - virtual int GetKillType() const { return killtype;} - virtual void SetKillType(int t) { killtype = t; } - virtual bool GetRespawn() const { return respawn; } - virtual void SetRespawn(bool r) { respawn = r; } - virtual Point GetRespawnLoc() const { return loc; } - virtual void SetRespawnLoc(const Point& p) { loc = p; } - virtual int GetFlightDeck() const { return deck; } - virtual void SetFlightDeck(int n) { deck = n; } - -private: - DWORD objid; - DWORD kill_id; - int killtype; - bool respawn; - Point loc; - int deck; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetObjHyper : public NetData -{ -public: - static const char* TYPENAME() { return "NetObjHyper"; } - - NetObjHyper() : objid(0), fc_src(0), fc_dst(0), transtype(0) { } - - enum { TYPE=NET_OBJ_HYPER, SIZE=56 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD id) { objid = id; } - - const Point& GetLocation() const { return location; } - const Text& GetRegion() const { return region; } - DWORD GetFarcaster1() const { return fc_src; } - DWORD GetFarcaster2() const { return fc_dst; } - int GetTransitionType() const { return transtype; } - - void SetLocation(const Point& loc) { location = loc; } - void SetRegion(const char* rgn) { region = rgn; } - void SetFarcaster1(DWORD f) { fc_src = f; } - void SetFarcaster2(DWORD f) { fc_dst = f; } - void SetTransitionType(int t) { transtype = t; } - -private: - DWORD objid; - Point location; - Text region; - DWORD fc_src; - DWORD fc_dst; - int transtype; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetObjTarget : public NetData -{ -public: - static const char* TYPENAME() { return "NetObjTarget"; } - - NetObjTarget() : objid(0), tgtid(0), sysix(0) { } - - enum { TYPE=NET_OBJ_TARGET, SIZE=7 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - - DWORD GetTgtID() const { return tgtid; } - void SetTgtID(DWORD o) { tgtid = o; } - int GetSubtarget() const { return sysix; } - void SetSubtarget(int n) { sysix = n; } - -private: - DWORD objid; - DWORD tgtid; - int sysix; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetObjEmcon : public NetData -{ -public: - static const char* TYPENAME() { return "NetObjEmcon"; } - - NetObjEmcon() : objid(0), emcon(0) { } - - enum { TYPE=NET_OBJ_EMCON, SIZE=5 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - - int GetEMCON() const { return emcon; } - void SetEMCON(int n) { emcon = n; } - -private: - DWORD objid; - int emcon; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetSysDamage : public NetData -{ -public: - static const char* TYPENAME() { return "NetSysDamage"; } - - NetSysDamage() : objid(0), sysix(-1), dmgtype(0), damage(0) { } - - enum { TYPE=NET_SYS_DAMAGE, SIZE=12 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - - int GetSystem() const { return sysix; } - void SetSystem(int n) { sysix = n; } - BYTE GetDamageType() const { return dmgtype; } - void SetDamageType(BYTE t) { dmgtype = t; } - double GetDamage() const { return damage; } - void SetDamage(double d) { damage = d; } - -private: - DWORD objid; - int sysix; - BYTE dmgtype; - double damage; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetSysStatus : public NetData -{ -public: - static const char* TYPENAME() { return "NetSysStatus"; } - - NetSysStatus() : objid(0), sysix(-1), status(0), power(0), reactor(0), - avail(1) { } - - enum { TYPE=NET_SYS_STATUS, SIZE=12 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - - int GetSystem() const { return sysix; } - void SetSystem(int n) { sysix = n; } - BYTE GetStatus() const { return status; } - void SetStatus(BYTE s) { status = s; } - int GetPower() const { return power; } - void SetPower(int n) { power = n; } - int GetReactor() const { return reactor; } - void SetReactor(int n) { reactor = n; } - double GetAvailability() const { return avail; } - void SetAvailablility(double a) { avail = a; } - -private: - DWORD objid; - int sysix; - int status; - int power; - int reactor; - double avail; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetWepTrigger : public NetData -{ -public: - static const char* TYPENAME() { return "NetWepTrigger"; } - - NetWepTrigger() : objid(0), tgtid(0), sysix(-1), index(0), count(0), - decoy(false), probe(false) { } - - enum { TYPE=NET_WEP_TRIGGER, SIZE=10 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - - DWORD GetTgtID() const { return tgtid; } - void SetTgtID(DWORD o) { tgtid = o; } - int GetSubtarget() const { return sysix; } - void SetSubtarget(int n) { sysix = n; } - int GetIndex() const { return index; } - void SetIndex(int n) { index = n; } - int GetCount() const { return count; } - void SetCount(int n) { count = n; } - bool GetDecoy() const { return decoy; } - void SetDecoy(bool d) { decoy = d; } - bool GetProbe() const { return probe; } - void SetProbe(bool p) { probe = p; } - -private: - DWORD objid; - DWORD tgtid; - int sysix; - int index; - int count; - bool decoy; - bool probe; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetWepRelease : public NetData -{ -public: - static const char* TYPENAME() { return "NetWepRelease"; } - - NetWepRelease() : objid(0), tgtid(0), wepid(0), sysix(-1), index(0), - decoy(false), probe(false) { } - - enum { TYPE=NET_WEP_RELEASE, SIZE=11 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - - DWORD GetTgtID() const { return tgtid; } - void SetTgtID(DWORD o) { tgtid = o; } - int GetSubtarget() const { return sysix; } - void SetSubtarget(int n) { sysix = n; } - DWORD GetWepID() const { return wepid; } - void SetWepID(DWORD o) { wepid = o; } - int GetIndex() const { return index; } - void SetIndex(int n) { index = n; } - bool GetDecoy() const { return decoy; } - void SetDecoy(bool d) { decoy = d; } - bool GetProbe() const { return probe; } - void SetProbe(bool p) { probe = p; } - -private: - DWORD objid; - DWORD tgtid; - DWORD wepid; - int sysix; - int index; - bool decoy; - bool probe; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetWepDestroy : public NetData -{ -public: - static const char* TYPENAME() { return "NetWepDestroy"; } - - NetWepDestroy() : objid(0) { } - - enum { TYPE=NET_WEP_DESTROY, SIZE=4 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - -private: - DWORD objid; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class RadioMessage; -class NetCommMsg : public NetData -{ -public: - static const char* TYPENAME() { return "NetCommMsg"; } - - NetCommMsg() : objid(0), radio_message(0), length(0) { } - virtual ~NetCommMsg(); - - enum { TYPE=NET_COMM_MESSAGE, SIZE=200 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return length; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - - RadioMessage* GetRadioMessage() { return radio_message; } - void SetRadioMessage(RadioMessage* m); - -private: - DWORD objid; - RadioMessage* radio_message; - - int length; - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetChatMsg : public NetData -{ -public: - static const char* TYPENAME() { return "NetChatMsg"; } - - NetChatMsg() : dstid(0), length(0) { } - - enum { TYPE=NET_CHAT_MESSAGE, SIZE=210, MAX_CHAT=160, HDR_LEN=4, NAME_LEN=32 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return length; } - - virtual DWORD GetDstID() const { return dstid; } - virtual void SetDstID(DWORD d) { dstid = d; } - const Text& GetName() const { return name; } - void SetName(const char* m) { name = m; } - const Text& GetText() const { return text; } - void SetText(const char* m) { text = m; } - -private: - DWORD dstid; - Text name; - Text text; - - int length; - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetElemRequest : public NetData -{ -public: - static const char* TYPENAME() { return "NetElemRequest"; } - - NetElemRequest(); - - enum { TYPE=NET_ELEM_REQUEST, SIZE=64, NAME_LEN=32 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - const Text& GetName() const { return name; } - void SetName(const char* m) { name = m; } - -private: - Text name; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetElemCreate : public NetData -{ -public: - static const char* TYPENAME() { return "NetElemCreate"; } - - NetElemCreate(); - - enum { TYPE=NET_ELEM_CREATE, SIZE=192, NAME_LEN=32 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - const Text& GetName() const { return name; } - void SetName(const char* m) { name = m; } - const Text& GetCommander() const { return commander; } - void SetCommander(const char* m) { commander = m; } - const Text& GetObjective() const { return objective; } - void SetObjective(const char* m) { objective = m; } - const Text& GetCarrier() const { return carrier; } - void SetCarrier(const char* m) { carrier = m; } - - int GetIFF() const { return iff; } - void SetIFF(int n) { iff = n; } - int GetType() const { return type; } - void SetType(int n) { type = n; } - int GetIntel() const { return intel; } - void SetIntel(int n) { intel = n; } - int GetObjCode() const { return obj_code; } - void SetObjCode(int n) { obj_code = n; } - int GetSquadron() const { return squadron; } - void SetSquadron(int n) { squadron = n; } - - int* GetLoadout() { return load; } - void SetLoadout(int* n); - int* GetSlots() { return slots; } - void SetSlots(int* n); - - bool GetAlert() const { return alert; } - void SetAlert(bool a) { alert = a; } - - bool GetInFlight() const { return in_flight; } - void SetInFlight(bool f) { in_flight = f; } - -private: - Text name; - int iff; - int type; - int intel; - int obj_code; - int squadron; - - Text commander; - Text objective; - Text carrier; - - int load[16]; - int slots[4]; - bool alert; - bool in_flight; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetShipLaunch : public NetData -{ -public: - static const char* TYPENAME() { return "NetShipLaunch"; } - - NetShipLaunch() : objid(0), squadron(0), slot(0) { } - - enum { TYPE=NET_SHIP_LAUNCH, SIZE=16 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual int GetSquadron() const { return squadron; } - virtual int GetSlot() const { return slot; } - - virtual void SetObjID(DWORD o) { objid = o; } - virtual void SetSquadron(int s) { squadron = s; } - virtual void SetSlot(int s) { slot = s; } - -private: - DWORD objid; - int squadron; - int slot; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class Instruction; - -class NetNavData : public NetData -{ -public: - static const char* TYPENAME() { return "NetNavData"; } - - NetNavData(); - virtual ~NetNavData(); - - enum { TYPE=NET_NAV_DATA, SIZE=144, NAME_LEN=32 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - bool IsAdd() const { return create; } - bool IsEdit() const { return !create; } - const Text& GetElem() const { return elem; } - int GetIndex() const { return index; } - Instruction* GetNavPoint() const { return navpoint; } - - virtual void SetObjID(DWORD o) { objid = o; } - void SetAdd(bool b) { create = b; } - void SetElem(const char* e) { elem = e; } - void SetIndex(int n) { index = n; } - void SetNavPoint(Instruction* n); - -private: - DWORD objid; - bool create; - Text elem; - int index; - Instruction* navpoint; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetNavDelete : public NetData -{ -public: - static const char* TYPENAME() { return "NetNavDelete"; } - - NetNavDelete() : objid(0), index(0) { } - - enum { TYPE=NET_NAV_DELETE, SIZE=40 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - const Text& GetElem() const { return elem; } - int GetIndex() const { return index; } - - virtual void SetObjID(DWORD o) { objid = o; } - void SetElem(const char* e) { elem = e; } - void SetIndex(int n) { index = n; } - -private: - DWORD objid; - Text elem; - int index; - - BYTE data[SIZE]; -}; - -// +--------------------------------------------------------------------+ - -class NetSelfDestruct : public NetData -{ -public: - static const char* TYPENAME() { return "NetSelfDestruct"; } - - NetSelfDestruct() : objid(0), damage(0) { } - - enum { TYPE=NET_SELF_DESTRUCT, SIZE=8 }; - - virtual BYTE* Pack(); - virtual bool Unpack(const BYTE* data); - virtual int Type() const { return TYPE; } - virtual int Length() const { return SIZE; } - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD o) { objid = o; } - - float GetDamage() const { return damage; } - void SetDamage(float d) { damage = d; } - -private: - DWORD objid; - float damage; - - BYTE data[SIZE]; -}; - - -// +--------------------------------------------------------------------+ - -#endif // NetData_h - diff --git a/Stars45/NetFileServlet.cpp b/Stars45/NetFileServlet.cpp deleted file mode 100644 index 6b23d9d..0000000 --- a/Stars45/NetFileServlet.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - HTTP Servlet for File Transfer -*/ - - -#include "NetFileServlet.h" -#include "NetAdminServer.h" -#include "NetLayer.h" - -#include "DataLoader.h" - -// +-------------------------------------------------------------------+ - -bool -NetFileServlet::DoGet(HttpRequest& request, HttpResponse& response) -{ - if (!CheckUser(request, response)) - return true; - - Text content; - Text path = request.GetParam("path"); - Text name = request.GetParam("name"); - - if (name.length()) { - BYTE* buffer = 0; - DataLoader* loader = DataLoader::GetLoader(); - - if (loader) { - loader->SetDataPath(path); - int len = loader->LoadBuffer(name, buffer); - - if (len) { - content = Text((const char*) buffer, len); - } - - loader->ReleaseBuffer(buffer); - loader->SetDataPath(0); - } - } - - response.SetStatus(HttpResponse::SC_OK); - response.AddHeader("MIME-Version", "1.0"); - response.AddHeader("Cache-Control", "no-cache"); - response.AddHeader("Expires", "-1"); - response.AddHeader("Content-Type", "text/plain"); - response.SetContent(content); - - return true; -} - -// +-------------------------------------------------------------------+ - -bool -NetWebServlet::DoGet(HttpRequest& request, HttpResponse& response) -{ - Text content; - Text name = request.URI(); - bool found = false; - - if (name.length() > 4) { - char filename[256]; - strcpy_s(filename, name.data() + 1); // skip leading '/' - - FILE* f; - ::fopen_s(&f, filename, "rb"); - - if (f) { - ::fseek(f, 0, SEEK_END); - int len = ftell(f); - ::fseek(f, 0, SEEK_SET); - - BYTE* buf = new BYTE[len]; - - ::fread(buf, len, 1, f); - ::fclose(f); - - content = Text((const char*) buf, len); - delete [] buf; - - found = true; - ::Print("weblog: 200 OK %s %d bytes\n", name.data(), len); - } - else { - ::Print("weblog: 404 Not Found %s\n", name.data()); - } - } - - if (found) { - Text content_type = "text/plain"; - - if (name.contains(".gif")) - content_type = "image/gif"; - else if (name.contains(".jpg")) - content_type = "image/jpeg"; - else if (name.contains(".htm")) - content_type = "text/html"; - - response.SetStatus(HttpResponse::SC_OK); - response.AddHeader("MIME-Version", "1.0"); - response.AddHeader("Content-Type", content_type); - response.SetContent(content); - } - else { - response.SetStatus(HttpResponse::SC_NOT_FOUND); - } - - return true; -} diff --git a/Stars45/NetFileServlet.h b/Stars45/NetFileServlet.h deleted file mode 100644 index 7de3443..0000000 --- a/Stars45/NetFileServlet.h +++ /dev/null @@ -1,49 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - HTTP Servlet for File Transfer -*/ - - -#ifndef NetFileServlet_h -#define NetFileServlet_h - -#include "Types.h" -#include "NetAdminServer.h" -#include "NetUser.h" - -// +-------------------------------------------------------------------+ - -class Campaign; -class File; - -// +-------------------------------------------------------------------+ - -class NetFileServlet : public NetAdminServlet -{ -public: - NetFileServlet() { } - virtual ~NetFileServlet() { } - - virtual bool DoGet(HttpRequest& request, HttpResponse& response); -}; - -// +-------------------------------------------------------------------+ - -class NetWebServlet : public NetAdminServlet -{ -public: - NetWebServlet() { } - virtual ~NetWebServlet() { } - - virtual bool DoGet(HttpRequest& request, HttpResponse& response); -}; - -#endif // NetFileServlet_h \ No newline at end of file diff --git a/Stars45/NetGame.cpp b/Stars45/NetGame.cpp deleted file mode 100644 index c02b390..0000000 --- a/Stars45/NetGame.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Network Game Manager class -*/ - -#include "NetGame.h" -#include "NetGameClient.h" -#include "NetGameServer.h" -#include "NetClientConfig.h" -#include "NetServerConfig.h" -#include "NetPlayer.h" - -#include "NetMsg.h" -#include "NetData.h" -#include "NetLayer.h" - -#include "Player.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Sim.h" -#include "Element.h" -#include "HUDView.h" - -#include "NetHost.h" -#include "Game.h" -#include "Light.h" - -// +--------------------------------------------------------------------+ - -const int MAX_NET_FPS = 20; -const int MIN_NET_FRAME = 1000 / MAX_NET_FPS; - -const DWORD SHIP_ID_START = 0x0010; -const DWORD SHOT_ID_START = 0x0400; - -static NetGame* netgame = 0; - -static DWORD ship_id_key = SHIP_ID_START; -static DWORD shot_id_key = SHOT_ID_START; - -static long start_time = 0; - -// +--------------------------------------------------------------------+ - -NetGame::NetGame() -: objid(0), netid(0), link(0), local_player(0), last_send_time(0), active(true) -{ - netgame = this; - sim = Sim::GetSim(); - - ship_id_key = SHIP_ID_START; - shot_id_key = SHOT_ID_START; - - if (sim) - local_player = sim->GetPlayerShip(); - - Player* player = Player::GetCurrentPlayer(); - if (player) { - player_name = player->Name(); - player_pass = player->Password(); - } - - start_time = NetLayer::GetUTC(); -} - -NetGame::~NetGame() -{ - netgame = 0; - local_player = 0; - players.destroy(); - - if (link) { - double delta = fabs((double)(NetLayer::GetUTC() - start_time)); - double bandwidth = 10.0 * (link->GetBytesSent() + link->GetBytesRecv()) / delta; - double recvrate = link->GetPacketsRecv() / delta; - - Print("NetGame Stats\n-------------\n"); - Print(" packets sent %d\n", link->GetPacketsSent()); - Print(" packets recv %d\n", link->GetPacketsRecv()); - Print(" bytes sent %d\n", link->GetBytesSent()); - Print(" bytes recv %d\n", link->GetBytesRecv()); - Print(" retries %d\n", link->GetRetries()); - Print(" drops %d\n", link->GetDrops()); - Print(" avg lag %d msec\n", link->GetLag()); - Print(" time %d sec\n", (int) delta); - Print(" bandwidth %d bps\n", (int) bandwidth); - Print(" packet rate %d pps in\n\n", (int) recvrate); - - delete link; - } -} - -// +--------------------------------------------------------------------+ - -NetGame* -NetGame::Create() -{ - if (!netgame) { - if (NetServerConfig::GetInstance()) - netgame = new NetGameServer; - - else if (NetClientConfig::GetInstance() && NetClientConfig::GetInstance()->GetSelectedServer()) - netgame = new NetGameClient; - } - - return netgame; -} - -NetGame* -NetGame::GetInstance() -{ - return netgame; -} - -DWORD -NetGame::GetObjID() const -{ - if (local_player) - return local_player->GetObjID(); - - return 0; -} - -DWORD -NetGame::GetNextObjID(int type) -{ - if (type == SHIP) { - if (ship_id_key >= SHOT_ID_START) - ship_id_key = SHIP_ID_START; - - return ship_id_key++; - } - - else if (type == SHOT) { - if (shot_id_key >= 0xFFFE) - shot_id_key = SHOT_ID_START; - - return shot_id_key++; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -NetGame::ExecFrame() -{ - Send(); - Recv(); -} - -void -NetGame::Recv() -{ - NetMsg* msg = link->GetMessage(); - - while (msg) { - if (active) { - // For Debug Convenience: - // NetPlayer* player = FindPlayerByNetID(msg->NetID()); - - switch (msg->Type()) { - case NET_JOIN_REQUEST: DoJoinRequest(msg); break; - case NET_JOIN_ANNOUNCE: DoJoinAnnounce(msg); break; - case NET_QUIT_REQUEST: DoQuitRequest(msg); break; - case NET_QUIT_ANNOUNCE: DoQuitAnnounce(msg); break; - case NET_GAME_OVER: DoGameOver(msg); break; - case NET_DISCONNECT: DoDisconnect(msg); break; - - case NET_OBJ_LOC: DoObjLoc(msg); break; - case NET_OBJ_DAMAGE: DoObjDamage(msg); break; - case NET_OBJ_KILL: DoObjKill(msg); break; - case NET_OBJ_SPAWN: DoObjSpawn(msg); break; - case NET_OBJ_HYPER: DoObjHyper(msg); break; - case NET_OBJ_TARGET: DoObjTarget(msg); break; - case NET_OBJ_EMCON: DoObjEmcon(msg); break; - case NET_SYS_DAMAGE: DoSysDamage(msg); break; - case NET_SYS_STATUS: DoSysStatus(msg); break; - - case NET_ELEM_CREATE: DoElemCreate(msg); break; - case NET_ELEM_REQUEST: DoElemRequest(msg); break; - case NET_SHIP_LAUNCH: DoShipLaunch(msg); break; - case NET_NAV_DATA: DoNavData(msg); break; - case NET_NAV_DELETE: DoNavDelete(msg); break; - - case NET_WEP_TRIGGER: DoWepTrigger(msg); break; - case NET_WEP_RELEASE: DoWepRelease(msg); break; - case NET_WEP_DESTROY: DoWepDestroy(msg); break; - - case NET_COMM_MESSAGE: DoCommMsg(msg); break; - case NET_CHAT_MESSAGE: DoChatMsg(msg); break; - case NET_SELF_DESTRUCT: DoSelfDestruct(msg); break; - } - } - - delete msg; - msg = link->GetMessage(); - } -} - -// +--------------------------------------------------------------------+ - -void -NetGame::Send() -{ -} - -int -NetGame::NumPlayers() -{ - if (netgame) { - int num_players = netgame->players.size(); - - if (netgame->local_player) - num_players++; - - return num_players; - } - - return 0; -} - -NetPlayer* -NetGame::FindPlayerByName(const char* name) -{ - for (int i = 0; i < players.size(); i++) { - NetPlayer* p = players[i]; - - if (!strcmp(p->Name(), name)) - return p; - } - - return 0; -} - -NetPlayer* -NetGame::FindPlayerByNetID(DWORD netid) -{ - for (int i = 0; i < players.size(); i++) { - NetPlayer* p = players[i]; - - if (p->GetNetID() == netid) - return p; - } - - return 0; -} - -NetPlayer* -NetGame::FindPlayerByObjID(DWORD objid) -{ - for (int i = 0; i < players.size(); i++) { - NetPlayer* p = players[i]; - - if (p->GetObjID() == objid) - return p; - } - - return 0; -} - -Ship* -NetGame::FindShipByObjID(DWORD objid) -{ - if (sim) - return sim->FindShipByObjID(objid); - - return 0; -} - -Shot* -NetGame::FindShotByObjID(DWORD objid) -{ - if (sim) - return sim->FindShotByObjID(objid); - - return 0; -} - -NetPeer* -NetGame::GetPeer(NetPlayer* player) -{ - if (player && link) { - return link->FindPeer(player->GetNetID()); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -NetGame::Respawn(DWORD objid, Ship* spawn) -{ -} - -// +--------------------------------------------------------------------+ - -bool -NetGame::IsNetGame() -{ - return netgame != 0; -} - -bool -NetGame::IsNetGameClient() -{ - if (netgame) - return netgame->IsClient(); - return false; -} - -bool -NetGame::IsNetGameServer() -{ - if (netgame) - return netgame->IsServer(); - return false; -} diff --git a/Stars45/NetGame.h b/Stars45/NetGame.h deleted file mode 100644 index 1a79d30..0000000 --- a/Stars45/NetGame.h +++ /dev/null @@ -1,126 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Network Game Manager class -*/ - -#ifndef NetGame_h -#define NetGame_h - -#include "Types.h" -#include "Geometry.h" -#include "NetLink.h" -#include "Director.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Sim; -class Ship; -class Shot; -class NetData; -class NetMsg; -class NetPlayer; - -// +--------------------------------------------------------------------+ - -class NetGame -{ -public: - static const char* TYPENAME() { return "NetGame"; } - - enum { SHIP, SHOT }; - - NetGame(); - virtual ~NetGame(); - - virtual bool IsClient() const { return false; } - virtual bool IsServer() const { return false; } - virtual bool IsActive() const { return active; } - - virtual DWORD GetNetID() const { return netid; } - virtual DWORD GetObjID() const; - - virtual void ExecFrame(); - virtual void Recv(); - virtual void Send(); - - virtual void SendData(NetData* data) { } - - virtual NetPlayer* FindPlayerByName(const char* name); - virtual NetPlayer* FindPlayerByNetID(DWORD netid); - virtual NetPlayer* FindPlayerByObjID(DWORD objid); - virtual Ship* FindShipByObjID(DWORD objid); - virtual Shot* FindShotByObjID(DWORD objid); - - virtual NetPeer* GetPeer(NetPlayer* player); - - virtual void Respawn(DWORD objid, Ship* spawn); - - static NetGame* Create(); - static NetGame* GetInstance(); - static bool IsNetGame(); - static bool IsNetGameClient(); - static bool IsNetGameServer(); - static int NumPlayers(); - - static DWORD GetNextObjID(int type=SHIP); - -protected: - virtual void DoJoinRequest(NetMsg* msg) { } - virtual void DoJoinAnnounce(NetMsg* msg) { } - virtual void DoQuitRequest(NetMsg* msg) { } - virtual void DoQuitAnnounce(NetMsg* msg) { } - virtual void DoGameOver(NetMsg* msg) { } - virtual void DoDisconnect(NetMsg* msg) { } - - virtual void DoObjLoc(NetMsg* msg) { } - virtual void DoObjDamage(NetMsg* msg) { } - virtual void DoObjKill(NetMsg* msg) { } - virtual void DoObjSpawn(NetMsg* msg) { } - virtual void DoObjHyper(NetMsg* msg) { } - virtual void DoObjTarget(NetMsg* msg) { } - virtual void DoObjEmcon(NetMsg* msg) { } - virtual void DoSysDamage(NetMsg* msg) { } - virtual void DoSysStatus(NetMsg* msg) { } - - virtual void DoElemCreate(NetMsg* msg) { } - virtual void DoElemRequest(NetMsg* msg) { } - virtual void DoShipLaunch(NetMsg* msg) { } - virtual void DoNavData(NetMsg* msg) { } - virtual void DoNavDelete(NetMsg* msg) { } - - virtual void DoWepTrigger(NetMsg* msg) { } - virtual void DoWepRelease(NetMsg* msg) { } - virtual void DoWepDestroy(NetMsg* msg) { } - - virtual void DoCommMsg(NetMsg* msg) { } - virtual void DoChatMsg(NetMsg* msg) { } - virtual void DoSelfDestruct(NetMsg* msg) { } - - List players; - NetLink* link; - - DWORD objid; - DWORD netid; - Ship* local_player; - Text player_name; - Text player_pass; - Ship* target; - Sim* sim; - bool active; - - DWORD last_send_time; -}; - -// +--------------------------------------------------------------------+ - -#endif // NetGame_h - diff --git a/Stars45/NetGameClient.cpp b/Stars45/NetGameClient.cpp deleted file mode 100644 index 5b1440f..0000000 --- a/Stars45/NetGameClient.cpp +++ /dev/null @@ -1,1068 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Network Game Manager class -*/ - -#include "NetGameClient.h" -#include "NetClientConfig.h" -#include "NetLobby.h" -#include "NetPlayer.h" -#include "NetData.h" -#include "NetUtil.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Shield.h" -#include "Shot.h" -#include "Sim.h" -#include "SimEvent.h" -#include "Weapon.h" -#include "Element.h" -#include "Explosion.h" -#include "HUDView.h" -#include "RadioView.h" -#include "Instruction.h" -#include "Hangar.h" -#include "FlightDeck.h" -#include "Mission.h" - -#include "NetMsg.h" -#include "NetHost.h" -#include "NetLayer.h" -#include "NetPeer.h" - -#include "Clock.h" -#include "ContentBundle.h" -#include "Light.h" - -// +--------------------------------------------------------------------+ - -const int MAX_NET_FPS = 20; -const int MIN_NET_FRAME = 1000 / MAX_NET_FPS; - -const char* FormatGameTime(); - -// +--------------------------------------------------------------------+ - -NetGameClient::NetGameClient() -: server_id(0), join_req_time(0) -{ - Print("Constructing NetGameClient\n"); - - NetHost me; - Text server_name; - WORD port = 11101; - - NetClientConfig* ncc = NetClientConfig::GetInstance(); - if (ncc) { - NetServerInfo* info = ncc->GetSelectedServer(); - - if (info) { - server_name = info->hostname; - port = info->gameport; - } - } - - if (server_name.length() && port > 0) { - Print(" '%s' is a client of '%s'\n", me.Name(), server_name.data()); - link = new NetLink; - server_id = link->AddPeer(NetAddr(server_name, port)); - SendJoinRequest(); - } - else if (port == 0) { - Print(" '%s' invalid game port number %d\n", me.Name(), port); - } - else { - Print(" '%s' is a client without a server\n", me.Name()); - } -} - -NetGameClient::~NetGameClient() -{ - link->SendMessage(server_id, NET_QUIT_REQUEST, 0, 0, NetMsg::RELIABLE); - - // wait for message to be delivered before shutting down the link: - Sleep(500); - - join_backlog.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -NetGameClient::SendJoinRequest() -{ - if ((NetLayer::GetTime() - join_req_time) < 5000) - return; - - if (local_player && local_player->GetElement() && server_id) { - Print(" sending join request - name: '%s' elem: '%s' index: %d\n", - player_name.data(), - local_player->GetElement()->Name().data(), - local_player->GetElementIndex()); - - NetJoinRequest join_req; - join_req.SetName(player_name); - join_req.SetPassword(player_pass); - join_req.SetElement(local_player->GetElement()->Name()); - join_req.SetIndex(local_player->GetElementIndex()); - - link->SendMessage(server_id, join_req.Pack(), NetJoinRequest::SIZE, NetMsg::RELIABLE); - join_req_time = NetLayer::GetTime(); - - local_player->SetNetObserver(true); - } -} - -// +--------------------------------------------------------------------+ - -void -NetGameClient::DoJoinRequest(NetMsg* msg) -{ - if (!msg) return; - - NetJoinRequest join_req; - if (join_req.Unpack(msg->Data())) { - Print("Client received Join Request from '%s'\n", join_req.GetName()); - } -} - -void -NetGameClient::DoJoinAnnounce(NetMsg* msg) -{ - if (!msg) return; - - Sim* sim = Sim::GetSim(); - if (!sim) return; - - NetJoinAnnounce* join_ann = new NetJoinAnnounce; - bool saved = false; - - if (join_ann->Unpack(msg->Data())) { - DWORD nid = msg->NetID(); - DWORD oid = join_ann->GetObjID(); - Text name = join_ann->GetName(); - Text elem_name = join_ann->GetElement(); - Text region = join_ann->GetRegion(); - Point loc = join_ann->GetLocation(); - Point velocity = join_ann->GetVelocity(); - int index = join_ann->GetIndex(); - int shld_lvl = join_ann->GetShield(); - join_ann->SetNetID(nid); - Ship* ship = 0; - char ship_name[128]; - - strcpy_s(ship_name, ContentBundle::GetInstance()->GetText("NetGameClient.no-ship").data()); - - if (local_player && player_name == name) { - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameClient.local-accept"), name.data(), local_player->Name()); - - objid = oid; - netid = nid; - local_player->SetObjID(oid); - local_player->SetNetObserver(false); - Observe(local_player); - - SimRegion* rgn = local_player->GetRegion(); - if (rgn && region != rgn->Name()) { - SimRegion* dst = sim->FindRegion(region); - if (dst) dst->InsertObject(local_player); - } - - local_player->MoveTo(loc); - local_player->SetVelocity(velocity); - - Shield* shield = local_player->GetShield(); - if (shield) - shield->SetNetShieldLevel(shld_lvl); - } - else { - NetPlayer* remote_player = FindPlayerByObjID(oid); - if (remote_player) { - remote_player->SetName(name); - remote_player->SetObjID(oid); - - if (index > 0) - sprintf_s(ship_name, "%s %d", elem_name.data(), index); - else - sprintf_s(ship_name, "%s", elem_name.data()); - } - else { - Element* element = sim->FindElement(elem_name); - - if (element) { - ship = element->GetShip(index); - } - else { - Print("NetGameClient::DoJoinAnnounce() could not find elem %s for player '%s' objid %d\n", - elem_name.data(), name.data(), oid); - - NetUtil::SendElemRequest(elem_name.data()); - } - - if (!ship) { - // save it for later: - join_backlog.append(join_ann); - saved = true; - } - else { - strcpy_s(ship_name, ship->Name()); - - SimRegion* rgn = ship->GetRegion(); - if (rgn && region != rgn->Name()) { - SimRegion* dst = sim->FindRegion(region); - if (dst) dst->InsertObject(ship); - } - - ship->MoveTo(loc); - ship->SetVelocity(velocity); - - Shield* shield = ship->GetShield(); - if (shield) - shield->SetNetShieldLevel(shld_lvl); - - NetPlayer* remote_player = new NetPlayer(nid); - remote_player->SetName(name); - remote_player->SetObjID(oid); - remote_player->SetShip(ship); - - players.append(remote_player); - - if (name == "Server A.I. Ship") { - Print("Remote Player '%s' has joined as '%s' with ID %d\n", name.data(), ship_name, oid); - } - else { - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameClient.remote-join").data(), name.data(), ship_name); - } - } - } - } - } - - if (!saved) - delete join_ann; -} - -bool -NetGameClient::DoJoinBacklog(NetJoinAnnounce* join_ann) -{ - bool finished = false; - - if (!join_ann) - return finished; - - Sim* sim = Sim::GetSim(); - if (!sim) - return finished; - - DWORD nid = join_ann->GetNetID(); - DWORD oid = join_ann->GetObjID(); - Text name = join_ann->GetName(); - Text elem_name = join_ann->GetElement(); - Text region = join_ann->GetRegion(); - Point loc = join_ann->GetLocation(); - Point velocity = join_ann->GetVelocity(); - int index = join_ann->GetIndex(); - int shld_lvl = join_ann->GetShield(); - Ship* ship = 0; - char ship_name[128]; - - strcpy_s(ship_name, ContentBundle::GetInstance()->GetText("NetGameClient.no-ship").data()); - - if (nid && oid) { - NetPlayer* remote_player = FindPlayerByObjID(oid); - if (remote_player) { - remote_player->SetName(name); - remote_player->SetObjID(oid); - - if (index > 0) - sprintf_s(ship_name, "%s %d", elem_name.data(), index); - else - sprintf_s(ship_name, "%s", elem_name.data()); - } - else { - Element* element = sim->FindElement(elem_name); - - if (element) { - ship = element->GetShip(index); - } - - if (ship) { - strcpy_s(ship_name, ship->Name()); - - SimRegion* rgn = ship->GetRegion(); - if (rgn && region != rgn->Name()) { - SimRegion* dst = sim->FindRegion(region); - if (dst) dst->InsertObject(ship); - } - - ship->MoveTo(loc); - ship->SetVelocity(velocity); - - Shield* shield = ship->GetShield(); - if (shield) - shield->SetNetShieldLevel(shld_lvl); - - NetPlayer* remote_player = new NetPlayer(nid); - remote_player->SetName(name); - remote_player->SetObjID(oid); - remote_player->SetShip(ship); - - players.append(remote_player); - finished = true; - - if (name == "Server A.I. Ship") { - Print("NetGameClient::DoJoinBacklog() Remote Player '%s' has joined as '%s' with ID %d\n", name.data(), ship_name, oid); - } - else { - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameClient.remote-join").data(), name.data(), ship_name); - } - } - } - } - - return finished; -} - - -void -NetGameClient::DoQuitRequest(NetMsg* msg) -{ - if (!msg) return; - - Print("Client received Quit Request from NetID: %08X\n", msg->NetID()); -} - -void -NetGameClient::DoQuitAnnounce(NetMsg* msg) -{ - if (!msg) return; - - NetQuitAnnounce quit_ann; - quit_ann.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(quit_ann.GetObjID()); - - if (player) { - NetPlayer* zombie = players.remove(player); - - // return remote ship to ship pool: - Ship* s = zombie->GetShip(); - if (s) { - s->SetNetworkControl(0); - zombie->SetShip(0); - } - - if (quit_ann.GetDisconnected()) - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameClient.remote-discon").data(), zombie->Name()); - else - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameClient.remote-quit").data(), zombie->Name()); - delete zombie; - } - else { - Print("Quit Announce for unknown player %08X disconnected = %d\n", msg->NetID(), quit_ann.GetDisconnected()); - } -} - -void -NetGameClient::DoGameOver(NetMsg* msg) -{ - if (!msg) return; - - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameClient.game-over").data()); - players.destroy(); - active = false; -} - -void -NetGameClient::DoDisconnect(NetMsg* msg) -{ - if (!msg) return; - - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameClient.discon-detect").data()); - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameClient.please-exit").data()); - players.destroy(); - active = false; -} - -void -NetGameClient::DoObjLoc(NetMsg* msg) -{ - if (!msg) return; - - NetObjLoc obj_loc; - obj_loc.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(obj_loc.GetObjID()); - if (player) - player->DoObjLoc(&obj_loc); -} - -void -NetGameClient::DoObjDamage(NetMsg* msg) -{ - if (!msg) return; - - NetObjDamage obj_damage; - obj_damage.Unpack(msg->Data()); - - Ship* ship = FindShipByObjID(obj_damage.GetObjID()); - if (ship) { - Sim* sim = Sim::GetSim(); - Shot* shot = FindShotByObjID(obj_damage.GetShotID()); - const Ship* owner = 0; - const char* owner_name = "[NET]"; - - ship->InflictNetDamage(obj_damage.GetDamage(), shot); - - if (shot && sim) { - if (shot->Owner()) { - owner = shot->Owner(); - owner_name = owner->Name(); - } - - if (shot->IsMissile()) { - SimRegion* region = ship->GetRegion(); - float scale = ship->Design()->explosion_scale; - - if (scale <= 0) - scale = ship->Design()->scale; - - if (owner) { - const ShipDesign* owner_design = owner->Design(); - if (owner_design && owner_design->scale < scale) - scale = (float) owner_design->scale; - } - - sim->CreateExplosion(shot->Location(), Point(), Explosion::SHOT_BLAST, 20.0f * scale, scale, region); - } - - if (!shot->IsBeam()) { - if (owner) { - ShipStats* stats = ShipStats::Find(owner_name); - - if (stats) { - if (shot->IsPrimary()) - stats->AddGunHit(); - else if (shot->Damage() > 0) - stats->AddMissileHit(); - } - } - - shot->Destroy(); - } - } - } -} - -void -NetGameClient::DoObjKill(NetMsg* msg) -{ - if (!msg) return; - - NetObjKill obj_kill; - obj_kill.Unpack(msg->Data()); - - Ship* ship = FindShipByObjID(obj_kill.GetObjID()); - if (ship) { - Ship* killer = FindShipByObjID(obj_kill.GetKillerID()); - Text killer_name = ContentBundle::GetInstance()->GetText("NetGameClient.unknown"); - - if (killer) - killer_name = killer->Name(); - - // log the kill: - switch (obj_kill.GetKillType()) { - default: - case NetObjKill::KILL_MISC: - Print("Ship '%s' destroyed (misc) (%s)\n", ship->Name(), FormatGameTime()); - break; - - case NetObjKill::KILL_PRIMARY: - case NetObjKill::KILL_SECONDARY: - Print("Ship '%s' killed by '%s' (%s)\n", ship->Name(), killer_name.data(), FormatGameTime()); - break; - - case NetObjKill::KILL_COLLISION: - Print("Ship '%s' killed in collision with '%s' (%s)\n", ship->Name(), killer_name.data(), FormatGameTime()); - break; - - case NetObjKill::KILL_CRASH: - Print("Ship '%s' destroyed (crash) (%s)\n", ship->Name(), FormatGameTime()); - - case NetObjKill::KILL_DOCK: - Print("Ship '%s' docked (%s)\n", ship->Name(), FormatGameTime()); - } - - // record the kill in the stats: - if (killer && obj_kill.GetKillType() != NetObjKill::KILL_DOCK) { - ShipStats* kstats = ShipStats::Find(killer->Name()); - if (kstats) { - if (obj_kill.GetKillType() == NetObjKill::KILL_PRIMARY) - kstats->AddEvent(SimEvent::GUNS_KILL, ship->Name()); - - else if (obj_kill.GetKillType() == NetObjKill::KILL_SECONDARY) - kstats->AddEvent(SimEvent::MISSILE_KILL, ship->Name()); - } - - if (killer && killer->GetIFF() != ship->GetIFF()) { - if (ship->GetIFF() > 0 || killer->GetIFF() > 1) - kstats->AddPoints(ship->Value()); - } - } - - ShipStats* killee = ShipStats::Find(ship->Name()); - if (killee) { - if (obj_kill.GetKillType() == NetObjKill::KILL_DOCK) - killee->AddEvent(SimEvent::DOCK, killer_name); - else - killee->AddEvent(SimEvent::DESTROYED, killer_name); - } - - if (obj_kill.GetKillType() == NetObjKill::KILL_DOCK) { - FlightDeck* deck = killer->GetFlightDeck(obj_kill.GetFlightDeck()); - sim->NetDockShip(ship, killer, deck); - } - else { - ship->InflictNetDamage(ship->Integrity()); - ship->DeathSpiral(); - - if (!obj_kill.GetRespawn()) - ship->SetRespawnCount(0); - else - ship->SetRespawnLoc(obj_kill.GetRespawnLoc()); - } - } - - // this shouldn't happen in practice, - // but if it does, this is what should be done: - else { - Shot* shot = FindShotByObjID(obj_kill.GetObjID()); - - if (shot) { - ::Print("NetGameClient::DoObjKill destroying shot '%s'\n", shot->Name()); - shot->Destroy(); - } - } -} - -void -NetGameClient::DoObjSpawn(NetMsg* msg) -{ -} - -void -NetGameClient::DoObjHyper(NetMsg* msg) -{ - if (!msg) return; - Print("Client received OBJ HYPER from NetID: %08x\n", msg->NetID()); - - NetObjHyper obj_hyper; - obj_hyper.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(obj_hyper.GetObjID()); - if (player && player->GetShip()) - player->DoObjHyper(&obj_hyper); -} - -void -NetGameClient::DoObjTarget(NetMsg* msg) -{ - if (!msg) return; - - NetObjTarget obj_target; - obj_target.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(obj_target.GetObjID()); - if (player) - player->DoObjTarget(&obj_target); -} - -void -NetGameClient::DoObjEmcon(NetMsg* msg) -{ - if (!msg) return; - - NetObjEmcon obj_emcon; - obj_emcon.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(obj_emcon.GetObjID()); - if (player) - player->DoObjEmcon(&obj_emcon); -} - -// +--------------------------------------------------------------------+ - -void -NetGameClient::DoSysDamage(NetMsg* msg) -{ - if (!msg) return; - - NetSysDamage sys_damage; - sys_damage.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(sys_damage.GetObjID()); - if (player && player->GetShip()) - player->DoSysDamage(&sys_damage); -} - -void -NetGameClient::DoSysStatus(NetMsg* msg) -{ - if (!msg) return; - - NetSysStatus sys_status; - sys_status.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(sys_status.GetObjID()); - if (player && player->GetShip()) - player->DoSysStatus(&sys_status); -} - -// +--------------------------------------------------------------------+ - -void -NetGameClient::DoElemCreate(NetMsg* msg) -{ - if (!msg) return; - - NetElemCreate elem_create; - elem_create.Unpack(msg->Data()); - - const char* elem_name = elem_create.GetName().data(); - - ::Print("NetGameClient::DoElemCreate name: %s iff: %d type %s\n", - elem_name, - elem_create.GetIFF(), - Mission::RoleName(elem_create.GetType())); - - Sim* sim = Sim::GetSim(); - Element* elem = sim->FindElement(elem_name); - if (elem) { - ::Print(" element '%' already exists - ignored\n", elem_name); - return; - } - - elem = sim->CreateElement(elem_name, - elem_create.GetIFF(), - elem_create.GetType()); - - int* load = elem_create.GetLoadout(); - int* slots = elem_create.GetSlots(); - int squadron = elem_create.GetSquadron(); - int code = elem_create.GetObjCode(); - Text target = elem_create.GetObjective(); - bool alert = elem_create.GetAlert(); - bool active = elem_create.GetInFlight(); - - elem->SetIntelLevel(elem_create.GetIntel()); - elem->SetLoadout(load); - - if (code > Instruction::RTB || target.length() > 0) { - Instruction* obj = new Instruction(code, target); - elem->AddObjective(obj); - } - - Ship* carrier = sim->FindShip(elem_create.GetCarrier()); - if (carrier) { - elem->SetCarrier(carrier); - - Hangar* hangar = carrier->GetHangar(); - if (hangar) { - Text squadron_name = hangar->SquadronName(squadron); - elem->SetSquadron(squadron_name); - - if (active) { - for (int i = 0; i < 4; i++) { - int slot = slots[i]; - if (slot > -1) { - hangar->GotoActiveFlight(squadron, slot, elem, load); - } - } - } - - else { - FlightDeck* deck = 0; - int queue = 1000; - - for (int i = 0; i < carrier->NumFlightDecks(); i++) { - FlightDeck* d = carrier->GetFlightDeck(i); - - if (d && d->IsLaunchDeck()) { - int dq = hangar->PreflightQueue(d); - - if (dq < queue) { - queue = dq; - deck = d; - } - } - } - - for (int i = 0; i < 4; i++) { - int slot = slots[i]; - if (slot > -1) { - hangar->GotoAlert(squadron, slot, deck, elem, load, !alert); - } - } - } - } - } -} - -void -NetGameClient::DoShipLaunch(NetMsg* msg) -{ - if (!msg) return; - - NetShipLaunch ship_launch; - ship_launch.Unpack(msg->Data()); - - Sim* sim = Sim::GetSim(); - int squadron = ship_launch.GetSquadron(); - int slot = ship_launch.GetSlot(); - - Ship* carrier = FindShipByObjID(ship_launch.GetObjID()); - - if (carrier) { - Hangar* hangar = carrier->GetHangar(); - - if (hangar) { - hangar->Launch(squadron, slot); - } - } -} - -void -NetGameClient::DoWepTrigger(NetMsg* msg) -{ - if (!msg) return; - - NetWepTrigger trigger; - trigger.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(trigger.GetObjID()); - if (player) - player->DoWepTrigger(&trigger); -} - -void -NetGameClient::DoWepRelease(NetMsg* msg) -{ - if (!msg) return; - - NetWepRelease release; - release.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(release.GetObjID()); - if (player) { - player->DoWepRelease(&release); - } - - else { - Ship* shooter = FindShipByObjID(release.GetObjID()); - if (shooter) { - int index = release.GetIndex(); - DWORD tgtid = release.GetTgtID(); - DWORD wepid = release.GetWepID(); - int subid = release.GetSubtarget(); - bool decoy = release.GetDecoy(); - bool probe = release.GetProbe(); - - Weapon* w = 0; - - if (decoy) w = shooter->GetDecoy(); - else if (probe) w = shooter->GetProbeLauncher(); - else w = shooter->GetWeaponByIndex(index); - - if (w && !w->IsPrimary()) { - SimObject* target = FindShipByObjID(tgtid); - System* subtgt = 0; - - if (target) { - if (subid >= 0) { - Ship* tgt_ship = (Ship*) target; - subtgt = tgt_ship->Systems().at(subid); - } - } - else { - target = FindShotByObjID(tgtid); - } - - Shot* shot = w->NetFireSecondary(target, subtgt, wepid); - - if (shot && shot->IsDrone()) { - if (probe) - shooter->SetProbe((Drone*) shot); - - else if (decoy) - shooter->AddActiveDecoy((Drone*) shot); - } - } - } - } -} - -void -NetGameClient::DoNavData(NetMsg* msg) -{ - if (!msg) return; - - NetNavData nav_data; - nav_data.Unpack(msg->Data()); - - Element* elem = sim->FindElement(nav_data.GetElem()); - Ship* ship = FindShipByObjID(nav_data.GetObjID()); - - if (elem) { - if (nav_data.IsAdd()) { - Instruction* navpt = new Instruction(*nav_data.GetNavPoint()); - Instruction* after = 0; - int index = nav_data.GetIndex(); - - if (index >= 0 && index < elem->GetFlightPlan().size()) - after = elem->GetFlightPlan().at(index); - - elem->AddNavPoint(navpt, after, false); - } - - else { - Instruction* navpt = nav_data.GetNavPoint(); - Instruction* exist = 0; - int index = nav_data.GetIndex(); - - if (navpt && index >= 0 && index < elem->GetFlightPlan().size()) { - exist = elem->GetFlightPlan().at(index); - - *exist = *navpt; - } - } - } -} - -void -NetGameClient::DoNavDelete(NetMsg* msg) -{ - if (!msg) return; - - NetNavDelete nav_delete; - nav_delete.Unpack(msg->Data()); - - Element* elem = sim->FindElement(nav_delete.GetElem()); - Ship* ship = FindShipByObjID(nav_delete.GetObjID()); - - if (elem) { - int index = nav_delete.GetIndex(); - - if (index < 0) { - elem->ClearFlightPlan(false); - } - - else if (index < elem->FlightPlanLength()) { - Instruction* npt = elem->GetFlightPlan().at(index); - elem->DelNavPoint(npt, false); - } - } -} - -void -NetGameClient::DoWepDestroy(NetMsg* msg) -{ - if (!msg) return; - - NetWepDestroy destroy; - destroy.Unpack(msg->Data()); - - Shot* shot = FindShotByObjID(destroy.GetObjID()); - if (shot) { - if (shot->IsBeam()) - ::Print("NetGameClient::DoWepDestroy shot '%s'\n", shot->Name()); - - shot->Destroy(); - } -} - -void -NetGameClient::DoCommMsg(NetMsg* msg) -{ - if (!msg) return; - - NetCommMsg comm_msg; - comm_msg.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(comm_msg.GetObjID()); - if (player) - player->DoCommMessage(&comm_msg); -} - -void -NetGameClient::DoChatMsg(NetMsg* msg) -{ - if (!msg) return; - - NetChatMsg chat_msg; - chat_msg.Unpack(msg->Data()); - - Text name = chat_msg.GetName(); - if (name.length() < 1) - name = ContentBundle::GetInstance()->GetText("NetGameClient.chat.unknown"); - - HUDView::Message("%s> %s", name.data(), chat_msg.GetText().data()); -} - -void -NetGameClient::DoSelfDestruct(NetMsg* msg) -{ - if (!msg) return; - - NetSelfDestruct self_destruct; - self_destruct.Unpack(msg->Data()); - - Ship* ship = FindShipByObjID(self_destruct.GetObjID()); - if (ship) { - ship->InflictNetDamage(self_destruct.GetDamage()); - } -} - -// +--------------------------------------------------------------------+ - -void -NetGameClient::Send() -{ - DWORD time = Clock::GetInstance()->GameTime(); - - // don't flood the network... - if (time - last_send_time < MIN_NET_FRAME) - return; - - last_send_time = time; - - if (local_player && objid && server_id) { - double r, p, y; - local_player->Cam().Orientation().ComputeEulerAngles(r,p,y); - - NetObjLoc obj_loc; - - obj_loc.SetObjID(objid); - obj_loc.SetLocation(local_player->Location()); - obj_loc.SetVelocity(local_player->Velocity()); - obj_loc.SetOrientation(Point(r,p,y)); - obj_loc.SetThrottle(local_player->Throttle() > 10); - obj_loc.SetAugmenter(local_player->Augmenter()); - obj_loc.SetGearDown(local_player->IsGearDown()); - - Shield* shield = local_player->GetShield(); - if (shield) - obj_loc.SetShield((int) shield->GetPowerLevel()); - else - obj_loc.SetShield(0); - - BYTE* obj_loc_data = obj_loc.Pack(); - - link->SendMessage(server_id, obj_loc_data, NetObjLoc::SIZE); - } -} - -// +--------------------------------------------------------------------+ - -void -NetGameClient::SendData(NetData* net_data) -{ - if (!net_data || !server_id) - return; - - if (local_player || net_data->Type() < 0x20) { - BYTE* data = net_data->Pack(); - BYTE flags = 0; - - if (net_data->Type() >= 0x10) - flags |= NetMsg::RELIABLE; - - link->SendMessage(server_id, data, net_data->Length(), flags); - } -} - -// +--------------------------------------------------------------------+ - -void -NetGameClient::ExecFrame() -{ - if (local_player) { - if (local_player->GetObjID() == 0) { - SendJoinRequest(); - } - - else if (active) { - // check health of server: - NetPeer* server_peer = link->FindPeer(server_id); - if (server_peer && (NetLayer::GetUTC() - server_peer->LastReceiveTime() > 15)) { - NetMsg net_disco(0, NET_DISCONNECT, 0, 0, 0); - DoDisconnect(&net_disco); - } - - // if server is still there, - else if (server_peer) { - - // check if any old join announcements still need to be processed: - ListIter iter = join_backlog; - while (++iter) { - NetJoinAnnounce* join_ann = iter.value(); - - if (DoJoinBacklog(join_ann)) { - iter.removeItem(); - delete join_ann; - } - } - } - } - } - - NetGame::ExecFrame(); -} - -// +--------------------------------------------------------------------+ - -bool -NetGameClient::Update(SimObject* obj) -{ - if (obj->Type() == SimObject::SIM_SHIP) { - Ship* s = (Ship*) obj; - if (local_player == s) - local_player = 0; - } - - return SimObserver::Update(obj); -} - -const char* -NetGameClient::GetObserverName() const -{ - return "NetGameClient"; -} - -// +--------------------------------------------------------------------+ - -void -NetGameClient::Respawn(DWORD oid, Ship* spawn) -{ - if (!oid || !spawn) return; - - Print("NetGameClient::Respawn(%d, %s)\n", oid, spawn->Name()); - spawn->SetObjID(oid); - Observe(spawn); - - NetPlayer* p = FindPlayerByObjID(oid); - if (p) - p->SetShip(spawn); - - if (objid == oid) { - Print(" RESPAWN LOCAL PLAYER\n\n"); - local_player = spawn; - } -} diff --git a/Stars45/NetGameClient.h b/Stars45/NetGameClient.h deleted file mode 100644 index 3ec397b..0000000 --- a/Stars45/NetGameClient.h +++ /dev/null @@ -1,86 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Network Game Manager class -*/ - -#ifndef NetGameClient_h -#define NetGameClient_h - -#include "NetGame.h" -#include "SimObject.h" - -// +--------------------------------------------------------------------+ - -class NetJoinAnnounce; - -// +--------------------------------------------------------------------+ - -class NetGameClient : public NetGame, public SimObserver -{ -public: - NetGameClient(); - virtual ~NetGameClient(); - - virtual bool IsClient() const { return true; } - virtual bool IsServer() const { return false; } - - virtual void ExecFrame(); - virtual void Send(); - virtual void SendData(NetData* data); - virtual void Respawn(DWORD objid, Ship* spawn); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - -protected: - virtual void DoJoinRequest(NetMsg* msg); - virtual void DoJoinAnnounce(NetMsg* msg); - virtual void DoQuitRequest(NetMsg* msg); - virtual void DoQuitAnnounce(NetMsg* msg); - virtual void DoGameOver(NetMsg* msg); - virtual void DoDisconnect(NetMsg* msg); - - virtual void DoObjLoc(NetMsg* msg); - virtual void DoObjDamage(NetMsg* msg); - virtual void DoObjKill(NetMsg* msg); - virtual void DoObjSpawn(NetMsg* msg); - virtual void DoObjHyper(NetMsg* msg); - virtual void DoObjTarget(NetMsg* msg); - virtual void DoObjEmcon(NetMsg* msg); - virtual void DoSysDamage(NetMsg* msg); - virtual void DoSysStatus(NetMsg* msg); - - virtual void DoElemCreate(NetMsg* msg); - virtual void DoShipLaunch(NetMsg* msg); - virtual void DoNavData(NetMsg* msg); - virtual void DoNavDelete(NetMsg* msg); - - virtual void DoWepTrigger(NetMsg* msg); - virtual void DoWepRelease(NetMsg* msg); - virtual void DoWepDestroy(NetMsg* msg); - - virtual void DoCommMsg(NetMsg* msg); - virtual void DoChatMsg(NetMsg* msg); - virtual void DoSelfDestruct(NetMsg* msg); - - virtual void SendJoinRequest(); - - virtual bool DoJoinBacklog(NetJoinAnnounce* join_ann); - - DWORD server_id; - DWORD join_req_time; - List join_backlog; -}; - -// +--------------------------------------------------------------------+ - -#endif // NetGameClient_h - diff --git a/Stars45/NetGameServer.cpp b/Stars45/NetGameServer.cpp deleted file mode 100644 index ef33a90..0000000 --- a/Stars45/NetGameServer.cpp +++ /dev/null @@ -1,1202 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Server-Side Network Game Manager class -*/ - -#include "NetGameServer.h" -#include "NetServerConfig.h" -#include "NetLobbyServer.h" -#include "NetPlayer.h" -#include "NetUser.h" -#include "NetMsg.h" -#include "NetData.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Shield.h" -#include "Sim.h" -#include "SimEvent.h" -#include "Element.h" -#include "HUDView.h" -#include "RadioMessage.h" -#include "RadioView.h" -#include "Instruction.h" -#include "Hangar.h" -#include "FlightDeck.h" -#include "Mission.h" -#include "Text.h" - -#include "NetLayer.h" -#include "NetHost.h" -#include "NetPeer.h" -#include "NetUtil.h" -#include "Game.h" -#include "Clock.h" -#include "ContentBundle.h" -#include "Light.h" - -// +--------------------------------------------------------------------+ - -const int MAX_NET_FPS = 20; -const int MIN_NET_FRAME = 1000 / MAX_NET_FPS; - -// +--------------------------------------------------------------------+ - -NetGameServer::NetGameServer() -{ - Print("Constructing NetGameServer\n"); - - Text hostname = "0.0.0.0"; - WORD server_port = 11101; - - if (NetServerConfig::GetInstance()) { - hostname = NetServerConfig::GetInstance()->Hostname(); - server_port = NetServerConfig::GetInstance()->GetGamePort(); - } - - NetAddr server(hostname.data(), server_port); - - link = new NetLink(server); - - ListIter rgn_iter = sim->GetRegions(); - while (++rgn_iter) { - SimRegion* rgn = rgn_iter.value(); - - ListIter iter = rgn->Ships(); - while (++iter) { - Ship* s = iter.value(); - s->SetObjID(GetNextObjID()); - Observe(s); - ships.append(s); - } - } - - if (local_player) { - Observe(local_player); - objid = local_player->GetObjID(); - } -} - -NetGameServer::~NetGameServer() -{ - ListIter player = players; - while (++player) { - NetPlayer* p = player.value(); - - if (p->GetShip()) - p->GetShip()->SetRespawnCount(0); - - link->SendMessage(p->GetNetID(), NET_GAME_OVER, 0, 0, NetMsg::RELIABLE); - } - - Sleep(500); - - ListIter iter = ships; - while (++iter) { - Ship* s = iter.value(); - s->SetRespawnCount(0); - } - - zombies.destroy(); - ships.clear(); -} - -// +--------------------------------------------------------------------+ - -void -NetGameServer::ExecFrame() -{ - NetGame::ExecFrame(); - CheckSessions(); - - ListIter rgn_iter = sim->GetRegions(); - while (++rgn_iter) { - SimRegion* rgn = rgn_iter.value(); - - ListIter iter = rgn->Ships(); - while (++iter) { - Ship* s = iter.value(); - - if (s->GetObjID() == 0) { - s->SetObjID(GetNextObjID()); - Observe(s); - ships.append(s); - - NetJoinAnnounce join_ann; - join_ann.SetShip(s); - join_ann.SetName("Server A.I. Ship"); - SendData(&join_ann); - } - } - } - - - static DWORD time_mark = 0; - - if (!time_mark) time_mark = Clock::GetInstance()->RealTime(); - else if (Clock::GetInstance()->RealTime() - time_mark > 60000) { - time_mark = Clock::GetInstance()->RealTime(); - - if (link && players.size() > 0) { - Print("Server Stats\n-------------\n"); - Print(" packets sent %d\n", link->GetPacketsSent()); - Print(" packets recv %d\n", link->GetPacketsRecv()); - Print(" bytes sent %d\n", link->GetBytesSent()); - Print(" bytes recv %d\n", link->GetBytesRecv()); - Print(" retries %d\n", link->GetRetries()); - Print(" drops %d\n", link->GetDrops()); - Print(" avg lag %d msec\n", link->GetLag()); - } - } -} - -void -NetGameServer::CheckSessions() -{ - if (!link) - return; - - ListIter iter = players; - while (++iter) { - NetPlayer* player = iter.value(); - NetPeer* peer = link->FindPeer(player->GetNetID()); - - if (peer && (NetLayer::GetUTC() - peer->LastReceiveTime()) > NET_DISCONNECT_TIME) { - // announce drop: - NetPlayer* zombie = iter.removeItem(); - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameServer.remote-discon").data(), zombie->Name()); - - // tell everyone else: - NetQuitAnnounce quit_ann; - quit_ann.SetObjID(zombie->GetObjID()); - quit_ann.SetDisconnected(true); - SendData(&quit_ann); - - // return remote ship to ship pool: - Ship* s = zombie->GetShip(); - if (s) { - Observe(s); - ships.append(s); - s->SetNetworkControl(0); - zombie->SetShip(0); - - NetJoinAnnounce join_ann; - join_ann.SetShip(s); - join_ann.SetName("Server A.I. Ship"); - SendData(&join_ann); - } - - zombies.append(zombie); - } - } -} - -NetPlayer* -NetGameServer::FindZombieByObjID(DWORD objid) -{ - for (int i = 0; i < zombies.size(); i++) { - NetPlayer* p = zombies[i]; - - if (p->GetObjID() == objid) - return p; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -NetGameServer::DoJoinRequest(NetMsg* msg) -{ - if (!msg) return; - - bool unpause = players.isEmpty(); - - NetJoinRequest join_req; - if (join_req.Unpack(msg->Data())) { - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameServer::join-request").data(), join_req.GetName(), join_req.GetElement(), join_req.GetIndex()); - - DWORD nid = msg->NetID(); - Text name = join_req.GetName(); - Text serno = join_req.GetSerialNumber(); - Text elem_name = join_req.GetElement(); - int index = join_req.GetIndex(); - Ship* ship = 0; - Sim* sim = Sim::GetSim(); - - if (sim) { - Element* element = sim->FindElement(elem_name); - - if (element) - ship = element->GetShip(index); - } - - if (!ship) { - Print(" JOIN DENIED: could not locate ship for remote player\n"); - return; - } - - if (!ship->GetObjID()) { - Print(" JOIN DENIED: remote player requested ship with objid = 0\n"); - return; - } - - NetLobbyServer* lobby = NetLobbyServer::GetInstance(); - - if (lobby) { - NetUser* user = lobby->FindUserByName(name); - - if (!user) - user = lobby->FindUserByNetID(nid); - - if (!user) { - Print(" JOIN DENIED: remote player '%s' not found in lobby\n", name.data()); - return; - } - - else if (!user->IsAuthOK()) { - Print(" JOIN DENIED: remote player '%s' not authenticated\n", name.data()); - return; - } - } - - NetPlayer* remote_player = FindPlayerByNetID(nid); - if (remote_player && remote_player->GetShip() != ship) { - Print(" disconnecting remote player from ship '%s'\n", ship->Name()); - players.remove(remote_player); - delete remote_player; - remote_player = 0; - } - - if (!remote_player) { - Ignore(ship); - ships.remove(ship); - - remote_player = new NetPlayer(nid); - remote_player->SetName(name); - remote_player->SetSerialNumber(serno); - remote_player->SetObjID(ship->GetObjID()); - remote_player->SetShip(ship); - - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameServer::join-announce").data()); - Print("remote player name = %s\n", name.data()); - Print(" obj = %d\n", ship->GetObjID()); - Print(" ship = %s\n", ship->Name()); - - remote_player->SetObjID(ship->GetObjID()); - - // tell the new player about the server: - if (local_player) { - NetJoinAnnounce join_ann; - join_ann.SetShip(local_player); - join_ann.SetName(player_name); - link->SendMessage(remote_player->GetNetID(), join_ann.Pack(), NetJoinAnnounce::SIZE, NetMsg::RELIABLE); - } - - // tell the new player about the existing remote players: - ListIter iter = players; - while (++iter) { - Ship* s = iter->GetShip(); - - if (s) { - NetJoinAnnounce join_ann; - join_ann.SetShip(s); - join_ann.SetName(iter->Name()); - join_ann.SetObjID(iter->GetObjID()); - link->SendMessage(remote_player->GetNetID(), join_ann.Pack(), NetJoinAnnounce::SIZE, NetMsg::RELIABLE); - } - } - - // tell the new player about the A.I. controlled ships: - ListIter ai_iter = ships; - while (++ai_iter) { - Ship* s = ai_iter.value(); - if (s != local_player) { - NetJoinAnnounce join_ann; - join_ann.SetShip(s); - join_ann.SetName("Server A.I. Ship"); - link->SendMessage(remote_player->GetNetID(), join_ann.Pack(), NetJoinAnnounce::SIZE, NetMsg::RELIABLE); - } - } - - // make the new player an "existing" remote player: - players.append(remote_player); - - // tell existing players about the new player: - // NOTE, this also provides the net id to the new player! - iter.reset(); - while (++iter) { - Ship* s = remote_player->GetShip(); - - NetJoinAnnounce join_ann; - join_ann.SetShip(s); - join_ann.SetName(remote_player->Name()); - join_ann.SetObjID(remote_player->GetObjID()); - link->SendMessage(iter->GetNetID(), join_ann.Pack(), NetJoinAnnounce::SIZE, NetMsg::RELIABLE); - } - - if (unpause) { - auto game = Game::GetInstance(); - if (game) - game->Pause(false); - } - } - } -} - -void -NetGameServer::DoJoinAnnounce(NetMsg* msg) -{ - if (!msg) return; - - NetJoinAnnounce join_ann; - if (join_ann.Unpack(msg->Data())) { - Print("Server received Join Announce from '%s'\n", join_ann.GetName()); - } -} - -void -NetGameServer::DoQuitRequest(NetMsg* msg) -{ - if (!msg) return; - - NetPlayer* player = FindPlayerByNetID(msg->NetID()); - - if (player) { - NetPlayer* zombie = players.remove(player); - HUDView::Message(ContentBundle::GetInstance()->GetText("NetGameServer.remote-quit").data(), zombie->Name()); - - // tell everyone else: - NetQuitAnnounce quit_ann; - quit_ann.SetObjID(zombie->GetObjID()); - SendData(&quit_ann); - - // return remote ship to ship pool: - Ship* s = zombie->GetShip(); - if (s) { - Observe(s); - ships.append(s); - s->SetNetworkControl(0); - zombie->SetShip(0); - - NetJoinAnnounce join_ann; - join_ann.SetShip(s); - join_ann.SetName("Server A.I. Ship"); - SendData(&join_ann); - } - - zombies.append(zombie); - } - else { - Print("Quit Request from unknown player NetID: %08X\n", msg->NetID()); - } -} - -void -NetGameServer::DoQuitAnnounce(NetMsg* msg) -{ - if (!msg) return; - Print("Server received Quit Announce from NetID: %08x\n", msg->NetID()); -} - -void -NetGameServer::DoGameOver(NetMsg* msg) -{ - if (!msg) return; - Print("Server received Game Over from NetID: %08x\n", msg->NetID()); -} - -void -NetGameServer::DoDisconnect(NetMsg* msg) -{ - if (!msg) return; - Print("Server received Disconnect from NetID: %08x\n", msg->NetID()); -} - -void -NetGameServer::DoObjLoc(NetMsg* msg) -{ - if (!msg) return; - - NetObjLoc obj_loc; - obj_loc.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(obj_loc.GetObjID()); - if (player && player->GetShip()) { - player->DoObjLoc(&obj_loc); - } - - else { - player = FindZombieByObjID(obj_loc.GetObjID()); - - if (player) - SendDisconnect(player); - } -} - -void -NetGameServer::DoObjDamage(NetMsg* msg) -{ - if (!msg) return; - Print("Server received OBJ DAMAGE from NetID: %08x (ignored)\n", msg->NetID()); -} - -void -NetGameServer::DoObjKill(NetMsg* msg) -{ - if (!msg) return; - - NetObjKill obj_kill; - obj_kill.Unpack(msg->Data()); - - if (obj_kill.GetKillType() != NetObjKill::KILL_DOCK) { - Print("Server received OBJ KILL from NetID: %08x (ignored)\n", msg->NetID()); - return; - } - - Ship* ship = FindShipByObjID(obj_kill.GetObjID()); - if (ship) { - Ship* killer = FindShipByObjID(obj_kill.GetKillerID()); - Text killer_name = ContentBundle::GetInstance()->GetText("NetGameServer.unknown"); - - if (killer) - killer_name = killer->Name(); - - ShipStats* killee = ShipStats::Find(ship->Name()); - if (killee) - killee->AddEvent(SimEvent::DOCK, killer_name); - - FlightDeck* deck = killer->GetFlightDeck(obj_kill.GetFlightDeck()); - sim->NetDockShip(ship, killer, deck); - } -} - -void -NetGameServer::DoObjSpawn(NetMsg* msg) -{ - if (!msg) return; - Print("Server received OBJ SPAWN from NetID: %08x (ignored)\n", msg->NetID()); -} - -void -NetGameServer::DoObjHyper(NetMsg* msg) -{ - if (!msg) return; - Print("Server received OBJ HYPER from NetID: %d\n", msg->NetID()); - - NetObjHyper obj_hyper; - obj_hyper.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(obj_hyper.GetObjID()); - if (player && player->GetShip()) { - if (player->DoObjHyper(&obj_hyper)) { - SendData(&obj_hyper); - } - } - else { - player = FindZombieByObjID(obj_hyper.GetObjID()); - - if (player) - SendDisconnect(player); - } -} - -void -NetGameServer::DoObjTarget(NetMsg* msg) -{ - if (!msg) return; - - NetObjTarget obj_target; - obj_target.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(obj_target.GetObjID()); - if (player) { - player->DoObjTarget(&obj_target); - } - else { - player = FindZombieByObjID(obj_target.GetObjID()); - - if (player) - SendDisconnect(player); - } -} - -void -NetGameServer::DoObjEmcon(NetMsg* msg) -{ - if (!msg) return; - - NetObjEmcon obj_emcon; - obj_emcon.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(obj_emcon.GetObjID()); - if (player) { - player->DoObjEmcon(&obj_emcon); - } - else { - player = FindZombieByObjID(obj_emcon.GetObjID()); - - if (player) - SendDisconnect(player); - } -} - -// +--------------------------------------------------------------------+ - -void -NetGameServer::DoSysDamage(NetMsg* msg) -{ - if (!msg) return; - - NetSysDamage sys_damage; - sys_damage.Unpack(msg->Data()); - - NetPlayer* player = FindZombieByObjID(sys_damage.GetObjID()); - - if (player) - SendDisconnect(player); -} - -void -NetGameServer::DoSysStatus(NetMsg* msg) -{ - if (!msg) return; - - NetSysStatus sys_status; - sys_status.Unpack(msg->Data()); - - Ship* ship = FindShipByObjID(sys_status.GetObjID()); - NetPlayer* player = FindPlayerByNetID(msg->NetID()); - - if (ship) { - if (!player || ship->GetObjID() != player->GetObjID()) { - /** - Print("NetGameServer::DoSysStatus - received request for ship '%s' from wrong player %s\n", - ship->Name(), player ? player->Name() : "null"); - **/ - - return; - } - - player->DoSysStatus(&sys_status); - - // rebroadcast: - System* sys = ship->GetSystem(sys_status.GetSystem()); - NetUtil::SendSysStatus(ship, sys); - } - - else { - player = FindZombieByObjID(sys_status.GetObjID()); - - if (player) - SendDisconnect(player); - } -} - -// +--------------------------------------------------------------------+ - -void -NetGameServer::DoElemRequest(NetMsg* msg) -{ - if (!msg) return; - - NetElemRequest elem_request; - elem_request.Unpack(msg->Data()); - - Sim* sim = Sim::GetSim(); - Element* elem = sim->FindElement(elem_request.GetName()); - - if (elem) { - int squadron = -1; - int slots[] = { -1,-1,-1,-1 }; - Ship* carrier = elem->GetCarrier(); - - if (carrier && carrier->GetHangar()) { - Hangar* hangar = carrier->GetHangar(); - - for (int i = 0; i < 4; i++) { - hangar->FindSquadronAndSlot(elem->GetShip(i+1), squadron, slots[i]); - } - } - - NetUtil::SendElemCreate(elem, squadron, slots, false, true); - } -} - -// +--------------------------------------------------------------------+ - -void -NetGameServer::DoElemCreate(NetMsg* msg) -{ - if (!msg) return; - - NetElemCreate elem_create; - elem_create.Unpack(msg->Data()); - - Sim* sim = Sim::GetSim(); - Element* elem = sim->CreateElement(elem_create.GetName(), - elem_create.GetIFF(), - elem_create.GetType()); - - int* load = elem_create.GetLoadout(); - int* slots = elem_create.GetSlots(); - int squadron = elem_create.GetSquadron(); - int code = elem_create.GetObjCode(); - Text target = elem_create.GetObjective(); - bool alert = elem_create.GetAlert(); - - elem->SetIntelLevel(elem_create.GetIntel()); - elem->SetLoadout(load); - - if (code > Instruction::RTB || target.length() > 0) { - Instruction* obj = new Instruction(code, target); - elem->AddObjective(obj); - } - - Ship* carrier = sim->FindShip(elem_create.GetCarrier()); - if (carrier) { - elem->SetCarrier(carrier); - - Hangar* hangar = carrier->GetHangar(); - if (hangar) { - Text squadron_name = hangar->SquadronName(squadron); - elem->SetSquadron(squadron_name); - - FlightDeck* deck = 0; - int queue = 1000; - - for (int i = 0; i < carrier->NumFlightDecks(); i++) { - FlightDeck* d = carrier->GetFlightDeck(i); - - if (d && d->IsLaunchDeck()) { - int dq = hangar->PreflightQueue(d); - - if (dq < queue) { - queue = dq; - deck = d; - } - } - } - - for (int i = 0; i < 4; i++) { - int slot = slots[i]; - if (slot > -1) { - hangar->GotoAlert(squadron, slot, deck, elem, load, !alert); - } - } - } - } - - NetUtil::SendElemCreate(elem, - elem_create.GetSquadron(), - elem_create.GetSlots(), - elem_create.GetAlert()); -} - -void -NetGameServer::DoShipLaunch(NetMsg* msg) -{ - if (!msg) return; - - NetShipLaunch ship_launch; - ship_launch.Unpack(msg->Data()); - - Sim* sim = Sim::GetSim(); - int squadron = ship_launch.GetSquadron(); - int slot = ship_launch.GetSlot(); - - NetPlayer* player = FindPlayerByObjID(ship_launch.GetObjID()); - if (player) { - Ship* carrier = player->GetShip(); - - if (carrier) { - Hangar* hangar = carrier->GetHangar(); - - if (hangar) { - hangar->Launch(squadron, slot); - } - - NetUtil::SendShipLaunch(carrier, squadron, slot); - } - } -} - -void -NetGameServer::DoNavData(NetMsg* msg) -{ - if (!msg) return; - - NetNavData nav_data; - nav_data.Unpack(msg->Data()); - - Element* elem = sim->FindElement(nav_data.GetElem()); - - if (elem) { - if (nav_data.IsAdd()) { - Instruction* navpt = new Instruction(*nav_data.GetNavPoint()); - Instruction* after = 0; - int index = nav_data.GetIndex(); - - if (index >= 0 && index < elem->GetFlightPlan().size()) - after = elem->GetFlightPlan().at(index); - - elem->AddNavPoint(navpt, after, false); - } - - else { - Instruction* navpt = nav_data.GetNavPoint(); - Instruction* exist = 0; - int index = nav_data.GetIndex(); - - if (navpt && index >= 0 && index < elem->GetFlightPlan().size()) { - exist = elem->GetFlightPlan().at(index); - *exist = *navpt; - } - } - - SendData(&nav_data); - } -} - -void -NetGameServer::DoNavDelete(NetMsg* msg) -{ - if (!msg) return; - - NetNavDelete nav_delete; - nav_delete.Unpack(msg->Data()); - - Element* elem = sim->FindElement(nav_delete.GetElem()); - - if (elem) { - int index = nav_delete.GetIndex(); - - if (index < 0) { - elem->ClearFlightPlan(false); - } - - else if (index < elem->FlightPlanLength()) { - Instruction* npt = elem->GetFlightPlan().at(index); - elem->DelNavPoint(npt, false); - } - - SendData(&nav_delete); - } -} - -void -NetGameServer::DoWepTrigger(NetMsg* msg) -{ - if (!msg) return; - - NetWepTrigger trigger; - trigger.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(trigger.GetObjID()); - if (player) { - player->DoWepTrigger(&trigger); - } - else { - player = FindZombieByObjID(trigger.GetObjID()); - - if (player) - SendDisconnect(player); - } -} - -void -NetGameServer::DoWepRelease(NetMsg* msg) -{ - if (!msg) return; - - NetWepRelease release; - release.Unpack(msg->Data()); - - NetPlayer* player = FindPlayerByObjID(release.GetObjID()); - if (player) { - player->DoWepRelease(&release); - } - else { - player = FindZombieByObjID(release.GetObjID()); - - if (player) - SendDisconnect(player); - } - - Print("WEP RELEASE on server? objid = %d\n", release.GetObjID()); -} - -void -NetGameServer::DoWepDestroy(NetMsg* msg) -{ -} - -void -NetGameServer::DoCommMsg(NetMsg* msg) -{ - if (!msg) return; - - NetCommMsg comm_msg; - comm_msg.Unpack(msg->Data()); - - RadioMessage* radio_msg = comm_msg.GetRadioMessage(); - - NetPlayer* player = FindPlayerByObjID(comm_msg.GetObjID()); - if (player && radio_msg) { - player->DoCommMessage(&comm_msg); - - int channel = comm_msg.GetRadioMessage()->Channel(); - - ListIter dst = players; - while (++dst) { - NetPlayer* remote_player = dst.value(); - if (remote_player->GetNetID() && - (channel == 0 || channel == remote_player->GetIFF())) { - - BYTE* data = comm_msg.Pack(); - int size = comm_msg.Length(); - - link->SendMessage(remote_player->GetNetID(), data, size, NetMsg::RELIABLE); - } - } - } - else { - player = FindZombieByObjID(comm_msg.GetObjID()); - - if (player) - SendDisconnect(player); - } -} - -void -NetGameServer::DoChatMsg(NetMsg* msg) -{ - if (!msg) return; - - NetChatMsg chat_msg; - chat_msg.Unpack(msg->Data()); - - RouteChatMsg(chat_msg); -} - -void -NetGameServer::RouteChatMsg(NetChatMsg& chat_msg) -{ - DWORD dst_id = chat_msg.GetDstID(); - - // broadcast or team: - if (dst_id == 0xffff || dst_id <= 10) { - BYTE* data = chat_msg.Pack(); - int size = chat_msg.Length(); - - ListIter dst = players; - while (++dst) { - NetPlayer* remote_player = dst.value(); - if (remote_player->GetNetID() && chat_msg.GetName() != remote_player->Name()) { - if (dst_id == 0xffff || dst_id == 0 || remote_player->GetIFF() == (int) dst_id-1) - link->SendMessage(remote_player->GetNetID(), data, size); - } - } - - if (local_player && (dst_id == 0xffff || dst_id == 0 || local_player->GetIFF() == (int) dst_id-1)) { - Text name = chat_msg.GetName(); - if (name.length() < 1) - name = ContentBundle::GetInstance()->GetText("NetGameServer.chat.unknown"); - - // don't echo general messages from the local player. - // they are already displayed by the chat entry code - // in starshatter.cpp - - if (name != player_name) - HUDView::Message("%s> %s", name.data(), chat_msg.GetText().data()); - } - } - - // direct to local player: - else if (local_player && local_player->GetObjID() == dst_id) { - Text name = chat_msg.GetName(); - if (name.length() < 1) - name = ContentBundle::GetInstance()->GetText("NetGameServer.chat.unknown"); - - HUDView::Message("%s> %s", name.data(), chat_msg.GetText().data()); - } - - // ship-to-ship, but not to local player: - else if (!local_player || local_player->GetObjID() != dst_id) { - NetPlayer* remote_player = FindPlayerByObjID(dst_id); - if (remote_player && remote_player->GetNetID()) { - BYTE* data = chat_msg.Pack(); - int size = chat_msg.Length(); - link->SendMessage(remote_player->GetNetID(), data, size); - } - - // record message in server log: - ::Print("%s> %s\n", chat_msg.GetName().data(), chat_msg.GetText().data()); - } - - if (dst_id == 0xffff) - return; - - // record message in chat log: - NetLobbyServer* lobby = NetLobbyServer::GetInstance(); - - if (!lobby) - return; - - NetUser* user = lobby->FindUserByName(chat_msg.GetName()); - - if (user) - lobby->AddChat(user, chat_msg.GetText(), false); // don't re-route -} - -// +--------------------------------------------------------------------+ - -const char* FormatGameTime(); - -void -NetGameServer::DoSelfDestruct(NetMsg* msg) -{ - if (!msg) return; - - NetSelfDestruct self_destruct; - self_destruct.Unpack(msg->Data()); - - Ship* ship = FindShipByObjID(self_destruct.GetObjID()); - NetPlayer* player = FindPlayerByNetID(msg->NetID()); - - if (ship) { - if (!player || ship->GetObjID() != player->GetObjID()) { - Print("NetGameServer::DoSelfDestruct - received request for ship '%s' from wrong player %s\n", - ship->Name(), player ? player->Name() : "null"); - - return; - } - - ship->InflictNetDamage(self_destruct.GetDamage()); - - SendData(&self_destruct); - - int ship_destroyed = (!ship->InTransition() && ship->Integrity() < 1.0f); - - // then delete the ship: - if (ship_destroyed) { - NetUtil::SendObjKill(ship, 0, NetObjKill::KILL_MISC); - Print(" %s Self Destruct (%s)\n", ship->Name(), FormatGameTime()); - - ShipStats* killee = ShipStats::Find(ship->Name()); - if (killee) - killee->AddEvent(SimEvent::DESTROYED, ship->Name()); - - ship->DeathSpiral(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetGameServer::Send() -{ - if (players.isEmpty()) - return; - - DWORD time = Clock::GetInstance()->GameTime(); - - // don't flood the network... - if (time - last_send_time < MIN_NET_FRAME) - return; - - last_send_time = time; - - // tell the remote players where *we* are: - if (local_player && !local_player->IsNetObserver() && objid) { - double r, p, y; - local_player->Cam().Orientation().ComputeEulerAngles(r,p,y); - - NetObjLoc obj_loc; - obj_loc.SetObjID(objid); - obj_loc.SetLocation(local_player->Location()); - obj_loc.SetVelocity(local_player->Velocity()); - obj_loc.SetOrientation(Point(r,p,y)); - obj_loc.SetThrottle(local_player->Throttle() > 10); - obj_loc.SetAugmenter(local_player->Augmenter()); - obj_loc.SetGearDown(local_player->IsGearDown()); - - Shield* shield = local_player->GetShield(); - if (shield) - obj_loc.SetShield((int) shield->GetPowerLevel()); - else - obj_loc.SetShield(0); - - SendData(&obj_loc); - } - - // tell each remote player where all the others are: - ListIter src = players; - while (++src) { - NetPlayer* player = src.value(); - - Ship* player_ship = player->GetShip(); - - if (player_ship) { - double r, p, y; - player_ship->Cam().Orientation().ComputeEulerAngles(r,p,y); - - NetObjLoc obj_loc; - obj_loc.SetObjID(player->GetObjID()); - obj_loc.SetLocation(player_ship->Location()); - obj_loc.SetVelocity(player_ship->Velocity()); - obj_loc.SetOrientation(Point(r,p,y)); - obj_loc.SetThrottle(player_ship->Throttle() > 10); - obj_loc.SetAugmenter(player_ship->Augmenter()); - obj_loc.SetGearDown(player_ship->IsGearDown()); - - Shield* shield = player_ship->GetShield(); - if (shield) - obj_loc.SetShield((int) shield->GetPowerLevel()); - else - obj_loc.SetShield(0); - - BYTE* obj_loc_data = obj_loc.Pack(); - - ListIter dst = players; - while (++dst) { - NetPlayer* remote_player = dst.value(); - if (remote_player->GetNetID() && remote_player != player) - link->SendMessage(remote_player->GetNetID(), obj_loc_data, NetObjLoc::SIZE); - } - } - } - - // tell each remote player where all the A.I. ships are: - ListIter ai_iter = ships; - while (++ai_iter) { - Ship* s = ai_iter.value(); - - if (s && !s->IsStatic()) { - double r, p, y; - s->Cam().Orientation().ComputeEulerAngles(r,p,y); - - NetObjLoc obj_loc; - obj_loc.SetObjID(s->GetObjID()); - obj_loc.SetLocation(s->Location()); - obj_loc.SetVelocity(s->Velocity()); - obj_loc.SetOrientation(Point(r,p,y)); - obj_loc.SetThrottle(s->Throttle() > 10); - obj_loc.SetAugmenter(s->Augmenter()); - obj_loc.SetGearDown(s->IsGearDown()); - - Shield* shield = s->GetShield(); - if (shield) - obj_loc.SetShield((int) shield->GetPowerLevel()); - else - obj_loc.SetShield(0); - - SendData(&obj_loc); - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetGameServer::SendData(NetData* net_data) -{ - if (net_data) { - BYTE* data = net_data->Pack(); - int size = net_data->Length(); - BYTE flags = 0; - bool all = true; // include player with objid in net_data? - DWORD oid = net_data->GetObjID(); - - BYTE msg_type = net_data->Type(); - - if (msg_type >= 0x10) - flags |= NetMsg::RELIABLE; - - if (msg_type == NET_WEP_TRIGGER || - msg_type == NET_COMM_MESSAGE || - msg_type == NET_CHAT_MESSAGE || - msg_type == NET_OBJ_HYPER || - msg_type == NET_ELEM_CREATE || - msg_type == NET_NAV_DATA || - msg_type == NET_NAV_DELETE) { - all = false; - } - - ListIter dst = players; - while (++dst) { - NetPlayer* remote_player = dst.value(); - if (remote_player->GetNetID() && (all || oid != remote_player->GetObjID())) - link->SendMessage(remote_player->GetNetID(), data, size, flags); - } - } -} - -void -NetGameServer::SendDisconnect(NetPlayer* zombie) -{ - if (zombie) { - NetDisconnect disconnect; - BYTE* data = disconnect.Pack(); - int size = disconnect.Length(); - BYTE flags = NetMsg::RELIABLE; - - if (zombie->GetNetID()) - link->SendMessage(zombie->GetNetID(), data, size, flags); - } -} - -// +--------------------------------------------------------------------+ - -bool -NetGameServer::Update(SimObject* obj) -{ - if (obj->Type() == SimObject::SIM_SHIP) { - Ship* s = (Ship*) obj; - if (local_player == s) - local_player = 0; - - if (ships.contains(s)) - ships.remove(s); - } - - return SimObserver::Update(obj); -} - -const char* -NetGameServer::GetObserverName() const -{ - return "NetGameServer"; -} - -// +--------------------------------------------------------------------+ - -void -NetGameServer::Respawn(DWORD oid, Ship* spawn) -{ - if (!oid || !spawn) return; - - Print("NetGameServer::Respawn(%d, %s)\n", oid, spawn->Name()); - spawn->SetObjID(oid); - Observe(spawn); - - NetPlayer* p = FindPlayerByObjID(oid); - if (p) - p->SetShip(spawn); - else - ships.append(spawn); - - if (objid == oid) { - Print(" RESPAWN LOCAL PLAYER\n\n"); - local_player = spawn; - } -} diff --git a/Stars45/NetGameServer.h b/Stars45/NetGameServer.h deleted file mode 100644 index 12b5827..0000000 --- a/Stars45/NetGameServer.h +++ /dev/null @@ -1,89 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Server-Side Network Game Manager class -*/ - -#ifndef NetGameServer_h -#define NetGameServer_h - -#include "NetGame.h" -#include "SimObject.h" - -// +--------------------------------------------------------------------+ - -class NetChatMsg; - -// +--------------------------------------------------------------------+ - -class NetGameServer : public NetGame, public SimObserver -{ -public: - NetGameServer(); - virtual ~NetGameServer(); - - virtual bool IsClient() const { return false; } - virtual bool IsServer() const { return true; } - - virtual void ExecFrame(); - virtual void CheckSessions(); - - virtual void Send(); - virtual void SendData(NetData* data); - virtual void Respawn(DWORD objid, Ship* spawn); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - virtual void RouteChatMsg(NetChatMsg& chat_msg); - -protected: - virtual void DoJoinRequest(NetMsg* msg); - virtual void DoJoinAnnounce(NetMsg* msg); - virtual void DoQuitRequest(NetMsg* msg); - virtual void DoQuitAnnounce(NetMsg* msg); - virtual void DoGameOver(NetMsg* msg); - virtual void DoDisconnect(NetMsg* msg); - - virtual void DoObjLoc(NetMsg* msg); - virtual void DoObjDamage(NetMsg* msg); - virtual void DoObjKill(NetMsg* msg); - virtual void DoObjSpawn(NetMsg* msg); - virtual void DoObjHyper(NetMsg* msg); - virtual void DoObjTarget(NetMsg* msg); - virtual void DoObjEmcon(NetMsg* msg); - virtual void DoSysDamage(NetMsg* msg); - virtual void DoSysStatus(NetMsg* msg); - - virtual void DoElemRequest(NetMsg* msg); - virtual void DoElemCreate(NetMsg* msg); - virtual void DoShipLaunch(NetMsg* msg); - virtual void DoNavData(NetMsg* msg); - virtual void DoNavDelete(NetMsg* msg); - - virtual void DoWepTrigger(NetMsg* msg); - virtual void DoWepRelease(NetMsg* msg); - virtual void DoWepDestroy(NetMsg* msg); - - virtual void DoCommMsg(NetMsg* msg); - virtual void DoChatMsg(NetMsg* msg); - virtual void DoSelfDestruct(NetMsg* msg); - - virtual NetPlayer* FindZombieByObjID(DWORD objid); - virtual void SendDisconnect(NetPlayer* zombie); - - List ships; - List zombies; -}; - -// +--------------------------------------------------------------------+ - -#endif // NetGameServer_h - diff --git a/Stars45/NetLobby.cpp b/Stars45/NetLobby.cpp deleted file mode 100644 index 81eecae..0000000 --- a/Stars45/NetLobby.cpp +++ /dev/null @@ -1,628 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Base Class for Multiplayer Game Lobby classes -*/ - -#include "NetLobby.h" -#include "NetLobbyClient.h" -#include "NetLobbyServer.h" -#include "NetClientConfig.h" -#include "NetServerConfig.h" -#include "NetChat.h" -#include "NetUser.h" - -#include "NetMsg.h" -#include "NetData.h" -#include "NetLayer.h" - -#include "Player.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Campaign.h" -#include "Element.h" -#include "Mission.h" - -#include "NetHost.h" -#include "Game.h" -#include "Light.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ - -const int MAX_NET_FPS = 50; -const int MIN_NET_FRAME = 1000 / MAX_NET_FPS; - -const DWORD SHIP_ID_START = 0x0010; -const DWORD SHOT_ID_START = 0x0400; - -static NetLobby* instance = 0; - -static DWORD ship_id_key = SHIP_ID_START; -static DWORD shot_id_key = SHOT_ID_START; - -// +--------------------------------------------------------------------+ - -NetLobby::NetLobby(bool temporary) -: link(0), local_user(0), last_send_time(0), active(true), -selected_mission(0), mission(0), status(0) -{ - if (!temporary) - instance = this; -} - -NetLobby::~NetLobby() -{ - if (instance == this) - instance = 0; - - unit_map.destroy(); - users.destroy(); - campaigns.destroy(); - chat_log.destroy(); - - if (local_user) { - delete local_user; - local_user = 0; - } - - if (link) { - delete link; - link = 0; - } - - mission = 0; -} - -// +--------------------------------------------------------------------+ - -NetLobby* -NetLobby::GetInstance() -{ - return instance; -} - -// +--------------------------------------------------------------------+ - -void -NetLobby::ExecFrame() -{ - Send(); - Recv(); -} - -void -NetLobby::Recv() -{ - NetMsg* msg = link->GetMessage(); - - while (msg) { - if (active) { - NetPeer* peer = link->FindPeer(msg->NetID()); - - static char buffer[256]; - char* text = 0; - - if (msg->Length() > 2) { - if (msg->Length() < 250) { - ZeroMemory(buffer, sizeof(buffer)); - CopyMemory(buffer, msg->Data()+2, msg->Length()-2); - text = buffer; - } - else if (msg->Length() < 1024 * 1024) { - text = new char[msg->Length()]; - ZeroMemory(text, msg->Length()); - CopyMemory(text, msg->Data()+2, msg->Length()-2); - } - } - - switch (msg->Type()) { - case NET_LOBBY_PING: DoPing(peer, text); break; - case NET_LOBBY_SERVER_INFO: DoServerInfo(peer, text); break; - case NET_LOBBY_SERVER_MODS: DoServerMods(peer, text); break; - case NET_LOBBY_LOGIN: DoLogin(peer, text); break; - case NET_LOBBY_LOGOUT: DoLogout(peer, text); break; - - case NET_LOBBY_AUTH_USER: DoAuthUser(peer, text); break; - case NET_LOBBY_USER_AUTH: DoUserAuth(peer, text); break; - - case NET_LOBBY_CHAT: DoChat(peer, text); break; - case NET_LOBBY_USER_LIST: DoUserList(peer, text); break; - case NET_LOBBY_BAN_USER: DoBanUser(peer, text); break; - case NET_LOBBY_MISSION_LIST: DoMissionList(peer, text); break; - case NET_LOBBY_MISSION_SELECT: DoMissionSelect(peer, text); break; - case NET_LOBBY_MISSION_DATA: DoMissionData(peer, text); break; - case NET_LOBBY_UNIT_LIST: DoUnitList(peer, text); break; - case NET_LOBBY_MAP_UNIT: DoMapUnit(peer, text); break; - case NET_LOBBY_GAME_START: DoGameStart(peer, text); break; - case NET_LOBBY_GAME_STOP: DoGameStop(peer, text); break; - case NET_LOBBY_EXIT: DoExit(peer, text); break; - } - - if (text && text != buffer) - delete [] text; - } - - delete msg; - msg = link->GetMessage(); - } -} - -// +--------------------------------------------------------------------+ - -void -NetLobby::Send() -{ -} - -// +-------------------------------------------------------------------+ - -DWORD -NetLobby::GetLag() -{ - if (link) - return link->GetLag(); - - return 0; -} - -// +-------------------------------------------------------------------+ - -void -NetLobby::SetLocalUser(NetUser* user) -{ - if (user != local_user) { - if (local_user) { - delete local_user; - local_user = 0; - } - - if (user) { - local_user = user; - local_user->SetHost(true); - } - } -} - -void -NetLobby::BanUser(NetUser* user) -{ -} - -void -NetLobby::AddUser(NetUser* user) -{ - if (user) { - if (user != local_user && !users.contains(user)) { - users.append(user); - Print("NetLobby User Logged In - name: '%s' id: %d host: %d\n", - user->Name().data(), - user->GetNetID(), - user->IsHost()); - } - } -} - -void -NetLobby::DelUser(NetUser* user) -{ - if (user) { - if (user == local_user) - local_user = 0; - - else - users.remove(user); - - UnmapUnit(user->Name()); - - Print("NetLobby User Logged Out - name: '%s' id: %d host: %d\n", - user->Name().data(), - user->GetNetID(), - user->IsHost()); - - user->SetHost(false); - delete user; - } -} - -int -NetLobby::NumUsers() -{ - int num = 0; - - if (local_user) - num = 1; - - num += users.size(); - - return num; -} - -NetUser* -NetLobby::GetHost() -{ - for (int i = 0; i < users.size(); i++) { - NetUser* u = users[i]; - - if (u->IsHost()) - return u; - } - - return 0; -} - -bool -NetLobby::HasHost() -{ - bool host = false; - - if (local_user && local_user->IsHost()) - host = true; - - for (int i = 0; i < users.size() && !host; i++) { - if (users[i]->IsHost()) - host = true; - } - - if (status > NetServerInfo::LOBBY) - host = true; - - return host; -} - -bool -NetLobby::SetUserHost(NetUser* user, bool host) -{ - bool ok = false; - - if (user && users.contains(user)) { - if (host && !HasHost()) { - user->SetHost(true); - ok = true; - } - else if (!host) { - user->SetHost(false); - ok = true; - } - } - - return ok; -} - -NetUser* -NetLobby::GetLocalUser() -{ - return local_user; -} - -List& -NetLobby::GetUsers() -{ - return users; -} - -List& -NetLobby::GetServerMods() -{ - return server_mods; -} - -NetUser* -NetLobby::FindUserByAddr(const NetAddr& addr) -{ - for (int i = 0; i < users.size(); i++) { - NetUser* u = users[i]; - if (u->GetAddress().IPAddr() == addr.IPAddr()) - return u; - } - - return 0; -} - -NetUser* -NetLobby::FindUserByName(const char* name) -{ - if (local_user && !_stricmp(local_user->Name(), name)) - return local_user; - - for (int i = 0; i < users.size(); i++) { - NetUser* u = users[i]; - if (!_stricmp(u->Name(), name)) - return u; - } - - return 0; -} - -NetUser* -NetLobby::FindUserByNetID(DWORD id) -{ - for (int i = 0; i < users.size(); i++) { - NetUser* u = users[i]; - if (u->GetNetID() == id) - return u; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -NetLobby::ParseMsg(Text msg, List& params) -{ - params.destroy(); - - BlockReader reader(msg.data(), msg.length()); - Scanner lexer(&reader); - - Token name = lexer.Get(); - - while (name.type() == Token::AlphaIdent) { - Token value = lexer.Get(); - if (value.type() != Token::EOT) { - Text val = value.symbol(); - - if (val[0] == '"' && val[val.length()-1] == '"') { - val = val.substring(1, val.length()-2); - } - - NetLobbyParam* param = new NetLobbyParam(name.symbol(), val); - params.append(param); - - name = lexer.Get(); - } - - else { - name = Token(Token::EOT); - } - } -} - -// +--------------------------------------------------------------------+ - -bool -NetLobby::Ping() -{ - Sleep(500); - return false; -} - -// +-------------------------------------------------------------------+ - -void -NetLobby::AddChat(NetUser* user, const char* msg, bool route) -{ - if (user && msg && *msg) - chat_log.append(new NetChatEntry(user, msg)); -} - -List& -NetLobby::GetChat() -{ - return chat_log; -} - -void -NetLobby::ClearChat() -{ - chat_log.destroy(); -} - -// +-------------------------------------------------------------------+ - -List& -NetLobby::GetCampaigns() -{ - return campaigns; -} - -// +-------------------------------------------------------------------+ - -void -NetLobby::AddUnitMap(MissionElement* elem, int index) -{ - if (elem) - unit_map.append(new NetUnitEntry(elem, index)); -} - -List& -NetLobby::GetUnitMap() -{ - return unit_map; -} - -void -NetLobby::ClearUnitMap() -{ - unit_map.destroy(); -} - -void -NetLobby::MapUnit(int n, const char* user, bool lock) -{ - if (n >= 0 && n < unit_map.size()) { - NetUnitEntry* unit = unit_map[n]; - - if (!lock && unit->GetLocked()) - return; - - if (user && *user) { - for (int i = 0; i < unit_map.size(); i++) { - NetUnitEntry* u = unit_map[i]; - if (u->GetUserName() == user) { - if (!lock && u->GetLocked()) return; - u->SetUserName(""); - } - } - } - - unit->SetUserName(user); - unit->SetLock(lock); - } -} - -void -NetLobby::UnmapUnit(const char* user) -{ - if (user && *user) { - for (int i = 0; i < unit_map.size(); i++) { - NetUnitEntry* u = unit_map[i]; - if (u->GetUserName() == user) { - u->SetUserName(""); - u->SetLock(false); - return; - } - } - } -} - -bool -NetLobby::IsMapped(const char* user) -{ - if (user && *user) { - for (int i = 0; i < unit_map.size(); i++) { - NetUnitEntry* u = unit_map[i]; - if (u->GetUserName() == user) { - return true; - } - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -void -NetLobby::SelectMission(DWORD id) -{ - if (selected_mission != id) { - selected_mission = id; - ClearUnitMap(); - - int mission_id = selected_mission; - int campaign_id = -1; - Campaign* campaign = 0; - mission = 0; - - campaign_id = mission_id >> NET_CAMPAIGN_SHIFT; - mission_id = mission_id & NET_MISSION_MASK; - - ListIter c_iter = Campaign::GetAllCampaigns(); - while (++c_iter) { - campaign = c_iter.value(); - - if (campaign->GetCampaignId() == campaign_id) { - mission = campaign->GetMission(mission_id); - break; - } - } - - if (campaign && mission) { - Campaign::SelectCampaign(campaign->Name()); - campaign->SetMissionId(mission_id); - - ListIter iter = mission->GetElements(); - while (++iter) { - MissionElement* elem = iter.value(); - - if (elem->IsPlayable()) { - if (elem->Count() == 1) { - AddUnitMap(elem); - } - else { - for (int i = 0; i < elem->Count(); i++) - AddUnitMap(elem, i+1); - } - } - } - } - - else { - selected_mission = 0; - mission = 0; - } - } -} - -// +--------------------------------------------------------------------+ - -bool -NetLobby::IsNetLobbyClient() -{ - if (instance) - return instance->IsClient(); - return false; -} - -bool -NetLobby::IsNetLobbyServer() -{ - if (instance) - return instance->IsServer(); - return false; -} - -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ -// +-------------------------------------------------------------------+ - -NetUnitEntry::NetUnitEntry(MissionElement* e, int n) -: index(n), lock(false), lives(1), hull(100), role(0) -{ - if (e) { - elem = e->Name(); - iff = e->GetIFF(); - - if (e->GetDesign()) - design = e->GetDesign()->name; - } -} - -NetUnitEntry::NetUnitEntry(const char* e, const char* d, int i, int n) -: elem(e), design(d), iff(i), index(n), lock(false), lives(1), -hull(100), role(0) -{ } - -NetUnitEntry::~NetUnitEntry() -{ } - -Text -NetUnitEntry::GetDescription() const -{ - if (elem) { - static char buffer[1024]; - - sprintf_s(buffer, "name \"%s\" index %d design \"%s\" iff %d user \"%s\" lives %d hull %d role %d lock %d ", - elem.data(), - index, - design.data(), - iff, - user.data(), - lives, - hull, - role, - lock); - - return buffer; - } - - return "name \"Not Found\" "; -} - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -NetServerInfo::NetServerInfo() -: nplayers(0), hosted(0), status(0), port(0), gameport(0), save(false), ping_time(0) -{ } - diff --git a/Stars45/NetLobby.h b/Stars45/NetLobby.h deleted file mode 100644 index 028e931..0000000 --- a/Stars45/NetLobby.h +++ /dev/null @@ -1,288 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Base Class for Multiplayer Game Lobby classes -*/ - -#ifndef NetLobby_h -#define NetLobby_h - -#include "Types.h" -#include "NetLink.h" -#include "List.h" - -#define NET_CAMPAIGN_SHIFT 12 -#define NET_MISSION_MASK 0xfff -#define NET_DISCONNECT_TIME 30 - -// +-------------------------------------------------------------------+ - -class Campaign; -class Mission; -class MissionElement; -class MissionInfo; -class NetCampaignInfo; -class NetChatEntry; -class NetUser; -class NetUnitEntry; -class NetLobbyParam; -class ModInfo; - -// +--------------------------------------------------------------------+ - -class NetLobby -{ -public: - static const char* TYPENAME() { return "NetLobby"; } - - NetLobby(bool temporary = false); - virtual ~NetLobby(); - - virtual bool IsClient() const { return false; } - virtual bool IsServer() const { return false; } - virtual bool IsActive() const { return active; } - - virtual void ExecFrame(); - virtual void Recv(); - virtual void Send(); - virtual int GetLastError() const { return 0; } - - virtual NetUser* FindUserByAddr(const NetAddr& addr); - virtual NetUser* FindUserByName(const char* name); - virtual NetUser* FindUserByNetID(DWORD id); - - virtual void BanUser(NetUser* user); - virtual void AddUser(NetUser* user); - virtual void DelUser(NetUser* user); - virtual bool SetUserHost(NetUser* user, bool host); - virtual int NumUsers(); - virtual NetUser* GetHost(); - virtual bool HasHost(); - virtual bool IsHost() const { return false; } - virtual List& GetUsers(); - - virtual List& GetServerMods(); - - virtual NetUser* GetLocalUser(); - virtual void SetLocalUser(NetUser* user); - - virtual int GetStatus() const { return status; } - virtual void SetStatus(int s) { status = s; } - - virtual void AddChat(NetUser* user, const char* msg, bool route=true); - virtual List& - GetChat(); - virtual void ClearChat(); - virtual void SaveChat() { } - virtual DWORD GetStartTime() const { return start_time; } - - virtual List& - GetCampaigns(); - - virtual void AddUnitMap(MissionElement* elem, int index=0); - virtual List& - GetUnitMap(); - virtual void ClearUnitMap(); - virtual void MapUnit(int n, const char* user, bool lock=false); - virtual void UnmapUnit(const char* user); - virtual bool IsMapped(const char* user); - - virtual Mission* GetSelectedMission() { return mission; } - virtual DWORD GetSelectedMissionID() const { return selected_mission; } - virtual void SelectMission(DWORD id); - - virtual const Text& GetMachineInfo() { return machine_info; } - virtual WORD GetGamePort() { return 0; } - - // actions: - virtual bool Ping(); - virtual void GameStart() { } - virtual void GameStop() { } - virtual DWORD GetLag(); - - // instance management: - static NetLobby* GetInstance(); - static bool IsNetLobbyClient(); - static bool IsNetLobbyServer(); - -protected: - virtual void DoPing(NetPeer* peer, Text msg) { } - virtual void DoServerInfo(NetPeer* peer, Text msg) { } - virtual void DoServerMods(NetPeer* peer, Text msg) { } - virtual void DoLogin(NetPeer* peer, Text msg) { } - virtual void DoLogout(NetPeer* peer, Text msg) { } - virtual void DoAuthUser(NetPeer* peer, Text msg) { } - virtual void DoUserAuth(NetPeer* peer, Text msg) { } - virtual void DoChat(NetPeer* peer, Text msg) { } - virtual void DoUserList(NetPeer* peer, Text msg) { } - virtual void DoBanUser(NetPeer* peer, Text msg) { } - virtual void DoMissionList(NetPeer* peer, Text msg) { } - virtual void DoMissionSelect(NetPeer* peer, Text msg) { } - virtual void DoMissionData(NetPeer* peer, Text msg) { } - virtual void DoUnitList(NetPeer* peer, Text msg) { } - virtual void DoMapUnit(NetPeer* peer, Text msg) { } - virtual void DoGameStart(NetPeer* peer, Text msg) { } - virtual void DoGameStop(NetPeer* peer, Text msg) { } - virtual void DoExit(NetPeer* peer, Text msg) { } - - virtual void ParseMsg(Text msg, List& params); - - NetLink* link; - NetUser* local_user; - List users; - List chat_log; - List campaigns; - List unit_map; - Text machine_info; - List server_mods; - - bool active; - DWORD last_send_time; - DWORD start_time; - DWORD selected_mission; - Mission* mission; - int status; -}; - -// +-------------------------------------------------------------------+ - -class NetLobbyParam -{ -public: - static const char* TYPENAME() { return "NetLobbyParam"; } - - NetLobbyParam(const char* n, const char* v) : name(n), value(v) { } - - int operator == (const NetLobbyParam& p) const { return name == p.name; } - - Text name; - Text value; -}; - -// +-------------------------------------------------------------------+ - -class NetUnitEntry -{ -public: - static const char* TYPENAME() { return "NetUnitEntry"; } - - NetUnitEntry(MissionElement* elem, int index=0); - NetUnitEntry(const char* elem, const char* design, int iff, int index=0); - ~NetUnitEntry(); - - int operator == (const NetUnitEntry& e) const { return (elem == e.elem) && (index == e.index); } - - Text GetDescription() const; - const Text& GetUserName() const { return user; } - const Text& GetElemName() const { return elem; } - const Text& GetDesign() const { return design; } - int GetIFF() const { return iff; } - int GetIndex() const { return index; } - int GetLives() const { return lives; } - int GetIntegrity() const { return hull; } - int GetMissionRole() const { return role; } - bool GetLocked() const { return lock; } - - void SetUserName(const char* u) { user = u; } - void SetElemName(const char* e) { elem = e; } - void SetDesign(const char* d) { design = d; } - void SetIFF(int i) { iff = i; } - void SetIndex(int i) { index = i; } - void SetLives(int i) { lives = i; } - void SetIntegrity(int i) { hull = i; } - void SetMissionRole(int i) { role = i; } - void SetLock(bool l) { lock = l; } - -private: - Text user; - Text elem; - Text design; - int iff; - int index; - int lives; - int hull; - int role; - bool lock; -}; - -// +--------------------------------------------------------------------+ - -class NetServerInfo -{ -public: - static const char* TYPENAME() { return "NetServerInfo"; } - - enum STATUS { OFFLINE, LOBBY, BRIEFING, ACTIVE, DEBRIEFING, PERSISTENT }; - - NetServerInfo(); - - Text name; - Text hostname; - Text password; - Text type; - NetAddr addr; - WORD port; - WORD gameport; - bool save; - - Text version; - Text machine_info; - int nplayers; - int hosted; - int status; - - DWORD ping_time; -}; - -// +--------------------------------------------------------------------+ - -class NetCampaignInfo -{ -public: - static const char* TYPENAME() { return "NetCampaignInfo"; } - - NetCampaignInfo() : id(0) { } - ~NetCampaignInfo() { } - - int id; - Text name; - - List missions; -}; - -// +--------------------------------------------------------------------+ - -enum NET_LOBBY_MESSAGES { - NET_LOBBY_PING = 0x10, - NET_LOBBY_SERVER_INFO, - NET_LOBBY_SERVER_MODS, - NET_LOBBY_LOGIN, - NET_LOBBY_LOGOUT, - NET_LOBBY_CHAT, - NET_LOBBY_USER_LIST, - NET_LOBBY_BAN_USER, - NET_LOBBY_MISSION_LIST, - NET_LOBBY_MISSION_SELECT, - NET_LOBBY_MISSION_DATA, - NET_LOBBY_UNIT_LIST, - NET_LOBBY_MAP_UNIT, - - NET_LOBBY_AUTH_USER, - NET_LOBBY_USER_AUTH, - - NET_LOBBY_GAME_START, - NET_LOBBY_GAME_STOP, - NET_LOBBY_EXIT -}; - -// +--------------------------------------------------------------------+ - -#endif // NetLobby_h - diff --git a/Stars45/NetLobbyClient.cpp b/Stars45/NetLobbyClient.cpp deleted file mode 100644 index ca0ff81..0000000 --- a/Stars45/NetLobbyClient.cpp +++ /dev/null @@ -1,807 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Stream-oriented network client class -*/ - - -#include "NetLobbyClient.h" -#include "NetClientConfig.h" -#include "NetAuth.h" -#include "NetChat.h" -#include "Campaign.h" -#include "Player.h" -#include "Starshatter.h" -#include "ModInfo.h" - -#include "NetHost.h" -#include "NetPeer.h" -#include "NetLink.h" -#include "NetMsg.h" -#include "NetLayer.h" -#include "FormatUtil.h" -#include "VersionInfo.h" - -// +-------------------------------------------------------------------+ - -NetLobbyClient::NetLobbyClient() -: NetLobby(false), server_id(0), host(false), exit_code(0), temporary(false) -{ - NetHost me; - Text server_name; - WORD port = 11101; - - ping_req_time = 0; - chat_req_time = 0; - user_req_time = 0; - camp_req_time = 0; - unit_req_time = 0; - mods_req_time = 0; - - NetClientConfig* ncc = NetClientConfig::GetInstance(); - if (ncc) { - NetServerInfo* info = ncc->GetSelectedServer(); - - if (info) { - server_name = info->hostname; - addr = info->addr; - port = info->port; - gamepass = info->password; - } - } - - if (server_name.length() && port > 0) { - Print(" '%s' is a client of '%s'\n", me.Name(), server_name.data()); - link = new NetLink; - server_id = link->AddPeer(NetAddr(server_name, port)); - } - else if (port == 0) { - Print(" '%s' invalid lobby port number %d\n", me.Name(), port); - } - else { - Print(" '%s' is a client without a server\n", me.Name()); - } -} - -NetLobbyClient::NetLobbyClient(const NetAddr& server_addr) -: NetLobby(true), server_id(0), addr(server_addr), host(false), exit_code(0), -temporary(true) -{ - ping_req_time = 0; - chat_req_time = 0; - user_req_time = 0; - camp_req_time = 0; - unit_req_time = 0; - mods_req_time = 0; - - if (addr.IPAddr() != 0) { - link = new NetLink; - server_id = link->AddPeer(addr); - } -} - -NetLobbyClient::~NetLobbyClient() -{ - missions.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyClient::SendData(int type, Text msg) -{ - if (link && server_id && type > 0 && type < 255) { - if (msg.length()) - link->SendMessage(server_id, (BYTE) type, msg.data(), msg.length(), NetMsg::RELIABLE); - else - link->SendMessage(server_id, (BYTE) type, 0, 0, NetMsg::RELIABLE); - } -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyClient::ExecFrame() -{ - NetLobby::ExecFrame(); - - if (!temporary) { - // check health of server: - NetPeer* s = link->FindPeer(server_id); - if (s && (NetLayer::GetUTC() - s->LastReceiveTime() > NET_DISCONNECT_TIME)) { - exit_code = 2; - } - - // send keep alive ping: - if ((NetLayer::GetUTC() - ping_req_time > NET_DISCONNECT_TIME/3)) { - SendData(NET_LOBBY_SERVER_INFO, Text()); - ping_req_time = NetLayer::GetUTC(); - } - } -} - -// +--------------------------------------------------------------------+ - -bool -NetLobbyClient::Login(bool host_req) -{ - Player* player = Player::GetCurrentPlayer(); - if (!player) - return false; - - host = host_req; - - Text login = "name \""; - login += SafeQuotes(player->Name()); - login += "\" pass \""; - login += SafeQuotes(player->Password()); - login += "\" version \""; - login += versionInfo; - login += "\" "; - - char buffer[256]; - - sprintf_s(buffer, "host %s rank %d time %d miss %d kill %d loss %d ", - host ? "true" : "false", - player->Rank(), - player->FlightTime(), - player->Missions(), - player->Kills(), - player->Losses()); - - login += buffer; - - login += "sig \""; - login += SafeQuotes(player->Signature()); - login += "\" squad \""; - login += SafeQuotes(player->Squadron()); - login += "\" "; - - if (gamepass.length() > 0) { - login += "gamepass \""; - login += SafeQuotes(gamepass); - login += "\" "; - } - - SendData(NET_LOBBY_LOGIN, login); - ExecFrame(); - return true; -} - -bool -NetLobbyClient::Logout() -{ - if (host) - GameStop(); - - SendData(NET_LOBBY_LOGOUT, Text()); - Sleep(250); - ExecFrame(); - return true; -} - -// +--------------------------------------------------------------------+ - -bool -NetLobbyClient::Ping() -{ - Text no_data; - - SendData(NET_LOBBY_PING, no_data); - Sleep(100); - - SendData(NET_LOBBY_PING, no_data); - Sleep(100); - - SendData(NET_LOBBY_PING, no_data); - Sleep(100); - - SendData(NET_LOBBY_SERVER_INFO, no_data); - Sleep(700); - ExecFrame(); - - return (server_info.status > NetServerInfo::OFFLINE); -} - -void -NetLobbyClient::GameStart() -{ - SendData(NET_LOBBY_GAME_START, Text()); - Sleep(100); - - SetStatus(NetServerInfo::ACTIVE); - Starshatter::GetInstance()->SetGameMode(Starshatter::PREP_MODE); - - // discard unit map selection data so that - // it will be refreshed when we return to - // the lobby after the mission: - - ClearUnitMap(); -} - -void -NetLobbyClient::GameStop() -{ - SendData(NET_LOBBY_GAME_STOP, Text()); - ExecFrame(); - Sleep(100); - - SetStatus(NetServerInfo::LOBBY); -} - -// +--------------------------------------------------------------------+ - -const Text& -NetLobbyClient::GetMachineInfo() -{ - if (server_info.status > NetServerInfo::OFFLINE) - return server_info.machine_info; - - return NetLobby::GetMachineInfo(); -} - -int -NetLobbyClient::GetStatus() const -{ - if (server_info.status > NetServerInfo::OFFLINE) - return server_info.status; - - return NetLobby::GetStatus(); -} - -int -NetLobbyClient::NumUsers() -{ - if (server_info.status > NetServerInfo::OFFLINE) - return server_info.nplayers; - - return NetLobby::NumUsers(); -} - -bool -NetLobbyClient::HasHost() -{ - if (server_info.status > NetServerInfo::OFFLINE) - return server_info.hosted ? true : false; - - return NetLobby::HasHost(); -} - -WORD -NetLobbyClient::GetGamePort() -{ - if (server_info.status > NetServerInfo::OFFLINE) - return server_info.gameport; - - return NetLobby::GetGamePort(); -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyClient::AddChat(NetUser* user, const char* msg, bool route) -{ - if (!msg || !*msg) return; - - char buffer[280]; - sprintf_s(buffer, "msg \"%s\"", SafeQuotes(msg)); - - SendData(NET_LOBBY_CHAT, buffer); - ExecFrame(); -} - -List& -NetLobbyClient::GetChat() -{ - if (chat_log.size() < 1 && (NetLayer::GetUTC() - chat_req_time > 3)) { - SendData(NET_LOBBY_CHAT, Text()); - chat_req_time = NetLayer::GetUTC(); - } - - return chat_log; -} - -List& -NetLobbyClient::GetUsers() -{ - if (users.size() < 1 && (NetLayer::GetUTC() - user_req_time > 2)) { - SendData(NET_LOBBY_USER_LIST, Text()); - user_req_time = NetLayer::GetUTC(); - } - - return users; -} - -List& -NetLobbyClient::GetServerMods() -{ - if (server_mods.size() < 1 && (NetLayer::GetUTC() - mods_req_time > 2)) { - SendData(NET_LOBBY_SERVER_MODS, Text()); - mods_req_time = NetLayer::GetUTC(); - } - - return server_mods; -} - -List& -NetLobbyClient::GetUnitMap() -{ - bool request = selected_mission && - unit_map.size() < 1 && - (NetLayer::GetUTC() - unit_req_time > 2); - - if (selected_mission && GetStatus() == NetServerInfo::ACTIVE && (NetLayer::GetUTC() - unit_req_time > 5)) - request = true; - - if (request) { - SendData(NET_LOBBY_UNIT_LIST, Text()); - unit_req_time = NetLayer::GetUTC(); - } - - return unit_map; -} - -// +--------------------------------------------------------------------+ - -List& -NetLobbyClient::GetCampaigns() -{ - if (campaigns.size() < 1 && (NetLayer::GetUTC() - camp_req_time > 3)) { - SendData(NET_LOBBY_MISSION_LIST, Text()); - camp_req_time = NetLayer::GetUTC(); - } - - return campaigns; -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyClient::BanUser(NetUser* user) -{ - char buffer[512]; - sprintf_s(buffer, "user \"%s\"", SafeQuotes(user->Name())); - SendData(NET_LOBBY_BAN_USER, buffer); -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyClient::SelectMission(DWORD id) -{ - char buffer[32]; - sprintf_s(buffer, "m_id 0x%08x", id); - SendData(NET_LOBBY_MISSION_SELECT, buffer); -} - -void -NetLobbyClient::MapUnit(int n, const char* user, bool lock) -{ - if (user && strlen(user) > 250) - return; - - char buffer[512]; - sprintf_s(buffer, "id %d user \"%s\" lock %s", - n, SafeQuotes(user), lock ? "true" : "false"); - SendData(NET_LOBBY_MAP_UNIT, buffer); -} - -Mission* -NetLobbyClient::GetSelectedMission() -{ - mission = 0; - - // ask server for mission: - SendData(NET_LOBBY_MISSION_DATA, Text()); - - // wait for answer: - int i = 150; - while (i-- > 0 && !mission) { - Sleep(100); - ExecFrame(); - } - - return mission; -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyClient::DoAuthUser(NetPeer* peer, Text msg) -{ - List params; - ParseMsg(msg, params); - - int level = NetAuth::NET_AUTH_STANDARD; - Text salt; - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - int num = 0; - sscanf_s(p->value, "%d", &num); - - if (p->name == "level") { - level = num; - } - - else if (p->name == "salt") { - salt = p->value; - } - } - - Text response = NetAuth::CreateAuthResponse(level, salt); - if (response.length() > 0) - SendData(NET_LOBBY_USER_AUTH, response); -} - -void -NetLobbyClient::DoServerInfo(NetPeer* peer, Text msg) -{ - List params; - ParseMsg(msg, params); - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - int num = 0; - sscanf_s(p->value, "%d", &num); - - if (p->name == "info") { - server_info.machine_info = p->value; - } - - else if (p->name == "version") { - server_info.version = p->value; - } - - else if (p->name == "mode") { - server_info.status = num; - } - - else if (p->name == "users") { - server_info.nplayers = num; - } - - else if (p->name == "host") { - server_info.hosted = (p->value == "true"); - } - - else if (p->name == "port") { - server_info.gameport = (WORD) num; - } - } - - params.destroy(); -} - -void -NetLobbyClient::DoChat(NetPeer* peer, Text msg) -{ - List params; - ParseMsg(msg, params); - - int id = 0; - Text user_name; - Text chat_msg; - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - int num = 0; - sscanf_s(p->value, "%d", &num); - - if (p->name == "id") - id = num; - - else if (p->name == "user") - user_name = p->value; - - else if (p->name == "msg") - chat_msg = p->value; - } - - params.destroy(); - - // receive chat from server: - if (id && chat_msg.length()) { - NetChatEntry* entry = new NetChatEntry(id, user_name, chat_msg); - - if (!chat_log.contains(entry)) - chat_log.insertSort(entry); - else - delete entry; // received duplicate - } -} - -void -NetLobbyClient::DoServerMods(NetPeer* peer, Text msg) -{ - mods_req_time = NetLayer::GetUTC() + 3600; - - List params; - ParseMsg(msg, params); - server_mods.destroy(); - - Text name; - Text version; - Text url; - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - if (p->name == "mod") { - name = p->value; - } - - else if (p->name == "url") { - url = p->value; - } - - else if (p->name == "ver") { - version = p->value; - - ModInfo* info = new ModInfo(name, version, url); - server_mods.append(info); - } - } - - params.destroy(); -} - -void -NetLobbyClient::DoUserList(NetPeer* peer, Text msg) -{ - List params; - ParseMsg(msg, params); - - users.destroy(); - - Text user_name; - Text host_flag; - Text signature; - Text squadron; - int rank = 0; - int flight_time = 0; - int mission_count = 0; - int kills = 0; - int losses = 0; - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - int num = 0; - sscanf_s(p->value, "%d", &num); - - if (p->name == "name") - user_name = p->value; - - else if (p->name == "sig") - signature = p->value; - - else if (p->name == "squad") - squadron = p->value; - - else if (p->name == "rank") - rank = num; - - else if (p->name == "time") - flight_time = num; - - else if (p->name == "miss") - mission_count = num; - - else if (p->name == "kill") - kills = num; - - else if (p->name == "loss") - losses = num; - - else if (p->name == "host") { - host_flag = p->value; - - NetUser* u = new NetUser(user_name); - u->SetHost((host_flag == "true") ? true : false); - u->SetSignature(signature); - u->SetSquadron(squadron); - u->SetRank(rank); - u->SetFlightTime(flight_time); - u->SetMissions(mission_count); - u->SetKills(kills); - u->SetLosses(losses); - - AddUser(u); - } - } - - params.destroy(); -} - -void -NetLobbyClient::DoMissionList(NetPeer* peer, Text msg) -{ - List params; - ParseMsg(msg, params); - - if (params.size() > 2) { - campaigns.destroy(); - - NetCampaignInfo* c = 0; - MissionInfo* m = 0; - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - if (p->name == "c_id") { - c = new NetCampaignInfo; - sscanf_s(p->value, "0x%x", &c->id); - campaigns.append(c); - - m = 0; - } - - else if (c && p->name == "c_name") { - c->name = p->value; - } - - else if (p->name == "m_id") { - int id = 0; - sscanf_s(p->value, "0x%x", &id); - - int m_id = id & NET_MISSION_MASK; - int c_id = id >> NET_CAMPAIGN_SHIFT; - - for (int i = 0; i < campaigns.size(); i++) { - NetCampaignInfo* c = campaigns[i]; - if (c->id == c_id) { - m = new MissionInfo; - m->id = m_id; - c->missions.append(m); - missions.append(m); // for later garbage collection - break; - } - } - } - - else if (m && p->name == "m_name") { - m->name = p->value; - } - - else if (m && p->name == "m_desc") { - m->description = p->value; - } - } - } - - params.destroy(); -} - -void -NetLobbyClient::DoMissionSelect(NetPeer* peer, Text msg) -{ - List params; - ParseMsg(msg, params); - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - int num = 0; - sscanf_s(p->value, "0x%x", &num); - - if (p->name == "m_id") { - if (selected_mission != (DWORD) num) { - selected_mission = num; - ClearUnitMap(); - } - } - } - - params.destroy(); -} - -void -NetLobbyClient::DoMissionData(NetPeer* peer, Text msg) -{ - Campaign* c = Campaign::SelectCampaign("Multiplayer Missions"); - - if (c) { - c->LoadNetMission(99999, msg.data()); - mission = c->GetMission(99999); - } - - if (msg.length()) { - FILE* f; - ::fopen_s(&f, "multi_mission_recv.def", "wb"); - if (f) { - ::fwrite(msg.data(), msg.length(), 1, f); - ::fclose(f); - } - } -} - -void -NetLobbyClient::DoUnitList(NetPeer* peer, Text msg) -{ - List params; - ParseMsg(msg, params); - - if (params.size() > 2) { - ClearUnitMap(); - - Text elem_name; - Text design; - Text user_name; - int iff; - int index; - int lives = 1; - int hull = 100; - int role = 0; - int lock = 0; - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - if (p->name == "name") { - elem_name = p->value; - } - else if (p->name == "design") { - design = p->value; - } - else if (p->name == "user") { - user_name = p->value; - } - else if (p->name == "index") { - sscanf_s(p->value, "%d", &index); - } - else if (p->name == "iff") { - sscanf_s(p->value, "%d", &iff); - } - else if (p->name == "lives") { - sscanf_s(p->value, "%d", &lives); - } - else if (p->name == "hull") { - sscanf_s(p->value, "%d", &hull); - } - else if (p->name == "role") { - sscanf_s(p->value, "%d", &role); - } - else if (p->name == "lock") { - sscanf_s(p->value, "%d", &lock); - - NetUnitEntry* entry = new NetUnitEntry(elem_name, design, iff, index); - entry->SetUserName(user_name); - entry->SetLives(lives); - entry->SetIntegrity(hull); - entry->SetMissionRole(role); - entry->SetLock(lock ? true : false); - - unit_map.append(entry); - } - } - } - - params.destroy(); -} - -void -NetLobbyClient::DoMapUnit(NetPeer* peer, Text msg) -{ -} - -void -NetLobbyClient::DoGameStart(NetPeer* peer, Text msg) -{ -} - -void -NetLobbyClient::DoExit(NetPeer* peer, Text msg) -{ - exit_code = 1; -} diff --git a/Stars45/NetLobbyClient.h b/Stars45/NetLobbyClient.h deleted file mode 100644 index c54cea7..0000000 --- a/Stars45/NetLobbyClient.h +++ /dev/null @@ -1,103 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - UDP-oriented network lobby client class -*/ - - -#ifndef NetLobbyClient_h -#define NetLobbyClient_h - -#include "NetLobby.h" -#include "NetClientConfig.h" - -// +-------------------------------------------------------------------+ - -class NetLobbyClient : public NetLobby -{ -public: - NetLobbyClient(); - NetLobbyClient(const NetAddr& server_addr); - virtual ~NetLobbyClient(); - - int operator == (const NetLobbyClient& c) const { return this == &c; } - - virtual void ExecFrame(); - virtual bool Login(bool host=false); - virtual bool Logout(); - virtual int GetLastError() const { return exit_code; } - - // actions: - virtual bool Ping(); - virtual void GameStart(); - virtual void GameStop(); - - virtual void BanUser(NetUser* user); - - virtual void AddChat(NetUser* user, const char* msg, bool route=true); - virtual List& - GetChat(); - - NetAddr GetServerAddr() const { return addr; } - virtual bool IsHost() const { return host; } - virtual bool IsClient() const { return true; } - - virtual List& GetUsers(); - virtual List& GetCampaigns(); - virtual List& GetUnitMap(); - virtual void MapUnit(int n, const char* user, bool lock=false); - virtual void SelectMission(DWORD id); - virtual Mission* GetSelectedMission(); - - virtual List& GetServerMods(); - - // overrides for ping support: - virtual const Text& GetMachineInfo(); - virtual int GetStatus() const; - virtual int NumUsers(); - virtual bool HasHost(); - virtual WORD GetGamePort(); - -protected: - virtual void SendData(int type, Text msg); - virtual void DoServerInfo(NetPeer* peer, Text msg); - virtual void DoServerMods(NetPeer* peer, Text msg); - virtual void DoAuthUser(NetPeer* peer, Text msg); - virtual void DoChat(NetPeer* peer, Text msg); - virtual void DoUserList(NetPeer* peer, Text msg); - virtual void DoMissionList(NetPeer* peer, Text msg); - virtual void DoMissionSelect(NetPeer* peer, Text msg); - virtual void DoMissionData(NetPeer* peer, Text msg); - virtual void DoUnitList(NetPeer* peer, Text msg); - virtual void DoMapUnit(NetPeer* peer, Text msg); - virtual void DoGameStart(NetPeer* peer, Text msg); - virtual void DoExit(NetPeer* peer, Text msg); - - DWORD server_id; - NetAddr addr; - bool host; - Text gamepass; - int exit_code; - - NetServerInfo server_info; - List missions; - - bool temporary; - DWORD ping_req_time; - DWORD chat_req_time; - DWORD user_req_time; - DWORD camp_req_time; - DWORD unit_req_time; - DWORD mods_req_time; -}; - -// +-------------------------------------------------------------------+ - -#endif // NetLobbyClient_h \ No newline at end of file diff --git a/Stars45/NetLobbyDlg.cpp b/Stars45/NetLobbyDlg.cpp deleted file mode 100644 index f878916..0000000 --- a/Stars45/NetLobbyDlg.cpp +++ /dev/null @@ -1,473 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "NetLobbyDlg.h" -#include "NetUnitDlg.h" -#include "NetClientConfig.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "Ship.h" -#include "Player.h" -#include "Campaign.h" - -#include "NetAddr.h" -#include "NetLobbyClient.h" -#include "NetLobbyServer.h" -#include "NetUser.h" -#include "NetChat.h" - -#include "DataLoader.h" -#include "Video.h" -#include "Keyboard.h" -#include "MachineInfo.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(NetLobbyDlg, OnCampaignSelect); -DEF_MAP_CLIENT(NetLobbyDlg, OnMissionSelect); -DEF_MAP_CLIENT(NetLobbyDlg, OnApply); -DEF_MAP_CLIENT(NetLobbyDlg, OnCancel); - -// +--------------------------------------------------------------------+ - -NetLobbyDlg::NetLobbyDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -net_lobby(0) -{ - selected_campaign = 0; - selected_mission = 0; - last_chat = 0; - host_mode = false; - - Init(def); -} - -NetLobbyDlg::~NetLobbyDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::RegisterControls() -{ - lst_campaigns = (ComboBox*) FindControl(200); - REGISTER_CLIENT(EID_SELECT, lst_campaigns, NetLobbyDlg, OnCampaignSelect); - - lst_missions = (ListBox*) FindControl(201); - REGISTER_CLIENT(EID_SELECT, lst_missions, NetLobbyDlg, OnMissionSelect); - - txt_desc = FindControl(202); - lst_players = (ListBox*) FindControl(210); - lst_chat = (ListBox*) FindControl(211); - edt_chat = (EditBox*) FindControl(212); - - if (edt_chat) - edt_chat->SetText(""); - - apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, apply, NetLobbyDlg, OnApply); - - cancel = (Button*) FindControl(2); - REGISTER_CLIENT(EID_CLICK, cancel, NetLobbyDlg, OnCancel); -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::Show() -{ - if (!IsShown()) { - // clear server data: - if (lst_chat) lst_chat->ClearItems(); - if (lst_campaigns) lst_campaigns->ClearItems(); - if (lst_missions) lst_missions->ClearItems(); - if (txt_desc) txt_desc->SetText(""); - if (apply) apply->SetEnabled(false); - - if (lst_missions) { - lst_missions->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - lst_missions->SetLeading(2); - } - - selected_campaign = 0; - selected_mission = 0; - last_chat = 0; - - FormWindow::Show(); - - net_lobby = NetLobby::GetInstance(); - - if (!net_lobby) { - Starshatter* stars = Starshatter::GetInstance(); - if (stars) - stars->StartLobby(); - - net_lobby = NetLobby::GetInstance(); - } - - if (net_lobby) { - if (net_lobby->IsServer()) { - host_mode = true; - - NetUser* user = net_lobby->GetLocalUser(); - - if (!user) { - Player* player = Player::GetCurrentPlayer(); - if (player) { - user = new NetUser(player); - user->SetHost(true); - } - else { - ::Print("NetLobbyDlg::Show() Host mode - no current player?\n"); - } - } - - net_lobby->SetLocalUser(user); - } - - SelectMission(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::ExecFrame() -{ - ExecLobbyFrame(); - - if (Keyboard::KeyDown(VK_RETURN)) { - if (edt_chat && edt_chat->GetText().length() > 0) { - SendChat(edt_chat->GetText()); - edt_chat->SetText(""); - } - } - - GetPlayers(); - GetChat(); - - if (lst_campaigns) { - if (lst_campaigns->NumItems() < 1) - GetMissions(); - else - GetSelectedMission(); - } -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::ExecLobbyFrame() -{ - if (net_lobby && net_lobby->GetLastError() != 0) { - if (net_lobby->IsClient()) { - Starshatter* stars = Starshatter::GetInstance(); - if (stars) - stars->StopLobby(); - - net_lobby = 0; - manager->ShowNetClientDlg(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::GetPlayers() -{ - if (!lst_players) return; - - if (net_lobby) { - lst_players->ClearItems(); - - NetUser* u = net_lobby->GetLocalUser(); - if (u) { - Text name = Player::RankAbrv(u->Rank()); - name += " "; - name += u->Name(); - - int count = lst_players->AddItem(u->IsHost() ? "*" : " "); - lst_players->SetItemText(count-1, 1, name); - host_mode = true; - } - - ListIter iter = net_lobby->GetUsers(); - while (++iter) { - NetUser* u = iter.value(); - int count = lst_players->AddItem(u->IsHost() ? "*" : " "); - - Text name = Player::RankAbrv(u->Rank()); - name += " "; - name += u->Name(); - - lst_players->SetItemText(count-1, 1, name); - - if (Player::GetCurrentPlayer()->Name() == u->Name()) - host_mode = u->IsHost(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::GetChat() -{ - if (!lst_chat) return; - - if (net_lobby) { - int last_item = lst_chat->NumItems() - 1; - int count = 0; - bool added = false; - - ListIter iter = net_lobby->GetChat(); - while (++iter) { - NetChatEntry* c = iter.value(); - - if (count++ > last_item) { - int n = lst_chat->AddItem(c->GetUser()); - lst_chat->SetItemText(n-1, 1, c->GetMessage()); - added = true; - } - } - - if (added) - lst_chat->EnsureVisible(lst_chat->NumItems()+1); - } -} - -void -NetLobbyDlg::SendChat(Text msg) -{ - if (msg.length() < 1) return; - - Player* player = Player::GetCurrentPlayer(); - - if (msg[0] >= '0' && msg[0] <= '9') { - if (player) { - Text macro = player->ChatMacro(msg[0] - '0'); - - if (macro.length()) - msg = macro; - } - } - - if (net_lobby) - net_lobby->AddChat(net_lobby->GetLocalUser(), msg); -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::GetMissions() -{ - if (!lst_campaigns || !lst_missions) - return; - - if (net_lobby) { - lst_campaigns->ClearItems(); - - List& campaigns = net_lobby->GetCampaigns(); - - if (campaigns.size()) { - ListIter c_iter = campaigns; - while (++c_iter) { - NetCampaignInfo* c = c_iter.value(); - lst_campaigns->AddItem(c->name); - } - - lst_campaigns->SetSelection(0); - NetCampaignInfo* c = campaigns[0]; - - lst_missions->ClearItems(); - - ListIter m_iter = c->missions; - while (++m_iter) { - MissionInfo* m = m_iter.value(); - lst_missions->AddItem(m->name); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::GetSelectedMission() -{ - if (!lst_campaigns || !lst_missions) return; - - if (net_lobby) { - if (net_lobby->GetSelectedMissionID()) { - int id = net_lobby->GetSelectedMissionID(); - - selected_campaign = id >> NET_CAMPAIGN_SHIFT; - selected_mission = id & NET_MISSION_MASK; - - List& campaigns = net_lobby->GetCampaigns(); - - for (int i = 0; i < campaigns.size(); i++) { - NetCampaignInfo* c = campaigns[i]; - - if (c->id == selected_campaign) { - lst_campaigns->SetSelection(i); - OnCampaignSelect(0); - - for (int j = 0; j < c->missions.size(); j++) { - MissionInfo* m = c->missions[j]; - - if (m->id == selected_mission) { - lst_missions->SetSelected(j); - OnMissionSelect(0); - } - } - } - } - } - else if (selected_campaign) { - selected_campaign = 0; - selected_mission = 0; - } - - lst_campaigns->SetEnabled(selected_campaign == 0); - lst_missions->SetEnabled(selected_mission == 0); - - if (!host_mode) - apply->SetEnabled(selected_mission != 0); - } -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::SelectMission() -{ - if (!lst_campaigns || !lst_missions) return; - - bool selected = false; - - if (net_lobby) { - int c_index = lst_campaigns->GetSelectedIndex(); - int m_index = lst_missions->GetSelection(); - - List& campaigns = net_lobby->GetCampaigns(); - - if (c_index >= 0 && c_index < campaigns.size() && m_index >= 0) { - NetCampaignInfo* c = campaigns[c_index]; - - if (m_index < c->missions.size()) { - MissionInfo* m = c->missions[m_index]; - - DWORD id = (c->id << NET_CAMPAIGN_SHIFT) + - (m->id & NET_MISSION_MASK); - - net_lobby->SelectMission(id); - selected = true; - } - } - - if (!selected) - net_lobby->SelectMission(0); - } -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::OnCampaignSelect(AWEvent* event) -{ - if (net_lobby) { - List& campaigns = net_lobby->GetCampaigns(); - - if (lst_campaigns && lst_missions && campaigns.size()) { - int index = lst_campaigns->GetSelectedIndex(); - - if (index >= 0 && index < campaigns.size()) { - NetCampaignInfo* c = campaigns[index]; - - lst_missions->ClearItems(); - txt_desc->SetText(""); - - ListIter iter = c->missions; - while (++iter) { - MissionInfo* m = iter.value(); - lst_missions->AddItem(m->name); - } - } - } - } -} - -void -NetLobbyDlg::OnMissionSelect(AWEvent* event) -{ - if (net_lobby) { - List& campaigns = net_lobby->GetCampaigns(); - - if (lst_campaigns && lst_missions && txt_desc && campaigns.size()) { - txt_desc->SetText(""); - - if (host_mode && apply) - apply->SetEnabled(false); - - int c_index = lst_campaigns->GetSelectedIndex(); - int m_index = lst_missions->GetSelection(); - - if (c_index >= 0 && c_index < campaigns.size()) { - NetCampaignInfo* c = campaigns[c_index]; - - if (m_index >= 0 && m_index < c->missions.size()) { - MissionInfo* m = c->missions[m_index]; - txt_desc->SetText(m->description); - - if (host_mode && apply) - apply->SetEnabled(true); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyDlg::OnApply(AWEvent* event) -{ - if (host_mode) - SelectMission(); - - manager->ShowNetUnitDlg(); - - NetUnitDlg* unit_dlg = manager->GetNetUnitDlg(); - if (unit_dlg) - unit_dlg->SetHostMode(host_mode); -} - -void -NetLobbyDlg::OnCancel(AWEvent* event) -{ - if (net_lobby) { - net_lobby->SelectMission(0); - net_lobby = 0; - - Starshatter* stars = Starshatter::GetInstance(); - if (stars) - stars->StopLobby(); - } - - manager->ShowNetClientDlg(); -} diff --git a/Stars45/NetLobbyDlg.h b/Stars45/NetLobbyDlg.h deleted file mode 100644 index c8b9b5d..0000000 --- a/Stars45/NetLobbyDlg.h +++ /dev/null @@ -1,88 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef NetLobbyDlg_h -#define NetLobbyDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "EditBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class NetClientConfig; -class NetLobby; -class NetCampaignInfo; -class MissionInfo; -class NetChatEntry; -class NetUser; - -// +--------------------------------------------------------------------+ - -class NetLobbyDlg : public FormWindow -{ -public: - NetLobbyDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~NetLobbyDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnCampaignSelect(AWEvent* event); - virtual void OnMissionSelect(AWEvent* event); - - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - - virtual void ExecLobbyFrame(); - -protected: - virtual void GetPlayers(); - virtual void GetChat(); - virtual void GetMissions(); - virtual void GetSelectedMission(); - virtual void SendChat(Text msg); - virtual void SelectMission(); - - MenuScreen* manager; - - ComboBox* lst_campaigns; - ListBox* lst_missions; - ActiveWindow* txt_desc; - ListBox* lst_players; - ListBox* lst_chat; - EditBox* edt_chat; - - Button* apply; - Button* cancel; - - NetLobby* net_lobby; - - int selected_campaign; - int selected_mission; - int last_chat; - bool host_mode; -}; - -// +--------------------------------------------------------------------+ - -#endif // NetLobbyDlg_h - diff --git a/Stars45/NetLobbyServer.cpp b/Stars45/NetLobbyServer.cpp deleted file mode 100644 index b3060c5..0000000 --- a/Stars45/NetLobbyServer.cpp +++ /dev/null @@ -1,1361 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - NetLink Engine for Multiplayer Lobby -*/ - -#include "NetLobbyServer.h" -#include "NetServerConfig.h" -#include "NetClientConfig.h" -#include "NetBrokerClient.h" -#include "NetAuth.h" -#include "NetChat.h" -#include "NetUser.h" -#include "Campaign.h" -#include "Mission.h" -#include "StarServer.h" -#include "Starshatter.h" -#include "StarServer.h" -#include "ShipDesign.h" -#include "Sim.h" -#include "Text.h" - -#include "ModConfig.h" -#include "ModInfo.h" - -#include "NetGame.h" -#include "NetPlayer.h" -#include "NetUtil.h" - -#include "NetPeer.h" -#include "NetLayer.h" -#include "NetHost.h" -#include "NetMsg.h" - -#include "MachineInfo.h" -#include "Clock.h" -#include "FormatUtil.h" -#include "VersionInfo.h" - -// +-------------------------------------------------------------------+ - -static NetLobbyServer* net_lobby_server = 0; - -NetLobbyServer::NetLobbyServer() -: announce_time(0), server_config(0), motd_index(1) -{ - status = NetServerInfo::LOBBY; - server_name = Text("Starshatter NetLobbyServer ") + versionInfo; - start_time = NetLayer::GetUTC(); - - selected_mission = 0; - - Text hostname = "0.0.0.0"; - WORD server_port = 11100; - - server_config = NetServerConfig::GetInstance(); - if (server_config) { - hostname = server_config->Hostname(); - server_name = server_config->Name(); - server_port = server_config->GetLobbyPort(); - server_mission = server_config->GetMission(); - - NetAuth::SetAuthLevel(server_config->GetAuthLevel()); - - server_addr = NetAddr(hostname.data(), server_port); - link = new NetLink(server_addr); - } - - LoadMOTD(); - - StarServer* star_server = StarServer::GetInstance(); - DWORD mission_id = 0; - - // only one mission: - if (star_server && server_mission.length() > 0) { - NetCampaignInfo* c = new NetCampaignInfo; - c->id = Campaign::MULTIPLAYER_MISSIONS; - c->name = "Persistent Multiplayer"; - campaigns.append(c); - - ListIter c_iter = Campaign::GetAllCampaigns(); - while (++c_iter && !mission_id) { - Campaign* campaign = c_iter.value(); - - if (campaign->GetCampaignId() == Campaign::MULTIPLAYER_MISSIONS) { - ListIter m_iter = campaign->GetMissionList(); - while (++m_iter && !mission_id) { - MissionInfo* m = m_iter.value(); - - if (m->script == server_mission) { - c->missions.append(m); - mission_id = (Campaign::MULTIPLAYER_MISSIONS << NET_CAMPAIGN_SHIFT) + m->id; - - SelectMission(mission_id); - star_server->SetGameMode(StarServer::LOAD_MODE); - - // lock in mission: - SetStatus(NetServerInfo::PERSISTENT); - } - } - } - } - } - - // player host may select mission: - if (!mission_id) { - campaigns.destroy(); - - ListIter c_iter = Campaign::GetAllCampaigns(); - while (++c_iter) { - Campaign* campaign = c_iter.value(); - - if (campaign->GetCampaignId() >= Campaign::MULTIPLAYER_MISSIONS) { - NetCampaignInfo* c = new NetCampaignInfo; - c->id = campaign->GetCampaignId(); - c->name = campaign->Name(); - campaigns.append(c); - - ListIter m_iter = campaign->GetMissionList(); - while (++m_iter) { - MissionInfo* m = m_iter.value(); - c->missions.append(m); - } - } - } - } - - ModConfig* config = ModConfig::GetInstance(); - List& mods = config->GetModInfoList(); - - server_mods.clear(); - server_mods.append(mods); - - net_lobby_server = this; -} - -NetLobbyServer::~NetLobbyServer() -{ - ListIter iter = users; - while (++iter) { - NetUser* u = iter.value(); - SendData(u, NET_LOBBY_EXIT, Text()); - ExecFrame(); - } - - Sleep(500); - - unit_map.destroy(); - chat_log.destroy(); - users.destroy(); - motd.destroy(); - - if (net_lobby_server == this) - net_lobby_server = 0; -} - -NetLobbyServer* -NetLobbyServer::GetInstance() -{ - return net_lobby_server; -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyServer::LoadMOTD() -{ - motd.destroy(); - - FILE* f; - fopen_s(&f, "motd.txt", "rb"); - - if (f) { - char line[256]; - - while (fgets(line, 256, f)) { - int n = strlen(line) - 1; - - while (n >= 0 && isspace(line[n])) - line[n--] = 0; - - motd.append(new Text(line)); - } - } -} - -void -NetLobbyServer::SendMOTD(NetUser* user) -{ - if (motd.size() < 1) return; - - char buffer[512]; - - for (int i = 0; i < motd.size(); i++) { - Text* line = motd[i]; - - sprintf_s(buffer, "id %d user \" \" msg \"%s\"", - motd_index++, line->data()); - - SendData(user, NET_LOBBY_CHAT, buffer); - } - - sprintf_s(buffer, "id %d user \" \" msg \" \"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); -} - -void -NetLobbyServer::SendMods(NetUser* user) -{ - char buffer[300]; - - ModConfig* config = ModConfig::GetInstance(); - List& mods = config->GetModInfoList(); - - if (mods.size() < 1) return; - - for (int i = 0; i < mods.size(); i++) { - ModInfo* info = mods[i]; - - sprintf_s(buffer, "id %d user \"Enabled Mods:\" msg \"%d. '%s' ", - motd_index++, i+1, info->Name().data()); - - Text msg = buffer; - - if (info->Version().length() > 0) { - msg += "version "; - msg += info->Version().data(); - } - - if (info->URL().length() > 0) { - msg += " - "; - msg += info->URL().data(); - } - - msg += "\""; - - SendData(user, NET_LOBBY_CHAT, msg); - } - - sprintf_s(buffer, "id %d user \" \" msg \" \"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); -} - -// +--------------------------------------------------------------------+ - -void -NetLobbyServer::ExecFrame() -{ - NetLobby::ExecFrame(); - - if (announce_time == 0 || Clock::GetInstance()->RealTime() - announce_time > 200000) { - GameOn(); - announce_time = Clock::GetInstance()->RealTime(); - } - - if (GetStatus() == NetServerInfo::BRIEFING) { - NetGame* net_game = NetGame::GetInstance(); - - if (net_game && net_game->NumPlayers() > 0) { - SetStatus(NetServerInfo::ACTIVE); - } - } - - StarServer* star_server = StarServer::GetInstance(); - DWORD mission_id = 0; - - // restart persistent mission? - if (star_server && - star_server->GetGameMode() == StarServer::MENU_MODE && - server_mission.length() > 0) { - - NetCampaignInfo* c = campaigns.last(); - - if (!c || c->name != "Persistent Multiplayer") { - c = new NetCampaignInfo; - c->id = Campaign::MULTIPLAYER_MISSIONS; - c->name = "Persistent Multiplayer"; - campaigns.append(c); - } - else { - c->missions.clear(); - } - - ListIter c_iter = Campaign::GetAllCampaigns(); - while (++c_iter && !mission_id) { - Campaign* campaign = c_iter.value(); - - if (campaign->GetCampaignId() == Campaign::MULTIPLAYER_MISSIONS) { - ListIter m_iter = campaign->GetMissionList(); - while (++m_iter && !mission_id) { - MissionInfo* m = m_iter.value(); - - if (m->script == server_mission) { - c->missions.append(m); - mission_id = (Campaign::MULTIPLAYER_MISSIONS << NET_CAMPAIGN_SHIFT) + m->id; - - // unlock old mission: - SetStatus(NetServerInfo::LOBBY); - - SelectMission(mission_id); - - if (star_server->GetGameMode() == StarServer::MENU_MODE) { - star_server->SetGameMode(StarServer::LOAD_MODE); - } - - // lock in new mission: - SetStatus(NetServerInfo::PERSISTENT); - } - } - } - } - } - - CheckSessions(); -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyServer::SendData(NetUser* dst, int type, Text msg) -{ - if (link && dst && type > 0 && type < 255) { - if (msg.length()) - link->SendMessage(dst->GetNetID(), (BYTE) type, msg.data(), msg.length(), NetMsg::RELIABLE); - else - link->SendMessage(dst->GetNetID(), (BYTE) type, 0, 0, NetMsg::RELIABLE); - } -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyServer::CheckSessions() -{ - if (!link) - return; - - bool dropped = false; - - ListIter u_iter = users; - while (++u_iter) { - NetUser* u = u_iter.value(); - NetPeer* p = link->FindPeer(u->GetNetID()); - - if (p && (NetLayer::GetUTC() - p->LastReceiveTime()) > NET_DISCONNECT_TIME) { - // check game peer for activity: - NetGame* game = NetGame::GetInstance(); - NetPlayer* player = 0; - NetPeer* p2 = 0; - - if (game) { - player = game->FindPlayerByName(u->Name()); - - if (player) { - p2 = game->GetPeer(player); - - if (p2 && (NetLayer::GetUTC() - p2->LastReceiveTime()) < NET_DISCONNECT_TIME) { - p->SetLastReceiveTime(p2->LastReceiveTime()); - continue; - } - } - else { - ::Print("NetLobbyServer::CheckSessions() Could not find player for '%s'\n", u->Name().data()); - } - } - else { - ::Print("NetLobbyServer::CheckSessions() Could not find net game for '%s'\n", u->Name().data()); - } - - // announce drop: - char timestr[64]; - FormatTime(timestr, Clock::GetInstance()->RealTime()/1000); - Print("NetLobbyServer: Dropped inactive connection '%s' %s\n", - u->Name().data(), timestr); - - if (u->IsHost()) { - Print(" User was host - ending net game.\n"); - GameStop(); - } - - u_iter.removeItem(); // first remove user from list - NetLobby::UnmapUnit(u->Name()); // then unmap unit - delete u; // now it is safe to discard the inactive user - - dropped = true; - } - } - - if (dropped) { - SendUsers(); - SendUnits(); - } -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyServer::GameStart() -{ - if (status < NetServerInfo::ACTIVE) { - SetStatus(NetServerInfo::BRIEFING); - - if (Starshatter::GetInstance()) { - Starshatter::GetInstance()->SetGameMode(Starshatter::PREP_MODE); - } - else { - StarServer* s = StarServer::GetInstance(); - if (s && s->GetGameMode() == StarServer::MENU_MODE) { - s->SetGameMode(StarServer::LOAD_MODE); - } - } - } -} - -void -NetLobbyServer::GameStop() -{ - if (GetStatus() != NetServerInfo::PERSISTENT) { - SetStatus(NetServerInfo::LOBBY); - - StarServer* s = StarServer::GetInstance(); - if (s && s->GetGameMode() != StarServer::MENU_MODE) { - s->SetGameMode(StarServer::MENU_MODE); - } - } -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyServer::BanUser(NetUser* user) -{ - if (user && !user->IsHost()) { - ::Print("NetLobbyServer::BanUser name '%s' addr %d.%d.%d.%d\n", - user->Name().data(), - user->GetAddress().B1(), - user->GetAddress().B2(), - user->GetAddress().B3(), - user->GetAddress().B4()); - - SendData(user, NET_LOBBY_EXIT, Text()); - - if (server_config) - server_config->BanUser(user); - - DelUser(user); - } -} - -void -NetLobbyServer::AddUser(NetUser* user) -{ - if (server_config && server_config->IsUserBanned(user)) { - delete user; - return; - } - - NetLobby::AddUser(user); - SendUsers(); -} - -void -NetLobbyServer::DelUser(NetUser* user) -{ - NetLobby::DelUser(user); - SendUsers(); -} - -void -NetLobbyServer::SendUsers() -{ - Text content; - - ListIter u_iter = users; - while (++u_iter) { - NetUser* u = u_iter.value(); - content += u->GetDescription(); - } - - u_iter.reset(); - - while (++u_iter) { - NetUser* u = u_iter.value(); - SendData(u, NET_LOBBY_USER_LIST, content); - } -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyServer::RequestAuth(NetUser* user) -{ - if (user) { - Text request = NetAuth::CreateAuthRequest(user); - - if (request.length() > 0) - SendData(user, NET_LOBBY_AUTH_USER, request); - } -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyServer::AddChat(NetUser* user, const char* msg, bool route) -{ - NetChatEntry* entry = 0; - - if (user && msg && *msg) { - bool msg_ok = false; - const char* p = msg; - - while (*p && !msg_ok) { - if (!isspace(*p++)) - msg_ok = true; - } - - if (msg_ok) { - entry = new NetChatEntry(user, msg); - - chat_log.append(entry); - - // forward to all clients: - if (users.size()) { - char buffer[768]; - char msg_buf[256]; - char usr_buf[256]; - - // safe quotes uses a static buffer, - // so make sure to save copies of the - // results when using more than one in - // a function call... - - strcpy_s(msg_buf, SafeQuotes(msg)); - strcpy_s(usr_buf, SafeQuotes(user->Name())); - - sprintf_s(buffer, "id %d user \"%s\" msg \"%s\"", - entry->GetID(), usr_buf, msg_buf); - - ListIter iter = users; - while (++iter) { - NetUser* u = iter.value(); - SendData(u, NET_LOBBY_CHAT, buffer); - } - - if (route) { - // send to active game: - NetUtil::SendChat(0xffff, usr_buf, msg_buf); - } - } - } - } -} - -void -NetLobbyServer::ClearChat() -{ - NetLobby::ClearChat(); -} - -void -NetLobbyServer::SaveChat() -{ - FILE* f; - fopen_s(&f, "chat.txt", "wb"); - if (f) { - for (int i = 0; i < chat_log.size(); i++) { - NetChatEntry* c = chat_log[i]; - fprintf(f, "%08x [%s] %s\n", - c->GetTime(), - c->GetUser().data(), - c->GetMessage().data()); - } - - fclose(f); - } -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyServer::SelectMission(DWORD id) -{ - if (GetStatus() == NetServerInfo::PERSISTENT) - return; - - NetLobby::SelectMission(id); - - // inform all users of the selection: - char buffer[32]; - sprintf_s(buffer, "m_id 0x%08x", selected_mission); - - ListIter iter = users; - while (++iter) { - NetUser* u = iter.value(); - SendData(u, NET_LOBBY_MISSION_SELECT, buffer); - } -} - -// +-------------------------------------------------------------------+ - -List& -NetLobbyServer::GetUnitMap() -{ - if (!mission) { - unit_map.destroy(); - return unit_map; - } - - List units; - ListIter iter = mission->GetElements(); - int i = 0; - - Sim* sim = Sim::GetSim(); - if (sim && sim->GetElements().size() > 0) - iter = sim->GetMissionElements(); - - // create new entries for the playable elements in the mission or simulation: - while (++iter) { - MissionElement* elem = iter.value(); - - if (elem->IsPlayable()) { - NetUnitEntry* u = 0; - if (elem->Count() == 1) { - u = new NetUnitEntry(elem, 0); - u->SetLives(elem->RespawnCount() + 1); - u->SetMissionRole(elem->MissionRole()); - u->SetIFF(elem->GetIFF()); - - if (elem->GetDesign()) - u->SetDesign(elem->GetDesign()->name); - - if (elem->Ships().size() > 0) { - MissionShip* s = elem->Ships()[0]; - u->SetIntegrity((int) s->Integrity()); - } - units.append(u); - } - else { - for (int i = 0; i < elem->Count(); i++) { - u = new NetUnitEntry(elem, i+1); - u->SetMissionRole(elem->MissionRole()); - u->SetIFF(elem->GetIFF()); - - if (elem->GetDesign()) - u->SetDesign(elem->GetDesign()->name); - - if (elem->Ships().size() > i) { - MissionShip* s = elem->Ships()[i]; - u->SetLives(s->Respawns() + 1); - u->SetIntegrity((int) s->Integrity()); - } - units.append(u); - } - } - } - } - - // match new entries with any existing map entries: - if (unit_map.size()) { - for (i = 0; i < units.size(); i++) { - NetUnitEntry* e_new = units[i]; - NetUnitEntry* e_old = unit_map.find(e_new); - - if (e_old) { - e_new->SetUserName(e_old->GetUserName()); - e_new->SetLock(e_old->GetLocked()); - } - } - } - - // rewrite the unit map with the new entries: - ClearUnitMap(); - for (i = 0; i < units.size(); i++) { - unit_map.append(units[i]); - } - - return unit_map; -} - -void -NetLobbyServer::MapUnit(int n, const char* user, bool lock) -{ - NetLobby::MapUnit(n, user, lock); - - Text reply; - - ListIter map_iter = GetUnitMap(); - while (++map_iter) { - NetUnitEntry* unit = map_iter.value(); - reply += unit->GetDescription(); - } - - ListIter u_iter = users; - while (++u_iter) { - NetUser* u = u_iter.value(); - SendData(u, NET_LOBBY_UNIT_LIST, reply); - } -} - -void -NetLobbyServer::UnmapUnit(const char* user) -{ - NetLobby::UnmapUnit(user); - - Text reply; - - ListIter map_iter = GetUnitMap(); - while (++map_iter) { - NetUnitEntry* unit = map_iter.value(); - reply += unit->GetDescription(); - } - - ListIter u_iter = users; - while (++u_iter) { - NetUser* u = u_iter.value(); - SendData(u, NET_LOBBY_UNIT_LIST, reply); - } -} - -void -NetLobbyServer::SendUnits() -{ - Text content; - - ListIter map_iter = GetUnitMap(); - while (++map_iter) { - NetUnitEntry* unit = map_iter.value(); - content += unit->GetDescription(); - } - - ListIter u_iter = users; - while (++u_iter) { - NetUser* u = u_iter.value(); - SendData(u, NET_LOBBY_UNIT_LIST, content); - } -} - -// +-------------------------------------------------------------------+ - -Text -NetLobbyServer::Serialize(Mission* m, NetUser* user) -{ - Text s; - - if (!m || !user) - return s; - - NetUnitEntry* unit = 0; - - ListIter u_iter = GetUnitMap(); - while (++u_iter && !unit) { - NetUnitEntry* u = u_iter.value(); - if (u->GetUserName() == user->Name()) - unit = u; - } - - if (unit) - s = m->Serialize(unit->GetElemName(), unit->GetIndex()); - - return s; -} - -Mission* -NetLobbyServer::GetSelectedMission() -{ - if (mission) { - Text content = Serialize(mission, GetLocalUser()); - Campaign* c = Campaign::SelectCampaign("Multiplayer Missions"); - - if (c) { - c->LoadNetMission(99999, content.data()); - return c->GetMission(99999); - } - } - - return mission; -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyServer::GameOn() -{ - NetHost host; - const char* type = "Starshatter"; - const char* password = "No"; - char address[32]; - - strcpy_s(address, "0"); - - if (server_config) { - if (server_config->GetGameType() == NetServerConfig::NET_GAME_PRIVATE) - return; - - if (server_config->GetGameType() == NetServerConfig::NET_GAME_LAN) { - type = "Starshatter-LAN"; - sprintf_s(address, "%d.%d.%d.%d", - host.Address().B1(), - host.Address().B2(), - host.Address().B3(), - host.Address().B4()); - } - else { - type = "Starshatter"; - sprintf_s(address, "0.0.0.0"); - } - - if (server_config->GetGamePass().length() > 0) - password = "Yes"; - } - - NetBrokerClient::GameOn(server_name, - type, - address, - server_addr.Port(), - password); -} - -void -NetLobbyServer::GameOff() -{ -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyServer::DoPing(NetPeer* peer, Text s) -{ } - -void -NetLobbyServer::DoServerInfo(NetPeer* peer, Text s) -{ - if (peer && peer->NetID()) { - char buffer[1024]; - WORD gameport = 11101; - - if (server_config) - gameport = server_config->GetGamePort(); - - sprintf_s(buffer, "info \"%s\" version \"%s\" mode %d users %d host %s port %d", - MachineInfo::GetShortDescription(), - versionInfo, - GetStatus(), - NumUsers(), - HasHost() ? "true" : "false", - gameport); - - link->SendMessage(peer->NetID(), (BYTE) NET_LOBBY_SERVER_INFO, buffer, strlen(buffer), NetMsg::RELIABLE); - } -} - -void -NetLobbyServer::DoServerMods(NetPeer* peer, Text s) -{ - if (peer && peer->NetID()) { - Text response; - ModConfig* config = ModConfig::GetInstance(); - List& mods = config->GetModInfoList(); - ListIter mod_iter = mods; - - char buffer[32]; - sprintf_s(buffer, "num %d ", mods.size()); - response += buffer; - - while (++mod_iter) { - ModInfo* info = mod_iter.value(); - - response += "mod \""; - response += info->Name(); - response += "\" url \""; - response += info->URL(); - response += "\" ver \""; - response += info->Version(); - response += "\" "; - } - - link->SendMessage(peer->NetID(), (BYTE) NET_LOBBY_SERVER_MODS, response, response.length(), NetMsg::RELIABLE); - } -} - -// +-------------------------------------------------------------------+ - -void -NetLobbyServer::DoLogin(NetPeer* peer, Text msg) -{ - List params; - ParseMsg(msg, params); - - Text name; - Text pass; - Text host; - Text gamepass; - Text signature; - Text squadron; - Text version; - int rank = 0; - int flight_time = 0; - int missions = 0; - int kills = 0; - int losses = 0; - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - int num = 0; - sscanf_s(p->value, "%d", &num); - - if (p->name == "name") - name = p->value; - - else if (p->name == "pass") - pass = p->value; - - else if (p->name == "gamepass") - gamepass = p->value; - - else if (p->name == "host") - host = p->value; - - else if (p->name == "sig") - signature = p->value; - - else if (p->name == "squad") - squadron = p->value; - - else if (p->name == "version") - version = p->value; - - else if (p->name == "rank") - rank = num; - - else if (p->name == "time") - flight_time = num; - - else if (p->name == "miss") - missions = num; - - else if (p->name == "kill") - kills = num; - - else if (p->name == "loss") - losses = num; - } - - params.destroy(); - - // first check the game version: - if (version != versionInfo) { - Print("NetLobbyServer - user '%s' tried to login with invalid game version '%s'\n", - name.data(), version.data()); - - return; - } - - // next check the game password: - if (server_config && server_config->GetGamePass().length() > 0) { - if (gamepass != server_config->GetGamePass()) { - Print("NetLobbyServer - user '%s' tried to login with invalid game password '%s'\n", - name.data(), gamepass.data()); - - return; - } - } - - // now try to log the user in: - NetUser* pre_existing = FindUserByName(name); - - // is user already logged in? - if (pre_existing) { - if (pre_existing->Pass() == pass && - pre_existing->GetAddress().IPAddr() == peer->Address().IPAddr()) { - } - } - - // otherwise, create a new user: - else { - NetUser* user = new NetUser(name); - user->SetAddress(peer->Address()); - user->SetNetID(peer->NetID()); - user->SetPass(pass); - user->SetSignature(signature); - user->SetSquadron(squadron); - user->SetRank(rank); - user->SetFlightTime(flight_time); - user->SetMissions(missions); - user->SetKills(kills); - user->SetLosses(losses); - - if (host == "true" && !HasHost()) - user->SetHost(true); - - AddUser(user); - RequestAuth(user); - SendMOTD(user); - SendMods(user); - } -} - -void -NetLobbyServer::DoLogout(NetPeer* peer, Text msg) -{ - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user) { - if (user->IsHost()) - GameStop(); - - DelUser(user); - } -} - -void -NetLobbyServer::DoUserAuth(NetPeer* peer, Text msg) -{ - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user) { - NetAuth::AuthUser(user, msg); - - if (!user->IsAuthOK()) { - char buffer[256]; - - sprintf_s(buffer, "id %d user \"SERVER\" msg \"**********\"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); - - sprintf_s(buffer, "id %d user \"SERVER\" msg \"*** Your game configuration does not match the server.\"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); - - if (server_mods.size() > 0) { - sprintf_s(buffer, "id %d user \"SERVER\" msg \"*** Please check that you have the proper mods deployed in\"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); - sprintf_s(buffer, "id %d user \"SERVER\" msg \"*** the order shown above.\"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); - } - - else { - sprintf_s(buffer, "id %d user \"SERVER\" msg \"*** Please verify that you have no mods deployed.\"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); - } - - sprintf_s(buffer, "id %d user \"SERVER\" msg \"*** You will not be permitted to join the game with an invalid\"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); - - sprintf_s(buffer, "id %d user \"SERVER\" msg \"*** configuration. You may reconnect to this server after you\"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); - - sprintf_s(buffer, "id %d user \"SERVER\" msg \"*** have corrected your mod configuration.\"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); - - sprintf_s(buffer, "id %d user \"SERVER\" msg \"**********\"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); - - sprintf_s(buffer, "id %d user \" \" msg \" \"", motd_index++); - SendData(user, NET_LOBBY_CHAT, buffer); - } - } -} - -void -NetLobbyServer::DoChat(NetPeer* peer, Text msg) -{ - List params; - ParseMsg(msg, params); - - Text chat_msg; - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - int num = 0; - sscanf_s(p->value, "%d", &num); - - if (p->name == "msg") { - chat_msg = p->value; - } - } - - params.destroy(); - - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user) { - // receive chat from client: - if (chat_msg.length()) { - AddChat(user, chat_msg); - } - - // request for chat log: - else { - ListIter iter = chat_log; - while (++iter) { - NetChatEntry* entry = iter.value(); - - char buffer[512]; - char msg_buf[256]; - char usr_buf[256]; - - // safe quotes uses a static buffer, - // so make sure to save copies of the - // results when using more than one in - // a function call... - - strcpy_s(msg_buf, SafeQuotes(entry->GetMessage())); - strcpy_s(usr_buf, SafeQuotes(entry->GetUser())); - - sprintf_s(buffer, "id %d user \"%s\" msg \"%s\"", - entry->GetID(), usr_buf, msg_buf); - - SendData(user, NET_LOBBY_CHAT, buffer); - } - } - } -} - -void -NetLobbyServer::DoUserList(NetPeer* peer, Text msg) -{ - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user) { - Text content; - - if (local_user) - content += local_user->GetDescription(); - - ListIter iter = users; - while (++iter) { - NetUser* u = iter.value(); - content += u->GetDescription(); - } - - SendData(user, NET_LOBBY_USER_LIST, content); - } -} - -void -NetLobbyServer::DoBanUser(NetPeer* peer, Text msg) -{ - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user && user->IsHost() && user->IsAuthOK()) { - List params; - ParseMsg(msg, params); - - if (params.size() > 0) { - NetLobbyParam* p = params[0]; - - if (p->name == "user") { - Text user_name = p->value; - - NetUser* u = FindUserByName(user_name); - if (u && !u->IsHost()) - BanUser(u); - } - } - - params.destroy(); - } -} - -void -NetLobbyServer::DoMissionList(NetPeer* peer, Text msg) -{ - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user) { - Text reply; - char buffer[4096]; - - ListIter c_iter = Campaign::GetAllCampaigns(); - while (++c_iter) { - Campaign* c = c_iter.value(); - - if (c->GetCampaignId() >= Campaign::MULTIPLAYER_MISSIONS) { - sprintf_s(buffer, "c_id 0x%08x c_name \"%s\" ", - c->GetCampaignId(), - SafeQuotes(c->Name())); - - reply += buffer; - } - } - - c_iter.reset(); - - while (++c_iter) { - Campaign* c = c_iter.value(); - - if (c->GetCampaignId() >= Campaign::MULTIPLAYER_MISSIONS) { - - ListIter m_iter = c->GetMissionList(); - while (++m_iter) { - MissionInfo* m = m_iter.value(); - - int mission_id = (c->GetCampaignId() << NET_CAMPAIGN_SHIFT) + m->id; - - sprintf_s(buffer, "m_id 0x%08x ", mission_id); - reply += buffer; - - reply += "m_name \""; - reply += SafeQuotes(m->name); - - // long version of safe quotes: - int n = 0; - const char* s = m->description.data(); - - while (*s && n < 4090) { - if (*s == '"') { - buffer[n++] = '\''; - s++; - } - else if (*s == '\n') { - buffer[n++] = '\\'; - buffer[n++] = 'n'; - s++; - } - else if (*s == '\t') { - buffer[n++] = '\\'; - buffer[n++] = 't'; - s++; - } - else { - buffer[n++] = *s++; - } - } - - // don't forget the null terminator! - buffer[n] = 0; - - reply += "\" m_desc \""; - reply += buffer; - - reply += "\" "; - } - } - } - - SendData(user, NET_LOBBY_MISSION_LIST, reply); - - sprintf_s(buffer, "m_id 0x%08x", selected_mission); - SendData(user, NET_LOBBY_MISSION_SELECT, buffer); - } -} - -void -NetLobbyServer::DoMissionSelect(NetPeer* peer, Text msg) -{ - if (GetStatus() == NetServerInfo::PERSISTENT) - return; - - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user && user->IsHost() && user->IsAuthOK()) { - List params; - ParseMsg(msg, params); - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - int num = 0; - sscanf_s(p->value, "0x%x", &num); - - if (p->name == "m_id") { - SelectMission(num); - } - } - - params.destroy(); - } -} - -void -NetLobbyServer::DoMissionData(NetPeer* peer, Text msg) -{ - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user && mission && user->IsAuthOK()) { - Text reply = Serialize(mission, user); - SendData(user, NET_LOBBY_MISSION_DATA, reply); - - FILE* f = ::fopen("multi_mission_send.def", "wb"); - if (f) { - ::fwrite(reply.data(), reply.length(), 1, f); - ::fclose(f); - } - } -} - -void -NetLobbyServer::DoUnitList(NetPeer* peer, Text msg) -{ - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user && unit_map.size() && user->IsAuthOK()) { - Text reply; - - ListIter iter = GetUnitMap(); - while (++iter) { - NetUnitEntry* unit = iter.value(); - reply += unit->GetDescription(); - } - - SendData(user, NET_LOBBY_UNIT_LIST, reply); - } -} - -void -NetLobbyServer::DoMapUnit(NetPeer* peer, Text msg) -{ - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user && unit_map.size() && user->IsAuthOK()) { - List params; - ParseMsg(msg, params); - - int id = 0; - bool lock = false; - Text user_name; - - for (int i = 0; i < params.size(); i++) { - NetLobbyParam* p = params[i]; - - if (p->name == "id") { - sscanf_s(p->value, "%d", &id); - } - - else if (p->name == "user") { - user_name = p->value; - } - - else if (p->name == "lock") { - lock = (p->value == "true") ? true : false; - } - } - - params.destroy(); - - MapUnit(id, user_name, lock); - } -} - -void -NetLobbyServer::DoGameStart(NetPeer* peer, Text msg) -{ - GameStart(); -} - -void -NetLobbyServer::DoGameStop(NetPeer* peer, Text msg) -{ - NetUser* user = FindUserByNetID(peer->NetID()); - - if (user && user->IsHost() && user->IsAuthOK()) - GameStop(); -} diff --git a/Stars45/NetLobbyServer.h b/Stars45/NetLobbyServer.h deleted file mode 100644 index 0b1327a..0000000 --- a/Stars45/NetLobbyServer.h +++ /dev/null @@ -1,118 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - UDP Server Engine for Multiplayer Lobby -*/ - - -#ifndef NetLobbyServer_h -#define NetLobbyServer_h - -// FOR NETWORK MENU TESTING (extra latency in msec): -// #define EXTRA_LATENCY 300 - -#include "NetLobby.h" - -// +-------------------------------------------------------------------+ - -class Mission; -class MissionElement; -class NetChatEntry; -class NetServerConfig; -class NetUser; -class NetUnitEntry; - -// +-------------------------------------------------------------------+ - -class NetLobbyServer : public NetLobby -{ -public: - NetLobbyServer(); - virtual ~NetLobbyServer(); - - int operator == (const NetLobbyServer& s) const { return this == &s; } - - virtual void ExecFrame(); - virtual bool IsHost() const { return true; } - virtual bool IsServer() const { return true; } - - virtual void BanUser(NetUser* user); - virtual void AddUser(NetUser* user); - virtual void DelUser(NetUser* user); - virtual void SendUsers(); - virtual void RequestAuth(NetUser* user); - - virtual void AddChat(NetUser* user, const char* msg, bool route=true); - virtual void ClearChat(); - virtual void SaveChat(); - - virtual List& - GetUnitMap(); - virtual void MapUnit(int n, const char* user, bool lock=false); - virtual void UnmapUnit(const char* user); - virtual void SendUnits(); - - virtual void SelectMission(DWORD id); - virtual Text Serialize(Mission* m, NetUser* u=0); - virtual Mission* GetSelectedMission(); - - virtual Text GetServerName() const { return server_name; } - virtual void SetServerName(const char* s) { server_name = s; } - virtual Text GetServerMission() const { return server_mission; } - virtual void SetServerMission(const char* script) - { server_mission = script; } - - virtual void GameStart(); - virtual void GameStop(); - - virtual void GameOn(); - virtual void GameOff(); - - // singleton locator: - static NetLobbyServer* GetInstance(); - -protected: - virtual void CheckSessions(); - - virtual void SendData(NetUser* dst, int type, Text msg); - virtual void DoPing(NetPeer* peer, Text msg); - virtual void DoServerInfo(NetPeer* peer, Text msg); - virtual void DoServerMods(NetPeer* peer, Text msg); - virtual void DoLogin(NetPeer* peer, Text msg); - virtual void DoLogout(NetPeer* peer, Text msg); - virtual void DoUserAuth(NetPeer* peer, Text msg); - virtual void DoChat(NetPeer* peer, Text msg); - virtual void DoUserList(NetPeer* peer, Text msg); - virtual void DoBanUser(NetPeer* peer, Text msg); - virtual void DoMissionList(NetPeer* peer, Text msg); - virtual void DoMissionSelect(NetPeer* peer, Text msg); - virtual void DoMissionData(NetPeer* peer, Text msg); - virtual void DoUnitList(NetPeer* peer, Text msg); - virtual void DoMapUnit(NetPeer* peer, Text msg); - virtual void DoGameStart(NetPeer* peer, Text msg); - virtual void DoGameStop(NetPeer* peer, Text msg); - - virtual void LoadMOTD(); - virtual void SendMOTD(NetUser* user); - virtual void SendMods(NetUser* user); - - Text server_name; - NetAddr server_addr; - DWORD announce_time; - NetServerConfig* server_config; - Text server_mission; - int motd_index; - - List motd; -}; - -// +-------------------------------------------------------------------+ - -#endif // NetLobbyServer_h \ No newline at end of file diff --git a/Stars45/NetPacket.cpp b/Stars45/NetPacket.cpp deleted file mode 100644 index 1056e11..0000000 --- a/Stars45/NetPacket.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Network Game Manager and Player classes -*/ - -#include "NetPacket.h" -#include "NetLink.h" -#include "NetMsg.h" -#include "Ship.h" - -#include "Game.h" - -// +--------------------------------------------------------------------+ - -const int PING_SIZE = 8; -const int SHIP_LOC_SIZE = 36; -const int JOIN_REQ_SIZE = 116; -const int JOIN_ANN_SIZE = 116; -const int QUIT_ANN_SIZE = 8; - -// +--------------------------------------------------------------------+ - -NetPacket::NetPacket(NetMsg* g) -: msg(g) -{ } - -NetPacket::NetPacket(DWORD netid, BYTE type) -{ - int len = 0; - char buf[256]; - ZeroMemory(buf, 256); - - switch (type) { - case NET_PING: len = PING_SIZE; break; - case NET_PONG: len = PING_SIZE; break; - case NET_OBJ_LOC: len = SHIP_LOC_SIZE; break; - - case NET_JOIN_REQUEST: len = JOIN_REQ_SIZE; break; - case NET_JOIN_ANNOUNCE: len = JOIN_ANN_SIZE; break; - case NET_QUIT_ANNOUNCE: len = QUIT_ANN_SIZE; break; - - default: len = JOIN_REQ_SIZE; break; - } - - msg = new NetMsg(netid, type, buf, len); -} - -NetPacket::~NetPacket() -{ - delete msg; -} - -bool -NetPacket::Send(NetLink& link) -{ - bool sent = false; - - if (msg) - sent = link.SendMessage(msg); - - msg = 0; - return sent; -} - -// +--------------------------------------------------------------------+ - -DWORD -NetPacket::NetID() const -{ - if (msg) - return msg->NetID(); - - return 0; -} - -BYTE -NetPacket::Type() const -{ - if (msg) - return msg->Type(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -DWORD -NetPacket::GetPingSequence() -{ - if (msg && msg->Length() >= PING_SIZE) { - DWORD* data = (DWORD*) (msg->Data()+4); - return *data; - } - - return 0; -} - -void -NetPacket::SetPingSequence(DWORD seq) -{ - if (msg && msg->Length() >= PING_SIZE) { - DWORD* data = (DWORD*) (msg->Data()+4); - *data = seq; - } -} - -// +--------------------------------------------------------------------+ - -DWORD -NetPacket::GetNetID() -{ - if (msg && msg->Length() >= PING_SIZE) { - DWORD* data = (DWORD*) (msg->Data()+4); - return *data; - } - - return 0; -} - -void -NetPacket::SetNetID(DWORD id) -{ - if (msg && msg->Length() >= PING_SIZE) { - DWORD* data = (DWORD*) (msg->Data()+4); - *data = id; - } -} - -// +--------------------------------------------------------------------+ - -Point -NetPacket::GetShipLocation() -{ - if (msg && msg->Length() >= SHIP_LOC_SIZE) { - long* data = (long*) (msg->Data()+8); - long x = *(data + 0); - long y = *(data + 1); - long z = *(data + 2); - - return Point(x/100.0, y/100.0, z/100.0); - } - - return Point(); -} - -void -NetPacket::SetShipLocation(const Point& loc) -{ - if (msg && msg->Length() >= SHIP_LOC_SIZE) { - long x = (long) (loc.x * 100); - long y = (long) (loc.y * 100); - long z = (long) (loc.z * 100); - - long* data = (long*) (msg->Data()+8); - - *(data + 0) = x; - *(data + 1) = y; - *(data + 2) = z; - } -} - -// +--------------------------------------------------------------------+ - -Point -NetPacket::GetShipVelocity() -{ - if (msg && msg->Length() >= SHIP_LOC_SIZE) { - short* data = (short*) (msg->Data()+20); - - short dx = *(data + 0); - short dy = *(data + 1); - short dz = *(data + 2); - - return Point(dx, dy, dz); - } - - return Point(); -} - -void -NetPacket::SetShipVelocity(const Point& vel) -{ - if (msg && msg->Length() >= SHIP_LOC_SIZE) { - short* data = (short*) (msg->Data()+20); - - *(data + 0) = (short) vel.x; - *(data + 1) = (short) vel.y; - *(data + 2) = (short) vel.z; - } -} - -// +--------------------------------------------------------------------+ - -Point -NetPacket::GetShipOrientation() -{ - if (msg && msg->Length() >= SHIP_LOC_SIZE) { - short* data = (short*) (msg->Data()+26); - - short r = *(data + 0); - short p = *(data + 1); - short y = *(data + 2); - - return Point(2*PI*r/32767, 2*PI*p/32767, 2*PI*y/32767); - } - - return Point(); -} - -void -NetPacket::SetShipOrientation(const Point& rpy) -{ - if (msg && msg->Length() >= SHIP_LOC_SIZE) { - short* data = (short*) (msg->Data()+26); - - *(data + 0) = (short) (32767*rpy.x/(2*PI)); - *(data + 1) = (short) (32767*rpy.y/(2*PI)); - *(data + 2) = (short) (32767*rpy.z/(2*PI)); - } -} - -// +--------------------------------------------------------------------+ - -double -NetPacket::GetThrottle() -{ - if (msg && msg->Length() >= SHIP_LOC_SIZE) { - BYTE* data = (BYTE*) msg->Data()+32; - - return (double) *data; - } - - return 0; -} - -void -NetPacket::SetThrottle(double t) -{ - if (msg && msg->Length() >= SHIP_LOC_SIZE) { - BYTE* data = (BYTE*) msg->Data()+32; - - *data = (BYTE) t; - } -} - -// +--------------------------------------------------------------------+ - -bool -NetPacket::GetTrigger(int i) -{ - if (i >= 0 && i < 8 && msg && msg->Length() >= SHIP_LOC_SIZE) { - BYTE* data = (BYTE*) msg->Data()+33; - - BYTE select = 1 << i; - return (*data & select)?true:false; - } - - return false; -} - -void -NetPacket::SetTrigger(int i, bool trigger) -{ - if (i >= 0 && i < 8 && msg && msg->Length() >= SHIP_LOC_SIZE) { - BYTE* data = (BYTE*) msg->Data()+33; - - BYTE select = 1 << i; - - if (trigger) - *data = *data | select; - else - *data = *data & ~select; - } -} - -// +--------------------------------------------------------------------+ - -const char* -NetPacket::GetName() -{ - if (msg && msg->Length() >= JOIN_REQ_SIZE) { - BYTE* data = (BYTE*) msg->Data()+20; - - return (const char*) data; - } - - return 0; -} - -void -NetPacket::SetName(const char* name) -{ - if (msg && msg->Length() >= JOIN_REQ_SIZE) { - BYTE* data = (BYTE*) msg->Data()+20; - strncpy((char*) data, name, 32); - } -} - -// +--------------------------------------------------------------------+ - -const char* -NetPacket::GetDesign() -{ - if (msg && msg->Length() >= JOIN_REQ_SIZE) { - BYTE* data = (BYTE*) msg->Data()+52; - - return (const char*) data; - } - - return 0; -} - -void -NetPacket::SetDesign(const char* design) -{ - if (msg && msg->Length() >= JOIN_REQ_SIZE) { - BYTE* data = (BYTE*) msg->Data()+52; - strncpy((char*) data, design, 32); - } -} - -// +--------------------------------------------------------------------+ - -const char* -NetPacket::GetRegion() -{ - if (msg && msg->Length() >= JOIN_REQ_SIZE) { - BYTE* data = (BYTE*) msg->Data()+84; - - return (const char*) data; - } - - return 0; -} - -void -NetPacket::SetRegion(const char* rgn_name) -{ - if (msg && msg->Length() >= JOIN_REQ_SIZE) { - BYTE* data = (BYTE*) msg->Data()+84; - strncpy((char*) data, rgn_name, 32); - } -} - -// +--------------------------------------------------------------------+ - diff --git a/Stars45/NetPacket.h b/Stars45/NetPacket.h deleted file mode 100644 index 910eaab..0000000 --- a/Stars45/NetPacket.h +++ /dev/null @@ -1,73 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Wrapper for low-level datagram class -*/ - -#ifndef NetPacket_h -#define NetPacket_h - -#include "Types.h" -#include "Geometry.h" -#include "NetData.h" - -// +--------------------------------------------------------------------+ - -class NetLink; -class NetMsg; - -// +--------------------------------------------------------------------+ - -class NetPacket -{ -public: - static const char* TYPENAME() { return "NetPacket"; } - - NetPacket(NetMsg* g); - NetPacket(DWORD netid, BYTE type); - ~NetPacket(); - - bool Send(NetLink& link); - - // various accessors: - DWORD NetID() const; - BYTE Type() const; - - DWORD GetPingSequence(); - void SetPingSequence(DWORD seq); - DWORD GetNetID(); - void SetNetID(DWORD id); - Point GetShipLocation(); - void SetShipLocation(const Point& loc); - Point GetShipVelocity(); - void SetShipVelocity(const Point& vel); - Point GetShipOrientation(); - void SetShipOrientation(const Point& rpy); - double GetThrottle(); - void SetThrottle(double t); - const char* GetName(); - void SetName(const char* name); - const char* GetDesign(); - void SetDesign(const char* design); - const char* GetRegion(); - void SetRegion(const char* rgn_name); - bool GetTrigger(int i); - void SetTrigger(int i, bool trigger); - - -protected: - NetMsg* msg; -}; - - -// +--------------------------------------------------------------------+ - -#endif // NetPacket_h - diff --git a/Stars45/NetPassDlg.cpp b/Stars45/NetPassDlg.cpp deleted file mode 100644 index d510dbd..0000000 --- a/Stars45/NetPassDlg.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Network Server Password Dialog Active Window class -*/ - -#include "NetPassDlg.h" -#include "MenuScreen.h" -#include "NetClientConfig.h" -#include "NetLobby.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "EditBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(NetPassDlg, OnApply); -DEF_MAP_CLIENT(NetPassDlg, OnCancel); - -// +--------------------------------------------------------------------+ - -NetPassDlg::NetPassDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -btn_apply(0), btn_cancel(0), edt_pass(0), lbl_name(0) -{ - Init(def); -} - -NetPassDlg::~NetPassDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -NetPassDlg::RegisterControls() -{ - btn_apply = (Button*) FindControl(1); - btn_cancel = (Button*) FindControl(2); - - REGISTER_CLIENT(EID_CLICK, btn_apply, NetPassDlg, OnApply); - REGISTER_CLIENT(EID_CLICK, btn_cancel, NetPassDlg, OnCancel); - - lbl_name = FindControl(110); - edt_pass = (EditBox*) FindControl(200); - - if (edt_pass) - edt_pass->SetText(""); -} - -// +--------------------------------------------------------------------+ - -void -NetPassDlg::Show() -{ - if (!IsShown()) { - FormWindow::Show(); - - NetClientConfig* config = NetClientConfig::GetInstance(); - - if (config && lbl_name) { - NetServerInfo* info = config->GetSelectedServer(); - - if (info) - lbl_name->SetText(info->name); - } - - if (edt_pass) { - edt_pass->SetText(""); - edt_pass->SetFocus(); - } - } -} - -// +--------------------------------------------------------------------+ - -static bool tab_latch = false; - -void -NetPassDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnApply(0); - } -} - -// +--------------------------------------------------------------------+ - -void -NetPassDlg::OnApply(AWEvent* event) -{ - NetClientConfig* config = NetClientConfig::GetInstance(); - - if (config && edt_pass) { - NetServerInfo* info = config->GetSelectedServer(); - - if (info && edt_pass->GetText().length() < 250) { - char buffer[256]; - strcpy_s(buffer, edt_pass->GetText().data()); - - // trim from first occurrence of invalid character - char* p = strpbrk(buffer, "\n\r\t"); - if (p) *p = 0; - - info->password = SafeQuotes(buffer); - - if (manager) { - manager->ShowNetLobbyDlg(); - return; - } - } - } - - if (manager) { - manager->ShowNetClientDlg(); - } -} - -void -NetPassDlg::OnCancel(AWEvent* event) -{ - if (manager) - manager->ShowNetClientDlg(); -} diff --git a/Stars45/NetPassDlg.h b/Stars45/NetPassDlg.h deleted file mode 100644 index de66b7e..0000000 --- a/Stars45/NetPassDlg.h +++ /dev/null @@ -1,57 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Network Server Password Dialog Active Window class -*/ - -#ifndef NetPassDlg_h -#define NetPassDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; - -// +--------------------------------------------------------------------+ - -class NetPassDlg : public FormWindow -{ -public: - NetPassDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~NetPassDlg(); - - virtual void RegisterControls(); - virtual void Show(); - - // Operations: - virtual void ExecFrame(); - - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - -protected: - MenuScreen* manager; - - Button* btn_apply; - Button* btn_cancel; - EditBox* edt_pass; - ActiveWindow* lbl_name; -}; - -#endif // NetPassDlg_h - diff --git a/Stars45/NetPlayer.cpp b/Stars45/NetPlayer.cpp deleted file mode 100644 index 9632b94..0000000 --- a/Stars45/NetPlayer.cpp +++ /dev/null @@ -1,468 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Network Player (Director) class -*/ - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include - -#include "NetPlayer.h" -#include "NetGame.h" -#include "NetMsg.h" -#include "NetData.h" -#include "NetUtil.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Shield.h" -#include "Shot.h" -#include "Sim.h" -#include "SimEvent.h" -#include "System.h" -#include "Weapon.h" -#include "WeaponGroup.h" -#include "Element.h" -#include "HUDView.h" -#include "Explosion.h" -#include "Farcaster.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" - -#include "NetHost.h" -#include "Game.h" -#include "Light.h" - -// +--------------------------------------------------------------------+ - -NetPlayer::~NetPlayer() -{ - if (ship) { - ship->SetNetworkControl(); - - Sim* sim = Sim::GetSim(); - sim->DestroyShip(ship); - } -} - -// +--------------------------------------------------------------------+ - -void -NetPlayer::SetShip(Ship* s) -{ - if (ship != s) { - if (ship) { - ship->EnableRepair(true); - Ignore(ship); - } - - ship = s; - - if (ship) { - Observe(ship); - ship->SetNetworkControl(this); - ship->SetObjID(objid); - - iff = ship->GetIFF(); - - // Turn off auto-repair. All repair data should - // come in over the network from the remote player: - - ship->EnableRepair(false); - - // Set all ship weapons back to manual fire control. - // All trigger events should come over the network, - // not from weapon auto aiming ai: - - ListIter iter = ship->Weapons(); - while (++iter) { - WeaponGroup* group = iter.value(); - - ListIter w_iter = group->GetWeapons(); - while (++w_iter) { - Weapon* weapon = w_iter.value(); - - weapon->SetFiringOrders(Weapon::MANUAL); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -const double BLEED = 0.5; - -bool -NetPlayer::DoObjLoc(NetObjLoc* obj_loc) -{ - if (ship && obj_loc) { - loc_error = obj_loc->GetLocation() - ship->Location(); - bleed_time = BLEED; - - ship->SetVelocity(obj_loc->GetVelocity()); - Point o = obj_loc->GetOrientation(); - ship->SetAbsoluteOrientation(o.x, o.y, o.z); - ship->SetThrottle(obj_loc->GetThrottle() ? 100 : 0); - ship->SetAugmenter(obj_loc->GetAugmenter()); - - if (obj_loc->GetGearDown()) - ship->LowerGear(); - else - ship->RaiseGear(); - - Shield* shield = ship->GetShield(); - if (shield) - shield->SetPowerLevel(obj_loc->GetShield()); - - return true; - } - - return false; -} - -bool -NetPlayer::DoObjHyper(NetObjHyper* obj_hyper) -{ - if (ship && obj_hyper) { - Sim* sim = Sim::GetSim(); - SimRegion* rgn = sim->FindRegion(obj_hyper->GetRegion()); - DWORD fc1_id = obj_hyper->GetFarcaster1(); - DWORD fc2_id = obj_hyper->GetFarcaster2(); - Ship* fc1 = 0; - Ship* fc2 = 0; - int trans = obj_hyper->GetTransitionType(); - - if (ship->GetRegion() == rgn) { - ::Print("NetPlayer::DoObjHyper ship: '%s' rgn: '%s' trans: %d (IGNORED)\n\n", - ship->Name(), obj_hyper->GetRegion().data(), trans); - - return false; - } - - ::Print("NetPlayer::DoObjHyper ship: '%s' rgn: '%s' trans: %d\n\n", - ship->Name(), obj_hyper->GetRegion().data(), trans); - - // orbital transition? - if (trans == Ship::TRANSITION_DROP_ORBIT) { - ship->SetTransition(1.0f, Ship::TRANSITION_DROP_ORBIT, ship->Location()); - ship->CompleteTransition(); - } - - else if (trans == Ship::TRANSITION_MAKE_ORBIT) { - ship->SetTransition(1.0f, Ship::TRANSITION_MAKE_ORBIT, ship->Location()); - ship->CompleteTransition(); - } - - else { - if (fc1_id) - fc1 = sim->FindShipByObjID(fc1_id); - - if (fc2_id) - fc2 = sim->FindShipByObjID(fc2_id); - - sim->CreateExplosion(ship->Location(), Point(0,0,0), - Explosion::QUANTUM_FLASH, 1.0f, 0, ship->GetRegion()); - - sim->RequestHyperJump(ship, rgn, obj_hyper->GetLocation(), trans, fc1, fc2); - - ShipStats* stats = ShipStats::Find(ship->Name()); - stats->AddEvent(SimEvent::QUANTUM_JUMP, rgn->Name()); - } - - return true; - } - - return false; -} - -bool -NetPlayer::DoObjTarget(NetObjTarget* obj_target) -{ - if (ship && obj_target) { - DWORD tgtid = obj_target->GetTgtID(); - int subid = obj_target->GetSubtarget(); - SimObject* target = 0; - System* subtgt = 0; - - NetGame* net_game = NetGame::GetInstance(); - if (net_game && tgtid) { - target = net_game->FindShipByObjID(tgtid); - - if (target) { - if (subid >= 0) { - Ship* tgt_ship = (Ship*) target; - subtgt = tgt_ship->Systems().at(subid); - } - } - else { - target = net_game->FindShotByObjID(tgtid); - } - } - - ship->SetTarget(target, subtgt, true); // from net = true (don't resend) - - return true; - } - - return false; -} - -bool -NetPlayer::DoObjEmcon(NetObjEmcon* obj_emcon) -{ - if (ship && obj_emcon) { - int emcon = obj_emcon->GetEMCON(); - ship->SetEMCON(emcon, true); // from net = true (don't resend) - - return true; - } - - return false; -} - -bool -NetPlayer::DoWepTrigger(NetWepTrigger* trigger) -{ - if (ship && trigger) { - int index = trigger->GetIndex(); - int count = trigger->GetCount(); - DWORD tgtid = trigger->GetTgtID(); - int subid = trigger->GetSubtarget(); - bool decoy = trigger->GetDecoy(); - bool probe = trigger->GetProbe(); - - Weapon* w = 0; - - if (decoy) w = ship->GetDecoy(); - else if (probe) w = ship->GetProbeLauncher(); - else w = ship->GetWeaponByIndex(index); - - if (w) { - SimObject* target = 0; - System* subtgt = 0; - - NetGame* net_game = NetGame::GetInstance(); - if (net_game) { - target = net_game->FindShipByObjID(tgtid); - - if (target) { - if (subid >= 0) { - Ship* tgt_ship = (Ship*) target; - subtgt = tgt_ship->Systems().at(subid); - } - } - else { - target = net_game->FindShotByObjID(tgtid); - } - - // re-broadcast: - if (net_game->IsServer()) { - if (w->IsPrimary()) { - w->NetFirePrimary(target, subtgt, count); - net_game->SendData(trigger); - } - else { - DWORD wepid = NetGame::GetNextObjID(NetGame::SHOT); - Shot* shot = w->NetFireSecondary(target, subtgt, wepid); - - if (shot && shot->IsDrone()) { - if (probe) - ship->SetProbe((Drone*) shot); - - else if (decoy) - ship->AddActiveDecoy((Drone*) shot); - } - - NetWepRelease release; - release.SetObjID(objid); - release.SetTgtID(tgtid); - release.SetSubtarget(subid); - release.SetWepID(wepid); - release.SetIndex(index); - release.SetDecoy(decoy); - release.SetProbe(probe); - - net_game->SendData(&release); - } - } - - else { - if (w->IsPrimary()) { - w->NetFirePrimary(target, subtgt, count); - } - } - - return true; - } - } - - } - return false; -} - -bool -NetPlayer::DoWepRelease(NetWepRelease* release) -{ - if (ship && release) { - int index = release->GetIndex(); - DWORD tgtid = release->GetTgtID(); - DWORD wepid = release->GetWepID(); - int subid = release->GetSubtarget(); - bool decoy = release->GetDecoy(); - bool probe = release->GetProbe(); - - Weapon* w = 0; - - if (decoy) w = ship->GetDecoy(); - else if (probe) w = ship->GetProbeLauncher(); - else w = ship->GetWeaponByIndex(index); - - if (w && !w->IsPrimary()) { - SimObject* target = 0; - System* subtgt = 0; - - NetGame* net_game = NetGame::GetInstance(); - if (net_game) { - target = net_game->FindShipByObjID(tgtid); - - if (target) { - if (subid >= 0) { - Ship* tgt_ship = (Ship*) target; - subtgt = tgt_ship->Systems().at(subid); - } - } - else { - target = net_game->FindShotByObjID(tgtid); - } - } - - Shot* shot = w->NetFireSecondary(target, subtgt, wepid); - - if (shot && shot->IsDrone()) { - if (probe) - ship->SetProbe((Drone*) shot); - - else if (decoy) - ship->AddActiveDecoy((Drone*) shot); - } - - return true; - } - } - - return false; -} - -bool -NetPlayer::DoCommMessage(NetCommMsg* comm_msg) -{ - if (ship && comm_msg) { - RadioTraffic* traffic = RadioTraffic::GetInstance(); - RadioMessage* radio_msg = comm_msg->GetRadioMessage(); - - if (traffic && radio_msg) { - if (radio_msg->DestinationElem() || radio_msg->DestinationShip()) { - // radio traffic owns the sent message, - // so we must give it a cloned object that is - // safe to delete: - traffic->SendMessage(new RadioMessage(*radio_msg)); - return true; - } - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -NetPlayer::DoSysDamage(NetSysDamage* sys_damage) -{ - if (ship && sys_damage) { - System* sys = ship->GetSystem(sys_damage->GetSystem()); - ship->InflictNetSystemDamage( sys, - sys_damage->GetDamage(), - sys_damage->GetDamageType()); - - return true; - } - - return false; -} - -bool -NetPlayer::DoSysStatus(NetSysStatus* sys_status) -{ - if (ship && sys_status) { - System* sys = ship->GetSystem(sys_status->GetSystem()); - ship->SetNetSystemStatus( sys, - sys_status->GetStatus(), - sys_status->GetPower(), - sys_status->GetReactor(), - sys_status->GetAvailability()); - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -void -NetPlayer::ExecFrame(double seconds) -{ - if (ship) { - // bleed off the location error: - if (loc_error.length() > 0 && bleed_time > 0) { - double fragment = std::min(seconds / BLEED, bleed_time); - ship->MoveTo(ship->Location() + loc_error * fragment); - bleed_time -= fragment; - } - - // update the ship location by dead reckoning: - ship->MoveTo(ship->Location() + ship->Velocity() * seconds); - - // let the FLCS run, so that the drive flares will work: - ship->ExecFLCSFrame(); - - // now update the graphic rep and light sources: - if (ship->Rep()) { - ship->Rep()->MoveTo(ship->Location()); - ship->Rep()->SetOrientation(ship->Cam().Orientation()); - } - - if (ship->LightSrc()) { - ship->LightSrc()->MoveTo(ship->Location()); - } - } -} - -// +--------------------------------------------------------------------+ - -bool -NetPlayer::Update(SimObject* obj) -{ - if (obj == ship) { - ship = 0; - } - - return SimObserver::Update(obj); -} - -const char* -NetPlayer::GetObserverName() const -{ - return "NetPlayer"; -} diff --git a/Stars45/NetPlayer.h b/Stars45/NetPlayer.h deleted file mode 100644 index 5867669..0000000 --- a/Stars45/NetPlayer.h +++ /dev/null @@ -1,97 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Network Player (Director) class -*/ - -#ifndef NetPlayer_h -#define NetPlayer_h - -#include "Types.h" -#include "Geometry.h" -#include "Director.h" -#include "SimObject.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Sim; -class Ship; -class NetMsg; -class NetObjLoc; -class NetObjHyper; -class NetObjTarget; -class NetObjEmcon; -class NetSysDamage; -class NetSysStatus; -class NetWepTrigger; -class NetWepRelease; -class NetWepDestroy; -class NetCommMsg; - -// +--------------------------------------------------------------------+ - -class NetPlayer : public Director, public SimObserver -{ -public: - static const char* TYPENAME() { return "NetPlayer"; } - - NetPlayer(DWORD nid) : netid(nid), objid(0), ship(0), iff(0) { } - ~NetPlayer(); - - int operator == (const NetPlayer& p) const { return netid == p.netid; } - - DWORD GetNetID() const { return netid; } - DWORD GetObjID() const { return objid; } - void SetObjID(DWORD o) { objid = o; } - - int GetIFF() const { return iff; } - Ship* GetShip() const { return ship; } - void SetShip(Ship* s); - - const char* Name() const { return name; } - void SetName(const char* n) { name = n; } - const char* SerialNumber() const { return serno; } - void SetSerialNumber(const char* n) { serno = n; } - - virtual void ExecFrame(double seconds); - - bool DoObjLoc(NetObjLoc* obj_loc); - bool DoObjHyper(NetObjHyper* obj_hyper); - bool DoObjTarget(NetObjTarget* obj_target); - bool DoObjEmcon(NetObjEmcon* obj_emcon); - bool DoWepTrigger(NetWepTrigger* trigger); - bool DoWepRelease(NetWepRelease* release); - bool DoCommMessage(NetCommMsg* comm_msg); - bool DoSysDamage(NetSysDamage* sys_damage); - bool DoSysStatus(NetSysStatus* sys_status); - - virtual int Type() const { return 2; } - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - -protected: - DWORD netid; - DWORD objid; - Text name; - Text serno; - Ship* ship; - int iff; - - Point loc_error; - double bleed_time; -}; - -// +--------------------------------------------------------------------+ - -#endif // NetPlayer_h - diff --git a/Stars45/NetServerConfig.cpp b/Stars45/NetServerConfig.cpp deleted file mode 100644 index bb4e235..0000000 --- a/Stars45/NetServerConfig.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/* 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 "NetServerConfig.h" -#include "NetUser.h" - -#include "NetLayer.h" -#include "NetAddr.h" -#include "NetGame.h" -#include "NetHost.h" -#include "NetServer.h" -#include "HttpServer.h" -#include "HttpServletExec.h" -#include "NetLobbyServer.h" -#include "NetAuth.h" - -#include "Token.h" -#include "Game.h" -#include "DataLoader.h" -#include "ParseUtil.h" -#include "VersionInfo.h" - -// +--------------------------------------------------------------------+ - -NetServerConfig* NetServerConfig::instance = 0; - -// +--------------------------------------------------------------------+ - -NetServerConfig::NetServerConfig() -{ - instance = this; - - hostname = "0.0.0.0"; - name = "Starshatter "; - admin_name = "system"; - admin_pass = "manager"; - admin_port = 11111; - lobby_port = 11100; - game_port = 11101; - game_type = NET_GAME_PUBLIC; - auth_level = NetAuth::NET_AUTH_STANDARD; - poolsize = 8; - session_timeout = 300; - - name += versionInfo; - - Load(); -} - -NetServerConfig::~NetServerConfig() -{ - instance = 0; - - banned_addrs.destroy(); - banned_names.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -NetServerConfig::Initialize() -{ - if (!instance) - instance = new NetServerConfig(); -} - -void -NetServerConfig::Close() -{ - delete instance; - instance = 0; -} - -// +--------------------------------------------------------------------+ - -void -NetServerConfig::Load() -{ - // read the config file: - BYTE* block = 0; - int blocklen = 0; - int port = 0; - - char filename[64]; - strcpy_s(filename, "server.cfg"); - - FILE* f; - ::fopen_s(&f, 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) { - delete [] block; - return; - } - - Parser parser(new BlockReader((const char*) block, blocklen)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'.\n", filename); - delete [] block; - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "SERVER_CONFIG") { - Print("WARNING: invalid '%s' file. Using defaults\n", filename); - delete [] block; - return; - } - } - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "hostname") { - GetDefText(instance->hostname, def, filename); - } - - else if (def->name()->value() == "name") { - GetDefText(instance->name, def, filename); - } - - else if (def->name()->value() == "admin_name") { - GetDefText(instance->admin_name, def, filename); - } - - else if (def->name()->value() == "admin_pass") { - GetDefText(instance->admin_pass, def, filename); - } - - else if (def->name()->value() == "game_pass") { - GetDefText(instance->game_pass, def, filename); - } - - else if (def->name()->value() == "mission") { - GetDefText(instance->mission, def, filename); - } - - else if (def->name()->value() == "auth_level") { - Text level; - - if (def->term() && def->term()->isText()) { - GetDefText(level, def, filename); - - level.toLower(); - - if (level.indexOf("min") == 0) - instance->auth_level = NetAuth::NET_AUTH_MINIMAL; - - else if (level == "standard" || level == "std") - instance->auth_level = NetAuth::NET_AUTH_STANDARD; - - else if (level == "secure") - instance->auth_level = NetAuth::NET_AUTH_SECURE; - } - - else { - GetDefNumber(instance->auth_level, def, filename); - } - } - - else if (def->name()->value() == "admin_port") { - GetDefNumber(port, def, filename); - if (port > 1024 && port < 48000) - instance->admin_port = (WORD) port; - } - - else if (def->name()->value() == "lobby_port") { - GetDefNumber(port, def, filename); - if (port > 1024 && port < 48000) - instance->lobby_port = (WORD) port; - } - - else if (def->name()->value() == "game_port") { - GetDefNumber(port, def, filename); - if (port > 1024 && port < 48000) - instance->game_port = (WORD) port; - } - - else if (def->name()->value() == "game_type") { - Text type; - GetDefText(type, def, filename); - type.setSensitive(false); - - if (type == "LAN") - instance->game_type = NET_GAME_LAN; - - else if (type == "private") - instance->game_type = NET_GAME_PRIVATE; - - else - instance->game_type = NET_GAME_PUBLIC; - } - - else if (def->name()->value() == "poolsize") { - GetDefNumber(instance->poolsize, def, filename); - } - - else if (def->name()->value() == "session_timeout") { - GetDefNumber(instance->session_timeout, def, filename); - } - - else - Print("WARNING: unknown label '%s' in '%s'\n", - def->name()->value().data(), filename); - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - } - } - } - while (term); - - delete [] block; - - LoadBanList(); -} - -// +--------------------------------------------------------------------+ - -void -NetServerConfig::Save() -{ - FILE* f; - fopen_s(&f, "server.cfg", "wb"); - if (f) { - fprintf(f, "SERVER_CONFIG\n\n"); - fprintf(f, "hostname: \"%s\"\n", instance->hostname.data()); - fprintf(f, "name: \"%s\"\n", instance->name.data()); - fprintf(f, "admin_name: \"%s\"\n", instance->admin_name.data()); - fprintf(f, "admin_pass: \"%s\"\n", instance->admin_pass.data()); - fprintf(f, "game_pass: \"%s\"\n", instance->game_pass.data()); - fprintf(f, "\n"); - fprintf(f, "admin_port: %d\n", instance->admin_port); - fprintf(f, "lobby_port: %d\n", instance->lobby_port); - fprintf(f, "game_port: %d\n", instance->game_port); - - switch (instance->game_type) { - case NET_GAME_LAN: - fprintf(f, "game_type: LAN\n"); - break; - - case NET_GAME_PRIVATE: - fprintf(f, "game_type: private\n"); - break; - - case NET_GAME_PUBLIC: - default: - fprintf(f, "game_type: public\n"); - break; - } - - switch (instance->auth_level) { - case NetAuth::NET_AUTH_MINIMAL: - fprintf(f, "auth_level: minimal\n"); - break; - - case NetAuth::NET_AUTH_STANDARD: - default: - fprintf(f, "auth_level: standard\n"); - break; - - case NetAuth::NET_AUTH_SECURE: - fprintf(f, "auth_level: secure\n"); - break; - } - - fprintf(f, "\n"); - fprintf(f, "poolsize: %d\n", instance->poolsize); - fprintf(f, "session_timeout: %d\n", instance->session_timeout); - - if (mission.length() > 0) { - fprintf(f, "\nmission: \"%s\"\n", instance->mission.data()); - } - - fclose(f); - } -} - -// +--------------------------------------------------------------------+ - -Text -NetServerConfig::Clean(const char* s) -{ - if (!s || !*s) return Text(); - - int len = strlen(s); - char* buff = new char[len+1]; - ZeroMemory(buff, len+1); - - char* p = buff; - - for (int i = 0; i < len; i++) { - char c = s[i]; - - if (c >= 32 && c < 127) - *p++ = c; - } - - Text result(buff); - delete [] buff; - - return result; -} - -// +--------------------------------------------------------------------+ - -void -NetServerConfig::LoadBanList() -{ - // read the config file: - BYTE* block = 0; - int blocklen = 0; - int port = 0; - - char filename[64]; - strcpy_s(filename, "banned.cfg"); - - FILE* f; - ::fopen_s(&f, 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) { - delete [] block; - return; - } - - Parser parser(new BlockReader((const char*) block, blocklen)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'.\n", filename); - delete [] block; - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "BANNED_CONFIG") { - Print("WARNING: invalid '%s' file.\n", filename); - delete [] block; - return; - } - } - - banned_addrs.destroy(); - banned_names.destroy(); - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "name") { - Text name; - GetDefText(name, def, filename); - banned_names.append(new Text(name)); - } - - else if (def->name()->value() == "addr") { - DWORD addr; - GetDefNumber(addr, def, filename); - banned_addrs.append(new NetAddr(addr)); - } - } - - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - } - } - } - while (term); - - delete [] block; -} - -void -NetServerConfig::BanUser(NetUser* user) -{ - if (!user || IsUserBanned(user)) - return; - - NetAddr* user_addr = new NetAddr(user->GetAddress().IPAddr()); - Text* user_name = new Text(user->Name()); - - banned_addrs.append(user_addr); - banned_names.append(user_name); - - FILE* f; - fopen_s(&f, "banned.cfg", "wb"); - if (f) { - fprintf(f, "BANNED_CONFIG\n\n"); - - ListIter a_iter = banned_addrs; - while (++a_iter) { - NetAddr* addr = a_iter.value(); - fprintf(f, "addr: 0x%08x // %d.%d.%d.%d\n", - addr->IPAddr(), - addr->B1(), - addr->B2(), - addr->B3(), - addr->B4()); - } - - fprintf(f, "\n"); - - ListIter n_iter = banned_names; - while (++n_iter) { - Text* name = n_iter.value(); - fprintf(f, "name: \"%s\"\n", name->data()); - } - - fclose(f); - } -} - -bool -NetServerConfig::IsUserBanned(NetUser* user) -{ - if (user) { - NetAddr user_addr = user->GetAddress(); - Text user_name = user->Name(); - - user_addr.SetPort(0); - - return banned_addrs.contains(&user_addr) || - banned_names.contains(&user_name); - } - - return false; -} - diff --git a/Stars45/NetServerConfig.h b/Stars45/NetServerConfig.h deleted file mode 100644 index be582ce..0000000 --- a/Stars45/NetServerConfig.h +++ /dev/null @@ -1,101 +0,0 @@ -/* 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 - -*/ - -#ifndef NetServerConfig_h -#define NetServerConfig_h - -#include "Types.h" -#include "Game.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class NetAddr; -class NetUser; - -// +--------------------------------------------------------------------+ - -class NetServerConfig -{ -public: - static const char* TYPENAME() { return "NetServerConfig"; } - - NetServerConfig(); - ~NetServerConfig(); - - enum GAME_TYPE { - NET_GAME_LAN, - NET_GAME_PRIVATE, - NET_GAME_PUBLIC - }; - - const Text& Hostname() const { return hostname; } - const Text& Name() const { return name; } - const Text& GetAdminName() const { return admin_name; } - const Text& GetAdminPass() const { return admin_pass; } - const Text& GetGamePass() const { return game_pass; } - const Text& GetMission() const { return mission; } - WORD GetAdminPort() const { return admin_port; } - WORD GetLobbyPort() const { return lobby_port; } - WORD GetGamePort() const { return game_port; } - int GetPoolsize() const { return poolsize; } - int GetSessionTimeout() const { return session_timeout; } - int GetGameType() const { return game_type; } - int GetAuthLevel() const { return auth_level; } - - void SetHostname(const char* s) { hostname = Clean(s); } - void SetName(const char* s) { name = Clean(s); } - void SetAdminName(const char* s){ admin_name = Clean(s); } - void SetAdminPass(const char* s){ admin_pass = Clean(s); } - void SetGamePass(const char* s) { game_pass = Clean(s); } - void SetMission(const char* s) { mission = Clean(s); } - void SetGameType(int t) { game_type = t; } - void SetAdminPort(WORD p) { admin_port = p; } - void SetLobbyPort(WORD p) { lobby_port = p; } - void SetGamePort(WORD p) { game_port = p; } - void SetPoolsize(int s) { poolsize = s; } - void SetSessionTimeout(int t) { session_timeout = t; } - void SetAuthLevel(int n) { auth_level = n; } - - void Load(); - void Save(); - - bool IsUserBanned(NetUser* user); - void BanUser(NetUser* user); - - static void Initialize(); - static void Close(); - static NetServerConfig* GetInstance() { return instance; } - -private: - void LoadBanList(); - Text Clean(const char* s); - - Text hostname; - Text name; - Text admin_name; - Text admin_pass; - Text game_pass; - Text mission; - - WORD admin_port; - WORD lobby_port; - WORD game_port; - int poolsize; - int session_timeout; - int game_type; - int auth_level; - - List banned_addrs; - List banned_names; - - static NetServerConfig* instance; -}; - -#endif // NetServerConfig_h diff --git a/Stars45/NetServerDlg.cpp b/Stars45/NetServerDlg.cpp deleted file mode 100644 index 1729123..0000000 --- a/Stars45/NetServerDlg.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "NetServerDlg.h" -#include "NetServerConfig.h" -#include "MenuScreen.h" -#include "Starshatter.h" - -#include "NetAddr.h" -#include "HttpClient.h" -#include "HttpServer.h" - -#include "DataLoader.h" -#include "Button.h" -#include "EditBox.h" -#include "ComboBox.h" -#include "Video.h" -#include "Keyboard.h" -#include "MachineInfo.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(NetServerDlg, OnApply); -DEF_MAP_CLIENT(NetServerDlg, OnCancel); - -// +--------------------------------------------------------------------+ - -NetServerDlg::NetServerDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr) -{ - config = NetServerConfig::GetInstance(); - Init(def); -} - -NetServerDlg::~NetServerDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -NetServerDlg::RegisterControls() -{ - edt_name = (EditBox*) FindControl(200); - cmb_type = (ComboBox*) FindControl(201); - edt_game_port = (EditBox*) FindControl(202); - edt_admin_port = (EditBox*) FindControl(203); - edt_game_pass = (EditBox*) FindControl(204); - edt_admin_name = (EditBox*) FindControl(205); - edt_admin_pass = (EditBox*) FindControl(206); - - btn_apply = (Button*) FindControl(1); - btn_cancel = (Button*) FindControl(2); - - REGISTER_CLIENT(EID_CLICK, btn_apply, NetServerDlg, OnApply); - REGISTER_CLIENT(EID_CLICK, btn_cancel, NetServerDlg, OnCancel); -} - -// +--------------------------------------------------------------------+ - -void -NetServerDlg::Show() -{ - if (!IsShown()) - FormWindow::Show(); - - NetServerConfig::Initialize(); - config = NetServerConfig::GetInstance(); - - if (config) { - config->Load(); - - char buff[32]; - - if (edt_name) { - edt_name->SetText(config->Name()); - edt_name->SetFocus(); - } - - if (cmb_type) - cmb_type->SetSelection(config->GetGameType()); - - if (edt_game_port) { - sprintf_s(buff, "%d", config->GetLobbyPort()); - edt_game_port->SetText(buff); - } - - if (edt_admin_port) { - sprintf_s(buff, "%d", config->GetAdminPort()); - edt_admin_port->SetText(buff); - } - - if (edt_game_pass) - edt_game_pass->SetText(config->GetGamePass()); - - if (edt_admin_name) - edt_admin_name->SetText(config->GetAdminName()); - - if (edt_admin_pass) - edt_admin_pass->SetText(config->GetAdminPass()); - } -} - -// +--------------------------------------------------------------------+ - -void -NetServerDlg::ExecFrame() -{ -} - -// +--------------------------------------------------------------------+ - -void -NetServerDlg::OnApply(AWEvent* event) -{ - if (config) { - if (edt_name) - config->SetName(edt_name->GetText()); - - if (cmb_type) - config->SetGameType(cmb_type->GetSelectedIndex()); - - if (edt_game_port) { - int port = 0; - sscanf_s(edt_game_port->GetText(), "%d", &port); - config->SetLobbyPort((WORD) port); - config->SetGamePort((WORD) port+1); - } - - if (edt_admin_port) { - int port = 0; - sscanf_s(edt_admin_port->GetText(), "%d", &port); - config->SetAdminPort((WORD) port); - } - - if (edt_game_pass) - config->SetGamePass(edt_game_pass->GetText()); - - if (edt_admin_name) - config->SetAdminName(edt_admin_name->GetText()); - - if (edt_admin_pass) - config->SetAdminPass(edt_admin_pass->GetText()); - - - config->Save(); - } - - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - ::Print("\nSTART LOCAL SERVER\n\n"); - stars->SetLobbyMode(Starshatter::NET_LOBBY_SERVER); - manager->ShowNetLobbyDlg(); - } - else { - manager->ShowMenuDlg(); - } -} - -void -NetServerDlg::OnCancel(AWEvent* event) -{ - NetServerConfig::Close(); - manager->ShowNetClientDlg(); -} diff --git a/Stars45/NetServerDlg.h b/Stars45/NetServerDlg.h deleted file mode 100644 index 4c70323..0000000 --- a/Stars45/NetServerDlg.h +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef NetServerDlg_h -#define NetServerDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class NetServerConfig; - -// +--------------------------------------------------------------------+ - -class NetServerDlg : public FormWindow -{ -public: - NetServerDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~NetServerDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - -protected: - MenuScreen* manager; - NetServerConfig* config; - - EditBox* edt_name; - ComboBox* cmb_type; - EditBox* edt_game_port; - EditBox* edt_admin_port; - EditBox* edt_game_pass; - EditBox* edt_admin_name; - EditBox* edt_admin_pass; - - Button* btn_apply; - Button* btn_cancel; -}; - -#endif // NetServerDlg_h - diff --git a/Stars45/NetUnitDlg.cpp b/Stars45/NetUnitDlg.cpp deleted file mode 100644 index 038c082..0000000 --- a/Stars45/NetUnitDlg.cpp +++ /dev/null @@ -1,641 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "NetUnitDlg.h" -#include "NetClientConfig.h" -#include "ConfirmDlg.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Mission.h" -#include "Ship.h" -#include "Player.h" -#include "Campaign.h" -#include "ShipDesign.h" - -#include "NetAddr.h" -#include "NetLobbyClient.h" -#include "NetLobbyServer.h" -#include "NetUser.h" -#include "NetChat.h" - -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Video.h" -#include "Keyboard.h" -#include "MachineInfo.h" -#include "Clock.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(NetUnitDlg, OnSelect); -DEF_MAP_CLIENT(NetUnitDlg, OnUnit); -DEF_MAP_CLIENT(NetUnitDlg, OnMap); -DEF_MAP_CLIENT(NetUnitDlg, OnUnMap); -DEF_MAP_CLIENT(NetUnitDlg, OnBan); -DEF_MAP_CLIENT(NetUnitDlg, OnBanConfirm); -DEF_MAP_CLIENT(NetUnitDlg, OnApply); -DEF_MAP_CLIENT(NetUnitDlg, OnCancel); - -// +--------------------------------------------------------------------+ - -NetUnitDlg::NetUnitDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -net_lobby(0), unit_index(-1) -{ - last_chat = 0; - host_mode = false; - - Init(def); -} - -NetUnitDlg::~NetUnitDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -NetUnitDlg::RegisterControls() -{ - lst_players = (ListBox*) FindControl(201); - lst_units = (ListBox*) FindControl(202); - lst_chat = (ListBox*) FindControl(211); - edt_chat = (EditBox*) FindControl(212); - - REGISTER_CLIENT(EID_SELECT, lst_units, NetUnitDlg, OnUnit); - - if (edt_chat) - edt_chat->SetText(""); - - btn_select = (Button*) FindControl(206); - REGISTER_CLIENT(EID_CLICK, btn_select, NetUnitDlg, OnSelect); - - btn_map = (Button*) FindControl(203); - REGISTER_CLIENT(EID_CLICK, btn_map, NetUnitDlg, OnMap); - - btn_unmap = (Button*) FindControl(204); - REGISTER_CLIENT(EID_CLICK, btn_unmap, NetUnitDlg, OnUnMap); - - btn_ban = (Button*) FindControl(205); - - if (btn_ban) { - REGISTER_CLIENT(EID_CLICK, btn_ban, NetUnitDlg, OnBan); - REGISTER_CLIENT(EID_USER_1, btn_ban, NetUnitDlg, OnBanConfirm); - } - - btn_apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, btn_apply, NetUnitDlg, OnApply); - - btn_cancel = (Button*) FindControl(2); - REGISTER_CLIENT(EID_CLICK, btn_cancel, NetUnitDlg, OnCancel); -} - -// +--------------------------------------------------------------------+ - -void -NetUnitDlg::Show() -{ - if (!IsShown()) { - FormWindow::Show(); - - // clear server data: - if (lst_players) { - lst_players->ClearItems(); - lst_players->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - lst_players->SetLeading(2); - } - - if (lst_units) { - lst_units->ClearItems(); - lst_units->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - lst_units->SetLeading(2); - } - - if (lst_chat) lst_chat->ClearItems(); - last_chat = 0; - - if (btn_apply) - btn_apply->SetEnabled(false); - - net_lobby = NetLobby::GetInstance(); - host_mode = false; - - if (net_lobby) { - host_mode = net_lobby->IsHost(); - } - - if (host_mode) { - btn_select->Hide(); - btn_map->Show(); - btn_unmap->Show(); - btn_ban->Show(); - } - else { - btn_select->Show(); - btn_map->Hide(); - btn_unmap->Hide(); - btn_ban->Hide(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetUnitDlg::ExecFrame() -{ - ExecLobbyFrame(); - - if (!net_lobby) - return; - - Text player_name; - - if (Player::GetCurrentPlayer()) - player_name = Player::GetCurrentPlayer()->Name(); - - if (btn_select) { - bool enable = false; - - if (lst_players && lst_units && btn_select->IsVisible()) { - int sel_unit = lst_units->GetSelection(); - - enable = sel_unit >= 0 && - lst_units->GetItemText(sel_unit).length() == 0; - } - - btn_select->SetEnabled(enable); - } - - if (btn_map) { - bool enable = false; - - if (lst_players && lst_units && btn_map->IsVisible()) { - int sel_play = lst_players->GetSelection(); - int sel_unit = lst_units->GetSelection(); - - enable = sel_unit >= 0 && sel_play >= 0 && - lst_units->GetItemText(sel_unit).length() == 0; - - if (enable && !host_mode) { - NetUser* u = (NetUser*) lst_players->GetItemData(sel_play); - if (!u || u->Name() != player_name) - enable = false; - } - } - - btn_map->SetEnabled(enable); - } - - if (btn_unmap) { - bool enable = false; - - if (lst_players && lst_units && btn_unmap->IsVisible()) { - int sel_play = lst_players->GetSelection(); - int sel_unit = lst_units->GetSelection(); - - enable = sel_unit >= 0 && lst_units->GetItemText(sel_unit).length() > 0; - - if (enable && !host_mode) { - NetUser* u = (NetUser*) lst_units->GetItemData(sel_unit); - if (!u || u->Name() != Player::GetCurrentPlayer()->Name()) - enable = false; - } - } - - btn_unmap->SetEnabled(enable); - } - - if (btn_ban) { - bool enable = false; - - if (lst_players && lst_units && host_mode && btn_ban->IsVisible()) { - int sel_play = lst_players->GetSelection(); - int sel_unit = lst_units->GetSelection(); - - enable = sel_play >= 0 && sel_unit < 0; - - if (enable) { - NetUser* u = (NetUser*) lst_players->GetItemData(sel_play); - if (u && u->Name() == player_name) - enable = false; - } - } - - btn_ban->SetEnabled(enable); - } - - if (btn_apply) { - bool ok_to_start = net_lobby->IsMapped(player_name); - - NetUser* host = net_lobby->GetHost(); - if (host && !net_lobby->IsMapped(host->Name())) - ok_to_start = false; - - btn_apply->SetEnabled(ok_to_start); - } - - if (Keyboard::KeyDown(VK_RETURN)) { - if (edt_chat && edt_chat->GetText().length() > 0) { - SendChat(edt_chat->GetText()); - edt_chat->SetText(""); - } - } - - CheckUnitMapping(); - GetChat(); - GetUnits(); - GetAvailable(); -} - -// +--------------------------------------------------------------------+ - -void -NetUnitDlg::ExecLobbyFrame() -{ - Starshatter* stars = Starshatter::GetInstance(); - - if (!net_lobby) { - manager->ShowNetClientDlg(); - } - - else if (net_lobby->GetLastError() != 0) { - if (net_lobby->IsClient()) { - if (stars) - stars->StopLobby(); - - net_lobby = 0; - manager->ShowNetClientDlg(); - } - } -} - -// +--------------------------------------------------------------------+ - -static bool assignment_change = false; -static int num_users = 0; - -void -NetUnitDlg::CheckUnitMapping() -{ - if (net_lobby && lst_units) { - ListIter iter = net_lobby->GetUnitMap(); - List& units = iter.container(); - List& users = net_lobby->GetUsers(); - - if (users.size() != num_users) { - assignment_change = true; - num_users = users.size(); - } - - if (units.size() != lst_units->NumItems()) { - assignment_change = true; - } - - else if (lst_units->NumItems()) { - for (int i = 0; i < units.size(); i++) { - NetUnitEntry* e = units.at(i); - Text user_name = e->GetUserName(); - NetUser* u = net_lobby->FindUserByName(user_name); - - if (lst_units->GetItemData(i) != (DWORD) u) - assignment_change = true; - } - } - } -} - -void -NetUnitDlg::GetAvailable() -{ - if (!lst_players) return; - - Text player_name; - - if (Player::GetCurrentPlayer()) - player_name = Player::GetCurrentPlayer()->Name(); - - if (net_lobby) { - List available_users; - - NetUser* u = net_lobby->GetLocalUser(); - if (u) { - bool assigned = false; - ListIter iter = net_lobby->GetUnitMap(); - while (++iter) { - NetUnitEntry* unit = iter.value(); - if (unit->GetUserName() == u->Name()) - assigned = true; - } - - if (!assigned) - available_users.append(u); - } - - ListIter iter = net_lobby->GetUsers(); - while (++iter) { - NetUser* u = iter.value(); - bool assigned = false; - ListIter iter = net_lobby->GetUnitMap(); - while (++iter) { - NetUnitEntry* unit = iter.value(); - if (unit->GetUserName() == u->Name()) - assigned = true; - } - - if (!assigned) { - available_users.append(u); - } - } - - if (available_users.size() != lst_players->NumItems()) { - assignment_change = true; - lst_players->ClearItems(); - - for (int i = 0; i < available_users.size(); i++) { - NetUser* u = available_users[i]; - - Text name = Player::RankAbrv(u->Rank()); - name += " "; - name += u->Name(); - - lst_players->AddItemWithData(name.data(), (DWORD) u); - - if (!host_mode && u->Name() == player_name) { - lst_players->SetSelected(lst_players->NumItems()-1); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -NetUnitDlg::GetUnits() -{ - if (!lst_units) return; - - if (net_lobby) { - ListIter iter = net_lobby->GetUnitMap(); - List& units = iter.container(); - List& users = net_lobby->GetUsers(); - - if (assignment_change) { - lst_units->ClearItems(); - - for (int i = 0; i < units.size(); i++) { - NetUnitEntry* e = units.at(i); - - char name[64]; - char team[16]; - - if (e->GetIndex()) - sprintf_s(name, "%s %d", e->GetElemName().data(), e->GetIndex()); - else - strcpy_s(name, e->GetElemName().data()); - - sprintf_s(team, "%d", e->GetIFF()); - - Text user_name = e->GetUserName(); - - NetUser* u = net_lobby->FindUserByName(user_name); - if (u) { - user_name = Player::RankAbrv(u->Rank()); - user_name += " "; - user_name += u->Name(); - } - - int count = lst_units->AddItemWithData(user_name, (DWORD) u); - lst_units->SetItemText(count-1, 1, name); - lst_units->SetItemText(count-1, 2, e->GetDesign()); - - if (lst_units->NumColumns() > 4) { - lst_units->SetItemText(count-1, 3, Mission::RoleName(e->GetMissionRole())); - lst_units->SetItemText(count-1, 4, team); - } - else if (lst_units->NumColumns() > 3) { - lst_units->SetItemText(count-1, 3, team); - } - } - } - } - - assignment_change = false; -} - -// +--------------------------------------------------------------------+ - -void -NetUnitDlg::GetChat() -{ - if (!lst_chat) return; - - if (net_lobby) { - int last_item = lst_chat->NumItems() - 1; - int count = 0; - bool added = false; - - ListIter iter = net_lobby->GetChat(); - while (++iter) { - NetChatEntry* c = iter.value(); - - if (count++ > last_item) { - int n = lst_chat->AddItem(c->GetUser()); - lst_chat->SetItemText(n-1, 1, c->GetMessage()); - added = true; - } - } - - if (added) - lst_chat->EnsureVisible(lst_chat->NumItems()+1); - } -} - - -void -NetUnitDlg::SendChat(Text msg) -{ - if (msg.length() < 1) return; - - Player* player = Player::GetCurrentPlayer(); - - if (msg[0] >= '0' && msg[0] <= '9') { - if (player) { - Text macro = player->ChatMacro(msg[0] - '0'); - - if (macro.length()) - msg = macro; - } - } - - if (net_lobby) - net_lobby->AddChat(0, msg); -} - -// +--------------------------------------------------------------------+ - -void -NetUnitDlg::OnUnit(AWEvent* event) -{ - if (!lst_units || host_mode) return; - - static DWORD unit_click_time = 0; - - int list_index = lst_units->GetListIndex(); - - // double-click: - if (list_index == unit_index && Clock::GetInstance()->RealTime() - unit_click_time < 350) { - OnSelect(0); - } - - unit_click_time = Clock::GetInstance()->RealTime(); - unit_index = list_index; -} - -// +--------------------------------------------------------------------+ - -void -NetUnitDlg::OnSelect(AWEvent* event) -{ - if (!lst_players || !lst_units) return; - - Text player_name; - - if (Player::GetCurrentPlayer()) - player_name = Player::GetCurrentPlayer()->Name(); - - int sel_unit = lst_units->GetSelection(); - - if (net_lobby) { - net_lobby->MapUnit(sel_unit, player_name, host_mode); - lst_units->ClearItems(); - } - - assignment_change = true; - - GetUnits(); - GetAvailable(); -} - -// +--------------------------------------------------------------------+ - -void -NetUnitDlg::OnMap(AWEvent* event) -{ - if (!lst_players || !lst_units) return; - - int sel_player = lst_players->GetSelection(); - int sel_unit = lst_units->GetSelection(); - - if (net_lobby) { - NetUser* u = (NetUser*) lst_players->GetItemData(sel_player); - net_lobby->MapUnit(sel_unit, u->Name(), host_mode); - lst_units->ClearItems(); - } - - assignment_change = true; - - GetUnits(); - GetAvailable(); -} - -void -NetUnitDlg::OnUnMap(AWEvent* event) -{ - if (!lst_players || !lst_units) return; - - if (net_lobby) { - net_lobby->MapUnit(lst_units->GetSelection(), 0, host_mode); - lst_units->ClearItems(); - } - - assignment_change = true; - - GetUnits(); - GetAvailable(); -} - -void -NetUnitDlg::OnBan(AWEvent* event) -{ - if (!lst_players) return; - - int sel_player = lst_players->GetSelection(); - - if (net_lobby) { - NetUser* u = (NetUser*) lst_players->GetItemData(sel_player); - - ConfirmDlg* confirm = manager->GetConfirmDlg(); - if (confirm) { - char msg[512]; - sprintf_s(msg, ContentBundle::GetInstance()->GetText("NetUnitDlg.are-you-sure").data(), u->Name().data()); - confirm->SetMessage(msg); - confirm->SetTitle(ContentBundle::GetInstance()->GetText("NetUnitDlg.confirm-ban")); - confirm->SetParentControl(btn_ban); - - manager->ShowConfirmDlg(); - } - - else { - OnBanConfirm(event); - } - } -} - -void -NetUnitDlg::OnBanConfirm(AWEvent* event) -{ - if (!lst_players) return; - - int sel_player = lst_players->GetSelection(); - - if (net_lobby) { - NetUser* u = (NetUser*) lst_players->GetItemData(sel_player); - net_lobby->BanUser(u); - lst_units->ClearItems(); - } - - GetUnits(); - GetAvailable(); -} - -void -NetUnitDlg::OnApply(AWEvent* event) -{ - bool ok = false; - - if (net_lobby) { - Mission* mission = net_lobby->GetSelectedMission(); - - if (mission) { - net_lobby->GameStart(); - ok = true; - } - } - - if (!ok) OnCancel(0); -} - -void -NetUnitDlg::OnCancel(AWEvent* event) -{ - if (net_lobby) { - net_lobby->SelectMission(0); - net_lobby = 0; - } - - manager->ShowNetLobbyDlg(); -} diff --git a/Stars45/NetUnitDlg.h b/Stars45/NetUnitDlg.h deleted file mode 100644 index 8278426..0000000 --- a/Stars45/NetUnitDlg.h +++ /dev/null @@ -1,92 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Multiplayer Unit Selection Dialog Active Window class -*/ - -#ifndef NetUnitDlg_h -#define NetUnitDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "EditBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class NetClientConfig; -class NetLobby; -class NetChatEntry; -class NetUser; - -// +--------------------------------------------------------------------+ - -class NetUnitDlg : public FormWindow -{ -public: - NetUnitDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~NetUnitDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnSelect(AWEvent* event); - virtual void OnUnit(AWEvent* event); - virtual void OnMap(AWEvent* event); - virtual void OnUnMap(AWEvent* event); - virtual void OnBan(AWEvent* event); - virtual void OnBanConfirm(AWEvent* event); - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - - virtual void ExecLobbyFrame(); - - virtual bool GetHostMode() const { return host_mode; } - virtual void SetHostMode(bool h) { host_mode = h; } - -protected: - virtual void GetAvailable(); - virtual void GetUnits(); - virtual void GetChat(); - virtual void SendChat(Text msg); - virtual void CheckUnitMapping(); - - MenuScreen* manager; - - ListBox* lst_players; - ListBox* lst_units; - ListBox* lst_chat; - EditBox* edt_chat; - - Button* btn_select; - Button* btn_map; - Button* btn_unmap; - Button* btn_ban; - Button* btn_apply; - Button* btn_cancel; - - NetLobby* net_lobby; - - int last_chat; - int unit_index; - bool host_mode; -}; - -// +--------------------------------------------------------------------+ - -#endif // NetUnitDlg_h - diff --git a/Stars45/NetUser.cpp b/Stars45/NetUser.cpp deleted file mode 100644 index d8a8ba9..0000000 --- a/Stars45/NetUser.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - This class represents a user connecting to the multiplayer lobby -*/ - - -#include "NetUser.h" -#include "NetAuth.h" -#include "NetLobby.h" -#include "Player.h" -#include "FormatUtil.h" - -// +-------------------------------------------------------------------+ - -static Color user_colors[] = { - Color::BrightBlue, - Color::BrightRed, - Color::BrightGreen, - Color::Cyan, - Color::Orange, - Color::Magenta, - Color::Yellow, - Color::White, - Color::Gray, - Color::DarkRed, - Color::Tan, - Color::Violet -}; - -static int user_color_index = 0; - -// +-------------------------------------------------------------------+ - -NetUser::NetUser(const char* n) - : name(n), netid(0), host(false), - rank(0), flight_time(0), missions(0), kills(0), losses(0), - auth_state(NetAuth::NET_AUTH_INITIAL), - auth_level(NetAuth::NET_AUTH_MINIMAL) -{ - if (user_color_index < 0 || user_color_index >= 12) - user_color_index = 0; - - color = user_colors[user_color_index++]; - - ZeroMemory(salt, sizeof(salt)); -} - -NetUser::NetUser(const Player* player) - : netid(0), host(false), - rank(0), flight_time(0), missions(0), kills(0), losses(0), - auth_state(NetAuth::NET_AUTH_INITIAL), - auth_level(NetAuth::NET_AUTH_MINIMAL) -{ - if (user_color_index < 0 || user_color_index >= 12) - user_color_index = 0; - - color = user_colors[user_color_index++]; - - if (player) { - name = player->Name(); - pass = player->Password(); - signature = player->Signature(); - squadron = player->Squadron(); - rank = player->Rank(); - flight_time = player->FlightTime(); - missions = player->Missions(); - kills = player->Kills(); - losses = player->Losses(); - } - - ZeroMemory(salt, sizeof(salt)); -} - -NetUser::~NetUser() -{ } - -// +-------------------------------------------------------------------+ - -Text -NetUser::GetDescription() -{ - Text content; - - content += "name \""; - content += SafeQuotes(name); - content += "\" sig \""; - content += SafeQuotes(signature); - content += "\" squad \""; - content += SafeQuotes(squadron); - - char buffer[256]; - sprintf_s(buffer, "\" rank %d time %d miss %d kill %d loss %d host %s ", - rank, flight_time, missions, kills, losses, - host ? "true" : "false"); - - content += buffer; - - return content; -} - -// +-------------------------------------------------------------------+ - -bool -NetUser::IsAuthOK() const -{ - return auth_state == NetAuth::NET_AUTH_OK; -} diff --git a/Stars45/NetUser.h b/Stars45/NetUser.h deleted file mode 100644 index 79b0d2c..0000000 --- a/Stars45/NetUser.h +++ /dev/null @@ -1,111 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - This class represents a user connecting to the multiplayer lobby -*/ - - -#ifndef NetUser_h -#define NetUser_h - -#include "Types.h" -#include "NetAddr.h" -#include "NetLobby.h" -#include "Color.h" - -// +-------------------------------------------------------------------+ - -class Player; - -// +-------------------------------------------------------------------+ - -class NetUser -{ -public: - static const char* TYPENAME() { return "NetUser"; } - - NetUser(const char* name); - NetUser(const Player* player); - virtual ~NetUser(); - - int operator == (const NetUser& u) const { return this == &u; } - - const Text& Name() const { return name; } - const Text& Pass() const { return pass; } - const NetAddr& GetAddress() const { return addr; } - Color GetColor() const { return color; } - const Text& GetSessionID() const { return session_id; } - DWORD GetNetID() const { return netid; } - bool IsHost() const { return host; } - - int AuthLevel() const { return auth_level; } - int AuthState() const { return auth_state; } - const char* Salt() const { return salt; } - bool IsAuthOK() const; - - const Text& Squadron() const { return squadron; } - const Text& Signature() const { return signature; } - int Rank() const { return rank; } - int FlightTime() const { return flight_time; } - int Missions() const { return missions; } - int Kills() const { return kills; } - int Losses() const { return losses; } - - void SetName(const char* n) { name = n; } - void SetPass(const char* p) { pass = p; } - void SetAddress(const NetAddr& a) - { addr = a; } - - void SetColor(Color c) { color = c; } - void SetNetID(DWORD id) { netid = id; } - void SetSessionID(Text s) { session_id = s; } - void SetHost(bool h) { host = h; } - - void SetAuthLevel(int n) { auth_level = n; } - void SetAuthState(int n) { auth_state = n; } - void SetSalt(const char* s) { strcpy_s(salt, s);} - - void SetSquadron(const char* s) { squadron = s; } - void SetSignature(const char* s){ signature = s; } - void SetRank(int n) { rank = n; } - void SetFlightTime(int n) { flight_time = n;} - void SetMissions(int n) { missions = n; } - void SetKills(int n) { kills = n; } - void SetLosses(int n) { losses = n; } - - Text GetDescription(); - -protected: - Text name; - Text pass; - Text session_id; - NetAddr addr; - DWORD netid; - Color color; - bool host; - - // authentication: - int auth_state; - int auth_level; - char salt[33]; - - // stats: - Text squadron; - Text signature; - int rank; - int flight_time; - int missions; - int kills; - int losses; -}; - -// +-------------------------------------------------------------------+ - -#endif // NetUser_h \ No newline at end of file diff --git a/Stars45/NetUtil.cpp b/Stars45/NetUtil.cpp deleted file mode 100644 index 4b3fb97..0000000 --- a/Stars45/NetUtil.cpp +++ /dev/null @@ -1,422 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Utility class to simplify sending NetData messages. -*/ - - -#include "NetUtil.h" -#include "NetData.h" -#include "NetGame.h" -#include "NetGameServer.h" - -#include "Element.h" -#include "Instruction.h" -#include "Random.h" -#include "Ship.h" -#include "Shot.h" -#include "System.h" -#include "Weapon.h" - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendObjDamage(SimObject* obj, double dmg, Shot* shot) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !obj) return; - - if (net_game->IsServer() && obj->GetObjID()) { - NetObjDamage damage; - damage.SetObjID(obj->GetObjID()); - damage.SetDamage((float) dmg); - - if (shot) - damage.SetShotID(shot->GetObjID()); - - net_game->SendData(&damage); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendSysDamage(Ship* obj, System* sys, double dmg) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !obj || !sys) return; - - if (net_game->IsServer() && obj->GetObjID()) { - NetSysDamage damage; - damage.SetObjID(obj->GetObjID()); - damage.SetDamage(dmg); - damage.SetSystem(sys->GetID()); - - net_game->SendData(&damage); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendSysStatus(Ship* obj, System* sys) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !obj || !sys) return; - - if (obj->GetObjID()) { - NetSysStatus status; - status.SetObjID(obj->GetObjID()); - status.SetSystem( (int) sys->GetID()); - status.SetStatus( (int) sys->Status()); - status.SetPower( (int) sys->GetPowerLevel()); - status.SetReactor((int) sys->GetSourceIndex()); - status.SetAvailablility(sys->Availability()); - - net_game->SendData(&status); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendObjKill(Ship* obj, const Ship* killer, int type, int deck) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !obj) return; - - if (type == NetObjKill::KILL_DOCK || (net_game->IsServer() && obj->GetObjID())) { - NetObjKill kill; - kill.SetObjID(obj->GetObjID()); - kill.SetFlightDeck(deck); - - if (killer) - kill.SetKillerID(killer->GetObjID()); - - kill.SetKillType(type); - - if (type != NetObjKill::KILL_DOCK && obj->RespawnCount() > 0) { - Print("NetObjKill preparing respawn for %s\n", obj->Name()); - - Point respawn_loc = RandomPoint() * 1.75; - kill.SetRespawn(true); - kill.SetRespawnLoc(respawn_loc); - obj->SetRespawnLoc(respawn_loc); - } - else { - Print("NetObjKill no respawn for %s\n", obj->Name()); - } - - net_game->SendData(&kill); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendObjHyper(Ship* obj, const char* rgn, const Point& loc, -const Ship* fc1, const Ship* fc2, int transtype) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !obj) return; - - if (obj->GetObjID()) { - NetObjHyper obj_hyper; - obj_hyper.SetObjID(obj->GetObjID()); - obj_hyper.SetRegion(rgn); - obj_hyper.SetLocation(loc); - obj_hyper.SetTransitionType(transtype); - - if (fc1) - obj_hyper.SetFarcaster1(fc1->GetObjID()); - - if (fc2) - obj_hyper.SetFarcaster2(fc2->GetObjID()); - - net_game->SendData(&obj_hyper); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendObjTarget(Ship* obj) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !obj) return; - - if (obj->GetObjID()) { - NetObjTarget obj_target; - obj_target.SetObjID(obj->GetObjID()); - - SimObject* target = obj->GetTarget(); - if (target) { - obj_target.SetTgtID(target->GetObjID()); - - System* subtarget = obj->GetSubTarget(); - - if (subtarget) { - Ship* s = (Ship*) target; - obj_target.SetSubtarget(subtarget->GetID()); - } - } - - net_game->SendData(&obj_target); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendObjEmcon(Ship* obj) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !obj) return; - - if (obj->GetObjID()) { - NetObjEmcon obj_emcon; - obj_emcon.SetObjID(obj->GetObjID()); - obj_emcon.SetEMCON(obj->GetEMCON()); - net_game->SendData(&obj_emcon); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendWepTrigger(Weapon* wep, int count) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !wep) return; - - if (wep->IsPrimary() || net_game->IsClient()) { - NetWepTrigger trigger; - trigger.SetObjID(wep->Owner()->GetObjID()); - - SimObject* target = wep->GetTarget(); - if (target) { - trigger.SetTgtID(target->GetObjID()); - - System* subtarget = wep->GetSubTarget(); - - if (subtarget) { - Ship* s = (Ship*) target; - trigger.SetSubtarget(subtarget->GetID()); - } - } - - trigger.SetIndex(wep->GetIndex()); - trigger.SetCount(count); - trigger.SetDecoy(wep->IsDecoy()); - trigger.SetProbe(wep->IsProbe()); - - net_game->SendData(&trigger); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendWepRelease(Weapon* wep, Shot* shot) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !wep || !shot) return; - - if (net_game->IsServer() && wep->IsMissile()) { - DWORD wepid = NetGame::GetNextObjID(NetGame::SHOT); - shot->SetObjID(wepid); - - NetWepRelease release; - release.SetObjID(wep->Owner()->GetObjID()); - - SimObject* target = wep->GetTarget(); - if (target) - release.SetTgtID(target->GetObjID()); - - System* subtarget = wep->GetSubTarget(); - if (target && subtarget && target->Type() == SimObject::SIM_SHIP) { - Ship* tgt = (Ship*) target; - release.SetSubtarget(subtarget->GetID()); - } - - release.SetWepID(wepid); - release.SetIndex(wep->GetIndex()); - release.SetDecoy(shot->IsDecoy()); - release.SetProbe(shot->IsProbe()); - - net_game->SendData(&release); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendWepDestroy(Shot* shot) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !shot) return; - - if (net_game->IsServer() && shot->GetObjID()) { - NetWepDestroy destroy; - - destroy.SetObjID(shot->GetObjID()); - - net_game->SendData(&destroy); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendChat(DWORD dst, const char* name, const char* text) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !name || !*name || !text || !*text) return; - - NetChatMsg chat_msg; - chat_msg.SetDstID(dst); - chat_msg.SetName(name); - chat_msg.SetText(text); - - if (net_game->IsClient()) { - net_game->SendData(&chat_msg); - } - - else { - NetGameServer* net_game_server = (NetGameServer*) net_game; - net_game_server->RouteChatMsg(chat_msg); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendElemRequest(const char* name) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !name) return; - - NetElemRequest elem_request; - elem_request.SetName(name); - - ::Print("NetUtil::SendElemRequest name: '%s'\n", name); - net_game->SendData(&elem_request); -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendElemCreate(Element* elem, int squadron, int* slots, bool alert, bool in_flight) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !elem) return; - - NetElemCreate elem_create; - elem_create.SetName(elem->Name()); - elem_create.SetType(elem->Type()); - elem_create.SetIFF(elem->GetIFF()); - elem_create.SetIntel(elem->IntelLevel()); - elem_create.SetLoadout(elem->Loadout()); - elem_create.SetSquadron(squadron); - elem_create.SetSlots(slots); - elem_create.SetAlert(alert); - elem_create.SetInFlight(in_flight); - - if (elem->NumObjectives() > 0) { - Instruction* obj = elem->GetObjective(0); - - if (obj) { - elem_create.SetObjCode(obj->Action()); - elem_create.SetObjective(obj->TargetName()); - } - } - - if (elem->GetCarrier()) - elem_create.SetCarrier(elem->GetCarrier()->Name()); - - if (elem->GetCommander()) - elem_create.SetCommander(elem->GetCommander()->Name()); - - ::Print("NetUtil::SendElemCreate iff: %d name: '%s'\n", elem->GetIFF(), elem->Name().data()); - net_game->SendData(&elem_create); -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendShipLaunch(Ship* carrier, int squadron, int slot) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !carrier) return; - - if (carrier->GetObjID()) { - NetShipLaunch ship_launch; - - ship_launch.SetObjID(carrier->GetObjID()); - ship_launch.SetSquadron(squadron); - ship_launch.SetSlot(slot); - - net_game->SendData(&ship_launch); - } -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendNavData(bool add, Element* elem, int index, Instruction* navpt) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !elem || !navpt) return; - - // resolve rloc before copying the navpoint into the net nav data structure: - Point loc = navpt->Location(); - - NetNavData nav_data; - nav_data.SetObjID(net_game->GetObjID()); - nav_data.SetAdd(add); - nav_data.SetElem(elem->Name()); - nav_data.SetIndex(index); - nav_data.SetNavPoint(navpt); - - net_game->SendData(&nav_data); -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendNavDelete(Element* elem, int index) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !elem) return; - - NetNavDelete nav_delete; - nav_delete.SetObjID(net_game->GetObjID()); - nav_delete.SetElem(elem->Name()); - nav_delete.SetIndex(index); - - net_game->SendData(&nav_delete); -} - -// +-------------------------------------------------------------------+ - -void -NetUtil::SendSelfDestruct(Ship* obj, double dmg) -{ - NetGame* net_game = NetGame::GetInstance(); - if (!net_game || !obj) return; - - if (obj->GetObjID()) { - NetSelfDestruct sd; - sd.SetObjID(obj->GetObjID()); - sd.SetDamage((float) dmg); - - net_game->SendData(&sd); - } -} diff --git a/Stars45/NetUtil.h b/Stars45/NetUtil.h deleted file mode 100644 index d64f56f..0000000 --- a/Stars45/NetUtil.h +++ /dev/null @@ -1,55 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Utility class to simplify sending NetData messages. -*/ - - -#ifndef NetUtil_h -#define NetUtil_h - -#include "Types.h" -#include "Geometry.h" - -// +-------------------------------------------------------------------+ - -class Element; -class Instruction; -class SimObject; -class Ship; -class Shot; -class System; -class Weapon; - -// +-------------------------------------------------------------------+ - -class NetUtil -{ -public: - static void SendObjDamage(SimObject* obj, double damage, Shot* shot=0); - static void SendObjKill(Ship* obj, const Ship* killer, int type=0, int deck=0); - static void SendObjHyper(Ship* obj, const char* rgn, const Point& loc, const Ship* fc1=0, const Ship* fc2=0, int ttype=0); - static void SendObjTarget(Ship* obj); - static void SendObjEmcon(Ship* obj); - static void SendSysDamage(Ship* obj, System* sys, double damage); - static void SendSysStatus(Ship* obj, System* sys); - static void SendWepTrigger(Weapon* wep, int count=1); - static void SendWepRelease(Weapon* wep, Shot* shot); - static void SendWepDestroy(Shot* shot); - static void SendChat(DWORD dst, const char* name, const char* text); - static void SendElemRequest(const char* name); - static void SendElemCreate(Element* elem, int squadron, int* slots, bool alert, bool in_flight=false); - static void SendShipLaunch(Ship* carrier, int squadron, int slot); - static void SendNavData(bool add, Element* elem, int index, Instruction* navpt); - static void SendNavDelete(Element* elem, int index); - static void SendSelfDestruct(Ship* ship, double damage); -}; - -#endif // NetUtil_h \ No newline at end of file diff --git a/Stars45/OptDlg.cpp b/Stars45/OptDlg.cpp deleted file mode 100644 index ddc01ad..0000000 --- a/Stars45/OptDlg.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "OptDlg.h" -#include "MenuScreen.h" -#include "Starshatter.h" -#include "Ship.h" -#include "HUDView.h" -#include "Player.h" - -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "MachineInfo.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(OptDlg, OnApply); -DEF_MAP_CLIENT(OptDlg, OnCancel); -DEF_MAP_CLIENT(OptDlg, OnEnter); -DEF_MAP_CLIENT(OptDlg, OnExit); -DEF_MAP_CLIENT(OptDlg, OnAudio); -DEF_MAP_CLIENT(OptDlg, OnVideo); -DEF_MAP_CLIENT(OptDlg, OnOptions); -DEF_MAP_CLIENT(OptDlg, OnControls); -DEF_MAP_CLIENT(OptDlg, OnMod); - -// +--------------------------------------------------------------------+ - -OptDlg::OptDlg(Screen* s, FormDef& def, BaseScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -apply(0), cancel(0), vid_btn(0), aud_btn(0), ctl_btn(0), opt_btn(0), mod_btn(0), -closed(true) -{ - Init(def); -} - -OptDlg::~OptDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -OptDlg::RegisterControls() -{ - if (apply) - return; - - flight_model = (ComboBox*) FindControl(201); - flying_start = (ComboBox*) FindControl(211); - landings = (ComboBox*) FindControl(202); - ai_difficulty = (ComboBox*) FindControl(203); - hud_mode = (ComboBox*) FindControl(204); - hud_color = (ComboBox*) FindControl(205); - ff_mode = (ComboBox*) FindControl(206); - grid_mode = (ComboBox*) FindControl(207); - gunsight = (ComboBox*) FindControl(208); - description = FindControl(500); - apply = (Button*) FindControl(1); - cancel = (Button*) FindControl(2); - vid_btn = (Button*) FindControl(901); - aud_btn = (Button*) FindControl(902); - ctl_btn = (Button*) FindControl(903); - opt_btn = (Button*) FindControl(904); - mod_btn = (Button*) FindControl(905); - - if (flight_model) { - REGISTER_CLIENT(EID_MOUSE_ENTER, flight_model, OptDlg, OnEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, flight_model, OptDlg, OnExit); - } - - if (flying_start) { - REGISTER_CLIENT(EID_MOUSE_ENTER, flying_start, OptDlg, OnEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, flying_start, OptDlg, OnExit); - } - - if (landings) { - REGISTER_CLIENT(EID_MOUSE_ENTER, landings, OptDlg, OnEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, landings, OptDlg, OnExit); - } - - if (ai_difficulty) { - REGISTER_CLIENT(EID_MOUSE_ENTER, ai_difficulty, OptDlg, OnEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, ai_difficulty, OptDlg, OnExit); - } - - if (hud_mode) { - REGISTER_CLIENT(EID_MOUSE_ENTER, hud_mode, OptDlg, OnEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, hud_mode, OptDlg, OnExit); - } - - if (hud_color) { - REGISTER_CLIENT(EID_MOUSE_ENTER, hud_color, OptDlg, OnEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, hud_color, OptDlg, OnExit); - } - - if (ff_mode) { - REGISTER_CLIENT(EID_MOUSE_ENTER, ff_mode, OptDlg, OnEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, ff_mode, OptDlg, OnExit); - } - - if (grid_mode) { - REGISTER_CLIENT(EID_MOUSE_ENTER, grid_mode, OptDlg, OnEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, grid_mode, OptDlg, OnExit); - } - - if (gunsight) { - REGISTER_CLIENT(EID_MOUSE_ENTER, gunsight, OptDlg, OnEnter); - REGISTER_CLIENT(EID_MOUSE_EXIT, gunsight, OptDlg, OnExit); - } - - if (apply) - REGISTER_CLIENT(EID_CLICK, apply, OptDlg, OnApply); - - if (cancel) - REGISTER_CLIENT(EID_CLICK, cancel, OptDlg, OnCancel); - - if (vid_btn) - REGISTER_CLIENT(EID_CLICK, vid_btn, OptDlg, OnVideo); - - if (aud_btn) - REGISTER_CLIENT(EID_CLICK, aud_btn, OptDlg, OnAudio); - - if (ctl_btn) - REGISTER_CLIENT(EID_CLICK, ctl_btn, OptDlg, OnControls); - - if (opt_btn) - REGISTER_CLIENT(EID_CLICK, opt_btn, OptDlg, OnOptions); - - if (mod_btn) - REGISTER_CLIENT(EID_CLICK, mod_btn, OptDlg, OnMod); -} - -// +--------------------------------------------------------------------+ - -void -OptDlg::Show() -{ - FormWindow::Show(); - - if (closed) { - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - if (flight_model) - flight_model->SetSelection(Ship::GetFlightModel()); - - if (landings) - landings->SetSelection(Ship::GetLandingModel()); - - if (hud_mode) - hud_mode->SetSelection(HUDView::IsArcade() ? 1 : 0); - - if (hud_color) - hud_color->SetSelection(HUDView::DefaultColorSet()); - - if (ff_mode) - ff_mode->SetSelection((int) (Ship::GetFriendlyFireLevel() * 4)); - } - - Player* player = Player::GetCurrentPlayer(); - if (player) { - if (flying_start) - flying_start->SetSelection(player->FlyingStart()); - - if (ai_difficulty) - ai_difficulty->SetSelection(ai_difficulty->NumItems() - player->AILevel() - 1); - - if (grid_mode) - grid_mode->SetSelection(player->GridMode()); - - if (gunsight) - gunsight->SetSelection(player->Gunsight()); - } - } - - if (vid_btn) vid_btn->SetButtonState(0); - if (aud_btn) aud_btn->SetButtonState(0); - if (ctl_btn) ctl_btn->SetButtonState(0); - if (opt_btn) opt_btn->SetButtonState(1); - if (mod_btn) mod_btn->SetButtonState(0); - - closed = false; -} - -// +--------------------------------------------------------------------+ - -void -OptDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnApply(0); - } -} - -// +--------------------------------------------------------------------+ - -void OptDlg::OnAudio(AWEvent* event) { manager->ShowAudDlg(); } -void OptDlg::OnVideo(AWEvent* event) { manager->ShowVidDlg(); } -void OptDlg::OnOptions(AWEvent* event) { manager->ShowOptDlg(); } -void OptDlg::OnControls(AWEvent* event) { manager->ShowCtlDlg(); } -void OptDlg::OnMod(AWEvent* event) { manager->ShowModDlg(); } - -// +--------------------------------------------------------------------+ - -void -OptDlg::OnApply(AWEvent* event) -{ - manager->ApplyOptions(); -} - -void -OptDlg::OnCancel(AWEvent* event) -{ - manager->CancelOptions(); -} - -// +--------------------------------------------------------------------+ - -void -OptDlg::OnEnter(AWEvent* event) -{ - ActiveWindow* src = event->window; - - if (src && description) - description->SetText(src->GetAltText()); -} - -void -OptDlg::OnExit(AWEvent* event) -{ - ComboBox* cmb = (ComboBox*) event->window; - - if (!cmb || cmb->IsListShowing()) - return; - - if (description) - description->SetText(""); -} - -// +--------------------------------------------------------------------+ - -void -OptDlg::Apply() -{ - if (closed) return; - - Player* player = Player::GetCurrentPlayer(); - if (player) { - if (flight_model) - player->SetFlightModel(flight_model->GetSelectedIndex()); - - if (flying_start) - player->SetFlyingStart(flying_start->GetSelectedIndex()); - - if (landings) - player->SetLandingModel(landings->GetSelectedIndex()); - - if (ai_difficulty) - player->SetAILevel(ai_difficulty->NumItems() - ai_difficulty->GetSelectedIndex() - 1); - - if (hud_mode) - player->SetHUDMode(hud_mode->GetSelectedIndex()); - - if (hud_color) - player->SetHUDColor(hud_color->GetSelectedIndex()); - - if (ff_mode) - player->SetFriendlyFire(ff_mode->GetSelectedIndex()); - - if (grid_mode) - player->SetGridMode(grid_mode->GetSelectedIndex()); - - if (gunsight) - player->SetGunsight(gunsight->GetSelectedIndex()); - - Player::Save(); - } - - if (flight_model) - Ship::SetFlightModel(flight_model->GetSelectedIndex()); - - if (landings) - Ship::SetLandingModel(landings->GetSelectedIndex()); - - if (hud_mode) - HUDView::SetArcade(hud_mode->GetSelectedIndex() > 0); - - if (hud_color) - HUDView::SetDefaultColorSet(hud_color->GetSelectedIndex()); - - if (ff_mode) - Ship::SetFriendlyFireLevel(ff_mode->GetSelectedIndex() / 4.0); - - HUDView* hud = HUDView::GetInstance(); - if (hud) hud->SetHUDColorSet(hud_color->GetSelectedIndex()); - - closed = true; -} - -void -OptDlg::Cancel() -{ - closed = true; -} diff --git a/Stars45/OptDlg.h b/Stars45/OptDlg.h deleted file mode 100644 index ab0202c..0000000 --- a/Stars45/OptDlg.h +++ /dev/null @@ -1,86 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef OptDlg_h -#define OptDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class BaseScreen; - -// +--------------------------------------------------------------------+ - -class OptDlg : public FormWindow -{ -public: - OptDlg(Screen* s, FormDef& def, BaseScreen* mgr); - virtual ~OptDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void Apply(); - virtual void Cancel(); - - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - - virtual void OnEnter(AWEvent* event); - virtual void OnExit(AWEvent* event); - - virtual void OnAudio(AWEvent* event); - virtual void OnVideo(AWEvent* event); - virtual void OnOptions(AWEvent* event); - virtual void OnControls(AWEvent* event); - virtual void OnMod(AWEvent* event); - -protected: - BaseScreen* manager; - - ComboBox* flight_model; - ComboBox* flying_start; - ComboBox* landings; - ComboBox* ai_difficulty; - ComboBox* hud_mode; - ComboBox* hud_color; - ComboBox* joy_mode; - ComboBox* ff_mode; - ComboBox* grid_mode; - ComboBox* gunsight; - - ActiveWindow* description; - - Button* aud_btn; - Button* vid_btn; - Button* opt_btn; - Button* ctl_btn; - Button* mod_btn; - - Button* apply; - Button* cancel; - - bool closed; -}; - -#endif // OptDlg_h - diff --git a/Stars45/PCX.CPP b/Stars45/PCX.CPP deleted file mode 100644 index b1d8656..0000000 --- a/Stars45/PCX.CPP +++ /dev/null @@ -1,514 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - PCX image file loader -*/ - - -#include "Pcx.h" - -#include -#include -#include - -// +--------------------------------------------------------------------+ - -#define MAX_SIZE (4*1024*1024) - -enum { BYTEMODE, RUNMODE }; - -// +--------------------------------------------------------------------+ - -PcxImage::PcxImage() -: width(0), height(0), bitmap(0), himap(0), imagebytes(0) -{ } - -PcxImage::PcxImage(short w, short h, unsigned char* bits, unsigned char* colors) -: bitmap(0), himap(0) -{ - hdr.manufacturer = 10; // Always set to 10 - hdr.version = 5; // Always 5 for 256-color files - hdr.encoding = 1; // Always set to 1 - hdr.bits_per_pixel = 8; // Should be 8 for 256-color files - hdr.xmin = 0; - hdr.xmax = w-1; - hdr.ymin = 0; - hdr.ymax = h-1; - hdr.hres = 0x48; - hdr.vres = 0x48; - - hdr.palette16[ 0] = (unsigned char) 0x00; - hdr.palette16[ 1] = (unsigned char) 0x00; - hdr.palette16[ 2] = (unsigned char) 0x00; - hdr.palette16[ 3] = (unsigned char) 0x80; - hdr.palette16[ 4] = (unsigned char) 0x00; - hdr.palette16[ 5] = (unsigned char) 0x00; - hdr.palette16[ 6] = (unsigned char) 0x00; - hdr.palette16[ 7] = (unsigned char) 0x80; - hdr.palette16[ 8] = (unsigned char) 0x00; - hdr.palette16[ 9] = (unsigned char) 0x80; - hdr.palette16[10] = (unsigned char) 0x80; - hdr.palette16[11] = (unsigned char) 0x00; - hdr.palette16[12] = (unsigned char) 0x00; - hdr.palette16[13] = (unsigned char) 0x00; - hdr.palette16[14] = (unsigned char) 0x80; - hdr.palette16[15] = (unsigned char) 0x80; - - hdr.palette16[16] = (unsigned char) 0x00; - hdr.palette16[17] = (unsigned char) 0x80; - hdr.palette16[18] = (unsigned char) 0x00; - hdr.palette16[19] = (unsigned char) 0x80; - hdr.palette16[20] = (unsigned char) 0x80; - hdr.palette16[21] = (unsigned char) 0xC0; - hdr.palette16[22] = (unsigned char) 0xC0; - hdr.palette16[23] = (unsigned char) 0xC0; - hdr.palette16[24] = (unsigned char) 0xC0; - hdr.palette16[25] = (unsigned char) 0xDC; - hdr.palette16[26] = (unsigned char) 0xC0; - hdr.palette16[27] = (unsigned char) 0xA6; - hdr.palette16[28] = (unsigned char) 0xCA; - hdr.palette16[29] = (unsigned char) 0xF0; - hdr.palette16[30] = (unsigned char) 0x33; - hdr.palette16[31] = (unsigned char) 0x2B; - - hdr.palette16[32] = (unsigned char) 0x1F; - hdr.palette16[33] = (unsigned char) 0x2B; - hdr.palette16[34] = (unsigned char) 0x23; - hdr.palette16[35] = (unsigned char) 0x1B; - hdr.palette16[36] = (unsigned char) 0x5F; - hdr.palette16[37] = (unsigned char) 0x5F; - hdr.palette16[38] = (unsigned char) 0x5F; - hdr.palette16[39] = (unsigned char) 0x2F; - hdr.palette16[40] = (unsigned char) 0x2F; - hdr.palette16[41] = (unsigned char) 0x2F; - hdr.palette16[42] = (unsigned char) 0x27; - hdr.palette16[43] = (unsigned char) 0x27; - hdr.palette16[44] = (unsigned char) 0x27; - hdr.palette16[45] = (unsigned char) 0x1F; - hdr.palette16[46] = (unsigned char) 0x1F; - hdr.palette16[47] = (unsigned char) 0x1F; - - hdr.reserved = 0; // Reserved for future use - hdr.color_planes = 1; // Color planes - hdr.bytes_per_line = w; // Number of bytes in 1 line of pixels - hdr.palette_type = 1; // Should be 1 for color palette - - for (unsigned int i = 0; i < 58; i++) - hdr.filler[i] = 0; - - width = w; - height = h; - imagebytes = width * height; - - bitmap = new unsigned char [imagebytes]; - - if (bitmap) { - for (unsigned long i = 0; i < imagebytes; i++) - bitmap[i] = bits[i]; - - unsigned char* p = pal; - for (int i = 0; i < 256; i++) { - *p++ = *colors++; - *p++ = *colors++; - *p++ = *colors++; - colors++; - } - } -} - -PcxImage::PcxImage(short w, short h, unsigned long* hibits) -: bitmap(0), himap(0) -{ - hdr.manufacturer = 10; // Always set to 10 - hdr.version = 5; // Always 5 for true color files - hdr.encoding = 1; // Always set to 1 - hdr.bits_per_pixel = 8; // Should be 8 for true color files - hdr.xmin = 0; - hdr.xmax = w-1; - hdr.ymin = 0; - hdr.ymax = h-1; - hdr.hres = 0x48; - hdr.vres = 0x48; - - hdr.palette16[ 0] = (unsigned char) 0x00; - hdr.palette16[ 1] = (unsigned char) 0x00; - hdr.palette16[ 2] = (unsigned char) 0x00; - hdr.palette16[ 3] = (unsigned char) 0x80; - hdr.palette16[ 4] = (unsigned char) 0x00; - hdr.palette16[ 5] = (unsigned char) 0x00; - hdr.palette16[ 6] = (unsigned char) 0x00; - hdr.palette16[ 7] = (unsigned char) 0x80; - hdr.palette16[ 8] = (unsigned char) 0x00; - hdr.palette16[ 9] = (unsigned char) 0x80; - hdr.palette16[10] = (unsigned char) 0x80; - hdr.palette16[11] = (unsigned char) 0x00; - hdr.palette16[12] = (unsigned char) 0x00; - hdr.palette16[13] = (unsigned char) 0x00; - hdr.palette16[14] = (unsigned char) 0x80; - hdr.palette16[15] = (unsigned char) 0x80; - - hdr.palette16[16] = (unsigned char) 0x00; - hdr.palette16[17] = (unsigned char) 0x80; - hdr.palette16[18] = (unsigned char) 0x00; - hdr.palette16[19] = (unsigned char) 0x80; - hdr.palette16[20] = (unsigned char) 0x80; - hdr.palette16[21] = (unsigned char) 0xC0; - hdr.palette16[22] = (unsigned char) 0xC0; - hdr.palette16[23] = (unsigned char) 0xC0; - hdr.palette16[24] = (unsigned char) 0xC0; - hdr.palette16[25] = (unsigned char) 0xDC; - hdr.palette16[26] = (unsigned char) 0xC0; - hdr.palette16[27] = (unsigned char) 0xA6; - hdr.palette16[28] = (unsigned char) 0xCA; - hdr.palette16[29] = (unsigned char) 0xF0; - hdr.palette16[30] = (unsigned char) 0x33; - hdr.palette16[31] = (unsigned char) 0x2B; - - hdr.palette16[32] = (unsigned char) 0x1F; - hdr.palette16[33] = (unsigned char) 0x2B; - hdr.palette16[34] = (unsigned char) 0x23; - hdr.palette16[35] = (unsigned char) 0x1B; - hdr.palette16[36] = (unsigned char) 0x5F; - hdr.palette16[37] = (unsigned char) 0x5F; - hdr.palette16[38] = (unsigned char) 0x5F; - hdr.palette16[39] = (unsigned char) 0x2F; - hdr.palette16[40] = (unsigned char) 0x2F; - hdr.palette16[41] = (unsigned char) 0x2F; - hdr.palette16[42] = (unsigned char) 0x27; - hdr.palette16[43] = (unsigned char) 0x27; - hdr.palette16[44] = (unsigned char) 0x27; - hdr.palette16[45] = (unsigned char) 0x1F; - hdr.palette16[46] = (unsigned char) 0x1F; - hdr.palette16[47] = (unsigned char) 0x1F; - - hdr.reserved = 0; // Reserved for future use - hdr.color_planes = 3; // Color planes - hdr.bytes_per_line = w; // Number of bytes in 1 line of pixels - hdr.palette_type = 1; // Should be 1 for color palette - - for (unsigned int i = 0; i < 58; i++) - hdr.filler[i] = 0; - - width = w; - height = h; - imagebytes = width * height; - - himap = new unsigned long [imagebytes]; - - if (himap) { - for (unsigned long i = 0; i < imagebytes; i++) - himap[i] = hibits[i]; - } -} - -PcxImage::~PcxImage() -{ - delete [] bitmap; - delete [] himap; -} - -// +--------------------------------------------------------------------+ - -int PcxImage::Load(char *filename) -{ - unsigned long i; - short mode=BYTEMODE, bytecount; - unsigned char abyte, *p; - FILE *f; - - fopen_s(&f, filename,"rb"); - if (f == NULL) - return PCX_NOFILE; - - fread(&hdr, sizeof(PcxHeader), 1, f); - - // read 256 color PCX file - if (hdr.color_planes == 1) { - width = 1 + hdr.xmax - hdr.xmin; - height = 1 + hdr.ymax - hdr.ymin; - imagebytes = width * height; - - if (imagebytes > MAX_SIZE) - return PCX_TOOBIG; - - // get palette from pcx file - fseek(f,-768L,SEEK_END); - fread(pal,768,1,f); - - // now go back and read the pixel data: - fseek(f,sizeof(PcxHeader),SEEK_SET); - - delete [] himap; himap = 0; - delete [] bitmap; bitmap = 0; - - himap = new unsigned long [imagebytes]; - if (himap == NULL) - return PCX_NOMEM; - - // force alpha channel to 255 - memset(himap, 0xff, imagebytes*4); - - unsigned long* pix = himap; - for (i=0; i 0xbf) { - bytecount = abyte & 0x3f; - abyte = fgetc(f); - if (--bytecount > 0) - mode = RUNMODE; - } - } - else if (--bytecount == 0) { - mode = BYTEMODE; - } - - *pix++ = 0xff000000 | (pal[3*abyte] << 16) | (pal[3*abyte+1] << 8) | (pal[3*abyte+2]); - } - } - - // read 24-bit (true COLOR) PCX file - else { - width = 1 + hdr.xmax - hdr.xmin; - height = 1 + hdr.ymax - hdr.ymin; - imagebytes = width * height; - - if (imagebytes > MAX_SIZE) - return PCX_TOOBIG; - - delete [] himap; himap = 0; - delete [] bitmap; bitmap = 0; - - himap = new unsigned long [imagebytes]; - if (himap == NULL) - return PCX_NOMEM; - - // force alpha channel to 255 - memset(himap, 0xff, imagebytes*4); - - for (int row = 0; row < height; row++) { - // RED, GREEN, BLUE - for (int plane = 2; plane >= 0; plane--) { - p = ((unsigned char*) himap) + width*row*4 + plane; - for (int col = 0; col < width; col++) { - if (mode == BYTEMODE) { - abyte = fgetc(f); - - if (abyte > 0xbf) { - bytecount = abyte & 0x3f; - abyte = fgetc(f); - if (--bytecount > 0) - mode = RUNMODE; - } - } - else if (--bytecount == 0) { - mode = BYTEMODE; - } - - *p = abyte; - p += 4; - } - } - } - } - - fclose(f); - return PCX_OK; -} - -// +--------------------------------------------------------------------+ - -int PcxImage::LoadBuffer(unsigned char* buf, int len) -{ - unsigned long i; - short mode=BYTEMODE, bytecount; - unsigned char abyte, *p; - unsigned char* fp; - - if (buf == NULL) - return PCX_NOFILE; - - fp = buf; - memcpy(&hdr, buf, sizeof(PcxHeader)); - fp += sizeof(PcxHeader); - - // read 256 color PCX file - if (hdr.color_planes == 1) { - width = 1 + hdr.xmax - hdr.xmin; - height = 1 + hdr.ymax - hdr.ymin; - imagebytes = width * height; - - if (imagebytes > MAX_SIZE) - return PCX_TOOBIG; - - // get palette from end of pcx file - memcpy(pal,buf+len-768,768); - - delete [] himap; himap = 0; - delete [] bitmap; bitmap = 0; - - himap = new unsigned long [imagebytes]; - if (himap == NULL) - return PCX_NOMEM; - - memset(himap, 0, imagebytes*4); - - unsigned long* pix = himap; - for (i=0; i 0xbf) { - bytecount = abyte & 0x3f; - abyte = *fp++; - if (--bytecount > 0) - mode = RUNMODE; - } - } - else if (--bytecount == 0) { - mode = BYTEMODE; - } - - *pix++ = 0xff000000 | (pal[3*abyte] << 16) | (pal[3*abyte+1] << 8) | (pal[3*abyte+2]); - } - } - - // read 24-bit (true COLOR) PCX file - else { - width = 1 + hdr.xmax - hdr.xmin; - height = 1 + hdr.ymax - hdr.ymin; - imagebytes = width * height; - - if (imagebytes > MAX_SIZE) - return PCX_TOOBIG; - - delete [] himap; himap = 0; - delete [] bitmap; bitmap = 0; - - himap = new unsigned long [imagebytes]; - if (himap == NULL) - return PCX_NOMEM; - - memset(himap, 0, imagebytes*4); - - for (int row = 0; row < height; row++) { - // RED, GREEN, BLUE - for (int plane = 2; plane >= 0; plane--) { - p = ((unsigned char*) himap) + width*row*4 + plane; - for (int col = 0; col < width; col++) { - if (mode == BYTEMODE) { - abyte = *fp++; - - if (abyte > 0xbf) { - bytecount = abyte & 0x3f; - abyte = *fp++; - if (--bytecount > 0) - mode = RUNMODE; - } - } - else if (--bytecount == 0) { - mode = BYTEMODE; - } - - *p = abyte; - p += 4; - } - } - } - } - - return PCX_OK; -} - -// +--------------------------------------------------------------------+ - -int PcxImage::Save(char *filename) -{ - short mode=BYTEMODE; - FILE *f; - - fopen_s(&f, filename,"wb"); - if (f == NULL) - return PCX_NOFILE; - - fwrite(&hdr, sizeof(PcxHeader), 1, f); - - if (hdr.color_planes == 1) { - unsigned char *p = bitmap; - unsigned long total = imagebytes; - unsigned long row = 0; - unsigned char palette_marker = 12; - - while (total) { - unsigned char* start = p; - unsigned char count = 0; - - while (*start == *p && count < 0x3f && row < width) { - p++; - count++; - row++; - } - - if (count > 1 || *start > 0xbf) { - unsigned char b[2]; - b[0] = 0xc0 | count; - b[1] = *start; - fwrite(b, 2, 1, f); - } - else { - fwrite(start, 1, 1, f); - } - - total -= count; - - if (row == width) - row = 0; - } - - fwrite(&palette_marker,1,1,f); - fwrite(pal,768,1,f); - } - - // write 24-bit (TRUE COLOR) PCX file - else { - for (int row = 0; row < height; row++) { - for (int plane = 2; plane >= 0; plane--) { - unsigned long col = 0; - unsigned char* p = ((unsigned char*) himap) + width*row*4 + plane; - - while (col < width) { - unsigned char* start = p; - unsigned char count = 0; - - while (*start == *p && count < 0x3f && col < width) { - p += 4; - count++; - col++; - } - - if (count > 1 || *start > 0xbf) { - unsigned char b[2]; - b[0] = 0xc0 | count; - b[1] = *start; - fwrite(b, 2, 1, f); - } - else { - fwrite(start, 1, 1, f); - } - } - } - } - } - - fclose(f); - return PCX_OK; // return success -} - diff --git a/Stars45/Panic.cpp b/Stars45/Panic.cpp deleted file mode 100644 index 67c29b7..0000000 --- a/Stars45/Panic.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* 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. -*/ - -#include "Panic.h" - -#include -#include - -#include "Utils.h" - -namespace Panic -{ - - -static std::string panic_msg; - - -void Panic(const char* msg) -{ - if (msg) - Print("*** PANIC: %s\n", msg); - else - Print("*** PANIC! ***\n"); - - std::ostringstream full_msg; - if (msg) - full_msg << msg; - else - full_msg << "Unspecified fatal error"; - full_msg << std::endl << "This game will now terminate."; - panic_msg = full_msg.str(); -} - - -bool Panicked() -{ - return !panic_msg.empty(); -} - - -const char* Message() -{ - return panic_msg.c_str(); -} - - -} // namespace Panic diff --git a/Stars45/Panic.h b/Stars45/Panic.h deleted file mode 100644 index 431a1f6..0000000 --- a/Stars45/Panic.h +++ /dev/null @@ -1,19 +0,0 @@ -/* 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. -*/ - -#ifndef Panic_h -#define Panic_h - - -namespace Panic -{ -void Panic(const char* msg = nullptr); -bool Panicked(); -const char* Message(); -} - - -#endif // Panic_h diff --git a/Stars45/ParseUtil.cpp b/Stars45/ParseUtil.cpp deleted file mode 100644 index fd701d9..0000000 --- a/Stars45/ParseUtil.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Parser utility functions -*/ - -#include "ParseUtil.h" -#include "DataLoader.h" - -#include "stdio.h" - -// +--------------------------------------------------------------------+ - -bool GetDefBool(bool& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing BOOL TermDef in '%s'\n", file); - return false; - } - - TermBool* tn = def->term()->isBool(); - if (tn) { - dst = tn->value(); - return true; - } - else { - Print("WARNING: invalid bool %s in '%s'. value = ", def->name()->value().data(), file); - def->term()->print(10); - Print("\n"); - } - - return false; -} - -bool GetDefText(Text& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing TEXT TermDef in '%s'\n", file); - return false; - } - - TermText* tn = def->term()->isText(); - if (tn) { - dst = tn->value(); - return true; - } - else - Print("WARNING: invalid TEXT %s in '%s'\n", def->name()->value().data(), file); - - return false; -} - -bool GetDefText(char* dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing TEXT TermDef in '%s'\n", file); - return false; - } - - TermText* tn = def->term()->isText(); - if (tn) { - strcpy(dst, tn->value()); - return true; - } - else - Print("WARNING: invalid TEXT %s in '%s'\n", def->name()->value().data(), file); - - return false; -} - -bool GetDefNumber(int& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing NUMBER TermDef in '%s'\n", file); - return false; - } - - TermNumber* tr = def->term()->isNumber(); - if (tr) { - dst = (int) tr->value(); - return true; - } - else - Print("WARNING: invalid NUMBER %s in '%s'\n", def->name()->value().data(), file); - - return false; -} - -bool GetDefNumber(DWORD& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing NUMBER TermDef in '%s'\n", file); - return false; - } - - TermNumber* tr = def->term()->isNumber(); - if (tr) { - dst = (DWORD) tr->value(); - return true; - } - else - Print("WARNING: invalid NUMBER %s in '%s'\n", def->name()->value().data(), file); - - return false; -} - -bool GetDefNumber(float& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing NUMBER TermDef in '%s'\n", file); - return false; - } - - TermNumber* tr = def->term()->isNumber(); - if (tr) { - dst = (float) tr->value(); - return true; - } - else - Print("WARNING: invalid NUMBER %s in '%s'\n", def->name()->value().data(), file); - - return false; -} - -bool GetDefNumber(double& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing NUMBER TermDef in '%s'\n", file); - return false; - } - - TermNumber* tr = def->term()->isNumber(); - if (tr) { - dst = (double) tr->value(); - return true; - } - else - Print("WARNING: invalid NUMBER %s in '%s'\n", def->name()->value().data(), file); - - return false; -} - -bool GetDefVec(Vec3& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing VEC3 TermDef in '%s'\n", file); - return false; - } - - TermArray* val = def->term()->isArray(); - if (val) { - if (val->elements()->size() != 3) { - Print("WARNING: malformed vector in '%s'\n", file); - } - else { - dst.x = (float) (val->elements()->at(0)->isNumber()->value()); - dst.y = (float) (val->elements()->at(1)->isNumber()->value()); - dst.z = (float) (val->elements()->at(2)->isNumber()->value()); - - return true; - } - } - else { - Print("WARNING: vector expected in '%s'\n", file); - } - - return false; -} - -bool GetDefRect(Rect& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing RECT TermDef in '%s'\n", file); - return false; - } - - TermArray* val = def->term()->isArray(); - if (val) { - if (val->elements()->size() != 4) { - Print("WARNING: malformed rect in '%s'\n", file); - } - else { - dst.x = (int) (val->elements()->at(0)->isNumber()->value()); - dst.y = (int) (val->elements()->at(1)->isNumber()->value()); - dst.w = (int) (val->elements()->at(2)->isNumber()->value()); - dst.h = (int) (val->elements()->at(3)->isNumber()->value()); - - return true; - } - } - else { - Print("WARNING: rect expected in '%s'\n", file); - } - - return false; -} - -bool GetDefInsets(Insets& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing Insets TermDef in '%s'\n", file); - return false; - } - - TermArray* val = def->term()->isArray(); - if (val) { - if (val->elements()->size() != 4) { - Print("WARNING: malformed Insets in '%s'\n", file); - } - else { - dst.left = (WORD) (val->elements()->at(0)->isNumber()->value()); - dst.right = (WORD) (val->elements()->at(1)->isNumber()->value()); - dst.top = (WORD) (val->elements()->at(2)->isNumber()->value()); - dst.bottom = (WORD) (val->elements()->at(3)->isNumber()->value()); - - return true; - } - } - else { - Print("WARNING: Insets expected in '%s'\n", file); - } - - return false; -} - -bool GetDefColor(Color& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing COLOR TermDef in '%s'\n", file); - return false; - } - - TermArray* val = def->term()->isArray(); - if (val) { - if (val->elements()->size() != 3) { - Print("WARNING: malformed color in '%s'\n", file); - } - else { - BYTE r, g, b; - double v0 = (val->elements()->at(0)->isNumber()->value()); - double v1 = (val->elements()->at(1)->isNumber()->value()); - double v2 = (val->elements()->at(2)->isNumber()->value()); - - if (v0 >= 0 && v0 <= 1 && - v1 >= 0 && v1 <= 1 && - v2 >= 0 && v2 <= 1) { - - r = (BYTE) (v0 * 255); - g = (BYTE) (v1 * 255); - b = (BYTE) (v2 * 255); - - } - else { - r = (BYTE) v0; - g = (BYTE) v1; - b = (BYTE) v2; - } - - dst = Color(r,g,b); - return true; - } - } - else { - Print("WARNING: color expected in '%s'\n", file); - } - - return false; -} - -bool GetDefColor(ColorValue& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing COLOR TermDef in '%s'\n", file); - return false; - } - - TermArray* val = def->term()->isArray(); - if (val) { - if (val->elements()->size() < 3 || val->elements()->size() > 4) { - Print("WARNING: malformed color in '%s'\n", file); - } - else { - double r = (val->elements()->at(0)->isNumber()->value()); - double g = (val->elements()->at(1)->isNumber()->value()); - double b = (val->elements()->at(2)->isNumber()->value()); - double a = 1; - - if (val->elements()->size() == 4) - a = (val->elements()->at(3)->isNumber()->value()); - - dst.Set((float) r, (float) g, (float) b, (float) a); - return true; - } - } - else { - Print("WARNING: color expected in '%s'\n", file); - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool GetDefArray(int* dst, int size, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing ARRAY TermDef in '%s'\n", file); - return false; - } - - TermArray* val = def->term()->isArray(); - if (val) { - int nelem = val->elements()->size(); - - if (nelem > size) - nelem = size; - - for (int i = 0; i < nelem; i++) - *dst++ = (int) (val->elements()->at(i)->isNumber()->value()); - - return true; - } - else { - Print("WARNING: array expected in '%s'\n", file); - } - - return false; -} - -bool GetDefArray(float* dst, int size, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing ARRAY TermDef in '%s'\n", file); - return false; - } - - TermArray* val = def->term()->isArray(); - if (val) { - int nelem = val->elements()->size(); - - if (nelem > size) - nelem = size; - - for (int i = 0; i < nelem; i++) - *dst++ = (float) (val->elements()->at(i)->isNumber()->value()); - - return true; - } - else { - Print("WARNING: array expected in '%s'\n", file); - } - - return false; -} - -bool GetDefArray(double* dst, int size, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing ARRAY TermDef in '%s'\n", file); - return false; - } - - TermArray* val = def->term()->isArray(); - if (val) { - int nelem = val->elements()->size(); - - if (nelem > size) - nelem = size; - - for (int i = 0; i < nelem; i++) - *dst++ = (double) (val->elements()->at(i)->isNumber()->value()); - - return true; - } - else { - Print("WARNING: array expected in '%s'\n", file); - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool GetDefArray(std::vector& array, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing ARRAY TermDef in '%s'\n", file); - return false; - } - - TermArray* val = def->term()->isArray(); - if (val) { - int nelem = val->elements()->size(); - - array.clear(); - - for (int i = 0; i < nelem; i++) - array.push_back((DWORD) (val->elements()->at(i)->isNumber()->value())); - - return true; - } - else { - Print("WARNING: integer array expected in '%s'\n", file); - } - - return false; -} - -bool GetDefArray(std::vector& array, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing ARRAY TermDef in '%s'\n", file); - return false; - } - - TermArray* val = def->term()->isArray(); - if (val) { - int nelem = val->elements()->size(); - - array.clear(); - - for (int i = 0; i < nelem; i++) - array.push_back((float) (val->elements()->at(i)->isNumber()->value())); - - return true; - } - else { - Print("WARNING: float array expected in '%s'\n", file); - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool GetDefTime(int& dst, TermDef* def, const char* file) -{ - if (!def || !def->term()) { - Print("WARNING: missing TIME TermDef in '%s'\n", file); - return false; - } - - TermText* tn = def->term()->isText(); - - if (tn) { - int d = 0; - int h = 0; - int m = 0; - int s = 0; - - char buf[64]; - strcpy_s(buf, tn->value()); - - if (strchr(buf, '/')) - sscanf_s(buf, "%d/%d:%d:%d", &d, &h, &m, &s); - else - sscanf_s(buf, "%d:%d:%d", &h, &m, &s); - - dst = d * 24 * 60 * 60 + - h * 60 * 60 + - m * 60 + - s; - - return true; - } - else - Print("WARNING: invalid TIME %s in '%s'\n", def->name()->value().data(), file); - - return false; -} - - diff --git a/Stars45/ParseUtil.h b/Stars45/ParseUtil.h deleted file mode 100644 index c234d00..0000000 --- a/Stars45/ParseUtil.h +++ /dev/null @@ -1,51 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Parser utility functions -*/ - -#ifndef ParseUtil_h -#define ParseUtil_h - -#include -#include "Types.h" -#include "Geometry.h" -#include "Color.h" - -#include "Text.h" -#include "Parser.h" -#include "Reader.h" -#include "Token.h" - -// +--------------------------------------------------------------------+ - -bool GetDefBool(bool& dst, TermDef* def, const char* file); -bool GetDefText(Text& dst, TermDef* def, const char* file); -bool GetDefText(char* dst, TermDef* def, const char* file); -bool GetDefNumber(int& dst, TermDef* def, const char* file); -bool GetDefNumber(DWORD& dst, TermDef* def, const char* file); -bool GetDefNumber(float& dst, TermDef* def, const char* file); -bool GetDefNumber(double& dst, TermDef* def, const char* file); -bool GetDefVec(Vec3& dst, TermDef* def, const char* file); -bool GetDefColor(Color& dst, TermDef* def, const char* file); -bool GetDefColor(ColorValue& dst, TermDef* def, const char* file); -bool GetDefRect(Rect& dst, TermDef* def, const char* file); -bool GetDefInsets(Insets& dst, TermDef* def, const char* file); -bool GetDefTime(int& dst, TermDef* def, const char* file); - -bool GetDefArray(int* dst, int size, TermDef* def, const char* file); -bool GetDefArray(float* dst, int size, TermDef* def, const char* file); -bool GetDefArray(double* dst, int size, TermDef* def, const char* file); -bool GetDefArray(std::vector& array, TermDef* def, const char* file); -bool GetDefArray(std::vector& array, TermDef* def, const char* file); - -// +--------------------------------------------------------------------+ - -#endif // ParseUtil_h diff --git a/Stars45/Parser.cpp b/Stars45/Parser.cpp deleted file mode 100644 index 09827cf..0000000 --- a/Stars45/Parser.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Implementation of the generic Parser class -*/ - -#include "Reader.h" -#include "Token.h" -#include "Parser.h" -#include "Term.h" -#include "Utils.h" -#include -#include - -enum KEYS { KEY_TRUE, KEY_FALSE, KEY_DEF, KEY_MINUS }; - -static int dump_tokens = 0; - -// +-------------------------------------------------------------------+ - -Term* error(char* msg, const Token& token) -{ - static char buf[1024]; - sprintf_s(buf, " near '%s' in line %d.", (const char*) token.symbol(), token.line()); - - return error(msg, buf); -} - -// +-------------------------------------------------------------------+ - -Parser::Parser(Reader* r) -{ - reader = r ? r : new ConsoleReader; - lexer = new Scanner(reader); - - Token::addKey("true", KEY_TRUE); - Token::addKey("false", KEY_FALSE); - Token::addKey(":", KEY_DEF); - Token::addKey("-", KEY_MINUS); -} - -Parser::~Parser() -{ - delete lexer; - delete reader; - //Token::close(); -} - -Term* -Parser::ParseTerm() -{ - Term* t = ParseTermBase(); - if (t == 0) return t; - - Term* t2 = ParseTermRest(t); - - return t2; -} - -Term* -Parser::ParseTermRest(Term* base) -{ - Token t = lexer->Get(); - - switch (t.type()) { - default: - lexer->PutBack(); - return base; - - case Token::StringLiteral: { - // concatenate adjacent string literal tokens: - TermText* text = base->isText(); - if (text) { - TermText* base2 = new TermText(text->value() + t.symbol()(1, t.symbol().length()-2)); - delete base; - return ParseTermRest(base2); - } - else { - lexer->PutBack(); - } - } - break; - - case Token::Keyword: - switch (t.key()) { - case KEY_DEF: - if (base->isText()) - return new TermDef(base->isText(), ParseTerm()); - else - return error("(Parse) illegal lhs in def", t); - - default: - lexer->PutBack(); - return base; - } - break; - } - - return base; -} - -static int xtol(const char* p) -{ - int n = 0; - - while (*p) { - char digit = *p++; - n *= 16; - - if (digit >= '0' && digit <= '9') - n += digit - '0'; - - else if (digit >= 'a' && digit <= 'f') - n += digit - 'a' + 10; - - else if (digit >= 'A' && digit <= 'F') - n += digit - 'A' + 10; - } - - return n; -} - -Term* -Parser::ParseTermBase() -{ - Token t = lexer->Get(); - int n = 0; - double d = 0.0; - - switch (t.type()) { - case Token::IntLiteral: { - if (dump_tokens) - Print("%s", t.symbol().data()); - - char nstr[256], *p = nstr; - for (int i = 0; i < (int) t.symbol().length(); i++) - if (t.symbol()[i] != '_') - *p++ = t.symbol()[i]; - *p++ = '\0'; - - // handle hex notation: - if (nstr[1] == 'x') - n = xtol(nstr+2); - - else - n = atol(nstr); - - return new TermNumber(n); - } - - case Token::FloatLiteral: { - if (dump_tokens) - Print("%s", t.symbol().data()); - - char nstr[256], *p = nstr; - for (int i = 0; i < (int) t.symbol().length(); i++) - if (t.symbol()[i] != '_') - *p++ = t.symbol()[i]; - *p++ = '\0'; - - d = atof(nstr); - return new TermNumber(d); - } - - case Token::StringLiteral: - if (dump_tokens) - Print("%s", t.symbol().data()); - - return new TermText(t.symbol()(1, t.symbol().length()-2)); - - case Token::AlphaIdent: - if (dump_tokens) - Print("%s", t.symbol().data()); - - return new TermText(t.symbol()); - - case Token::Keyword: - if (dump_tokens) - Print("%s", t.symbol().data()); - - switch (t.key()) { - case KEY_FALSE: return new TermBool(0); - case KEY_TRUE: return new TermBool(1); - - case KEY_MINUS: { - Token next = lexer->Get(); - if (next.type() == Token::IntLiteral) { - if (dump_tokens) - Print("%s", next.symbol().data()); - - char nstr[256], *p = nstr; - for (int i = 0; i < (int) next.symbol().length(); i++) - if (next.symbol()[i] != '_') - *p++ = next.symbol()[i]; - *p++ = '\0'; - - n = -1 * atol(nstr); - return new TermNumber(n); - } - else if (next.type() == Token::FloatLiteral) { - if (dump_tokens) - Print("%s", next.symbol().data()); - - char nstr[256], *p = nstr; - for (int i = 0; i < (int) next.symbol().length(); i++) - if (next.symbol()[i] != '_') - *p++ = next.symbol()[i]; - *p++ = '\0'; - - d = -1.0 * atof(nstr); - return new TermNumber(d); - } - else { - lexer->PutBack(); - return error("(Parse) illegal token '-': number expected", next); - } - } - break; - - default: - lexer->PutBack(); - return 0; - } - - case Token::LParen: return ParseArray(); - - case Token::LBrace: return ParseStruct(); - - case Token::CharLiteral: - return error("(Parse) illegal token ", t); - - default: - lexer->PutBack(); - return 0; - } -} - -TermArray* -Parser::ParseArray() -{ - TermList* elems = ParseTermList(0); - Token end = lexer->Get(); - - if (end.type() != Token::RParen) - return (TermArray*) error("(Parse) ')' missing in array-decl", end); - - return new TermArray(elems); -} - -TermStruct* -Parser::ParseStruct() -{ - TermList* elems = ParseTermList(1); - Token end = lexer->Get(); - - if (end.type() != Token::RBrace) - return (TermStruct*) error("(Parse) '}' missing in struct", end); - - return new TermStruct(elems); -} - -TermList* -Parser::ParseTermList(int for_struct) -{ - TermList* tlist = new TermList; - - Term* term = ParseTerm(); - while (term) { - if (for_struct && !term->isDef()) { - return (TermList*) error("(Parse) non-definition term in struct"); - } - else if (!for_struct && term->isDef()) { - return (TermList*) error("(Parse) illegal definition in array"); - } - - tlist->append(term); - Token t = lexer->Get(); - - /*** OLD WAY: COMMA SEPARATORS REQUIRED *** - if (t.type() != Token::Comma) { - lexer->PutBack(); - term = 0; - } - else - term = ParseTerm(); - /*******************************************/ - - // NEW WAY: COMMA SEPARATORS OPTIONAL: - if (t.type() != Token::Comma) { - lexer->PutBack(); - } - - term = ParseTerm(); - } - - return tlist; -} - - - diff --git a/Stars45/Parser.h b/Stars45/Parser.h deleted file mode 100644 index 84fe268..0000000 --- a/Stars45/Parser.h +++ /dev/null @@ -1,45 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Declaration of the generic Parser class -*/ - -#ifndef PARSER_H -#define PARSER_H - -#include "Text.h" -#include "Term.h" - -// +-------------------------------------------------------------------+ - -class Reader; -class Scanner; - -// +-------------------------------------------------------------------+ - -class Parser -{ -public: - Parser(Reader* r = 0); - ~Parser(); - - Term* ParseTerm(); - Term* ParseTermBase(); - Term* ParseTermRest(Term* base); - TermList* ParseTermList(int for_struct); - TermArray* ParseArray(); - TermStruct* ParseStruct(); - -private: - Reader* reader; - Scanner* lexer; -}; - -#endif diff --git a/Stars45/Particles.cpp b/Stars45/Particles.cpp deleted file mode 100644 index 911b06f..0000000 --- a/Stars45/Particles.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Particle Burst class -*/ - -#include "Particles.h" -#include "Projector.h" -#include "Light.h" -#include "Bitmap.h" -#include "Clock.h" -#include "Random.h" - -// +--------------------------------------------------------------------+ - -inline float randf() { return (rand()-16384.0f)/32768.0f; } - -// +--------------------------------------------------------------------+ - -Particles::Particles(Bitmap* bitmap, int np, const Vec3& base_loc, const Vec3& vel, -float bspeed, float dr, float s, float bloom, float dec, float rate, -bool cont, bool trail, bool rise, int a, int nframes) -: nparts(np), base_speed(bspeed), max_speed(bspeed*3.0f), -drag(dr), min_scale(s), max_scale(bloom), decay(dec), -release_rate(rate), continuous(cont), trailing(trail), rising(rise), -blend(a), extra(0.0f), point_sprite(0), emitting(true) -{ - MoveTo(base_loc); - ref_loc = base_loc; - - trans = true; - luminous = true; - shadow = false; - nverts = nparts; - - if (max_scale < min_scale) - max_scale = min_scale; - - velocity = new Point[nverts]; - part_loc = new Point[nverts]; - release = new Point[nverts]; - intensity = new float[nverts]; - timestamp = new float[nverts]; - scale = new float[nverts]; - angle = new float[nverts]; - frame = new BYTE[nverts]; - - float speed = base_speed; - - for (int i = 0; i < nverts; i++) { - intensity[i] = 1.0f; - timestamp[i] = (float) (Clock::GetInstance()->GameTime() / 1000.0); - scale[i] = (float) (min_scale); - angle[i] = (float) (Random(0, 2*PI)); - frame[i] = 0; - - part_loc[i] = Point(); - release[i] = ref_loc; - velocity[i] = RandomVector(speed); - velocity[i] += vel; - - if (speed < max_speed) - speed += (float) Random(max_speed/15.0, max_speed/5.0); - else - speed = base_speed; - } - - radius = 15000.0f; - - if (decay > 2) - decay /= 256.0f; - - if (nparts < 8) { - nverts = 1; - } - - else if (nparts > 50 || continuous) { - nverts = (int) (nparts * 0.125 * release_rate); - } - - point_sprite = new Sprite(bitmap, nframes); - point_sprite->Scale(s); - point_sprite->SetBlendMode(blend); - point_sprite->SetFrameRate(nframes * decay); -} - -Particles::~Particles() -{ - delete point_sprite; - delete [] velocity; - delete [] part_loc; - delete [] release; - delete [] timestamp; - delete [] intensity; - delete [] scale; - delete [] angle; - delete [] frame; -} - -// +--------------------------------------------------------------------+ - -void Particles::ExecFrame(double seconds) -{ - point_sprite->Update(); - - ref_loc = loc; - radius += max_speed * (float) seconds; - - float scaled_drag = (float) exp(-drag * seconds); - float scale_inc = (float) ((max_scale-min_scale)*seconds*2); - - for (int i = 0; i < nverts; i++) { - part_loc[i] += velocity[i] * (float) seconds; - - if (rising) { - part_loc[i].y += (float) ((randf() + 1) * scale[i] * 80 * seconds); - } - - // do the (chunky) blooming effect: - if (max_scale > 0 && scale[i] < max_scale) { - scale[i] += scale_inc * (float) ((i%3)/3.0); - } - - double rho = angle[i]; - int rot = i%4; - switch (rot) { - case 0: rho += seconds * 0.13; break; - case 1: rho -= seconds * 0.11; break; - case 2: rho += seconds * 0.09; break; - case 3: rho -= seconds * 0.07; break; - default: break; - } - - angle[i] = (float) rho; - intensity[i] -= (float) (decay * seconds); - - if (point_sprite->NumFrames() > 1) { - double age = Clock::GetInstance()->GameTime()/1000.0 - timestamp[i]; - int n = (int) (age * point_sprite->FrameRate()); - - if (n >= point_sprite->NumFrames()) - n = point_sprite->NumFrames() - 1; - - frame[i] = n; - } - - velocity[i] *= scaled_drag; - } - - if (nverts < nparts && emitting) { - int nv = nverts; - double delta = nparts * release_rate * seconds; - int new_parts = (int) (delta + extra); - extra = (float) (delta + extra - new_parts); - nverts += new_parts; - - if (nverts > nparts) - nverts = nparts; - - for (int i = nv; i < nverts; i++) { - intensity[i] = 1; - timestamp[i] = (float) (Clock::GetInstance()->GameTime() / 1000.0); - scale[i] = (float) (min_scale); - angle[i] = (float) (Random(0, 2*PI)); - frame[i] = 0; - part_loc[i] = Point(); - release[i] = ref_loc; - } - } - - if (nverts > nparts) - nverts = nparts; - - // recycle dead particles: - if (continuous) { - float speed = base_speed; - - for (int i = 0; i < nverts; i++) { - if (intensity[i] <= 0) { - part_loc[i] = Point(); - release[i] = ref_loc; - - intensity[i] = 1; - timestamp[i] = (float) (Clock::GetInstance()->GameTime() / 1000.0); - scale[i] = (float) (min_scale); - angle[i] = (float) (PI * rand() / 16384.0); - frame[i] = 0; - velocity[i] = RandomVector(speed); - - if (speed < max_speed) - speed += (float) Random(max_speed/25.0, max_speed/18.0); - else - speed = base_speed; - } - } - } -} - -// +--------------------------------------------------------------------+ - -bool -Particles::CheckVisibility(Projector& projector) -{ - float base = 256; - - if (point_sprite && point_sprite->Frame()) - base = (float) point_sprite->Frame()->Width(); - - float particle_radius = base * max_scale; - - if (projector.IsVisible( Location(), Radius()) && - projector.ApparentRadius(Location(), particle_radius) > 1) { - - visible = true; - } - else { - visible = false; - } - - return visible; -} - -// +--------------------------------------------------------------------+ - -void -Particles::Render(Video* video, DWORD flags) -{ - if (hidden || !visible || !video || !point_sprite) - return; - - if (blend == 2 && !(flags & Graphic::RENDER_ALPHA)) - return; - - if (blend == 4 && !(flags & Graphic::RENDER_ADDITIVE)) - return; - - for (int i = 0; i < nverts; i++) { - Point vloc; - - if (trailing) { - vloc = part_loc[i] + release[i] - offset; - } - else { - vloc = part_loc[i] + loc; - } - - point_sprite->MoveTo(vloc); - point_sprite->SetShade(intensity[i]); - point_sprite->Rescale(scale[i]); - point_sprite->SetAngle(angle[i]); - point_sprite->SetFrameIndex(frame[i]); - - point_sprite->Render(video, flags); - } -} diff --git a/Stars45/Particles.h b/Stars45/Particles.h deleted file mode 100644 index af540da..0000000 --- a/Stars45/Particles.h +++ /dev/null @@ -1,85 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Particle burst class -*/ - -#ifndef Particles_h -#define Particles_h - -#include "Types.h" -#include "Geometry.h" -#include "Graphic.h" -#include "Sprite.h" - -// +--------------------------------------------------------------------+ - -class Particles : public Graphic -{ -public: - Particles(Bitmap* bitmap, - int np, - const Vec3& base_loc, - const Vec3& vel, - float base_speed = 500.0f, - float drag = 1.0f, - float scale = 1.0f, - float bloom = 0.0f, - float decay = 100.0f, - float release = 1.0f, - bool cont = false, - bool trail = true, - bool rise = false, - int blend = 3, - int nframes = 1); - - virtual ~Particles(); - - virtual void Render(Video* video, DWORD flags); - virtual void ExecFrame(double seconds); - virtual void TranslateBy(const Point& ref) { offset = ref; loc = loc - ref; } - virtual bool CheckVisibility(Projector& projector); - - virtual bool IsEmitting() const { return emitting; } - virtual void StopEmitting() { emitting = false; } - -protected: - int nparts; - int nverts; - int blend; - bool continuous; - bool trailing; - bool rising; - bool emitting; - - float base_speed; - float max_speed; - float drag; - float release_rate; - float decay; - float min_scale; - float max_scale; - float extra; - - Point ref_loc; - Point offset; - Point* velocity; - Point* part_loc; - Point* release; - float* timestamp; - float* intensity; - float* scale; - float* angle; - BYTE* frame; - - Sprite* point_sprite; -}; - -#endif // Particles_h diff --git a/Stars45/Pcx.h b/Stars45/Pcx.h deleted file mode 100644 index 86c8bc3..0000000 --- a/Stars45/Pcx.h +++ /dev/null @@ -1,67 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - PCX image file loader -*/ - -#ifndef PCX_H -#define PCX_H - -// +--------------------------------------------------------------------+ - -enum { PCX_OK, PCX_NOMEM, PCX_TOOBIG, PCX_NOFILE }; - -struct PcxHeader -{ - char manufacturer; // Always set to 10 - char version; // Always 5 for 256-color files - char encoding; // Always set to 1 - char bits_per_pixel; // Should be 8 for 256-color files - short xmin,ymin; // Coordinates for top left corner - short xmax,ymax; // Width and height of image - short hres; // Horizontal resolution of image - short vres; // Vertical resolution of image - char palette16[48]; // EGA palette; not used for 256-color files - char reserved; // Reserved for future use - char color_planes; // Color planes - short bytes_per_line; // Number of bytes in 1 line of pixels - short palette_type; // Should be 2 for color palette - char filler[58]; // Nothing but junk -}; - -// +--------------------------------------------------------------------+ - -struct PcxImage -{ - static const char* TYPENAME() { return "PcxImage"; } - - PcxImage(short w, short h, unsigned long* hibits); - PcxImage(short w, short h, unsigned char* bits, unsigned char* colors); - - PcxImage(); - ~PcxImage(); - - int Load(char *filename); - int Save(char *filename); - - int LoadBuffer(unsigned char* buf, int len); - - PcxHeader hdr; - unsigned char* bitmap; - unsigned long* himap; - unsigned char pal[768]; - unsigned long imagebytes; - unsigned short width, height; -}; - -// +--------------------------------------------------------------------+ - - -#endif diff --git a/Stars45/Physical.cpp b/Stars45/Physical.cpp deleted file mode 100644 index 6c2e90e..0000000 --- a/Stars45/Physical.cpp +++ /dev/null @@ -1,774 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract Physical Object -*/ - -#include "Physical.h" -#include "Graphic.h" -#include "Light.h" -#include "Director.h" - -// +--------------------------------------------------------------------+ - -int Physical::id_key = 1; -double Physical::sub_frame = 1.0 / 60.0; - -static const double GRAV = 6.673e-11; - -// +--------------------------------------------------------------------+ - -Physical::Physical() - : id(id_key++), obj_type(0), rep(0), light(0), - thrust(0.0f), drag(0.0f), lat_thrust(false), - trans_x(0.0f), trans_y(0.0f), trans_z(0.0f), straight(false), - roll(0.0f), pitch(0.0f), yaw(0.0f), dr(0.0f), dp(0.0f), dy(0.0f), - dr_acc(0.0f), dp_acc(0.0f), dy_acc(0.0f), - dr_drg(0.0f), dp_drg(0.0f), dy_drg(0.0f), - flight_path_yaw(0.0f), flight_path_pitch(0.0f), primary_mass(0), - roll_rate(1.0f), pitch_rate(1.0f), yaw_rate(1.0f), shake(0.0f), - radius(0.0f), mass(1.0f), integrity(1.0f), life(-1), dir(0), - g_accel(0.0f), Do(0.0f), CL(0.0f), CD(0.0f), alpha(0.0f), stall(0.0f) -{ - strcpy_s(name, "unknown object"); -} - -// +--------------------------------------------------------------------+ - -Physical::Physical(const char* n, int t) - : id(id_key++), obj_type(t), rep(0), light(0), - thrust(0.0f), drag(0.0f), lat_thrust(false), - trans_x(0.0f), trans_y(0.0f), trans_z(0.0f), straight(false), - roll(0.0f), pitch(0.0f), yaw(0.0f), dr(0.0f), dp(0.0f), dy(0.0f), - dr_acc(0.0f), dp_acc(0.0f), dy_acc(0.0f), - dr_drg(0.0f), dp_drg(0.0f), dy_drg(0.0f), - flight_path_yaw(0.0f), flight_path_pitch(0.0f), primary_mass(0), - roll_rate(1.0f), pitch_rate(1.0f), yaw_rate(1.0f), shake(0.0f), - radius(0.0f), mass(1.0f), integrity(1.0f), life(-1), dir(0), - g_accel(0.0f), Do(0.0f), CL(0.0f), CD(0.0f), alpha(0.0f), stall(0.0f) -{ - strncpy_s(name, n, NAMELEN-1); - name[NAMELEN-1] = 0; -} - -// +--------------------------------------------------------------------+ - -Physical::~Physical() -{ - // inform graphic rep and light that we are leaving: - GRAPHIC_DESTROY(rep); - LIGHT_DESTROY(light); - - // we own the director - delete dir; - dir = 0; -} - -// +--------------------------------------------------------------------+ -#undef random -inline double random() { return rand()-16384; } - -void -Physical::ExecFrame(double s) -{ - Point orig_velocity = Velocity(); - arcade_velocity = Point(); - - // if this object is under direction, - // but doesn't need subframe accuracy, - // update the control parameters: - if (dir && !dir->Subframe()) - dir->ExecFrame(s); - - // decrement life before destroying the frame time: - if (life > 0) - life -= s; - - // integrate equations - // using slices no larger - // than sub_frame: - - double seconds = s; - - while (s > 0.0) { - if (s > sub_frame) - seconds = sub_frame; - else - seconds = s; - - // if the director needs subframe accuracy, run it now: - if (dir && dir->Subframe()) - dir->ExecFrame(seconds); - - if (!straight) - AngularFrame(seconds); - - // LINEAR MOVEMENT ---------------------------- - Point pos = cam.Pos(); - - // if the object is thrusting, - // accelerate along the camera normal: - if (thrust) { - Point thrustvec = cam.vpn(); - thrustvec *= ((thrust/mass) * seconds); - velocity += thrustvec; - } - - LinearFrame(seconds); - - // move the position by the (time-frame scaled) velocity: - pos += velocity * seconds; - cam.MoveTo(pos); - - s -= seconds; - } - - alpha = 0.0f; - - // now update the graphic rep and light sources: - if (rep) { - rep->MoveTo(cam.Pos()); - rep->SetOrientation(cam.Orientation()); - } - - if (light) { - light->MoveTo(cam.Pos()); - } - - if (!straight) - CalcFlightPath(); - - accel = (Velocity() - orig_velocity) * (1/seconds); - if (!_finite(accel.x) || !_finite(accel.y) || !_finite(accel.z)) - accel = Point(); -} - -// +--------------------------------------------------------------------+ - -void -Physical::AeroFrame(double s) -{ - arcade_velocity = Point(); - - // if this object is under direction, - // but doesn't need subframe accuracy, - // update the control parameters: - if (dir && !dir->Subframe()) - dir->ExecFrame(s); - - // decrement life before destroying the frame time: - if (life > 0) - life -= s; - - // integrate equations - // using slices no larger - // than sub_frame: - - double seconds = s; - - while (s > 0.0) { - if (s > sub_frame) - seconds = sub_frame; - else - seconds = s; - - // if the director needs subframe accuracy, run it now: - if (dir && dir->Subframe()) - dir->ExecFrame(seconds); - - AngularFrame(seconds); - - // LINEAR MOVEMENT ---------------------------- - Point pos = cam.Pos(); - - // if the object is thrusting, - // accelerate along the camera normal: - if (thrust) { - Point thrustvec = cam.vpn(); - thrustvec *= ((thrust/mass) * seconds); - velocity += thrustvec; - } - - // AERODYNAMICS ------------------------------ - - if (lat_thrust) - LinearFrame(seconds); - - // if no thrusters, do constant gravity: - else if (g_accel > 0) - velocity += Point(0, -g_accel, 0) * seconds; - - // compute alpha, rho, drag, and lift: - - Point vfp = velocity; - double v = vfp.Normalize(); - double v_2 = 0; - double rho = GetDensity(); - double lift = 0; - - if (v > 150) { - v_2 = (v-150) * (v-150); - - Point vfp1 = vfp - cam.vrt() * (vfp * cam.vrt()); - vfp1.Normalize(); - - double cos_alpha = vfp1 * cam.vpn(); - - if (cos_alpha >= 1) { - alpha = 0.0f; - } - else { - alpha = (float) acos(cos_alpha); - } - - // if flight path is above nose, alpha is negative: - if (vfp1 * cam.vup() > 0) - alpha = -alpha; - - if (alpha <= stall) { - lift = CL * alpha * rho * v_2; - } - else { - lift = CL * (2*stall - alpha) * rho * v_2; - } - - // add lift to velocity: - if (_finite(lift)) - velocity += cam.vup() * lift * seconds; - else - lift = 0; - - // if drag applies, decellerate: - double alpha_2 = alpha*alpha; - double drag_eff = (drag + (CD * alpha_2)) * rho * v_2; - - Point vn = velocity; - vn.Normalize(); - - velocity += vn * -drag_eff * seconds; - } - else { - velocity *= exp(-drag * seconds); - } - - // move the position by the (time-frame scaled) velocity: - pos += velocity * seconds; - cam.MoveTo(pos); - - s -= seconds; - } - - // now update the graphic rep and light sources: - if (rep) { - rep->MoveTo(cam.Pos()); - rep->SetOrientation(cam.Orientation()); - } - - if (light) { - light->MoveTo(cam.Pos()); - } -} - -double -Physical::GetDensity() const -{ - double alt = cam.Pos().y; - double rho = 0.75 * Do * (250e3-alt)/250e3; - - return rho; -} - -// +--------------------------------------------------------------------+ - -void -Physical::ArcadeFrame(double s) -{ - // if this object is under direction, - // but doesn't need subframe accuracy, - // update the control parameters: - if (dir && !dir->Subframe()) - dir->ExecFrame(s); - - // decrement life before destroying the frame time: - if (life > 0) - life -= s; - - // integrate equations - // using slices no larger - // than sub_frame: - - double seconds = s; - - while (s > 0.0) { - if (s > sub_frame) - seconds = sub_frame; - else - seconds = s; - - // if the director needs subframe accuracy, run it now: - if (dir && dir->Subframe()) - dir->ExecFrame(seconds); - - if (!straight) - AngularFrame(seconds); - - Point pos = cam.Pos(); - - // ARCADE FLIGHT MODEL: - // arcade_velocity vector is always in line with heading - - double speed = arcade_velocity.Normalize(); - double bleed = arcade_velocity * cam.vpn(); - - speed *= pow(bleed, 30); - arcade_velocity = cam.vpn() * speed; - - if (thrust) { - Point thrustvec = cam.vpn(); - thrustvec *= ((thrust/mass) * seconds); - arcade_velocity += thrustvec; - } - - if (drag) - arcade_velocity *= exp(-drag * seconds); - - LinearFrame(seconds); - - // move the position by the (time-frame scaled) velocity: - pos += arcade_velocity * seconds + - velocity * seconds; - - cam.MoveTo(pos); - - s -= seconds; - } - - alpha = 0.0f; - - // now update the graphic rep and light sources: - if (rep) { - rep->MoveTo(cam.Pos()); - rep->SetOrientation(cam.Orientation()); - } - - if (light) { - light->MoveTo(cam.Pos()); - } -} - -// +--------------------------------------------------------------------+ - -void -Physical::AngularFrame(double seconds) -{ - if (!straight) { - dr += (float) (dr_acc * seconds); - dy += (float) (dy_acc * seconds); - dp += (float) (dp_acc * seconds); - - dr *= (float) exp(-dr_drg * seconds); - dy *= (float) exp(-dy_drg * seconds); - dp *= (float) exp(-dp_drg * seconds); - - roll = (float) (dr * seconds); - pitch = (float) (dp * seconds); - yaw = (float) (dy * seconds); - - if (shake > 0.01) { - vibration = Point(random(), random(), random()); - vibration.Normalize(); - vibration *= (float) (shake * seconds); - - shake *= (float) exp(-1.5 * seconds); - } - else { - vibration.x = vibration.y = vibration.z = 0.0f; - shake = 0.0f; - } - - cam.Aim(roll, pitch, yaw); - } -} - -// +--------------------------------------------------------------------+ - -void -Physical::LinearFrame(double seconds) -{ - // deal with lateral thrusters: - - if (trans_x) { // side-to-side - Point transvec = cam.vrt(); - transvec *= ((trans_x/mass) * seconds); - - velocity += transvec; - } - - if (trans_y) { // fore-and-aft - Point transvec = cam.vpn(); - transvec *= ((trans_y/mass) * seconds); - - velocity += transvec; - } - - if (trans_z) { // up-and-down - Point transvec = cam.vup(); - transvec *= ((trans_z/mass) * seconds); - - velocity += transvec; - } - - // if gravity applies, attract: - if (primary_mass > 0) { - Point g = primary_loc - cam.Pos(); - double r = g.Normalize(); - - g *= GRAV * primary_mass / (r*r); - - velocity += g * seconds; - } - - // constant gravity: - else if (g_accel > 0) { - velocity += Point(0, -g_accel, 0) * seconds; - } - - // if drag applies, decellerate: - if (drag) - velocity *= exp(-drag * seconds); -} - -// +--------------------------------------------------------------------+ - -void -Physical::CalcFlightPath() -{ - flight_path_yaw = 0.0f; - flight_path_pitch = 0.0f; - - // transform flight path into camera frame: - Point flight_path = velocity; - if (flight_path.Normalize() < 1) - return; - - Point tmp = flight_path; - flight_path.x = tmp * cam.vrt(); - flight_path.y = tmp * cam.vup(); - flight_path.z = tmp * cam.vpn(); - - if (flight_path.z < 0.1) - return; - - // first, compute azimuth: - flight_path_yaw = (float) atan(flight_path.x / flight_path.z); - if (flight_path.z < 0) flight_path_yaw -= (float) PI; - if (flight_path_yaw < -PI) flight_path_yaw += (float) (2*PI); - - // then, rotate path into azimuth frame to compute elevation: - Camera yaw_cam; - yaw_cam.Clone(cam); - yaw_cam.Yaw(flight_path_yaw); - - flight_path.x = tmp * yaw_cam.vrt(); - flight_path.y = tmp * yaw_cam.vup(); - flight_path.z = tmp * yaw_cam.vpn(); - - flight_path_pitch = (float) atan(flight_path.y / flight_path.z); -} - -// +--------------------------------------------------------------------+ - -void -Physical::MoveTo(const Point& new_loc) -{ - cam.MoveTo(new_loc); -} - -void -Physical::TranslateBy(const Point& ref) -{ - Point new_loc = cam.Pos() - ref; - cam.MoveTo(new_loc); -} - -void -Physical::ApplyForce(const Point& force) -{ - velocity += force/mass; -} - -void -Physical::ApplyTorque(const Point& torque) -{ - dr += (float) (torque.x/mass); - dp += (float) (torque.y/mass); - dy += (float) (torque.z/mass); -} - -void -Physical::SetThrust(double t) -{ - thrust = (float) t; -} - -void -Physical::SetTransX(double t) -{ - trans_x = (float) t; -} - -void -Physical::SetTransY(double t) -{ - trans_y = (float) t; -} - -void -Physical::SetTransZ(double t) -{ - trans_z = (float) t; -} - -// +--------------------------------------------------------------------+ - -void -Physical::SetHeading(double r, double p, double y) -{ - roll = (float) r; - pitch = (float) p; - yaw = (float) y; - - cam.Aim(roll, pitch, yaw); -} - -void -Physical::LookAt(const Point& dst) -{ - cam.LookAt(dst); -} - -void -Physical::CloneCam(const Camera& c) -{ - cam.Clone(c); -} - -void -Physical::SetAbsoluteOrientation(double r, double p, double y) -{ - roll = (float) r; - pitch = (float) p; - yaw = (float) y; - - Camera work(Location().x, Location().y, Location().z); - work.Aim(r,p,y); - cam.Clone(work); -} - -void -Physical::ApplyRoll(double r) -{ - if (r > 1) r = 1; - else if (r < -1) r = -1; - - dr_acc = (float) r * roll_rate; -} - -void -Physical::ApplyPitch(double p) -{ - if (p > 1) p = 1; - else if (p < -1) p = -1; - - dp_acc = (float) p * pitch_rate; -} - -void -Physical::ApplyYaw(double y) -{ - if (y > 1) y = 1; - else if (y < -1) y = -1; - - dy_acc = (float) y * yaw_rate; -} - -void -Physical::SetAngularRates(double r, double p, double y) -{ - roll_rate = (float) r; - pitch_rate = (float) p; - yaw_rate = (float) y; -} - -void -Physical::GetAngularRates(double& r, double& p, double& y) -{ - r = roll_rate; - p = pitch_rate; - y = yaw_rate; -} - -void -Physical::SetAngularDrag(double r, double p, double y) -{ - dr_drg = (float) r; - dp_drg = (float) p; - dy_drg = (float) y; -} - -void -Physical::GetAngularDrag(double& r, double& p, double& y) -{ - r = dr_drg; - p = dp_drg; - y = dy_drg; -} - -void -Physical::GetAngularThrust(double& r, double& p, double& y) -{ - r = 0; - p = 0; - y = 0; - - if (dr_acc > 0.05 * roll_rate) r = 1; - else if (dr_acc < -0.05 * roll_rate) r = -1; - else if (dr > 0.01 * roll_rate) r = -1; - else if (dr < -0.01 * roll_rate) r = 1; - - if (dy_acc > 0.05 * yaw_rate) y = 1; - else if (dy_acc < -0.05 * yaw_rate) y = -1; - else if (dy > 0.01 * yaw_rate) y = -1; - else if (dy < -0.01 * yaw_rate) y = 1; - - if (dp_acc > 0.05 * pitch_rate) p = 1; - else if (dp_acc < -0.05 * pitch_rate) p = -1; - else if (dp > 0.01 * pitch_rate) p = -1; - else if (dp < -0.01 * pitch_rate) p = 1; -} - - -void -Physical::SetPrimary(const Point& l, double m) -{ - primary_loc = l; - primary_mass = m; -} - -void -Physical::SetGravity(double g) -{ - if (g >= 0) - g_accel = (float) g; -} - -void -Physical::SetBaseDensity(double d) -{ - if (d >= 0) - Do = (float) d; -} - -// +--------------------------------------------------------------------+ - -void -Physical::InflictDamage(double damage, int /*type*/) -{ - integrity -= (float) damage; - - if (integrity < 1.0f) - integrity = 0.0f; -} - -// +--------------------------------------------------------------------+ - -int -Physical::CollidesWith(Physical& o) -{ - // representation collision test (will do bounding spheres first): - if (rep && o.rep) - return rep->CollidesWith(*o.rep); - - Point delta_loc = Location() - o.Location(); - - // bounding spheres test: - if (delta_loc.length() > radius + o.radius) - return 0; - - // assume collision: - return 1; -} - - -// +--------------------------------------------------------------------+ - -void -Physical::ElasticCollision(Physical& a, Physical& b) -{ - double mass_sum = a.mass + b.mass; - double mass_delta = a.mass - b.mass; - - Point vel_a = (Point(b.velocity) * (2 * b.mass) + Point(a.velocity) * mass_delta) * (1/mass_sum); - Point vel_b = (Point(a.velocity) * (2 * a.mass) - Point(b.velocity) * mass_delta) * (1/mass_sum); - - a.velocity = vel_a; - b.velocity = vel_b; -} - -// +--------------------------------------------------------------------+ - -void -Physical::InelasticCollision(Physical& a, Physical& b) -{ - double mass_sum = a.mass + b.mass; - - Point vel_a = (Point(a.velocity) * a.mass + Point(b.velocity) * b.mass) * (1/mass_sum); - - a.velocity = vel_a; - b.velocity = vel_a; -} - -// +--------------------------------------------------------------------+ - -void -Physical::SemiElasticCollision(Physical& a, Physical& b) -{ - double mass_sum = a.mass + b.mass; - double mass_delta = a.mass - b.mass; - - Point avel = a.Velocity(); - Point bvel = b.Velocity(); - Point dv = avel - bvel; - - // low delta-v: stick - if (dv.length() < 20) { - if (a.mass > b.mass) { - b.velocity = a.velocity; - } - - else { - a.velocity = b.velocity; - } - } - - // high delta-v: bounce - else { - Point Ve_a = (bvel * (2 * b.mass) + avel * mass_delta) * (1/mass_sum) * 0.65; - Point Ve_b = (avel * (2 * a.mass) - bvel * mass_delta) * (1/mass_sum) * 0.65; - Point Vi_ab = (avel * a.mass + bvel * b.mass) * (1/mass_sum) * 0.35; - - a.arcade_velocity = Point(); - b.arcade_velocity = Point(); - - a.velocity = Ve_a + Vi_ab; - b.velocity = Ve_b + Vi_ab; - } -} - diff --git a/Stars45/Physical.h b/Stars45/Physical.h deleted file mode 100644 index b9a9be5..0000000 --- a/Stars45/Physical.h +++ /dev/null @@ -1,204 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract Physical Object -*/ - -#ifndef Physical_h -#define Physical_h - -#include "Types.h" -#include "Geometry.h" -#include "Camera.h" - -// +--------------------------------------------------------------------+ - -class Director; -class Graphic; -class Light; - -// +--------------------------------------------------------------------+ - -class Physical -{ -public: - static const char* TYPENAME() { return "Physical"; } - - Physical(); - Physical(const char* n, int t=0); - virtual ~Physical(); - - int operator == (const Physical& p) const { return id == p.id; } - - // Integration Loop Control: - static void SetSubFrameLength(double seconds) { sub_frame = seconds; } - static double GetSubFrameLength() { return sub_frame; } - - // operations - virtual void ExecFrame(double seconds); - virtual void AeroFrame(double seconds); - virtual void ArcadeFrame(double seconds); - - virtual void AngularFrame(double seconds); - virtual void LinearFrame(double seconds); - - virtual void CalcFlightPath(); - - virtual void MoveTo(const Point& new_loc); - virtual void TranslateBy(const Point& ref); - virtual void ApplyForce(const Point& force); - virtual void ApplyTorque(const Point& torque); - virtual void SetThrust(double t); - virtual void SetTransX(double t); - virtual void SetTransY(double t); - virtual void SetTransZ(double t); - virtual void SetHeading(double r, double p, double y); - virtual void LookAt(const Point& dst); - virtual void ApplyRoll(double roll_acc); - virtual void ApplyPitch(double pitch_acc); - virtual void ApplyYaw(double yaw_acc); - - virtual int CollidesWith(Physical& o); - static void ElasticCollision(Physical& a, Physical& b); - static void InelasticCollision(Physical& a, Physical& b); - static void SemiElasticCollision(Physical& a, Physical& b); - virtual void InflictDamage(double damage, int type = 0); - - // accessors: - int Identity() const { return id; } - int Type() const { return obj_type; } - const char* Name() const { return name; } - - Point Location() const { return cam.Pos(); } - Point Heading() const { return cam.vpn(); } - Point LiftLine() const { return cam.vup(); } - Point BeamLine() const { return cam.vrt(); } - Point Velocity() const { return velocity + arcade_velocity; } - Point Acceleration() - const { return accel; } - double Thrust() const { return thrust; } - double TransX() const { return trans_x; } - double TransY() const { return trans_y; } - double TransZ() const { return trans_z; } - double Drag() const { return drag; } - - double Roll() const { return roll; } - double Pitch() const { return pitch; } - double Yaw() const { return yaw; } - Point Rotation() const { return Point(dp,dr,dy); } - - double Alpha() const { return alpha; } - - double FlightPathYawAngle() const { return flight_path_yaw; } - double FlightPathPitchAngle() const { return flight_path_pitch; } - - double Radius() const { return radius; } - double Mass() const { return mass; } - double Integrity() const { return integrity; } - double Life() const { return life; } - - double Shake() const { return shake; } - const Point& Vibration() const { return vibration; } - - const Camera& Cam() const { return cam; } - Graphic* Rep() const { return rep; } - Light* LightSrc() const { return light; } - - Director* GetDirector() const { return dir; } - - // mutators: - virtual void SetAngularRates(double r, double p, double y); - virtual void GetAngularRates(double& r, double& p, double& y); - virtual void SetAngularDrag(double r, double p, double y); - virtual void GetAngularDrag(double& r, double& p, double& y); - virtual void GetAngularThrust(double& r, double& p, double& y); - virtual void SetVelocity(const Point& v) { velocity = v; } - virtual void SetAbsoluteOrientation(double roll, double pitch, double yaw); - virtual void CloneCam(const Camera& cam); - virtual void SetDrag(double d) { drag = (float) d; } - - virtual void SetPrimary(const Point& loc, double mass); - virtual void SetGravity(double g); - virtual void SetBaseDensity(double d); - - virtual double GetBaseDensity() const { return Do; } - virtual double GetDensity() const; - - enum { NAMELEN = 48 }; - -protected: - static int id_key; - - // identification: - int id; - int obj_type; - char name[NAMELEN]; - - // position, velocity, and acceleration: - Camera cam; - Point velocity; - Point arcade_velocity; - Point accel; - float thrust; - float trans_x; - float trans_y; - float trans_z; - float drag; - - // attitude and angular velocity: - float roll, pitch, yaw; - float dr, dp, dy; - float dr_acc, dp_acc, dy_acc; - float dr_drg, dp_drg, dy_drg; - - float flight_path_yaw; - float flight_path_pitch; - - // gravitation: - Point primary_loc; - double primary_mass; - - // aerodynamics: - float g_accel; // acceleration due to gravity (constant) - float Do; // atmospheric density at sea level - float CL; // base coefficient of lift - float CD; // base coefficient of drag - float alpha; // current angle of attack (radians) - float stall; // stall angle of attack (radians) - bool lat_thrust; // lateral thrusters enabled in aero mode? - bool straight; - - // vibration: - float shake; - Point vibration; - - // scale factors for ApplyXxx(): - float roll_rate, pitch_rate, yaw_rate; - - // physical properties: - double life; - float radius; - float mass; - float integrity; - - // graphic representation: - Graphic* rep; - Light* light; - - // AI or human controller: - Director* dir; // null implies an autonomous object - - static double sub_frame; -}; - -// +--------------------------------------------------------------------+ - -#endif // Physical_h - diff --git a/Stars45/PlanScreen.cpp b/Stars45/PlanScreen.cpp deleted file mode 100644 index e560be4..0000000 --- a/Stars45/PlanScreen.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/* 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 "PlanScreen.h" -#include "FormDef.h" -#include "MsnObjDlg.h" -#include "MsnPkgDlg.h" -#include "MsnWepDlg.h" -#include "MsnNavDlg.h" -#include "DebriefDlg.h" -#include "AwardDlg.h" -#include "Campaign.h" -#include "Mission.h" -#include "Sim.h" -#include "Starshatter.h" -#include "StarSystem.h" - -#include "GameWinDX9.h" -#include "Video.h" -#include "Screen.h" -#include "ActiveWindow.h" -#include "Mouse.h" -#include "Keyboard.h" -#include "FadeView.h" -#include "Color.h" -#include "Bitmap.h" -#include "Font.h" -#include "FontMgr.h" -#include "EventDispatch.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -PlanScreen::PlanScreen() -: screen(0), navdlg(0), award_dlg(0), debrief_dlg(0), -objdlg(0), pkgdlg(0), wepdlg(0), isShown(false) -{ - loader = DataLoader::GetLoader(); -} - -PlanScreen::~PlanScreen() -{ - TearDown(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::Setup(Screen* s) -{ - if (!s) - return; - - screen = s; - - // create windows - loader->UseFileSystem(true); - - FormDef msn_obj_def("MsnObjDlg", 0); - msn_obj_def.Load("MsnObjDlg"); - objdlg = new MsnObjDlg(screen, msn_obj_def, this); - - FormDef msn_pkg_def("MsnPkgDlg", 0); - msn_pkg_def.Load("MsnPkgDlg"); - pkgdlg = new MsnPkgDlg(screen, msn_pkg_def, this); - - FormDef msn_nav_def("MsnNavDlg", 0); - msn_nav_def.Load("MsnNavDlg"); - navdlg = new MsnNavDlg(screen, msn_nav_def, this); - - FormDef msn_wep_def("MsnWepDlg", 0); - msn_wep_def.Load("MsnWepDlg"); - wepdlg = new MsnWepDlg(screen, msn_wep_def, this); - - FormDef award_def("AwardDlg", 0); - award_def.Load("AwardDlg"); - award_dlg = new AwardDlg(screen, award_def, this); - - FormDef debrief_def("DebriefDlg", 0); - debrief_def.Load("DebriefDlg"); - debrief_dlg = new DebriefDlg(screen, debrief_def, this); - - loader->UseFileSystem(Starshatter::UseFileSystem()); - ShowMsnDlg(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::TearDown() -{ - if (screen) { - screen->DelWindow(objdlg); - screen->DelWindow(pkgdlg); - screen->DelWindow(wepdlg); - screen->DelWindow(navdlg); - screen->DelWindow(debrief_dlg); - screen->DelWindow(award_dlg); - } - - delete objdlg; - delete pkgdlg; - delete wepdlg; - delete navdlg; - delete debrief_dlg; - delete award_dlg; - - objdlg = 0; - pkgdlg = 0; - wepdlg = 0; - navdlg = 0; - debrief_dlg = 0; - award_dlg = 0; - screen = 0; -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::ExecFrame() -{ - GameWinDX9::GetInstance()->SetScreenColor(Color::Black); - - Mission* mission = 0; - Campaign* campaign = Campaign::GetCampaign(); - - if (campaign) - mission = campaign->GetMission(); - - if (navdlg) { - navdlg->SetMission(mission); - - if (navdlg->IsShown()) - navdlg->ExecFrame(); - } - - if (objdlg && objdlg->IsShown()) { - objdlg->ExecFrame(); - } - - if (pkgdlg && pkgdlg->IsShown()) { - pkgdlg->ExecFrame(); - } - - if (wepdlg && wepdlg->IsShown()) { - wepdlg->ExecFrame(); - } - - if (award_dlg && award_dlg->IsShown()) { - award_dlg->ExecFrame(); - } - - if (debrief_dlg && debrief_dlg->IsShown()) { - debrief_dlg->ExecFrame(); - } -} - -// +--------------------------------------------------------------------+ - -bool -PlanScreen::CloseTopmost() -{ - if (debrief_dlg->IsShown()) { - debrief_dlg->OnClose(0); - } - - if (award_dlg->IsShown()) { - return true; - } - - return false; -} - -void -PlanScreen::Show() -{ - if (!isShown) { - ShowMsnDlg(); - isShown = true; - } -} - -void -PlanScreen::Hide() -{ - HideAll(); - isShown = false; -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::ShowMsnDlg() -{ - HideAll(); - Mouse::Show(true); - objdlg->Show(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::HideMsnDlg() -{ - HideAll(); - Mouse::Show(true); - objdlg->Show(); -} - -bool -PlanScreen::IsMsnShown() -{ - return IsMsnObjShown() || IsMsnPkgShown() || IsMsnWepShown(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::ShowMsnObjDlg() -{ - HideAll(); - Mouse::Show(true); - objdlg->Show(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::HideMsnObjDlg() -{ - HideAll(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -bool -PlanScreen::IsMsnObjShown() -{ - return objdlg && objdlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::ShowMsnPkgDlg() -{ - HideAll(); - Mouse::Show(true); - pkgdlg->Show(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::HideMsnPkgDlg() -{ - HideAll(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -bool -PlanScreen::IsMsnPkgShown() -{ - return pkgdlg && pkgdlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::ShowMsnWepDlg() -{ - HideAll(); - Mouse::Show(true); - wepdlg->Show(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::HideMsnWepDlg() -{ - HideAll(); - Mouse::Show(true); -} - -// +--------------------------------------------------------------------+ - -bool -PlanScreen::IsMsnWepShown() -{ - return wepdlg && wepdlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::ShowNavDlg() -{ - if (navdlg && !navdlg->IsShown()) { - HideAll(); - Mouse::Show(true); - navdlg->Show(); - } -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::HideNavDlg() -{ - if (navdlg && navdlg->IsShown()) { - HideAll(); - Mouse::Show(true); - } -} - -// +--------------------------------------------------------------------+ - -bool -PlanScreen::IsNavShown() -{ - return navdlg && navdlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::ShowDebriefDlg() -{ - HideAll(); - Mouse::Show(true); - debrief_dlg->Show(); -} - -void -PlanScreen::HideDebriefDlg() -{ - HideAll(); - Mouse::Show(true); -} - -bool -PlanScreen::IsDebriefShown() -{ - return debrief_dlg && debrief_dlg->IsShown(); -} - -// +--------------------------------------------------------------------+ - -void -PlanScreen::ShowAwardDlg() -{ - HideAll(); - Mouse::Show(true); - award_dlg->Show(); -} - -void -PlanScreen::HideAwardDlg() -{ - HideAll(); - Mouse::Show(true); -} - -bool -PlanScreen::IsAwardShown() -{ - return award_dlg && award_dlg->IsShown(); -} - - -// +--------------------------------------------------------------------+ - -void -PlanScreen::HideAll() -{ - if (objdlg) objdlg->Hide(); - if (pkgdlg) pkgdlg->Hide(); - if (wepdlg) wepdlg->Hide(); - if (navdlg) navdlg->Hide(); - if (award_dlg) award_dlg->Hide(); - if (debrief_dlg) debrief_dlg->Hide(); -} \ No newline at end of file diff --git a/Stars45/PlanScreen.h b/Stars45/PlanScreen.h deleted file mode 100644 index d033ed6..0000000 --- a/Stars45/PlanScreen.h +++ /dev/null @@ -1,107 +0,0 @@ -/* 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 - -*/ - -#ifndef PlanScreen_h -#define PlanScreen_h - -#include "Types.h" -#include "Bitmap.h" -#include "Screen.h" -#include "BaseScreen.h" - -// +--------------------------------------------------------------------+ - -class MsnObjDlg; -class MsnPkgDlg; -class MsnWepDlg; -class MsnNavDlg; -class DebriefDlg; -class AwardDlg; - -class Bitmap; -class DataLoader; -class Font; -class Screen; -class Video; -class VideoFactory; - -// +--------------------------------------------------------------------+ - -class PlanScreen : public BaseScreen -{ -public: - PlanScreen(); - virtual ~PlanScreen(); - - virtual void Setup(Screen* screen); - virtual void TearDown(); - virtual bool CloseTopmost(); - - virtual bool IsShown() const { return isShown; } - virtual void Show(); - virtual void Hide(); - - virtual void ShowMsnDlg(); - virtual void HideMsnDlg(); - virtual bool IsMsnShown(); - - virtual void ShowMsnObjDlg(); - virtual void HideMsnObjDlg(); - virtual bool IsMsnObjShown(); - virtual MsnObjDlg* GetMsnObjDlg() { return objdlg; } - - virtual void ShowMsnPkgDlg(); - virtual void HideMsnPkgDlg(); - virtual bool IsMsnPkgShown(); - virtual MsnPkgDlg* GetMsnPkgDlg() { return pkgdlg; } - - virtual void ShowMsnWepDlg(); - virtual void HideMsnWepDlg(); - virtual bool IsMsnWepShown(); - virtual MsnWepDlg* GetMsnWepDlg() { return wepdlg; } - - virtual void ShowNavDlg(); - virtual void HideNavDlg(); - virtual bool IsNavShown(); - virtual NavDlg* GetNavDlg() { return (NavDlg*) navdlg; } - - virtual void ShowDebriefDlg(); - virtual void HideDebriefDlg(); - virtual bool IsDebriefShown(); - virtual DebriefDlg* GetDebriefDlg() { return debrief_dlg; } - - virtual void ShowAwardDlg(); - virtual void HideAwardDlg(); - virtual bool IsAwardShown(); - virtual AwardDlg* GetAwardDlg() { return award_dlg; } - - virtual void ExecFrame(); - virtual void HideAll(); - - -private: - Screen* screen; - - MsnObjDlg* objdlg; - MsnPkgDlg* pkgdlg; - MsnWepDlg* wepdlg; - MsnNavDlg* navdlg; - DebriefDlg* debrief_dlg; - AwardDlg* award_dlg; - - DataLoader* loader; - - int wc, hc; - bool isShown; -}; - -// +--------------------------------------------------------------------+ - -#endif // PlanScreen_h - diff --git a/Stars45/Player.cpp b/Stars45/Player.cpp deleted file mode 100644 index bb4a6d3..0000000 --- a/Stars45/Player.cpp +++ /dev/null @@ -1,1553 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Player / Logbook class -*/ - - -#include "Player.h" -#include "NetLobbyServer.h" -#include "NetLayer.h" -#include "Ship.h" -#include "SimEvent.h" -#include "Campaign.h" -#include "CampaignSaveGame.h" -#include "Random.h" -#include "HUDView.h" -#include "Mfd.h" - -#include "DataLoader.h" -#include "Encrypt.h" -#include "ParseUtil.h" -#include "FormatUtil.h" -#include "Bitmap.h" -#include "Clock.h" -#include "ContentBundle.h" - -// +-------------------------------------------------------------------+ - -class AwardInfo -{ -public: - static const char* TYPENAME() { return "AwardInfo"; } - - AwardInfo() : - type(RANK), - id(0), - large_insignia(0), - small_insignia(0), - granted_ship_classes(0x7), - total_points(0), - mission_points(0), - total_missions(0), - kills(0), - lost(0), - collision(0), - campaign_id(0), - campaign_complete(false), - dynamic_campaign(false), - ceremony(true), - required_awards(0), - lottery(0), - min_rank(0), - max_rank((int) 1e9), - min_ship_class(0), - max_ship_class((int) 1e9) - { } - ~AwardInfo() { } - - enum TYPE { RANK, MEDAL }; - - int type; - int id; - Text name; - Text abrv; - Text desc; - Text grant; - Text desc_sound; - Text grant_sound; - Bitmap* large_insignia; - Bitmap* small_insignia; - int granted_ship_classes; - - int total_points; - int mission_points; - int total_missions; - int kills; - int lost; - int collision; - int campaign_id; - bool campaign_complete; - bool dynamic_campaign; - bool ceremony; - - int required_awards; - int lottery; - int min_rank; - int max_rank; - int min_ship_class; - int max_ship_class; -}; - -static List rank_table; -static List medal_table; -static bool config_exists = false; - -// +-------------------------------------------------------------------+ - -Player::Player(const char* n) - : uid(0), name(n), create_date(0), points(0), medals(0), flight_time(0), - missions(0), kills(0), losses(0), campaigns(0), trained(0), - flight_model(0), flying_start(0), landing_model(0), - ai_level(1), hud_mode(0), hud_color(1), - ff_level(4), grid(1), gunsight(0), award(0) -{ - name.setSensitive(false); - - mfd[0] = -1; - mfd[1] = -1; - mfd[2] = -1; - mfd[3] = -1; -} - -Player::Player() - : uid(0), create_date(0), points(0), medals(0), flight_time(0), - missions(0), kills(0), losses(0), campaigns(0), trained(0), - flight_model(0), flying_start(0), landing_model(0), - ai_level(1), hud_mode(0), hud_color(1), - ff_level(4), grid(1), gunsight(0), award(0) -{ - name.setSensitive(false); - - mfd[0] = -1; - mfd[1] = -1; - mfd[2] = -1; - mfd[3] = -1; -} - -Player::~Player() -{ } - -// +-------------------------------------------------------------------+ - -void -Player::SetName(const char* n) -{ - if (n && *n) - name = n; -} - -void -Player::SetPassword(const char* p) -{ - if (p && *p) { - pass = p; - - if (pass.length() > 16) - pass = pass.substring(0, 16); - } -} - -void -Player::SetSquadron(const char* s) -{ - if (s && *s) - squadron = s; -} - -void -Player::SetSignature(const char* s) -{ - if (s && *s) - signature = s; -} - -const Text& -Player::ChatMacro(int n) const -{ - if (n >= 0 && n < 10) - return chat_macros[n]; - - return chat_macros[0]; -} - -void -Player::SetChatMacro(int n, const char* m) -{ - if (n >= 0 && n < 10 && m && *m) - chat_macros[n] = m; -} - -void -Player::SetPoints(int p) -{ - if (p >= 0) - points = p; -} - -void -Player::SetMedals(int m) -{ - medals = m; -} - -void -Player::SetCampaigns(int n) -{ - campaigns = n; -} - -void -Player::SetTrained(int n) -{ - if (n == 0) - trained = 0; - - else if (n > 0 && n <= 20) - trained = trained | (1 << (n-1)); - - else if (n > 20) - trained = n; -} - -bool -Player::HasTrained(int n) const -{ - if (n > 0 && n <= 20) - return (trained & (1 << (n-1))) ? true : false; - - return false; -} - -bool -Player::HasCompletedCampaign(int id) const -{ - if (id > 0 && id < 30) - return (campaigns & (1 << id)) ? true : false; - - return false; -} - -void -Player::SetCampaignComplete(int id) -{ - if (id > 0 && id < 30) { - campaigns = campaigns | (1 << id); - Save(); - } -} - -void -Player::SetCreateDate(int d) -{ - if (d >= 0) - create_date = d; -} - -void -Player::SetFlightTime(int t) -{ - if (t >= 0) - flight_time = t; -} - -void -Player::SetMissions(int m) -{ - if (m >= 0) - missions = m; -} - -void -Player::SetKills(int k) -{ - if (k >= 0) - kills = k; -} - -void -Player::SetLosses(int l) -{ - if (l >= 0) - losses = l; -} - -// +-------------------------------------------------------------------+ - -void -Player::AddFlightTime(int t) -{ - if (t > 0) - flight_time += t; -} - -void -Player::AddPoints(int p) -{ - if (p > 0) - points += p; -} - -void -Player::AddMissions(int m) -{ - if (m > 0) - missions += m; -} - -void -Player::AddKills(int k) -{ - if (k > 0) - kills += k; -} - -void -Player::AddLosses(int l) -{ - if (l > 0) - losses += l; -} - -// +-------------------------------------------------------------------+ - -void -Player::SetFlightModel(int n) -{ - if (n >= Ship::FM_STANDARD && n <= Ship::FM_ARCADE) { - flight_model = n; - Ship::SetFlightModel(n); - } -} - -void -Player::SetFlyingStart(int n) -{ - flying_start = n; -} - -void -Player::SetLandingModel(int n) -{ - if (n >= Ship::LM_STANDARD && n <= Ship::LM_EASIER) { - landing_model = n; - Ship::SetLandingModel(landing_model); - } -} - -void -Player::SetAILevel(int n) -{ - ai_level = n; -} - -void -Player::SetHUDMode(int n) -{ - hud_mode = n; - HUDView::SetArcade(n > 0); -} - -void -Player::SetHUDColor(int n) -{ - hud_color = n; - HUDView::SetDefaultColorSet(n); -} - -void -Player::SetFriendlyFire(int n) -{ - if (n >= 0 && n <= 4) { - ff_level = n; - Ship::SetFriendlyFireLevel(n/4.0); - } -} - -void -Player::SetGridMode(int n) -{ - if (n >= 0 && n <= 1) { - grid = n; - } -} - -void -Player::SetGunsight(int n) -{ - if (n >= 0 && n <= 1) { - gunsight = n; - } -} - -void -Player::ClearShowAward() -{ - award = 0; -} - -Text -Player::AwardName() const -{ - if (award) - return award->name; - - return Text(); -} - -Text -Player::AwardDesc() const -{ - if (award) - return award->grant; - - return Text(); -} - -Bitmap* -Player::AwardImage() const -{ - if (award) - return award->large_insignia; - - return 0; -} - -Sound* -Player::AwardSound() const -{ - if (award && award->grant_sound.length()) { - DataLoader* loader = DataLoader::GetLoader(); - Sound* result = 0; - - loader->LoadSound(award->grant_sound, result); - return result; - } - - return 0; -} - -// +-------------------------------------------------------------------+ - -const char* -Player::RankName(int rank) -{ - ListIter iter = rank_table; - while (++iter) { - AwardInfo* award = iter.value(); - if (award->id == rank) - return award->name; - } - - return "Conscript"; -} - -const char* -Player::RankAbrv(int rank) -{ - ListIter iter = rank_table; - while (++iter) { - AwardInfo* award = iter.value(); - if (award->id == rank) - return award->abrv; - } - - return ""; -} - -Bitmap* -Player::RankInsignia(int rank, int size) -{ - ListIter iter = rank_table; - while (++iter) { - AwardInfo* award = iter.value(); - if (award->id == rank) { - if (size == 0) - return award->small_insignia; - - if (size == 1) - return award->large_insignia; - } - } - - return 0; -} - -const char* -Player::RankDescription(int rank) -{ - ListIter iter = rank_table; - while (++iter) { - AwardInfo* award = iter.value(); - if (award->id == rank) - return award->desc; - } - - return ""; -} - -int -Player::RankFromName(const char* name) -{ - ListIter iter = rank_table; - while (++iter) { - AwardInfo* award = iter.value(); - if (award->name == name) - return award->id; - } - - return 0; -} - -int -Player::Rank() const -{ - for (int i = rank_table.size()-1; i >= 0; i--) { - AwardInfo* award = rank_table[i]; - if (points >= award->total_points) - return award->id; - } - - return 0; -} - -void -Player::SetRank(int r) -{ - ListIter iter = rank_table; - while (++iter) { - AwardInfo* award = iter.value(); - if (r == award->id) - points = award->total_points; - } -} - -int -Player::Medal(int n) const -{ - if (n < 0) - return 0; - - for (int i = 0; i < 16; i++) { - int selector = 1 << (15-i); - - // found a medal: - if (medals & selector) { - - // and it's the nth medal! - if (n == 0) { - return selector; - } - - n--; - } - } - - return 0; -} - -// +-------------------------------------------------------------------+ - -const char* -Player::MedalName(int medal) -{ - ListIter iter = medal_table; - while (++iter) { - AwardInfo* award = iter.value(); - if (award->id == medal) - return award->name; - } - - return ""; -} - -Bitmap* -Player::MedalInsignia(int medal, int size) -{ - ListIter iter = medal_table; - while (++iter) { - AwardInfo* award = iter.value(); - if (award->id == medal) { - if (size == 0) - return award->small_insignia; - - if (size == 1) - return award->large_insignia; - } - } - - return 0; -} - -const char* -Player::MedalDescription(int medal) -{ - ListIter iter = medal_table; - while (++iter) { - AwardInfo* award = iter.value(); - if (award->id == medal) - return award->desc; - } - - return ""; -} - -// +-------------------------------------------------------------------+ - -bool -Player::CanCommand(int ship_class) -{ - if (ship_class <= Ship::ATTACK) - return true; - - for (int i = rank_table.size()-1; i >= 0; i--) { - AwardInfo* award = rank_table[i]; - if (points > award->total_points) { - return (ship_class & award->granted_ship_classes) != 0; - } - } - - return false; -} - -int -Player::CommandRankRequired(int ship_class) -{ - for (int i = 0; i < rank_table.size(); i++) { - AwardInfo* award = rank_table[i]; - if ((ship_class & award->granted_ship_classes) != 0) { - return i; - } - } - - return rank_table.size()-1; -} - -// +-------------------------------------------------------------------+ - -int -Player::GetMissionPoints(ShipStats* s, DWORD start_time) -{ - int result = 0; - - if (s) { - result = s->GetPoints(); - - int flight_time = (Clock::GetInstance()->GameTime() - start_time) / 1000; - - // if player survived mission, award one experience point - // for each minute of action, in ten point blocks: - if (!s->GetDeaths() && !s->GetColls()) { - int minutes = flight_time / 60; - minutes /= 10; - minutes *= 10; - result += minutes; - - if (s->HasEvent(SimEvent::DOCK)) - result += 100; - } - else { - result -= (int) (2.5 * Ship::Value(s->GetShipClass())); - } - - if (result < 0) - result = 0; - } - - return result; -} - -// +-------------------------------------------------------------------+ - -void -Player::ProcessStats(ShipStats* s, DWORD start_time) -{ - if (!s) return; - - int old_rank = Rank(); - int pts = GetMissionPoints(s, start_time); - - AddPoints(pts); - AddPoints(s->GetCommandPoints()); - AddKills(s->GetGunKills()); - AddKills(s->GetMissileKills()); - AddLosses(s->GetDeaths()); - AddLosses(s->GetColls()); - AddMissions(1); - AddFlightTime((Clock::GetInstance()->GameTime() - start_time) / 1000); - - int rank = Rank(); - - // did the player earn a promotion? - if (old_rank != rank) { - ListIter iter = rank_table; - while (++iter) { - AwardInfo* a = iter.value(); - if (rank == a->id) { - award = a; - } - } - } - - // if not, did the player earn a medal? - else { - ListIter iter = medal_table; - while (++iter) { - AwardInfo* a = iter.value(); - - if (EarnedAward(a, s) && a->ceremony) { - award = a; - break; - } - } - } - - // persist all stats, promotions, and medals: - Save(); -} - -bool -Player::EarnedAward(AwardInfo* a, ShipStats* s) -{ - if (!a || !s) - return false; - - // already earned this medal? - if (a->id & medals) - return false; - - // eligible for this medal? - int rank = Rank(); - if (a->min_rank > rank || a->max_rank < rank) - return false; - - if ((a->required_awards & medals) < a->required_awards) - return false; - - if (a->min_ship_class > s->GetShipClass() || a->max_ship_class < s->GetShipClass()) - return false; - - if (a->total_points > points) - return false; - - if (a->total_missions > missions) - return false; - - if (a->campaign_id && a->campaign_complete) { - if (!HasCompletedCampaign(a->campaign_id)) - return false; - } - - else { - // campaign related requirements - Campaign* c = Campaign::GetCampaign(); - - if (c) { - if (a->dynamic_campaign && !c->IsDynamic()) - return false; - } - } - - // sufficient merit for this medal? - if (a->mission_points > s->GetPoints()) - return false; - - if (a->kills > s->GetGunKills() + s->GetMissileKills()) - return false; - - if (a->mission_points > s->GetPoints()) - return false; - - // player must survive mission if lost = -1 - if (a->lost < 0 && (s->GetDeaths() || s->GetColls())) - return false; - - // do we need to be wounded in battle? - if (a->lost > s->GetDeaths() || a->collision > s->GetColls()) - return false; - - // final lottery check: - if (a->lottery < 2 || RandomChance(1, a->lottery)) { - medals |= a->id; - return true; - } - - // what do we have for the losers, judge? - return false; -} - -// +-------------------------------------------------------------------+ - -static List player_roster; -static Player* current_player = 0; - -List& -Player::GetRoster() -{ - return player_roster; -} - -Player* -Player::GetCurrentPlayer() -{ - return current_player; -} - -void -Player::SelectPlayer(Player* p) -{ - HUDView* hud = HUDView::GetInstance(); - - if (current_player && current_player != p) { - if (hud) { - for (int i = 0; i < 3; i++) { - MFD* mfd = hud->GetMFD(i); - - if (mfd) - current_player->mfd[i] = mfd->GetMode(); - } - } - } - - if (player_roster.contains(p)) { - current_player = p; - - Ship::SetFlightModel(p->flight_model); - Ship::SetLandingModel(p->landing_model); - HUDView::SetArcade(p->hud_mode > 0); - HUDView::SetDefaultColorSet(p->hud_color); - - if (hud) { - for (int i = 0; i < 3; i++) { - if (p->mfd[i] >= 0) { - MFD* mfd = hud->GetMFD(i); - - if (mfd) - mfd->SetMode(p->mfd[i]); - } - } - } - } -} - -Player* -Player::Find(const char* name) -{ - for (int i = 0; i < player_roster.size(); i++) { - Player* p = player_roster.at(i); - if (p->Name() == name) - return p; - } - - return 0; -} - -Player* -Player::Create(const char* name) -{ - if (name && *name) { - // check for existence: - if (Find(name)) - return 0; - - Player* newbie = new Player(name); - newbie->SetCreateDate(NetLayer::GetUTC()); - - player_roster.append(newbie); - newbie->CreateUniqueID(); - return newbie; - } - - return 0; -} - -void -Player::Destroy(Player* p) -{ - if (p) { - player_roster.remove(p); - - if (p == current_player) { - current_player = 0; - - if (player_roster.size()) - current_player = player_roster.at(0); - } - - CampaignSaveGame::RemovePlayer(p); - delete p; - } -} - -// +-------------------------------------------------------------------+ - -void -Player::Initialize() -{ - LoadAwardTables(); - Load(); - - if (!current_player) { - if (!player_roster.size()) { - Create("Pilot"); - } - - SelectPlayer(player_roster.at(0)); - } -} - -void -Player::Close() -{ - if (current_player && !player_roster.contains(current_player)) - delete current_player; - - player_roster.destroy(); - current_player = 0; - - rank_table.destroy(); - medal_table.destroy(); -} - -// +-------------------------------------------------------------------+ - -bool -Player::ConfigExists() -{ - return config_exists; -} - -// +-------------------------------------------------------------------+ - -#define GET_DEF_BOOL(x) if(pdef->name()->value()==(#x))GetDefBool(player->x,pdef,filename) -#define GET_DEF_TEXT(x) if(pdef->name()->value()==(#x))GetDefText(player->x,pdef,filename) -#define GET_DEF_NUM(x) if(pdef->name()->value()==(#x))GetDefNumber(player->x,pdef,filename) - -void -Player::Load() -{ - config_exists = false; - - // read the config file: - BYTE* block = 0; - int blocklen = 0; - - char filename[64]; - strcpy_s(filename, "player.cfg"); - - FILE* f; - ::fopen_s(&f, filename, "rb"); - - if (f) { - config_exists = true; - - ::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); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "PLAYER_CONFIG") { - Print("WARNING: invalid '%s' file. Using defaults\n", filename); - return; - } - } - - if (current_player && !player_roster.contains(current_player)) - delete current_player; - player_roster.destroy(); - current_player = 0; - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "player") { - - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: player structure missing in '%s'\n", filename); - } - else { - Player* player = new Player; - bool current = false; - TermStruct* val = def->term()->isStruct(); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - GET_DEF_TEXT(name); - else GET_DEF_TEXT(squadron); - else GET_DEF_TEXT(signature); - - else GET_DEF_NUM(uid); - else GET_DEF_NUM(flight_model); - else GET_DEF_NUM(flying_start); - else GET_DEF_NUM(landing_model); - else GET_DEF_NUM(ai_level); - else GET_DEF_NUM(hud_mode); - else GET_DEF_NUM(hud_color); - else GET_DEF_NUM(ff_level); - else GET_DEF_NUM(grid); - else GET_DEF_NUM(gunsight); - - else if (pdef->name()->value() == ("chat_0")) - GetDefText(player->chat_macros[0], pdef, filename); - - else if (pdef->name()->value() == ("chat_1")) - GetDefText(player->chat_macros[1], pdef, filename); - - else if (pdef->name()->value() == ("chat_2")) - GetDefText(player->chat_macros[2], pdef, filename); - - else if (pdef->name()->value() == ("chat_3")) - GetDefText(player->chat_macros[3], pdef, filename); - - else if (pdef->name()->value() == ("chat_4")) - GetDefText(player->chat_macros[4], pdef, filename); - - else if (pdef->name()->value() == ("chat_5")) - GetDefText(player->chat_macros[5], pdef, filename); - - else if (pdef->name()->value() == ("chat_6")) - GetDefText(player->chat_macros[6], pdef, filename); - - else if (pdef->name()->value() == ("chat_7")) - GetDefText(player->chat_macros[7], pdef, filename); - - else if (pdef->name()->value() == ("chat_8")) - GetDefText(player->chat_macros[8], pdef, filename); - - else if (pdef->name()->value() == ("chat_9")) - GetDefText(player->chat_macros[9], pdef, filename); - - else if (pdef->name()->value() == ("mfd0")) - GetDefNumber(player->mfd[0], pdef, filename); - - else if (pdef->name()->value() == ("mfd1")) - GetDefNumber(player->mfd[1], pdef, filename); - - else if (pdef->name()->value() == ("mfd2")) - GetDefNumber(player->mfd[2], pdef, filename); - - else if (pdef->name()->value() == ("current")) - GetDefBool(current, pdef, filename); - - else if (pdef->name()->value() == ("trained")) - GetDefNumber(player->trained, pdef, filename); - - else if (pdef->name()->value() == ("stats")) { - Text stats; - GetDefText(stats, pdef, filename); - player->DecodeStats(stats); - } - - else if (pdef->name()->value().indexOf("XXX_CHEAT_A1B2C3_") == 0) { - if (pdef->name()->value().contains("points")) - GetDefNumber(player->points, pdef, filename); - - else if (pdef->name()->value().contains("rank")) { - int rank=0; - GetDefNumber(rank, pdef, filename); - player->SetRank(rank); - } - - else if (pdef->name()->value().contains("medals")) - GetDefNumber(player->medals, pdef, filename); - - else if (pdef->name()->value().contains("campaigns")) - GetDefNumber(player->campaigns, pdef, filename); - - else if (pdef->name()->value().contains("missions")) - GetDefNumber(player->missions, pdef, filename); - - else if (pdef->name()->value().contains("kills")) - GetDefNumber(player->kills, pdef, filename); - - else if (pdef->name()->value().contains("losses")) - GetDefNumber(player->losses, pdef, filename); - - else if (pdef->name()->value().contains("flight_time")) - GetDefNumber(player->flight_time, pdef, filename); - } - } - } - - player_roster.append(player); - player->CreateUniqueID(); - - if (current) - SelectPlayer(player); - } - - } - else { - Print("WARNING: unknown label '%s' in '%s'\n", - def->name()->value().data(), filename); - } - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - } - } - } - while (term); - - delete [] block; -} - -// +-------------------------------------------------------------------+ - -void -Player::Save() -{ - HUDView* hud = HUDView::GetInstance(); - if (hud && current_player) { - for (int i = 0; i < 3; i++) { - MFD* mfd = hud->GetMFD(i); - - if (mfd) - current_player->mfd[i] = mfd->GetMode(); - } - } - - FILE* f; - fopen_s(&f, "player.cfg", "wb"); - if (f) { - fprintf(f, "PLAYER_CONFIG\n\n"); - - ListIter iter = player_roster; - while (++iter) { - Player* p = iter.value(); - - fprintf(f, "player: {\n"); - fprintf(f, " uid: %d,\n", p->uid); - fprintf(f, " name: \"%s\",\n", SafeQuotes(p->name.data())); - fprintf(f, " squadron: \"%s\",\n", SafeQuotes(p->squadron.data())); - fprintf(f, " signature: \"%s\",\n", SafeQuotes(p->signature.data())); - - Text stat_data = p->EncodeStats(); - - if (stat_data.length() > 32) { - char tmp[64]; - int len = stat_data.length(); - - for (int n = 0; n < len; n += 32) { - ZeroMemory(tmp, sizeof(tmp)); - const char* p = stat_data.data() + n; - strncpy(tmp, p, 32); - - if (n == 0) - fprintf(f, " stats: \"%s\"\n", tmp); - else if (n < len-32) - fprintf(f, " \"%s\"\n", tmp); - else - fprintf(f, " \"%s\",\n", tmp); - } - } - - if (p == current_player) - fprintf(f, " current: true,\n"); - else - fprintf(f, " current: false,\n"); - - fprintf(f, " trained: %d,\n", p->trained); - fprintf(f, " flight_model: %d,\n", p->flight_model); - fprintf(f, " flying_start: %d,\n", p->flying_start); - fprintf(f, " landing_model: %d,\n", p->landing_model); - fprintf(f, " ai_level: %d,\n", p->ai_level); - fprintf(f, " hud_mode: %d,\n", p->hud_mode); - fprintf(f, " hud_color: %d,\n", p->hud_color); - fprintf(f, " ff_level: %d,\n", p->ff_level); - fprintf(f, " grid: %d,\n", p->grid); - fprintf(f, " gunsight: %d,\n", p->gunsight); - - for (int i = 0; i < 10; i++) { - fprintf(f, " chat_%d: \"%s\",\n", i, SafeQuotes(p->chat_macros[i].data())); - } - - for (int i = 0; i < 3; i++) { - if (p->mfd[i] >= 0) { - fprintf(f, " mfd%d: %d,\n", i, p->mfd[i]); - } - } - - fprintf(f, "}\n\n"); - } - - fclose(f); - - config_exists = true; - } -} - -// +-------------------------------------------------------------------+ - -static char stat_buf[280]; -static char code_buf[280]; - -Text -Player::EncodeStats() -{ - ZeroMemory(stat_buf, 280); - ZeroMemory(code_buf, 280); - - sprintf_s(stat_buf, "%-16s%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x", - pass.data(), - create_date, - points, - flight_time, - missions, - kills, - losses, - medals, - campaigns, - 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32); - - for (int i = 0; i < 16; i++) - for (int j = 0; j < 16; j++) - code_buf[i*16 + j] = stat_buf[j*16 + i]; - - return Encryption::Encode(Encryption::Encrypt(code_buf)); -} - -void -Player::DecodeStats(const char* stats) -{ - ZeroMemory(stat_buf, 280); - ZeroMemory(code_buf, 280); - - if (!stats || !*stats) { - Print("Player::DecodeStats() invalid or missing stats\n"); - create_date = NetLayer::GetUTC(); - return; - } - - Text plain = Encryption::Decrypt(Encryption::Decode(stats)); - - if (plain.length() == 64) { - for (int i = 0; i < 8; i++) - for (int j = 0; j < 8; j++) - stat_buf[j*8 + i] = plain[i*8 +j]; - } - - else if (plain.length() == 256) { - for (int i = 0; i < 16; i++) - for (int j = 0; j < 16; j++) - stat_buf[j*16 + i] = plain[i*16 +j]; - } - - else { - Print("Player::DecodeStats() invalid plain text length %d\n", plain.length()); - create_date = NetLayer::GetUTC(); - return; - } - - char work[32]; - ZeroMemory(work, 32); - CopyMemory(work, stat_buf, 16); - for (int i = 15; i > 0; i--) - if (work[i] == ' ') work[i] = 0; - else break; - pass = work; - - ZeroMemory(work, 16); - CopyMemory(work, stat_buf+16, 8); - sscanf_s(work, "%x", &create_date); - - ZeroMemory(work, 16); - CopyMemory(work, stat_buf+24, 8); - sscanf_s(work, "%x", &points); - if (points < 0) points = 0; - - ZeroMemory(work, 16); - CopyMemory(work, stat_buf+32, 8); - sscanf_s(work, "%x", &flight_time); - if (flight_time < 0) flight_time = 0; - - ZeroMemory(work, 16); - CopyMemory(work, stat_buf+40, 8); - sscanf_s(work, "%x", &missions); - if (missions < 0) missions = 0; - - ZeroMemory(work, 16); - CopyMemory(work, stat_buf+48, 8); - sscanf_s(work, "%x", &kills); - if (kills < 0) kills = 0; - - ZeroMemory(work, 16); - CopyMemory(work, stat_buf+56, 8); - sscanf_s(work, "%x", &losses); - if (losses < 0) losses = 0; - - if (plain.length() > 64) { - ZeroMemory(work, 16); - CopyMemory(work, stat_buf+64, 8); - sscanf_s(work, "%x", &medals); - - ZeroMemory(work, 16); - CopyMemory(work, stat_buf+72, 8); - sscanf_s(work, "%x", &campaigns); - } - - if (create_date == 0) { - ::Print("WARNING - loaded player with zero stats '%s'\n", name.data()); - create_date = NetLayer::GetUTC(); - } -} - -// +-------------------------------------------------------------------+ - -void -Player::LoadAwardTables() -{ - DataLoader* loader = DataLoader::GetLoader(); - - if (!loader) return; - - BYTE* block = 0; - const char* filename = "awards.def"; - - loader->SetDataPath("Awards/"); - loader->LoadBuffer(filename, block, true); - Parser parser(new BlockReader((const char*) block)); - - Term* term = parser.ParseTerm(); - - if (!term) { - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "AWARDS") { - return; - } - } - - rank_table.destroy(); - medal_table.destroy(); - - ::Print("Loading Ranks and Medals\n"); - - do { - delete term; term = 0; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "award") { - - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: award structure missing in '%s'\n", filename); - } - else { - AwardInfo* award = new AwardInfo; - TermStruct* val = def->term()->isStruct(); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == ("name")) { - GetDefText(award->name, pdef, filename); - award->name = ContentBundle::GetInstance()->GetText(award->name); - } - - else if (pdef->name()->value() == ("abrv")) { - GetDefText(award->abrv, pdef, filename); - award->abrv = ContentBundle::GetInstance()->GetText(award->abrv); - } - - else if (pdef->name()->value() == ("desc")) { - GetDefText(award->desc, pdef, filename); - if (award->desc.length() <= 40) - award->desc = ContentBundle::GetInstance()->GetText(award->desc); - } - - else if (pdef->name()->value() == ("award")) { - GetDefText(award->grant, pdef, filename); - if (award->grant.length() <= 40) - award->grant = ContentBundle::GetInstance()->GetText(award->grant); - } - - else if (pdef->name()->value() == ("desc_sound")) - GetDefText(award->desc_sound, pdef, filename); - - else if (pdef->name()->value() == ("award_sound")) - GetDefText(award->grant_sound, pdef, filename); - - else if (pdef->name()->value().indexOf("large") == 0) { - Text txt; - GetDefText(txt, pdef, filename); - txt.setSensitive(false); - - if (!txt.contains(".pcx")) - txt.append(".pcx"); - - loader->CacheBitmap(txt, award->large_insignia); - } - - else if (pdef->name()->value().indexOf("small") == 0) { - Text txt; - GetDefText(txt, pdef, filename); - txt.setSensitive(false); - - if (!txt.contains(".pcx")) - txt.append(".pcx"); - - loader->CacheBitmap(txt, award->small_insignia); - - if (award->small_insignia) - award->small_insignia->AutoMask(); - } - - else if (pdef->name()->value() == ("type")) { - Text txt; - GetDefText(txt, pdef, filename); - txt.setSensitive(false); - - if (txt == "rank") - award->type = AwardInfo::RANK; - - else if (txt == "medal") - award->type = AwardInfo::MEDAL; - } - - else if (pdef->name()->value() == ("id")) - GetDefNumber(award->id, pdef, filename); - - else if (pdef->name()->value() == ("total_points")) - GetDefNumber(award->total_points, pdef, filename); - - else if (pdef->name()->value() == ("mission_points")) - GetDefNumber(award->mission_points, pdef, filename); - - else if (pdef->name()->value() == ("total_missions")) - GetDefNumber(award->total_missions, pdef, filename); - - else if (pdef->name()->value() == ("kills")) - GetDefNumber(award->kills, pdef, filename); - - else if (pdef->name()->value() == ("lost")) - GetDefNumber(award->lost, pdef, filename); - - else if (pdef->name()->value() == ("collision")) - GetDefNumber(award->collision, pdef, filename); - - else if (pdef->name()->value() == ("campaign_id")) - GetDefNumber(award->campaign_id, pdef, filename); - - else if (pdef->name()->value() == ("campaign_complete")) - GetDefBool(award->campaign_complete, pdef, filename); - - else if (pdef->name()->value() == ("dynamic_campaign")) - GetDefBool(award->dynamic_campaign, pdef, filename); - - else if (pdef->name()->value() == ("ceremony")) - GetDefBool(award->ceremony, pdef, filename); - - else if (pdef->name()->value() == ("required_awards")) - GetDefNumber(award->required_awards, pdef, filename); - - else if (pdef->name()->value() == ("lottery")) - GetDefNumber(award->lottery, pdef, filename); - - else if (pdef->name()->value() == ("min_rank")) - GetDefNumber(award->min_rank, pdef, filename); - - else if (pdef->name()->value() == ("max_rank")) - GetDefNumber(award->max_rank, pdef, filename); - - else if (pdef->name()->value() == ("min_ship_class")) { - Text classname; - GetDefText(classname, pdef, filename); - award->min_ship_class = Ship::ClassForName(classname); - } - - else if (pdef->name()->value() == ("max_ship_class")) { - Text classname; - GetDefText(classname, pdef, filename); - award->max_ship_class = Ship::ClassForName(classname); - } - - else if (pdef->name()->value().indexOf("grant") == 0) - GetDefNumber(award->granted_ship_classes, pdef, filename); - } - } - - if (award->type == AwardInfo::RANK) { - rank_table.append(award); - } - - else if (award->type == AwardInfo::MEDAL) { - medal_table.append(award); - } - - else { - delete award; - } - } - } - else { - Print("WARNING: unknown label '%s' in '%s'\n", - def->name()->value().data(), filename); - } - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - } - } - } - while (term); - - loader->ReleaseBuffer(block); - loader->SetDataPath(0); -} - -// +-------------------------------------------------------------------+ - -void -Player::CreateUniqueID() -{ - ListIter iter = player_roster; - while (++iter) { - Player* p = iter.value(); - - if (p != this && p->uid >= uid) - uid = p->uid + 1; - } - - if (uid < 1) - uid = 1; -} diff --git a/Stars45/Player.h b/Stars45/Player.h deleted file mode 100644 index 91f5025..0000000 --- a/Stars45/Player.h +++ /dev/null @@ -1,186 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Player / Logbook class -*/ - - -#ifndef Player_h -#define Player_h - -#include "Types.h" -#include "List.h" -#include "Text.h" - -// +-------------------------------------------------------------------+ - -class Player; -class Bitmap; -class ShipStats; -class AwardInfo; -class Sound; - -// +-------------------------------------------------------------------+ - -class Player -{ -public: - static const char* TYPENAME() { return "Player"; } - - Player(const char* name); - virtual ~Player(); - - int operator == (const Player& u) const { return name == u.name; } - - int Identity() const { return uid; } - const Text& Name() const { return name; } - const Text& Password() const { return pass; } - const Text& Squadron() const { return squadron; } - const Text& Signature() const { return signature; } - const Text& ChatMacro(int n) const; - int CreateDate() const { return create_date; } - int Rank() const; - int Medal(int n) const; - int Points() const { return points; } - int Medals() const { return medals; } - int FlightTime() const { return flight_time; } - int Missions() const { return missions; } - int Kills() const { return kills; } - int Losses() const { return losses; } - int Campaigns() const { return campaigns; } - int Trained() const { return trained; } - - int FlightModel() const { return flight_model; } - int FlyingStart() const { return flying_start; } - int LandingModel() const { return landing_model; } - int AILevel() const { return ai_level; } - int HUDMode() const { return hud_mode; } - int HUDColor() const { return hud_color; } - int FriendlyFire() const { return ff_level; } - int GridMode() const { return grid; } - int Gunsight() const { return gunsight; } - - bool ShowAward() const { return award != 0; } - Text AwardName() const; - Text AwardDesc() const; - Bitmap* AwardImage() const; - Sound* AwardSound() const; - - bool CanCommand(int ship_class); - - void SetName(const char* n); - void SetPassword(const char* p); - void SetSquadron(const char* s); - void SetSignature(const char* s); - void SetChatMacro(int n, const char* m); - void SetCreateDate(int d); - void SetRank(int r); - void SetPoints(int p); - void SetMedals(int m); - void SetCampaigns(int n); - void SetTrained(int n); - void SetFlightTime(int t); - void SetMissions(int m); - void SetKills(int k); - void SetLosses(int l); - - void AddFlightTime(int t); - void AddPoints(int p); - void AddMedal(int m); - void AddMissions(int m); - void AddKills(int k); - void AddLosses(int l); - - bool HasTrained(int n) const; - bool HasCompletedCampaign(int id) const; - void SetCampaignComplete(int id); - - void SetFlightModel(int n); - void SetFlyingStart(int n); - void SetLandingModel(int n); - void SetAILevel(int n); - void SetHUDMode(int n); - void SetHUDColor(int n); - void SetFriendlyFire(int n); - void SetGridMode(int n); - void SetGunsight(int n); - - void ClearShowAward(); - - Text EncodeStats(); - void DecodeStats(const char* stats); - - int GetMissionPoints(ShipStats* stats, DWORD start_time); - void ProcessStats(ShipStats* stats, DWORD start_time); - bool EarnedAward(AwardInfo* a, ShipStats* s); - - static const char* RankName(int rank); - static const char* RankAbrv(int rank); - static int RankFromName(const char* name); - static Bitmap* RankInsignia(int rank, int size); - static const char* RankDescription(int rank); - static const char* MedalName(int medal); - static Bitmap* MedalInsignia(int medal, int size); - static const char* MedalDescription(int medal); - static int CommandRankRequired(int ship_class); - - static List& GetRoster(); - static Player* GetCurrentPlayer(); - static void SelectPlayer(Player* p); - static Player* Create(const char* name); - static void Destroy(Player* p); - static Player* Find(const char* name); - static void Initialize(); - static void Close(); - static void Load(); - static void Save(); - static bool ConfigExists(); - static void LoadAwardTables(); - -protected: - Player(); - - void CreateUniqueID(); - - int uid; - Text name; - Text pass; - Text squadron; - Text signature; - Text chat_macros[10]; - int mfd[4]; - - // stats: - int create_date; - int points; - int medals; // bitmap of earned medals - int flight_time; - int missions; - int kills; - int losses; - int campaigns; // bitmap of completed campaigns - int trained; // id of highest training mission completed - - // gameplay options: - int flight_model; - int flying_start; - int landing_model; - int ai_level; - int hud_mode; - int hud_color; - int ff_level; - int grid; - int gunsight; - - // transient: - AwardInfo* award; -}; - -#endif // Player_h \ No newline at end of file diff --git a/Stars45/PlayerDlg.cpp b/Stars45/PlayerDlg.cpp deleted file mode 100644 index e69a515..0000000 --- a/Stars45/PlayerDlg.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "PlayerDlg.h" -#include "AwardShowDlg.h" -#include "ConfirmDlg.h" -#include "MenuScreen.h" -#include "Player.h" - -#include "FormatUtil.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "EditBox.h" -#include "ImageBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "MachineInfo.h" -#include "WndProc.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(PlayerDlg, OnApply); -DEF_MAP_CLIENT(PlayerDlg, OnCancel); -DEF_MAP_CLIENT(PlayerDlg, OnSelectPlayer); -DEF_MAP_CLIENT(PlayerDlg, OnAdd); -DEF_MAP_CLIENT(PlayerDlg, OnDel); -DEF_MAP_CLIENT(PlayerDlg, OnDelConfirm); -DEF_MAP_CLIENT(PlayerDlg, OnRank); -DEF_MAP_CLIENT(PlayerDlg, OnMedal); - -// +--------------------------------------------------------------------+ - -PlayerDlg::PlayerDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -lst_roster(0), btn_add(0), btn_del(0), -txt_name(0), txt_password(0), txt_squadron(0), txt_signature(0), -img_rank(0) -{ - Init(def); -} - -PlayerDlg::~PlayerDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -PlayerDlg::RegisterControls() -{ - lst_roster = (ListBox*) FindControl(200); - btn_add = (Button*) FindControl(101); - btn_del = (Button*) FindControl(102); - txt_name = (EditBox*) FindControl(201); - txt_password = (EditBox*) FindControl(202); - txt_squadron = (EditBox*) FindControl(203); - txt_signature = (EditBox*) FindControl(204); - - lbl_createdate = FindControl(205); - lbl_rank = FindControl(206); - lbl_flighttime = FindControl(207); - lbl_missions = FindControl(208); - lbl_kills = FindControl(209); - lbl_losses = FindControl(210); - lbl_points = FindControl(211); - - img_rank = (ImageBox*) FindControl(220); - REGISTER_CLIENT(EID_CLICK, img_rank, PlayerDlg, OnRank); - - for (int i = 0; i < 15; i++) { - medals[i] = -1; - img_medals[i] = (ImageBox*) FindControl(230 + i); - if (img_medals[i]) - REGISTER_CLIENT(EID_CLICK, img_medals[i], PlayerDlg, OnMedal); - } - - for (int i = 0; i < 10; i++) { - txt_chat[i] = (EditBox*) FindControl(300 + i); - } - - REGISTER_CLIENT(EID_SELECT, lst_roster, PlayerDlg, OnSelectPlayer); - REGISTER_CLIENT(EID_CLICK, btn_add, PlayerDlg, OnAdd); - REGISTER_CLIENT(EID_CLICK, btn_del, PlayerDlg, OnDel); - REGISTER_CLIENT(EID_USER_1, btn_del, PlayerDlg, OnDelConfirm); - - apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, apply, PlayerDlg, OnApply); - - cancel = (Button*) FindControl(2); - REGISTER_CLIENT(EID_CLICK, cancel, PlayerDlg, OnCancel); -} - -// +--------------------------------------------------------------------+ - -void -PlayerDlg::Show() -{ - FormWindow::Show(); - - if (!lst_roster) return; - lst_roster->ClearItems(); - lst_roster->SetSelectedStyle(ListBox::LIST_ITEM_STYLE_FILLED_BOX); - lst_roster->SetLeading(2); - - int current_index = 0; - - List& roster = Player::GetRoster(); - for (int i = 0; i < roster.size(); i++) { - Player* p = roster[i]; - lst_roster->AddItem(p->Name()); - if (p == Player::GetCurrentPlayer()) - current_index = i; - } - - lst_roster->SetSelected(current_index); - ShowPlayer(); - - apply->SetEnabled(roster.size() > 0); -} - -// +--------------------------------------------------------------------+ - -void -PlayerDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnApply(0); - } -} - -// +--------------------------------------------------------------------+ - -void -PlayerDlg::ShowPlayer() -{ - Player* p = Player::GetCurrentPlayer(); - - if (p) { - if (txt_name) txt_name->SetText(p->Name()); - if (txt_password) txt_password->SetText(p->Password()); - if (txt_squadron) txt_squadron->SetText(p->Squadron()); - if (txt_signature) txt_signature->SetText(p->Signature()); - - char flight_time[64], missions[16], kills[16], losses[16], points[16]; - FormatTime(flight_time, p->FlightTime()); - sprintf_s(missions, "%d", p->Missions()); - sprintf_s(kills, "%d", p->Kills()); - sprintf_s(losses, "%d", p->Losses()); - sprintf_s(points, "%d", p->Points()); - - if (lbl_createdate) lbl_createdate->SetText(FormatTimeString(p->CreateDate())); - if (lbl_rank) lbl_rank->SetText(Player::RankName(p->Rank())); - if (lbl_flighttime) lbl_flighttime->SetText(flight_time); - if (lbl_missions) lbl_missions->SetText(missions); - if (lbl_kills) lbl_kills->SetText(kills); - if (lbl_losses) lbl_losses->SetText(losses); - if (lbl_points) lbl_points->SetText(points); - - if (img_rank) { - img_rank->SetPicture(*Player::RankInsignia(p->Rank(), 0)); - img_rank->Show(); - } - - for (int i = 0; i < 15; i++) { - if (img_medals[i]) { - int medal = p->Medal(i); - if (medal) { - medals[i] = medal; - img_medals[i]->SetPicture(*Player::MedalInsignia(medal, 0)); - img_medals[i]->Show(); - } - else { - medals[i] = -1; - img_medals[i]->Hide(); - } - } - } - - for (int i = 0; i < 10; i++) { - if (txt_chat[i]) - txt_chat[i]->SetText(p->ChatMacro(i)); - } - } - else { - if (txt_name) txt_name->SetText(""); - if (txt_password) txt_password->SetText(""); - if (txt_squadron) txt_squadron->SetText(""); - if (txt_signature) txt_signature->SetText(""); - - if (lbl_createdate) lbl_createdate->SetText(""); - if (lbl_rank) lbl_rank->SetText(""); - if (lbl_flighttime) lbl_flighttime->SetText(""); - if (lbl_missions) lbl_missions->SetText(""); - if (lbl_kills) lbl_kills->SetText(""); - if (lbl_losses) lbl_losses->SetText(""); - if (lbl_points) lbl_points->SetText(""); - - if (img_rank) img_rank->Hide(); - - for (int i = 0; i < 15; i++) { - medals[i] = -1; - if (img_medals[i]) - img_medals[i]->Hide(); - } - - for (int i = 0; i < 10; i++) { - if (txt_chat[i]) - txt_chat[i]->SetText(""); - } - } -} - -// +--------------------------------------------------------------------+ - -void -PlayerDlg::UpdatePlayer() -{ - Player* p = Player::GetCurrentPlayer(); - - if (p) { - if (txt_name) p->SetName(txt_name->GetText()); - if (txt_password) p->SetPassword(txt_password->GetText()); - if (txt_squadron) p->SetSquadron(txt_squadron->GetText()); - if (txt_signature) p->SetSignature(txt_signature->GetText()); - - for (int i = 0; i < 10; i++) { - if (txt_chat[i]) - p->SetChatMacro(i, txt_chat[i]->GetText()); - } - } -} - -// +--------------------------------------------------------------------+ - -void -PlayerDlg::OnSelectPlayer(AWEvent* event) -{ - if (!lst_roster) return; - - UpdatePlayer(); - - int index = lst_roster->GetSelection(); - - List& roster = Player::GetRoster(); - if (index >= 0 && index < roster.size()) { - Player::SelectPlayer(roster.at(index)); - } - - ShowPlayer(); - - apply->SetEnabled(roster.size() > 0); -} - -void -PlayerDlg::OnAdd(AWEvent* event) -{ - Player::Create("Pilot"); - ShowPlayer(); - - if (!lst_roster) return; - lst_roster->ClearItems(); - - List& roster = Player::GetRoster(); - for (int i = 0; i < roster.size(); i++) { - Player* p = roster[i]; - lst_roster->AddItem(p->Name()); - lst_roster->SetSelected(i, (p == Player::GetCurrentPlayer())); - } - - apply->SetEnabled(roster.size() > 0); -} - -void -PlayerDlg::OnDel(AWEvent* event) -{ - if (!Player::GetCurrentPlayer()) - return; - - ConfirmDlg* confirm = manager->GetConfirmDlg(); - if (confirm) { - char msg[256]; - sprintf_s(msg, ContentBundle::GetInstance()->GetText("PlayerDlg.are-you-sure").data(), - Player::GetCurrentPlayer()->Name().data()); - confirm->SetMessage(msg); - confirm->SetTitle(ContentBundle::GetInstance()->GetText("PlayerDlg.confirm-delete")); - confirm->SetParentControl(btn_del); - - manager->ShowConfirmDlg(); - } - - else { - OnDelConfirm(event); - } -} - -void -PlayerDlg::OnDelConfirm(AWEvent* event) -{ - Player::Destroy(Player::GetCurrentPlayer()); - ShowPlayer(); - - if (!lst_roster) return; - lst_roster->ClearItems(); - - List& roster = Player::GetRoster(); - for (int i = 0; i < roster.size(); i++) { - Player* p = roster[i]; - lst_roster->AddItem(p->Name()); - lst_roster->SetSelected(i, (p == Player::GetCurrentPlayer())); - } - - apply->SetEnabled(roster.size() > 0); -} - -// +--------------------------------------------------------------------+ - -void -PlayerDlg::OnRank(AWEvent* event) -{ - Player* p = Player::GetCurrentPlayer(); - AwardShowDlg* award_dlg = manager->GetAwardDlg(); - - if (p && award_dlg) { - award_dlg->SetRank(p->Rank()); - manager->ShowAwardDlg(); - } -} - -void -PlayerDlg::OnMedal(AWEvent* event) -{ - Player* p = Player::GetCurrentPlayer(); - AwardShowDlg* award_dlg = manager->GetAwardDlg(); - - if (p && award_dlg) { - int m = -1, i; - - for (i = 0; i < 15; i++) { - if (event->window == img_medals[i]) { - m = i; - break; - } - } - - if (m >= 0) { - award_dlg->SetMedal(medals[i]); - manager->ShowAwardDlg(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -PlayerDlg::OnApply(AWEvent* event) -{ - Player* player = Player::GetCurrentPlayer(); - if (player) { - UpdatePlayer(); - Player::Save(); - } - - FlushKeys(); - manager->ShowMenuDlg(); -} - -void -PlayerDlg::OnCancel(AWEvent* event) -{ - Player::Load(); - FlushKeys(); - manager->ShowMenuDlg(); -} diff --git a/Stars45/PlayerDlg.h b/Stars45/PlayerDlg.h deleted file mode 100644 index eace5a4..0000000 --- a/Stars45/PlayerDlg.h +++ /dev/null @@ -1,85 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef PlayerDlg_h -#define PlayerDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class Player; - -// +--------------------------------------------------------------------+ - -class PlayerDlg : public FormWindow -{ -public: - PlayerDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~PlayerDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - virtual void OnSelectPlayer(AWEvent* event); - virtual void OnAdd(AWEvent* event); - virtual void OnDel(AWEvent* event); - virtual void OnDelConfirm(AWEvent* event); - virtual void OnRank(AWEvent* event); - virtual void OnMedal(AWEvent* event); - - virtual void UpdatePlayer(); - virtual void ShowPlayer(); - -protected: - MenuScreen* manager; - - ListBox* lst_roster; - Button* btn_add; - Button* btn_del; - - EditBox* txt_name; - EditBox* txt_password; - EditBox* txt_squadron; - EditBox* txt_signature; - - EditBox* txt_chat[10]; - - ActiveWindow* lbl_createdate; - ActiveWindow* lbl_rank; - ActiveWindow* lbl_flighttime; - ActiveWindow* lbl_missions; - ActiveWindow* lbl_kills; - ActiveWindow* lbl_losses; - ActiveWindow* lbl_points; - ImageBox* img_rank; - ImageBox* img_medals[15]; - int medals[15]; - - Button* apply; - Button* cancel; -}; - -#endif // PlayerDlg_h - diff --git a/Stars45/PngImage.cpp b/Stars45/PngImage.cpp deleted file mode 100644 index d8f1244..0000000 --- a/Stars45/PngImage.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - BMP image file loader -*/ - - -#include "PngImage.h" - -#include -#include -#include - -#include "Types.h" - -// Needed for compatibility with libpng 1.4++ -#define png_infopp_NULL (png_infopp)NULL -#define png_voidp_NULL (png_voidp)NULL -#define int_p_NULL (int*)NULL - -#include "png.h" - -// +--------------------------------------------------------------------+ - -PngImage::PngImage() -: width(0), height(0), bpp(0), alpha_loaded(false), image(0) -{ } - -PngImage::~PngImage() -{ - delete [] image; -} - -// +--------------------------------------------------------------------+ - -int PngImage::Load(char *filename) -{ - int status = PNG_INVALID; - FILE* f; - - fopen_s(&f, filename,"rb"); - if (f == NULL) - return PNG_NOFILE; - - BYTE buf[12]; - fread(buf, 8, 1, f); - fseek(f, 0, SEEK_SET); - - if (png_sig_cmp(buf, (png_size_t)0, 8)) - return PNG_INVALID; - - png_structp png_ptr; - png_infop info_ptr; - - /* Create and initialize the png_struct with the desired error handler - * functions. If you want to use the default stderr and longjump method, - * you can supply NULL for the last three parameters. We also supply the - * the compiler header file version, so that we know if the application - * was compiled with a compatible version of the library. REQUIRED - */ - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - - if (!png_ptr) { - return PNG_NOMEM; - } - - /* Allocate/initialize the memory for image information. REQUIRED. */ - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); - return PNG_NOMEM; - } - - png_init_io(png_ptr, f); - png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL); - - status = CreateImage(png_ptr, info_ptr); - - png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); - - fclose(f); - return status; -} - -// +--------------------------------------------------------------------+ - -struct PngIOStruct -{ - BYTE* fp; - BYTE* buffer; - DWORD length; -}; - -static void png_user_read_data(png_structp read_ptr, png_bytep data, png_size_t length) -{ - PngIOStruct* read_io_ptr = (PngIOStruct*) png_get_io_ptr(read_ptr); - - if (!read_io_ptr) - return; - - if (read_io_ptr->fp + length < read_io_ptr->buffer + read_io_ptr->length) { - memcpy(data, read_io_ptr->fp, length); - read_io_ptr->fp += length; - } -} - -static void png_user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ -} - -static void png_user_flush_data(png_structp png_ptr) -{ -} - -int PngImage::LoadBuffer(unsigned char* buf, int len) -{ - int status = PNG_INVALID; - PngIOStruct io; - - if (buf == NULL) - return PNG_NOFILE; - - if (png_sig_cmp(buf, (png_size_t)0, 8)) - return PNG_INVALID; - - io.buffer = buf; - io.fp = buf; - io.length = len; - - png_structp png_ptr; - png_infop info_ptr; - - /* Create and initialize the png_struct with the desired error handler - * functions. If you want to use the default stderr and longjump method, - * you can supply NULL for the last three parameters. We also supply the - * the compiler header file version, so that we know if the application - * was compiled with a compatible version of the library. REQUIRED - */ - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - - if (!png_ptr) { - return PNG_NOMEM; - } - - /* Allocate/initialize the memory for image information. REQUIRED. */ - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); - return PNG_NOMEM; - } - - png_set_read_fn(png_ptr, (void *) (&io), png_user_read_data); - png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL); - - status = CreateImage(png_ptr, info_ptr); - - png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); - - return status; -} - -// +--------------------------------------------------------------------+ - -int -PngImage::CreateImage(png_structp png_ptr, png_infop info_ptr) -{ - int status = PNG_INVALID; - - width = png_get_image_width(png_ptr, info_ptr); - height = png_get_image_height(png_ptr, info_ptr); - bpp = png_get_bit_depth(png_ptr, info_ptr); - - if (width > 0 && width < 32768 && height > 0 && height < 32768) { - // true-color: - if (bpp >= 24) { - status = PNG_OK; - - if ( png_get_channels(png_ptr, info_ptr) == 4) - alpha_loaded = true; - - image = new DWORD[width*height]; - BYTE** rows = png_get_rows(png_ptr, info_ptr); - - for (DWORD row = 0; row < height; row++) { - BYTE* p = rows[row]; - - for (DWORD col = 0; col < width; col++) { - DWORD red = *p++; - DWORD green = *p++; - DWORD blue = *p++; - DWORD alpha = 0xff; - - if ( png_get_channels(png_ptr, info_ptr) == 4) - alpha = *p++; - - image[row*width+col] = (alpha << 24) | (red << 16) | (green << 8) | blue; - } - } - } - - // paletted: - else if (bpp == 8) { - DWORD pal[256]; - - png_bytep trans_alpha; int num_trans; png_color_16p trans_color; - png_colorp palette; - int num_palette; - - png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color); - png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); - - if (num_trans > 0) - alpha_loaded = true; - - for (int i = 0; i < 256; i++) { - if (i < num_palette) { - DWORD red = palette[i].red; - DWORD green = palette[i].green; - DWORD blue = palette[i].blue; - DWORD alpha = 0xff; - - if (i < num_trans) - alpha = trans_alpha[i]; - - pal[i] = (alpha << 24) | (red << 16) | (green << 8) | blue; - } - - else { - pal[i] = 0; - } - } - - image = new DWORD[width*height]; - BYTE** rows = png_get_rows(png_ptr, info_ptr); - - for (DWORD row = 0; row < height; row++) { - BYTE* p = rows[row]; - - for (DWORD col = 0; col < width; col++) { - BYTE index = *p++; - image[row*width+col] = pal[index]; - } - } - } - } - - return status; -} \ No newline at end of file diff --git a/Stars45/PngImage.h b/Stars45/PngImage.h deleted file mode 100644 index f712461..0000000 --- a/Stars45/PngImage.h +++ /dev/null @@ -1,47 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - PNG image file loader -*/ - -#ifndef PngImage_h -#define PngImage_h - -#include "png.h" - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -enum { PNG_OK, PNG_NOMEM, PNG_INVALID, PNG_NOFILE }; - -// +--------------------------------------------------------------------+ - -struct PngImage -{ - static const char* TYPENAME() { return "PngImage"; } - - PngImage(); - ~PngImage(); - - int Load(char *filename); - int LoadBuffer(unsigned char* buf, int len); - int CreateImage(png_structp png_ptr, png_infop info_ptr); - - DWORD* image; - DWORD width; - DWORD height; - DWORD bpp; - bool alpha_loaded; -}; - -// +--------------------------------------------------------------------+ - -#endif // PngImage_h diff --git a/Stars45/Polygon.cpp b/Stars45/Polygon.cpp deleted file mode 100644 index d3e3b27..0000000 --- a/Stars45/Polygon.cpp +++ /dev/null @@ -1,738 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Polygon and VertexSet structures for 3D rendering -*/ - -#include "Polygon.h" -#include "Bitmap.h" - -// +--------------------------------------------------------------------+ - -VertexSet::VertexSet(int m) - : nverts(0), space(OBJECT_SPACE), tu1(0), tv1(0), tangent(0), binormal(0) -{ - Resize(m); -} - -// +--------------------------------------------------------------------+ - -VertexSet::~VertexSet() -{ - Delete(); -} - -// +--------------------------------------------------------------------+ - -void -VertexSet::Resize(int m, bool preserve) -{ - // easy cases (no data will be preserved): - if (!m || !nverts || !preserve) { - bool additional_tex_coords = (tu1 != 0); - - Delete(); - - nverts = m; - - if (nverts <= 0) { - ZeroMemory(this, sizeof(VertexSet)); - } - - else { - loc = new Vec3[nverts]; - nrm = new Vec3[nverts]; - s_loc = new Vec3[nverts]; - tu = new float[nverts]; - tv = new float[nverts]; - rw = new float[nverts]; - diffuse = new DWORD[nverts]; - specular = new DWORD[nverts]; - - if (additional_tex_coords) - CreateAdditionalTexCoords(); - - if (!loc || !nrm || !s_loc || !rw || !tu || !tv || !diffuse || !specular) { - nverts = 0; - - delete [] loc; - delete [] nrm; - delete [] s_loc; - delete [] rw; - delete [] tu; - delete [] tv; - delete [] tu1; - delete [] tv1; - delete [] diffuse; - delete [] specular; - - ZeroMemory(this, sizeof(VertexSet)); - } - } - } - - // actually need to copy data: - else { - int np = nverts; - - nverts = m; - - if (nverts < np) - np = nverts; - - Vec3* new_loc = new Vec3[nverts]; - Vec3* new_nrm = new Vec3[nverts]; - Vec3* new_s_loc = new Vec3[nverts]; - float* new_rw = new float[nverts]; - float* new_tu = new float[nverts]; - float* new_tv = new float[nverts]; - float* new_tu1 = 0; - float* new_tv1 = 0; - DWORD* new_diffuse = new DWORD[nverts]; - DWORD* new_specular = new DWORD[nverts]; - - if (tu1) - new_tu1 = new float[nverts]; - - if (tv1) - new_tv1 = new float[nverts]; - - if (new_loc) { - CopyMemory(new_loc, loc, np * sizeof(Vec3)); - delete [] loc; - loc = new_loc; - } - - if (new_nrm) { - CopyMemory(new_nrm, nrm, np * sizeof(Vec3)); - delete [] nrm; - nrm = new_nrm; - } - - if (new_s_loc) { - CopyMemory(new_s_loc, s_loc, np * sizeof(Vec3)); - delete [] s_loc; - s_loc = new_s_loc; - } - - if (new_tu) { - CopyMemory(new_tu, tu, np * sizeof(float)); - delete [] tu; - tu = new_tu; - } - - if (new_tv) { - CopyMemory(new_tv, tv, np * sizeof(float)); - delete [] tv; - tv = new_tv; - } - - if (new_tu1) { - CopyMemory(new_tu1, tu1, np * sizeof(float)); - delete [] tu1; - tu = new_tu1; - } - - if (new_tv1) { - CopyMemory(new_tv1, tv1, np * sizeof(float)); - delete [] tv1; - tv = new_tv1; - } - - if (new_diffuse) { - CopyMemory(new_diffuse, diffuse, np * sizeof(DWORD)); - delete [] diffuse; - diffuse = new_diffuse; - } - - if (new_specular) { - CopyMemory(new_specular, specular, np * sizeof(DWORD)); - delete [] specular; - specular = new_specular; - } - - if (!loc || !nrm || !s_loc || !rw || !tu || !tv || !diffuse || !specular) { - Delete(); - ZeroMemory(this, sizeof(VertexSet)); - } - } -} - -// +--------------------------------------------------------------------+ - -void -VertexSet::Delete() -{ - if (nverts) { - delete [] loc; - delete [] nrm; - delete [] s_loc; - delete [] rw; - delete [] tu; - delete [] tv; - delete [] tu1; - delete [] tv1; - delete [] diffuse; - delete [] specular; - delete [] tangent; - delete [] binormal; - - tangent = 0; - binormal = 0; - } -} - -// +--------------------------------------------------------------------+ - -void -VertexSet::Clear() -{ - if (nverts) { - ZeroMemory(loc, sizeof(Vec3) * nverts); - ZeroMemory(nrm, sizeof(Vec3) * nverts); - ZeroMemory(s_loc, sizeof(Vec3) * nverts); - ZeroMemory(tu, sizeof(float) * nverts); - ZeroMemory(tv, sizeof(float) * nverts); - ZeroMemory(rw, sizeof(float) * nverts); - ZeroMemory(diffuse, sizeof(DWORD) * nverts); - ZeroMemory(specular, sizeof(DWORD) * nverts); - - if (tu1) - ZeroMemory(tu1, sizeof(float) * nverts); - - if (tv1) - ZeroMemory(tv1, sizeof(float) * nverts); - - if (tangent) - ZeroMemory(tangent, sizeof(Vec3) * nverts); - - if (binormal) - ZeroMemory(binormal, sizeof(Vec3) * nverts); - } -} - -// +--------------------------------------------------------------------+ - -void -VertexSet::CreateTangents() -{ - if (tangent) delete [] tangent; - if (binormal) delete [] binormal; - - tangent = 0; - binormal = 0; - - if (nverts) { - tangent = new Vec3[nverts]; - binormal = new Vec3[nverts]; - } -} - -// +--------------------------------------------------------------------+ - -void -VertexSet::CreateAdditionalTexCoords() -{ - if (tu1) delete [] tu1; - if (tv1) delete [] tv1; - - tu1 = 0; - tv1 = 0; - - if (nverts) { - tu1 = new float[nverts]; - tv1 = new float[nverts]; - } -} - -// +--------------------------------------------------------------------+ - -bool -VertexSet::CopyVertex(int dst, int src) -{ - if (src >= 0 && src < nverts && dst >= 0 && dst < nverts) { - loc[dst] = loc[src]; - nrm[dst] = nrm[src]; - s_loc[dst] = s_loc[src]; - tu[dst] = tu[src]; - tv[dst] = tv[src]; - diffuse[dst] = diffuse[src]; - specular[dst] = specular[src]; - - if (tu1) - tu1[dst] = tu1[src]; - - if (tv1) - tv1[dst] = tv1[src]; - - if (tangent) - tangent[dst] = tangent[src]; - - if (binormal) - binormal[dst] = binormal[src]; - - return true; - } - - return false; -} - -VertexSet* -VertexSet::Clone() const -{ - VertexSet* result = new VertexSet(nverts); - - CopyMemory(result->loc, loc, nverts * sizeof(Vec3)); - CopyMemory(result->nrm, nrm, nverts * sizeof(Vec3)); - CopyMemory(result->s_loc, s_loc, nverts * sizeof(Vec3)); - CopyMemory(result->rw, rw, nverts * sizeof(float)); - CopyMemory(result->tu, tu, nverts * sizeof(float)); - CopyMemory(result->tv, tv, nverts * sizeof(float)); - CopyMemory(result->diffuse, diffuse, nverts * sizeof(DWORD)); - CopyMemory(result->specular, specular, nverts * sizeof(DWORD)); - - if (tu1) { - if (!result->tu1) - result->tu1 = new float[nverts]; - - CopyMemory(result->tu1, tu1, nverts * sizeof(float)); - } - - if (tv1) { - if (!result->tv1) - result->tv1 = new float[nverts]; - - CopyMemory(result->tv1, tv1, nverts * sizeof(float)); - } - - if (tangent) { - if (!result->tangent) - result->tangent = new Vec3[nverts]; - - CopyMemory(result->tangent, tangent, nverts * sizeof(Vec3)); - } - - if (binormal) { - if (!result->binormal) - result->binormal = new Vec3[nverts]; - - CopyMemory(result->binormal, binormal, nverts * sizeof(Vec3)); - } - - return result; -} - -void -VertexSet::CalcExtents(Point& plus, Point& minus) -{ - plus = Point(-1e6, -1e6, -1e6); - minus = Point( 1e6, 1e6, 1e6); - - for (int i = 0; i < nverts; i++) { - if (loc[i].x > plus.x) plus.x = loc[i].x; - if (loc[i].x < minus.x) minus.x = loc[i].x; - if (loc[i].y > plus.y) plus.y = loc[i].y; - if (loc[i].y < minus.y) minus.y = loc[i].y; - if (loc[i].z > plus.z) plus.z = loc[i].z; - if (loc[i].z < minus.z) minus.z = loc[i].z; - } -} - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -Poly::Poly(int init) - : nverts(0), visible(1), material(0), vertex_set(0), sortval(0), flatness(0) -{ } - -// +--------------------------------------------------------------------+ -// Check to see if a test point is within the bounds of the poly. -// The point is assumed to be coplanar with the poly. Return 1 if -// the point is inside, 0 if the point is outside. - -Vec2 projverts[Poly::MAX_VERTS]; - -static inline double extent3(double a, double b, double c) -{ - double d1 = fabs(a-b); - double d2 = fabs(a-c); - double d3 = fabs(b-c); - - if (d1 > d2) { - if (d1 > d3) - return d1; - else - return d3; - } - else { - if (d2 > d3) - return d2; - else - return d3; - } -} - -int Poly::Contains(const Vec3& pt) const -{ - // find largest 2d projection of this 3d Poly: - int projaxis; - - double pnx = fabs(plane.normal.x); - double pny = fabs(plane.normal.y); - double pnz = fabs(plane.normal.z); - - if (pnx > pny) - if (pnx > pnz) - if (plane.normal.x > 0) - projaxis = 1; - else - projaxis = -1; - else - if (plane.normal.z > 0) - projaxis = 3; - else - projaxis = -3; - else - if (pny > pnz) - if (plane.normal.y > 0) - projaxis = 2; - else - projaxis = -2; - else - if (plane.normal.z > 0) - projaxis = 3; - else - projaxis = -3; - - int i; - - for (i = 0; i < nverts; i++) { - Vec3 loc = vertex_set->loc[verts[i]]; - switch (projaxis) { - case 1: projverts[i] = Vec2(loc.y, loc.z); break; - case -1: projverts[i] = Vec2(loc.z, loc.y); break; - case 2: projverts[i] = Vec2(loc.z, loc.x); break; - case -2: projverts[i] = Vec2(loc.x, loc.z); break; - case 3: projverts[i] = Vec2(loc.x, loc.y); break; - case -3: projverts[i] = Vec2(loc.y, loc.x); break; - } - } - - // now project the test point into the same plane: - Vec2 test; - switch (projaxis) { - case 1: test.x = pt.y; test.y = pt.z; break; - case -1: test.x = pt.z; test.y = pt.y; break; - case 2: test.x = pt.z; test.y = pt.x; break; - case -2: test.x = pt.x; test.y = pt.z; break; - case 3: test.x = pt.x; test.y = pt.y; break; - case -3: test.x = pt.y; test.y = pt.x; break; - } - - const float INSIDE_EPSILON = -0.01f; - - // if the test point is outside of any segment, - // it is outside the entire convex Poly. - for (i = 0; i < nverts-1; i++) { - if (verts[i] != verts[i+1]) { - Vec2 segment = projverts[i+1] - projverts[i]; - Vec2 segnorm = segment.normal(); - Vec2 tdelta = projverts[i] - test; - float inside = segnorm * tdelta; - if (inside < INSIDE_EPSILON) - return 0; - } - } - - // check last segment, too: - if (verts[0] != verts[nverts-1]) { - Vec2 segment = projverts[0] - projverts[nverts-1]; - float inside = segment.normal() * (projverts[0] - test); - if (inside < INSIDE_EPSILON) - return 0; - } - - // still here? must be inside: - return 1; -} - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -Material::Material() - : power(1.0f), brilliance(1.0f), bump(0.0f), blend(MTL_SOLID), - shadow(true), luminous(false), - tex_diffuse(0), tex_specular(0), tex_bumpmap(0), tex_emissive(0), - tex_alternate(0), tex_detail(0), thumbnail(0) -{ - ZeroMemory(name, sizeof(name)); - ZeroMemory(shader, sizeof(shader)); - - ambient_value = 0.2f; - diffuse_value = 1.0f; - specular_value = 0.0f; - emissive_value = 0.0f; -} - -// +--------------------------------------------------------------------+ - -Material::~Material() -{ - // these objects are owned by the shared - // bitmap cache, so don't delete them now: - tex_diffuse = 0; - tex_specular = 0; - tex_bumpmap = 0; - tex_emissive = 0; - tex_alternate = 0; - tex_detail = 0; - - // the thumbnail is unique to the material, - // so it is never cached: - if (thumbnail) - delete thumbnail; -} - -// +--------------------------------------------------------------------+ - -int -Material::operator == (const Material& m) const -{ - if (this == &m) return 1; - - if (Ka != m.Ka) return 0; - if (Kd != m.Kd) return 0; - if (Ks != m.Ks) return 0; - if (Ke != m.Ke) return 0; - if (power != m.power) return 0; - if (brilliance != m.brilliance) return 0; - if (bump != m.bump) return 0; - if (blend != m.blend) return 0; - if (shadow != m.shadow) return 0; - if (tex_diffuse != m.tex_diffuse) return 0; - if (tex_specular != m.tex_specular) return 0; - if (tex_bumpmap != m.tex_bumpmap) return 0; - if (tex_emissive != m.tex_emissive) return 0; - if (tex_alternate != m.tex_alternate) return 0; - if (tex_detail != m.tex_detail) return 0; - - return !strcmp(name, m.name); -} - -// +--------------------------------------------------------------------+ - -void -Material::Clear() -{ - Ka = ColorValue(); - Kd = ColorValue(); - Ks = ColorValue(); - Ke = ColorValue(); - - power = 1.0f; - bump = 0.0f; - blend = MTL_SOLID; - shadow = true; - - tex_diffuse = 0; - tex_specular = 0; - tex_bumpmap = 0; - tex_emissive = 0; - tex_alternate = 0; - tex_detail = 0; -} - -// +--------------------------------------------------------------------+ - -static char shader_name[Material::NAMELEN]; - -const char* -Material::GetShader(int pass) const -{ - int level = 0; - if (pass > 1) pass--; - - for (int i = 0; i < NAMELEN; i++) { - if (shader[i] == '/') { - level++; - - if (level > pass) - return 0; - } - - else if (shader[i] != 0) { - if (level == pass) { - ZeroMemory(shader_name, NAMELEN); - - char* s = shader_name; - while (i < NAMELEN && shader[i] != 0 && shader[i] != '/') { - *s++ = shader[i++]; - } - - return shader_name; - } - } - - else { - return 0; - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Material::CreateThumbnail(int size) -{ - if (!thumbnail) { - thumbnail = new Bitmap(size, size); - } - - if (!thumbnail || thumbnail->Width() != thumbnail->Height()) - return; - - size = thumbnail->Width(); - - DWORD* image = new DWORD[size*size]; - DWORD* dst = image; - - for (int j = 0; j < size; j++) { - for (int i = 0; i < size; i++) { - *dst++ = GetThumbColor(i, j, size); - } - } - - thumbnail->CopyHighColorImage(size, size, image, Bitmap::BMP_SOLID); -} - -DWORD -Material::GetThumbColor(int i, int j, int size) -{ - Color result = Color::LightGray; - - double x = i - size/2; - double y = j - size/2; - double r = 0.9 * size/2; - double d = sqrt(x*x + y*y); - - if (d <= r) { - double z = sqrt(r*r - x*x - y*y); - - Point loc(x,y,z); - Point nrm = loc; nrm.Normalize(); - Point light(1,-1,1); light.Normalize(); - Point eye(0,0,1); - - ColorValue c = Ka * ColorValue(0.25f, 0.25f, 0.25f); // ambient light - ColorValue white(1,1,1); - - double diffuse = nrm*light; - double v = 1 - (acos(nrm.y)/PI); - double u = asin(nrm.x / sin(acos(nrm.y))) / PI + 0.5; - - ColorValue cd = Kd; - ColorValue cs = Ks; - ColorValue ce = Ke; - - if (tex_diffuse) { - int tu = (int) (u * tex_diffuse->Width()); - int tv = (int) (v * tex_diffuse->Height()); - cd = Kd * tex_diffuse->GetColor(tu,tv); - } - - if (tex_emissive) { - int tu = (int) (u * tex_emissive->Width()); - int tv = (int) (v * tex_emissive->Height()); - ce = Ke * tex_emissive->GetColor(tu,tv); - } - - if (tex_bumpmap && bump != 0 && nrm.z > 0) { - // compute derivatives B(u,v) - int tu = (int) (u * tex_bumpmap->Width()); - int tv = (int) (v * tex_bumpmap->Height()); - - DWORD tmpred = tex_bumpmap->GetColor(tu,tv).Red(); - double du1 = tmpred - tex_bumpmap->GetColor(tu-1,tv).Red(); - double du2 = tex_bumpmap->GetColor(tu+1,tv).Red() - tmpred; - - double dv1 = tmpred - tex_bumpmap->GetColor(tu,tv-1).Red(); - double dv2 = tex_bumpmap->GetColor(tu,tv+1).Red() - tmpred; - - double du = (du1 + du2) / 512 * 1e-8; - double dv = (dv1 + dv2) / 512 * 1e-8; - - if (du || dv) { - Point Nu = nrm.cross(Point(0,-1,0)); Nu.Normalize(); - Point Nv = nrm.cross(Point(1, 0,0)); Nv.Normalize(); - - nrm += (Nu*du*bump); - nrm += (Nv*dv*bump); - nrm.Normalize(); - - diffuse = nrm*light; - v = 1 - (acos(nrm.y)/PI); - u = asin(nrm.x / sin(acos(nrm.y))) / PI + 0.5; - } - } - - if (tex_specular) { - int tu = (int) (u * tex_specular->Width()); - int tv = (int) (v * tex_specular->Height()); - cs = Ks * tex_specular->GetColor(tu,tv); - } - - // anisotropic diffuse lighting - if (brilliance >= 0) { - diffuse = pow(diffuse, (double)brilliance); - } - - // forward lighting - if (diffuse > 0) { - // diffuse - c += cd * (white * diffuse); - - // specular - if (power > 0) { - double spec = ((nrm * 2*(nrm*light) - light) * eye); - if (spec > 0.01) { - spec = pow(spec, (double)power); - c += cs * (white * spec); - } - } - } - - // back lighting - else { - diffuse *= -0.5; - c += cd * (white * diffuse); - - // specular - if (power > 0) { - light *= -1; - - double spec = ((nrm * 2*(nrm*light) - light) * eye); - if (spec > 0.01) { - spec = pow(spec, (double)power); - c += cs * (white * spec) * 0.7; - } - } - } - - c += ce; - - result = c.ToColor(); - } - - return result.Value(); -} diff --git a/Stars45/Polygon.h b/Stars45/Polygon.h deleted file mode 100644 index e011afc..0000000 --- a/Stars45/Polygon.h +++ /dev/null @@ -1,158 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Polygon structures: VertexSet, Poly, Material -*/ - -#ifndef Polygon_h -#define Polygon_h - -#include "Geometry.h" -#include "Color.h" - -// +--------------------------------------------------------------------+ - -class Bitmap; -struct Poly; -struct Material; -struct VertexSet; - -// +--------------------------------------------------------------------+ - -struct Poly -{ - static const char* TYPENAME() { return "Poly"; } - - enum { MAX_VERTS = 4 }; - - Poly() { } - Poly(int init); - ~Poly() { } - - int operator < (const Poly& p) const { return sortval < p.sortval; } - int operator == (const Poly& p) const { return this == &p; } - - int Contains(const Vec3& pt) const; - - BYTE nverts; - BYTE visible; - WORD verts[MAX_VERTS]; - WORD vlocs[MAX_VERTS]; - VertexSet* vertex_set; - Material* material; - int sortval; - float flatness; - Plane plane; -}; - -// +--------------------------------------------------------------------+ - -struct Material -{ - static const char* TYPENAME() { return "Material"; } - - enum BLEND_TYPE { MTL_SOLID=1, MTL_TRANSLUCENT=2, MTL_ADDITIVE=4 }; - enum { NAMELEN=32 }; - - Material(); - ~Material(); - - int operator == (const Material& m) const; - - void Clear(); - - char name[NAMELEN]; - char shader[NAMELEN]; - - ColorValue Ka; // ambient color - ColorValue Kd; // diffuse color - ColorValue Ks; // specular color - ColorValue Ke; // emissive color - float power; // highlight sharpness (big=shiny) - float brilliance; // diffuse power function - float bump; // bump level (0=none) - DWORD blend; // alpha blend type - bool shadow; // casts shadow - bool luminous; // verts have their own lighting - - Bitmap* tex_diffuse; - Bitmap* tex_specular; - Bitmap* tex_bumpmap; - Bitmap* tex_emissive; - Bitmap* tex_alternate; - Bitmap* tex_detail; - - bool IsSolid() const { return blend == MTL_SOLID; } - bool IsTranslucent() const { return blend == MTL_TRANSLUCENT; } - bool IsGlowing() const { return blend == MTL_ADDITIVE; } - const char* GetShader(int n) const; - - // - // Support for Magic GUI - // - - Color ambient_color; - Color diffuse_color; - Color specular_color; - Color emissive_color; - - float ambient_value; - float diffuse_value; - float specular_value; - float emissive_value; - - Bitmap* thumbnail; // preview image - - void CreateThumbnail(int size=128); - DWORD GetThumbColor(int i, int j, int size); -}; - -// +--------------------------------------------------------------------+ - -struct VertexSet -{ - static const char* TYPENAME() { return "VertexSet"; } - - enum VertexSpaces { OBJECT_SPACE, WORLD_SPACE, VIEW_SPACE, SCREEN_SPACE }; - - VertexSet(int m); - ~VertexSet(); - - void Resize(int m, bool preserve=false); - void Delete(); - void Clear(); - void CreateTangents(); - void CreateAdditionalTexCoords(); - bool CopyVertex(int dst, int src); - void CalcExtents(Point& plus, Point& minus); - - VertexSet* Clone() const; - - int nverts; - int space; - - Vec3* loc; - Vec3* nrm; - Vec3* s_loc; - float* rw; - float* tu; - float* tv; - float* tu1; - float* tv1; - DWORD* diffuse; - DWORD* specular; - Vec3* tangent; - Vec3* binormal; -}; - -// +--------------------------------------------------------------------+ - -#endif // Polygon_h - diff --git a/Stars45/Power.cpp b/Stars45/Power.cpp deleted file mode 100644 index f86c5af..0000000 --- a/Stars45/Power.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Power generation and usage classes -*/ - -#include "Power.h" -#include "Ship.h" -#include "NetUtil.h" - -#include "Game.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ - -static char* source_type[] = { - "sys.power.battery", "sys.power.auxilliary", "sys.power.fusion" -}; - -static int source_value[] = { - 1, 2, 4 -}; - -PowerSource::PowerSource(SUBTYPE s, double max_out, double f_ratio) -: System(POWER_SOURCE, (int) s, "Power", source_value[s], 0), -max_output((float) max_out), fuel_ratio((float) f_ratio), -route_changed(false), requested_power_level(1.0f) -{ - name = ContentBundle::GetInstance()->GetText(source_type[s]); - abrv = ContentBundle::GetInstance()->GetText(Text(source_type[s]) + ".abrv"); - - if (fuel_ratio < 1) { - switch (subtype) { // enough to last for [n] hours at full power - case BATTERY: fuel_ratio = max_output * 5 * 3600 / 100; break; - case AUX: fuel_ratio = max_output * 50 * 3600 / 100; break; - case FUSION: fuel_ratio = max_output * 100 * 3600 / 100; break; - } - } - - capacity = 100.0f; - - if (subtype != BATTERY) { - emcon_power[0] = 10; - emcon_power[1] = 50; - emcon_power[2] = 100; - } -} - -PowerSource::PowerSource(const PowerSource& p) -: System(p), -max_output(p.max_output), fuel_ratio(p.fuel_ratio), -route_changed(false), requested_power_level(1.0f) -{ - Mount(p); - SetAbbreviation(p.Abbreviation()); -} - -// +----------------------------------------------------------------------+ - -void -PowerSource::AddClient(System* client) -{ - if (client) { - int old_src_index = client->GetSourceIndex(); - - client->SetSourceIndex(GetID()); - clients.append(client); - route_changed = true; - - if (ship && old_src_index != GetID()) - NetUtil::SendSysStatus(ship, client); - } -} - -void -PowerSource::RemoveClient(System* client) -{ - if (client && clients.contains(client)) { - client->SetSourceIndex(-1); - clients.remove(client); - route_changed = true; - } -} - -// +----------------------------------------------------------------------+ - -int -PowerSource::Charge() const -{ - return (int) capacity; -} - -void -PowerSource::SetFuelRange(double hours) -{ - if (hours > 0) - fuel_ratio = (float) (max_output * hours * 3600 / 100); -} - -// +----------------------------------------------------------------------+ - -void -PowerSource::ExecFrame(double seconds) -{ - if (seconds < 0.001) - seconds = 0.001; - - if (capacity <= 0) - capacity = 0; - - System::ExecFrame(seconds); - - double energy_requested = 0; - double energy_avail = 0; - double total_distrib = 0; - - // fuel leak? - if (availability < 0.4 && capacity > 0) - capacity -= (float) (0.03 * seconds); - - if (IsPowerOn() && capacity > 0) { - energy_avail = max_output * seconds * power_level * availability; - - if (power_level < requested_power_level) { - power_level += (float) (seconds * 0.03); // thirty seconds to charge up - - if (power_level > requested_power_level) - power_level = (float) requested_power_level; - } - else if (power_level > requested_power_level) { - power_level -= (float) (seconds * 0.10); // ten seconds to power down - - if (power_level < requested_power_level) - power_level = (float) requested_power_level; - } - } - - ListIter iter = clients; - while (++iter) { - System* sink = iter.value(); - - if (sink->IsPowerOn()) { - double joules = sink->GetRequest(seconds); - - if (joules > 0) { - if (sink->IsPowerCritical()) { - - if (joules > energy_avail) - joules = energy_avail; - - energy_avail -= joules; - total_distrib += joules; - sink->Distribute(joules, seconds); - } - else { - energy_requested += joules; - } - } - } - else { - sink->Distribute(-0.2 * sink->GetCapacity() * seconds, seconds); - } - } - - if (energy_avail > 0) { - - // enough to go around: - if (energy_requested <= energy_avail) { - iter.reset(); - - while (++iter) { - System* sink = iter.value(); - - if (sink->IsPowerOn() && !sink->IsPowerCritical()) { - double joules = sink->GetRequest(seconds); - total_distrib += joules; - sink->Distribute(joules, seconds); - } - } - } - - // load balancing: - else { - iter.reset(); - while (++iter) { - System* sink = iter.value(); - - if (sink->IsPowerOn() && !sink->IsPowerCritical()) { - double request = sink->GetRequest(seconds); - double delivery = 0; - - if (request > 0) - delivery = energy_avail * (request/energy_requested); - - if (delivery > 0) { - total_distrib += delivery; - sink->Distribute(delivery, seconds); - } - } - } - } - } - - if (IsPowerOn() && capacity > 0 && !Game::GetInstance()->Paused()) { - // reactors always burn at least 10% of max (to maintain operating temp): - if (subtype != BATTERY) { - double baseline = 0.1 * max_output * seconds; - - if (total_distrib < baseline) - total_distrib = baseline; - } - - // expend fuel: - if (total_distrib > 0) { - double effective_fuel_ratio = fuel_ratio; - - switch (Ship::GetFlightModel()) { - default: - case Ship::FM_STANDARD: - effective_fuel_ratio = 1 * fuel_ratio * (0.25 + 0.75 * availability); - break; - - case Ship::FM_RELAXED: - effective_fuel_ratio = 3 * fuel_ratio * (0.25 + 0.75 * availability); - break; - - case Ship::FM_ARCADE: - effective_fuel_ratio = 4 * fuel_ratio * (0.25 + 0.75 * availability); - break; - } - - capacity -= (float) (total_distrib / effective_fuel_ratio); - } - } - - else if (capacity <= 0) { - capacity = 0.0f; - PowerOff(); - } -} - -// +--------------------------------------------------------------------+ - -void -PowerSource::SetPowerLevel(double level) -{ - if (level > 100) - level = 100; - else if (level < 0) - level = 0; - - level /= 100; - - if (requested_power_level != level) { - // if the system is on emergency override power, - // do not let the EMCON system use this method - // to drop it back to normal power: - if (requested_power_level > 1 && level == 1) { - requested_power_level = 1.2f; - } - - else { - requested_power_level = (float) level; - } - } -} - -void -PowerSource::SetOverride(bool over) -{ - bool changed = false; - - if (over && requested_power_level != 1.2f) { - requested_power_level = 1.2f; - changed = true; - } - - else if (!over && requested_power_level > 1) { - requested_power_level = 1.0f; - changed = true; - } - - if (changed) - NetUtil::SendSysStatus(ship, this); -} - -void -PowerSource::DrainPower(double to_level) -{ - if (to_level >= 0 && to_level < power_level) - power_level = (float) to_level; -} diff --git a/Stars45/Power.h b/Stars45/Power.h deleted file mode 100644 index 3037f3a..0000000 --- a/Stars45/Power.h +++ /dev/null @@ -1,61 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Power generation and usage classes -*/ - -#ifndef Power_h -#define Power_h - -#include "Types.h" -#include "System.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class PowerSource : public System -{ -public: - enum SUBTYPE { BATTERY, AUX, FUSION }; - - PowerSource(SUBTYPE s, double max_output, double fuel_ratio=0); - PowerSource(const PowerSource& rhs); - - virtual void ExecFrame(double seconds); - - void AddClient(System* client); - void RemoveClient(System* client); - - List& Clients() { return clients; } - - virtual int Charge() const; - - virtual void SetFuelRange(double hours); - - bool RouteChanged() const { return route_changed; } - void RouteScanned() { route_changed = false; } - - // override from System: - virtual void SetPowerLevel(double level); - virtual void SetOverride(bool over); - - // for power drain damage: - virtual void DrainPower(double to_level); - -protected: - float max_output; - float fuel_ratio; - List clients; - bool route_changed; - float requested_power_level; -}; - -#endif // Power_h - diff --git a/Stars45/Projector.cpp b/Stars45/Projector.cpp deleted file mode 100644 index afa456e..0000000 --- a/Stars45/Projector.cpp +++ /dev/null @@ -1,473 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - 3D Projection Camera class -*/ - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include - -#include "Projector.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -static const float CLIP_PLANE_EPSILON = 0.0001f; -static const double Z_NEAR = 1.0; - -// +--------------------------------------------------------------------+ - -static Camera emergency_cam; - -// +--------------------------------------------------------------------+ - -Projector::Projector(Window* window, Camera* cam) -: camera(cam), infinite(0), depth_scale(1.0f), orthogonal(false), field_of_view(2) -{ - if (!camera) - camera = &emergency_cam; - - UseWindow(window); -} - -Projector::~Projector() -{ } - -// +--------------------------------------------------------------------+ - -void -Projector::UseCamera(Camera* cam) -{ - if (cam) - camera = cam; - else - camera = &emergency_cam; -} - -void -Projector::UseWindow(Window* win) -{ - Rect r = win->GetRect(); - width = r.w; - height = r.h; - - xcenter = (width / 2.0); - ycenter = (height / 2.0); - - xclip0 = 0.0f; - xclip1 = (float) width-0.5f; - yclip0 = 0.0f; - yclip1 = (float) height-0.5f; - - SetFieldOfView(field_of_view); -} - -void -Projector::SetFieldOfView(double fov) -{ - field_of_view = fov; - - xscreenscale = width / fov; - yscreenscale = height / fov; - - maxscale = std::max(xscreenscale, yscreenscale); - - xangle = atan(2.0/fov * maxscale/xscreenscale); - yangle = atan(2.0/fov * maxscale/yscreenscale); -} - -double -Projector::GetFieldOfView() const -{ - return field_of_view; -} - -void -Projector::SetDepthScale(float scale) -{ - depth_scale = scale; -} - -double -Projector::GetDepthScale() const -{ - return depth_scale; -} - -int -Projector::SetInfinite(int i) -{ - int old = infinite; - infinite = i; - return old; -} - -// +--------------------------------------------------------------------+ - -void -Projector::StartFrame() -{ - SetUpFrustum(); - SetWorldSpace(); -} - -// +--------------------------------------------------------------------+ -// Transform a point from worldspace to viewspace. -// +--------------------------------------------------------------------+ - -void -Projector::Transform(Vec3& vec) const -{ - Vec3 tvert = vec; - - // Translate into a viewpoint-relative coordinate - if (!infinite) - tvert -= camera->Pos(); - - // old method: - vec.x = (tvert * camera->vrt()); - vec.y = (tvert * camera->vup()); - vec.z = (tvert * camera->vpn()); - - // Rotate into the view orientation - // vec = tvert * camera->Orientation(); -} - -// +--------------------------------------------------------------------+ -// Transform a point from worldspace to viewspace. -// +--------------------------------------------------------------------+ - -void -Projector::Transform(Point& point) const -{ - Point tvert = point; - - // Translate into a viewpoint-relative coordinate - if (!infinite) - tvert -= camera->Pos(); - - // old method: - point.x = (tvert * camera->vrt()); - point.y = (tvert * camera->vup()); - point.z = (tvert * camera->vpn()); - - // Rotate into the view orientation - // point = tvert * camera->Orientation(); -} - -// +--------------------------------------------------------------------+ -// APPARENT RADIUS OF PROJECTED OBJECT -// Project a viewspace point into screen coordinates. -// Use projected Z to determine apparent radius of object. -// +--------------------------------------------------------------------+ - -float -Projector::ProjectRadius(const Vec3& v, float radius) const -{ - return (float) fabs((radius * maxscale) / v.z); -} - -// +--------------------------------------------------------------------+ -// IN PLACE PROJECTION OF POINT -// Project a viewspace point into screen coordinates. -// Note that the y axis goes up in worldspace and viewspace, but -// goes down in screenspace. -// +--------------------------------------------------------------------+ - -void -Projector::Project(Vec3& v, bool clamp) const -{ - double zrecip; - - if (orthogonal) { - double scale = field_of_view/2; - v.x = (float) (xcenter + scale * v.x); - v.y = (float) (height - (ycenter + scale * v.y)); - v.z = (float) (0.0f); - } - - else { - //zrecip = 2 * (1.0e5 / (1.0e5-1)) / v.z; - //zrecip = 2 * 0.97 / v.z; -- what the heck was this version used for? - - zrecip = 2 / v.z; - v.x = (float) (xcenter + maxscale * v.x * zrecip); - v.y = (float) (height - (ycenter + maxscale * v.y * zrecip)); - v.z = (float) (1 - zrecip); - } - - // clamp the point to the viewport: - if (clamp) { - if (v.x < xclip0) v.x = xclip0; - if (v.x > xclip1) v.x = xclip1; - if (v.y < yclip0) v.y = yclip0; - if (v.y > yclip1) v.y = yclip1; - } -} - -// +--------------------------------------------------------------------+ -// IN PLACE PROJECTION OF POINT -// Project a viewspace point into screen coordinates. -// Note that the y axis goes up in worldspace and viewspace, but -// goes down in screenspace. -// +--------------------------------------------------------------------+ - -void -Projector::Project(Point& v, bool clamp) const -{ - double zrecip; - - if (orthogonal) { - double scale = field_of_view/2; - v.x = (xcenter + scale * v.x); - v.y = (height - (ycenter + scale * v.y)); - v.z = 0; - } - - else { - zrecip = 1 / v.z; - v.x = (xcenter + 2 * maxscale * v.x * zrecip); - v.y = (height - (ycenter + 2 * maxscale * v.y * zrecip)); - v.z = (1 - zrecip); - } - - // clamp the point to the viewport: - if (clamp) { - if (v.x < xclip0) v.x = xclip0; - if (v.x > xclip1) v.x = xclip1; - if (v.y < yclip0) v.y = yclip0; - if (v.y > yclip1) v.y = yclip1; - } -} - -// +--------------------------------------------------------------------+ -// IN PLACE UN-PROJECTION OF POINT -// Convert a point in screen coordinates back to viewspace. -// Note that the y axis goes up in worldspace and viewspace, but -// goes down in screenspace. -// +--------------------------------------------------------------------+ - -void -Projector::Unproject(Point& v) const -{ - double zrecip = 1 / v.z; - - /*** - * forward projection: -v.x = (xcenter + maxscale * v.x * zrecip); -v.y = (height - (ycenter + maxscale * v.y * zrecip)); -v.z = (1 - zrecip); -***/ - - v.x = ( v.x - xcenter) / (maxscale * zrecip); - v.y = (height - v.y - ycenter) / (maxscale * zrecip); -} - -// +--------------------------------------------------------------------+ -// IN PLACE PROJECTION OF RECTANGLE (FOR SPRITES) -// Project a viewspace point into screen coordinates. -// Note that the y axis goes up in worldspace and viewspace, but -// goes down in screenspace. -// +--------------------------------------------------------------------+ - -void -Projector::ProjectRect(Point& v, double& w, double& h) const -{ - double zrecip; - - if (orthogonal) { - double scale = field_of_view/2; - v.x = (xcenter + scale * v.x); - v.y = (height - (ycenter + scale * v.y)); - v.z = 0; - } - - else { - zrecip = 1 / v.z; - v.x = (xcenter + 2 * maxscale * v.x * zrecip); - v.y = (height - (ycenter + 2 * maxscale * v.y * zrecip)); - v.z = (1 - Z_NEAR*zrecip); - - w *= maxscale * zrecip; - h *= maxscale * zrecip; - } -} - -// +--------------------------------------------------------------------+ -// Set up a clip plane with the specified normal. -// +--------------------------------------------------------------------+ - -void -Projector::SetWorldspaceClipPlane(Vec3& normal, Plane& plane) -{ - // Rotate the plane normal into worldspace - ViewToWorld(normal, plane.normal); - plane.distance = (float) (camera->Pos() * plane.normal + CLIP_PLANE_EPSILON); -} - -// +--------------------------------------------------------------------+ -// Set up the planes of the frustum, in worldspace coordinates. -// +--------------------------------------------------------------------+ - -void -Projector::SetUpFrustum() -{ - double angle, s, c; - Vec3 normal; - - angle = XAngle(); - s = sin(angle); - c = cos(angle); - - // Left clip plane - normal.x = (float) s; - normal.y = (float) 0; - normal.z = (float) c; - view_planes[0].normal = normal; - view_planes[0].distance = CLIP_PLANE_EPSILON; - SetWorldspaceClipPlane(normal, world_planes[0]); - - // Right clip plane - normal.x = (float) -s; - view_planes[1].normal = normal; - view_planes[1].distance = CLIP_PLANE_EPSILON; - SetWorldspaceClipPlane(normal, world_planes[1]); - - angle = YAngle(); - s = sin(angle); - c = cos(angle); - - // Bottom clip plane - normal.x = (float) 0; - normal.y = (float) s; - normal.z = (float) c; - view_planes[2].normal = normal; - view_planes[2].distance = CLIP_PLANE_EPSILON; - SetWorldspaceClipPlane(normal, world_planes[2]); - - // Top clip plane - normal.y = (float) -s; - view_planes[3].normal = normal; - view_planes[3].distance = CLIP_PLANE_EPSILON; - SetWorldspaceClipPlane(normal, world_planes[3]); -} - -// +--------------------------------------------------------------------+ -// Clip the point against the frustum and return 1 if partially inside -// Return 2 if completely inside -// +--------------------------------------------------------------------+ - -int -Projector::IsVisible(const Vec3& v, float radius) const -{ - int visible = 1; - int complete = 1; - - Plane* plane = (Plane*) frustum_planes; - if (infinite) { - complete = 0; - - for (int i = 0; visible && (i < NUM_FRUSTUM_PLANES); i++) { - visible = ((v * plane->normal) >= CLIP_PLANE_EPSILON); - plane++; - } - } - else { - for (int i = 0; visible && (i < NUM_FRUSTUM_PLANES); i++) { - float dot = v * plane->normal; - visible = ((dot + radius) >= plane->distance); - complete = complete && ((dot - radius) >= plane->distance); - plane++; - } - } - - return visible + complete; -} - -// +--------------------------------------------------------------------+ -// Clip the bouding point against the frustum and return non zero -// if at least partially inside. This version is not terribly -// efficient as it checks all eight box corners rather than just -// the minimum two. -// +--------------------------------------------------------------------+ - -int -Projector::IsBoxVisible(const Point* p) const -{ - int i, j, outside = 0; - - // if all eight corners are outside of the same - // frustrum plane, then the box is not visible - Plane* plane = (Plane*) frustum_planes; - - if (infinite) { - for (i = 0; !outside && (i < NUM_FRUSTUM_PLANES); i++) { - for (j = 0; j < 8; j++) - outside += (p[j] * plane->normal) < CLIP_PLANE_EPSILON; - - if (outside < 8) - outside = 0; - - plane++; - } - } - else { - for (i = 0; !outside && (i < NUM_FRUSTUM_PLANES); i++) { - for (j = 0; j < 8; j++) - outside += (p[j] * plane->normal) < plane->distance; - - if (outside < 8) - outside = 0; - - plane++; - } - } - - // if not outside, then the box is visible - return !outside; -} - -// +--------------------------------------------------------------------+ - -float -Projector::ApparentRadius(const Vec3& v, float radius) const -{ - Vec3 vloc = v; - - Transform(vloc); // transform in place - return ProjectRadius(vloc, radius); -} - - -// +--------------------------------------------------------------------+ -// Rotate a vector from viewspace to worldspace. -// +--------------------------------------------------------------------+ - -void -Projector::ViewToWorld(Point& pin, Point& pout) -{ - // Rotate into the world orientation - pout.x = pin.x * camera->vrt().x + pin.y * camera->vup().x + pin.z * camera->vpn().x; - pout.y = pin.x * camera->vrt().y + pin.y * camera->vup().y + pin.z * camera->vpn().y; - pout.z = pin.x * camera->vrt().z + pin.y * camera->vup().z + pin.z * camera->vpn().z; -} - -void -Projector::ViewToWorld(Vec3& vin, Vec3& vout) -{ - // Rotate into the world orientation - vout.x = (float) (vin.x * camera->vrt().x + vin.y * camera->vup().x + vin.z * camera->vpn().x); - vout.y = (float) (vin.x * camera->vrt().y + vin.y * camera->vup().y + vin.z * camera->vpn().y); - vout.z = (float) (vin.x * camera->vrt().z + vin.y * camera->vup().z + vin.z * camera->vpn().z); -} - diff --git a/Stars45/Projector.h b/Stars45/Projector.h deleted file mode 100644 index 20f0f7b..0000000 --- a/Stars45/Projector.h +++ /dev/null @@ -1,105 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - 3D Projection Camera class -*/ - -#ifndef Projector_h -#define Projector_h - -#include "Geometry.h" -#include "Window.h" -#include "Camera.h" -#include "Polygon.h" - -// +--------------------------------------------------------------------+ - -class Projector -{ -public: - Projector(Window* win, Camera* cam); - virtual ~Projector(); - - // Operations: - virtual void UseWindow(Window* win); - virtual void UseCamera(Camera* cam); - virtual void SetDepthScale(float scale); - virtual double GetDepthScale() const; - virtual void SetFieldOfView(double fov); - virtual double GetFieldOfView() const; - virtual int SetInfinite(int i); - virtual void StartFrame(); - - // accessor: - Point Pos() const { return camera->Pos(); } - Point vrt() { return camera->vrt(); } - Point vup() { return camera->vup(); } - Point vpn() { return camera->vpn(); } - const Matrix& Orientation() const { return camera->Orientation(); } - - double XAngle() const { return xangle; } - double YAngle() const { return yangle; } - - bool IsOrthogonal() const { return orthogonal; } - void SetOrthogonal(bool o) { orthogonal = o; } - - // projection and clipping geometry: - virtual void Transform(Vec3& vec) const; - virtual void Transform(Point& point) const; - - virtual void Project(Vec3& vec, bool clamp=true) const; - virtual void Project(Point& point, bool clamp=true) const; - virtual void ProjectRect(Point& origin, double& w, double& h) const; - - virtual float ProjectRadius(const Vec3& vec, float radius) const; - - virtual void Unproject(Point& point) const; - int IsVisible(const Vec3& v, float radius) const; - int IsBoxVisible(const Point* p) const; - - float ApparentRadius(const Vec3& v, float radius) const; - - virtual void SetWorldSpace() { frustum_planes = world_planes; } - virtual void SetViewSpace() { frustum_planes = view_planes; } - - Plane* GetCurrentClipPlanes() { return frustum_planes; } - - void SetUpFrustum(); - void ViewToWorld(Point& pin, Point& pout); - void ViewToWorld(Vec3& vin, Vec3& vout); - void SetWorldspaceClipPlane(Vec3& normal, Plane& plane); - -protected: - Camera* camera; - - int width, height; - double field_of_view; - double xscreenscale, yscreenscale, maxscale; - double xcenter, ycenter; - double xangle, yangle; - - int infinite; - float depth_scale; - bool orthogonal; - - enum DISPLAY_CONST { - NUM_FRUSTUM_PLANES= 4, - }; - - Plane* frustum_planes; - Plane world_planes[NUM_FRUSTUM_PLANES]; - Plane view_planes[NUM_FRUSTUM_PLANES]; - - float xclip0, xclip1; - float yclip0, yclip1; -}; - -#endif // Projector_h - diff --git a/Stars45/QuantumDrive.cpp b/Stars45/QuantumDrive.cpp deleted file mode 100644 index bcc8356..0000000 --- a/Stars45/QuantumDrive.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Quantum Drive class -*/ - -#include "QuantumDrive.h" -#include "Ship.h" -#include "Explosion.h" -#include "Drive.h" -#include "Sim.h" -#include "SimEvent.h" -#include "StarSystem.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Random.h" - -// +----------------------------------------------------------------------+ - -static int drive_value = 3; - -// +----------------------------------------------------------------------+ - -QuantumDrive::QuantumDrive(SUBTYPE s, double cap, double rate) -: System(DRIVE, s, "Quantum", drive_value, (float) cap, (float) cap, (float) rate), -dst_rgn(0), active_state(ACTIVE_READY), warp_fov(1), jump_time(0), countdown(5) -{ - name = ContentBundle::GetInstance()->GetText("sys.quantum"); - abrv = ContentBundle::GetInstance()->GetText("sys.quantum.abrv"); - - emcon_power[0] = 0; - emcon_power[1] = 0; - emcon_power[2] = 100; -} - -// +----------------------------------------------------------------------+ - -QuantumDrive::QuantumDrive(const QuantumDrive& d) -: System(d), -dst_rgn(0), active_state(ACTIVE_READY), warp_fov(1), jump_time(0), -countdown(d.countdown) -{ - Mount(d); - SetAbbreviation(d.Abbreviation()); - - energy = capacity; -} - -// +--------------------------------------------------------------------+ - -QuantumDrive::~QuantumDrive() -{ } - -// +--------------------------------------------------------------------+ - -void -QuantumDrive::SetDestination(SimRegion* rgn, const Point& loc) -{ - dst_rgn = rgn; - dst_loc = loc; -} - -// +--------------------------------------------------------------------+ - -bool -QuantumDrive::Engage(bool immediate) -{ - if (active_state == ACTIVE_READY && ship != 0 && - IsPowerOn() && Status() == NOMINAL && energy == capacity) { - - active_state = ACTIVE_COUNTDOWN; - if (immediate) { - jump_time = 1; - return true; - } - - jump_time = countdown; - - SimRegion* rgn = ship->GetRegion(); - - ListIter s_iter = rgn->Ships(); - while (++s_iter) { - Ship* s = s_iter.value(); - - if (s != ship) { - double dist = Point(s->Location() - ship->Location()).length(); - - if (dist < 25e3) - jump_time += 5; - - else if (dist < 50e3) - jump_time += 2; - - else if (dist < 100e3) - jump_time += 1; - - else if (dist < 200e3) - jump_time += 0.5; - } - } - - return true; - } - - return false; -} - -void -QuantumDrive::PowerOff() -{ - System::PowerOff(); - AbortJump(); -} - -void -QuantumDrive::AbortJump() -{ - active_state = ACTIVE_READY; - jump_time = 0; - energy = 0; - warp_fov = 1; - - ship->SetWarp(warp_fov); - - SimRegion* r = ship->GetRegion(); - ListIter neighbor = r->Ships(); - - while (++neighbor) { - if (neighbor->IsDropship()) { - Ship* s = neighbor.value(); - Point delta = s->Location() - ship->Location(); - - if (delta.length() < 5e3) - s->SetWarp(warp_fov); - } - } -} - -// +--------------------------------------------------------------------+ - -void -QuantumDrive::ExecFrame(double seconds) -{ - System::ExecFrame(seconds); - - if (active_state == ACTIVE_READY) - return; - - if (ship) { - bool warping = false; - - if (active_state == ACTIVE_COUNTDOWN) { - if (jump_time > 0) { - jump_time -= seconds; - } - - else { - jump_time = 0; - active_state = ACTIVE_PREWARP; - } - } - - else if (active_state == ACTIVE_PREWARP) { - if (warp_fov < 5000) { - warp_fov *= 1.5; - } - else { - Jump(); - energy = 0.0f; - } - - warping = true; - } - - else if (active_state == ACTIVE_POSTWARP) { - if (warp_fov > 1) { - warp_fov *= 0.75; - } - else { - warp_fov = 1; - active_state = ACTIVE_READY; - } - - warping = true; - } - - if (warping) { - ship->SetWarp(warp_fov); - - SimRegion* r = ship->GetRegion(); - ListIter neighbor = r->Ships(); - - while (++neighbor) { - if (neighbor->IsDropship()) { - Ship* s = neighbor.value(); - Point delta = s->Location() - ship->Location(); - - if (delta.length() < 5e3) - s->SetWarp(warp_fov); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -QuantumDrive::Jump() -{ - Sim* sim = Sim::GetSim(); - - if (ship && sim) { - double dist = 150e3 + Random(0, 60e3); - Point esc_vec = dst_rgn->GetOrbitalRegion()->Location() - - dst_rgn->GetOrbitalRegion()->Primary()->Location(); - - esc_vec.Normalize(); - esc_vec *= dist; - esc_vec += RandomDirection() * Random(15e3, 22e3); - - if (subtype == HYPER) - sim->CreateExplosion(ship->Location(), Point(0,0,0), Explosion::HYPER_FLASH, 1, 1, ship->GetRegion()); - else - sim->CreateExplosion(ship->Location(), Point(0,0,0), Explosion::QUANTUM_FLASH, 1, 0, ship->GetRegion()); - - sim->RequestHyperJump(ship, dst_rgn, esc_vec); - - ShipStats* stats = ShipStats::Find(ship->Name()); - stats->AddEvent(SimEvent::QUANTUM_JUMP, dst_rgn->Name()); - } - - dst_rgn = 0; - dst_loc = Point(); - - active_state = ACTIVE_POSTWARP; -} diff --git a/Stars45/QuantumDrive.h b/Stars45/QuantumDrive.h deleted file mode 100644 index 36adb64..0000000 --- a/Stars45/QuantumDrive.h +++ /dev/null @@ -1,72 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Quantum (JUMP) Drive (system) class -*/ - -#ifndef QuantumDrive_h -#define QuantumDrive_h - -#include "Types.h" -#include "System.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class SimRegion; - -// +--------------------------------------------------------------------+ - -class QuantumDrive : public System -{ -public: - enum SUBTYPE { QUANTUM, HYPER }; - - QuantumDrive(SUBTYPE s, double capacity, double sink_rate); - QuantumDrive(const QuantumDrive& rhs); - virtual ~QuantumDrive(); - - enum ACTIVE_STATES { - ACTIVE_READY, ACTIVE_COUNTDOWN, ACTIVE_PREWARP, ACTIVE_POSTWARP - }; - - void SetDestination(SimRegion* rgn, const Point& loc); - bool Engage(bool immediate=false); - int ActiveState() const { return active_state; } - double WarpFactor() const { return warp_fov; } - double JumpTime() const { return jump_time; } - virtual void PowerOff(); - - virtual void ExecFrame(double seconds); - - void SetShip(Ship* s) { ship = s; } - Ship* GetShip() const { return ship; } - - double GetCountdown() const { return countdown; } - void SetCountdown(double d) { countdown = d; } - -protected: - void Jump(); - void AbortJump(); - - int active_state; - - Ship* ship; - double warp_fov; - double jump_time; - double countdown; - - SimRegion* dst_rgn; - Point dst_loc; -}; - -#endif // QuantumDrive_h - diff --git a/Stars45/QuantumFlash.cpp b/Stars45/QuantumFlash.cpp deleted file mode 100644 index 34d2764..0000000 --- a/Stars45/QuantumFlash.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Quantum Warp Out special effect class -*/ - -#include "QuantumFlash.h" - -#include "Light.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Game.h" -#include "Random.h" -#include "Scene.h" - -// +--------------------------------------------------------------------+ - -static Bitmap* quantum_flash_texture = 0; - -// +--------------------------------------------------------------------+ - -QuantumFlash::QuantumFlash() -: nverts(64), npolys(16), mtl(0), verts(0), polys(0), beams(0), -texture(quantum_flash_texture), length(8000), width(0), -shade(1.0) -{ - trans = true; - luminous = true; - - if (!texture || texture->Width() < 1) { - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Explosions/"); - loader->LoadTexture("quantum.pcx", quantum_flash_texture, Bitmap::BMP_TRANSLUCENT); - loader->SetDataPath(0); - texture = quantum_flash_texture; - } - - loc = Vec3(0.0f, 0.0f, 1000.0f); - - mtl = new Material; - verts = new VertexSet(nverts); - polys = new Poly[npolys]; - beams = new Matrix[npolys]; - - mtl->Kd = Color::White; - mtl->tex_diffuse = texture; - mtl->tex_emissive = texture; - mtl->blend = Video::BLEND_ADDITIVE; - mtl->luminous = true; - - verts->nverts = nverts; - - for (int i = 0; i < npolys; i++) { - verts->loc[4*i+0] = Point( width, 0, 1000); - verts->loc[4*i+1] = Point( width, -length, 1000); - verts->loc[4*i+2] = Point(-width, -length, 1000); - verts->loc[4*i+3] = Point(-width, 0, 1000); - - for (int n = 0; n < 4; n++) { - verts->diffuse[4*i+n] = D3DCOLOR_RGBA(255,255,255,255); - verts->specular[4*i+n] = D3DCOLOR_RGBA( 0, 0, 0,255); - verts->tu[4*i+n] = (n < 2) ? 0.0f : 1.0f; - verts->tv[4*i+n] = (n > 0 && n < 3) ? 1.0f : 0.0f; - } - - beams[i].Roll( Random(-2*PI, 2*PI)); - beams[i].Pitch(Random(-2*PI, 2*PI)); - beams[i].Yaw( Random(-2*PI, 2*PI)); - - polys[i].nverts = 4; - polys[i].visible = 1; - polys[i].sortval = 0; - polys[i].vertex_set = verts; - polys[i].material = mtl; - - polys[i].verts[0] = 4*i+0; - polys[i].verts[1] = 4*i+1; - polys[i].verts[2] = 4*i+2; - polys[i].verts[3] = 4*i+3; - } - - radius = (float) length; - length = 0; - strcpy_s(name, "QuantumFlash"); -} - -// +--------------------------------------------------------------------+ - -QuantumFlash::~QuantumFlash() -{ - delete mtl; - delete verts; - delete [] polys; - delete [] beams; -} - -// +--------------------------------------------------------------------+ - -void -QuantumFlash::Render(Video* video, DWORD flags) -{ - if (hidden || !visible || !video || ((flags & RENDER_ADDITIVE) == 0)) - return; - - const Camera* cam = video->GetCamera(); - - if (cam) { - UpdateVerts(cam->Pos()); - video->DrawPolys(npolys, polys); - } -} - -// +--------------------------------------------------------------------+ - -void -QuantumFlash::UpdateVerts(const Point& cam_pos) -{ - if (length < radius) { - length += radius/80; - width += 1; - } - - for (int i = 0; i < npolys; i++) { - Matrix& m = beams[i]; - - m.Yaw(0.05); - Point vpn = Point(m(2,0), m(2,1), m(2,2)); - - Point head = loc; - Point tail = loc - vpn * length; - Point vtail = tail - head; - Point vcam = cam_pos - loc; - Point vtmp = vcam.cross(vtail); - vtmp.Normalize(); - Point vlat = vtmp * -width; - - verts->loc[4*i+0] = head + vlat; - verts->loc[4*i+1] = tail + vlat * 8; - verts->loc[4*i+2] = tail - vlat * 8; - verts->loc[4*i+3] = head - vlat; - - DWORD color = D3DCOLOR_RGBA((BYTE) (255*shade), (BYTE) (255*shade), (BYTE) (255*shade), 255); - - for (int n = 0; n < 4; n++) { - verts->diffuse[4*i+n] = color; - } - } -} - -// +--------------------------------------------------------------------+ - -void -QuantumFlash::SetOrientation(const Matrix& o) -{ - orientation = o; -} - -void -QuantumFlash::SetShade(double s) -{ - if (s < 0) s = 0; - else if (s > 1) s = 1; - - shade = s; -} - diff --git a/Stars45/QuantumFlash.h b/Stars45/QuantumFlash.h deleted file mode 100644 index 6141970..0000000 --- a/Stars45/QuantumFlash.h +++ /dev/null @@ -1,59 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Quantum Warp Out special effect class -*/ - -#ifndef QuantumFlash_h -#define QuantumFlash_h - -#include "Types.h" -#include "Geometry.h" -#include "Graphic.h" -#include "Polygon.h" -#include "SimObject.h" - -// +--------------------------------------------------------------------+ - -class QuantumFlash : public Graphic -{ -public: - QuantumFlash(); - virtual ~QuantumFlash(); - - // operations - virtual void Render(Video* video, DWORD flags); - - // accessors / mutators - virtual void SetOrientation(const Matrix& o); - void SetDirection(const Point& v); - void SetEndPoints(const Point& from, const Point& to); - - double Shade() const { return shade; } - void SetShade(double s); - -protected: - void UpdateVerts(const Point& cam_pos); - - double length; - double width; - double shade; - - int npolys, nverts; - Material* mtl; - VertexSet* verts; - Poly* polys; - Matrix* beams; - Bitmap* texture; - - Matrix orientation; -}; - -#endif // QuantumFlash_h diff --git a/Stars45/QuantumView.cpp b/Stars45/QuantumView.cpp deleted file mode 100644 index c3ab4f4..0000000 --- a/Stars45/QuantumView.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Quantum Destination HUD Overlay -*/ - -#include "QuantumView.h" -#include "QuantumDrive.h" -#include "HUDView.h" -#include "Ship.h" -#include "Element.h" -#include "Sim.h" -#include "StarSystem.h" -#include "FormatUtil.h" - -#include "Color.h" -#include "Window.h" -#include "Video.h" -#include "Screen.h" -#include "DataLoader.h" -#include "Scene.h" -#include "Font.h" -#include "FontMgr.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Clock.h" -#include "ContentBundle.h" -#include "Menu.h" - -static Color hud_color = Color::Black; - -// +====================================================================+ -// -// QUANTUM DRIVE DESTINATION MENU: -// - -static Menu* quantum_menu = 0; -static bool show_menu = false; - -void -QuantumView::Initialize() -{ - static int initialized = 0; - if (initialized) return; - - quantum_menu = new Menu(ContentBundle::GetInstance()->GetText("QuantumView.menu")); - - initialized = 1; -} - -void -QuantumView::Close() -{ - delete quantum_menu; -} - -// +====================================================================+ - -QuantumView* QuantumView::quantum_view = 0; - -QuantumView::QuantumView(Window* c) -: View(c), sim(0), ship(0), font(0) -{ - quantum_view = this; - sim = Sim::GetSim(); - - width = window->Width(); - height = window->Height(); - xcenter = (width / 2.0) - 0.5; - ycenter = (height / 2.0) + 0.5; - font = FontMgr::Find("HUD"); - - HUDView* hud = HUDView::GetInstance(); - if (hud) - SetColor(hud->GetTextColor()); -} - -QuantumView::~QuantumView() -{ - quantum_view = 0; -} - -void -QuantumView::OnWindowMove() -{ - width = window->Width(); - height = window->Height(); - xcenter = (width / 2.0) - 0.5; - ycenter = (height / 2.0) + 0.5; -} - -// +--------------------------------------------------------------------+ - -bool -QuantumView::Update(SimObject* obj) -{ - if (obj == ship) - ship = 0; - - return SimObserver::Update(obj); -} - -const char* -QuantumView::GetObserverName() const -{ - return "QuantumView"; -} - -// +--------------------------------------------------------------------+ - -void -QuantumView::Refresh() -{ - sim = Sim::GetSim(); - - if (sim && ship != sim->GetPlayerShip()) { - ship = sim->GetPlayerShip(); - - if (ship) { - if (ship->Life() == 0 || ship->IsDying() || ship->IsDead()) { - ship = 0; - } - else { - Observe(ship); - } - } - } - - if (IsMenuShown()) { - Rect menu_rect(width-115, 10, 115, 12); - - font->SetColor(hud_color); - font->SetAlpha(1); - font->DrawText(quantum_menu->GetTitle(), 0, menu_rect, DT_CENTER); - - menu_rect.y += 15; - - ListIter item = quantum_menu->GetItems(); - while (++item) { - item->SetEnabled(true); - - font->DrawText(item->GetText(), 0, menu_rect, DT_LEFT); - menu_rect.y += 10; - } - } -} - -// +--------------------------------------------------------------------+ - -void -QuantumView::ExecFrame() -{ - HUDView* hud = HUDView::GetInstance(); - if (hud) { - if (hud_color != hud->GetTextColor()) { - hud_color = hud->GetTextColor(); - SetColor(hud_color); - } - } - - static double time_til_change = 0; - - if (time_til_change > 0) - time_til_change -= Clock::GetInstance()->GuiDelta(); - - if (time_til_change <= 0) { - time_til_change = 0; - - if (show_menu) { - QuantumDrive* quantum_drive = 0; - - if (ship) - quantum_drive = ship->GetQuantumDrive(); - - if (quantum_drive && quantum_drive->ActiveState() != QuantumDrive::ACTIVE_READY) { - show_menu = false; - return; - } - - int max_items = quantum_menu->NumItems(); - - for (int i = 0; i < max_items; i++) { - if (Keyboard::KeyDown('1' + i)) { - MenuItem* item = quantum_menu->GetItem(i); - if (item && item->GetEnabled()) { - - SimRegion* rgn = (SimRegion*) item->GetData(); - - if (rgn) { - quantum_drive->SetDestination(rgn, Point(0,0,0)); - quantum_drive->Engage(); - } - - show_menu = false; - time_til_change = 0.3; - break; - } - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -QuantumView::SetColor(Color c) -{ - hud_color = c; -} - -// +--------------------------------------------------------------------+ - -bool -QuantumView::IsMenuShown() -{ - return show_menu; -} - -void -QuantumView::ShowMenu() -{ - if (!ship) return; - - if (!show_menu) { - if (ship->IsStarship() && ship->GetQuantumDrive()) { - GetQuantumMenu(ship); - show_menu = true; - } - - for (int i = 0; i < 10; i++) { - if (Keyboard::KeyDown('1' + i)) { - // just need to clear the key down flag - // so we don't process old keystrokes - // as valid menu picks... - } - } - } -} - -void -QuantumView::CloseMenu() -{ - show_menu = false; -} - -// +--------------------------------------------------------------------+ - -Menu* -QuantumView::GetQuantumMenu(Ship* s) -{ - if (s && sim) { - if (s->IsStarship()) { - quantum_menu->ClearItems(); - - SimRegion* current_region = ship->GetRegion(); - - if (!current_region) return 0; - - StarSystem* current_system = current_region->System(); - - List rgn_list; - - ListIter iter = sim->GetRegions(); - while (++iter) { - SimRegion* rgn = iter.value(); - StarSystem* rgn_system = rgn->System(); - - if (rgn != ship->GetRegion() && !rgn->IsAirSpace() && - rgn_system == current_system) { - rgn_list.append(rgn); - } - } - - // sort local regions by distance from star: - rgn_list.sort(); - - // now add regions in other star systems: - iter.reset(); - while (++iter) { - SimRegion* rgn = iter.value(); - StarSystem* rgn_system = rgn->System(); - - if (rgn != ship->GetRegion() && rgn->Type() != SimRegion::AIR_SPACE && - rgn_system != current_system && current_region->Links().contains(rgn)) { - rgn_list.append(rgn); - } - } - - int n = 1; - iter.attach(rgn_list); - while (++iter) { - SimRegion* rgn = iter.value(); - StarSystem* rgn_system = rgn->System(); - char text[64]; - - if (rgn_system != current_system) - sprintf_s(text, "%d. %s/%s", n++, rgn_system->Name(), rgn->Name()); - else - sprintf_s(text, "%d. %s", n++, rgn->Name()); - - quantum_menu->AddItem(text, (DWORD) rgn); - } - - return quantum_menu; - } - } - - return 0; -} diff --git a/Stars45/QuantumView.h b/Stars45/QuantumView.h deleted file mode 100644 index 3d07480..0000000 --- a/Stars45/QuantumView.h +++ /dev/null @@ -1,72 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Radio Communications HUD Overlay -*/ - -#ifndef QuantumView_h -#define QuantumView_h - -#include "Types.h" -#include "View.h" -#include "SimObject.h" -#include "Color.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class RadioMessage; -class HUDView; -class Menu; -class Font; - -// +--------------------------------------------------------------------+ - -class QuantumView : public View, -public SimObserver -{ -public: - QuantumView(Window* c); - virtual ~QuantumView(); - - // Operations: - virtual void Refresh(); - virtual void OnWindowMove(); - virtual void ExecFrame(); - - virtual Menu* GetQuantumMenu(Ship* ship); - virtual bool IsMenuShown(); - virtual void ShowMenu(); - virtual void CloseMenu(); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - static void SetColor(Color c); - - static void Initialize(); - static void Close(); - - static QuantumView* GetInstance() { return quantum_view; } - -protected: - int width, height; - double xcenter, ycenter; - - Font* font; - Sim* sim; - Ship* ship; - - static QuantumView* quantum_view; -}; - -#endif // QuantumView_h - diff --git a/Stars45/QuitView.cpp b/Stars45/QuitView.cpp deleted file mode 100644 index 90b90ab..0000000 --- a/Stars45/QuitView.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for End Mission menu -*/ - -#include "QuitView.h" -#include "HUDView.h" -#include "RadioView.h" -#include "Ship.h" -#include "Contact.h" -#include "Sim.h" -#include "SimEvent.h" -#include "Campaign.h" -#include "Starshatter.h" -#include "GameScreen.h" - -#include "CameraView.h" -#include "Color.h" -#include "Window.h" -#include "Video.h" -#include "Screen.h" -#include "DataLoader.h" -#include "Scene.h" -#include "FontMgr.h" -#include "Button.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "MouseController.h" -#include "Game.h" -#include "Clock.h" -#include "ContentBundle.h" -#include "Menu.h" - -// +====================================================================+ - -static bool show_menu = false; -static Bitmap* menu_bmp = 0; -static MouseController* mouse_con = 0; -static bool mouse_active = false; -static const int w2 = 200; -static const int h2 = 128; - -void -QuitView::Initialize() -{ - if (!menu_bmp) { - menu_bmp = new Bitmap; - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Screens/"); - loader->LoadBitmap("QuitWin.pcx", *menu_bmp, Bitmap::BMP_TRANSPARENT); - loader->SetDataPath(0); - } -} - -void -QuitView::Close() -{ - delete menu_bmp; -} - -// +====================================================================+ - -QuitView* QuitView::quit_view = 0; - -QuitView::QuitView(Window* c) -: View(c), mouse_latch(false) -{ - quit_view = this; - sim = Sim::GetSim(); - - width = window->Width(); - height = window->Height(); - xcenter = width / 2; - ycenter = height / 2; - - mouse_con = MouseController::GetInstance(); -} - -QuitView::~QuitView() -{ - quit_view = 0; -} - -void -QuitView::OnWindowMove() -{ - width = window->Width(); - height = window->Height(); - xcenter = width / 2; - ycenter = height / 2; -} - -// +--------------------------------------------------------------------+ - -void -QuitView::Refresh() -{ - if (show_menu && menu_bmp) { - Rect clip_rect; - - clip_rect.x = xcenter - w2; - clip_rect.y = ycenter - h2; - clip_rect.w = w2 * 2; - clip_rect.h = h2 * 2; - - window->ClipBitmap(xcenter - w2, - ycenter - h2, - xcenter - w2 + menu_bmp->Width(), - ycenter - h2 + menu_bmp->Height(), - menu_bmp, - Color::White, - Video::BLEND_SOLID, - clip_rect); - } -} - -// +--------------------------------------------------------------------+ - -void -QuitView::ExecFrame() -{ - sim = Sim::GetSim(); - - if (show_menu) { - Color::SetFade(1, Color::Black, 0); - int action = 0; - - if (Mouse::LButton()) { - mouse_latch = true; - } - else if (mouse_latch) { - mouse_latch = false; - - if (Mouse::X() > xcenter - w2 && Mouse::X() < xcenter + w2) { - int y0 = ycenter - h2; - - for (int i = 0; i < 4; i++) - if (Mouse::Y() >= y0 + 75 + i * 30 && Mouse::Y() <= y0 + 105 + i * 30) - action = i+1; - } - } - - for (int i = 1; i <= 4; i++) { - if (Keyboard::KeyDown('0' + i)) - action = i; - } - - // was mission long enough to accept? - if (action == 1 && !CanAccept()) { - Button::PlaySound(Button::SND_REJECT); - action = 3; - } - - // exit and accept: - if (action == 1) { - CloseMenu(); - Clock::GetInstance()->SetTimeCompression(1.0); - - Starshatter* stars = Starshatter::GetInstance(); - stars->SetGameMode(Starshatter::PLAN_MODE); - } - - // quit and discard results: - else if (action == 2) { - CloseMenu(); - Clock::GetInstance()->SetTimeCompression(1.0); - - Starshatter* stars = Starshatter::GetInstance(); - Campaign* campaign = Campaign::GetCampaign(); - - // discard mission and events: - if (sim) sim->UnloadMission(); - else ShipStats::Initialize(); - - if (campaign && campaign->GetCampaignId() < Campaign::SINGLE_MISSIONS) { - campaign->RollbackMission(); - stars->SetGameMode(Starshatter::CMPN_MODE); - } - - else { - stars->SetGameMode(Starshatter::MENU_MODE); - } - } - - // resume: - else if (action == 3) { - CloseMenu(); - } - - // controls: - else if (action == 4) { - GameScreen* game_screen = GameScreen::GetInstance(); - - if (game_screen) - game_screen->ShowCtlDlg(); - else - CloseMenu(); - } - } -} - -// +--------------------------------------------------------------------+ - -bool -QuitView::IsMenuShown() -{ - return show_menu; -} - -// +--------------------------------------------------------------------+ - -bool -QuitView::CanAccept() -{ - sim = Sim::GetSim(); - - if (!sim || sim->IsNetGame()) - return true; - - Ship* player_ship = sim->GetPlayerShip(); - - if (player_ship->MissionClock() < 60000) { - RadioView::Message(ContentBundle::GetInstance()->GetText("QuitView.too-soon")); - RadioView::Message(ContentBundle::GetInstance()->GetText("QuitView.abort")); - return false; - } - - ListIter iter = player_ship->ContactList(); - while (++iter) { - Contact* c = iter.value(); - Ship* cship = c->GetShip(); - int ciff = c->GetIFF(player_ship); - - if (c->Threat(player_ship)) { - RadioView::Message(ContentBundle::GetInstance()->GetText("QuitView.threats-present")); - RadioView::Message(ContentBundle::GetInstance()->GetText("QuitView.abort")); - return false; - } - - else if (cship && ciff > 0 && ciff != player_ship->GetIFF()) { - Point delta = c->Location() - player_ship->Location(); - double dist = delta.length(); - - if (cship->IsDropship() && dist < 50e3) { - RadioView::Message(ContentBundle::GetInstance()->GetText("QuitView.threats-present")); - RadioView::Message(ContentBundle::GetInstance()->GetText("QuitView.abort")); - return false; - } - - else if (cship->IsStarship() && dist < 100e3) { - RadioView::Message(ContentBundle::GetInstance()->GetText("QuitView.threats-present")); - RadioView::Message(ContentBundle::GetInstance()->GetText("QuitView.abort")); - return false; - } - } - } - - return true; -} - -void -QuitView::ShowMenu() -{ - if (!show_menu) { - show_menu = true; - - for (int i = 0; i < 10; i++) { - if (Keyboard::KeyDown('1' + i)) { - // just need to clear the key down flag - // so we don't process old keystrokes - // as valid menu picks... - } - } - - Button::PlaySound(Button::SND_CONFIRM); - Game::GetInstance()->Pause(true); - - if (mouse_con) { - mouse_active = mouse_con->Active(); - mouse_con->SetActive(false); - } - } -} - -void -QuitView::CloseMenu() -{ - show_menu = false; - Game::GetInstance()->Pause(false); - - if (mouse_con) - mouse_con->SetActive(mouse_active); -} diff --git a/Stars45/QuitView.h b/Stars45/QuitView.h deleted file mode 100644 index d893efc..0000000 --- a/Stars45/QuitView.h +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for End Mission menu -*/ - -#ifndef QuitView_h -#define QuitView_h - -#include "Types.h" -#include "View.h" -#include "Bitmap.h" -#include "Font.h" -#include "SimObject.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class HUDView; -class Menu; - -// +--------------------------------------------------------------------+ - -class QuitView : public View -{ -public: - QuitView(Window* c); - virtual ~QuitView(); - - // Operations: - virtual void Refresh(); - virtual void OnWindowMove(); - virtual void ExecFrame(); - - virtual bool CanAccept(); - virtual bool IsMenuShown(); - virtual void ShowMenu(); - virtual void CloseMenu(); - - static void Initialize(); - static void Close(); - - static QuitView* GetInstance() { return quit_view; } - -protected: - int width, height; - int xcenter, ycenter; - bool mouse_latch; - - Sim* sim; - - static QuitView* quit_view; -}; - -#endif // QuitView_h - diff --git a/Stars45/RLoc.cpp b/Stars45/RLoc.cpp deleted file mode 100644 index 911c4ea..0000000 --- a/Stars45/RLoc.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Navigation Point class implementation -*/ - -#include "RLoc.h" -#include "Random.h" - -// +----------------------------------------------------------------------+ - -RLoc::RLoc() - : rloc(0), dex(0), dex_var(5.0e3f), az(0), az_var(3.1415f), el(0), el_var(0.1f) -{ } - -RLoc::RLoc(const Point& l, double d, double dv) - : loc(l), base_loc(l), rloc(0), dex((float) d), dex_var((float) dv), - az(0), az_var(3.1415f), el(0), el_var(0.1f) -{ } - -RLoc::RLoc(RLoc* l, double d, double dv) - : rloc(l), dex((float) d), dex_var((float) dv), - az(0), az_var(3.1415f), el(0), el_var(0.1f) -{ } - -RLoc::RLoc(const RLoc& r) - : loc(r.loc), base_loc(r.base_loc), rloc(r.rloc), - dex(r.dex), dex_var(r.dex_var), - az(r.az), az_var(r.az_var), - el(r.el), el_var(r.el_var) -{ } - -RLoc::~RLoc() -{ } - -// +----------------------------------------------------------------------+ - -const Point& -RLoc::Location() -{ - if (rloc || dex > 0) Resolve(); - return loc; -} - -// +----------------------------------------------------------------------+ - -void -RLoc::Resolve() -{ - if (rloc) { - base_loc = rloc->Location(); - rloc = 0; - } - - if (dex > 0) { - double d = dex + Random(-dex_var, dex_var); - double a = az + Random(-az_var, az_var); - double e = el + Random(-el_var, el_var); - - Point p = Point(d * sin(a), - d * -cos(a), - d * sin(e)); - - loc = base_loc + p; - dex = 0; - } - else { - loc = base_loc; - } -} - -// +----------------------------------------------------------------------+ - -void -RLoc::SetBaseLocation(const Point& l) -{ - base_loc = l; - loc = l; -} diff --git a/Stars45/RLoc.h b/Stars45/RLoc.h deleted file mode 100644 index eedc5ac..0000000 --- a/Stars45/RLoc.h +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Relative Location (RLoc) class declaration -*/ - -#ifndef RLoc_h -#define RLoc_h - -#include "Types.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class RLoc -{ -public: - RLoc(); - RLoc(const Point& loc, double d, double dv=5e3); - RLoc(RLoc* rloc, double d, double dv=5e3); - RLoc(const RLoc& r); - ~RLoc(); - - // accessors: - const Point& Location(); - const Point& BaseLocation() const { return base_loc; } - RLoc* ReferenceLoc() const { return rloc; } - double Distance() const { return dex; } - double DistanceVar() const { return dex_var; } - double Azimuth() const { return az; } - double AzimuthVar() const { return az_var; } - double Elevation() const { return el; } - double ElevationVar() const { return el_var; } - - void Resolve(); - - // mutators: - void SetBaseLocation(const Point& l); - void SetReferenceLoc(RLoc* r) { rloc = r; } - void SetDistance(double d) { dex = (float) d; } - void SetDistanceVar(double dv) { dex_var = (float) dv; } - void SetAzimuth(double a) { az = (float) a; } - void SetAzimuthVar(double av) { az_var = (float) av; } - void SetElevation(double e) { el = (float) e; } - void SetElevationVar(double ev) { el_var = (float) ev; } - -private: - Point loc; - Point base_loc; - RLoc* rloc; - - float dex; - float dex_var; - float az; - float az_var; - float el; - float el_var; -}; - -// +--------------------------------------------------------------------+ - -#endif // RLoc_h - diff --git a/Stars45/RadioHandler.cpp b/Stars45/RadioHandler.cpp deleted file mode 100644 index b395c6e..0000000 --- a/Stars45/RadioHandler.cpp +++ /dev/null @@ -1,557 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Radio message handler class implementation -*/ - -#include "RadioHandler.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "Instruction.h" - -#include "Contact.h" -#include "Element.h" -#include "Mission.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Sim.h" -#include "StarSystem.h" -#include "Power.h" -#include "Drive.h" -#include "Shield.h" -#include "Hangar.h" -#include "FlightDeck.h" -#include "WeaponGroup.h" -#include "SteerAI.h" - -#include "Text.h" -#include "Game.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ - -RadioHandler::RadioHandler() -{ } - -RadioHandler::~RadioHandler() -{ } - -// +----------------------------------------------------------------------+ - -bool -RadioHandler::ProcessMessage(RadioMessage* msg, Ship* s) -{ - if (!s || !msg || !msg->Sender()) - return false; - - if (s->Class() >= Ship::FARCASTER && s->Class() <= Ship::C3I) - return false; - - if (msg->Sender()->IsRogue()) { - Ship* sender = (Ship*) msg->Sender(); // cast-away const - RadioMessage* nak = new RadioMessage(sender, s, RadioMessage::NACK); - RadioTraffic::Transmit(nak); - return false; - } - - bool respond = (s != msg->Sender()); - - // SPECIAL CASE: - // skip navpoint must be processed by elem leader, - // even if the elem leader sent the message: - - if (msg->Action() == RadioMessage::SKIP_NAVPOINT && !respond) - ProcessMessageAction(msg, s); - - if (!ProcessMessageOrders(msg, s)) - respond = respond && ProcessMessageAction(msg, s); - - return respond; -} - -// +----------------------------------------------------------------------+ - -bool -RadioHandler::IsOrder(int action) -{ - bool result = false; - - switch (action) { - default: - case RadioMessage::NONE: - case RadioMessage::ACK: - case RadioMessage::NACK: result = false; break; - - // target mgt: - case RadioMessage::ATTACK: - case RadioMessage::ESCORT: - case RadioMessage::BRACKET: - case RadioMessage::IDENTIFY: result = true; break; - - // combat mgt: - case RadioMessage::COVER_ME: - case RadioMessage::WEP_HOLD: - case RadioMessage::FORM_UP: result = true; break; - - case RadioMessage::WEP_FREE: - case RadioMessage::SAY_POSITION: - case RadioMessage::LAUNCH_PROBE: result = false; break; - - // formation mgt: - case RadioMessage::GO_DIAMOND: - case RadioMessage::GO_SPREAD: - case RadioMessage::GO_BOX: - case RadioMessage::GO_TRAIL: result = true; break; - - // mission mgt: - case RadioMessage::MOVE_PATROL: result = true; break; - case RadioMessage::SKIP_NAVPOINT: result = false; break; - case RadioMessage::RESUME_MISSION: result = true; break; - - case RadioMessage::RTB: - case RadioMessage::DOCK_WITH: - case RadioMessage::QUANTUM_TO: - case RadioMessage::FARCAST_TO: result = true; break; - - // sensor mgt: - case RadioMessage::GO_EMCON1: - case RadioMessage::GO_EMCON2: - case RadioMessage::GO_EMCON3: result = true; break; - - // support: - case RadioMessage::REQUEST_PICTURE: - case RadioMessage::REQUEST_SUPPORT: - case RadioMessage::PICTURE: result = false; break; - - // traffic control: - case RadioMessage::CALL_INBOUND: - case RadioMessage::CALL_APPROACH: - case RadioMessage::CALL_CLEARANCE: - case RadioMessage::CALL_FINALS: - case RadioMessage::CALL_WAVE_OFF: result = false; break; - } - - return result; -} - -// +----------------------------------------------------------------------+ - -bool -RadioHandler::ProcessMessageOrders(RadioMessage* msg, Ship* ship) -{ - Instruction* instruction = ship->GetRadioOrders(); - int action = 0; - - if (msg && msg->Action() == RadioMessage::RESUME_MISSION) { - instruction->SetAction(RadioMessage::NONE); - instruction->SetFormation(-1); - instruction->SetWeaponsFree(true); - if (instruction->GetTarget()) { - instruction->ClearTarget(); - ship->DropTarget(); - } - return true; - } - - if (msg && IsOrder(msg->Action())) { - int posture_only = false; - - action = msg->Action(); - - if (action == RadioMessage::FORM_UP) - action = RadioMessage::WEP_HOLD; - - // target orders => drop current target: - if (action >= RadioMessage::ATTACK && - action <= RadioMessage::COVER_ME || - action == RadioMessage::WEP_HOLD || - action >= RadioMessage::DOCK_WITH && - action <= RadioMessage::FARCAST_TO) { - - if (ship != msg->Sender()) - ship->DropTarget(); - - Director* dir = ship->GetDirector(); - if (dir && dir->Type() >= SteerAI::SEEKER && dir->Type() <= SteerAI::GROUND) { - SteerAI* ai = (SteerAI*) dir; - ai->SetTarget(0); - } - - // farcast and quantum jump radio messages: - if (action >= RadioMessage::QUANTUM_TO) { - Sim* sim = Sim::GetSim(); - - if (sim) { - SimRegion* rgn = sim->FindRegion(msg->Info()); - - if (rgn) { - instruction->SetAction(action); - instruction->SetLocation(Point(0,0,0)); - instruction->SetRegion(rgn); - instruction->SetFarcast(action == RadioMessage::FARCAST_TO); - instruction->SetWeaponsFree(false); - return true; - } - } - } - } - - // formation orders => set formation: - if (action >= RadioMessage::GO_DIAMOND && - action <= RadioMessage::GO_TRAIL) { - - switch (action) { - case RadioMessage::GO_DIAMOND: instruction->SetFormation(Instruction::DIAMOND); break; - case RadioMessage::GO_SPREAD: instruction->SetFormation(Instruction::SPREAD); break; - case RadioMessage::GO_BOX: instruction->SetFormation(Instruction::BOX); break; - case RadioMessage::GO_TRAIL: instruction->SetFormation(Instruction::TRAIL); break; - } - - posture_only = true; - } - - // emcon orders => set emcon: - if (action >= RadioMessage::GO_EMCON1 && - action <= RadioMessage::GO_EMCON3) { - - switch (msg->Action()) { - case RadioMessage::GO_EMCON1: instruction->SetEMCON(1); break; - case RadioMessage::GO_EMCON2: instruction->SetEMCON(2); break; - case RadioMessage::GO_EMCON3: instruction->SetEMCON(3); break; - } - - posture_only = true; - } - - if (!posture_only) { - instruction->SetAction(action); - instruction->ClearTarget(); - - if (msg->TargetList().size() > 0) { - SimObject* msg_tgt = msg->TargetList().at(0); - instruction->SetTarget(msg_tgt); - instruction->SetLocation(msg_tgt->Location()); - } - - else if (action == RadioMessage::COVER_ME) { - instruction->SetTarget((Ship*) msg->Sender()); - instruction->SetLocation(msg->Sender()->Location()); - } - - else if (action == RadioMessage::MOVE_PATROL) { - instruction->SetLocation(msg->Location()); - } - - // handle element engagement: - if (action == RadioMessage::ATTACK && msg->TargetList().size() > 0) { - Element* elem = msg->DestinationElem(); - - if (!elem && msg->DestinationShip()) - elem = msg->DestinationShip()->GetElement(); - - if (elem) { - SimObject* msg_tgt = msg->TargetList().at(0); - if (msg_tgt && msg_tgt->Type() == SimObject::SIM_SHIP) { - Element* tgt = ((Ship*) msg_tgt)->GetElement(); - elem->SetAssignment(tgt); - - if (msg->TargetList().size() > 1) - instruction->SetTarget(tgt->Name().data()); - else - instruction->SetTarget(msg_tgt); - } - else { - elem->ResumeAssignment(); - } - } - } - - else if (action == RadioMessage::RESUME_MISSION) { - Element* elem = msg->DestinationElem(); - - if (!elem && msg->DestinationShip()) - elem = msg->DestinationShip()->GetElement(); - - if (elem) { - elem->ResumeAssignment(); - } - } - } - - instruction->SetWeaponsFree(action <= RadioMessage::WEP_FREE); - return true; - } - - return false; -} - -// +----------------------------------------------------------------------+ - -bool -RadioHandler::ProcessMessageAction(RadioMessage* msg, Ship* ship) -{ - if (!msg) return false; - - if (msg->Action() == RadioMessage::CALL_INBOUND) - return Inbound(msg, ship); - - if (msg->Action() == RadioMessage::CALL_FINALS) - return true; // acknowledge - - if (msg->Action() == RadioMessage::REQUEST_PICTURE) - return Picture(msg, ship); - - if (msg->Action() == RadioMessage::REQUEST_SUPPORT) - return Support(msg, ship); - - if (msg->Action() == RadioMessage::SKIP_NAVPOINT) - return SkipNavpoint(msg, ship); - - if (msg->Action() == RadioMessage::LAUNCH_PROBE) - return LaunchProbe(msg, ship); - - return false; -} - -bool -RadioHandler::SkipNavpoint(RadioMessage* msg, Ship* ship) -{ - // Find next Instruction: - Instruction* navpt = ship->GetNextNavPoint(); - int elem_index = ship->GetElementIndex(); - - if (navpt && elem_index < 2) { - ship->SetNavptStatus(navpt, Instruction::SKIPPED); - } - - return true; -} - -bool -RadioHandler::LaunchProbe(RadioMessage* msg, Ship* ship) -{ - if (ship && ship->GetProbeLauncher()) { - ship->LaunchProbe(); - return ship->GetProbe() != 0; - } - - return false; -} - -bool -RadioHandler::Inbound(RadioMessage* msg, Ship* ship) -{ - Ship* inbound = (Ship*) msg->Sender(); - Hangar* hangar = ship->GetHangar(); - FlightDeck* deck = 0; - int squadron = -1; - int slot = -1; - bool same_rgn = false; - - if (inbound && inbound->GetRegion() == ship->GetRegion()) - same_rgn = true; - - // is the sender already inbound to us? - if (inbound->GetInbound() && - inbound->GetInbound()->GetDeck() && - inbound->GetInbound()->GetDeck()->GetCarrier() == ship) { - InboundSlot* islot = inbound->GetInbound(); - deck = islot->GetDeck(); - squadron = islot->Squadron(); - slot = islot->Index(); - } - - // otherwise, find space for sender: - else { - if (hangar && same_rgn) { - if (hangar->FindSlot(inbound, squadron, slot)) { - int shortest_queue = 1000; - - for (int i = 0; i < ship->NumFlightDecks(); i++) { - FlightDeck* d = ship->GetFlightDeck(i); - if (d->IsRecoveryDeck()) { - int nwaiting = d->GetRecoveryQueue().size(); - - if (nwaiting < shortest_queue) { - deck = d; - shortest_queue = nwaiting; - } - } - } - } - } - } - - // if no space (or not a carrier!) wave sender off: - if (!deck || !same_rgn || squadron < 0 || slot < 0) { - RadioMessage* wave_off = new RadioMessage(inbound, ship, RadioMessage::NACK); - if (!hangar) - wave_off->SetInfo(ContentBundle::GetInstance()->GetText("RadioHandler.no-hangar")); - - else if (!same_rgn) { - char info[256]; - sprintf_s(info, ContentBundle::GetInstance()->GetText("RadioHandler.too-far-away").data(), ship->GetRegion()->Name()); - wave_off->SetInfo(info); - } - - else - wave_off->SetInfo(ContentBundle::GetInstance()->GetText("RadioHandler.all-full")); - - RadioTraffic::Transmit(wave_off); - return false; - } - - // put sender in recovery queue, if not already there: - InboundSlot* inbound_slot = inbound->GetInbound(); - int sequence = 0; - - if (!inbound_slot) { - inbound_slot = new InboundSlot(inbound, deck, squadron, slot); - sequence = deck->Inbound(inbound_slot); - } - else { - sequence = inbound_slot->Index(); - } - - // inform sender of status: - RadioMessage* approach = new RadioMessage(inbound, ship, RadioMessage::CALL_APPROACH); - - if (inbound_slot->Cleared()) { - char info[256]; - sprintf_s(info, ContentBundle::GetInstance()->GetText("RadioHandler.cleared").data(), deck->Name()); - approach->SetInfo(info); - } - else if (sequence) { - char info[256]; - sprintf_s(info, ContentBundle::GetInstance()->GetText("RadioHandler.sequenced").data(), sequence, deck->Name()); - approach->SetInfo(info); - } - - RadioTraffic::Transmit(approach); - - return false; -} - -bool -RadioHandler::Picture(RadioMessage* msg, Ship* ship) -{ - if (!ship) return false; - - // try to find some enemy fighters in the area: - Ship* tgt = 0; - double range = 1e9; - - ListIter iter = ship->ContactList(); - while (++iter) { - Contact* c = iter.value(); - int iff = c->GetIFF(ship); - Ship* s = c->GetShip(); - - if (s && s->IsDropship() && s->IsHostileTo(ship)) { - double s_range = Point(msg->Sender()->Location() - s->Location()).length(); - if (!tgt || s_range < range) { - tgt = s; - range = s_range; - } - } - } - - // found some: - if (tgt) { - Element* sender = msg->Sender()->GetElement(); - Element* tgt_elem = tgt->GetElement(); - RadioMessage* response = new RadioMessage(sender, ship, RadioMessage::ATTACK); - - if (tgt_elem) { - for (int i = 1; i <= tgt_elem->NumShips(); i++) - response->AddTarget(tgt_elem->GetShip(i)); - } - else { - response->AddTarget(tgt); - } - - RadioTraffic::Transmit(response); - } - - // nobody worth killin': - else { - Ship* sender = (Ship*) msg->Sender(); // cast-away const - RadioMessage* response = new RadioMessage(sender, ship, RadioMessage::PICTURE); - RadioTraffic::Transmit(response); - } - - return false; -} - -bool -RadioHandler::Support(RadioMessage* msg, Ship* ship) -{ - if (!ship) return false; - - // try to find some fighters with time on their hands... - Element* help = 0; - Element* cmdr = ship->GetElement(); - Element* baby = msg->Sender()->GetElement(); - SimRegion* rgn = msg->Sender()->GetRegion(); - - for (int i = 0; i < rgn->Ships().size(); i++) { - Ship* s = rgn->Ships().at(i); - Element* e = s->GetElement(); - - if (e && s->IsDropship() && - e->Type() == Mission::PATROL && - e != baby && - cmdr->CanCommand(e) && - s->GetRadioOrders()->Action() == RadioMessage::NONE) { - help = e; - break; - } - } - - // found some: - if (help) { - RadioMessage* escort = new RadioMessage(help, ship, RadioMessage::ESCORT); - escort->TargetList().append(msg->Sender()); - RadioTraffic::Transmit(escort); - - Text ok = ContentBundle::GetInstance()->GetText("RadioHandler.help-enroute"); - Ship* sender = (Ship*) msg->Sender(); // cast-away const - RadioMessage* response = new RadioMessage(sender, ship, RadioMessage::ACK); - response->SetInfo(ok); - RadioTraffic::Transmit(response); - } - - // no help in sight: - else { - Text nope = ContentBundle::GetInstance()->GetText("RadioHandler.no-help-for-you"); - Ship* sender = (Ship*) msg->Sender(); // cast-away const - RadioMessage* response = new RadioMessage(sender, ship, RadioMessage::NACK); - response->SetInfo(nope); - RadioTraffic::Transmit(response); - } - - return false; -} - -// +----------------------------------------------------------------------+ - -void -RadioHandler::AcknowledgeMessage(RadioMessage* msg, Ship* s) -{ - if (s && msg && msg->Sender() && msg->Action()) { - if (msg->Action() >= RadioMessage::ACK && msg->Action() <= RadioMessage::NACK) - return; // nothing to say here - - Ship* sender = (Ship*) msg->Sender(); // cast-away const - RadioMessage* ack = new RadioMessage(sender, s, RadioMessage::ACK); - RadioTraffic::Transmit(ack); - } -} - diff --git a/Stars45/RadioHandler.h b/Stars45/RadioHandler.h deleted file mode 100644 index 2e43611..0000000 --- a/Stars45/RadioHandler.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - RadioHandler (radio comms) class declaration -*/ - -#ifndef RadioHandler_h -#define RadioHandler_h - -#include "Types.h" -#include "Geometry.h" -#include "SimObject.h" - -// +--------------------------------------------------------------------+ - -class RadioMessage; -class Ship; - -// +--------------------------------------------------------------------+ - -class RadioHandler -{ -public: - RadioHandler(); - virtual ~RadioHandler(); - - virtual bool ProcessMessage(RadioMessage* msg, Ship* s); - virtual void AcknowledgeMessage(RadioMessage* msg, Ship* s); - -protected: - virtual bool IsOrder(int action); - virtual bool ProcessMessageOrders(RadioMessage* msg, Ship* s); - virtual bool ProcessMessageAction(RadioMessage* msg, Ship* s); - - virtual bool Inbound(RadioMessage* msg, Ship* s); - virtual bool Picture(RadioMessage* msg, Ship* s); - virtual bool Support(RadioMessage* msg, Ship* s); - virtual bool SkipNavpoint(RadioMessage* msg, Ship* s); - virtual bool LaunchProbe(RadioMessage* msg, Ship* s); -}; - -// +--------------------------------------------------------------------+ - -#endif // RadioHandler_h - diff --git a/Stars45/RadioMessage.cpp b/Stars45/RadioMessage.cpp deleted file mode 100644 index ecf3e04..0000000 --- a/Stars45/RadioMessage.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Radio communication message class implementation -*/ - -#include "RadioMessage.h" -#include "Ship.h" -#include "Text.h" - -// +----------------------------------------------------------------------+ - -RadioMessage::RadioMessage(Ship* dst, const Ship* s, int a) -: dst_ship(dst), dst_elem(0), sender(s), action(a), channel(0) -{ - if (s) - channel = s->GetIFF(); -} - -RadioMessage::RadioMessage(Element* dst, const Ship* s, int a) -: dst_ship(0), dst_elem(dst), sender(s), action(a), channel(0) -{ - if (s) - channel = s->GetIFF(); -} - -RadioMessage::RadioMessage(const RadioMessage& rm) -: dst_ship(rm.dst_ship), dst_elem(rm.dst_elem), -sender(rm.sender), action(rm.action), channel(rm.channel), -info(rm.info), location(rm.location) -{ - if (rm.target_list.size() > 0) { - for (int i = 0; i < rm.target_list.size(); i++) { - SimObject* obj = rm.target_list.at(i); - target_list.append(obj); - } - } -} - -RadioMessage::~RadioMessage() -{ } - -// +----------------------------------------------------------------------+ - -const char* -RadioMessage::ActionName(int a) -{ - if (a == ACK) { - int coin = rand(); - if (coin < 10000) return "Acknowledged"; - if (coin < 17000) return "Roger that"; - if (coin < 20000) return "Understood"; - if (coin < 22000) return "Copy that"; - return "Affirmative"; - } - - if (a == DISTRESS) { - int coin = rand(); - if (coin < 15000) return "Mayday! Mayday!"; - if (coin < 18000) return "She's breaking up!"; - if (coin < 21000) return "Checking out!"; - return "We're going down!"; - } - - if (a == WARN_ACCIDENT) { - int coin = rand(); - if (coin < 15000) return "Check your fire!"; - if (coin < 18000) return "Watch it!"; - if (coin < 21000) return "Hey! We're on your side!"; - return "Confirm your targets!"; - } - - if (a == WARN_TARGETED) { - int coin = rand(); - if (coin < 15000) return "Break off immediately!"; - if (coin < 20000) return "Buddy spike!"; - return "Abort! Abort!"; - } - - switch (a) { - case NONE: return ""; - - case NACK: return "Negative, Unable"; - - case ATTACK: return "Engage"; - case ESCORT: return "Escort"; - case BRACKET: return "Bracket"; - case IDENTIFY: return "Identify"; - - case COVER_ME: return "Cover Me"; - case MOVE_PATROL: return "Vector"; - case SKIP_NAVPOINT: return "Skip Navpoint"; - case RESUME_MISSION: return "Resume Mission"; - case RTB: return "Return to Base"; - case DOCK_WITH: return "Dock With"; - case QUANTUM_TO: return "Jump to"; - case FARCAST_TO: return "Farcast to"; - - case GO_DIAMOND: return "Goto Diamond Formation"; - case GO_SPREAD: return "Goto Spread Formation"; - case GO_BOX: return "Goto Box Formation"; - case GO_TRAIL: return "Goto Trail Formation"; - - case WEP_FREE: return "Break and Attack"; - case WEP_HOLD: return "Hold All Weapons"; - case FORM_UP: return "Return to Formation"; - case SAY_POSITION: return "Say Your Position"; - - case LAUNCH_PROBE: return "Launch Probe"; - case GO_EMCON1: return "Goto EMCON 1"; - case GO_EMCON2: return "Goto EMCON 2"; - case GO_EMCON3: return "Goto EMCON 3"; - - case REQUEST_PICTURE: return "Request Picture"; - case REQUEST_SUPPORT: return "Request Support"; - case PICTURE: return "Picture is clear"; - - case CALL_INBOUND: return "Calling Inbound"; - case CALL_APPROACH: return "Roger your approach"; - case CALL_CLEARANCE: return "You have clearance"; - case CALL_FINALS: return "On final approach"; - case CALL_WAVE_OFF: return "Wave off - Runway is closed"; - - case DECLARE_ROGUE: return "Prepare to be destroyed!"; - - case CALL_ENGAGING: return "Engaging"; - case FOX_1: return "Fox One!"; - case FOX_2: return "Fox Two!"; - case FOX_3: return "Fox Three!"; - case SPLASH_1: return "Splash One!"; - case SPLASH_2: return "Splash Two!"; - case SPLASH_3: return "Splash Three!"; - case SPLASH_4: return "Splash Four!"; - case SPLASH_5: return "Target Destroyed!"; - case SPLASH_6: return "Enemy Destroyed!"; - case SPLASH_7: return "Confirmed Kill!"; - case BREAK_ORBIT: return "Breaking Orbit"; - case MAKE_ORBIT: return "Heading for Orbit"; - case QUANTUM_JUMP: return "Going Quantum"; - - default: return "Unknown"; - } -} - -// +----------------------------------------------------------------------+ - -void -RadioMessage::AddTarget(SimObject* obj) -{ - if (obj && !target_list.contains(obj)) { - target_list.append(obj); - } -} - - - diff --git a/Stars45/RadioMessage.h b/Stars45/RadioMessage.h deleted file mode 100644 index 0a04daf..0000000 --- a/Stars45/RadioMessage.h +++ /dev/null @@ -1,154 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - RadioMessage (radio comms) class declaration -*/ - -#ifndef RadioMessage_h -#define RadioMessage_h - -#include "Types.h" -#include "Geometry.h" -#include "SimObject.h" -#include "Instruction.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Element; -class Ship; -class SimObject; - -// +--------------------------------------------------------------------+ - -class RadioMessage -{ -public: - enum ACTION - { - NONE = 0, - - DOCK_WITH = Instruction::DOCK, - RTB = Instruction::RTB, - QUANTUM_TO = Instruction::NUM_ACTIONS, - FARCAST_TO, - - // protocol: - ACK, - NACK, - - // target mgt: - ATTACK, - ESCORT, - BRACKET, - IDENTIFY, - - // combat mgt: - COVER_ME, - WEP_FREE, - WEP_HOLD, - FORM_UP, // alias for wep_hold - SAY_POSITION, - - // sensor mgt: - LAUNCH_PROBE, - GO_EMCON1, - GO_EMCON2, - GO_EMCON3, - - // formation mgt: - GO_DIAMOND, - GO_SPREAD, - GO_BOX, - GO_TRAIL, - - // mission mgt: - MOVE_PATROL, - SKIP_NAVPOINT, - RESUME_MISSION, - - // misc announcements: - CALL_ENGAGING, - FOX_1, - FOX_2, - FOX_3, - SPLASH_1, - SPLASH_2, - SPLASH_3, - SPLASH_4, - SPLASH_5, // target destroyed - SPLASH_6, // enemy destroyed - SPLASH_7, // confirmed kill - DISTRESS, - BREAK_ORBIT, - MAKE_ORBIT, - QUANTUM_JUMP, - - // friendly fire: - WARN_ACCIDENT, - WARN_TARGETED, - DECLARE_ROGUE, - - // support: - PICTURE, - REQUEST_PICTURE, - REQUEST_SUPPORT, - - // traffic control: - CALL_INBOUND, - CALL_APPROACH, - CALL_CLEARANCE, - CALL_FINALS, - CALL_WAVE_OFF, - - NUM_ACTIONS - }; - - RadioMessage(Ship* dst, const Ship* sender, int action); - RadioMessage(Element* dst, const Ship* sender, int action); - RadioMessage(const RadioMessage& rm); - virtual ~RadioMessage(); - - // accessors: - static const char* ActionName(int a); - - const Ship* Sender() const { return sender; } - Ship* DestinationShip() const { return dst_ship; } - Element* DestinationElem() const { return dst_elem; } - int Action() const { return action; } - List& TargetList() { return target_list; } - const Point& Location() const { return location; } - const Text& Info() const { return info; } - int Channel() const { return channel; } - - // mutators: - void SetDestinationShip(Ship* s) { dst_ship = s; } - void SetDestinationElem(Element* e) { dst_elem = e; } - void AddTarget(SimObject* s); - void SetLocation(const Point& l) { location = l; } - void SetInfo(Text msg) { info = msg; } - void SetChannel(int c) { channel = c; } - -protected: - const Ship* sender; - Ship* dst_ship; - Element* dst_elem; - int action; - List target_list; - Point location; - Text info; - int channel; -}; - -// +--------------------------------------------------------------------+ - -#endif // RadioMessage_h - diff --git a/Stars45/RadioTraffic.cpp b/Stars45/RadioTraffic.cpp deleted file mode 100644 index a67cd9f..0000000 --- a/Stars45/RadioTraffic.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Radio message handler class implementation -*/ - -#include "RadioTraffic.h" -#include "RadioMessage.h" -#include "RadioView.h" -#include "RadioVox.h" -#include "Instruction.h" -#include "Ship.h" -#include "Contact.h" -#include "Element.h" -#include "Sim.h" -#include "NetGame.h" -#include "NetData.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Text.h" - -// +----------------------------------------------------------------------+ - -RadioTraffic* RadioTraffic::radio_traffic = 0; - -// +----------------------------------------------------------------------+ - -RadioTraffic::RadioTraffic() -{ - radio_traffic = this; -} - -RadioTraffic::~RadioTraffic() -{ - traffic.destroy(); -} - -// +----------------------------------------------------------------------+ - -void -RadioTraffic::Initialize() -{ - if (!radio_traffic) - radio_traffic = new RadioTraffic; -} - -void -RadioTraffic::Close() -{ - delete radio_traffic; - radio_traffic = 0; -} - -// +--------------------------------------------------------------------+ - -void -RadioTraffic::SendQuickMessage(Ship* ship, int action) -{ - if (!ship) return; - - Element* elem = ship->GetElement(); - - if (elem) { - if (action >= RadioMessage::REQUEST_PICTURE) { - Ship* controller = ship->GetController(); - - if (controller && !ship->IsStarship()) { - RadioMessage* msg = new RadioMessage(controller, ship, action); - Transmit(msg); - } - } - else if (action >= RadioMessage::SPLASH_1 && action <= RadioMessage::DISTRESS) { - RadioMessage* msg = new RadioMessage((Element*) 0, ship, action); - Transmit(msg); - } - else { - RadioMessage* msg = new RadioMessage(elem, ship, action); - - if (action == RadioMessage::ATTACK || action == RadioMessage::ESCORT) - msg->AddTarget(ship->GetTarget()); - - Transmit(msg); - } - } -} - -// +----------------------------------------------------------------------+ - -void -RadioTraffic::Transmit(RadioMessage* msg) -{ - if (msg && radio_traffic) { - NetGame* net_game = NetGame::GetInstance(); - if (net_game) { - NetCommMsg net_msg; - net_msg.SetRadioMessage(msg); - net_game->SendData(&net_msg); - } - - radio_traffic->SendMessage(msg); - } -} - -// +----------------------------------------------------------------------+ - -void -RadioTraffic::SendMessage(RadioMessage* msg) -{ - if (!msg) return; - - Sim* sim = Sim::GetSim(); - Ship* player = sim->GetPlayerShip(); - int iff = 0; - - if (player) - iff = player->GetIFF(); - - if (msg->DestinationShip()) { - traffic.append(msg); - - if (msg->Channel() == 0 || msg->Channel() == iff) - DisplayMessage(msg); - - if (!NetGame::IsNetGameClient()) - msg->DestinationShip()->HandleRadioMessage(msg); - } - - else if (msg->DestinationElem()) { - traffic.append(msg); - - if (msg->Channel() == 0 || msg->Channel() == iff) - DisplayMessage(msg); - - if (!NetGame::IsNetGameClient()) - msg->DestinationElem()->HandleRadioMessage(msg); - } - - else { - if (msg->Channel() == 0 || msg->Channel() == iff) - DisplayMessage(msg); - - delete msg; - } -} - -// +----------------------------------------------------------------------+ - -Text -RadioTraffic::TranslateVox(const char* phrase) -{ - Text vox = "vox."; - vox += phrase; - vox.toLower(); - vox = ContentBundle::GetInstance()->GetText(vox); - - if (vox.contains("vox.")) // failed to translate - return Text(phrase); // return the original text - - return vox; -} - -void -RadioTraffic::DisplayMessage(RadioMessage* msg) -{ - if (!msg) return; - - char txt_buf[256]; txt_buf[0] = 0; - char msg_buf[128]; msg_buf[0] = 0; - char src_buf[64]; src_buf[0] = 0; - char dst_buf[64]; dst_buf[0] = 0; - char act_buf[64]; act_buf[0] = 0; - int vox_channel = 0; - - Ship* dst_ship = msg->DestinationShip(); - Element* dst_elem = msg->DestinationElem(); - - // BUILD SRC AND DST BUFFERS ------------------- - - if (msg->Sender()) { - const Ship* sender = msg->Sender(); - - // orders to self? - if (dst_elem && dst_elem->NumShips() == 1 && dst_elem->GetShip(1) == sender) { - if (msg->Action() >= RadioMessage::CALL_ENGAGING) { - sprintf_s(src_buf, "%s", sender->Name()); - - if (sender->IsStarship()) - vox_channel = (sender->Identity()%3) + 5; - } - } - - // orders to other ships: - else { - if (sender->IsStarship()) { - vox_channel = (sender->Identity()%3) + 5; - } - else { - vox_channel = sender->GetElementIndex(); - } - - if (msg->Action() >= RadioMessage::CALL_ENGAGING) { - sprintf_s(src_buf, "%s", sender->Name()); - } - else { - sprintf_s(src_buf, "This is %s", sender->Name()); - - if (dst_ship) { - // internal announcement - if (dst_ship->GetElement() == sender->GetElement()) { - dst_elem = sender->GetElement(); - int index = sender->GetElementIndex(); - - if (index > 1 && dst_elem) { - sprintf_s(dst_buf, "%s Leader", (const char*) dst_elem->Name()); - sprintf_s(src_buf, "this is %s %d", (const char*) dst_elem->Name(), index); - } - else { - sprintf_s(src_buf, "this is %s leader", (const char*) dst_elem->Name()); - } - } - - else { - strcpy_s(dst_buf, (const char*) dst_ship->Name()); - src_buf[0] = tolower(src_buf[0]); - } - } - - else if (dst_elem) { - // flight - if (dst_elem->NumShips() > 1) { - sprintf_s(dst_buf, "%s Flight", (const char*) dst_elem->Name()); - - // internal announcement - if (sender->GetElement() == dst_elem) { - int index = sender->GetElementIndex(); - - if (index > 1) { - sprintf_s(dst_buf, "%s Leader", (const char*) dst_elem->Name()); - sprintf_s(src_buf, "this is %s %d", (const char*) dst_elem->Name(), index); - } - else { - sprintf_s(src_buf, "this is %s leader", (const char*) dst_elem->Name()); - } - } - } - - // solo - else { - strcpy_s(dst_buf, (const char*) dst_elem->Name()); - src_buf[0] = tolower(src_buf[0]); - } - } - } - } - } - - // BUILD ACTION AND TARGET BUFFERS ------------------- - - SimObject* target = 0; - - strcpy_s(act_buf, RadioMessage::ActionName(msg->Action())); - - if (msg->TargetList().size() > 0) - target = msg->TargetList()[0]; - - if (msg->Action() == RadioMessage::ACK || - msg->Action() == RadioMessage::NACK) { - - if (dst_ship == msg->Sender()) { - src_buf[0] = 0; - dst_buf[0] = 0; - - if (msg->Action() == RadioMessage::ACK) - sprintf_s(msg_buf, "%s.", TranslateVox("Acknowledged").data()); - else - sprintf_s(msg_buf, "%s.", TranslateVox("Unable").data()); - } - else if (msg->Sender()) { - dst_buf[0] = 0; - - if (msg->Info().length()) { - sprintf_s(msg_buf, "%s. %s", - TranslateVox(act_buf).data(), - (const char*) msg->Info()); - } - else { - sprintf_s(msg_buf, "%s.", TranslateVox(act_buf).data()); - } - } - else { - if (msg->Info().length()) { - sprintf_s(msg_buf, "%s. %s", - TranslateVox(act_buf).data(), - (const char*) msg->Info()); - } - else { - sprintf_s(msg_buf, "%s.", TranslateVox(act_buf).data()); - } - } - } - - else if (msg->Action() == RadioMessage::MOVE_PATROL) { - sprintf_s(msg_buf, "%s.", TranslateVox("Move patrol.").data()); - } - - else if (target && dst_ship && msg->Sender()) { - Contact* c = msg->Sender()->FindContact(target); - - if (c && c->GetIFF(msg->Sender()) > 10) { - sprintf_s(msg_buf, "%s %s.", TranslateVox(act_buf).data(), TranslateVox("unknown contact").data()); - } - - else { - sprintf_s(msg_buf, "%s %s.", - TranslateVox(act_buf).data(), - target->Name()); - } - } - - else if (target) { - sprintf_s(msg_buf, "%s %s.", - TranslateVox(act_buf).data(), - target->Name()); - } - - else if (msg->Info().length()) { - sprintf_s(msg_buf, "%s %s", - TranslateVox(act_buf).data(), - (const char*) msg->Info()); - } - - else { - strcpy_s(msg_buf, TranslateVox(act_buf).data()); - } - - char last_char = msg_buf[strlen(msg_buf)-1]; - if (last_char != '!' && last_char != '.' && last_char != '?') - strcat_s(msg_buf, "."); - - // final format: - if (dst_buf[0] && src_buf[0]) { - sprintf_s(txt_buf, "%s %s. %s", TranslateVox(dst_buf).data(), TranslateVox(src_buf).data(), msg_buf); - txt_buf[0] = toupper(txt_buf[0]); - } - - else if (src_buf[0]) { - sprintf_s(txt_buf, "%s. %s", TranslateVox(src_buf).data(), msg_buf); - txt_buf[0] = toupper(txt_buf[0]); - } - - else if (dst_buf[0]) { - sprintf_s(txt_buf, "%s %s", TranslateVox(dst_buf).data(), msg_buf); - txt_buf[0] = toupper(txt_buf[0]); - } - - else { - strcpy_s(txt_buf, msg_buf); - } - - // vox: - const char* path[8] = { "1", "1", "2", "3", "4", "5", "6", "7" }; - - RadioVox* vox = new RadioVox(vox_channel, path[vox_channel], txt_buf); - - if (vox) { - vox->AddPhrase(dst_buf); - vox->AddPhrase(src_buf); - vox->AddPhrase(act_buf); - - if (!vox->Start()) { - RadioView::Message(txt_buf); - delete vox; - } - } -} - -// +----------------------------------------------------------------------+ - -void -RadioTraffic::DiscardMessages() -{ - if (radio_traffic) - radio_traffic->traffic.destroy(); -} diff --git a/Stars45/RadioTraffic.h b/Stars45/RadioTraffic.h deleted file mode 100644 index 5ffd1ec..0000000 --- a/Stars45/RadioTraffic.h +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - RadioTraffic maintains a history of all messages sent between ships - in the simulation. This class also handles displaying relevant - traffic to the player. -*/ - -#ifndef RadioTraffic_h -#define RadioTraffic_h - -#include "Types.h" -#include "Geometry.h" -#include "SimObject.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Element; -class RadioMessage; -class Ship; -class SimObject; - -// +--------------------------------------------------------------------+ - -class RadioTraffic -{ -public: - RadioTraffic(); - ~RadioTraffic(); - - // accessors: - static void Initialize(); - static void Close(); - - static RadioTraffic* GetInstance() { return radio_traffic; } - - static void SendQuickMessage(Ship* ship, int msg); - static void Transmit(RadioMessage* msg); - static void DiscardMessages(); - static Text TranslateVox(const char* phrase); - - void SendMessage(RadioMessage* msg); - void DisplayMessage(RadioMessage* msg); - - -protected: - List traffic; - - static RadioTraffic* radio_traffic; -}; - -// +--------------------------------------------------------------------+ - -#endif // RadioTraffic_h - diff --git a/Stars45/RadioView.cpp b/Stars45/RadioView.cpp deleted file mode 100644 index 8a63091..0000000 --- a/Stars45/RadioView.cpp +++ /dev/null @@ -1,641 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Radio Communications HUD Overlay -*/ - -#include - -#include "RadioView.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "QuantumView.h" -#include "HUDView.h" -#include "Ship.h" -#include "Element.h" -#include "Sim.h" -#include "Starshatter.h" - -#include "CameraView.h" -#include "Color.h" -#include "Window.h" -#include "Video.h" -#include "Screen.h" -#include "DataLoader.h" -#include "Scene.h" -#include "FontMgr.h" -#include "FormatUtil.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Clock.h" -#include "ContentBundle.h" -#include "Menu.h" - -static Color hud_color = Color::Black; -static Color txt_color = Color::White; - -// +====================================================================+ -// -// RADIO COMMUNICATIONS MENU: -// - -static Menu* fighter_menu = 0; -static Menu* starship_menu = 0; -static Menu* target_menu = 0; -static Menu* combat_menu = 0; -static Menu* formation_menu = 0; -static Menu* sensors_menu = 0; -static Menu* mission_menu = 0; -static Menu* wing_menu = 0; -static Menu* elem_menu = 0; -static Menu* control_menu = 0; - -static int starship_page = 0; -static int num_pages = 0; -const int PAGE_SIZE = 9; - -static MenuHistory history; - -void -RadioView::Initialize() -{ - static int initialized = 0; - if (initialized) return; - - target_menu = new Menu(ContentBundle::GetInstance()->GetText("RadioView.menu.TARGET")); - target_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.attack"), RadioMessage::ATTACK); - target_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.bracket"), RadioMessage::BRACKET); - target_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.escort"), RadioMessage::ESCORT); - - combat_menu = new Menu(ContentBundle::GetInstance()->GetText("RadioView.menu.COMBAT")); - combat_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.cover"), RadioMessage::COVER_ME); - combat_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.break-attack"), RadioMessage::WEP_FREE); - combat_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.form-up"), RadioMessage::FORM_UP); - - formation_menu = new Menu(ContentBundle::GetInstance()->GetText("RadioView.menu.FORMATION")); - formation_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.diamond"), RadioMessage::GO_DIAMOND); - formation_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.spread"), RadioMessage::GO_SPREAD); - formation_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.box"), RadioMessage::GO_BOX); - formation_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.trail"), RadioMessage::GO_TRAIL); - - sensors_menu = new Menu(ContentBundle::GetInstance()->GetText("RadioView.menu.SENSORS")); - sensors_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.emcon-1"), RadioMessage::GO_EMCON1); - sensors_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.emcon-2"), RadioMessage::GO_EMCON2); - sensors_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.emcon-3"), RadioMessage::GO_EMCON3); - sensors_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.probe"), RadioMessage::LAUNCH_PROBE); - - mission_menu = new Menu(ContentBundle::GetInstance()->GetText("RadioView.menu.MISSION")); - mission_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.skip-navpt"), RadioMessage::SKIP_NAVPOINT); - mission_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.resume"), RadioMessage::RESUME_MISSION); - mission_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.rtb"), RadioMessage::RTB); - - wing_menu = new Menu(ContentBundle::GetInstance()->GetText("RadioView.menu.WINGMAN")); - wing_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.target"), target_menu); - wing_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.combat"), combat_menu); - wing_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.formation"), formation_menu); - wing_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.mission"), mission_menu); - wing_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.sensors"), sensors_menu); - - elem_menu = new Menu(ContentBundle::GetInstance()->GetText("RadioView.menu.ELEMENT")); - elem_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.target"), target_menu); - elem_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.combat"), combat_menu); - elem_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.formation"), formation_menu); - elem_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.mission"), mission_menu); - elem_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.sensors"), sensors_menu); - - control_menu = new Menu(ContentBundle::GetInstance()->GetText("RadioView.menu.CONTROL")); - control_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.picture"), RadioMessage::REQUEST_PICTURE); - control_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.backup"), RadioMessage::REQUEST_SUPPORT); - control_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.call-inbound"), RadioMessage::CALL_INBOUND); - control_menu->AddItem(ContentBundle::GetInstance()->GetText("RadioView.item.call-finals"), RadioMessage::CALL_FINALS); - - fighter_menu = new Menu(ContentBundle::GetInstance()->GetText("RadioView.menu.RADIO")); - fighter_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.wingman"), wing_menu); - fighter_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.element"), elem_menu); - fighter_menu->AddMenu(ContentBundle::GetInstance()->GetText("RadioView.item.control"), control_menu); - - starship_menu = new Menu(ContentBundle::GetInstance()->GetText("RadioView.menu.RADIO")); - - initialized = 1; -} - -void -RadioView::Close() -{ - history.Clear(); - - delete fighter_menu; - delete starship_menu; - delete target_menu; - delete combat_menu; - delete formation_menu; - delete sensors_menu; - delete mission_menu; - delete wing_menu; - delete elem_menu; - delete control_menu; -} - -static bool TargetRequired(const MenuItem* item) -{ - if (item) { - switch (item->GetData()) { - case RadioMessage::ATTACK: - case RadioMessage::BRACKET: - case RadioMessage::ESCORT: - return true; - - default: - if (item->GetData() == (DWORD) target_menu) - return true; - } - } - - return false; -} - -// +====================================================================+ - -RadioView* RadioView::radio_view = 0; -std::mutex RadioView::sync; - -RadioView::RadioView(Window* c) -: View(c), sim(0), ship(0), font(0), dst_elem(0) -{ - radio_view = this; - sim = Sim::GetSim(); - - width = window->Width(); - height = window->Height(); - xcenter = (width / 2.0) - 0.5; - ycenter = (height / 2.0) + 0.5; - font = FontMgr::Find("HUD"); - - HUDView* hud = HUDView::GetInstance(); - if (hud) - SetColor(hud->GetTextColor()); - - for (int i = 0; i < MAX_MSG; i++) - msg_time[i] = 0; -} - -RadioView::~RadioView() -{ - radio_view = 0; -} - -void -RadioView::OnWindowMove() -{ - width = window->Width(); - height = window->Height(); - xcenter = (width / 2.0) - 0.5; - ycenter = (height / 2.0) + 0.5; -} - -// +--------------------------------------------------------------------+ - -bool -RadioView::Update(SimObject* obj) -{ - if (obj == ship) { - ship = 0; - history.Clear(); - } - - return SimObserver::Update(obj); -} - -const char* -RadioView::GetObserverName() const -{ - return "RadioView"; -} - -// +--------------------------------------------------------------------+ - -void -RadioView::Refresh() -{ - sim = Sim::GetSim(); - - if (!font) - return; - - font->SetColor(txt_color); - font->SetAlpha(1); - - if (sim && ship != sim->GetPlayerShip()) { - ship = sim->GetPlayerShip(); - history.Clear(); - - if (ship) { - if (ship->Life() == 0 || ship->IsDying() || ship->IsDead()) { - ship = 0; - } - else { - Observe(ship); - } - } - } - - QuantumView* qv = QuantumView::GetInstance(); - - if (!qv || !qv->IsMenuShown()) { - Menu* menu = history.GetCurrent(); - - if (menu) { - Rect menu_rect(width-115, 10, 115, 12); - - font->DrawText(menu->GetTitle(), 0, menu_rect, DT_CENTER); - menu_rect.y += 15; - - ListIter item = menu->GetItems(); - while (++item) { - if (ship->GetEMCON() < 2 || - (TargetRequired(item.value()) && !ship->GetTarget()) || - item->GetText().contains("KIA")) { - item->SetEnabled(false); - font->SetAlpha(0.35); - } - else { - item->SetEnabled(true); - font->SetAlpha(1); - } - - font->DrawText(item->GetText(), 0, menu_rect, DT_LEFT); - menu_rect.y += 10; - } - } - } - - int message_queue_empty = true; - - // age messages: - for (int i = 0; i < MAX_MSG; i++) { - if (msg_time[i] > 0) { - msg_time[i] -= Clock::GetInstance()->GuiDelta(); - - if (msg_time[i] <= 0) { - msg_time[i] = 0; - msg_text[i] = ""; - } - - message_queue_empty = false; - } - } - - if (!message_queue_empty) { - // advance message pipeline: - for (int i = 0; i < MAX_MSG; i++) { - if (msg_time[0] == 0) { - for (int j = 0; j < MAX_MSG-1; j++) { - msg_time[j] = msg_time[j+1]; - msg_text[j] = msg_text[j+1]; - } - - msg_time[MAX_MSG-1] = 0; - msg_text[MAX_MSG-1] = ""; - } - } - - bool hud_off = false; - - if (HUDView::GetInstance()) - hud_off = (HUDView::GetInstance()->GetHUDMode() == HUDView::HUD_MODE_OFF); - - // draw messages: - if (!hud_off) { - for (int i = 0; i < MAX_MSG; i++) { - if (msg_time[i] > 0) { - Rect msg_rect(0, 95 + i*10, width, 12); - - if (msg_time[i] > 1) - font->SetAlpha(1); - else - font->SetAlpha(0.5 + 0.5*msg_time[i]); - - font->DrawText(msg_text[i].data(), msg_text[i].length(), msg_rect, DT_CENTER); - } - } - - font->SetAlpha(1); - } - } - - Starshatter* stars = Starshatter::GetInstance(); - if (stars && stars->GetChatMode()) { - Text chat; - - switch (stars->GetChatMode()) { - case 1: chat = "ALL: "; break; - case 2: chat = "TEAM: "; break; - case 3: chat = "WING: "; break; - case 4: chat = "UNIT: "; break; - } - - chat += stars->GetChatText(); - - Rect chat_rect(width/2 - 250, height-150, 500, 12); - font->DrawText(chat, 0, chat_rect, DT_LEFT); - - chat_rect.Inflate(2,2); - window->DrawRect(chat_rect, hud_color); - } -} - -// +--------------------------------------------------------------------+ - -void -RadioView::SendRadioMessage(Ship* ship, MenuItem* item) -{ - if (!ship || !item) return; - Element* elem = ship->GetElement(); - if (!elem) return; - - // check destination: - if (dst_elem) { - RadioMessage* msg = new RadioMessage(dst_elem, ship, item->GetData()); - - if (TargetRequired(item)) - msg->AddTarget(ship->GetTarget()); - - RadioTraffic::Transmit(msg); - dst_elem = 0; - } - - else if (history.Find(ContentBundle::GetInstance()->GetText("RadioView.menu.WINGMAN"))) { // wingman menu - int index = ship->GetElementIndex(); - int wing = 0; - - switch (index) { - case 1: wing = 2; break; - case 2: wing = 1; break; - case 3: wing = 4; break; - case 4: wing = 3; break; - } - - if (wing) { - Ship* dst = elem->GetShip(wing); - if (dst) { - RadioMessage* msg = new RadioMessage(dst, ship, item->GetData()); - - if (TargetRequired(item)) - msg->AddTarget(ship->GetTarget()); - - RadioTraffic::Transmit(msg); - } - } - } - - else if (history.Find(ContentBundle::GetInstance()->GetText("RadioView.menu.ELEMENT"))) { // element menu - RadioMessage* msg = new RadioMessage(elem, ship, item->GetData()); - - if (TargetRequired(item)) - msg->AddTarget(ship->GetTarget()); - - RadioTraffic::Transmit(msg); - } - - else if (history.Find(ContentBundle::GetInstance()->GetText("RadioView.menu.CONTROL"))) { // control menu - RadioMessage* msg = 0; - Ship* controller = ship->GetController(); - - if (controller) { - msg = new RadioMessage(controller, ship, item->GetData()); - RadioTraffic::Transmit(msg); - } - } -} - -// +--------------------------------------------------------------------+ - -void -RadioView::ExecFrame() -{ - HUDView* hud = HUDView::GetInstance(); - if (hud) { - if (txt_color != hud->GetTextColor()) { - txt_color = hud->GetTextColor(); - SetColor(txt_color); - } - - hud_color = hud->GetHUDColor(); - } - - static int current_key = 0; - - if (current_key > 0 && Keyboard::KeyDown(current_key)) - return; - - current_key = 0; - - Menu* menu = history.GetCurrent(); - if (menu) { - int max_items = menu->NumItems(); - - if (menu == starship_menu && Keyboard::KeyDown('0')) { - current_key = '0'; - if (++starship_page >= num_pages) - starship_page = 0; - - history.Pop(); - history.Push(GetRadioMenu(ship)); - } - else { - for (int i = 0; i < max_items; i++) { - if (Keyboard::KeyDown('1' + i)) { - current_key = '1' + i; - MenuItem* item = menu->GetItem(i); - if (item && item->GetEnabled()) { - if (item->GetSubmenu()) { - if (history.GetCurrent() == starship_menu) - dst_elem = (Element*) item->GetData(); - - history.Push(item->GetSubmenu()); - } - else { - // execute radio message: - SendRadioMessage(ship, item); - - // clear radio menu: - history.Clear(); - } - - break; - } - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -RadioView::SetColor(Color c) -{ - HUDView* hud = HUDView::GetInstance(); - - if (hud) { - hud_color = hud->GetHUDColor(); - txt_color = hud->GetTextColor(); - } - else { - hud_color = c; - txt_color = c; - } -} - -// +--------------------------------------------------------------------+ - -bool -RadioView::IsMenuShown() -{ - return history.GetCurrent() != 0; -} - -void -RadioView::ShowMenu() -{ - if (!ship) return; - - if (!history.GetCurrent()) { - history.Push(GetRadioMenu(ship)); - - for (int i = 0; i < 10; i++) { - if (Keyboard::KeyDown('1' + i)) { - // just need to clear the key down flag - // so we don't process old keystrokes - // as valid menu picks... - } - } - } -} - -void -RadioView::CloseMenu() -{ - history.Clear(); - dst_elem = 0; - starship_page = 0; - num_pages = 0; -} - -// +--------------------------------------------------------------------+ - -Menu* -RadioView::GetRadioMenu(Ship* s) -{ - dst_elem = 0; - - if (s && sim) { - if (s->IsStarship()) { - starship_menu->ClearItems(); - - int n = 0; - int page_offset = starship_page*PAGE_SIZE; - - ListIter elem = sim->GetElements(); - - if (num_pages == 0) { - while (++elem) { - if (elem->IsFinished() || elem->IsSquadron() || elem->IsStatic()) - continue; - - if (ship->GetIFF() == elem->GetIFF() && ship->GetElement() != elem.value()) - n++; - } - - num_pages = (n/PAGE_SIZE) + (n%PAGE_SIZE > 0); - n = 0; - elem.reset(); - } - - while (++elem) { - if (elem->IsFinished() || elem->IsSquadron() || elem->IsStatic()) - continue; - - if (ship->GetIFF() == elem->GetIFF() && ship->GetElement() != elem.value()) { - if (n >= page_offset && n < page_offset+PAGE_SIZE) { - char text[64]; - sprintf_s(text, "%d. %s", n+1 - page_offset, (const char*) elem->Name()); - - if (elem->IsActive()) { - starship_menu->AddMenu(text, elem_menu, (DWORD) elem.value()); - } - else { - strcat_s(text, " "); - strcat_s(text, ContentBundle::GetInstance()->GetText("RadioView.item.not-avail").data()); - starship_menu->AddItem(text, 0, false); - } - } - n++; - } - } - - if (num_pages > 1) { - char text[64]; - sprintf_s(text, ContentBundle::GetInstance()->GetText("RadioView.item.next-page").data(), starship_page + 1, num_pages); - starship_menu->AddItem(text); - } - - return starship_menu; - } - else if (s->IsDropship()) { - return fighter_menu; - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -RadioView::Message(const char* msg) -{ - const std::lock_guard lock(sync); - - if (radio_view) { - int index = -1; - - for (int i = 0; i < MAX_MSG; i++) { - if (radio_view->msg_time[i] <= 0) { - index = i; - break; - } - } - - // no space; advance pipeline: - if (index < 0) { - for (int i = 0; i < MAX_MSG-1; i++) { - radio_view->msg_text[i] = radio_view->msg_text[i+1]; - radio_view->msg_time[i] = radio_view->msg_time[i+1]; - } - - index = MAX_MSG-1; - } - - radio_view->msg_text[index] = msg; - radio_view->msg_time[index] = 10; - } -} - -void -RadioView::ClearMessages() -{ - if (radio_view) { - for (int i = 0; i < MAX_MSG-1; i++) { - radio_view->msg_text[i] = Text(); - radio_view->msg_time[i] = 0; - } - } -} diff --git a/Stars45/RadioView.h b/Stars45/RadioView.h deleted file mode 100644 index 1d25459..0000000 --- a/Stars45/RadioView.h +++ /dev/null @@ -1,88 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Radio Communications HUD Overlay -*/ - -#ifndef RadioView_h -#define RadioView_h - -#include - -#include "Types.h" -#include "View.h" -#include "Color.h" -#include "SimObject.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Font; -class Element; -class Ship; -class RadioMessage; -class CameraView; -class HUDView; -class Menu; -class MenuItem; - -// +--------------------------------------------------------------------+ - -class RadioView : public View, -public SimObserver -{ -public: - RadioView(Window* c); - virtual ~RadioView(); - - // Operations: - virtual void Refresh(); - virtual void OnWindowMove(); - virtual void ExecFrame(); - - virtual Menu* GetRadioMenu(Ship* ship); - virtual bool IsMenuShown(); - virtual void ShowMenu(); - virtual void CloseMenu(); - - static void Message(const char* msg); - static void ClearMessages(); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - static void SetColor(Color c); - - static void Initialize(); - static void Close(); - - static RadioView* GetInstance() { return radio_view; } - -protected: - void SendRadioMessage(Ship* ship, MenuItem* item); - - int width, height; - double xcenter, ycenter; - - Font* font; - Sim* sim; - Ship* ship; - Element* dst_elem; - - enum { MAX_MSG=6 }; - Text msg_text[MAX_MSG]; - double msg_time[MAX_MSG]; - - static RadioView* radio_view; - static std::mutex sync; -}; - -#endif // RadioView_h - diff --git a/Stars45/RadioVox.cpp b/Stars45/RadioVox.cpp deleted file mode 100644 index 8942caf..0000000 --- a/Stars45/RadioVox.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Radio Communications HUD Overlay -*/ - -#include - -#include "RadioVox.h" -#include "RadioView.h" -#include "AudioConfig.h" - -#include "DataLoader.h" -#include "Game.h" -#include "Sound.h" - -// +====================================================================+ -// -// RADIO VOX CONTROLLER: -// - -DWORD WINAPI VoxUpdateProc(LPVOID link); - -class RadioVoxController -{ -public: - enum { MAX_QUEUE = 5 }; - - RadioVoxController(); - ~RadioVoxController(); - - bool Add(RadioVox* vox); - void Update(); - DWORD UpdateThread(); - - bool shutdown; - HANDLE hthread; - List queue; - std::mutex sync; -}; - -static RadioVoxController* controller = 0; - -// +--------------------------------------------------------------------+ - -RadioVoxController::RadioVoxController() -: hthread(0), shutdown(false) -{ - DWORD thread_id = 0; - hthread = CreateThread(0, 4096, VoxUpdateProc, - (LPVOID) this, 0, &thread_id); -} - -// +--------------------------------------------------------------------+ - -RadioVoxController::~RadioVoxController() -{ - shutdown = true; - - WaitForSingleObject(hthread, 500); - CloseHandle(hthread); - hthread = 0; - - queue.destroy(); -} - -// +--------------------------------------------------------------------+ - -DWORD WINAPI VoxUpdateProc(LPVOID link) -{ - RadioVoxController* controller = (RadioVoxController*) link; - - if (controller) - return controller->UpdateThread(); - - return (DWORD) E_POINTER; -} - -// +--------------------------------------------------------------------+ - -DWORD -RadioVoxController::UpdateThread() -{ - while (!shutdown) { - Update(); - Sleep(50); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -RadioVoxController::Update() -{ - const std::lock_guard lock(sync); - - if (queue.size()) { - RadioVox* vox = queue.first(); - - if (!vox->Update()) - delete queue.removeIndex(0); - } -} - -bool -RadioVoxController::Add(RadioVox* vox) -{ - if (!vox || vox->sounds.isEmpty()) - return false; - - const std::lock_guard lock(sync); - - if (queue.size() < MAX_QUEUE) { - queue.append(vox); - return true; - } - - return false; -} - -// +====================================================================+ -// -// RADIO VOX MESSAGE: -// - -void -RadioVox::Initialize() -{ - if (!controller) { - controller = new RadioVoxController; - } -} - -void -RadioVox::Close() -{ - delete controller; - controller = 0; -} - -// +--------------------------------------------------------------------+ - -RadioVox::RadioVox(int n, const char* p, const char* m) -: path(p), message(m), index(0), channel(n) -{ -} - -RadioVox::~RadioVox() -{ - sounds.destroy(); -} - -// +--------------------------------------------------------------------+ - -bool -RadioVox::AddPhrase(const char* key) -{ - if (AudioConfig::VoxVolume() <= AudioConfig::Silence()) - return false; - - DataLoader* loader = DataLoader::GetLoader(); - if (!loader) - return false; - - if (key && *key) { - char datapath[256]; - char filename[256]; - - sprintf_s(datapath, "Vox/%s/", path.data()); - sprintf_s(filename, "%s.wav", key); - - bool use_fs = loader->IsFileSystemEnabled(); - Sound* sound = 0; - - loader->UseFileSystem(true); - loader->SetDataPath(datapath); - loader->LoadSound(filename, sound, Sound::LOCALIZED, true); // optional sound - loader->SetDataPath(0); - loader->UseFileSystem(use_fs); - - if (sound) { - sound->SetVolume(AudioConfig::VoxVolume()); - sound->SetFlags(Sound::LOCALIZED | Sound::LOCKED); - sound->SetFilename(filename); - sounds.append(sound); - - return true; - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -RadioVox::Start() -{ - if (controller) - return controller->Add(this); - - return false; -} - -bool -RadioVox::Update() -{ - if (message.length()) { - RadioView::Message(message); - message = ""; - } - - bool active = false; - - while (!active && index < sounds.size()) { - Sound* s = sounds[index]; - - if (s->IsReady()) { - if (channel & 1) - s->SetPan(channel * -3000); - else - s->SetPan(channel * 3000); - - s->Play(); - active = true; - } - - else if (s->IsPlaying()) { - s->Update(); - active = true; - } - - else { - index++; - } - } - - return active; -} diff --git a/Stars45/RadioVox.h b/Stars45/RadioVox.h deleted file mode 100644 index 447b854..0000000 --- a/Stars45/RadioVox.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Radio Communications HUD Overlay -*/ - -#ifndef RadioVox_h -#define RadioVox_h - -#include "Types.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Element; -class Ship; -class RadioMessage; -class Sound; - -// +--------------------------------------------------------------------+ - -class RadioVox -{ - friend class RadioVoxController; - -public: - static const char* TYPENAME() { return "RadioVox"; } - - RadioVox(int channel, const char* path, const char* message=0); - virtual ~RadioVox(); - - // Operations: - virtual bool AddPhrase(const char* key); - virtual bool Start(); - - static void Initialize(); - static void Close(); - -protected: - virtual bool Update(); - - Text path; - Text message; - List sounds; - int index; - int channel; -}; - -#endif // RadioVox_h - diff --git a/Stars45/Random.cpp b/Stars45/Random.cpp deleted file mode 100644 index 18f6031..0000000 --- a/Stars45/Random.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Utility functions for generating random numbers and locations. -*/ - -#include "Random.h" - -// +----------------------------------------------------------------------+ - -void RandomInit() -{ - srand(timeGetTime()); -} - -// +----------------------------------------------------------------------+ - -Point RandomDirection() -{ - Point p = Point(rand() - 16384, rand() - 16384, 0); - p.Normalize(); - return p; -} - -// +----------------------------------------------------------------------+ - -Point RandomPoint() -{ - Point p = Point(rand() - 16384, rand() - 16384, 0); - p.Normalize(); - p *= 15e3 + rand()/3; - return p; -} - -// +----------------------------------------------------------------------+ - -Vec3 RandomVector(double radius) -{ - Vec3 v = Vec3(rand() - 16384, rand() - 16384, rand() - 16384); - v.Normalize(); - - if (radius > 0) - v *= (float) radius; - else - v *= (float) Random(radius/3, radius); - - return v; -} - -// +----------------------------------------------------------------------+ - -double Random(double min, double max) -{ - double delta = max - min; - double r = delta * rand() / 32768.0; - - return min + r; -} - -// +----------------------------------------------------------------------+ - -int RandomIndex() -{ - static int index = 0; - static int table[16] = { 0, 9, 4, 7, 14, 11, 2, 12, 1, 5, 13, 8, 6, 10, 3, 15 }; - - int r = 1 + ((rand() & 0x0700) >> 8); - index += r; - if (index > 1e7) index = 0; - return table[index % 16]; -} - -// +----------------------------------------------------------------------+ - -bool RandomChance(int wins, int tries) -{ - double fraction = 256.0 * wins / tries; - double r = (rand() >> 4) & 0xFF; - - return r < fraction; -} - -// +----------------------------------------------------------------------+ - -int RandomSequence(int current, int range) -{ - if (range > 1) { - int step = (int) Random(1, range-1); - return (current + step) % range; - } - - return current; -} - -// +----------------------------------------------------------------------+ - -int RandomShuffle(int count) -{ - static int set_size = -1; - static BYTE set[256]; - static int index = -1; - - if (count < 0 || count > 250) - return 0; - - if (set_size != count) { - set_size = count; - index = -1; - } - - // need to reshuffle - if (index < 0 || index > set_size-1) { - // set up the deck - int tmp[256]; - for (int i = 0; i < 256; i++) - tmp[i] = i; - - // shuffle the cards - for (int i = 0; i < set_size; i++) { - int n = (int) Random(0, set_size); - int tries = set_size; - while (tmp[n] < 0 && tries--) { - n = (n+1) % set_size; - } - - if (tmp[n] >= 0) { - set[i] = tmp[n]; - tmp[n] = -1; - } - else { - set[i] = 0; - } - } - - index = 0; - } - - return set[index++]; -} diff --git a/Stars45/Random.h b/Stars45/Random.h deleted file mode 100644 index 01f4f57..0000000 --- a/Stars45/Random.h +++ /dev/null @@ -1,34 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Utility functions for generating random numbers and locations. -*/ - -#ifndef Random_h -#define Random_h - -#include "Types.h" -#include "Geometry.h" - -// +----------------------------------------------------------------------+ - -void RandomInit(); -Point RandomDirection(); -Point RandomPoint(); -Vec3 RandomVector(double radius); -double Random(double min=0, double max=1); -int RandomIndex(); -bool RandomChance(int wins=1, int tries=2); -int RandomSequence(int current, int range); -int RandomShuffle(int count); - -// +----------------------------------------------------------------------+ - -#endif // Random_h diff --git a/Stars45/Reader.cpp b/Stars45/Reader.cpp deleted file mode 100644 index 682627d..0000000 --- a/Stars45/Reader.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Implementation of the Reader class -*/ - -#include "Reader.h" -#include -#include -#include -#include "Utils.h" - -// +-------------------------------------------------------------------+ - -Text -ConsoleReader::more() -{ - // loop until the user types something - do { - printPrimaryPrompt(); - fillInputBuffer(); - } while (! *p); - - return Text(p); -} - -void -ConsoleReader::printPrimaryPrompt() -{ - printf("- "); -} - -void -ConsoleReader::fillInputBuffer() -{ - fgets(buffer, 980, stdin); - p = buffer; - while (isspace(*p)) p++; -} - -// +-------------------------------------------------------------------+ - -FileReader::FileReader(const char* fname) - : filename(fname), done(0) -{ } - -Text -FileReader::more() -{ - if (done) return Text(); - - std::fstream fin(filename, std::fstream::in); - - if (!fin) { - Print("ERROR(Parse): Could not open file '%s'\n", filename.data()); - return Text(); - } - - Text result; - char buf[1000], newline; - - while (fin.get(buf, 1000)) { - result.append(buf); - fin.get(newline); - result.append(newline); - } - - done = 1; - return result; -} - -// +-------------------------------------------------------------------+ - -BlockReader::BlockReader(const char* block) - : data((char*) block), done(0), length(0) -{ } - -BlockReader::BlockReader(const char* block, int len) - : data((char*) block), done(0), length(len) -{ } - -Text -BlockReader::more() -{ - if (done) return Text(); - - if (length) { - Text result(data, length); - done = 1; - return result; - } - else if (data) { - Text result(data); - done = 1; - return result; - } - - done = 1; - return Text(); -} - - diff --git a/Stars45/Reader.h b/Stars45/Reader.h deleted file mode 100644 index e1154d1..0000000 --- a/Stars45/Reader.h +++ /dev/null @@ -1,67 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Declaration of the Reader class -*/ - -#ifndef READER_H -#define READER_H - -#include "Text.h" - -// +-------------------------------------------------------------------+ - -class Reader -{ -public: - Reader() { } - virtual ~Reader() { } - - virtual Text more() = 0; -}; - -class ConsoleReader : public Reader -{ -public: - virtual Text more(); - - void printPrimaryPrompt(); - void fillInputBuffer(); - -private: - char buffer[1000]; - char* p; -}; - -class FileReader : public Reader -{ -public: - FileReader(const char* fname); - virtual Text more(); - -private: - Text filename; - int done; -}; - -class BlockReader : public Reader -{ -public: - BlockReader(const char* block); - BlockReader(const char* block, int len); - virtual Text more(); - -private: - char* data; - int done; - int length; -}; - -#endif diff --git a/Stars45/Res.cpp b/Stars45/Res.cpp deleted file mode 100644 index f6a160e..0000000 --- a/Stars45/Res.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract Resource class -*/ - -#include "Res.h" - -// +--------------------------------------------------------------------+ - -static int RESOURCE_KEY = 1; - -Resource::Resource() -: id((HANDLE) RESOURCE_KEY++) -{ } - -Resource::~Resource() -{ } - diff --git a/Stars45/Res.h b/Stars45/Res.h deleted file mode 100644 index dbd1295..0000000 --- a/Stars45/Res.h +++ /dev/null @@ -1,36 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract Resource class -*/ - -#ifndef Res_h -#define Res_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class Resource -{ -public: - Resource(); - virtual ~Resource(); - - int operator == (const Resource& r) const { return id == r.id; } - - HANDLE Handle() const { return id; } - -protected: - HANDLE id; -}; - -#endif // Res_h - diff --git a/Stars45/RichTextBox.cpp b/Stars45/RichTextBox.cpp deleted file mode 100644 index fe64f0d..0000000 --- a/Stars45/RichTextBox.cpp +++ /dev/null @@ -1,452 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Window class -*/ - -#include "RichTextBox.h" -#include "EventDispatch.h" -#include "Color.h" -#include "Bitmap.h" -#include "Font.h" -#include "FontMgr.h" -#include "Mouse.h" -#include "Screen.h" -#include "View.h" - -// +--------------------------------------------------------------------+ - -RichTextBox::RichTextBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid, DWORD astyle) -: ScrollWindow(p->GetScreen(), ax, ay, aw, ah, aid, astyle, p) -{ - leading = 2; - - char buf[32]; - sprintf_s(buf, "RichTextBox %d", id); - desc = buf; -} - -RichTextBox::RichTextBox(Screen* screen, int ax, int ay, int aw, int ah, DWORD aid, DWORD astyle) -: ScrollWindow(screen, ax, ay, aw, ah, aid, astyle) -{ - leading = 2; - - char buf[32]; - sprintf_s(buf, "RichTextBox %d", id); - desc = buf; -} - -RichTextBox::~RichTextBox() -{ -} - -// +--------------------------------------------------------------------+ - -void -RichTextBox::SetText(const char* t) -{ - ActiveWindow::SetText(t); - ScrollTo(0); -} - -// +--------------------------------------------------------------------+ - -void -RichTextBox::DrawContent(const Rect& ctrl_rect) -{ - DrawTabbedText(); -} - -// +--------------------------------------------------------------------+ - -void -RichTextBox::DrawTabbedText() -{ - if (font && text.length()) { - int border_size = 4; - - if (style & WIN_RAISED_FRAME && style & WIN_SUNK_FRAME) - border_size = 8; - - Rect label_rect = rect; - - label_rect.x = border_size; - label_rect.y = border_size; - label_rect.w -= border_size * 2; - label_rect.h -= border_size * 2; - - if (scroll_bar) - label_rect.w -= SCROLL_TRACK; - - if (line_height < font->Height()) - line_height = font->Height(); - - font->SetColor(fore_color); - DrawRichText(label_rect); - } -} - -// +--------------------------------------------------------------------+ - -int RichTextBox::find_next_word_start(const char* text, int index) -{ - // step through intra-word space: - while (text[index] && isspace(text[index]) && - (text[index] != '\t') && - (text[index] != '\n') && - (text[index] != '<')) - index++; - - return index; -} - -int RichTextBox::find_next_word_end(const char* text, int index) -{ - // check for leading newline or tag: - if (text[index] == '\n' || text[index] == '\t' || text[index] == '<') - return index; - - // step through intra-word space: - while (text[index] && isspace(text[index])) - index++; - - // step through word: - while (text[index] && !isspace(text[index]) && - (text[index] != '-') && - (text[index] != '<')) - index++; - - if (index) { - if (text[index] != '-') - return index-1; - else - return index; - } - - return 0; -} - -int RichTextBox::parse_hex_digit(char c) -{ - if (isalpha(c)) - return 10 + tolower(c) - 'a'; - - else if (isdigit(c)) - return c - '0'; - - return 0; -} - -int RichTextBox::process_tag(const char* text, int index, Font*& font) -{ - if (text[index] == '<') { - char tag[64]; - int i = 0; - - while (text[index] && (text[index] != '>')) - tag[i++] = text[index++]; - - if (text[index] == '>') - tag[i++] = text[index++]; - - tag[i] = 0; - - switch (tag[1]) { - case 'c': - case 'C': if (_strnicmp(tag+1, "color", 5) == 0) { - int r = 0; - int g = 0; - int b = 0; - - if (i > 12) { - r = 16 * parse_hex_digit(tag[ 7]) + parse_hex_digit(tag[ 8]); - g = 16 * parse_hex_digit(tag[ 9]) + parse_hex_digit(tag[10]); - b = 16 * parse_hex_digit(tag[11]) + parse_hex_digit(tag[12]); - } - - font->SetColor(Color(r,g,b)); - } - break; - - case 'f': - case 'F': if (_strnicmp(tag+1, "font", 4) == 0) { - Color current_color = Color::White; - - if (font) - current_color = font->GetColor(); - - tag[i-1] = 0; - font = FontMgr::Find(tag+6); - font->SetColor(current_color); - } - break; - } - } - - return index; -} - -int -RichTextBox::GetNextTab(int xpos) -{ - for (int i = 0; i < 10; i++) { - if (tab[i] > xpos) - return tab[i]; - } - - return (xpos / 20) * 20 + 20; -} - -void -RichTextBox::DrawRichText(Rect& text_rect) -{ - // clip the rect: - Rect clip_rect = ClipRect(text_rect); - clip_rect.h -= 8; - - if (clip_rect.w < 1 || clip_rect.h < 1) - return; - - const char* t = text.data(); - int count = text.length(); - int nlines = 0; - - int xpos = 0; - int block_start = 0; - int block_count = 0; - int curr_word_end = -1; - int next_word_end = 0; - int eol_index = 0; - - int new_line = 0; - int x_offset = 0; - int y_offset = 0; - int length = 0; - - Font* rich_font = font; - rich_font->SetColor(fore_color); - - if (smooth_scroll) { - double fraction = smooth_offset - (int) smooth_offset; - - y_offset = (int) ((1-fraction) * (rich_font->Height() + leading)); - } - - // while there is still text: - while (block_start < count) { - bool found_tag = false; - - do { - found_tag = false; - - if (t[block_start] == '<') { - block_start = process_tag(t, block_start, rich_font); - found_tag = true; - } - - else if (t[block_start] == '\t') { - block_start++; - x_offset = GetNextTab(x_offset); - - if (x_offset > text_rect.w) { - nlines++; - if (nlines > top_index) - y_offset += rich_font->Height() + leading; - x_offset = 0; - new_line = false; - } - - found_tag = true; - } - - else if (t[block_start] == '\r') { - block_start++; - - if (t[block_start] == '\n') - block_start++; - - nlines++; - if (nlines > top_index) - y_offset += rich_font->Height() + leading; - x_offset = 0; - new_line = false; - - found_tag = true; - } - - else if (t[block_start] == '\n') { - block_start++; - - if (t[block_start] == '\r') - block_start++; - - nlines++; - if (nlines > top_index) - y_offset += rich_font->Height() + leading; - x_offset = 0; - new_line = false; - - found_tag = true; - } - } - while (found_tag); - - next_word_end = find_next_word_end(t, block_start); - - if (!next_word_end || next_word_end == curr_word_end) { - new_line = true; - } - - else if (t[next_word_end] == '\n') { - eol_index = curr_word_end = next_word_end; - new_line = true; - } - - else { - int word_len = next_word_end - block_start + 1; - - length = rich_font->StringWidth(t+block_start, word_len); - - // if this word was too long, wrap to next line: - if (x_offset + length > text_rect.w) { - nlines++; - if (nlines > top_index) - y_offset += rich_font->Height() + leading; - x_offset = 0; - new_line = false; - } - - // is there a trailing newline? - curr_word_end = next_word_end; - - // check for a newline in the next block of white space: - eol_index = 0; - const char* eol = &t[curr_word_end+1]; - while (*eol && isspace(*eol) && *eol != '\n') - eol++; - - if (*eol == '\n') { - eol_index = eol - t; - new_line = true; - } - } - - block_count = curr_word_end - block_start + 1; - - if (block_count > 0) { - length = rich_font->StringWidth(t+block_start, block_count); - } - - // there was a single word longer than the entire line: - else { - block_count = next_word_end - block_start + 1; - length = rich_font->StringWidth(t+block_start, block_count); - curr_word_end = next_word_end; - } - - if (length > 0 && nlines >= top_index && nlines < top_index+page_size) { - int x1 = text_rect.x + x_offset + rect.x; - int y1 = text_rect.y + y_offset + rect.y; - - rich_font->DrawString(t+block_start, block_count, x1, y1, clip_rect); - } - - if (new_line) { - nlines++; - if (nlines > top_index) - y_offset += rich_font->Height() + leading; - x_offset = 0; - new_line = false; - } - - else if (length < 1 || text[next_word_end] == '-') { - x_offset += length; - } - - else { - x_offset += length + rich_font->SpaceWidth(); - } - - if (eol_index > 0) - curr_word_end = eol_index; - - block_start = find_next_word_start(t, curr_word_end+1); - } - - line_count = nlines; -} - -// +--------------------------------------------------------------------+ - -int RichTextBox::OnMouseMove(int x, int y) -{ - if (captured) { - ActiveWindow* test = GetCapture(); - - if (test != this) { - captured = false; - } - - else { - if (scrolling == SCROLL_THUMB) { - mouse_y = y - rect.y - TRACK_START; - - int dest = (int) ((double) mouse_y/track_length * (line_count-1)); - ScrollTo(dest); - } - } - } - - return ActiveWindow::OnMouseMove(x,y); -} - -// +--------------------------------------------------------------------+ - -int RichTextBox::OnLButtonDown(int x, int y) -{ - return ScrollWindow::OnLButtonDown(x,y); -} - -// +--------------------------------------------------------------------+ - -int RichTextBox::OnLButtonUp(int x, int y) -{ - return ScrollWindow::OnLButtonUp(x,y); -} - -// +--------------------------------------------------------------------+ - -int RichTextBox::OnMouseWheel(int wheel) -{ - return ScrollWindow::OnMouseWheel(wheel); -} - -// +--------------------------------------------------------------------+ - -int RichTextBox::OnClick() -{ - int fire_click = !scrolling; - - if (scrolling == SCROLL_THUMB) - scrolling = SCROLL_NONE; - - if (fire_click) - return ActiveWindow::OnClick(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -int RichTextBox::OnKeyDown(int vk, int flags) -{ - return ScrollWindow::OnKeyDown(vk, flags); -} - diff --git a/Stars45/RichTextBox.h b/Stars45/RichTextBox.h deleted file mode 100644 index 826d483..0000000 --- a/Stars45/RichTextBox.h +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Rich Text Window - an HTML-like control -*/ - -#ifndef RichTextBox_h -#define RichTextBox_h - -#include "Types.h" -#include "Color.h" -#include "Bitmap.h" -#include "ScrollWindow.h" -#include "EventTarget.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class RichTextBox : public ScrollWindow -{ -public: - static const char* TYPENAME() { return "RichTextBox"; } - - RichTextBox(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid=0, DWORD astyle=0); - RichTextBox(Screen* s, int ax, int ay, int aw, int ah, DWORD aid=0, DWORD astyle=0); - virtual ~RichTextBox(); - - int operator == (const RichTextBox& w) const { return id == w.id; } - - // Operations: - virtual void DrawContent(const Rect& ctrl_rect); - virtual void SetText(const char* t); - - // Event Target Interface: - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnMouseWheel(int wheel); - virtual int OnClick(); - - virtual int OnKeyDown(int vk, int flags); - -protected: - virtual void DrawTabbedText(); - virtual void DrawRichText(Rect& text_rect); - int GetNextTab(int xpos); - - virtual int find_next_word_start(const char* text, int index); - virtual int find_next_word_end(const char* text, int index); - virtual int parse_hex_digit(char c); - virtual int process_tag(const char* text, int index, Font*& font); - -}; - -#endif // RichTextBox_h - diff --git a/Stars45/Scene.cpp b/Stars45/Scene.cpp deleted file mode 100644 index 4f977f4..0000000 --- a/Stars45/Scene.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A 3D Scene -*/ - -#include "Scene.h" -#include "Graphic.h" -#include "Light.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -Scene::Scene() -{ } - -Scene::~Scene() -{ - background.destroy(); - foreground.destroy(); - graphics.destroy(); - sprites.destroy(); - - lights.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -Scene::AddBackground(Graphic* g) -{ - if (g) { - if (!background.contains(g)) - background.append(g); - - g->SetScene(this); - } -} - -void -Scene::DelBackground(Graphic* g) -{ - if (g) { - background.remove(g); - g->SetScene(0); - } -} - -// +--------------------------------------------------------------------+ - -void -Scene::AddForeground(Graphic* g) -{ - if (g) { - if (!foreground.contains(g)) - foreground.append(g); - - g->SetScene(this); - } -} - -void -Scene::DelForeground(Graphic* g) -{ - if (g) { - foreground.remove(g); - g->SetScene(0); - } -} - -// +--------------------------------------------------------------------+ - -void -Scene::AddGraphic(Graphic* g) -{ - if (g) { - if (!graphics.contains(g)) - graphics.append(g); - - g->SetScene(this); - } -} - -void -Scene::DelGraphic(Graphic* g) -{ - if (g) { - graphics.remove(g) || // it's gotta be in here somewhere! - foreground.remove(g) || // use the logical-or operator to early - sprites.remove(g) || // out when we find it... - background.remove(g); - - g->SetScene(0); - } -} - -// +--------------------------------------------------------------------+ - -void -Scene::AddSprite(Graphic* g) -{ - if (g) { - if (!sprites.contains(g)) - sprites.append(g); - - g->SetScene(this); - } -} - -void -Scene::DelSprite(Graphic* g) -{ - if (g) { - sprites.remove(g); - g->SetScene(0); - } -} - -// +--------------------------------------------------------------------+ - -void -Scene::AddLight(Light* l) -{ - if (l) { - if (!lights.contains(l)) - lights.append(l); - l->SetScene(this); - } -} - -void -Scene::DelLight(Light* l) -{ - if (l) { - lights.remove(l); - l->SetScene(0); - } -} - -// +--------------------------------------------------------------------+ - -void -Scene::Collect() -{ - ListIter iter = graphics; - - while (++iter) { - Graphic* g = iter.value(); - if (g->Life() == 0) { - delete iter.removeItem(); - } - } - - iter.attach(sprites); - - while (++iter) { - Graphic* g = iter.value(); - if (g->Life() == 0) { - delete iter.removeItem(); - } - } - - ListIter iter1 = lights; - - while (++iter1) { - Light* l = iter1.value(); - if (l->Life() == 0) { - delete iter1.removeItem(); - } - } -} - - -// +--------------------------------------------------------------------+ - -bool -Scene::IsLightObscured(const Point& obj_pos, const Point& light_pos, double obj_radius, Point* impact_point) const -{ - Point dir = light_pos - obj_pos; - double len = dir.Normalize(); - - Scene* pThis = (Scene*) this; // cast-away const - Graphic* g = 0; - bool obscured = false; - - ListIter g_iter = pThis->graphics; - while (++g_iter && !obscured) { - g = g_iter.value(); - - if (g->CastsShadow() && !g->Hidden() && !g->IsInfinite()) { - double gdist = (g->Location() - obj_pos).length(); - if (gdist > 0.1 && // different than object being obscured - g->Radius() > obj_radius && // larger than object being obscured - (g->Radius()*400)/gdist > 10) { // projects to a resonable size - - Point delta = (g->Location() - light_pos); - - if (delta.length() > g->Radius() / 100) { // not the object that is emitting the light - Point impact; - obscured = g->CheckRayIntersection(obj_pos, dir, len, impact, false) ? true : false; - - if (impact_point) - *impact_point = impact; - } - } - - else if (obj_radius < 0 && gdist < 0.1) { // special case for camera (needed for cockpits) - Point delta = (g->Location() - light_pos); - - if (delta.length() > g->Radius() / 100) { // not the object that is emitting the light - Point impact; - obscured = g->CheckRayIntersection(obj_pos, dir, len, impact, false) ? true : false; - } - } - } - } - - g_iter.attach(pThis->foreground); - while (++g_iter && !obscured) { - g = g_iter.value(); - - if (g->CastsShadow() && !g->Hidden()) { - double gdist = (g->Location() - obj_pos).length(); - if (gdist > 0.1 && // different than object being obscured - g->Radius() > obj_radius && // larger than object being obscured - (g->Radius()*400)/gdist > 10) { // projects to a resonable size - - Point delta = (g->Location() - light_pos); - - if (delta.length() > g->Radius() / 100) { // not the object that is emitting the light - Point impact; - obscured = g->CheckRayIntersection(obj_pos, dir, len, impact, false) ? true : false; - - if (impact_point) - *impact_point = impact; - } - } - - else if (obj_radius < 0 && gdist < 0.1) { // special case for camera (needed for cockpits) - Point delta = (g->Location() - light_pos); - - if (delta.length() > g->Radius() / 100) { // not the object that is emitting the light - Point impact; - obscured = g->CheckRayIntersection(obj_pos, dir, len, impact, false) ? true : false; - } - } - } - } - - return obscured; -} diff --git a/Stars45/Scene.h b/Stars45/Scene.h deleted file mode 100644 index c1c955b..0000000 --- a/Stars45/Scene.h +++ /dev/null @@ -1,75 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A 3D Scene, basically a collection of 3D graphic objects -*/ - -#ifndef Scene_h -#define Scene_h - -#include "Types.h" -#include "Color.h" -#include "Geometry.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Graphic; -class Light; - -// +--------------------------------------------------------------------+ - -class Scene -{ -public: - static const char* TYPENAME() { return "Scene"; } - - Scene(); - virtual ~Scene(); - - void AddBackground(Graphic* g); - void DelBackground(Graphic* g); - void AddForeground(Graphic* g); - void DelForeground(Graphic* g); - void AddGraphic(Graphic* g); - void DelGraphic(Graphic* g); - void AddSprite(Graphic* g); - void DelSprite(Graphic* g); - - void AddLight(Light* l); - void DelLight(Light* l); - - List& Background() { return background; } - List& Foreground() { return foreground; } - List& Graphics() { return graphics; } - List& Sprites() { return sprites; } - List& Lights() { return lights; } - Color Ambient() { return ambient; } - void SetAmbient(Color a) { ambient = a; } - - virtual void Collect(); - - virtual bool IsLightObscured(const Point& obj_pos, - const Point& light_pos, - double obj_radius, - Point* imp_point=0) const; - -protected: - List background; - List foreground; - List graphics; - List sprites; - List lights; - Color ambient; -}; - -// +--------------------------------------------------------------------+ - -#endif // Scene_h diff --git a/Stars45/Screen.cpp b/Stars45/Screen.cpp deleted file mode 100644 index 36dd577..0000000 --- a/Stars45/Screen.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - General Screen class - maintains and displays a list of windows -*/ - -#include "Screen.h" -#include "Bitmap.h" -#include "Color.h" -#include "Window.h" -#include "Mouse.h" -#include "Pcx.h" -#include "Video.h" - -// +--------------------------------------------------------------------+ - -Screen::Screen(Video* v) -: width(0), height(0), video(v), clear(0), closed(0) -{ - if (video) { - width = video->Width(); - height = video->Height(); - } - - Mouse::Create(this); -} - -Screen::~Screen() -{ - Mouse::Close(); - - closed = 1; - window_list.destroy(); -} - -// +--------------------------------------------------------------------+ - -bool -Screen::AddWindow(Window* c) -{ - if (!c || closed) return false; - - if (c->X() < 0) return false; - if (c->Y() < 0) return false; - if (c->X() + c->Width() > Width()) return false; - if (c->Y() + c->Height() > Height()) return false; - - if (!window_list.contains(c)) - window_list.append(c); - - return true; -} - -bool -Screen::DelWindow(Window* c) -{ - if (!c || closed) return false; - - return window_list.remove(c) == c; -} - -// +--------------------------------------------------------------------+ - -void -Screen::ClearAllFrames(bool clear_all) -{ - if (clear_all) - clear = -1; - else - clear = 0; -} - -void -Screen::ClearNextFrames(int num_frames) -{ - if (clear >= 0 && clear < num_frames) - clear = num_frames; -} - -// +--------------------------------------------------------------------+ - -bool -Screen::SetBackgroundColor(Color c) -{ - if (video) - return video->SetBackgroundColor(c); - else - return false; -} - -// +--------------------------------------------------------------------+ - -bool -Screen::Resize(int w, int h) -{ - // scale all root-level windows to new screen size: - - ListIter iter = window_list; - while (++iter) { - Window* win = iter.value(); - Rect tmprect = win->GetRect(); - - double w_x = tmprect.x / (double) width; - double w_y = tmprect.y / (double) height; - double w_w = tmprect.w / (double) width; - double w_h = tmprect.h / (double) height; - - Rect r; - - r.x = (int) (w_x * w); - r.y = (int) (w_y * h); - r.w = (int) (w_w * w); - r.h = (int) (w_h * h); - - win->MoveTo(r); - } - - width = w; - height = h; - - return true; -} - -// +--------------------------------------------------------------------+ - -bool -Screen::Refresh() -{ - if (clear && !video->ClearAll()) - return false; - - video->StartFrame(); - - ListIter iter = window_list; - while (++iter) { - Window* win = iter.value(); - - if (win->IsShown()) { - win->Paint(); - } - } - - Mouse::Paint(); - - video->EndFrame(); - - if (clear > 0) clear--; - return true; -} - - - - diff --git a/Stars45/Screen.h b/Stars45/Screen.h deleted file mode 100644 index 3fe966a..0000000 --- a/Stars45/Screen.h +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - General Screen class - maintains and displays a list of windows -*/ - -#ifndef Screen_h -#define Screen_h - -#include "Types.h" -#include "Color.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Bitmap; -class Window; -struct Rect; - -// +--------------------------------------------------------------------+ - -class Screen -{ -public: - static const char* TYPENAME() { return "Screen"; } - - Screen(Video* v); - virtual ~Screen(); - - virtual bool SetBackgroundColor(Color c); - - virtual bool Resize(int w, int h); - virtual bool Refresh(); - virtual bool AddWindow(Window* c); - virtual bool DelWindow(Window* c); - - int Width() const { return width; } - int Height() const { return height; } - - virtual void ClearAllFrames(bool clear_all); - virtual void ClearNextFrames(int num_frames); - - virtual Video* GetVideo() const { return video; } - -protected: - int width; - int height; - int clear; - int closed; - - Video* video; - - List window_list; -}; - -#endif // Screen_h - diff --git a/Stars45/ScrollWindow.cpp b/Stars45/ScrollWindow.cpp deleted file mode 100644 index 6425ff8..0000000 --- a/Stars45/ScrollWindow.cpp +++ /dev/null @@ -1,629 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ScrollWindow ActiveWindow class -*/ - -#include "ScrollWindow.h" -#include "Button.h" -#include "Bitmap.h" -#include "FormWindow.h" -#include "Video.h" -#include "Font.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Clock.h" - -// +--------------------------------------------------------------------+ - -static int old_cursor; - -// +--------------------------------------------------------------------+ - -ScrollWindow::ScrollWindow(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid, DWORD s, ActiveWindow* paw) -: ActiveWindow(p->GetScreen(), ax, ay, aw, ah, aid, s, paw) -{ - captured = false; - dragging = false; - selecting = false; - scrolling = SCROLL_NONE; - - leading = 0; - scroll_bar = SCROLL_AUTO; - dragdrop = false; - scroll_count = 0; - line_count = 0; - page_count = 0; - page_size = 1; - top_index = 0; - line_height = 0; - mouse_x = 0; - mouse_y = 0; - - smooth_scroll = false; - smooth_offset = 0; - - track_length = ah - 2*TRACK_START - THUMB_HEIGHT; - thumb_pos = TRACK_START; - - char buf[32]; - sprintf_s(buf, "ScrollWindow %d", id); - desc = buf; -} - -ScrollWindow::ScrollWindow(Screen* s, int ax, int ay, int aw, int ah, DWORD aid, DWORD s1, ActiveWindow* paw) -: ActiveWindow(s, ax, ay, aw, ah, aid, s1, paw) -{ - captured = false; - dragging = false; - selecting = false; - scrolling = SCROLL_NONE; - - leading = 0; - scroll_bar = SCROLL_AUTO; - dragdrop = false; - scroll_count = 0; - line_count = 0; - page_count = 0; - page_size = 1; - top_index = 0; - line_height = 0; - mouse_x = 0; - mouse_y = 0; - - smooth_scroll = false; - smooth_offset = 0; - - track_length = ah - 2*TRACK_START - THUMB_HEIGHT; - thumb_pos = TRACK_START; - - char buf[32]; - sprintf_s(buf, "ScrollWindow %d", id); - desc = buf; -} - -ScrollWindow::~ScrollWindow() -{ } - -// +--------------------------------------------------------------------+ - -void -ScrollWindow::MoveTo(const Rect& r) -{ - ActiveWindow::MoveTo(r); - - track_length = rect.h - 2*TRACK_START - THUMB_HEIGHT; - thumb_pos = TRACK_START; -} - -// +--------------------------------------------------------------------+ - -void -ScrollWindow::Paint() -{ - if (transparent) { - DrawTransparent(); - } - - else { - ActiveWindow::Paint(); - } -} - -// +--------------------------------------------------------------------+ - -void -ScrollWindow::Draw() -{ - int x = 0; - int y = 0; - int w = rect.w; - int h = rect.h; - - if (w < 1 || h < 1 || !shown) - return; - - ActiveWindow::Draw(); - - if (line_height < 1) - line_height = GetFont()->Height(); - page_size = h / (line_height + leading); - - Rect ctrl_rect(x,y,w,h); - ctrl_rect.Deflate(BORDER_WIDTH, BORDER_WIDTH); - - if (IsScrollVisible()) { - ctrl_rect.w -= SCROLL_TRACK; - } - - DrawContent(ctrl_rect); - DrawScrollBar(); -} - -// +--------------------------------------------------------------------+ - -void -ScrollWindow::DrawTransparent() -{ - int x = 0; - int y = 0; - int w = rect.w; - int h = rect.h; - - if (w < 1 || h < 1 || !shown) - return; - - if (line_height < 1) - line_height = GetFont()->Height(); - page_size = h / (line_height + leading); - - Rect ctrl_rect(x,y,w,h); - ctrl_rect.Deflate(BORDER_WIDTH, BORDER_WIDTH); - - if (IsScrollVisible()) { - ctrl_rect.w -= SCROLL_TRACK; - } - - DrawTransparentContent(ctrl_rect); - DrawScrollBar(); -} - -// +--------------------------------------------------------------------+ - -void -ScrollWindow::DrawContent(const Rect& ctrl_rect) -{ - // override to do control-specific drawing -} - -void -ScrollWindow::DrawTransparentContent(const Rect& ctrl_rect) -{ - // override (if necessary) to do control-specific drawing - DrawContent(ctrl_rect); -} - -void -ScrollWindow::DrawScrollBar() -{ - // draw scroll bar if necessary: - if (IsScrollVisible()) { - Color save_color = back_color; - back_color = ShadeColor(back_color, 1.3); - - // draw scroll track border: - DrawLine(rect.w-SCROLL_TRACK, BORDER_WIDTH, rect.w-SCROLL_TRACK, rect.h-BORDER_WIDTH, back_color); - - // draw top button - Rect btn_rect(rect.w-SCROLL_WIDTH, BORDER_WIDTH, SCROLL_WIDTH-BORDER_WIDTH, SCROLL_HEIGHT); - FillRect(btn_rect, back_color); - DrawStyleRect(btn_rect, WIN_RAISED_FRAME); - - // draw bottom button: - btn_rect.y = rect.h - (SCROLL_HEIGHT+BORDER_WIDTH); - FillRect(btn_rect, back_color); - DrawStyleRect(btn_rect, WIN_RAISED_FRAME); - - // draw thumb: - btn_rect.y = thumb_pos; - btn_rect.h = btn_rect.w; - FillRect(btn_rect, back_color); - DrawStyleRect(btn_rect, WIN_RAISED_FRAME); - - back_color = save_color; - } - - if (scrolling && scroll_count) - Scroll(scrolling, scroll_count); -} - -// +--------------------------------------------------------------------+ - -bool -ScrollWindow::IsScrollVisible() -{ - bool vis = false; - - if (scroll_bar == SCROLL_ALWAYS || - (scroll_bar == SCROLL_AUTO && - line_count > page_size)) { - vis = true; - } - - return vis; -} - -int ScrollWindow::GetLineHeight() -{ - return line_height; -} - -void ScrollWindow::SetLineHeight(int h) -{ - if (h >= 0) - line_height = h; -} - -int ScrollWindow::GetLeading() -{ - return leading; -} - -void ScrollWindow::SetLeading(int nNewValue) -{ - if (leading != nNewValue && nNewValue >= 0) { - leading = nNewValue; - } -} - -int ScrollWindow::GetDragDrop() -{ - return dragdrop; -} - -void ScrollWindow::SetDragDrop(int nNewValue) -{ - if (dragdrop != nNewValue && (nNewValue == 0 || nNewValue == 1)) { - dragdrop = nNewValue; - } -} - -int ScrollWindow::GetScrollBarVisible() -{ - return scroll_bar; -} - -void ScrollWindow::SetScrollBarVisible(int nNewValue) -{ - if (scroll_bar != nNewValue) { - scroll_bar = nNewValue; - } -} - -bool ScrollWindow::GetSmoothScroll() -{ - return smooth_scroll; -} - -void ScrollWindow::SetSmoothScroll(bool bNewValue) -{ - if (smooth_scroll != bNewValue) { - smooth_scroll = bNewValue; - smooth_offset = top_index; - } -} - -bool ScrollWindow::CanScroll(int direction, int nlines) -{ - return false; -} - -void ScrollWindow::EnsureVisible(int index) -{ - if (index < top_index) - ScrollTo(index); - - else if (index > top_index+page_size) - ScrollTo(index-page_size); -} - -void ScrollWindow::Scroll(int direction, int nlines) -{ - if (nlines) { - scrolling = direction; - - if (direction == SCROLL_UP || direction == SCROLL_PAGE_UP) { - top_index--; - - if (top_index < 0) - top_index = 0; - - else - scroll_count = nlines-1; - } - - else if (direction == SCROLL_DOWN || direction == SCROLL_PAGE_DOWN) { - top_index++; - - if (top_index >= line_count) - top_index = line_count-1; - - else - scroll_count = nlines-1; - } - - smooth_offset = top_index; - thumb_pos = TRACK_START + (int) (track_length * (double) top_index/(line_count-1)); - - if (scroll_count < 1) - scrolling = SCROLL_NONE; - } -} - -void ScrollWindow::SmoothScroll(int direction, double nlines) -{ - if (!smooth_scroll) { - Scroll(direction, (int) nlines); - return; - } - - if (direction == SCROLL_UP || direction == SCROLL_PAGE_UP) { - smooth_offset -= nlines; - - if (smooth_offset < 0) - smooth_offset = 0; - } - - else if (direction == SCROLL_DOWN || direction == SCROLL_PAGE_DOWN) { - smooth_offset += nlines; - - if (smooth_offset >= line_count) - smooth_offset = line_count-1; - } - - top_index = (int) smooth_offset; - thumb_pos = TRACK_START + (int) (track_length * smooth_offset/(line_count-1)); - scrolling = SCROLL_NONE; -} - -void ScrollWindow::ScrollTo(int index) -{ - if (index >= 0 && index < line_count) { - top_index = index; - smooth_offset = index; - - thumb_pos = TRACK_START + (int) (track_length * smooth_offset/(line_count-1)); - } -} - -int ScrollWindow::GetTopIndex() -{ - return top_index; -} - -int ScrollWindow::GetPageCount() -{ - return line_count / GetPageSize(); -} - -int ScrollWindow::GetPageSize() -{ - return page_size; -} - -int ScrollWindow::GetScrollTrack() -{ - return rect.w-SCROLL_TRACK; -} - -int ScrollWindow::GetLineCount() -{ - return line_count; -} - -// +--------------------------------------------------------------------+ - -int ScrollWindow::OnMouseMove(int x, int y) -{ - bool dirty = false; - - if (captured) { - ActiveWindow* test = GetCapture(); - - if (test != this) { - captured = false; - dirty = true; - } - - else { - if (selecting && !dragging) { - if (dragdrop && (x < rect.x || - x > rect.x+rect.w || - y < rect.y || - y > rect.y+rect.h)) { - - dragging = true; - OnDragStart(x,y); - } - } - - if (scrolling == SCROLL_THUMB) { - mouse_y = y - rect.y - TRACK_START; - - int dest = (int) ((double) mouse_y/track_length * (line_count-1)); - ScrollTo(dest); - dirty = true; - } - } - } - - return ActiveWindow::OnMouseMove(x,y); -} - -// +--------------------------------------------------------------------+ - -int ScrollWindow::OnLButtonDown(int x, int y) -{ - if (!captured) - captured = SetCapture(); - - mouse_x = x - rect.x; - mouse_y = y - rect.y; - - int x_scroll_bar = rect.w; - - if (scroll_bar == SCROLL_ALWAYS || - (scroll_bar == SCROLL_AUTO && - line_count > page_size)) - x_scroll_bar -= SCROLL_WIDTH; - - if (mouse_x < x_scroll_bar) { - scrolling = SCROLL_NONE; - selecting = true; - } - - else { - selecting = false; - - if (mouse_y < TRACK_START) { - scrolling = SCROLL_UP; - Scroll(scrolling, 1); - Button::PlaySound(Button::SND_LIST_SCROLL); - } - - else if (mouse_y > rect.h-TRACK_START) { - scrolling = SCROLL_DOWN; - if (top_index < line_count-1) - top_index++; - Button::PlaySound(Button::SND_LIST_SCROLL); - } - - else if (mouse_y < thumb_pos) { - scrolling = SCROLL_PAGE_UP; - Scroll(scrolling, page_size); - Button::PlaySound(Button::SND_LIST_SCROLL); - } - - else if (mouse_y > thumb_pos+THUMB_HEIGHT) { - scrolling = SCROLL_PAGE_DOWN; - Scroll(scrolling, page_size); - Button::PlaySound(Button::SND_LIST_SCROLL); - } - - else { - scrolling = SCROLL_THUMB; - } - } - - return ActiveWindow::OnLButtonDown(x,y); -} - -// +--------------------------------------------------------------------+ - -int ScrollWindow::OnLButtonUp(int x, int y) -{ - if (captured) { - mouse_x = x-rect.x; - mouse_y = y-rect.y; - - if (dragging) { - if (mouse_x < 0 || mouse_x > rect.w || mouse_y < 0 || mouse_y > rect.h) { - FormWindow* parent_form = (FormWindow*) form; - - if (parent_form) { - ActiveWindow* drop_target = parent_form->FindControl(x,y); - - if (drop_target && drop_target->IsEnabled() && drop_target->IsShown()) - drop_target->OnDragDrop(x,y,this); - } - } - } - - ReleaseCapture(); - captured = false; - - Mouse::SetCursor((Mouse::CURSOR) old_cursor); - } - - dragging = false; - selecting = false; - - return ActiveWindow::OnLButtonUp(x,y); -} - -// +--------------------------------------------------------------------+ - -int ScrollWindow::OnMouseWheel(int wheel) -{ - if (wheel > 0) - Scroll(SCROLL_UP, 1); - - else if (wheel < 0) - Scroll(SCROLL_DOWN, 1); - - if (GetLineCount() > 0) { - static double scroll_time = 0; - Clock* clock = Clock::GetInstance(); - - if (clock->RealTime() - scroll_time > 0.5) { - scroll_time = clock->RealTime(); - Button::PlaySound(Button::SND_LIST_SCROLL); - } - } - - return ActiveWindow::OnMouseWheel(wheel); -} - -// +--------------------------------------------------------------------+ - -int ScrollWindow::OnClick() -{ - int fire_select = !scrolling; - - if (scrolling == SCROLL_THUMB) - scrolling = SCROLL_NONE; - - if (fire_select) - return ActiveWindow::OnSelect(); - else - return ActiveWindow::OnClick(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -int ScrollWindow::OnKeyDown(int vk, int flags) -{ - switch (vk) { - case VK_UP: Scroll(SCROLL_UP, 1); - Button::PlaySound(Button::SND_LIST_SCROLL); - break; - - case VK_DOWN: Scroll(SCROLL_DOWN, 1); - Button::PlaySound(Button::SND_LIST_SCROLL); - break; - - case VK_PRIOR: Scroll(SCROLL_UP, page_count); - Button::PlaySound(Button::SND_LIST_SCROLL); - break; - - case VK_NEXT: Scroll(SCROLL_DOWN, page_count); - Button::PlaySound(Button::SND_LIST_SCROLL); - break; - - case VK_HOME: EnsureVisible(0); - Button::PlaySound(Button::SND_LIST_SCROLL); - break; - - case VK_END: EnsureVisible(line_count-1); - Button::PlaySound(Button::SND_LIST_SCROLL); - break; - - default: break; - } - - return ActiveWindow::OnKeyDown(vk, flags); -} - -// +--------------------------------------------------------------------+ - -int ScrollWindow::OnDragStart(int x, int y) -{ - old_cursor = Mouse::SetCursor(Mouse::DRAG); - return ActiveWindow::OnDragStart(x,y); -} - -// +--------------------------------------------------------------------+ - -int ScrollWindow::OnDragDrop(int x, int y, ActiveWindow* source) -{ - return ActiveWindow::OnDragDrop(x,y,source); -} diff --git a/Stars45/ScrollWindow.h b/Stars45/ScrollWindow.h deleted file mode 100644 index 910b117..0000000 --- a/Stars45/ScrollWindow.h +++ /dev/null @@ -1,131 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ScrollWindow base class for List, Edit, and Rich Text controls -*/ - -#ifndef ScrollWindow_h -#define ScrollWindow_h - -#include "Types.h" -#include "ActiveWindow.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class ScrollWindow : public ActiveWindow -{ -public: - enum POLICY { SCROLL_NEVER, - SCROLL_AUTO, - SCROLL_ALWAYS - }; - - enum SCROLL { SCROLL_NONE, - SCROLL_UP, - SCROLL_PAGE_UP, - SCROLL_DOWN, - SCROLL_PAGE_DOWN, - SCROLL_THUMB - }; - - enum MISC { BORDER_WIDTH = 2, - EXTRA_WIDTH = 4, - SCROLL_WIDTH = 16, - SCROLL_HEIGHT = 6, - SCROLL_TRACK = SCROLL_WIDTH + 1, - TRACK_START = BORDER_WIDTH + SCROLL_HEIGHT, - THUMB_HEIGHT = SCROLL_WIDTH, - HEADING_EXTRA = BORDER_WIDTH + EXTRA_WIDTH - }; - - ScrollWindow(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid, DWORD style=0, ActiveWindow* parent=0); - ScrollWindow(Screen* s, int ax, int ay, int aw, int ah, DWORD aid, DWORD style=0, ActiveWindow* parent=0); - virtual ~ScrollWindow(); - - // Operations: - virtual void Paint(); - virtual void Draw(); - virtual void DrawTransparent(); - virtual void DrawContent(const Rect& ctrl_rect); - virtual void DrawTransparentContent(const Rect& ctrl_rect); - virtual void DrawScrollBar(); - virtual void MoveTo(const Rect& r); - - // Event Target Interface: - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnMouseWheel(int wheel); - virtual int OnClick(); - - virtual int OnKeyDown(int vk, int flags); - - // pseudo-events: - virtual int OnDragStart(int x, int y); - virtual int OnDragDrop(int x, int y, ActiveWindow* source); - - // Property accessors: - virtual int GetLineHeight(); - virtual void SetLineHeight(int h); - - virtual int GetLeading(); - virtual void SetLeading(int nNewValue); - virtual int GetScrollBarVisible(); - virtual void SetScrollBarVisible(int nNewValue); - virtual int GetDragDrop(); - virtual void SetDragDrop(int nNewValue); - virtual bool GetSmoothScroll(); - virtual void SetSmoothScroll(bool s); - - virtual bool IsScrollVisible(); - virtual bool CanScroll(int direction, int nlines=1); - virtual void EnsureVisible(int index); - virtual void Scroll(int direction, int nlines=1); - virtual void SmoothScroll(int direction, double nlines); - virtual void ScrollTo(int index); - - // read-only: - virtual int GetTopIndex(); - virtual int GetLineCount(); - virtual int GetPageCount(); - virtual int GetPageSize(); - virtual int GetScrollTrack(); - - int IsDragging() const { return dragging; } - int IsSelecting() const { return selecting; } - int IsScrolling() const { return scrolling; } - -protected: - int captured; - int dragging; - int selecting; - int scrolling; - int scroll_count; - int mouse_x; - int mouse_y; - int track_length; - int thumb_pos; - - int leading; - int scroll_bar; - int dragdrop; - int line_count; - int page_count; - int page_size; - int top_index; - int line_height; - - bool smooth_scroll; - double smooth_offset; -}; - -#endif // ScrollWindow_h - diff --git a/Stars45/SeekerAI.cpp b/Stars45/SeekerAI.cpp deleted file mode 100644 index 7976dfd..0000000 --- a/Stars45/SeekerAI.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Seeker Missile (low-level) Artificial Intelligence class -*/ - -#include "SeekerAI.h" -#include "Ship.h" -#include "Shot.h" -#include "System.h" -#include "WeaponDesign.h" - -#include "Clock.h" - -// +----------------------------------------------------------------------+ - -SeekerAI::SeekerAI(SimObject* s) - : SteerAI(s), shot((Shot*) s), orig_target(0), - pursuit(1), delay(0), overshot(false) -{ - ai_type = SEEKER; - - seek_gain = 25; - seek_damp = 0.55; -} - - -// +--------------------------------------------------------------------+ - -SeekerAI::~SeekerAI() -{ - if (shot) { - if (shot->Owner()) - ((Ship*) shot->Owner())->SetMissileEta(shot->Identity(), 0); - } -} - -// +--------------------------------------------------------------------+ - -void -SeekerAI::ExecFrame(double seconds) -{ - // setup: - FindObjective(); - - // adaptive behavior: - Navigator(); -} - -// +--------------------------------------------------------------------+ - -void -SeekerAI::Navigator() -{ - if (delay > 0) { - delay -= Clock::GetInstance()->Delta(); - } - else { - Steer s = SeekTarget(); - self->ApplyYaw((float) s.yaw); - self->ApplyPitch((float) s.pitch); - } -} - -void -SeekerAI::SetTarget(SimObject* targ, System* sub) -{ - if (!orig_target && targ && targ->Type() == SimObject::SIM_SHIP) { - orig_target = (Ship*) targ; - Observe(orig_target); - } - - SteerAI::SetTarget(targ, sub); - - if (!target) { - shot->SetEta(0); - - if (shot->Owner()) - ((Ship*) shot->Owner())->SetMissileEta(shot->Identity(), 0); - } -} - -void -SeekerAI::FindObjective() -{ - if (!shot || !target) return; - - if (target->Life() == 0) { - if (target != orig_target) - SetTarget(orig_target,0); - else - SetTarget(0,0); - - return; - } - - Point tloc = target->Location(); - tloc = Transform(tloc); - - // seeker head limit of 45 degrees: - if (tloc.z < 0 || tloc.z < fabs(tloc.x) || tloc.z < fabs(tloc.y)) { - overshot = true; - SetTarget(0,0); - return; - } - - // distance from self to target: - distance = Point(target->Location() - self->Location()).length(); - - // are we being spoofed? - CheckDecoys(distance); - - Point cv = ClosingVelocity(); - - // time to reach target: - double time = distance / cv.length(); - double predict = time; - if (predict > 15) - predict = 15; - - // pure pursuit: - if (pursuit == 1 || time < 0.1) { - obj_w = target->Location(); - } - - // lead pursuit: - else { - // where the target will be when we reach it: - Point run_vec = target->Velocity(); - obj_w = target->Location() + (run_vec * predict); - } - - // subsystem offset: - if (subtarget) { - Point offset = target->Location() - subtarget->MountLocation(); - obj_w -= offset; - } - else if (target->Type() == SimObject::SIM_SHIP) { - Ship* tgt_ship = (Ship*) target; - - if (tgt_ship->IsGroundUnit()) - obj_w += Point(0,150,0); - } - - - distance = Point(obj_w - self->Location()).length(); - time = distance / cv.length(); - - // where we will be when the target gets there: - if (predict > 0.1 && predict < 15) { - Point self_dest = self->Location() + cv * predict; - Point err = obj_w - self_dest; - - obj_w += err; - } - - // transform into camera coords: - objective = Transform(obj_w); - objective.Normalize(); - - shot->SetEta((int) time); - - if (shot->Owner()) - ((Ship*) shot->Owner())->SetMissileEta(shot->Identity(), (int) time); -} - -// +--------------------------------------------------------------------+ - -void -SeekerAI::CheckDecoys(double target_distance) -{ - // if the assigned target has the burner lit, - // ignore the decoys: - if (orig_target && orig_target->Augmenter()) { - SetTarget(orig_target); - return; - } - - if (target && - target == orig_target && - orig_target->GetActiveDecoys().size()) { - - ListIter decoy = orig_target->GetActiveDecoys(); - - while (++decoy) { - double decoy_distance = Point(decoy->Location() - self->Location()).length(); - - if (decoy_distance < target_distance) { - if (rand() < 1600) { - SetTarget(decoy.value(), 0); - return; - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -bool -SeekerAI::Overshot() -{ - return overshot; -} - -// +--------------------------------------------------------------------+ - -Steer -SeekerAI::AvoidCollision() -{ - return Steer(); -} - -// +--------------------------------------------------------------------+ - -Steer -SeekerAI::SeekTarget() -{ - if (!self || !target || Overshot()) - return Steer(); - - return Seek(objective); -} - -// +--------------------------------------------------------------------+ - -bool -SeekerAI::Update(SimObject* obj) -{ - if (obj == target) { - if (obj->Type() == SimObject::SIM_SHOT && orig_target != 0) - target = orig_target; - } - - if (obj == orig_target) - orig_target = 0; - - return SteerAI::Update(obj); -} - -const char* -SeekerAI::GetObserverName() const -{ - static char name[64]; - sprintf_s(name, "SeekerAI(%s)", self->Name()); - return name; -} - diff --git a/Stars45/SeekerAI.h b/Stars45/SeekerAI.h deleted file mode 100644 index f1a4a52..0000000 --- a/Stars45/SeekerAI.h +++ /dev/null @@ -1,72 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Seeker Missile (low-level) Artifical Intelligence class -*/ - -#ifndef SeekerAI_h -#define SeekerAI_h - -#include "Types.h" -#include "SteerAI.h" -#include "SimObject.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class Shot; - -class SeekerAI : public SteerAI -{ -public: - SeekerAI(SimObject* s); - virtual ~SeekerAI(); - - virtual int Type() const { return 1001; } - virtual int Subframe() const { return true; } - - virtual void ExecFrame(double seconds); - virtual void FindObjective(); - virtual void SetTarget(SimObject* targ, System* sub=0); - virtual bool Overshot(); - - virtual void SetPursuit(int p) { pursuit = p; } - virtual int GetPursuit() const { return pursuit; } - - virtual void SetDelay(double d) { delay = d; } - virtual double GetDelay() const { return delay; } - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - -protected: - // behaviors: - virtual Steer AvoidCollision(); - virtual Steer SeekTarget(); - - // accumulate behaviors: - virtual void Navigator(); - - virtual void CheckDecoys(double distance); - - Ship* orig_target; - Shot* shot; - int pursuit; // type of pursuit curve - // 1: pure pursuit - // 2: lead pursuit - - double delay; // don't start seeking until then - bool overshot; -}; - -// +--------------------------------------------------------------------+ - -#endif // SeekerAI_h - diff --git a/Stars45/Sensor.cpp b/Stars45/Sensor.cpp deleted file mode 100644 index e5a4932..0000000 --- a/Stars45/Sensor.cpp +++ /dev/null @@ -1,849 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Integrated (Passive and Active) Sensor Package class implementation -*/ - -#include "Sensor.h" -#include "Contact.h" -#include "Element.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Shot.h" -#include "Drone.h" -#include "WeaponDesign.h" -#include "Sim.h" -#include "CombatGroup.h" -#include "CombatUnit.h" - -#include "Game.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ - -const double SENSOR_THRESHOLD = 0.25; - -// +----------------------------------------------------------------------+ - -Sensor::Sensor() -: System(SENSOR, 1, "Dual Sensor Pkg", 1, 10, 10, 10), -mode(STD), target(0), -nsettings(0), range_index(0) -{ - name = ContentBundle::GetInstance()->GetText("sys.sensor"); - abrv = ContentBundle::GetInstance()->GetText("sys.sensor.abrv"); - - SetMode(mode); - power_flags = POWER_WATTS; - - ZeroMemory(range_settings, sizeof(range_settings)); -} - -// +----------------------------------------------------------------------+ - -Sensor::Sensor(const Sensor& s) -: System(s), mode(STD), target(0), -nsettings(s.nsettings), range_index(0) -{ - Mount(s); - - SetMode(mode); - power_flags = POWER_WATTS; - - CopyMemory(range_settings, s.range_settings, sizeof(range_settings)); - - if (nsettings) - range_index = nsettings-1; -} - -// +--------------------------------------------------------------------+ - -Sensor::~Sensor() -{ - ClearAllContacts(); -} - -// +--------------------------------------------------------------------+ - -void -Sensor::ClearAllContacts() -{ - contacts.destroy(); -} - -// +--------------------------------------------------------------------+ - -double -Sensor::GetBeamLimit() const -{ - if (mode == ACM) - return 15*DEGREES; - - if (mode <= GM) - return 45*DEGREES; - - return 175*DEGREES; -} - -double -Sensor::GetBeamRange() const -{ - return (double) range_settings[range_index]; -} - -void -Sensor::IncreaseRange() -{ - if (range_index < nsettings-1) - range_index++; - else - range_index = nsettings-1; -} - -void -Sensor::DecreaseRange() -{ - if (range_index > 0) - range_index--; - else - range_index = 0; -} - -void -Sensor::AddRange(double r) -{ - if (nsettings < 8) - range_settings[nsettings++] = (float) r; - - range_index = nsettings-1; -} - -void -Sensor::SetMode(Mode m) -{ - if (mode != m) { - // dump the contact list when changing in/out of GM: - if (mode == GM || m == GM) - ClearAllContacts(); - - // dump the current target on mode changes: - if (m <= GM) { - if (ship) - ship->DropTarget(); - - Ignore(target); - target = 0; - } - } - - mode = m; -} - -// +----------------------------------------------------------------------+ - -bool -Sensor::Update(SimObject* obj) -{ - if (obj == target) { - target = 0; - } - - return SimObserver::Update(obj); -} - -const char* -Sensor::GetObserverName() const -{ - return "Sensor"; -} - -// +--------------------------------------------------------------------+ - -void -Sensor::ExecFrame(double seconds) -{ - if (Game::GetInstance()->Paused()) - return; - - System::ExecFrame(seconds); - - if (!IsPowerOn() || energy <= 0) { - ClearAllContacts(); - return; - } - - if (ship && ship->GetAIMode() < 2) { - // just pretend to work this frame: - energy = 0.0f; - return; - } - - if (ship && ship->GetRegion()) { - const Camera* cam = &ship->Cam(); - double az1 = -45*DEGREES; - double az2 = 45*DEGREES; - - if (mode > GM) { - az1 = -175*DEGREES; - az2 = 175*DEGREES; - } - - ListIter ship_iter(ship->GetRegion()->Ships()); - while (++ship_iter) { - Ship* c_ship = ship_iter.value(); - - if (c_ship != ship) { - ProcessContact(c_ship, az1, az2); - } - else { - Contact* c = FindContact(c_ship); - - if (!c) { - c = new Contact(c_ship, 0.0f, 0.0f); - contacts.append(c); - } - - // update track: - if (c) { - c->loc = c_ship->Location(); - c->d_pas = 2.0f; - c->d_act = 2.0f; - - c->UpdateTrack(); - } - } - } - - ListIter threat_iter(ship->GetThreatList()); - while (++threat_iter) { - ProcessContact(threat_iter.value(), az1, az2); - } - - ListIter drone_iter(ship->GetRegion()->Drones()); - while (++drone_iter) { - ProcessContact(drone_iter.value(), az1, az2); - } - - List& track_list = ship->GetRegion()->TrackList(ship->GetIFF()); - ListIter c_iter(contacts); - - while (++c_iter) { - Contact* contact = c_iter.value(); - Ship* c_ship = contact->GetShip(); - Shot* c_shot = contact->GetShot(); - double c_life = -1; - - if (c_ship) { - c_life = c_ship->Life(); - - // look for quantum jumps and orbit transitions: - if (c_ship->GetRegion() != ship->GetRegion()) - c_life = 0; - } - - else if (c_shot) { - c_life = c_shot->Life(); - } - - else { - c_life = 0; - } - - if (contact->Age() < 0 || c_life == 0) { - delete c_iter.removeItem(); - } - - else if (ship && ship->GetIFF() >= 0 && ship->GetIFF() < 5) { - // update shared track database: - Contact* t = track_list.find(contact); - - if (c_ship) { - if (!t) { - Contact* track = new Contact(c_ship, contact->d_pas, contact->d_act); - track->loc = c_ship->Location(); - track_list.append(track); - } - - else { - t->loc = c_ship->Location(); - t->Merge(contact); - t->UpdateTrack(); - } - } - - else if (c_shot) { - if (!t) { - Contact* track = new Contact(c_shot, contact->d_pas, contact->d_act); - track->loc = c_shot->Location(); - track_list.append(track); - } - - else { - t->loc = c_shot->Location(); - t->Merge(contact); - t->UpdateTrack(); - } - } - } - } - - - if (mode == ACM) { - if (!ship->GetTarget()) - ship->LockTarget(SimObject::SIM_SHIP, true, true); - } - } - - energy = 0.0f; -} - -// +--------------------------------------------------------------------+ - -void -Sensor::ProcessContact(Ship* c_ship, double az1, double az2) -{ - if (c_ship->IsNetObserver()) - return; - - double sensor_range = GetBeamRange(); - - // translate: - const Camera* cam = &ship->Cam(); - Point targ_pt = c_ship->Location() - ship->Location(); - - // rotate: - double tx = targ_pt * cam->vrt(); - double ty = targ_pt * cam->vup(); - double tz = targ_pt * cam->vpn(); - - // convert to spherical coords: - double rng = targ_pt.length(); - double az = asin(fabs(tx) / rng); - double el = asin(fabs(ty) / rng); - if (tx < 0) az = -az; - if (ty < 0) el = -el; - - double min_range = rng; - Drone* probe = ship->GetProbe(); - bool probescan = false; - - if (ship->GetIFF() == c_ship->GetIFF()) { - min_range = 1; - } - - else if (probe) { - Point probe_pt = c_ship->Location() - probe->Location(); - double prng = probe_pt.length(); - - if (prng < probe->Design()->lethal_radius && prng < rng) { - min_range = prng; - probescan = true; - } - } - - bool vis = tz > 1 && (c_ship->Radius()/rng > 0.001); - bool threat = (c_ship->Life() != 0 && - c_ship->GetIFF() && - c_ship->GetIFF() != ship->GetIFF() && - c_ship->GetEMCON() > 2 && - c_ship->IsTracking(ship)); - - if (!threat) { - if (mode == GM && !c_ship->IsGroundUnit()) - return; - - if (mode != GM && c_ship->IsGroundUnit()) - return; - - if (min_range > sensor_range || min_range > c_ship->Design()->detet) { - if (c_ship == target) { - ship->DropTarget(); - Ignore(target); - target = 0; - } - - return; - } - } - - // clip: - if (threat || vis || mode >= PST || tz > 1) { - - // correct az/el for back hemisphere: - if (tz < 0) { - if (az < 0) az = -PI - az; - else az = PI - az; - } - - double d_pas = 0; - double d_act = 0; - double effectivity = energy/capacity * availability; - - // did this contact get scanned this frame? - if (effectivity > SENSOR_THRESHOLD) { - if (az >= az1 && az <= az2 && (mode >= PST || fabs(el) < 45*DEGREES)) { - double passive_range_limit = 500e3; - if (c_ship->Design()->detet > passive_range_limit) - passive_range_limit = c_ship->Design()->detet; - - d_pas = c_ship->PCS() * effectivity * (1 - min_range/passive_range_limit); - - if (d_pas < 0) - d_pas = 0; - - if (probescan) { - double max_range = probe->Design()->lethal_radius; - d_act = c_ship->ACS() * (1 - min_range/max_range); - } - - else if (mode != PAS && mode != PST) { - double max_range = sensor_range; - d_act = c_ship->ACS() * effectivity * (1 - min_range/max_range); - } - - if (d_act < 0) - d_act = 0; - } - } - - // yes, update or add new contact: - if (threat || vis || d_pas > SENSOR_THRESHOLD || d_act > SENSOR_THRESHOLD) { - Element* elem = c_ship->GetElement(); - CombatUnit* unit = c_ship->GetCombatUnit(); - - if (elem && ship && elem->GetIFF() != ship->GetIFF() && elem->IntelLevel() < Intel::LOCATED) { - elem->SetIntelLevel(Intel::LOCATED); - } - - if (unit && ship && unit->GetIFF() != ship->GetIFF()) { - CombatGroup* group = unit->GetCombatGroup(); - - if (group && group->IntelLevel() < Intel::LOCATED && - group->IntelLevel() > Intel::RESERVE) { - group->SetIntelLevel(Intel::LOCATED); - } - } - - Contact* c = FindContact(c_ship); - - if (!c) { - c = new Contact(c_ship, 0.0f, 0.0f); - contacts.append(c); - } - - // update track: - if (c) { - c->loc = c_ship->Location(); - c->d_pas = (float) d_pas; - c->d_act = (float) d_act; - c->probe = probescan; - - c->UpdateTrack(); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Sensor::ProcessContact(Shot* c_shot, double az1, double az2) -{ - double sensor_range = GetBeamRange(); - - if (c_shot->IsPrimary() || c_shot->IsDecoy()) - return; - - // translate: - const Camera* cam = &ship->Cam(); - Point targ_pt = c_shot->Location() - ship->Location(); - - // rotate: - double tx = targ_pt * cam->vrt(); - double ty = targ_pt * cam->vup(); - double tz = targ_pt * cam->vpn(); - - // convert to spherical coords: - double rng = targ_pt.length(); - double az = asin(fabs(tx) / rng); - double el = asin(fabs(ty) / rng); - if (tx < 0) az = -az; - if (ty < 0) el = -el; - - bool vis = tz > 1 && (c_shot->Radius()/rng > 0.001); - bool threat = (c_shot->IsTracking(ship)); - - // clip: - if (threat || vis || ((mode >= PST || tz > 1) && rng <= sensor_range)) { - - // correct az/el for back hemisphere: - if (tz < 0) { - if (az < 0) az = -PI - az; - else az = PI - az; - } - - double d_pas = 0; - double d_act = 0; - double effectivity = energy/capacity * availability; - - // did this contact get scanned this frame? - if (effectivity > SENSOR_THRESHOLD) { - if (az >= az1 && az <= az2 && (mode >= PST || fabs(el) < 45*DEGREES)) { - if (rng < sensor_range/2) - d_pas = 1.5; - else - d_pas = 0.5; - - if (mode != PAS && mode != PST) - d_act = effectivity * (1 - rng/sensor_range); - - if (d_act < 0) - d_act = 0; - } - } - - // yes, update or add new contact: - if (threat || vis || d_pas > SENSOR_THRESHOLD || d_act > SENSOR_THRESHOLD) { - Contact* c = FindContact(c_shot); - - if (!c) { - c = new Contact(c_shot, 0.0f, 0.0f); - contacts.append(c); - } - - // update track: - if (c) { - c->loc = c_shot->Location(); - c->d_pas = (float) d_pas; - c->d_act = (float) d_act; - - c->UpdateTrack(); - } - } - } -} - -Contact* -Sensor::FindContact(Ship* s) -{ - ListIter iter(contacts); - while (++iter) { - Contact* c = iter.value(); - if (c->GetShip() == s) - return c; - } - - return 0; -} - -Contact* -Sensor::FindContact(Shot* s) -{ - ListIter iter(contacts); - while (++iter) { - Contact* c = iter.value(); - if (c->GetShot() == s) - return c; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -bool -Sensor::IsTracking(SimObject* tgt) -{ - if (tgt && mode != GM && mode != PAS && mode != PST && IsPowerOn()) { - if (tgt == target) - return true; - - Contact* c = 0; - - if (tgt->Type() == SimObject::SIM_SHIP) { - c = FindContact((Ship*) tgt); - } - else { - c = FindContact((Shot*) tgt); - } - - return (c != 0 && c->ActReturn() > SENSOR_THRESHOLD && !c->IsProbed()); - } - - return false; -} - -// +--------------------------------------------------------------------+ - -const double sensor_lock_threshold = 0.5; - -struct TargetOffset { - static const char* TYPENAME() { return "TargetOffset"; } - - SimObject* target; - double offset; - - TargetOffset() : target(0), offset(10) { } - TargetOffset(SimObject* t, double o) : target(t), offset(o) { } - int operator< (const TargetOffset& o) const { return offset < o.offset; } - int operator<=(const TargetOffset& o) const { return offset <= o.offset; } - int operator==(const TargetOffset& o) const { return offset == o.offset; } -}; - -SimObject* -Sensor::LockTarget(int type, bool closest, bool hostile) -{ - if (!ship || ship->GetEMCON() < 3) { - Ignore(target); - target = 0; - return target; - } - - SimObject* test = 0; - ListIter contact(ship->ContactList()); - - List targets; - - while (++contact) { - if (type == SimObject::SIM_SHIP) - test = contact->GetShip(); - else - test = contact->GetShot(); - - if (!test) - continue; - - // do not target own missiles: - if (contact->GetShot() && contact->GetShot()->Owner() == ship) - continue; - - double tgt_range = contact->Range(ship); - - // do not target ships outside of detet range: - if (contact->GetShip() && contact->GetShip()->Design()->detet < tgt_range) - continue; - - double d_pas = contact->PasReturn(); - double d_act = contact->ActReturn(); - bool vis = contact->Visible(ship) || contact->Threat(ship); - - if (!vis && d_pas < sensor_lock_threshold && d_act < sensor_lock_threshold) - continue; - - if (closest) { - if (hostile && (contact->GetIFF(ship) == 0 || contact->GetIFF(ship) == ship->GetIFF())) - continue; - - targets.append(new TargetOffset(test, tgt_range)); - } - - // clip: - else if (contact->InFront(ship)) { - double az, el, rng; - - contact->GetBearing(ship, az, el, rng); - az = fabs(az / PI); - el = fabs(el / PI); - - if (az <= 0.2 && el <= 0.2) - targets.append(new TargetOffset(test, az+el)); - } - } - - targets.sort(); - - if (target) { - int index = 100000; - int i = 0; - - if (targets.size() > 0) { - ListIter iter(targets); - while (++iter) { - if (iter->target == target) { - index = i; - break; - } - - i++; - } - - if (index < targets.size()-1) - index++; - else - index = 0; - - target = targets[index]->target; - Observe(target); - } - } - else if (targets.size() > 0) { - target = targets[0]->target; - Observe(target); - } - else { - target = 0; - } - - targets.destroy(); - - if (target && mode < STD) - mode = STD; - - return target; -} - -// +--------------------------------------------------------------------+ - -SimObject* -Sensor::LockTarget(SimObject* candidate) -{ - Ignore(target); - target = 0; - - if (ship->GetEMCON() < 3) - return target; - - if (!candidate) - return target; - - int type = candidate->Type(); - SimObject* test = 0; - ListIter contact(ship->ContactList()); - - while (++contact) { - if (type == SimObject::SIM_SHIP) - test = contact->GetShip(); - else - test = contact->GetShot(); - - if (test == candidate) { - double d_pas = contact->PasReturn(); - double d_act = contact->ActReturn(); - bool vis = contact->Visible(ship) || contact->Threat(ship); - - if (vis || d_pas > sensor_lock_threshold || d_act > sensor_lock_threshold) { - target = test; - Observe(target); - } - - break; - } - } - - if (target && mode < STD) - mode = STD; - - return target; -} - -// +--------------------------------------------------------------------+ - -SimObject* -Sensor::AcquirePassiveTargetForMissile() -{ - SimObject* pick = 0; - double min_off = 2; - - ListIter contact(ship->ContactList()); - - while (++contact) { - SimObject* test = contact->GetShip(); - double d = contact->PasReturn(); - - if (d < 1) continue; - - // clip: - if (contact->InFront(ship)) { - double az, el, rng; - - contact->GetBearing(ship, az, el, rng); - az = fabs(az / PI); - el = fabs(el / PI); - - if (az + el < min_off) { - min_off = az + el; - pick = test; - } - } - } - - return pick; -} - -// +--------------------------------------------------------------------+ - -SimObject* -Sensor::AcquireActiveTargetForMissile() -{ - SimObject* pick = 0; - double min_off = 2; - - ListIter contact(ship->ContactList()); - - while (++contact) { - SimObject* test = contact->GetShip(); - double d = contact->ActReturn(); - - if (d < 1) continue; - - if (contact->InFront(ship)) { - double az, el, rng; - - contact->GetBearing(ship, az, el, rng); - az = fabs(az / PI); - el = fabs(el / PI); - - if (az + el < min_off) { - min_off = az + el; - pick = test; - } - } - } - - return pick; -} - -// +--------------------------------------------------------------------+ - -void -Sensor::DoEMCON(int index) -{ - int e = GetEMCONPower(index); - - if (power_level * 100 > e || emcon != index) { - if (e == 0) { - PowerOff(); - } - else if (emcon != index) { - PowerOn(); - - if (power_level * 100 > e) { - SetPowerLevel(e); - } - - if (emcon == 3) { - if (GetMode() < PST) - SetMode(STD); - else - SetMode(CST); - } - else { - int m = GetMode(); - if (m < PST && m > PAS) - SetMode(Sensor::PAS); - else if (m == CST) - SetMode(PST); - } - } - } - - emcon = index; -} - diff --git a/Stars45/Sensor.h b/Stars45/Sensor.h deleted file mode 100644 index 5462c18..0000000 --- a/Stars45/Sensor.h +++ /dev/null @@ -1,85 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Integrated (Passive and Active) Sensor Package class -*/ - -#ifndef Sensor_h -#define Sensor_h - -#include "Types.h" -#include "SimObject.h" -#include "System.h" -#include "Geometry.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Shot; -class Contact; - -// +--------------------------------------------------------------------+ - -class Sensor : public System, public SimObserver -{ -public: - enum Mode { - PAS, STD, ACM, GM, // fighter modes - PST, CST // starship modes - }; - - Sensor(); - Sensor(const Sensor& rhs); - virtual ~Sensor(); - - virtual void ExecFrame(double seconds); - virtual SimObject* LockTarget(int type=SimObject::SIM_SHIP, - bool closest=false, - bool hostile=false); - virtual SimObject* LockTarget(SimObject* candidate); - virtual bool IsTracking(SimObject* tgt); - virtual void DoEMCON(int emcon); - - virtual void ClearAllContacts(); - - virtual Mode GetMode() const { return mode; } - virtual void SetMode(Mode m); - virtual double GetBeamLimit() const; - virtual double GetBeamRange() const; - virtual void IncreaseRange(); - virtual void DecreaseRange(); - virtual void AddRange(double r); - - Contact* FindContact(Ship* s); - Contact* FindContact(Shot* s); - - // borrow this sensor for missile seeker - SimObject* AcquirePassiveTargetForMissile(); - SimObject* AcquireActiveTargetForMissile(); - - // SimObserver: - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - -protected: - void ProcessContact(Ship* contact, double az1, double az2); - void ProcessContact(Shot* contact, double az1, double az2); - - Mode mode; - int nsettings; - int range_index; - float range_settings[8]; - SimObject* target; - - List contacts; -}; - -#endif // Sensor_h - diff --git a/Stars45/Sha1.cpp b/Stars45/Sha1.cpp deleted file mode 100644 index 7e3de70..0000000 --- a/Stars45/Sha1.cpp +++ /dev/null @@ -1,589 +0,0 @@ -/* -* Sha1.cpp -* -* Copyright (C) 1998 -* Paul E. Jones -* All Rights Reserved. -* -***************************************************************************** -* $Id: sha1.cpp,v 1.6 2001/03/20 06:54:54 paulej Exp $ -***************************************************************************** -* -* Description: -* This class implements the Secure Hashing Standard as defined -* in FIPS PUB 180-1 published April 17, 1995. -* -* The Secure Hashing Standard, which uses the Secure Hashing -* Algorithm (SHA), produces a 160-bit message digest for a -* given data stream. In theory, it is highly improbable that -* two messages will produce the same message digest. Therefore, -* this algorithm can serve as a means of providing a "fingerprint" -* for a message. -* -* Portability Issues: -* SHA-1 is defined in terms of 32-bit "words". This code was -* written with the expectation that the processor has at least -* a 32-bit machine word size. If the machine word size is larger, -* the code should still function properly. One caveat to that -* is that the input functions taking characters and character arrays -* assume that only 8 bits of information are stored in each character. -* -* Caveats: -* SHA-1 is designed to work with messages less than 2^64 bits long. -* Although SHA-1 allows a message digest to be generated for -* messages of any number of bits less than 2^64, this implementation -* only works with messages with a length that is a multiple of 8 -* bits. -* -*/ - - -#include "Sha1.h" - -/* -* SHA1 -* -* Description: -* This is the constructor for the sha1 class. -* -* Parameters: -* None. -* -* Returns: -* Nothing. -* -* Comments: -* -*/ -SHA1::SHA1() -{ - Reset(); -} - -/* -* ~SHA1 -* -* Description: -* This is the destructor for the sha1 class -* -* Parameters: -* None. -* -* Returns: -* Nothing. -* -* Comments: -* -*/ -SHA1::~SHA1() -{ - // The destructor does nothing -} - -/* -* Reset -* -* Description: -* This function will initialize the sha1 class member variables -* in preparation for computing a new message digest. -* -* Parameters: -* None. -* -* Returns: -* Nothing. -* -* Comments: -* -*/ -void SHA1::Reset() -{ - Length_Low = 0; - Length_High = 0; - Message_Block_Index = 0; - - H[0] = 0x67452301; - H[1] = 0xEFCDAB89; - H[2] = 0x98BADCFE; - H[3] = 0x10325476; - H[4] = 0xC3D2E1F0; - - Computed = false; - Corrupted = false; -} - -/* -* Result -* -* Description: -* This function will return the 160-bit message digest into the -* array provided. -* -* Parameters: -* message_digest_array: [out] -* This is an array of five unsigned integers which will be filled -* with the message digest that has been computed. -* -* Returns: -* True if successful, false if it failed. -* -* Comments: -* -*/ -bool SHA1::Result(unsigned *message_digest_array) -{ - int i; // Counter - - if (Corrupted) - { - return false; - } - - if (!Computed) - { - PadMessage(); - Computed = true; - } - - for(i = 0; i < 5; i++) - { - message_digest_array[i] = H[i]; - } - - return true; -} - -/* -* Input -* -* Description: -* This function accepts an array of octets as the next portion of -* the message. -* -* Parameters: -* message_array: [in] -* An array of characters representing the next portion of the -* message. -* -* Returns: -* Nothing. -* -* Comments: -* -*/ -void SHA1::Input( const unsigned char *message_array, -unsigned length) -{ - if (!length) - { - return; - } - - if (Computed || Corrupted) - { - Corrupted = true; - return; - } - - while(length-- && !Corrupted) - { - Message_Block[Message_Block_Index++] = (*message_array & 0xFF); - - Length_Low += 8; - Length_Low &= 0xFFFFFFFF; // Force it to 32 bits - if (Length_Low == 0) - { - Length_High++; - Length_High &= 0xFFFFFFFF; // Force it to 32 bits - if (Length_High == 0) - { - Corrupted = true; // Message is too long - } - } - - if (Message_Block_Index == 64) - { - ProcessMessageBlock(); - } - - message_array++; - } -} - -/* -* Input -* -* Description: -* This function accepts an array of octets as the next portion of -* the message. -* -* Parameters: -* message_array: [in] -* An array of characters representing the next portion of the -* message. -* length: [in] -* The length of the message_array -* -* Returns: -* Nothing. -* -* Comments: -* -*/ -void SHA1::Input( const char *message_array, -unsigned length) -{ - Input((unsigned char *) message_array, length); -} - -/* -* Input -* -* Description: -* This function accepts a single octets as the next message element. -* -* Parameters: -* message_element: [in] -* The next octet in the message. -* -* Returns: -* Nothing. -* -* Comments: -* -*/ -void SHA1::Input(unsigned char message_element) -{ - Input(&message_element, 1); -} - -/* -* Input -* -* Description: -* This function accepts a single octet as the next message element. -* -* Parameters: -* message_element: [in] -* The next octet in the message. -* -* Returns: -* Nothing. -* -* Comments: -* -*/ -void SHA1::Input(char message_element) -{ - Input((unsigned char *) &message_element, 1); -} - -/* -* operator<< -* -* Description: -* This operator makes it convenient to provide character strings to -* the SHA1 object for processing. -* -* Parameters: -* message_array: [in] -* The character array to take as input. -* -* Returns: -* A reference to the SHA1 object. -* -* Comments: -* Each character is assumed to hold 8 bits of information. -* -*/ -SHA1& SHA1::operator<<(const char *message_array) -{ - const char *p = message_array; - - while(*p) - { - Input(*p); - p++; - } - - return *this; -} - -/* -* operator<< -* -* Description: -* This operator makes it convenient to provide character strings to -* the SHA1 object for processing. -* -* Parameters: -* message_array: [in] -* The character array to take as input. -* -* Returns: -* A reference to the SHA1 object. -* -* Comments: -* Each character is assumed to hold 8 bits of information. -* -*/ -SHA1& SHA1::operator<<(const unsigned char *message_array) -{ - const unsigned char *p = message_array; - - while(*p) - { - Input(*p); - p++; - } - - return *this; -} - -/* -* operator<< -* -* Description: -* This function provides the next octet in the message. -* -* Parameters: -* message_element: [in] -* The next octet in the message -* -* Returns: -* A reference to the SHA1 object. -* -* Comments: -* The character is assumed to hold 8 bits of information. -* -*/ -SHA1& SHA1::operator<<(const char message_element) -{ - Input((unsigned char *) &message_element, 1); - - return *this; -} - -/* -* operator<< -* -* Description: -* This function provides the next octet in the message. -* -* Parameters: -* message_element: [in] -* The next octet in the message -* -* Returns: -* A reference to the SHA1 object. -* -* Comments: -* The character is assumed to hold 8 bits of information. -* -*/ -SHA1& SHA1::operator<<(const unsigned char message_element) -{ - Input(&message_element, 1); - - return *this; -} - -/* -* ProcessMessageBlock -* -* Description: -* This function will process the next 512 bits of the message -* stored in the Message_Block array. -* -* Parameters: -* None. -* -* Returns: -* Nothing. -* -* Comments: -* Many of the variable names in this function, especially the single -* character names, were used because those were the names used -* in the publication. -* -*/ -void SHA1::ProcessMessageBlock() -{ - const unsigned K[] = { // Constants defined for SHA-1 - 0x5A827999, - 0x6ED9EBA1, - 0x8F1BBCDC, - 0xCA62C1D6 - }; - int t; // Loop counter - unsigned temp; // Temporary word value - unsigned W[80]; // Word sequence - unsigned A, B, C, D, E; // Word buffers - - /* - * Initialize the first 16 words in the array W - */ - for(t = 0; t < 16; t++) - { - W[t] = Message_Block[t * 4] << 24; - W[t] |= Message_Block[t * 4 + 1] << 16; - W[t] |= Message_Block[t * 4 + 2] << 8; - W[t] |= Message_Block[t * 4 + 3]; - } - - for(t = 16; t < 80; t++) - { - W[t] = CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); - } - - A = H[0]; - B = H[1]; - C = H[2]; - D = H[3]; - E = H[4]; - - for(t = 0; t < 20; t++) - { - temp = CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 20; t < 40; t++) - { - temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 40; t < 60; t++) - { - temp = CircularShift(5,A) + - ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = CircularShift(30,B); - B = A; - A = temp; - } - - for(t = 60; t < 80; t++) - { - temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; - temp &= 0xFFFFFFFF; - E = D; - D = C; - C = CircularShift(30,B); - B = A; - A = temp; - } - - H[0] = (H[0] + A) & 0xFFFFFFFF; - H[1] = (H[1] + B) & 0xFFFFFFFF; - H[2] = (H[2] + C) & 0xFFFFFFFF; - H[3] = (H[3] + D) & 0xFFFFFFFF; - H[4] = (H[4] + E) & 0xFFFFFFFF; - - Message_Block_Index = 0; -} - -/* -* PadMessage -* -* Description: -* According to the standard, the message must be padded to an even -* 512 bits. The first padding bit must be a '1'. The last 64 bits -* represent the length of the original message. All bits in between -* should be 0. This function will pad the message according to those -* rules by filling the message_block array accordingly. It will also -* call ProcessMessageBlock() appropriately. When it returns, it -* can be assumed that the message digest has been computed. -* -* Parameters: -* None. -* -* Returns: -* Nothing. -* -* Comments: -* -*/ -void SHA1::PadMessage() -{ - /* - * Check to see if the current message block is too small to hold - * the initial padding bits and length. If so, we will pad the - * block, process it, and then continue padding into a second block. - */ - if (Message_Block_Index > 55) - { - Message_Block[Message_Block_Index++] = 0x80; - while(Message_Block_Index < 64) - { - Message_Block[Message_Block_Index++] = 0; - } - - ProcessMessageBlock(); - - while(Message_Block_Index < 56) - { - Message_Block[Message_Block_Index++] = 0; - } - } - else - { - Message_Block[Message_Block_Index++] = 0x80; - while(Message_Block_Index < 56) - { - Message_Block[Message_Block_Index++] = 0; - } - - } - - /* - * Store the message length as the last 8 octets - */ - Message_Block[56] = (Length_High >> 24) & 0xFF; - Message_Block[57] = (Length_High >> 16) & 0xFF; - Message_Block[58] = (Length_High >> 8) & 0xFF; - Message_Block[59] = (Length_High) & 0xFF; - Message_Block[60] = (Length_Low >> 24) & 0xFF; - Message_Block[61] = (Length_Low >> 16) & 0xFF; - Message_Block[62] = (Length_Low >> 8) & 0xFF; - Message_Block[63] = (Length_Low) & 0xFF; - - ProcessMessageBlock(); -} - - -/* -* CircularShift -* -* Description: -* This member function will perform a circular shifting operation. -* -* Parameters: -* bits: [in] -* The number of bits to shift (1-31) -* word: [in] -* The value to shift (assumes a 32-bit integer) -* -* Returns: -* The shifted value. -* -* Comments: -* -*/ -unsigned SHA1::CircularShift(int bits, unsigned word) -{ - return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32-bits)); -} diff --git a/Stars45/Sha1.h b/Stars45/Sha1.h deleted file mode 100644 index ec64462..0000000 --- a/Stars45/Sha1.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* Sha1.h -* -* Copyright (C) 1998 -* Paul E. Jones -* All Rights Reserved. -* -***************************************************************************** -* $Id: sha1.h,v 1.4 2001/03/20 06:25:06 paulej Exp $ -***************************************************************************** -* -* Description: -* This class implements the Secure Hashing Standard as defined -* in FIPS PUB 180-1 published April 17, 1995. -* -* Many of the variable names in this class, especially the single -* character names, were used because those were the names used -* in the publication. -* -* Please read the file sha1.cpp for more information. -* -*/ - -#ifndef _SHA1_H_ -#define _SHA1_H_ - -class SHA1 -{ - -public: - - SHA1(); - virtual ~SHA1(); - - /* - * Re-initialize the class - */ - void Reset(); - - /* - * Returns the message digest - */ - bool Result(unsigned *message_digest_array); - - /* - * Provide input to SHA1 - */ - void Input( const unsigned char *message_array, - unsigned length); - void Input( const char *message_array, - unsigned length); - void Input(unsigned char message_element); - void Input(char message_element); - SHA1& operator<<(const char *message_array); - SHA1& operator<<(const unsigned char *message_array); - SHA1& operator<<(const char message_element); - SHA1& operator<<(const unsigned char message_element); - -private: - - /* - * Process the next 512 bits of the message - */ - void ProcessMessageBlock(); - - /* - * Pads the current message block to 512 bits - */ - void PadMessage(); - - /* - * Performs a circular left shift operation - */ - inline unsigned CircularShift(int bits, unsigned word); - - unsigned H[5]; // Message digest buffers - - unsigned Length_Low; // Message length in bits - unsigned Length_High; // Message length in bits - - unsigned char Message_Block[64]; // 512-bit message blocks - int Message_Block_Index; // Index into message block array - - bool Computed; // Is the digest computed? - bool Corrupted; // Is the message digest corruped? - -}; - -#endif diff --git a/Stars45/Shadow.cpp b/Stars45/Shadow.cpp deleted file mode 100644 index f64c033..0000000 --- a/Stars45/Shadow.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Dynamic Stencil Shadow Volumes -*/ - -#include "Shadow.h" -#include "Light.h" -#include "Solid.h" -#include "Scene.h" -#include "Video.h" - -static bool visible_shadow_volumes = false; - -// +--------------------------------------------------------------------+ - -Shadow::Shadow(Solid* s) - : verts(0), nverts(0), max_verts(0), edges(0), num_edges(0), enabled(true) -{ - solid = s; - - if (solid && solid->GetModel()) { - Model* model = solid->GetModel(); - int npolys = model->NumPolys(); - - max_verts = model->NumVerts() * 4; - verts = new Vec3[max_verts]; - edges = new WORD[npolys * 6]; - } -} - -// +--------------------------------------------------------------------+ - -Shadow::~Shadow() -{ - if (verts) delete [] verts; - if (edges) delete [] edges; -} - -// +--------------------------------------------------------------------+ - -void -Shadow::Reset() -{ - num_edges = 0; - nverts = 0; -} - -// +--------------------------------------------------------------------+ - -void -Shadow::Render(Video* video) -{ - if (enabled) - video->DrawShadow(solid, nverts, verts, visible_shadow_volumes); -} - -// +--------------------------------------------------------------------+ - -void -Shadow::Update(Light* light) -{ - Reset(); - - if (!light || !solid || !solid->GetModel() || !edges) return; - - Vec3 lpos = light->Location(); - bool directional = light->Type() == Light::LIGHT_DIRECTIONAL; - Model* model = solid->GetModel(); - - ListIter iter = model->GetSurfaces(); - while (++iter) { - Surface* s = iter.value(); - - // transform light location into surface object space - Matrix xform(solid->Orientation()); // XXX should be: (s->GetOrientation()); - - Vec3 tmp = light->Location(); - - if (!directional) - tmp -= (solid->Location() + s->GetOffset()); - - lpos.x = tmp * Vec3(xform(0,0), xform(0,1), xform(0,2)); - lpos.y = tmp * Vec3(xform(1,0), xform(1,1), xform(1,2)); - lpos.z = tmp * Vec3(xform(2,0), xform(2,1), xform(2,2)); - - // compute the silohuette for the mesh with respect to the light: - - for (int i = 0; i < s->NumPolys(); i++) { - Poly* p = s->GetPolys() + i; - - // skip polys with non-shadowing materials: - if (p->material && !p->material->shadow) - continue; - - // if this poly faces the light: - if (p->plane.normal * lpos > 0) { - for (int n = 0; n < p->nverts; n++) { - if (n < p->nverts-1) - AddEdge(p->vlocs[n], p->vlocs[n+1]); - else - AddEdge(p->vlocs[n], p->vlocs[0]); - } - } - } - - // extrude the silohuette away from the light source - // to create the shadow volume: - - Vec3 extent = lpos * -1; - extent.Normalize(); - extent *= 50.0e3f; //solid->Radius() * 2.1f; - - for (int i = 0; i < (int) num_edges; i++) { - if (nverts+6 <= max_verts) { - Vec3 v1 = s->GetVLoc()[edges[2*i+0]]; - Vec3 v2 = s->GetVLoc()[edges[2*i+1]]; - Vec3 v3 = v1 + extent; - Vec3 v4 = v2 + extent; - - verts[nverts++] = v1; - verts[nverts++] = v2; - verts[nverts++] = v3; - - verts[nverts++] = v2; - verts[nverts++] = v4; - verts[nverts++] = v3; - } - } - } -} - -void -Shadow::AddEdge(WORD v1, WORD v2) -{ - // Remove interior edges (which appear in the list twice) - for (DWORD i = 0; i < num_edges; i++) { - if ((edges[2*i+0] == v1 && edges[2*i+1] == v2) || - (edges[2*i+0] == v2 && edges[2*i+1] == v1)) - { - if (num_edges > 1) { - edges[2*i+0] = edges[2*(num_edges-1)+0]; - edges[2*i+1] = edges[2*(num_edges-1)+1]; - } - - num_edges--; - return; - } - } - - edges[2*num_edges+0] = v1; - edges[2*num_edges+1] = v2; - - num_edges++; -} - -bool -Shadow::GetVisibleShadowVolumes() -{ - return visible_shadow_volumes; -} - -void -Shadow::SetVisibleShadowVolumes(bool vis) -{ - visible_shadow_volumes = vis; -} diff --git a/Stars45/Shadow.h b/Stars45/Shadow.h deleted file mode 100644 index 5427f64..0000000 --- a/Stars45/Shadow.h +++ /dev/null @@ -1,69 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Dynamic Stencil Shadow Volumes -*/ - -#ifndef Shadow_h -#define Shadow_h - -#include "Geometry.h" -#include "Color.h" - -// +--------------------------------------------------------------------+ - -#define Shadow_DESTROY(x) if (x) { x->Destroy(); x = 0; } - -// +--------------------------------------------------------------------+ - -class Light; -class Scene; -class Solid; -class Video; - -// +--------------------------------------------------------------------+ - -class Shadow -{ -public: - static const char* TYPENAME() { return "Shadow"; } - - Shadow(Solid* solid); - virtual ~Shadow(); - - int operator == (const Shadow& s) const { return this == &s; } - - // operations - void Render(Video* video); - void Update(Light* light); - void AddEdge(WORD v1, WORD v2); - void Reset(); - - bool IsEnabled() const { return enabled; } - void SetEnabled(bool e) { enabled = e; } - - static void SetVisibleShadowVolumes(bool vis); - static bool GetVisibleShadowVolumes(); - -protected: - Solid* solid; - Vec3* verts; - int nverts; - int max_verts; - bool enabled; - - WORD* edges; - DWORD num_edges; -}; - -// +--------------------------------------------------------------------+ - -#endif // Shadow_h - diff --git a/Stars45/Shield.cpp b/Stars45/Shield.cpp deleted file mode 100644 index e7c8fb8..0000000 --- a/Stars45/Shield.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon class -*/ - -#include "Shield.h" -#include "Shot.h" -#include "WeaponDesign.h" - -#include "Game.h" -#include "ContentBundle.h" - -// +----------------------------------------------------------------------+ - -static char* shield_name[] = { - "sys.shield.none", - "sys.shield.deflector", - "sys.shield.grav", - "sys.shield.hyper" -}; - -static int shield_value[] = { - 0, 2, 2, 3 -}; - -// +----------------------------------------------------------------------+ - -Shield::Shield(SUBTYPE shield_type) -: System(SHIELD, shield_type, "shield", shield_value[shield_type], 100, 0), -shield_cutoff(0.0f), shield_capacitor(false), shield_bubble(false), -deflection_cost(1.0f), shield_curve(0.05f) -{ - name = ContentBundle::GetInstance()->GetText(shield_name[shield_type]); - abrv = ContentBundle::GetInstance()->GetText("sys.shield.abrv"); - - power_flags = POWER_WATTS | POWER_CRITICAL; - energy = 0.0f; - power_level = 0.0f; - shield_level = 0.0f; - - switch (shield_type) { - default: - case DEFLECTOR: - capacity = sink_rate = 2.0e3f; - shield_factor = 0.05f; - break; - - case GRAV_SHIELD: - capacity = sink_rate = 7.0e3f; - shield_factor = 0.01f; - break; - - case HYPER_SHIELD: - capacity = sink_rate = 10.0e3f; - shield_factor = 0.003f; - break; - } - - emcon_power[0] = 0; - emcon_power[1] = 0; - emcon_power[2] = 100; -} - -// +----------------------------------------------------------------------+ - -Shield::Shield(const Shield& s) -: System(s), shield_factor(s.shield_factor), requested_power_level(0.0f), -shield_cutoff(s.shield_cutoff), shield_capacitor(s.shield_capacitor), -shield_bubble(s.shield_bubble), deflection_cost(s.deflection_cost), -shield_curve(s.shield_curve) -{ - power_flags = s.power_flags; - energy = 0.0f; - power_level = 0.0f; - shield_level = 0.0f; - - Mount(s); -} - -// +--------------------------------------------------------------------+ - -Shield::~Shield() -{ } - -void -Shield::SetShieldCapacitor(bool c) -{ - shield_capacitor = c; - - if (shield_capacitor) { - power_flags = POWER_CRITICAL; - shield_curve = 0.05f; - } - else { - power_flags = POWER_WATTS | POWER_CRITICAL; - shield_curve = 0.25f; - } -} - -// +--------------------------------------------------------------------+ - -void -Shield::ExecFrame(double seconds) -{ - System::ExecFrame(seconds); - - if (power_level < requested_power_level) { - power_level += (float) (seconds * 0.10); // ten seconds to charge up - - if (power_level > requested_power_level) - power_level = (float) requested_power_level; - } - else if (power_level > requested_power_level) { - power_level -= (float) (seconds * 0.20); // five seconds to power down - - if (power_level < requested_power_level) - power_level = (float) requested_power_level; - } - - if (power_level < 0.01 && !shield_capacitor) { - shield_level = 0.0f; - energy = 0.0f; - } -} - -// +----------------------------------------------------------------------+ - -void -Shield::Distribute(double delivered_energy, double seconds) -{ - System::Distribute(delivered_energy, seconds); - - if (shield_capacitor) { - if (shield_cutoff > 0 && shield_cutoff < 0.999) { - float cutoff = shield_cutoff * capacity; - - if (energy > cutoff) - shield_level = (energy-cutoff)/(capacity-cutoff); - else - shield_level = 0.0f; - } - - else { - shield_level = energy/capacity; - } - } - else { - shield_level = energy/sink_rate; - energy = 0.0f; - } - - if (shield_level < 0) - shield_level = 0; -} - -// +--------------------------------------------------------------------+ - -double -Shield::DeflectDamage(Shot* shot, double damage) -{ - double filter = 1; - double penetration = 5; - double leak = 0; - - if (shot) - penetration = shot->Design()->penetration; - - filter = 1 - shield_factor * penetration; - - if (filter < 0) - filter = 0; - - else if (filter > 1) - filter = 1; - - if (shield_capacitor) { - if (shield_cutoff > 0 && shield_level < 1e-6) { - leak = damage; - energy -= (float) (damage * deflection_cost); - } - - else { - leak = damage * (1 - pow(shield_level, shield_curve) * filter * availability); - - double deflected = damage - leak; - energy -= (float) deflected * deflection_cost; - } - - } - else { - leak = damage * (1 - pow(shield_level, shield_curve) * filter * availability); - } - - return leak; -} - -// +--------------------------------------------------------------------+ - -void -Shield::SetPowerLevel(double level) -{ - if (level > 100) - level = 100; - else if (level < 0) - level = 0; - - level /= 100; - - if (requested_power_level != level) { - // if the system is on emergency override power, - // do not let the EMCON system use this method - // to drop it back to normal power: - if (power_level > 1 && level == 1) { - requested_power_level = (float) power_level; - return; - } - - requested_power_level = (float) level; - } -} - -void -Shield::SetNetShieldLevel(int level) -{ - if (level > 100) level = 100; - else if (level < 0) level = 0; - - requested_power_level = (float) (level/100.0); - power_level = requested_power_level; -} - -void -Shield::DoEMCON(int index) -{ - int e = GetEMCONPower(index); - - if (power_level * 100 > e || emcon != index) { - if (e == 0) { - PowerOff(); - } - else if (emcon != index) { - PowerOn(); - - if (power_level * 100 > e) - SetPowerLevel(e); - } - } - - emcon = index; -} diff --git a/Stars45/Shield.h b/Stars45/Shield.h deleted file mode 100644 index 57dc7dc..0000000 --- a/Stars45/Shield.h +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Conventional Shield (system) class -*/ - -#ifndef Shield_h -#define Shield_h - -#include "Types.h" -#include "System.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Shot; -class Sound; - -// +--------------------------------------------------------------------+ - -class Shield : public System -{ -public: - enum SUBTYPE { DEFLECTOR = 1, GRAV_SHIELD, HYPER_SHIELD }; - - Shield(SUBTYPE s); - Shield(const Shield& rhs); - virtual ~Shield(); - - virtual void ExecFrame(double seconds); - double DeflectDamage(Shot* shot, double shot_damage); - - double ShieldLevel() const { return shield_level * 100; } - double ShieldFactor() const { return shield_factor; } - double ShieldCurve() const { return shield_curve; } - void SetShieldFactor(double f) { shield_factor = (float) f; } - void SetShieldCurve(double c) { shield_curve = (float) c; } - double ShieldCutoff() const { return shield_cutoff; } - void SetShieldCutoff(double f) { shield_cutoff = (float) f; } - double Capacity() const { return capacity; } - double Consumption() const { return sink_rate; } - void SetConsumption(double r) { sink_rate = (float)r; } - bool ShieldCapacitor() const { return shield_capacitor; } - void SetShieldCapacitor(bool c); - bool ShieldBubble() const { return shield_bubble; } - void SetShieldBubble(bool b) { shield_bubble = b; } - double DeflectionCost() const { return deflection_cost; } - void SetDeflectionCost(double c) { deflection_cost = (float) c; } - - // override from System: - virtual void SetPowerLevel(double level); - virtual void SetNetShieldLevel(int level); - - virtual void Distribute(double delivered_energy, double seconds); - virtual void DoEMCON(int emcon); - -protected: - bool shield_capacitor; - bool shield_bubble; - float shield_factor; - float shield_level; - float shield_curve; - float shield_cutoff; - float requested_power_level; - float deflection_cost; -}; - -#endif // Shield_h - diff --git a/Stars45/ShieldRep.cpp b/Stars45/ShieldRep.cpp deleted file mode 100644 index ccce2d6..0000000 --- a/Stars45/ShieldRep.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ShieldRep Solid class -*/ - -#include "ShieldRep.h" -#include "Random.h" - -#include "Game.h" -#include "Light.h" -#include "Solid.h" -#include "Bitmap.h" -#include "Color.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -const int MAX_SHIELD_HITS = 16; - -// +--------------------------------------------------------------------+ - -struct ShieldHit -{ - Vec3 hitloc; - double damage; - double age; - Shot* shot; - - ShieldHit() : damage(0), age(0), shot(0) { } -}; - -// +--------------------------------------------------------------------+ - -ShieldRep::ShieldRep() -{ - bubble = false; - luminous = true; - trans = true; - nhits = 0; - - hits = new ShieldHit[MAX_SHIELD_HITS]; -} - -ShieldRep::~ShieldRep() -{ - delete [] hits; -} - -// +--------------------------------------------------------------------+ - -void -ShieldRep::Hit(Vec3 impact, Shot* shot, double damage) -{ - if (!model || model->GetSurfaces().size() < 1) - return; - - // transform impact into object space: - Matrix xform(Orientation()); - - Vec3 tmp = impact - loc; - - impact.x = tmp * Vec3(xform(0,0), xform(0,1), xform(0,2)); - impact.y = tmp * Vec3(xform(1,0), xform(1,1), xform(1,2)); - impact.z = tmp * Vec3(xform(2,0), xform(2,1), xform(2,2)); - - // find slot to store the hit: - int i; - int slot = -1; - double age = -1; - - for (i = 0; i < MAX_SHIELD_HITS; i++) { - if (hits[i].shot == shot) { - slot = i; - break; - } - } - - if (slot < 0) { - for (i = 0; i < MAX_SHIELD_HITS; i++) { - if (hits[i].damage <= 0) { - slot = i; - break; - } - - if (hits[i].age > age) { - slot = i; - age = hits[i].age; - } - } - } - - if (slot >= 0 && slot < MAX_SHIELD_HITS) { - // record the hit in the slot: - hits[slot].hitloc = impact; - hits[slot].damage = damage; - hits[slot].age = 1; - hits[slot].shot = shot; - - if (nhits < MAX_SHIELD_HITS) - nhits++; - } -} - -// +--------------------------------------------------------------------+ - -void -ShieldRep::Energize(double seconds, bool b) -{ - bubble = b; - - if (nhits < 1) return; - - nhits = 0; - - for (int i = 0; i < MAX_SHIELD_HITS; i++) { - if (hits[i].damage > 0) { - // age the hit: - hits[i].age += seconds; - hits[i].damage -= (hits[i].damage * 4 * seconds); - - // collect garbage: - if (hits[i].damage < 10) { - hits[i].age = 0; - hits[i].damage = 0; - hits[i].shot = 0; - } - else { - nhits++; - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -ShieldRep::TranslateBy(const Point& ref) -{ - true_eye_point = ref; - Solid::TranslateBy(ref); -} - -// +--------------------------------------------------------------------+ - -void -ShieldRep::Illuminate() -{ - if (!model) return; - - Surface* surf = model->GetSurfaces().first(); - VertexSet* vset = surf->GetVertexSet(); - int nverts = vset->nverts; - - for (int i = 0; i < nverts; i++) { - vset->diffuse[i] = 0; - vset->specular[i] = 0; - } - - double all_damage = 0; - - if (nhits < 1) return; - - for (int i = 0; i < MAX_SHIELD_HITS; i++) { - if (hits[i].damage > 0) { - // add the hit's contribution to the shield verts: - Vec3 hitloc = hits[i].hitloc; - double hitdam = hits[i].damage * 2000; - - all_damage += hits[i].damage; - - if (!bubble) { - - double limit = radius * radius; - if (hitdam > limit) - hitdam = limit; - - for (int v = 0; v < nverts; v++) { - double dist = (vset->loc[v] - hitloc).length(); - - if (dist < 1) - dist = 1; // can't divide by zero! - - else - dist = pow(dist, 2.7); - - double pert = Random(0.1, 1.5); - double intensity = pert*hitdam/dist; - - if (intensity > 0.003) - vset->diffuse[v] = ((Color::White * intensity) + vset->diffuse[v]).Value(); - } - - } - } - } - - if (bubble) { - double shield_gain = 1; - - if (all_damage < 1000) { - shield_gain = all_damage / 1000; - } - - for (int i = 0; i < nverts; i++) { - Vec3 vloc = (vset->loc[i] * orientation) + loc; - Vec3 vnrm = (vset->nrm[i] * orientation); - - Vec3 V = vloc * -1.0f; - V.Normalize(); - - double intensity = 1 - V*vnrm; - - if (intensity > 0) { - intensity *= intensity; - - if (intensity > 1) intensity = 1; - - intensity *= (shield_gain * Random(0.75, 1.0)); - - Color vs = Color::White * intensity; - vset->diffuse[i] = vs.Value(); - } - } - } - - InvalidateSurfaceData(); -} - -void -ShieldRep::Render(Video* video, DWORD flags) -{ - if ((flags & RENDER_ADDITIVE) == 0) - return; - - if (nhits > 0) { - Illuminate(); - Solid::Render(video, RENDER_ALPHA); // have to lie about the render flag - // or the engine will reject the solid - } -} \ No newline at end of file diff --git a/Stars45/ShieldRep.h b/Stars45/ShieldRep.h deleted file mode 100644 index b034c0d..0000000 --- a/Stars45/ShieldRep.h +++ /dev/null @@ -1,47 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ShieldRep Solid class -*/ - -#ifndef ShieldRep_h -#define ShieldRep_h - -#include "Types.h" -#include "Solid.h" - -// +--------------------------------------------------------------------+ - -struct ShieldHit; -class Shot; - -class ShieldRep : public Solid -{ -public: - ShieldRep(); - virtual ~ShieldRep(); - - // operations - virtual void Render(Video* video, DWORD flags); - virtual void Energize(double seconds, bool bubble=false); - int ActiveHits() const { return nhits; } - virtual void Hit(Vec3 impact, Shot* shot, double damage=0); - virtual void TranslateBy(const Point& ref); - virtual void Illuminate(); - -protected: - int nhits; - ShieldHit* hits; - Point true_eye_point; - bool bubble; -}; - -#endif // ShieldRep_h - diff --git a/Stars45/Ship.cpp b/Stars45/Ship.cpp deleted file mode 100644 index 531f99f..0000000 --- a/Stars45/Ship.cpp +++ /dev/null @@ -1,5313 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Starship class -*/ - -#include "Ship.h" -#include "ShipAI.h" -#include "ShipCtrl.h" -#include "ShipDesign.h" -#include "ShipKiller.h" -#include "Shot.h" -#include "Drone.h" -#include "SeekerAI.h" -#include "HardPoint.h" -#include "Weapon.h" -#include "WeaponGroup.h" -#include "Shield.h" -#include "ShieldRep.h" -#include "Computer.h" -#include "FlightComp.h" -#include "Drive.h" -#include "QuantumDrive.h" -#include "Farcaster.h" -#include "Thruster.h" -#include "Power.h" -#include "FlightDeck.h" -#include "LandingGear.h" -#include "Hangar.h" -#include "Sensor.h" -#include "Contact.h" -#include "CombatUnit.h" -#include "Element.h" -#include "Instruction.h" -#include "RadioMessage.h" -#include "RadioHandler.h" -#include "RadioTraffic.h" -#include "NavLight.h" -#include "NavSystem.h" -#include "NavAI.h" -#include "DropShipAI.h" -#include "Explosion.h" -#include "MissionEvent.h" -#include "ShipSolid.h" -#include "Sim.h" -#include "SimEvent.h" -#include "StarSystem.h" -#include "TerrainRegion.h" -#include "Terrain.h" -#include "System.h" -#include "Component.h" -#include "KeyMap.h" -#include "RadioView.h" -#include "AudioConfig.h" -#include "CameraDirector.h" -#include "HUDView.h" -#include "Random.h" -#include "RadioVox.h" - -#include "NetGame.h" -#include "NetUtil.h" - -#include "MotionController.h" -#include "Keyboard.h" -#include "Joystick.h" -#include "Bolt.h" -#include "Game.h" -#include "Clock.h" -#include "ContentBundle.h" -#include "Solid.h" -#include "Shadow.h" -#include "Skin.h" -#include "Sprite.h" -#include "Light.h" -#include "Bitmap.h" -#include "Button.h" -#include "Sound.h" -#include "DataLoader.h" -#include "Panic.h" - -#include "Parser.h" -#include "Reader.h" - -// +----------------------------------------------------------------------+ - -static int base_contact_id = 0; -static double range_min = 0; -static double range_max = 250e3; - -int Ship::control_model = 0; // standard -int Ship::flight_model = 0; // standard -int Ship::landing_model = 0; // standard -double Ship::friendly_fire_level = 1; // 100% - -const int HIT_NOTHING = 0; -const int HIT_HULL = 1; -const int HIT_SHIELD = 2; -const int HIT_BOTH = 3; -const int HIT_TURRET = 4; - -// +----------------------------------------------------------------------+ - -Ship::Ship(const char* ship_name, const char* reg_num, ShipDesign* ship_dsn, int IFF, int cmd_ai, const int* load) - : IFF_code(IFF), killer(0), throttle(0), augmenter(false), throttle_request(0), - shield(0), shieldRep(0), main_drive(0), quantum_drive(0), farcaster(0), - check_fire(false), probe(0), sensor_drone(0), primary(0), secondary(1), - cmd_chain_index(0), target(0), subtarget(0), radio_orders(0), launch_point(0), - g_force(0.0f), sensor(0), navsys(0), flcs(0), hangar(0), respawns(0), invulnerable(false), - thruster(0), decoy(0), ai_mode(2), command_ai_level(cmd_ai), flcs_mode(FLCS_AUTO), loadout(0), - emcon(3), old_emcon(3), master_caution(false), cockpit(0), gear(0), skin(0), - auto_repair(true), last_repair_time(0), last_eval_time(0), last_beam_time(0), last_bolt_time(0), - warp_fov(1), flight_phase(LAUNCH), launch_time(0), carrier(0), dock(0), ff_count(0), - inbound(0), element(0), director_info("Init"), combat_unit(0), net_control(0), - track(0), ntrack(0), track_time(0), helm_heading(0.0f), helm_pitch(0.0f), - altitude_agl(-1.0e6f), transition_time(0.0f), transition_type(TRANSITION_NONE), - friendly_fire_time(0), ward(0), net_observer_mode(false), orig_elem_index(-1) -{ - sim = Sim::GetSim(); - - strcpy_s(name, ship_name); - if (reg_num && *reg_num) - strcpy_s(regnum, reg_num); - else regnum[0] = 0; - - design = ship_dsn; - - if (!design) { - char msg[256]; - sprintf_s(msg, "No ship design found for '%s'\n", ship_name); - Panic::Panic(msg); - } - - obj_type = SimObject::SIM_SHIP; - - radius = design->radius; - mass = design->mass; - integrity = design->integrity; - vlimit = design->vlimit; - - agility = design->agility; - wep_mass = 0.0f; - wep_resist = 0.0f; - - CL = design->CL; - CD = design->CD; - stall = design->stall; - - chase_vec = design->chase_vec; - bridge_vec = design->bridge_vec; - - acs = design->acs; - pcs = design->acs; - - auto_repair = design->repair_auto; - - while (!base_contact_id) - base_contact_id = rand() % 1000; - - contact_id = base_contact_id++; - int sys_id = 0; - - for (int i = 0; i < design->reactors.size(); i++) { - PowerSource* reactor = new PowerSource(*design->reactors[i]); - reactor->SetShip(this); - reactor->SetID(sys_id++); - reactors.append(reactor); - systems.append(reactor); - } - - for (int i = 0; i < design->drives.size(); i++) { - Drive* drive = new Drive(*design->drives[i]); - drive->SetShip(this); - drive->SetID(sys_id++); - - int src_index = drive->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(drive); - - drives.append(drive); - systems.append(drive); - } - - if (design->quantum_drive) { - quantum_drive = new QuantumDrive(*design->quantum_drive); - quantum_drive->SetShip(this); - quantum_drive->SetID(sys_id++); - - int src_index = quantum_drive->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(quantum_drive); - - quantum_drive->SetShip(this); - systems.append(quantum_drive); - } - - if (design->farcaster) { - farcaster = new Farcaster(*design->farcaster); - farcaster->SetShip(this); - farcaster->SetID(sys_id++); - - int src_index = farcaster->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(farcaster); - - farcaster->SetShip(this); - systems.append(farcaster); - } - - if (design->thruster) { - thruster = new Thruster(*design->thruster); - thruster->SetShip(this); - thruster->SetID(sys_id++); - - int src_index = thruster->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(thruster); - - thruster->SetShip(this); - systems.append(thruster); - } - - if (design->shield) { - shield = new Shield(*design->shield); - shield->SetShip(this); - shield->SetID(sys_id++); - - int src_index = shield->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(shield); - - if (design->shield_model) { - shieldRep = new ShieldRep; - shieldRep->UseModel(design->shield_model); - } - - systems.append(shield); - } - - for (int i = 0; i < design->flight_decks.size(); i++) { - FlightDeck* deck = new FlightDeck(*design->flight_decks[i]); - deck->SetShip(this); - deck->SetCarrier(this); - deck->SetID(sys_id++); - deck->SetIndex(i); - - int src_index = deck->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(deck); - - flight_decks.append(deck); - systems.append(deck); - } - - if (design->flight_decks.size() > 0) { - if (!hangar) { - hangar = new Hangar; - hangar->SetShip(this); - } - } - - if (design->squadrons.size() > 0) { - if (!hangar) { - hangar = new Hangar; - hangar->SetShip(this); - } - - for (int i = 0; i < design->squadrons.size(); i++) { - ShipSquadron* s = design->squadrons[i]; - hangar->CreateSquadron(s->name, 0, s->design, s->count, GetIFF(), 0, 0, s->avail); - } - } - - if (design->gear) { - gear = new LandingGear(*design->gear); - gear->SetShip(this); - gear->SetID(sys_id++); - - int src_index = gear->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(gear); - - systems.append(gear); - } - - if (design->sensor) { - sensor = new Sensor(*design->sensor); - sensor->SetShip(this); - sensor->SetID(sys_id++); - - int src_index = sensor->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(sensor); - - if (IsStarship() || IsStatic() || !strncmp(design->name, "Camera", 6)) - sensor->SetMode(Sensor::CST); - - systems.append(sensor); - } - - int wep_index = 1; - - for (int i = 0; i < design->weapons.size(); i++) { - Weapon* gun = new Weapon(*design->weapons[i]); - gun->SetID(sys_id++); - gun->SetOwner(this); - gun->SetIndex(wep_index++); - - int src_index = gun->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(gun); - - WeaponGroup* group = FindWeaponGroup(gun->Group()); - group->AddWeapon(gun); - group->SetAbbreviation(gun->Abbreviation()); - - systems.append(gun); - - if (IsDropship() && gun->GetTurret()) - gun->SetFiringOrders(Weapon::POINT_DEFENSE); - else - gun->SetFiringOrders(Weapon::MANUAL); - } - - int loadout_size = design->hard_points.size(); - - if (load && loadout_size > 0) { - loadout = new int[loadout_size]; - - for (int i = 0; i < loadout_size; i++) { - int mounted_weapon = loadout[i] = load[i]; - - if (mounted_weapon < 0) - continue; - - Weapon* missile = design->hard_points[i]->CreateWeapon(mounted_weapon); - - if (missile) { - missile->SetID(sys_id++); - missile->SetOwner(this); - missile->SetIndex(wep_index++); - - WeaponGroup* group = FindWeaponGroup(missile->Group()); - group->AddWeapon(missile); - group->SetAbbreviation(missile->Abbreviation()); - - systems.append(missile); - } - } - } - - if (weapons.size() > 1) { - primary = -1; - secondary = -1; - - for (int i = 0; i < weapons.size(); i++) { - WeaponGroup* group = weapons[i]; - if (group->IsPrimary() && primary < 0) { - primary = i; - - // turrets on fighters are set to point defense by default, - // this forces the primary turret back to manual control - group->SetFiringOrders(Weapon::MANUAL); - } - - else if (group->IsMissile() && secondary < 0) { - secondary = i; - } - } - - if (primary < 0) primary = 0; - if (secondary < 0) secondary = 1; - - if (weapons.size() > 4) { - ::Print("WARNING: Ship '%s' type '%s' has %d wep groups (max=4)\n", - Name(), DesignName(), weapons.size()); - } - } - - if (design->decoy) { - decoy = new Weapon(*design->decoy); - decoy->SetOwner(this); - decoy->SetID(sys_id++); - decoy->SetIndex(wep_index++); - - int src_index = decoy->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(decoy); - - systems.append(decoy); - } - - for (int i = 0; i < design->navlights.size(); i++) { - NavLight* navlight = new NavLight(*design->navlights[i]); - navlight->SetShip(this); - navlight->SetID(sys_id++); - navlight->SetOffset(((DWORD) this) << 2); - navlights.append(navlight); - systems.append(navlight); - } - - if (design->navsys) { - navsys = new NavSystem(*design->navsys); - navsys->SetShip(this); - navsys->SetID(sys_id++); - - int src_index = navsys->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(navsys); - - systems.append(navsys); - } - - if (design->probe) { - probe = new Weapon(*design->probe); - probe->SetOwner(this); - probe->SetID(sys_id++); - probe->SetIndex(wep_index++); - - int src_index = probe->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(probe); - - systems.append(probe); - } - - for (int i = 0; i < design->computers.size(); i++) { - Computer* comp = 0; - - if (design->computers[i]->Subtype() == Computer::FLIGHT) { - flcs = new FlightComp(*design->computers[i]); - - flcs->SetShip(this); - flcs->SetMode(flcs_mode); - flcs->SetVelocityLimit(vlimit); - - if (thruster) - flcs->SetTransLimit(thruster->TransXLimit(), - thruster->TransYLimit(), - thruster->TransZLimit()); - else - flcs->SetTransLimit(design->trans_x, - design->trans_y, - design->trans_z); - - comp = flcs; - } - else { - comp = new Computer(*design->computers[i]); - } - - comp->SetShip(this); - comp->SetID(sys_id++); - int src_index = comp->GetSourceIndex(); - if (src_index >= 0 && src_index < reactors.size()) - reactors[src_index]->AddClient(comp); - - computers.append(comp); - systems.append(comp); - } - - radio_orders = new Instruction("", Point(0,0,0)); - - // Load Detail Set: - for (int i = 0; i < DetailSet::MAX_DETAIL; i++) { - if (design->models[i].size() > 0) { - Solid* solid = new ShipSolid(this); - solid->UseModel(design->models[i].at(0)); - solid->CreateShadows(1); - - Point* offset = 0; - Point* spin = 0; - - if (design->offsets[i].size() > 0) - offset = new Point(*design->offsets[i].at(0)); - - if (design->spin_rates.size() > 0) - spin = new Point(*design->spin_rates.at(0)); - - detail_level = detail.DefineLevel(design->feature_size[i], solid, offset, spin); - } - - if (design->models[i].size() > 1) { - for (int n = 1; n < design->models[i].size(); n++) { - Solid* solid = new ShipSolid(this); //Solid; - solid->UseModel(design->models[i].at(n)); - solid->CreateShadows(1); - - Point* offset = 0; - Point* spin = 0; - - if (design->offsets[i].size() > n) - offset = new Point(*design->offsets[i].at(n)); - - if (design->spin_rates.size() > n) - spin = new Point(*design->spin_rates.at(n)); - - detail.AddToLevel(detail_level, solid, offset, spin); - } - } - } - - // start with lowest available detail: - detail_level = 0; // this is highest -> detail.NumLevels()-1); - rep = detail.GetRep(detail_level); - - if (design->cockpit_model) { - cockpit = new Solid; - cockpit->UseModel(design->cockpit_model); - cockpit->SetForeground(true); - } - - if (design->main_drive >= 0 && design->main_drive < drives.size()) - main_drive = drives[design->main_drive]; - - // only use light from drives: - light = 0; - - // setup starship helm stuff: - if (IsStarship()) { - flcs_mode = FLCS_HELM; - } - - // initialize the AI: - dir = 0; - SetControls(0); - - for (int i = 0; i < 4; i++) { - missile_id[i] = 0; - missile_eta[i] = 0; - trigger[i] = false; - } -} - -// +--------------------------------------------------------------------+ - -Ship::~Ship() -{ - // the loadout can not be cleared during Destroy, because it - // is needed after Destroy to create the re-spawned ship - - delete [] loadout; - loadout = 0; - - Destroy(); -} - -// +--------------------------------------------------------------------+ - -void -Ship::Destroy() -{ - // destroy fighters on deck: - ListIter deck = flight_decks; - while (++deck) { - for (int i = 0; i < deck->NumSlots(); i++) { - Ship* s = deck->GetShip(i); - - if (s && !s->IsDying() && !s->IsDead()) { - if (sim && sim->IsActive()) { - s->DeathSpiral(); - } - else { - s->transition_type = TRANSITION_DEAD; - s->Destroy(); - } - } - } - } - - if (element) { - // mission ending for this ship, evaluate objectives one last time: - for (int i = 0; i < element->NumObjectives(); i++) { - Instruction* obj = element->GetObjective(i); - - if (obj->Status() <= Instruction::ACTIVE) { - obj->Evaluate(this); - } - } - - combat_unit = element->GetCombatUnit(); - SetElement(0); - } - - delete [] track; - track = 0; - - delete shield; - shield = 0; - delete sensor; - sensor = 0; - delete navsys; - navsys = 0; - delete thruster; - thruster = 0; - delete farcaster; - farcaster = 0; - delete quantum_drive; - quantum_drive = 0; - delete decoy; - decoy = 0; - delete probe; - probe = 0; - delete gear; - gear = 0; - - main_drive = 0; - flcs = 0; - - // repair queue does not own the systems under repair: - repair_queue.clear(); - - navlights.destroy(); - flight_decks.destroy(); - computers.destroy(); - weapons.destroy(); - drives.destroy(); - reactors.destroy(); - - // this is now a list of dangling pointers: - systems.clear(); - - delete hangar; - hangar = 0; - - // this also destroys the rep: - detail.Destroy(); - rep = 0; - - GRAPHIC_DESTROY(cockpit); - GRAPHIC_DESTROY(shieldRep); - LIGHT_DESTROY(light); - - delete launch_point; - launch_point = 0; - - delete radio_orders; - radio_orders = 0; - - delete dir; - dir = 0; - - delete killer; - killer = 0; - - // inbound slot is deleted by flight deck: - inbound = 0; - - life = 0; - Notify(); -} - -// +--------------------------------------------------------------------+ - -void -Ship::Initialize() -{ - ShipDesign::Initialize(); - Thruster::Initialize(); -} - -// +--------------------------------------------------------------------+ - -void -Ship::Close() -{ - ShipDesign::Close(); - Thruster::Close(); -} - -void -Ship::SetupAgility() -{ - const float ROLL_SPEED = (float)(PI * 0.1500); - const float PITCH_SPEED = (float)(PI * 0.0250); - const float YAW_SPEED = (float)(PI * 0.0250); - - drag = design->drag; - dr_drg = design->roll_drag; - dp_drg = design->pitch_drag; - dy_drg = design->yaw_drag; - - if (IsDying()) { - drag = 0.0f; - dr_drg *= 0.25f; - dp_drg *= 0.25f; - dy_drg *= 0.25f; - } - - if (flight_model > 0) { - drag = design->arcade_drag; - thrust *= 10.0f; - } - - float yaw_air_factor = 1.0f; - - if (IsAirborne()) { - bool grounded = AltitudeAGL() < Radius()/2; - - if (flight_model > 0) { - drag *= 2.0f; - - if (gear && gear->GetState() != LandingGear::GEAR_UP) - drag *= 2.0f; - - if (grounded) - drag *= 3.0f; - } - - else { - if (Class() != LCA) - yaw_air_factor = 0.3f; - - double rho = GetDensity(); - double speed = Velocity().length(); - - agility = design->air_factor * rho * speed - wep_resist; - - if (grounded && agility < 0) - agility = 0; - - else if (!grounded && agility < 0.5 * design->agility) - agility = 0.5 * design->agility; - - else if (agility > 2 * design->agility) - agility = 2 * design->agility; - - // undercarriage aerodynamic drag - if (gear && gear->GetState() != LandingGear::GEAR_UP) - drag *= 5.0f; - - // wheel rolling friction - if (grounded) - drag *= 10.0f; - - // dead engine drag ;-) - if (thrust < 10) - drag *= 5.0f; - } - } - - else { - agility = design->agility - wep_resist; - - if (agility < 0.5 * design->agility) - agility = 0.5 * design->agility; - - if (flight_model == 0) - drag = 0.0f; - } - - float rr = (float) (design->roll_rate * PI / 180); - float pr = (float) (design->pitch_rate * PI / 180); - float yr = (float) (design->yaw_rate * PI / 180); - - if (rr == 0) rr = (float) agility * ROLL_SPEED; - if (pr == 0) pr = (float) agility * PITCH_SPEED; - if (yr == 0) yr = (float) agility * YAW_SPEED * yaw_air_factor; - - SetAngularRates(rr, pr, yr); -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetRegion(SimRegion* rgn) -{ - SimObject::SetRegion(rgn); - - const double GRAV = 6.673e-11; - - if (IsGroundUnit()) { - // glue buildings to the terrain: - Point loc = Location(); - Terrain* terrain = region->GetTerrain(); - - if (terrain) { - loc.y = terrain->Height(loc.x, loc.z); - MoveTo(loc); - } - } - - else if (IsAirborne()) { - Orbital* primary = GetRegion()->GetOrbitalRegion()->Primary(); - - double m0 = primary->Mass(); - double r = primary->Radius(); - - SetGravity((float) (GRAV * m0 / (r*r))); - SetBaseDensity(1.0f); - } - - else { - SetGravity(0.0f); - SetBaseDensity(0.0f); - - if (IsStarship()) - flcs_mode = FLCS_HELM; - else - flcs_mode = FLCS_AUTO; - } -} - -// +--------------------------------------------------------------------+ - -int -Ship::GetTextureList(List& textures) -{ - textures.clear(); - - for (int d = 0; d < detail.NumLevels(); d++) { - for (int i = 0; i < detail.NumModels(d); i++) { - Graphic* g = detail.GetRep(d, i); - - if (g->IsSolid()) { - Solid* solid = (Solid*) g; - Model* model = solid->GetModel(); - - if (model) { - for (int n = 0; n < model->NumMaterials(); n++) { - //textures.append(model->textures[n]); - } - } - } - } - } - - return textures.size(); -} - -// +--------------------------------------------------------------------+ - -void -Ship::Activate(Scene& scene) -{ - int i = 0; - SimObject::Activate(scene); - - for (i = 0; i < detail.NumModels(detail_level); i++) { - Graphic* g = detail.GetRep(detail_level, i); - scene.AddGraphic(g); - } - - for (i = 0; i < flight_decks.size(); i++) - scene.AddLight(flight_decks[i]->GetLight()); - - if (shieldRep) - scene.AddGraphic(shieldRep); - - if (cockpit) { - scene.AddForeground(cockpit); - cockpit->Hide(); - } - - Drive* drive = GetDrive(); - if (drive) { - for (i = 0; i < drive->NumEngines(); i++) { - Graphic* flare = drive->GetFlare(i); - if (flare) { - scene.AddGraphic(flare); - } - - Graphic* trail = drive->GetTrail(i); - if (trail) { - scene.AddGraphic(trail); - } - } - } - - Thruster* thruster = GetThruster(); - if (thruster) { - for (i = 0; i < thruster->NumThrusters(); i++) { - Graphic* flare = thruster->Flare(i); - if (flare) { - scene.AddGraphic(flare); - } - - Graphic* trail = thruster->Trail(i); - if (trail) { - scene.AddGraphic(trail); - } - } - } - - for (int n = 0; n < navlights.size(); n++) { - NavLight* navlight = navlights[n]; - for (i = 0; i < navlight->NumBeacons(); i++) { - Graphic* beacon = navlight->Beacon(i); - if (beacon) - scene.AddGraphic(beacon); - } - } - - ListIter g = weapons; - while (++g) { - ListIter w = g->GetWeapons(); - while (++w) { - Solid* turret = w->GetTurret(); - if (turret) { - scene.AddGraphic(turret); - - Solid* turret_base = w->GetTurretBase(); - if (turret_base) - scene.AddGraphic(turret_base); - } - if (w->IsMissile()) { - for (i = 0; i < w->Ammo(); i++) { - Solid* store = w->GetVisibleStore(i); - if (store) - scene.AddGraphic(store); - } - } - } - } - - if (gear && gear->GetState() != LandingGear::GEAR_UP) { - for (int i = 0; i < gear->NumGear(); i++) { - scene.AddGraphic(gear->GetGear(i)); - } - } -} - -void -Ship::Deactivate(Scene& scene) -{ - int i = 0; - SimObject::Deactivate(scene); - - for (i = 0; i < detail.NumModels(detail_level); i++) { - Graphic* g = detail.GetRep(detail_level, i); - scene.DelGraphic(g); - } - - for (i = 0; i < flight_decks.size(); i++) - scene.DelLight(flight_decks[i]->GetLight()); - - if (shieldRep) - scene.DelGraphic(shieldRep); - - if (cockpit) - scene.DelForeground(cockpit); - - Drive* drive = GetDrive(); - if (drive) { - for (i = 0; i < drive->NumEngines(); i++) { - Graphic* flare = drive->GetFlare(i); - if (flare) { - scene.DelGraphic(flare); - } - - Graphic* trail = drive->GetTrail(i); - if (trail) { - scene.DelGraphic(trail); - } - } - } - - Thruster* thruster = GetThruster(); - if (thruster) { - for (i = 0; i < thruster->NumThrusters(); i++) { - Graphic* flare = thruster->Flare(i); - if (flare) { - scene.DelGraphic(flare); - } - - Graphic* trail = thruster->Trail(i); - if (trail) { - scene.DelGraphic(trail); - } - } - } - - for (int n = 0; n < navlights.size(); n++) { - NavLight* navlight = navlights[n]; - for (i = 0; i < navlight->NumBeacons(); i++) { - Graphic* beacon = navlight->Beacon(i); - if (beacon) - scene.DelGraphic(beacon); - } - } - - ListIter g = weapons; - while (++g) { - ListIter w = g->GetWeapons(); - while (++w) { - Solid* turret = w->GetTurret(); - if (turret) { - scene.DelGraphic(turret); - - Solid* turret_base = w->GetTurretBase(); - if (turret_base) - scene.DelGraphic(turret_base); - } - if (w->IsMissile()) { - for (i = 0; i < w->Ammo(); i++) { - Solid* store = w->GetVisibleStore(i); - if (store) - scene.DelGraphic(store); - } - } - } - } - - if (gear) { - for (int i = 0; i < gear->NumGear(); i++) { - scene.DelGraphic(gear->GetGear(i)); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::MatchOrientation(const Ship& s) -{ - Point pos = cam.Pos(); - cam.Clone(s.cam); - cam.MoveTo(pos); - - if (rep) - rep->SetOrientation(cam.Orientation()); - - if (cockpit) - cockpit->SetOrientation(cam.Orientation()); -} - -// +--------------------------------------------------------------------+ - -void -Ship::ClearTrack() -{ - const int DEFAULT_TRACK_LENGTH = 20; // 10 seconds - - if (!track) { - track = new Point[DEFAULT_TRACK_LENGTH]; - } - - track[0] = Location(); - ntrack = 1; - track_time = Clock::GetInstance()->GameTime(); -} - -void -Ship::UpdateTrack() -{ - const int DEFAULT_TRACK_UPDATE = 500; // milliseconds - const int DEFAULT_TRACK_LENGTH = 20; // 10 seconds - - DWORD time = Clock::GetInstance()->GameTime(); - - if (!track) { - track = new Point[DEFAULT_TRACK_LENGTH]; - track[0] = Location(); - ntrack = 1; - track_time = time; - } - - else if (time - track_time > DEFAULT_TRACK_UPDATE) { - if (Location() != track[0]) { - for (int i = DEFAULT_TRACK_LENGTH-2; i >= 0; i--) - track[i+1] = track[i]; - - track[0] = Location(); - if (ntrack < DEFAULT_TRACK_LENGTH) ntrack++; - } - - track_time = time; - } -} - -Point -Ship::TrackPoint(int i) const -{ - if (track && i < ntrack) - return track[i]; - - return Point(); -} - -// +--------------------------------------------------------------------+ - -const char* -Ship::Abbreviation() const -{ - return design->abrv; -} - -const char* -Ship::DesignName() const -{ - return design->DisplayName(); -} - -const char* -Ship::DesignFileName() const -{ - return design->filename; -} - -const char* -Ship::ClassName() const -{ - return ShipDesign::ClassName(design->type); -} - -const char* -Ship::ClassName(int c) -{ - return ShipDesign::ClassName(c); -} - -int -Ship::ClassForName(const char* name) -{ - return ShipDesign::ClassForName(name); -} - -Ship::CLASSIFICATION -Ship::Class() const -{ - return (CLASSIFICATION) design->type; -} - -bool -Ship::IsGroundUnit() const -{ - return (design->type & GROUND_UNITS) ? true : false; -} - -bool -Ship::IsStarship() const -{ - return (design->type & STARSHIPS) ? true : false; -} - -bool -Ship::IsDropship() const -{ - return (design->type & DROPSHIPS) ? true : false; -} - -bool -Ship::IsStatic() const -{ - return design->type >= STATION; -} - -bool -Ship::IsRogue() const -{ - return ff_count >= 50; -} - -// +--------------------------------------------------------------------+ - -bool -Ship::IsHostileTo(const SimObject* o) const -{ - if (o) { - if (IsRogue()) - return true; - - if (o->Type() == SIM_SHIP) { - Ship* s = (Ship*) o; - - if (s->IsRogue()) - return true; - - if (GetIFF() == 0) { - if (s->GetIFF() > 1) - return true; - } - else { - if (s->GetIFF() > 0 && s->GetIFF() != GetIFF()) - return true; - } - } - - else if (o->Type() == SIM_SHOT || o->Type() == SIM_DRONE) { - Shot* s = (Shot*) o; - - if (GetIFF() == 0) { - if (s->GetIFF() > 1) - return true; - } - else { - if (s->GetIFF() > 0 && s->GetIFF() != GetIFF()) - return true; - } - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -double -Ship::RepairSpeed() const -{ - return design->repair_speed; -} - -int -Ship::RepairTeams() const -{ - return design->repair_teams; -} - -// +--------------------------------------------------------------------+ - -int -Ship::NumContacts() const -{ - // cast-away const: - return ((Ship*)this)->ContactList().size(); -} - -List& -Ship::ContactList() -{ - if (region) - return region->TrackList(GetIFF()); - - static List empty_contact_list; - return empty_contact_list; -} - -Contact* -Ship::FindContact(SimObject* s) const -{ - if (!s) return 0; - - ListIter c_iter = ((Ship*) this)->ContactList(); - while (++c_iter) { - Contact* c = c_iter.value(); - - if (c->GetShip() == s) - return c; - - if (c->GetShot() == s) - return c; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -Ship* -Ship::GetController() const -{ - Ship* controller = 0; - - if (carrier) { - // are we in same region as carrier? - if (carrier->GetRegion() == GetRegion()) { - return carrier; - } - - // if not, figure out who our control unit is: - else { - double distance = 10e6; - - ListIter iter = GetRegion()->Carriers(); - while (++iter) { - Ship* test = iter.value(); - if (test->GetIFF() == GetIFF()) { - double d = Point(Location() - test->Location()).length(); - if (d < distance) { - controller = test; - distance = d; - } - } - } - } - } - - if (!controller) { - if (element && element->GetCommander()) - controller = element->GetCommander()->GetShip(1); - } - - return controller; -} - -int -Ship::NumInbound() const -{ - int result = 0; - - for (int i = 0; i < flight_decks.size(); i++) { - result += flight_decks[i]->GetRecoveryQueue().size(); - } - - return result; -} - -int -Ship::NumFlightDecks() const -{ - return flight_decks.size(); -} - -FlightDeck* -Ship::GetFlightDeck(int i) const -{ - if (i >= 0 && i < flight_decks.size()) - return flight_decks[i]; - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetFlightPhase(OP_MODE phase) -{ - if (phase == ACTIVE && !launch_time) { - launch_time = Clock::GetInstance()->GameTime() + 1; - dock = 0; - - if (element) - element->SetLaunchTime(launch_time); - } - - flight_phase = phase; - - if (flight_phase == ACTIVE) - dock = 0; -} - -void -Ship::SetCarrier(Ship* c, FlightDeck* d) -{ - carrier = c; - dock = d; - - if (carrier) - Observe(carrier); -} - -void -Ship::SetInbound(InboundSlot* s) -{ - inbound = s; - - if (inbound && flight_phase == ACTIVE) { - flight_phase = APPROACH; - - SetCarrier((Ship*) inbound->GetDeck()->GetCarrier(), inbound->GetDeck()); - - HUDView* hud = HUDView::GetInstance(); - - if (hud && hud->GetShip() == this) - hud->SetHUDMode(HUDView::HUD_MODE_ILS); - } -} - -void -Ship::Stow() -{ - if (carrier && carrier->GetHangar()) - carrier->GetHangar()->Stow(this); -} - -bool -Ship::IsGearDown() -{ - if (gear && gear->GetState() == LandingGear::GEAR_DOWN) - return true; - - return false; -} - -void -Ship::LowerGear() -{ - if (gear && gear->GetState() != LandingGear::GEAR_DOWN) { - gear->SetState(LandingGear::GEAR_LOWER); - Scene* scene = 0; - - if (rep) - scene = rep->GetScene(); - - if (scene) { - for (int i = 0; i < gear->NumGear(); i++) { - Solid* g = gear->GetGear(i); - if (g) { - if (detail_level == 0) - scene->DelGraphic(g); - else - scene->AddGraphic(g); - } - } - } - } -} - -void -Ship::RaiseGear() -{ - if (gear && gear->GetState() != LandingGear::GEAR_UP) - gear->SetState(LandingGear::GEAR_RAISE); -} - -void -Ship::ToggleGear() -{ - if (gear) { - if (gear->GetState() == LandingGear::GEAR_UP || - gear->GetState() == LandingGear::GEAR_RAISE) { - LowerGear(); - } - else { - RaiseGear(); - } - } -} - -void -Ship::ToggleNavlights() -{ - bool enable = false; - - for (int i = 0; i < navlights.size(); i++) { - if (i == 0) - enable = !navlights[0]->IsEnabled(); - - if (enable) - navlights[i]->Enable(); - else - navlights[i]->Disable(); - } -} - -// +--------------------------------------------------------------------+ - -int -Ship::CollidesWith(Physical& o) -{ - // bounding spheres test: - Point delta_loc = Location() - o.Location(); - if (delta_loc.length() > radius + o.Radius()) - return 0; - - if (!o.Rep()) - return 1; - - for (int i = 0; i < detail.NumModels(detail_level); i++) { - Graphic* g = detail.GetRep(detail_level, i); - - if (o.Type() == SimObject::SIM_SHIP) { - Ship* o_ship = (Ship*) &o; - int o_det = o_ship->detail_level; - - for (int j = 0; j < o_ship->detail.NumModels(o_det); j++) { - Graphic* o_g = o_ship->detail.GetRep(o_det, j); - - if (g->CollidesWith(*o_g)) - return 1; - } - } - else { - // representation collision test (will do bounding spheres first): - if (g->CollidesWith(*o.Rep())) - return 1; - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -static DWORD ff_warn_time = 0; - -int -Ship::HitBy(Shot* shot, Point& impact) -{ - if (shot->Owner() == this || IsNetObserver()) - return HIT_NOTHING; - - if (shot->IsFlak()) - return HIT_NOTHING; - - if (InTransition()) - return HIT_NOTHING; - - Point shot_loc = shot->Location(); - Point delta = shot_loc - Location(); - double dlen = delta.length(); - - Point hull_impact; - int hit_type = HIT_NOTHING; - double dscale = 1; - float scale = design->explosion_scale; - Weapon* wep = 0; - - if (!shot->IsMissile() && !shot->IsBeam()) { - if (dlen > Radius() * 2) - return HIT_NOTHING; - } - - if (scale <= 0) - scale = design->scale; - - if (shot->Owner()) { - const ShipDesign* owner_design = shot->Owner()->Design(); - if (owner_design && owner_design->scale < scale) - scale = (float) owner_design->scale; - } - - - // MISSILE PROCESSING ------------------------------------------------ - - if (shot->IsMissile() && rep) { - if (dlen < rep->Radius()) { - hull_impact = impact = shot_loc; - - hit_type = CheckShotIntersection(shot, impact, hull_impact, &wep); - - if (hit_type) { - if (shot->Damage() > 0) { - DWORD flash = Explosion::HULL_FLASH; - - if ((hit_type & HIT_SHIELD) != 0) - flash = Explosion::SHIELD_FLASH; - - sim->CreateExplosion(impact, Velocity(), flash, 0.3f * scale, scale, region); - sim->CreateExplosion(impact, Point(), Explosion::SHOT_BLAST, 2.0f, scale, region); - } - } - } - - if (hit_type == HIT_NOTHING && shot->IsArmed()) { - SeekerAI* seeker = (SeekerAI*) shot->GetDirector(); - - // if the missile overshot us, take damage proportional to distance - double damage_radius = shot->Design()->lethal_radius; - if (dlen < (damage_radius + Radius())) { - if (seeker && seeker->Overshot()) { - dscale = 1.0 - (dlen / (damage_radius + Radius())); - - if (dscale > 1) - dscale = 1; - - if (ShieldStrength() > 5) { - hull_impact = impact = shot_loc; - - if (shot->Damage() > 0) { - if (shieldRep) - shieldRep->Hit(impact, shot, shot->Damage()*dscale); - sim->CreateExplosion(impact, Velocity(), Explosion::SHIELD_FLASH, 0.20f * scale, scale, region); - sim->CreateExplosion(impact, Point(), Explosion::SHOT_BLAST, 20.0f * scale, scale, region); - } - - hit_type = HIT_BOTH; - } - else { - hull_impact = impact = shot_loc; - - if (shot->Damage() > 0) { - sim->CreateExplosion(impact, Velocity(), Explosion::HULL_FLASH, 0.30f * scale, scale, region); - sim->CreateExplosion(impact, Point(), Explosion::SHOT_BLAST, 20.0f * scale, scale, region); - } - - hit_type = HIT_HULL; - } - } - } - } - } - - // ENERGY WEP PROCESSING --------------------------------------------- - - else { - hit_type = CheckShotIntersection(shot, impact, hull_impact, &wep); - - // impact: - if (hit_type) { - - if (hit_type & HIT_SHIELD) { - if (shieldRep) - shieldRep->Hit(impact, shot, shot->Damage()); - sim->CreateExplosion(impact, Velocity(), Explosion::SHIELD_FLASH, 0.20f * scale, scale, region); - } - - else { - if (shot->IsBeam()) - sim->CreateExplosion(impact, Velocity(), Explosion::BEAM_FLASH, 0.30f * scale, scale, region); - else - sim->CreateExplosion(impact, Velocity(), Explosion::HULL_FLASH, 0.30f * scale, scale, region); - - if (IsStarship()) { - Point burst_vel = hull_impact - Location(); - burst_vel.Normalize(); - burst_vel *= Radius() * 0.5; - burst_vel += Velocity(); - - sim->CreateExplosion(hull_impact, burst_vel, Explosion::HULL_BURST, 0.50f * scale, scale, region, this); - } - } - } - } - - // DAMAGE RESOLUTION ------------------------------------------------- - - if (hit_type != HIT_NOTHING && shot->IsArmed()) { - double effective_damage = shot->Damage() * dscale; - - // FRIENDLY FIRE -------------------------------------------------- - - if (shot->Owner()) { - Ship* s = (Ship*) shot->Owner(); - - if (!IsRogue() && s->GetIFF() == GetIFF() && - s->GetDirector() && s->GetDirector()->Type() < 1000) { - bool was_rogue = s->IsRogue(); - - // only count beam hits once - if (shot->Damage() && !shot->HitTarget() && GetFriendlyFireLevel() > 0) { - int penalty = 1; - - if (shot->IsBeam()) penalty = 5; - else if (shot->IsDrone()) penalty = 7; - - if (s->GetTarget() == this) penalty *= 3; - - s->IncFriendlyFire(penalty); - } - - effective_damage *= GetFriendlyFireLevel(); - - if (Class() > DRONE && s->Class() > DRONE) { - if (s->IsRogue() && !was_rogue) { - RadioMessage* warn = new RadioMessage(s, this, RadioMessage::DECLARE_ROGUE); - RadioTraffic::Transmit(warn); - } - else if (!s->IsRogue() && (Clock::GetInstance()->GameTime() - ff_warn_time) > 5000) { - ff_warn_time = Clock::GetInstance()->GameTime(); - - RadioMessage* warn = 0; - if (s->GetTarget() == this) - warn = new RadioMessage(s, this, RadioMessage::WARN_TARGETED); - else - warn = new RadioMessage(s, this, RadioMessage::WARN_ACCIDENT); - - RadioTraffic::Transmit(warn); - } - } - } - } - - if (effective_damage > 0) { - if (!shot->IsBeam() && shot->Design()->damage_type == WeaponDesign::DMG_NORMAL) { - ApplyTorque(shot->Velocity() * (float) effective_damage * 1e-6f); - } - - if (!NetGame::IsNetGameClient()) { - InflictDamage(effective_damage, shot, hit_type, hull_impact); - } - } - } - - return hit_type; -} - -static bool CheckRaySphereIntersection(Point loc, double radius, Point Q, Point w, double len) -{ - Point d0 = loc - Q; - Point d1 = d0.cross(w); - double dlen = d1.length(); // distance of point from line - - if (dlen > radius) // clean miss - return false; // (no impact) - - // possible collision course... - // find the point on the ray that is closest - // to the sphere's location: - Point closest = Q + w * (d0 * w); - - // find the leading edge, and it's distance from the location: - Point leading_edge = Q + w*len; - Point leading_delta = leading_edge - loc; - double leading_dist = leading_delta.length(); - - // if the leading edge is not within the sphere, - if (leading_dist > radius) { - // check to see if the closest point is between the - // ray's endpoints: - Point delta1 = closest - Q; - Point delta2 = leading_edge - Q; // this is w*len - - // if the closest point is not between the leading edge - // and the origin, this ray does not intersect: - if (delta1 * delta2 < 0 || delta1.length() > len) { - return false; - } - } - - return true; -} - -int -Ship::CheckShotIntersection(Shot* shot, Point& ipt, Point& hpt, Weapon** wep) -{ - int hit_type = HIT_NOTHING; - Point shot_loc = shot->Location(); - Point shot_org = shot->Origin(); - Point shot_vpn = shot_loc - shot_org; - double shot_len = shot_vpn.Normalize(); - double blow_len = shot_len; - bool hit_hull = false; - bool easy = false; - - if (shot_len <= 0) - return hit_type; - - if (shot_len < 1000) - shot_len = 1000; - - Point hull_impact; - Point shield_impact; - Point turret_impact; - Point closest; - double d0 = 1e9; - double d1 = 1e9; - double ds = 1e9; - - if (dir && dir->Type() == SteerAI::FIGHTER) { - ShipAI* shipAI = (ShipAI*) dir; - easy = shipAI->GetAILevel() < 2; - } - - if (shieldRep && ShieldStrength() > 5) { - if (shieldRep->CheckRayIntersection(shot_org, shot_vpn, shot_len, shield_impact)) { - hit_type = HIT_SHIELD; - closest = shield_impact; - d0 = Point(closest - shot_org).length(); - ds = d0; - - ipt = shield_impact; - } - } - - if (shieldRep && hit_type == HIT_SHIELD && !shot->IsBeam()) - blow_len = shieldRep->Radius() * 2; - - for (int i = 0; i < detail.NumModels(detail_level) && !hit_hull; i++) { - Solid* s = (Solid*) detail.GetRep(detail_level, i); - if (s) { - if (easy) { - hit_hull = CheckRaySphereIntersection(s->Location(), s->Radius(), shot_org, shot_vpn, shot_len); - } - else { - hit_hull = s->CheckRayIntersection(shot_org, shot_vpn, blow_len, hull_impact)?true:false; - } - } - } - - if (hit_hull) { - if (ShieldStrength() > 5 && !shieldRep) - hit_type = HIT_SHIELD; - - hit_type = hit_type | HIT_HULL; - hpt = hull_impact; - - d1 = Point(hull_impact - shot_org).length(); - - if (d1 < d0) { - closest = hull_impact; - d0 = d1; - } - } - - if (IsStarship() || IsStatic()) { - ListIter g_iter = Weapons(); - while (++g_iter) { - WeaponGroup* g = g_iter.value(); - - if (g->GetDesign() && g->GetDesign()->turret_model) { - double tsize = g->GetDesign()->turret_model->Radius(); - - ListIter w_iter = g->GetWeapons(); - while (++w_iter) { - Weapon* w = w_iter.value(); - - Point tloc = w->GetTurret()->Location(); - - if (CheckRaySphereIntersection(tloc, tsize, shot_org, shot_vpn, shot_len)) { - Point delta = tloc - shot_org; - d1 = delta.length(); - - if (d1 < d0) { - if (wep) *wep = w; - hit_type = hit_type | HIT_TURRET; - turret_impact = tloc; - - d0 = d1; - - closest = turret_impact; - hull_impact = turret_impact; - hpt = turret_impact; - - if (d1 < ds) - ipt = turret_impact; - } - } - } - } - } - } - - // trim beam shots to closest impact point: - if (hit_type && shot->IsBeam()) { - shot->SetBeamPoints(shot_org, closest); - } - - return hit_type; -} - -// +--------------------------------------------------------------------+ - -void -Ship::InflictNetDamage(double damage, Shot* shot) -{ - if (damage > 0 && !IsNetObserver()) { - Physical::InflictDamage(damage, 0); - - // shake by percentage of maximum damage - double newshake = 50 * damage/design->integrity; - const double MAX_SHAKE = 7; - - if (shake < MAX_SHAKE) shake += (float) newshake; - if (shake > MAX_SHAKE) shake = (float) MAX_SHAKE; - } -} - -void -Ship::InflictNetSystemDamage(System* system, double damage, BYTE dmg_type) -{ - if (system && damage > 0 && !IsNetObserver()) { - bool dmg_normal = dmg_type == WeaponDesign::DMG_NORMAL; - bool dmg_power = dmg_type == WeaponDesign::DMG_POWER; - bool dmg_emp = dmg_type == WeaponDesign::DMG_EMP; - - double sys_damage = damage; - double avail = system->Availability(); - - if (dmg_normal || system->IsPowerCritical() && dmg_emp) { - system->ApplyDamage(sys_damage); - master_caution = true; - - if (system->GetExplosionType() && (avail - system->Availability()) >= 50) { - float scale = design->explosion_scale; - if (scale <= 0) - scale = design->scale; - - sim->CreateExplosion(system->MountLocation(), Velocity() * 0.7f, system->GetExplosionType(), 0.2f * scale, scale, region, this, system); - } - } - } -} - -void -Ship::SetNetSystemStatus(System* system, int status, int power, int reactor, double avail) -{ - if (system && !IsNetObserver()) { - if (system->GetPowerLevel() != power) - system->SetPowerLevel(power); - - if (system->GetSourceIndex() != reactor) { - System* s = GetSystem(reactor); - - if (s && s->Type() == System::POWER_SOURCE) { - PowerSource* reac = (PowerSource*) s; - reac->AddClient(system); - } - } - - if (system->Status() != status) { - if (status == System::MAINT) { - ListIter comp = system->GetComponents(); - while (++comp) { - Component* c = comp.value(); - - if (c->Status() < Component::NOMINAL && c->Availability() < 75) { - if (c->SpareCount() && - c->ReplaceTime() <= 300 && - (c->Availability() < 50 || - c->ReplaceTime() < c->RepairTime())) { - - c->Replace(); - } - - else if (c->Availability() >= 50 || c->NumJerried() < 5) { - c->Repair(); - } - } - } - - RepairSystem(system); - } - } - - if (system->Availability() < avail) { - system->SetNetAvail(avail); - } - else { - system->SetNetAvail(-1); - } - } -} - -// +----------------------------------------------------------------------+ - -bool IsWeaponBlockedFriendly(Weapon* w, const SimObject* test) -{ - if (w->GetTarget()) { - Point tgt = w->GetTarget()->Location(); - Point obj = test->Location(); - Point wep = w->MountLocation(); - - Point dir = tgt - wep; - double d = dir.Normalize(); - Point rho = obj - wep; - double r = rho.Normalize(); - - // if target is much closer than obstacle, - // don't worry about friendly fire... - if (d < 1.5 * r) - return false; - - Point dst = dir * r + wep; - double err = (obj - dst).length(); - - if (err < test->Radius() * 1.5) - return true; - } - - return false; -} - -void -Ship::CheckFriendlyFire() -{ - // if no weapons, there is no worry about friendly fire... - if (weapons.size() < 1) - return; - - // only check once each second - if (Clock::GetInstance()->GameTime() - friendly_fire_time < 1000) - return; - - List w_list; - int i, j; - - // clear the FF blocked flag on all weapons - for (i = 0; i < weapons.size(); i++) { - WeaponGroup* g = weapons[i]; - - for (j = 0; j < g->NumWeapons(); j++) { - Weapon* w = g->GetWeapon(j); - w_list.append(w); - w->SetBlockedFriendly(false); - } - } - - // for each friendly ship within some kind of weapons range, - ListIter c_iter = ContactList(); - while (++c_iter) { - Contact* c = c_iter.value(); - Ship* cship = c->GetShip(); - Shot* cshot = c->GetShot(); - - if (cship && cship != this && (cship->GetIFF() == 0 || cship->GetIFF() == GetIFF())) { - double range = (cship->Location() - Location()).length(); - - if (range > 100e3) - continue; - - // check each unblocked weapon to see if it is blocked by that ship - ListIter iter = w_list; - while (++iter) { - Weapon* w = iter.value(); - - if (!w->IsBlockedFriendly()) - w->SetBlockedFriendly(IsWeaponBlockedFriendly(w, cship)); - } - } - - else if (cshot && cshot->GetIFF() == GetIFF()) { - double range = (cshot->Location() - Location()).length(); - - if (range > 30e3) - continue; - - // check each unblocked weapon to see if it is blocked by that shot - ListIter iter = w_list; - while (++iter) { - Weapon* w = iter.value(); - - if (!w->IsBlockedFriendly()) - w->SetBlockedFriendly(IsWeaponBlockedFriendly(w, cshot)); - } - } - } - - friendly_fire_time = Clock::GetInstance()->GameTime() + (DWORD) Random(0, 500); -} - -// +----------------------------------------------------------------------+ - -Ship* -Ship::GetLeader() const -{ - if (element) - return element->GetShip(1); - - return (Ship*) this; -} - -int -Ship::GetElementIndex() const -{ - if (element) - return element->FindIndex(this); - - return 0; -} - -int -Ship::GetOrigElementIndex() const -{ - return orig_elem_index; -} - -void -Ship::SetElement(Element* e) -{ - element = e; - - if (element) { - combat_unit = element->GetCombatUnit(); - - if (combat_unit) { - integrity = (float) (design->integrity - combat_unit->GetSustainedDamage()); - } - - orig_elem_index = element->FindIndex(this); - } -} - -void -Ship::SetLaunchPoint(Instruction* pt) -{ - if (pt && !launch_point) - launch_point = pt; -} - -void -Ship::AddNavPoint(Instruction* pt, Instruction* after) -{ - if (GetElementIndex() == 1) - element->AddNavPoint(pt, after); -} - -void -Ship::DelNavPoint(Instruction* pt) -{ - if (GetElementIndex() == 1) - element->DelNavPoint(pt); -} - -void -Ship::ClearFlightPlan() -{ - if (GetElementIndex() == 1) - element->ClearFlightPlan(); -} - -// +----------------------------------------------------------------------+ - -bool -Ship::IsAutoNavEngaged() -{ - if (navsys && navsys->AutoNavEngaged()) - return true; - - return false; -} - -void -Ship::SetAutoNav(bool engage) -{ - if (navsys) { - if (navsys->AutoNavEngaged()) { - if (!engage) - navsys->DisengageAutoNav(); - } - else { - if (engage) - navsys->EngageAutoNav(); - } - - if (sim) - SetControls(sim->GetControls()); - } -} - -void -Ship::CommandMode() -{ - if (!dir || dir->Type() != ShipCtrl::DIR_TYPE) { - const char* msg = "Captain on the bridge"; - RadioVox* vox = new RadioVox(0, "1", msg); - - if (vox) { - vox->AddPhrase(msg); - - if (!vox->Start()) { - RadioView::Message( RadioTraffic::TranslateVox(msg) ); - delete vox; - } - } - - SetControls(sim->GetControls()); - } - - else { - const char* msg = "Exec, you have the conn"; - RadioVox* vox = new RadioVox(0, "1", msg); - - if (vox) { - vox->AddPhrase(msg); - - if (!vox->Start()) { - RadioView::Message( RadioTraffic::TranslateVox(msg) ); - delete vox; - } - } - - SetControls(0); - } -} - -// +----------------------------------------------------------------------+ - -Instruction* -Ship::GetNextNavPoint() -{ - if (launch_point && launch_point->Status() <= Instruction::ACTIVE) - return launch_point; - - if (element) - return element->GetNextNavPoint(); - - return 0; -} - -int -Ship::GetNavIndex(const Instruction* n) -{ - if (element) - return element->GetNavIndex(n); - - return 0; -} - -double -Ship::RangeToNavPoint(const Instruction* n) -{ - double distance = 0; - - if (n && n->Region()) { - Point npt = n->Region()->Location() + n->Location(); - npt -= GetRegion()->Location(); - npt = npt.OtherHand(); // convert from map to sim coords - - distance = Point(npt - Location()).length(); - } - - return distance; -} - -void -Ship::SetNavptStatus(Instruction* navpt, int status) -{ - if (navpt && navpt->Status() != status) { - if (status == Instruction::COMPLETE) { - if (navpt->Action() == Instruction::ASSAULT) - ::Print("Completed Assault\n"); - - else if (navpt->Action() == Instruction::STRIKE) - ::Print("Completed Strike\n"); - } - - navpt->SetStatus(status); - - if (status == Instruction::COMPLETE) - sim->ProcessEventTrigger(MissionEvent::TRIGGER_NAVPT, 0, Name(), GetNavIndex(navpt)); - - if (element) { - int index = element->GetNavIndex(navpt); - - if (index >= 0) - NetUtil::SendNavData(false, element, index-1, navpt); - } - } -} - -List& -Ship::GetFlightPlan() -{ - if (element) - return element->GetFlightPlan(); - - static List dummy_flight_plan; - return dummy_flight_plan; -} - -int -Ship::FlightPlanLength() -{ - if (element) - return element->FlightPlanLength(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetWard(Ship* s) -{ - if (ward == s) - return; - - ward = s; - - if (ward) - Observe(ward); -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetTarget(SimObject* targ, System* sub, bool from_net) -{ - if (targ && targ->Type() == SimObject::SIM_SHIP) { - Ship* targ_ship = (Ship*) targ; - - if (targ_ship && targ_ship->IsNetObserver()) - return; - } - - if (target != targ) { - // DON'T IGNORE TARGET, BECAUSE IT MAY BE IN THREAT LIST - target = targ; - if (target) Observe(target); - - if (sim && target) - sim->ProcessEventTrigger(MissionEvent::TRIGGER_TARGET, 0, target->Name()); - } - - subtarget = sub; - - ListIter weapon = weapons; - while (++weapon) { - if (weapon->GetFiringOrders() != Weapon::POINT_DEFENSE) { - weapon->SetTarget(target, subtarget); - - if (sub || !IsStarship()) - weapon->SetSweep(Weapon::SWEEP_NONE); - else - weapon->SetSweep(Weapon::SWEEP_TIGHT); - } - } - - if (!from_net && NetGame::GetInstance()) - NetUtil::SendObjTarget(this); - - // track engagement: - if (target && target->Type() == SimObject::SIM_SHIP) { - Element* elem = GetElement(); - Element* tgt_elem = ((Ship*) target)->GetElement(); - - if (elem) - elem->SetAssignment(tgt_elem); - } -} - -void -Ship::DropTarget() -{ - target = 0; - subtarget = 0; - - SetTarget(target, subtarget); -} - -// +--------------------------------------------------------------------+ - -void -Ship::CycleSubTarget(int dir) -{ - if (!target || target->Type() != SimObject::SIM_SHIP) - return; - - Ship* tgt = (Ship*) target; - - if (tgt->IsDropship()) - return; - - System* subtgt = 0; - - ListIter sys = tgt->Systems(); - - if (dir > 0) { - int latch = (subtarget == 0); - while (++sys) { - if (sys->Type() == System::COMPUTER || // computers are not targetable - sys->Type() == System::SENSOR) // sensors are not targetable - continue; - - if (sys.value() == subtarget) { - latch = 1; - } - - else if (latch) { - subtgt = sys.value(); - break; - } - } - } - - else { - System* prev = 0; - - while (++sys) { - if (sys->Type() == System::COMPUTER || // computers are not targetable - sys->Type() == System::SENSOR) // sensors are not targetable - continue; - - if (sys.value() == subtarget) { - subtgt = prev; - break; - } - - prev = sys.value(); - } - - if (!subtarget) - subtgt = prev; - } - - SetTarget(tgt, subtgt); -} - -// +--------------------------------------------------------------------+ - -void -Ship::ExecFrame(double seconds) -{ - ZeroMemory(trigger, sizeof(trigger)); - altitude_agl = -1.0e6f; - - if (flight_phase < LAUNCH) { - DockFrame(seconds); - return; - } - - if (flight_phase == LAUNCH || - (flight_phase == TAKEOFF && AltitudeAGL() > Radius())) { - SetFlightPhase(ACTIVE); - } - - if (transition_time > 0) { - transition_time -= (float) seconds; - - if (transition_time <= 0) { - CompleteTransition(); - return; - } - - if (rep && IsDying() && killer) { - killer->ExecFrame(seconds); - } - } - - // observers do not run out of power: - if (IsNetObserver()) { - for (int i = 0; i < reactors.size(); i++) - reactors[i]->SetFuelRange(1e6); - } - - if (IsStatic()) { - StatFrame(seconds); - return; - } - - CheckFriendlyFire(); - ExecNavFrame(seconds); - ExecEvalFrame(seconds); - - if (IsAirborne()) { - // are we trying to make orbit? - if (Location().y >= TERRAIN_ALTITUDE_LIMIT) - MakeOrbit(); - } - - if (!InTransition()) { - ExecSensors(seconds); - ExecThrottle(seconds); - } - - else if (IsDropping() || IsAttaining() || IsSkipping()) { - throttle = 100; - } - - if (target && target->Life() == 0) { - DropTarget(); - } - - ExecPhysics(seconds); - - if (!InTransition()) { - UpdateTrack(); - } - - // are we docking? - if (IsDropship()) { - ListIter iter = GetRegion()->Carriers(); - - while (++iter) { - Ship* carrier_target = iter.value(); - - double range = (Location() - carrier_target->Location()).length(); - if (range > carrier_target->Radius() * 1.5) - continue; - - if (carrier_target->GetIFF() == GetIFF() || carrier_target->GetIFF() == 0) { - for (int i = 0; i < carrier_target->NumFlightDecks(); i++) { - if (carrier_target->GetFlightDeck(i)->Recover(this)) - break; - } - } - } - } - - ExecSystems(seconds); - ExecMaintFrame(seconds); - - if (flight_decks.size() > 0) { - Camera* global_cam = CameraDirector::GetInstance()->GetCamera(); - Point global_cam_loc = global_cam->Pos(); - bool disable_shadows = false; - - for (int i = 0; i < flight_decks.size(); i++) { - if (flight_decks[i]->ContainsPoint(global_cam_loc)) - disable_shadows = true; - } - - EnableShadows(!disable_shadows); - } - - if (!_finite(Location().x)) { - DropTarget(); - } - - if (!IsStatic() && !IsGroundUnit() && GetFlightModel() < 2) - CalcFlightPath(); -} - -// +--------------------------------------------------------------------+ - -void -Ship::LaunchProbe() -{ - if (net_observer_mode) - return; - - if (sensor_drone) { - sensor_drone = 0; - } - - if (probe) { - sensor_drone = (Drone*) probe->Fire(); - - if (sensor_drone) - Observe(sensor_drone); - - else if (sim->GetPlayerShip() == this) - Button::PlaySound(Button::SND_REJECT); - } -} - -void -Ship::SetProbe(Drone* d) -{ - if (sensor_drone != d) { - sensor_drone = d; - - if (sensor_drone) - Observe(sensor_drone); - } -} - -void -Ship::ExecSensors(double seconds) -{ - // how visible are we? - DoEMCON(); - - // what can we see? - if (sensor) - sensor->ExecFrame(seconds); - - // can we still see our target? - if (target) { - int target_found = 0; - ListIter c_iter = ContactList(); - while (++c_iter) { - Contact* c = c_iter.value(); - - if (target == c->GetShip() || target == c->GetShot()) { - target_found = 1; - - bool vis = c->Visible(this) || c->Threat(this); - - if (!vis && !c->PasLock() && !c->ActLock()) - DropTarget(); - } - } - - if (!target_found) - DropTarget(); - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::ExecNavFrame(double seconds) -{ - bool auto_pilot = false; - - // update director info string: - SetFLCSMode(flcs_mode); - - if (navsys) { - navsys->ExecFrame(seconds); - - if (navsys->AutoNavEngaged()) { - if (dir && dir->Type() == NavAI::DIR_TYPE) { - NavAI* navai = (NavAI*) dir; - - if (navai->Complete()) { - navsys->DisengageAutoNav(); - SetControls(sim->GetControls()); - } - else { - auto_pilot = true; - } - } - } - } - - // even if we are not on auto pilot, - // have we completed the next navpoint? - - Instruction* navpt = GetNextNavPoint(); - if (navpt && !auto_pilot) { - if (navpt->Region() == GetRegion()) { - double distance = 0; - - Point npt = navpt->Location(); - - if (navpt->Region()) - npt += navpt->Region()->Location(); - - Sim* sim = Sim::GetSim(); - if (sim->GetActiveRegion()) - npt -= sim->GetActiveRegion()->Location(); - - npt = npt.OtherHand(); - - // distance from self to navpt: - distance = Point(npt - Location()).length(); - - if (distance < 10 * Radius()) - SetNavptStatus(navpt, Instruction::COMPLETE); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::ExecEvalFrame(double seconds) -{ - // is it already too late? - if (life == 0 || integrity < 1) return; - - const DWORD EVAL_FREQUENCY = 1000; // once every second - static DWORD last_eval_frame = 0; // one ship per game frame - - if (element && element->NumObjectives() > 0 && - Clock::GetInstance()->GameTime() - last_eval_time > EVAL_FREQUENCY && - last_eval_frame != Game::GetInstance()->Frame()) { - - last_eval_time = Clock::GetInstance()->GameTime(); - last_eval_frame = Game::GetInstance()->Frame(); - - for (int i = 0; i < element->NumObjectives(); i++) { - Instruction* obj = element->GetObjective(i); - - if (obj->Status() <= Instruction::ACTIVE) { - obj->Evaluate(this); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::ExecPhysics(double seconds) -{ - if (net_control) { - net_control->ExecFrame(seconds); - Thrust(seconds); // drive flare - } - else { - thrust = (float) Thrust(seconds); - SetupAgility(); - - if (seconds > 0) { - g_force = 0.0f; - } - - if (IsAirborne()) { - Point v1 = velocity; - AeroFrame(seconds); - Point v2 = velocity; - Point dv = v2 - v1 + Point(0, g_accel*seconds, 0); - - if (seconds > 0) { - g_force = (float) (dv * cam.vup() / seconds) / 9.8f; - } - } - - else if (IsDying() || flight_model < 2) { // standard and relaxed modes - Physical::ExecFrame(seconds); - } - - else { // arcade mode - Physical::ArcadeFrame(seconds); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::ExecThrottle(double seconds) -{ - double spool = 75 * seconds; - - if (throttle < throttle_request) - if (throttle_request-throttle < spool) - throttle = throttle_request; - else - throttle += spool; - - else if (throttle > throttle_request) - if (throttle - throttle_request < spool) - throttle = throttle_request; - else - throttle -= spool; -} - -// +--------------------------------------------------------------------+ - -void -Ship::ExecSystems(double seconds) -{ - if (!rep) - return; - - int i; - - ListIter iter = systems; - while (++iter) { - System* sys = iter.value(); - - sys->Orient(this); - - // sensors have already been executed, - // they can not be run twice in a frame! - if (sys->Type() != System::SENSOR) - sys->ExecFrame(seconds); - } - - // hangars and weapon groups are not systems - // they must be executed separately from above - if (hangar) - hangar->ExecFrame(seconds); - - wep_mass = 0.0f; - wep_resist = 0.0f; - - bool winchester_cycle = false; - - for (i = 0; i < weapons.size(); i++) { - WeaponGroup* w_group = weapons[i]; - w_group->ExecFrame(seconds); - - if (w_group->GetTrigger() && w_group->GetFiringOrders() == Weapon::MANUAL) { - - Weapon* gun = w_group->GetSelected(); - - SimObject* gun_tgt = gun->GetTarget(); - - // if no target has been designated for this - // weapon, let it guide on the contact closest - // to its boresight. this must be done before - // firing the weapon. - - if (sensor && gun->Guided() && !gun->Design()->beam && !gun_tgt) { - gun->SetTarget(sensor->AcquirePassiveTargetForMissile(), 0); - } - - gun->Fire(); - - w_group->SetTrigger(false); - w_group->CycleWeapon(); - w_group->CheckAmmo(); - - // was that the last shot from this missile group? - if (w_group->IsMissile() && w_group->Ammo() < 1) { - - // is this the current secondary weapon group? - if (weapons[secondary] == w_group) { - winchester_cycle = true; - } - } - } - - wep_mass += w_group->Mass(); - wep_resist += w_group->Resistance(); - } - - // if we just fired the last shot in the current secondary - // weapon group, auto cycle to another secondary weapon: - if (winchester_cycle) { - int old_secondary = secondary; - - CycleSecondary(); - - // do not winchester-cycle to an A2G missile type, - // or a missile that is also out of ammo, - // keep going! - - while (secondary != old_secondary) { - Weapon* missile = GetSecondary(); - if (missile && missile->CanTarget(Ship::GROUND_UNITS)) - CycleSecondary(); - - else if (weapons[secondary]->Ammo() < 1) - CycleSecondary(); - - else - break; - } - } - - mass = (float) design->mass + wep_mass; - - if (IsDropship()) - agility = (float) design->agility - wep_resist; - - if (shieldRep) { - Solid* solid = (Solid*) rep; - shieldRep->MoveTo(solid->Location()); - shieldRep->SetOrientation(solid->Orientation()); - - bool bubble = false; - if (shield) - bubble = shield->ShieldBubble(); - - if (shieldRep->ActiveHits()) { - shieldRep->Energize(seconds, bubble); - shieldRep->Show(); - } - else { - shieldRep->Hide(); - } - } - - if (cockpit) { - Solid* solid = (Solid*) rep; - - Point cpos = cam.Pos() + - cam.vrt() * bridge_vec.x + - cam.vpn() * bridge_vec.y + - cam.vup() * bridge_vec.z; - - cockpit->MoveTo(cpos); - cockpit->SetOrientation(solid->Orientation()); - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::AeroFrame(double seconds) -{ - float g_save = g_accel; - - if (Class() == LCA) { - lat_thrust = true; - SetGravity(0.0f); - } - - if (AltitudeAGL() < Radius()) { - SetGravity(0.0f); - - // on the ground/runway? - double bottom = 1e9; - double tlevel = Location().y - AltitudeAGL(); - - // taking off or landing? - if (flight_phase < ACTIVE || flight_phase > APPROACH) { - if (dock) - tlevel = dock->MountLocation().y; - } - - if (tlevel < 0) - tlevel = 0; - - if (gear) - bottom = gear->GetTouchDown()-1; - else - bottom = Location().y-6; - - if (bottom < tlevel) - TranslateBy(Point(0, bottom-tlevel, 0)); - } - - // MODEL 2: ARCADE - if (flight_model >= 2) { - Physical::ArcadeFrame(seconds); - } - - // MODEL 1: RELAXED - else if (flight_model == 1) { - Physical::ExecFrame(seconds); - } - - // MODEL 0: STANDARD - else { - // apply drag-torque (i.e. turn ship into - // velocity vector to minimize drag): - - Point vnrm = velocity; - double v = vnrm.Normalize(); - double pitch_deflection = vnrm * cam.vup(); - double yaw_deflection = vnrm * cam.vrt(); - - if (lat_thrust && v < 250) { - } - - else { - if (v < 250) { - double factor = 1.2 + (250 - v) / 100; - - ApplyPitch(pitch_deflection * -factor); - ApplyYaw(yaw_deflection * factor); - - dp += (float) (dp_acc * seconds); - dy += (float) (dy_acc * seconds); - } - - else { - if (fabs(pitch_deflection) > stall) { - ApplyPitch(pitch_deflection * -1.2); - dp += (float) (dp_acc * seconds); - } - - ApplyYaw(yaw_deflection * 2); - dy += (float) (dy_acc * seconds); - } - } - - // compute rest of physics: - Physical::AeroFrame(seconds); - } - - SetGravity(g_save); -} - -// +--------------------------------------------------------------------+ - -void -Ship::LinearFrame(double seconds) -{ - Physical::LinearFrame(seconds); - - if (!IsAirborne() || Class() != LCA) - return; - - // damp lateral movement in atmosphere: - - // side-to-side - if (!trans_x) { - Point transvec = cam.vrt(); - transvec *= (transvec * velocity) * seconds * 0.5; - velocity -= transvec; - } - - // fore-and-aft - if (!trans_y && fabs(thrust) < 1.0f) { - Point transvec = cam.vpn(); - transvec *= (transvec * velocity) * seconds * 0.25; - velocity -= transvec; - } - - // up-and-down - if (!trans_z) { - Point transvec = cam.vup(); - transvec *= (transvec * velocity) * seconds * 0.5; - velocity -= transvec; - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::DockFrame(double seconds) -{ - SelectDetail(seconds); - - if (sim->GetPlayerShip() == this) { - // Make sure the thruster sound is diabled - // when the player is on the runway or catapult - if (thruster) { - thruster->ExecTrans(0,0,0); - } - } - - if (rep) { - // Update the graphic rep and light sources: - // (This is usually done by the physics class, - // but when the ship is in dock, we skip the - // standard physics processing): - rep->MoveTo(cam.Pos()); - rep->SetOrientation(cam.Orientation()); - - if (light) - light->MoveTo(cam.Pos()); - - ListIter iter = systems; - while (++iter) - iter->Orient(this); - - double spool = 75 * seconds; - - if (flight_phase == DOCKING) { - throttle_request = 0; - throttle = 0; - } - - else if (throttle < throttle_request) - if (throttle_request-throttle < spool) - throttle = throttle_request; - else - throttle += spool; - - else if (throttle > throttle_request) - if (throttle - throttle_request < spool) - throttle = throttle_request; - else - throttle -= spool; - - // make sure there is power to run the drive: - for (int i = 0; i < reactors.size(); i++) - reactors[i]->ExecFrame(seconds); - - // count up weapon ammo for status mfd: - for (int i = 0; i < weapons.size(); i++) - weapons[i]->ExecFrame(seconds); - - // show drive flare while on catapult: - if (main_drive) { - main_drive->SetThrottle(throttle); - - if (throttle > 0) - main_drive->Thrust(seconds); // show drive flare - } - } - - if (cockpit && !cockpit->Hidden()) { - Solid* solid = (Solid*) rep; - - Point cpos = cam.Pos() + - cam.vrt() * bridge_vec.x + - cam.vpn() * bridge_vec.y + - cam.vup() * bridge_vec.z; - - cockpit->MoveTo(cpos); - cockpit->SetOrientation(solid->Orientation()); - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::StatFrame(double seconds) -{ - if (flight_phase != ACTIVE) { - flight_phase = ACTIVE; - launch_time = Clock::GetInstance()->GameTime() + 1; - - if (element) - element->SetLaunchTime(launch_time); - } - - if (IsGroundUnit()) { - // glue buildings to the terrain: - Point loc = Location(); - Terrain* terrain = region->GetTerrain(); - - if (terrain) { - loc.y = terrain->Height(loc.x, loc.z); - MoveTo(loc); - } - } - - if (rep) { - rep->MoveTo(cam.Pos()); - rep->SetOrientation(cam.Orientation()); - } - - if (light) { - light->MoveTo(cam.Pos()); - } - - ExecSensors(seconds); - - if (target && target->Life() == 0) { - DropTarget(); - } - - if (dir) dir->ExecFrame(seconds); - - SelectDetail(seconds); - - int i = 0; - - if (rep) { - ListIter iter = systems; - while (++iter) - iter->Orient(this); - - for (i = 0; i < reactors.size(); i++) - reactors[i]->ExecFrame(seconds); - - for (i = 0; i < navlights.size(); i++) - navlights[i]->ExecFrame(seconds); - - for (i = 0; i < weapons.size(); i++) - weapons[i]->ExecFrame(seconds); - - if (farcaster) { - farcaster->ExecFrame(seconds); - - if (navlights.size() == 2) { - if (farcaster->Charge() > 99) { - navlights[0]->Enable(); - navlights[1]->Disable(); - } - else { - navlights[0]->Disable(); - navlights[1]->Enable(); - } - } - } - - if (shield) - shield->ExecFrame(seconds); - - if (hangar) - hangar->ExecFrame(seconds); - - if (flight_decks.size() > 0) { - Camera* global_cam = CameraDirector::GetInstance()->GetCamera(); - Point global_cam_loc = global_cam->Pos(); - bool disable_shadows = false; - - for (i = 0; i < flight_decks.size(); i++) { - flight_decks[i]->ExecFrame(seconds); - - if (flight_decks[i]->ContainsPoint(global_cam_loc)) - disable_shadows = true; - } - - EnableShadows(!disable_shadows); - } - } - - if (shieldRep) { - Solid* solid = (Solid*) rep; - shieldRep->MoveTo(solid->Location()); - shieldRep->SetOrientation(solid->Orientation()); - - bool bubble = false; - if (shield) - bubble = shield->ShieldBubble(); - - if (shieldRep->ActiveHits()) { - shieldRep->Energize(seconds, bubble); - shieldRep->Show(); - } - else { - shieldRep->Hide(); - } - } - - if (!_finite(Location().x)) { - DropTarget(); - } -} - -// +--------------------------------------------------------------------+ - -Graphic* -Ship::Cockpit() const -{ - return cockpit; -} - -void -Ship::ShowCockpit() -{ - if (cockpit) { - cockpit->Show(); - - ListIter g = weapons; - while (++g) { - ListIter w = g->GetWeapons(); - while (++w) { - Solid* turret = w->GetTurret(); - if (turret) { - turret->Show(); - - Solid* turret_base = w->GetTurretBase(); - if (turret_base) - turret_base->Show(); - } - - if (w->IsMissile()) { - for (int i = 0; i < w->Ammo(); i++) { - Solid* store = w->GetVisibleStore(i); - if (store) { - store->Show(); - } - } - } - } - } - } -} - -void -Ship::HideCockpit() -{ - if (cockpit) - cockpit->Hide(); -} - -// +--------------------------------------------------------------------+ - -void -Ship::SelectDetail(double seconds) -{ - detail.ExecFrame(seconds); - detail.SetLocation(GetRegion(), Location()); - - int new_level = detail.GetDetailLevel(); - - if (detail_level != new_level) { - Scene* scene = 0; - - // remove current rep from scene (if necessary): - for (int i = 0; i < detail.NumModels(detail_level); i++) { - Graphic* g = detail.GetRep(detail_level, i); - if (g) { - scene = g->GetScene(); - if (scene) - scene->DelGraphic(g); - } - } - - // switch to new rep: - detail_level = new_level; - rep = detail.GetRep(detail_level); - - // add new rep to scene (if necessary): - if (scene) { - for (int i = 0; i < detail.NumModels(detail_level); i++) { - Graphic* g = detail.GetRep(detail_level, i); - Point s = detail.GetSpin(detail_level, i); - Matrix m = cam.Orientation(); - - m.Pitch(s.x); - m.Yaw(s.z); - m.Roll(s.y); - - scene->AddGraphic(g); - g->MoveTo(cam.Pos() + detail.GetOffset(detail_level, i)); - g->SetOrientation(m); - } - - // show/hide external stores and landing gear... - if (detail.NumLevels() > 0) { - if (gear && (gear->GetState() != LandingGear::GEAR_UP)) { - for (int i = 0; i < gear->NumGear(); i++) { - Solid* g = gear->GetGear(i); - - if (g) { - if (detail_level == 0) - scene->DelGraphic(g); - else - scene->AddGraphic(g); - } - } - } - - ListIter g = weapons; - while (++g) { - ListIter w = g->GetWeapons(); - while (++w) { - Solid* turret = w->GetTurret(); - if (turret) { - if (detail_level == 0) - scene->DelGraphic(turret); - else - scene->AddGraphic(turret); - - Solid* turret_base = w->GetTurretBase(); - if (turret_base) { - if (detail_level == 0) - scene->DelGraphic(turret_base); - else - scene->AddGraphic(turret_base); - } - } - if (w->IsMissile()) { - for (int i = 0; i < w->Ammo(); i++) { - Solid* store = w->GetVisibleStore(i); - if (store) { - if (detail_level == 0) - scene->DelGraphic(store); - else - scene->AddGraphic(store); - } - } - } - } - } - } - } - } - - else { - int nmodels = detail.NumModels(detail_level); - - if (nmodels > 1) { - for (int i = 0; i < nmodels; i++) { - Graphic* g = detail.GetRep(detail_level, i); - Point s = detail.GetSpin(detail_level, i); - Matrix m = cam.Orientation(); - - m.Pitch(s.x); - m.Yaw(s.z); - m.Roll(s.y); - - g->MoveTo(cam.Pos() + detail.GetOffset(detail_level, i)); - g->SetOrientation(m); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::ShowRep() -{ - for (int i = 0; i < detail.NumModels(detail_level); i++) { - Graphic* g = detail.GetRep(detail_level, i); - g->Show(); - } - - if (gear && (gear->GetState() != LandingGear::GEAR_UP)) { - for (int i = 0; i < gear->NumGear(); i++) { - Solid* g = gear->GetGear(i); - if (g) g->Show(); - } - } - - ListIter g = weapons; - while (++g) { - ListIter w = g->GetWeapons(); - while (++w) { - Solid* turret = w->GetTurret(); - if (turret) { - turret->Show(); - - Solid* turret_base = w->GetTurretBase(); - if (turret_base) - turret_base->Show(); - } - - if (w->IsMissile()) { - for (int i = 0; i < w->Ammo(); i++) { - Solid* store = w->GetVisibleStore(i); - if (store) { - store->Show(); - } - } - } - } - } -} - -void -Ship::HideRep() -{ - for (int i = 0; i < detail.NumModels(detail_level); i++) { - Graphic* g = detail.GetRep(detail_level, i); - g->Hide(); - } - - if (gear && (gear->GetState() != LandingGear::GEAR_UP)) { - for (int i = 0; i < gear->NumGear(); i++) { - Solid* g = gear->GetGear(i); - if (g) g->Hide(); - } - } - - ListIter g = weapons; - while (++g) { - ListIter w = g->GetWeapons(); - while (++w) { - Solid* turret = w->GetTurret(); - if (turret) { - turret->Hide(); - - Solid* turret_base = w->GetTurretBase(); - if (turret_base) - turret_base->Hide(); - } - - if (w->IsMissile()) { - for (int i = 0; i < w->Ammo(); i++) { - Solid* store = w->GetVisibleStore(i); - if (store) { - store->Hide(); - } - } - } - } - } -} - -void -Ship::EnableShadows(bool enable) -{ - for (int i = 0; i < detail.NumModels(detail_level); i++) { - Graphic* g = detail.GetRep(detail_level, i); - - if (g->IsSolid()) { - Solid* s = (Solid*) g; - - ListIter iter = s->GetShadows(); - while (++iter) { - Shadow* shadow = iter.value(); - shadow->SetEnabled(enable); - } - } - } -} - -// +--------------------------------------------------------------------+ - -bool -Ship::Update(SimObject* obj) -{ - if (obj == ward) - ward = 0; - - if (obj == target) { - target = 0; - subtarget = 0; - } - - if (obj == carrier) { - carrier = 0; - dock = 0; - inbound = 0; - } - - if (obj->Type() == SimObject::SIM_SHOT || - obj->Type() == SimObject::SIM_DRONE) { - Shot* s = (Shot*) obj; - - if (sensor_drone == s) - sensor_drone = 0; - - if (decoy_list.contains(s)) - decoy_list.remove(s); - - if (threat_list.contains(s)) - threat_list.remove(s); - } - - return SimObserver::Update(obj); -} - -// +--------------------------------------------------------------------+ - -int -Ship::GetFuelLevel() const -{ - if (reactors.size() > 0) { - PowerSource* reactor = reactors[0]; - if (reactor) - return reactor->Charge(); - } - - return 0; -} - -void -Ship::SetThrottle(double percent) -{ - throttle_request = percent; - - if (throttle_request < 0) throttle_request = 0; - else if (throttle_request > 100) throttle_request = 100; - - if (throttle_request < 50) - augmenter = false; -} - -void -Ship::SetAugmenter(bool enable) -{ - if (throttle <= 50) - enable = false; - - if (main_drive && main_drive->MaxAugmenter() <= 0) - enable = false; - - augmenter = enable; -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetTransition(double trans_time, int trans_type, const Point& trans_loc) -{ - transition_time = (float) trans_time; - transition_type = trans_type; - transition_loc = trans_loc; -} - -void -Ship::DropOrbit() -{ - if (IsDropship() && transition_type == TRANSITION_NONE && !IsAirborne()) { - SimRegion* dst_rgn = sim->FindNearestTerrainRegion(this); - - if (dst_rgn && - dst_rgn->GetOrbitalRegion()->Primary() == - GetRegion()->GetOrbitalRegion()->Primary()) { - - transition_time = 10.0f; - transition_type = TRANSITION_DROP_ORBIT; - transition_loc = Location() + Heading() * (-2*Radius()); - - RadioTraffic::SendQuickMessage(this, RadioMessage::BREAK_ORBIT); - SetControls(0); - } - } -} - -void -Ship::MakeOrbit() -{ - if (IsDropship() && transition_type == TRANSITION_NONE && IsAirborne()) { - transition_time = 5.0f; - transition_type = TRANSITION_MAKE_ORBIT; - transition_loc = Location() + Heading() * (-2*Radius()); - - RadioTraffic::SendQuickMessage(this, RadioMessage::MAKE_ORBIT); - SetControls(0); - } -} - -// +--------------------------------------------------------------------+ - -bool -Ship::IsInCombat() -{ - if (IsRogue()) - return true; - - bool combat = false; - - ListIter c_iter = ContactList(); - while (++c_iter) { - Contact* c = c_iter.value(); - Ship* cship = c->GetShip(); - int ciff = c->GetIFF(this); - Point delta = c->Location() - Location(); - double dist = delta.length(); - - if (c->Threat(this) && !cship) { - if (IsStarship()) - combat = dist < 120e3; - else - combat = dist < 60e3; - } - - else if (cship && ciff > 0 && ciff != GetIFF()) { - if (IsStarship() && cship->IsStarship()) - combat = dist < 120e3; - else - combat = dist < 60e3; - } - } - - return combat; -} - -// +--------------------------------------------------------------------+ - -bool -Ship::CanTimeSkip() -{ - bool go = false; - Instruction* navpt = GetNextNavPoint(); - - if (MissionClock() < 10000 || NetGame::IsNetGame()) - return go; - - if (navpt) { - go = true; - - if (navpt->Region() != GetRegion()) - go = false; - - else if (Point(navpt->Location().OtherHand() - Location()).length() < 30e3) - go = false; - } - - if (go) - go = !IsInCombat(); - - return go; -} - -void -Ship::TimeSkip() -{ - if (CanTimeSkip()) { - // go back to regular time before performing the skip: - Clock::GetInstance()->SetTimeCompression(1.0); - - transition_time = 7.5f; - transition_type = TRANSITION_TIME_SKIP; - transition_loc = Location() + Heading() * (Velocity().length() * 4); - // 2500; //(8*Radius()); - - if (rand() < 16000) - transition_loc += BeamLine() * (2.5*Radius()); - else - transition_loc += BeamLine() * (-2 *Radius()); - - if (rand() < 8000) - transition_loc += LiftLine() * (-1*Radius()); - else - transition_loc += LiftLine() * (1.8*Radius()); - - SetControls(0); - } - - else if (sim->GetPlayerShip() == this) { - SetAutoNav(true); - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::DropCam(double time, double range) -{ - transition_type = TRANSITION_DROP_CAM; - - if (time > 0) - transition_time = (float) time; - else - transition_time = 10.0f; - - Point offset = Heading() * (Velocity().length() * 5); - double lateral_offset = 2 * Radius(); - double vertical_offset = Radius(); - - if (vertical_offset > 300) - vertical_offset = 300; - - if (rand() < 16000) - lateral_offset *= -1; - - if (rand() < 8000) - vertical_offset *= -1; - - offset += BeamLine() * lateral_offset; - offset += LiftLine() * vertical_offset; - - if (range > 0) - offset *= range; - - transition_loc = Location() + offset; -} - -// +--------------------------------------------------------------------+ - -void -Ship::DeathSpiral() -{ - if (!killer) - killer = new ShipKiller(this); - - ListIter iter = systems; - while (++iter) - iter->PowerOff(); - - // transfer arcade velocity to newtonian velocity: - if (flight_model >= 2) { - velocity += arcade_velocity; - } - - if (GetIFF() < 100 && !IsGroundUnit()) { - RadioTraffic::SendQuickMessage(this, RadioMessage::DISTRESS); - } - - transition_type = TRANSITION_DEATH_SPIRAL; - - killer->BeginDeathSpiral(); - - transition_time = killer->TransitionTime(); - transition_loc = killer->TransitionLoc(); -} - -// +--------------------------------------------------------------------+ - -void -Ship::CompleteTransition() -{ - int old_type = transition_type; - transition_time = 0.0f; - transition_type = TRANSITION_NONE; - - switch (old_type) { - case TRANSITION_NONE: - case TRANSITION_DROP_CAM: - default: - return; - - case TRANSITION_DROP_ORBIT: { - SetControls(0); - SimRegion* dst_rgn = sim->FindNearestTerrainRegion(this); - Point dst_loc = Location().OtherHand() * 0.20; - dst_loc.x += 6000 * GetElementIndex(); - dst_loc.z = TERRAIN_ALTITUDE_LIMIT * 0.95; - dst_loc += RandomDirection() * 2e3; - - sim->RequestHyperJump(this, dst_rgn, dst_loc, TRANSITION_DROP_ORBIT); - - ShipStats* stats = ShipStats::Find(Name()); - stats->AddEvent(SimEvent::BREAK_ORBIT, dst_rgn->Name()); - } - break; - - case TRANSITION_MAKE_ORBIT: { - SetControls(0); - SimRegion* dst_rgn = sim->FindNearestSpaceRegion(this); - double dist = 200.0e3 + 10.0e3 * GetElementIndex(); - Point esc_vec = dst_rgn->GetOrbitalRegion()->Location() - - dst_rgn->GetOrbitalRegion()->Primary()->Location(); - - esc_vec.z = -100 * GetElementIndex(); - esc_vec.Normalize(); - esc_vec *= -dist; - esc_vec += RandomDirection() * 2e3; - - sim->RequestHyperJump(this, dst_rgn, esc_vec, TRANSITION_MAKE_ORBIT); - - ShipStats* stats = ShipStats::Find(Name()); - stats->AddEvent(SimEvent::MAKE_ORBIT, dst_rgn->Name()); - } - break; - - case TRANSITION_TIME_SKIP: { - Instruction* navpt = GetNextNavPoint(); - - if (navpt) { - Point delta = navpt->Location().OtherHand() - Location(); - Point unit = delta; unit.Normalize(); - Point trans = delta + unit * -20e3; - double dist = trans.length(); - double speed = navpt->Speed(); - - if (speed < 50) speed = 500; - - double etr = dist / speed; - - sim->ResolveTimeSkip(etr); - } - } - break; - - case TRANSITION_DEATH_SPIRAL: - SetControls(0); - transition_type = TRANSITION_DEAD; - break; - } - -} - -bool -Ship::IsAirborne() const -{ - if (region) - return region->Type() == SimRegion::AIR_SPACE; - - return false; -} - -double -Ship::CompassHeading() const -{ - Point heading = Heading(); - double compass_heading = atan2(fabs(heading.x), heading.z); - - if (heading.x < 0) - compass_heading *= -1; - - double result = compass_heading + PI; - - if (result >= 2*PI) - result -= 2*PI; - - return result; -} - -double -Ship::CompassPitch() const -{ - Point heading = Heading(); - return asin(heading.y); -} - -double -Ship::AltitudeMSL() const -{ - return Location().y; -} - -double -Ship::AltitudeAGL() const -{ - if (altitude_agl < -1000) { - Ship* pThis = (Ship*) this; // cast-away const - Point loc = Location(); - - Terrain* terrain = region->GetTerrain(); - - if (terrain) - pThis->altitude_agl = (float) (loc.y - terrain->Height(loc.x, loc.z)); - - else - pThis->altitude_agl = (float) loc.y; - - if (!_finite(altitude_agl)) { - pThis->altitude_agl = 0.0f; - } - } - - return altitude_agl; -} - -double -Ship::GForce() const -{ - return g_force; -} - -// +--------------------------------------------------------------------+ - -WeaponGroup* -Ship::FindWeaponGroup(const char* name) -{ - WeaponGroup* group = 0; - - ListIter iter = weapons; - while (!group && ++iter) - if (!_stricmp(iter->Name(), name)) - group = iter.value(); - - if (!group) { - group = new WeaponGroup(name); - weapons.append(group); - } - - return group; -} - -void -Ship::SelectWeapon(int n, int w) -{ - if (n < weapons.size()) - weapons[n]->SelectWeapon(w); -} - -// +--------------------------------------------------------------------+ - -void -Ship::CyclePrimary() -{ - if (weapons.isEmpty()) - return; - - if (IsDropship() && primary < weapons.size()) { - WeaponGroup* p = weapons[primary]; - Weapon* w = p->GetSelected(); - - if (w && w->GetTurret()) { - p->SetFiringOrders(Weapon::POINT_DEFENSE); - } - } - - int n = primary + 1; - while (n != primary) { - if (n >= weapons.size()) - n = 0; - - if (weapons[n]->IsPrimary()) { - weapons[n]->SetFiringOrders(Weapon::MANUAL); - break; - } - - n++; - } - - primary = n; -} - -// +--------------------------------------------------------------------+ - -void -Ship::CycleSecondary() -{ - if (weapons.isEmpty()) - return; - - int n = secondary + 1; - while (n != secondary) { - if (n >= weapons.size()) - n = 0; - - if (weapons[n]->IsMissile()) - break; - - n++; - } - - secondary = n; - - // automatically switch sensors to appropriate mode: - if (IsAirborne()) { - Weapon* missile = GetSecondary(); - if (missile && missile->CanTarget(Ship::GROUND_UNITS)) - SetSensorMode(Sensor::GM); - else if (sensor && sensor->GetMode() == Sensor::GM) - SetSensorMode(Sensor::STD); - } -} - -int -Ship::GetMissileEta(int index) const -{ - if (index >= 0 && index < 4) - return missile_eta[index]; - - return 0; -} - -void -Ship::SetMissileEta(int id, int eta) -{ - int index = -1; - - // are we tracking this missile's eta? - for (int i = 0; i < 4; i++) - if (id == missile_id[i]) - index = i; - - // if not, can we find an open slot to track it in? - if (index < 0) { - for (int i = 0; i < 4 && index < 0; i++) { - if (missile_eta[i] == 0) { - index = i; - missile_id[i] = id; - } - } - } - - // track the eta: - if (index >= 0 && index < 4) { - if (eta > 3599) - eta = 3599; - - missile_eta[index] = (BYTE) eta; - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::DoEMCON() -{ - ListIter iter = systems; - while (++iter) { - System* s = iter.value(); - s->DoEMCON(emcon); - } - - old_emcon = emcon; -} - -// +--------------------------------------------------------------------+ - -double -Ship::Thrust(double seconds) const -{ - double total_thrust = 0; - - if (main_drive) { - // velocity limiter: - Point H = Heading(); - Point V = Velocity(); - double vmag = V.Normalize(); - double eff_throttle = throttle; - double thrust_factor = 1; - double vfwd = H * V; - bool aug_on = main_drive->IsAugmenterOn(); - - if (vmag > vlimit && vfwd > 0) { - double vmax = vlimit; - if (aug_on) - vmax *= 1.5; - - vfwd = 0.5 * vfwd + 0.5; - - // reduce drive efficiency at high fwd speed: - thrust_factor = (vfwd * pow(vmax,3) / pow(vmag,3)) + (1-vfwd); - } - - if (flcs) - eff_throttle = flcs->Throttle(); - - // square-law throttle curve to increase sensitivity - // at lower throttle settings: - if (flight_model > 1) { - eff_throttle /= 100; - eff_throttle *= eff_throttle; - eff_throttle *= 100; - } - - main_drive->SetThrottle(eff_throttle, augmenter); - total_thrust += thrust_factor * main_drive->Thrust(seconds); - - if (aug_on && shake < 1.5) - ((Ship*) this)->shake = 1.5f; - } - - return total_thrust; -} - -// +--------------------------------------------------------------------+ - -void -Ship::CycleFLCSMode() -{ - switch (flcs_mode) { - case FLCS_MANUAL: SetFLCSMode(FLCS_HELM); break; - case FLCS_AUTO: SetFLCSMode(FLCS_MANUAL); break; - case FLCS_HELM: SetFLCSMode(FLCS_AUTO); break; - - default: - if (IsStarship()) - flcs_mode = (BYTE) FLCS_HELM; - else - flcs_mode = (BYTE) FLCS_AUTO; - break; - } - - // reset helm heading to compass heading when switching - // back to helm mode from manual mode: - - if (flcs_mode == FLCS_HELM) { - if (IsStarship()) { - SetHelmHeading(CompassHeading()); - SetHelmPitch(CompassPitch()); - } - else { - flcs_mode = (BYTE) FLCS_AUTO; - } - } -} - -void -Ship::SetFLCSMode(int mode) -{ - flcs_mode = (BYTE) mode; - - if (IsAirborne()) - flcs_mode = (BYTE) FLCS_MANUAL; - - if (dir && dir->Type() < SteerAI::SEEKER) { - switch (flcs_mode) { - case FLCS_MANUAL: director_info = ContentBundle::GetInstance()->GetText("flcs.manual"); break; - case FLCS_AUTO: director_info = ContentBundle::GetInstance()->GetText("flcs.auto"); break; - case FLCS_HELM: director_info = ContentBundle::GetInstance()->GetText("flcs.helm"); break; - default: director_info = ContentBundle::GetInstance()->GetText("flcs.fault"); break; - } - - if (!flcs || !flcs->IsPowerOn()) - director_info = ContentBundle::GetInstance()->GetText("flcs.offline"); - - else if (IsAirborne()) - director_info = ContentBundle::GetInstance()->GetText("flcs.atmospheric"); - } - - if (flcs) - flcs->SetMode(mode); -} - -int -Ship::GetFLCSMode() const -{ - return (int) flcs_mode; -} - -void -Ship::SetTransX(double t) -{ - float limit = design->trans_x; - - if (thruster) - limit = (float) thruster->TransXLimit(); - - trans_x = (float) t; - - if (trans_x) { - if (trans_x > limit) - trans_x = limit; - else if (trans_x < -limit) - trans_x = -limit; - - // reduce thruster efficiency at high fwd speed: - double vfwd = cam.vrt() * Velocity(); - double vmag = fabs(vfwd); - if (vmag > vlimit) { - if (trans_x > 0 && vfwd > 0 || trans_x < 0 && vfwd < 0) - trans_x *= (float) (pow(vlimit,4) / pow(vmag,4)); - } - } -} - -void -Ship::SetTransY(double t) -{ - float limit = design->trans_y; - - if (thruster) - limit = (float) thruster->TransYLimit(); - - trans_y = (float) t; - - if (trans_y) { - double vmag = Velocity().length(); - - if (trans_y > limit) - trans_y = limit; - else if (trans_y < -limit) - trans_y = -limit; - - // reduce thruster efficiency at high fwd speed: - if (vmag > vlimit) { - double vfwd = cam.vpn() * Velocity(); - - if (trans_y > 0 && vfwd > 0 || trans_y < 0 && vfwd < 0) - trans_y *= (float) (pow(vlimit,4) / pow(vmag,4)); - } - } -} - -void -Ship::SetTransZ(double t) -{ - float limit = design->trans_z; - - if (thruster) - limit = (float) thruster->TransZLimit(); - - trans_z = (float) t; - - if (trans_z) { - - if (trans_z > limit) - trans_z = limit; - else if (trans_z < -limit) - trans_z = -limit; - - // reduce thruster efficiency at high fwd speed: - double vfwd = cam.vup() * Velocity(); - double vmag = fabs(vfwd); - if (vmag > vlimit) { - if (trans_z > 0 && vfwd > 0 || trans_z < 0 && vfwd < 0) - trans_z *= (float) (pow(vlimit,4) / pow(vmag,4)); - } - } -} - -void -Ship::ExecFLCSFrame() -{ - if (flcs) - flcs->ExecSubFrame(); -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetHelmHeading(double h) -{ - while (h < 0) - h += 2*PI; - - while (h >= 2*PI) - h -= 2*PI; - - helm_heading = (float) h; -} - -void -Ship::SetHelmPitch(double p) -{ - const double PITCH_LIMIT = 80 * DEGREES; - - if (p < -PITCH_LIMIT) - p = -PITCH_LIMIT; - - else if (p > PITCH_LIMIT) - p = PITCH_LIMIT; - - helm_pitch = (float) p; -} - -void -Ship::ApplyHelmYaw(double y) -{ - // rotate compass into helm-relative orientation: - double compass = CompassHeading() - helm_heading; - double turn = y * PI/4; - - if (compass > PI) - compass -= 2*PI; - else if (compass < -PI) - compass += 2*PI; - - // if requested turn is more than 170, reject it: - if (fabs(compass + turn) > 170*DEGREES) - return; - - SetHelmHeading(helm_heading + turn); -} - -void -Ship::ApplyHelmPitch(double p) -{ - SetHelmPitch(helm_pitch - p * PI/4); -} - -void -Ship::ApplyPitch(double p) -{ - if (flight_model == 0) { // standard flight model - if (IsAirborne()) - p *= 0.5; - - // command for pitch up is negative - if (p < 0) { - if (alpha > PI/6) { - p *= 0.05; - } - else if (g_force > 12.0) { - double limit = 0.5 - (g_force - 12.0)/10.0; - - if (limit < 0) - p = 0; - else - p *= limit; - } - } - - // command for pitch down is positive - else if (p > 0) { - if (alpha < -PI/8) { - p *= 0.05; - } - else if (g_force < -3) { - p *= 0.1; - } - } - } - - Physical::ApplyPitch(p); -} - -// +--------------------------------------------------------------------+ - -bool -Ship::FireWeapon(int n) -{ - bool fired = false; - - if (n >= 0 && !CheckFire()) { - if (n < 4) - trigger[n] = true; - - if (n < weapons.size()) { - weapons[n]->SetTrigger(true); - fired = weapons[n]->GetTrigger(); - } - } - - if (!fired && sim->GetPlayerShip() == this) - Button::PlaySound(Button::SND_REJECT); - - return fired; -} - -bool -Ship::FireDecoy() -{ - Shot* drone = 0; - - if (decoy && !CheckFire()) { - drone = decoy->Fire(); - - if (drone) { - Observe(drone); - decoy_list.append(drone); - } - } - - if (sim->GetPlayerShip() == this) { - if (NetGame::IsNetGame()) { - if (decoy && decoy->Ammo() < 1) - Button::PlaySound(Button::SND_REJECT); - } - - else if (!drone) { - Button::PlaySound(Button::SND_REJECT); - } - } - - return drone != 0; -} - -void -Ship::AddActiveDecoy(Drone* drone) -{ - if (drone) { - Observe(drone); - decoy_list.append(drone); - } -} - -Weapon* -Ship::GetPrimary() const -{ - if (weapons.size() > primary) - return weapons[primary]->GetSelected(); - return 0; -} - -Weapon* -Ship::GetSecondary() const -{ - if (weapons.size() > secondary) - return weapons[secondary]->GetSelected(); - return 0; -} - -Weapon* -Ship::GetWeaponByIndex(int n) -{ - for (int i = 0; i < weapons.size(); i++) { - WeaponGroup* g = weapons[i]; - - List& wlist = g->GetWeapons(); - for (int j = 0; j < wlist.size(); j++) { - Weapon* w = wlist[j]; - - if (w->GetIndex() == n) { - return w; - } - } - } - - return 0; -} - -WeaponGroup* -Ship::GetPrimaryGroup() const -{ - if (weapons.size() > primary) - return weapons[primary]; - return 0; -} - -WeaponGroup* -Ship::GetSecondaryGroup() const -{ - if (weapons.size() > secondary) - return weapons[secondary]; - return 0; -} - -WeaponDesign* -Ship::GetPrimaryDesign() const -{ - if (weapons.size() > primary) - return (WeaponDesign*) weapons[primary]->GetSelected()->Design(); - return 0; -} - -WeaponDesign* -Ship::GetSecondaryDesign() const -{ - if (weapons.size() > secondary) - return (WeaponDesign*) weapons[secondary]->GetSelected()->Design(); - return 0; -} - -Weapon* -Ship::GetDecoy() const -{ - return decoy; -} - -List& -Ship::GetActiveDecoys() -{ - return decoy_list; -} - -List& -Ship::GetThreatList() -{ - return threat_list; -} - -void -Ship::AddThreat(Shot* s) -{ - if (!threat_list.contains(s)) { - Observe(s); - threat_list.append(s); - } -} - -void -Ship::DropThreat(Shot* s) -{ - if (threat_list.contains(s)) { - threat_list.remove(s); - } -} - -bool -Ship::GetTrigger(int i) const -{ - if (i >= 0) { - if (i < 4) - return trigger[i]; - - else if (i < weapons.size()) - return weapons[i]->GetTrigger(); - } - - return false; -} - -void -Ship::SetTrigger(int i) -{ - if (i >= 0 && !CheckFire()) { - if (i < 4) - trigger[i] = true; - - if (i < weapons.size()) - weapons[i]->SetTrigger(); - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetSensorMode(int mode) -{ - if (sensor) - sensor->SetMode((Sensor::Mode) mode); -} - -int -Ship::GetSensorMode() const -{ - if (sensor) - return (int) sensor->GetMode(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -bool -Ship::IsTracking(SimObject* tgt) -{ - if (tgt && sensor) - return sensor->IsTracking(tgt); - - return false; -} - -// +--------------------------------------------------------------------+ - -void -Ship::LockTarget(int type, bool closest, bool hostile) -{ - if (sensor) - SetTarget(sensor->LockTarget(type, closest, hostile)); -} - -// +--------------------------------------------------------------------+ - -void -Ship::LockTarget(SimObject* candidate) -{ - if (sensor) - SetTarget(sensor->LockTarget(candidate)); - else - SetTarget(candidate); -} - -// +--------------------------------------------------------------------+ - -double -Ship::InflictDamage(double damage, Shot* shot, int hit_type, Point impact) -{ - double damage_applied = 0; - - if (Game::GetInstance()->Paused() || IsNetObserver() || IsInvulnerable()) - return damage_applied; - - if (Integrity() == 0) // already dead? - return damage_applied; - - const double MAX_SHAKE = 7; - double hull_damage = damage; - bool hit_shield = (hit_type & HIT_SHIELD) != 0; - bool hit_hull = (hit_type & HIT_HULL) != 0; - bool hit_turret = (hit_type & HIT_TURRET) != 0; - - if (impact == Point(0,0,0)) - impact = Location(); - - if (hit_shield && ShieldStrength() > 0) { - hull_damage = shield->DeflectDamage(shot, damage); - - if (shot) { - if (shot->IsBeam()) { - if (design->beam_hit_sound_resource) { - if (Clock::GetInstance()->RealTime() - last_beam_time > 400) { - Sound* s = design->beam_hit_sound_resource->Duplicate(); - s->SetLocation(impact); - s->SetVolume(AudioConfig::EfxVolume()); - s->Play(); - - last_beam_time = Clock::GetInstance()->RealTime(); - } - } - } - - else { - if (design->bolt_hit_sound_resource) { - if (Clock::GetInstance()->RealTime() - last_bolt_time > 400) { - Sound* s = design->bolt_hit_sound_resource->Duplicate(); - s->SetLocation(impact); - s->SetVolume(AudioConfig::EfxVolume()); - s->Play(); - - last_bolt_time = Clock::GetInstance()->RealTime(); - } - } - } - } - } - - if (hit_hull) { - hull_damage = InflictSystemDamage(hull_damage, shot, impact); - - int damage_type = WeaponDesign::DMG_NORMAL; - - if (shot && shot->Design()) - damage_type = shot->Design()->damage_type; - - if (damage_type == WeaponDesign::DMG_NORMAL) { - damage_applied = hull_damage; - Physical::InflictDamage(damage_applied, 0); - NetUtil::SendObjDamage(this, damage_applied, shot); - } - } - - else if (hit_turret) { - hull_damage = InflictSystemDamage(hull_damage, shot, impact) * 0.3; - - int damage_type = WeaponDesign::DMG_NORMAL; - - if (shot && shot->Design()) - damage_type = shot->Design()->damage_type; - - if (damage_type == WeaponDesign::DMG_NORMAL) { - damage_applied = hull_damage; - Physical::InflictDamage(damage_applied, 0); - NetUtil::SendObjDamage(this, damage_applied, shot); - } - } - - // shake by percentage of maximum damage - double newshake = 50 * damage/design->integrity; - - if (shake < MAX_SHAKE) shake += (float) newshake; - if (shake > MAX_SHAKE) shake = (float) MAX_SHAKE; - - // start fires as needed: - if ((IsStarship() || IsGroundUnit() || RandomChance(1,3)) && hit_hull && damage_applied > 0) { - int old_integrity = (int) ((integrity + damage_applied)/design->integrity * 10); - int new_integrity = (int) ((integrity )/design->integrity * 10); - - if (new_integrity < 5 && new_integrity < old_integrity) { - // need accurate hull impact for starships, - if (rep) { - Point detonation = impact*2 - Location(); - Point direction = Location() - detonation; - double distance = direction.Normalize() * 3; - rep->CheckRayIntersection(detonation, direction, distance, impact); - - // pull fire back into hull a bit: - direction = Location() - impact; - impact += direction * 0.2; - - float scale = (float) design->scale; - - if (IsDropship()) - sim->CreateExplosion(impact, Velocity(), Explosion::SMOKE_TRAIL, 0.01f * scale, 0.5f * scale, region, this); - else - sim->CreateExplosion(impact, Velocity(), Explosion::HULL_FIRE, 0.10f * scale, scale, region, this); - } - } - } - - return damage_applied; -} - -double -Ship::InflictSystemDamage(double damage, Shot* shot, Point impact) -{ - if (IsNetObserver()) - return 0; - - // find the system that is closest to the impact point: - System* system = 0; - double distance = 1e6; - double blast_radius = 0; - int dmg_type = 0; - - if (shot) - dmg_type = shot->Design()->damage_type; - - bool dmg_normal = dmg_type == WeaponDesign::DMG_NORMAL; - bool dmg_power = dmg_type == WeaponDesign::DMG_POWER; - bool dmg_emp = dmg_type == WeaponDesign::DMG_EMP; - double to_level = 0; - - if (dmg_power) { - to_level = 1 - damage / 1e4; - - if (to_level < 0) - to_level = 0; - } - - // damage caused by weapons applies to closest system: - if (shot) { - if (shot->IsMissile()) - blast_radius = 300; - - ListIter iter = systems; - while (++iter) { - System* candidate = iter.value(); - double sysrad = candidate->Radius(); - - if (dmg_power) - candidate->DrainPower(to_level); - - if (sysrad > 0 || dmg_emp && candidate->IsPowerCritical()) { - double test_distance = (impact - candidate->MountLocation()).length(); - - if ((test_distance-blast_radius) < sysrad || dmg_emp && candidate->IsPowerCritical()) { - if (test_distance < distance) { - system = candidate; - distance = test_distance; - } - } - } - } - - // if a system was in range of the blast, assess the damage: - if (system) { - double hull_damage = damage * system->HullProtection(); - double sys_damage = damage - hull_damage; - double avail = system->Availability(); - - if (dmg_normal || system->IsPowerCritical() && dmg_emp) { - system->ApplyDamage(sys_damage); - NetUtil::SendSysDamage(this, system, sys_damage); - - master_caution = true; - - if (dmg_normal) { - if (sys_damage < 100) - damage -= sys_damage; - else - damage -= 100; - } - - if (system->GetExplosionType() && (avail - system->Availability()) >= 50) { - float scale = design->explosion_scale; - if (scale <= 0) - scale = design->scale; - - sim->CreateExplosion(system->MountLocation(), Velocity() * 0.7f, system->GetExplosionType(), 0.2f * scale, scale, region, this, system); - } - } - } - } - - // damage caused by collision applies to all systems: - else { - // ignore incidental bumps: - if (damage < 100) - return damage; - - ListIter iter = systems; - while (++iter) { - System* sys = iter.value(); - - if (rand() > 24000) { - double base_damage = 33.0 + rand()/1000.0; - double sys_damage = base_damage * (1.0 - sys->HullProtection()); - sys->ApplyDamage(sys_damage); - NetUtil::SendSysDamage(this, system, sys_damage); - damage -= sys_damage; - - master_caution = true; - } - } - - // just in case this ship has lots of systems... - if (damage < 0) - damage = 0; - } - - // return damage remaining - return damage; -} - -// +--------------------------------------------------------------------+ - -int -Ship::ShieldStrength() const -{ - if (!shield) return 0; - - return (int) shield->ShieldLevel(); -} - -int -Ship::HullStrength() const -{ - if (design) - return (int) (Integrity() / design->integrity * 100); - - return 10; -} - -// +--------------------------------------------------------------------+ - -System* -Ship::GetSystem(int sys_id) -{ - System* s = 0; - - if (sys_id >= 0) { - if (sys_id < systems.size()) { - s = systems[sys_id]; - if (s->GetID() == sys_id) - return s; - } - - ListIter iter = systems; - while (++iter) { - s = iter.value(); - - if (s->GetID() == sys_id) - return s; - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Ship::RepairSystem(System* sys) -{ - if (!repair_queue.contains(sys)) { - repair_queue.append(sys); - sys->Repair(); - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::IncreaseRepairPriority(int task_index) -{ - if (task_index > 0 && task_index < repair_queue.size()) { - System* task1 = repair_queue.at(task_index-1); - System* task2 = repair_queue.at(task_index); - - repair_queue.at(task_index-1) = task2; - repair_queue.at(task_index) = task1; - } -} - -void -Ship::DecreaseRepairPriority(int task_index) -{ - if (task_index >= 0 && task_index < repair_queue.size()-1) { - System* task1 = repair_queue.at(task_index); - System* task2 = repair_queue.at(task_index+1); - - repair_queue.at(task_index) = task2; - repair_queue.at(task_index+1) = task1; - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::ExecMaintFrame(double seconds) -{ - // is it already too late? - if (life == 0 || integrity < 1) return; - - const DWORD REPAIR_FREQUENCY = 5000; // once every five seconds - static DWORD last_repair_frame = 0; // one ship per game frame - - if (auto_repair && - Clock::GetInstance()->GameTime() - last_repair_time > REPAIR_FREQUENCY && - last_repair_frame != Game::GetInstance()->Frame()) { - - last_repair_time = Clock::GetInstance()->GameTime(); - last_repair_frame = Game::GetInstance()->Frame(); - - ListIter iter = systems; - while (++iter) { - System* sys = iter.value(); - - if (sys->Status() != System::NOMINAL) { - bool started_repairs = false; - - // emergency power routing: - if (sys->Type() == System::POWER_SOURCE && sys->Availability() < 33) { - PowerSource* src = (PowerSource*) sys; - PowerSource* dst = 0; - - for (int i = 0; i < reactors.size(); i++) { - PowerSource* pwr = reactors[i]; - - if (pwr != src && pwr->Availability() > src->Availability()) { - if (!dst || - (pwr->Availability() > dst->Availability() && - pwr->Charge() > dst->Charge())) - dst = pwr; - } - } - - if (dst) { - while (src->Clients().size() > 0) { - System* s = src->Clients().at(0); - src->RemoveClient(s); - dst->AddClient(s); - } - } - } - - ListIter comp = sys->GetComponents(); - while (++comp) { - Component* c = comp.value(); - - if (c->Status() < Component::NOMINAL && c->Availability() < 75) { - if (c->SpareCount() && - c->ReplaceTime() <= 300 && - (c->Availability() < 50 || - c->ReplaceTime() < c->RepairTime())) { - - c->Replace(); - started_repairs = true; - } - - else if (c->Availability() >= 50 || c->NumJerried() < 5) { - c->Repair(); - started_repairs = true; - } - } - } - - if (started_repairs) - RepairSystem(sys); - } - } - } - - if (repair_queue.size() > 0 && RepairTeams() > 0) { - int team = 0; - ListIter iter = repair_queue; - while (++iter && team < RepairTeams()) { - System* sys = iter.value(); - - sys->ExecMaintFrame(seconds * RepairSpeed()); - team++; - - if (sys->Status() != System::MAINT) { - iter.removeItem(); - - // emergency power routing (restore): - if (sys->Type() == System::POWER_SOURCE && - sys->Status() == System::NOMINAL) { - PowerSource* src = (PowerSource*) sys; - int isrc = reactors.index(src); - - for (int i = 0; i < reactors.size(); i++) { - PowerSource* pwr = reactors[i]; - - if (pwr != src) { - List xfer; - - for (int j = 0; j < pwr->Clients().size(); j++) { - System* s = pwr->Clients().at(j); - - if (s->GetSourceIndex() == isrc) { - xfer.append(s); - } - } - - for (int j = 0; j < xfer.size(); j++) { - System* s = xfer.at(j); - pwr->RemoveClient(s); - src->AddClient(s); - } - } - } - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetNetworkControl(Director* net) -{ - net_control = net; - - delete dir; - dir = 0; - - if (!net_control && GetIFF() < 100) { - if (IsStatic()) - dir = 0; - else if (IsStarship()) - dir = SteerAI::Create(this, SteerAI::STARSHIP); - else - dir = SteerAI::Create(this, SteerAI::FIGHTER); - } -} - -void -Ship::SetControls(MotionController* m) -{ - if (IsDropping() || IsAttaining()) { - if (dir && dir->Type() != DropShipAI::DIR_TYPE) { - delete dir; - dir = new DropShipAI(this); - } - - return; - } - - else if (IsSkipping()) { - if (navsys && sim->GetPlayerShip() == this) - navsys->EngageAutoNav(); - } - - else if (IsDying() || IsDead()) { - if (dir) { - delete dir; - dir = 0; - } - - if (navsys && navsys->AutoNavEngaged()) { - navsys->DisengageAutoNav(); - } - - return; - } - - else if (life == 0) { - if (dir || navsys) { - ::Print("Warning: dying ship '%' still has not been destroyed!\n", name); - delete dir; - dir = 0; - - if (navsys && navsys->AutoNavEngaged()) - navsys->DisengageAutoNav(); - } - - return; - } - - if (navsys && navsys->AutoNavEngaged()) { - NavAI* nav = 0; - - if (dir) { - if (dir->Type() != NavAI::DIR_TYPE) { - delete dir; - dir = 0; - } - else { - nav = (NavAI*) dir; - } - } - - if (!nav) { - nav = new NavAI(this); - dir = nav; - return; - } - - else if (!nav->Complete()) { - return; - } - } - - if (dir) { - delete dir; - dir = 0; - } - - if (m) { - Keyboard::FlushKeys(); - m->Acquire(); - dir = new ShipCtrl(this, m); - director_info = ContentBundle::GetInstance()->GetText("flcs.auto"); - } - else if (GetIFF() < 100) { - if (IsStatic()) - dir = SteerAI::Create(this, SteerAI::GROUND); - - else if (IsStarship() && !IsAirborne()) - dir = SteerAI::Create(this, SteerAI::STARSHIP); - - else - dir = SteerAI::Create(this, SteerAI::FIGHTER); - } -} - -// +--------------------------------------------------------------------+ - -Color -Ship::IFFColor(int iff) -{ - Color c; - - switch (iff) { - case 0: // NEUTRAL, NON-COMBAT - c = Color(192,192,192); - break; - - case 1: // TERELLIAN ALLIANCE - c = Color(70,70,220); - break; - - case 2: // MARAKAN HEGEMONY - c = Color(220,20,20); - break; - - case 3: // BROTHERHOOD OF IRON - c = Color(200,180,20); - break; - - case 4: // ZOLON EMPIRE - c = Color(20,200,20); - break; - - case 5: - c = Color(128, 0, 128); - break; - - case 6: - c = Color(40,192,192); - break; - - default: - c = Color(128,128,128); - break; - } - - return c; -} - -Color -Ship::MarkerColor() const -{ - return IFFColor(IFF_code); -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetIFF(int iff) -{ - IFF_code = iff; - - if (hangar) - hangar->SetAllIFF(iff); - - DropTarget(); - - if (dir && dir->Type() >= 1000) { - SteerAI* ai = (SteerAI*) dir; - ai->DropTarget(); - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetRogue(bool r) -{ - bool rogue = IsRogue(); - - ff_count = r ? 1000 : 0; - - if (!rogue && IsRogue()) { - Print("Ship '%s' has been made rogue\n", Name()); - } - else if (rogue && !IsRogue()) { - Print("Ship '%s' is no longer rogue\n", Name()); - } -} - -void -Ship::SetFriendlyFire(int f) -{ - bool rogue = IsRogue(); - - ff_count = f; - - if (!rogue && IsRogue()) { - Print("Ship '%s' has been made rogue with ff_count = %d\n", Name(), ff_count); - } - else if (rogue && !IsRogue()) { - Print("Ship '%s' is no longer rogue\n", Name()); - } -} - -void -Ship::IncFriendlyFire(int f) -{ - if (f > 0) { - bool rogue = IsRogue(); - - ff_count += f; - - if (!rogue && IsRogue()) { - Print("Ship '%s' has been made rogue with ff_count = %d\n", Name(), ff_count); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Ship::SetEMCON(int e, bool from_net) -{ - if (e < 1) emcon = 1; - else if (e > 3) emcon = 3; - else emcon = (BYTE) e; - - if (emcon != old_emcon && !from_net && NetGame::GetInstance()) - NetUtil::SendObjEmcon(this); -} - -double -Ship::PCS() const -{ - double e_factor = design->e_factor[emcon-1]; - - if (IsAirborne() && !IsGroundUnit()) { - if (AltitudeAGL() < 40) - return 0; - - if (AltitudeAGL() < 200) { - double clutter = AltitudeAGL() / 200; - return clutter * e_factor; - } - } - - return e_factor * pcs; -} - -double -Ship::ACS() const -{ - if (IsAirborne() && !IsGroundUnit()) { - if (AltitudeAGL() < 40) - return 0; - - if (AltitudeAGL() < 200) { - double clutter = AltitudeAGL() / 200; - return clutter * acs; - } - } - - return acs; -} - -DWORD -Ship::MissionClock() const -{ - if (launch_time > 0) - return Clock::GetInstance()->GameTime() + 1 - launch_time; - - return 0; -} - -// +----------------------------------------------------------------------+ - -Instruction* -Ship::GetRadioOrders() const -{ - return radio_orders; -} - -void -Ship::ClearRadioOrders() -{ - if (radio_orders) { - radio_orders->SetAction(0); - radio_orders->ClearTarget(); - radio_orders->SetLocation(Point()); - } -} - -void -Ship::HandleRadioMessage(RadioMessage* msg) -{ - if (!msg) return; - - static RadioHandler rh; - - if (rh.ProcessMessage(msg, this)) - rh.AcknowledgeMessage(msg, this); -} - -// +----------------------------------------------------------------------+ - -int -Ship::Value() const -{ - return Value(design->type); -} - -// +----------------------------------------------------------------------+ - -int -Ship::Value(int type) -{ - int value = 0; - - switch (type) { - case DRONE: value = 10; break; - case FIGHTER: value = 20; break; - case ATTACK: value = 40; break; - case LCA: value = 50; break; - - case COURIER: value = 100; break; - case CARGO: value = 100; break; - case CORVETTE: value = 100; break; - case FREIGHTER: value = 250; break; - case FRIGATE: value = 200; break; - case DESTROYER: value = 500; break; - case CRUISER: value = 800; break; - case BATTLESHIP: value = 1000; break; - case CARRIER: value = 1500; break; - case SWACS: value = 500; break; - case DREADNAUGHT: value = 1500; break; - - case STATION: value = 2500; break; - case FARCASTER: value = 5000; break; - - case MINE: value = 20; break; - case COMSAT: value = 200; break; - case DEFSAT: value = 300; break; - - case BUILDING: value = 100; break; - case FACTORY: value = 250; break; - case SAM: value = 100; break; - case EWR: value = 200; break; - case C3I: value = 500; break; - case STARBASE: value = 2000; break; - - default: value = 100; break; - } - - return value; -} - -// +----------------------------------------------------------------------+ - -double -Ship::AIValue() const -{ - int i = 0; - double value = 0; - - for (i = 0; i < reactors.size(); i++) { - const PowerSource* r = reactors[i]; - value += r->Value(); - } - - for (i = 0; i < drives.size(); i++) { - const Drive* d = drives[i]; - value += d->Value(); - } - - for (i = 0; i < weapons.size(); i++) { - const WeaponGroup* w = weapons[i]; - value += w->Value(); - } - - return value; -} diff --git a/Stars45/Ship.h b/Stars45/Ship.h deleted file mode 100644 index 26cf971..0000000 --- a/Stars45/Ship.h +++ /dev/null @@ -1,582 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Starship (or space/ground station) class -*/ - -#ifndef Ship_h -#define Ship_h - -#include "Types.h" -#include "SimObject.h" -#include "DetailSet.h" -#include "Director.h" -#include "Geometry.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class Shot; -class Drone; - -class Bitmap; -class CombatUnit; -class Computer; -class Contact; -class Drive; -class Element; -class Farcaster; -class FlightComp; -class FlightDeck; -class Hangar; -class InboundSlot; -class Instruction; -class LandingGear; -class MotionController; -class NavLight; -class NavSystem; -class PowerSource; -class QuantumDrive; -class RadioMessage; -class Shield; -class ShieldRep; -class ShipDesign; -class ShipKiller; -class Solid; -class Skin; -class Sound; -class Sensor; -class System; -class Thruster; -class Weapon; -class WeaponDesign; -class WeaponGroup; - -// +--------------------------------------------------------------------+ - -class Ship : public SimObject, -public SimObserver -{ -public: - static const char* TYPENAME() { return "Ship"; } - - enum CLASSIFICATION { - DRONE = 0x0001, - FIGHTER = 0x0002, - ATTACK = 0x0004, - LCA = 0x0008, - COURIER = 0x0010, - CARGO = 0x0020, - CORVETTE = 0x0040, - FREIGHTER = 0x0080, - FRIGATE = 0x0100, - DESTROYER = 0x0200, - CRUISER = 0x0400, - BATTLESHIP = 0x0800, - CARRIER = 0x1000, - DREADNAUGHT = 0x2000, - - STATION = 0x4000, - FARCASTER = 0x8000, - - MINE = 0x00010000, - COMSAT = 0x00020000, - DEFSAT = 0x00040000, - SWACS = 0x00080000, - - BUILDING = 0x00100000, - FACTORY = 0x00200000, - SAM = 0x00400000, - EWR = 0x00800000, - C3I = 0x01000000, - STARBASE = 0x02000000, - - DROPSHIPS = 0x0000000f, - STARSHIPS = 0x0000fff0, - SPACE_UNITS = 0x000f0000, - GROUND_UNITS = 0xfff00000 - }; - - enum OP_MODE { DOCKED, ALERT, LOCKED, LAUNCH, TAKEOFF, ACTIVE, APPROACH, RECOVERY, DOCKING }; - enum FLCS_MODE { FLCS_MANUAL, FLCS_AUTO, FLCS_HELM }; - enum TRAN_TYPE { TRANSITION_NONE, - TRANSITION_DROP_CAM, - TRANSITION_DROP_ORBIT, - TRANSITION_MAKE_ORBIT, - TRANSITION_TIME_SKIP, - TRANSITION_DEATH_SPIRAL, - TRANSITION_DEAD }; - - enum FLIGHT_MODEL { FM_STANDARD, FM_RELAXED, FM_ARCADE }; - enum LANDING_MODEL { LM_STANDARD, LM_EASIER }; - - // CONSTRUCTORS: - Ship(const char* ship_name, const char* reg_num, ShipDesign* design, int IFF=0, int cmd_ai=0, const int* loadout=0); - virtual ~Ship(); - - int operator == (const Ship& s) const { return id == s.id; } - - static void Initialize(); - static void Close(); - - virtual void ExecFrame(double seconds); - virtual void AeroFrame(double seconds); - virtual void StatFrame(double seconds); - virtual void DockFrame(double seconds); - virtual void LinearFrame(double seconds); - virtual void ExecSensors(double seconds); - - void ExecNavFrame(double seconds); - void ExecPhysics(double seconds); - void ExecThrottle(double seconds); - void ExecSystems(double seconds); - - virtual void Activate(Scene& scene); - virtual void Deactivate(Scene& scene); - virtual void SelectDetail(double seconds); - virtual void SetRegion(SimRegion* rgn); - virtual int GetTextureList(List& textures); - - // DIRECTION: - virtual void SetControls(MotionController* m); - virtual void SetNetworkControl(Director* net_ctrl=0); - void SetDirectorInfo(const char* msg) { director_info = msg; } - const char* GetDirectorInfo() const { return director_info; } - void SetAIMode(int n) { ai_mode = (BYTE) n; } - int GetAIMode() const { return (int) ai_mode; } - void SetCommandAILevel(int n) { command_ai_level = (BYTE) n; } - int GetCommandAILevel() const { return command_ai_level; } - virtual int GetFlightPhase() const { return flight_phase; } - virtual void SetFlightPhase(OP_MODE phase); - bool IsNetObserver() const { return net_observer_mode; } - void SetNetObserver(bool n) { net_observer_mode = n; } - - bool IsInvulnerable() const { return invulnerable; } - void SetInvulnerable(bool n) { invulnerable = n; } - - double GetHelmHeading() const { return helm_heading; } - double GetHelmPitch() const { return helm_pitch; } - void SetHelmHeading(double h); - void SetHelmPitch(double p); - virtual void ApplyHelmYaw(double y); - virtual void ApplyHelmPitch(double p); - virtual void ApplyPitch(double pitch_acc); // override for G limiter - - void ArcadeStop() { arcade_velocity *= 0; } - - // CAMERA: - Point BridgeLocation() const { return bridge_vec; } - Point ChaseLocation() const { return chase_vec; } - Point TransitionLocation() const { return transition_loc; } - - // FLIGHT DECK: - Ship* GetController() const; - int NumInbound() const; - int NumFlightDecks() const; - FlightDeck* GetFlightDeck(int i=0) const; - Ship* GetCarrier() const { return carrier; } - FlightDeck* GetDock() const { return dock; } - void SetCarrier(Ship* c, FlightDeck* d); - void Stow(); - InboundSlot* GetInbound() const { return inbound; } - void SetInbound(InboundSlot* s); - - // DRIVE SYSTEMS: - int GetFuelLevel() const; // (0-100) percent of full tank - void SetThrottle(double percent); - void SetAugmenter(bool enable); - double Thrust(double seconds) const; - double VelocityLimit() const { return vlimit; } - Drive* GetDrive() const { return main_drive; } - double Throttle() const { return throttle; } - bool Augmenter() const { return augmenter; } - QuantumDrive* GetQuantumDrive() const { return quantum_drive; } - Farcaster* GetFarcaster() const { return farcaster; } - - bool IsAirborne() const; - bool IsDropCam() const { return transition_type == TRANSITION_DROP_CAM; } - bool IsDropping() const { return transition_type == TRANSITION_DROP_ORBIT; } - bool IsAttaining() const { return transition_type == TRANSITION_MAKE_ORBIT; } - bool IsSkipping() const { return transition_type == TRANSITION_TIME_SKIP; } - bool IsDying() const { return transition_type == TRANSITION_DEATH_SPIRAL; } - bool IsDead() const { return transition_type == TRANSITION_DEAD; } - bool InTransition() const { return transition_type != TRANSITION_NONE; } - void DropOrbit(); - void MakeOrbit(); - bool CanTimeSkip(); - bool IsInCombat(); - void TimeSkip(); - void DropCam(double time=10, double range=0); - void DeathSpiral(); - void CompleteTransition(); - void SetTransition(double trans_time, int trans_type, const Point& trans_loc); - - double CompassHeading() const; - double CompassPitch() const; - double AltitudeMSL() const; - double AltitudeAGL() const; - double GForce() const; - - virtual void SetupAgility(); - - // FLIGHT CONTROL SYSTEM (FLCS): - void ExecFLCSFrame(); - void CycleFLCSMode(); - void SetFLCSMode(int mode); - int GetFLCSMode() const; - void SetTransX(double t); - void SetTransY(double t); - void SetTransZ(double t); - - bool IsGearDown(); - void LowerGear(); - void RaiseGear(); - void ToggleGear(); - void ToggleNavlights(); - - // WEAPON SYSTEMS: - virtual void CheckFriendlyFire(); - virtual void CheckFire(bool c) { check_fire = c; } - virtual bool CheckFire() const { return (check_fire||net_observer_mode)?true:false; } - virtual void SelectWeapon(int n, int w); - virtual bool FireWeapon(int n); - virtual bool FirePrimary() { return FireWeapon(primary); } - virtual bool FireSecondary() { return FireWeapon(secondary); } - virtual bool FireDecoy(); - virtual void CyclePrimary(); - virtual void CycleSecondary(); - virtual Weapon* GetPrimary() const; - virtual Weapon* GetSecondary() const; - virtual Weapon* GetWeaponByIndex(int n); - virtual WeaponGroup* GetPrimaryGroup() const; - virtual WeaponGroup* GetSecondaryGroup() const; - virtual Weapon* GetDecoy() const; - virtual List& GetActiveDecoys(); - virtual void AddActiveDecoy(Drone* d); - virtual int* GetLoadout() { return loadout; } - - List& GetThreatList(); - void AddThreat(Shot* s); - void DropThreat(Shot* s); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const { return name; } - - virtual int GetMissileEta(int index) const; - virtual void SetMissileEta(int id, int eta); - - virtual WeaponDesign* GetPrimaryDesign() const; - virtual WeaponDesign* GetSecondaryDesign() const; - - virtual void SetTarget(SimObject* t, System* sub=0, bool from_net=false); - virtual SimObject* GetTarget() const { return target; } - virtual System* GetSubTarget() const { return subtarget; } - virtual void CycleSubTarget(int dir=1); - virtual void DropTarget(); - virtual void LockTarget(int type=SimObject::SIM_SHIP, - bool closest=false, - bool hostile=false); - virtual void LockTarget(SimObject* candidate); - virtual bool IsTracking(SimObject* tgt); - virtual bool GetTrigger(int i) const; - virtual void SetTrigger(int i); - - Ship* GetWard() const { return ward; } - void SetWard(Ship* s); - - // SHIELD SYSTEMS: - virtual double InflictDamage(double damage, - Shot* shot = 0, - int hit_type = 3, - Point hull_impact = Point(0,0,0)); - - virtual double InflictSystemDamage(double damage, Shot* shot, Point impact); - - virtual void InflictNetDamage(double damage, Shot* shot=0); - virtual void InflictNetSystemDamage(System* system, double damage, BYTE type); - virtual void SetNetSystemStatus(System* system, int status, int power, int reactor, double avail); - virtual void SetIntegrity(float n) { integrity = n; } - - virtual void Destroy(); - virtual int ShieldStrength() const; - virtual int HullStrength() const; - virtual int HitBy(Shot* shot, Point& impact); - virtual int CollidesWith(Physical& o); - - // SENSORS AND VISIBILITY: - virtual int GetContactID() const { return contact_id; } - virtual int GetIFF() const { return IFF_code; } - virtual void SetIFF(int iff); - virtual Color MarkerColor() const; - static Color IFFColor(int iff); - virtual void DoEMCON(); - virtual double PCS() const; - virtual double ACS() const; - int NumContacts() const; // actual sensor contacts - List& ContactList(); - virtual int GetSensorMode() const; - virtual void SetSensorMode(int mode); - virtual void LaunchProbe(); - virtual Weapon* GetProbeLauncher() const { return probe; } - virtual Drone* GetProbe() const { return sensor_drone; } - virtual void SetProbe(Drone* d); - virtual int GetEMCON() const { return emcon; } - virtual void SetEMCON(int e, bool from_net=false); - virtual Contact* FindContact(SimObject* s) const; - virtual bool IsHostileTo(const SimObject* o) const; - - // GENERAL ACCESSORS: - const char* Registry() const { return regnum; } - void SetName(const char* ident) { strcpy_s(name, ident); } - const ShipDesign* Design() const { return design; } - const char* Abbreviation() const; - const char* DesignName() const; - const char* DesignFileName() const; - static const char* ClassName(int c); - static int ClassForName(const char* name); - const char* ClassName() const; - CLASSIFICATION Class() const; - bool IsGroundUnit() const; - bool IsStarship() const; - bool IsDropship() const; - bool IsStatic() const; - bool IsRogue() const; - void SetRogue(bool r=true); - int GetFriendlyFire() const { return ff_count; } - void SetFriendlyFire(int f); - void IncFriendlyFire(int f=1); - double Agility() const { return agility; } - DWORD MissionClock() const; - Graphic* Cockpit() const; - void ShowCockpit(); - void HideCockpit(); - int Value() const; - double AIValue() const; - static int Value(int type); - - const Skin* GetSkin() const { return skin; } - void UseSkin(const Skin* s) { skin = s; } - void ShowRep(); - void HideRep(); - void EnableShadows(bool enable); - - int RespawnCount() const { return respawns; } - void SetRespawnCount(int r) { respawns = r; } - const Point& RespawnLoc() const { return respawn_loc; } - void SetRespawnLoc(const Point& rl) - { respawn_loc = rl; } - - double WarpFactor() const { return warp_fov; } - void SetWarp(double w) { warp_fov = (float) w; } - - void MatchOrientation(const Ship& s); - - // ORDERS AND NAVIGATION: - void ExecEvalFrame(double seconds); - void SetLaunchPoint(Instruction* pt); - void AddNavPoint(Instruction* pt, Instruction* afterPoint=0); - void DelNavPoint(Instruction* pt); - void ClearFlightPlan(); - Instruction* GetNextNavPoint(); - int GetNavIndex(const Instruction* n); - double RangeToNavPoint(const Instruction* n); - void SetNavptStatus(Instruction* n, int status); - List& GetFlightPlan(); - int FlightPlanLength(); - CombatUnit* GetCombatUnit() const { return combat_unit; } - Element* GetElement() const { return element; } - Ship* GetLeader() const; - int GetElementIndex() const; - int GetOrigElementIndex() const; - void SetElement(Element* e); - - Instruction* GetRadioOrders() const; - void ClearRadioOrders(); - void HandleRadioMessage(RadioMessage* msg); - bool IsAutoNavEngaged(); - void SetAutoNav(bool engage=true); - void CommandMode(); - - void ClearTrack(); - void UpdateTrack(); - int TrackLength() const { return ntrack; } - Point TrackPoint(int i) const; - - // DAMAGE CONTROL AND ENGINEERING: - List& RepairQueue() { return repair_queue; } - double RepairSpeed() const; - int RepairTeams() const; - void RepairSystem(System* sys); - void IncreaseRepairPriority(int task_index); - void DecreaseRepairPriority(int task_index); - void ExecMaintFrame(double seconds); - bool AutoRepair() const { return auto_repair; } - void EnableRepair(bool e) { auto_repair = e; } - bool MasterCaution() const { return master_caution; } - void ClearCaution() { master_caution = 0; } - - // SYSTEM ACCESSORS: - List& Systems() { return systems; } - List& Weapons() { return weapons; } - List& Drives() { return drives; } - List& Computers() { return computers; } - List& FlightDecks() { return flight_decks; } - List& Reactors() { return reactors; } - List& NavLights() { return navlights; } - Shield* GetShield() { return shield; } - Solid* GetShieldRep() { return (Solid*) shieldRep; } - Sensor* GetSensor() { return sensor; } - NavSystem* GetNavSystem() { return navsys; } - FlightComp* GetFLCS() { return flcs; } - Thruster* GetThruster() { return thruster; } - Hangar* GetHangar() { return hangar; } - LandingGear* GetGear() { return gear; } - - System* GetSystem(int sys_id); - - static int GetControlModel() { return control_model; } - static void SetControlModel(int n) { control_model = n; } - static int GetFlightModel() { return flight_model; } - static void SetFlightModel(int f) { flight_model = f; } - static int GetLandingModel() { return landing_model; } - static void SetLandingModel(int f) { landing_model = f; } - static double GetFriendlyFireLevel() { return friendly_fire_level; } - static void SetFriendlyFireLevel(double f) - { friendly_fire_level = f; } - -protected: - int CheckShotIntersection(Shot* shot, Point& ipt, Point& hpt, Weapon** wep=0); - WeaponGroup* FindWeaponGroup(const char* name); - - char regnum[16]; - ShipDesign* design; - ShipKiller* killer; - DetailSet detail; - int detail_level; - Sim* sim; - double vlimit; - double agility; - double throttle; - double throttle_request; - bool augmenter; - float wep_mass; - float wep_resist; - - int IFF_code; - int cmd_chain_index; - int ff_count; - OP_MODE flight_phase; - - SimObject* target; - System* subtarget; - Ship* ward; - int check_fire; - int primary; - int secondary; - - const Skin* skin; - Solid* cockpit; - Drive* main_drive; - QuantumDrive* quantum_drive; - Farcaster* farcaster; - Shield* shield; - ShieldRep* shieldRep; - NavSystem* navsys; - FlightComp* flcs; - Sensor* sensor; - LandingGear* gear; - Thruster* thruster; - Weapon* decoy; - Weapon* probe; - Drone* sensor_drone; - Hangar* hangar; - List decoy_list; - List threat_list; - - List systems; - List reactors; - List weapons; - List drives; - List computers; - List flight_decks; - List navlights; - List repair_queue; - - CombatUnit* combat_unit; - Element* element; - int orig_elem_index; - Instruction* radio_orders; - Instruction* launch_point; - - Vec3 chase_vec; - Vec3 bridge_vec; - - const char* director_info; - BYTE ai_mode; - BYTE command_ai_level; - BYTE flcs_mode; - bool net_observer_mode; - - float pcs; // passive sensor cross section - float acs; // active sensor cross section - BYTE emcon; - BYTE old_emcon; - bool invulnerable; - - DWORD launch_time; - DWORD friendly_fire_time; - - Ship* carrier; - FlightDeck* dock; - InboundSlot* inbound; - - Director* net_control; - - Point* track; - int ntrack; - DWORD track_time; - - float helm_heading; - float helm_pitch; - - float altitude_agl; - float g_force; - - float warp_fov; - - float transition_time; - int transition_type; - Point transition_loc; - Point respawn_loc; - int respawns; - - bool master_caution; - bool auto_repair; - DWORD last_repair_time; - DWORD last_eval_time; - DWORD last_beam_time; - DWORD last_bolt_time; - - int missile_id[4]; - BYTE missile_eta[4]; - bool trigger[4]; - int* loadout; - - int contact_id; - - static int control_model; - static int flight_model; - static int landing_model; - static double friendly_fire_level; -}; - -#endif // Ship_h - diff --git a/Stars45/ShipAI.cpp b/Stars45/ShipAI.cpp deleted file mode 100644 index 4030f34..0000000 --- a/Stars45/ShipAI.cpp +++ /dev/null @@ -1,1360 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Starship (low-level) Artificial Intelligence class -*/ - -#include "ShipAI.h" -#include "TacticalAI.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Shot.h" -#include "Element.h" -#include "NavLight.h" -#include "Instruction.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "Contact.h" -#include "WeaponGroup.h" -#include "Drive.h" -#include "Shield.h" -#include "Sim.h" -#include "Player.h" -#include "StarSystem.h" -#include "FlightComp.h" -#include "Farcaster.h" -#include "QuantumDrive.h" -#include "Debris.h" -#include "Asteroid.h" - -#include "Clock.h" -#include "ContentBundle.h" -#include "Random.h" - -// +----------------------------------------------------------------------+ - -ShipAI::ShipAI(SimObject* s) - : SteerAI(s), - support(0), rumor(0), threat(0), threat_missile(0), drop_time(0), - too_close(0), navpt(0), patrol(0), engaged_ship_id(0), - bracket(false), identify(false), hold(false), takeoff(false), - throttle(0), old_throttle(0), element_index(1), splash_count(0), - tactical(0), farcaster(0), ai_level(2), last_avoid_time(0), - last_call_time(0) -{ - ship = (Ship*) self; - - Sim* sim = Sim::GetSim(); - Ship* pship = sim->GetPlayerShip(); - int player_team = 1; - - if (pship) - player_team = pship->GetIFF(); - - Player* player = Player::GetCurrentPlayer(); - if (player) { - if (ship && ship->GetIFF() && ship->GetIFF() != player_team) { - ai_level = player->AILevel(); - } - else if (player->AILevel() == 0) { - ai_level = 1; - } - } - - // evil alien ships are *always* smart: - if (ship && ship->GetIFF() > 1 && ship->Design()->auto_roll > 1) { - ai_level = 2; - } -} - - -// +--------------------------------------------------------------------+ - -ShipAI::~ShipAI() -{ - delete tactical; -} - -void -ShipAI::ClearTactical() -{ - delete tactical; - tactical = 0; -} - -// +--------------------------------------------------------------------+ - -Ship* -ShipAI::GetWard() const -{ - return ship->GetWard(); -} - -void -ShipAI::SetWard(Ship* s) -{ - if (ship == nullptr) - return; - if (s == ship->GetWard()) - return; - - if (ship) - ship->SetWard(s); - - Point form = RandomDirection(); - form.SwapYZ(); - - if (fabs(form.x) < 0.5) { - if (form.x < 0) - form.x = -0.5; - else - form.x = 0.5; - } - - if (ship && ship->IsStarship()) { - form *= 30e3; - } - else { - form *= 15e3; - form.y = 500; - } - - SetFormationDelta(form); -} - -void -ShipAI::SetSupport(Ship* s) -{ - if (support == s) - return; - - support = s; - - if (support) - Observe(support); -} - -void -ShipAI::SetRumor(Ship* s) -{ - if (!s || rumor == s) - return; - - rumor = s; - - if (rumor) - Observe(rumor); -} - -void -ShipAI::ClearRumor() -{ - rumor = 0; -} - -void -ShipAI::SetThreat(Ship* s) -{ - if (threat == s) - return; - - threat = s; - - if (threat) - Observe(threat); -} - -void -ShipAI::SetThreatMissile(Shot* s) -{ - if (threat_missile == s) - return; - - threat_missile = s; - - if (threat_missile) - Observe(threat_missile); -} - -bool -ShipAI::Update(SimObject* obj) -{ - if (obj == support) - support = 0; - - if (obj == threat) - threat = 0; - - if (obj == threat_missile) - threat_missile = 0; - - if (obj == rumor) - rumor = 0; - - return SteerAI::Update(obj); -} - -const char* -ShipAI::GetObserverName() const -{ - static char name[64]; - sprintf_s(name, "ShipAI(%s)", self->Name()); - return name; -} - -// +--------------------------------------------------------------------+ - -Point -ShipAI::GetPatrol() const -{ - return patrol_loc; -} - -void -ShipAI::SetPatrol(const Point& p) -{ - patrol = 1; - patrol_loc = p; -} - -void -ShipAI::ClearPatrol() -{ - patrol = 0; -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::ExecFrame(double secs) -{ - seconds = secs; - - if (drop_time > 0) drop_time -= seconds; - if (!ship) return; - - ship->SetDirectorInfo(" "); - - // check to make sure current navpt is still valid: - if (navpt) - navpt = ship->GetNextNavPoint(); - - if (ship->GetFlightPhase() == Ship::TAKEOFF || ship->GetFlightPhase() == Ship::LAUNCH) - takeoff = true; - - if (takeoff) { - FindObjective(); - Navigator(); - - if (ship->MissionClock() > 10000) - takeoff = false; - - return; - } - - // initial assessment: - if (ship->MissionClock() < 5000) - return; - - element_index = ship->GetElementIndex(); - - NavlightControl(); - CheckTarget(); - - if (tactical) - tactical->ExecFrame(seconds); - - if (target && target != ship->GetTarget()) { - ship->LockTarget(target); - - // if able to lock target, and target is a ship (not a shot)... - if (target == ship->GetTarget() && target->Type() == SimObject::SIM_SHIP) { - - // if this isn't the same ship we last called out: - if (target->Identity() != engaged_ship_id && Clock::GetInstance()->GameTime() - last_call_time > 10000) { - // call engaging: - RadioMessage* msg = new RadioMessage(ship->GetElement(), ship, RadioMessage::CALL_ENGAGING); - msg->AddTarget(target); - RadioTraffic::Transmit(msg); - last_call_time = Clock::GetInstance()->GameTime(); - - engaged_ship_id = target->Identity(); - } - } - } - - else if (!target) { - target = ship->GetTarget(); - - if (engaged_ship_id && !target) { - engaged_ship_id = 0; - - /*** - *** XXX - *** Not the right place to make this decision. - *** - *** There is a brief wait between killing a target and - *** selecting a new one, so this message is sent after - *** every kill. - *** - *** Need to track when the entire element has been - *** put down. - - if (element_index == 1) { - RadioMessage* msg = new RadioMessage(ship->GetElement(), ship, RadioMessage::RESUME_MISSION); - RadioTraffic::Transmit(msg); - } - - *** - ***/ - } - } - - FindObjective(); - Navigator(); -} - -// +--------------------------------------------------------------------+ - -Point -ShipAI::ClosingVelocity() -{ - if (ship && target) { - if (ship->GetPrimaryDesign()) { - WeaponDesign* guns = ship->GetPrimaryDesign(); - Point delta = target->Location() - ship->Location(); - - // fighters need to aim the ship so that the guns will hit the target - if (guns->firing_cone < 10*DEGREES && guns->max_range <= delta.length()) { - Point aim_vec = ship->Heading(); - aim_vec.Normalize(); - - Point shot_vel = ship->Velocity() + aim_vec * guns->speed; - return shot_vel - target->Velocity(); - } - - // ships with turreted weapons just need to worry about actual closing speed - else { - return ship->Velocity() - target->Velocity(); - } - } - - else { - return ship->Velocity(); - } - } - - return Point(1,0,0); -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::FindObjective() -{ - distance = 0; - - int order = ship->GetRadioOrders()->Action(); - - if (order == RadioMessage::QUANTUM_TO || - order == RadioMessage::FARCAST_TO) { - - FindObjectiveQuantum(); - objective = Transform(obj_w); - return; - } - - bool form = (order == RadioMessage::WEP_HOLD) || - (order == RadioMessage::FORM_UP) || - (order == RadioMessage::MOVE_PATROL) || - (order == RadioMessage::RTB) || - (order == RadioMessage::DOCK_WITH) || - (!order && !target) || - (farcaster); - - Ship* ward = ship->GetWard(); - - // if not the element leader, stay in formation: - if (form && element_index > 1) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.formation")); - - if (navpt && navpt->Action() == Instruction::LAUNCH) { - FindObjectiveNavPoint(); - } - else { - navpt = 0; - FindObjectiveFormation(); - } - - // transform into camera coords: - objective = Transform(obj_w); - return; - } - - // under orders? - bool directed = false; - if (tactical) - directed = (tactical->RulesOfEngagement() == TacticalAI::DIRECTED); - - // threat processing: - if (threat && !directed) { - double d_threat = Point(threat->Location() - ship->Location()).length(); - - // seek support: - if (support) { - double d_support = Point(support->Location() - ship->Location()).length(); - if (d_support > 35e3) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.regroup")); - FindObjectiveTarget(support); - objective = Transform(obj_w); - return; - } - } - - // run away: - else if (threat != target) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.retreat")); - obj_w = ship->Location() + Point(ship->Location() - threat->Location()) * 100; - objective = Transform(obj_w); - return; - } - } - - // normal processing: - if (target) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-target")); - FindObjectiveTarget(target); - objective = AimTransform(obj_w); - } - - else if (patrol) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.patrol")); - FindObjectivePatrol(); - objective = Transform(obj_w); - } - - else if (ward) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-ward")); - FindObjectiveFormation(); - objective = Transform(obj_w); - } - - else if (navpt && form) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-navpt")); - FindObjectiveNavPoint(); - objective = Transform(obj_w); - } - - else if (rumor) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.search")); - FindObjectiveTarget(rumor); - objective = Transform(obj_w); - } - - else { - obj_w = Point(); - objective = Point(); - } -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::FindObjectiveTarget(SimObject* tgt) -{ - if (!tgt) { - obj_w = Point(); - return; - } - - navpt = 0; // this tells fire control that we are chasing a target, - // instead of a navpoint! - - Point cv = ClosingVelocity(); - double cvl = cv.length(); - double time = 0; - - if (cvl > 50) { - // distance from self to target: - distance = Point(tgt->Location() - self->Location()).length(); - - // time to reach target: - time = distance / cvl; - - // where the target will be when we reach it: - if (time < 15) { - Point run_vec = tgt->Velocity(); - obj_w = tgt->Location() + (run_vec * time); - - - if (time < 10) - obj_w += (tgt->Acceleration() * 0.33 * time * time); - } - else { - obj_w = tgt->Location(); - } - } - - else { - obj_w = tgt->Location(); - } - - distance = Point(obj_w - self->Location()).length(); - - if (cvl > 50) { - time = distance / cvl; - - // where we will be when the target gets there: - if (time < 15) { - Point self_dest = self->Location() + cv * time; - Point err = obj_w - self_dest; - - obj_w += err; - } - } - - Point approach = obj_w - self->Location(); - distance = approach.length(); - - if (bracket && distance > 25e3) { - Point offset = approach.cross(Point(0,1,0)); - offset.Normalize(); - offset *= 15e3; - - Ship* s = (Ship*) self; - if (s->GetElementIndex() & 1) - obj_w -= offset; - else - obj_w += offset; - } -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::FindObjectivePatrol() -{ - navpt = 0; - - Point npt = patrol_loc; - obj_w = npt; - - // distance from self to navpt: - distance = Point(obj_w - self->Location()).length(); - - if (distance < 1000) { - ship->ClearRadioOrders(); - ClearPatrol(); - } -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::FindObjectiveNavPoint() -{ - SimRegion* self_rgn = ship->GetRegion(); - SimRegion* nav_rgn = navpt->Region(); - QuantumDrive* qdrive = ship->GetQuantumDrive(); - - if (!self_rgn) - return; - - if (!nav_rgn) { - nav_rgn = self_rgn; - navpt->SetRegion(nav_rgn); - } - - bool use_farcaster = self_rgn != nav_rgn && - (navpt->Farcast() || - !qdrive || - !qdrive->IsPowerOn() || - qdrive->Status() < System::DEGRADED - ); - - if (use_farcaster) { - FindObjectiveFarcaster(self_rgn, nav_rgn); - } - - else { - if (farcaster) { - if (farcaster->GetShip()->GetRegion() != self_rgn) - farcaster = farcaster->GetDest()->GetFarcaster(); - - obj_w = farcaster->EndPoint(); - } - - else { - // transform from starsystem to world coordinates: - Point npt = navpt->Region()->Location() + navpt->Location(); - - SimRegion* active_region = ship->GetRegion(); - - if (active_region) - npt -= active_region->Location(); - - npt = npt.OtherHand(); - - obj_w = npt; - } - - // distance from self to navpt: - distance = Point(obj_w - ship->Location()).length(); - - if (farcaster && distance < 1000) - farcaster = 0; - - if (distance < 1000 || (navpt->Action() == Instruction::LAUNCH && distance > 25000)) - ship->SetNavptStatus(navpt, Instruction::COMPLETE); - } -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::FindObjectiveQuantum() -{ - Instruction* orders = ship->GetRadioOrders(); - SimRegion* self_rgn = ship->GetRegion(); - SimRegion* nav_rgn = orders->Region(); - QuantumDrive* qdrive = ship->GetQuantumDrive(); - - if (!self_rgn || !nav_rgn) - return; - - bool use_farcaster = self_rgn != nav_rgn && - (orders->Farcast() || - !qdrive || - !qdrive->IsPowerOn() || - qdrive->Status() < System::DEGRADED - ); - - if (use_farcaster) { - FindObjectiveFarcaster(self_rgn, nav_rgn); - } - - else { - if (farcaster) { - if (farcaster->GetShip()->GetRegion() != self_rgn) - farcaster = farcaster->GetDest()->GetFarcaster(); - - obj_w = farcaster->EndPoint(); - } - - else { - // transform from starsystem to world coordinates: - Point npt = orders->Region()->Location() + orders->Location(); - - SimRegion* active_region = ship->GetRegion(); - - if (active_region) - npt -= active_region->Location(); - - npt = npt.OtherHand(); - - obj_w = npt; - - if (qdrive && qdrive->ActiveState() == QuantumDrive::ACTIVE_READY) { - qdrive->SetDestination(nav_rgn, orders->Location()); - qdrive->Engage(); - return; - } - } - - // distance from self to navpt: - distance = Point(obj_w - ship->Location()).length(); - - if (farcaster) { - if (distance < 1000) { - farcaster = 0; - ship->ClearRadioOrders(); - } - } - else if (self_rgn == nav_rgn) { - ship->ClearRadioOrders(); - } - } -} - -void -ShipAI::FindObjectiveFarcaster(SimRegion* src_rgn, SimRegion* dst_rgn) -{ - if (!farcaster) { - ListIter s = src_rgn->Ships(); - while (++s && !farcaster) { - if (s->GetFarcaster()) { - const Ship* dest = s->GetFarcaster()->GetDest(); - if (dest && dest->GetRegion() == dst_rgn) { - farcaster = s->GetFarcaster(); - } - } - } - } - - if (farcaster) { - Point apt = farcaster->ApproachPoint(0); - Point npt = farcaster->StartPoint(); - double r1 = (ship->Location() - npt).length(); - - if (r1 > 50e3) { - obj_w = apt; - distance = r1; - } - - else { - double r2 = (ship->Location() - apt).length(); - double r3 = (npt - apt).length(); - - if (r1+r2 < 1.2*r3) { - obj_w = npt; - distance = r1; - } - else { - obj_w = apt; - distance = r2; - } - } - - objective = Transform(obj_w); - } -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::SetFormationDelta(const Point& point) -{ - formation_delta = point; -} - -void -ShipAI::FindObjectiveFormation() -{ - const double prediction = 5; - - // find the base position: - Element* elem = ship->GetElement(); - Ship* lead = elem->GetShip(1); - Ship* ward = ship->GetWard(); - - if (!lead || lead == ship) { - lead = ward; - - distance = (lead->Location() - self->Location()).length(); - if (distance < 30e3 && lead->Velocity().length() < 50) { - obj_w = self->Location() + lead->Heading() * 1e6; - distance = -1; - return; - } - } - - obj_w = lead->Location() + lead->Velocity() * prediction; - Matrix m; m.Rotate(0, 0, lead->CompassHeading() - PI); - Point fd = formation_delta * m; - obj_w += fd; - - // try to avoid smacking into the ground... - if (ship->IsAirborne()) { - if (ship->AltitudeAGL() < 3000 || lead->AltitudeAGL() < 3000) { - obj_w.y += 500; - } - } - - Point dst_w = self->Location() + self->Velocity() * prediction; - Point dlt_w = obj_w - dst_w; - - distance = dlt_w.length(); - - // get slot z distance: - dlt_w += ship->Location(); - slot_dist = Transform(dlt_w).z; - - Director* lead_dir = lead->GetDirector(); - if (lead_dir && (lead_dir->Type() == FIGHTER || lead_dir->Type() == STARSHIP)) { - ShipAI* lead_ai = (ShipAI*) lead_dir; - farcaster = lead_ai->GetFarcaster(); - } - else { - Instruction* navpt = elem->GetNextNavPoint(); - if (!navpt) { - farcaster = 0; - return; - } - - SimRegion* self_rgn = ship->GetRegion(); - SimRegion* nav_rgn = navpt->Region(); - QuantumDrive* qdrive = ship->GetQuantumDrive(); - - if (self_rgn && !nav_rgn) { - nav_rgn = self_rgn; - navpt->SetRegion(nav_rgn); - } - - bool use_farcaster = self_rgn != nav_rgn && - (navpt->Farcast() || - !qdrive || - !qdrive->IsPowerOn() || - qdrive->Status() < System::DEGRADED - ); - - if (use_farcaster) { - ListIter s = self_rgn->Ships(); - while (++s && !farcaster) { - if (s->GetFarcaster()) { - const Ship* dest = s->GetFarcaster()->GetDest(); - if (dest && dest->GetRegion() == nav_rgn) { - farcaster = s->GetFarcaster(); - } - } - } - } - else if (farcaster) { - if (farcaster->GetShip()->GetRegion() != self_rgn) - farcaster = farcaster->GetDest()->GetFarcaster(); - - obj_w = farcaster->EndPoint(); - distance = Point(obj_w - ship->Location()).length(); - - if (distance < 1000) - farcaster = 0; - } - } -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::Splash(const Ship* targ) -{ - if (splash_count > 6) - splash_count = 4; - - // call splash: - RadioTraffic::SendQuickMessage(ship, RadioMessage::SPLASH_1 + splash_count); - splash_count++; -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::SetTarget(SimObject* targ, System* sub) -{ - if (targ != target) { - bracket = false; - } - - SteerAI::SetTarget(targ, sub); -} - -void -ShipAI::DropTarget(double dtime) -{ - SetTarget(0); - drop_time = dtime; // seconds until we can re-acquire - - ship->DropTarget(); -} - -void -ShipAI::SetBracket(bool b) -{ - bracket = b; - identify = false; -} - -void -ShipAI::SetIdentify(bool i) -{ - identify = i; - bracket = false; -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::Navigator() -{ - accumulator.Clear(); - magnitude = 0; - - hold = false; - if ((ship->GetElement() && ship->GetElement()->GetHoldTime() > 0) || - (navpt && navpt->Status() == Instruction::COMPLETE && navpt->HoldTime() > 0)) - hold = true; - - ship->SetFLCSMode(Ship::FLCS_HELM); - - if (target) - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-target")); - else if (rumor) - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-rumor")); - else - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.none")); - - Accumulate(AvoidCollision()); - Accumulate(AvoidTerrain()); - - if (!hold) - Accumulate(SeekTarget()); - - HelmControl(); - ThrottleControl(); - FireControl(); - AdjustDefenses(); -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::HelmControl() -{ - double trans_x = 0; - double trans_y = 0; - double trans_z = 0; - - ship->SetHelmHeading(accumulator.yaw); - - if (fabs(accumulator.pitch) < 5*DEGREES || fabs(accumulator.pitch) > 45*DEGREES) { - trans_z = objective.y; - ship->SetHelmPitch(0); - } - - else { - ship->SetHelmPitch(accumulator.pitch); - } - - ship->SetTransX(trans_x); - ship->SetTransY(trans_y); - ship->SetTransZ(trans_z); - - ship->ExecFLCSFrame(); -} - -/***************************************** -** -** NOTE: -** No one is really using this method. -** It is overridden by both StarshipAI -** and FighterAI. -** -*****************************************/ - -void -ShipAI::ThrottleControl() -{ - if (navpt && !threat && !target) { // lead only, get speed from navpt - double speed = navpt->Speed(); - - if (speed > 0) - throttle = speed / ship->VelocityLimit() * 100; - else - throttle = 50; - } - - else if (patrol && !threat && !target) { // lead only, get speed from navpt - double speed = 200; - - if (distance > 5000) - speed = 500; - - if (ship->Velocity().length() > speed) - throttle = 0; - else - throttle = 50; - } - - else { - if (threat || target || element_index < 2) { // element lead - throttle = 100; - - if (!threat && !target) - throttle = 50; - - if (accumulator.brake > 0) { - throttle *= (1 - accumulator.brake); - } - } - - else { // wingman - Ship* lead = ship->GetElement()->GetShip(1); - double lv = lead->Velocity().length(); - double sv = ship->Velocity().length(); - double dv = lv-sv; - double dt = 0; - - if (dv > 0) dt = dv * 1e-2 * seconds; - else if (dv < 0) dt = dv * 1e-2 * seconds; - - throttle = old_throttle + dt; - } - } - - old_throttle = throttle; - ship->SetThrottle((int) throttle); -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::NavlightControl() -{ - Ship* leader = ship->GetLeader(); - - if (leader && leader != ship) { - bool navlight_enabled = false; - - if (leader->NavLights().size() > 0) - navlight_enabled = leader->NavLights().at(0)->IsEnabled(); - - for (int i = 0; i < ship->NavLights().size(); i++) { - if (navlight_enabled) - ship->NavLights().at(i)->Enable(); - else - ship->NavLights().at(i)->Disable(); - } - } -} - -// +--------------------------------------------------------------------+ - -Steer -ShipAI::AvoidTerrain() -{ - Steer avoid; - return avoid; -} - -// +--------------------------------------------------------------------+ - -Steer -ShipAI::AvoidCollision() -{ - Steer avoid; - - if (!ship || !ship->GetRegion() || !ship->GetRegion()->IsActive()) - return avoid; - - if (other && (other->Life() == 0 || other->Integrity() < 1)) { - other = 0; - last_avoid_time = 0; // check for a new obstacle immediately - } - - if (!other && Clock::GetInstance()->GameTime() - last_avoid_time < 500) - return avoid; - - brake = 0; - - // don't get closer than this: - double avoid_dist = 5 * self->Radius(); - - if (avoid_dist < 1e3) avoid_dist = 1e3; - else if (avoid_dist > 12e3) avoid_dist = 12e3; - - // find the soonest potential collision, - // ignore any that occur after this: - double avoid_time = 15; - - if (ship->Design()->avoid_time > 0) - avoid_time = ship->Design()->avoid_time; - else if (ship->IsStarship()) - avoid_time *= 1.5; - - Point bearing = self->Velocity(); - bearing.Normalize(); - - bool found = false; - int num_contacts = ship->NumContacts(); - ListIter contact = ship->ContactList(); - - // check current obstacle first: - if (other) { - found = AvoidTestSingleObject(other, bearing, avoid_dist, avoid_time, avoid); - } - - if (!found) { - // avoid ships: - while (++contact && !found) { - Ship* c_ship = contact->GetShip(); - - if (c_ship && c_ship != ship && c_ship->IsStarship()) { - found = AvoidTestSingleObject(c_ship, bearing, avoid_dist, avoid_time, avoid); - } - } - - // also avoid large pieces of debris: - if (!found) { - ListIter iter = ship->GetRegion()->Rocks(); - while (++iter && !found) { - Debris* debris = iter.value(); - - if (debris->Mass() > ship->Mass()) - found = AvoidTestSingleObject(debris, bearing, avoid_dist, avoid_time, avoid); - } - } - - // and asteroids: - if (!found) { - // give asteroids a wider berth - - avoid_dist *= 8; - - ListIter iter = ship->GetRegion()->Roids(); - while (++iter && !found) { - Asteroid* roid = iter.value(); - found = AvoidTestSingleObject(roid, bearing, avoid_dist, avoid_time, avoid); - } - - if (!found) - avoid_dist /= 8; - } - - // if found, steer to avoid: - if (other) { - avoid = Avoid(obstacle, (float) (ship->Radius() + other->Radius() + avoid_dist * 0.9)); - avoid.brake = brake; - - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.avoid-collision")); - } - } - - last_avoid_time = Clock::GetInstance()->GameTime(); - return avoid; -} - -bool -ShipAI::AvoidTestSingleObject(SimObject* obj, -const Point& bearing, -double avoid_dist, -double& avoid_time, -Steer& avoid) -{ - if (too_close == obj->Identity()) { - double dist = (ship->Location() - obj->Location()).length(); - double closure = (ship->Velocity() - obj->Velocity()) * bearing; - - if (closure > 1 && dist < avoid_dist) { - avoid = AvoidCloseObject(obj); - return true; - } - else { - too_close = 0; - } - } - - // will we get close? - double time = ClosestApproachTime(ship->Location(), ship->Velocity(), - obj->Location(), obj->Velocity()); - - // already past the obstacle: - if (time <= 0) { - if (other == obj) other = 0; - return false; - } - - // how quickly could we collide? - Point current_relation = ship->Location() - obj->Location(); - double current_distance = current_relation.length() - ship->Radius() - obj->Radius(); - - // are we really far away? - if (current_distance > 25e3) { - if (other == obj) other = 0; - return false; - } - - // is the obstacle a farcaster? - if (obj->Type() == SimObject::SIM_SHIP) { - Ship* c_ship = (Ship*) obj; - - if (c_ship->GetFarcaster()) { - // are we on a safe vector? - Point dir = ship->Velocity(); - dir.Normalize(); - - double angle_off = fabs(acos(dir * obj->Cam().vpn())); - - if (angle_off > 90*DEGREES) - angle_off = 180*DEGREES - angle_off; - - if (angle_off < 35*DEGREES) { - // will we pass through the center? - Point d = ship->Location() + dir * (current_distance + ship->Radius() + obj->Radius()); - double err = (obj->Location() - d).length(); - - if (err < 0.667 * obj->Radius()) { - return false; - } - } - } - } - - // rate of closure: - double closing_velocity = (ship->Velocity() - obj->Velocity()) * bearing; - - // are we too close already? - if (current_distance < (avoid_dist * 0.35)) { - if (closing_velocity > 1 || current_distance < ship->Radius()) { - avoid = AvoidCloseObject(obj); - return true; - } - } - - // too far away to worry about: - double separation = (avoid_dist + obj->Radius()); - if ((current_distance-separation) / closing_velocity > avoid_time) { - if (other == obj) other = 0; - return false; - } - - // where will we be? - Point selfpt = ship->Location() + ship->Velocity() * time; - Point testpt = obj->Location() + obj->Velocity() * time; - - // how close will we get? - double dist = (selfpt - testpt).length() - - ship->Radius() - - obj->Radius(); - - // that's too close: - if (dist < avoid_dist) { - if (dist < avoid_dist * 0.25 && time < avoid_time * 0.5) { - avoid = AvoidCloseObject(obj); - return true; - } - - obstacle = Transform(testpt); - - if (obstacle.z > 0) { - other = obj; - avoid_time = time; - brake = 0.5; - - Observe(other); - } - } - - // hysteresis: - else if (other == obj && dist > avoid_dist * 1.25) { - other = 0; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -Steer -ShipAI::AvoidCloseObject(SimObject* obj) -{ - too_close = obj->Identity(); - obstacle = Transform(obj->Location()); - other = obj; - - Observe(other); - - Steer avoid = Flee(obstacle); - avoid.brake = 0.3; - - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.avoid-collision")); - return avoid; -} - -// +--------------------------------------------------------------------+ - -Steer -ShipAI::SeekTarget() -{ - Ship* ward = ship->GetWard(); - - if (!target && !ward && !navpt && !patrol) { - if (element_index > 1) { - // wingmen keep in formation: - return Seek(objective); - } - - if (farcaster) { - return Seek(objective); - } - - if (rumor) { - return Seek(objective); - } - - return Steer(); - } - - if (patrol) { - Steer result = Seek(objective); - - if (distance < 2000) { - result.brake = 1; - } - - return result; - } - - if (target && too_close == target->Identity()) { - drop_time = 4; - return Avoid(objective, 0.0f); - } - else if (drop_time > 0) { - return Steer(); - } - - return Seek(objective); -} - -// +--------------------------------------------------------------------+ - -Steer -ShipAI::EvadeThreat() -{ - return Steer(); -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::FireControl() -{ -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::AdjustDefenses() -{ - Shield* shield = ship->GetShield(); - - if (shield) { - double desire = 50; - - if (threat_missile || threat) - desire = 100; - - shield->SetPowerLevel(desire); - } -} - -// +--------------------------------------------------------------------+ - -void -ShipAI::CheckTarget() -{ - if (target) { - if (target->Life() == 0) - target = 0; - - else if (target->Type() == SimObject::SIM_SHIP) { - Ship* tgt_ship = (Ship*) target; - - if (tgt_ship->GetIFF() == ship->GetIFF() && !tgt_ship->IsRogue()) - target = 0; - } - } -} diff --git a/Stars45/ShipAI.h b/Stars45/ShipAI.h deleted file mode 100644 index 610a5a9..0000000 --- a/Stars45/ShipAI.h +++ /dev/null @@ -1,152 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Common base class and interface for low-level ship AI -*/ - -#ifndef ShipAI_h -#define ShipAI_h - -#include "Types.h" -#include "SteerAI.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class Shot; -class Instruction; -class TacticalAI; -class Farcaster; - -// +--------------------------------------------------------------------+ - -class ShipAI : public SteerAI -{ -public: - ShipAI(SimObject* s); - virtual ~ShipAI(); - - virtual void ExecFrame(double seconds); - virtual int Subframe() const { return true; } - - virtual Ship* GetShip() const { return ship; } - - virtual Ship* GetWard() const; - virtual void SetWard(Ship* s); - virtual Ship* GetThreat() const { return threat; } - virtual void SetThreat(Ship* s); - virtual Ship* GetSupport() const { return support; } - virtual void SetSupport(Ship* s); - virtual Ship* GetRumor() const { return rumor; } - virtual void SetRumor(Ship* s); - virtual Shot* GetThreatMissile() const { return threat_missile; } - virtual void SetThreatMissile(Shot* s); - virtual Instruction* GetNavPoint() const { return navpt; } - virtual void SetNavPoint(Instruction* n) { navpt = n; } - virtual Point GetPatrol() const; - virtual void SetPatrol(const Point& p); - virtual void ClearPatrol(); - virtual void ClearRumor(); - virtual void ClearTactical(); - - virtual Farcaster* GetFarcaster() { return farcaster; } - - // convert the goal point from world to local coords: - virtual void FindObjective(); - - virtual void Splash(const Ship* targ); - virtual void SetTarget(SimObject* targ, System* sub=0); - virtual void DropTarget(double drop_time=1.5); - virtual double DropTime() const { return drop_time; } - virtual void SetBracket(bool bracket); - virtual void SetIdentify(bool identify); - - virtual void SetFormationDelta(const Point& point); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - virtual int GetAILevel() const { return ai_level; } - -protected: - // accumulate behaviors: - virtual void Navigator(); - - // behaviors: - virtual bool AvoidTestSingleObject(SimObject* obj, - const Point& bearing, - double avoid_dist, - double& avoid_time, - Steer& steer); - - virtual Steer AvoidCloseObject(SimObject* obj); - virtual Steer AvoidCollision(); - virtual Steer AvoidTerrain(); - virtual Steer SeekTarget(); - virtual Steer EvadeThreat(); - - virtual Point ClosingVelocity(); - - // compute the goal point in world coords based on current ai state: - virtual void FindObjectiveTarget(SimObject* tgt); - virtual void FindObjectiveNavPoint(); - virtual void FindObjectiveFormation(); - virtual void FindObjectivePatrol(); - virtual void FindObjectiveQuantum(); - virtual void FindObjectiveFarcaster(SimRegion* src, SimRegion* dst); - - // fire on target if appropriate: - virtual void AdjustDefenses(); - virtual void FireControl(); - virtual void HelmControl(); - virtual void ThrottleControl(); - virtual void NavlightControl(); - - virtual void CheckTarget(); - - Ship* ship; - Ship* support; - Ship* rumor; - Ship* threat; - Shot* threat_missile; - Instruction* navpt; - Point obstacle; - TacticalAI* tactical; - Farcaster* farcaster; - int engaged_ship_id; - int splash_count; - - Point formation_delta; - double slot_dist; - - double throttle; - double old_throttle; - double seconds; - double drop_time; - double brake; - DWORD last_avoid_time; - DWORD last_call_time; - - int element_index; - int too_close; - bool bracket; - bool identify; - bool hold; - bool takeoff; - - int patrol; - Point patrol_loc; - int ai_level; -}; - -// +--------------------------------------------------------------------+ - -#endif // ShipAI_h - diff --git a/Stars45/ShipCtrl.cpp b/Stars45/ShipCtrl.cpp deleted file mode 100644 index d1fd00e..0000000 --- a/Stars45/ShipCtrl.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Ship Controller class -*/ - -#include "ShipCtrl.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Shield.h" -#include "Sensor.h" -#include "NavSystem.h" -#include "FlightComp.h" -#include "LandingGear.h" -#include "Sim.h" -#include "StarSystem.h" -#include "Starshatter.h" -#include "HUDView.h" -#include "HUDSounds.h" -#include "KeyMap.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" - -#include "MouseController.h" -#include "Keyboard.h" -#include "Joystick.h" -#include "Clock.h" -#include "DataLoader.h" - -// +--------------------------------------------------------------------+ - -ShipCtrl::ShipCtrl(Ship* s, MotionController* ctrl) -: ship(s), controller(ctrl), throttle_active(false), launch_latch(false), -pickle_latch(false), target_latch(false) -{ - for (int i = 0; i < 10; i++) - GetAsyncKeyState('0'+i); -} - -// +--------------------------------------------------------------------+ - -int -ShipCtrl::KeyDown(int action) -{ - int k = Joystick::KeyDownMap(action) || - Keyboard::KeyDownMap(action); - - return k; -} - -int -ShipCtrl::Toggled(int action) -{ - static double last_toggle_time = 0; - - if (KeyDown(action)) { - if ((Clock::GetInstance()->RealTime() - last_toggle_time) > 250) { - last_toggle_time = Clock::GetInstance()->RealTime(); - return 1; - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -ShipCtrl::Launch() -{ - if (controller) { - ship->SetThrottle(100); - throttle_active = false; - launch_latch = true; - } -} - -// +--------------------------------------------------------------------+ - -void -ShipCtrl::ExecFrame(double seconds) -{ - Starshatter* stars = Starshatter::GetInstance(); - if (stars && stars->GetChatMode()) return; - if (!ship) return; - - const int DELTA_THROTTLE = 5; - - controller->Acquire(); - - if (ship->IsStarship() && ship->GetFLCSMode() == Ship::FLCS_HELM) { - ship->ApplyHelmPitch(controller->Pitch() * seconds); - ship->ApplyHelmYaw(controller->Yaw() * seconds); - } - else { - ship->ApplyRoll(controller->Roll()); - ship->ApplyPitch(controller->Pitch()); - ship->ApplyYaw(controller->Yaw()); - } - - ship->SetTransX(controller->X() * ship->Design()->trans_x); - ship->SetTransY(controller->Y() * ship->Design()->trans_y); - ship->SetTransZ(controller->Z() * ship->Design()->trans_z); - - bool augmenter = false; - - if (controller->Throttle() > 0.05) { - if (throttle_active) { - ship->SetThrottle(controller->Throttle() * 100); - - if (controller->Throttle() >= 0.99) - augmenter = true; - } - else if (!launch_latch || controller->Throttle() > 0.5) { - throttle_active = true; - launch_latch = false; - } - } - else if (throttle_active) { - ship->SetThrottle(0); - throttle_active = false; - } - - ship->ExecFLCSFrame(); - - static double time_til_change = 0.0; - - if (time_til_change < 0.001) { - if (KeyDown(KEY_THROTTLE_UP)) { - ship->SetThrottle(ship->Throttle() + DELTA_THROTTLE); - time_til_change = 0.05; - } - - else if (KeyDown(KEY_THROTTLE_DOWN)) { - ship->SetThrottle(ship->Throttle() - DELTA_THROTTLE); - time_til_change = 0.05; - } - - else if (KeyDown(KEY_THROTTLE_ZERO)) { - ship->SetThrottle(0); - if (ship->GetFLCS()) - ship->GetFLCS()->FullStop(); - time_til_change = 0.05; - } - - else if (KeyDown(KEY_THROTTLE_FULL)) { - ship->SetThrottle(100); - time_til_change = 0.05; - } - - else if (KeyDown(KEY_FLCS_MODE_AUTO)) { - ship->CycleFLCSMode(); - time_til_change = 0.5f; - } - - else if (KeyDown(KEY_CYCLE_PRIMARY)) { - HUDSounds::PlaySound(HUDSounds::SND_WEP_MODE); - ship->CyclePrimary(); - time_til_change = 0.5f; - } - - else if (KeyDown(KEY_CYCLE_SECONDARY)) { - HUDSounds::PlaySound(HUDSounds::SND_WEP_MODE); - ship->CycleSecondary(); - time_til_change = 0.5f; - } - - if (ship->GetShield()) { - Shield* shield = ship->GetShield(); - double level = shield->GetPowerLevel(); - - if (KeyDown(KEY_SHIELDS_FULL)) { - HUDSounds::PlaySound(HUDSounds::SND_SHIELD_LEVEL); - shield->SetPowerLevel(100); - time_til_change = 0.5f; - } - - else if (KeyDown(KEY_SHIELDS_ZERO)) { - HUDSounds::PlaySound(HUDSounds::SND_SHIELD_LEVEL); - shield->SetPowerLevel(0); - time_til_change = 0.5f; - } - - else if (KeyDown(KEY_SHIELDS_UP)) { - if (level < 25) level = 25; - else if (level < 50) level = 50; - else if (level < 75) level = 75; - else level = 100; - - HUDSounds::PlaySound(HUDSounds::SND_SHIELD_LEVEL); - shield->SetPowerLevel(level); - time_til_change = 0.5f; - } - - else if (KeyDown(KEY_SHIELDS_DOWN)) { - if (level > 75) level = 75; - else if (level > 50) level = 50; - else if (level > 25) level = 25; - else level = 0; - - HUDSounds::PlaySound(HUDSounds::SND_SHIELD_LEVEL); - shield->SetPowerLevel(level); - time_til_change = 0.5f; - } - - } - - if (ship->GetSensor()) { - Sensor* sensor = ship->GetSensor(); - - if (sensor->GetMode() < Sensor::PST) { - if (KeyDown(KEY_SENSOR_MODE)) { - int sensor_mode = sensor->GetMode() + 1; - if (sensor_mode > Sensor::GM) - sensor_mode = Sensor::PAS; - - sensor->SetMode((Sensor::Mode) sensor_mode); - time_til_change = 0.5f; - } - - else if (KeyDown(KEY_SENSOR_GROUND_MODE)) { - if (ship->IsAirborne()) { - sensor->SetMode(Sensor::GM); - time_til_change = 0.5f; - } - } - } - else { - // manual "return to search" command for starships: - if (KeyDown(KEY_SENSOR_MODE)) { - ship->DropTarget(); - } - } - - if (KeyDown(KEY_SENSOR_RANGE_PLUS)) { - sensor->IncreaseRange(); - time_til_change = 0.5f; - } - - else if (KeyDown(KEY_SENSOR_RANGE_MINUS)) { - sensor->DecreaseRange(); - time_til_change = 0.5f; - } - } - - if (KeyDown(KEY_EMCON_PLUS)) { - ship->SetEMCON(ship->GetEMCON()+1); - time_til_change = 0.5f; - } - - else if (KeyDown(KEY_EMCON_MINUS)) { - ship->SetEMCON(ship->GetEMCON()-1); - time_til_change = 0.5f; - } - } - else - time_til_change -= seconds; - - if (controller->ActionMap(KEY_ACTION_0)) - ship->FirePrimary(); - - if (controller->ActionMap(KEY_ACTION_1)) { - if (!pickle_latch) - ship->FireSecondary(); - - pickle_latch = true; - } - else { - pickle_latch = false; - } - - if (controller->ActionMap(KEY_ACTION_3)) { - if (!target_latch) - ship->LockTarget(SimObject::SIM_SHIP); - - target_latch = true; - } - else { - target_latch = false; - } - - ship->SetAugmenter(augmenter || (KeyDown(KEY_AUGMENTER) ? true : false)); - - if (Toggled(KEY_DECOY)) - ship->FireDecoy(); - - if (Toggled(KEY_LAUNCH_PROBE)) - ship->LaunchProbe(); - - if (Toggled(KEY_GEAR_TOGGLE)) - ship->ToggleGear(); - - if (Toggled(KEY_NAVLIGHT_TOGGLE)) - ship->ToggleNavlights(); - - if (Toggled(KEY_LOCK_TARGET)) - ship->LockTarget(SimObject::SIM_SHIP, false, true); - - else if (Toggled(KEY_LOCK_THREAT)) - ship->LockTarget(SimObject::SIM_DRONE); - - else if (Toggled(KEY_LOCK_CLOSEST_SHIP)) - ship->LockTarget(SimObject::SIM_SHIP, true, false); - - else if (Toggled(KEY_LOCK_CLOSEST_THREAT)) - ship->LockTarget(SimObject::SIM_DRONE, true, false); - - else if (Toggled(KEY_LOCK_HOSTILE_SHIP)) - ship->LockTarget(SimObject::SIM_SHIP, true, true); - - else if (Toggled(KEY_LOCK_HOSTILE_THREAT)) - ship->LockTarget(SimObject::SIM_DRONE, true, true); - - else if (Toggled(KEY_CYCLE_SUBTARGET)) - ship->CycleSubTarget(1); - - else if (Toggled(KEY_PREV_SUBTARGET)) - ship->CycleSubTarget(-1); - - if (Toggled(KEY_AUTO_NAV)) { - ship->SetAutoNav(true); - // careful: this object has just been deleted! - return; - } - - if (Toggled(KEY_DROP_ORBIT)) { - ship->DropOrbit(); - // careful: this object has just been deleted! - return; - } -} - diff --git a/Stars45/ShipCtrl.h b/Stars45/ShipCtrl.h deleted file mode 100644 index 69391ae..0000000 --- a/Stars45/ShipCtrl.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Starship (or space/ground station) class -*/ - -#ifndef ShipCtrl_h -#define ShipCtrl_h - -#include "Types.h" -#include "SimObject.h" -#include "MotionController.h" -#include "Director.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class ShipDesign; -class KeyMap; - -// +--------------------------------------------------------------------+ - -class ShipCtrl : public Director -{ -public: - enum TYPE { DIR_TYPE = 1 }; - - ShipCtrl(Ship* s, MotionController* m); - - virtual void ExecFrame(double seconds); - virtual int Subframe() const { return true; } - virtual void Launch(); - - static int KeyDown(int action); - static int Toggled(int action); - - virtual int Type() const { return DIR_TYPE; } - -protected: - Ship* ship; - MotionController* controller; - - bool throttle_active; - bool launch_latch; - bool pickle_latch; - bool target_latch; -}; - -#endif // ShipCtrl_h - diff --git a/Stars45/ShipDesign.cpp b/Stars45/ShipDesign.cpp deleted file mode 100644 index cda8013..0000000 --- a/Stars45/ShipDesign.cpp +++ /dev/null @@ -1,3702 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Starship Design parameters class -*/ - -#include "ShipDesign.h" -#include "Ship.h" -#include "Shot.h" -#include "Power.h" -#include "HardPoint.h" -#include "Weapon.h" -#include "WeaponDesign.h" -#include "Shield.h" -#include "Sensor.h" -#include "NavLight.h" -#include "NavSystem.h" -#include "Drive.h" -#include "QuantumDrive.h" -#include "Farcaster.h" -#include "Thruster.h" -#include "FlightDeck.h" -#include "LandingGear.h" -#include "Computer.h" -#include "SystemDesign.h" -#include "Component.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Solid.h" -#include "Skin.h" -#include "Sprite.h" -#include "Light.h" -#include "Bitmap.h" -#include "Sound.h" -#include "DataLoader.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ - -const char* ship_design_class_name[32] = { - "Drone", "Fighter", - "Attack", "LCA", - "Courier", "Cargo", - "Corvette", "Freighter", - - "Frigate", "Destroyer", - "Cruiser", "Battleship", - "Carrier", "Dreadnaught", - - "Station", "Farcaster", - - "Mine", "DEFSAT", - "COMSAT", "SWACS", - - "Building", "Factory", - "SAM", "EWR", - "C3I", "Starbase", - - "0x04000000", "0x08000000", - "0x10000000", "0x20000000", - "0x40000000", "0x80000000" -}; - -// +--------------------------------------------------------------------+ - -static const int NAMELEN = 64; -static bool degrees = false; - -struct ShipCatalogEntry { - static const char* TYPENAME() { return "ShipCatalogEntry"; } - - ShipCatalogEntry() : hide(false), design(0) {} - - ShipCatalogEntry(const char* n, const char* t, const char* p, const char* f, bool h=false) : - name(n), type(t), path(p), file(f), hide(h), design(0) {} - - ~ShipCatalogEntry() { delete design; } - - Text name; - Text type; - Text path; - Text file; - bool hide; - - ShipDesign* design; -}; - -static List catalog; -static List mod_catalog; - -// +--------------------------------------------------------------------+ - -#define GET_DEF_BOOL(n) if (defname==(#n)) GetDefBool((n), def, filename) -#define GET_DEF_TEXT(n) if (defname==(#n)) GetDefText((n), def, filename) -#define GET_DEF_NUM(n) if (defname==(#n)) GetDefNumber((n), def, filename) -#define GET_DEF_VEC(n) if (defname==(#n)) GetDefVec((n), def, filename) - -static char cockpit_name[80]; -static List detail[4]; -static List offset[4]; - -static char errmsg[256]; - -// +--------------------------------------------------------------------+ - -ShipLoad::ShipLoad() -{ - ZeroMemory(name, sizeof(name)); - ZeroMemory(load, sizeof(load)); - mass = 0; -} - -ShipSquadron::ShipSquadron() -{ - name[0] = 0; - design = 0; - count = 4; - avail = 4; -} - -static void PrepareModel(Model& model) -{ - bool uses_bumps = false; - - ListIter iter = model.GetMaterials(); - while (++iter && !uses_bumps) { - Material* mtl = iter.value(); - if (mtl->tex_bumpmap != 0 && mtl->bump != 0) - uses_bumps = true; - } - - if (uses_bumps) - model.ComputeTangents(); -} - -// +--------------------------------------------------------------------+ - -ShipDesign::ShipDesign() -: sensor(0), navsys(0), shield(0), type(0), decoy(0), -probe(0), gear(0), valid(false), secret(false), auto_roll(1), cockpit_model(0), -bolt_hit_sound_resource(0), beam_hit_sound_resource(0), lod_levels(0) -{ - ZeroMemory(filename, sizeof(filename)); - ZeroMemory(path_name, sizeof(path_name)); - ZeroMemory(name, sizeof(name)); - ZeroMemory(display_name, sizeof(display_name)); - ZeroMemory(abrv, sizeof(abrv)); - - for (int i = 0; i < 4; i++) - feature_size[i] = 0.0f; -} - -// +--------------------------------------------------------------------+ - -ShipDesign::ShipDesign(const char* n, const char* p, const char* fname, bool s) -: sensor(0), navsys(0), shield(0), type(0), -quantum_drive(0), farcaster(0), thruster(0), shield_model(0), decoy(0), -probe(0), gear(0), valid(false), secret(s), auto_roll(1), cockpit_model(0), -bolt_hit_sound_resource(0), beam_hit_sound_resource(0), lod_levels(0) -{ - ZeroMemory(filename, sizeof(filename)); - ZeroMemory(path_name, sizeof(path_name)); - ZeroMemory(name, sizeof(name)); - ZeroMemory(display_name, sizeof(display_name)); - ZeroMemory(abrv, sizeof(abrv)); - - strcpy_s(name, n); - - if (!strstr(fname, ".def")) - sprintf_s(filename, "%s.def", fname); - else - strcpy_s(filename, fname); - - for (int i = 0; i < 4; i++) - feature_size[i] = 0.0f; - - scale = 1.0f; - - agility = 2e2f; - air_factor = 0.1f; - vlimit = 8e3f; - drag = 2.5e-5f; - arcade_drag = 1.0f; - roll_drag = 5.0f; - pitch_drag = 5.0f; - yaw_drag = 5.0f; - - roll_rate = 0.0f; - pitch_rate = 0.0f; - yaw_rate = 0.0f; - - trans_x = 0.0f; - trans_y = 0.0f; - trans_z = 0.0f; - - turn_bank = (float) (PI/8); - - CL = 0.0f; - CD = 0.0f; - stall = 0.0f; - - prep_time = 30.0f; - avoid_time = 0.0f; - avoid_fighter = 0.0f; - avoid_strike = 0.0f; - avoid_target = 0.0f; - commit_range = 0.0f; - - splash_radius = -1.0f; - scuttle = 5e3f; - repair_speed = 1.0f; - repair_teams = 2; - repair_auto = true; - repair_screen = true; - wep_screen = true; - - chase_vec = Vec3(0, -100, 20); - bridge_vec = Vec3(0, 0, 0); - beauty_cam = Vec3(0, 0, 0); - cockpit_scale = 1.0f; - - radius = 1.0f; - integrity = 500.0f; - - primary = 0; - secondary = 1; - main_drive = -1; - - pcs = 3.0f; - acs = 1.0f; - detet = 250.0e3f; - e_factor[0] = 0.1f; - e_factor[1] = 0.3f; - e_factor[2] = 1.0f; - - explosion_scale = 0.0f; - death_spiral_time = 3.0f; - - if (!secret) - Print("Loading ShipDesign '%s'\n", name); - - strcpy_s(path_name, p); - if (path_name[strlen(path_name)-1] != '/') - strcat_s(path_name, "/"); - - // Load Design File: - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(path_name); - - BYTE* block; - int blocklen = loader->LoadBuffer(filename, block, true); - - // file not found: - if (blocklen <= 4) { - valid = false; - return; - } - - Parser parser(new BlockReader((const char*) block, blocklen)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'\n", filename); - valid = false; - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "SHIP") { - Print("ERROR: invalid ship design file '%s'\n", filename); - valid = false; - return; - } - } - - cockpit_name[0] = 0; - valid = true; - degrees = false; - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - ParseShip(def); - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - } - } - } - while (term); - - for (int i = 0; i < 4; i++) { - int n = 0; - ListIter iter = detail[i]; - while (++iter) { - const char* model_name = iter.value()->data(); - - Model* model = new Model; - if (!model->Load(model_name, scale)) { - Print("ERROR: Could not load detail %d, model '%s'\n", i, model_name); - delete model; - model = 0; - valid = false; - } - - else { - lod_levels = i+1; - - if (model->Radius() > radius) - radius = (float) model->Radius(); - - models[i].append(model); - PrepareModel(*model); - - if (offset[i].size()) { - *offset[i].at(n) *= scale; - offsets[i].append(offset[i].at(n)); // transfer ownership - } - else - offsets[i].append(new Point); - - n++; - } - } - - detail[i].destroy(); - } - - if (!secret) - Print(" Ship Design Radius = %f\n", radius); - - if (cockpit_name[0]) { - const char* model_name = cockpit_name; - - cockpit_model = new Model; - if (!cockpit_model->Load(model_name, cockpit_scale)) { - Print("ERROR: Could not load cockpit model '%s'\n", model_name); - delete cockpit_model; - cockpit_model = 0; - } - else { - if (!secret) - Print(" Loaded cockpit model '%s', preparing tangents\n", model_name); - PrepareModel(*cockpit_model); - } - } - - if (beauty.Width() < 1 && loader->FindFile("beauty.pcx")) - loader->LoadBitmap("beauty.pcx", beauty); - - if (hud_icon.Width() < 1 && loader->FindFile("hud_icon.pcx")) - loader->LoadBitmap("hud_icon.pcx", hud_icon); - - loader->ReleaseBuffer(block); - loader->SetDataPath(0); - - if (abrv[0] == 0) { - switch (type) { - case Ship::DRONE: strcpy_s(abrv, "DR"); break; - case Ship::FIGHTER: strcpy_s(abrv, "F"); break; - case Ship::ATTACK: strcpy_s(abrv, "F/A"); break; - case Ship::LCA: strcpy_s(abrv, "LCA"); break; - case Ship::CORVETTE: strcpy_s(abrv, "FC"); break; - case Ship::COURIER: - case Ship::CARGO: - case Ship::FREIGHTER: strcpy_s(abrv, "MV"); break; - case Ship::FRIGATE: strcpy_s(abrv, "FF"); break; - case Ship::DESTROYER: strcpy_s(abrv, "DD"); break; - case Ship::CRUISER: strcpy_s(abrv, "CA"); break; - case Ship::BATTLESHIP: strcpy_s(abrv, "BB"); break; - case Ship::CARRIER: strcpy_s(abrv, "CV"); break; - case Ship::DREADNAUGHT: strcpy_s(abrv, "DN"); break; - case Ship::MINE: strcpy_s(abrv, "MINE"); break; - case Ship::COMSAT: strcpy_s(abrv, "COMS"); break; - case Ship::DEFSAT: strcpy_s(abrv, "DEFS"); break; - case Ship::SWACS: strcpy_s(abrv, "SWAC"); break; - default: break; - } - } - - if (scuttle < 1) - scuttle = 1; - - if (splash_radius < 0) - splash_radius = radius * 12.0f; - - if (repair_speed <= 1e-6) - repair_speed = 1.0e-6f; - - if (commit_range <= 0) { - if (type <= Ship::LCA) - commit_range = 80.0e3f; - else - commit_range = 200.0e3f; - } - - // calc standard loadout weights: - ListIter sl = loadouts; - while (++sl) { - for (int i = 0; i < hard_points.size(); i++) { - HardPoint* hp = hard_points[i]; - sl->mass += hp->GetCarryMass(sl->load[i]); - } - } -} - -// +--------------------------------------------------------------------+ - -ShipDesign::~ShipDesign() -{ - delete bolt_hit_sound_resource; - delete beam_hit_sound_resource; - delete cockpit_model; - delete navsys; - delete sensor; - delete shield; - delete thruster; - delete farcaster; - delete quantum_drive; - delete decoy; - delete probe; - delete gear; - - navlights.destroy(); - flight_decks.destroy(); - hard_points.destroy(); - computers.destroy(); - weapons.destroy(); - drives.destroy(); - reactors.destroy(); - loadouts.destroy(); - map_sprites.destroy(); - - delete shield_model; - for (int i = 0; i < 4; i++) { - models[i].destroy(); - offsets[i].destroy(); - } - - spin_rates.destroy(); - - for (int i = 0; i < 10; i++) { - delete debris[i].model; - } -} - -const char* -ShipDesign::DisplayName() const -{ - if (display_name[0]) - return display_name; - - return name; -} - -// +--------------------------------------------------------------------+ - -void AddModCatalogEntry(const char* design_name, const char* design_path) -{ - if (!design_name || !*design_name) - return; - - ShipCatalogEntry* entry = 0; - - for (int i = 0; i < catalog.size(); i++) { - ShipCatalogEntry* e = catalog[i]; - if (e->name == design_name) { - if (design_path && *design_path && e->path != design_path) - continue; - entry = e; - return; - } - } - - for (int i = 0; i < mod_catalog.size(); i++) { - ShipCatalogEntry* e = mod_catalog[i]; - if (e->name == design_name) { - if (design_path && *design_path) { - Text full_path = "Mods/Ships/"; - full_path += design_path; - - if (e->path != full_path) - continue; - } - - entry = e; - return; - } - } - - // still here? not found yet: - Text file = Text(design_name) + ".def"; - Text path = Text("Mods/Ships/"); - Text name; - Text type; - bool valid = false; - - if (design_path && *design_path) - path += design_path; - else - path += design_name; - - path += "/"; - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(path); - - BYTE* block; - int blocklen = loader->LoadBuffer(file, block, true); - - // file not found: - if (blocklen <= 4) { - return; - } - - Parser parser(new BlockReader((const char*) block, blocklen)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'\n", file.data()); - delete block; - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "SHIP") { - Print("ERROR: invalid ship design file '%s'\n", file.data()); - delete block; - return; - } - } - - valid = true; - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - Text defname = def->name()->value(); - defname.setSensitive(false); - - if (defname == "class") { - if (!GetDefText(type, def, file)) { - Print("WARNING: invalid or missing ship class in '%s'\n", file.data()); - valid = false; - } - } - - else if (defname == "name") { - if (!GetDefText(name, def, file)) { - Print("WARNING: invalid or missing ship name in '%s'\n", file.data()); - valid = false; - } - } - } - else { - Print("WARNING: term ignored in '%s'\n", file.data()); - term->print(); - } - } - } - while (term && valid && (name.length() < 1 || type.length() < 1)); - - delete block; - - if (valid && name.length() && type.length()) { - Print("Add Mod Catalog Entry '%s' Class '%s'\n", name.data(), type.data()); - - ShipCatalogEntry* entry = new ShipCatalogEntry(name, type, path, file); - mod_catalog.append(entry); - } -} - -void -ShipDesign::Initialize() -{ - if (catalog.size()) return; - - LoadCatalog("Ships/", "catalog.def"); - LoadSkins("Mods/Skins/"); - - List mod_designs; - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath("Mods/Ships/"); - loader->ListFiles("*.def", mod_designs, true); - - for (int i = 0; i < mod_designs.size(); i++) { - Text full_name = *mod_designs[i]; - full_name.setSensitive(false); - - if (full_name.contains('/') && !full_name.contains("catalog")) { - char path[1024]; - strcpy_s(path, full_name.data()); - - char* name = path + full_name.length(); - while (*name != '/') - name--; - - *name++ = 0; - - char* p = strrchr(name, '.'); - if (p && strlen(p) > 3) { - if ((p[1] == 'd' || p[1] == 'D') && - (p[2] == 'e' || p[2] == 'E') && - (p[3] == 'f' || p[3] == 'F')) { - - *p = 0; - } - } - - // Just do a quick parse of the def file and add the - // info to the catalog. DON'T preload all of the models, - // textures, and weapons at this time. That takes way - // too long with some of the larger user mods. - - AddModCatalogEntry(name, path); - } - } - - mod_designs.destroy(); - loader->SetDataPath(0); -} - -void -ShipDesign::Close() -{ - mod_catalog.destroy(); - catalog.destroy(); -} - -// +--------------------------------------------------------------------+ - -int -ShipDesign::LoadCatalog(const char* path, const char* fname, bool mod) -{ - int result = 0; - - // Load Design Catalog File: - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(path); - - char filename[NAMELEN]; - ZeroMemory(filename, NAMELEN); - strncpy(filename, fname, NAMELEN-1); - - Print("Loading ship design catalog: %s%s\n", path, filename); - - BYTE* block; - int blocklen = loader->LoadBuffer(filename, block, true); - Parser parser(new BlockReader((const char*) block, blocklen)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'\n", filename); - loader->ReleaseBuffer(block); - loader->SetDataPath(0); - return result; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "SHIPCATALOG") { - Print("ERROR: invalid ship catalog file '%s'\n", filename); - loader->ReleaseBuffer(block); - loader->SetDataPath(0); - return result; - } - } - - do { - delete term; - - term = parser.ParseTerm(); - - Text name, type, fname, path; - bool hide = false; - - if (term) { - TermDef* def = term->isDef(); - if (def && def->term() && def->term()->isStruct()) { - TermStruct* val = def->term()->isStruct(); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") { - if (!GetDefText(name, pdef, filename)) - Print("WARNING: invalid or missing ship name in '%s'\n", filename); - } - else if (defname == "type") { - if (!GetDefText(type, pdef, filename)) - Print("WARNING: invalid or missing ship type in '%s'\n", filename); - } - else if (defname == "path") { - if (!GetDefText(path, pdef, filename)) - Print("WARNING: invalid or missing ship path in '%s'\n", filename); - } - else if (defname == "file") { - if (!GetDefText(fname, pdef, filename)) - Print("WARNING: invalid or missing ship file in '%s'\n", filename); - } - else if (defname == "hide" || defname == "secret") { - GetDefBool(hide, pdef, filename); - } - } - } - - ShipCatalogEntry* entry = new ShipCatalogEntry(name, type, path, fname, hide); - - if (mod) mod_catalog.append(entry); - else catalog.append(entry); - - result++; - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - } - } - } - while (term); - - loader->ReleaseBuffer(block); - loader->SetDataPath(0); - - return result; -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::LoadSkins(const char* path, const char* archive) -{ - // Load MOD Skin Files: - List list; - DataLoader* loader = DataLoader::GetLoader(); - bool oldfs = loader->IsFileSystemEnabled(); - - loader->UseFileSystem(true); - loader->SetDataPath(path); - loader->ListArchiveFiles(archive, "*.def", list); - - ListIter iter = list; - while (++iter) { - Text filename = *iter.value(); - BYTE* block; - int blocklen = loader->LoadBuffer(filename, block, true); - - // file not found: - if (blocklen <= 4) { - continue; - } - - Parser parser(new BlockReader((const char*) block, blocklen)); - Term* term = parser.ParseTerm(); - ShipDesign* design = 0; - - if (!term) { - Print("ERROR: could not parse '%s'\n", filename.data()); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "SKIN") { - Print("ERROR: invalid skin file '%s'\n", filename.data()); - return; - } - } - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - Text defname = def->name()->value(); - defname.setSensitive(false); - - if (defname == "name") { - Text name; - GetDefText(name, def, filename); - design = Get(name); - } - - else if (defname == "skin" && design != 0) { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: skin struct missing in '%s'\n", filename.data()); - } - else { - TermStruct* val = def->term()->isStruct(); - Skin* skin = design->ParseSkin(val); - - if (skin) - skin->SetPath(archive); - } - } - } - } - } - while (term); - } - - loader->UseFileSystem(oldfs); -} - -// +--------------------------------------------------------------------+ - -int -ShipDesign::StandardCatalogSize() -{ - return catalog.size(); -} - -void -ShipDesign::PreloadCatalog(int index) -{ - if (index >= 0 && index < catalog.size()) { - ShipCatalogEntry* entry = catalog[index]; - - if (entry->hide) - return; - - int ship_class = ClassForName(entry->type); - if (ship_class > Ship::STARSHIPS) - return; - - if (!entry->path.contains("Alliance_")) - return; - - if (!entry->design) { - entry->design = new ShipDesign(entry->name, - entry->path, - entry->file, - entry->hide); - } - } - - else { - ListIter iter = catalog; - while (++iter) { - ShipCatalogEntry* entry = iter.value(); - - if (!entry->design) { - entry->design = new ShipDesign(entry->name, - entry->path, - entry->file, - entry->hide); - } - } - } -} - -// +--------------------------------------------------------------------+ - -bool -ShipDesign::CheckName(const char* design_name) -{ - ShipCatalogEntry* entry = 0; - - for (int i = 0; i < catalog.size(); i++) { - if (catalog.at(i)->name == design_name) { - entry = catalog.at(i); - break; - } - } - - if (!entry) { - for (int i = 0; i < mod_catalog.size(); i++) { - if (mod_catalog.at(i)->name == design_name) { - entry = mod_catalog.at(i); - break; - } - } - } - - return entry != 0; -} - -// +--------------------------------------------------------------------+ - -ShipDesign* -ShipDesign::Get(const char* design_name, const char* design_path) -{ - if (!design_name || !*design_name) - return 0; - - ShipCatalogEntry* entry = 0; - - for (int i = 0; i < catalog.size(); i++) { - ShipCatalogEntry* e = catalog[i]; - if (e->name == design_name) { - if (design_path && *design_path && e->path != design_path) - continue; - entry = e; - break; - } - } - - if (!entry) { - for (int i = 0; i < mod_catalog.size(); i++) { - ShipCatalogEntry* e = mod_catalog[i]; - if (e->name == design_name) { - if (design_path && *design_path) { - Text full_path = "Mods/Ships/"; - full_path += design_path; - - if (e->path != full_path) - continue; - } - - entry = e; - break; - } - } - } - - if (entry) { - if (!entry->design) { - entry->design = new ShipDesign(entry->name, - entry->path, - entry->file, - entry->hide); - } - return entry->design; - } - else { - Print("ShipDesign: no catalog entry for design '%s', checking mods...\n", design_name); - return ShipDesign::FindModDesign(design_name, design_path); - } -} - -ShipDesign* -ShipDesign::FindModDesign(const char* design_name, const char* design_path) -{ - Text file = Text(design_name) + ".def"; - Text path = Text("Mods/Ships/"); - - if (design_path && *design_path) - path += design_path; - else - path += design_name; - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(path); - - ShipDesign* design = new ShipDesign(design_name, path, file); - - if (design->valid) { - Print("ShipDesign: found mod design '%s'\n", design->name); - - ShipCatalogEntry* entry = new ShipCatalogEntry(design->name, - ClassName(design->type), - path, - file); - mod_catalog.append(entry); - entry->design = design; - return entry->design; - } - else { - delete design; - } - - return 0; -} - -void -ShipDesign::ClearModCatalog() -{ - mod_catalog.destroy(); - - for (int i = 0; i < catalog.size(); i++) { - ShipCatalogEntry* e = catalog[i]; - - if (e && e->design) { - ListIter iter = e->design->skins; - - while (++iter) { - Skin* skin = iter.value(); - if (*skin->Path()) - iter.removeItem(); - } - } - } -} - -// +--------------------------------------------------------------------+ - -int -ShipDesign::GetDesignList(int type, List& designs) -{ - designs.clear(); - - for (int i = 0; i < catalog.size(); i++) { - ShipCatalogEntry* e = catalog[i]; - - int etype = ClassForName(e->type); - if (etype & type) { - if (!e->design) - e->design = new ShipDesign(e->name, - e->path, - e->file, - e->hide); - - if (e->hide || !e->design || !e->design->valid || e->design->secret) - continue; - - designs.append(&e->name); - } - } - - for (int i = 0; i < mod_catalog.size(); i++) { - ShipCatalogEntry* e = mod_catalog[i]; - - int etype = ClassForName(e->type); - if (etype & type) { - designs.append(&e->name); - } - } - - return designs.size(); -} - -// +--------------------------------------------------------------------+ - -int -ShipDesign::ClassForName(const char* name) -{ - if (!name || !name[0]) - return 0; - - for (int i = 0; i < 32; i++) { - if (!_stricmp(name, ship_design_class_name[i])) { - return 1 << i; - } - } - - return 0; -} - -const char* -ShipDesign::ClassName(int type) -{ - if (type != 0) { - int index = 0; - - while (!(type & 1)) { - type >>= 1; - index++; - } - - if (index >= 0 && index < 32) - return ship_design_class_name[index]; - } - - return "Unknown"; -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseShip(TermDef* def) -{ - char detail_name[NAMELEN]; - Vec3 off_loc; - Vec3 spin; - Text defname = def->name()->value(); - - defname.setSensitive(false); - - if (defname == "cockpit_model") { - if (!GetDefText(cockpit_name, def, filename)) - Print("WARNING: invalid or missing cockpit_model in '%s'\n", filename); - } - - else if (defname == "model" || defname == "detail_0") { - if (!GetDefText(detail_name, def, filename)) - Print("WARNING: invalid or missing model in '%s'\n", filename); - - detail[0].append(new Text(detail_name)); - } - - else if (defname == "detail_1") { - if (!GetDefText(detail_name, def, filename)) - Print("WARNING: invalid or missing detail_1 in '%s'\n", filename); - - detail[1].append(new Text(detail_name)); - } - - else if (defname == "detail_2") { - if (!GetDefText(detail_name, def, filename)) - Print("WARNING: invalid or missing detail_2 in '%s'\n", filename); - - detail[2].append(new Text(detail_name)); - } - - else if (defname == "detail_3") { - if (!GetDefText(detail_name, def, filename)) - Print("WARNING: invalid or missing detail_3 in '%s'\n", filename); - - detail[3].append(new Text(detail_name)); - } - - else if (defname == "spin") { - if (!GetDefVec(spin, def, filename)) - Print("WARNING: invalid or missing spin in '%s'\n", filename); - - spin_rates.append(new Point(spin)); - } - - else if (defname == "offset_0") { - if (!GetDefVec(off_loc, def, filename)) - Print("WARNING: invalid or missing offset_0 in '%s'\n", filename); - - offset[0].append(new Point(off_loc)); - } - - else if (defname == "offset_1") { - if (!GetDefVec(off_loc, def, filename)) - Print("WARNING: invalid or missing offset_1 in '%s'\n", filename); - - offset[1].append(new Point(off_loc)); - } - - else if (defname == "offset_2") { - if (!GetDefVec(off_loc, def, filename)) - Print("WARNING: invalid or missing offset_2 in '%s'\n", filename); - - offset[2].append(new Point(off_loc)); - } - - else if (defname == "offset_3") { - if (!GetDefVec(off_loc, def, filename)) - Print("WARNING: invalid or missing offset_3 in '%s'\n", filename); - - offset[3].append(new Point(off_loc)); - } - - else if (defname == "beauty") { - if (def->term() && def->term()->isArray()) { - GetDefVec(beauty_cam, def, filename); - - if (degrees) { - beauty_cam.x *= (float) DEGREES; - beauty_cam.y *= (float) DEGREES; - } - } - - else { - char beauty_name[64]; - if (!GetDefText(beauty_name, def, filename)) - Print("WARNING: invalid or missing beauty in '%s'\n", filename); - - DataLoader* loader = DataLoader::GetLoader(); - loader->LoadBitmap(beauty_name, beauty); - } - } - - else if (defname == "hud_icon") { - char hud_icon_name[64]; - if (!GetDefText(hud_icon_name, def, filename)) - Print("WARNING: invalid or missing hud_icon in '%s'\n", filename); - - DataLoader* loader = DataLoader::GetLoader(); - loader->LoadBitmap(hud_icon_name, hud_icon); - } - - else if (defname == "feature_0") { - if (!GetDefNumber(feature_size[0], def, filename)) - Print("WARNING: invalid or missing feature_0 in '%s'\n", filename); - } - - else if (defname == "feature_1") { - if (!GetDefNumber(feature_size[1], def, filename)) - Print("WARNING: invalid or missing feature_1 in '%s'\n", filename); - } - - else if (defname == "feature_2") { - if (!GetDefNumber(feature_size[2], def, filename)) - Print("WARNING: invalid or missing feature_2 in '%s'\n", filename); - } - - else if (defname == "feature_3") { - if (!GetDefNumber(feature_size[3], def, filename)) - Print("WARNING: invalid or missing feature_3 in '%s'\n", filename); - } - - - else if (defname == "class") { - char typestr[64]; - if (!GetDefText(typestr, def, filename)) - Print("WARNING: invalid or missing ship class in '%s'\n", filename); - - type = ClassForName(typestr); - - if (type <= Ship::LCA) { - repair_auto = false; - repair_screen = false; - wep_screen = false; - } - } - - else GET_DEF_TEXT(name); - else GET_DEF_TEXT(description); - else GET_DEF_TEXT(display_name); - else GET_DEF_TEXT(abrv); - else GET_DEF_NUM(pcs); - else GET_DEF_NUM(acs); - else GET_DEF_NUM(detet); - else GET_DEF_NUM(scale); - else GET_DEF_NUM(explosion_scale); - else GET_DEF_NUM(mass); - else GET_DEF_NUM(vlimit); - else GET_DEF_NUM(agility); - else GET_DEF_NUM(air_factor); - else GET_DEF_NUM(roll_rate); - else GET_DEF_NUM(pitch_rate); - else GET_DEF_NUM(yaw_rate); - else GET_DEF_NUM(integrity); - else GET_DEF_NUM(drag); - else GET_DEF_NUM(arcade_drag); - else GET_DEF_NUM(roll_drag); - else GET_DEF_NUM(pitch_drag); - else GET_DEF_NUM(yaw_drag); - else GET_DEF_NUM(trans_x); - else GET_DEF_NUM(trans_y); - else GET_DEF_NUM(trans_z); - else GET_DEF_NUM(turn_bank); - else GET_DEF_NUM(cockpit_scale); - else GET_DEF_NUM(auto_roll); - - else GET_DEF_NUM(CL); - else GET_DEF_NUM(CD); - else GET_DEF_NUM(stall); - - else GET_DEF_NUM(prep_time); - else GET_DEF_NUM(avoid_time); - else GET_DEF_NUM(avoid_fighter); - else GET_DEF_NUM(avoid_strike); - else GET_DEF_NUM(avoid_target); - else GET_DEF_NUM(commit_range); - - else GET_DEF_NUM(splash_radius); - else GET_DEF_NUM(scuttle); - else GET_DEF_NUM(repair_speed); - else GET_DEF_NUM(repair_teams); - else GET_DEF_BOOL(secret); - else GET_DEF_BOOL(repair_auto); - else GET_DEF_BOOL(repair_screen); - else GET_DEF_BOOL(wep_screen); - else GET_DEF_BOOL(degrees); - - else if (defname == "emcon_1") { - GetDefNumber(e_factor[0], def, filename); - } - - else if (defname == "emcon_2") { - GetDefNumber(e_factor[1], def, filename); - } - - else if (defname == "emcon_3") { - GetDefNumber(e_factor[2], def, filename); - } - - else if (defname == "chase") { - if (!GetDefVec(chase_vec, def, filename)) - Print("WARNING: invalid or missing chase cam loc in '%s'\n", filename); - - chase_vec *= (float) scale; - } - - else if (defname == "bridge") { - if (!GetDefVec(bridge_vec, def, filename)) - Print("WARNING: invalid or missing bridge cam loc in '%s'\n", filename); - - bridge_vec *= (float) scale; - } - - else if (defname == "power") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: power source struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParsePower(val); - } - } - - else if (defname == "main_drive" || defname == "drive") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: main drive struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseDrive(val); - } - } - - else if (defname == "quantum" || defname == "quantum_drive") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: quantum_drive struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseQuantumDrive(val); - } - } - - else if (defname == "sender" || defname == "farcaster") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: farcaster struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseFarcaster(val); - } - } - - else if (defname == "thruster") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: thruster struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseThruster(val); - } - } - - else if (defname == "navlight") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: navlight struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseNavlight(val); - } - } - - else if (defname == "flightdeck") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: flightdeck struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseFlightDeck(val); - } - } - - else if (defname == "gear") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: gear struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseLandingGear(val); - } - } - - else if (defname == "weapon") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: weapon struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseWeapon(val); - } - } - - else if (defname == "hardpoint") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: hardpoint struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseHardPoint(val); - } - } - - else if (defname == "loadout") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: loadout struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseLoadout(val); - } - } - - else if (defname == "decoy") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: decoy struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseWeapon(val); - } - } - - else if (defname == "probe") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: probe struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseWeapon(val); - } - } - - else if (defname == "sensor") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: sensor struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseSensor(val); - } - } - - else if (defname == "nav") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: nav struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseNavsys(val); - } - } - - else if (defname == "computer") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: computer struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseComputer(val); - } - } - - else if (defname == "shield") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: shield struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseShield(val); - } - } - - else if (defname == "death_spiral") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: death spiral struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseDeathSpiral(val); - } - } - - else if (defname == "map") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: map struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseMap(val); - } - } - - else if (defname == "squadron") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: squadron struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseSquadron(val); - } - } - - else if (defname == "skin") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: skin struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseSkin(val); - } - } - - else { - Print("WARNING: unknown parameter '%s' in '%s'\n", - defname.data(), filename); - } - - if (description.length()) - description = ContentBundle::GetInstance()->GetText(description); -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParsePower(TermStruct* val) -{ - int stype = 0; - float output = 1000.0f; - float fuel = 0.0f; - Vec3 loc(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - Text design_name; - Text pname; - Text pabrv; - int etype = 0; - int emcon_1 = -1; - int emcon_2 = -1; - int emcon_3 = -1; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "type") { - TermText* tname = pdef->term()->isText(); - - if (tname) { - if (tname->value()[0] == 'B') stype = PowerSource::BATTERY; - else if (tname->value()[0] == 'A') stype = PowerSource::AUX; - else if (tname->value()[0] == 'F') stype = PowerSource::FUSION; - else Print("WARNING: unknown power source type '%s' in '%s'\n", tname->value().data(), filename); - } - } - - else if (defname == "name") { - GetDefText(pname, pdef, filename); - } - - else if (defname == "abrv") { - GetDefText(pabrv, pdef, filename); - } - - else if (defname == "design") { - GetDefText(design_name, pdef, filename); - } - - else if (defname == "max_output") { - GetDefNumber(output, pdef, filename); - } - else if (defname == "fuel_range") { - GetDefNumber(fuel, pdef, filename); - } - - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - GetDefNumber(size, pdef, filename); - size *= (float) scale; - } - else if (defname == "hull_factor") { - GetDefNumber(hull, pdef, filename); - } - - else if (defname == "explosion") { - GetDefNumber(etype, pdef, filename); - } - - else if (defname == "emcon_1") { - GetDefNumber(emcon_1, pdef, filename); - } - - else if (defname == "emcon_2") { - GetDefNumber(emcon_2, pdef, filename); - } - - else if (defname == "emcon_3") { - GetDefNumber(emcon_3, pdef, filename); - } - } - } - - PowerSource* source = new PowerSource((PowerSource::SUBTYPE) stype, output); - if (pname.length()) source->SetName(pname); - if (pabrv.length()) source->SetName(pabrv); - source->SetFuelRange(fuel); - source->Mount(loc, size, hull); - source->SetExplosionType(etype); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - source->SetDesign(sd); - } - - if (emcon_1 >= 0 && emcon_1 <= 100) - source->SetEMCONPower(1, emcon_1); - - if (emcon_2 >= 0 && emcon_2 <= 100) - source->SetEMCONPower(1, emcon_2); - - if (emcon_3 >= 0 && emcon_3 <= 100) - source->SetEMCONPower(1, emcon_3); - - reactors.append(source); -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseDrive(TermStruct* val) -{ - Text dname; - Text dabrv; - int dtype = 0; - int etype = 0; - float dthrust = 1.0f; - float daug = 0.0f; - float dscale = 1.0f; - Vec3 loc(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - Text design_name; - int emcon_1 = -1; - int emcon_2 = -1; - int emcon_3 = -1; - bool trail = true; - Drive* drive = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "type") { - TermText* tname = pdef->term()->isText(); - - if (tname) { - Text tval = tname->value(); - tval.setSensitive(false); - - if (tval == "Plasma") dtype = Drive::PLASMA; - else if (tval == "Fusion") dtype = Drive::FUSION; - else if (tval == "Alien") dtype = Drive::GREEN; - else if (tval == "Green") dtype = Drive::GREEN; - else if (tval == "Red") dtype = Drive::RED; - else if (tval == "Blue") dtype = Drive::BLUE; - else if (tval == "Yellow") dtype = Drive::YELLOW; - else if (tval == "Stealth") dtype = Drive::STEALTH; - - else Print("WARNING: unknown drive type '%s' in '%s'\n", tname->value().data(), filename); - } - } - else if (defname == "name") { - if (!GetDefText(dname, pdef, filename)) - Print("WARNING: invalid or missing name for drive in '%s'\n", filename); - } - - else if (defname == "abrv") { - if (!GetDefText(dabrv, pdef, filename)) - Print("WARNING: invalid or missing abrv for drive in '%s'\n", filename); - } - - else if (defname == "design") { - if (!GetDefText(design_name, pdef, filename)) - Print("WARNING: invalid or missing design for drive in '%s'\n", filename); - } - - else if (defname == "thrust") { - if (!GetDefNumber(dthrust, pdef, filename)) - Print("WARNING: invalid or missing thrust for drive in '%s'\n", filename); - } - - else if (defname == "augmenter") { - if (!GetDefNumber(daug, pdef, filename)) - Print("WARNING: invalid or missing augmenter for drive in '%s'\n", filename); - } - - else if (defname == "scale") { - if (!GetDefNumber(dscale, pdef, filename)) - Print("WARNING: invalid or missing scale for drive in '%s'\n", filename); - } - - else if (defname == "port") { - Vec3 port; - float flare_scale = 0; - - if (pdef->term()->isArray()) { - GetDefVec(port, pdef, filename); - port *= scale; - flare_scale = dscale; - } - - else if (pdef->term()->isStruct()) { - TermStruct* val = pdef->term()->isStruct(); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef2 = val->elements()->at(i)->isDef(); - if (pdef2) { - if (pdef2->name()->value() == "loc") { - GetDefVec(port, pdef2, filename); - port *= scale; - } - - else if (pdef2->name()->value() == "scale") { - GetDefNumber(flare_scale, pdef2, filename); - } - } - } - - if (flare_scale <= 0) - flare_scale = dscale; - } - - if (!drive) - drive = new Drive((Drive::SUBTYPE) dtype, dthrust, daug, trail); - - drive->AddPort(port, flare_scale); - } - - else if (defname == "loc") { - if (!GetDefVec(loc, pdef, filename)) - Print("WARNING: invalid or missing loc for drive in '%s'\n", filename); - loc *= (float) scale; - } - - else if (defname == "size") { - if (!GetDefNumber(size, pdef, filename)) - Print("WARNING: invalid or missing size for drive in '%s'\n", filename); - size *= (float) scale; - } - - else if (defname == "hull_factor") { - if (!GetDefNumber(hull, pdef, filename)) - Print("WARNING: invalid or missing hull_factor for drive in '%s'\n", filename); - } - - else if (defname == "explosion") { - if (!GetDefNumber(etype, pdef, filename)) - Print("WARNING: invalid or missing explosion for drive in '%s'\n", filename); - } - - else if (defname == "emcon_1") { - GetDefNumber(emcon_1, pdef, filename); - } - - else if (defname == "emcon_2") { - GetDefNumber(emcon_2, pdef, filename); - } - - else if (defname == "emcon_3") { - GetDefNumber(emcon_3, pdef, filename); - } - - else if (defname == "trail" || defname == "show_trail") { - GetDefBool(trail, pdef, filename); - } - } - } - - if (!drive) - drive = new Drive((Drive::SUBTYPE) dtype, dthrust, daug, trail); - - drive->SetSourceIndex(reactors.size()-1); - drive->Mount(loc, size, hull); - if (dname.length()) drive->SetName(dname); - if (dabrv.length()) drive->SetAbbreviation(dabrv); - drive->SetExplosionType(etype); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - drive->SetDesign(sd); - } - - if (emcon_1 >= 0 && emcon_1 <= 100) - drive->SetEMCONPower(1, emcon_1); - - if (emcon_2 >= 0 && emcon_2 <= 100) - drive->SetEMCONPower(1, emcon_2); - - if (emcon_3 >= 0 && emcon_3 <= 100) - drive->SetEMCONPower(1, emcon_3); - - main_drive = drives.size(); - drives.append(drive); -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseQuantumDrive(TermStruct* val) -{ - double capacity = 250e3; - double consumption = 1e3; - Vec3 loc(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - float countdown = 5.0f; - Text design_name; - Text type_name; - Text abrv; - int subtype = QuantumDrive::QUANTUM; - int emcon_1 = -1; - int emcon_2 = -1; - int emcon_3 = -1; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "design") { - GetDefText(design_name, pdef, filename); - } - else if (defname == "abrv") { - GetDefText(abrv, pdef, filename); - } - else if (defname == "type") { - GetDefText(type_name, pdef, filename); - type_name.setSensitive(false); - - if (type_name.contains("hyper")) { - subtype = QuantumDrive::HYPER; - } - } - else if (defname == "capacity") { - GetDefNumber(capacity, pdef, filename); - } - else if (defname == "consumption") { - GetDefNumber(consumption, pdef, filename); - } - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - GetDefNumber(size, pdef, filename); - size *= (float) scale; - } - else if (defname == "hull_factor") { - GetDefNumber(hull, pdef, filename); - } - else if (defname == "jump_time") { - GetDefNumber(countdown, pdef, filename); - } - else if (defname == "countdown") { - GetDefNumber(countdown, pdef, filename); - } - - else if (defname == "emcon_1") { - GetDefNumber(emcon_1, pdef, filename); - } - - else if (defname == "emcon_2") { - GetDefNumber(emcon_2, pdef, filename); - } - - else if (defname == "emcon_3") { - GetDefNumber(emcon_3, pdef, filename); - } - } - } - - QuantumDrive* drive = new QuantumDrive((QuantumDrive::SUBTYPE) subtype, capacity, consumption); - drive->SetSourceIndex(reactors.size()-1); - drive->Mount(loc, size, hull); - drive->SetCountdown(countdown); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - drive->SetDesign(sd); - } - - if (abrv.length()) - drive->SetAbbreviation(abrv); - - if (emcon_1 >= 0 && emcon_1 <= 100) - drive->SetEMCONPower(1, emcon_1); - - if (emcon_2 >= 0 && emcon_2 <= 100) - drive->SetEMCONPower(1, emcon_2); - - if (emcon_3 >= 0 && emcon_3 <= 100) - drive->SetEMCONPower(1, emcon_3); - - quantum_drive = drive; -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseFarcaster(TermStruct* val) -{ - Text design_name; - double capacity = 300e3; - double consumption = 15e3; // twenty second recharge - int napproach = 0; - Vec3 approach[Farcaster::NUM_APPROACH_PTS]; - Vec3 loc(0.0f, 0.0f, 0.0f); - Vec3 start(0.0f, 0.0f, 0.0f); - Vec3 end(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - int emcon_1 = -1; - int emcon_2 = -1; - int emcon_3 = -1; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "design") { - GetDefText(design_name, pdef, filename); - } - else if (defname == "capacity") { - GetDefNumber(capacity, pdef, filename); - } - else if (defname == "consumption") { - GetDefNumber(consumption, pdef, filename); - } - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - GetDefNumber(size, pdef, filename); - size *= (float) scale; - } - else if (defname == "hull_factor") { - GetDefNumber(hull, pdef, filename); - } - - else if (defname == "start") { - GetDefVec(start, pdef, filename); - start *= (float) scale; - } - else if (defname == "end") { - GetDefVec(end, pdef, filename); - end *= (float) scale; - } - else if (defname == "approach") { - if (napproach < Farcaster::NUM_APPROACH_PTS) { - GetDefVec(approach[napproach], pdef, filename); - approach[napproach++] *= (float) scale; - } - else { - Print("WARNING: farcaster approach point ignored in '%s' (max=%d)\n", - filename, Farcaster::NUM_APPROACH_PTS); - } - } - - else if (defname == "emcon_1") { - GetDefNumber(emcon_1, pdef, filename); - } - - else if (defname == "emcon_2") { - GetDefNumber(emcon_2, pdef, filename); - } - - else if (defname == "emcon_3") { - GetDefNumber(emcon_3, pdef, filename); - } - } - } - - Farcaster* caster = new Farcaster(capacity, consumption); - caster->SetSourceIndex(reactors.size()-1); - caster->Mount(loc, size, hull); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - caster->SetDesign(sd); - } - - caster->SetStartPoint(start); - caster->SetEndPoint(end); - - for (int i = 0; i < napproach; i++) - caster->SetApproachPoint(i, approach[i]); - - if (emcon_1 >= 0 && emcon_1 <= 100) - caster->SetEMCONPower(1, emcon_1); - - if (emcon_2 >= 0 && emcon_2 <= 100) - caster->SetEMCONPower(1, emcon_2); - - if (emcon_3 >= 0 && emcon_3 <= 100) - caster->SetEMCONPower(1, emcon_3); - - farcaster = caster; -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseThruster(TermStruct* val) -{ - if (thruster) { - Print("WARNING: additional thruster ignored in '%s'\n", filename); - return; - } - - double thrust = 100; - - Vec3 loc(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - Text design_name; - float tscale = 1.0f; - int emcon_1 = -1; - int emcon_2 = -1; - int emcon_3 = -1; - int dtype = 0; - - Thruster* drive = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - - if (defname == "type") { - TermText* tname = pdef->term()->isText(); - - if (tname) { - Text tval = tname->value(); - tval.setSensitive(false); - - if (tval == "Plasma") dtype = Drive::PLASMA; - else if (tval == "Fusion") dtype = Drive::FUSION; - else if (tval == "Alien") dtype = Drive::GREEN; - else if (tval == "Green") dtype = Drive::GREEN; - else if (tval == "Red") dtype = Drive::RED; - else if (tval == "Blue") dtype = Drive::BLUE; - else if (tval == "Yellow") dtype = Drive::YELLOW; - else if (tval == "Stealth") dtype = Drive::STEALTH; - - else Print("WARNING: unknown thruster type '%s' in '%s'\n", tname->value().data(), filename); - } - } - - else if (defname == "thrust") { - GetDefNumber(thrust, pdef, filename); - } - - else if (defname == "design") { - GetDefText(design_name, pdef, filename); - } - - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - GetDefNumber(size, pdef, filename); - size *= (float) scale; - } - else if (defname == "hull_factor") { - GetDefNumber(hull, pdef, filename); - } - else if (defname == "scale") { - GetDefNumber(tscale, pdef, filename); - } - else if (defname.contains("port") && pdef->term()) { - Vec3 port; - float port_scale = 0; - DWORD fire = 0; - - if (pdef->term()->isArray()) { - GetDefVec(port, pdef, filename); - port *= scale; - port_scale = tscale; - } - - else if (pdef->term()->isStruct()) { - TermStruct* val = pdef->term()->isStruct(); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef2 = val->elements()->at(i)->isDef(); - if (pdef2) { - if (pdef2->name()->value() == "loc") { - GetDefVec(port, pdef2, filename); - port *= scale; - } - - else if (pdef2->name()->value() == "fire") { - GetDefNumber(fire, pdef2, filename); - } - - else if (pdef2->name()->value() == "scale") { - GetDefNumber(port_scale, pdef2, filename); - } - } - } - - if (port_scale <= 0) - port_scale = tscale; - } - - if (!drive) - drive = new Thruster(dtype, thrust, tscale); - - if (defname == "port" || defname == "port_bottom") - drive->AddPort(Thruster::BOTTOM, port, fire, port_scale); - - else if (defname == "port_top") - drive->AddPort(Thruster::TOP, port, fire, port_scale); - - else if (defname == "port_left") - drive->AddPort(Thruster::LEFT, port, fire, port_scale); - - else if (defname == "port_right") - drive->AddPort(Thruster::RIGHT, port, fire, port_scale); - - else if (defname == "port_fore") - drive->AddPort(Thruster::FORE, port, fire, port_scale); - - else if (defname == "port_aft") - drive->AddPort(Thruster::AFT, port, fire, port_scale); - } - - else if (defname == "emcon_1") { - GetDefNumber(emcon_1, pdef, filename); - } - - else if (defname == "emcon_2") { - GetDefNumber(emcon_2, pdef, filename); - } - - else if (defname == "emcon_3") { - GetDefNumber(emcon_3, pdef, filename); - } - } - } - - if (!drive) - drive = new Thruster(dtype, thrust, tscale); - drive->SetSourceIndex(reactors.size()-1); - drive->Mount(loc, size, hull); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - drive->SetDesign(sd); - } - - if (emcon_1 >= 0 && emcon_1 <= 100) - drive->SetEMCONPower(1, emcon_1); - - if (emcon_2 >= 0 && emcon_2 <= 100) - drive->SetEMCONPower(1, emcon_2); - - if (emcon_3 >= 0 && emcon_3 <= 100) - drive->SetEMCONPower(1, emcon_3); - - thruster = drive; -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseNavlight(TermStruct* val) -{ - Text dname; - Text dabrv; - Text design_name; - int nlights = 0; - float dscale = 1.0f; - float period = 10.0f; - Vec3 bloc[NavLight::MAX_LIGHTS]; - int btype[NavLight::MAX_LIGHTS]; - DWORD pattern[NavLight::MAX_LIGHTS]; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") - GetDefText(dname, pdef, filename); - else if (defname == "abrv") - GetDefText(dabrv, pdef, filename); - - else if (defname == "design") { - GetDefText(design_name, pdef, filename); - } - - else if (defname == "scale") { - GetDefNumber(dscale, pdef, filename); - } - else if (defname == "period") { - GetDefNumber(period, pdef, filename); - } - else if (defname == "light") { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: light struct missing for ship '%s' in '%s'\n", name, filename); - } - else { - TermStruct* val = pdef->term()->isStruct(); - - Vec3 loc; - int t = 0; - DWORD ptn = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "type") { - GetDefNumber(t, pdef, filename); - } - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - } - else if (defname == "pattern") { - GetDefNumber(ptn, pdef, filename); - } - } - } - - if (t < 1 || t > 4) - t = 1; - - if (nlights < NavLight::MAX_LIGHTS) { - bloc[nlights] = loc * scale; - btype[nlights] = t-1; - pattern[nlights] = ptn; - nlights++; - } - else { - Print("WARNING: Too many lights ship '%s' in '%s'\n", name, filename); - } - } - } - } - } - - NavLight* nav = new NavLight(period, dscale); - if (dname.length()) nav->SetName(dname); - if (dabrv.length()) nav->SetAbbreviation(dabrv); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - nav->SetDesign(sd); - } - - for (int i = 0; i < nlights; i++) - nav->AddBeacon(bloc[i], pattern[i], btype[i]); - - navlights.append(nav); -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseFlightDeck(TermStruct* val) -{ - Text dname; - Text dabrv; - Text design_name; - float dscale = 1.0f; - float az = 0.0f; - int etype = 0; - - bool launch = false; - bool recovery = false; - int nslots = 0; - int napproach = 0; - int nrunway = 0; - DWORD filters[10]; - Vec3 spots[10]; - Vec3 approach[FlightDeck::NUM_APPROACH_PTS]; - Vec3 runway[2]; - Vec3 loc(0,0,0); - Vec3 start(0,0,0); - Vec3 end(0,0,0); - Vec3 cam(0,0,0); - Vec3 box(0,0,0); - float cycle_time = 0.0f; - float size = 0.0f; - float hull = 0.5f; - - float light = 0.0f; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") - GetDefText(dname, pdef, filename); - else if (defname == "abrv") - GetDefText(dabrv, pdef, filename); - else if (defname == "design") - GetDefText(design_name, pdef, filename); - - else if (defname == "start") { - GetDefVec(start, pdef, filename); - start *= (float) scale; - } - else if (defname == "end") { - GetDefVec(end, pdef, filename); - end *= (float) scale; - } - else if (defname == "cam") { - GetDefVec(cam, pdef, filename); - cam *= (float) scale; - } - else if (defname == "box" || defname == "bounding_box") { - GetDefVec(box, pdef, filename); - box *= (float) scale; - } - else if (defname == "approach") { - if (napproach < FlightDeck::NUM_APPROACH_PTS) { - GetDefVec(approach[napproach], pdef, filename); - approach[napproach++] *= (float) scale; - } - else { - Print("WARNING: flight deck approach point ignored in '%s' (max=%d)\n", - filename, FlightDeck::NUM_APPROACH_PTS); - } - } - else if (defname == "runway") { - GetDefVec(runway[nrunway], pdef, filename); - runway[nrunway++] *= (float) scale; - } - else if (defname == "spot") { - if (pdef->term()->isStruct()) { - TermStruct* s = pdef->term()->isStruct(); - for (int i = 0; i < s->elements()->size(); i++) { - TermDef* d = s->elements()->at(i)->isDef(); - if (d) { - if (d->name()->value() == "loc") { - GetDefVec(spots[nslots], d, filename); - spots[nslots] *= (float) scale; - } - else if (d->name()->value() == "filter") { - GetDefNumber(filters[nslots], d, filename); - } - } - } - - nslots++; - } - - else if (pdef->term()->isArray()) { - GetDefVec(spots[nslots], pdef, filename); - spots[nslots] *= (float) scale; - filters[nslots++] = 0xf; - } - } - - else if (defname == "light") { - GetDefNumber(light, pdef, filename); - } - - else if (defname == "cycle_time") { - GetDefNumber(cycle_time, pdef, filename); - } - - else if (defname == "launch") { - GetDefBool(launch, pdef, filename); - } - - else if (defname == "recovery") { - GetDefBool(recovery, pdef, filename); - } - - else if (defname == "azimuth") { - GetDefNumber(az, pdef, filename); - if (degrees) az *= (float) DEGREES; - } - - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - GetDefNumber(size, pdef, filename); - size *= (float) scale; - } - else if (defname == "hull_factor") { - GetDefNumber(hull, pdef, filename); - } - else if (defname == "explosion") { - GetDefNumber(etype, pdef, filename); - } - } - } - - FlightDeck* deck = new FlightDeck(); - deck->Mount(loc, size, hull); - if (dname.length()) deck->SetName(dname); - if (dabrv.length()) deck->SetAbbreviation(dabrv); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - deck->SetDesign(sd); - } - - if (launch) - deck->SetLaunchDeck(); - else if (recovery) - deck->SetRecoveryDeck(); - - deck->SetAzimuth(az); - deck->SetBoundingBox(box); - deck->SetStartPoint(start); - deck->SetEndPoint(end); - deck->SetCamLoc(cam); - deck->SetExplosionType(etype); - - if (light > 0) - deck->SetLight(light); - - for (int i = 0; i < napproach; i++) - deck->SetApproachPoint(i, approach[i]); - - for (int i = 0; i < nrunway; i++) - deck->SetRunwayPoint(i, runway[i]); - - for (int i = 0; i < nslots; i++) - deck->AddSlot(spots[i], filters[i]); - - if (cycle_time > 0) - deck->SetCycleTime(cycle_time); - - flight_decks.append(deck); -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseLandingGear(TermStruct* val) -{ - Text dname; - Text dabrv; - Text design_name; - int ngear = 0; - Vec3 start[LandingGear::MAX_GEAR]; - Vec3 end[LandingGear::MAX_GEAR]; - Model* model[LandingGear::MAX_GEAR]; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") - GetDefText(dname, pdef, filename); - else if (defname == "abrv") - GetDefText(dabrv, pdef, filename); - - else if (defname == "design") { - GetDefText(design_name, pdef, filename); - } - - else if (defname == "gear") { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: gear struct missing for ship '%s' in '%s'\n", name, filename); - } - else { - TermStruct* val = pdef->term()->isStruct(); - - Vec3 v1, v2; - char mod_name[256]; - - ZeroMemory(mod_name, sizeof(mod_name)); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "model") { - GetDefText(mod_name, pdef, filename); - } - else if (defname == "start") { - GetDefVec(v1, pdef, filename); - } - else if (defname == "end") { - GetDefVec(v2, pdef, filename); - } - } - } - - if (ngear < LandingGear::MAX_GEAR) { - Model* m = new Model; - if (!m->Load(mod_name, scale)) { - Print("WARNING: Could not load landing gear model '%s'\n", mod_name); - delete m; - m = 0; - } - else { - model[ngear] = m; - start[ngear] = v1 * scale; - end[ngear] = v2 * scale; - ngear++; - } - } - else { - Print("WARNING: Too many landing gear ship '%s' in '%s'\n", name, filename); - } - } - } - } - } - - gear = new LandingGear(); - if (dname.length()) gear->SetName(dname); - if (dabrv.length()) gear->SetAbbreviation(dabrv); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - gear->SetDesign(sd); - } - - for (int i = 0; i < ngear; i++) - gear->AddGear(model[i], start[i], end[i]); -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseWeapon(TermStruct* val) -{ - Text wtype; - Text wname; - Text wabrv; - Text design_name; - Text group_name; - int nmuz = 0; - Vec3 muzzles[Weapon::MAX_BARRELS]; - Vec3 loc(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - float az = 0.0f; - float el = 0.0f; - float az_max = 1e6f; - float az_min = 1e6f; - float el_max = 1e6f; - float el_min = 1e6f; - float az_rest = 1e6f; - float el_rest = 1e6f; - int etype = 0; - int emcon_1 = -1; - int emcon_2 = -1; - int emcon_3 = -1; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "type") - GetDefText(wtype, pdef, filename); - else if (defname == "name") - GetDefText(wname, pdef, filename); - else if (defname == "abrv") - GetDefText(wabrv, pdef, filename); - else if (defname == "design") - GetDefText(design_name, pdef, filename); - else if (defname == "group") - GetDefText(group_name, pdef, filename); - - else if (defname == "muzzle") { - if (nmuz < Weapon::MAX_BARRELS) { - GetDefVec(muzzles[nmuz], pdef, filename); - nmuz++; - } - else { - Print("WARNING: too many muzzles (max=%d) for weapon in '%s'\n", filename, Weapon::MAX_BARRELS); - } - } - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - GetDefNumber(size, pdef, filename); - size *= (float) scale; - } - else if (defname == "hull_factor") { - GetDefNumber(hull, pdef, filename); - } - else if (defname == "azimuth") { - GetDefNumber(az, pdef, filename); - if (degrees) az *= (float) DEGREES; - } - else if (defname == "elevation") { - GetDefNumber(el, pdef, filename); - if (degrees) el *= (float) DEGREES; - } - - else if (defname==("aim_az_max")) { - GetDefNumber(az_max,pdef,filename); - if (degrees) az_max *= (float) DEGREES; - az_min = 0.0f - az_max; - } - - else if (defname==("aim_el_max")) { - GetDefNumber(el_max,pdef,filename); - if (degrees) el_max *= (float) DEGREES; - el_min = 0.0f - el_max; - } - - else if (defname==("aim_az_min")) { - GetDefNumber(az_min,pdef,filename); - if (degrees) az_min *= (float) DEGREES; - } - - else if (defname==("aim_el_min")) { - GetDefNumber(el_min,pdef,filename); - if (degrees) el_min *= (float) DEGREES; - } - - else if (defname==("aim_az_rest")) { - GetDefNumber(az_rest,pdef,filename); - if (degrees) az_rest *= (float) DEGREES; - } - - else if (defname==("aim_el_rest")) { - GetDefNumber(el_rest,pdef,filename); - if (degrees) el_rest *= (float) DEGREES; - } - - else if (defname == "rest_azimuth") { - GetDefNumber(az_rest, pdef, filename); - if (degrees) az_rest *= (float) DEGREES; - } - else if (defname == "rest_elevation") { - GetDefNumber(el_rest, pdef, filename); - if (degrees) el_rest *= (float) DEGREES; - } - else if (defname == "explosion") { - GetDefNumber(etype, pdef, filename); - } - - else if (defname == "emcon_1") { - GetDefNumber(emcon_1, pdef, filename); - } - - else if (defname == "emcon_2") { - GetDefNumber(emcon_2, pdef, filename); - } - - else if (defname == "emcon_3") { - GetDefNumber(emcon_3, pdef, filename); - } - else { - Print("WARNING: unknown weapon parameter '%s' in '%s'\n", - defname.data(), filename); - } - } - } - - WeaponDesign* meta = WeaponDesign::Find(wtype); - if (!meta) { - Print("WARNING: unusual weapon name '%s' in '%s'\n", (const char*) wtype, filename); - } - else { - // non-turret weapon muzzles are relative to ship scale: - if (meta->turret_model == 0) { - for (int i = 0; i < nmuz; i++) - muzzles[i] *= (float) scale; - } - - // turret weapon muzzles are relative to weapon scale: - else { - for (int i = 0; i < nmuz; i++) - muzzles[i] *= (float) meta->scale; - } - - Weapon* gun = new Weapon(meta, nmuz, muzzles, az, el); - gun->SetSourceIndex(reactors.size()-1); - gun->Mount(loc, size, hull); - - if (az_max < 1e6) gun->SetAzimuthMax(az_max); - if (az_min < 1e6) gun->SetAzimuthMin(az_min); - if (az_rest < 1e6) gun->SetRestAzimuth(az_rest); - - if (el_max < 1e6) gun->SetElevationMax(el_max); - if (el_min < 1e6) gun->SetElevationMin(el_min); - if (el_rest < 1e6) gun->SetRestElevation(el_rest); - - if (emcon_1 >= 0 && emcon_1 <= 100) - gun->SetEMCONPower(1, emcon_1); - - if (emcon_2 >= 0 && emcon_2 <= 100) - gun->SetEMCONPower(1, emcon_2); - - if (emcon_3 >= 0 && emcon_3 <= 100) - gun->SetEMCONPower(1, emcon_3); - - if (wname.length()) gun->SetName(wname); - if (wabrv.length()) gun->SetAbbreviation(wabrv); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - gun->SetDesign(sd); - } - - if (group_name.length()) { - gun->SetGroup(group_name); - } - - gun->SetExplosionType(etype); - - if (meta->decoy_type && !decoy) - decoy = gun; - else if (meta->probe && !probe) - probe = gun; - else - weapons.append(gun); - } - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(path_name); -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseHardPoint(TermStruct* val) -{ - Text wtypes[8]; - Text wname; - Text wabrv; - Text design; - Vec3 muzzle; - Vec3 loc(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - float az = 0.0f; - float el = 0.0f; - int ntypes = 0; - int emcon_1 = -1; - int emcon_2 = -1; - int emcon_3 = -1; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "type") - GetDefText(wtypes[ntypes++], pdef, filename); - else if (defname == "name") - GetDefText(wname, pdef, filename); - else if (defname == "abrv") - GetDefText(wabrv, pdef, filename); - else if (defname == "design") - GetDefText(design, pdef, filename); - - else if (defname == "muzzle") { - GetDefVec(muzzle, pdef, filename); - muzzle *= (float) scale; - } - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - GetDefNumber(size, pdef, filename); - size *= (float) scale; - } - else if (defname == "hull_factor") { - GetDefNumber(hull, pdef, filename); - } - else if (defname == "azimuth") { - GetDefNumber(az, pdef, filename); - if (degrees) az *= (float) DEGREES; - } - else if (defname == "elevation") { - GetDefNumber(el, pdef, filename); - if (degrees) el *= (float) DEGREES; - } - - else if (defname == "emcon_1") { - GetDefNumber(emcon_1, pdef, filename); - } - - else if (defname == "emcon_2") { - GetDefNumber(emcon_2, pdef, filename); - } - - else if (defname == "emcon_3") { - GetDefNumber(emcon_3, pdef, filename); - } - else { - Print("WARNING: unknown weapon parameter '%s' in '%s'\n", - defname.data(), filename); - } - } - } - - HardPoint* hp = new HardPoint(muzzle, az, el); - if (hp) { - for (int i = 0; i < ntypes; i++) { - WeaponDesign* meta = WeaponDesign::Find(wtypes[i]); - if (!meta) { - Print("WARNING: unusual weapon name '%s' in '%s'\n", (const char*) wtypes[i], filename); - } - else { - hp->AddDesign(meta); - } - } - - hp->Mount(loc, size, hull); - if (wname.length()) hp->SetName(wname); - if (wabrv.length()) hp->SetAbbreviation(wabrv); - if (design.length()) hp->SetDesign(design); - - hard_points.append(hp); - } - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(path_name); -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseLoadout(TermStruct* val) -{ - ShipLoad* load = new ShipLoad; - - if (!load) return; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") - GetDefText(load->name, pdef, filename); - - else if (defname == "stations") - GetDefArray(load->load, 16, pdef, filename); - - else - Print("WARNING: unknown loadout parameter '%s' in '%s'\n", - defname.data(), filename); - } - } - - loadouts.append(load); -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseSensor(TermStruct* val) -{ - Text design_name; - Vec3 loc(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - int nranges = 0; - float ranges[8]; - int emcon_1 = -1; - int emcon_2 = -1; - int emcon_3 = -1; - - ZeroMemory(ranges, sizeof(ranges)); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "range") { - GetDefNumber(ranges[nranges++], pdef, filename); - } - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - size *= (float) scale; - GetDefNumber(size, pdef, filename); - } - else if (defname == "hull_factor") { - GetDefNumber(hull, pdef, filename); - } - else if (defname == "design") { - GetDefText(design_name, pdef, filename); - } - else if (defname == "emcon_1") { - GetDefNumber(emcon_1, pdef, filename); - } - - else if (defname == "emcon_2") { - GetDefNumber(emcon_2, pdef, filename); - } - - else if (defname == "emcon_3") { - GetDefNumber(emcon_3, pdef, filename); - } - } - } - - if (!sensor) { - sensor = new Sensor(); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - sensor->SetDesign(sd); - } - - for (int i = 0; i < nranges; i++) - sensor->AddRange(ranges[i]); - - if (emcon_1 >= 0 && emcon_1 <= 100) - sensor->SetEMCONPower(1, emcon_1); - - if (emcon_2 >= 0 && emcon_2 <= 100) - sensor->SetEMCONPower(1, emcon_2); - - if (emcon_3 >= 0 && emcon_3 <= 100) - sensor->SetEMCONPower(1, emcon_3); - - sensor->Mount(loc, size, hull); - sensor->SetSourceIndex(reactors.size()-1); - } - else { - Print("WARNING: additional sensor ignored in '%s'\n", filename); - } -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseNavsys(TermStruct* val) -{ - Text design_name; - Vec3 loc(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - size *= (float) scale; - GetDefNumber(size, pdef, filename); - } - else if (defname == "hull_factor") { - GetDefNumber(hull, pdef, filename); - } - else if (defname == "design") - GetDefText(design_name, pdef, filename); - } - } - - if (!navsys) { - navsys = new NavSystem; - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - navsys->SetDesign(sd); - } - - navsys->Mount(loc, size, hull); - navsys->SetSourceIndex(reactors.size()-1); - } - else { - Print("WARNING: additional nav system ignored in '%s'\n", filename); - } -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseComputer(TermStruct* val) -{ - Text comp_name("Computer"); - Text comp_abrv("Comp"); - Text design_name; - int comp_type = 1; - Vec3 loc(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") { - GetDefText(comp_name, pdef, filename); - } - else if (defname == "abrv") { - GetDefText(comp_abrv, pdef, filename); - } - else if (defname == "design") { - GetDefText(design_name, pdef, filename); - } - else if (defname == "type") { - GetDefNumber(comp_type, pdef, filename); - } - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - size *= (float) scale; - GetDefNumber(size, pdef, filename); - } - else if (defname == "hull_factor") { - GetDefNumber(hull, pdef, filename); - } - } - } - - Computer* comp = new Computer(comp_type, comp_name); - comp->Mount(loc, size, hull); - comp->SetAbbreviation(comp_abrv); - comp->SetSourceIndex(reactors.size()-1); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - comp->SetDesign(sd); - } - - computers.append(comp); -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseShield(TermStruct* val) -{ - Text dname; - Text dabrv; - Text design_name; - Text model_name; - double factor = 0; - double capacity = 0; - double consumption = 0; - double cutoff = 0; - double curve = 0; - double def_cost = 1; - int shield_type = 0; - Vec3 loc(0.0f, 0.0f, 0.0f); - float size = 0.0f; - float hull = 0.5f; - int etype = 0; - bool shield_capacitor = false; - bool shield_bubble = false; - int emcon_1 = -1; - int emcon_2 = -1; - int emcon_3 = -1; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "type") { - GetDefNumber(shield_type, pdef, filename); - } - else if (defname == "name") - GetDefText(dname, pdef, filename); - else if (defname == "abrv") - GetDefText(dabrv, pdef, filename); - else if (defname == "design") - GetDefText(design_name, pdef, filename); - else if (defname == "model") - GetDefText(model_name, pdef, filename); - - else if (defname == "loc") { - GetDefVec(loc, pdef, filename); - loc *= (float) scale; - } - else if (defname == "size") { - GetDefNumber(size, pdef, filename); - size *= (float) scale; - } - else if (defname == "hull_factor") - GetDefNumber(hull, pdef, filename); - - else if (defname.contains("factor")) - GetDefNumber(factor, pdef, filename); - else if (defname.contains("cutoff")) - GetDefNumber(cutoff, pdef, filename); - else if (defname.contains("curve")) - GetDefNumber(curve, pdef, filename); - else if (defname.contains("capacitor")) - GetDefBool(shield_capacitor, pdef, filename); - else if (defname.contains("bubble")) - GetDefBool(shield_bubble, pdef, filename); - else if (defname == "capacity") - GetDefNumber(capacity, pdef, filename); - else if (defname == "consumption") - GetDefNumber(consumption, pdef, filename); - else if (defname == "deflection_cost") - GetDefNumber(def_cost, pdef, filename); - else if (defname == "explosion") - GetDefNumber(etype, pdef, filename); - - else if (defname == "emcon_1") { - GetDefNumber(emcon_1, pdef, filename); - } - - else if (defname == "emcon_2") { - GetDefNumber(emcon_2, pdef, filename); - } - - else if (defname == "emcon_3") { - GetDefNumber(emcon_3, pdef, filename); - } - - else if (defname == "bolt_hit_sound") { - GetDefText(bolt_hit_sound, pdef, filename); - } - - else if (defname == "beam_hit_sound") { - GetDefText(beam_hit_sound, pdef, filename); - } - } - } - - if (!shield) { - if (shield_type) { - shield = new Shield((Shield::SUBTYPE) shield_type); - shield->SetSourceIndex(reactors.size()-1); - shield->Mount(loc, size, hull); - if (dname.length()) shield->SetName(dname); - if (dabrv.length()) shield->SetAbbreviation(dabrv); - - if (design_name.length()) { - SystemDesign* sd = SystemDesign::Find(design_name); - if (sd) - shield->SetDesign(sd); - } - - shield->SetExplosionType(etype); - shield->SetShieldCapacitor(shield_capacitor); - shield->SetShieldBubble(shield_bubble); - - if (factor > 0) shield->SetShieldFactor(factor); - if (capacity > 0) shield->SetCapacity(capacity); - if (cutoff > 0) shield->SetShieldCutoff(cutoff); - if (consumption > 0) shield->SetConsumption(consumption); - if (def_cost > 0) shield->SetDeflectionCost(def_cost); - if (curve > 0) shield->SetShieldCurve(curve); - - if (emcon_1 >= 0 && emcon_1 <= 100) - shield->SetEMCONPower(1, emcon_1); - - if (emcon_2 >= 0 && emcon_2 <= 100) - shield->SetEMCONPower(1, emcon_2); - - if (emcon_3 >= 0 && emcon_3 <= 100) - shield->SetEMCONPower(1, emcon_3); - - if (model_name.length()) { - shield_model = new Model; - if (!shield_model->Load(model_name, scale)) { - Print("ERROR: Could not load shield model '%s'\n", model_name.data()); - delete shield_model; - shield_model = 0; - valid = false; - } - else { - shield_model->SetDynamic(true); - shield_model->SetLuminous(true); - } - } - - DataLoader* loader = DataLoader::GetLoader(); - DWORD SOUND_FLAGS = Sound::LOCALIZED | Sound::LOC_3D; - - if (bolt_hit_sound.length()) { - if (!loader->LoadSound(bolt_hit_sound, bolt_hit_sound_resource, SOUND_FLAGS, true)) { - loader->SetDataPath("Sounds/"); - loader->LoadSound(bolt_hit_sound, bolt_hit_sound_resource, SOUND_FLAGS); - loader->SetDataPath(path_name); - } - } - - if (beam_hit_sound.length()) { - if (!loader->LoadSound(beam_hit_sound, beam_hit_sound_resource, SOUND_FLAGS, true)) { - loader->SetDataPath("Sounds/"); - loader->LoadSound(beam_hit_sound, beam_hit_sound_resource, SOUND_FLAGS); - loader->SetDataPath(path_name); - } - } - } - else { - Print("WARNING: invalid shield type in '%s'\n", filename); - } - } - else { - Print("WARNING: additional shield ignored in '%s'\n", filename); - } -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseDeathSpiral(TermStruct* val) -{ - int exp_index = -1; - int debris_index = -1; - int fire_index = -1; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* def = val->elements()->at(i)->isDef(); - if (def) { - Text defname = def->name()->value(); - defname.setSensitive(false); - - if (defname == "time") { - GetDefNumber(death_spiral_time, def, filename); - } - - else if (defname == "explosion") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: explosion struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseExplosion(val, ++exp_index); - } - } - - // BACKWARD COMPATIBILITY: - else if (defname == "explosion_type") { - GetDefNumber(explosion[++exp_index].type, def, filename); - } - - else if (defname == "explosion_time") { - GetDefNumber(explosion[exp_index].time, def, filename); - } - - else if (defname == "explosion_loc") { - GetDefVec(explosion[exp_index].loc, def, filename); - explosion[exp_index].loc *= (float) scale; - } - - else if (defname == "final_type") { - GetDefNumber(explosion[++exp_index].type, def, filename); - explosion[exp_index].final = true; - } - - else if (defname == "final_loc") { - GetDefVec(explosion[exp_index].loc, def, filename); - explosion[exp_index].loc *= (float) scale; - } - - - else if (defname == "debris") { - if (def->term() && def->term()->isText()) { - Text model_name; - GetDefText(model_name, def, filename); - Model* model = new Model; - if (!model->Load(model_name, scale)) { - Print("Could not load debris model '%s'\n", model_name.data()); - delete model; - return; - } - - PrepareModel(*model); - debris[++debris_index].model = model; - fire_index = -1; - } - else if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: debris struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseDebris(val, ++debris_index); - } - } - - else if (defname == "debris_mass") { - GetDefNumber(debris[debris_index].mass, def, filename); - } - - else if (defname == "debris_speed") { - GetDefNumber(debris[debris_index].speed, def, filename); - } - - else if (defname == "debris_drag") { - GetDefNumber(debris[debris_index].drag, def, filename); - } - - else if (defname == "debris_loc") { - GetDefVec(debris[debris_index].loc, def, filename); - debris[debris_index].loc *= (float) scale; - } - - else if (defname == "debris_count") { - GetDefNumber(debris[debris_index].count, def, filename); - } - - else if (defname == "debris_life") { - GetDefNumber(debris[debris_index].life, def, filename); - } - - else if (defname == "debris_fire") { - if (++fire_index < 5) { - GetDefVec(debris[debris_index].fire_loc[fire_index], def, filename); - debris[debris_index].fire_loc[fire_index] *= (float) scale; - } - } - - else if (defname == "debris_fire_type") { - GetDefNumber(debris[debris_index].fire_type, def, filename); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseExplosion(TermStruct* val, int index) -{ - ShipExplosion* exp = &explosion[index]; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* def = val->elements()->at(i)->isDef(); - if (def) { - Text defname = def->name()->value(); - defname.setSensitive(false); - - if (defname == "time") { - GetDefNumber(exp->time, def, filename); - } - - else if (defname == "type") { - GetDefNumber(exp->type, def, filename); - } - - else if (defname == "loc") { - GetDefVec(exp->loc, def, filename); - exp->loc *= (float) scale; - } - - else if (defname == "final") { - GetDefBool(exp->final, def, filename); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseDebris(TermStruct* val, int index) -{ - char model_name[NAMELEN]; - int fire_index = 0; - ShipDebris* deb = &debris[index]; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* def = val->elements()->at(i)->isDef(); - if (def) { - Text defname = def->name()->value(); - - if (defname == "model") { - GetDefText(model_name, def, filename); - Model* model = new Model; - if (!model->Load(model_name, scale)) { - Print("Could not load debris model '%s'\n", model_name); - delete model; - return; - } - - PrepareModel(*model); - deb->model = model; - } - - else if (defname == "mass") { - GetDefNumber(deb->mass, def, filename); - } - - else if (defname == "speed") { - GetDefNumber(deb->speed, def, filename); - } - - else if (defname == "drag") { - GetDefNumber(deb->drag, def, filename); - } - - else if (defname == "loc") { - GetDefVec(deb->loc, def, filename); - deb->loc *= (float) scale; - } - - else if (defname == "count") { - GetDefNumber(deb->count, def, filename); - } - - else if (defname == "life") { - GetDefNumber(deb->life, def, filename); - } - - else if (defname == "fire") { - if (fire_index < 5) { - GetDefVec(deb->fire_loc[fire_index], def, filename); - deb->fire_loc[fire_index] *= (float) scale; - fire_index++; - } - } - - else if (defname == "fire_type") { - GetDefNumber(deb->fire_type, def, filename); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseMap(TermStruct* val) -{ - char sprite_name[NAMELEN]; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "sprite") { - GetDefText(sprite_name, pdef, filename); - - Bitmap* sprite = new Bitmap(); - DataLoader* loader = DataLoader::GetLoader(); - loader->LoadBitmap(sprite_name, *sprite, Bitmap::BMP_TRANSLUCENT); - - map_sprites.append(sprite); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -ShipDesign::ParseSquadron(TermStruct* val) -{ - char name[NAMELEN]; - char design[NAMELEN]; - int count = 4; - int avail = 4; - - name[0] = 0; - design[0] = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - Text defname = pdef->name()->value(); - defname.setSensitive(false); - - if (defname == "name") { - GetDefText(name, pdef, filename); - } - else if (defname == "design") { - GetDefText(design, pdef, filename); - } - else if (defname == "count") { - GetDefNumber(count, pdef, filename); - } - else if (defname == "avail") { - GetDefNumber(avail, pdef, filename); - } - } - } - - ShipSquadron* s = new ShipSquadron; - strcpy_s(s->name, name); - - s->design = Get(design); - s->count = count; - s->avail = avail; - - squadrons.append(s); -} - -// +--------------------------------------------------------------------+ - -Skin* -ShipDesign::ParseSkin(TermStruct* val) -{ - Skin* skin = 0; - char name[NAMELEN]; - - name[0] = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* def = val->elements()->at(i)->isDef(); - if (def) { - Text defname = def->name()->value(); - defname.setSensitive(false); - - if (defname == "name") { - GetDefText(name, def, filename); - - skin = new Skin(name); - } - else if (defname == "material" || defname == "mtl") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: skin struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseSkinMtl(val, skin); - } - } - } - } - - if (skin && skin->NumCells()) { - skins.append(skin); - } - - else if (skin) { - delete skin; - skin = 0; - } - - return skin; -} - -void -ShipDesign::ParseSkinMtl(TermStruct* val, Skin* skin) -{ - Material* mtl = new Material; - if (mtl == nullptr) - return; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* def = val->elements()->at(i)->isDef(); - if (def) { - Text defname = def->name()->value(); - defname.setSensitive(false); - - if (defname == "name") { - GetDefText(mtl->name, def, filename); - } - else if (defname == "Ka") { - GetDefColor(mtl->Ka, def, filename); - } - else if (defname == "Kd") { - GetDefColor(mtl->Kd, def, filename); - } - else if (defname == "Ks") { - GetDefColor(mtl->Ks, def, filename); - } - else if (defname == "Ke") { - GetDefColor(mtl->Ke, def, filename); - } - else if (defname == "Ns" || defname == "power") { - GetDefNumber(mtl->power, def, filename); - } - else if (defname == "bump") { - GetDefNumber(mtl->bump, def, filename); - } - else if (defname == "luminous") { - GetDefBool(mtl->luminous, def, filename); - } - - else if (defname == "blend") { - if (def->term() && def->term()->isNumber()) - GetDefNumber(mtl->blend, def, filename); - - else if (def->term() && def->term()->isText()) { - Text val; - GetDefText(val, def, filename); - val.setSensitive(false); - - if (val == "alpha" || val == "translucent") - mtl->blend = Material::MTL_TRANSLUCENT; - - else if (val == "additive") - mtl->blend = Material::MTL_ADDITIVE; - - else - mtl->blend = Material::MTL_SOLID; - } - } - - else if (defname.indexOf("tex_d") == 0) { - char tex_name[64]; - if (!GetDefText(tex_name, def, filename)) - Print("WARNING: invalid or missing tex_diffuse in '%s'\n", filename); - - DataLoader* loader = DataLoader::GetLoader(); - loader->LoadTexture(tex_name, mtl->tex_diffuse); - } - - else if (defname.indexOf("tex_s") == 0) { - char tex_name[64]; - if (!GetDefText(tex_name, def, filename)) - Print("WARNING: invalid or missing tex_specular in '%s'\n", filename); - - DataLoader* loader = DataLoader::GetLoader(); - loader->LoadTexture(tex_name, mtl->tex_specular); - } - - else if (defname.indexOf("tex_b") == 0) { - char tex_name[64]; - if (!GetDefText(tex_name, def, filename)) - Print("WARNING: invalid or missing tex_bumpmap in '%s'\n", filename); - - DataLoader* loader = DataLoader::GetLoader(); - loader->LoadTexture(tex_name, mtl->tex_bumpmap); - } - - else if (defname.indexOf("tex_e") == 0) { - char tex_name[64]; - if (!GetDefText(tex_name, def, filename)) - Print("WARNING: invalid or missing tex_emissive in '%s'\n", filename); - - DataLoader* loader = DataLoader::GetLoader(); - - loader->LoadTexture(tex_name, mtl->tex_emissive); - } - } - } - - if (skin && mtl) - skin->AddMaterial(mtl); -} - -const Skin* -ShipDesign::FindSkin(const char* skin_name) const -{ - int n = skins.size(); - - for (int i = 0; i < n; i++) { - Skin* s = skins[n-1-i]; - - if (!strcmp(s->Name(), skin_name)) - return s; - } - - return 0; -} diff --git a/Stars45/ShipDesign.h b/Stars45/ShipDesign.h deleted file mode 100644 index c0159b0..0000000 --- a/Stars45/ShipDesign.h +++ /dev/null @@ -1,291 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Starship Design parameters class -*/ - -#ifndef ShipDesign_h -#define ShipDesign_h - -#include "Types.h" -#include "Bitmap.h" -#include "Geometry.h" -#include "Term.h" -#include "List.h" - -// +----------------------------------------------------------------------+ - -class ShipDesign; -class Model; -class Skin; -class PowerSource; -class Weapon; -class HardPoint; -class Computer; -class Drive; -class QuantumDrive; -class Farcaster; -class Thruster; -class Sensor; -class NavLight; -class NavSystem; -class Shield; -class FlightDeck; -class LandingGear; -class System; -class Sound; - -// +====================================================================+ - -class ShipLoad -{ -public: - static const char* TYPENAME() { return "ShipLoad"; } - - ShipLoad(); - - char name[64]; - int load[16]; - double mass; -}; - -class ShipSquadron -{ -public: - static const char* TYPENAME() { return "ShipSquadron"; } - - ShipSquadron(); - - char name[64]; - ShipDesign* design; - int count; - int avail; -}; - -class ShipExplosion -{ -public: - static const char* TYPENAME() { return "ShipExplosion"; } - - ShipExplosion() { ZeroMemory(this, sizeof(ShipExplosion)); } - - int type; - float time; - Vec3 loc; - bool final; -}; - -class ShipDebris -{ -public: - static const char* TYPENAME() { return "ShipDebris"; } - - ShipDebris() { ZeroMemory(this, sizeof(ShipDebris)); } - - Model* model; - int count; - int life; - Vec3 loc; - float mass; - float speed; - float drag; - int fire_type; - Vec3 fire_loc[5]; -}; - -// +====================================================================+ -// Used to share common information about ships of a single type. -// ShipDesign objects are loaded from a text file and stored in a -// static list (catalog) member for use by the Ship. - -class ShipDesign -{ -public: - static const char* TYPENAME() { return "ShipDesign"; } - - enum CONSTANTS { - MAX_DEBRIS = 10, - MAX_EXPLOSIONS = 10 - }; - - ShipDesign(); - ShipDesign(const char* name, const char* path, const char* filename, bool secret=false); - ~ShipDesign(); - - // public interface: - static void Initialize(); - static void Close(); - static bool CheckName(const char* name); - static ShipDesign* Get(const char* design_name, const char* design_path=0); - static ShipDesign* FindModDesign(const char* design_name, const char* design_path=0); - static void ClearModCatalog(); - static int GetDesignList(int type, List& designs); // never destroy the design list! - - static int ClassForName(const char* name); - static const char* ClassName(int type); - - static int LoadCatalog(const char* path, const char* file, bool mod=false); - static void LoadSkins(const char* path, const char* archive=0); - static void PreloadCatalog(int index=-1); - static int StandardCatalogSize(); - - int operator == (const ShipDesign& s) const { return !strncmp(name, s.name, 31); } - - // Parser: - void ParseShip(TermDef* def); - - void ParsePower(TermStruct* val); - void ParseDrive(TermStruct* val); - void ParseQuantumDrive(TermStruct* val); - void ParseFarcaster(TermStruct* val); - void ParseThruster(TermStruct* val); - void ParseNavlight(TermStruct* val); - void ParseFlightDeck(TermStruct* val); - void ParseLandingGear(TermStruct* val); - void ParseWeapon(TermStruct* val); - void ParseHardPoint(TermStruct* val); - void ParseSensor(TermStruct* val); - void ParseNavsys(TermStruct* val); - void ParseComputer(TermStruct* val); - void ParseShield(TermStruct* val); - void ParseDeathSpiral(TermStruct* val); - void ParseExplosion(TermStruct* val, int index); - void ParseDebris(TermStruct* val, int index); - void ParseLoadout(TermStruct* val); - void ParseMap(TermStruct* val); - void ParseSquadron(TermStruct* val); - Skin* ParseSkin(TermStruct* val); - void ParseSkinMtl(TermStruct* val, Skin* skin); - - // general information: - const char* DisplayName() const; - - char filename[64]; - char path_name[64]; - char name[64]; - char display_name[64]; - char abrv[16]; - int type; - float scale; - int auto_roll; - bool valid; - bool secret; // don't display in editor - Text description; // background info for tactical reference - - // LOD representation: - int lod_levels; - List models[4]; - List offsets[4]; - float feature_size[4]; - List spin_rates; - - // player selectable skins: - List skins; - const Skin* FindSkin(const char* skin_name) const; - - // virtual cockpit: - Model* cockpit_model; - float cockpit_scale; - - // performance: - float vlimit; - float agility; - float air_factor; - float roll_rate; - float pitch_rate; - float yaw_rate; - float trans_x; - float trans_y; - float trans_z; - float turn_bank; - Vec3 chase_vec; - Vec3 bridge_vec; - Vec3 beauty_cam; - - float prep_time; - - // physical data: - float drag, roll_drag, pitch_drag, yaw_drag; - float arcade_drag; - float mass, integrity, radius; - - // aero data: - float CL, CD, stall; - - // weapons: - int primary; - int secondary; - - // drives: - int main_drive; - - // visibility: - float pcs; // passive sensor cross section - float acs; // active sensor cross section - float detet; // maximum detection range - float e_factor[3]; // pcs scaling by emcon setting - - // ai settings: - float avoid_time; - float avoid_fighter; - float avoid_strike; - float avoid_target; - float commit_range; - - // death spriral sequence: - float death_spiral_time; - float explosion_scale; - ShipExplosion explosion[MAX_EXPLOSIONS]; - ShipDebris debris[MAX_DEBRIS]; - - List reactors; - List weapons; - List hard_points; - List drives; - List computers; - List flight_decks; - List navlights; - QuantumDrive* quantum_drive; - Farcaster* farcaster; - Thruster* thruster; - Sensor* sensor; - NavSystem* navsys; - Shield* shield; - Model* shield_model; - Weapon* decoy; - Weapon* probe; - LandingGear* gear; - - float splash_radius; - float scuttle; - float repair_speed; - int repair_teams; - bool repair_auto; - bool repair_screen; - bool wep_screen; - - Text bolt_hit_sound; - Text beam_hit_sound; - - Sound* bolt_hit_sound_resource; - Sound* beam_hit_sound_resource; - - List loadouts; - List map_sprites; - List squadrons; - - Bitmap beauty; - Bitmap hud_icon; -}; - -// +--------------------------------------------------------------------+ - -#endif // ShipDesign_h - diff --git a/Stars45/ShipKiller.cpp b/Stars45/ShipKiller.cpp deleted file mode 100644 index f071115..0000000 --- a/Stars45/ShipKiller.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ShipKiller class implementation -*/ - -#include "ShipKiller.h" -#include "Sim.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "System.h" -#include "Weapon.h" -#include "Shot.h" -#include "Explosion.h" -#include "Debris.h" -#include "HUDSounds.h" - -#include "Solid.h" -#include "Random.h" - -// +----------------------------------------------------------------------+ - -ShipKiller::ShipKiller(Ship* s) -: ship(s), DEATH_CAM_LINGER(5.0f), time(0.0f), exp_time(0.0f), exp_index(0) -{ -} - -ShipKiller::~ShipKiller() -{ -} - -// +----------------------------------------------------------------------+ - -inline int random_index() -{ - return (int) (rand()/3277); -} - -// +----------------------------------------------------------------------+ - -void -ShipKiller::BeginDeathSpiral() -{ - if (!ship) return; - - // shut down all ship systems: - ListIter iter = ship->Systems(); - while (++iter) { - iter->PowerOff(); - iter->SetPowerLevel(0); - - if (iter->Type() == System::WEAPON) { - Weapon* gun = (Weapon*) iter.value(); - - for (int i = 0; i < Weapon::MAX_BARRELS; i++) { - Shot* beam = gun->GetBeam(i); - if (beam) - beam->Destroy(); - } - } - } - - if (ship->GetShieldRep()) - ship->GetShieldRep()->Hide(); - - Sim* sim = Sim::GetSim(); - const ShipDesign* design = ship->Design(); - - float time_to_go = design->death_spiral_time; - time = DEATH_CAM_LINGER + time_to_go; - loc = ship->Location() + ship->Velocity() * (time_to_go-1.0f); - - if (rand() < 16000) - loc += ship->BeamLine() * -3 * ship->Radius(); - else - loc += ship->BeamLine() * 3 * ship->Radius(); - - if (rand() < 8000) - loc += ship->LiftLine() * -1 * ship->Radius(); - else - loc += ship->LiftLine() * 2 * ship->Radius(); - - // stop on crash: - if (ship->IsGroundUnit() || (ship->IsAirborne() && ship->AltitudeAGL() < ship->Radius()*2)) { - time = DEATH_CAM_LINGER; - loc = ship->Location() + Point(6*ship->Radius(), 7*ship->Radius(), 8*ship->Radius()); - ship->SetVelocity(Point(0,0,0)); - } - // else, slow tumble: - else { - Point torque = RandomVector(ship->Mass()/7); - ship->ApplyTorque(torque); - - for (int i = 0; i < 5; i++) { - exp_index = random_index() % ShipDesign::MAX_EXPLOSIONS; - if (design->explosion[exp_index].type > 0 && !design->explosion[exp_index].final) - break; - } - - float exp_scale = design->explosion_scale; - if (exp_scale <= 0) - exp_scale = design->scale; - - exp_time = design->explosion[exp_index].time; - - if (design->explosion[exp_index].type > 0) { - Point exp_loc = ship->Location() + (design->explosion[exp_index].loc * ship->Cam().Orientation()); - sim->CreateExplosion(exp_loc, - ship->Velocity(), - design->explosion[exp_index].type, - (float) ship->Radius(), - exp_scale, - ship->GetRegion(), - ship); - } - } - - ship->SetControls(0); - ship->SetupAgility(); -} - -// +----------------------------------------------------------------------+ - -void -ShipKiller::ExecFrame(double seconds) -{ - Sim* sim = Sim::GetSim(); - const ShipDesign* design = ship->Design(); - - time -= (float) seconds; - exp_time -= (float) seconds; - - float exp_scale = design->explosion_scale; - if (exp_scale <= 0) - exp_scale = design->scale; - - if (exp_time < 0) { - exp_index++; - if (exp_index >= ShipDesign::MAX_EXPLOSIONS || design->explosion[exp_index].final) - exp_index = 0; - - exp_time = design->explosion[exp_index].time; - - if (design->explosion[exp_index].type > 0) { - Point exp_loc = ship->Location() + (design->explosion[exp_index].loc * ship->Cam().Orientation()); - sim->CreateExplosion(exp_loc, - ship->Velocity(), - design->explosion[exp_index].type, - (float) ship->Radius(), - exp_scale, - ship->GetRegion(), - ship); - } - } - - if (time < DEATH_CAM_LINGER) { - for (int i = 0; i < ShipDesign::MAX_EXPLOSIONS; i++) { - if (design->explosion[i].final) { - Point exp_loc = ship->Location() + (design->explosion[i].loc * ship->Cam().Orientation()); - sim->CreateExplosion(exp_loc, - ship->Velocity(), - design->explosion[i].type, - (float) ship->Radius(), - exp_scale, - ship->GetRegion()); - } - } - - for (int i = 0; i < ShipDesign::MAX_DEBRIS; i++) { - if (design->debris[i].model) { - Point debris_loc = ship->Location() + (design->debris[i].loc * ship->Cam().Orientation()); - Point debris_vel = debris_loc - ship->Location(); - debris_vel.Normalize(); - - if (design->debris[i].speed > 0) - debris_vel *= design->debris[i].speed; - else - debris_vel *= 200; - - if (ship->IsGroundUnit()) { - debris_vel *= 2; - - if (debris_vel.y < 0) - debris_vel.y *= -1; - } - - for (int n = 0; n < design->debris[i].count; n++) { - Debris* debris = sim->CreateDebris(debris_loc, - debris_vel + ship->Velocity(), - design->debris[i].model, - design->debris[i].mass, - ship->GetRegion()); - - debris->SetLife(design->debris[i].life); - debris->SetDrag(design->debris[i].drag); - - if (n == 0) { - debris->CloneCam(ship->Cam()); - debris->MoveTo(debris_loc); - } - - for (int fire = 0; fire < 5; fire++) { - if (design->debris[i].fire_loc[fire] == Vec3(0,0,0)) - continue; - - Point fire_loc = debris->Location() + (design->debris[i].fire_loc[fire] * debris->Cam().Orientation()); - - if (design->debris[i].fire_type > 0) { - sim->CreateExplosion(fire_loc, - ship->Velocity(), - design->debris[i].fire_type, - exp_scale, - exp_scale, - ship->GetRegion(), - debris); - } - else { - sim->CreateExplosion(fire_loc, - ship->Velocity(), - Explosion::SMALL_FIRE, - exp_scale, - exp_scale, - ship->GetRegion(), - debris); - - sim->CreateExplosion(fire_loc, - ship->Velocity(), - Explosion::SMOKE_TRAIL, - exp_scale * 0.25f, - exp_scale * 0.25f, - ship->GetRegion(), - debris); - } - } - - if (n+1 < design->debris[i].count) { - debris_vel = RandomVector(1); - - if (design->debris[i].speed > 0) - debris_vel *= design->debris[i].speed * Random(0.8, 1.2); - else - debris_vel *= 300 + rand()/50; - } - } - } - } - - if (ship == sim->GetPlayerShip()) - HUDSounds::StopSound(HUDSounds::SND_RED_ALERT); - - sim->CreateSplashDamage(ship); - ship->Destroy(); // CAREFUL!!! This will also delete this object! - } -} diff --git a/Stars45/ShipKiller.h b/Stars45/ShipKiller.h deleted file mode 100644 index 9e3d430..0000000 --- a/Stars45/ShipKiller.h +++ /dev/null @@ -1,54 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - ShipKiller (i.e. death spiral) class -*/ - -#ifndef ShipKiller_h -#define ShipKiller_h - -#include "Types.h" -#include "Geometry.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Ship; - -// +--------------------------------------------------------------------+ - -class ShipKiller -{ -public: - const float DEATH_CAM_LINGER; - - // CONSTRUCTORS: - ShipKiller(Ship* ship); - virtual ~ShipKiller(); - - virtual void BeginDeathSpiral(); - virtual void ExecFrame(double seconds); - - // GENERAL ACCESSORS: - virtual float TransitionTime() const { return time; } - virtual Point TransitionLoc() const { return loc; } - -protected: - Ship* ship; - - float time; - Point loc; - - float exp_time; - int exp_index; -}; - -#endif // ShipKiller_h - diff --git a/Stars45/ShipSolid.cpp b/Stars45/ShipSolid.cpp deleted file mode 100644 index bffcc54..0000000 --- a/Stars45/ShipSolid.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "ShipSolid.h" -#include "Ship.h" -#include "Sim.h" -#include "StarSystem.h" -#include "TerrainRegion.h" - -#include "Game.h" -#include "Skin.h" - -// +--------------------------------------------------------------------+ - -ShipSolid::ShipSolid(Ship* s) -: ship(s), skin(0), in_soup(false) -{ -} - -// +--------------------------------------------------------------------+ - -ShipSolid::~ShipSolid() -{ -} - -// +--------------------------------------------------------------------+ - -void -ShipSolid::TranslateBy(const Point& ref) -{ - true_eye_point = ref; - Solid::TranslateBy(ref); -} - -// +--------------------------------------------------------------------+ - -void -ShipSolid::Render(Video* video, DWORD flags) -{ - if (hidden || !visible || !video || Depth() > 5e6) - return; - - const Skin* s = 0; - - if (ship) - s = ship->GetSkin(); - else - s = skin; - - if (s) - s->ApplyTo(model); - - bool fog = false; - - if (ship && ship->IsAirborne()) { - fog = true; - - TerrainRegion* rgn = (TerrainRegion*) ship->GetRegion()->GetOrbitalRegion(); - double visibility = rgn->GetWeather().Visibility(); - FLOAT fog_density = (FLOAT) (rgn->FogDensity() * 2.5e-5 * 1/visibility); - Color fog_color = rgn->FogColor(); - - // Use BLACK fog on secondary lighting pass - // This will effectively "filter out" the highlights - // with distance... - - if (flags & Graphic::RENDER_ADD_LIGHT) - fog_color = Color::Black; - - video->SetRenderState(Video::FOG_ENABLE, true); - video->SetRenderState(Video::FOG_COLOR, fog_color.Value()); - video->SetRenderState(Video::FOG_DENSITY, *((DWORD*) &fog_density)); - } - - if (!fog) video->SetRenderState(Video::FOG_ENABLE, false); - - Solid::Render(video, flags); - - if (fog) video->SetRenderState(Video::FOG_ENABLE, false); - - if (s) - s->Restore(model); -} - - diff --git a/Stars45/ShipSolid.h b/Stars45/ShipSolid.h deleted file mode 100644 index 02d2322..0000000 --- a/Stars45/ShipSolid.h +++ /dev/null @@ -1,51 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - 3D Solid (Polygon) Object -*/ - -#ifndef ShipSolid_h -#define ShipSolid_h - -#include "Solid.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class Skin; - -// +--------------------------------------------------------------------+ - -class ShipSolid : public Solid -{ -public: - static const char* TYPENAME() { return "ShipSolid"; } - - ShipSolid(Ship* s); - virtual ~ShipSolid(); - - virtual void Render(Video* video, DWORD flags); - virtual void TranslateBy(const Point& ref); - - const Skin* GetSkin() const { return skin; } - void SetSkin(const Skin* s) { skin = s; } - -protected: - Ship* ship; - const Skin* skin; - Point true_eye_point; - Point fog_loc; - bool in_soup; -}; - -// +--------------------------------------------------------------------+ - -#endif // ShipSolid_h - diff --git a/Stars45/Shot.cpp b/Stars45/Shot.cpp deleted file mode 100644 index 0af927e..0000000 --- a/Stars45/Shot.cpp +++ /dev/null @@ -1,625 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Laser and Missile class -*/ - -#include "Shot.h" -#include "Weapon.h" -#include "DriveSprite.h" -#include "SeekerAI.h" -#include "Sim.h" -#include "Ship.h" -#include "Trail.h" -#include "Random.h" -#include "AudioConfig.h" -#include "TerrainRegion.h" -#include "Terrain.h" - -#include "Game.h" -#include "Clock.h" -#include "Bolt.h" -#include "Sprite.h" -#include "Solid.h" -#include "Light.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Sound.h" - -// +--------------------------------------------------------------------+ - -Shot::Shot(const Point& pos, const Camera& shot_cam, WeaponDesign* dsn, const Ship* ship) -: first_frame(true), owner(ship), flash(0), flare(0), trail(0), sound(0), eta(0), -charge(1.0f), design(dsn), offset(1.0e5f), altitude_agl(-1.0e6f), hit_target(false) -{ - obj_type = SimObject::SIM_SHOT; - type = design->type; - primary = design->primary; - beam = design->beam; - base_damage = design->damage; - armed = false; - - radius = 10.0f; - - if (primary || design->decoy_type || !design->guided) { - straight = true; - armed = true; - } - - cam.Clone(shot_cam); - - life = design->life; - velocity = cam.vpn() * (double) design->speed; - - MoveTo(pos); - - if (beam) - origin = pos + (shot_cam.vpn() * -design->length); - - switch (design->graphic_type) { - case Graphic::BOLT: { - Bolt* s = new Bolt(design->length, design->width, design->shot_img, 1); - s->SetDirection(cam.vpn()); - rep = s; - } - break; - - case Graphic::SPRITE: { - Sprite* s = 0; - - if (design->animation) - s = new DriveSprite(design->animation, design->anim_length); - else - s = new DriveSprite(design->shot_img); - - s->Scale((double) design->scale); - rep = s; - } - break; - - case Graphic::SOLID: { - Solid* s = new Solid; - s->UseModel(design->shot_model); - rep = s; - - radius = rep->Radius(); - } - break; - } - - if (rep) - rep->MoveTo(pos); - - light = 0; - - if (design->light > 0) { - light = new Light(design->light); - light->SetColor(design->light_color); - } - - mass = design->mass; - drag = design->drag; - thrust = 0.0f; - - dr_drg = design->roll_drag; - dp_drg = design->pitch_drag; - dy_drg = design->yaw_drag; - - SetAngularRates((float) design->roll_rate, (float) design->pitch_rate, (float) design->yaw_rate); - - if (design->flash_img != 0) { - flash = new Sprite(design->flash_img); - flash->Scale((double) design->flash_scale); - flash->MoveTo(pos - cam.vpn() * design->length); - flash->SetLuminous(true); - } - - if (design->flare_img != 0) { - flare = new DriveSprite(design->flare_img); - flare->Scale((double) design->flare_scale); - flare->MoveTo(pos); - } - - if (owner) { - iff_code = (BYTE) owner->GetIFF(); - Observe((SimObject*) owner); - } - - sprintf_s(name, "Shot(%s)", design->name.data()); -} - -// +--------------------------------------------------------------------+ - -Shot::~Shot() -{ - GRAPHIC_DESTROY(flash); - GRAPHIC_DESTROY(flare); - GRAPHIC_DESTROY(trail); - - if (sound) { - sound->Stop(); - sound->Release(); - } -} - -// +--------------------------------------------------------------------+ - -const char* -Shot::DesignName() const -{ - return design->name; -} - -// +--------------------------------------------------------------------+ - -void -Shot::SetCharge(float c) -{ - charge = c; - - // trim beam life to amount of energy available: - if (beam) - life = design->life * charge / design->charge; -} - -void -Shot::SetFuse(double seconds) -{ - if (seconds > 0 && !beam) - life = seconds; -} - -// +--------------------------------------------------------------------+ - -void -Shot::SeekTarget(SimObject* target, System* sub) -{ - if (dir && !primary) { - SeekerAI* seeker = (SeekerAI*) dir; - SimObject* old_target = seeker->GetTarget(); - - if (old_target->Type()==SimObject::SIM_SHIP) { - Ship* tgt_ship = (Ship*) old_target; - tgt_ship->DropThreat(this); - } - } - - delete dir; - dir = 0; - - if (target) { - SeekerAI* seeker = new SeekerAI(this); - seeker->SetTarget(target, sub); - seeker->SetPursuit(design->guided); - seeker->SetDelay(1); - - dir = seeker; - - if (!primary && target->Type()==SimObject::SIM_SHIP) { - Ship* tgt_ship = (Ship*) target; - tgt_ship->AddThreat(this); - } - } -} - -bool -Shot::IsTracking(Ship* tgt) const -{ - return tgt && (GetTarget() == tgt); -} - -SimObject* -Shot::GetTarget() const -{ - if (dir) { - SeekerAI* seeker = (SeekerAI*) dir; - - if (seeker->GetDelay() <= 0) - return seeker->GetTarget(); - } - - return 0; -} - -bool -Shot::IsFlak() const -{ - return design && design->flak; -} - -// +--------------------------------------------------------------------+ - -bool -Shot::IsHostileTo(const SimObject* o) const -{ - if (o) { - if (o->Type() == SIM_SHIP) { - Ship* s = (Ship*) o; - - if (s->IsRogue()) - return true; - - if (s->GetIFF() > 0 && s->GetIFF() != GetIFF()) - return true; - } - - else if (o->Type() == SIM_SHOT || o->Type() == SIM_DRONE) { - Shot* s = (Shot*) o; - - if (s->GetIFF() > 0 && s->GetIFF() != GetIFF()) - return true; - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -void -Shot::ExecFrame(double seconds) -{ - altitude_agl = -1.0e6f; - - // add random flickering effect: - double flicker = 0.75 + (double) rand() / 8e4; - if (flicker > 1) flicker = 1; - - if (flare) { - flare->SetShade(flicker); - } - else if (beam) { - Bolt* blob = (Bolt*) rep; - blob->SetShade(flicker); - offset -= (float) (seconds * 10); - } - - if (Game::GetInstance()->Paused()) - return; - - if (beam) { - if (!first_frame) { - if (life > 0) { - life -= seconds; - - if (life < 0) - life = 0; - } - } - } - else { - origin = Location(); - - if (!first_frame) - Physical::ExecFrame(seconds); - else - Physical::ExecFrame(0); - - double len = design->length; - if (len < 50) len = 50; - - if (!trail && life > 0 && design->life - life > 0.2) { - if (design->trail.length()) { - trail = new Trail(design->trail_img, design->trail_length); - - if (design->trail_width > 0) - trail->SetWidth(design->trail_width); - - if (design->trail_dim > 0) - trail->SetDim(design->trail_dim); - - trail->AddPoint(Location() + Heading() * -100); - - Scene* scene = 0; - - if (rep) - scene = rep->GetScene(); - - if (scene) - scene->AddGraphic(trail); - } - } - - if (trail) - trail->AddPoint(Location()); - - if (!armed) { - SeekerAI* seeker = (SeekerAI*) dir; - - if (seeker && seeker->GetDelay() <= 0) - armed = true; - } - - // handle submunitions: - else if (design->det_range > 0 && design->det_count > 0) { - if (dir && !primary) { - SeekerAI* seeker = (SeekerAI*) dir; - SimObject* target = seeker->GetTarget(); - - if (target) { - double range = Point(Location() - target->Location()).length(); - - if (range < design->det_range) { - life = 0; - - Sim* sim = Sim::GetSim(); - WeaponDesign* child_design = WeaponDesign::Find(design->det_child); - - if (sim && child_design) { - double spread = design->det_spread; - - Camera aim_cam; - aim_cam.Clone(Cam()); - aim_cam.LookAt(target->Location()); - - for (int i = 0; i < design->det_count; i++) { - Shot* child = sim->CreateShot(Location(), aim_cam, child_design, - owner, owner->GetRegion()); - - child->SetCharge(child_design->charge); - - if (child_design->guided) - child->SeekTarget(target, seeker->GetSubTarget()); - - if (child_design->beam) - child->SetBeamPoints(Location(), target->Location()); - - if (i) aim_cam.LookAt(target->Location()); - aim_cam.Pitch(Random(-spread, spread)); - aim_cam.Yaw(Random(-spread, spread)); - } - } - } - } - } - } - - if (flash && !first_frame) - GRAPHIC_DESTROY(flash); - - if (thrust < design->thrust) - thrust += (float) (seconds * 5.0e3); - else - thrust = design->thrust; - } - - first_frame = 0; - - if (flare) - flare->MoveTo(Location()); -} - -// +--------------------------------------------------------------------+ - -void -Shot::Disarm() -{ - if (armed && !primary) { - armed = false; - delete dir; - dir = 0; - } -} - -void -Shot::Destroy() -{ - life = 0; -} - -// +--------------------------------------------------------------------+ - -void -Shot::SetBeamPoints(const Point& from, const Point& to) -{ - if (beam) { - MoveTo(to); - origin = from; - - if (sound) { - sound->SetLocation(from); - } - - if (rep) { - Bolt* s = (Bolt*) rep; - s->SetEndPoints(from, to); - - double len = Point(to - from).length() / 500; - s->SetTextureOffset(offset, offset + len); - } - } - - if (flash) { - flash->MoveTo(origin); - } -} - -// +--------------------------------------------------------------------+ - -double -Shot::AltitudeMSL() const -{ - return Location().y; -} - -double -Shot::AltitudeAGL() const -{ - if (altitude_agl < -1000) { - Shot* pThis = (Shot*) this; // cast-away const - Point loc = Location(); - Terrain* terrain = region->GetTerrain(); - - if (terrain) - pThis->altitude_agl = (float) (loc.y - terrain->Height(loc.x, loc.z)); - - else - pThis->altitude_agl = (float) loc.y; - - if (!_finite(altitude_agl)) { - pThis->altitude_agl = 0.0f; - } - } - - return altitude_agl; -} - -// +--------------------------------------------------------------------+ - -void -Shot::Initialize() -{ -} - -// +--------------------------------------------------------------------+ - -void -Shot::Close() -{ -} - -// +--------------------------------------------------------------------+ - -double -Shot::Damage() const -{ - double damage = 0; - - // beam damage based on length: - if (beam) { - double fade = 1; - - if (design) { - // linear fade with distance: - double len = Point(origin - Location()).length(); - - if (len > design->min_range) - fade = (design->length - len) / (design->length - design->min_range); - } - - damage = base_damage * charge * fade * Clock::GetInstance()->Delta(); - } - - // energy wep damage based on time: - else if (primary) { - damage = base_damage * charge * life; - } - - // missile damage is constant: - else { - damage = base_damage * charge; - } - - return damage; -} - -double -Shot::Length() const -{ - if (design) - return design->length; - - return 500; -} - -// +--------------------------------------------------------------------+ - -void -Shot::Activate(Scene& scene) -{ - SimObject::Activate(scene); - - if (trail) - scene.AddGraphic(trail); - - if (flash) - scene.AddGraphic(flash); - - if (flare) - scene.AddGraphic(flare); - - if (first_frame) { - if (design->sound_resource) { - sound = design->sound_resource->Duplicate(); - - if (sound) { - long max_vol = AudioConfig::EfxVolume(); - long volume = -1000; - - if (volume > max_vol) - volume = max_vol; - - if (beam) { - sound->SetLocation(origin); - sound->SetVolume(volume); - sound->Play(); - } - else { - sound->SetLocation(Location()); - sound->SetVolume(volume); - sound->Play(); - sound = 0; // fire and forget: - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Shot::Deactivate(Scene& scene) -{ - SimObject::Deactivate(scene); - - if (trail) - scene.DelGraphic(trail); - - if (flash) - scene.DelGraphic(flash); - - if (flare) - scene.DelGraphic(flare); -} - -// +--------------------------------------------------------------------+ - -int -Shot::GetIFF() const -{ - return iff_code; -} - -// +--------------------------------------------------------------------+ - -Color -Shot::MarkerColor() const -{ - return Ship::IFFColor(GetIFF()); -} - -// +--------------------------------------------------------------------+ - -const char* -Shot::GetObserverName() const -{ - return name; -} - -// +--------------------------------------------------------------------+ - -bool -Shot::Update(SimObject* obj) -{ - if (obj == (SimObject*) owner) - owner = 0; - - return SimObserver::Update(obj); -} diff --git a/Stars45/Shot.h b/Stars45/Shot.h deleted file mode 100644 index aae242c..0000000 --- a/Stars45/Shot.h +++ /dev/null @@ -1,128 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Laser and Missile class -*/ - -#ifndef Shot_h -#define Shot_h - -#include "Types.h" -#include "Geometry.h" -#include "SimObject.h" -#include "Color.h" - -// +--------------------------------------------------------------------+ - -class Camera; -class Ship; -class Trail; -class System; -class WeaponDesign; -class Sprite; -class Sound; - -// +--------------------------------------------------------------------+ - -class Shot : public SimObject, -public SimObserver -{ -public: - static const char* TYPENAME() { return "Shot"; } - - Shot(const Point& pos, const Camera& cam, WeaponDesign* design, const Ship* ship=0); - virtual ~Shot(); - - virtual void SeekTarget(SimObject* target, System* sub=0); - virtual void ExecFrame(double factor); - static void Initialize(); - static void Close(); - - virtual void Activate(Scene& scene); - virtual void Deactivate(Scene& scene); - - const Ship* Owner() const { return owner; } - double Damage() const; - int ShotType() const { return type; } - virtual SimObject* GetTarget() const; - - virtual bool IsPrimary() const { return primary; } - virtual bool IsDrone() const { return false; } - virtual bool IsDecoy() const { return false; } - virtual bool IsProbe() const { return false; } - virtual bool IsMissile() const { return !primary; } - virtual bool IsArmed() const { return armed; } - virtual bool IsBeam() const { return beam; } - virtual bool IsFlak() const; - virtual bool IsHostileTo(const SimObject* o) const; - - bool HitTarget() const { return hit_target; } - void SetHitTarget(bool h) { hit_target = h; } - - virtual bool IsTracking(Ship* tgt) const; - virtual double PCS() const { return 0; } - virtual double ACS() const { return 0; } - virtual int GetIFF() const; - virtual Color MarkerColor() const; - - const Point& Origin() const { return origin; } - float Charge() const { return charge; } - void SetCharge(float c); - double Length() const; - Graphic* GetTrail() const { return (Graphic*) trail; } - void SetFuse(double seconds); - - void SetBeamPoints(const Point& from, const Point& to); - virtual void Disarm(); - virtual void Destroy(); - - const WeaponDesign* Design() const { return design; } - const char* DesignName() const; - int GetEta() const { return eta; } - void SetEta(int t) { eta = t; } - - double AltitudeMSL() const; - double AltitudeAGL() const; - - // SimObserver interface: - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - int operator == (const Shot& s) const { return id == s.id; } - -protected: - const Ship* owner; - - int type; - float base_damage; - float charge; - float offset; - float altitude_agl; - short eta; - BYTE iff_code; - bool first_frame; - bool primary; - bool beam; - bool armed; - bool hit_target; - - Sprite* flash; // muzzle flash - Sprite* flare; // drive flare - Trail* trail; // exhaust trail - - Sound* sound; - WeaponDesign* design; - - // for beam weapons: - Point origin; -}; - -#endif // Shot_h - diff --git a/Stars45/Sim.cpp b/Stars45/Sim.cpp deleted file mode 100644 index 36d5356..0000000 --- a/Stars45/Sim.cpp +++ /dev/null @@ -1,3814 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simulation Universe and Region classes -*/ - -#include "Sim.h" -#include "SimEvent.h" -#include "SimObject.h" -#include "Starshatter.h" -#include "StarSystem.h" -#include "Contact.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Element.h" -#include "Instruction.h" -#include "RadioTraffic.h" -#include "Shot.h" -#include "Drone.h" -#include "Explosion.h" -#include "Debris.h" -#include "Asteroid.h" -#include "Drive.h" -#include "QuantumDrive.h" -#include "Sensor.h" -#include "NavLight.h" -#include "Shield.h" -#include "Weapon.h" -#include "WeaponGroup.h" -#include "Hangar.h" -#include "FlightDeck.h" -#include "Sky.h" -#include "Grid.h" -#include "Mfd.h" -#include "AudioConfig.h" -#include "Mission.h" -#include "MissionEvent.h" -#include "CameraDirector.h" -#include "MusicDirector.h" -#include "Combatant.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "HUDView.h" -#include "SeekerAI.h" -#include "ShipAI.h" -#include "Power.h" -#include "Callsign.h" -#include "GameScreen.h" -#include "Terrain.h" -#include "TerrainPatch.h" - -#include "NetGame.h" -#include "NetClientConfig.h" -#include "NetServerConfig.h" -#include "NetPlayer.h" -#include "NetUtil.h" -#include "NetData.h" - -#include "Game.h" -#include "Clock.h" -#include "ContentBundle.h" -#include "Sound.h" -#include "Bolt.h" -#include "Solid.h" -#include "Sprite.h" -#include "Light.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "ParseUtil.h" -#include "MouseController.h" -#include "Player.h" -#include "Random.h" -#include "Video.h" - -const char* FormatGameTime(); - -// +--------------------------------------------------------------------+ - -class SimHyper -{ -public: - SimHyper(Ship* o, SimRegion* r, const Point& l, int t, bool h, Ship* fc1, Ship* fc2) - : ship(o), rgn(r), loc(l), type(t), hyperdrive(h), fc_src(fc1), fc_dst(fc2) { } - - Ship* ship; - SimRegion* rgn; - Point loc; - int type; - bool hyperdrive; - Ship* fc_src; - Ship* fc_dst; -}; - -// +--------------------------------------------------------------------+ - -class SimSplash -{ -public: - SimSplash(SimRegion* r, const Point& l, double d, double n) - : rgn(r), loc(l), damage(d), range(n), - owner_name("Collateral Damage"), missile(false) { } - - Text owner_name; - Point loc; - double damage; - double range; - SimRegion* rgn; - bool missile; -}; - -// +--------------------------------------------------------------------+ - -static bool first_frame = true; -Sim* Sim::sim = 0; - -Sim::Sim(MotionController* c) - : ctrl(c), test_mode(false), grid_shown(false), dust(0), - star_system(0), active_region(0), mission(0), netgame(0), - start_time(0) -{ - Drive::Initialize(); - Explosion::Initialize(); - FlightDeck::Initialize(); - NavLight::Initialize(); - Shot::Initialize(); - MFD::Initialize(); - Asteroid::Initialize(); - - if (!sim) - sim = this; - - cam_dir = CameraDirector::GetInstance(); -} - -Sim::~Sim() -{ - UnloadMission(); - - Shot::Close(); - FlightDeck::Close(); - NavLight::Close(); - Token::close(); - Asteroid::Close(); - - if (sim == this) - sim = 0; -} - -// +--------------------------------------------------------------------+ - -void -Sim::CommitMission() -{ - for (int i = 0; i < regions.size(); i++) - regions[i]->CommitMission(); - - if (ShipStats::NumStats() > 0) { - Print("\n\nFINAL SCORE '%s'\n", (const char*) mission->Name()); - Print("Name Kill1 Kill2 Died Colls Points Cmd Pts\n"); - Print("---------------- ----- ----- ----- ----- ------ ------\n"); - - int tk1 = 0; - int tk2 = 0; - int td = 0; - int tc = 0; - - for (int i = 0; i < ShipStats::NumStats(); i++) { - ShipStats* s = ShipStats::GetStats(i); - s->Summarize(); - - Print("%-16s %5d %5d %5d %5d %6d %6d\n", - s->GetName(), - s->GetGunKills(), - s->GetMissileKills(), - s->GetDeaths(), - s->GetColls(), - s->GetPoints(), - s->GetCommandPoints()); - - tk1 += s->GetGunKills(); - tk2 += s->GetMissileKills(); - td += s->GetDeaths(); - tc += s->GetColls(); - - CombatGroup* group = s->GetCombatGroup(); - - if (group) { - Combatant* c = group->GetCombatant(); - - if (c) - c->AddScore(s->GetPoints()); - - if (s->GetElementIndex() == 1) - group->SetSorties(group->Sorties() + 1); - - group->SetKills(group->Kills() + s->GetGunKills() + s->GetMissileKills()); - group->SetPoints(group->Points() + s->GetPoints()); - } - - if (s->IsPlayer()) { - Player* p = Player::GetCurrentPlayer(); - p->ProcessStats(s, start_time); - - if (mission && mission->Type() == Mission::TRAINING && - s->GetDeaths() == 0 && s->GetColls() == 0) - p->SetTrained(mission->Identity()); - - Player::Save(); // save training state right now before we forget! - } - } - - Print("--------------------------------------------\n"); - Print("TOTAL %5d %5d %5d %5d\n\n", tk1, tk2, td, tc); - - ShipStats::Initialize(); - } -} - -// +--------------------------------------------------------------------+ - -void -Sim::UnloadMission() -{ - if (netgame) { - delete netgame; - netgame = 0; - } - - HUDView* hud = HUDView::GetInstance(); - if (hud) - hud->HideAll(); - - ShipStats::Initialize(); - - events.destroy(); - mission_elements.destroy(); - elements.destroy(); - finished.destroy(); - - if (active_region) - active_region->Deactivate(); - - if (star_system) - star_system->Deactivate(); - - if (mission) { - mission->SetActive(false); - mission->SetComplete(true); - } - - regions.destroy(); - scene.Collect(); - - GRAPHIC_DESTROY(dust); - - star_system = 0; - active_region = 0; - mission = 0; - - // reclaim memory used by radio traffic: - RadioTraffic::DiscardMessages(); - - // release texture memory for 2D screens: - Video* video = Video::GetInstance(); - if (video) - video->InvalidateCache(); - - cam_dir = CameraDirector::GetInstance(); - if (cam_dir) - cam_dir->SetShip(0); - - AudioConfig::SetTraining(false); -} - -bool -Sim::IsActive() const -{ - return mission && mission->IsActive(); -} - -bool -Sim::IsComplete() const -{ - return mission && mission->IsComplete(); -} - -// +--------------------------------------------------------------------+ - -void -Sim::LoadMission(Mission* m, bool preload_textures) -{ - cam_dir = CameraDirector::GetInstance(); - - if (!mission) { - mission = m; - mission->SetActive(true); - - if (preload_textures) { - Video* video = Video::GetInstance(); - List all_models; - //List all_textures; - - ListIter elem_iter = mission->GetElements(); - while (++elem_iter) { - MissionElement* elem = elem_iter.value(); - const ShipDesign* design = elem->GetDesign(); - - if (design) { - for (int i = 0; i < 4; i++) { - List& models = (List&) design->models[i]; // cast-away const - - ListIter model_iter = models; - while (++model_iter) { - Model* model = model_iter.value(); - if (!all_models.contains(model)) { - all_models.append(model); - //model->GetAllTextures(all_textures); - - ListIter surf_iter = model->GetSurfaces(); - while (++surf_iter) { - Surface* surface = surf_iter.value(); - video->PreloadSurface(surface); - } - } - } - } - } - } - - /* - if (video && all_textures.size() > 0) { - ::Print("Preloading %d textures into video texture cache\n", all_textures.size()); - ListIter bmp_iter = all_textures; - while (++bmp_iter) { - Bitmap* bmp = bmp_iter.value(); - video->PreloadTexture(bmp); - } - } - */ - } - } -} - -void -Sim::ExecMission() -{ - cam_dir = CameraDirector::GetInstance(); - - if (!mission) { - Print("Sim::ExecMission() - No mission to execute.\n"); - return; - } - - if (elements.size() || finished.size()) { - Print("Sim::ExecMission(%s) mission is already executing.\n", mission->Name()); - return; - } - - Print("\nExec Mission: '%s'\n", (const char*) mission->Name()); - - if (cam_dir) - cam_dir->Reset(); - - if (mission->Stardate() > 0) - StarSystem::SetBaseTime(mission->Stardate(), true); - - star_system = mission->GetStarSystem(); - star_system->Activate(scene); - - int dust_factor = 0; - - if (Starshatter::GetInstance()) - dust_factor = Starshatter::GetInstance()->Dust(); - - if (star_system->NumDust() * dust_factor) { - dust = new Dust(star_system->NumDust() * 2*(dust_factor+1), dust_factor > 1); - scene.AddGraphic(dust); - } - - CreateRegions(); - BuildLinks(); - CreateElements(); - CopyEvents(); - - if (netgame) { - delete netgame; - netgame = 0; - } - - first_frame = true; - start_time = Clock::GetInstance()->GameTime(); - - AudioConfig::SetTraining(mission->Type() == Mission::TRAINING); -} - -// +--------------------------------------------------------------------+ - -void -Sim::CreateRegions() -{ - const char* active_region_name = 0; - - if (mission) - active_region_name = mission->GetRegion(); - else return; - - ListIter iter = mission->GetSystemList(); - while (++iter) { - StarSystem* sys = iter.value(); - - // insert objects from star system: - ListIter star = sys->Bodies(); - while (++star) { - ListIter planet = star->Satellites(); - while (++planet) { - ListIter moon = planet->Satellites(); - while (++moon) { - ListIter rgn = moon->Regions(); - while (++rgn) { - SimRegion* sim_region = new SimRegion(this, rgn.value()); - regions.append(sim_region); - if (!strcmp(active_region_name, sim_region->Name())) { - ActivateRegion(sim_region); - } - } - } - - ListIter rgn = planet->Regions(); - while (++rgn) { - SimRegion* sim_region = new SimRegion(this, rgn.value()); - regions.append(sim_region); - if (!strcmp(active_region_name, sim_region->Name())) { - ActivateRegion(sim_region); - } - } - } - - ListIter rgn = star->Regions(); - while (++rgn) { - SimRegion* sim_region = new SimRegion(this, rgn.value()); - regions.append(sim_region); - if (!strcmp(active_region_name, sim_region->Name())) { - ActivateRegion(sim_region); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Sim::BuildLinks() -{ - ListIter iter = regions; - while (++iter) { - SimRegion* rgn = iter.value(); - OrbitalRegion* orb = rgn->GetOrbitalRegion(); - - if (orb) { - ListIter lnk_iter = orb->Links(); - while (++lnk_iter) { - Text* t = lnk_iter.value(); - - SimRegion* tgt = FindRegion(*t); - - if (tgt && !rgn->Links().contains(tgt)) - rgn->Links().append(tgt); - } - } - } -} - -void -Sim::CreateElements() -{ - ListIter e_iter = mission->GetElements(); - while (++e_iter) { - MissionElement* msn_elem = e_iter.value(); - - // add element to a carrier? - if (msn_elem->IsSquadron()) { - Ship* carrier = FindShip(msn_elem->Carrier()); - if (carrier) { - Hangar* hangar = carrier->GetHangar(); - - if (hangar) { - int* def_load = 0; - - if (msn_elem->Loadouts().size()) { - MissionLoad* m = msn_elem->Loadouts().at(0); - - if (m->GetName().length()) { - ShipDesign* dsn = (ShipDesign*) msn_elem->GetDesign(); - ListIter sl_iter = dsn->loadouts; - while (++sl_iter) { - ShipLoad* sl = sl_iter.value(); - - if (m->GetName() == sl->name) - def_load = sl->load; - } - } - - if (!def_load) { - def_load = m->GetStations(); - } - } - - hangar->CreateSquadron(msn_elem->Name(), msn_elem->GetCombatGroup(), - msn_elem->GetDesign(), msn_elem->Count(), - msn_elem->GetIFF(), - def_load, msn_elem->MaintCount(), msn_elem->DeadCount()); - - Element* element = CreateElement(msn_elem->Name(), - msn_elem->GetIFF(), - msn_elem->MissionRole()); - - element->SetCarrier(carrier); - element->SetCombatGroup(msn_elem->GetCombatGroup()); - element->SetCombatUnit(msn_elem->GetCombatUnit()); - element->SetCount(msn_elem->Count()); - element->SetRogue(false); - element->SetPlayable(false); - element->SetLoadout(def_load); - } - } - } - - // create the element in space: - else { - Ship* carrier = 0; - Hangar* hangar = 0; - int squadron = -1; - int slot = 0; - - // first create the package element: - Element* element = CreateElement(msn_elem->Name(), - msn_elem->GetIFF(), - msn_elem->MissionRole()); - - element->SetPlayer(msn_elem->Player()); - element->SetCombatGroup(msn_elem->GetCombatGroup()); - element->SetCombatUnit(msn_elem->GetCombatUnit()); - element->SetCommandAILevel(msn_elem->CommandAI()); - element->SetHoldTime(msn_elem->HoldTime()); - element->SetZoneLock(msn_elem->ZoneLock() ? true : false); - element->SetRogue(msn_elem->IsRogue()); - element->SetPlayable(msn_elem->IsPlayable()); - element->SetIntelLevel(msn_elem->IntelLevel()); - - // if this is the player's element, make sure to activate the region: - if (msn_elem->Player()) { - SimRegion* rgn = FindRegion(msn_elem->Region()); - - if (rgn && rgn != active_region) - ActivateRegion(rgn); - } - - // if element belongs to a squadron, - // find the carrier, squadron, flight deck, etc.: - if (msn_elem->Squadron().length() > 0) { - MissionElement* squadron_elem = mission->FindElement(msn_elem->Squadron()); - - if (squadron_elem) { - element->SetSquadron(msn_elem->Squadron()); - - Element* cmdr = FindElement(squadron_elem->Carrier()); - - if (cmdr) { - element->SetCommander(cmdr); - carrier = cmdr->GetShip(1); - - if (carrier) { - element->SetCarrier(carrier); - hangar = carrier->GetHangar(); - - for (int s = 0; s < hangar->NumSquadrons(); s++) { - if (hangar->SquadronName(s) == msn_elem->Squadron()) { - squadron = s; - break; - } - } - } - } - } - } - - else if (msn_elem->Commander().length() > 0) { - Element* cmdr = FindElement(msn_elem->Commander()); - - if (cmdr) { - element->SetCommander(cmdr); - } - } - - ListIter obj = msn_elem->Objectives(); - while (++obj) { - Instruction* o = obj.value(); - Instruction* instr = 0; - - instr = new Instruction(*o); - - element->AddObjective(instr); - } - - if (msn_elem->Instructions().size() > 0) { - ListIter instr = msn_elem->Instructions(); - while (++instr) { - element->AddInstruction(*instr); - } - } - - ListIter nav = msn_elem->NavList(); - while (++nav) { - SimRegion* rgn = FindRegion(nav->RegionName()); - - if (!rgn) - rgn = FindRegion(msn_elem->Region()); - - if (rgn) { - Instruction* npt = new - Instruction(rgn, nav->Location(), nav->Action()); - - npt->SetStatus(nav->Status()); - npt->SetEMCON(nav->EMCON()); - npt->SetFormation(nav->Formation()); - npt->SetSpeed(nav->Speed()); - npt->SetTarget(nav->TargetName()); - npt->SetHoldTime(nav->HoldTime()); - npt->SetFarcast(nav->Farcast()); - - element->AddNavPoint(npt); - } - } - - bool alertPrep = false; - int* loadout = 0; - int respawns = msn_elem->RespawnCount(); - - // if ships are to start on alert, - // spot them onto the appropriate launch deck: - if (hangar && element && msn_elem->Count() > 0 && msn_elem->IsAlert()) { - FlightDeck* deck = 0; - int queue = 1000; - const ShipDesign* dsn = msn_elem->GetDesign(); - - if (dsn) { - for (int i = 0; i < carrier->NumFlightDecks(); i++) { - FlightDeck* d = carrier->GetFlightDeck(i); - int dq = hangar->PreflightQueue(d); - - if (d && d->IsLaunchDeck() && d->SpaceLeft(dsn->type) && dq < queue) { - queue = dq; - deck = d; - } - } - } - - if (deck) { - alertPrep = true; - - // choose best loadout: - if (msn_elem->Loadouts().size()) { - MissionLoad* l = msn_elem->Loadouts().at(0); - if (l->GetName().length()) { - ListIter sl = ((ShipDesign*) dsn)->loadouts; - while (++sl) { - if (!_stricmp(sl->name, l->GetName())) - loadout = sl->load; - } - } - - else { - loadout = l->GetStations(); - } - } - - element->SetLoadout(loadout); - - for (int i = 0; i < msn_elem->Count(); i++) { - int squadron = -1; - int slot = -1; - - if (hangar->FindAvailSlot(msn_elem->GetDesign(), squadron, slot)) { - alertPrep = alertPrep && - hangar->GotoAlert(squadron, - slot, - deck, - element, - loadout, - true, // package for launch - true); // expedite - - HangarSlot* s = (HangarSlot*) hangar->GetSlot(squadron, slot); - Ship* alertShip = hangar->GetShip(s); - - if (alertShip) { - alertShip->SetRespawnCount(respawns); - - if (msn_elem->Player() == i+1) { - if (alertShip->GetRegion()) { - alertShip->GetRegion()->SetPlayerShip(alertShip); - } - else { - ::Print("WARNING: alert ship '%s' region is null\n", alertShip->Name()); - } - } - } - } - } - } - } - - if (!alertPrep) { - // then, create the ships: - for (int i = 0; i < msn_elem->Count(); i++) { - MissionShip* msn_ship = 0; - Text sname = msn_elem->GetShipName(i); - Text rnum = msn_elem->GetRegistry(i); - Text rgn_name = msn_elem->Region(); - - if (msn_elem->Ships().size() > i) { - msn_ship = msn_elem->Ships()[i]; - sname = msn_ship->Name(); - rnum = msn_ship->RegNum(); - rgn_name = msn_ship->Region(); - } - - Point l2 = msn_elem->Location(); - - if (msn_ship && fabs(msn_ship->Location().x) < 1e9) { - l2 = msn_ship->Location(); - } - else if (i) { - Point offset = RandomPoint(); - offset.z = Random(-1e3, 1e3); - - if (msn_elem->Count() < 5) - offset *= 0.3; - - l2 += offset; - } - - // choose best loadout: - ListIter l = msn_elem->Loadouts(); - while (++l) { - if ((l->GetShip() == i) || (l->GetShip() < 0 && loadout == 0)) { - if (l->GetName().length()) { - ListIter sl = ((ShipDesign*) msn_elem->GetDesign())->loadouts; - while (++sl) { - if (!_stricmp(sl->name, l->GetName())) - loadout = sl->load; - } - } - - else { - loadout = l->GetStations(); - } - } - } - - element->SetLoadout(loadout); - - Ship* ship = CreateShip(sname, rnum, - (ShipDesign*) msn_elem->GetDesign(), - rgn_name, l2, - msn_elem->GetIFF(), - msn_elem->CommandAI(), - loadout); - - if (ship) { - double heading = msn_elem->Heading(); - const Skin* skin = msn_elem->GetSkin(); - - if (msn_ship) { - heading = msn_ship->Heading(); - - if (msn_ship->GetSkin()) - skin = msn_ship->GetSkin(); - } - - ship->SetRogue(msn_elem->IsRogue()); - ship->SetInvulnerable(msn_elem->IsInvulnerable()); - ship->SetHeading(0, 0, heading + PI); - ship->SetRespawnCount(respawns); - ship->UseSkin(skin); - - if (!netgame) - ship->SetRespawnLoc(RandomPoint() * 2); - - if (ship->IsStarship()) - ship->SetHelmHeading(heading); - - else if (ship->IsAirborne() && ship->AltitudeAGL() > 25) - ship->SetVelocity(ship->Heading() * 250); - - if (element) - element->AddShip(ship); - - if (hangar) - hangar->FindSlot(ship, squadron, slot, Hangar::ACTIVE); - - if (ship->GetRegion() && msn_elem->Player() == i+1) - ship->GetRegion()->SetPlayerShip(ship); - - if (ship->NumFlightDecks()) { - for (int i = 0; i < ship->NumFlightDecks(); i++) { - FlightDeck* deck = ship->GetFlightDeck(i); - if (deck) - deck->Orient(ship); - } - } - - if (msn_ship) { - ship->SetVelocity(msn_ship->Velocity().OtherHand()); - ship->SetIntegrity((float) msn_ship->Integrity()); - ship->SetRespawnCount(msn_ship->Respawns()); - - if (msn_ship->Ammo()[0] > -10) { - for (int i = 0; i < 64; i++) { - Weapon* w = ship->GetWeaponByIndex(i+1); - if (w) - w->SetAmmo(msn_ship->Ammo()[i]); - else - break; - } - } - - if (msn_ship->Fuel()[0] > -10) { - for (int i = 0; i < 4; i++) { - if (ship->Reactors().size() > i) { - PowerSource* p = ship->Reactors()[i]; - p->SetCapacity(msn_ship->Fuel()[i]); - } - } - } - - if (msn_ship->Decoys() > -10) { - Weapon* w = ship->GetDecoy(); - if (w) - w->SetAmmo(msn_ship->Decoys()); - } - - if (msn_ship->Probes() > -10) { - Weapon* w = ship->GetProbeLauncher(); - if (w) - w->SetAmmo(msn_ship->Probes()); - } - } - - Shield* shield = ship->GetShield(); - - if (shield) { - shield->SetPowerLevel(50); - } - - if (ship->Class() > Ship::FRIGATE) { - ListIter iter = ship->Weapons(); - while (++iter) { - WeaponGroup* weapon = iter.value(); - - // anti-air weapon? - if (weapon->GetDesign()->target_type & Ship::DRONE) { - weapon->SetFiringOrders(Weapon::POINT_DEFENSE); - } - else { - weapon->SetFiringOrders(Weapon::MANUAL); - } - } - } - - if (ship->Class() > Ship::DRONE && ship->Class() < Ship::STATION) { - ShipStats* stats = ShipStats::Find(sname); - if (stats) { - char design[64]; - sprintf_s(design, "%s %s", ship->Abbreviation(), ship->Design()->display_name); - stats->SetType(design); - stats->SetShipClass(ship->Class()); - stats->SetRole(Mission::RoleName(msn_elem->MissionRole())); - stats->SetIFF(ship->GetIFF()); - stats->SetRegion(msn_elem->Region()); - stats->SetCombatGroup(msn_elem->GetCombatGroup()); - stats->SetCombatUnit(msn_elem->GetCombatUnit()); - stats->SetPlayer(msn_elem->Player() == i+1); - stats->SetElementIndex(ship->GetElementIndex()); - } - } - } // ship - } // count - } - } - } -} - -void -Sim::CopyEvents() -{ - events.destroy(); - - if (mission) { - ListIter iter = mission->GetEvents(); - while (++iter) { - MissionEvent* orig = iter.value(); - MissionEvent* event = new MissionEvent(*orig); - events.append(event); - } - } -} - -// +--------------------------------------------------------------------+ - -const char* -Sim::FindAvailCallsign(int IFF) -{ - const char* call = "Unidentified"; - - for (int i = 0; i < 32; i++) { - call = Callsign::GetCallsign(IFF); - - if (!FindElement(call)) - break; - } - - return call; -} - -Element* -Sim::CreateElement(const char* callsign, int IFF, int type) -{ - Element* elem = new Element(callsign, IFF, type); - elements.append(elem); - return elem; -} - -void -Sim::DestroyElement(Element* elem) -{ - if (elements.contains(elem)) - elements.remove(elem); - - delete elem; -} - -Element* -Sim::FindElement(const char* name) -{ - ListIter iter = elements; - - while (++iter) { - Element* elem = iter.value(); - Text ename = elem->Name(); - - if (ename == name) - return elem; - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -int -Sim::GetAssignedElements(Element* elem, List& assigned) -{ - assigned.clear(); - - if (elem) { - for (int i = 0; i < elements.size(); i++) { - Element* e = elements.at(i); - if (!e->IsSquadron() && e->GetAssignment() == elem) - assigned.append(e); - } - } - - return assigned.size(); -} - -// +--------------------------------------------------------------------+ - -Ship* -Sim::CreateShip(const char* name, const char* reg_num, ShipDesign* design, const char* rgn_name, const Point& loc, int IFF, int cmd_ai, const int* loadout) -{ - if (!design) { - Print("WARNING: CreateShip(%s): invalid design\n", name); - return 0; - } - - SimRegion* rgn = FindRegion(rgn_name); - - if (!rgn) { - return 0; - } - - Ship* ship = new Ship(name, reg_num, design, IFF, cmd_ai, loadout); - ship->MoveTo(loc.OtherHand()); - - if (rgn) { - Print("Inserting Ship(%s) into Region(%s) (%s)\n", ship->Name(), rgn->Name(), FormatGameTime()); - rgn->InsertObject(ship); - - if (ship->IsAirborne() && ship->AltitudeAGL() > 25) - ship->SetVelocity(ship->Heading() * 250); - } - - return ship; -} - -Ship* -Sim::FindShip(const char* name, const char* rgn_name) -{ - Ship* ship = 0; - - if (rgn_name) { - SimRegion* rgn = FindRegion(rgn_name); - if (rgn) - ship = rgn->FindShip(name); - } - - if (!ship) { - ListIter rgn = regions; - while (++rgn && !ship) - ship = rgn->FindShip(name); - } - - return ship; -} - -void -Sim::DestroyShip(Ship* ship) -{ - SimRegion* rgn = ship->GetRegion(); - if (rgn) - rgn->DestroyShip(ship); -} - -void -Sim::NetDockShip(Ship* ship, Ship* carrier, FlightDeck* deck) -{ - SimRegion* rgn = ship->GetRegion(); - if (rgn) - rgn->NetDockShip(ship, carrier, deck); -} - -Ship* -Sim::FindShipByObjID(DWORD objid) -{ - Ship* ship = 0; - - ListIter rgn = regions; - while (++rgn && !ship) - ship = rgn->FindShipByObjID(objid); - - return ship; -} - -Shot* -Sim::FindShotByObjID(DWORD objid) -{ - Shot* shot = 0; - - ListIter rgn = regions; - while (++rgn && !shot) - shot = rgn->FindShotByObjID(objid); - - return shot; -} - -// +--------------------------------------------------------------------+ - -Orbital* -Sim::FindOrbitalBody(const char* name) -{ - Orbital* body = 0; - - if (mission) { - ListIter iter = mission->GetSystemList(); - while (++iter && !body) { - StarSystem* sys = iter.value(); - body = sys->FindOrbital(name); - } - } - - return body; -} - - -// +--------------------------------------------------------------------+ - -Shot* -Sim::CreateShot(const Point& pos, const Camera& shot_cam, WeaponDesign* design, const Ship* ship, SimRegion* rgn) -{ - Shot* shot = 0; - - if (design->drone) - shot = new Drone(pos, shot_cam, design, ship); - else - shot = new Shot( pos, shot_cam, design, ship); - - if (rgn) - rgn->InsertObject(shot); - - else if (active_region) - active_region->InsertObject(shot); - - return shot; -} - -// +--------------------------------------------------------------------+ - -Explosion* -Sim::CreateExplosion(const Point& pos, const Point& vel, int type, float exp_scale, float part_scale, SimRegion* rgn, SimObject* source, System* sys) -{ - // don't bother creating explosions that can't be seen: - if (!rgn || !active_region || rgn != active_region) - return 0; - - Explosion* exp = new Explosion(type, pos, vel, exp_scale, part_scale, rgn, source); - - if (rgn) - rgn->InsertObject(exp); - - else if (active_region) - active_region->InsertObject(exp); - - return exp; -} - -// +--------------------------------------------------------------------+ - -Debris* -Sim::CreateDebris(const Point& pos, const Point& vel, Model* model, double mass, SimRegion* rgn) -{ - Debris* debris = new Debris(model, pos, vel, mass); - - if (rgn) - rgn->InsertObject(debris); - - else if (active_region) - active_region->InsertObject(debris); - - return debris; -} - -// +--------------------------------------------------------------------+ - -Asteroid* -Sim::CreateAsteroid(const Point& pos, int t, double mass, SimRegion* rgn) -{ - Asteroid* asteroid = new Asteroid(t, pos, mass); - - if (rgn) - rgn->InsertObject(asteroid); - - else if (active_region) - active_region->InsertObject(asteroid); - - return asteroid; -} - -// +--------------------------------------------------------------------+ - -void -Sim::CreateSplashDamage(Ship* ship) -{ - if (ship && ship->GetRegion() && ship->Design()->splash_radius > 1) { - SimSplash* splash = new - SimSplash(ship->GetRegion(), - ship->Location(), - ship->Design()->integrity / 4, - ship->Design()->splash_radius); - - splash->owner_name = ship->Name(); - splashlist.append(splash); - } -} - -// +--------------------------------------------------------------------+ - -void -Sim::CreateSplashDamage(Shot* shot) -{ - if (shot && shot->GetRegion()) { - double damage = shot->Damage(); - if (damage < shot->Design()->damage) - damage = shot->Design()->damage; - - SimSplash* splash = new - SimSplash(shot->GetRegion(), - shot->Location(), - damage, - shot->Design()->lethal_radius); - - if (shot->Owner()) - splash->owner_name = shot->Owner()->Name(); - - splash->missile = shot->IsMissile(); - - splashlist.append(splash); - CreateExplosion(shot->Location(), Point(), Explosion::SHOT_BLAST, 20.0f, 1.0f, shot->GetRegion()); - } -} - -// +--------------------------------------------------------------------+ - -void -Sim::ShowGrid(int show) -{ - Player* player = Player::GetCurrentPlayer(); - - if (player && player->GridMode() == 0) { - show = 0; - grid_shown = false; - } - - ListIter rgn = regions; - while (++rgn) { - rgn->ShowGrid(show); - } - - grid_shown = show?true:false; -} - -bool -Sim::GridShown() const -{ - return grid_shown; -} - -// +--------------------------------------------------------------------+ - -List& -Sim::GetSystemList() -{ - if (mission) - return mission->GetSystemList(); - - static List dummy_system_list; - return dummy_system_list; -} - -// +--------------------------------------------------------------------+ - -void -Sim::NextView() -{ - if (active_region) - active_region->NextView(); -} - -Ship* -Sim::GetPlayerShip() -{ - if (active_region) - return active_region->GetPlayerShip(); - - Starshatter* stars = Starshatter::GetInstance(); - if (stars && stars->InCutscene()) { - Ship* player = 0; - - ListIter rgn = regions; - while (++rgn && !player) { - player = rgn->GetPlayerShip(); - } - - return player; - } - - return 0; -} - -Element* -Sim::GetPlayerElement() -{ - Element* elem = 0; - - for (int i = 0; i < elements.size(); i++) { - Element* e = elements[i]; - - if (e->Player() > 0) - elem = e; - } - - return elem; -} - -bool -Sim::IsSelected(Ship* s) -{ - if (active_region) - return active_region->IsSelected(s); - - return false; -} - -ListIter -Sim::GetSelection() -{ - if (active_region) - return active_region->GetSelection(); - - static List empty; - return empty; -} - -void -Sim::ClearSelection() -{ - if (active_region) - active_region->ClearSelection(); -} - -void -Sim::AddSelection(Ship* s) -{ - if (active_region) - active_region->AddSelection(s); -} - -void -Sim::SetSelection(Ship* newsel) -{ - if (active_region) - active_region->SetSelection(newsel); -} - -// +--------------------------------------------------------------------+ - -void -Sim::SetTestMode(bool t) -{ - test_mode = t; - Ship* pship = GetPlayerShip(); - - if (pship) - if (IsTestMode()) - pship->SetControls(0); - else - pship->SetControls(ctrl); -} - -// +--------------------------------------------------------------------+ - -SimRegion* -Sim::FindRegion(const char* name) -{ - ListIter rgn = regions; - while (++rgn) - if (rgn->name == name) - return rgn.value(); - - return 0; -} - -SimRegion* -Sim::FindRegion(OrbitalRegion* orgn) -{ - ListIter rgn = regions; - while (++rgn) - if (rgn->orbital_region == orgn) - return rgn.value(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -SimRegion* -Sim::FindNearestSpaceRegion(SimObject* object) -{ - return FindNearestRegion(object, REAL_SPACE); -} - -SimRegion* -Sim::FindNearestTerrainRegion(SimObject* object) -{ - return FindNearestRegion(object, AIR_SPACE); -} - -SimRegion* -Sim::FindNearestRegion(SimObject* object, int type) -{ - if (!object) return 0; - - SimRegion* result = 0; - double distance = 1.0e40; - Point objloc = object->Location(); - - objloc = objloc.OtherHand(); - - if (object->GetRegion()) - objloc += object->GetRegion()->Location(); - - ListIter rgn = regions; - while (++rgn) { - if (rgn->Type() == type) { - OrbitalRegion* orgn = rgn->GetOrbitalRegion(); - if (orgn) { - double test = fabs((orgn->Location() - objloc).length()); - if (test < distance) { - result = rgn.value(); - distance = test; - } - } - } - } - - return result; -} - -SimRegion* -Sim::FindNearestSpaceRegion(Orbital* body) -{ - SimRegion* result = 0; - - if (!body) - return result; - - ListIter rgn = regions; - while (++rgn && !result) { - if (rgn->IsOrbital()) { - OrbitalRegion* orgn = rgn->GetOrbitalRegion(); - if (orgn) { - ListIter iter = body->Regions(); - while (++iter) { - if (iter.value() == orgn) - result = rgn.value(); - } - } - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -bool -Sim::ActivateRegion(SimRegion* rgn) -{ - if (rgn && active_region != rgn && regions.contains(rgn)) { - if (active_region) - active_region->Deactivate(); - - if (!active_region || active_region->System() != rgn->System()) { - if (active_region) - active_region->System()->Deactivate(); - rgn->System()->Activate(scene); - } - - active_region = rgn; - star_system = active_region->System(); - - if (star_system) { - star_system->SetActiveRegion(active_region->orbital_region); - } - else { - ::Print("WARNING: Sim::ActivateRegion() No star system found for rgn '%s'", rgn->Name()); - } - - active_region->Activate(); - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -void -Sim::RequestHyperJump(Ship* obj, SimRegion* rgn, const Point& loc, -int type, Ship* fc1, Ship* fc2) -{ - bool hyperdrive = false; - - if (obj->GetQuantumDrive() && obj->GetQuantumDrive()->Subtype() == QuantumDrive::HYPER) - hyperdrive = true; - - jumplist.append(new SimHyper(obj, rgn, loc, type, hyperdrive, fc1, fc2)); -} - -// +--------------------------------------------------------------------+ - -void -Sim::ExecFrame(double seconds) -{ - if (first_frame) { - first_frame = false; - netgame = NetGame::Create(); - } - - if (netgame) - netgame->ExecFrame(); - - if (regions.isEmpty()) { - active_region = 0; - rgn_queue.clear(); - jumplist.destroy(); - scene.Collect(); - return; - } - - ListIter elem = elements; - while (++elem) - if (!elem->IsSquadron()) - elem->ExecFrame(seconds); - - ListIter rgn = regions; - while (++rgn) - if (rgn.value() != active_region && rgn->NumShips() && !rgn_queue.contains(rgn.value())) - rgn_queue.append(rgn.value()); - - // execframe for one inactive sim region: - if (rgn_queue.size()) { - SimRegion* exec_rgn = rgn_queue.removeIndex(0); - - while (exec_rgn && (exec_rgn->NumShips() == 0 || exec_rgn == active_region)) - if (rgn_queue.size()) - exec_rgn = rgn_queue.removeIndex(0); - else - exec_rgn = 0; - - if (exec_rgn) - exec_rgn->ExecFrame(seconds); - } - - if (active_region) - active_region->ExecFrame(seconds); - - ExecEvents(seconds); - ResolveHyperList(); - ResolveSplashList(); - - // GC all the dead objects: - scene.Collect(); - - if (!IsTestMode()) { - ListIter e_iter = elements; - while (++e_iter) { - Element* elem = e_iter.value(); - if (!elem->IsSquadron() && elem->IsFinished()) { - finished.append(e_iter.removeItem()); - } - } - } - - // setup music - if (!MusicDirector::IsNoMusic()) { - Starshatter* stars = Starshatter::GetInstance(); - if (stars && stars->GetGameMode() == Starshatter::PLAY_MODE) { - Ship* player_ship = GetPlayerShip(); - if (player_ship) { - int phase = player_ship->GetFlightPhase(); - - if (phase < Ship::ACTIVE) { - MusicDirector::SetMode(MusicDirector::LAUNCH); - } - - else if (phase > Ship::ACTIVE) { - MusicDirector::SetMode(MusicDirector::RECOVERY); - } - - else { - if (player_ship->IsInCombat()) { - MusicDirector::SetMode(MusicDirector::COMBAT); - } - - else { - MusicDirector::SetMode(MusicDirector::FLIGHT); - } - } - } - } - } -} - -void -Sim::ExecEvents(double seconds) -{ - ListIter iter = events; - while (++iter) { - MissionEvent* event = iter.value(); - event->ExecFrame(seconds); - } -} - -void -Sim::ResolveHyperList() -{ - // resolve the hyper space transitions: - if (jumplist.size()) { - Ship* pship = GetPlayerShip(); - - ListIter j_iter = jumplist; - while (++j_iter) { - SimHyper* jump = j_iter.value(); - Ship* jumpship = jump->ship; - - if (jumpship) { - SimRegion* dest = jump->rgn; - - if (!dest) - dest = FindNearestSpaceRegion(jumpship); - - if (dest) { - // bring along fighters on deck: - ListIter deck = jumpship->FlightDecks(); - while (++deck) { - for (int i = 0; i < deck->NumSlots(); i++) { - Ship* s = deck->GetShip(i); - - if (s) { - dest->InsertObject(s); - s->ClearTrack(); - } - } - } - - if (jump->type == 0 && !jump->hyperdrive) { - // bring along nearby ships: - // have to do it in two parts, because inserting the ships - // into the destination corrupts the iter over the current - // region's list of ships... - - // part one: gather the ships that will be jumping: - List riders; - ListIter neighbor = jumpship->GetRegion()->Ships(); - while (++neighbor) { - if (neighbor->IsDropship()) { - Ship* s = neighbor.value(); - if (s == jumpship) continue; - - Point delta = s->Location() - jumpship->Location(); - - if (delta.length() < 5e3) { - riders.append(s); - } - } - } - - // part two: now transfer the list to the destination: - for (int i = 0; i < riders.size(); i++) { - Ship* s = riders[i]; - Point delta = s->Location() - jumpship->Location(); - dest->InsertObject(s); - s->MoveTo(jump->loc.OtherHand() + delta); - s->ClearTrack(); - - if (jump->fc_dst) { - double r = jump->fc_dst->Roll(); - double p = jump->fc_dst->Pitch(); - double w = jump->fc_dst->Yaw(); - - s->SetAbsoluteOrientation(r, p, w); - s->SetVelocity(jump->fc_dst->Heading() * 500); - } - - ProcessEventTrigger(MissionEvent::TRIGGER_JUMP, 0, s->Name()); - } - } - - // now it is safe to move the main jump ship: - dest->InsertObject(jumpship); - jumpship->MoveTo(jump->loc.OtherHand()); - jumpship->ClearTrack(); - - ProcessEventTrigger(MissionEvent::TRIGGER_JUMP, 0, jumpship->Name()); - NetUtil::SendObjHyper(jumpship, dest->Name(), jump->loc, jump->fc_src, jump->fc_dst, jump->type); - - // if using farcaster: - if (jump->fc_src) { - ::Print("Ship '%s' farcast to '%s'\n", jumpship->Name(), dest->Name()); - CreateExplosion(jumpship->Location(), Point(0,0,0), Explosion::QUANTUM_FLASH, 1.0f, 0, dest); - - if (jump->fc_dst) { - double r = jump->fc_dst->Roll(); - double p = jump->fc_dst->Pitch(); - double w = jump->fc_dst->Yaw(); - - jumpship->SetAbsoluteOrientation(r, p, w); - jumpship->SetVelocity(jump->fc_dst->Heading() * 500); - } - - jumpship->SetHelmHeading(jumpship->CompassHeading()); - jumpship->SetHelmPitch(0); - } - - // break orbit: - else if (jump->type == Ship::TRANSITION_DROP_ORBIT) { - ::Print("Ship '%s' broke orbit to '%s'\n", jumpship->Name(), dest->Name()); - jumpship->SetAbsoluteOrientation(0,PI/4,0); - jumpship->SetVelocity(jumpship->Heading() * 1.0e3); - } - - // make orbit: - else if (jump->type == Ship::TRANSITION_MAKE_ORBIT) { - ::Print("Ship '%s' achieved orbit '%s'\n", jumpship->Name(), dest->Name()); - jumpship->LookAt(Point(0,0,0)); - jumpship->SetVelocity(jumpship->Heading() * 500.0); - } - - // hyper jump: - else { - ::Print("Ship '%s' quantum to '%s'\n", jumpship->Name(), dest->Name()); - - if (jump->hyperdrive) - CreateExplosion(jumpship->Location(), Point(0,0,0), Explosion::HYPER_FLASH, 1, 1, dest); - else - CreateExplosion(jumpship->Location(), Point(0,0,0), Explosion::QUANTUM_FLASH, 1, 0, dest); - - jumpship->LookAt(Point(0,0,0)); - jumpship->SetVelocity(jumpship->Heading() * 500.0); - jumpship->SetHelmHeading(jumpship->CompassHeading()); - jumpship->SetHelmPitch(0); - } - } - - else if (regions.size() > 1) { - ::Print("Warning: Unusual jump request for ship '%s'\n", jumpship->Name()); - regions[1]->InsertObject(jumpship); - } - - Sensor* sensor = jumpship->GetSensor(); - if (sensor) - sensor->ClearAllContacts(); - } - } - - jumplist.destroy(); - - if (pship && pship->GetRegion()) { - if (active_region != pship->GetRegion()) { - pship->GetRegion()->SetPlayerShip(pship); - } - } - } -} - -void -Sim::ResolveSplashList() -{ - if (splashlist.size()) { - ListIter iter = splashlist; - while (++iter) { - SimSplash* splash = iter.value(); - - if (!splash->rgn) - continue; - - // damage ships: - ListIter s_iter = splash->rgn->Ships(); - while (++s_iter) { - Ship* ship = s_iter.value(); - - double distance = (ship->Location() - splash->loc).length(); - - if (distance > 1 && distance < splash->range) { - double damage = splash->damage * (1 - distance/splash->range); - if (!NetGame::IsNetGameClient()) { - ship->InflictDamage(damage); - } - - int ship_destroyed = (!ship->InTransition() && ship->Integrity() < 1.0f); - - // then delete the ship: - if (ship_destroyed) { - NetUtil::SendObjKill(ship, 0, NetObjKill::KILL_MISC); - Print(" %s Killed %s (%s)\n", (const char*) splash->owner_name, ship->Name(), FormatGameTime()); - - // record the kill - ShipStats* killer = ShipStats::Find(splash->owner_name); - if (killer) { - if (splash->missile) - killer->AddEvent(SimEvent::MISSILE_KILL, ship->Name()); - else - killer->AddEvent(SimEvent::GUNS_KILL, ship->Name()); - } - - Ship* owner = FindShip(splash->owner_name, splash->rgn->Name()); - if (owner && owner->GetIFF() != ship->GetIFF()) { - if (ship->GetIFF() > 0 || owner->GetIFF() > 1) { - killer->AddPoints(ship->Value()); - - Element* elem = owner->GetElement(); - if (elem) { - if (owner->GetElementIndex() > 1) { - Ship* s = elem->GetShip(1); - - if (s) { - ShipStats* cmdr_stats = ShipStats::Find(s->Name()); - if (cmdr_stats) { - cmdr_stats->AddCommandPoints(ship->Value()/2); - } - } - } - - Element* cmdr = elem->GetCommander(); - if (cmdr) { - Ship* s = cmdr->GetShip(1); - - if (s) { - ShipStats* cmdr_stats = ShipStats::Find(s->Name()); - if (cmdr_stats) { - cmdr_stats->AddCommandPoints(ship->Value()/2); - } - } - } - } - } - } - - ShipStats* killee = ShipStats::Find(ship->Name()); - if (killee) - killee->AddEvent(SimEvent::DESTROYED, splash->owner_name); - - ship->DeathSpiral(); - } - } - } - - // damage drones: - ListIter drone_iter = splash->rgn->Drones(); - while (++drone_iter) { - Drone* drone = drone_iter.value(); - - double distance = (drone->Location() - splash->loc).length(); - - if (distance > 1 && distance < splash->range) { - double damage = splash->damage * (1 - distance/splash->range); - drone->InflictDamage(damage); - - int destroyed = (drone->Integrity() < 1.0f); - - // then mark the drone for deletion: - if (destroyed) { - NetUtil::SendWepDestroy(drone); - sim->CreateExplosion(drone->Location(), drone->Velocity(), 21 /* was LARGE_EXP */, 1.0f, 1.0f, splash->rgn); - drone->SetLife(0); - } - } - } - } - - splashlist.destroy(); - } -} - -// +--------------------------------------------------------------------+ - -void -Sim::ProcessEventTrigger(int type, int event_id, const char* ship, int param) -{ - Text ship_name = ship; - - ListIter iter = events; - while (++iter) { - MissionEvent* event = iter.value(); - - if (event->IsPending() && event->Trigger() == type) { - switch (type) { - case MissionEvent::TRIGGER_DAMAGE: - case MissionEvent::TRIGGER_DESTROYED: - case MissionEvent::TRIGGER_JUMP: - case MissionEvent::TRIGGER_LAUNCH: - case MissionEvent::TRIGGER_DOCK: - case MissionEvent::TRIGGER_TARGET: - if (event->TriggerParam() <= param) { - if (ship_name.indexOf(event->TriggerShip()) == 0) - event->Activate(); - } - break; - - case MissionEvent::TRIGGER_NAVPT: - if (event->TriggerParam() == param) { - if (ship_name.indexOf(event->TriggerShip()) == 0) - event->Activate(); - } - break; - - case MissionEvent::TRIGGER_EVENT: - case MissionEvent::TRIGGER_SKIPPED: - if (event->TriggerParam() == event_id) - event->Activate(); - break; - } - } - } -} - -double -Sim::MissionClock() const -{ - return (Clock::GetInstance()->GameTime() - start_time) / 1000.0; -} - -// +--------------------------------------------------------------------+ - -void -Sim::SkipCutscene() -{ - Starshatter* stars = Starshatter::GetInstance(); - if (stars && stars->InCutscene()) { - ListIter iter = events; - bool end = false; - double end_time = 0; - - while (++iter && !end) { - MissionEvent* event = iter.value(); - - if (event->IsPending() || event->IsActive()) { - if (event->Event() == MissionEvent::END_SCENE || - event->Event() == MissionEvent::END_MISSION) { - end = true; - end_time = event->Time(); - } - - if (event->Event() == MissionEvent::FIRE_WEAPON) { - event->Skip(); - } - - else { - event->Activate(); - event->Execute(true); - } - } - } - - double skip_time = end_time - MissionClock(); - if (skip_time > 0) { - Clock::GetInstance()->SkipGameTime(skip_time); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Sim::ResolveTimeSkip(double seconds) -{ - double skipped = 0; - - // allow elements to process hold time, and release as needed: - ListIter elem = elements; - while (++elem) - elem->ExecFrame(seconds); - - // step through the skip, ten seconds at a time: - if (active_region) { - double total_skip = seconds; - double frame_skip = 10; - Ship* player = GetPlayerShip(); - - while (total_skip > frame_skip) { - if (active_region->CanTimeSkip()) { - active_region->ResolveTimeSkip(frame_skip); - total_skip -= frame_skip; - skipped += frame_skip; - } - // break out early if player runs into bad guys... - else { - total_skip = 0; - } - } - - if (total_skip > 0) - active_region->ResolveTimeSkip(total_skip); - skipped += total_skip; - } - - // give player control after time skip: - Ship* player_ship = GetPlayerShip(); - if (player_ship) { - player_ship->SetAutoNav(false); - player_ship->SetThrottle(75); - - HUDView* hud = HUDView::GetInstance(); - if (hud) - hud->SetHUDMode(HUDView::HUD_MODE_TAC); - - if (IsTestMode()) - player_ship->SetControls(0); - } - - Clock::GetInstance()->SkipGameTime(skipped); - CameraDirector::SetCameraMode(CameraDirector::MODE_COCKPIT); -} - -// +--------------------------------------------------------------------+ - -ListIter -Sim::GetMissionElements() -{ - mission_elements.destroy(); - - ListIter iter = elements; - while (++iter) { - Element* elem = iter.value(); - - int num_live_ships = 0; - - for (int i = 0; i < elem->NumShips(); i++) { - Ship* s = elem->GetShip(i+1); - - if (s && !s->IsDying() && !s->IsDead()) - num_live_ships++; - } - - if (elem->IsSquadron() || num_live_ships > 0) { - MissionElement* msn_elem = CreateMissionElement(elem); - - if (msn_elem) - mission_elements.append(msn_elem); - } - } - - return mission_elements; -} - -MissionElement* -Sim::CreateMissionElement(Element* elem) -{ - MissionElement* msn_elem = 0; - - if (elem->IsSquadron()) { - if (!elem->GetCarrier() || elem->GetCarrier()->Integrity() < 1) - return msn_elem; - } - - if (elem && !elem->IsNetObserver()) { - msn_elem = new MissionElement; - - msn_elem->SetName(elem->Name()); - msn_elem->SetIFF(elem->GetIFF()); - msn_elem->SetMissionRole(elem->Type()); - - if (elem->IsSquadron() && elem->GetCarrier()) { - Ship* carrier = elem->GetCarrier(); - - msn_elem->SetCarrier(carrier->Name()); - msn_elem->SetCount(elem->GetCount()); - msn_elem->SetLocation(carrier->Location().OtherHand()); - - if (carrier->GetRegion()) - msn_elem->SetRegion(carrier->GetRegion()->Name()); - - int squadron_index = 0; - Hangar* hangar = FindSquadron(elem->Name(), squadron_index); - - if (hangar) { - msn_elem->SetDeadCount(hangar->NumShipsDead(squadron_index)); - msn_elem->SetMaintCount(hangar->NumShipsMaint(squadron_index)); - - const ShipDesign* design = hangar->SquadronDesign(squadron_index); - msn_elem->SetDesign(design); - - Text design_path = design->path_name; - design_path.setSensitive(false); - - if (design_path.indexOf("/Mods/Ships") == 0) { - design_path = design_path.substring(11, 1000); - msn_elem->SetPath(design_path); - } - } - } - - else { - msn_elem->SetSquadron(elem->GetSquadron()); - msn_elem->SetCount(elem->NumShips()); - } - - if (elem->GetCommander()) - msn_elem->SetCommander(elem->GetCommander()->Name()); - - msn_elem->SetCombatGroup(elem->GetCombatGroup()); - msn_elem->SetCombatUnit(elem->GetCombatUnit()); - - Ship* ship = elem->GetShip(1); - if (ship) { - if (ship->GetRegion()) - msn_elem->SetRegion(ship->GetRegion()->Name()); - - msn_elem->SetLocation(ship->Location().OtherHand()); - msn_elem->SetDesign(ship->Design()); - - msn_elem->SetPlayer(elem->Player()); - msn_elem->SetCommandAI(elem->GetCommandAILevel()); - msn_elem->SetHoldTime((int) elem->GetHoldTime()); - msn_elem->SetZoneLock(elem->GetZoneLock()); - msn_elem->SetHeading(ship->CompassHeading()); - - msn_elem->SetPlayable(elem->IsPlayable()); - msn_elem->SetRogue(elem->IsRogue()); - msn_elem->SetIntelLevel(elem->IntelLevel()); - - Text design_path = ship->Design()->path_name; - design_path.setSensitive(false); - - if (design_path.indexOf("/Mods/Ships") == 0) { - design_path = design_path.substring(11, 1000); - msn_elem->SetPath(design_path); - } - - msn_elem->SetRespawnCount(ship->RespawnCount()); - } - - MissionLoad* loadout = new MissionLoad; - CopyMemory(loadout->GetStations(), elem->Loadout(), 16 * sizeof(int)); - - msn_elem->Loadouts().append(loadout); - - int num_obj = elem->NumObjectives(); - for (int i = 0; i < num_obj; i++) { - Instruction* o = elem->GetObjective(i); - Instruction* instr = 0; - - instr = new Instruction(*o); - - msn_elem->AddObjective(instr); - } - - int num_inst = elem->NumInstructions(); - for (int i = 0; i < num_inst; i++) { - Text instr = elem->GetInstruction(i); - msn_elem->AddInstruction(instr); - } - - ListIter nav_iter = elem->GetFlightPlan(); - while (++nav_iter) { - Instruction* nav = nav_iter.value(); - Instruction* npt = new - Instruction(nav->RegionName(), nav->Location(), nav->Action()); - - npt->SetFormation(nav->Formation()); - npt->SetSpeed(nav->Speed()); - npt->SetTarget(nav->TargetName()); - npt->SetHoldTime(nav->HoldTime()); - npt->SetFarcast(nav->Farcast()); - npt->SetStatus(nav->Status()); - - msn_elem->AddNavPoint(npt); - } - - for (int i = 0; i < elem->NumShips(); i++) { - ship = elem->GetShip(i+1); - - if (ship) { - MissionShip* s = new MissionShip; - - s->SetName(ship->Name()); - s->SetRegNum(ship->Registry()); - s->SetRegion(ship->GetRegion()->Name()); - s->SetLocation(ship->Location().OtherHand()); - s->SetVelocity(ship->Velocity().OtherHand()); - - s->SetRespawns(ship->RespawnCount()); - s->SetHeading(ship->CompassHeading()); - s->SetIntegrity(ship->Integrity()); - - if (ship->GetDecoy()) - s->SetDecoys(ship->GetDecoy()->Ammo()); - - if (ship->GetProbeLauncher()) - s->SetProbes(ship->GetProbeLauncher()->Ammo()); - - int n; - int ammo[16]; - int fuel[4]; - - for (n = 0; n < 16; n++) { - Weapon* w = ship->GetWeaponByIndex(n+1); - - if (w) - ammo[n] = w->Ammo(); - else - ammo[n] = -10; - } - - for (n = 0; n < 4; n++) { - if (ship->Reactors().size() > n) - fuel[n] = ship->Reactors()[n]->Charge(); - else - fuel[n] = -10; - } - - s->SetAmmo(ammo); - s->SetFuel(fuel); - - msn_elem->Ships().append(s); - } - } - } - - return msn_elem; -} - -Hangar* -Sim::FindSquadron(const char* name, int& index) -{ - Hangar* hangar = 0; - - ListIter iter = regions; - while (++iter && !hangar) { - SimRegion* rgn = iter.value(); - - ListIter s_iter = rgn->Carriers(); - while (++s_iter && !hangar) { - Ship* carrier = s_iter.value(); - Hangar* h = carrier->GetHangar(); - - for (int i = 0; i < h->NumSquadrons() && !hangar; i++) { - if (h->SquadronName(i) == name) { - hangar = h; - index = i; - } - } - } - } - - return hangar; -} - -// +===================================================================-+ - -SimRegion::SimRegion(Sim* s, const char* n, int t) - : sim(s), name(n), type(t), orbital_region(0), star_system(0), player_ship(0), - grid(0), active(false), current_view(0), sim_time(0), ai_index(0), terrain(0) -{ - if (sim) { - star_system = sim->GetStarSystem(); - } -} - -SimRegion::SimRegion(Sim* s, OrbitalRegion* r) - : sim(s), orbital_region(r), type(REAL_SPACE), star_system(0), player_ship(0), - grid(0), active(false), current_view(0), sim_time(0), ai_index(0), terrain(0) -{ - if (r) { - star_system = r->System(); - } - - if (orbital_region) { - name = orbital_region->Name(); - grid = new Grid((int) orbital_region->Radius(), - (int) orbital_region->GridSpace()); - - - if (orbital_region->Type() == Orbital::TERRAIN) { - TerrainRegion* trgn = (TerrainRegion*) orbital_region; - terrain = new Terrain(trgn); - - type = AIR_SPACE; - } - - else if (orbital_region->Asteroids() > 0) { - int asteroids = orbital_region->Asteroids(); - - for (int i = 0; i < asteroids; i++) { - Point init_loc((rand()-16384.0f) * 30, - (rand()-16384.0f) * 3, - (rand()-16384.0f) * 30); - sim->CreateAsteroid(init_loc, i, Random(1e7, 1e8), this); - } - } - } - else { - name = ContentBundle::GetInstance()->GetText("Unknown"); - } -} - -SimRegion::~SimRegion() -{ - GRAPHIC_DESTROY(grid); - delete terrain; - explosions.destroy(); - shots.destroy(); - ships.destroy(); - debris.destroy(); - asteroids.destroy(); - dead_ships.destroy(); - - for (int i = 0; i < 5; i++) - track_database[i].destroy(); -} - -int -SimRegion::operator < (const SimRegion& r) const -{ - return (orbital_region && r.orbital_region && *orbital_region < *r.orbital_region); -} - -int -SimRegion::operator <= (const SimRegion& r) const -{ - return (orbital_region && r.orbital_region && *orbital_region <= *r.orbital_region); -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::SetPlayerShip(Ship* ship) -{ - // there can only be a player ship when playing the game locally - if (Starshatter::GetInstance()) { - int player_index = ships.index(ship); - - if (player_index >= 0) { - if (sim->GetActiveRegion() != this) - sim->ActivateRegion(this); - - AttachPlayerShip(player_index); - } - - else { - Print("SimRegion %s could not set player ship '%s' - not in region\n", - name.data(), ship ? ship->Name() : "(null)"); - } - } - - // if this is a stand-alone server, set player ship to null - else { - if (player_ship) - player_ship->SetControls(0); - - current_view = -1; - player_ship = 0; - } -} - -void -SimRegion::AttachPlayerShip(int index) -{ - if (player_ship) - player_ship->SetControls(0); - - current_view = index; - player_ship = ships[current_view]; - - CameraDirector* cam_dir = CameraDirector::GetInstance(); - if (cam_dir) - cam_dir->SetShip(player_ship); - - if (sim->dust) - sim->dust->Reset(player_ship->Location()); - - if (!sim->IsTestMode()) - player_ship->SetControls(sim->ctrl); - - MouseController* mouse_con = MouseController::GetInstance(); - if (mouse_con) - mouse_con->SetActive(false); -} - -void -SimRegion::NextView() -{ - if (ships.size()) { - int original_view = current_view; - - do { - current_view++; - if (current_view >= ships.size()) { - current_view = 0; - } - } - while (ships[current_view]->Life() == 0 && current_view != original_view); - - if (current_view != original_view) { - ClearSelection(); - - if (!sim->IsTestMode()) - player_ship->SetControls(0); - - if (player_ship->Rep()) - player_ship->Rep()->Show(); - - AttachPlayerShip(current_view); - } - } -} - -bool -SimRegion::IsSelected(Ship* s) -{ - return selection.contains(s); -} - -ListIter -SimRegion::GetSelection() -{ - return selection; -} - -void -SimRegion::SetSelection(Ship* newsel) -{ - selection.clear(); - selection.append(newsel); -} - -void -SimRegion::ClearSelection() -{ - selection.clear(); -} - -void -SimRegion::AddSelection(Ship* newsel) -{ - if (!newsel || - newsel->GetFlightPhase() < Ship::ACTIVE || - newsel->GetFlightPhase() >= Ship::RECOVERY) - return; - - if (!selection.contains(newsel)) - selection.append(newsel); -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::Activate() -{ - if (!sim) return; - - ListIter ship = ships; - while (++ship) - ship->Activate(sim->scene); - - ListIter shot = shots; - while (++shot) - shot->Activate(sim->scene); - - ListIter exp = explosions; - while (++exp) - exp->Activate(sim->scene); - - ListIter deb = debris; - while (++deb) - deb->Activate(sim->scene); - - ListIter a = asteroids; - while (++a) - a->Activate(sim->scene); - - if (grid) - sim->scene.AddGraphic(grid); - - if (terrain) - terrain->Activate(sim->scene); - - player_ship = 0; - active = true; -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::Deactivate() -{ - if (!sim) return; - - ListIter ship = ships; - while (++ship) - ship->Deactivate(sim->scene); - - ListIter shot = shots; - while (++shot) - shot->Deactivate(sim->scene); - - ListIter exp = explosions; - while (++exp) - exp->Deactivate(sim->scene); - - ListIter deb = debris; - while (++deb) - deb->Deactivate(sim->scene); - - ListIter a = asteroids; - while (++a) - a->Deactivate(sim->scene); - - if (grid) - sim->scene.DelGraphic(grid); - - if (terrain) - terrain->Deactivate(sim->scene); - - player_ship = 0; - active = false; - - for (int i = 0; i < 5; i++) - track_database[i].destroy(); -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::ExecFrame(double secs) -{ - if (!sim) return; - - double seconds = secs; - - // DON'T REALLY KNOW WHAT PURPOSE THIS SERVES.... - if (!active) { - double max_frame = 3 * Game::GetInstance()->GetMaxFrameLength(); - long new_time = Clock::GetInstance()->GameTime(); - double delta = new_time - sim_time; - seconds = delta / 1000.0; - - if (seconds > max_frame) - seconds = max_frame; - } - - sim_time = Clock::GetInstance()->GameTime(); - - if (orbital_region) - location = orbital_region->Location(); - - CameraDirector* cam_dir = CameraDirector::GetInstance(); - - Point ref; - - if (active && cam_dir) { - ref = cam_dir->GetCamera()->Pos(); - UpdateSky(seconds, ref); - } - - if (terrain) - terrain->ExecFrame(seconds); - - UpdateTracks(seconds); - UpdateShips(seconds); - UpdateShots(seconds); - UpdateExplosions(seconds); - - if (!Game::GetInstance()->Paused()) { - DamageShips(); - DockShips(); - - if (active) { - CollideShips(); - CrashShips(); - } - - DestroyShips(); - } - - if (active && cam_dir && player_ship) { - Sound::SetListener(*(cam_dir->GetCamera()), player_ship->Velocity()); - } -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::ShowGrid(int show) -{ - if (grid) { - if (show) - grid->Show(); - else - grid->Hide(); - } -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::UpdateSky(double seconds, const Point& ref) -{ - Dust* dust = sim->dust; - - if (dust) { - if (orbital_region && orbital_region->Type() == Orbital::TERRAIN) { - dust->Hide(); - } - else { - dust->Show(); - - dust->ExecFrame(seconds, ref); - - if (player_ship && dust->Hidden()) { - dust->Reset(player_ship->Location()); - dust->Show(); - } - } - } - - ListIter a = asteroids; - while (++a) { - a->ExecFrame(seconds); - } -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::UpdateShips(double seconds) -{ - int ship_index = 0; - if (ai_index > ships.size()) - ai_index = 0; - - ListIter ship_iter = ships; - Ship* ship = 0; - - while (++ship_iter) { - ship = ship_iter.value(); - - if (ship_index == ai_index || ship == player_ship) - ship->SetAIMode(2); - else - ship->SetAIMode(1); - - ship->ExecFrame(seconds); - ship_index++; - } - - ai_index++; -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::UpdateShots(double seconds) -{ - ListIter shot_iter = shots; - while (++shot_iter) { - Shot* shot = shot_iter.value(); - shot->ExecFrame(seconds); - - if (shot->Design()->flak) { - SeekerAI* seeker = (SeekerAI*) shot->GetDirector(); - - if (shot->Life() < 0.02 || seeker && seeker->Overshot()) { - shot->SetFuse(0.001); // set lifetime to ~zero - sim->CreateSplashDamage(shot); - } - } - - if (shot->Life() < 0.01) { // died of old age - NetUtil::SendWepDestroy(shot); - - if (shot->IsDrone()) - drones.remove((Drone*) shot); - - shot_iter.removeItem(); - delete shot; - shot = 0; - } - } -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::UpdateExplosions(double seconds) -{ - ListIter exp_iter = explosions; - while (++exp_iter) { - Explosion* exp = exp_iter.value(); - exp->ExecFrame(seconds); - - if (exp->Life() < 0.01) { // died of old age - exp_iter.removeItem(); - delete exp; - } - } - - ListIter debris_iter = debris; - while (++debris_iter) { - Debris* d = debris_iter.value(); - d->ExecFrame(seconds); - - if (d->Life() < 0.01) { // died of old age - debris_iter.removeItem(); - delete d; - } - } -} - -// +--------------------------------------------------------------------+ -// Check for collisions between ships and shots, and apply damage. -// Also look for damage to drones and debris. - -void -SimRegion::DamageShips() -{ - if (ships.size() == 0 || shots.size() == 0) - return; - - Point impact; - - // FOR EACH SHOT IN THE REGION: - ListIter shot_iter = shots; - while (++shot_iter) { - Shot* shot = shot_iter.value(); - const Ship* owner = shot->Owner(); - const char* owner_name; - - if (owner) - owner_name = owner->Name(); - else - owner_name = "[KIA]"; - - // CHECK FOR COLLISION WITH A SHIP: - ListIter ship_iter = ships; - while (shot && ++ship_iter) { - Ship* ship = ship_iter.value(); - int hit = ship->HitBy(shot, impact); - - if (hit) { - // recon imager: - if (shot->Damage() < 0) { - ShipStats* shooter = ShipStats::Find(owner_name); - if (shooter) { - shooter->AddEvent(SimEvent::SCAN_TARGET, ship->Name()); - } - } - - // live round: - else if (shot->Damage() > 0) { - int ship_destroyed = (!ship->InTransition() && ship->Integrity() < 1.0f); - - // then delete the ship: - if (ship_destroyed) { - NetUtil::SendObjKill(ship, owner, shot->IsMissile() ? NetObjKill::KILL_SECONDARY : NetObjKill::KILL_PRIMARY); - Director* director; - - Print(" %s Killed %s (%s)\n", owner_name, ship->Name(), FormatGameTime()); - - if (owner) - director = owner->GetDirector(); - - // alert the killer - if (director && director->Type() > SteerAI::SEEKER && director->Type() < SteerAI::GROUND) { - ShipAI* shipAI = (ShipAI*) director; - shipAI->Splash(ship); - } - - // record the kill - ShipStats* killer = ShipStats::Find(owner_name); - if (killer) { - if (shot->IsMissile()) - killer->AddEvent(SimEvent::MISSILE_KILL, ship->Name()); - else - killer->AddEvent(SimEvent::GUNS_KILL, ship->Name()); - } - - if (owner && owner->GetIFF() != ship->GetIFF()) { - if (ship->GetIFF() > 0 || owner->GetIFF() > 1) { - killer->AddPoints(ship->Value()); - - Element* elem = owner->GetElement(); - if (elem) { - if (owner->GetElementIndex() > 1) { - Ship* s = elem->GetShip(1); - - if (s) { - ShipStats* cmdr_stats = ShipStats::Find(s->Name()); - if (cmdr_stats) { - cmdr_stats->AddCommandPoints(ship->Value()/2); - } - } - } - - Element* cmdr = elem->GetCommander(); - if (cmdr) { - Ship* s = cmdr->GetShip(1); - - if (s) { - ShipStats* cmdr_stats = ShipStats::Find(s->Name()); - if (cmdr_stats) { - cmdr_stats->AddCommandPoints(ship->Value()/2); - } - } - } - } - } - } - - ShipStats* killee = ShipStats::Find(ship->Name()); - if (killee) - killee->AddEvent(SimEvent::DESTROYED, owner_name); - - ship->DeathSpiral(); - } - } - - // finally, consume the shot: - if (!shot->IsBeam()) { - if (owner) { - ShipStats* stats = ShipStats::Find(owner_name); - if (shot->Design()->primary) - stats->AddGunHit(); - else if (shot->Damage() > 0) - stats->AddMissileHit(); - } - - NetUtil::SendWepDestroy(shot); - - if (shot->IsDrone()) - drones.remove((Drone*) shot); - - shot_iter.removeItem(); - delete shot; - shot = 0; - } - else if (!shot->HitTarget()) { - shot->SetHitTarget(true); - - if (owner) { - ShipStats* stats = ShipStats::Find(owner_name); - if (shot->Design()->primary) - stats->AddGunHit(); - } - } - } - } - - // CHECK FOR COLLISION WITH A DRONE: - if (shot && shot->Design()->target_type & Ship::DRONE) { - ListIter drone_iter = drones; - while (shot && ++drone_iter) { - Drone* d = drone_iter.value(); - - if (d == shot || d->Owner() == owner) - continue; - - int hit = d->HitBy(shot, impact); - if (hit) { - int destroyed = (d->Integrity() < 1.0f); - - // then mark the drone for deletion: - if (destroyed) { - NetUtil::SendWepDestroy(d); - sim->CreateExplosion(d->Location(), d->Velocity(), 21, 1.0f, 1.0f, this); - d->SetLife(0); - } - - // finally, consume the shot: - if (!shot->IsBeam()) { - if (owner) { - ShipStats* stats = ShipStats::Find(owner_name); - if (shot->Design()->primary) - stats->AddGunHit(); - else - stats->AddMissileHit(); - } - - NetUtil::SendWepDestroy(shot); - - if (shot->IsDrone()) - drones.remove((Drone*) shot); - - shot_iter.removeItem(); - delete shot; - shot = 0; - } - } - } - } - - // CHECK FOR COLLISION WITH DEBRIS: - ListIter debris_iter = debris; - while (shot && ++debris_iter) { - Debris* d = debris_iter.value(); - - if (d->Radius() < 50) - continue; - - int hit = d->HitBy(shot, impact); - if (hit) { - int destroyed = (d->Integrity() < 1.0f); - - // then delete the debris: - if (destroyed) { - sim->CreateExplosion(d->Location(), d->Velocity(), Explosion::LARGE_EXPLOSION, 1.0f, 1.0f, this); - debris_iter.removeItem(); - delete d; - } - - // finally, consume the shot: - if (!shot->IsBeam()) { - NetUtil::SendWepDestroy(shot); - if (shot->IsDrone()) - drones.remove((Drone*) shot); - - shot_iter.removeItem(); - delete shot; - shot = 0; - } - } - } - - // CHECK FOR COLLISION WITH ASTEROIDS: - ListIter a_iter = asteroids; - while (shot && ++a_iter) { - Asteroid* a = a_iter.value(); - - int hit = a->HitBy(shot, impact); - if (hit) { - if (!shot->IsBeam()) { - if (shot->IsDrone()) - drones.remove((Drone*) shot); - - shot_iter.removeItem(); - delete shot; - shot = 0; - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::CollideShips() -{ - if (ships.size() < 2 && debris.size() < 1) - return; - - List kill_list; - - int s_index = 0; - - ListIter ship_iter = ships; - while (++ship_iter) { - Ship* ship = ship_iter.value(); - - if (ship->InTransition() || - ship->GetFlightPhase() < Ship::ACTIVE || - ship->MissionClock() < 10000 || - ship->IsNetObserver()) - continue; - - int t_index = 0; - ListIter targ_iter = ships; - while (++targ_iter) { - Ship* targ = targ_iter.value(); - - if (t_index++ <= s_index) continue; - - if (targ == ship) continue; - - if (targ->InTransition() || - targ->GetFlightPhase() < Ship::ACTIVE || - targ->MissionClock() < 10000 || - targ->IsNetObserver()) - continue; - - // ignore AI fighter collisions: - if (ship->IsDropship() && - ship != player_ship && - targ->IsDropship() && - targ != player_ship) - continue; - - // don't collide with own runway! - if (ship->IsAirborne() && ship->GetCarrier() == targ) - continue; - if (targ->IsAirborne() && targ->GetCarrier() == ship) - continue; - - // impact: - if (ship->CollidesWith(*targ)) { - Vec3 tv1 = targ->Velocity(); - Vec3 sv1 = ship->Velocity(); - - Physical::SemiElasticCollision(*ship, *targ); - - Vec3 tv2 = targ->Velocity(); - Vec3 sv2 = ship->Velocity(); - - double dvs = (sv2-sv1).length(); - double dvt = (tv2-tv1).length(); - - if (dvs > 20) dvs *= dvs; - if (dvt > 20) dvt *= dvt; - - if (!NetGame::IsNetGameClient()) { - double old_integrity = ship->Integrity(); - ship->InflictDamage(dvs); - double hull_damage = old_integrity - ship->Integrity(); - NetUtil::SendObjDamage(ship, hull_damage); - - old_integrity = targ->Integrity(); - targ->InflictDamage(dvt); - hull_damage = old_integrity - targ->Integrity(); - NetUtil::SendObjDamage(targ, hull_damage); - } - - // then delete the ship: - if (targ->Integrity() < 1.0f) { - NetUtil::SendObjKill(targ, ship, NetObjKill::KILL_COLLISION); - Print(" ship %s died in collision with %s (%s)\n", targ->Name(), ship->Name(), FormatGameTime()); - if (!kill_list.contains(targ)) { - ShipStats* r = ShipStats::Find(targ->Name()); - if (r) r->AddEvent(SimEvent::COLLIDE, ship->Name()); - - if (targ->GetIFF() > 0 && ship->GetIFF() != targ->GetIFF()) { - r = ShipStats::Find(ship->Name()); - if (r) r->AddPoints(targ->Value()); - } - - kill_list.insert(targ); - } - } - - if (ship->Integrity() < 1.0f) { - NetUtil::SendObjKill(ship, targ, NetObjKill::KILL_COLLISION); - Print(" ship %s died in collision with %s (%s)\n", ship->Name(), targ->Name(), FormatGameTime()); - if (!kill_list.contains(ship)) { - ShipStats* r = ShipStats::Find(ship->Name()); - if (r) r->AddEvent(SimEvent::COLLIDE, targ->Name()); - - if (ship->GetIFF() > 0 && ship->GetIFF() != targ->GetIFF()) { - r = ShipStats::Find(targ->Name()); - if (r) r->AddPoints(ship->Value()); - } - - kill_list.insert(ship); - } - } - } - } - - ListIter debris_iter = debris; - while (++debris_iter) { - Debris* d = debris_iter.value(); - - if (d->Radius() < 50) - continue; - - if (ship->CollidesWith(*d)) { - Vec3 tv1 = d->Velocity(); - Vec3 sv1 = ship->Velocity(); - - Physical::SemiElasticCollision(*ship, *d); - - Vec3 tv2 = d->Velocity(); - Vec3 sv2 = ship->Velocity(); - - if (!NetGame::IsNetGameClient()) { - ship->InflictDamage((sv2-sv1).length()); - } - - d->InflictDamage((tv2-tv1).length()); - - // then delete the debris: - if (d->Integrity() < 1.0f) { - sim->CreateExplosion(d->Location(), d->Velocity(), Explosion::LARGE_EXPLOSION, 1.0f, 1.0f, this); - debris_iter.removeItem(); - delete d; - } - - if (ship->Integrity() < 1.0f) { - if (!kill_list.contains(ship)) { - ShipStats* r = ShipStats::Find(ship->Name()); - if (r) r->AddEvent(SimEvent::COLLIDE, ContentBundle::GetInstance()->GetText("DEBRIS")); - - kill_list.insert(ship); - } - } - } - } - - ListIter a_iter = asteroids; - while (++a_iter) { - Asteroid* a = a_iter.value(); - - if (ship->CollidesWith(*a)) { - Vec3 sv1 = ship->Velocity(); - Physical::SemiElasticCollision(*ship, *a); - Vec3 sv2 = ship->Velocity(); - - if (!NetGame::IsNetGameClient()) { - ship->InflictDamage((sv2-sv1).length() * 10); - } - - if (ship->Integrity() < 1.0f) { - if (!kill_list.contains(ship)) { - ShipStats* r = ShipStats::Find(ship->Name()); - if (r) r->AddEvent(SimEvent::COLLIDE, ContentBundle::GetInstance()->GetText("ASTEROID")); - - kill_list.insert(ship); - } - } - } - } - - s_index++; - } - - ListIter killed(kill_list); - while (++killed) { - Ship* kill = killed.value(); - kill->DeathSpiral(); - } -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::CrashShips() -{ - if (type != AIR_SPACE || NetGame::IsNetGameClient()) - return; - - ListIter ship_iter = ships; - while (++ship_iter) { - Ship* ship = ship_iter.value(); - - if (!ship->IsGroundUnit() && - !ship->InTransition() && - ship->Class() != Ship::LCA && - ship->AltitudeAGL() < ship->Radius()/2) { - if (ship->GetFlightPhase() == Ship::ACTIVE || ship->GetFlightPhase() == Ship::APPROACH) { - ship->InflictDamage(1e6); - - if (ship->Integrity() < 1.0f) { - Print(" ship destroyed by crash: %s (%s)\n", ship->Name(), FormatGameTime()); - ShipStats* r = ShipStats::Find(ship->Name()); - if (r) r->AddEvent(SimEvent::CRASH); - - ship->DeathSpiral(); - } - } - } - } - - ListIter shot_iter = shots; - while (++shot_iter) { - Shot* shot = shot_iter.value(); - - if (shot->IsBeam() || shot->IsDecoy()) - continue; - - if (shot->AltitudeMSL() < 5e3 && - shot->AltitudeAGL() < 5) { - - // shot hit the ground, destroy it: - NetUtil::SendWepDestroy(shot); - - if (shot->IsDrone()) - drones.remove((Drone*) shot); - - shot_iter.removeItem(); - delete shot; - } - } -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::DestroyShips() -{ - ListIter ship_iter = ships; - while (++ship_iter) { - Ship* ship = ship_iter.value(); - - if (ship->IsDead()) { - // must use the iterator to remove the current - // item from the container: - ship_iter.removeItem(); - DestroyShip(ship); - } - } -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::DestroyShip(Ship* ship) -{ - if (!ship) return; - - Ship* spawn = 0; - - ships.remove(ship); - carriers.remove(ship); - selection.remove(ship); - - Text rgn_name; - if (ship->GetRegion()) - rgn_name = ship->GetRegion()->Name(); - - bool player_destroyed = (player_ship == ship); - - char ship_name[64]; - char ship_reg[64]; - strcpy_s(ship_name, ship->Name()); - strcpy_s(ship_reg, ship->Registry()); - - ShipDesign* ship_design = (ShipDesign*) ship->Design(); - int ship_iff = ship->GetIFF(); - int cmd_ai = ship->GetCommandAILevel(); - bool respawn = sim->IsTestMode() && !ship->IsGroundUnit(); - bool observe = false; - - if (!respawn) - respawn = ship->RespawnCount() > 0; - - if (sim->netgame) { - if (!respawn) - observe = player_destroyed; - } - - if (respawn || observe) { - if (!sim->netgame || !respawn) - ship->SetRespawnLoc(RandomPoint() * 2); - - Point spawn_loc = ship->RespawnLoc(); - - if (ship->IsAirborne() && spawn_loc.z < 5e3) - spawn_loc.z = Random(8e3, 10e3); - - spawn = sim->CreateShip(ship_name, ship_reg, ship_design, rgn_name, spawn_loc, ship_iff, cmd_ai, observe ? 0 : ship->GetLoadout()); - spawn->SetRespawnCount(ship->RespawnCount() - 1); - spawn->SetNetObserver(observe); - - if (sim->netgame && respawn) - sim->netgame->Respawn(ship->GetObjID(), spawn); - - int n = strlen(ship_name); - if (n > 2) { - if (ship_name[n-2] == ' ' && isdigit(ship_name[n-1])) - ship_name[n-2] = 0; - } - - Element* elem = sim->FindElement(ship_name); - if (elem) - elem->AddShip(spawn, ship->GetOrigElementIndex()); - else - Print("Warning: No Element found for '%s' on respawn.\n", ship_name); - - if (player_destroyed) - SetPlayerShip(spawn); - } - else { - // close mission, return to menu: - if (player_destroyed) { - Starshatter* stars = Starshatter::GetInstance(); - if (stars) - stars->SetGameMode(Starshatter::PLAN_MODE); - } - } - - sim->ProcessEventTrigger(MissionEvent::TRIGGER_DESTROYED, 0, ship->Name()); - - dead_ships.insert(ship); - ship->Destroy(); -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::NetDockShip(Ship* ship, Ship* carrier, FlightDeck* deck) -{ - if (!ship || !carrier || !deck) return; - - deck->Dock(ship); -} - -// +--------------------------------------------------------------------+ - -Ship* -SimRegion::FindShip(const char* ship_name) -{ - Ship* ship = 0; - - if (ship_name && *ship_name) { - int name_len = strlen(ship_name); - - ListIter ship_iter = ships; - while (++ship_iter && !ship) { - Ship* test = ship_iter.value(); - if (!strncmp(test->Name(), ship_name, name_len)) { - int test_len = strlen(test->Name()); - - // The only fuzzy match is for element indices. - // The desired name "Alpha" matches "Alpha 1" and "Alpha 2" - // but not "Alpha-Centauri" - - if (test_len > name_len && test->Name()[name_len] != ' ') - continue; - - ship = test; - } - } - } - - return ship; -} - -Ship* -SimRegion::FindShipByObjID(DWORD objid) -{ - Ship* ship = 0; - - ListIter ship_iter = ships; - while (++ship_iter && !ship) { - Ship* test = ship_iter.value(); - if (test->GetObjID() == objid) - ship = test; - } - - return ship; -} - -Shot* -SimRegion::FindShotByObjID(DWORD objid) -{ - Shot* shot = 0; - - ListIter shot_iter = shots; - while (++shot_iter && !shot) { - Shot* test = shot_iter.value(); - if (test->GetObjID() == objid) - shot = test; - } - - if (!shot) { - ListIter drone_iter = drones; - while (++drone_iter && !shot) { - Drone* test = drone_iter.value(); - if (test->GetObjID() == objid) - shot = test; - } - } - - return shot; -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::DockShips() -{ - if (ships.size() == 0) - return; - - ListIter ship_iter = ships; - while (++ship_iter) { - Ship* ship = ship_iter.value(); - int docked = (ship->GetFlightPhase() == Ship::DOCKED); - - if (docked) { - sim->ProcessEventTrigger(MissionEvent::TRIGGER_DOCK, 0, ship->Name()); - - // who did this ship dock with? - Ship* carrier = ship->GetCarrier(); - - if (carrier) { - ShipStats* s = ShipStats::Find(ship->Name()); - if (s) { - if (ship->IsAirborne()) - s->AddEvent(SimEvent::LAND, carrier->Name()); - else - s->AddEvent(SimEvent::DOCK, carrier->Name()); - } - - ShipStats* c = ShipStats::Find(carrier->Name()); - if (c) c->AddEvent(SimEvent::RECOVER_SHIP, ship->Name()); - } - - // then delete the ship: - int player_docked = (player_ship == ship); - char ship_name[33]; - strcpy_s(ship_name, ship->Name()); - - selection.remove(ship); - dead_ships.insert(ship_iter.removeItem()); - ship->Destroy(); - - if (player_docked) { - // close mission, return to menu: - Starshatter* stars = Starshatter::GetInstance(); - if (stars) - stars->SetGameMode(Starshatter::PLAN_MODE); - } - - if (carrier) - Print(" %s Docked with %s\n", ship_name, carrier->Name()); - } - } -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::InsertObject(Ship* ship) -{ - if (!ship) return; - - SimRegion* orig = ship->GetRegion(); - - if (orig != this) { - if (orig != 0) { - if (orig->active) - ship->Deactivate(sim->scene); - - orig->ships.remove(ship); - orig->carriers.remove(ship); - orig->selection.remove(ship); - } - - ships.append(ship); - - if (ship->NumFlightDecks()) - carriers.append(ship); - - TranslateObject(ship); - ship->SetRegion(this); - - if (active) - ship->Activate(sim->scene); - } -} - -void -SimRegion::InsertObject(Shot* shot) -{ - if (!shot) return; - - SimRegion* orig = shot->GetRegion(); - - if (orig != this) { - if (orig != 0) - orig->shots.remove(shot); - - shots.append(shot); - if (shot->IsDrone()) - drones.append((Drone*) shot); - - TranslateObject(shot); - shot->SetRegion(this); - - if (active) - shot->Activate(sim->scene); - } -} - -void -SimRegion::InsertObject(Explosion* exp) -{ - if (!exp) return; - - SimRegion* orig = exp->GetRegion(); - - if (orig != this) { - if (orig != 0) - orig->explosions.remove(exp); - - explosions.append(exp); - TranslateObject(exp); - exp->SetRegion(this); - - if (active) - exp->Activate(sim->scene); - } -} - -void -SimRegion::InsertObject(Debris* d) -{ - if (!d) return; - - SimRegion* orig = d->GetRegion(); - - if (orig != this) { - if (orig != 0) - orig->debris.remove(d); - - debris.append(d); - TranslateObject(d); - d->SetRegion(this); - - if (active) - d->Activate(sim->scene); - } -} - -void -SimRegion::InsertObject(Asteroid* a) -{ - if (!a) return; - - SimRegion* orig = a->GetRegion(); - - if (orig != this) { - if (orig != 0) - orig->asteroids.remove(a); - - asteroids.append(a); - TranslateObject(a); - a->SetRegion(this); - - if (active) - a->Activate(sim->scene); - } -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::TranslateObject(SimObject* object) -{ - if (orbital_region) - location = orbital_region->Location(); - - if (object) { - SimRegion* orig = object->GetRegion(); - if (orig) { - Point delta = Location() - orig->Location(); - delta = delta.OtherHand(); - object->TranslateBy(delta); - } - } -} - -// +--------------------------------------------------------------------+ - -List& -SimRegion::TrackList(int iff) -{ - if (iff >= 0 && iff < 5) - return track_database[iff]; - - static List empty; - return empty; -} - -void -SimRegion::UpdateTracks(double seconds) -{ - for (int i = 0; i < 5; i++) { - ListIter track_iter = track_database[i]; - - while (++track_iter) { - Contact* t = track_iter.value(); - Ship* c_ship = t->GetShip(); - Shot* c_shot = t->GetShot(); - double c_life = 0; - - if (c_ship) { - c_life = c_ship->Life(); - - // look for quantum jumps and orbit transitions: - if (c_ship->GetRegion() != this || c_ship->IsNetObserver()) - c_life = 0; - } - - else if (c_shot) - c_life = c_shot->Life(); - - if (t->Age() < 0 || c_life == 0) { - track_iter.removeItem(); - delete t; - } - - else { - t->Reset(); - } - } - } -} - -// +--------------------------------------------------------------------+ - -bool -SimRegion::CanTimeSkip() const -{ - bool ok = false; - - if (player_ship) { - ok = true; - - for (int i = 0; ok && i < ships.size(); i++) { - Ship* s = ships[i]; - - if (s != player_ship && s->GetIFF() && s->GetIFF() != player_ship->GetIFF()) { - double dist = Point(s->Location() - player_ship->Location()).length(); - - if (s->IsStarship()) - ok = dist > 60e3; - else - ok = dist > 30e3; - } - } - } - - return ok; -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::ResolveTimeSkip(double seconds) -{ - for (int i = 0; i < ships.size(); i++) { - Ship* ship = ships[i]; - Ship* ward = ship->GetWard(); - - // remember to burn fuel and fix stuff... - ship->ExecSystems(seconds); - ship->ExecMaintFrame(seconds); - - ship->ClearTrack(); - ListIter contact = ship->ContactList(); - while (++contact) - contact->ClearTrack(); - - if (ship->IsStatic()) - continue; - - // if ship is cleared inbound, land him: - InboundSlot* inbound = ship->GetInbound(); - if (inbound) { - if (inbound->Cleared()) { - FlightDeck* deck = inbound->GetDeck(); - - if (deck) { - ship->SetCarrier((Ship*) deck->GetCarrier(), deck); - ship->SetFlightPhase(Ship::DOCKED); - ship->Stow(); - deck->Clear(inbound->Index()); - } - } - - // cleared or not, once you're inbound, don't seek navpoints: - continue; - } - - if (ship->GetHangar()) { - ship->GetHangar()->ExecFrame(seconds); - - List& flight_decks = ship->FlightDecks(); - for (int n = 0; n < flight_decks.size(); n++) - flight_decks[n]->ExecFrame(seconds); - } - - Instruction* navpt = ship->GetNextNavPoint(); - Point dest = ship->Location(); - double speed = 500; - double space = 2.0e3 * (ship->GetElementIndex() - 1); - - if (ship->IsStarship()) - space *= 5; - - if (navpt && navpt->Action() == Instruction::LAUNCH) { - ship->SetNavptStatus(navpt, Instruction::COMPLETE); - navpt = ship->GetNextNavPoint(); - } - - if (navpt) { - dest = navpt->Location().OtherHand(); - speed = navpt->Speed(); - } - - else if (ward) { - Point delta = ship->Location() - ward->Location(); - delta.y = 0; - - if (delta.length() > 25e3) { - delta.Normalize(); - dest = ward->Location() + delta * 25e3; - } - } - - Point delta = dest - ship->Location(); - Point unit = delta; - double dist = unit.Normalize() - space; - - if (dist > 1e3) { - if (speed < 50) - speed = 500; - - double etr = dist / speed; - - if (etr > seconds) - etr = seconds; - - Point trans = unit * (speed * etr); - - if (ship->GetFuelLevel() > 1) { - ship->MoveTo(ship->Location() + trans); - ship->SetVelocity(unit * speed); - } - ship->LookAt(dest); - - if (ship->IsStarship()) { - ship->SetFLCSMode(Ship::FLCS_HELM); - ship->SetHelmHeading(ship->CompassHeading()); - ship->SetHelmPitch(ship->CompassPitch()); - } - } - - else if (navpt && navpt->Status() <= Instruction::ACTIVE) { - ship->SetNavptStatus(navpt, Instruction::COMPLETE); - } - - if (ward) { - Point ward_heading = ward->Heading(); - ward_heading.y = 0; - ward_heading.Normalize(); - - if (ship->GetFuelLevel() > 1) { - ship->SetVelocity(ward->Velocity()); - } - ship->LookAt(ship->Location() + ward_heading * 1e6); - - if (ship->IsStarship()) { - ship->SetFLCSMode(Ship::FLCS_HELM); - ship->SetHelmHeading(ship->CompassHeading()); - ship->SetHelmPitch(ship->CompassPitch()); - } - } - - if (dist > 1 || ward) { - for (int j = 0; j < ships.size(); j++) { - Ship* test = ships[j]; - - if (ship != test && test->Mass() >= ship->Mass()) { - Point delta = ship->Location() - test->Location(); - - if (delta.length() < ship->Radius() * 2 + test->Radius() * 2) { - ship->MoveTo(test->Location() + RandomPoint().OtherHand()); - } - } - } - } - } - - DockShips(); -} - -// +--------------------------------------------------------------------+ - -void -SimRegion::CommitMission() -{ - for (int i = 0; i < dead_ships.size(); i++) { - Ship* s = dead_ships[i]; - - if (s->GetCombatUnit() && s->GetFlightPhase() != Ship::DOCKED) - s->GetCombatUnit()->Kill(1); - } - - for (int i = 0; i < ships.size(); i++) { - Ship* s = ships[i]; - CombatUnit* u = s->GetCombatUnit(); - - if (u) { - Point u_loc = s->Location().OtherHand(); - if (u_loc.z > 20e3) - u_loc.z = 20e3; - else if (u_loc.z < -20e3) - u_loc.z = -20e3; - - if (u->IsStarship()) { - u->SetRegion(s->GetRegion()->Name()); - u->MoveTo(u_loc); - } - - if (!u->IsDropship()) { - if (s->Integrity() < 1) - u->Kill(1); - else - u->SetSustainedDamage(s->Design()->integrity - s->Integrity()); - } - - CombatGroup* g = u->GetCombatGroup(); - if (g && g->Type() > CombatGroup::FLEET && g->GetFirstUnit() == u) { - if (!g->IsZoneLocked()) - g->SetRegion(s->GetRegion()->Name()); - else - u->SetRegion(g->GetRegion()); - - g->MoveTo(u_loc); - } - } - } -} - -// +--------------------------------------------------------------------+ - -const char* FormatGameTime() -{ - static char txt[64]; - - int t = Clock::GetInstance()->GameTime(); - - int h = ( t / 3600000); - int m = ((t - h*3600000) / 60000); - int s = ((t - h*3600000 - m*60000) / 1000); - int e = ( t - h*3600000 - m*60000 - s*1000); - - if (h > 0) - sprintf_s(txt, "%02d:%02d:%02d.%03d", h,m,s,e); - else - sprintf_s(txt, "%02d:%02d.%03d", m,s,e); - - return txt; -} diff --git a/Stars45/Sim.h b/Stars45/Sim.h deleted file mode 100644 index cf8696b..0000000 --- a/Stars45/Sim.h +++ /dev/null @@ -1,329 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simulation Universe and Region classes -*/ - -#ifndef Sim_h -#define Sim_h - -#include "Types.h" -#include "Universe.h" -#include "Scene.h" -#include "Physical.h" -#include "Geometry.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Sim; -class SimRegion; -class SimObject; -class SimObserver; -class SimHyper; -class SimSplash; - -class StarSystem; -class Orbital; -class OrbitalRegion; -class Asteroid; - -class NetGame; - -class CameraDirector; -class Contact; -class Ship; -class ShipDesign; -class System; -class Element; -class Shot; -class Drone; -class Explosion; -class Debris; -class WeaponDesign; -class MotionController; -class Dust; -class Grid; -class Mission; -class MissionElement; -class MissionEvent; -class Hangar; -class FlightDeck; - -class Terrain; -class TerrainPatch; - -class Model; - -// +--------------------------------------------------------------------+ - -class Sim : public Universe -{ - friend class SimRegion; - -public: - enum { REAL_SPACE, AIR_SPACE }; - - Sim(MotionController* ctrl); - virtual ~Sim(); - - static Sim* GetSim() { return sim; } - - virtual void ExecFrame(double seconds); - - void LoadMission(Mission* msn, bool preload_textures=false); - void ExecMission(); - void CommitMission(); - void UnloadMission(); - - void NextView(); - void ShowGrid(int show = true); - bool GridShown() const; - - const char* FindAvailCallsign(int IFF); - Element* CreateElement(const char* callsign, int IFF, int type=0/*PATROL*/); - void DestroyElement(Element* elem); - Ship* CreateShip(const char* name, - const char* reg_num, - ShipDesign* design, - const char* rgn_name, - const Point& loc, - int IFF=0, - int cmd_ai=0, - const int* loadout=0); - Ship* FindShip(const char* name, const char* rgn_name=0); - Shot* CreateShot(const Point& pos, const Camera& shot_cam, WeaponDesign* d, const Ship* ship=0, SimRegion* rgn=0); - Explosion* CreateExplosion(const Point& pos, const Point& vel, int type, float exp_scale, float part_scale, SimRegion* rgn=0, SimObject* source=0, System* sys=0); - Debris* CreateDebris(const Point& pos, const Point& vel, Model* model, double mass, SimRegion* rgn=0); - Asteroid* CreateAsteroid(const Point& pos, int type, double mass, SimRegion* rgn=0); - void CreateSplashDamage(Ship* ship); - void CreateSplashDamage(Shot* shot); - void DestroyShip(Ship* ship); - void NetDockShip(Ship* ship, Ship* carrier, FlightDeck* deck); - - virtual Ship* FindShipByObjID(DWORD objid); - virtual Shot* FindShotByObjID(DWORD objid); - - Mission* GetMission() { return mission; } - List& GetEvents() { return events; } - List& GetRegions() { return regions; } - SimRegion* FindRegion(const char* name); - SimRegion* FindRegion(OrbitalRegion* rgn); - SimRegion* FindNearestSpaceRegion(SimObject* object); - SimRegion* FindNearestSpaceRegion(Orbital* body); - SimRegion* FindNearestTerrainRegion(SimObject* object); - SimRegion* FindNearestRegion(SimObject* object, int type); - bool ActivateRegion(SimRegion* rgn); - - void RequestHyperJump(Ship* obj, - SimRegion* rgn, - const Point& loc, - int type=0, - Ship* fc_src=0, - Ship* fc_dst=0); - - SimRegion* GetActiveRegion() { return active_region; } - StarSystem* GetStarSystem() { return star_system; } - List& GetSystemList(); - Scene* GetScene() { return &scene; } - Ship* GetPlayerShip(); - Element* GetPlayerElement(); - Orbital* FindOrbitalBody(const char* name); - - void SetSelection(Ship* s); - bool IsSelected(Ship* s); - ListIter GetSelection(); - void ClearSelection(); - void AddSelection(Ship* s); - - void SetTestMode(bool t=true); - - bool IsTestMode() const { return test_mode; } - bool IsNetGame() const { return netgame != 0; } - bool IsActive() const; - bool IsComplete() const; - - MotionController* GetControls() const { return ctrl; } - - Element* FindElement(const char* name); - List& GetElements() { return elements; } - - int GetAssignedElements(Element* elem, List& assigned); - - void SkipCutscene(); - void ResolveTimeSkip(double seconds); - void ResolveHyperList(); - void ResolveSplashList(); - - void ExecEvents(double seconds); - void ProcessEventTrigger(int type, int event_id=0, const char* ship=0, int param=0); - double MissionClock() const; - DWORD StartTime() const { return start_time; } - - // Create a list of mission elements based on the current - // state of the simulation. Used for multiplayer join in progress. - ListIter GetMissionElements(); - -protected: - void CreateRegions(); - void CreateElements(); - void CopyEvents(); - void BuildLinks(); - - // Convert a single live element into a mission element - // that can be serialized over the net. - MissionElement* CreateMissionElement(Element* elem); - Hangar* FindSquadron(const char* name, int& index); - - static Sim* sim; - SimRegion* active_region; - StarSystem* star_system; - Scene scene; - Dust* dust; - CameraDirector* cam_dir; - - List regions; - List rgn_queue; - List jumplist; - List splashlist; - List elements; - List finished; - List events; - List mission_elements; - - MotionController* ctrl; - - bool test_mode; - bool grid_shown; - Mission* mission; - - NetGame* netgame; - DWORD start_time; -}; - -// +--------------------------------------------------------------------+ - -class SimRegion -{ - friend class Sim; - -public: - static const char* TYPENAME() { return "SimRegion"; } - - enum { REAL_SPACE, AIR_SPACE }; - - SimRegion(Sim* sim, const char* name, int type); - SimRegion(Sim* sim, OrbitalRegion* rgn); - virtual ~SimRegion(); - - int operator == (const SimRegion& r) const { return (sim==r.sim) && (name==r.name); } - int operator < (const SimRegion& r) const; - int operator <= (const SimRegion& r) const; - - virtual void Activate(); - virtual void Deactivate(); - virtual void ExecFrame(double seconds); - void ShowGrid(int show = true); - void NextView(); - Ship* FindShip(const char* name); - Ship* GetPlayerShip() { return player_ship; } - void SetPlayerShip(Ship* ship); - OrbitalRegion* GetOrbitalRegion() { return orbital_region; } - Terrain* GetTerrain() { return terrain; } - bool IsActive() const { return active; } - bool IsAirSpace() const { return type == AIR_SPACE; } - bool IsOrbital() const { return type == REAL_SPACE; } - bool CanTimeSkip()const; - - virtual Ship* FindShipByObjID(DWORD objid); - virtual Shot* FindShotByObjID(DWORD objid); - - virtual void InsertObject(Ship* ship); - virtual void InsertObject(Shot* shot); - virtual void InsertObject(Explosion* explosion); - virtual void InsertObject(Debris* debris); - virtual void InsertObject(Asteroid* asteroid); - - const char* Name() const { return name; } - int Type() const { return type; } - int NumShips() { return ships.size(); } - List& Ships() { return ships; } - List& Carriers() { return carriers; } - List& Shots() { return shots; } - List& Drones() { return drones; } - List& Rocks() { return debris; } - List& Roids() { return asteroids; } - List& Explosions() { return explosions; } - List& Links() { return links; } - StarSystem* System() { return star_system; } - - Point Location() const { return location; } - - void SetSelection(Ship* s); - bool IsSelected(Ship* s); - ListIter GetSelection(); - void ClearSelection(); - void AddSelection(Ship* s); - - List& TrackList(int iff); - - void ResolveTimeSkip(double seconds); - -protected: - void CommitMission(); - void TranslateObject(SimObject* object); - - void AttachPlayerShip(int index); - void DestroyShips(); - void DestroyShip(Ship* ship); - void NetDockShip(Ship* ship, Ship* carrier, FlightDeck* deck); - - void UpdateSky(double seconds, const Point& ref); - void UpdateShips(double seconds); - void UpdateShots(double seconds); - void UpdateExplosions(double seconds); - void UpdateTracks(double seconds); - - void DamageShips(); - void CollideShips(); - void CrashShips(); - void DockShips(); - - Sim* sim; - Text name; - int type; - StarSystem* star_system; - OrbitalRegion* orbital_region; - Point location; - Grid* grid; - Terrain* terrain; - bool active; - - Ship* player_ship; - int current_view; - List ships; - List carriers; - List selection; - List dead_ships; - List shots; - List drones; - List explosions; - List debris; - List asteroids; - List track_database[5]; - List links; - - DWORD sim_time; - int ai_index; -}; - -#endif // Sim_h - diff --git a/Stars45/SimEvent.cpp b/Stars45/SimEvent.cpp deleted file mode 100644 index 4fad773..0000000 --- a/Stars45/SimEvent.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simulation Events for mission summary -*/ - -#include "SimEvent.h" -#include "Sim.h" -#include "Clock.h" -#include "ContentBundle.h" - -// +====================================================================+ - -List records; - -// +====================================================================+ - -SimEvent::SimEvent(int e, const char* t, const char* i) -: event(e), count(0) -{ - Sim* sim = Sim::GetSim(); - if (sim) { - time = (int) sim->MissionClock(); - } - else { - time = (int) (Clock::GetInstance()->GameTime()/1000); - } - - SetTarget(t); - SetInfo(i); -} - -SimEvent::~SimEvent() -{ -} - -// +--------------------------------------------------------------------+ - -void -SimEvent::SetTime(int t) -{ - time = t; -} - -void -SimEvent::SetTarget(const char* t) -{ - if (t && t[0]) - target = t; -} - -void -SimEvent::SetInfo(const char* i) -{ - if (i && i[0]) - info = i; -} - -void -SimEvent::SetCount(int c) -{ - count = c; -} - -Text -SimEvent::GetEventDesc() const -{ - switch (event) { - case LAUNCH: return ContentBundle::GetInstance()->GetText("sim.event.Launch"); - case DOCK: return ContentBundle::GetInstance()->GetText("sim.event.Dock"); - case LAND: return ContentBundle::GetInstance()->GetText("sim.event.Land"); - case EJECT: return ContentBundle::GetInstance()->GetText("sim.event.Eject"); - case CRASH: return ContentBundle::GetInstance()->GetText("sim.event.Crash"); - case COLLIDE: return ContentBundle::GetInstance()->GetText("sim.event.Collision With"); - case DESTROYED: return ContentBundle::GetInstance()->GetText("sim.event.Destroyed By"); - case MAKE_ORBIT: return ContentBundle::GetInstance()->GetText("sim.event.Make Orbit"); - case BREAK_ORBIT: return ContentBundle::GetInstance()->GetText("sim.event.Break Orbit"); - case QUANTUM_JUMP: return ContentBundle::GetInstance()->GetText("sim.event.Quantum Jump"); - case LAUNCH_SHIP: return ContentBundle::GetInstance()->GetText("sim.event.Launch Ship"); - case RECOVER_SHIP: return ContentBundle::GetInstance()->GetText("sim.event.Recover Ship"); - case FIRE_GUNS: return ContentBundle::GetInstance()->GetText("sim.event.Fire Guns"); - case FIRE_MISSILE: return ContentBundle::GetInstance()->GetText("sim.event.Fire Missile"); - case DROP_DECOY: return ContentBundle::GetInstance()->GetText("sim.event.Drop Decoy"); - case GUNS_KILL: return ContentBundle::GetInstance()->GetText("sim.event.Guns Kill"); - case MISSILE_KILL: return ContentBundle::GetInstance()->GetText("sim.event.Missile Kill"); - case LAUNCH_PROBE: return ContentBundle::GetInstance()->GetText("sim.event.Launch Probe"); - case SCAN_TARGET: return ContentBundle::GetInstance()->GetText("sim.event.Scan Target"); - default: return ContentBundle::GetInstance()->GetText("sim.event.no event"); - } -} - -// +====================================================================+ - -ShipStats::ShipStats(const char* n, int i) -: name(n), iff(i), kill1(0), kill2(0), lost(0), coll(0), points(0), -cmd_points(0), gun_shots(0), gun_hits(0), missile_shots(0), missile_hits(0), -combat_group(0), combat_unit(0), player(false), ship_class(0), elem_index(-1) -{ - if (!n || !n[0]) - name = ContentBundle::GetInstance()->GetText("[unknown]"); -} - -ShipStats::~ShipStats() -{ - events.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -ShipStats::SetType(const char* t) -{ - if (t && t[0]) - type = t; -} - -void -ShipStats::SetRole(const char* r) -{ - if (r && r[0]) - role = r; -} - -void -ShipStats::SetRegion(const char* r) -{ - if (r && r[0]) - region = r; -} - -void -ShipStats::SetCombatGroup(CombatGroup* g) -{ - combat_group = g; -} - -void -ShipStats::SetCombatUnit(CombatUnit* u) -{ - combat_unit = u; -} - -void -ShipStats::SetElementIndex(int n) -{ - elem_index = n; -} - -void -ShipStats::SetPlayer(bool p) -{ - player = p; -} - -// +--------------------------------------------------------------------+ - -void -ShipStats::Summarize() -{ - kill1 = 0; - kill2 = 0; - lost = 0; - coll = 0; - - ListIter iter = events; - while (++iter) { - SimEvent* event = iter.value(); - int code = event->GetEvent(); - - if (code == SimEvent::GUNS_KILL) - kill1++; - - else if (code == SimEvent::MISSILE_KILL) - kill2++; - - else if (code == SimEvent::DESTROYED) - lost++; - - else if (code == SimEvent::CRASH) - coll++; - - else if (code == SimEvent::COLLIDE) - coll++; - } -} - -// +--------------------------------------------------------------------+ - -SimEvent* -ShipStats::AddEvent(SimEvent* e) -{ - events.append(e); - return e; -} - -SimEvent* -ShipStats::AddEvent(int event, const char* tgt, const char* info) -{ - SimEvent* e = new SimEvent(event, tgt, info); - events.append(e); - return e; -} - -bool -ShipStats::HasEvent(int event) -{ - for (int i = 0; i < events.size(); i++) - if (events[i]->GetEvent() == event) - return true; - - return false; -} - -// +--------------------------------------------------------------------+ - -void ShipStats::Initialize() { records.destroy(); } -void ShipStats::Close() { records.destroy(); } - -// +--------------------------------------------------------------------+ - -int -ShipStats::NumStats() -{ - return records.size(); -} - -ShipStats* -ShipStats::GetStats(int i) -{ - if (i >= 0 && i < records.size()) - return records.at(i); - - return 0; -} - -ShipStats* -ShipStats::Find(const char* name) -{ - if (name && name[0]) { - ListIter iter = records; - while (++iter) { - ShipStats* stats = iter.value(); - if (!strcmp(stats->GetName(), name)) - return stats; - } - - ShipStats* stats = new ShipStats(name); - records.append(stats); - return stats; - } - - return 0; -} - diff --git a/Stars45/SimEvent.h b/Stars45/SimEvent.h deleted file mode 100644 index d4fe795..0000000 --- a/Stars45/SimEvent.h +++ /dev/null @@ -1,162 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simulation Universe and Region classes -*/ - -#ifndef SimEvent_h -#define SimEvent_h - -#include "Types.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Sim; -class SimRegion; -class SimObject; -class SimObserver; -class SimHyper; -class CombatGroup; -class CombatUnit; - -// +--------------------------------------------------------------------+ - -class SimEvent -{ -public: - static const char* TYPENAME() { return "SimEvent"; } - - enum EVENT { LAUNCH=1, DOCK, LAND, EJECT, CRASH, COLLIDE, DESTROYED, - MAKE_ORBIT, BREAK_ORBIT, QUANTUM_JUMP, - LAUNCH_SHIP, RECOVER_SHIP, - FIRE_GUNS, FIRE_MISSILE, DROP_DECOY, - GUNS_KILL, MISSILE_KILL, - LAUNCH_PROBE, SCAN_TARGET - }; - - SimEvent(int event, const char* tgt=0, const char* info=0); - ~SimEvent(); - - int GetEvent() const { return event; } - int GetTime() const { return time; } - Text GetEventDesc() const; - const char* GetTarget() const { return target; } - const char* GetInfo() const { return info; } - int GetCount() const { return count; } - - void SetTarget(const char* tgt); - void SetInfo(const char* info); - void SetCount(int count); - void SetTime(int time); - -private: - int event; - int time; - Text target; - Text info; - int count; -}; - -// +--------------------------------------------------------------------+ - -class ShipStats -{ -public: - static const char* TYPENAME() { return "ShipStats"; } - - ShipStats(const char* name, int iff=0); - ~ShipStats(); - - static void Initialize(); - static void Close(); - static ShipStats* Find(const char* name); - static int NumStats(); - static ShipStats* GetStats(int i); - - void Summarize(); - - const char* GetName() const { return name; } - const char* GetType() const { return type; } - const char* GetRole() const { return role; } - const char* GetRegion() const { return region; } - CombatGroup* GetCombatGroup() const { return combat_group; } - CombatUnit* GetCombatUnit() const { return combat_unit; } - int GetElementIndex() const { return elem_index; } - int GetShipClass() const { return ship_class; } - int GetIFF() const { return iff; } - int GetGunKills() const { return kill1; } - int GetMissileKills() const { return kill2; } - int GetDeaths() const { return lost; } - int GetColls() const { return coll; } - int GetPoints() const { return points; } - int GetCommandPoints()const { return cmd_points; } - - int GetGunShots() const { return gun_shots; } - int GetGunHits() const { return gun_hits; } - int GetMissileShots() const { return missile_shots; } - int GetMissileHits() const { return missile_hits; } - - bool IsPlayer() const { return player; } - - List& - GetEvents() { return events; } - SimEvent* AddEvent(SimEvent* e); - SimEvent* AddEvent(int event, const char* tgt=0, const char* info=0); - bool HasEvent(int event); - - void SetShipClass(int c) { ship_class = c; } - void SetIFF(int i) { iff = i; } - void SetType(const char* t); - void SetRole(const char* r); - void SetRegion(const char* r); - void SetCombatGroup(CombatGroup* g); - void SetCombatUnit(CombatUnit* u); - void SetElementIndex(int n); - void SetPlayer(bool p); - - void AddGunShot() { gun_shots++; } - void AddGunHit() { gun_hits++; } - void AddMissileShot() { missile_shots++; } - void AddMissileHit() { missile_hits++; } - void AddPoints(int p) { points += p; } - void AddCommandPoints(int p) { cmd_points += p; } - -private: - Text name; - Text type; - Text role; - Text region; - CombatGroup* combat_group; - CombatUnit* combat_unit; - bool player; - int elem_index; - int ship_class; - int iff; - int kill1; - int kill2; - int lost; - int coll; - - int gun_shots; - int gun_hits; - - int missile_shots; - int missile_hits; - - int points; - int cmd_points; - - List events; -}; - -#endif // SimEvent_h - diff --git a/Stars45/SimObject.cpp b/Stars45/SimObject.cpp deleted file mode 100644 index 24fac59..0000000 --- a/Stars45/SimObject.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simulation Object and Observer classes -*/ - -#include "SimObject.h" - -#include "Graphic.h" -#include "Light.h" -#include "Scene.h" - -// +--------------------------------------------------------------------+ - -SimObserver::~SimObserver() -{ - ListIter observed = observe_list; - while (++observed) - observed->Unregister(this); -} - -void -SimObserver::Observe(SimObject* obj) -{ - if (obj) { - obj->Register(this); - - if (!observe_list.contains(obj)) - observe_list.append(obj); - } -} - -void -SimObserver::Ignore(SimObject* obj) -{ - if (obj) { - obj->Unregister(this); - observe_list.remove(obj); - } -} - -bool -SimObserver::Update(SimObject* obj) -{ - if (obj) - observe_list.remove(obj); - - return true; -} - -const char* -SimObserver::GetObserverName() const -{ - static char name[32]; - sprintf_s(name, "SimObserver 0x%08x", (DWORD) this); - return name; -} - -// +--------------------------------------------------------------------+ - -SimObject::~SimObject() -{ - Notify(); -} - -// +--------------------------------------------------------------------+ - -void -SimObject::Notify() -{ - if (!notifying) { - notifying = true; - - int nobservers = observers.size(); - int nupdate = 0; - - if (nobservers > 0) { - ListIter iter = observers; - while (++iter) { - SimObserver* observer = iter.value(); - observer->Update(this); - nupdate++; - } - - observers.clear(); - } - - if (nobservers != nupdate) { - ::Print("WARNING: incomplete notify sim object '%s' - %d of %d notified\n", - Name(), nupdate, nobservers); - } - - notifying = false; - } - else { - ::Print("WARNING: double notify on sim object '%s'\n", Name()); - } -} - -// +--------------------------------------------------------------------+ - -void -SimObject::Register(SimObserver* observer) -{ - if (!notifying && !observers.contains(observer)) - observers.append(observer); -} - -// +--------------------------------------------------------------------+ - -void -SimObject::Unregister(SimObserver* observer) -{ - if (!notifying) - observers.remove(observer); -} - -// +--------------------------------------------------------------------+ - -void -SimObject::Activate(Scene& scene) -{ - if (rep) - scene.AddGraphic(rep); - if (light) - scene.AddLight(light); - - active = true; -} - -void -SimObject::Deactivate(Scene& scene) -{ - if (rep) - scene.DelGraphic(rep); - if (light) - scene.DelLight(light); - - active = false; -} - diff --git a/Stars45/SimObject.h b/Stars45/SimObject.h deleted file mode 100644 index 10fcfbf..0000000 --- a/Stars45/SimObject.h +++ /dev/null @@ -1,98 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Simulation Object and Observer classes -*/ - -#ifndef SimObject_h -#define SimObject_h - -#include "Types.h" -#include "Physical.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Sim; -class SimRegion; -class SimObject; -class SimObserver; -class Scene; - -// +--------------------------------------------------------------------+ - -class SimObject : public Physical -{ - friend class SimRegion; - -public: - static const char* TYPENAME() { return "SimObject"; } - - enum TYPES { - SIM_SHIP=100, - SIM_SHOT, - SIM_DRONE, - SIM_EXPLOSION, - SIM_DEBRIS, - SIM_ASTEROID - }; - - SimObject() : region(0), objid(0), active(0), notifying(0) { } - SimObject(const char* n, int t=0) : Physical(n,t), region(0), objid(0), active(0), notifying(0) { } - virtual ~SimObject(); - - virtual SimRegion* GetRegion() const { return region; } - virtual void SetRegion(SimRegion* rgn) { region = rgn; } - - virtual void Notify(); - virtual void Register(SimObserver* obs); - virtual void Unregister(SimObserver* obs); - - virtual void Activate(Scene& scene); - virtual void Deactivate(Scene& scene); - - virtual DWORD GetObjID() const { return objid; } - virtual void SetObjID(DWORD id) { objid = id; } - - virtual bool IsHostileTo(const SimObject* o) - const { return false; } - -protected: - SimRegion* region; - List observers; - DWORD objid; - bool active; - bool notifying; -}; - -// +--------------------------------------------------------------------+ - -class SimObserver -{ -public: - static const char* TYPENAME() { return "SimObserver"; } - - virtual ~SimObserver(); - - int operator == (const SimObserver& o) const { return this == &o; } - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - virtual void Observe(SimObject* obj); - virtual void Ignore(SimObject* obj); - - -protected: - List observe_list; -}; - -#endif // SimObject_h - diff --git a/Stars45/Skin.cpp b/Stars45/Skin.cpp deleted file mode 100644 index 62363c5..0000000 --- a/Stars45/Skin.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Classes for rendering solid meshes of polygons -*/ - -#include "Skin.h" -#include "Solid.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -Skin::Skin(const char* n) -{ - if (n && *n) { - strncpy_s(name, n, NAMELEN); - name[NAMELEN-1] = 0; - } - - else { - ZeroMemory(name, NAMELEN); - } - - ZeroMemory(path, 256); -} - -// +--------------------------------------------------------------------+ - -Skin::~Skin() -{ - cells.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -Skin::SetName(const char* n) -{ - if (n && *n) { - strncpy_s(name, n, NAMELEN); - name[NAMELEN-1] = 0; - } -} - -void -Skin::SetPath(const char* n) -{ - if (n && *n) { - strncpy_s(path, n, 256); - path[255] = 0; - } - - else { - ZeroMemory(path, 256); - } -} - -// +--------------------------------------------------------------------+ - -void -Skin::AddMaterial(const Material* mtl) -{ - if (!mtl) return; - - bool found = false; - - ListIter iter = cells; - while (++iter && !found) { - SkinCell* s = iter.value(); - - if (s->skin && !strcmp(s->skin->name, mtl->name)) { - s->skin = mtl; - found = true; - } - } - - if (!found) { - SkinCell* s = new SkinCell(mtl); - cells.append(s); - } -} - -// +--------------------------------------------------------------------+ - -void -Skin::ApplyTo(Model* model) const -{ - if (model) { - for (int i = 0; i < cells.size(); i++) { - SkinCell* s = cells[i]; - - if (s->skin) { - s->orig = model->ReplaceMaterial(s->skin); - } - } - } -} - -void -Skin::Restore(Model* model) const -{ - if (model) { - for (int i = 0; i < cells.size(); i++) { - SkinCell* s = cells[i]; - - if (s->orig) { - model->ReplaceMaterial(s->orig); - s->orig = 0; - } - } - } -} - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -SkinCell::SkinCell(const Material* mtl) - : skin(mtl), orig(0) -{ -} - -SkinCell::~SkinCell() -{ - delete skin; -} - -// +--------------------------------------------------------------------+ - -int -SkinCell::operator == (const SkinCell& other) const -{ - if (skin == other.skin) - return true; - - if (skin && other.skin) - return !strcmp(skin->name, other.skin->name); - - return false; -} - -// +--------------------------------------------------------------------+ - -const char* -SkinCell::Name() const -{ - if (skin) - return skin->name; - - return "Invalid Skin Cell"; -} - -// +--------------------------------------------------------------------+ - -void -SkinCell::SetSkin(const Material* mtl) -{ - skin = mtl; -} - -void -SkinCell::SetOrig(const Material* mtl) -{ - orig = mtl; -} diff --git a/Stars45/Skin.h b/Stars45/Skin.h deleted file mode 100644 index 25c5a75..0000000 --- a/Stars45/Skin.h +++ /dev/null @@ -1,91 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Classes for managing run-time selectable skins on solid objects -*/ - -#ifndef Skin_h -#define Skin_h - -#include "Polygon.h" -#include "Graphic.h" -#include "Video.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Solid; -class Model; -class Surface; -class Segment; - -class Skin; -class SkinCell; - -// +--------------------------------------------------------------------+ - -class Skin -{ -public: - static const char* TYPENAME() { return "Skin"; } - enum { NAMELEN=64 }; - - Skin(const char* name = 0); - virtual ~Skin(); - - // operations - void ApplyTo(Model* model) const; - void Restore(Model* model) const; - - // accessors / mutators - const char* Name() const { return name; } - const char* Path() const { return path; } - int NumCells() const { return cells.size(); } - - void SetName(const char* n); - void SetPath(const char* n); - void AddMaterial(const Material* mtl); - -protected: - char name[NAMELEN]; - char path[256]; - List cells; -}; - -// +--------------------------------------------------------------------+ - -class SkinCell -{ - friend class Skin; - -public: - static const char* TYPENAME() { return "SkinCell"; } - - SkinCell(const Material* mtl=0); - ~SkinCell(); - - int operator == (const SkinCell& other) const; - - const char* Name() const; - const Material* Skin() const { return skin; } - const Material* Orig() const { return orig; } - - void SetSkin(const Material* mtl); - void SetOrig(const Material* mtl); - -private: - const Material* skin; - const Material* orig; -}; - -// +--------------------------------------------------------------------+ - -#endif // Skin_h - diff --git a/Stars45/Sky.cpp b/Stars45/Sky.cpp deleted file mode 100644 index ff25044..0000000 --- a/Stars45/Sky.cpp +++ /dev/null @@ -1,723 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Celestial sphere, stars, planets, space dust... -*/ - -#include "Sky.h" -#include "StarSystem.h" - -#include "Clock.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Light.h" -#include "Random.h" -#include "Utils.h" - - -// +====================================================================+ - -Stars::Stars(int nstars) -{ - infinite = true; - luminous = true; - shadow = false; - - vset = new VertexSet(nstars); - colors = new Color[nstars]; - - for (int i = 0; i < nstars; i++) { - vset->loc[i] = RandomVector(1000); - - ColorValue val = ColorValue((float) Random(0.7, 0.8), - (float) Random(0.7, 0.8), - (float) Random(0.7, 0.8)); - Color c = val.ToColor(); - - colors[i] = c; - vset->diffuse[i] = c.Value(); - vset->specular[i] = 0; - } - - strcpy_s(name, "Stars"); -} - -Stars::~Stars() -{ - delete [] colors; - delete vset; -} - -// +--------------------------------------------------------------------+ - -void -Stars::Illuminate(double scale) -{ - if (!vset) - return; - - for (int i = 0; i < vset->nverts; i++) { - Color c = colors[i] * scale; - vset->diffuse[i] = c.Value(); - } -} - -// +--------------------------------------------------------------------+ - -void -Stars::Render(Video* video, DWORD flags) -{ - if (!vset || !video || (flags & Graphic::RENDER_ADDITIVE) == 0) - return; - - video->SetBlendType(Video::BLEND_ADDITIVE); - video->DrawPoints(vset); -} - -// +====================================================================+ - -static const double BOUNDARY = 3000; -static const double BOUNDARYx2 = BOUNDARY * 2; - -Dust::Dust(int ndust, bool b) - : really_hidden(false), bright(b) -{ - radius = (float) BOUNDARYx2; - luminous = true; - vset = new VertexSet(ndust); - - Reset(Point(0, 0, 0)); - strcpy_s(name, "Dust"); -} - -// +--------------------------------------------------------------------+ - -Dust::~Dust() -{ - delete vset; -} - -// +--------------------------------------------------------------------+ - -void -Dust::Reset(const Point& ref) -{ - BYTE c = 0; - - for (int i = 0; i < vset->nverts; i++) { - vset->loc[i] = Vec3( Random(-BOUNDARY, BOUNDARY), - Random(-BOUNDARY, BOUNDARY), - Random(-BOUNDARY, BOUNDARY) ); - - if (bright) - c = (BYTE) Random(96,200); - else - c = (BYTE) Random(64,156); - - vset->diffuse[i] = Color(c,c,c).Value(); - vset->specular[i] = 0; - } -} - -// +--------------------------------------------------------------------+ - -void -Dust::ExecFrame(double factor, const Point& ref) -{ - if (Clock::GetInstance()->TimeCompression() > 4.0) { - Hide(); - return; - } - - Show(); - - Point delta = ref - loc; - double dlen = delta.length(); - - if (dlen < 0.0001) - return; - - if (dlen > BOUNDARY) { - Reset(ref); - } - else { - // wrap around if necessary to keep in view - for (int i = 0; i < vset->nverts; i++) { - Vec3 v = vset->loc[i]; - - v -= delta; - - if (v.x > BOUNDARY) v.x -= (float) BOUNDARYx2; - if (v.x < -BOUNDARY) v.x += (float) BOUNDARYx2; - if (v.y > BOUNDARY) v.y -= (float) BOUNDARYx2; - if (v.y < -BOUNDARY) v.y += (float) BOUNDARYx2; - if (v.z > BOUNDARY) v.z -= (float) BOUNDARYx2; - if (v.z < -BOUNDARY) v.z += (float) BOUNDARYx2; - - vset->loc[i] = v; - } - } - - MoveTo(ref); -} - -// +--------------------------------------------------------------------+ - -void -Dust::Render(Video* video, DWORD flags) -{ - if (hidden || really_hidden) - return; - - if (!vset || !video || (flags & Graphic::RENDER_SOLID) == 0 || (flags & Graphic::RENDER_ADD_LIGHT) != 0) - return; - - video->SetBlendType(Video::BLEND_SOLID); - video->SetRenderState(Video::Z_ENABLE, false); - video->SetRenderState(Video::Z_WRITE_ENABLE, false); - - video->DrawPoints(vset); - - video->SetRenderState(Video::Z_ENABLE, true); - video->SetRenderState(Video::Z_WRITE_ENABLE, true); -} - -// +--------------------------------------------------------------------+ - -void -Dust::Hide() -{ - hidden = true; - really_hidden = true; -} - -void -Dust::Show() -{ - hidden = false; - really_hidden = false; -} - -// +====================================================================+ - -PlanetRep::PlanetRep(const char* surface_name, const char* glow_name, - double rad, const Vec3& pos, double tscale, - const char* rngname, double minrad, double maxrad, - Color atmos, const char* gloss_name) - : mtl_surf(0), mtl_limb(0), mtl_ring(0), star_system(0) -{ - loc = pos; - - radius = (float) rad; - has_ring = 0; - ring_verts = -1; - ring_polys = -1; - ring_rad = 0; - body_rad = rad; - daytime = false; - atmosphere = atmos; - star_system = 0; - - if (!surface_name || !*surface_name) { - Print(" invalid Planet patch - no surface texture specified\n"); - return; - } - - Print(" constructing Planet patch %s\n", surface_name); - strncpy(name, surface_name, 31); - name[31] = 0; - - Bitmap* bmp_surf = 0; - Bitmap* bmp_spec = 0; - Bitmap* bmp_glow = 0; - Bitmap* bmp_ring = 0; - Bitmap* bmp_limb = 0; - - DataLoader* loader = DataLoader::GetLoader(); - loader->LoadTexture(surface_name, bmp_surf, Bitmap::BMP_SOLID, true); - - if (glow_name && *glow_name) { - Print(" loading glow texture %s\n", glow_name); - loader->LoadTexture(glow_name, bmp_glow, Bitmap::BMP_SOLID, true); - } - - if (gloss_name && *gloss_name) { - Print(" loading gloss texture %s\n", gloss_name); - loader->LoadTexture(gloss_name, bmp_spec, Bitmap::BMP_SOLID, true); - } - - mtl_surf = new Material; - - mtl_surf->Ka = Color::LightGray; - mtl_surf->Kd = Color::White; - mtl_surf->Ke = bmp_glow ? Color::White : Color::Black; - mtl_surf->Ks = bmp_spec ? Color::LightGray : Color::Black; - mtl_surf->power = 25.0f; - mtl_surf->tex_diffuse = bmp_surf; - mtl_surf->tex_specular = bmp_spec; - mtl_surf->tex_emissive = bmp_glow; - mtl_surf->blend = Material::MTL_SOLID; - - if (bmp_spec && Video::GetInstance()->IsSpecMapEnabled()) { - if (glow_name && strstr(glow_name, "light")) - strcpy_s(mtl_surf->shader, "SimplePix/PlanetSurfNightLight"); - - else if (glow_name) - strcpy_s(mtl_surf->shader, "SimplePix/PlanetSurf"); - } - - if (atmosphere != Color::Black) { - mtl_limb = new Material; - - mtl_limb->Ka = atmosphere; - - strcpy_s(mtl_limb->shader, "PlanetLimb"); - - Print(" loading atmospheric limb texture PlanetLimb.pcx\n"); - loader->LoadTexture("PlanetLimb.pcx", bmp_limb, Bitmap::BMP_TRANSLUCENT, true); - mtl_limb->tex_diffuse = bmp_limb; - mtl_limb->blend = Material::MTL_TRANSLUCENT; - } - - if (maxrad > 0 && minrad > 0) { - has_ring = 1; - radius = (float) maxrad; - ring_rad = (maxrad + minrad)/2; - loader->LoadTexture(rngname, bmp_ring, Bitmap::BMP_SOLID, true); - - mtl_ring = new Material; - - mtl_ring->Ka = Color::LightGray; - mtl_ring->Kd = Color::White; - mtl_ring->Ks = Color::Gray; - mtl_ring->Ke = Color::Black; - mtl_ring->power = 30.0f; - mtl_ring->tex_diffuse = bmp_ring; - mtl_ring->blend = Material::MTL_TRANSLUCENT; - } - - if (rad > 2e6 && rad < 1e8) - CreateSphere(rad, 24, 32, minrad, maxrad, 48, tscale); - else - CreateSphere(rad, 16, 24, minrad, maxrad, 48, tscale); -} - -// +--------------------------------------------------------------------+ - -PlanetRep::~PlanetRep() -{ -} - -// +--------------------------------------------------------------------+ - -void -PlanetRep::CreateSphere(double radius, int nrings, int nsections, -double minrad, double maxrad, int rsections, -double tscale) -{ - const int sect_verts = nsections + 1; - - model = new Model; - own_model = 1; - - Surface* surface = new Surface; - - int i, j, m, n; - - int npolys = (nrings + 2) * nsections; - int nverts = (nrings + 3) * sect_verts; - - int ppolys = npolys; - int pverts = nverts; - - int apolys = 0; - int averts = 0; - - if (atmosphere != Color::Black) { - apolys = npolys; - averts = nverts; - - npolys *= 2; - nverts *= 2; - } - - if (has_ring) { - ring_verts = nverts; - ring_polys = npolys; - - npolys += rsections * 3; // top, bottom, edge - nverts += rsections * 6; - } - - surface->SetName(name); - surface->CreateVerts(nverts); - surface->CreatePolys(npolys); - - VertexSet* vset = surface->GetVertexSet(); - - if (!vset || vset->nverts < nverts) { - ::Print("WARNING: insufficient memory for planet '%s'\n", name); - return; - } - - Poly* polys = surface->GetPolys(); - - if (!polys) { - ::Print("WARNING: insufficient memory for planet '%s'\n", name); - return; - } - - ZeroMemory(polys, sizeof(Poly) * npolys); - - // Generate vertex points for planetary rings: - double dtheta = PI / (nrings + 2); - double dphi = 2 * PI / nsections; - double theta = 0; - n = 0; // vertex being generated - - for (i = 0; i < nrings+3; i++) { - double y = radius * cos(theta); // y is the same for entire ring - double v = theta / PI; // v is the same for entire ring - double rsintheta = radius * sin(theta); - double phi = 0; - - for (j = 0; j < sect_verts; j++) { - double x = rsintheta * sin(phi); - double z = rsintheta * cos(phi); - - vset->loc[n] = Vec3(x, y, z); - vset->nrm[n] = Vec3(x, y, z); - vset->tu[n] = (float) (tscale * (1 - (phi/(2.0*PI)))); - vset->tv[n] = (float) (tscale * v); - - vset->nrm[n].Normalize(); - - phi += dphi; - n++; - } - - theta += dtheta; - } - - // Generate vertex points for rings: - if (has_ring) { - n = ring_verts; - - double dphi = 2.0 * PI / rsections; - double y = 0; // y is the same for entire ring - - // top of ring: - double phi = 0; - for (j = 0; j < rsections; j++) { - double x = minrad * sin(phi); - double z = minrad * cos(phi); - - vset->loc[n] = Vec3(x, y, z); - vset->nrm[n] = Vec3(0, 1, 0); - vset->tu[n] = (j & 1) ? 1.0f : 0.0f; - vset->tv[n] = 0.0f; - n++; - - x = maxrad * sin(phi); - z = maxrad * cos(phi); - - vset->loc[n] = Vec3(x, y, z); - vset->nrm[n] = Vec3(0, 1, 0); - vset->tu[n] = (j & 1) ? 1.0f : 0.0f; - vset->tv[n] = 1.0f; - n++; - - phi += dphi; - } - - // bottom of ring: - phi = 0; - for (j = 0; j < rsections; j++) { - double x = minrad * sin(phi); - double z = minrad * cos(phi); - - vset->loc[n] = Vec3(x, y, z); - vset->nrm[n] = Vec3(0, -1, 0); - vset->tu[n] = (j & 1) ? 1.0f : 0.0f; - vset->tv[n] = 0.0f; - n++; - - x = maxrad * sin(phi); - z = maxrad * cos(phi); - - vset->loc[n] = Vec3(x, y, z); - vset->nrm[n] = Vec3(0, -1, 0); - vset->tu[n] = (j & 1) ? 1.0f : 0.0f; - vset->tv[n] = 1.0f; - n++; - - phi += dphi; - } - - // edge of ring: - phi = 0; - for (j = 0; j < rsections; j++) { - double x = maxrad * sin(phi); - double z = maxrad * cos(phi); - - Point normal = Point(x,0,z); - normal.Normalize(); - - double thickness = maxrad/333; - - vset->loc[n] = Vec3(x, y+thickness, z); - vset->nrm[n] = normal; - vset->tu[n] = (j & 1) ? 1.0f : 0.0f; - vset->tv[n] = 1.0f; - n++; - - vset->loc[n] = Vec3(x, y-thickness, z); - vset->nrm[n] = normal; - vset->tu[n] = (j & 1) ? 1.0f : 0.0f; - vset->tv[n] = 1.0f; - n++; - - phi += dphi; - } - } - - for (i = 0; i < npolys; i++) { - polys[i].nverts = 3; - polys[i].vertex_set = vset; - polys[i].material = mtl_surf; - } - - // Generate triangles for top and bottom caps. - for (i = 0; i < nsections; i++) { - Poly& p0 = polys[i]; - p0.verts[2] = i; - p0.verts[1] = sect_verts + i; - p0.verts[0] = sect_verts + ((i+1) % sect_verts); - - Poly& p1 = polys[ppolys - nsections + i]; - p1.verts[2] = pverts - 1 - i; - p1.verts[1] = pverts - 1 - sect_verts - i; - p1.verts[0] = pverts - 2 - sect_verts - i; - - surface->AddIndices(6); - } - - // Generate triangles for the planetary rings - m = sect_verts; // first vertex in current ring - n = nsections; // triangle being generated, skip the top cap - - for (i = 0; i < nrings; i++) { - for (j = 0; j < nsections; j++) { - Poly& p0 = polys[n]; - p0.nverts = 4; - p0.verts[3] = m + j; - p0.verts[2] = m + (sect_verts) + j; - p0.verts[1] = m + (sect_verts) + ((j + 1) % (sect_verts)); - p0.verts[0] = m + ((j + 1) % (sect_verts)); - n++; - - surface->AddIndices(6); - } - - m += sect_verts; - } - - if (averts && apolys && mtl_limb) { - for (i = 0; i < pverts; i++) { - vset->loc[averts + i] = vset->loc[i]; - vset->nrm[averts + i] = vset->nrm[i]; - } - - for (i = 0; i < ppolys; i++) { - Poly& p0 = polys[i]; - Poly& p1 = polys[apolys + i]; - - p1.vertex_set = vset; - p1.material = mtl_limb; - - p1.nverts = p0.nverts; - p1.verts[0] = p0.verts[0]; - p1.verts[1] = p0.verts[1]; - p1.verts[2] = p0.verts[2]; - p1.verts[3] = p0.verts[3]; - - surface->AddIndices(p1.nverts == 3 ? 3 : 6); - } - } - - if (has_ring) { - // Generate quads for the rings - m = ring_verts; // first vertex in top of ring, after planet verts - n = ring_polys; // quad being generated, after planet polys - - // top of ring: - for (j = 0; j < rsections; j++) { - Poly& p0 = polys[n]; - p0.nverts = 4; - p0.material = mtl_ring; - - p0.verts[3] = m + 2*j; - p0.verts[2] = m + 2*j + 1; - p0.verts[1] = m + ((2*j + 3) % (rsections*2)); - p0.verts[0] = m + ((2*j + 2) % (rsections*2)); - - surface->AddIndices(6); - - n++; - } - - // bottom of ring: - // first vertex in bottom of ring, after top ring verts - m = ring_verts + 2*rsections; - - for (j = 0; j < rsections; j++) { - Poly& p0 = polys[n]; - p0.nverts = 4; - p0.material = mtl_ring; - - p0.verts[0] = m + 2*j; - p0.verts[1] = m + 2*j + 1; - p0.verts[2] = m + ((2*j + 3) % (rsections*2)); - p0.verts[3] = m + ((2*j + 2) % (rsections*2)); - - surface->AddIndices(6); - - n++; - } - - // edge of ring: - // first vertex in edge of ring, after bottom ring verts - m = ring_verts + 4*rsections; - - for (j = 0; j < rsections; j++) { - Poly& p0 = polys[n]; - p0.nverts = 4; - p0.material = mtl_ring; - - p0.verts[3] = m + 2*j; - p0.verts[2] = m + 2*j + 1; - p0.verts[1] = m + ((2*j + 3) % (rsections*2)); - p0.verts[0] = m + ((2*j + 2) % (rsections*2)); - - surface->AddIndices(6); - - n++; - } - } - - // then assign them to cohesive segments: - Segment* segment = 0; - - for (n = 0; n < npolys; n++) { - Poly& poly = polys[n]; - poly.plane = Plane(vset->loc[poly.verts[0]], - vset->loc[poly.verts[2]], - vset->loc[poly.verts[1]]); - - if (segment && segment->material == polys[n].material) { - segment->npolys++; - } - else { - segment = new Segment; - - segment->npolys = 1; - segment->polys = &polys[n]; - segment->material = segment->polys->material; - - surface->GetSegments().append(segment); - } - } - - model->AddSurface(surface); -} - - -int -PlanetRep::CheckRayIntersection(Point Q, Point w, double len, Point& ipt, -bool treat_translucent_polys_as_solid) -{ - // compute leading edge of ray: - Point dst = Q + w*len; - - // check right angle spherical distance: - Point d0 = loc - Q; - Point d1 = d0.cross(w); - double dlen = d1.length(); // distance of point from line - - if (dlen > body_rad) // clean miss - return 0; // (no impact) - - // possible collision course... - Point d2 = Q + w * (d0 * w); - - // so check the leading edge: - Point delta0 = dst - loc; - - if (delta0.length() > radius) { - // and the endpoints: - Point delta1 = d2 - Q; - Point delta2 = dst - Q; - - // if d2 is not between Q and dst, we missed: - if (delta1 * delta2 < 0 || - delta1.length() > delta2.length()) { - return 0; - } - } - - return 1; -} - -void -PlanetRep::SetDaytime(bool d) -{ - daytime = d; - - if (daytime) { - if (mtl_surf) mtl_surf->blend = Material::MTL_ADDITIVE; - if (mtl_ring) mtl_ring->blend = Material::MTL_ADDITIVE; - } - - else { - if (mtl_surf) mtl_surf->blend = Material::MTL_SOLID; - if (mtl_ring) mtl_ring->blend = Material::MTL_TRANSLUCENT; - } -} - -void -PlanetRep::SetStarSystem(StarSystem* system) -{ - star_system = system; -} - -// +--------------------------------------------------------------------+ - -void -PlanetRep::Render(Video* video, DWORD flags) -{ - Solid::Render(video, flags); - - /*** - *** DEBUG - *** - -Matrix orient = Orientation(); -orient.Transpose(); - -video->SetObjTransform(orient, Location()); - -Surface* surf = model->GetSurfaces().first(); -Poly* polys = surf->GetPolys(); - -for (int i = 0; i < 5; i++) - video->DrawPolyOutline(polys + i); -/***/ -} - diff --git a/Stars45/Sky.h b/Stars45/Sky.h deleted file mode 100644 index 2ea0c59..0000000 --- a/Stars45/Sky.h +++ /dev/null @@ -1,104 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Celestial sphere, stars, planets, space dust... -*/ - -#ifndef Sky_h -#define Sky_h - -#include "Types.h" -#include "Solid.h" -#include "Bitmap.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class StarSystem; - -// +--------------------------------------------------------------------+ - -class Stars : public Graphic -{ -public: - Stars(int nstars); - virtual ~Stars(); - - virtual void Illuminate(double scale); - virtual void Render(Video* video, DWORD flags); - -protected: - VertexSet* vset; - Color* colors; -}; - -// +--------------------------------------------------------------------+ - -class Dust : public Graphic -{ -public: - Dust(int ndust, bool bright=false); - virtual ~Dust(); - - virtual void Render(Video* video, DWORD flags); - virtual void Reset(const Point& ref); - virtual void ExecFrame(double factor, const Point& ref); - - virtual void Hide(); - virtual void Show(); - -protected: - bool really_hidden; - bool bright; - VertexSet* vset; -}; - -// +--------------------------------------------------------------------+ - -class PlanetRep : public Solid -{ -public: - PlanetRep(const char* img_west, const char* img_glow, - double rad, const Vec3& pos, double tscale = 1, - const char* rngname=0, double minrad = 0, double maxrad = 0, - Color atmos = Color::Black, const char* img_gloss=0); - virtual ~PlanetRep(); - - virtual Color Atmosphere() const { return atmosphere; } - virtual void SetAtmosphere(Color a) { atmosphere = a; } - virtual void SetDaytime(bool d); - virtual void SetStarSystem(StarSystem* system); - - virtual void Render(Video* video, DWORD flags); - - virtual int CheckRayIntersection(Point pt, Point vpn, double len, Point& ipt, - bool treat_translucent_polys_as_solid=true); - -protected: - void CreateSphere(double radius, int nrings, int nsections, - double minrad, double maxrad, int rsections, - double tscale); - - Material* mtl_surf; - Material* mtl_limb; - Material* mtl_ring; - int has_ring; - int ring_verts; - int ring_polys; - double ring_rad; - double body_rad; - Color atmosphere; - bool daytime; - - StarSystem* star_system; -}; - -#endif // Sky_h - diff --git a/Stars45/Slider.cpp b/Stars45/Slider.cpp deleted file mode 100644 index 2970ac6..0000000 --- a/Stars45/Slider.cpp +++ /dev/null @@ -1,555 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Slider/Gauge ActiveWindow class -*/ - -#include "Slider.h" -#include "Video.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -Slider::Slider(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid) -: ActiveWindow(p->GetScreen(), ax, ay, aw, ah, aid, 0, p) -{ - captured = false; - dragging = false; - - border_color = Color::Black; - fill_color = Color::DarkBlue; - - active = true; - border = true; - num_leds = 1; - orientation = 0; - - range_min = 0; - range_max = 100; - step_size = 10; - show_thumb = 0; - thumb_size = -1; - - nvalues = 1; - ZeroMemory(value, sizeof(value)); - - marker[0] = -1; - marker[1] = -1; - - char buf[32]; - sprintf_s(buf, "Slider %d", id); //-V576 - desc = buf; -} - -Slider::Slider(Screen* s, int ax, int ay, int aw, int ah, DWORD aid) -: ActiveWindow(s, ax, ay, aw, ah, aid) -{ - captured = false; - dragging = false; - - border_color = Color::Black; - fill_color = Color::DarkBlue; - - active = true; - border = true; - num_leds = 1; - orientation = 0; - - range_min = 0; - range_max = 100; - step_size = 10; - show_thumb = 0; - thumb_size = -1; - - nvalues = 1; - ZeroMemory(value, sizeof(value)); - - marker[0] = -1; - marker[1] = -1; - - char buf[32]; - sprintf_s(buf, "Slider %d", id); //-V576 - desc = buf; -} - -Slider::~Slider() -{ -} - -// +--------------------------------------------------------------------+ - -void -Slider::Draw() -{ - int x = 0; - int y = 0; - int w = rect.w; - int h = rect.h; - - if (w < 1 || h < 1 || !shown) - return; - - Rect ctrl_rect(x,y,w,h); - - // draw the border: - if (border) { - Color oc = ShadeColor(border_color, 1); - DrawRect(0,0,w-1,h-1,oc); - DrawRect(1,1,w-2,h-2,oc); - - ctrl_rect.Deflate(2,2); - } - - // draw the bevel: - FillRect(ctrl_rect, back_color); - DrawStyleRect(ctrl_rect, WIN_SUNK_FRAME); - - // HORIZONTAL - if (orientation == 0) { - // draw the leds: - int led_width = ((w - 6) / (num_leds)) - 1; - int led_height = ((h - 5) / (nvalues)) - 1; - - if (nvalues < 2) { - int fill_width = (int) ((double)(w-4) * FractionalValue()); - int num_lit = fill_width / (led_width+1); - - Color fc = ShadeColor(fill_color, 1); - - if (num_leds == 1) { - FillRect(2,2,2+fill_width,h-3,fc); - } - else { - int x0 = 2; - - for (int i = 0; i < num_lit; i++) { - FillRect(x0,2,x0+led_width,h-3,fc); - x0 += led_width + 1; - } - } - - // draw the thumb: - if (thumb_size) { - if (thumb_size < 0) thumb_size = h; - - thumb_pos = 2+fill_width; - - Rect thumb_rect(thumb_pos-thumb_size/2, 0, thumb_size, h); - - if (thumb_rect.x < 0) - thumb_rect.x = 0; - - else if (thumb_rect.x > w-thumb_size) - thumb_rect.x = w-thumb_size; - - if (show_thumb) { - FillRect(thumb_rect, back_color); - DrawStyleRect(thumb_rect, WIN_RAISED_FRAME); - } - } - } - - else { - Color fc = ShadeColor(fill_color, 1); - - int y0 = 3; - - for (int i = 0; i < nvalues; i++) { - int fill_width = (int) ((double)(w-6) * FractionalValue(i)); - FillRect(3,y0,3+fill_width,y0+led_height,fc); - - y0 += led_height+1; - } - } - - // draw the markers: - if (marker[0] >= 0) { - int m = marker[0]; - Color c = ShadeColor(base_color, 1.6); // full highlight - DrawLine(m-3, 1, m+4, 1, c); - c = ShadeColor(base_color, 1.3); // soft highlight - DrawLine(m-3, 2, m-3, 4, c); - DrawLine(m-2, 4, m-2, 6, c); - DrawLine(m-1, 6, m-1, 8, c); - DrawLine(m , 8, m , 10, c); - c = base_color; // body - DrawLine(m-2, 2, m-2, 4, c); - DrawLine(m-1, 2, m-1, 6, c); - DrawLine(m , 2, m , 8, c); - DrawLine(m+1, 2, m+1, 6, c); - DrawLine(m+2, 2, m+2, 4, c); - c = ShadeColor(base_color, 0.5); // shadow - DrawLine(m+1, 6, m+1, 8, c); - DrawLine(m+2, 4, m+2, 6, c); - DrawLine(m+3, 2, m+3, 4, c); - } - - if (marker[1] >= 0) { - int m = marker[0]; - Color c = ShadeColor(base_color, 0.5); // shadow - DrawLine(m-3, h-2, m+4, h-2, c); - DrawLine(m+1, h-6, m+1, h-8, c); - DrawLine(m+2, h-4, m+2, h-6, c); - DrawLine(m+3, h-2, m+3, h-4, c); - c = ShadeColor(base_color, 1.3); // soft highlight - DrawLine(m-3, h-2, m-3, h-4, c); - DrawLine(m-2, h-4, m-2, h-6, c); - DrawLine(m-1, h-6, m-1, h-8, c); - DrawLine(m , h-8, m , h-10, c); - c = base_color; // body - DrawLine(m-2, h-2, m-2, h-4, c); - DrawLine(m-1, h-2, m-1, h-6, c); - DrawLine(m , h-2, m , h-8, c); - DrawLine(m+1, h-2, m+1, h-6, c); - DrawLine(m+2, h-2, m+2, h-4, c); - } - } - - // VERTICAL - else { - // draw the leds: - int led_width = ((w - 5) / (nvalues)) - 1; - - if (num_leds > 1) { - } - else { - if (nvalues < 2) { - led_width = w - 4; - int led_height = (int) ((double)(h-4) * FractionalValue()); - - Color fc = ShadeColor(fill_color, 1); - FillRect(2, h-2-led_height, 2+led_width, h-2, fc); - - // draw the thumb: - if (thumb_size) { - if (thumb_size < 0) thumb_size = w; - - thumb_pos = h-2-led_height; - - Rect thumb_rect(0, thumb_pos-(thumb_size/2), w, thumb_size); - - if (thumb_rect.y < 0) - thumb_rect.y = 0; - - else if (thumb_rect.y > h-thumb_size) - thumb_rect.y = h-thumb_size; - - if (show_thumb) { - FillRect(thumb_rect, back_color); - DrawStyleRect(thumb_rect, WIN_RAISED_FRAME); - } - } - } - - else { - Color fc = ShadeColor(fill_color, 1); - - int x0 = 3; - - for (int i = 0; i < nvalues; i++) { - int led_height = (int) ((double)(h-6) * FractionalValue(i)); - FillRect(x0,h-3-led_height,x0+led_width,h-3,fc); - - x0 += led_width+1; - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -bool Slider::GetActive() -{ - return active; -} - -void Slider::SetActive(bool bNewValue) -{ - active = bNewValue; -} - -bool Slider::GetBorder() -{ - return border; -} - -void Slider::SetBorder(bool bNewValue) -{ - border = bNewValue; -} - -Color Slider::GetBorderColor() -{ - return border_color; -} - -void Slider::SetBorderColor(Color newValue) -{ - border_color = newValue; -} - -Color Slider::GetFillColor() -{ - return fill_color; -} - -void Slider::SetFillColor(Color cNewValue) -{ - fill_color = cNewValue; -} - -int Slider::GetNumLeds() -{ - return num_leds; -} - -void Slider::SetNumLeds(int nNewValue) -{ - if (nNewValue >= 0) { - num_leds = nNewValue; - } -} - -int Slider::GetOrientation() -{ - return orientation; -} - -void Slider::SetOrientation(int nNewValue) -{ - if (nNewValue == 0 || nNewValue == 1) { - orientation = nNewValue; - } -} - -int Slider::GetRangeMin() -{ - return range_min; -} - -void Slider::SetRangeMin(int nNewValue) -{ - range_min = nNewValue; -} - -int Slider::GetRangeMax() -{ - return range_max; -} - -void Slider::SetRangeMax(int nNewValue) -{ - range_max = nNewValue; -} - -int Slider::GetStepSize() -{ - return step_size; -} - -void Slider::SetStepSize(int nNewValue) -{ - if (nNewValue < range_max - range_min) - step_size = nNewValue; -} - -bool Slider::GetShowThumb() -{ - return show_thumb?true:false; -} - -void Slider::SetShowThumb(bool bNewValue) -{ - show_thumb = bNewValue; -} - -int Slider::GetThumbSize() -{ - return thumb_size; -} - -void Slider::SetThumbSize(int nNewValue) -{ - if (nNewValue < range_max - range_min) - thumb_size = nNewValue; -} - -int Slider::NumValues() -{ - return nvalues; -} - -int Slider::GetValue(int index) -{ - if (index >= 0 && index < nvalues) - return value[index]; - - return 0; -} - -void Slider::SetValue(int nNewValue, int index) -{ - if (index >= 0 && index < MAX_VAL) { - value[index] = nNewValue; - - if (index >= nvalues) - nvalues = index+1; - } -} - -void Slider::SetMarker(int nNewValue, int index) -{ - if (index >= 0 && index < 2) { - marker[index] = nNewValue; - } -} - -double Slider::FractionalValue(int index) -{ - if (index >= 0 && index < nvalues) - return ((double) (value[index]-range_min)) / ((double) (range_max-range_min)); - - return 0; -} - -// +--------------------------------------------------------------------+ - -void Slider::StepUp(int index) -{ - if (index >= 0 && index < nvalues) { - value[index] += step_size; - - if (value[index] > range_max) - value[index] = range_max; - } -} - -void Slider::StepDown(int index) -{ - if (index >= 0 && index < nvalues) { - value[index] -= step_size; - - if (value[index] < range_min) - value[index] = range_min; - } -} - -// +--------------------------------------------------------------------+ - -int Slider::OnMouseMove(int x, int y) -{ - bool dirty = false; - - if (captured) - { - ActiveWindow* test = GetCapture(); - - if (test != this) - { - captured = false; - dirty = true; - } - - else if (dragging) - { - mouse_x = x - rect.x; - if (mouse_x < 0) mouse_x = 0; - else if (mouse_x > rect.w) mouse_x = rect.w; - - mouse_y = rect.h - (y - rect.y); - if (mouse_y < 0) mouse_y = 0; - else if (mouse_y > rect.h) mouse_y = rect.h; - - // HORIZONTAL - if (orientation == 0) { - SetValue((int) ((double) mouse_x/rect.w * (range_max-range_min) + range_min)); - } - - // VERTICAL - else { - SetValue((int) ((double) mouse_y/rect.h * (range_max-range_min) + range_min)); - } - - dirty = true; - } - } - - if (dirty) - OnClick(); - - return ActiveWindow::OnMouseMove(x,y); -} - -int Slider::OnLButtonDown(int x, int y) -{ - if (!active) - return 0; - - if (!captured) - captured = SetCapture(); - - mouse_x = x - rect.x; - mouse_y = y - rect.y; - - // HORIZONTAL - if (orientation == 0) { - if (mouse_x < thumb_pos-thumb_size/2) { - StepDown(); - } - - else if (mouse_x > thumb_pos+thumb_size/2) { - StepUp(); - } - - else { - dragging = true; - } - } - - // VERTICAL - else { - if (mouse_y < thumb_pos-thumb_size/2) { - StepUp(); - } - - else if (mouse_y > thumb_pos+thumb_size/2) { - StepDown(); - } - - else { - dragging = true; - } - } - - if (!dragging) - OnClick(); - - return ActiveWindow::OnLButtonDown(x,y); -} - -int Slider::OnLButtonUp(int x, int y) -{ - if (!active) - return 0; - - if (captured) { - ReleaseCapture(); - captured = 0; - dragging = false; - } - - return ActiveWindow::OnLButtonUp(x,y); -} - -int Slider::OnClick() -{ - return ActiveWindow::OnClick(); -} diff --git a/Stars45/Slider.h b/Stars45/Slider.h deleted file mode 100644 index 6221803..0000000 --- a/Stars45/Slider.h +++ /dev/null @@ -1,106 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Slider/Gauge ActiveWindow class -*/ - -#ifndef Slider_h -#define Slider_h - -#include "Types.h" -#include "ActiveWindow.h" - -// +--------------------------------------------------------------------+ - -class Slider : public ActiveWindow -{ -public: - static const char* TYPENAME() { return "Slider"; } - - enum { MAX_VAL=8, ORIENT_HORIZONTAL=0, ORIENT_VERTICAL=1 }; - - Slider(ActiveWindow* p, int ax, int ay, int aw, int ah, DWORD aid); - Slider(Screen* s, int ax, int ay, int aw, int ah, DWORD aid); - virtual ~Slider(); - - // Operations: - virtual void Draw(); - - // Event Target Interface: - virtual int OnMouseMove(int x, int y); - virtual int OnLButtonDown(int x, int y); - virtual int OnLButtonUp(int x, int y); - virtual int OnClick(); - - // Property accessors: - bool GetActive(); - void SetActive(bool bNewValue); - Color GetFillColor(); - void SetFillColor(Color c); - bool GetBorder(); - void SetBorder(bool bNewValue); - Color GetBorderColor(); - void SetBorderColor(Color c); - - int GetNumLeds(); - void SetNumLeds(int nNewValue); - int GetOrientation(); - void SetOrientation(int nNewValue); - - int GetRangeMin(); - void SetRangeMin(int nNewValue); - int GetRangeMax(); - void SetRangeMax(int nNewValue); - int GetStepSize(); - void SetStepSize(int nNewValue); - int GetThumbSize(); - void SetThumbSize(int nNewValue); - bool GetShowThumb(); - void SetShowThumb(bool bNewValue); - - int NumValues(); - int GetValue(int index=0); - void SetValue(int nNewValue, int index=0); - double FractionalValue(int index=0); - - void SetMarker(int nNewValue, int index=0); - - // Methods: - void StepUp(int index=0); - void StepDown(int index=0); - -protected: - int captured; - int dragging; - int mouse_x; - int mouse_y; - - bool active; // true => slider; false => gauge - bool border; - Color border_color; - Color fill_color; // default: dark blue - - int num_leds; // default: 1 - int orientation; // 0 => horizontal; !0 => vertical - - int range_min; - int range_max; - int step_size; - int show_thumb; - int thumb_size; - int thumb_pos; - - int nvalues; - int value[MAX_VAL]; - int marker[2]; -}; - -#endif // Slider_h - diff --git a/Stars45/Solid.cpp b/Stars45/Solid.cpp deleted file mode 100644 index ff4f610..0000000 --- a/Stars45/Solid.cpp +++ /dev/null @@ -1,2476 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Classes for rendering solid meshes of polygons -*/ - -#include "Solid.h" -#include "Scene.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Light.h" -#include "Shadow.h" -#include "Projector.h" -#include "Opcode.h" -#include "Utils.h" - -#ifdef for -#undef for -#endif - -// +--------------------------------------------------------------------+ - -static bool use_collision_detection = true; - -bool Solid::IsCollisionEnabled() { return use_collision_detection; } -void Solid::EnableCollision(bool e) { use_collision_detection = e; } - -// +--------------------------------------------------------------------+ - -Opcode::AABBTreeCollider opcode_collider; - -class OPCODE_data -{ -public: - OPCODE_data(Surface* s) { - bool status = false; - - if (s) { - using namespace Opcode; - opcode_collider.SetFirstContact(true); - - npolys = s->NumPolys(); - nverts = s->NumVerts(); - ntris = s->NumIndices() / 3; - - locs = new IcePoint[nverts]; - tris = new IndexedTriangle[ntris]; - - if (locs && tris) { - int i, n = 0; - - for (i = 0; i < nverts; i++) { - IcePoint* p = locs + i; - Vec3* v = s->GetVertexSet()->loc + i; - - p->Set(v->x, v->y, v->z); - } - - for (i = 0; i < npolys; i++) { - Poly* p = s->GetPolys() + i; - - if (p->nverts == 3) { - IndexedTriangle& t = tris[n++]; - - t.mVRef[0] = p->verts[0]; - t.mVRef[1] = p->verts[2]; - t.mVRef[2] = p->verts[1]; - } - else { - IndexedTriangle& t1 = tris[n++]; - IndexedTriangle& t2 = tris[n++]; - - t1.mVRef[0] = p->verts[0]; - t1.mVRef[1] = p->verts[2]; - t1.mVRef[2] = p->verts[1]; - - t2.mVRef[0] = p->verts[0]; - t2.mVRef[1] = p->verts[3]; - t2.mVRef[2] = p->verts[2]; - } - } - - mesh.SetNbVertices(nverts); - mesh.SetNbTriangles(ntris); - mesh.SetPointers(tris, locs); - - OPCODECREATE creator; - creator.mIMesh = &mesh; - status = model.Build(creator); - } - } - else { - tris = 0; - locs = 0; - npolys = 0; - nverts = 0; - ntris = 0; - } - } - - ~OPCODE_data() { - delete [] tris; - delete [] locs; - } - - Opcode::Model model; - Opcode::MeshInterface mesh; - IndexedTriangle* tris; - IcePoint* locs; - int npolys; - int nverts; - int ntris; -}; - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -Solid::Solid() - : model(0), own_model(1), roll(0.0f), pitch(0.0f), yaw(0.0f), intersection_poly(0) -{ - shadow = true; - sprintf_s(name, "Solid %d", id); -} - -// +--------------------------------------------------------------------+ - -Solid::~Solid() -{ - if (own_model) - delete model; - - shadows.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -Solid::Update() -{ -} - -// +--------------------------------------------------------------------+ - -void -Solid::SetOrientation(const Matrix& o) -{ - orientation = o; -} - -void -Solid::SetLuminous(bool l) -{ - luminous = l; - - if (model && luminous) { - model->luminous = luminous; - - ListIter iter = model->GetMaterials(); - - while (++iter) { - Material* mtl = iter.value(); - - mtl->Ka = Color::Black; - mtl->Kd = Color::Black; - mtl->Ks = Color::Black; - mtl->Ke = Color::White; - - if (mtl->tex_diffuse && !mtl->tex_emissive) - mtl->tex_emissive = mtl->tex_diffuse; - } - - ListIter s_iter = model->GetSurfaces(); - while (++s_iter) { - Surface* surface = s_iter.value(); - VertexSet* vset = surface->GetVertexSet(); - - for (int i = 0; i < vset->nverts; i++) { - vset->diffuse[i] = Color::White.Value(); - vset->specular[i] = Color::Black.Value(); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Solid::SetOrientation(const Solid& match) -{ - if (!model || infinite) - return; - - // copy the orientation matrix from the solid we are matching: - orientation = match.Orientation(); -} - -// +--------------------------------------------------------------------+ - -void -Solid::Render(Video* video, DWORD flags) -{ - if (flags & RENDER_ADDITIVE) - return; - - if (video && model && model->NumPolys()) { - DWORD blend_modes = Video::BLEND_SOLID; - - if (flags == RENDER_ALPHA) - blend_modes = Video::BLEND_ALPHA | Video::BLEND_ADDITIVE; - - video->DrawSolid(this, blend_modes); - } -} - -// +--------------------------------------------------------------------+ - -void -Solid::SelectDetail(Projector* p) -{ -} - -// +--------------------------------------------------------------------+ - -void -Solid::ProjectScreenRect(Projector* p) -{ - if (model && p) { - Point tmp = loc; - p->Transform(tmp); - - if (tmp.z > 1) { - int l = 2000; - int r = -2000; - int t = 2000; - int b = -2000; - - for (int i = 0; i < 6; i++) { - Point extent; - - if (i < 2) - extent.x = model->extents[i]; - - else if (i < 4) - extent.y = model->extents[i]; - - else - extent.z = model->extents[i]; - - extent = extent * orientation + loc; - - p->Transform(extent); - p->Project(extent); - - if (extent.x < l) l = (int) extent.x; - if (extent.x > r) r = (int) extent.x; - if (extent.y < t) t = (int) extent.y; - if (extent.y > b) b = (int) extent.y; - } - - screen_rect.x = l; - screen_rect.y = t; - screen_rect.w = r-l; - screen_rect.h = b-t; - return; - } - } - - screen_rect.x = 2000; - screen_rect.y = 2000; - screen_rect.w = 0; - screen_rect.h = 0; -} - -// +--------------------------------------------------------------------+ -// Polygon Interference Detection: - -int -Solid::CollidesWith(Graphic& o) -{ - Vec3 delta_loc = Location() - o.Location(); - - // bounding spheres test: - if (delta_loc.length() > Radius() + o.Radius()) - return 0; - - // possible collision, but no further refinement can be done: - if (!o.IsSolid()) - return 1; - - Solid& s = (Solid&) o; - - // use the OPCODE library to check for polygon interference: - if (model && s.model) { - using namespace Opcode; - - bool contact = false; - - // first, reverse the orientation matrices for OPCODE: - Matrix m1 = orientation; - Matrix m2 = s.orientation; - - Matrix4x4 world0; - Matrix4x4 world1; - - world0.m[0][0] = (float) m1.elem[0][0]; - world0.m[0][1] = (float) m1.elem[0][1]; - world0.m[0][2] = (float) m1.elem[0][2]; - world0.m[0][3] = 0.0f; - - world0.m[1][0] = (float) m1.elem[1][0]; - world0.m[1][1] = (float) m1.elem[1][1]; - world0.m[1][2] = (float) m1.elem[1][2]; - world0.m[1][3] = 0.0f; - - world0.m[2][0] = (float) m1.elem[2][0]; - world0.m[2][1] = (float) m1.elem[2][1]; - world0.m[2][2] = (float) m1.elem[2][2]; - world0.m[2][3] = 0.0f; - - world0.m[3][0] = (float) Location().x; - world0.m[3][1] = (float) Location().y; - world0.m[3][2] = (float) Location().z; - world0.m[3][3] = 1.0f; - - world1.m[0][0] = (float) m2.elem[0][0]; - world1.m[0][1] = (float) m2.elem[1][0]; - world1.m[0][2] = (float) m2.elem[2][0]; - world1.m[0][3] = 0.0f; - - world1.m[1][0] = (float) m2.elem[0][1]; - world1.m[1][1] = (float) m2.elem[1][1]; - world1.m[1][2] = (float) m2.elem[2][1]; - world1.m[1][3] = 0.0f; - - world1.m[2][0] = (float) m2.elem[0][2]; - world1.m[2][1] = (float) m2.elem[1][2]; - world1.m[2][2] = (float) m2.elem[2][2]; - world1.m[2][3] = 0.0f; - - world1.m[3][0] = (float) s.Location().x; - world1.m[3][1] = (float) s.Location().y; - world1.m[3][2] = (float) s.Location().z; - world1.m[3][3] = 1.0f; - - ListIter s1_iter = model->surfaces; - while (++s1_iter && !contact) { - Surface* s1 = s1_iter.value(); - - ListIter s2_iter = s.model->surfaces; - while (++s2_iter && !contact) { - Surface* s2 = s2_iter.value(); - - if (s1->opcode && s2->opcode) { - BVTCache bvt; - bvt.Model0 = &s1->opcode->model; - bvt.Model1 = &s2->opcode->model; - - if (opcode_collider.Collide(bvt, &world0, &world1)) - if (opcode_collider.GetContactStatus() != 0) - contact = true; - } - } - } - - return contact; - } - - - return 1; -} - -// +--------------------------------------------------------------------+ -// Find the intersection of the ray (Q + w*len) with the solid. -// If the ray intersects a polygon of the solid, place the intersection -// point in ipt, and return 1. Otherwise, return 0. - -int -Solid::CheckRayIntersection(Point Q, Point w, double len, Point& ipt, -bool treat_translucent_polys_as_solid) -{ - int impact = 0; - - if (!model || model->npolys < 1) - return impact; - - // check right angle spherical distance: - Point d0 = loc - Q; - Point d1 = d0.cross(w); - double dlen = d1.length(); // distance of point from line - - if (dlen > radius) // clean miss - return 0; // (no impact) - - // possible collision course... - - /********************************** - - - /--- + leading_edge = Q + w * len - / / \ - delta2 / delta 0 - / / \ - / *........x <- solid location - / / - / / delta1 -/--- Q * = closest point - - -************************************/ - - // find the point on the ray that is closest - // to the solid's location: - Point closest = Q + w * (d0 * w); - - // find the leading edge, and it's distance from the location: - Point leading_edge = Q + w*len; - Point leading_delta = leading_edge - loc; - double leading_dist = leading_delta.length(); - - // if the leading edge is not within the bounding sphere, - if (leading_dist > radius) { - // check to see if the closest point is between the - // ray's endpoints: - Point delta1 = closest - Q; - Point delta2 = leading_edge - Q; // this is w*len - - // if the closest point is not between the leading edge - // and the origin, this ray does not intersect: - if (delta1 * delta2 < 0 || delta1.length() > len) { - return 0; - } - } - - // probable hit at this point... - - // if not active, that's good enough: - if (GetScene() == 0) { - ipt = closest; - return 1; - } - - // transform ray into object space: - Matrix xform(Orientation()); - - Vec3 tmp = w; - - w.x = tmp * Vec3(xform(0,0), xform(0,1), xform(0,2)); - w.y = tmp * Vec3(xform(1,0), xform(1,1), xform(1,2)); - w.z = tmp * Vec3(xform(2,0), xform(2,1), xform(2,2)); - - tmp = Q-loc; - - Q.x = tmp * Vec3(xform(0,0), xform(0,1), xform(0,2)); - Q.y = tmp * Vec3(xform(1,0), xform(1,1), xform(1,2)); - Q.z = tmp * Vec3(xform(2,0), xform(2,1), xform(2,2)); - - double min = len; - intersection_poly = 0; - - // check each polygon: - ListIter iter = model->surfaces; - while (++iter) { - Surface* s = iter.value(); - Poly* p = s->GetPolys(); - - for (int i = 0; i < s->NumPolys(); i++) { - if (!treat_translucent_polys_as_solid && p->material && !p->material->IsSolid()) { - p++; - continue; - } - - Point v = p->plane.normal; - double d = p->plane.distance; - - double denom = w*v; - - if (denom < -1.0e-5) { - Point P = v * d; - double ilen = ((P-Q)*v)/denom; - - if (ilen > 0 && ilen < min) { - Point intersect = Q + w * ilen; - - if (p->Contains(intersect)) { - intersection_poly = p; - ipt = intersect; - min = ilen; - impact = 1; - } - } - } - - p++; - } - } - - // xform impact point back into world coordinates: - - if (impact) { - ipt = (ipt * Orientation()) + loc; - } - - return impact; -} - -// +--------------------------------------------------------------------+ - -void -Solid::ClearModel() -{ - if (own_model && model) { - delete model; - model = 0; - } - - radius = 0.0f; -} - -// +--------------------------------------------------------------------+ - -void -Solid::UseModel(Model* m) -{ - // get rid of the existing model: - ClearModel(); - - // point to the new model: - own_model = 0; - model = m; - radius = m->radius; -} - -// +--------------------------------------------------------------------+ - -bool -Solid::Load(const char* mag_file, double scale) -{ - // get ready to load, delete existing model: - ClearModel(); - - // loading our own copy, so we own the model: - model = new Model; - own_model = 1; - - // now load the model: - if (model->Load(mag_file, scale)) { - radius = model->radius; - strncpy_s(name, model->name, sizeof(name)); - return true; - } - - // load failed: - ClearModel(); - return false; -} - -bool -Solid::Load(ModelFile* mod_file, double scale) -{ - // get ready to load, delete existing model: - ClearModel(); - - // loading our own copy, so we own the model: - model = new Model; - own_model = 1; - - // now load the model: - if (model->Load(mod_file, scale)) { - radius = model->radius; - return true; - } - - // load failed: - ClearModel(); - return false; -} - -bool -Solid::Rescale(double scale) -{ - if (!own_model || !model) - return false; - - radius = 0; - - ListIter iter = model->GetSurfaces(); - while (++iter) { - Surface* s = iter.value(); - - for (int v = 0; v < s->NumVerts(); v++) { - s->vertex_set->loc[v] *= (float) scale; - s->vloc[v] *= (float) scale; - - float lvi = s->vloc[v].length(); - if (lvi > radius) - radius = lvi; - } - } - - model->radius = radius; - - InvalidateSurfaceData(); - - return true; -} - -void -Solid::CreateShadows(int nlights) -{ - while (shadows.size() < nlights) { - shadows.append(new Shadow(this)); - } -} - -void -Solid::UpdateShadows(List& lights) -{ - List active_lights; - ListIter iter = lights; - - while (++iter) { - Light* light = iter.value(); - - if (light->IsActive() && light->CastsShadow()) { - double distance = Point(Location() - light->Location()).length(); - double intensity = light->Intensity(); - - if (light->Type() == Light::LIGHT_POINT) { - if (intensity / distance > 1) - active_lights.append(light); - } - - else if (light->Type() == Light::LIGHT_DIRECTIONAL) { - if (intensity > 0.65) - active_lights.insert(light); - } - } - } - - iter.attach(active_lights); - - while (++iter) { - Light* light = iter.value(); - int index = iter.index(); - - if (index < shadows.size()) { - shadows[index]->Update(light); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Solid::DeletePrivateData() -{ - if (model) - model->DeletePrivateData(); -} - -// +--------------------------------------------------------------------+ - -void -Solid::InvalidateSurfaceData() -{ - if (!model) - return; - - bool invalidate = model->IsDynamic(); - - ListIter iter = model->GetSurfaces(); - while (++iter) { - Surface* s = iter.value(); - VideoPrivateData* vpd = s->GetVideoPrivateData(); - - if (vpd) { - if (invalidate) { - vpd->Invalidate(); - } - else { - delete vpd; - s->SetVideoPrivateData(0); - } - } - } -} - -void -Solid::InvalidateSegmentData() -{ - if (!model) - return; - - bool invalidate = model->IsDynamic(); - - ListIter iter = model->GetSurfaces(); - while (++iter) { - Surface* s = iter.value(); - - ListIter seg_iter = s->GetSegments(); - while (++seg_iter) { - Segment* segment = seg_iter.value(); - VideoPrivateData* vpd = segment->GetVideoPrivateData(); - - if (vpd) { - if (invalidate) { - vpd->Invalidate(); - } - else { - delete vpd; - segment->SetVideoPrivateData(0); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -bool -Solid::IsDynamic() const -{ - if (model) - return model->IsDynamic(); - - return false; -} - -void -Solid::SetDynamic(bool d) -{ - if (model && own_model) - model->SetDynamic(d); -} - -// +--------------------------------------------------------------------+ - -void -Solid::GetAllTextures(List& textures) -{ - if (model) - model->GetAllTextures(textures); -} - -void -Model::GetAllTextures(List& textures) -{ - ListIter m_iter = materials; - while (++m_iter) { - Material* m = m_iter.value(); - - if (m->tex_diffuse && !textures.contains(m->tex_diffuse)) - textures.append(m->tex_diffuse); - - if (m->tex_specular && !textures.contains(m->tex_specular)) - textures.append(m->tex_specular); - - if (m->tex_emissive && !textures.contains(m->tex_emissive)) - textures.append(m->tex_emissive); - - if (m->tex_bumpmap && !textures.contains(m->tex_bumpmap)) - textures.append(m->tex_bumpmap); - - if (m->tex_detail && !textures.contains(m->tex_detail)) - textures.append(m->tex_detail); - } -} - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -Model::Model() - : nverts(0), npolys(0), radius(0), luminous(false), dynamic(false) -{ - ZeroMemory(name, sizeof(name)); -} - -Model::Model(const Model& m) - : nverts(0), npolys(0), radius(0), luminous(false), dynamic(false) -{ - operator=(m); -} - -// +--------------------------------------------------------------------+ - -Model::~Model() -{ - surfaces.destroy(); - materials.destroy(); -} - -Model& -Model::operator = (const Model& m) -{ - if (this != &m) { - surfaces.destroy(); - materials.destroy(); - - CopyMemory(name, m.name, Solid::NAMELEN); - - nverts = m.nverts; - npolys = m.npolys; - radius = m.radius; - luminous = m.luminous; - dynamic = m.dynamic; - - Model* pmod = (Model*) &m; - - ListIter m_iter = pmod->materials; - while (++m_iter) { - Material* matl1 = m_iter.value(); - Material* matl2 = new Material; - - CopyMemory(matl2, matl1, sizeof(Material)); - matl2->thumbnail = 0; - - materials.append(matl2); - } - - ListIter s_iter = pmod->surfaces; - while (++s_iter) { - Surface* surf1 = s_iter.value(); - Surface* surf2 = new Surface; - - surf2->Copy(*surf1, this); - surfaces.append(surf2); - } - } - - return *this; -} - -// +--------------------------------------------------------------------+ - -int -Model::NumSegments() const -{ - int nsegments = 0; - - for (int i = 0; i < surfaces.size(); i++) { - const Surface* s = surfaces[i]; - nsegments += s->NumSegments(); - } - - return nsegments; -} - -// +--------------------------------------------------------------------+ - -inline bool Collinear(const double* a, const double* b, const double* c) -{ - Point ab(b[0]-a[0], b[1]-a[1], b[2]-a[2]); - Point ac(c[0]-a[0], c[1]-a[1], c[2]-a[2]); - Point cross = ab.cross(ac); - return (cross.length() == 0); -} - -struct HomogenousPlane -{ - double distance; - double normal_x; - double normal_y; - double normal_z; - double normal_w; -}; - -static void LoadPlane(Plane& p, DataLoader* l, BYTE*& fp) -{ - HomogenousPlane tmp; - l->fread(&tmp, sizeof(HomogenousPlane), 1, fp); -} - -static void LoadFlags(LPDWORD flags, DataLoader* l, BYTE*& fp) -{ - DWORD magic_flags; - l->fread(&magic_flags, sizeof(DWORD), 1, fp); - - /** OLD MAGIC FLAGS -enum { FLAT_SHADED = 1, - LUMINOUS = 2, - TRANSLUCENT = 4, \\ must swap - CHROMAKEY = 8, // these two - FOREGROUND = 16, -- not used - WIREFRAME = 32, -- not used - SPECULAR1 = 64, - SPECULAR2 = 128 }; -***/ - - const DWORD magic_mask = 0x0fc3; - - *flags = magic_flags & magic_mask; -} - -// +--------------------------------------------------------------------+ - -bool -Model::Load(const char* mag_file, double scale) -{ - BYTE* block; - DataLoader* loader = DataLoader::GetLoader(); - bool result = false; - - radius = 0.0f; - extents[0] = 0.0f; - extents[1] = 0.0f; - extents[2] = 0.0f; - extents[3] = 0.0f; - extents[4] = 0.0f; - extents[5] = 0.0f; - - if (!loader) { - Print("MAG Open Failed: no data loader for file '%s'\n", mag_file); - return result; - } - - int size = loader->LoadBuffer(mag_file, block); - BYTE* fp = block; - - // check MAG file: - if (!size) { - Print("MAG Open Failed: could not open file '%s'\n", mag_file); - return result; - } - - strncpy_s(name, mag_file, 31); - name[31] = 0; - - char file_id[5]; - CopyMemory(file_id, block, 4); - file_id[4] = '\0'; - int version = 1; - - if (!strcmp(file_id, "MAG6")) { - version = 6; - } - else if (!strcmp(file_id, "MAG5")) { - version = 5; - } - else if (!strcmp(file_id, "MAG4")) { - version = 4; - } - else { - Print("MAG Open Failed: File '%s' Invalid file type '%s'\n", mag_file, file_id); - loader->ReleaseBuffer(block); - return result; - } - - // get ready to load, delete existing model: - surfaces.destroy(); - materials.destroy(); - nverts = 0; - npolys = 0; - - // now load the model: - switch (version) { - case 4: - case 5: - result = LoadMag5(block, size, scale); - break; - - case 6: - result = LoadMag6(block, size, scale); - break; - - default: - break; - } - - loader->ReleaseBuffer(block); - return result; -} - -// +--------------------------------------------------------------------+ - -bool -Model::Load(ModelFile* mod_file, double scale) -{ - if (mod_file) { - return mod_file->Load(this, scale); - } - - return false; -} - -// +--------------------------------------------------------------------+ - -static int mcomp(const void* a, const void* b) -{ - Poly* pa = (Poly*) a; - Poly* pb = (Poly*) b; - - if (pa->sortval == pb->sortval) - return 0; - - if (pa->sortval < pb->sortval) - return 1; - - return -1; -} - -bool -Model::LoadMag5(BYTE* block, int len, double scale) -{ - bool result = false; - - DataLoader* loader = DataLoader::GetLoader(); - BYTE* fp = block + 4; - int ntex = 0; - int nsurfs = 0; - - loader->fread(&ntex, sizeof(ntex), 1, fp); - loader->fread(&nsurfs, sizeof(nsurfs), 1, fp); - - // create a default gray material: - Material* mtl = new Material; - - if (mtl) { - mtl->Ka = Color::LightGray; - mtl->Kd = Color::LightGray; - mtl->Ks = ColorValue(0.2f,0.2f,0.2f); - mtl->power = 20.0f; - - mtl->ambient_value = 1.0f; - mtl->ambient_color = Color::LightGray; - mtl->diffuse_value = 1.0f; - mtl->diffuse_color = Color::LightGray; - mtl->specular_value = 0.2f; - mtl->specular_color = Color::White; - strcpy_s(mtl->name, "(default)"); - - materials.append(mtl); - } - - // read texture list: - for (int i = 0; i < ntex; i++) { - mtl = new Material; - char tname[32]; - - if (mtl) { - mtl->Ka = ColorValue(0.5f,0.5f,0.5f); - mtl->Kd = ColorValue(1.0f,1.0f,1.0f); - mtl->Ks = ColorValue(0.2f,0.2f,0.2f); - mtl->power = 20.0f; - - mtl->ambient_value = 1.0f; - mtl->ambient_color = Color::Gray; - mtl->diffuse_value = 1.0f; - mtl->diffuse_color = Color::White; - mtl->specular_value = 0.2f; - mtl->specular_color = Color::White; - - loader->fread(tname, 32, 1, fp); - loader->LoadTexture(tname, mtl->tex_diffuse, Bitmap::BMP_SOLID, true); - strcpy_s(mtl->name, tname); - - char* dot = strrchr(mtl->name, '.'); - if (dot) - *dot = 0; - - char* plus = strrchr(mtl->name, '+'); - if (plus) - *plus = 0; - - materials.append(mtl); - } - } - - - loader->fread(&nverts, 4, 1, fp); - loader->fread(&npolys, 4, 1, fp); - - // plan on creating four verts per poly: - int mag_nverts = nverts; - int next_vert = nverts; - - nverts = npolys * 4; - - Surface* s = new Surface; - VertexSet* vset = 0; - - if (s) { - strcpy_s(s->name, "default"); - - s->model = this; - s->vertex_set = new VertexSet(nverts); - s->vloc = new Vec3[nverts]; - - ZeroMemory(s->vertex_set->loc, nverts * sizeof(Vec3)); - ZeroMemory(s->vertex_set->diffuse, nverts * sizeof(DWORD)); - ZeroMemory(s->vertex_set->specular, nverts * sizeof(DWORD)); - ZeroMemory(s->vertex_set->tu, nverts * sizeof(float)); - ZeroMemory(s->vertex_set->tv, nverts * sizeof(float)); - ZeroMemory(s->vertex_set->rw, nverts * sizeof(float)); - ZeroMemory(s->vloc, nverts * sizeof(Vec3)); - - s->npolys = npolys; - s->polys = new Poly[npolys]; - - ZeroMemory(s->polys, sizeof(Poly) * npolys); - surfaces.append(s); - - vset = s->vertex_set; - - int v; - // read vertex set: - for (v = 0; v < mag_nverts; v++) { - Vec3 vert, norm; - DWORD vstate; - - loader->fread(&vert, sizeof(Vec3), 1, fp); - loader->fread(&norm, sizeof(Vec3), 1, fp); - loader->fread(&vstate, sizeof(DWORD), 1, fp); - - vert.SwapYZ(); - vert *= (float) scale; - - vset->loc[v] = vert; - vset->nrm[v] = norm; - - double d = vert.length(); - if (d > radius) - radius = (float) d; - - if (vert.x > extents[0]) extents[0] = vert.x; - if (vert.x < extents[1]) extents[1] = vert.x; - if (vert.y > extents[2]) extents[2] = vert.y; - if (vert.y < extents[3]) extents[3] = vert.y; - if (vert.z > extents[4]) extents[4] = vert.z; - if (vert.z < extents[5]) extents[5] = vert.z; - } - - while (v < nverts) - vset->nrm[v++] = Vec3(1,0,0); - - // read polys: - Vec3 dummy_center; - DWORD dummy_flags; - DWORD dummy_color; - Plane dummy_plane; - int texture_num; - int poly_nverts; - int vert_index_buffer[32]; - float texture_index_buffer[32]; - - for (int n = 0; n < npolys; n++) { - Poly& poly = s->polys[n]; - poly.vertex_set = vset; - - loader->fread(&dummy_flags, sizeof(DWORD), 1, fp); - loader->fread(&dummy_center, sizeof(Vec3), 1, fp); - - LoadPlane(dummy_plane, loader, fp); - - loader->fread(&dummy_color, sizeof(DWORD), 1, fp); - loader->fread(&texture_num, sizeof(int), 1, fp); - - if (texture_num >= 0 && texture_num < ntex) { - int mtl_num = texture_num + 1; - poly.material = materials[mtl_num]; - poly.sortval = texture_num; - - bool flag_translucent = (dummy_flags & 0x04) ? true : false; - bool flag_transparent = (dummy_flags & 0x08) ? true : false; - - // luminous - if (dummy_flags & 2) { - mtl = materials[mtl_num]; - - mtl->Ka = ColorValue(0,0,0,0); - mtl->Kd = ColorValue(0,0,0,0); - mtl->Ks = ColorValue(0,0,0,0); - mtl->Ke = ColorValue(1,1,1,1); - - mtl->tex_emissive = mtl->tex_diffuse; - } - - // glowing (additive) - if (flag_translucent && flag_transparent) - materials[mtl_num]->blend = Material::MTL_ADDITIVE; - - // translucent (alpha) - else if (flag_translucent) - materials[mtl_num]->blend = Material::MTL_TRANSLUCENT; - - // transparent (just use alpha for this) - else if (flag_transparent) - materials[mtl_num]->blend = Material::MTL_TRANSLUCENT; - } - else { - poly.material = materials.first(); - poly.sortval = 1000; - } - - // hack: store flat shaded flag in unused visible byte - poly.visible = (BYTE) (dummy_flags & 1); - - loader->fread(&poly_nverts, sizeof(int), 1, fp); - loader->fread(vert_index_buffer, sizeof(int), poly_nverts, fp); - - if (poly_nverts == 3) - s->nindices += 3; - - else if (poly_nverts == 4) - s->nindices += 6; - - poly.nverts = poly_nverts; - for (int vi = 0; vi < poly_nverts; vi++) { - v = vert_index_buffer[vi]; - - if (vset->rw[v] > 0) { - vset->CopyVertex(next_vert, v); - v = next_vert++; - } - - vset->rw[v] = 1; - poly.verts[vi] = v; - } - - loader->fread(texture_index_buffer, sizeof(float), poly_nverts, fp); // tu's - for (int vi = 0; vi < poly_nverts; vi++) { - v = poly.verts[vi]; - vset->tu[v] = texture_index_buffer[vi]; - } - - loader->fread(texture_index_buffer, sizeof(float), poly_nverts, fp); // tv's - for (int vi = 0; vi < poly_nverts; vi++) { - v = poly.verts[vi]; - vset->tv[v] = texture_index_buffer[vi]; - } - - fp += 16; - } - - // pass 2 (adjust vertex normals for flat polys): - for (int n = 0; n < npolys; n++) { - Poly& poly = s->polys[n]; - poly.plane = Plane(vset->loc[poly.verts[0]], - vset->loc[poly.verts[2]], - vset->loc[poly.verts[1]]); - - // hack: retrieve flat shaded flag from unused visible byte - if (poly.visible) { - poly_nverts = poly.nverts; - - for (int vi = 0; vi < poly_nverts; vi++) { - v = poly.verts[vi]; - vset->nrm[v] = poly.plane.normal; - } - } - } - - // sort the polys by material index: - qsort((void*) s->polys, s->npolys, sizeof(Poly), mcomp); - - // then assign them to cohesive segments: - Segment* segment = 0; - - for (int n = 0; n < npolys; n++) { - if (segment && segment->material == s->polys[n].material) { - segment->npolys++; - } - else { - segment = 0; - } - - if (!segment) { - segment = new Segment; - - segment->npolys = 1; - segment->polys = &s->polys[n]; - segment->material = segment->polys->material; - segment->model = this; - - s->segments.append(segment); - } - } - - s->BuildHull(); - - result = nverts && npolys; - } - - return result; -} - -// +--------------------------------------------------------------------+ - -struct MaterialMag6 { - char name[Material::NAMELEN]; - char shader[Material::NAMELEN]; - float power; // highlight sharpness (big=shiny) - float brilliance; // diffuse power function - float bump; // bump level (0=none) - DWORD blend; // alpha blend type - bool shadow; // material casts shadow - bool luminous; // verts have their own lighting - - Color ambient_color; - Color diffuse_color; - Color specular_color; - Color emissive_color; - - float ambient_value; - float diffuse_value; - float specular_value; - float emissive_value; - - BYTE tex_diffuse; - BYTE tex_specular; - BYTE tex_bumpmap; - BYTE tex_emissive; -}; - -// +--------------------------------------------------------------------+ - -bool -Model::LoadMag6(BYTE* block, int len, double scale) -{ - bool result = false; - - DataLoader* loader = DataLoader::GetLoader(); - BYTE* fp = block + 4; - int ntex = 0; - int nmtls = 0; - int nsurfs = 0; - List textures; - - loader->fread(&ntex, sizeof(ntex), 1, fp); // size of texture block - loader->fread(&nmtls, sizeof(nmtls), 1, fp); // number of materials - loader->fread(&nsurfs, sizeof(nsurfs), 1, fp); // number of surfaces - - // read texture list: - if (ntex) { - char* buffer = new char[ntex]; - char* p = buffer; - Bitmap* bmp = 0; - - loader->fread(buffer, ntex, 1, fp); - - while (p < buffer + ntex) { - loader->LoadTexture(p, bmp, Bitmap::BMP_SOLID, true); - textures.append(bmp); - - p += strlen(p) + 1; - } - - delete [] buffer; - } - - for (int i = 0; i < nmtls; i++) { - MaterialMag6 m6; - Material* mtl = new Material; - - loader->fread(&m6, sizeof(m6), 1, fp); - - if (mtl) { - CopyMemory(mtl->name, m6.name, Material::NAMELEN); - CopyMemory(mtl->shader, m6.shader, Material::NAMELEN); - - mtl->ambient_value = m6.ambient_value; - mtl->ambient_color = m6.ambient_color; - mtl->diffuse_value = m6.diffuse_value; - mtl->diffuse_color = m6.diffuse_color; - mtl->specular_value = m6.specular_value; - mtl->specular_color = m6.specular_color; - mtl->emissive_value = m6.emissive_value; - mtl->emissive_color = m6.emissive_color; - - mtl->Ka = ColorValue(mtl->ambient_color) * mtl->ambient_value; - mtl->Kd = ColorValue(mtl->diffuse_color) * mtl->diffuse_value; - mtl->Ks = ColorValue(mtl->specular_color) * mtl->specular_value; - mtl->Ke = ColorValue(mtl->emissive_color) * mtl->emissive_value; - - mtl->power = m6.power; - mtl->brilliance = m6.brilliance; - mtl->bump = m6.bump; - mtl->blend = m6.blend; - mtl->shadow = m6.shadow; - mtl->luminous = m6.luminous; - - if (m6.tex_diffuse && m6.tex_diffuse <= textures.size()) - mtl->tex_diffuse = textures[m6.tex_diffuse - 1]; - - if (m6.tex_specular && m6.tex_specular <= textures.size()) - mtl->tex_specular = textures[m6.tex_specular - 1]; - - if (m6.tex_emissive && m6.tex_emissive <= textures.size()) - mtl->tex_emissive = textures[m6.tex_emissive - 1]; - - if (m6.tex_bumpmap && m6.tex_bumpmap <= textures.size()) - mtl->tex_bumpmap = textures[m6.tex_bumpmap - 1]; - - materials.append(mtl); - } - } - - for (int i = 0; i < nsurfs; i++) { - int nverts = 0; - int npolys = 0; - BYTE namelen = 0; - char name[128]; - - loader->fread(&nverts, 4, 1, fp); - loader->fread(&npolys, 4, 1, fp); - loader->fread(&namelen, 1, 1, fp); - loader->fread(name, 1, namelen, fp); - - Surface* surface = new Surface; - surface->model = this; - surface->SetName(name); - surface->CreateVerts(nverts); - surface->CreatePolys(npolys); - - VertexSet* vset = surface->GetVertexSet(); - Poly* polys = surface->GetPolys(); - - ZeroMemory(polys, sizeof(Poly) * npolys); - - // read vertex set: - for (int v = 0; v < nverts; v++) { - loader->fread(&vset->loc[v], sizeof(float), 3, fp); - loader->fread(&vset->nrm[v], sizeof(float), 3, fp); - loader->fread(&vset->tu[v], sizeof(float), 1, fp); - loader->fread(&vset->tv[v], sizeof(float), 1, fp); - - vset->loc[v] *= (float) scale; - - Vec3 vert = vset->loc[v]; - - double d = vert.length(); - if (d > radius) - radius = (float) d; - - if (vert.x > extents[0]) extents[0] = vert.x; - if (vert.x < extents[1]) extents[1] = vert.x; - if (vert.y > extents[2]) extents[2] = vert.y; - if (vert.y < extents[3]) extents[3] = vert.y; - if (vert.z > extents[4]) extents[4] = vert.z; - if (vert.z < extents[5]) extents[5] = vert.z; - } - - // read polys: - for (int n = 0; n < npolys; n++) { - Poly& poly = polys[n]; - BYTE poly_nverts = 0; - BYTE material_index = 0; - WORD poly_verts[8]; - - loader->fread(&poly_nverts, sizeof(BYTE), 1, fp); - loader->fread(&material_index, sizeof(BYTE), 1, fp); - loader->fread(&poly_verts[0], sizeof(WORD), poly_nverts, fp); - - if (poly_nverts >= 3) { - poly.nverts = poly_nverts; - - for (int i = 0; i < poly_nverts; i++) { - poly.verts[i] = poly_verts[i]; - } - } - else { - poly.sortval = 666; - } - - if (material_index > 0) { - poly.material = materials[material_index-1]; - poly.sortval = material_index; - } - else if (materials.size()) { - poly.material = materials.first(); - poly.sortval = 1; - } - else { - poly.sortval = 1000; - } - - if (poly.nverts == 3) - surface->AddIndices(3); - - else if (poly.nverts == 4) - surface->AddIndices(6); - - poly.vertex_set = vset; - poly.plane = Plane(vset->loc[poly.verts[0]], - vset->loc[poly.verts[2]], - vset->loc[poly.verts[1]]); - } - - // sort the polys by material index: - qsort((void*) polys, npolys, sizeof(Poly), mcomp); - - // then assign them to cohesive segments: - Segment* segment = 0; - - for (int n = 0; n < npolys; n++) { - if (segment && segment->material == polys[n].material) { - segment->npolys++; - } - else { - segment = 0; - } - - if (!segment) { - segment = new Segment; - - segment->npolys = 1; - segment->polys = &polys[n]; - segment->material = segment->polys->material; - segment->model = this; - - surface->GetSegments().append(segment); - } - } - - surface->BuildHull(); - surfaces.append(surface); - - this->nverts += nverts; - this->npolys += npolys; - } - - - result = nverts && npolys; - return result; -} - -void -Model::AddSurface(Surface* surface) -{ - if (surface) { - surface->model = this; - - ListIter iter = surface->segments; - while (++iter) { - Segment* segment = iter.value(); - segment->model = this; - } - - surface->BuildHull(); - surfaces.append(surface); - - nverts += surface->NumVerts(); - npolys += surface->NumPolys(); - } -} - - -// +--------------------------------------------------------------------+ - -const Material* -Model::FindMaterial(const char* mtl_name) const -{ - if (mtl_name && *mtl_name) { - Model* pThis = (Model*) this; - - ListIter iter = pThis->materials; - while (++iter) { - Material* mtl = iter.value(); - - if (!strcmp(mtl->name, mtl_name)) - return mtl; - } - } - - return 0; -} - -const Material* -Model::ReplaceMaterial(const Material* mtl) -{ - const Material* mtl_orig = 0; - - if (mtl) { - mtl_orig = FindMaterial(mtl->name); - - if (mtl_orig) { - int n = materials.index(mtl_orig); - materials[n] = (Material*) mtl; - - ListIter surf_iter = surfaces; - while (++surf_iter) { - Surface* surf = surf_iter.value(); - - ListIter seg_iter = surf->GetSegments(); - while (++seg_iter) { - Segment* segment = seg_iter.value(); - - if (segment->material == mtl_orig) - segment->material = (Material*) mtl; - } - } - } - } - - return mtl_orig; -} - -// +--------------------------------------------------------------------+ - -Poly* -Model::AddPolys(int nsurf, int np, int nv) -{ - if (nsurf >= 0 && nsurf < surfaces.size()) - return surfaces[nsurf]->AddPolys(np, nv); - - ::Print("WARNING: AddPolys(%d,%d,%d) invalid surface\n", nsurf, np, nv); - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Model::ExplodeMesh() -{ - ListIter iter = surfaces; - - int nv = 0; - int np = 0; - - while (++iter) { - Surface* s = iter.value(); - s->ExplodeMesh(); - - nv += s->NumVerts(); - np += s->NumPolys(); - } - - nverts = nv; - npolys = np; -} - -// +--------------------------------------------------------------------+ - -void -Model::OptimizeMesh() -{ - ListIter iter = surfaces; - - int nv = 0; - int np = 0; - - while (++iter) { - Surface* s = iter.value(); - s->OptimizeMesh(); - - nv += s->NumVerts(); - np += s->NumPolys(); - } - - nverts = nv; - npolys = np; -} - -// +--------------------------------------------------------------------+ - -void -Model::OptimizeMaterials() -{ - for (int i = 0; i < materials.size(); i++) { - Material* m1 = materials[i]; - - for (int n = i; n < materials.size(); n++) { - Material* m2 = materials[n]; - - // if they match, merge them: - if (*m1 == *m2) { - List polys; - SelectPolys(polys, m2); - - ListIter iter = polys; - while (++iter) { - Poly* p = iter.value(); - p->material = m1; - } - - // and discard the duplicate: - materials.remove(m2); - delete m2; - } - } - } -} - -void -Model::ScaleBy(double factor) -{ - ListIter iter = surfaces; - - while (++iter) { - Surface* s = iter.value(); - s->ScaleBy(factor); - } -} - -// +--------------------------------------------------------------------+ - -void -Model::Normalize() -{ - ListIter iter = surfaces; - - while (++iter) { - Surface* s = iter.value(); - s->Normalize(); - } -} - -void -Model::SelectPolys(List& polys, Vec3 loc) -{ - ListIter iter = surfaces; - - while (++iter) { - Surface* s = iter.value(); - s->SelectPolys(polys, loc); - } -} - -void -Model::SelectPolys(List& polys, Material* m) -{ - ListIter iter = surfaces; - - while (++iter) { - Surface* s = iter.value(); - s->SelectPolys(polys, m); - } -} - -void -Model::ComputeTangents() -{ - ListIter iter = surfaces; - - while (++iter) { - Surface* s = iter.value(); - s->ComputeTangents(); - } -} - -// +--------------------------------------------------------------------+ - -void -Model::DeletePrivateData() -{ - ListIter iter = surfaces; - while (++iter) { - Surface* s = iter.value(); - VideoPrivateData* vpd = s->GetVideoPrivateData(); - - if (vpd) { - delete vpd; - s->SetVideoPrivateData(0); - } - - ListIter seg_iter = s->GetSegments(); - while (++seg_iter) { - Segment* segment = seg_iter.value(); - VideoPrivateData* vpdp = segment->video_data; - - if (vpdp) { - delete vpdp; - segment->video_data = 0; - } - } - } -} - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -Surface::Surface() - : model(0), vertex_set(0), vloc(0), nhull(0), npolys(0), nindices(0), - polys(0), state(0), video_data(0), opcode(0) -{ - ZeroMemory(name, sizeof(name)); -} - -Surface::~Surface() -{ - segments.destroy(); - - delete opcode; - delete vertex_set; - delete [] vloc; - delete [] polys; - delete video_data; - - model = 0; -} - -// +--------------------------------------------------------------------+ - -void -Surface::Copy(Surface& s, Model* m) -{ - segments.destroy(); - - delete opcode; - delete vertex_set; - delete [] vloc; - delete [] polys; - delete video_data; - - CopyMemory(name, s.name, Solid::NAMELEN); - - model = m; - radius = s.radius; - nhull = s.nhull; - npolys = s.npolys; - nindices = s.nindices; - state = s.state; - offset = s.offset; - orientation = s.orientation; - opcode = 0; - video_data = 0; - - vertex_set = s.vertex_set->Clone(); - - if (nhull > 0) { - vloc = new Vec3[nhull]; - CopyMemory(vloc, s.vloc, nhull * sizeof(Vec3)); - } - else { - vloc = 0; - } - - polys = new Poly[npolys]; - CopyMemory(polys, s.polys, npolys * sizeof(Poly)); - - for (int i = 0; i < npolys; i++) { - polys[i].vertex_set = vertex_set; - - if (s.polys[i].material) - polys[i].material = (Material*) model->FindMaterial(s.polys[i].material->name); - } - - ListIter iter = s.segments; - while (++iter) { - Segment* seg1 = iter.value(); - Segment* seg2 = new Segment; - - seg2->npolys = seg1->npolys; - seg2->polys = polys + (seg1->polys - s.polys); - - if (seg2->polys[0].material) - seg2->material = seg2->polys[0].material; - - seg2->model = model; - seg2->video_data = 0; - - segments.append(seg2); - } -} - -// +--------------------------------------------------------------------+ - -void -Surface::SetName(const char* n) -{ - int len = sizeof(name); - - ZeroMemory(name, len); - strncpy_s(name, n, len-1); -} - -void -Surface::SetHidden(bool b) -{ - if (b) - state = state | HIDDEN; - - else - state = state & ~HIDDEN; -} - -void -Surface::SetLocked(bool b) -{ - if (b) - state = state | LOCKED; - - else - state = state & ~LOCKED; -} - -void -Surface::SetSimplified(bool b) -{ - if (b) - state = state | SIMPLE; - - else - state = state & ~SIMPLE; -} - -void -Surface::CreateVerts(int nverts) -{ - if (!vertex_set && !vloc) { - vertex_set = new VertexSet(nverts); - vloc = new Vec3[nverts]; - } -} - -void -Surface::CreatePolys(int np) -{ - if (!polys && !npolys) { - npolys = np; - polys = new Poly[npolys]; - - ZeroMemory(polys, npolys * sizeof(Poly)); - } -} - -// +--------------------------------------------------------------------+ - -Poly* -Surface::AddPolys(int np, int nv) -{ - if ( polys && vertex_set && - np > 0 && np + npolys < MAX_POLYS && - nv > 0 && nv + vertex_set->nverts < MAX_VERTS) - { - int newverts = nv + vertex_set->nverts; - int newpolys = np + npolys; - - vertex_set->Resize(newverts, true); - - Poly* pset = new Poly[newpolys]; - Poly* pnew = pset + npolys; - - CopyMemory(pset, polys, npolys * sizeof(Poly)); - ZeroMemory(pnew, np * sizeof(Poly)); - - if (segments.size() > 0) { - Segment* seg = segments.last(); - Material* mtl = seg->material; - - for (int i = 0; i < np; i++) { - Poly* p = pnew + i; - p->material = mtl; - } - - seg->npolys += np; - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Surface::ExplodeMesh() -{ - if (!vertex_set || vertex_set->nverts < 3) - return; - - int i, j, v; - int nverts = 0; - - // count max verts: - for (i = 0; i < npolys; i++) { - Poly* p = polys + i; - nverts += p->nverts; - } - - // create target vertex set: - VertexSet* vset = new VertexSet(nverts); - v = 0; - - // explode verts: - for (i = 0; i < npolys; i++) { - Poly* p = polys + i; - p->vertex_set = vset; - - for (j = 0; j < p->nverts; j++) { - int vsrc = p->verts[j]; - - vset->loc[v] = vertex_set->loc[vsrc]; - vset->nrm[v] = vertex_set->nrm[vsrc]; - vset->tu[v] = vertex_set->tu[vsrc]; - vset->tv[v] = vertex_set->tv[vsrc]; - vset->rw[v] = vertex_set->rw[vsrc]; - vset->diffuse[v] = vertex_set->diffuse[vsrc]; - vset->specular[v] = vertex_set->specular[vsrc]; - - p->verts[j] = v++; - } - } - - // finalize: - if (vset) { - delete vertex_set; - vertex_set = vset; - } - - if (vloc) - delete [] vloc; - - vloc = new Vec3[nverts]; - - ComputeTangents(); - BuildHull(); -} - -// +--------------------------------------------------------------------+ - -const double SELECT_EPSILON = 0.05; -const double SELECT_TEXTURE = 0.0001; - -static bool MatchVerts(VertexSet* vset, int i, int j) -{ - double d = 0; - const Vec3& vl1 = vset->loc[i]; - const Vec3& vn1 = vset->nrm[i]; - float tu1 = vset->tu[i]; - float tv1 = vset->tv[i]; - const Vec3& vl2 = vset->loc[j]; - const Vec3& vn2 = vset->nrm[j]; - float tu2 = vset->tu[j]; - float tv2 = vset->tv[j]; - - d = fabs(vl1.x - vl2.x); - if (d > SELECT_EPSILON) - return false; - - d = fabs(vl1.y - vl2.y); - if (d > SELECT_EPSILON) - return false; - - d = fabs(vl1.z - vl2.z); - if (d > SELECT_EPSILON) - return false; - - d = fabs(vn1.x - vn2.x); - if (d > SELECT_EPSILON) - return false; - - d = fabs(vn1.y - vn2.y); - if (d > SELECT_EPSILON) - return false; - - d = fabs(vn1.z - vn2.z); - if (d > SELECT_EPSILON) - return false; - - d = fabs(tu1 - tu2); - if (d > SELECT_TEXTURE) - return false; - - d = fabs(tv1 - tv2); - if (d > SELECT_TEXTURE) - return false; - - return true; -} - -void -Surface::OptimizeMesh() -{ - if (!vertex_set || vertex_set->nverts < 3) - return; - - int nverts = vertex_set->nverts; - int used = 0; - int final = 0; - int nmatch = 0; - - // create vertex maps: - BYTE* vert_map = new BYTE[nverts]; - WORD* vert_dst = new WORD[nverts]; - ZeroMemory(vert_map, nverts * sizeof(BYTE)); - ZeroMemory(vert_dst, nverts * sizeof(WORD)); - - // count used verts: - for (int i = 0; i < npolys; i++) { - Poly* p = polys + i; - - for (int j = 0; j < p->nverts; j++) { - WORD vert = p->verts[j]; - - if (vert < nverts) { - vert_map[vert]++; - used++; - } - } - } - - // create target vertex set: - VertexSet* vset = new VertexSet(used); - int v = 0; - - // compress verts: - for (int i = 0; i < nverts; i++) { - if (vert_map[i] == 0) continue; - - vert_dst[i] = v; - vset->loc[v] = vertex_set->loc[i]; - vset->nrm[v] = vertex_set->nrm[i]; - vset->tu[v] = vertex_set->tu[i]; - vset->tv[v] = vertex_set->tv[i]; - vset->rw[v] = vertex_set->rw[i]; - vset->diffuse[v] = vertex_set->diffuse[i]; - vset->specular[v] = vertex_set->specular[i]; - - for (int j = i+1; j < nverts; j++) { - if (vert_map[j] == 0) continue; - - if (MatchVerts(vertex_set, i, j)) { - vert_map[j] = 0; - vert_dst[j] = v; - nmatch++; - } - } - - v++; - } - - final = v; - - // remap polys: - for (int n = 0; n < npolys; n++) { - Poly* p = polys + n; - p->vertex_set = vset; - for (int v = 0; v < p->nverts; v++) { - p->verts[v] = vert_dst[ p->verts[v] ]; - } - } - - // finalize: - if (vset && final < nverts) { - delete vertex_set; - vertex_set = vset; - vset->Resize(final, true); - nverts = final; - } - - // clean up and rebuild hull: - delete [] vert_map; - - if (vloc) - delete [] vloc; - - vloc = new Vec3[nverts]; - - ComputeTangents(); - BuildHull(); -} - -// +--------------------------------------------------------------------+ - -void -Surface::ScaleBy(double factor) -{ - offset *= factor; - - if (vertex_set && vertex_set->nverts) { - for (int i = 0; i < vertex_set->nverts; i++) { - vertex_set->loc[i] *= (float) factor; - } - } -} - -// +--------------------------------------------------------------------+ - -void -Surface::BuildHull() -{ - if (npolys < 1 || !vertex_set || vertex_set->nverts < 1) - return; - - nhull = 0; - - for (int i = 0; i < npolys; i++) { - Poly* p = polys + i; - - for (int n = 0; n < p->nverts; n++) { - WORD v = p->verts[n]; - WORD h; - - for (h = 0; h < nhull; h++) { - Vec3& vl = vertex_set->loc[v]; - Vec3& loc = vloc[h]; - - double d = vl.x - loc.x; - - if (d < -SELECT_EPSILON || d > SELECT_EPSILON) - continue; - - d = vl.y - loc.y; - - if (d < -SELECT_EPSILON || d > SELECT_EPSILON) - continue; - - d = vl.z - loc.z; - - if (d < -SELECT_EPSILON || d > SELECT_EPSILON) - continue; - - // found a match: - break; - } - - // didn't find a match: - if (h >= nhull) { - vloc[h] = vertex_set->loc[v]; - nhull = h+1; - } - - p->vlocs[n] = h; - } - } - - if (use_collision_detection) - InitializeCollisionHull(); -} - -// +--------------------------------------------------------------------+ - -void -Surface::Normalize() -{ - if (npolys < 1 || !vertex_set || vertex_set->nverts < 1) - return; - - // STEP ONE: initialize poly planes - - for (int i = 0; i < npolys; i++) { - Poly* p = polys + i; - - p->plane = Plane( vertex_set->loc[ p->verts[0] ], - vertex_set->loc[ p->verts[2] ], - vertex_set->loc[ p->verts[1] ] ); - } - - // STEP TWO: compute vertex normals by averaging adjecent poly planes - - List faces; - for (int v = 0; v < vertex_set->nverts; v++) { - faces.clear(); - SelectPolys(faces, vertex_set->loc[v]); - - if (faces.size()) { - vertex_set->nrm[v] = Vec3(0.0f, 0.0f, 0.0f); - - for (int i = 0; i < faces.size(); i++) { - vertex_set->nrm[v] += faces[i]->plane.normal; - } - - vertex_set->nrm[v].Normalize(); - } - - else if (vertex_set->loc[v].length() > 0) { - vertex_set->nrm[v] = vertex_set->loc[v]; - vertex_set->nrm[v].Normalize(); - } - - else { - vertex_set->nrm[v] = Vec3(0.0f, 1.0f, 0.0f); - } - } - - // STEP THREE: adjust vertex normals for poly flatness - - for (int i = 0; i < npolys; i++) { - Poly* p = polys + i; - - for (int n = 0; n < p->nverts; n++) { - int v = p->verts[n]; - - vertex_set->nrm[v] = vertex_set->nrm[v] * (1.0f - p->flatness) + - p->plane.normal * ( p->flatness); - } - } -} - -void -Surface::SelectPolys(List& selection, Vec3 loc) -{ - const double SELECT_EPSILON = 0.05; - - for (int i = 0; i < npolys; i++) { - Poly* p = polys + i; - - for (int n = 0; n < p->nverts; n++) { - int v = p->verts[n]; - Vec3& vl = vertex_set->loc[v]; - double d = vl.x - loc.x; - - if (d < -SELECT_EPSILON || d > SELECT_EPSILON) - continue; - - d = vl.y - loc.y; - - if (d < -SELECT_EPSILON || d > SELECT_EPSILON) - continue; - - d = vl.z - loc.z; - - if (d < -SELECT_EPSILON || d > SELECT_EPSILON) - continue; - - selection.append(p); - break; - } - } -} - -void -Surface::SelectPolys(List& selection, Material* m) -{ - for (int i = 0; i < npolys; i++) { - Poly* p = polys + i; - - if (p->material == m) - selection.append(p); - } -} - -// +--------------------------------------------------------------------+ - -void -Surface::ComputeTangents() -{ - Vec3 tangent; - Vec3 binormal; - - if (!vertex_set || !vertex_set->nverts) - return; - - if (vertex_set->tangent) - return; - - vertex_set->CreateTangents(); - - for (int i = 0; i < npolys; i++) { - Poly* p = polys + i; - - CalcGradients(*p, tangent, binormal); - - for (int n = 0; n < p->nverts; n++) { - vertex_set->tangent[p->verts[n]] = tangent; - vertex_set->binormal[p->verts[n]] = binormal; - } - } -} - -void -Surface::CalcGradients(Poly& p, Vec3& tangent, Vec3& binormal) -{ - // using Eric Lengyel's approach with a few modifications - // from Mathematics for 3D Game Programmming and Computer Graphics - // want to be able to trasform a vector in Object Space to Tangent Space - // such that the x-axis cooresponds to the 's' direction and the - // y-axis corresponds to the 't' direction, and the z-axis corresponds - // to <0,0,1>, straight up out of the texture map - - VertexSet* vset = p.vertex_set; - - Vec3 P = vset->loc[p.verts[1]] - vset->loc[p.verts[0]]; - Vec3 Q = vset->loc[p.verts[2]] - vset->loc[p.verts[0]]; - - float s1 = vset->tu[p.verts[1]] - vset->tu[p.verts[0]]; - float t1 = vset->tv[p.verts[1]] - vset->tv[p.verts[0]]; - float s2 = vset->tu[p.verts[2]] - vset->tu[p.verts[0]]; - float t2 = vset->tv[p.verts[2]] - vset->tv[p.verts[0]]; - - float tmp = 1.0f; - float denom = s1*t2 - s2*t1; - - if (fabsf(denom) > 0.0001f) - tmp = 1.0f/(denom); - - tangent.x = (t2*P.x - t1*Q.x) * tmp; - tangent.y = (t2*P.y - t1*Q.y) * tmp; - tangent.z = (t2*P.z - t1*Q.z) * tmp; - - tangent.Normalize(); - - binormal.x = (s1*Q.x - s2*P.x) * tmp; - binormal.y = (s1*Q.y - s2*P.y) * tmp; - binormal.z = (s1*Q.z - s2*P.z) * tmp; - - binormal.Normalize(); -} - -void -Surface::InitializeCollisionHull() -{ - opcode = new OPCODE_data(this); -} - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -Segment::Segment() -{ - ZeroMemory(this, sizeof(Segment)); -} - -Segment::Segment(int n, Poly* p, Material* mtl, Model* mod) - : npolys(n), polys(p), material(mtl), model(mod), video_data(0) -{ -} - -Segment::~Segment() -{ - delete video_data; - - ZeroMemory(this, sizeof(Segment)); -} - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -ModelFile::ModelFile(const char* fname) - : model(0), pname(0), pnverts(0), pnpolys(0), pradius(0) -{ - int len = sizeof(filename); - ZeroMemory(filename, len); - strncpy_s(filename, fname, len); - filename[len-1] = 0; -} - -ModelFile::~ModelFile() -{ -} - -bool -ModelFile::Load(Model* m, double scale) -{ - model = m; - - // expose model innards for child classes: - - if (model) { - pname = model->name; - pnverts = &model->nverts; - pnpolys = &model->npolys; - pradius = &model->radius; - } - - return false; -} - -bool -ModelFile::Save(Model* m) -{ - model = m; - - // expose model innards for child classes: - - if (model) { - pname = model->name; - pnverts = &model->nverts; - pnpolys = &model->npolys; - pradius = &model->radius; - } - - return false; -} - diff --git a/Stars45/Solid.h b/Stars45/Solid.h deleted file mode 100644 index 5cb4464..0000000 --- a/Stars45/Solid.h +++ /dev/null @@ -1,312 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Classes for rendering solid meshes of polygons -*/ - -#ifndef Solid_h -#define Solid_h - -#include "Polygon.h" -#include "Graphic.h" -#include "Video.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Solid; -class Model; -class ModelFile; -class Surface; -class Segment; -class Shadow; -class Light; - -class OPCODE_data; // for collision detection - -// +--------------------------------------------------------------------+ - -class Solid : public Graphic -{ -public: - static const char* TYPENAME() { return "Solid"; } - - enum { NAMELEN = 64 }; - - static bool IsCollisionEnabled(); - static void EnableCollision(bool enable); - - Solid(); - virtual ~Solid(); - - // operations - virtual void Render(Video* video, DWORD flags); - virtual void SelectDetail(Projector* p); - virtual void ProjectScreenRect(Projector* p); - virtual void Update(); - - // accessors / mutators - Model* GetModel() const { return model; } - void GetAllTextures(List& textures); - - virtual bool IsDynamic() const; - virtual void SetDynamic(bool d); - virtual void SetLuminous(bool l); - virtual void SetOrientation(const Matrix& o); - virtual void SetOrientation(const Solid& match); - const Matrix& Orientation() const { return orientation; } - float Roll() const { return roll; } - float Pitch() const { return pitch; } - float Yaw() const { return yaw; } - virtual bool IsSolid() const { return true; } - - // stencil shadows - virtual void CreateShadows(int nlights=1); - virtual void UpdateShadows(List& lights); - List& GetShadows() { return shadows; } - - bool Load(const char* mag_file, double scale=1.0); - bool Load(ModelFile* loader, double scale=1.0); - void UseModel(Model* model); - void ClearModel(); - bool Rescale(double scale); - - // collision detection - virtual int CollidesWith(Graphic& o); - virtual int CheckRayIntersection(Point pt, Point vpn, double len, Point& ipt, - bool treat_translucent_polys_as_solid=true); - virtual Poly* GetIntersectionPoly() const { return intersection_poly; } - - // buffer management - virtual void DeletePrivateData(); - virtual void InvalidateSurfaceData(); - virtual void InvalidateSegmentData(); - -protected: - Model* model; - bool own_model; - - float roll, pitch, yaw; - Matrix orientation; - Poly* intersection_poly; - - List shadows; -}; - -// +--------------------------------------------------------------------+ - -class Model -{ - friend class Solid; - friend class ModelFile; - -public: - static const char* TYPENAME() { return "Model"; } - - enum { MAX_VERTS = 64000, MAX_POLYS = 16000 }; - - Model(); - Model(const Model& m); - ~Model(); - - Model& operator = (const Model& m); - int operator == (const Model& that) const { return this == &that; } - - bool Load(const char* mag_file, double scale=1.0); - bool Load(ModelFile* loader, double scale=1.0); - - const char* Name() const { return name; } - int NumVerts() const { return nverts; } - int NumSurfaces() const { return surfaces.size(); } - int NumMaterials() const { return materials.size(); } - int NumPolys() const { return npolys; } - int NumSegments() const; - double Radius() const { return radius; } - bool IsDynamic() const { return dynamic; } - void SetDynamic(bool d) { dynamic = d; } - bool IsLuminous() const { return luminous; } - void SetLuminous(bool l) { luminous = l; } - - List& GetSurfaces() { return surfaces; } - List& GetMaterials() { return materials; } - const Material* FindMaterial(const char* mtl_name) const; - const Material* ReplaceMaterial(const Material* mtl); - void GetAllTextures(List& textures); - - Poly* AddPolys(int nsurf, int npolys, int nverts); - void ExplodeMesh(); - void OptimizeMesh(); - void OptimizeMaterials(); - void ScaleBy(double factor); - - void Normalize(); - void SelectPolys(List&, Material* mtl); - void SelectPolys(List&, Vec3 loc); - - void AddSurface(Surface* s); - void ComputeTangents(); - - // buffer management - void DeletePrivateData(); - -private: - bool LoadMag5(BYTE* block, int len, double scale); - bool LoadMag6(BYTE* block, int len, double scale); - - char name[Solid::NAMELEN]; - List surfaces; - List materials; - int nverts; - int npolys; - float radius; - float extents[6]; - bool luminous; - bool dynamic; -}; - -// +--------------------------------------------------------------------+ - -class Surface -{ - friend class Solid; - friend class Model; - -public: - static const char* TYPENAME() { return "Surface"; } - - enum { HIDDEN=1, LOCKED=2, SIMPLE=4, MAX_VERTS=64000, MAX_POLYS=16000 }; - - Surface(); - ~Surface(); - - int operator == (const Surface& s) const { return this == &s; } - - const char* Name() const { return name; } - int NumVerts() const { return vertex_set ? vertex_set->nverts : 0; } - int NumSegments() const { return segments.size(); } - int NumPolys() const { return npolys; } - int NumIndices() const { return nindices; } - bool IsHidden() const { return state & HIDDEN ? true : false; } - bool IsLocked() const { return state & LOCKED ? true : false; } - bool IsSimplified() const { return state & SIMPLE ? true : false; } - - Model* GetModel() const { return model; } - List& GetSegments() { return segments; } - const Point& GetOffset() const { return offset; } - const Matrix& GetOrientation() const { return orientation; } - double Radius() const { return radius; } - VertexSet* GetVertexSet() const { return vertex_set; } - Vec3* GetVLoc() const { return vloc; } - Poly* GetPolys() const { return polys; } - - void SetName(const char* n); - void SetHidden(bool b); - void SetLocked(bool b); - void SetSimplified(bool b); - - void CreateVerts(int nverts); - void CreatePolys(int npolys); - void AddIndices(int n) { nindices += n; } - Poly* AddPolys(int npolys, int nverts); - - VideoPrivateData* GetVideoPrivateData() const { return video_data; } - void SetVideoPrivateData(VideoPrivateData* vpd) - { video_data = vpd; } - - void ScaleBy(double factor); - - void BuildHull(); - void Normalize(); - void SelectPolys(List&, Material* mtl); - void SelectPolys(List&, Vec3 loc); - - void InitializeCollisionHull(); - void ComputeTangents(); - void CalcGradients(Poly& p, Vec3& tangent, Vec3& binormal); - - void Copy(Surface& s, Model* m); - void OptimizeMesh(); - void ExplodeMesh(); - -private: - char name[Solid::NAMELEN]; - Model* model; - VertexSet* vertex_set; // for rendering - Vec3* vloc; // for shadow hull - float radius; - int nhull; - int npolys; - int nindices; - int state; - Poly* polys; - List segments; - - Point offset; - Matrix orientation; - -public: - OPCODE_data* opcode; - -private: - VideoPrivateData* video_data; -}; - -// +--------------------------------------------------------------------+ - -class Segment -{ -public: - static const char* TYPENAME() { return "Segment"; } - - Segment(); - Segment(int n, Poly* p, Material* mtl, Model* mod=0); - ~Segment(); - - bool IsSolid() const { return material ? material->IsSolid() : true; } - bool IsTranslucent() const { return material ? material->IsTranslucent(): false; } - bool IsGlowing() const { return material ? material->IsGlowing() : false; } - - VideoPrivateData* GetVideoPrivateData() const { return video_data; } - void SetVideoPrivateData(VideoPrivateData* vpd) - { video_data = vpd; } - - int npolys; - Poly* polys; - Material* material; - Model* model; - VideoPrivateData* video_data; -}; - -// +--------------------------------------------------------------------+ - -class ModelFile -{ -public: - ModelFile(const char* fname); - virtual ~ModelFile(); - - virtual bool Load(Model* m, double scale=1.0); - virtual bool Save(Model* m); - -protected: - char filename[256]; - Model* model; - - // internal accessors: - char* pname; - int* pnverts; - int* pnpolys; - float* pradius; -}; - -// +--------------------------------------------------------------------+ - -#endif // Solid_h - diff --git a/Stars45/Sound.cpp b/Stars45/Sound.cpp deleted file mode 100644 index 01537e9..0000000 --- a/Stars45/Sound.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract sound class -*/ - -#include "Sound.h" -#include "SoundCard.h" -#include "Wave.h" - -#include "vorbis/codec.h" -#include "vorbis/vorbisfile.h" - -// +--------------------------------------------------------------------+ - -SoundCard* Sound::creator = 0; - -Sound* -Sound::CreateStream(const char* filename) -{ - Sound* sound = 0; - - if (!filename || !filename[0] || !creator) - return sound; - - int namelen = strlen(filename); - - if (namelen < 5) - return sound; - - if ((filename[namelen-3] == 'o' || filename[namelen-3] == 'O') && - (filename[namelen-2] == 'g' || filename[namelen-2] == 'G') && - (filename[namelen-1] == 'g' || filename[namelen-1] == 'G')) { - - return CreateOggStream(filename); - } - - WAVE_HEADER head; - WAVE_FMT fmt; - WAVE_FACT fact; - WAVE_DATA data; - WAVEFORMATEX wfex; - - ZeroMemory(&head, sizeof(head)); - ZeroMemory(&fmt, sizeof(fmt)); - ZeroMemory(&fact, sizeof(fact)); - ZeroMemory(&data, sizeof(data)); - - LPBYTE buf = 0; - LPBYTE p = 0; - int len = 0; - - FILE* f; - ::fopen_s(&f, filename, "rb"); - - if (f) { - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len > 4096) { - len = 4096; - } - - buf = new BYTE[len]; - - if (buf && len) - fread(buf, len, 1, f); - - fclose(f); - } - - - if (len > sizeof(head)) { - CopyMemory(&head, buf, sizeof(head)); - - if (head.RIFF == MAKEFOURCC('R', 'I', 'F', 'F') && - head.WAVE == MAKEFOURCC('W', 'A', 'V', 'E')) { - - p = buf + sizeof(WAVE_HEADER); - - do { - DWORD chunk_id = *((LPDWORD) p); - - switch (chunk_id) { - case MAKEFOURCC('f', 'm', 't', ' '): - CopyMemory(&fmt, p, sizeof(fmt)); - p += fmt.chunk_size + 8; - break; - - case MAKEFOURCC('f', 'a', 'c', 't'): - CopyMemory(&fact, p, sizeof(fact)); - p += fact.chunk_size + 8; - break; - - case MAKEFOURCC('s', 'm', 'p', 'l'): - CopyMemory(&fact, p, sizeof(fact)); - p += fact.chunk_size + 8; - break; - - case MAKEFOURCC('d', 'a', 't', 'a'): - CopyMemory(&data, p, sizeof(data)); - p += 8; - break; - - default: - delete[] buf; - return sound; - } - } - while (data.chunk_size == 0); - - wfex.wFormatTag = fmt.wFormatTag; - wfex.nChannels = fmt.nChannels; - wfex.nSamplesPerSec = fmt.nSamplesPerSec; - wfex.nAvgBytesPerSec = fmt.nAvgBytesPerSec; - wfex.nBlockAlign = fmt.nBlockAlign; - wfex.wBitsPerSample = fmt.wBitsPerSample; - wfex.cbSize = 0; - - sound = Create(Sound::STREAMED, &wfex); - - if (sound) { - sound->SetFilename(filename); - sound->StreamFile(filename, p - buf); - } - } - } - - delete[] buf; - return sound; -} - -// +--------------------------------------------------------------------+ - -Sound* -Sound::CreateOggStream(const char* filename) -{ - Sound* sound = 0; - - if (!filename || !filename[0] || !creator) - return sound; - - int namelen = strlen(filename); - - if (namelen < 5) - return sound; - - WAVEFORMATEX wfex; - ZeroMemory(&wfex, sizeof(wfex)); - - FILE* f; - ::fopen_s(&f, filename, "rb"); - - if (f) { - OggVorbis_File* povf = new OggVorbis_File; - - if (!povf) { - Print("Sound::CreateOggStream(%s) - out of memory!\n", filename); - return sound; - } - - ZeroMemory(povf, sizeof(OggVorbis_File)); - - if (ov_open(f, povf, NULL, 0) < 0) { - Print("Sound::CreateOggStream(%s) - not an Ogg bitstream\n", filename); - delete povf; - return sound; - } - - Print("\nOpened Ogg Bitstream '%s'\n", filename); - char **ptr=ov_comment(povf,-1)->user_comments; - vorbis_info *vi=ov_info(povf,-1); - while(*ptr){ - Print("%s\n", *ptr); - ++ptr; - } - - Print("Bitstream is %d channel, %ldHz\n", vi->channels, vi->rate); - Print("Decoded length: %ld samples\n", - (long)ov_pcm_total(povf,-1)); - Print("Encoded by: %s\n\n", ov_comment(povf,-1)->vendor); - - wfex.wFormatTag = WAVE_FORMAT_PCM; - wfex.nChannels = vi->channels; - wfex.nSamplesPerSec = vi->rate; - wfex.nAvgBytesPerSec = vi->channels * vi->rate * 2; - wfex.nBlockAlign = vi->channels * 2; - wfex.wBitsPerSample = 16; - wfex.cbSize = 0; - - sound = Create(Sound::STREAMED | Sound::OGGVORBIS, - &wfex, - sizeof(OggVorbis_File), - (LPBYTE) povf); - - sound->SetFilename(filename); - } - - return sound; -} - -// +--------------------------------------------------------------------+ - -Sound* -Sound::Create(DWORD flags, LPWAVEFORMATEX format) -{ - if (creator) return creator->CreateSound(flags, format); - else return 0; -} - -Sound* -Sound::Create(DWORD flags, LPWAVEFORMATEX format, DWORD len, LPBYTE data) -{ - if (creator) return creator->CreateSound(flags, format, len, data); - else return 0; -} - -void -Sound::SetListener(const Camera& cam, const Vec3& vel) -{ - if (creator) - creator->SetListener(cam, vel); -} - -// +--------------------------------------------------------------------+ - -Sound::Sound() - : status(UNINITIALIZED), volume(0), flags(0), looped(0), - velocity(0,0,0), location(0,0,0), sound_check(0) -{ - strcpy_s(filename, "Sound()"); -} - -// +--------------------------------------------------------------------+ - -Sound::~Sound() -{ } - -// +--------------------------------------------------------------------+ - -void -Sound::Release() -{ - flags &= ~LOCKED; -} - -// +--------------------------------------------------------------------+ - -void -Sound::AddToSoundCard() -{ - if (creator) - creator->AddSound(this); -} - -// +--------------------------------------------------------------------+ - -void -Sound::SetFilename(const char* s) -{ - if (s) { - int n = strlen(s); - - if (n >= 60) { - ZeroMemory(filename, sizeof(filename)); - strcpy_s(filename, "..."); - strcat_s(filename, s + n - 59); - filename[63] = 0; - } - - else { - strcpy_s(filename, s); - } - } -} - diff --git a/Stars45/Sound.h b/Stars45/Sound.h deleted file mode 100644 index 3837a7b..0000000 --- a/Stars45/Sound.h +++ /dev/null @@ -1,149 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract Sound Object -*/ - -#ifndef Sound_h -#define Sound_h - -#include "Types.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class SoundCard; -class SoundCheck; -class Camera; - -// +--------------------------------------------------------------------+ - -class Sound -{ -public: - static const char* TYPENAME() { return "Sound"; } - - static Sound* CreateStream(const char* filename); - static Sound* CreateOggStream(const char* filename); - static Sound* Create(DWORD flags, LPWAVEFORMATEX format); - static Sound* Create(DWORD flags, LPWAVEFORMATEX format, DWORD len, LPBYTE data); - static void SetListener(const Camera& cam, const Vec3& vel); - static void UseSoundCard(SoundCard* s) { creator = s; } - -public: - Sound(); - virtual ~Sound(); - - int operator==(const Sound& rhs) const { return this == &rhs; } - - enum FlagEnum { AMBIENT = 0x0000, - LOCALIZED = 0x0001, - LOC_3D = 0x0002, - MEMORY = 0x0000, - STREAMED = 0x0004, - ONCE = 0x0000, - LOOP = 0x0008, - FREE = 0x0000, - LOCKED = 0x0010, - DOPPLER = 0x0020, - INTERFACE = 0x0040, - OGGVORBIS = 0x4000, - RESOURCE = 0x8000 // not playable, only used to store data - }; - - enum StatusEnum { UNINITIALIZED, - INITIALIZING, - READY, - PLAYING, - DONE }; - - // once per frame: - virtual void Update() { } - - // mark for collection: - virtual void Release(); - - // data loading: - // this method is for streamed sounds: - virtual HRESULT StreamFile(const char* name, DWORD offset) { return E_NOINTERFACE; } - - // this method is for memory sounds: - virtual HRESULT Load(DWORD bytes, BYTE* data) { return E_NOINTERFACE; } // => Ready - - // this method is for sound resources: - virtual Sound* Duplicate() { return 0; } // => Ready - - // transport operations: - virtual HRESULT Play() { return E_NOINTERFACE; } // => Playing - virtual HRESULT Rewind() { return E_NOINTERFACE; } // => Ready - virtual HRESULT Pause() { return E_NOINTERFACE; } // => Ready - virtual HRESULT Stop() { return E_NOINTERFACE; } // => Done - - // accessors / mutators - int IsReady() const { return status == READY; } - int IsPlaying() const { return status == PLAYING; } - int IsDone() const { return status == DONE; } - int LoopCount() const { return looped; } - - virtual DWORD GetFlags() const { return flags; } - virtual void SetFlags(DWORD f) { flags = f; } - virtual DWORD GetStatus() const { return status; } - - virtual long GetVolume() const { return volume; } - virtual void SetVolume(long v) { volume = v; } - virtual long GetPan() const { return 0; } - virtual void SetPan(long p) { } - - // (only for streamed sounds) - virtual double GetTotalTime() const { return 0; } - virtual double GetTimeRemaining() const { return 0; } - virtual double GetTimeElapsed() const { return 0; } - - // These should be relative to the listener: - // (only used for localized sounds) - virtual const Vec3& GetLocation() const { return location; } - virtual void SetLocation(const Vec3& l) { location = l; } - virtual const Vec3& GetVelocity() const { return velocity; } - virtual void SetVelocity(const Vec3& v) { velocity = v; } - - virtual float GetMinDistance() const { return 0; } - virtual void SetMinDistance(float f) { } - virtual float GetMaxDistance() const { return 0; } - virtual void SetMaxDistance(float f) { } - - virtual void SetSoundCheck(SoundCheck* s) { sound_check = s; } - virtual void AddToSoundCard(); - - const char* GetFilename() const { return filename; } - void SetFilename(const char* s); - -protected: - DWORD flags; - DWORD status; - long volume; // centibels, (0 .. -10000) - int looped; - Vec3 location; - Vec3 velocity; - SoundCheck* sound_check; - char filename[64]; - - static SoundCard* creator; -}; - -// +--------------------------------------------------------------------+ - -class SoundCheck -{ -public: - virtual void Update(Sound* s) { } -}; - -#endif // Sound_h - diff --git a/Stars45/SoundCard.cpp b/Stars45/SoundCard.cpp deleted file mode 100644 index 1e54cce..0000000 --- a/Stars45/SoundCard.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract sound card class -*/ - -#include - -#include "SoundCard.h" -#include "Sound.h" - -// +--------------------------------------------------------------------+ - -DWORD WINAPI SoundCardUpdateProc(LPVOID link); - -// +--------------------------------------------------------------------+ - -SoundCard::SoundCard() -: status(SC_UNINITIALIZED), hthread(0), shutdown(false) -{ - DWORD thread_id = 0; - hthread = CreateThread(0, 4096, SoundCardUpdateProc, - (LPVOID) this, 0, &thread_id); -} - -// +--------------------------------------------------------------------+ - -SoundCard::~SoundCard() -{ - shutdown = true; - - WaitForSingleObject(hthread, 500); - CloseHandle(hthread); - hthread = 0; - - sounds.destroy(); - status = SC_UNINITIALIZED; -} - -// +--------------------------------------------------------------------+ - -DWORD WINAPI SoundCardUpdateProc(LPVOID link) -{ - SoundCard* card = (SoundCard*) link; - - if (card) - return card->UpdateThread(); - - return (DWORD) E_POINTER; -} - -// +--------------------------------------------------------------------+ - -DWORD -SoundCard::UpdateThread() -{ - while (!shutdown) { - Update(); - Sleep(50); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -SoundCard::Update() -{ - const std::lock_guard lock(sync); - - ListIter iter = sounds; - while (++iter) { - Sound* s = iter.value(); - - s->Update(); - - if (s->GetStatus() == Sound::DONE && - !(s->GetFlags() & Sound::LOCKED)) { - - delete iter.removeItem(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -SoundCard::AddSound(Sound* s) -{ - const std::lock_guard lock(sync); - - if (!sounds.contains(s)) - sounds.append(s); -} - diff --git a/Stars45/SoundCard.h b/Stars45/SoundCard.h deleted file mode 100644 index a791c81..0000000 --- a/Stars45/SoundCard.h +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract Audio Output class (hides details of DirectSound) -*/ - -#ifndef SoundCard_h -#define SoundCard_h - -#include - -#include "Types.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Sound; -class Camera; -struct Vec3; - -// +--------------------------------------------------------------------+ - -class SoundCard -{ -public: - static const char* TYPENAME() { return "SoundCard"; } - - SoundCard(); - virtual ~SoundCard(); - - enum SoundStatus { SC_UNINITIALIZED, - SC_OK, - SC_ERROR, - SC_BAD_PARAM }; - SoundStatus Status() const { return status; } - - // Format of the sound card's primary buffer: - virtual bool GetFormat(LPWAVEFORMATEX format) { return false; } - virtual bool SetFormat(LPWAVEFORMATEX format) { return false; } - virtual bool SetFormat(int bits, int channels, int hertz) { return false; } - virtual bool Pause() { return false; } - virtual bool Resume() { return false; } - virtual bool StopSoundEffects() { return false; } - - // Get a blank, writable sound buffer: - virtual Sound* CreateSound(DWORD flags, LPWAVEFORMATEX format) { return 0; } - - // Create a sound resource: - virtual Sound* CreateSound(DWORD flags, LPWAVEFORMATEX format, - DWORD len, LPBYTE data) { return 0; } - - // once per frame: - virtual void Update(); - - virtual void SetListener(const Camera& cam, const Vec3& vel) { } - virtual DWORD UpdateThread(); - virtual void AddSound(Sound* s); - -protected: - - bool shutdown; - HANDLE hthread; - SoundStatus status; - List sounds; - std::mutex sync; -}; - -#endif // SoundCard_h - diff --git a/Stars45/SoundD3D.cpp b/Stars45/SoundD3D.cpp deleted file mode 100644 index 803b85a..0000000 --- a/Stars45/SoundD3D.cpp +++ /dev/null @@ -1,1296 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - DirectSound and DirectSound3D (sound card) class -*/ - -//#define INITGUID -#include -#include -#include -#include - -#include - -#include "SoundD3D.h" -#include "Game.h" -#include "Utils.h" - -#ifdef DIRECT_SOUND_3D -#include "ia3d.h" -#endif - -// +--------------------------------------------------------------------+ - -char* DSErrStr(HRESULT dserr); -void SoundD3DError(const char* msg, HRESULT dserr); - -static int DS3D_report_errors = 1; - -#ifndef RELEASE -#define RELEASE(x) if (x) { x->Release(); x=NULL; } -#endif - -// +====================================================================+ -// | SOUND CARD D3D -// +====================================================================+ - -SoundCardD3D::SoundCardD3D(HWND hwnd) -: soundcard(0), primary(0) -{ - HRESULT err = 0; - status = SC_ERROR; - - // 1) Get interface to DirectSound object: - -#ifdef DIRECT_SOUND_3D - CoInitialize(NULL); - err = CoCreateInstance(CLSID_A3d, NULL, CLSCTX_INPROC_SERVER, - IID_IDirectSound, (VOID **)&soundcard); - - if (SUCCEEDED(err)) { - soundcard->Initialize(NULL); - SoundD3DError("Initialized Aureal3D Sound", 0); - } - else { - SoundD3DError("Could not initialize Aureal3D Sound", err); - SoundD3DError("Proceding with standard DirectSoundCreate", 0); -#endif - - err = DirectSoundCreate(0, &soundcard, 0); - if (FAILED(err)) { - SoundD3DError("Could not create DirectSound object.", err); - soundcard = 0; - primary = 0; - return; - } - -#ifdef DIRECT_SOUND_3D - } -#endif - - // 2) Set the cooperative level: - err = soundcard->SetCooperativeLevel(hwnd, DSSCL_PRIORITY); - if (FAILED(err)) { - SoundD3DError("Could not set cooperative level.", err); - RELEASE(soundcard); - return; - } - - // Prepare to initialize the primary buffer: - DSCAPS caps; - memset(&caps, 0, sizeof(caps)); - caps.dwSize = sizeof(caps); - - err = soundcard->GetCaps(&caps); - if (FAILED(err)) { - SoundD3DError("Could not get soundcard caps.", err); - RELEASE(soundcard); - return; - } - - if (caps.dwFlags & DSCAPS_EMULDRIVER) - Print(" WARNING: using DirectSound emulated drivers\n"); - - memset(&dsbd, 0, sizeof(dsbd)); - dsbd.dwSize = sizeof(dsbd); - -#ifdef DIRECT_SOUND_3D - int use_ds3d = true; - - // 3) Set up the primary buffer (try to use DS3D): - dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRL3D; - - err = soundcard->CreateSoundBuffer(&dsbd, &primary, 0); - if (err == DSERR_CONTROLUNAVAIL) { - use_ds3d = false; - - // try again, without using DS3D - dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLDEFAULT; - - err = soundcard->CreateSoundBuffer(&dsbd, &primary, 0); - if (FAILED(err)) { - SoundD3DError("Could not initialize primary buffer", err); - RELEASE(soundcard); - return; - } - else { - Print(" WARNING: DirectSound3D is not available, simulating instead\n"); - } - } - - // 4) Set up the listener: - if (primary && use_ds3d) { - err = primary->QueryInterface(IID_IDirectSound3DListener, (void**)&listener); - if (FAILED(err)) { - SoundD3DError("Could not get listener interface", err); - } - else { - listener->SetPosition(0.0f, 0.0f, 0.0f, DS3D_IMMEDIATE); - listener->SetOrientation(0.0f, 0.0f, 1.0f, - 0.0f, 1.0f, 0.0f, DS3D_IMMEDIATE); - } - } - -#else - // 3) Set up the primary buffer: - dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; - - err = soundcard->CreateSoundBuffer(&dsbd, &primary, 0); - if (FAILED(err)) { - SoundD3DError("Could not initialize primary buffer", err); - RELEASE(soundcard); - return; - } -#endif - - // 5) Set primary buffer parameters to 16 bit STEREO at 44kHz - SetFormat(16, 2, 44100); - - // read back the result format and display to the log file: - GetFormat(0); - ShowFormat(); - - status = SC_OK; -} - -// +--------------------------------------------------------------------+ - -SoundCardD3D::~SoundCardD3D() -{ - ListIter iter = sounds; - while (++iter) { - Sound* s = iter.value(); - s->Stop(); - } - - sounds.destroy(); - -#ifdef DIRECT_SOUND_3D - RELEASE(listener); -#endif - - RELEASE(primary); - RELEASE(soundcard); - - Print(" SoundCardD3D: shutdown\n"); - - status = SC_UNINITIALIZED; -} - -// +--------------------------------------------------------------------+ - -bool -SoundCardD3D::SetFormat(int bits, int channels, int hertz) -{ - if (!soundcard) return false; - - DSCAPS caps; - memset(&caps, 0, sizeof(caps)); - caps.dwSize = sizeof(caps); - soundcard->GetCaps(&caps); - - if (!(caps.dwFlags & DSCAPS_PRIMARY16BIT)) bits = 8; - if (!(caps.dwFlags & DSCAPS_PRIMARYSTEREO)) channels = 1; - - memset(&wfex, 0, sizeof(wfex)); - - wfex.wFormatTag = WAVE_FORMAT_PCM; - wfex.nChannels = channels; - wfex.nSamplesPerSec = hertz; - wfex.nBlockAlign = (channels * bits) / 8; - wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; - wfex.wBitsPerSample = bits; - - return SetFormat(&wfex); -} - -// +--------------------------------------------------------------------+ - -bool -SoundCardD3D::SetFormat(LPWAVEFORMATEX format) -{ - HRESULT err = E_FAIL; - - if (primary) - err = primary->SetFormat(format); - - return SUCCEEDED(err); -} - -// +--------------------------------------------------------------------+ - -bool -SoundCardD3D::GetFormat(LPWAVEFORMATEX format) -{ - if (!format) format = &wfex; - - HRESULT err = E_FAIL; - - if (primary) - err = primary->GetFormat(format, sizeof(WAVEFORMATEX), 0); - - return SUCCEEDED(err); -} - -// +--------------------------------------------------------------------+ - -void -SoundCardD3D::ShowFormat() -{ - Print(" SoundCardD3D Primary Buffer Format:\n"); - Print(" bits: %d\n", wfex.wBitsPerSample); - Print(" chls: %d\n", wfex.nChannels); - Print(" rate: %d\n\n", wfex.nSamplesPerSec); -} - -// +--------------------------------------------------------------------+ - -Sound* -SoundCardD3D::CreateSound(DWORD flags, LPWAVEFORMATEX format) -{ - if (!soundcard) return 0; - - Sound* result = new SoundD3D(soundcard, flags, format); - if (result) AddSound(result); - return result; -} - -// +--------------------------------------------------------------------+ - -Sound* -SoundCardD3D::CreateSound(DWORD flags, LPWAVEFORMATEX format, DWORD len, LPBYTE data) -{ - if (!soundcard) return 0; - Sound* result = new SoundD3D(soundcard, flags, format, len, data); - - if (flags & (Sound::STREAMED | Sound::OGGVORBIS)) { - if (result) - AddSound(result); - } - - return result; -} - -// +--------------------------------------------------------------------+ - -void -SoundCardD3D::SetListener(const Camera& cam, const Vec3& vel) -{ - Point pos = cam.Pos(); - -#ifdef DIRECT_SOUND_3D - listener->SetPosition((float) pos.x, (float) pos.z, (float) pos.y, DS3D_IMMEDIATE); - listener->SetOrientation((float) cam.vpn().x, (float) cam.vpn().y, (float) cam.vpn().z, - (float) cam.vup().x, (float) cam.vup().y, (float) cam.vup().z, - DS3D_IMMEDIATE); - listener->SetVelocity(vel.x, vel.y, vel.z, DS3D_IMMEDIATE); -#else - listener.Clone(cam); - listener.MoveTo(pos.x, pos.z, pos.y); - velocity = vel; -#endif -} - -// +--------------------------------------------------------------------+ - -bool -SoundCardD3D::Pause() -{ - const std::lock_guard lock(sync); - - ListIter iter = sounds; - while (++iter) { - Sound* s = iter.value(); - - if ((s->GetFlags() & Sound::INTERFACE) == 0) - s->Pause(); - } - - return true; -} - -// +--------------------------------------------------------------------+ - -bool -SoundCardD3D::Resume() -{ - const std::lock_guard lock(sync); - - ListIter iter = sounds; - while (++iter) { - Sound* s = iter.value(); - - if (s->IsReady()) - s->Play(); - } - - return true; -} - -// +--------------------------------------------------------------------+ - -bool -SoundCardD3D::StopSoundEffects() -{ - const std::lock_guard lock(sync); - - DWORD ok_sounds = (Sound::INTERFACE | Sound::OGGVORBIS | Sound::RESOURCE); - - ListIter iter = sounds; - while (++iter) { - Sound* s = iter.value(); - - if ((s->GetFlags() & ok_sounds) == 0) - s->Stop(); - } - - return true; -} - -// +====================================================================+ -// | SOUND D3D -// +====================================================================+ - -SoundD3D::SoundD3D(LPDIRECTSOUND card, DWORD flag_req, LPWAVEFORMATEX format) -: soundcard(card), buffer(0), min_dist(1.0f), max_dist(100000.0f), -stream(0), stream_left(0), min_safety(0), read_size(0), transfer(0), w(0), r(0), -stream_offset(0), data_len(0), data(0), moved(false), eos_written(false), eos_latch(0), -ov_file(0), total_time(0) -{ - flags = flag_req; - - CopyMemory(&wfex, format, sizeof(wfex)); - ZeroMemory(&dsbd, sizeof(dsbd)); - - dsbd.dwSize = sizeof(dsbd); - dsbd.dwFlags = DSBCAPS_CTRLVOLUME /* | DSBCAPS_GETCURRENTPOSITION2 */; - dsbd.lpwfxFormat = &wfex; - -#ifdef DIRECT_SOUND_3D - sound3d = 0; - if (flags & LOCALIZED) - if (flags & LOC_3D) - dsbd.dwFlags |= DSBCAPS_CTRL3D; - else - dsbd.dwFlags |= DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; -#else - dsbd.dwFlags |= DSBCAPS_LOCSOFTWARE; - - if (flags & LOCALIZED) - dsbd.dwFlags |= DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; -#endif - -} - -// +--------------------------------------------------------------------+ -// SOUND RESOURCE CONSTRUCTOR: -// (Now also used to create Ogg Vorbis streaming sound objects) - -SoundD3D::SoundD3D(LPDIRECTSOUND card, DWORD flag_req, LPWAVEFORMATEX format, DWORD len, LPBYTE pData) -: soundcard(card), buffer(0), min_dist(1.0f), max_dist(100000.0f), -stream(0), stream_left(0), min_safety(0), read_size(0), transfer(0), w(0), r(0), -stream_offset(0), data_len(0), data(0), moved(false), eos_written(false), eos_latch(0), -ov_file(0) -{ - flags = flag_req; - - if (!(flags & (STREAMED | OGGVORBIS))) - flags = flag_req | RESOURCE; - - CopyMemory(&wfex, format, sizeof(wfex)); - ZeroMemory(&dsbd, sizeof(dsbd)); - - dsbd.dwSize = sizeof(dsbd); - dsbd.dwFlags = DSBCAPS_CTRLVOLUME /* | DSBCAPS_GETCURRENTPOSITION2 */; - dsbd.lpwfxFormat = &wfex; - -#ifdef DIRECT_SOUND_3D - sound3d = 0; - if (flags & LOCALIZED) - if (flags & LOC_3D) - dsbd.dwFlags |= DSBCAPS_CTRL3D; - else - dsbd.dwFlags |= DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; -#else - if (flags & LOCALIZED) - dsbd.dwFlags |= DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; -#endif - - if (len) { - // If this is an OGG VORBIS streaming sound, - // the parameter that normally points to the actual data - // is used to pass in an Ogg Vorbis file structure instead: - - if (flags & OGGVORBIS) { - ov_file = (OggVorbis_File*) pData; - StreamOggFile(); - } - - else { - data_len = len; - data = new BYTE[len]; - - if (!data) { - data_len = 0; - } - - else { - CopyMemory(data, pData, data_len); - Load(data_len, data); - } - } - } -} - -// +--------------------------------------------------------------------+ - -SoundD3D::~SoundD3D() -{ - delete [] data; - delete [] transfer; - - if (ov_file) { - ov_clear(ov_file); - delete ov_file; - } - - else if (stream) { - fclose(stream); - } - - RELEASE(buffer); - -#ifdef DIRECT_SOUND_3D - RELEASE(sound3d); -#endif -} - -// +--------------------------------------------------------------------+ - -void -SoundD3D::Update() -{ - if (!buffer || status != PLAYING) return; // nothing to do - - DWORD dstat; - HRESULT hr = buffer->GetStatus(&dstat); - if (FAILED(hr)) { - SoundD3DError("Update: GetStatus failed", hr); - return; - } - - const std::lock_guard lock(sync); - - if (sound_check) sound_check->Update(this); - - if (!Game::GetInstance()->Paused() || flags & STREAMED) { - // see if we are done: - if (!(dstat & DSBSTATUS_PLAYING)) { - status = DONE; - buffer->Stop(); - return; - } - - // if not done, see if we need to change location params: - if (moved) { - Localize(); - } - } - - // if not done, see if we need to load more data - // into the streaming buffer: - if (flags & STREAMED) { - buffer->GetCurrentPosition(&r, 0); - - DWORD data_left; - if (w > r) - data_left = w - r; - else - data_left = w + (read_size + min_safety) - r; - - // getting low, fill 'er up: - if (eos_written || data_left <= min_safety) { - StreamBlock(); - - if (stream_left == 0) { - // if this is the end of a looping stream, - if (flags & LOOP) { - RewindStream(); - looped++; - } - else { - if (!eos_written) { - eos_written = true; - eos_latch = 3; - } - - else if (--eos_latch == 0) { - status = DONE; - buffer->Stop(); - } - } - } - - status = PLAYING; - } - } -} - -void -SoundD3D::StreamBlock() -{ - if (flags & OGGVORBIS) { - StreamOggBlock(); - return; - } - - if (!stream || !stream_left) - return; - - if (stream_left < read_size) { - if (stream_left > 0) { - fread(transfer, stream_left, 1, stream); - Load(stream_left, transfer); - stream_left = 0; - } - } - - else if (read_size > 0) { - fread(transfer, read_size, 1, stream); - Load(read_size, transfer); - stream_left -= read_size; - } -} - -int ogg_read_error_count = 0; - -void -SoundD3D::StreamOggBlock() -{ - int current_bitstream; - DWORD bytes_read = 0; - long retval = 0; - char* p = (char*) transfer; - - while (stream_left && bytes_read < read_size) { - retval = ov_read(ov_file, p, read_size-bytes_read, 0,2,1, ¤t_bitstream); - - if (retval == 0) { - /* EOF */ - stream_left = 0; - } - else if (retval < 0) { - /* error in the stream. Not a problem, just reporting it in - case the app cares. In this case, we don't. */ - ogg_read_error_count++; - } - else { - /* we don't bother dealing with sample rate changes, etc, but you'll have to ??? */ - bytes_read += retval; - stream_left -= retval; - p += retval; - } - } - - if (bytes_read) - Load(bytes_read, transfer); -} - -void -SoundD3D::RewindStream() -{ - if (flags & OGGVORBIS) { - RewindOggStream(); - return; - } - - if (!stream || !buffer) - return; - - // rewind the stream and keep going... - eos_written = false; - eos_latch = 0; - read_size = wfex.nAvgBytesPerSec / 2; - - // find the size of the file: - fseek(stream, 0, SEEK_END); - stream_left = ftell(stream) - stream_offset; - fseek(stream, stream_offset, SEEK_SET); - - total_time = (double) stream_left / - (double) wfex.nAvgBytesPerSec; - - if (stream_left < read_size) { - status = DONE; - buffer->Stop(); - } -} - -void -SoundD3D::RewindOggStream() -{ - if (!ov_file || !buffer) - return; - - // rewind the stream and keep going... - eos_written = false; - eos_latch = 0; - read_size = wfex.nAvgBytesPerSec / 2; - - // set the stream pointer back to the beginning: - ov_pcm_seek(ov_file, 0); - - // find the size of the file: - stream_left = (DWORD) ov_pcm_total(ov_file,-1); - stream_offset = 0; - - total_time = (double) stream_left / - (double) wfex.nAvgBytesPerSec; - - if (stream_left < read_size) { - status = DONE; - buffer->Stop(); - } -} - -void -SoundD3D::Localize() -{ -#ifdef DIRECT_SOUND_3D - if (sound3d) { - sound3d->SetMinDistance(min_dist, DS3D_IMMEDIATE); - sound3d->SetMaxDistance(max_dist, DS3D_IMMEDIATE); - sound3d->SetPosition(location.x, location.y, location.z, DS3D_IMMEDIATE); - sound3d->SetVelocity(velocity.x, velocity.y, velocity.z, DS3D_IMMEDIATE); - } - -#else - - // if no buffer, nothing to do: - if (!buffer) { - moved = false; - return; - } - - // Compute pan and volume from scratch: - - if ((flags & LOC_3D) && creator) { - Vec3 loc = location; - - SoundCardD3D* ears = (SoundCardD3D*) creator; - Camera& listener = ears->listener; - Vec3 ear_loc = listener.Pos(); ear_loc.SwapYZ(); - Vec3 direction = loc - ear_loc; - - loc.x = direction * listener.vrt(); - loc.y = direction * listener.vup(); - loc.z = direction * listener.vpn(); - - double pan = 10000; - if (loc.z != 0.0f) pan = fabs(1000.0f * loc.x / loc.z); - if (pan > 10000) pan = 10000; - if (loc.x < 0) pan = -pan; - - if (volume > 0) - volume = 0; - - double vol = volume; - double mind2 = min_dist * min_dist; - double maxd2 = max_dist * max_dist; - double d2 = (loc.x*loc.x) + (loc.y*loc.y) + (loc.z*loc.z); - - if (d2 > maxd2) - vol = -10000; - else if (d2 > mind2) - vol -= (d2-mind2)/(maxd2-mind2) * (vol+10000); - - // clamp volume to legal range: - if (vol < -10000) vol = -10000; - else if (vol > volume) vol = volume; - - /*** - Print("Localize: ears = (%f, %f, %f)\n", ear_loc.x, ear_loc.y, ear_loc.z); - Print(" world = (%f, %f, %f)\n", location.x, location.y, location.z); - Print(" view = (%f, %f, %f)\n", loc.x, loc.y, loc.z); - Print(" Pan=%f Volume=%f\n", pan, vol); - /***/ - - HRESULT hr = buffer->SetPan((LONG) pan); - if (!SUCCEEDED(hr)) { - char warn[512]; - sprintf_s(warn, "Warning could not set pan on buffer to %f", pan); - SoundD3DError(warn, hr); - } - - hr = buffer->SetVolume((LONG) vol); - if (!SUCCEEDED(hr)) { - char warn[512]; - sprintf_s(warn, "Warning: could not set volume on buffer to %f", vol); - SoundD3DError(warn, hr); - } - - // if not too far to hear... - if ((flags & DOPPLER) && (d2 < maxd2)) { - // COMPUTE DOPPLER SHIFT: - const float c = 10000.0f; - - direction.Normalize(); - float v_L = ears->velocity * direction; - float v_S = velocity * direction; - - DWORD f_shift = wfex.nSamplesPerSec; - - if (v_L != v_S) { - // towards listener: - if (v_S < 0) - f_shift = wfex.nSamplesPerSec + 20; - else - f_shift = wfex.nSamplesPerSec - 20; - } - - // distance rolloff of high frequencies: - double dist = sqrt(d2); - DWORD roll_off = (DWORD) (80 * dist/max_dist); - - f_shift -= roll_off; - - if (f_shift < 100) f_shift = 100; - if (f_shift > 100000) f_shift = 100000; - - hr = buffer->SetFrequency(f_shift); - if (!SUCCEEDED(hr)) { - char warn[512]; - sprintf_s(warn, "Warning: could not set Doppler frequency on buffer to %d", f_shift); //-V576 - SoundD3DError(warn, hr); - } - } - } - else { - buffer->SetPan((LONG) location.x); - buffer->SetVolume((LONG) volume); - } -#endif - - moved = false; -} - -// +--------------------------------------------------------------------+ - -Sound* -SoundD3D::Duplicate() -{ - Sound* sound = 0; - - if (flags & RESOURCE) { - sound = Sound::Create(flags & ~RESOURCE, &wfex); - - if (sound && !(flags & STREAMED)) { - sound->SetMinDistance(min_dist); - sound->SetMaxDistance(max_dist); - - if (!buffer) { - sound->Load(data_len, data); - } - - else { - SoundD3D* s3d = (SoundD3D*) sound; - soundcard->DuplicateSoundBuffer(buffer, &s3d->buffer); - sound->Rewind(); - } - } - } - - return sound; -} - -// +--------------------------------------------------------------------+ - -HRESULT -SoundD3D::StreamFile(const char* name, DWORD offset) -{ - DWORD buf_size = wfex.nAvgBytesPerSec / 2; - DWORD safety_zone = buf_size * 2; - - if (stream) { - delete[] transfer; - transfer = 0; - fclose(stream); - } - - status = UNINITIALIZED; - stream_left = 0; - stream_offset = offset; - - eos_written = false; - eos_latch = 0; - min_safety = safety_zone; - read_size = buf_size; - - fopen_s(&stream, name, "rb"); - - // open the stream: - if (stream == 0) { - SoundD3DError("StreamFile: could not open stream", E_FAIL); - return E_FAIL; - } - - // find the size of the file: - fseek(stream, 0, SEEK_END); - stream_left = ftell(stream) - offset; - fseek(stream, stream_offset, SEEK_SET); - - total_time = (double) stream_left / - (double) wfex.nAvgBytesPerSec; - - if (stream_left < read_size) { - read_size = stream_left; - } - - HRESULT hr = AllocateBuffer(read_size + min_safety); - - if (FAILED(hr)) - return hr; - - flags |= STREAMED; - - // preload the buffer: - w = r = 0; - transfer = new BYTE[read_size + 1024]; - - if (!transfer) { - hr = E_FAIL; - } - - else { - ZeroMemory(transfer, read_size+1024); - StreamBlock(); - } - - return hr; -} - -// +--------------------------------------------------------------------+ - -HRESULT -SoundD3D::StreamOggFile() -{ - DWORD buf_size = wfex.nAvgBytesPerSec / 2; - DWORD safety_zone = buf_size * 2; - - if (stream) { - delete[] transfer; - fclose(stream); - - transfer = 0; - stream = 0; - } - - status = UNINITIALIZED; - stream_left = (DWORD) ov_pcm_total(ov_file,-1); - stream_offset = 0; - - eos_written = false; - eos_latch = 0; - min_safety = safety_zone; - read_size = buf_size; - - total_time = (double) stream_left / - (double) wfex.nAvgBytesPerSec; - - if (stream_left < read_size) { - read_size = stream_left; - } - - HRESULT hr = AllocateBuffer(read_size + min_safety); - - if (FAILED(hr)) - return hr; - - flags |= STREAMED | OGGVORBIS; - - // preload the buffer: - w = r = 0; - transfer = new BYTE[read_size + 1024]; - - if (!transfer) { - hr = E_FAIL; - } - - else { - ZeroMemory(transfer, read_size+1024); - StreamOggBlock(); - } - - return hr; -} - -// +--------------------------------------------------------------------+ - -HRESULT -SoundD3D::Load(DWORD bytes, BYTE* data) -{ - status = UNINITIALIZED; - - HRESULT hr; - - if (!buffer) { - hr = AllocateBuffer(bytes); - if (FAILED(hr)) { - return hr; - } - } - - LPVOID dest1, dest2; - DWORD size1, size2; - - hr = buffer->Lock(w, bytes, &dest1, &size1, &dest2, &size2, 0); - - if (hr == DSERR_BUFFERLOST) { - buffer->Restore(); - hr = buffer->Lock(w, bytes, &dest1, &size1, &dest2, &size2, 0); - } - - if (SUCCEEDED(hr)) { - CopyMemory(dest1, data, size1); - if (dest2) { - CopyMemory(dest2, data + size1, size2); - } - - if (flags & STREAMED) - w = (w + size1 + size2) % (read_size + min_safety); - else - w += size1 + size2; - - hr = buffer->Unlock(dest1, size1, dest2, size2); - if (FAILED(hr)) { - SoundD3DError("Load: could not unlock buffer", hr); - } - } - else { - SoundD3DError("Load: could not lock buffer", hr); - } - - if (SUCCEEDED(hr)) { - status = READY; - } - - return hr; -} - -// +--------------------------------------------------------------------+ - -HRESULT -SoundD3D::AllocateBuffer(DWORD bytes) -{ - HRESULT hr = S_OK; - - if (!buffer) { - dsbd.dwBufferBytes = bytes; - - if (soundcard) { - hr = soundcard->CreateSoundBuffer(&dsbd, &buffer, NULL); - - if (FAILED(hr)) { - SoundD3DError("AllocateBuffer: could not create buffer", hr); - - Print(" dsbd.dwSize = %8d\n", dsbd.dwSize); - Print(" dsbd.dwFlags = %08x\n", dsbd.dwFlags); - Print(" dsbd.dwBufferBytes = %8d\n", dsbd.dwBufferBytes); - Print(" dsbd.lpwfxFormat = %08x\n", dsbd.lpwfxFormat); - - if (dsbd.lpwfxFormat) { - Print(" wfex.wBitsPerSample = %8d\n", dsbd.lpwfxFormat->wBitsPerSample); - Print(" wfex.nChannels = %8d\n", dsbd.lpwfxFormat->nChannels); - Print(" wfex.nSamplesPerSec = %8d\n", dsbd.lpwfxFormat->nSamplesPerSec); - } - } - } - else { - SoundD3DError("AllocateBuffer: soundcard is null", E_FAIL); - } - } - - return hr; -} - -// +--------------------------------------------------------------------+ - -HRESULT -SoundD3D::Play() -{ - if (IsPlaying()) return S_OK; - if (!buffer) return E_FAIL; - - HRESULT hr = E_FAIL; - - if (IsDone()) - hr = Rewind(); - - if (IsReady()) { - if (moved) - Localize(); - - if (flags & LOOP || flags & STREAMED) - hr = buffer->Play(0, 0, DSBPLAY_LOOPING); - else - hr = buffer->Play(0, 0, 0); - - if (SUCCEEDED(hr)) - status = PLAYING; - } - - return hr; -} - -// +--------------------------------------------------------------------+ - -HRESULT -SoundD3D::Rewind() -{ - if (!buffer) return E_FAIL; - - HRESULT hr = S_OK; - - if (IsPlaying()) - hr = Stop(); - - if (flags & STREAMED) { - RewindStream(); - StreamBlock(); - } - - else { - hr = buffer->SetCurrentPosition(0); - } - - if (SUCCEEDED(hr)) { - status = READY; - looped = 0; - } - - return hr; -} - -// +--------------------------------------------------------------------+ - -HRESULT -SoundD3D::Pause() -{ - if (status == DONE) - return S_OK; - - HRESULT hr = Stop(); - - if (SUCCEEDED(hr)) - status = READY; - - return hr; -} - -// +--------------------------------------------------------------------+ - -HRESULT -SoundD3D::Stop() -{ - if (!buffer) - return E_FAIL; - - if (!IsPlaying()) { - status = DONE; - return S_OK; - } - - status = DONE; - return buffer->Stop(); -} - -// +--------------------------------------------------------------------+ - -double -SoundD3D::GetTimeRemaining() const -{ - double time_left = -1; - - if (IsPlaying() || IsReady()) { - time_left = (double) stream_left / - (double) wfex.nAvgBytesPerSec; - } - - return time_left; -} - -double -SoundD3D::GetTimeElapsed() const -{ - double time_elapsed = 0; - - if (IsPlaying()) { - time_elapsed = total_time - GetTimeRemaining(); - } - - return time_elapsed; -} - -// +--------------------------------------------------------------------+ - -void -SoundD3D::SetVolume(long v) -{ - if (v > 0) v = 0; - else if (v < -10000) v = -10000; - - volume = v; - moved = true; -} - -// +--------------------------------------------------------------------+ - -long -SoundD3D::GetPan() const -{ - long p = 10000; - - if (location.z) p = (long) fabs(location.x/location.z); - if (p > 10000) p = 10000; - if (location.x < 0) p = -p; - - return p; -} - -void -SoundD3D::SetPan(long p) -{ - if (p > 10000) p = 10000; - if (p < -10000) p = -10000; - - location.x = (float) p; - location.y = 0.0f; - location.z = 1.0f; - moved = true; -} - -// +--------------------------------------------------------------------+ - -void -SoundD3D::SetLocation(const Vec3& l) -{ - location = l; - moved = true; -} - -void -SoundD3D::SetVelocity(const Vec3& v) -{ - velocity = v; - moved = true; -} - -// +--------------------------------------------------------------------+ - -float -SoundD3D::GetMinDistance() const -{ - return min_dist; -} - -void -SoundD3D::SetMinDistance(float f) -{ - min_dist = f; - moved = true; -} - -// +--------------------------------------------------------------------+ - -float -SoundD3D::GetMaxDistance() const -{ - return max_dist; -} -void -SoundD3D::SetMaxDistance(float f) -{ - max_dist = f; - moved = true; -} - - -// +--------------------------------------------------------------------+ - -void -SoundD3DError(const char* msg, HRESULT err) -{ - Print(" SoundD3D: %s. [%s]\n", msg, DSErrStr(err)); -} - -char* -DSErrStr(HRESULT err) -{ - switch (err) { - case DS_OK: return "DS_OK"; - - case DSERR_ALLOCATED: return - "The call failed because resources (such as a priority level) " - "were already being used by another caller."; - - case DSERR_CONTROLUNAVAIL: return - "The control (vol,pan,etc.) requested by the caller is not available."; - - case DSERR_INVALIDPARAM: return - "An invalid parameter was passed to the returning function."; - - case DSERR_INVALIDCALL: return - "This call is not valid for the current state of this object"; - - case DSERR_GENERIC: return - "An undetermined error occured inside the DirectSound subsystem"; - - case DSERR_PRIOLEVELNEEDED: return - "The caller does not have the priority level required for the function to succeed."; - - case DSERR_OUTOFMEMORY: return - "Not enough free memory is available to complete the operation"; - - case DSERR_BADFORMAT: return - "The specified WAVE format is not supported"; - - case DSERR_UNSUPPORTED: return - "The function called is not supported at this time"; - - case DSERR_NODRIVER: return - "No sound driver is available for use"; - - case DSERR_ALREADYINITIALIZED: return - "This object is already initialized"; - - case DSERR_NOAGGREGATION: return - "This object does not support aggregation"; - - case DSERR_BUFFERLOST: return - "The buffer memory has been lost, and must be restored."; - - case DSERR_OTHERAPPHASPRIO: return - "Another app has a higher priority level, preventing this call from succeeding."; - - case DSERR_UNINITIALIZED: return - "This object has not been initialized."; - -#ifdef DIRECT_SOUND_3D - case DSERR_NOINTERFACE: return - "The requested COM interface is not available."; -#endif - - default: return "Unknown Error Code"; - } - - return "Internal Error"; -} - diff --git a/Stars45/SoundD3D.h b/Stars45/SoundD3D.h deleted file mode 100644 index a667182..0000000 --- a/Stars45/SoundD3D.h +++ /dev/null @@ -1,162 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - DirectSound3D Audio Output and Buffer classes -*/ - -#ifndef SoundD3D_h -#define SoundD3D_h - -#include - -//#define DIRECT_SOUND_3D -#include "SoundCard.h" -#include "Sound.h" -#include "Camera.h" -#include -#include -#include "vorbis/vorbisfile.h" - -// +--------------------------------------------------------------------+ - -class SoundD3D; -class SoundCardD3D; - -// +--------------------------------------------------------------------+ -// Sound Implementation for DirectSound and DirectSound3D - -class SoundD3D : public Sound -{ -public: - static const char* TYPENAME() { return "SoundD3D"; } - - SoundD3D(LPDIRECTSOUND card, DWORD flags, LPWAVEFORMATEX format); - SoundD3D(LPDIRECTSOUND card, DWORD flags, LPWAVEFORMATEX format, DWORD len, LPBYTE data); - virtual ~SoundD3D(); - - virtual void Update(); - - virtual HRESULT StreamFile(const char* name, DWORD offset); - virtual HRESULT Load(DWORD bytes, BYTE* data); - virtual HRESULT Play(); - virtual HRESULT Rewind(); - virtual HRESULT Pause(); - virtual HRESULT Stop(); - - virtual Sound* Duplicate(); - - // (only for streamed sounds) - virtual double GetTotalTime() const { return total_time; } - virtual double GetTimeRemaining() const; - virtual double GetTimeElapsed() const; - - // (only used for localized sounds) - virtual void SetVolume(long v); - virtual long GetPan() const; - virtual void SetPan(long p); - virtual void SetLocation(const Vec3& l); - virtual void SetVelocity(const Vec3& v); - - virtual float GetMinDistance() const; - virtual void SetMinDistance(float f); - virtual float GetMaxDistance() const; - virtual void SetMaxDistance(float f); - - -protected: - void Localize(); - HRESULT AllocateBuffer(DWORD bytes); - HRESULT StreamOggFile(); - - void StreamBlock(); - void StreamOggBlock(); - void RewindStream(); - void RewindOggStream(); - - LPDIRECTSOUND soundcard; - WAVEFORMATEX wfex; - DSBUFFERDESC dsbd; - LPDIRECTSOUNDBUFFER buffer; - - DWORD data_len; - LPBYTE data; - -#ifdef DIRECT_SOUND_3D - LPDIRECTSOUND3DBUFFER sound3d; -#endif - - float min_dist; - float max_dist; - - // STREAMED SOUND SUPPORT: - FILE* stream; - DWORD stream_left; - double total_time; - DWORD min_safety; - DWORD read_size; - BYTE* transfer; - DWORD w, r; - DWORD stream_offset; - bool eos_written; - BYTE eos_latch; - bool moved; - - std::mutex sync; - OggVorbis_File* ov_file; -}; - -// +--------------------------------------------------------------------+ -// Sound Card Implementation for DS and DS3D - -class SoundCardD3D : public SoundCard -{ - friend class SoundD3D; - -public: - static const char* TYPENAME() { return "SoundCardD3D"; } - - SoundCardD3D(HWND hwnd); - virtual ~SoundCardD3D(); - - // Format of the sound card's primary buffer: - virtual bool GetFormat(LPWAVEFORMATEX format); - virtual bool SetFormat(LPWAVEFORMATEX format); - virtual bool SetFormat(int bits, int channels, int hertz); - - virtual void ShowFormat(); - - // Get a blank, writable sound buffer: - virtual Sound* CreateSound(DWORD flags, LPWAVEFORMATEX format); - - // Create a sound resource: - virtual Sound* CreateSound(DWORD flags, LPWAVEFORMATEX format, DWORD len, LPBYTE data); - - virtual void SetListener(const Camera& cam, const Vec3& vel); - virtual bool Pause(); - virtual bool Resume(); - virtual bool StopSoundEffects(); - -protected: - LPDIRECTSOUND soundcard; - LPDIRECTSOUNDBUFFER primary; - -#ifdef DIRECT_SOUND_3D - LPDIRECTSOUND3DLISTENER listener; -#else - Camera listener; - Vec3 velocity; -#endif - - WAVEFORMATEX wfex; - DSBUFFERDESC dsbd; -}; - -#endif // SoundD3D_h - diff --git a/Stars45/Sprite.cpp b/Stars45/Sprite.cpp deleted file mode 100644 index a845344..0000000 --- a/Stars45/Sprite.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Sprite (Polygon) Object -*/ - -#include "Sprite.h" -#include "Bitmap.h" -#include "Camera.h" -#include "Polygon.h" -#include "Video.h" -#include "Clock.h" - -// +--------------------------------------------------------------------+ - -Sprite::Sprite() -: w(0), h(0), nframes(0), own_frames(0), -frames(0), frame_index(0), frame_time(100), loop(0), shade(1.0), -angle(0.0), blend_mode(4), filter(1), vset(4), poly(0) -{ - trans = true; - - vset.space = VertexSet::WORLD_SPACE; - for (int i = 0; i < 4; i++) { - vset.diffuse[i] = Color::White.Value(); - } - - vset.tu[0] = 0.0f; - vset.tv[0] = 0.0f; - vset.tu[1] = 1.0f; - vset.tv[1] = 0.0f; - vset.tu[2] = 1.0f; - vset.tv[2] = 1.0f; - vset.tu[3] = 0.0f; - vset.tv[3] = 1.0f; - - poly.nverts = 4; - poly.vertex_set = &vset; - poly.material = &mtl; - poly.verts[0] = 0; - poly.verts[1] = 1; - poly.verts[2] = 2; - poly.verts[3] = 3; -} - -// +--------------------------------------------------------------------+ - -Sprite::Sprite(Bitmap* animation, int length, int repeat, int share) -: w(0), h(0), nframes(0), own_frames(0), -frames(0), frame_index(0), frame_time(67), loop(0), shade(1.0), -angle(0.0), blend_mode(4), filter(1), vset(4), poly(0) -{ - trans = true; - SetAnimation(animation, length, repeat, share); - - vset.space = VertexSet::WORLD_SPACE; - for (int i = 0; i < 4; i++) { - vset.diffuse[i] = Color::White.Value(); - } - - vset.tu[0] = 0.0f; - vset.tv[0] = 0.0f; - vset.tu[1] = 1.0f; - vset.tv[1] = 0.0f; - vset.tu[2] = 1.0f; - vset.tv[2] = 1.0f; - vset.tu[3] = 0.0f; - vset.tv[3] = 1.0f; - - poly.nverts = 4; - poly.vertex_set = &vset; - poly.material = &mtl; - poly.verts[0] = 0; - poly.verts[1] = 1; - poly.verts[2] = 2; - poly.verts[3] = 3;} - -// +--------------------------------------------------------------------+ - -Sprite::~Sprite() -{ - if (own_frames) { - if (nframes == 1) - delete frames; - else - delete [] frames; - } -} - -// +--------------------------------------------------------------------+ - -void -Sprite::Scale(double scale) -{ - if (scale >= 0) { - w = (int) (scale * w); - h = (int) (scale * h); - - radius = (float) ((w>h) ? w : h) / 2.0f; - } -} - -// +--------------------------------------------------------------------+ - -void -Sprite::Rescale(double scale) -{ - if (scale >= 0 && Frame()) { - w = (int) (scale * Frame()->Width()); - h = (int) (scale * Frame()->Height()); - - radius = (float) ((w>h) ? w : h) / 2.0f; - } -} - -// +--------------------------------------------------------------------+ - -void -Sprite::Reshape(int w1, int h1) -{ - if (w1 >= 0 && h1 >= 0 && Frame()) { - w = w1; - h = h1; - - radius = (float) ((w>h) ? w : h) / 2.0f; - } -} - -// +--------------------------------------------------------------------+ - -void -Sprite::SetAnimation(Bitmap* animation, int length, int repeat, int share) -{ - if (animation) { - strncpy_s(name, animation->GetFilename(), 31); - name[31] = 0; - - if (own_frames) { - if (nframes == 1) - delete frames; - else - delete [] frames; - } - - w = animation->Width(); - h = animation->Height(); - - radius = (float) ((w>h) ? w : h) / 2.0f; - - own_frames = !share; - nframes = length; - frames = animation; - frame_index = 0; - - if (repeat) { - loop = 1; - life = -1; - } - else { - loop = 0; - life = nframes; - } - - last_time = Clock::GetInstance()->RealTime() - frame_time; - } -} - -// +--------------------------------------------------------------------+ - -void -Sprite::SetTexCoords(const double* uv_interleaved) -{ - if (uv_interleaved) { - vset.tu[0] = (float) uv_interleaved[0]; - vset.tv[0] = (float) uv_interleaved[1]; - vset.tu[1] = (float) uv_interleaved[2]; - vset.tv[1] = (float) uv_interleaved[3]; - vset.tu[2] = (float) uv_interleaved[4]; - vset.tv[2] = (float) uv_interleaved[5]; - vset.tu[3] = (float) uv_interleaved[6]; - vset.tv[3] = (float) uv_interleaved[7]; - } - else { - vset.tu[0] = 0.0f; - vset.tv[0] = 0.0f; - vset.tu[1] = 1.0f; - vset.tv[1] = 0.0f; - vset.tu[2] = 1.0f; - vset.tv[2] = 1.0f; - vset.tu[3] = 0.0f; - vset.tv[3] = 1.0f; - } -} - -// +--------------------------------------------------------------------+ - -double -Sprite::FrameRate() const -{ - return 1000.0 / (double) frame_time; -} - -void -Sprite::SetFrameRate(double rate) -{ - if (rate > 0.001 && rate < 100) { - frame_time = (int) (1000.0 / rate); - } -} - -// +--------------------------------------------------------------------+ - -void -Sprite::SetFrameIndex(int n) -{ - if (n >= 0 && n < nframes) - frame_index = n; -} - -// +--------------------------------------------------------------------+ - -Bitmap* -Sprite::Frame() const -{ - return frames + frame_index; -} - -// +--------------------------------------------------------------------+ - -void -Sprite::Render(Video* video, DWORD flags) -{ - if (shade < 0.001 || hidden || !visible || !video) - return; - - if (blend_mode == 2 && !(flags & Graphic::RENDER_ALPHA)) - return; - - if (blend_mode == 4 && !(flags & Graphic::RENDER_ADDITIVE)) - return; - - if (life > 0 || loop) { - const Camera* camera = video->GetCamera(); - Matrix orient(camera->Orientation()); - Vec3 nrm(camera->vpn() * -1); - ColorValue white((float) shade, (float) shade, (float) shade, (float) shade); - DWORD diff = white.ToColor().Value(); - - orient.Roll(angle); - - Vec3 vx = Vec3((float) orient(0,0), - (float) orient(0,1), - (float) orient(0,2)) * (float) (w/2.0f); - - Vec3 vy = Vec3((float) orient(1,0), - (float) orient(1,1), - (float) orient(1,2)) * (float) (h/2.0f); - - vset.loc[0] = loc - vx + vy; - vset.nrm[0] = nrm; - vset.diffuse[0] = diff; - - vset.loc[1] = loc + vx + vy; - vset.nrm[1] = nrm; - vset.diffuse[1] = diff; - - vset.loc[2] = loc + vx - vy; - vset.nrm[2] = nrm; - vset.diffuse[2] = diff; - - vset.loc[3] = loc - vx - vy; - vset.nrm[3] = nrm; - vset.diffuse[3] = diff; - - if (luminous) { - mtl.Ka = Color::Black; - mtl.Kd = Color::Black; - mtl.Ks = Color::Black; - mtl.Ke = white; - mtl.tex_diffuse = Frame(); - mtl.tex_emissive = Frame(); - mtl.blend = blend_mode; - mtl.luminous = luminous; - } - - else { - mtl.Ka = white; - mtl.Kd = white; - mtl.Ks = Color::Black; - mtl.Ke = Color::Black; - mtl.tex_diffuse = Frame(); - mtl.tex_emissive = 0; - mtl.blend = blend_mode; - mtl.luminous = luminous; - } - - video->DrawPolys(1, &poly); - } - - memset(&screen_rect, 0, sizeof(Rect)); -} - -// +--------------------------------------------------------------------+ - -void -Sprite::Render2D(Video* video) -{ - if (shade < 0.001 || hidden || !visible || !video) - return; - - ColorValue white((float) shade, (float) shade, (float) shade, (float) shade); - DWORD diff = white.ToColor().Value(); - - double ca = cos(Angle()); - double sa = sin(Angle()); - - double w2 = Width() / 2.0; - double h2 = Height() / 2.0; - - vset.s_loc[0].x = (float) (loc.x + (-w2*ca - -h2*sa) - 0.5); - vset.s_loc[0].y = (float) (loc.y + (-w2*sa + -h2*ca) - 0.5); - vset.s_loc[0].z = 0.0f; - vset.rw[0] = 1.0f; - vset.diffuse[0] = diff; - - vset.s_loc[1].x = (float) (loc.x + ( w2*ca - -h2*sa) - 0.5); - vset.s_loc[1].y = (float) (loc.y + ( w2*sa + -h2*ca) - 0.5); - vset.s_loc[1].z = 0.0f; - vset.rw[1] = 1.0f; - vset.diffuse[1] = diff; - - vset.s_loc[2].x = (float) (loc.x + ( w2*ca - h2*sa) - 0.5); - vset.s_loc[2].y = (float) (loc.y + ( w2*sa + h2*ca) - 0.5); - vset.s_loc[2].z = 0.0f; - vset.rw[2] = 1.0f; - vset.diffuse[2] = diff; - - vset.s_loc[3].x = (float) (loc.x + (-w2*ca - h2*sa) - 0.5); - vset.s_loc[3].y = (float) (loc.y + (-w2*sa + h2*ca) - 0.5); - vset.s_loc[3].z = 0.0f; - vset.rw[3] = 1.0f; - vset.diffuse[3] = diff; - - mtl.Kd = white; - mtl.tex_diffuse = Frame(); - mtl.blend = blend_mode; - - video->DrawScreenPolys(1, &poly, blend_mode); -} - -// +--------------------------------------------------------------------+ - -void -Sprite::Update() -{ - if (life > 0 || loop) { - DWORD time = Clock::GetInstance()->RealTime(); - while (time - last_time > frame_time) { - life--; - frame_index++; - if (frame_index >= nframes) - frame_index = 0; - - last_time += frame_time; - } - - if (life < 0 && !loop) - life = 0; - } -} - diff --git a/Stars45/Sprite.h b/Stars45/Sprite.h deleted file mode 100644 index e3e3915..0000000 --- a/Stars45/Sprite.h +++ /dev/null @@ -1,89 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Sprite Object -*/ - -#ifndef Sprite_h -#define Sprite_h - -#include "Types.h" -#include "Graphic.h" -#include "Polygon.h" - -// +--------------------------------------------------------------------+ - -class Bitmap; - -class Sprite : public Graphic -{ -public: - static const char* TYPENAME() { return "Sprite"; } - - Sprite(); - Sprite(Bitmap* animation, int length=1, int repeat=1, int share=1); - virtual ~Sprite(); - - // operations - virtual void Render(Video* video, DWORD flags); - virtual void Render2D(Video* video); - virtual void Update(); - virtual void Scale(double scale); - virtual void Rescale(double scale); - virtual void Reshape(int w1, int h1); - - // accessors / mutators - int Width() const { return w; } - int Height() const { return h; } - int Looping() const { return loop; } - int NumFrames() const { return nframes; } - double FrameRate() const; - void SetFrameRate(double rate); - - double Shade() const { return shade; } - void SetShade(double s) { shade = s; } - double Angle() const { return angle; } - void SetAngle(double a) { angle = a; } - int BlendMode() const { return blend_mode; } - void SetBlendMode(int a) { blend_mode = a; } - int Filter() const { return filter; } - void SetFilter(int f) { filter = f; } - virtual void SetAnimation(Bitmap* animation, int length=1, int repeat=1, int share=1); - virtual void SetTexCoords(const double* uv_interleaved); - - Bitmap* Frame() const; - void SetFrameIndex(int n); - - virtual bool IsSprite() const { return true; } - -protected: - int w, h; - int loop; - - int nframes; - int own_frames; - Bitmap* frames; - int frame_index; - DWORD frame_time; - DWORD last_time; - double shade; - double angle; - int blend_mode; - int filter; - - Poly poly; - Material mtl; - VertexSet vset; -}; - -// +--------------------------------------------------------------------+ - -#endif // Sprite_h - diff --git a/Stars45/StarServer.cpp b/Stars45/StarServer.cpp deleted file mode 100644 index a03bd15..0000000 --- a/Stars45/StarServer.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/* 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 - - -#include "StarServer.h" -#include "Campaign.h" -#include "CombatRoster.h" -#include "Galaxy.h" -#include "Mission.h" -#include "Sim.h" -#include "SimEvent.h" -#include "Ship.h" -#include "Contact.h" -#include "QuantumDrive.h" -#include "Power.h" -#include "SystemDesign.h" -#include "WeaponDesign.h" -#include "Shot.h" -#include "Drive.h" -#include "Explosion.h" -#include "FlightDeck.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "Random.h" -#include "ModConfig.h" - -#include "NetLayer.h" -#include "NetGame.h" -#include "NetHost.h" -#include "NetServer.h" -#include "HttpServer.h" -#include "HttpServletExec.h" -#include "NetAdminServer.h" -#include "NetLobbyServer.h" -#include "NetServerConfig.h" - -#include "Token.h" -#include "MachineInfo.h" -#include "Game.h" -#include "Clock.h" -#include "ContentBundle.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "EventDispatch.h" -#include "MultiController.h" -#include "DataLoader.h" -#include "ParseUtil.h" -#include "VersionInfo.h" - -// +--------------------------------------------------------------------+ - -StarServer* StarServer::instance = 0; - -static Mission* current_mission = 0; -static double time_til_change = 0; -static bool exit_latch = true; - -// +--------------------------------------------------------------------+ - -StarServer::StarServer() -: loader(0), time_mark(0), minutes(0), game_mode(MENU_MODE), -admin_server(0), lobby_server(0) -{ - if (!instance) - instance = this; - - app_name = "Starserver 5.0"; - title_text = "Starserver"; - palette_name = "alpha"; - - server = true; - show_mouse = true; - - 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."; - - ::Print(err_msg); - ::Print("\n\nFATAL ERROR: EXIT."); - exit(-1); - } - - if (loader->FindFile("start.dat")) - loader->EnableDatafile("start.dat"); - - // no images or sounds in server mode: - loader->EnableMedia(false); -} - -StarServer::~StarServer() -{ - delete admin_server; - delete lobby_server; - - admin_server = 0; - lobby_server = 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 - - Drive::Close(); - Explosion::Close(); - FlightDeck::Close(); - Campaign::Close(); - CombatRoster::Close(); - Galaxy::Close(); - RadioTraffic::Close(); - Ship::Close(); - WeaponDesign::Close(); - SystemDesign::Close(); - DataLoader::Close(); - NetServerConfig::Close(); - ModConfig::Close(); - - instance = 0; - - server = false; -} - -// +--------------------------------------------------------------------+ - -bool -StarServer::Init(HINSTANCE hi, HINSTANCE hpi, LPSTR cmdline, int nCmdShow) -{ - if (loader) - loader->UseFileSystem(false); - - return Game::Init(hi, hpi, cmdline, nCmdShow); -} - -// +--------------------------------------------------------------------+ - -bool -StarServer::InitGame() -{ - if (!Game::InitGame()) - return false; - - RandomInit(); - ModConfig::Initialize(); - NetServerConfig::Initialize(); - SystemDesign::Initialize("sys.def"); - WeaponDesign::Initialize("wep.def"); - Ship::Initialize(); - Galaxy::Initialize(); - CombatRoster::Initialize(); - Campaign::Initialize(); - - Drive::Initialize(); - Explosion::Initialize(); - FlightDeck::Initialize(); - Ship::Initialize(); - Shot::Initialize(); - RadioTraffic::Initialize(); - - time_mark = Clock::GetInstance()->GameTime(); - minutes = 0; - - NetServerConfig* server_config = NetServerConfig::GetInstance(); - if (!server_config) - return false; - - ::Print("\n\n\nStarshatter Server Init\n"); - ::Print("-----------------------\n"); - ::Print("Server Name: %s\n", (const char*) server_config->Name()); - ::Print("Server Type: %d\n", server_config->GetGameType()); - - if (server_config->GetMission().length() > 0) - ::Print("Server Mission: %s\n", (const char*) server_config->GetMission()); - - ::Print("Lobby Server Port: %d\n", server_config->GetLobbyPort()); - ::Print("Admin Server Port: %d\n", server_config->GetAdminPort()); - ::Print("-----------------------\n"); - - NetLobbyServer* nls = new NetLobbyServer; - NetAdminServer* nas = NetAdminServer::GetInstance(server_config->GetAdminPort()); - nas->SetServerName(server_config->Name()); - - lobby_server = nls; - admin_server = nas; - - std::cout << "Started server listening on port " << server_config->GetLobbyPort() << std::endl; - - return true; -} - -// +--------------------------------------------------------------------+ - -void -StarServer::SetGameMode(int m) -{ - if (game_mode == m) - return; - - if (m == LOAD_MODE) { - Print(" game_mode = LOAD_MODE\n"); - paused = true; - } - - else if (m == PLAY_MODE) { - Print(" game_mode = PLAY_MODE\n"); - - if (!world) { - CreateWorld(); - InstantiateMission(); - } - - // stand alone server should wait for players to connect - // before unpausing the simulation... - Clock::GetInstance()->SetTimeCompression(1.0); - Pause(true); - } - - else if (m == MENU_MODE) { - Print(" game_mode = MENU_MODE\n"); - paused = true; - - Sim* sim = (Sim*) world; - - if (sim) - sim->UnloadMission(); - } - - game_mode = m; -} - -// +--------------------------------------------------------------------+ - -void -StarServer::SetNextMission(const char* script) -{ - if (lobby_server) - lobby_server->SetServerMission(script); -} - -// +--------------------------------------------------------------------+ - -void -StarServer::CreateWorld() -{ - RadioTraffic::Initialize(); - - // create world - if (!world) { - Sim* sim = new Sim(0); - world = sim; - Print(" World Created.\n"); - } -} - -void -StarServer::InstantiateMission() -{ - current_mission = 0; - - if (Campaign::GetCampaign()) { - current_mission = Campaign::GetCampaign()->GetMission(); - } - - Sim* sim = (Sim*) world; - - if (sim) { - sim->UnloadMission(); - - if (current_mission) { - sim->LoadMission(current_mission); - sim->ExecMission(); - sim->SetTestMode(false); - - Print(" Mission Instantiated.\n"); - std::cout << "Loaded mission: " << current_mission->Name() << std::endl; - } - - else { - Print(" *** WARNING: StarServer::InstantiateMission() - no mission selected ***\n"); - } - } -} - -// +--------------------------------------------------------------------+ - -bool -StarServer::GameLoop() -{ - if (active && paused) { - UpdateWorld(); - GameState(); - } - - else if (!active) { - UpdateWorld(); - GameState(); - Sleep(10); - } - - Game::GameLoop(); - return false; // must return false to keep processing - // true tells the outer loop to sleep until a - // windows event is available -} - -// +--------------------------------------------------------------------+ - -void -StarServer::UpdateWorld() -{ - Galaxy* galaxy = Galaxy::GetInstance(); - if (galaxy) galaxy->ExecFrame(); - - 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()); - } - - static DWORD refresh_time = 0; - if (Clock::GetInstance()->RealTime() - refresh_time > 1000) { - refresh_time = Clock::GetInstance()->RealTime(); - } -} - -// +--------------------------------------------------------------------+ - -void -StarServer::GameState() -{ - if (lobby_server) { - lobby_server->ExecFrame(); - - if (lobby_server->GetStatus() == NetServerInfo::PERSISTENT) - paused = NetGame::NumPlayers() < 1; - } - - if (game_mode == MENU_MODE) { - Sleep(30); - } - - else if (game_mode == LOAD_MODE) { - CreateWorld(); - InstantiateMission(); - - SetGameMode(PLAY_MODE); - } - - else if (game_mode == PLAY_MODE) { - 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); - } - - Sleep(10); - } -} - -// +--------------------------------------------------------------------+ - -DWORD WINAPI StarServerShutdownProc(LPVOID link) -{ - StarServer* stars = (StarServer*) link; - - Sleep(3000); - - if (stars) { - stars->Exit(); - return 0; - } - - return (DWORD) E_POINTER; -} - -DWORD WINAPI StarServerRestartProc(LPVOID link) -{ - StarServer* stars = (StarServer*) link; - - Sleep(3000); - - if (stars) { - char cmdline[256]; - strcpy_s(cmdline, "stars -server"); - - STARTUPINFO s; - ZeroMemory(&s, sizeof(s)); - s.cb = sizeof(s); - - PROCESS_INFORMATION pi; - ZeroMemory(&pi, sizeof(pi)); - - CreateProcess("stars.exe", cmdline, 0, 0, 0, 0, 0, 0, &s, &pi); - stars->Exit(); - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - return 0; - } - - return (DWORD) E_POINTER; -} - -void -StarServer::Shutdown(bool restart) -{ - DWORD thread_id = 0; - - if (restart) - CreateThread(0, 4096, StarServerRestartProc, (LPVOID) this, 0, &thread_id); - else - CreateThread(0, 4096, StarServerShutdownProc, (LPVOID) this, 0, &thread_id); -} \ No newline at end of file diff --git a/Stars45/StarServer.h b/Stars45/StarServer.h deleted file mode 100644 index 9776e07..0000000 --- a/Stars45/StarServer.h +++ /dev/null @@ -1,74 +0,0 @@ -/* 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 - -*/ - -#ifndef StarServer_h -#define StarServer_h - -#include "Types.h" -#include "Game.h" -#include "Bitmap.h" -#include "KeyMap.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class Ship; -class Sim; -class FadeView; -class CameraDirector; -class MultiController; -class MouseController; -class DataLoader; - -class NetServer; -class NetLobbyServer; - -// +--------------------------------------------------------------------+ - -class StarServer : public Game -{ -public: - StarServer(); - virtual ~StarServer(); - - virtual bool Init(HINSTANCE hi, HINSTANCE hpi, LPSTR cmdline, int nCmdShow); - virtual bool InitGame(); - virtual void GameState(); - - enum MODE { MENU_MODE, // main menu - LOAD_MODE, // loading mission into simulator - PLAY_MODE // active simulation - }; - - int GetGameMode() { return game_mode; } - void SetGameMode(int mode); - void SetNextMission(const char* script); - - void CreateWorld(); - void Shutdown(bool restart=false); - - static StarServer* GetInstance() { return instance; } - - -protected: - virtual bool GameLoop(); - virtual void UpdateWorld(); - virtual void InstantiateMission(); - - static StarServer* instance; - NetServer* admin_server; - NetLobbyServer* lobby_server; - DataLoader* loader; - - int game_mode; - DWORD time_mark; - DWORD minutes; -}; - -#endif // StarServer_h diff --git a/Stars45/StarSystem.cpp b/Stars45/StarSystem.cpp deleted file mode 100644 index 9d8e377..0000000 --- a/Stars45/StarSystem.cpp +++ /dev/null @@ -1,1953 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Various Heavenly Bodies -*/ - -#include "StarSystem.h" -#include "Galaxy.h" -#include "Sky.h" -#include "Starshatter.h" -#include "TerrainRegion.h" -#include "TerrainHaze.h" -#include "Weather.h" - -#include "Game.h" -#include "GameWinDX9.h" -#include "Clock.h" -#include "Sound.h" -#include "Solid.h" -#include "Light.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Scene.h" -#include "ParseUtil.h" - -const long double epoch = 0.5e9; -long double StarSystem::stardate = 0; - -// +====================================================================+ - -static long double base_time = 0; -static WORD oldcw = 0; -static WORD fpcw = 0; - -void StarSystem::SetBaseTime(long double t, bool absolute) -{ - if (absolute) { - base_time = t; - CalcStardate(); - } - - else if (t > 0) { - if (t > epoch) t -= epoch; - base_time = t; - CalcStardate(); - } -} - -long double StarSystem::GetBaseTime() -{ - return base_time; -} - -void StarSystem::CalcStardate() -{ - if (base_time < 1) { - time_t clock_seconds; - time(&clock_seconds); - - base_time = clock_seconds; - - while (base_time < 0) - base_time += epoch; - } - - long double gtime = (long double) Clock::GetInstance()->GameTime() / 1000.0; - long double sdate = gtime + base_time + epoch; - - stardate = sdate; -} - -static const double GRAV = 6.673e-11; -static const int NAMELEN = 64; - -// +====================================================================+ - -StarSystem::StarSystem(const char* sys_name, Point l, int iff, int s) -: name(sys_name), affiliation(iff), sky_stars(0), sky_dust(0), loc(l), seq(s), -active_region(0), instantiated(false), ambient(0,0,0), -sun_color(255,255,255), sun_scale(1), point_stars(0), poly_stars(0), -nebula(0), haze(0) -{ - center = new Orbital(this, "CG", Orbital::NOTHING, 1.0e35f, 0.0f, 0.0f, 0); - radius = 0.0f; -} - -// +--------------------------------------------------------------------+ - -StarSystem::~StarSystem() -{ - Print(" Destroying Star System %s\n", (const char*) name); - - if (instantiated) { - Deactivate(); - Destroy(); - } - - bodies.destroy(); - regions.destroy(); - all_regions.clear(); // do not destroy these! - - delete center; -} - -// +--------------------------------------------------------------------+ - -static OrbitalBody* primary_star = 0; -static OrbitalBody* primary_planet = 0; -static OrbitalBody* primary_moon = 0; - -void -StarSystem::Load() -{ - CalcStardate(); - active_region = 0; - - BYTE* block = 0; - DataLoader* loader = DataLoader::GetLoader(); - datapath = loader->GetDataPath(); - - sprintf_s(filename, "%s/%s.def", (const char*) name, (const char*) name); - - Print("Loading StarSystem: %s\n", filename); - loader->LoadBuffer(filename, block, true); - - if (!block) { - Print("ERROR: invalid star system file '%s'\n", filename); - exit(-2); - return; - } - - Parser parser(new BlockReader((const char*) block)); - - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'\n", filename); - exit(-3); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "STARSYSTEM") { - Print("ERROR: invalid star system file '%s'\n", filename); - term->print(10); - exit(-4); - return; - } - } - - // parse the system: - do { - delete term; - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "name") { - char namebuf[NAMELEN]; - namebuf[0] = 0; - GetDefText(namebuf, def, filename); - - if (namebuf[0]) - name = namebuf; - } - - else if (def->name()->value() == "sky") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: sky struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - - char imgname[NAMELEN]; - char magname[NAMELEN]; - char hazname[NAMELEN]; - - imgname[0] = 0; - magname[0] = 0; - hazname[0] = 0; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "poly_stars") - GetDefText(imgname, pdef, filename); - - else if (pdef->name()->value() == "nebula") - GetDefText(magname, pdef, filename); - - else if (pdef->name()->value() == "haze") - GetDefText(hazname, pdef, filename); - } - } - - if (imgname[0]) - sky_poly_stars = imgname; - - if (magname[0]) - sky_nebula = magname; - - if (hazname[0]) - sky_haze = hazname; - } - } - - else if (def->name()->value() == "stars") { - GetDefNumber(sky_stars, def, filename); - } - - else if (def->name()->value() == "ambient") { - Vec3 a; - GetDefVec(a, def, filename); - - ambient = Color((BYTE) a.x, (BYTE) a.y, (BYTE) a.z) * 2.5; - } - - else if (def->name()->value() == "dust") { - GetDefNumber(sky_dust, def, filename); - } - - else if (def->name()->value() == "star") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: star struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseStar(val); - } - } - - else if (def->name()->value() == "planet") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: planet struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParsePlanet(val); - } - } - - else if (def->name()->value() == "moon") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: moon struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseMoon(val); - } - } - - else if (def->name()->value() == "region") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: region struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseRegion(val); - } - } - - else if (def->name()->value() == "terrain") { - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: terrain struct missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - ParseTerrain(val); - } - } - - } - } - } - while (term); - - loader->ReleaseBuffer(block); -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::ParseStar(TermStruct* val) -{ - char star_name[NAMELEN]; - char img_name[NAMELEN]; - char map_name[NAMELEN]; - double light = 0.0; - double radius = 0.0; - double rot = 0.0; - double mass = 0.0; - double orbit = 0.0; - double tscale = 1.0; - bool retro = false; - Color color; - Color back; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") - GetDefText(star_name, pdef, filename); - - else if (pdef->name()->value() == "map" || pdef->name()->value() == "icon") - GetDefText(map_name, pdef, filename); - - else if (pdef->name()->value() == "image") - GetDefText(img_name, pdef, filename); - - else if (pdef->name()->value() == "mass") - GetDefNumber(mass, pdef, filename); - - else if (pdef->name()->value() == "orbit") - GetDefNumber(orbit, pdef, filename); - - else if (pdef->name()->value() == "radius") - GetDefNumber(radius, pdef, filename); - - else if (pdef->name()->value() == "rotation") - GetDefNumber(rot, pdef, filename); - - else if (pdef->name()->value() == "tscale") - GetDefNumber(tscale, pdef, filename); - - else if (pdef->name()->value() == "light") - GetDefNumber(light, pdef, filename); - - else if (pdef->name()->value() == "retro") - GetDefBool(retro, pdef, filename); - - else if (pdef->name()->value() == "color") { - Vec3 a; - GetDefVec(a, pdef, filename); - color = Color((BYTE) a.x, (BYTE) a.y, (BYTE) a.z); - } - - else if (pdef->name()->value() == "back" || pdef->name()->value() == "back_color") { - Vec3 a; - GetDefVec(a, pdef, filename); - back = Color((BYTE) a.x, (BYTE) a.y, (BYTE) a.z); - } - } - } - - OrbitalBody* star = new OrbitalBody(this, star_name, Orbital::STAR, mass, radius, orbit, center); - star->map_name = map_name; - star->tex_name = img_name; - star->light = light; - star->tscale = tscale; - star->subtype = Star::G; - star->retro = retro; - star->rotation = rot * 3600; - star->color = color; - star->back = back; - - // map icon: - if (*map_name) { - DataLoader::GetLoader()->LoadBitmap(map_name, star->map_icon, Bitmap::BMP_TRANSLUCENT, true); - } - - bodies.append(star); - primary_star = star; - primary_planet = 0; - primary_moon = 0; - - if (orbit > StarSystem::radius) - StarSystem::radius = orbit; -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::ParsePlanet(TermStruct* val) -{ - char pln_name[NAMELEN]; - char img_name[NAMELEN]; - char map_name[NAMELEN]; - char hi_name[NAMELEN]; - char img_ring[NAMELEN]; - char glo_name[NAMELEN]; - char glo_hi_name[NAMELEN]; - char gloss_name[NAMELEN]; - - double radius = 0.0; - double mass = 0.0; - double orbit = 0.0; - double rot = 0.0; - double minrad = 0.0; - double maxrad = 0.0; - double tscale = 1.0; - double tilt = 0.0; - bool retro = false; - bool lumin = false; - Color atmos = Color::Black; - - ZeroMemory(pln_name, NAMELEN); - ZeroMemory(hi_name, NAMELEN); - ZeroMemory(img_ring, NAMELEN); - ZeroMemory(glo_name, NAMELEN); - ZeroMemory(glo_hi_name, NAMELEN); - ZeroMemory(gloss_name, NAMELEN); - ZeroMemory(map_name, NAMELEN); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") - GetDefText(pln_name, pdef, filename); - - else if (pdef->name()->value() == "map" || pdef->name()->value() == "icon") - GetDefText(map_name, pdef, filename); - - else if (pdef->name()->value() == "image") - GetDefText(img_name, pdef, filename); - - else if (pdef->name()->value() == "image_west") - GetDefText(img_name, pdef, filename); - - else if (pdef->name()->value() == "image_east") - GetDefText(img_name, pdef, filename); - - else if (pdef->name()->value() == "glow") - GetDefText(glo_name, pdef, filename); - - else if (pdef->name()->value() == "gloss") - GetDefText(gloss_name, pdef, filename); - - else if (pdef->name()->value() == "high_res") - GetDefText(hi_name, pdef, filename); - - else if (pdef->name()->value() == "high_res_west") - GetDefText(hi_name, pdef, filename); - - else if (pdef->name()->value() == "high_res_east") - GetDefText(hi_name, pdef, filename); - - else if (pdef->name()->value() == "glow_high_res") - GetDefText(glo_hi_name, pdef, filename); - - else if (pdef->name()->value() == "mass") - GetDefNumber(mass, pdef, filename); - - else if (pdef->name()->value() == "orbit") - GetDefNumber(orbit, pdef, filename); - - else if (pdef->name()->value() == "retro") - GetDefBool(retro, pdef, filename); - - else if (pdef->name()->value() == "luminous") - GetDefBool(lumin, pdef, filename); - - else if (pdef->name()->value() == "rotation") - GetDefNumber(rot, pdef, filename); - - else if (pdef->name()->value() == "radius") - GetDefNumber(radius, pdef, filename); - - else if (pdef->name()->value() == "ring") - GetDefText(img_ring, pdef, filename); - - else if (pdef->name()->value() == "minrad") - GetDefNumber(minrad, pdef, filename); - - else if (pdef->name()->value() == "maxrad") - GetDefNumber(maxrad, pdef, filename); - - else if (pdef->name()->value() == "tscale") - GetDefNumber(tscale, pdef, filename); - - else if (pdef->name()->value() == "tilt") - GetDefNumber(tilt, pdef, filename); - - else if (pdef->name()->value() == "atmosphere") { - Vec3 a; - GetDefVec(a, pdef, filename); - atmos = Color((BYTE) a.x, (BYTE) a.y, (BYTE) a.z); - } - } - } - - OrbitalBody* planet = new OrbitalBody(this, pln_name, Orbital::PLANET, mass, radius, orbit, primary_star); - planet->map_name = map_name; - planet->tex_name = img_name; - planet->tex_high_res = hi_name; - planet->tex_ring = img_ring; - planet->tex_glow = glo_name; - planet->tex_glow_high_res = glo_hi_name; - planet->tex_gloss = gloss_name; - planet->ring_min = minrad; - planet->ring_max = maxrad; - planet->tscale = tscale; - planet->tilt = tilt; - planet->retro = retro; - planet->luminous = lumin; - planet->rotation = rot * 3600; - planet->atmosphere = atmos; - - if (primary_star) - primary_star->satellites.append(planet); - else - bodies.append(planet); - - primary_planet = planet; - primary_moon = 0; - - if (orbit > StarSystem::radius) - StarSystem::radius = orbit; - - // map icon: - if (map_name[0]) { - DataLoader::GetLoader()->LoadBitmap(map_name, planet->map_icon, Bitmap::BMP_TRANSLUCENT, true); - } -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::ParseMoon(TermStruct* val) -{ - char map_name[NAMELEN]; - char pln_name[NAMELEN]; - char img_name[NAMELEN]; - char hi_name[NAMELEN]; - char glo_name[NAMELEN]; - char glo_hi_name[NAMELEN]; - char gloss_name[NAMELEN]; - - double radius = 0.0; - double mass = 0.0; - double orbit = 0.0; - double rot = 0.0; - double tscale = 1.0; - double tilt = 0.0; - bool retro = false; - Color atmos = Color::Black; - - ZeroMemory(map_name, NAMELEN); - ZeroMemory(pln_name, NAMELEN); - ZeroMemory(hi_name, NAMELEN); - ZeroMemory(img_name, NAMELEN); - ZeroMemory(glo_name, NAMELEN); - ZeroMemory(glo_hi_name, NAMELEN); - ZeroMemory(gloss_name, NAMELEN); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") - GetDefText(pln_name, pdef, filename); - - else if (pdef->name()->value() == "map" || pdef->name()->value() == "icon") - GetDefText(map_name, pdef, filename); - - else if (pdef->name()->value() == "image") - GetDefText(img_name, pdef, filename); - - else if (pdef->name()->value() == "glow") - GetDefText(glo_name, pdef, filename); - - else if (pdef->name()->value() == "high_res") - GetDefText(hi_name, pdef, filename); - - else if (pdef->name()->value() == "glow_high_res") - GetDefText(glo_hi_name, pdef, filename); - - else if (pdef->name()->value() == "gloss") - GetDefText(gloss_name, pdef, filename); - - else if (pdef->name()->value() == "mass") - GetDefNumber(mass, pdef, filename); - - else if (pdef->name()->value() == "orbit") - GetDefNumber(orbit, pdef, filename); - - else if (pdef->name()->value() == "rotation") - GetDefNumber(rot, pdef, filename); - - else if (pdef->name()->value() == "retro") - GetDefBool(retro, pdef, filename); - - else if (pdef->name()->value() == "radius") - GetDefNumber(radius, pdef, filename); - - else if (pdef->name()->value() == "tscale") - GetDefNumber(tscale, pdef, filename); - - else if (pdef->name()->value() == "inclination") - GetDefNumber(tilt, pdef, filename); - - else if (pdef->name()->value() == "atmosphere") { - Vec3 a; - GetDefVec(a, pdef, filename); - atmos = Color((BYTE) a.x, (BYTE) a.y, (BYTE) a.z); - } - } - } - - OrbitalBody* moon = new OrbitalBody(this, pln_name, Orbital::MOON, mass, radius, orbit, primary_planet); - moon->map_name = map_name; - moon->tex_name = img_name; - moon->tex_high_res = hi_name; - moon->tex_glow = glo_name; - moon->tex_glow_high_res = glo_hi_name; - moon->tex_gloss = gloss_name; - moon->tscale = tscale; - moon->retro = retro; - moon->rotation = rot * 3600; - moon->tilt = tilt; - moon->atmosphere = atmos; - - if (primary_planet) - primary_planet->satellites.append(moon); - else { - Print("WARNING: no planet for moon %s in '%s', deleted.\n", pln_name, filename); - delete moon; - moon = 0; - } - - primary_moon = moon; - - // map icon: - if (map_name[0]) { - DataLoader::GetLoader()->LoadBitmap(map_name, moon->map_icon, Bitmap::BMP_TRANSLUCENT, true); - } -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::ParseRegion(TermStruct* val) -{ - char rgn_name[NAMELEN]; - char lnk_name[NAMELEN]; - double size = 1.0e6; - double orbit = 0.0; - double grid = 25000; - double inclination = 0.0; - int asteroids = 0; - - List links; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") - GetDefText(rgn_name, pdef, filename); - - else if (pdef->name()->value() == "link") { - GetDefText(lnk_name, pdef, filename); - if (lnk_name[0]) { - links.append(new Text(lnk_name)); - } - } - - else if (pdef->name()->value() == "orbit") - GetDefNumber(orbit, pdef, filename); - - else if (pdef->name()->value() == "size") - GetDefNumber(size, pdef, filename); - - else if (pdef->name()->value() == "radius") - GetDefNumber(size, pdef, filename); - - else if (pdef->name()->value() == "grid") - GetDefNumber(grid, pdef, filename); - - else if (pdef->name()->value() == "inclination") - GetDefNumber(inclination, pdef, filename); - - else if (pdef->name()->value() == "asteroids") - GetDefNumber(asteroids, pdef, filename); - } - } - - Orbital* primary = primary_moon; - if (!primary) primary = primary_planet; - if (!primary) primary = primary_star; - - OrbitalRegion* region = new OrbitalRegion(this, rgn_name, 0, size, orbit, primary); - region->grid = grid; - region->inclination = inclination; - region->asteroids = asteroids; - region->links.append(links); - - if (primary) - primary->regions.append(region); - else - regions.append(region); - - all_regions.append(region); - - if (orbit > StarSystem::radius) - StarSystem::radius = orbit; -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::ParseTerrain(TermStruct* val) -{ - Orbital* primary = primary_moon; - if (!primary) primary = primary_planet; - - if (!primary) { - Print("WARNING: Terrain region with no primary ignored in '%s'\n", filename); - return; - } - - TerrainRegion* region = 0; - - Text rgn_name; - Text patch_name; - Text patch_texture; - Text noise_tex0; - Text noise_tex1; - Text apron_name; - Text apron_texture; - Text water_texture; - Text env_texture_positive_x; - Text env_texture_negative_x; - Text env_texture_positive_y; - Text env_texture_negative_y; - Text env_texture_positive_z; - Text env_texture_negative_z; - Text haze_name; - Text sky_name; - Text clouds_high; - Text clouds_low; - Text shades_high; - Text shades_low; - - double size = 1.0e6; - double grid = 25000; - double inclination = 0.0; - double scale = 10e3; - double mtnscale = 1e3; - double fog_density = 0; - double fog_scale = 0; - double haze_fade = 0; - double clouds_alt_high= 0; - double clouds_alt_low= 0; - double w_period = 0; - double w_chances[Weather::NUM_STATES]; - - ZeroMemory(w_chances, sizeof(w_chances)); - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value() == "name") - GetDefText(rgn_name, pdef, filename); - - else if (pdef->name()->value() == "patch") - GetDefText(patch_name, pdef, filename); - - else if (pdef->name()->value() == "patch_texture") - GetDefText(patch_texture, pdef, filename); - - else if (pdef->name()->value() == "detail_texture_0") - GetDefText(noise_tex0, pdef, filename); - - else if (pdef->name()->value() == "detail_texture_1") - GetDefText(noise_tex1, pdef, filename); - - else if (pdef->name()->value() == "apron") - GetDefText(apron_name, pdef, filename); - - else if (pdef->name()->value() == "apron_texture") - GetDefText(apron_texture, pdef, filename); - - else if (pdef->name()->value() == "water_texture") - GetDefText(water_texture, pdef, filename); - - else if (pdef->name()->value() == "env_texture_positive_x") - GetDefText(env_texture_positive_x, pdef, filename); - - else if (pdef->name()->value() == "env_texture_negative_x") - GetDefText(env_texture_negative_x, pdef, filename); - - else if (pdef->name()->value() == "env_texture_positive_y") - GetDefText(env_texture_positive_y, pdef, filename); - - else if (pdef->name()->value() == "env_texture_negative_y") - GetDefText(env_texture_negative_y, pdef, filename); - - else if (pdef->name()->value() == "env_texture_positive_z") - GetDefText(env_texture_positive_z, pdef, filename); - - else if (pdef->name()->value() == "env_texture_negative_z") - GetDefText(env_texture_negative_z, pdef, filename); - - else if (pdef->name()->value() == "clouds_high") - GetDefText(clouds_high, pdef, filename); - - else if (pdef->name()->value() == "shades_high") - GetDefText(shades_high, pdef, filename); - - else if (pdef->name()->value() == "clouds_low") - GetDefText(clouds_low, pdef, filename); - - else if (pdef->name()->value() == "shades_low") - GetDefText(shades_low, pdef, filename); - - else if (pdef->name()->value() == "haze") - GetDefText(haze_name, pdef, filename); - - else if (pdef->name()->value() == "sky_color") - GetDefText(sky_name, pdef, filename); - - else if (pdef->name()->value() == "size" || - pdef->name()->value() == "radius") - GetDefNumber(size, pdef, filename); - - else if (pdef->name()->value() == "grid") - GetDefNumber(grid, pdef, filename); - - else if (pdef->name()->value() == "inclination") - GetDefNumber(inclination, pdef, filename); - - else if (pdef->name()->value() == "scale") - GetDefNumber(scale, pdef, filename); - - else if (pdef->name()->value() == "mtnscale" || - pdef->name()->value() == "mtn_scale") - GetDefNumber(mtnscale, pdef, filename); - - else if (pdef->name()->value() == "fog_density") - GetDefNumber(fog_density, pdef, filename); - - else if (pdef->name()->value() == "fog_scale") - GetDefNumber(fog_scale, pdef, filename); - - else if (pdef->name()->value() == "haze_fade") - GetDefNumber(haze_fade, pdef, filename); - - else if (pdef->name()->value() == "clouds_alt_high") - GetDefNumber(clouds_alt_high, pdef, filename); - - else if (pdef->name()->value() == "clouds_alt_low") - GetDefNumber(clouds_alt_low, pdef, filename); - - else if (pdef->name()->value() == "weather_period") - GetDefNumber(w_period, pdef, filename); - - else if (pdef->name()->value() == "weather_clear") - GetDefNumber(w_chances[0], pdef, filename); - else if (pdef->name()->value() == "weather_high_clouds") - GetDefNumber(w_chances[1], pdef, filename); - else if (pdef->name()->value() == "weather_moderate_clouds") - GetDefNumber(w_chances[2], pdef, filename); - else if (pdef->name()->value() == "weather_overcast") - GetDefNumber(w_chances[3], pdef, filename); - else if (pdef->name()->value() == "weather_fog") - GetDefNumber(w_chances[4], pdef, filename); - else if (pdef->name()->value() == "weather_storm") - GetDefNumber(w_chances[5], pdef, filename); - - else if (pdef->name()->value() == "layer") { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: terrain layer struct missing in '%s'\n", filename); - } - else { - - if (!region) - region = new TerrainRegion(this, rgn_name, size, primary); - - TermStruct* val = pdef->term()->isStruct(); - ParseLayer(region, val); - } - } - } - } - - if (!region) - region = new TerrainRegion(this, rgn_name, size, primary); - - region->grid = grid; - region->inclination = inclination; - region->patch_name = patch_name; - region->patch_texture = patch_texture; - region->noise_tex0 = noise_tex0; - region->noise_tex1 = noise_tex1; - region->apron_name = apron_name; - region->apron_texture = apron_texture; - region->water_texture = water_texture; - region->haze_name = haze_name; - region->clouds_high = clouds_high; - region->shades_high = shades_high; - region->clouds_low = clouds_low; - region->shades_low = shades_low; - region->scale = scale; - region->mtnscale = mtnscale; - region->fog_density = fog_density; - region->fog_scale = fog_scale; - region->haze_fade = haze_fade; - region->clouds_alt_high = clouds_alt_high; - region->clouds_alt_low = clouds_alt_low; - - region->env_texture_positive_x = env_texture_positive_x; - region->env_texture_negative_x = env_texture_negative_x; - region->env_texture_positive_y = env_texture_positive_y; - region->env_texture_negative_y = env_texture_negative_y; - region->env_texture_positive_z = env_texture_positive_z; - region->env_texture_negative_z = env_texture_negative_z; - - Weather& weather = region->GetWeather(); - - weather.SetPeriod(w_period); - - for (int i = 0; i < Weather::NUM_STATES; i++) - weather.SetChance(i, w_chances[i]); - - region->LoadSkyColors(sky_name); - - primary->regions.append(region); - all_regions.append(region); -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::ParseLayer(TerrainRegion* rgn, TermStruct* val) -{ - Text tile_name; - Text detail_name; - double height = 0; - - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - if (pdef->name()->value().indexOf("tile") == 0) - GetDefText(tile_name, pdef, filename); - - else if (pdef->name()->value().indexOf("detail") == 0) - GetDefText(detail_name, pdef, filename); - - else if (pdef->name()->value().contains("height") || - pdef->name()->value().contains("alt")) - GetDefNumber(height, pdef, filename); - } - } - - if (rgn) - rgn->AddLayer(height, tile_name, detail_name); -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::Create() -{ - if (Game::GetInstance()->Server()) - return; - - if (!instantiated) { - Print("Creating Star System %s\n", (const char*) name); - - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(datapath); - - // poly star shell: - if (sky_poly_stars.length()) { - poly_stars = new Solid; - poly_stars->Load(sky_poly_stars, 120); - poly_stars->SetLuminous(true); - poly_stars->SetInfinite(true); - - Print("Celestial Sphere '%s' loaded\n", (const char*) sky_poly_stars); - Print(" radius: %f\n", poly_stars->Radius()); - } - - if (sky_stars) { - Print("Point Stars: %d\n", sky_stars); - point_stars = new Stars(sky_stars); - } - - loader->SetDataPath(datapath); - - // nebula: - if (sky_nebula.length()) { - nebula = new Solid; - nebula->Load(sky_nebula, 100); - nebula->SetLuminous(true); - nebula->SetInfinite(true); - - Print("Nebular Sky '%s' loaded\n", (const char*) sky_nebula); - Print(" radius: %f\n", nebula->Radius()); - } - - // atmospheric haze: - if (sky_haze.length()) { - loader->SetDataPath(datapath); - haze = new TerrainHaze(); - haze->Load(sky_haze, 120); - - haze->SetInfinite(true); - - Print("Atmospheric Haze '%s' loaded\n", (const char*) sky_haze); - Print(" radius: %f\n", haze->Radius()); - - haze->Hide(); - } - - loader->SetDataPath(0); - - ListIter star = bodies; - while (++star) { - CreateBody(*star); - - ListIter planet = star->Satellites(); - while (++planet) { - CreateBody(*planet); - - ListIter moon = planet->Satellites(); - while (++moon) { - CreateBody(*moon); - } - } - } - } - - instantiated = true; -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::CreateBody(OrbitalBody& body) -{ - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(datapath); - - // stars: - if (body.type == Orbital::STAR) { - Point starloc = body.loc; - starloc = starloc.OtherHand(); - - PlanetRep* rep = new PlanetRep(body.tex_name, - 0, - body.radius, - starloc, - body.tscale); - - rep->SetLuminous(true); - rep->MoveTo(loc); - body.rep = rep; - - sun_brightness = body.light; - sun_color = body.color; - - Light* sun_light = new Light(1.1f); - sun_light->SetColor(sun_color); - sun_light->SetShadow(true); - sun_light->MoveTo(body.loc); - sun_light->SetType(Light::LIGHT_DIRECTIONAL); - - sun_lights.append(sun_light); - body.light_rep = sun_light; - - if (body.back != Color::Black) { - Light* back_light = new Light(0.6f); - back_light->SetColor(body.back); - back_light->SetShadow(false); - back_light->MoveTo(body.loc * -1); - back_light->SetType(Light::LIGHT_DIRECTIONAL); - - back_lights.append(back_light); - body.back_light = back_light; - } - } - - // planets and moons: - else { - Point planetloc = body.loc; - planetloc = planetloc.OtherHand(); - - double rmax = 0; - double rmin = 0; - - if (body.ring_max > 0) { - rmax = body.ring_max*body.radius; - rmin = body.ring_min*body.radius; - } - - Text surface = body.tex_name; - Text glow = body.tex_glow; - - if (GameWinDX9::GetInstance()->MaxTexSize() >= 512) { - if (body.tex_high_res.length()) - surface = body.tex_high_res; - - if (body.tex_glow_high_res.length()) - glow = body.tex_glow_high_res; - } - - PlanetRep* rep = new PlanetRep(surface, - glow, - body.radius, - planetloc, - body.tscale, - body.tex_ring, - rmin, - rmax, - body.atmosphere, - body.tex_gloss); - - rep->SetStarSystem(this); - - /*** - if (body.luminous) { - rep->SetLuminous(1); - } - ***/ - - if (body.tilt != 0) { - Matrix m; - m.Pitch(body.tilt); - - rep->SetOrientation(m); - } - - body.rep = rep; - } -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::Destroy() -{ - if (instantiated) { - ListIter star_iter = bodies; - while (++star_iter) { - OrbitalBody* star = star_iter.value(); - - GRAPHIC_DESTROY(star->rep); - LIGHT_DESTROY(star->light_rep); - LIGHT_DESTROY(star->back_light); - - ListIter planet = star->Satellites(); - while (++planet) { - GRAPHIC_DESTROY(planet->rep); - - ListIter moon = planet->Satellites(); - while (++moon) { - GRAPHIC_DESTROY(moon->rep); - } - } - } - - GRAPHIC_DESTROY(point_stars); - GRAPHIC_DESTROY(poly_stars); - GRAPHIC_DESTROY(nebula); - GRAPHIC_DESTROY(haze); - - sun_lights.clear(); - back_lights.clear(); - } - - instantiated = false; - sun_scale = 1; -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::Activate(Scene& scene) -{ - if (!instantiated) - Create(); - - Starshatter* stars = Starshatter::GetInstance(); - - if (!stars) - return; - - if (point_stars) { - scene.AddBackground(point_stars); - point_stars->Hide(); - } - - if (poly_stars) { - scene.AddBackground(poly_stars); - } - - if (stars->Nebula() && nebula) { - scene.AddBackground(nebula); - } - - if (haze) { - scene.AddBackground(haze); - haze->Hide(); - } - - ListIter star_iter = bodies; - while (++star_iter) { - OrbitalBody* star = star_iter.value(); - scene.AddGraphic(star->rep); - scene.AddLight(star->light_rep); - if (nebula && stars && stars->Nebula()) { - star->back_light->SetColor(star->back); - } - else { - Color c = Color(60,60,65); - star->back_light->SetColor(c); - } - scene.AddLight(star->back_light); - - if (nebula && stars && stars->Nebula()) { - scene.SetAmbient(ambient); - } - else { - Color c = ambient; - int n = (c.Red() + c.Green() + c.Blue()) / 3; - - c = Color(n,n,n); - scene.SetAmbient(c); - } - - ListIter planet = star->Satellites(); - while (++planet) { - scene.AddGraphic(planet->rep); - - ListIter moon = planet->Satellites(); - while (++moon) { - scene.AddGraphic(moon->rep); - } - } - } - - ExecFrame(); -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::Deactivate() -{ - if (!instantiated) - return; - - active_region = 0; - - if (point_stars && point_stars->GetScene()) - point_stars->GetScene()->DelBackground(point_stars); - - if (poly_stars && poly_stars->GetScene()) - poly_stars->GetScene()->DelBackground(poly_stars); - - if (nebula && nebula->GetScene()) - nebula->GetScene()->DelBackground(nebula); - - if (haze && haze->GetScene()) { - haze->GetScene()->DelBackground(haze); - haze->Hide(); - } - - ListIter star = bodies; - while (++star) { - if (star->rep && star->rep->GetScene()) - star->rep->GetScene()->DelGraphic(star->rep); - - if (star->light_rep && star->light_rep->GetScene()) - star->light_rep->GetScene()->DelLight(star->light_rep); - - if (star->back_light && star->back_light->GetScene()) - star->back_light->GetScene()->DelLight(star->back_light); - - ListIter planet = star->Satellites(); - while (++planet) { - if (planet->rep && planet->rep->GetScene()) - planet->rep->GetScene()->DelGraphic(planet->rep); - - ListIter moon = planet->Satellites(); - while (++moon) { - if (moon->rep && moon->rep->GetScene()) - moon->rep->GetScene()->DelGraphic(moon->rep); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -StarSystem::SetActiveRegion(OrbitalRegion* rgn) -{ - Scene* scene = 0; - - if (active_region != rgn) { - active_region = rgn; - - if (active_region) { - if (active_region->Type() != Orbital::TERRAIN) { - if (point_stars) point_stars->Hide(); - if (poly_stars) poly_stars->Show(); - if (nebula) nebula->Show(); - if (haze) haze->Hide(); - } - else { - if (point_stars) point_stars->Show(); - if (poly_stars) poly_stars->Hide(); - if (nebula) nebula->Hide(); - if (haze) haze->Show(); - } - - if (poly_stars) { - scene = poly_stars->GetScene(); - if (scene) - scene->SetAmbient(ambient); - } - else if (nebula) { - scene = nebula->GetScene(); - if (scene) - scene->SetAmbient(ambient); - } - - ListIter star = bodies; - while (++star) { - if (star->rep) - star->rep->Show(); - } - - ExecFrame(); - } - else { - if (point_stars) point_stars->Hide(); - if (poly_stars) poly_stars->Hide(); - if (nebula) nebula->Hide(); - if (haze) haze->Hide(); - - - ListIter star = bodies; - while (++star) { - if (star->rep) - star->rep->Hide(); - - if (star->light_rep) { - scene = star->light_rep->GetScene(); - if (scene) - scene->DelLight(star->light_rep); - } - - if (star->back_light) { - scene = star->back_light->GetScene(); - if (scene) - scene->DelLight(star->back_light); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -static BYTE max3(BYTE a, BYTE b, BYTE c) -{ - if (a > b) - if (a > c) return a; - else return c; - else - if (b > c) return b; - else return c; -} - -static BYTE min3(BYTE a, BYTE b, BYTE c) -{ - if (a < b) - if (a < c) return a; - else return c; - else - if (b < c) return b; - else return c; -} - -void -StarSystem::ExecFrame() -{ - CalcStardate(); - - ListIter star = bodies; - while (++star) - star->Update(); - - ListIter region = regions; - while (++region) - region->Update(); - - // update the graphic reps, relative to the active region: - if (instantiated && active_region) { - Point active_loc = active_region->Location(); - active_loc = active_loc.OtherHand(); - - Scene* scene = 0; - TerrainRegion* trgn = 0; - bool terrain = (active_region->Type() == Orbital::TERRAIN); - Matrix terrain_orientation; - Matrix terrain_transformation; - - if (terrain) { - trgn = (TerrainRegion*) active_region; - Color tmp = trgn->SkyColor(); - GameWinDX9::GetInstance()->SetScreenColor(tmp); - - tvpn = (active_region->Location() - active_region->Primary()->Location()); - tvpn.Normalize(); - tvup = Point(0,0,-1); - tvrt = tvpn.cross(tvup); - tvrt.Normalize(); - - terrain_orientation.Rotate(0, PI/2, 0); - terrain_transformation = Matrix(tvrt, tvup, tvpn); - - if (point_stars) { - point_stars->SetOrientation(terrain_transformation); - - Color sky_color = trgn->SkyColor(); - BYTE sky_red = (BYTE) sky_color.Red(); - BYTE sky_green = (BYTE) sky_color.Green(); - BYTE sky_blue = (BYTE) sky_color.Blue(); - - BYTE Max = max3(sky_red, sky_green, sky_blue); - BYTE Min = min3(sky_red, sky_green, sky_blue); - - BYTE lum = (BYTE) (240.0 * (Max + Min) / 510.0); - - if (lum > 50) { - point_stars->Hide(); - } - else { - Stars* pstars = (Stars*) point_stars; - - pstars->Illuminate(1.0 - lum / 50.0); - pstars->Show(); - } - - scene = point_stars->GetScene(); - } - - if (haze) { - ((TerrainHaze*)haze)->UseTerrainRegion(trgn); - scene = haze->GetScene(); - } - - if (scene) { - scene->SetAmbient(ambient); - } - - } - else { - GameWinDX9::GetInstance()->SetScreenColor(Color::Black); - } - - double star_alt = 0; - - ListIter star_iter = bodies; - while (++star_iter) { - OrbitalBody* star = star_iter.value(); - - if (active_region->Inclination() != 0) { - double distance = (active_region->Location() - star->Location()).length(); - star_alt = sin(active_region->Inclination()) * distance; - } - - if (terrain) { - Point sloc = TerrainTransform(star->Location()); - - if (star->rep) { - star->rep->MoveTo(sloc); - - PlanetRep* pr = (PlanetRep*) star->rep; - pr->SetDaytime(true); - } - - if (star->light_rep) { - star->light_rep->MoveTo(sloc); - star->light_rep->SetActive(sloc.y > -100); - } - - if (star->back_light) { - star->back_light->MoveTo(sloc * -1); - star->back_light->SetActive(sloc.y > -100); - } - - if (trgn && star->rep) { - if (trgn->IsEclipsed()) - star->rep->Hide(); - else - star->rep->Show(); - } - } - - else { - Point sloc = Point(star->Location() - active_region->Location()).OtherHand(); - sloc.y = star_alt; - - if (star->rep) { - star->rep->MoveTo(sloc); - - PlanetRep* pr = (PlanetRep*) star->rep; - pr->SetDaytime(false); - } - - if (star->light_rep) { - star->light_rep->MoveTo(sloc); - star->light_rep->SetActive(true); - } - - if (star->back_light) { - star->back_light->MoveTo(sloc * -1); - star->back_light->SetActive(true); - } - } - - ListIter planet_iter = star->Satellites(); - while (++planet_iter) { - OrbitalBody* planet = planet_iter.value(); - - if (planet->rep) { - PlanetRep* pr = (PlanetRep*) planet->rep; - - if (terrain) { - pr->MoveTo(TerrainTransform(planet->Location())); - pr->SetOrientation(terrain_orientation); - - if (planet == active_region->Primary()) { - pr->Hide(); - } - - else { - pr->Show(); - pr->SetDaytime(true); - } - } - else { - pr->Show(); - pr->TranslateBy(active_loc); - pr->SetDaytime(false); - } - } - - ListIter moon_iter = planet->Satellites(); - while (++moon_iter) { - OrbitalBody* moon = moon_iter.value(); - - if (moon->rep) { - PlanetRep* pr = (PlanetRep*) moon->rep; - - if (terrain) { - pr->MoveTo(TerrainTransform(moon->Location())); - pr->SetOrientation(terrain_orientation); - - if (moon == active_region->Primary()) { - pr->Hide(); - } - - else { - pr->Show(); - pr->SetDaytime(true); - } - } - else { - pr->Show(); - pr->TranslateBy(active_loc); - pr->SetDaytime(false); - } - } - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -Orbital* -StarSystem::FindOrbital(const char* name) -{ - if (!name || !name[0]) - return 0; - - ListIter star = bodies; - while (++star) { - if (!_stricmp(star->Name(), name)) - return star.value(); - - ListIter star_rgn = star->Regions(); - while (++star_rgn) { - if (!_stricmp(star_rgn->Name(), name)) - return star_rgn.value(); - } - - ListIter planet = star->Satellites(); - while (++planet) { - if (!_stricmp(planet->Name(), name)) - return planet.value(); - - ListIter planet_rgn = planet->Regions(); - while (++planet_rgn) { - if (!_stricmp(planet_rgn->Name(), name)) - return planet_rgn.value(); - } - - ListIter moon = planet->Satellites(); - while (++moon) { - if (!_stricmp(moon->Name(), name)) - return moon.value(); - - ListIter moon_rgn = moon->Regions(); - while (++moon_rgn) { - if (!_stricmp(moon_rgn->Name(), name)) - return moon_rgn.value(); - } - } - } - } - - ListIter region = regions; - while (++region) { - if (!_stricmp(region->Name(), name)) - return region.value(); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -OrbitalRegion* -StarSystem::FindRegion(const char* name) -{ - if (!name || !name[0]) - return 0; - - ListIter region = all_regions; - while (++region) { - if (!_stricmp(region->Name(), name)) - return region.value(); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -bool -StarSystem::HasLinkTo(StarSystem* s) const -{ - ListIter iter = ((StarSystem*) this)->all_regions; - while (++iter) { - OrbitalRegion* rgn = iter.value(); - - ListIter lnk_iter = rgn->Links(); - while (++lnk_iter) { - Text* t = lnk_iter.value(); - - if (s->FindRegion(*t)) - return true; - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -Point -StarSystem::TerrainTransform(const Point& loc) -{ - Point result; - - Point tmp = loc - active_region->Location(); - - result.x = tmp * tvrt; - result.z = tmp * tvup; - result.y = tmp * tvpn; - - return result; -} - -Color -StarSystem::Ambient() const -{ - Color result = ambient; - bool terrain = (active_region && active_region->Type() == Orbital::TERRAIN); - - if (terrain) { - TerrainRegion* trgn = (TerrainRegion*) active_region; - result = trgn->Ambient(); - - if (trgn->IsEclipsed()) - result = result * 0.3; - } - - return result; -} - -void -StarSystem::SetSunlight(Color color, double brightness) -{ - sun_color = color; - sun_scale = brightness; - - ListIter sun_iter = sun_lights; - while (++sun_iter) { - Light* sun_light = sun_iter.value(); - sun_light->SetColor(color); - sun_light->SetIntensity((float) (1.1 * sun_scale)); - } - - ListIter back_iter = back_lights; - while (++back_iter) { - Light* back_light = back_iter.value(); - back_light->SetIntensity((float) (0.5 * sun_scale)); - } -} - -void -StarSystem::SetBacklight(Color color, double brightness) -{ - ListIter back_iter = back_lights; - while (++back_iter) { - Light* back_light = back_iter.value(); - back_light->SetColor(color); - back_light->SetIntensity((float) (0.5 * brightness)); - } -} - -void -StarSystem::RestoreTrueSunColor() -{ - ListIter iter = bodies; - while (++iter) { - OrbitalBody* star = iter.value(); - - if (star) { - if (star->light_rep) { - star->light_rep->SetColor(star->LightColor()); - star->light_rep->SetIntensity(1.1f); - } - - if (star->back_light) { - star->back_light->SetColor(star->back); - star->back_light->SetIntensity(0.5f); - } - } - } -} - -// +====================================================================+ - -Color -Star::GetColor() const -{ - return GetColor(seq); -} - -int -Star::GetSize() const -{ - return GetSize(seq); -} - -Color -Star::GetColor(int s) -{ - switch (s) { - case O: return Color(128,128,255); break; - case B: return Color(192,192,255); break; - case A: return Color(220,220,255); break; - case F: return Color(255,255,255); break; - case G: return Color(255,255,128); break; - case K: return Color(255,192,100); break; - case M: return Color(255,100,100); break; - - case RED_GIANT: return Color(255, 80, 80); break; - case WHITE_DWARF: return Color(255,255,255); break; - case BLACK_HOLE: return Color( 0, 0, 0); break; - } - - return Color::White; -} - -int -Star::GetSize(int s) -{ - switch (s) { - case O: return 4; break; - case B: return 4; break; - case A: return 3; break; - case F: return 3; break; - case G: return 2; break; - case K: return 2; break; - case M: return 1; break; - - case RED_GIANT: return 4; break; - case WHITE_DWARF: return 1; break; - case BLACK_HOLE: return 3; break; - } - - return 3; -} - -// +====================================================================+ - -Orbital::Orbital(StarSystem* s, const char* n, OrbitalType t, double m, double r, double o, Orbital* p) -: name(n), type(t), subtype(0), radius(r), mass(m), orbit(o), -phase(0), period(0), rotation(0), retro(false), -system(s), primary(p), loc(0, 0, 0), rep(0), velocity(0) -{ - if (system && primary && orbit > 0) { - velocity = sqrt(GRAV * primary->Mass() / orbit); - period = 2 * PI * orbit / velocity; - } - - Update(); -} - -// +--------------------------------------------------------------------+ - -Orbital::~Orbital() -{ - delete rep; - regions.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -Orbital::Update() -{ - if (system && primary && orbit > 0) { - double grade = (retro) ? -1 : 1; - - // orbits are counter clockwise: - phase = -2 * PI * grade * StarSystem::Stardate() / period; - - loc = primary->Location() + Point((double) (orbit * cos(phase)), - (double) (orbit * sin(phase)), - 0); - } - - ListIter region = regions; - while (++region) - region->Update(); - - if (rep) - rep->MoveTo(loc.OtherHand()); -} - -// +--------------------------------------------------------------------+ - -Point -Orbital::PredictLocation(double delta_t) -{ - Point predicted_loc = Location(); - - if (system && primary && orbit > 0) { - predicted_loc = primary->PredictLocation(delta_t); - - double grade = (retro) ? -1 : 1; - - // orbits are(?) counter clockwise: - double predicted_phase = (double) (-2 * PI * grade * (StarSystem::Stardate()+delta_t) / period); - - predicted_loc += Point((double) (orbit * cos(predicted_phase)), - (double) (orbit * sin(predicted_phase)), - 0); - } - - return predicted_loc; -} - -void -Orbital::SetMapIcon(const Bitmap& img) -{ - if (img.Width() >=64 && img.Height() >= 64) { - map_icon.CopyBitmap(img); - map_icon.AutoMask(); - map_icon.MakeTexture(); - } -} - -// +====================================================================+ - -OrbitalBody::OrbitalBody(StarSystem* s, const char* n, OrbitalType t, double m, double r, double o, Orbital* p) -: Orbital(s, n, t, m, r, o, p), light(0), light_rep(0), back_light(0), -ring_min(0), ring_max(0), tilt(0), luminous(false) -{ - Update(); -} - -// +--------------------------------------------------------------------+ - -OrbitalBody::~OrbitalBody() -{ - satellites.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -OrbitalBody::Update() -{ - Orbital::Update(); - - theta = 0; - - if (rotation > 0) - theta = -2 * PI * StarSystem::Stardate() / rotation; - - ListIter body = satellites; - while (++body) - body->Update(); - - if (rep && theta != 0) { - Matrix m; - m.Pitch(tilt); - m.Roll(tilt/2); - m.Yaw(theta); - rep->SetOrientation(m); - } - - if (light_rep) { - Point bodyloc = loc; - bodyloc = bodyloc.OtherHand(); - light_rep->MoveTo(bodyloc); - } -} - -// +====================================================================+ - -OrbitalRegion::OrbitalRegion(StarSystem* s, const char* n, double m, double r, double o, Orbital* p) -: Orbital(s, n, REGION, m, r, o, p), grid(25.0e3f), inclination(0) -{ -} - -// +--------------------------------------------------------------------+ - -OrbitalRegion::~OrbitalRegion() -{ - links.destroy(); -} - diff --git a/Stars45/StarSystem.h b/Stars45/StarSystem.h deleted file mode 100644 index f5cd92c..0000000 --- a/Stars45/StarSystem.h +++ /dev/null @@ -1,321 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Various heavenly bodies -*/ - -#ifndef StarSystem_h -#define StarSystem_h - -#include "Types.h" -#include "Solid.h" -#include "Bitmap.h" -#include "Geometry.h" -#include "Text.h" -#include "Term.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class StarSystem; -class Orbital; -class OrbitalBody; -class OrbitalRegion; -class TerrainRegion; - -class Graphic; -class Light; -class Scene; - -// +--------------------------------------------------------------------+ - -class StarSystem -{ -public: - static const char* TYPENAME() { return "StarSystem"; } - - StarSystem(const char* name, Point loc, int iff=0, int s=4); - virtual ~StarSystem(); - - int operator == (const StarSystem& s) const { return name == s.name; } - - // operations: - virtual void Load(); - virtual void Create(); - virtual void Destroy(); - - virtual void Activate(Scene& scene); - virtual void Deactivate(); - - virtual void ExecFrame(); - - // accessors: - const char* Name() const { return name; } - const char* Govt() const { return govt; } - const char* Description() const { return description; } - int Affiliation() const { return affiliation; } - int Sequence() const { return seq; } - Point Location() const { return loc; } - int NumStars() const { return sky_stars; } - int NumDust() const { return sky_dust; } - Color Ambient() const; - - List& Bodies() { return bodies; } - List& Regions() { return regions; } - List& AllRegions() { return all_regions; } - OrbitalRegion* ActiveRegion() { return active_region; } - - Orbital* FindOrbital(const char* name); - OrbitalRegion* FindRegion(const char* name); - - void SetActiveRegion(OrbitalRegion* rgn); - - static void SetBaseTime(long double t, bool absolute=false); - static long double GetBaseTime(); - static long double Stardate() { return stardate; } - static void CalcStardate(); - double Radius() const { return radius; } - - void SetSunlight(Color color, double brightness=1); - void SetBacklight(Color color, double brightness=1); - void RestoreTrueSunColor(); - bool HasLinkTo(StarSystem* s) const; - const Text& GetDataPath() const { return datapath; } - -protected: - void ParseStar(TermStruct* val); - void ParsePlanet(TermStruct* val); - void ParseMoon(TermStruct* val); - void ParseRegion(TermStruct* val); - void ParseTerrain(TermStruct* val); - void ParseLayer(TerrainRegion* rgn, TermStruct* val); - - void CreateBody(OrbitalBody& body); - Point TerrainTransform(const Point& loc); - - char filename[64]; - Text name; - Text govt; - Text description; - Text datapath; - int affiliation; - int seq; - Point loc; - static long double stardate; - double radius; - bool instantiated; - - int sky_stars; - int sky_dust; - Text sky_poly_stars; - Text sky_nebula; - Text sky_haze; - double sky_uscale; - double sky_vscale; - Color ambient; - Color sun_color; - double sun_brightness; - double sun_scale; - List sun_lights; - List back_lights; - - Graphic* point_stars; - Solid* poly_stars; - Solid* nebula; - Solid* haze; - - List bodies; - List regions; - List all_regions; - - Orbital* center; - OrbitalRegion* active_region; - - Point tvpn, tvup, tvrt; -}; - -// +--------------------------------------------------------------------+ - -class Star -{ -public: - static const char* TYPENAME() { return "Star"; } - - Star(const char* n, const Point& l, int s) : name(n), loc(l), seq(s) { } - virtual ~Star() { } - - enum SPECTRAL_CLASS { BLACK_HOLE, WHITE_DWARF, RED_GIANT, - O, B, A, F, G, K, M }; - - int operator == (const Star& s) const { return name == s.name; } - - // accessors: - const char* Name() const { return name; } - const Point& Location() const { return loc; } - int Sequence() const { return seq; } - Color GetColor() const; - int GetSize() const; - - static Color GetColor(int spectral_class); - static int GetSize(int spectral_class); - -protected: - Text name; - Point loc; - int seq; -}; - -// +--------------------------------------------------------------------+ - -class Orbital -{ - friend class StarSystem; - -public: - static const char* TYPENAME() { return "Orbital"; } - - enum OrbitalType { NOTHING, STAR, PLANET, MOON, REGION, TERRAIN }; - - Orbital(StarSystem* sys, const char* n, OrbitalType t, double m, double r, double o, Orbital* p=0); - virtual ~Orbital(); - - int operator == (const Orbital& o) const { return type == o.type && name == o.name && system == o.system; } - int operator < (const Orbital& o) const { return loc.length() < o.loc.length(); } - int operator <= (const Orbital& o) const { return loc.length() <= o.loc.length(); } - - // operations: - virtual void Update(); - Point PredictLocation(double delta_t); - - // accessors: - const char* Name() const { return name; } - OrbitalType Type() const { return type; } - int SubType() const { return subtype; } - - const char* Description() const { return description; } - double Mass() const { return mass; } - double Radius() const { return radius; } - double Rotation() const { return rotation; } - double RotationPhase()const { return theta; } - double Orbit() const { return orbit; } - bool Retrograde() const { return retro; } - double Phase() const { return phase; } - double Period() const { return period; } - Point Location() const { return loc; } - Graphic* Rep() const { return rep; } - - const Bitmap& GetMapIcon() const { return map_icon; } - void SetMapIcon(const Bitmap& img); - - StarSystem* System() const { return system; } - Orbital* Primary() const { return primary; } - ListIter Regions() { return regions; } - -protected: - Text name; - OrbitalType type; - int subtype; - - Text description; - double mass; - double radius; - double rotation; - double theta; - double orbit; - double phase; - double period; - double velocity; - Point loc; - bool retro; - Graphic* rep; - Bitmap map_icon; - - StarSystem* system; - Orbital* primary; - - List regions; -}; - -// +--------------------------------------------------------------------+ - -class OrbitalBody : public Orbital -{ - friend class StarSystem; - -public: - static const char* TYPENAME() { return "OrbitalBody"; } - - OrbitalBody(StarSystem* sys, const char* n, OrbitalType t, double m, double r, double o, Orbital* prime=0); - virtual ~OrbitalBody(); - - // operations: - virtual void Update(); - - // accessors: - ListIter Satellites() { return satellites; } - - double Tilt() const { return tilt; } - double RingMin() const { return ring_min; } - double RingMax() const { return ring_max; } - - double LightIntensity() const { return light; } - Color LightColor() const { return color; } - bool Luminous() const { return luminous; } - -protected: - Text map_name; - Text tex_name; - Text tex_high_res; - Text tex_ring; - Text tex_glow; - Text tex_glow_high_res; - Text tex_gloss; - - double tscale; - double light; - double ring_min; - double ring_max; - double tilt; - Light* light_rep; - Light* back_light; - Color color; - Color back; - Color atmosphere; - bool luminous; - - List satellites; -}; - -// +--------------------------------------------------------------------+ - -class OrbitalRegion : public Orbital -{ - friend class StarSystem; - -public: - static const char* TYPENAME() { return "OrbitalRegion"; } - - OrbitalRegion(StarSystem* sys, const char* n, double m, double r, double o, Orbital* prime=0); - virtual ~OrbitalRegion(); - - double GridSpace() const { return grid; } - double Inclination() const { return inclination; } - int Asteroids() const { return asteroids; } - List& Links() { return links; } - -protected: - double grid; - double inclination; - int asteroids; - List links; -}; - -#endif // StarSystem_h - diff --git a/Stars45/Stars.ico b/Stars45/Stars.ico deleted file mode 100644 index 69980ca..0000000 Binary files a/Stars45/Stars.ico and /dev/null differ diff --git a/Stars45/Stars.rc.conf b/Stars45/Stars.rc.conf deleted file mode 100644 index 45479d3..0000000 --- a/Stars45/Stars.rc.conf +++ /dev/null @@ -1,39 +0,0 @@ -#include - -#include "resource.h" - -Stars ICON DISCARDABLE "Stars.ico" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION @RC_VERSION@ - PRODUCTVERSION @RC_VERSION@ - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "A military space combat simulator\0" - VALUE "CompanyName", "Starshatter: The Open Source Project Contributors\0" - VALUE "FileDescription", "Stars\0" - VALUE "FileVersion", "@VERSION@\0" - VALUE "InternalName", "Stars45\0" - VALUE "LegalCopyright", "Copyright (c) 2022, Starshatter: The Open Source Project Contributors\0" - VALUE "OriginalFilename", "Stars45.exe\0" - VALUE "ProductName", "Starshatter: The Open Source Project\0" - VALUE "ProductVersion", "@VERSION@\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/Stars45/Starshatter.cpp b/Stars45/Starshatter.cpp deleted file mode 100644 index 77aaca5..0000000 --- a/Stars45/Starshatter.cpp +++ /dev/null @@ -1,2838 +0,0 @@ -/* 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& 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 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& 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 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); - } - } - } -} diff --git a/Stars45/Starshatter.h b/Stars45/Starshatter.h deleted file mode 100644 index f18967d..0000000 --- a/Stars45/Starshatter.h +++ /dev/null @@ -1,219 +0,0 @@ -/* 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 - -*/ - -#ifndef Starshatter_h -#define Starshatter_h - -#include "Types.h" -#include "GameWinDX9.h" -#include "Bitmap.h" -#include "KeyMap.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Campaign; -class MenuScreen; -class CmpnScreen; -class PlanScreen; -class LoadScreen; -class GameScreen; -class Ship; -class Sim; -class FadeView; -class CameraDirector; -class MultiController; -class MouseController; -class MusicDirector; -class DataLoader; -class Font; -class TrackIR; -class Mission; - -class NetServer; -class NetLobby; - -// +--------------------------------------------------------------------+ - -class Starshatter : public GameWinDX9 -{ -public: - Starshatter(); - virtual ~Starshatter(); - - virtual bool Init(HINSTANCE hi, HINSTANCE hpi, LPSTR cmdline, int nCmdShow); - virtual bool InitGame(); - virtual bool ChangeVideo(); - virtual void GameState(); - virtual void Exit(); - virtual bool OnHelp(); - - enum MODE { 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 - }; - - enum LOBBY { NET_LOBBY_CLIENT, - NET_LOBBY_SERVER - }; - - int GetGameMode() { return game_mode; } - void SetGameMode(int mode); - void RequestChangeVideo(); - void LoadVideoConfig(const char* filename); - void SaveVideoConfig(const char* filename); - void SetupSplash(); - void SetupMenuScreen(); - void SetupCmpnScreen(); - void SetupPlanScreen(); - void SetupLoadScreen(); - void SetupGameScreen(); - void OpenTacticalReference(); - void CreateWorld(); - int KeyDown(int action) const; - - void PlayerCam(int mode); - void ViewSelection(); - - void MapKeys(); - static void MapKeys(KeyMap* mapping, int nkeys); - static void MapKey(int act, int key, int alt=0); - - void SetTestMode(int t) { test_mode = t; } - - static Starshatter* GetInstance() { return instance; } - - // graphic options: - int LensFlare() { return lens_flare; } - int Corona() { return corona; } - int Nebula() { return nebula; } - int Dust() { return dust; } - - KeyMap& GetKeyMap() { return keycfg; } - - int GetLoadProgress() { return load_progress; } - const char* GetLoadActivity() { return load_activity; } - - int GetChatMode() const { return chat_mode; } - void SetChatMode(int c); - const char* GetChatText() const { return chat_text.data(); } - - void StopNetGame(); - - int GetLobbyMode(); - void SetLobbyMode(int mode = NET_LOBBY_CLIENT); - void StartLobby(); - void StopLobby(); - - void ExecCutscene(const char* msn_file, const char* path); - void BeginCutscene(); - void EndCutscene(); - bool InCutscene() const { return cutscene > 0; } - Mission* GetCutsceneMission() const; - const char* GetSubtitles() const; - void EndMission(); - - void StartOrResumeGame(); - - static bool UseFileSystem(); - -protected: - virtual void DoMenuScreenFrame(); - virtual void DoCmpnScreenFrame(); - virtual void DoPlanScreenFrame(); - virtual void DoLoadScreenFrame(); - virtual void DoGameScreenFrame(); - virtual void DoMouseFrame(); - - virtual void DoChatMode(); - virtual void DoGameKeys(); - - virtual bool GameLoop(); - virtual void UpdateWorld(); - virtual void InstantiateMission(); - virtual bool ResizeVideo(); - virtual void InitMouse(); - - static Starshatter* instance; - Window* gamewin; - MenuScreen* menuscreen; - LoadScreen* loadscreen; - PlanScreen* planscreen; - GameScreen* gamescreen; - CmpnScreen* cmpnscreen; - - FadeView* splash; - int splash_index; - Bitmap splash_image; - MultiController* input; - MouseController* mouse_input; - TrackIR* head_tracker; - DataLoader* loader; - - Ship* player_ship; - CameraDirector* cam_dir; - MusicDirector* music_dir; - - Font* HUDfont; - Font* GUIfont; - Font* GUI_small_font; - Font* terminal; - Font* verdana; - Font* title_font; - Font* limerick18; - Font* limerick12; - Font* ocrb; - - DWORD time_mark; - DWORD minutes; - - double field_of_view; - double orig_fov; - - static int keymap[256]; - static int keyalt[256]; - KeyMap keycfg; - - bool tactical; - bool spinning; - int mouse_x; - int mouse_y; - int mouse_dx; - int mouse_dy; - - int game_mode; - int test_mode; - int req_change_video; - int video_changed; - - int lens_flare; - int corona; - int nebula; - int dust; - - double exit_time; - - int load_step; - int load_progress; - Text load_activity; - int catalog_index; - - int cutscene; - int lobby_mode; - NetLobby* net_lobby; - int chat_mode; - Text chat_text; -}; - -#endif // Starshatter_h diff --git a/Stars45/StarshipAI.cpp b/Stars45/StarshipAI.cpp deleted file mode 100644 index 69abdae..0000000 --- a/Stars45/StarshipAI.cpp +++ /dev/null @@ -1,821 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Starship (low-level) Artificial Intelligence class -*/ - -#include "StarshipAI.h" -#include "StarshipTacticalAI.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Element.h" -#include "Mission.h" -#include "Instruction.h" -#include "RadioMessage.h" -#include "Contact.h" -#include "WeaponGroup.h" -#include "Drive.h" -#include "Sim.h" -#include "StarSystem.h" -#include "FlightComp.h" -#include "Farcaster.h" -#include "QuantumDrive.h" - -#include "Clock.h" -#include "ContentBundle.h" -#include "Random.h" - -// +----------------------------------------------------------------------+ - -StarshipAI::StarshipAI(SimObject* s) -: ShipAI(s), sub_select_time(0), subtarget(0), tgt_point_defense(false) -{ - ai_type = STARSHIP; - - // signifies this ship is a dead hulk: - if (ship && ship->Design()->auto_roll < 0) { - Point torque(rand()-16000, rand()-16000, rand()-16000); - torque.Normalize(); - torque *= ship->Mass() / 10; - - ship->SetFLCSMode(0); - if (ship->GetFLCS()) - ship->GetFLCS()->PowerOff(); - - ship->ApplyTorque(torque); - ship->SetVelocity(RandomDirection() * Random(20, 50)); - - for (int i = 0; i < 64; i++) { - Weapon* w = ship->GetWeaponByIndex(i+1); - if (w) - w->DrainPower(0); - else - break; - } - } - - else { - tactical = new StarshipTacticalAI(this); - } - - sub_select_time = Clock::GetInstance()->GameTime() + (DWORD) Random(0, 2000); - point_defense_time = sub_select_time; -} - - -// +--------------------------------------------------------------------+ - -StarshipAI::~StarshipAI() -{ } - -// +--------------------------------------------------------------------+ - -void -StarshipAI::FindObjective() -{ - distance = 0; - - int order = ship->GetRadioOrders()->Action(); - - if (order == RadioMessage::QUANTUM_TO || - order == RadioMessage::FARCAST_TO) { - - FindObjectiveQuantum(); - objective = Transform(obj_w); - return; - } - - bool hold = order == RadioMessage::WEP_HOLD || - order == RadioMessage::FORM_UP; - - bool form = hold || - (!order && !target) || - (farcaster); - - // if not the element leader, stay in formation: - if (form && element_index > 1) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.formation")); - - if (navpt && navpt->Action() == Instruction::LAUNCH) { - FindObjectiveNavPoint(); - } - else { - navpt = 0; - FindObjectiveFormation(); - } - - // transform into camera coords: - objective = Transform(obj_w); - return; - } - - // under orders? - bool directed = false; - double threat_level = 0; - double support_level = 1; - Ship* ward = ship->GetWard(); - - if (tactical) { - directed = (tactical->RulesOfEngagement() == TacticalAI::DIRECTED); - threat_level = tactical->ThreatLevel(); - support_level = tactical->SupportLevel(); - } - - // threat processing: - if (hold || !directed && threat_level >= 2*support_level) { - - // seek support: - if (support) { - double d_support = Point(support->Location() - ship->Location()).length(); - if (d_support > 35e3) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.regroup")); - FindObjectiveTarget(support); - objective = Transform(obj_w); - return; - } - } - - // run away: - else if (threat && threat != target) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.retreat")); - obj_w = ship->Location() + Point(ship->Location() - threat->Location()) * 100; - objective = Transform(obj_w); - return; - } - } - - // weapons hold: - if (hold) { - if (navpt) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-navpt")); - FindObjectiveNavPoint(); - } - - else if (patrol) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.patrol")); - FindObjectivePatrol(); - } - - else { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.holding")); - objective = Point(); - } - } - - // normal processing: - else if (target) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-target")); - FindObjectiveTarget(target); - } - - else if (patrol) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.patrol")); - FindObjectivePatrol(); - } - - else if (ward) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-ward")); - FindObjectiveFormation(); - } - - else if (navpt) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-navpt")); - FindObjectiveNavPoint(); - } - - else if (rumor) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.search")); - FindObjectiveTarget(rumor); - } - - else { - objective = Point(); - } - - // transform into camera coords: - objective = Transform(obj_w); -} - -// +--------------------------------------------------------------------+ - -void -StarshipAI::Navigator() -{ - // signifies this ship is a dead hulk: - if (ship && ship->Design()->auto_roll < 0) { - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.dead")); - return; - } - - accumulator.Clear(); - magnitude = 0; - - hold = false; - if ((ship->GetElement() && ship->GetElement()->GetHoldTime() > 0) || - (navpt && navpt->Status() == Instruction::COMPLETE && navpt->HoldTime() > 0)) - hold = true; - - ship->SetFLCSMode(Ship::FLCS_HELM); - - if (!ship->GetDirectorInfo()) { - if (target) - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-target")); - else if (ship->GetWard()) - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.seek-ward")); - else - ship->SetDirectorInfo(ContentBundle::GetInstance()->GetText("ai.patrol")); - } - - if (farcaster && distance < 25e3) { - accumulator = SeekTarget(); - } - else { - accumulator = AvoidCollision(); - - if (!other && !hold) - accumulator = SeekTarget(); - } - - HelmControl(); - ThrottleControl(); - FireControl(); - AdjustDefenses(); -} - -// +--------------------------------------------------------------------+ - -void -StarshipAI::HelmControl() -{ - // signifies this ship is a dead hulk: - if (ship && ship->Design()->auto_roll < 0) { - return; - } - - double trans_x = 0; - double trans_y = 0; - double trans_z = 0; - - bool station_keeping = distance < 0; - - if (station_keeping) { - accumulator.brake = 1; - accumulator.stop = 1; - - ship->SetHelmPitch(0); - } - - else { - Element* elem = ship->GetElement(); - - Ship* ward = ship->GetWard(); - Ship* s_threat = 0; - if (threat && threat->Class() >= ship->Class()) - s_threat = threat; - - if (other || target || ward || s_threat || navpt || patrol || farcaster || element_index > 1) { - ship->SetHelmHeading(accumulator.yaw); - - if (elem->Type() == Mission::FLIGHT_OPS) { - ship->SetHelmPitch(0); - - if (ship->NumInbound() > 0) { - ship->SetHelmHeading(ship->CompassHeading()); - } - } - - else if (accumulator.pitch > 60*DEGREES) { - ship->SetHelmPitch(60*DEGREES); - } - - else if (accumulator.pitch < -60*DEGREES) { - ship->SetHelmPitch(-60*DEGREES); - } - - else { - ship->SetHelmPitch(accumulator.pitch); - } - - } - else { - ship->SetHelmPitch(0); - } - } - - ship->SetTransX(trans_x); - ship->SetTransY(trans_y); - ship->SetTransZ(trans_z); - - ship->ExecFLCSFrame(); -} - -void -StarshipAI::ThrottleControl() -{ - // signifies this ship is a dead hulk: - if (ship && ship->Design()->auto_roll < 0) { - return; - } - - // station keeping: - - if (distance < 0) { - old_throttle = 0; - throttle = 0; - - ship->SetThrottle(0); - - if (ship->GetFLCS()) - ship->GetFLCS()->FullStop(); - - return; - } - - // normal throttle processing: - - double ship_speed = ship->Velocity() * ship->Heading(); - double brakes = 0; - Ship* ward = ship->GetWard(); - Ship* s_threat = 0; - - if (threat && threat->Class() >= ship->Class()) - s_threat = threat; - - if (target || s_threat) { // target pursuit, or retreat - throttle = 100; - - if (target && distance < 50e3) { - double closing_speed = ship_speed; - - if (target) { - Point delta = target->Location() - ship->Location(); - delta.Normalize(); - - closing_speed = ship->Velocity() * delta; - } - - if (closing_speed > 300) { - throttle = 30; - brakes = 0.25; - } - } - - throttle *= (1 - accumulator.brake); - - if (throttle < 1 && ship->GetFLCS() != 0) - ship->GetFLCS()->FullStop(); - } - - else if (ward) { // escort, match speed of ward - double speed = ward->Velocity().length(); - throttle = old_throttle; - - if (speed == 0) { - double d = (ship->Location() - ward->Location()).length(); - - if (d > 30e3) - speed = (d - 30e3) / 100; - } - - if (speed > 0) { - if (ship_speed > speed) { - throttle = old_throttle - 1; - brakes = 0.2; - } - else if (ship_speed < speed - 10) { - throttle = old_throttle + 1; - } - } - else { - throttle = 0; - brakes = 0.5; - } - } - - else if (patrol || farcaster) { // seek patrol point - throttle = 100; - - if (distance < 10 * ship_speed) { - if (ship->Velocity().length() > 200) - throttle = 5; - else - throttle = 50; - } - } - - else if (navpt) { // lead only, get speed from navpt - double speed = navpt->Speed(); - throttle = old_throttle; - - if (hold) { - throttle = 0; - brakes = 1; - } - - else { - if (speed <= 0) - speed = 300; - - if (ship_speed > speed) { - if (throttle > 0 && old_throttle > 1) - throttle = old_throttle - 1; - - brakes = 0.25; - } - else if (ship_speed < speed - 10) { - throttle = old_throttle + 1; - } - } - } - - else if (element_index > 1) { // wingman - Ship* lead = ship->GetElement()->GetShip(1); - double lv = lead->Velocity().length(); - double sv = ship_speed; - double dv = lv-sv; - double dt = 0; - - if (dv > 0) dt = dv * 1e-2 * seconds; - else if (dv < 0) dt = dv * 1e-2 * seconds; - - throttle = old_throttle + dt; - } - - else { - throttle = 0; - } - - old_throttle = throttle; - ship->SetThrottle(throttle); - - if (ship_speed > 1 && brakes > 0) - ship->SetTransY(-brakes * ship->Design()->trans_y); - - else if (throttle > 10 && (ship->GetEMCON() < 2 || ship->GetFuelLevel() < 10)) - ship->SetTransY(ship->Design()->trans_y); -} - -// +--------------------------------------------------------------------+ - -Steer -StarshipAI::SeekTarget() -{ - if (navpt) { - SimRegion* self_rgn = ship->GetRegion(); - SimRegion* nav_rgn = navpt->Region(); - QuantumDrive* qdrive = ship->GetQuantumDrive(); - - if (self_rgn && !nav_rgn) { - nav_rgn = self_rgn; - navpt->SetRegion(nav_rgn); - } - - bool use_farcaster = self_rgn != nav_rgn && - (navpt->Farcast() || - !qdrive || - !qdrive->IsPowerOn() || - qdrive->Status() < System::DEGRADED - ); - - if (use_farcaster) { - if (!farcaster) { - ListIter s = self_rgn->Ships(); - while (++s && !farcaster) { - if (s->GetFarcaster()) { - const Ship* dest = s->GetFarcaster()->GetDest(); - if (dest && dest->GetRegion() == nav_rgn) { - farcaster = s->GetFarcaster(); - } - } - } - } - - if (farcaster) { - if (farcaster->GetShip()->GetRegion() != self_rgn) - farcaster = farcaster->GetDest()->GetFarcaster(); - - obj_w = farcaster->EndPoint(); - distance = Point(obj_w - ship->Location()).length(); - - if (distance < 1000) - farcaster = 0; - } - } - else if (self_rgn != nav_rgn) { - QuantumDrive* q = ship->GetQuantumDrive(); - - if (q) { - if (q->ActiveState() == QuantumDrive::ACTIVE_READY) { - q->SetDestination(navpt->Region(), navpt->Location()); - q->Engage(); - } - } - } - } - - return ShipAI::SeekTarget(); -} - -// +--------------------------------------------------------------------+ - -Steer -StarshipAI::AvoidCollision() -{ - if (!ship || ship->Velocity().length() < 25) - return Steer(); - - return ShipAI::AvoidCollision(); -} - -// +--------------------------------------------------------------------+ - -void -StarshipAI::FireControl() -{ - // identify unknown contacts: - if (identify) { - if (fabs(ship->GetHelmHeading() - ship->CompassHeading()) < 10*DEGREES) { - Contact* contact = ship->FindContact(target); - - if (contact && !contact->ActLock()) { - if (!ship->GetProbe()) { - ship->LaunchProbe(); - } - } - } - - return; - } - - // investigate last known location of enemy ship: - if (rumor && !target && ship->GetProbeLauncher() && !ship->GetProbe()) { - // is rumor in basket? - Point rmr = Transform(rumor->Location()); - rmr.Normalize(); - - double dx = fabs(rmr.x); - double dy = fabs(rmr.y); - - if (dx < 10*DEGREES && dy < 10*DEGREES && rmr.z > 0) { - ship->LaunchProbe(); - } - } - - // Corvettes and Frigates are anti-air platforms. They need to - // target missile threats even when the threat is aimed at another - // friendly ship. Forward facing weapons must be on auto fire, - // while lateral and aft facing weapons are set to point defense. - - if (ship->Class() == Ship::CORVETTE || ship->Class() == Ship::FRIGATE) { - ListIter iter = ship->Weapons(); - while (++iter) { - WeaponGroup* group = iter.value(); - - ListIter w_iter = group->GetWeapons(); - while (++w_iter) { - Weapon* weapon = w_iter.value(); - - double az = weapon->GetAzimuth(); - if (fabs(az) < 45*DEGREES) { - weapon->SetFiringOrders(Weapon::AUTO); - weapon->SetTarget(target, 0); - } - - else { - weapon->SetFiringOrders(Weapon::POINT_DEFENSE); - } - } - } - } - - // All other starships are free to engage ship targets. Weapon - // fire control is managed by the type of weapon. - - else { - System* subtgt = SelectSubtarget(); - - ListIter iter = ship->Weapons(); - while (++iter) { - WeaponGroup* weapon = iter.value(); - - if (weapon->GetDesign()->target_type & Ship::DROPSHIPS) { // anti-air weapon? - weapon->SetFiringOrders(Weapon::POINT_DEFENSE); - } - else if (weapon->IsDrone()) { // torpedoes - weapon->SetFiringOrders(Weapon::MANUAL); - weapon->SetTarget(target, 0); - - if (target && target->GetRegion() == ship->GetRegion()) { - Point delta = target->Location() - ship->Location(); - double range = delta.length(); - - if (range < weapon->GetDesign()->max_range * 0.9 && - !AssessTargetPointDefense()) - weapon->SetFiringOrders(Weapon::AUTO); - - else if (range < weapon->GetDesign()->max_range * 0.5) - weapon->SetFiringOrders(Weapon::AUTO); - } - } - else { // anti-ship weapon - weapon->SetFiringOrders(Weapon::AUTO); - weapon->SetTarget(target, subtgt); - weapon->SetSweep(subtgt ? Weapon::SWEEP_NONE : Weapon::SWEEP_TIGHT); - } - } - } -} - -// +--------------------------------------------------------------------+ - -System* -StarshipAI::SelectSubtarget() -{ - if (Clock::GetInstance()->GameTime() - sub_select_time < 2345) - return subtarget; - - subtarget = 0; - - if (!target || target->Type() != SimObject::SIM_SHIP || GetAILevel() < 1) - return subtarget; - - Ship* tgt_ship = (Ship*) target; - - if (!tgt_ship->IsStarship()) - return subtarget; - - Weapon* subtgt = 0; - double dist = 50e3; - Point svec = ship->Location() - tgt_ship->Location(); - - sub_select_time = Clock::GetInstance()->GameTime(); - - // first pass: turrets - ListIter g_iter = tgt_ship->Weapons(); - while (++g_iter) { - WeaponGroup* g = g_iter.value(); - - if (g->GetDesign() && g->GetDesign()->turret_model) { - ListIter w_iter = g->GetWeapons(); - while (++w_iter) { - Weapon* w = w_iter.value(); - - if (w->Availability() < 35) - continue; - - if (w->GetAimVector() * svec < 0) - continue; - - if (w->GetTurret()) { - Point tloc = w->GetTurret()->Location(); - Point delta = tloc - ship->Location(); - double dlen = delta.length(); - - if (dlen < dist) { - subtgt = w; - dist = dlen; - } - } - } - } - } - - // second pass: major weapons - if (!subtgt) { - g_iter.reset(); - while (++g_iter) { - WeaponGroup* g = g_iter.value(); - - if (g->GetDesign() && !g->GetDesign()->turret_model) { - ListIter w_iter = g->GetWeapons(); - while (++w_iter) { - Weapon* w = w_iter.value(); - - if (w->Availability() < 35) - continue; - - if (w->GetAimVector() * svec < 0) - continue; - - Point tloc = w->MountLocation(); - Point delta = tloc - ship->Location(); - double dlen = delta.length(); - - if (dlen < dist) { - subtgt = w; - dist = dlen; - } - } - } - } - } - - subtarget = subtgt; - return subtarget; -} - -// +--------------------------------------------------------------------+ - -bool -StarshipAI::AssessTargetPointDefense() -{ - if (Clock::GetInstance()->GameTime() - point_defense_time < 3500) - return tgt_point_defense; - - tgt_point_defense = false; - - if (!target || target->Type() != SimObject::SIM_SHIP || GetAILevel() < 2) - return tgt_point_defense; - - Ship* tgt_ship = (Ship*) target; - - if (!tgt_ship->IsStarship()) - return tgt_point_defense; - - Weapon* subtgt = 0; - Point svec = ship->Location() - tgt_ship->Location(); - - point_defense_time = Clock::GetInstance()->GameTime(); - - // first pass: turrets - ListIter g_iter = tgt_ship->Weapons(); - while (++g_iter && !tgt_point_defense) { - WeaponGroup* g = g_iter.value(); - - if (g->CanTarget(1)) { - ListIter w_iter = g->GetWeapons(); - while (++w_iter && !tgt_point_defense) { - Weapon* w = w_iter.value(); - - if (w->Availability() > 35 && w->GetAimVector() * svec > 0) - tgt_point_defense = true; - } - } - } - - return tgt_point_defense; -} - - -// +--------------------------------------------------------------------+ - -Point -StarshipAI::Transform(const Point& point) -{ - return point - self->Location(); -} - -Steer -StarshipAI::Seek(const Point& point) -{ - // the point is in relative world coordinates - // x: distance east(-) / west(+) - // y: altitude down(-) / up(+) - // z: distance north(-) / south(+) - - Steer result; - - result.yaw = atan2(point.x, point.z) + PI; - - double adjacent = sqrt(point.x*point.x + point.z*point.z); - if (fabs(point.y) > ship->Radius() && adjacent > ship->Radius()) - result.pitch = atan(point.y / adjacent); - - if (!_finite(result.yaw)) - result.yaw = 0; - - if (!_finite(result.pitch)) - result.pitch = 0; - - return result; -} - -Steer -StarshipAI::Flee(const Point& point) -{ - Steer result = Seek(point); - result.yaw += PI; - return result; -} - -Steer -StarshipAI::Avoid(const Point& point, float radius) -{ - Steer result = Seek(point); - - if (point * ship->BeamLine() > 0) - result.yaw -= PI/2; - else - result.yaw += PI/2; - - return result; -} - - diff --git a/Stars45/StarshipAI.h b/Stars45/StarshipAI.h deleted file mode 100644 index 59a27a9..0000000 --- a/Stars45/StarshipAI.h +++ /dev/null @@ -1,61 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Starship (low-level) Artifical Intelligence class -*/ - -#ifndef StarshipAI_h -#define StarshipAI_h - -#include "Types.h" -#include "ShipAI.h" - -// +--------------------------------------------------------------------+ - -class StarshipAI : public ShipAI -{ -public: - StarshipAI(SimObject* s); - virtual ~StarshipAI(); - - // convert the goal point from world to local coords: - virtual void FindObjective(); - -protected: - // accumulate behaviors: - virtual void Navigator(); - virtual Steer SeekTarget(); - virtual Steer AvoidCollision(); - - // steering functions: - virtual Steer Seek(const Point& point); - virtual Steer Flee(const Point& point); - virtual Steer Avoid(const Point& point, float radius); - - virtual Point Transform(const Point& pt); - - // fire on target if appropriate: - virtual void FireControl(); - virtual void HelmControl(); - virtual void ThrottleControl(); - - System* SelectSubtarget(); - bool AssessTargetPointDefense(); - - DWORD sub_select_time; - DWORD point_defense_time; - System* subtarget; - bool tgt_point_defense; -}; - -// +--------------------------------------------------------------------+ - -#endif // StarshipAI_h - diff --git a/Stars45/StarshipTacticalAI.cpp b/Stars45/StarshipTacticalAI.cpp deleted file mode 100644 index 4e20c1b..0000000 --- a/Stars45/StarshipTacticalAI.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Starship-specific mid-level (tactical) AI -*/ - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include - -#include "StarshipTacticalAI.h" -#include "ShipAI.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Shot.h" -#include "Element.h" -#include "Instruction.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "Contact.h" -#include "WeaponGroup.h" -#include "Drive.h" -#include "QuantumDrive.h" -#include "Sim.h" -#include "StarSystem.h" -#include "Starshatter.h" -#include "Random.h" - -#include "Clock.h" - -const double STARSHIP_TACTICAL_DROP_TIME = 15; - -// +----------------------------------------------------------------------+ - -StarshipTacticalAI::StarshipTacticalAI(ShipAI* ai) -: TacticalAI(ai), drop_time(1.0e9), bugout(false), ai_level(0), initial_integrity(0) -{ - if (ai && ai->GetShip()) { - ai_level = ai->GetAILevel(); - initial_integrity = ai->GetShip()->Integrity(); - } - - switch (ai_level) { - default: - case 2: THREAT_REACTION_TIME = 500; break; - case 1: THREAT_REACTION_TIME = 1000; break; - case 0: THREAT_REACTION_TIME = 2500; - drop_time = STARSHIP_TACTICAL_DROP_TIME + - Random(0, STARSHIP_TACTICAL_DROP_TIME); - break; - } -} - - -// +--------------------------------------------------------------------+ - -StarshipTacticalAI::~StarshipTacticalAI() -{ } - -// +--------------------------------------------------------------------+ - -void -StarshipTacticalAI::ExecFrame(double seconds) -{ - TacticalAI::ExecFrame(seconds); - - drop_time -= seconds; - - if (drop_time <= 0) { - drop_time = STARSHIP_TACTICAL_DROP_TIME; - - ship_ai->DropTarget(STARSHIP_TACTICAL_DROP_TIME/4); - } -} - -// +--------------------------------------------------------------------+ - -void -StarshipTacticalAI::FindThreat() -{ - // pick the closest contact on Threat Warning System: - Ship* threat_ship = 0; - Shot* threat_missile = 0; - Ship* rumor = 0; - double threat_dist = 1e9; - double CELL_SIZE = 20e3; - - threat_level = 0; - support_level = ship->AIValue() / CELL_SIZE; - - ListIter iter = ship->ContactList(); - - while (++iter) { - Contact* contact = iter.value(); - Ship* c_ship = contact->GetShip(); - Shot* c_shot = contact->GetShot(); - - if (!c_ship && !c_shot) - continue; - - if (c_ship && c_ship != ship) { - double basis = std::max(contact->Range(ship), CELL_SIZE); - double ai_value = c_ship->AIValue() / basis; - - if (c_ship->GetIFF() == ship->GetIFF()) { - support_level += ai_value; - } - else if (ship->GetIFF() > 0 && c_ship->GetIFF() > 0) { - threat_level += ai_value; - } - else if (c_ship->GetIFF() > 1) { // neutrals should not be afraid of alliance - threat_level += ai_value; - } - } - - if (contact->Threat(ship) && - (Clock::GetInstance()->GameTime() - contact->AcquisitionTime()) > THREAT_REACTION_TIME) { - - if (c_shot) { - threat_missile = c_shot; - rumor = (Ship* ) threat_missile->Owner(); - } - else { - double rng = contact->Range(ship); - - if (c_ship && - c_ship->Class() != Ship::FREIGHTER && - c_ship->Class() != Ship::FARCASTER) { - - - if (c_ship->GetTarget() == ship) { - if (!threat_ship || c_ship->Class() > threat_ship->Class()) { - threat_ship = c_ship; - threat_dist = 0; - } - } - else if (rng < threat_dist) { - threat_ship = c_ship; - threat_dist = rng; - } - - CheckBugOut(c_ship, rng); - } - } - } - } - - if (rumor) { - iter.reset(); - - while (++iter) { - if (iter->GetShip() == rumor) { - rumor = 0; - ship_ai->ClearRumor(); - break; - } - } - } - - ship_ai->SetRumor(rumor); - ship_ai->SetThreat(threat_ship); - ship_ai->SetThreatMissile(threat_missile); -} - -// +--------------------------------------------------------------------+ - -void -StarshipTacticalAI::FindSupport() -{ - if (threat_level < 0.01) { - ship_ai->SetSupport(0); - return; - } - - // pick the biggest friendly contact in the sector: - Ship* support = 0; - double support_dist = 1e9; - - ListIter c_iter = ship->ContactList(); - - while (++c_iter) { - Contact* contact = c_iter.value(); - if (contact->GetShip() && contact->GetIFF(ship) == ship->GetIFF()) { - Ship* c_ship = contact->GetShip(); - - if (c_ship != ship && c_ship->Class() >= ship->Class()) { - if (!support || c_ship->Class() > support->Class()) - support = c_ship; - } - } - } - - ship_ai->SetSupport(support); -} - -void -StarshipTacticalAI::CheckBugOut(Ship* c_ship, double rng) -{ - // see if carrier should bug out... - if (!ship || !c_ship || ship->Class() != Ship::CARRIER && ship->Class() != Ship::SWACS) - return; - - if (bugout) - return; - - if (ship->GetElement() && ship->GetElement()->GetZoneLock()) - return; - - if (c_ship->Class() < Ship::DESTROYER || c_ship->Class() > Ship::STATION) - return; - - Starshatter* stars = Starshatter::GetInstance(); - if (stars && stars->InCutscene()) - return; - - double sustained_damage = initial_integrity - ship->Integrity(); - double allowable_damage = ship->Design()->integrity * 0.25; - - if (rng > 50e3 && sustained_damage < allowable_damage) - return; - - // still here? we must need to bug out! - - Sim* sim = Sim::GetSim(); - SimRegion* dst = 0; - - List& regions = sim->GetRegions(); - - if (regions.size() > 1) { - int tries = 10; - while (!dst && tries--) { - int n = RandomIndex() % regions.size(); - dst = regions[n]; - - if (dst == ship->GetRegion() || dst->IsAirSpace()) - dst = 0; - } - } - - if (dst) { - // bug out! - QuantumDrive* quantum = ship->GetQuantumDrive(); - if (quantum) { - quantum->SetDestination(dst, Point(0,0,0)); - quantum->Engage(); - } - - // ask highest ranking escort to go with you: - Element* escort = 0; - - ListIter iter = sim->GetElements(); - while (++iter) { - Element* elem = iter.value(); - - if (!escort || elem->GetShipClass() > escort->GetShipClass()) { - if (ship->GetElement()->CanCommand(elem)) - escort = elem; - } - } - - if (escort) { - RadioMessage* msg = new RadioMessage(escort, ship, RadioMessage::QUANTUM_TO); - if (msg) { - msg->SetInfo(dst->Name()); - RadioTraffic::Transmit(msg); - } - } - - bugout = true; - } -} diff --git a/Stars45/StarshipTacticalAI.h b/Stars45/StarshipTacticalAI.h deleted file mode 100644 index d58b639..0000000 --- a/Stars45/StarshipTacticalAI.h +++ /dev/null @@ -1,46 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Starship-specific mid-level (tactical) AI -*/ - -#ifndef StarshipTacticalAI_h -#define StarshipTacticalAI_h - -#include "Types.h" -#include "TacticalAI.h" - -// +--------------------------------------------------------------------+ - -class StarshipTacticalAI : public TacticalAI -{ -public: - StarshipTacticalAI(ShipAI* ai); - virtual ~StarshipTacticalAI(); - - virtual void ExecFrame(double seconds); - -protected: - virtual void FindThreat(); - virtual void FindSupport(); - - virtual void CheckBugOut(Ship* c_ship, double range); - - DWORD THREAT_REACTION_TIME; - int ai_level; - double drop_time; - double initial_integrity; - bool bugout; -}; - -// +--------------------------------------------------------------------+ - -#endif // StarshipTacticalAI_h - diff --git a/Stars45/SteerAI.cpp b/Stars45/SteerAI.cpp deleted file mode 100644 index 6bc758a..0000000 --- a/Stars45/SteerAI.cpp +++ /dev/null @@ -1,451 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Steering (low-level) Artificial Intelligence class -*/ - -#include "SteerAI.h" -#include "SeekerAI.h" -#include "FighterAI.h" -#include "StarshipAI.h" -#include "GroundAI.h" -#include "System.h" - -#include "Clock.h" -#include "Physical.h" - -// +----------------------------------------------------------------------+ - -Steer Steer::operator+(const Steer& s) const -{ - return Steer(yaw+s.yaw, pitch+s.pitch, roll+s.roll, (brake>s.brake)?brake:s.brake); -} - -Steer Steer::operator-(const Steer& s) const -{ - return Steer(yaw-s.yaw, pitch-s.pitch, roll-s.roll, (brake brake) - brake = s.brake; - - if (s.stop) - stop = 1; - - return *this; -} - -Steer& Steer::operator-=(const Steer& s) -{ - yaw -= s.yaw; - pitch -= s.pitch; - roll -= s.roll; - - if (s.brake < brake) - brake = s.brake; - - if (s.stop) - stop = 1; - - return *this; -} - - -double -Steer::Magnitude() const -{ - return sqrt(yaw*yaw + pitch*pitch); -} - -// +--------------------------------------------------------------------+ - -Director* -SteerAI::Create(SimObject* self, int type) -{ - switch (type) { - case SEEKER: return new SeekerAI(self); - break; - - case STARSHIP: return new StarshipAI(self); - break; - - case GROUND: return new GroundAI(self); - break; - - default: - case FIGHTER: return new FighterAI(self); - break; - } -} - -// +----------------------------------------------------------------------+ - -SteerAI::SteerAI(SimObject* ship) -: self(ship), -target(0), subtarget(0), other(0), distance(0.0), evade_time(0), -objective(0.0f, 0.0f, 0.0f) -{ - seek_gain = 20; - seek_damp = 0.5; - - for (int i = 0; i < 3; i++) - az[i] = el[i] = 0; -} - - -// +--------------------------------------------------------------------+ - -SteerAI::~SteerAI() -{ } - -// +--------------------------------------------------------------------+ - -void -SteerAI::SetTarget(SimObject* targ, System* sub) -{ - if (target != targ) { - target = targ; - - if (target) - Observe(target); - } - - subtarget = sub; -} - -void -SteerAI::DropTarget(double dtime) -{ - SetTarget(0); -} - -// +--------------------------------------------------------------------+ - -bool -SteerAI::Update(SimObject* obj) -{ - if (obj == target) { - target = 0; - subtarget = 0; - } - - if (obj == other) { - other = 0; - } - - return SimObserver::Update(obj); -} - -const char* -SteerAI::GetObserverName() const -{ - static char name[64]; - sprintf_s(name, "SteerAI(%s)", self->Name()); - return name; -} - -// +--------------------------------------------------------------------+ - -Point -SteerAI::ClosingVelocity() -{ - if (self) { - if (target) - return self->Velocity() - target->Velocity(); - else - return self->Velocity(); - } - - return Point(1, 0, 0); -} - -void -SteerAI::FindObjective() -{ - if (!self || !target) return; - - Point cv = ClosingVelocity(); - double cvl = cv.length(); - double time = 0; - - if (cvl > 5) { - // distance from self to target: - distance = Point(target->Location() - self->Location()).length(); - - // time to reach target: - time = distance / cvl; - - // where the target will be when we reach it: - Point run_vec = target->Velocity(); - obj_w = target->Location() + (run_vec * time); - } - - else { - obj_w = target->Location(); - } - - // subsystem offset: - if (subtarget) { - Point offset = target->Location() - subtarget->MountLocation(); - obj_w -= offset; - } - - distance = Point(obj_w - self->Location()).length(); - - if (cvl > 5) - time = distance / cvl; - - // where we will be when the target gets there: - Point self_dest = self->Location() + cv * time; - Point err = obj_w - self_dest; - - obj_w += err; - - // transform into camera coords: - objective = Transform(obj_w); - objective.Normalize(); - - distance = Point(obj_w - self->Location()).length(); -} - -Point -SteerAI::Transform(const Point& pt) -{ - Point obj_t = pt - self->Location(); - Point result; - - if (self->FlightPathYawAngle() != 0 || self->FlightPathPitchAngle() != 0) { - double az = self->FlightPathYawAngle(); - double el = self->FlightPathPitchAngle(); - - const double MAX_ANGLE = 15*DEGREES; - const double MIN_ANGLE = 3*DEGREES; - - if (az > MAX_ANGLE) - az = MAX_ANGLE; - else if (az < -MAX_ANGLE) - az = -MAX_ANGLE; - else if (az > MIN_ANGLE) - az = MIN_ANGLE + (az-MIN_ANGLE)/2; - else if (az < -MIN_ANGLE) - az = -MIN_ANGLE + (az+MIN_ANGLE)/2; - - if (el > MAX_ANGLE) - el = MAX_ANGLE; - else if (el < -MAX_ANGLE) - el = -MAX_ANGLE; - else if (el > MIN_ANGLE) - el = MIN_ANGLE + (el-MIN_ANGLE)/2; - else if (el < -MIN_ANGLE) - el = -MIN_ANGLE + (el+MIN_ANGLE)/2; - - Camera cam; - cam.Clone(self->Cam()); - cam.Yaw(az); - cam.Pitch(-el); - - result = Point(obj_t * cam.vrt(), - obj_t * cam.vup(), - obj_t * cam.vpn()); - } - else { - Camera& cam = (Camera&) self->Cam(); // cast away const - - result = Point(obj_t * cam.vrt(), - obj_t * cam.vup(), - obj_t * cam.vpn()); - } - - return result; -} - -Point -SteerAI::AimTransform(const Point& pt) -{ - Camera& cam = (Camera&) self->Cam(); // cast away const - Point obj_t = pt - self->Location(); - - Point result = Point(obj_t * cam.vrt(), - obj_t * cam.vup(), - obj_t * cam.vpn()); - - return result; -} - -// +--------------------------------------------------------------------+ - -void -SteerAI::Navigator() -{ - accumulator.Clear(); - magnitude = 0; -} - -int -SteerAI::Accumulate(const Steer& steer) -{ - int overflow = 0; - - double mag = steer.Magnitude(); - - if (magnitude + mag > 1) { - overflow = 1; - double scale = (1 - magnitude) / mag; - - accumulator += steer * scale; - magnitude = 1; - - if (seeking) { - az[0] *= scale; - el[0] *= scale; - seeking = 0; - } - } - else { - accumulator += steer; - magnitude += mag; - } - - return overflow; -} - -// +--------------------------------------------------------------------+ - -Steer -SteerAI::Seek(const Point& point) -{ - Steer s; - - // advance memory pipeline: - az[2] = az[1]; az[1] = az[0]; - el[2] = el[1]; el[1] = el[0]; - - // approach - if (point.z > 0.0f) { - az[0] = atan2(fabs(point.x), point.z) * seek_gain; - el[0] = atan2(fabs(point.y), point.z) * seek_gain; - - if (point.x < 0) az[0] = -az[0]; - if (point.y > 0) el[0] = -el[0]; - - s.yaw = az[0] - seek_damp * (az[1] + az[2] * 0.5); - s.pitch = el[0] - seek_damp * (el[1] + el[2] * 0.5); - } - - // reverse - else { - if (point.x > 0) s.yaw = 1.0f; - else s.yaw = -1.0f; - - s.pitch = -point.y * 0.5f; - } - - seeking = 1; - - return s; -} - -// +--------------------------------------------------------------------+ - -Steer -SteerAI::Flee(const Point& pt) -{ - Steer s; - - Point point = pt; - point.Normalize(); - - // approach - if (point.z > 0.0f) { - if (point.x > 0) s.yaw = -1.0f; - else s.yaw = 1.0f; - } - - // flee - else { - s.yaw = -point.x; - s.pitch = point.y; - } - - return s; -} - -// +--------------------------------------------------------------------+ - -Steer -SteerAI::Avoid(const Point& point, float radius) -{ - Steer s; - - if (point.z > 0) { - double ax = radius - fabs(point.x); - double ay = radius - fabs(point.y); - - // go around? - if (ax < ay) { - s.yaw = atan2(ax, point.z) * seek_gain; - if (point.x > 0) s.yaw = -s.yaw; - } - - // go over/under: - else { - s.pitch = atan2(ay, point.z) * seek_gain; - if (point.y < 0) s.pitch = -s.pitch; - } - } - - return s; -} - -// +--------------------------------------------------------------------+ - -Steer -SteerAI::Evade(const Point& point, const Point& vel) -{ - Steer evade; - - if (Clock::GetInstance()->GameTime() - evade_time > 1250) { - evade_time = Clock::GetInstance()->GameTime(); - - int direction = (rand()>>9) & 0x07; - - switch (direction) { - default: - case 0: evade.yaw = 0; evade.pitch = -0.5; break; - case 1: evade.yaw = 0; evade.pitch = -1.0; break; - case 2: evade.yaw = 1; evade.pitch = -0.3; break; - case 3: evade.yaw = 1; evade.pitch = -0.6; break; - case 4: evade.yaw = 1; evade.pitch = -1.0; break; - case 5: evade.yaw = -1; evade.pitch = -0.3; break; - case 6: evade.yaw = -1; evade.pitch = -0.6; break; - case 7: evade.yaw = -1; evade.pitch = -1.0; break; - } - } - - return evade; -} - diff --git a/Stars45/SteerAI.h b/Stars45/SteerAI.h deleted file mode 100644 index 3227db4..0000000 --- a/Stars45/SteerAI.h +++ /dev/null @@ -1,124 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Steering (low-level) Artifical Intelligence class -*/ - -#ifndef SteerAI_h -#define SteerAI_h - -#include "Types.h" -#include "SimObject.h" -#include "Director.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class System; - -// +--------------------------------------------------------------------+ - -struct Steer -{ - Steer() : yaw(0), pitch(0), roll(0), brake(0), stop(0) { } - Steer(double y, double p, double r, double b=0) : yaw(y), pitch(p), roll(r), brake(b), stop(0) { } - Steer(const Steer& s) : yaw(s.yaw), pitch(s.pitch), roll(s.roll), brake(s.brake), stop(s.stop) { } - - Steer& operator = (const Steer& s) { yaw=s.yaw; pitch=s.pitch; roll=s.roll; brake = s.brake; stop = s.stop; return *this; } - - Steer operator+(const Steer& s) const; - Steer operator-(const Steer& s) const; - Steer operator*(double f) const; - Steer operator/(double f) const; - - Steer& operator+=(const Steer& s); - Steer& operator-=(const Steer& s); - - double Magnitude() const; - - void Clear() { yaw=0; pitch=0; roll=0; brake=0; stop=0; } - - double yaw, pitch, roll; - double brake; - int stop; -}; - -// +--------------------------------------------------------------------+ - -class SteerAI : public Director, public SimObserver -{ -public: - enum Type { SEEKER = 1000, FIGHTER, STARSHIP, GROUND }; - - SteerAI(SimObject* self); - virtual ~SteerAI(); - - static Director* Create(SimObject*, int type); - - virtual void SetTarget(SimObject* targ, System* sub=0); - virtual SimObject* GetTarget() const { return target; } - virtual System* GetSubTarget() const { return subtarget; } - virtual void DropTarget(double drop_time=1.5); - virtual int Type() const { return ai_type; } - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - // debug: - virtual Point GetObjective() const { return obj_w; } - virtual SimObject* GetOther() const { return other; } - -protected: - - // accumulate behaviors: - virtual void Navigator(); - virtual int Accumulate(const Steer& steer); - - // steering functions: - virtual Steer Seek(const Point& point); - virtual Steer Flee(const Point& point); - virtual Steer Avoid(const Point& point, float radius); - virtual Steer Evade(const Point& point, const Point& vel); - - // compute the goal point based on target stats: - virtual void FindObjective(); - virtual Point ClosingVelocity(); - - virtual Point Transform(const Point& pt); - virtual Point AimTransform(const Point& pt); - - int seeking; - - SimObject* self; - SimObject* target; - System* subtarget; - SimObject* other; - - Point obj_w; - Point objective; - - double distance; - double az[3], el[3]; - - Steer accumulator; - double magnitude; - DWORD evade_time; - - double seek_gain; - double seek_damp; - - int ai_type; -}; - - -// +--------------------------------------------------------------------+ - -#endif // SteerAI_h - diff --git a/Stars45/System.cpp b/Stars45/System.cpp deleted file mode 100644 index 111addc..0000000 --- a/Stars45/System.cpp +++ /dev/null @@ -1,397 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Generic Ship Subsystem class -*/ - -#include "System.h" -#include "SystemDesign.h" -#include "Component.h" -#include "NetUtil.h" - -#include "Game.h" - -// +----------------------------------------------------------------------+ - -System::System(System::CATEGORY t, int s, const char* n, int maxv, -double e, double c, double r) -: type(t), id(0), ship(0), subtype(s), status(NOMINAL), availability(1.0f), -safety(1.0f), stability(1.0f), crit_level(0.5f), net_avail(-1.0f), -mount_rel(0.0f, 0.0f, 0.0f), radius(0.0f), safety_overload(0.0f), -hull_factor(0.5f), energy((float) e), capacity((float) c), sink_rate((float) r), -power_level(1.0f), power_flags(0), source_index(0), power_on(true), -explosion_type(0), name(n), abrv(name), design(0), emcon(3) -{ - if (maxv < 100) - max_value = maxv; - else - max_value = (int) (maxv/100.0); - - emcon_power[0] = 100; - emcon_power[1] = 100; - emcon_power[2] = 100; -} - -// +----------------------------------------------------------------------+ - -System::System(const System& s) -: type(s.type), id(s.id), ship(0), subtype(s.subtype), status(s.status), -availability(s.availability), safety(s.safety), stability(s.stability), -crit_level(s.crit_level), net_avail(-1.0f), -mount_rel(s.mount_rel), radius(s.radius), safety_overload(0.0f), -hull_factor(s.hull_factor), energy(s.energy), capacity(s.capacity), -sink_rate(s.sink_rate), power_level(s.power_level), power_flags(s.power_flags), -source_index(s.source_index), power_on(s.power_on), max_value(s.max_value), -explosion_type(s.explosion_type), name(s.name), abrv(s.abrv), design(s.design), -emcon(s.emcon) -{ - if (design) { - // cast-away const - ListIter c = (List&) s.components; - while (++c) { - Component* comp = new Component(*(c.value())); - comp->SetSystem(this); - components.append(comp); - } - } - - emcon_power[0] = s.emcon_power[0]; - emcon_power[1] = s.emcon_power[1]; - emcon_power[2] = s.emcon_power[2]; -} - -// +--------------------------------------------------------------------+ - -System::~System() -{ - components.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -System::SetDesign(SystemDesign* d) -{ - if (design) { - design = 0; - components.destroy(); - } - - if (d) { - design = d; - - ListIter cd = design->components; - while (++cd) { - Component* comp = new Component(cd.value(), this); - components.append(comp); - } - } -} - -// +--------------------------------------------------------------------+ - -void -System::SetPowerLevel(double level) -{ - if (level > 100) - level = 100; - else if (level < 0) - level = 0; - - level /= 100; - - if (power_level != level) { - // if the system is on emergency override power, - // do not let the EMCON system use this method - // to drop it back to normal power: - if (power_level > 1 && level == 1) - return; - - power_level = (float) level; - - NetUtil::SendSysStatus(ship, this); - } -} - -void -System::SetOverride(bool over) -{ - bool changed = false; - - if (over && power_level != 1.2f) { - power_level = 1.2f; - changed = true; - } - - else if (!over && power_level > 1) { - power_level = 1.0f; - changed = true; - } - - if (changed) - NetUtil::SendSysStatus(ship, this); -} - -void -System::SetEMCONPower(int index, int power_level) -{ - if (index >= 1 && index <= 3) { - emcon_power[index-1] = (BYTE) power_level; - } -} - -int -System::GetEMCONPower(int index) -{ - if (index >= 1 && index <= 3) { - return emcon_power[index-1]; - } - - return 100; -} - -void -System::DoEMCON(int index) -{ - int e = GetEMCONPower(index); - - if (power_level * 100 > e || emcon != index) { - if (e == 0) { - PowerOff(); - } - else { - if (emcon != index) - PowerOn(); - - SetPowerLevel(e); - } - } - - emcon = index; -} - -// +--------------------------------------------------------------------+ - -void -System::ExecFrame(double seconds) -{ - if (seconds < 0.01) - seconds = 0.01; - - STATUS s = DESTROYED; - - if (availability > 0.99) - s = NOMINAL; - else if (availability > crit_level) - s = DEGRADED; - else - s = CRITICAL; - - bool repair = false; - - if (components.size() > 0) { - ListIter comp = components; - while (++comp) { - if (comp->Status() > Component::NOMINAL) { - repair = true; - break; - } - } - } - - if (repair) { - Repair(); - } - - else { - if (status != s) { - status = s; - NetUtil::SendSysStatus(ship, this); - } - - // collateral damage due to unsafe operation: - if (power_on && power_level > safety) { - safety_overload += (float) seconds; - - // inflict some damage now: - if (safety_overload > 60) { - safety_overload -= (float) (rand() / (1000 * (power_level-safety))); - ApplyDamage(15); - - NetUtil::SendSysStatus(ship, this); - } - } - - else if (safety_overload > 0) { - safety_overload -= (float) seconds; - } - } -} - -void -System::Repair() -{ - if (status != MAINT) { - status = MAINT; - safety_overload = 0.0f; - - NetUtil::SendSysStatus(ship, this); - } -} - -// +--------------------------------------------------------------------+ - -void -System::ExecMaintFrame(double seconds) -{ - if (components.size() > 0) { - ListIter comp = components; - while (++comp) { - if (comp->Status() > Component::NOMINAL) { - comp->ExecMaintFrame(seconds); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -System::ApplyDamage(double damage) -{ - if (!power_on) - damage /= 10; - - if (components.size() > 0) { - int index = rand() % components.size(); - - if (damage > 50) { - damage/=2; - components[index]->ApplyDamage(damage); - - index = rand() % components.size(); - } - - components[index]->ApplyDamage(damage); - - if (safety < 0.5) - SetPowerLevel(50); - - else if (safety < 1.0) - SetPowerLevel(safety * 100); - } - else { - availability -= (float) (damage/100.0f); - if (availability < 0.01) availability = 0.0f; - } -} - -void -System::CalcStatus() -{ - if (components.size() > 0) { - availability = 1.0f; - safety = 1.0f; - stability = 1.0f; - - ListIter comp = components; - while (++comp) { - if (comp->DamageEfficiency()) - availability *= comp->Availability() / 100.0f; - - if (comp->DamageSafety()) - safety *= comp->Availability() / 100.0f; - - if (comp->DamageStability()) - stability *= comp->Availability() / 100.0f; - - if (comp->IsJerried()) { - safety *= 0.95f; - stability *= 0.95f; - } - } - - if (net_avail >= 0 && availability < net_avail) - availability = net_avail; - } -} - -// +--------------------------------------------------------------------+ - -void -System::Mount(Point loc, float rad, float hull) -{ - mount_rel = loc; - radius = rad; - hull_factor = hull; -} - -void -System::Mount(const System& system) -{ - mount_rel = system.mount_rel; - radius = system.radius; - hull_factor = system.hull_factor; -} - -// +--------------------------------------------------------------------+ - -void -System::Orient(const Physical* rep) -{ - const Matrix& orientation = rep->Cam().Orientation(); - Point loc = rep->Location(); - - mount_loc = (mount_rel * orientation) + loc; -} - -// +----------------------------------------------------------------------+ - -double -System::GetRequest(double seconds) const -{ - if (!power_on || capacity == energy) - return 0; - - else - return power_level * sink_rate * seconds; -} - -// +----------------------------------------------------------------------+ - -void -System::Distribute(double delivered_energy, double seconds) -{ - if (UsesWatts()) { - if (seconds < 0.01) - seconds = 0.01; - - // convert Joules to Watts: - energy = (float) (delivered_energy/seconds); - } - - else if (!Game::GetInstance()->Paused()) { - energy += (float) delivered_energy; - - if (energy > capacity) - energy = capacity; - - else if (energy < 0) - energy = 0.0f; - } -} - -// +----------------------------------------------------------------------+ - -void -System::DrainPower(double to_level) -{ - energy = 0.0f; -} diff --git a/Stars45/System.h b/Stars45/System.h deleted file mode 100644 index d56c502..0000000 --- a/Stars45/System.h +++ /dev/null @@ -1,173 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Generic ship System class -*/ - -#ifndef System_h -#define System_h - -#include "Types.h" -#include "Physical.h" -#include "Geometry.h" - -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Component; -class Ship; -class SystemDesign; - -// +--------------------------------------------------------------------+ - -class System -{ - friend Component; - -public: - static const char* TYPENAME() { return "System"; } - - enum CATEGORY { MISC_SYSTEM=0, DRIVE=1, WEAPON, SHIELD, SENSOR, - COMPUTER, POWER_SOURCE, FLIGHT_DECK, FARCASTER }; - enum STATUS { DESTROYED, CRITICAL, DEGRADED, NOMINAL, MAINT }; - enum POWER_FLAGS { POWER_WATTS=1, POWER_CRITICAL=2 }; - - System(CATEGORY t, int s, const char* n, int maxv, - double energy=0, double capacity=100, double sink_rate=1); - System(const System& s); - virtual ~System(); - - int operator==(const System& s) const { return this == &s; } - - CATEGORY Type() const { return type; } - int Subtype() const { return subtype; } - const char* Name() const { return name; } - const char* Abbreviation() const { return abrv; } - - void SetName(const char* n) { name = n; } - void SetAbbreviation(const char* a) { abrv = a; } - void SetDesign(SystemDesign* d); - - virtual int Value() const { return (int) (max_value*availability*100); } - int MaxValue() const { return (int) (max_value*100); } - STATUS Status() const { return status; } - double Availability() const { return availability*100; } - double Safety() const { return safety*100; } - double Stability() const { return stability*100; } - virtual void CalcStatus(); - virtual void Repair(); - - double NetAvail() const { return net_avail; } - void SetNetAvail(double d){ net_avail = (float) d; } - - List& GetComponents() { return components; } - - virtual void ApplyDamage(double damage); - virtual void ExecFrame(double seconds); - virtual void ExecMaintFrame(double seconds); - virtual void DoEMCON(int emcon); - - // PHYSICAL LOCATION (for inflicting system damage): - virtual void Orient(const Physical* rep); - virtual void Mount(Point loc, float radius, float hull_factor=0.5f); - virtual void Mount(const System& system); - - Point MountLocation() const { return mount_loc; } - double Radius() const { return radius; } - double HullProtection() const { return hull_factor; } - - // POWER UTILIZATION: - bool IsPowerCritical() const { return (power_flags & POWER_CRITICAL)?true:false; } - bool UsesWatts() const { return (power_flags & POWER_WATTS)?true:false; } - - virtual double GetRequest(double seconds) const; - virtual void Distribute(double delivered_energy, double seconds); - - int GetSourceIndex() const { return source_index; } - void SetSourceIndex(int i) { source_index = i; } - - virtual int Charge() const { return (int) (100 * energy/capacity); } - - bool IsPowerOn() const { return power_on; } - virtual void PowerOn() { power_on = true; } - virtual void PowerOff() { power_on = false; } - - // percentage, but stored as 0-1 - virtual double GetPowerLevel() const { return power_level * 100; } - virtual void SetPowerLevel(double level); - virtual void SetOverride(bool over); - - // for power drain damage: - virtual void DrainPower(double to_level); - - void SetCapacity(double c) { capacity = (float) c; } - double GetCapacity() const { return capacity; } - double GetEnergy() const { return energy; } - double GetSinkRate() const { return sink_rate; } - void SetEMCONPower(int emcon, int power_level); - int GetEMCONPower(int emcon); - - int GetExplosionType() const { return explosion_type; } - void SetExplosionType(int t) { explosion_type = t; } - - Ship* GetShip() const { return ship; } - void SetShip(Ship* s) { ship = s; } - int GetID() const { return id; } - void SetID(int n) { id = n; } - -protected: - // AI information: - CATEGORY type; - Ship* ship; - int id; - int subtype; - int max_value; - - // Displayable name: - Text name; - Text abrv; - - // System health status: - STATUS status; - float crit_level; - float availability; - float safety; - float stability; - float safety_overload; - float net_avail; - - // Mounting: - Point mount_loc; // world space - Point mount_rel; // object space - float radius; - float hull_factor; - - // Power Sink: - float energy; - float capacity; - float sink_rate; - float power_level; - int source_index; - DWORD power_flags; - bool power_on; - BYTE emcon_power[3]; - BYTE emcon; - - int explosion_type; - - // Subcomponents: - SystemDesign* design; - List components; -}; - -#endif // System_h - diff --git a/Stars45/SystemDesign.cpp b/Stars45/SystemDesign.cpp deleted file mode 100644 index 97b65a3..0000000 --- a/Stars45/SystemDesign.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon Design parameters class -*/ - -#include "SystemDesign.h" -#include "Component.h" - -#include "Game.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ - -List SystemDesign::catalog; - -#define GET_DEF_TEXT(p,d,x) if(p->name()->value()==(#x))GetDefText(d->x,p,filename) -#define GET_DEF_NUM(p,d,x) if(p->name()->value()==(#x))GetDefNumber(d->x,p,filename) - -// +--------------------------------------------------------------------+ - -SystemDesign::SystemDesign() -{ } - -SystemDesign::~SystemDesign() -{ - components.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -SystemDesign::Initialize(const char* filename) -{ - Print("Loading System Designs '%s'\n", filename); - - // Load Design File: - DataLoader* loader = DataLoader::GetLoader(); - BYTE* block; - - int blocklen = loader->LoadBuffer(filename, block, true); - 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() != "SYSTEM") { - Print("ERROR: invalid system design file '%s'\n", filename); - exit(-4); - } - } - - int type = 1; - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - if (def->name()->value() == "system") { - - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: system structure missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - SystemDesign* design = new SystemDesign; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - GET_DEF_TEXT(pdef, design, name); - - else if (pdef->name()->value()==("component")) { - if (!pdef->term() || !pdef->term()->isStruct()) { - Print("WARNING: component structure missing in system '%s' in '%s'\n", (const char*) design->name, filename); - } - else { - TermStruct* val2 = pdef->term()->isStruct(); - ComponentDesign* comp_design = new ComponentDesign; - - for (int i = 0; i < val2->elements()->size(); i++) { - TermDef* pdef2 = val2->elements()->at(i)->isDef(); - if (pdef2) { - GET_DEF_TEXT(pdef2, comp_design, name); - else GET_DEF_TEXT(pdef2, comp_design, abrv); - else GET_DEF_NUM (pdef2, comp_design, repair_time); - else GET_DEF_NUM (pdef2, comp_design, replace_time); - else GET_DEF_NUM (pdef2, comp_design, spares); - else GET_DEF_NUM (pdef2, comp_design, affects); - - else { - Print("WARNING: parameter '%s' ignored in '%s'\n", - pdef2->name()->value().data(), filename); - } - } - } - - design->components.append(comp_design); - } - } - - else { - Print("WARNING: parameter '%s' ignored in '%s'\n", - pdef->name()->value().data(), filename); - } - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - val->elements()->at(i)->print(); - } - } - - catalog.append(design); - } - } - - else - Print("WARNING: unknown definition '%s' in '%s'\n", - def->name()->value().data(), filename); - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - } - } - } - while (term); - - loader->ReleaseBuffer(block); -} - -// +--------------------------------------------------------------------+ - -void -SystemDesign::Close() -{ - catalog.destroy(); -} - -// +--------------------------------------------------------------------+ - -SystemDesign* -SystemDesign::Find(const char* name) -{ - SystemDesign test; - test.name = name; - return catalog.find(&test); -} - diff --git a/Stars45/SystemDesign.h b/Stars45/SystemDesign.h deleted file mode 100644 index 3219e8a..0000000 --- a/Stars45/SystemDesign.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Generic ship System Design class -*/ - -#ifndef SystemDesign_h -#define SystemDesign_h - -#include "Types.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class ComponentDesign; - -// +--------------------------------------------------------------------+ - -class SystemDesign -{ -public: - static const char* TYPENAME() { return "SystemDesign"; } - - SystemDesign(); - ~SystemDesign(); - int operator == (const SystemDesign& rhs) const { return name == rhs.name; } - - static void Initialize(const char* filename); - static void Close(); - static SystemDesign* Find(const char* name); - - // Unique ID: - Text name; - - // Sub-components: - List components; - - static List catalog; -}; - -// +--------------------------------------------------------------------+ - - -#endif // SystemDesign_h - diff --git a/Stars45/TacRefDlg.cpp b/Stars45/TacRefDlg.cpp deleted file mode 100644 index ff623bc..0000000 --- a/Stars45/TacRefDlg.cpp +++ /dev/null @@ -1,688 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Tactical Reference Dialog Active Window class -*/ - -#include "TacRefDlg.h" -#include "MenuScreen.h" -#include "Campaign.h" -#include "Mission.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "WeaponDesign.h" -#include "WeaponGroup.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "EventDispatch.h" -#include "Mouse.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "ParseUtil.h" -#include "FormatUtil.h" -#include "Light.h" -#include "Solid.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: -DEF_MAP_CLIENT(TacRefDlg, OnClose); -DEF_MAP_CLIENT(TacRefDlg, OnSelect); -DEF_MAP_CLIENT(TacRefDlg, OnMode); -DEF_MAP_CLIENT(TacRefDlg, OnCamRButtonDown); -DEF_MAP_CLIENT(TacRefDlg, OnCamRButtonUp); -DEF_MAP_CLIENT(TacRefDlg, OnCamMove); -DEF_MAP_CLIENT(TacRefDlg, OnCamZoom); - -// +--------------------------------------------------------------------+ - -TacRefDlg::TacRefDlg(Screen* s, FormDef& def, MenuScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -beauty(0), camview(0), imgview(0), -txt_caption(0), txt_stats(0), txt_description(0), -lst_designs(0), btn_close(0), btn_ships(0), btn_weaps(0), -mode(MODE_NONE), radius(100), mouse_x(0), mouse_y(0), -cam_zoom(2.5), cam_az(-PI/6), cam_el(PI/7), captured(false), -ship_index(0), weap_index(0) -{ - Init(def); -} - -TacRefDlg::~TacRefDlg() -{ - if (beauty) { - beauty->DelView(camview); - beauty->DelView(imgview); - } - - delete camview; - delete imgview; -} - -// +--------------------------------------------------------------------+ - -void -TacRefDlg::RegisterControls() -{ - btn_close = (Button*) FindControl(1); - btn_ships = (Button*) FindControl(101); - btn_weaps = (Button*) FindControl(102); - lst_designs = (ListBox*) FindControl(200); - txt_caption = FindControl(301); - beauty = FindControl(401); - txt_stats = (RichTextBox*) FindControl(402); - txt_description = (RichTextBox*) FindControl(403); - - if (btn_close) { - REGISTER_CLIENT(EID_CLICK, btn_close, TacRefDlg, OnClose); - } - - if (btn_ships) { - btn_ships->SetButtonState(mode == MODE_SHIPS); - REGISTER_CLIENT(EID_CLICK, btn_ships, TacRefDlg, OnMode); - } - - if (btn_weaps) { - btn_weaps->SetButtonState(mode == MODE_WEAPONS); - REGISTER_CLIENT(EID_CLICK, btn_weaps, TacRefDlg, OnMode); - } - - if (lst_designs) { - REGISTER_CLIENT(EID_SELECT, lst_designs, TacRefDlg, OnSelect); - } - - if (beauty) { - REGISTER_CLIENT(EID_RBUTTON_DOWN, beauty, TacRefDlg, OnCamRButtonDown); - REGISTER_CLIENT(EID_RBUTTON_UP, beauty, TacRefDlg, OnCamRButtonUp); - REGISTER_CLIENT(EID_MOUSE_MOVE, beauty, TacRefDlg, OnCamMove); - REGISTER_CLIENT(EID_MOUSE_WHEEL, beauty, TacRefDlg, OnCamZoom); - - scene.SetAmbient(Color(60,60,60)); - - Point light_pos(3e6, 5e6, 4e6); - - Light* main_light = new Light(1.0f); //1.25f); - main_light->MoveTo(light_pos); - main_light->SetType(Light::LIGHT_DIRECTIONAL); - main_light->SetColor(Color::White); - main_light->SetShadow(true); - - scene.AddLight(main_light); - - Light* back_light = new Light(0.5f); - back_light->MoveTo(light_pos * -1); - back_light->SetType(Light::LIGHT_DIRECTIONAL); - back_light->SetColor(Color::White); - back_light->SetShadow(false); - - scene.AddLight(back_light); - - camview = new CameraView(beauty, &cam, &scene); - camview->SetProjectionType(Video::PROJECTION_PERSPECTIVE); - camview->SetFieldOfView(2); - - beauty->AddView(camview); - - imgview = new ImgView(beauty, 0); - imgview->SetBlend(Video::BLEND_ALPHA); - } -} - -// +--------------------------------------------------------------------+ - -void -TacRefDlg::Show() -{ - update_scene = !shown; - - FormWindow::Show(); - - if (update_scene) { - AWEvent event(btn_ships, EID_CLICK); - OnMode(&event); - } -} - -struct WepGroup { - Text name; - int count; - - WepGroup() : count(0) { } -}; -WepGroup* FindWepGroup(WepGroup* weapons, const char* name); - - -void -TacRefDlg::SelectShip(const ShipDesign* design) -{ - if (beauty && camview) { - scene.Graphics().clear(); - - if (design) { - radius = design->radius; - - UpdateCamera(); - - int level = design->lod_levels-1; - int n = design->models[level].size(); - - for (int i = 0; i < n; i++) { - Model* model = design->models[level].at(i); - - Solid* s = new Solid; - s->UseModel(model); - s->CreateShadows(1); - s->MoveTo(*design->offsets[level].at(i)); - - scene.Graphics().append(s); - } - } - } - - if (txt_caption) { - txt_caption->SetText(""); - - if (design) { - char txt[256]; - sprintf_s(txt, "%s %s", design->abrv, design->DisplayName()); - txt_caption->SetText(txt); - } - } - - if (txt_stats) { - txt_stats->SetText(""); - - if (design) { - Text desc; - char txt[256]; - - sprintf_s(txt, "%s\t\t\t%s\n", ContentBundle::GetInstance()->GetText("tacref.type").data(), Ship::ClassName(design->type)); - desc += txt; - - sprintf_s(txt, "%s\t\t\t%s\n", ContentBundle::GetInstance()->GetText("tacref.class").data(), design->DisplayName()); - desc += txt; - desc += ContentBundle::GetInstance()->GetText("tacref.length"); - desc += "\t\t"; - - if (design->type < Ship::STATION) - FormatNumber(txt, design->radius/2); - else - FormatNumber(txt, design->radius*2); - - strcat_s(txt, " m\n"); - desc += txt; - desc += ContentBundle::GetInstance()->GetText("tacref.mass"); - desc += "\t\t\t"; - - FormatNumber(txt, design->mass); - strcat_s(txt, " T\n"); - desc += txt; - desc += ContentBundle::GetInstance()->GetText("tacref.hull"); - desc += "\t\t\t"; - - FormatNumber(txt, design->integrity); - strcat_s(txt, "\n"); - desc += txt; - - if (design->weapons.size()) { - desc += ContentBundle::GetInstance()->GetText("tacref.weapons"); - - WepGroup groups[8]; - for (int w = 0; w < design->weapons.size(); w++) { - Weapon* gun = design->weapons[w]; - WepGroup* group = FindWepGroup(groups, gun->Group()); - - if (group) - group->count++; - } - - for (int g = 0; g < 8; g++) { - WepGroup* group = &groups[g]; - if (group && group->count) { - sprintf_s(txt, "\t\t%s (%d)\n\t\t", group->name.data(), group->count); - desc += txt; - - for (int w = 0; w < design->weapons.size(); w++) { - Weapon* gun = design->weapons[w]; - - if (group->name == gun->Group()) { - sprintf_s(txt, "\t\t\t%s\n\t\t", (const char*) gun->Design()->name); - desc += txt; - } - } - } - } - - desc += "\n"; - } - - txt_stats->SetText(desc); - } - } - - if (txt_description) { - if (design && design->description.length()) { - txt_description->SetText(design->description); - } - else { - txt_description->SetText(ContentBundle::GetInstance()->GetText("tacref.mass")); - } - } -} - -// +--------------------------------------------------------------------+ - -void -TacRefDlg::SelectWeapon(const WeaponDesign* design) -{ - if (beauty && imgview) { - imgview->SetPicture(0); - - if (design) - imgview->SetPicture(design->beauty_img); - } - - if (txt_caption) { - txt_caption->SetText(""); - - if (design) - txt_caption->SetText(design->name); - } - - if (txt_stats) { - txt_stats->SetText(""); - - if (design) { - Text desc; - char txt[256]; - - desc = ContentBundle::GetInstance()->GetText("tacref.name"); - desc += "\t"; - desc += design->name; - desc += "\n"; - desc += ContentBundle::GetInstance()->GetText("tacref.type"); - desc += "\t\t"; - - if (design->damage < 1) - desc += ContentBundle::GetInstance()->GetText("tacref.wep.other"); - else if (design->beam) - desc += ContentBundle::GetInstance()->GetText("tacref.wep.beam"); - else if (design->primary) - desc += ContentBundle::GetInstance()->GetText("tacref.wep.bolt"); - else if (design->drone) - desc += ContentBundle::GetInstance()->GetText("tacref.wep.drone"); - else if (design->guided) - desc += ContentBundle::GetInstance()->GetText("tacref.wep.guided"); - else - desc += ContentBundle::GetInstance()->GetText("tacref.wep.missile"); - - if (design->turret_model && design->damage >= 1) { - desc += " "; - desc += ContentBundle::GetInstance()->GetText("tacref.wep.turret"); - desc += "\n"; - } - else { - desc += "\n"; - } - - desc += ContentBundle::GetInstance()->GetText("tacref.targets"); - desc += "\t"; - - if ((design->target_type & Ship::DROPSHIPS) != 0) { - if ((design->target_type & Ship::STARSHIPS) != 0) { - if ((design->target_type & Ship::GROUND_UNITS) != 0) { - desc += ContentBundle::GetInstance()->GetText("tacref.targets.fsg"); - } - else { - desc += ContentBundle::GetInstance()->GetText("tacref.targets.fs"); - } - } - else { - if ((design->target_type & Ship::GROUND_UNITS) != 0) { - desc += ContentBundle::GetInstance()->GetText("tacref.targets.fg"); - } - else { - desc += ContentBundle::GetInstance()->GetText("tacref.targets.f"); - } - } - } - - else if ((design->target_type & Ship::STARSHIPS) != 0) { - if ((design->target_type & Ship::GROUND_UNITS) != 0) { - desc += ContentBundle::GetInstance()->GetText("tacref.targets.sg"); - } - else { - desc += ContentBundle::GetInstance()->GetText("tacref.targets.s"); - } - } - - else if ((design->target_type & Ship::GROUND_UNITS) != 0) { - desc += ContentBundle::GetInstance()->GetText("tacref.targets.g"); - } - - desc += "\n"; - desc += ContentBundle::GetInstance()->GetText("tacref.speed"); - desc += "\t"; - - FormatNumber(txt, design->speed); - desc += txt; - desc += "m/s\n"; - desc += ContentBundle::GetInstance()->GetText("tacref.range"); - desc += "\t"; - - FormatNumber(txt, design->max_range); - desc += txt; - desc += "m\n"; - desc += ContentBundle::GetInstance()->GetText("tacref.damage"); - desc += "\t"; - - if (design->damage > 0) { - FormatNumber(txt, design->damage * design->charge); - desc += txt; - if (design->beam) - desc += "/s"; - } - else { - desc += ContentBundle::GetInstance()->GetText("tacref.none"); - } - - desc += "\n"; - - if (!design->primary && design->damage > 0) { - desc += ContentBundle::GetInstance()->GetText("tacref.kill-radius"); - desc += "\t"; - FormatNumber(txt, design->lethal_radius); - desc += txt; - desc += " m\n"; - } - - txt_stats->SetText(desc); - } - } - - if (txt_description) { - if (design && design->description.length()) { - txt_description->SetText(design->description); - } - else { - txt_description->SetText(ContentBundle::GetInstance()->GetText("tacref.no-info")); - } - } -} - -// +--------------------------------------------------------------------+ - -void -TacRefDlg::ExecFrame() -{ -} - -// +--------------------------------------------------------------------+ - -bool -TacRefDlg::SetCaptureBeauty() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch && beauty) - return dispatch->CaptureMouse(beauty) ? true : false; - - return 0; -} - -bool -TacRefDlg::ReleaseCaptureBeauty() -{ - EventDispatch* dispatch = EventDispatch::GetInstance(); - if (dispatch && beauty) - return dispatch->ReleaseMouse(beauty) ? true : false; - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -TacRefDlg::UpdateAzimuth(double a) -{ - cam_az += a; - - if (cam_az > PI) - cam_az = -2*PI + cam_az; - - else if (cam_az < -PI) - cam_az = 2*PI + cam_az; -} - -void -TacRefDlg::UpdateElevation(double e) -{ - cam_el += e; - - const double limit = (0.43 * PI); - - if (cam_el > limit) - cam_el = limit; - else if (cam_el < -limit) - cam_el = -limit; -} - -void -TacRefDlg::UpdateZoom(double delta) -{ - cam_zoom *= delta; - - if (cam_zoom < 1.2) - cam_zoom = 1.2; - - else if (cam_zoom > 10) - cam_zoom = 10; -} - -void -TacRefDlg::UpdateCamera() -{ - double x = cam_zoom * radius * sin(cam_az) * cos(cam_el); - double y = cam_zoom * radius * cos(cam_az) * cos(cam_el); - double z = cam_zoom * radius * sin(cam_el); - - cam.LookAt(Point(0,0,0), Point(x,z,y), Point(0,1,0)); -} - -// +--------------------------------------------------------------------+ - -void -TacRefDlg::OnSelect(AWEvent* event) -{ - if (lst_designs) { - int seln = lst_designs->GetSelection(); - DWORD dsn = lst_designs->GetItemData(seln); - - if (mode == MODE_SHIPS) { - ship_index = seln; - - if (dsn) { - SelectShip((ShipDesign*) dsn); - } - } - - else if (mode == MODE_WEAPONS) { - weap_index = seln; - - if (dsn) { - SelectWeapon((WeaponDesign*) dsn); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -TacRefDlg::OnCamRButtonDown(AWEvent* event) -{ - captured = SetCaptureBeauty(); - mouse_x = event->x; - mouse_y = event->y; -} - -void -TacRefDlg::OnCamRButtonUp(AWEvent* event) -{ - if (captured) - ReleaseCaptureBeauty(); - - captured = false; - mouse_x = 0; - mouse_y = 0; -} - -void -TacRefDlg::OnCamMove(AWEvent* event) -{ - if (captured) { - int mouse_dx = event->x - mouse_x; - int mouse_dy = event->y - mouse_y; - - UpdateAzimuth( mouse_dx * 0.3 * DEGREES); - UpdateElevation( mouse_dy * 0.3 * DEGREES); - UpdateCamera(); - - mouse_x = event->x; - mouse_y = event->y; - } -} - -void -TacRefDlg::OnCamZoom(AWEvent* event) -{ - int w = Mouse::Wheel(); - - if (w < 0) { - while (w < 0) { - UpdateZoom(1.25); - w += 120; - } - } - else { - while (w > 0) { - UpdateZoom(0.75f); - w -= 120; - } - } - - UpdateCamera(); -} - -// +--------------------------------------------------------------------+ - -void -TacRefDlg::OnMode(AWEvent* event) -{ - if (event->window == btn_ships && mode != MODE_SHIPS) { - mode = MODE_SHIPS; - - if (lst_designs) { - lst_designs->ClearItems(); - - List designs; - - for (int n = 0; n < 16; n++) { - int type = 1 << n; - ShipDesign::GetDesignList(type, designs); - - ListIter iter = designs; - while (++iter) { - Text* val = iter.value(); - - const ShipDesign* dsn = ShipDesign::Get(*val); - - if (dsn) { - char txt[256]; - sprintf_s(txt, "%s %s", dsn->abrv, dsn->DisplayName()); - - lst_designs->AddItemWithData(txt, (DWORD) dsn); - } - else { - lst_designs->AddItemWithData(*val, 0); - } - } - } - - lst_designs->SetSelected(ship_index); - } - - if (beauty) { - beauty->AddView(camview); - beauty->DelView(imgview); - } - - DWORD dsn = lst_designs->GetItemData(ship_index); - - if (dsn) { - SelectShip((ShipDesign*) dsn); - } - } - - else if (event->window == btn_weaps && mode != MODE_WEAPONS) { - mode = MODE_WEAPONS; - - const WeaponDesign* design = 0; - - if (lst_designs) { - lst_designs->ClearItems(); - List designs; - - WeaponDesign::GetDesignList(designs); - - ListIter iter = designs; - while (++iter) { - Text* val = iter.value(); - - if (val->contains("Zolon") || val->contains("Inverted")) - continue; - - const WeaponDesign* dsn = WeaponDesign::Find(*val); - - if (dsn && !dsn->secret) { - lst_designs->AddItemWithData(*val, (DWORD) dsn); - - if (!design) - design = dsn; - } - } - - lst_designs->SetSelected(weap_index); - } - - if (beauty) { - beauty->DelView(camview); - beauty->AddView(imgview); - } - - DWORD dsn = lst_designs->GetItemData(weap_index); - - if (dsn) { - SelectWeapon((WeaponDesign*) dsn); - } - } - - btn_ships->SetButtonState(mode == MODE_SHIPS); - btn_weaps->SetButtonState(mode == MODE_WEAPONS); -} - -// +--------------------------------------------------------------------+ - -void -TacRefDlg::OnClose(AWEvent* event) -{ - manager->ShowMenuDlg(); -} - diff --git a/Stars45/TacRefDlg.h b/Stars45/TacRefDlg.h deleted file mode 100644 index 07f1f27..0000000 --- a/Stars45/TacRefDlg.h +++ /dev/null @@ -1,100 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Mission Briefing Dialog Active Window class -*/ - -#ifndef TacRefDlg_h -#define TacRefDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "MsnDlg.h" -#include "Bitmap.h" -#include "Button.h" -#include "CameraView.h" -#include "ImgView.h" -#include "Scene.h" -#include "Font.h" -#include "Text.h" -#include "ListBox.h" -#include "RichTextBox.h" - -// +--------------------------------------------------------------------+ - -class MenuScreen; -class ShipDesign; -class WeaponDesign; - -// +--------------------------------------------------------------------+ - -class TacRefDlg : public FormWindow -{ -public: - enum MODES { MODE_NONE, MODE_SHIPS, MODE_WEAPONS }; - - TacRefDlg(Screen* s, FormDef& def, MenuScreen* mgr); - virtual ~TacRefDlg(); - - virtual void RegisterControls(); - virtual void ExecFrame(); - virtual void Show(); - - // Operations: - virtual void OnClose(AWEvent* event); - virtual void OnMode(AWEvent* event); - virtual void OnSelect(AWEvent* event); - virtual void OnCamRButtonDown(AWEvent* event); - virtual void OnCamRButtonUp(AWEvent* event); - virtual void OnCamMove(AWEvent* event); - virtual void OnCamZoom(AWEvent* event); - -protected: - virtual void SelectShip(const ShipDesign* dsn); - virtual void SelectWeapon(const WeaponDesign* dsn); - - virtual void UpdateZoom(double r); - virtual void UpdateAzimuth(double a); - virtual void UpdateElevation(double e); - virtual void UpdateCamera(); - virtual bool SetCaptureBeauty(); - virtual bool ReleaseCaptureBeauty(); - - MenuScreen* manager; - ActiveWindow* beauty; - ListBox* lst_designs; - ActiveWindow* txt_caption; - RichTextBox* txt_stats; - RichTextBox* txt_description; - Button* btn_ships; - Button* btn_weaps; - Button* btn_close; - - ImgView* imgview; - CameraView* camview; - Scene scene; - Camera cam; - - int mode; - double radius; - double cam_zoom; - double cam_az; - double cam_el; - int mouse_x; - int mouse_y; - bool update_scene; - bool captured; - - int ship_index; - int weap_index; -}; - -#endif // TacRefDlg_h - diff --git a/Stars45/TacticalAI.cpp b/Stars45/TacticalAI.cpp deleted file mode 100644 index 7f4e64d..0000000 --- a/Stars45/TacticalAI.cpp +++ /dev/null @@ -1,957 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Generic Ship Tactical Level AI class -*/ - -#include "TacticalAI.h" -#include "ShipAI.h" -#include "CarrierAI.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Element.h" -#include "Instruction.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "Contact.h" -#include "WeaponGroup.h" -#include "Drive.h" -#include "Hangar.h" -#include "Sim.h" -#include "Shot.h" -#include "Drone.h" -#include "StarSystem.h" - -#include "Clock.h" -#include "Random.h" - -// +----------------------------------------------------------------------+ - -static int exec_time_seed = 0; - -// +----------------------------------------------------------------------+ - -TacticalAI::TacticalAI(ShipAI* ai) -: ship(0), ship_ai(0), carrier_ai(0), navpt(0), orders(0), -action(0), threat_level(0), support_level(1), -directed_tgtid(0) -{ - if (ai) { - ship_ai = ai; - ship = ai->GetShip(); - - Sim* sim = Sim::GetSim(); - - if (ship && ship->GetHangar() && ship->GetCommandAILevel() > 0 && - ship != sim->GetPlayerShip()) - carrier_ai = new CarrierAI(ship, ship_ai->GetAILevel()); - } - - agression = 0; - roe = FLEXIBLE; - element_index = 1; - exec_time = exec_time_seed; - exec_time_seed += 17; -} - -TacticalAI::~TacticalAI() -{ - delete carrier_ai; -} - -// +--------------------------------------------------------------------+ - -void -TacticalAI::ExecFrame(double secs) -{ - const int exec_period = 1000; - - if (!ship || !ship_ai) - return; - - navpt = ship->GetNextNavPoint(); - orders = ship->GetRadioOrders(); - - if ((int) Clock::GetInstance()->GameTime() - exec_time > exec_period) { - element_index = ship->GetElementIndex(); - - CheckOrders(); - SelectTarget(); - FindThreat(); - FindSupport(); - - if (element_index > 1) { - int formation = 0; - - if (orders && orders->Formation() >= 0) - formation = orders->Formation(); - - else if (navpt) - formation = navpt->Formation(); - - FindFormationSlot(formation); - } - - ship_ai->SetNavPoint(navpt); - - if (carrier_ai) - carrier_ai->ExecFrame(secs); - - exec_time += exec_period; - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalAI::CheckOrders() -{ - directed_tgtid = 0; - - if (CheckShipOrders()) - return; - - if (CheckFlightPlan()) - return; - - if (CheckObjectives()) - return; -} - -// +--------------------------------------------------------------------+ - -bool -TacticalAI::CheckShipOrders() -{ - return ProcessOrders(); -} - -// +--------------------------------------------------------------------+ - -bool -TacticalAI::CheckObjectives() -{ - bool processed = false; - Ship* ward = 0; - Element* elem = ship->GetElement(); - - if (elem) { - Instruction* obj = elem->GetTargetObjective(); - - if (obj) { - ship_ai->ClearPatrol(); - - if (obj->Action()) { - switch (obj->Action()) { - case Instruction::INTERCEPT: - case Instruction::STRIKE: - case Instruction::ASSAULT: - { - SimObject* tgt = obj->GetTarget(); - if (tgt && tgt->Type() == SimObject::SIM_SHIP) { - roe = DIRECTED; - SelectTargetDirected((Ship*) tgt); - } - } - break; - - case Instruction::DEFEND: - case Instruction::ESCORT: - { - SimObject* tgt = obj->GetTarget(); - if (tgt && tgt->Type() == SimObject::SIM_SHIP) { - roe = DEFENSIVE; - ward = (Ship*) tgt; - } - } - break; - - default: - break; - } - } - - orders = obj; - processed = true; - } - } - - ship_ai->SetWard(ward); - return processed; -} - -// +--------------------------------------------------------------------+ - -bool -TacticalAI::ProcessOrders() -{ - if (ship_ai) - ship_ai->ClearPatrol(); - - if (orders && orders->EMCON() > 0) { - int desired_emcon = orders->EMCON(); - - if (ship_ai && (ship_ai->GetThreat() || ship_ai->GetThreatMissile())) - desired_emcon = 3; - - if (ship->GetEMCON() != desired_emcon) - ship->SetEMCON(desired_emcon); - } - - if (orders && orders->Action()) { - switch (orders->Action()) { - case RadioMessage::ATTACK: - case RadioMessage::BRACKET: - case RadioMessage::IDENTIFY: - { - bool tgt_ok = false; - SimObject* tgt = orders->GetTarget(); - - if (tgt && tgt->Type() == SimObject::SIM_SHIP) { - Ship* tgt_ship = (Ship*) tgt; - - if (CanTarget(tgt_ship)) { - roe = DIRECTED; - SelectTargetDirected((Ship*) tgt); - - ship_ai->SetBracket(orders->Action() == RadioMessage::BRACKET); - ship_ai->SetIdentify(orders->Action() == RadioMessage::IDENTIFY); - ship_ai->SetNavPoint(0); - - tgt_ok = true; - } - } - - if (!tgt_ok) - ClearRadioOrders(); - } - break; - - case RadioMessage::ESCORT: - case RadioMessage::COVER_ME: - { - SimObject* tgt = orders->GetTarget(); - if (tgt && tgt->Type() == SimObject::SIM_SHIP) { - roe = DEFENSIVE; - ship_ai->SetWard((Ship*) tgt); - ship_ai->SetNavPoint(0); - } - else { - ClearRadioOrders(); - } - } - break; - - case RadioMessage::WEP_FREE: - roe = AGRESSIVE; - ship_ai->DropTarget(0.1); - break; - - case RadioMessage::WEP_HOLD: - case RadioMessage::FORM_UP: - roe = NONE; - ship_ai->DropTarget(5); - break; - - case RadioMessage::MOVE_PATROL: - roe = SELF_DEFENSIVE; - ship_ai->SetPatrol(orders->Location()); - ship_ai->SetNavPoint(0); - ship_ai->DropTarget(Random(5, 10)); - break; - - case RadioMessage::RTB: - case RadioMessage::DOCK_WITH: - roe = NONE; - - ship_ai->DropTarget(10); - - if (!ship->GetInbound()) { - RadioMessage* msg = 0; - Ship* controller = ship->GetController(); - - if (orders->Action() == RadioMessage::DOCK_WITH && orders->GetTarget()) { - controller = (Ship*) orders->GetTarget(); - } - - if (!controller) { - Element* elem = ship->GetElement(); - if (elem && elem->GetCommander()) { - Element* cmdr = elem->GetCommander(); - controller = cmdr->GetShip(1); - } - } - - if (controller && controller->GetHangar() && - controller->GetHangar()->CanStow(ship)) { - SimRegion* self_rgn = ship->GetRegion(); - SimRegion* rtb_rgn = controller->GetRegion(); - - if (self_rgn == rtb_rgn) { - double range = Point(controller->Location() - ship->Location()).length(); - - if (range < 50e3) { - msg = new RadioMessage(controller, ship, RadioMessage::CALL_INBOUND); - RadioTraffic::Transmit(msg); - } - } - } - else { - ship->ClearRadioOrders(); - } - - ship_ai->SetNavPoint(0); - } - break; - - case RadioMessage::QUANTUM_TO: - case RadioMessage::FARCAST_TO: - roe = NONE; - ship_ai->DropTarget(10); - break; - - } - - action = orders->Action(); - return true; - } - - // if we had an action before, this must be a "cancel orders" - else if (action) { - ClearRadioOrders(); - } - - return false; -} - -void -TacticalAI::ClearRadioOrders() -{ - action = 0; - roe = FLEXIBLE; - - if (ship_ai) - ship_ai->DropTarget(0.1); - - if (ship) - ship->ClearRadioOrders(); - -} - -// +--------------------------------------------------------------------+ - -bool -TacticalAI::CheckFlightPlan() -{ - Ship* ward = 0; - - // Find next Instruction: - navpt = ship->GetNextNavPoint(); - - roe = FLEXIBLE; - - if (navpt) { - switch (navpt->Action()) { - case Instruction::LAUNCH: - case Instruction::DOCK: - case Instruction::RTB: roe = NONE; - break; - - case Instruction::VECTOR: roe = SELF_DEFENSIVE; - break; - - case Instruction::DEFEND: - case Instruction::ESCORT: roe = DEFENSIVE; - break; - - case Instruction::INTERCEPT: - roe = DIRECTED; - break; - - case Instruction::RECON: - case Instruction::STRIKE: - case Instruction::ASSAULT: roe = DIRECTED; - break; - - case Instruction::PATROL: - case Instruction::SWEEP: roe = FLEXIBLE; - break; - - default: break; - } - - if (roe == DEFENSIVE) { - SimObject* tgt = navpt->GetTarget(); - - if (tgt && tgt->Type() == SimObject::SIM_SHIP) - ward = (Ship*) tgt; - } - - - if (navpt->EMCON() > 0) { - int desired_emcon = navpt->EMCON(); - - if (ship_ai && (ship_ai->GetThreat() || ship_ai->GetThreatMissile())) - desired_emcon = 3; - - if (ship->GetEMCON() != desired_emcon) - ship->SetEMCON(desired_emcon); - } - } - - if (ship_ai) - ship_ai->SetWard(ward); - - return (navpt != 0); -} - -// +--------------------------------------------------------------------+ - -void -TacticalAI::SelectTarget() -{ - if (!ship) { - roe = NONE; - return; - } - - // unarmed vessels should never engage an enemy: - if (ship->Weapons().size() < 1) - roe = NONE; - - SimObject* target = ship_ai->GetTarget(); - SimObject* ward = ship_ai->GetWard(); - - // if not allowed to engage, drop and return: - if (roe == NONE) { - if (target) - ship_ai->DropTarget(); - return; - } - - // if we have abandoned our ward, drop and return: - if (ward && roe != AGRESSIVE) { - double d = (ward->Location() - ship->Location()).length(); - double safe_zone = 50e3; - - if (target) { - if (ship->IsStarship()) - safe_zone = 100e3; - - if (d > safe_zone) { - ship_ai->DropTarget(); - return; - } - } - else { - if (d > safe_zone) { - return; - } - } - } - - // already have a target, keep it: - if (target) { - if (target->Life()) { - CheckTarget(); - - // frigates need to be ready to abandon ship-type targets - // in favor of drone-type targets, others should just go - // with what they have: - if (ship->Class() != Ship::CORVETTE && ship->Class() != Ship::FRIGATE) - return; - - // in case the check decided to drop the target: - target = ship_ai->GetTarget(); - } - - // if the old target is dead, forget it: - else { - ship_ai->DropTarget(); - target = 0; - } - } - - // if not allowed to acquire, forget it: - if (ship_ai->DropTime() > 0) - return; - - if (roe == DIRECTED) { - if (target && target->Type() == SimObject::SIM_SHIP) - SelectTargetDirected((Ship*) target); - else if (navpt && navpt->GetTarget() && navpt->GetTarget()->Type() == SimObject::SIM_SHIP) - SelectTargetDirected((Ship*) navpt->GetTarget()); - else - SelectTargetDirected(); - } - - else { - SelectTargetOpportunity(); - - // don't switch one ship target for another... - if (ship->Class() == Ship::CORVETTE || ship->Class() == Ship::FRIGATE) { - SimObject* potential_target = ship_ai->GetTarget(); - if (target && potential_target && target != potential_target) { - if (target->Type() == SimObject::SIM_SHIP && - potential_target->Type() == SimObject::SIM_SHIP) { - - ship_ai->SetTarget(target); - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalAI::SelectTargetDirected(Ship* tgt) -{ - Ship* potential_target = tgt; - - // try to target one of the element's objectives - // (if it shows up in the contact list) - - if (!tgt) { - Element* elem = ship->GetElement(); - - if (elem) { - Instruction* objective = elem->GetTargetObjective(); - - if (objective) { - SimObject* obj_sim_obj = objective->GetTarget(); - Ship* obj_tgt = 0; - - if (obj_sim_obj && obj_sim_obj->Type() == SimObject::SIM_SHIP) - obj_tgt = (Ship*) obj_sim_obj; - - if (obj_tgt) { - ListIter contact = ship->ContactList(); - while (++contact && !potential_target) { - Ship* test = contact->GetShip(); - - if (obj_tgt == test) { - potential_target = test; - } - } - } - } - } - } - - if (!CanTarget(potential_target)) - potential_target = 0; - - ship_ai->SetTarget(potential_target); - - if (tgt && tgt == ship_ai->GetTarget()) - directed_tgtid = tgt->Identity(); - else - directed_tgtid = 0; -} - -// +--------------------------------------------------------------------+ - -bool -TacticalAI::CanTarget(Ship* tgt) -{ - bool result = false; - - if (tgt && !tgt->InTransition()) { - if (tgt->IsRogue() || tgt->GetIFF() != ship->GetIFF()) - result = true; - } - - return result; -} - -// +--------------------------------------------------------------------+ - -void -TacticalAI::SelectTargetOpportunity() -{ - // NON-COMBATANTS do not pick targets of opportunity: - if (ship->GetIFF() == 0) - return; - - SimObject* potential_target = 0; - - // pick the closest combatant ship with a different IFF code: - double target_dist = ship->Design()->commit_range; - - SimObject* ward = ship_ai->GetWard(); - - // FRIGATES are primarily anti-air platforms, but may - // also attack smaller starships: - - if (ship->Class() == Ship::CORVETTE || ship->Class() == Ship::FRIGATE) { - Ship* current_ship_target = 0; - Shot* current_shot_target = 0; - - // if we are escorting a larger warship, it is good to attack - // the same target as our ward: - - if (ward) { - Ship* s = (Ship*) ward; - - if (s->Class() > ship->Class()) { - SimObject* obj = s->GetTarget(); - - if (obj && obj->Type() == SimObject::SIM_SHIP) { - current_ship_target = (Ship*) obj; - target_dist = (ship->Location() - obj->Location()).length(); - } - } - } - - ListIter contact = ship->ContactList(); - while (++contact) { - Ship* c_ship = contact->GetShip(); - Shot* c_shot = contact->GetShot(); - - if (!c_ship && !c_shot) - continue; - - int c_iff = contact->GetIFF(ship); - bool rogue = c_ship && c_ship->IsRogue(); - bool tgt_ok = c_iff > 0 && - c_iff != ship->GetIFF() && - c_iff < 1000; - - if (rogue || tgt_ok) { - if (c_ship && c_ship != ship && !c_ship->InTransition()) { - if (c_ship->Class() < Ship::DESTROYER || - (c_ship->Class() >= Ship::MINE && c_ship->Class() <= Ship::DEFSAT)) { - // found an enemy, check distance: - double dist = (ship->Location() - c_ship->Location()).length(); - - if (dist < 0.75 * target_dist && - (!current_ship_target || c_ship->Class() <= current_ship_target->Class())) { - current_ship_target = c_ship; - target_dist = dist; - } - } - } - - else if (c_shot) { - // found an enemy shot, is there enough time to engage? - if (c_shot->GetEta() < 3) - continue; - - // found an enemy shot, check distance: - double dist = (ship->Location() - c_shot->Location()).length(); - - if (!current_shot_target) { - current_shot_target = c_shot; - target_dist = dist; - } - - // is this shot a better target than the one we've found? - else { - Ship* ward = ship_ai->GetWard(); - - if ((c_shot->IsTracking(ward) || c_shot->IsTracking(ship)) && - (!current_shot_target->IsTracking(ward) || - !current_shot_target->IsTracking(ship))) { - current_shot_target = c_shot; - target_dist = dist; - } - else if (dist < target_dist) { - current_shot_target = c_shot; - target_dist = dist; - } - } - } - } - } - - if (current_shot_target) - potential_target = current_shot_target; - else - potential_target = current_ship_target; - } - - // ALL OTHER SHIP CLASSES ignore fighters and only engage - // other starships: - - else { - List ward_threats; - - ListIter contact = ship->ContactList(); - while (++contact) { - Ship* c_ship = contact->GetShip(); - - if (!c_ship) - continue; - - int c_iff = contact->GetIFF(ship); - bool rogue = c_ship->IsRogue(); - bool tgt_ok = c_ship != ship && - c_iff > 0 && - c_iff != ship->GetIFF() && - !c_ship->InTransition(); - - if (rogue || tgt_ok) { - if (c_ship->IsStarship() || c_ship->IsStatic()) { - // found an enemy, check distance: - double dist = (ship->Location() - c_ship->Location()).length(); - - if (dist < 0.75 * target_dist) { - potential_target = c_ship; - target_dist = dist; - } - - if (ward && c_ship->IsTracking(ward)) { - ward_threats.append(c_ship); - } - } - } - } - - // if this ship is protecting a ward, - // prefer targets that are threatening that ward: - if (potential_target && ward_threats.size() && !ward_threats.contains((Ship*)potential_target)) { - target_dist *= 2; - - ListIter iter = ward_threats; - while (++iter) { - Ship* threat = iter.value(); - - double dist = (ward->Location() - threat->Location()).length(); - - if (dist < target_dist) { - potential_target = threat; - target_dist = dist; - } - } - } - } - - if (ship->Class() != Ship::CARRIER && ship->Class() != Ship::SWACS) - ship_ai->SetTarget(potential_target); -} - -// +--------------------------------------------------------------------+ - -void -TacticalAI::CheckTarget() -{ - SimObject* tgt = ship_ai->GetTarget(); - - if (!tgt) return; - - if (tgt->GetRegion() != ship->GetRegion()) { - ship_ai->DropTarget(); - return; - } - - if (tgt->Type() == SimObject::SIM_SHIP) { - Ship* target = (Ship*) tgt; - - // has the target joined our side? - if (target->GetIFF() == ship->GetIFF() && !target->IsRogue()) { - ship_ai->DropTarget(); - return; - } - - // is the target already jumping/breaking/dying? - if (target->InTransition()) { - ship_ai->DropTarget(); - return; - } - - // have we been ordered to pursue the target? - if (directed_tgtid) { - if (directed_tgtid != target->Identity()) { - ship_ai->DropTarget(); - } - - return; - } - - // can we catch the target? - if (target->Design()->vlimit <= ship->Design()->vlimit || - ship->Velocity().length() <= ship->Design()->vlimit) - return; - - // is the target now out of range? - WeaponDesign* wep_dsn = ship->GetPrimaryDesign(); - if (!wep_dsn) - return; - - // compute the "give up" range: - double drop_range = 3 * wep_dsn->max_range; - if (drop_range > 0.75 * ship->Design()->commit_range) - drop_range = 0.75 * ship->Design()->commit_range; - - double range = Point(target->Location() - ship->Location()).length(); - if (range < drop_range) - return; - - // is the target closing or separating? - Point delta = (target->Location() + target->Velocity()) - - (ship->Location() + ship->Velocity()); - - if (delta.length() < range) - return; - - ship_ai->DropTarget(); - } - - else if (tgt->Type() == SimObject::SIM_DRONE) { - Drone* drone = (Drone*) tgt; - - // is the target still a threat? - if (drone->GetEta() < 1 || drone->GetTarget() == 0) - ship_ai->DropTarget(); - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalAI::FindThreat() -{ - // pick the closest contact on Threat Warning System: - Ship* threat = 0; - Shot* threat_missile = 0; - Ship* rumor = 0; - double threat_dist = 1e9; - const DWORD THREAT_REACTION_TIME = 1000; // 1 second - - ListIter iter = ship->ContactList(); - - while (++iter) { - Contact* contact = iter.value(); - - if (contact->Threat(ship) && - (Clock::GetInstance()->GameTime() - contact->AcquisitionTime()) > THREAT_REACTION_TIME) { - - if (contact->GetShot()) { - threat_missile = contact->GetShot(); - rumor = (Ship*) threat_missile->Owner(); - } - else { - double rng = contact->Range(ship); - - Ship* c_ship = contact->GetShip(); - if (c_ship && !c_ship->InTransition() && - c_ship->Class() != Ship::FREIGHTER && - c_ship->Class() != Ship::FARCASTER) { - - if (c_ship->GetTarget() == ship) { - if (!threat || c_ship->Class() > threat->Class()) { - threat = c_ship; - threat_dist = 0; - } - } - else if (rng < threat_dist) { - threat = c_ship; - threat_dist = rng; - } - } - } - } - } - - if (rumor && !rumor->InTransition()) { - iter.reset(); - - while (++iter) { - if (iter->GetShip() == rumor) { - rumor = 0; - ship_ai->ClearRumor(); - break; - } - } - } - else { - rumor = 0; - ship_ai->ClearRumor(); - } - - ship_ai->SetRumor(rumor); - ship_ai->SetThreat(threat); - ship_ai->SetThreatMissile(threat_missile); -} - -// +--------------------------------------------------------------------+ - -void -TacticalAI::FindSupport() -{ - if (!ship_ai->GetThreat()) { - ship_ai->SetSupport(0); - return; - } - - // pick the biggest friendly contact in the sector: - Ship* support = 0; - double support_dist = 1e9; - - ListIter contact = ship->ContactList(); - - while (++contact) { - if (contact->GetShip() && contact->GetIFF(ship) == ship->GetIFF()) { - Ship* c_ship = contact->GetShip(); - - if (c_ship != ship && c_ship->Class() >= ship->Class() && !c_ship->InTransition()) { - if (!support || c_ship->Class() > support->Class()) - support = c_ship; - } - } - } - - ship_ai->SetSupport(support); -} - -// +--------------------------------------------------------------------+ - -void -TacticalAI::FindFormationSlot(int formation) -{ - // find the formation delta: - int s = element_index - 1; - Point delta(10*s, 0, 10*s); - - // diamond: - if (formation == Instruction::DIAMOND) { - switch (element_index) { - case 2: delta = Point( 10, 0, -12); break; - case 3: delta = Point(-10, 0, -12); break; - case 4: delta = Point( 0, 0, -24); break; - } - } - - // spread: - if (formation == Instruction::SPREAD) { - switch (element_index) { - case 2: delta = Point( 15, 0, 0); break; - case 3: delta = Point(-15, 0, 0); break; - case 4: delta = Point(-30, 0, 0); break; - } - } - - // box: - if (formation == Instruction::BOX) { - switch (element_index) { - case 2: delta = Point(15, 0, 0); break; - case 3: delta = Point( 0, -1, -15); break; - case 4: delta = Point(15, -1, -15); break; - } - } - - // trail: - if (formation == Instruction::TRAIL) { - delta = Point(0, 0, -15*s); - } - - ship_ai->SetFormationDelta(delta * ship->Radius() * 2); -} diff --git a/Stars45/TacticalAI.h b/Stars45/TacticalAI.h deleted file mode 100644 index 116070c..0000000 --- a/Stars45/TacticalAI.h +++ /dev/null @@ -1,90 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Common base class and interface for mid-level (tactical) AI -*/ - -#ifndef TacticalAI_h -#define TacticalAI_h - -#include "Types.h" -#include "Director.h" - -// +--------------------------------------------------------------------+ - -class Ship; -class ShipAI; -class Instruction; -class CarrierAI; - -// +--------------------------------------------------------------------+ - -class TacticalAI : public Director -{ -public: - TacticalAI(ShipAI* ai); - virtual ~TacticalAI(); - - enum ROE { - NONE, - SELF_DEFENSIVE, - DEFENSIVE, - DIRECTED, - FLEXIBLE, - AGRESSIVE - }; - - virtual void ExecFrame(double seconds); - - virtual ROE RulesOfEngagement() const { return roe; } - virtual double ThreatLevel() const { return threat_level; } - virtual double SupportLevel() const { return support_level; } - -protected: - // pick the best target if we don't have one yet: - virtual void CheckOrders(); - virtual bool CheckShipOrders(); - virtual bool ProcessOrders(); - virtual bool CheckFlightPlan(); - virtual bool CheckObjectives(); - - virtual void SelectTarget(); - virtual void SelectTargetDirected(Ship* tgt=0); - virtual void SelectTargetOpportunity(); - virtual void CheckTarget(); - virtual void FindThreat(); - virtual void FindSupport(); - virtual void FindFormationSlot(int formation); - - virtual bool CanTarget(Ship* tgt); - virtual void ClearRadioOrders(); - - Ship* ship; - ShipAI* ship_ai; - CarrierAI* carrier_ai; - - Instruction* navpt; - Instruction* orders; - - double agression; - ROE roe; - int element_index; - int action; - int exec_time; - int directed_tgtid; - - double threat_level; - double support_level; -}; - -// +--------------------------------------------------------------------+ - -#endif // TacticalAI_h - diff --git a/Stars45/TacticalView.cpp b/Stars45/TacticalView.cpp deleted file mode 100644 index a631fad..0000000 --- a/Stars45/TacticalView.cpp +++ /dev/null @@ -1,1494 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Tactical Data Readout HUD Overlay -*/ - -#include "TacticalView.h" -#include "QuantumView.h" -#include "RadioView.h" -#include "RadioMessage.h" -#include "RadioTraffic.h" -#include "HUDSounds.h" -#include "HUDView.h" -#include "WepView.h" -#include "CameraDirector.h" -#include "Ship.h" -#include "ShipCtrl.h" -#include "ShipDesign.h" -#include "QuantumDrive.h" -#include "Farcaster.h" -#include "Instruction.h" -#include "Element.h" -#include "Contact.h" -#include "Sim.h" -#include "Starshatter.h" -#include "GameScreen.h" -#include "MenuView.h" - -#include "Projector.h" -#include "Color.h" -#include "Window.h" -#include "Video.h" -#include "DataLoader.h" -#include "Scene.h" -#include "FontMgr.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "MouseController.h" -#include "Menu.h" -#include "Clock.h" -#include "ContentBundle.h" -#include "FormatUtil.h" - -static Color hud_color = Color::Black; -static Color txt_color = Color::Black; - -// +--------------------------------------------------------------------+ - -TacticalView* TacticalView::tac_view = 0; - -// +--------------------------------------------------------------------+ - -TacticalView::TacticalView(Window* c, GameScreen* parent) -: View(c), gamescreen(parent), ship(0), camview(0), projector(0), -mouse_down(0), right_down(0), shift_down(0), -show_move(0), show_action(0), active_menu(0), menu_view(0), -msg_ship(0), base_alt(0), move_alt(0) -{ - tac_view = this; - sim = Sim::GetSim(); - - width = window->Width(); - height = window->Height(); - xcenter = (width / 2.0) - 0.5; - ycenter = (height / 2.0) + 0.5; - font = FontMgr::Find("HUD"); - - SetColor(Color::White); - - mouse_start.x = 0; - mouse_start.y = 0; - mouse_action.x = 0; - mouse_action.y = 0; - - menu_view = new MenuView(window); -} - -TacticalView::~TacticalView() -{ - delete menu_view; - tac_view = 0; -} - -void -TacticalView::OnWindowMove() -{ - width = window->Width(); - height = window->Height(); - xcenter = (width / 2.0) - 0.5; - ycenter = (height / 2.0) + 0.5; - - if (menu_view) - menu_view->OnWindowMove(); -} - -// +--------------------------------------------------------------------+ - -bool -TacticalView::Update(SimObject* obj) -{ - if (obj == ship) { - ship = 0; - } - - if (obj == msg_ship) { - msg_ship = 0; - } - - return SimObserver::Update(obj); -} - -const char* -TacticalView::GetObserverName() const -{ - return "TacticalView"; -} - -void -TacticalView::UseProjector(Projector* p) -{ - projector = p; -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::Refresh() -{ - sim = Sim::GetSim(); - - if (sim) { - bool rebuild = false; - - if (ship != sim->GetPlayerShip()) { - ship = sim->GetPlayerShip(); - - if (ship) { - if (ship->Life() == 0 || ship->IsDying() || ship->IsDead()) { - ship = 0; - } - else { - Observe(ship); - } - } - - rebuild = true; - } - - if (ship) { - if (current_sector != ship->GetRegion()->Name()) - rebuild = true; - - if (rebuild) { - BuildMenu(); - current_sector = ship->GetRegion()->Name(); - } - } - } - - if (!ship || ship->InTransition()) - return; - - DrawMouseRect(); - - if (sim) { - ListIter sel = sim->GetSelection(); - - if (sel.size()) { - while (++sel) { - Ship* selection = sel.value(); - - // draw selection rect on selected ship: - if (selection && selection->Rep()) - DrawSelection(selection); - } - - RadioView* rv = RadioView::GetInstance(); - QuantumView* qv = QuantumView::GetInstance(); - - if ((!rv || !rv->IsMenuShown()) && (!qv || !qv->IsMenuShown())) { - sel.reset(); - - if (sel.size() == 1) { - DrawSelectionInfo(sel.next()); - } - else { - DrawSelectionList(sel); - } - } - } - } - - DrawMenu(); - - if (show_move) { - Mouse::Show(false); - DrawMove(); - } - else if (show_action) { - Mouse::Show(false); - DrawAction(); - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::ExecFrame() -{ - HUDView* hud = HUDView::GetInstance(); - if (hud) { - if (hud_color != hud->GetTextColor()) { - hud_color = hud->GetTextColor(); - SetColor(hud_color); - } - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::SetColor(Color c) -{ - HUDView* hud = HUDView::GetInstance(); - - if (hud) { - hud_color = hud->GetHUDColor(); - txt_color = hud->GetTextColor(); - } - else { - hud_color = c; - txt_color = c; - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::DrawMouseRect() -{ - if (mouse_rect.w > 0 && mouse_rect.h > 0) { - Color c = hud_color * 0.66; - - if (shift_down) - c = Color::Orange; - - window->DrawRect(mouse_rect, c); - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::DrawSelection(Ship* seln) -{ - if (!seln) - return; - - Graphic* g = seln->Rep(); - Rect r = g->ScreenRect(); - - Point mark_pt = seln->Location(); - - projector->Transform(mark_pt); - - // clip: - if (mark_pt.z > 1.0) { - projector->Project(mark_pt); - - int x = (int) mark_pt.x; - int y = r.y; - - if (y >= 2000) - y = (int) mark_pt.y; - - if (x > 4 && x < width-4 && - y > 4 && y < height-4) { - - const int BAR_LENGTH = 40; - - // life bars: - int sx = x - BAR_LENGTH/2; - int sy = y - 8; - - double hull_strength = seln->HullStrength() / 100.0; - - int hw = (int) (BAR_LENGTH * hull_strength); - int sw = (int) (BAR_LENGTH * (seln->ShieldStrength() / 100.0)); - - if (hw < 0) hw = 0; - if (sw < 0) sw = 0; - - System::STATUS s = System::NOMINAL; - - if (hull_strength < 0.30) s = System::CRITICAL; - else if (hull_strength < 0.60) s = System::DEGRADED; - - Color hc = HUDView::GetStatusColor(s); - Color sc = hud_color; - - window->FillRect(sx, sy, sx+hw, sy+1, hc); - window->FillRect(sx, sy+3, sx+sw, sy+4, sc); - } - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::DrawSelectionInfo(Ship* seln) -{ - if (!ship || !seln) return; - - Rect label_rect(width-140, 10, 90, 12); - Rect info_rect(width-100, 10, 90, 12); - - if (width >= 800) { - label_rect.x -= 20; - info_rect.x -= 20; - info_rect.w += 20; - } - - static char name[64]; - static char design[64]; - static char shield[32]; - static char hull[32]; - static char range[32]; - static char heading[32]; - static char speed[32]; - static char orders[64]; - static char psv[32]; - static char act[32]; - - int show_labels = width > 640; - int full_info = true; - int shield_val = seln->ShieldStrength(); - int hull_val = seln->HullStrength(); - - if (shield_val < 0) shield_val = 0; - if (hull_val < 0) hull_val = 0; - - sprintf_s(name, "%s", seln->Name()); - - if (show_labels) { - sprintf_s(shield, "%s %03d", ContentBundle::GetInstance()->GetText("HUDView.symbol.shield").data(), shield_val); - sprintf_s(hull, "%s %03d", ContentBundle::GetInstance()->GetText("HUDView.symbol.hull").data(), hull_val); - } - else { - sprintf_s(shield, "%03d", shield_val); - sprintf_s(hull, "%03d", hull_val); - } - - FormatNumberExp(range, Point(seln->Location()-ship->Location()).length()/1000); - strcat_s(range, " km"); - sprintf_s(heading, "%03d %s", (int) (seln->CompassHeading() / DEGREES), ContentBundle::GetInstance()->GetText("HUDView.symbol.degrees").data()); - - double ss = seln->Velocity().length(); - if (seln->Velocity() * seln->Heading() < 0) - ss = -ss; - - FormatNumberExp(speed, ss); - strcat_s(speed, " m/s"); - - Contact* contact = 0; - - // always recognize ownside: - if (seln->GetIFF() != ship->GetIFF()) { - ListIter c = ship->ContactList(); - while (++c) { - if (c->GetShip() == seln) { - contact = c.value(); - if (c->GetIFF(ship) > seln->GetIFF()) { - sprintf_s(name, "%s %04d", ContentBundle::GetInstance()->GetText("TacView.contact").data(), seln->GetContactID()); - full_info = false; - } - - break; - } - } - } - - if (show_labels) { - font->SetColor(txt_color); - font->SetAlpha(1); - - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.name"), 5, label_rect, DT_LEFT); - label_rect.y += 10; - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.type"), 5, label_rect, DT_LEFT); - label_rect.y += 10; - - if (full_info) { - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.shield"), 5, label_rect, DT_LEFT); - label_rect.y += 10; - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.hull"), 5, label_rect, DT_LEFT); - label_rect.y += 10; - } - - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.range"), 4, label_rect, DT_LEFT); - label_rect.y += 10; - - if (full_info) { - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.speed"), 4, label_rect, DT_LEFT); - label_rect.y += 10; - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.heading"), 4, label_rect, DT_LEFT); - label_rect.y += 10; - } - else { - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.passive"), 4, label_rect, DT_LEFT); - label_rect.y += 10; - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.active"), 4, label_rect, DT_LEFT); - label_rect.y += 10; - } - } - - font->DrawText(name, 0, info_rect, DT_LEFT); - info_rect.y += 10; - - if (full_info) { - sprintf_s(design, "%s %s", seln->Abbreviation(), seln->Design()->display_name); - font->DrawText(design, 0, info_rect, DT_LEFT); - info_rect.y += 10; - } - else { - if (seln->IsStarship()) - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.starship"), 8, info_rect, DT_LEFT); - else - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.fighter"), 7, info_rect, DT_LEFT); - - info_rect.y += 10; - } - - if (full_info) { - font->DrawText(shield, 0, info_rect, DT_LEFT); - info_rect.y += 10; - - font->DrawText(hull, 0, info_rect, DT_LEFT); - info_rect.y += 10; - } - - font->DrawText(range, 0, info_rect, DT_LEFT); - info_rect.y += 10; - - if (full_info) { - font->DrawText(speed, 0, info_rect, DT_LEFT); - info_rect.y += 10; - - font->DrawText(heading, 0, info_rect, DT_LEFT); - info_rect.y += 10; - - if (seln->GetIFF() == ship->GetIFF()) { - Instruction* instr = seln->GetRadioOrders(); - if (instr && instr->Action()) { - strcpy_s(orders, RadioMessage::ActionName(instr->Action())); - - if (instr->Action() == RadioMessage::QUANTUM_TO) { - strcat_s(orders, " "); - strcat_s(orders, instr->RegionName()); - } - } - else { - *orders = 0; - } - - if (*orders) { - if (show_labels) { - font->DrawText(ContentBundle::GetInstance()->GetText("TacView.orders"), 5, label_rect, DT_LEFT); - label_rect.y += 10; - } - - font->DrawText(orders, 0, info_rect, DT_LEFT); - info_rect.y += 10; - } - } - } - else { - sprintf_s(psv, "%03d", (int) (contact->PasReturn() * 100.0)); - sprintf_s(act, "%03d", (int) (contact->ActReturn() * 100.0)); - - if (contact->Threat(ship)) - strcat_s(psv, " !"); - - font->DrawText(psv, 0, info_rect, DT_LEFT); - info_rect.y += 10; - font->DrawText(act, 0, info_rect, DT_LEFT); - info_rect.y += 10; - } - - /*** XXX DEBUG -font->DrawText(seln->GetDirectorInfo(), 0, info_rect, DT_LEFT); -info_rect.y += 10; -/***/ -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::DrawSelectionList(ListIter seln) -{ - int index = 0; - Rect info_rect(width-100, 10, 90, 12); - - while (++seln) { - char name[64]; - sprintf_s(name, "%s", seln->Name()); - - // always recognize ownside: - if (seln->GetIFF() != ship->GetIFF()) { - ListIter c = ship->ContactList(); - while (++c) { - if (c->GetShip() == seln.value()) { - if (c->GetIFF(ship) > seln->GetIFF()) { - sprintf_s(name, "%s %04d", ContentBundle::GetInstance()->GetText("TacView.contact").data(), seln->GetContactID()); - } - - break; - } - } - } - - font->DrawText(name, 0, info_rect, DT_LEFT); - info_rect.y += 10; - index++; - - if (index >= 10) - break; - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::DoMouseFrame() -{ - static DWORD rbutton_latch = 0; - - Starshatter* stars = Starshatter::GetInstance(); - - if (stars->InCutscene()) - return; - - if (Mouse::RButton()) { - MouseController* mouse_con = MouseController::GetInstance(); - if (!right_down && (!mouse_con || !mouse_con->Active())) { - rbutton_latch = Clock::GetInstance()->RealTime(); - right_down = true; - } - } - else { - if (sim && right_down && (Clock::GetInstance()->RealTime() - rbutton_latch < 250)) { - Ship* seln = WillSelectAt(Mouse::X(), Mouse::Y()); - - if (seln && sim->IsSelected(seln) && - seln->GetIFF() == ship->GetIFF() && - ship->GetElement()->CanCommand(seln->GetElement())) { - - msg_ship = seln; - Observe(msg_ship); - } - - else if (ship && seln == ship && - (!ship->GetDirector() || - ship->GetDirector()->Type() != ShipCtrl::DIR_TYPE)) { - - msg_ship = seln; - } - - else { - msg_ship = 0; - } - } - - right_down = false; - } - - if (menu_view) - menu_view->DoMouseFrame(); - - MouseController* mouse_con = MouseController::GetInstance(); - - if (!mouse_con || !mouse_con->Active()) { - if (Mouse::LButton()) { - if (!mouse_down) { - mouse_start.x = Mouse::X(); - mouse_start.y = Mouse::Y(); - - shift_down = Keyboard::KeyDown(VK_SHIFT); - } - - else { - if (Mouse::X() < mouse_start.x) { - mouse_rect.x = Mouse::X(); - mouse_rect.w = mouse_start.x - Mouse::X(); - } - else { - mouse_rect.x = mouse_start.x; - mouse_rect.w = Mouse::X() - mouse_start.x; - } - - if (Mouse::Y() < mouse_start.y) { - mouse_rect.y = Mouse::Y(); - mouse_rect.h = mouse_start.y - Mouse::Y(); - } - else { - mouse_rect.y = mouse_start.y; - mouse_rect.h = Mouse::Y() - mouse_start.y; - } - - // don't draw seln rectangle while zooming: - if (Mouse::RButton() || show_move || show_action) { - mouse_rect.w = 0; - mouse_rect.h = 0; - } - - else { - SelectRect(mouse_rect); - } - } - - mouse_down = true; - } - - else { - if (mouse_down) { - int mouse_x = Mouse::X(); - int mouse_y = Mouse::Y(); - - if (menu_view && menu_view->GetAction()) { - ProcessMenuItem(menu_view->GetAction()); - Mouse::Show(true); - } - else if (show_move) { - SendMove(); - show_move = false; - Mouse::Show(true); - } - else if (show_action) { - SendAction(); - show_action = false; - Mouse::Show(true); - } - else { - if (!HUDView::IsMouseLatched() && !WepView::IsMouseLatched()) { - int dx = (int) fabs((double) (mouse_x - mouse_start.x)); - int dy = (int) fabs((double) (mouse_y - mouse_start.y)); - - static DWORD click_time = 0; - - if (dx < 3 && dy < 3) { - bool hit = SelectAt(mouse_x, mouse_y); - - if (ship->IsStarship() && Clock::GetInstance()->RealTime() - click_time < 350) - SetHelm(hit); - - click_time = Clock::GetInstance()->RealTime(); - } - } - } - - mouse_rect = Rect(); - mouse_down = false; - } - } - } - - if (show_action && !mouse_down && !right_down) { - mouse_action.x = Mouse::X(); - mouse_action.y = Mouse::Y(); - } -} - -// +--------------------------------------------------------------------+ - -bool -TacticalView::SelectAt(int x, int y) -{ - if (!ship) return false; - - Ship* selection = WillSelectAt(x,y); - - if (selection && shift_down) - ship->SetTarget(selection); - - else if (sim && selection) - sim->SetSelection(selection); - - return selection != 0; -} - -// +--------------------------------------------------------------------+ - -bool -TacticalView::SelectRect(const Rect& rect) -{ - bool result = false; - - if (!ship || !sim) return result; - - if (rect.w > 8 || rect.h > 8) - sim->ClearSelection(); - - // check distance to each contact: - List& contact_list = ship->ContactList(); - - for (int i = 0; i < ship->NumContacts(); i++) { - Ship* test = contact_list[i]->GetShip(); - - if (test && test != ship) { - - Point test_loc = test->Location(); - projector->Transform(test_loc); - - if (test_loc.z > 1) { - projector->Project(test_loc); - - if (rect.Contains((int) test_loc.x, (int) test_loc.y)) { - // shift-select targets: - if (shift_down) { - if (test->GetIFF() == 0 || test->GetIFF() == ship->GetIFF()) - continue; - - ship->SetTarget(test); - result = true; - } - else { - sim->AddSelection(test); - result = true; - } - } - } - } - } - - // select self only in orbit cam - if (!shift_down && CameraDirector::GetCameraMode() == CameraDirector::MODE_ORBIT) { - Point test_loc = ship->Location(); - projector->Transform(test_loc); - - if (test_loc.z > 1) { - projector->Project(test_loc); - - if (rect.Contains((int) test_loc.x, (int) test_loc.y)) { - sim->AddSelection(ship); - result = true; - } - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -Ship* -TacticalView::WillSelectAt(int x, int y) -{ - Ship* selection = 0; - - if (ship) { - // check distance to each contact: - List& contact_list = ship->ContactList(); - - for (int i = 0; i < ship->NumContacts(); i++) { - Ship* test = contact_list[i]->GetShip(); - - if (test) { - // shift-select targets: - if (shift_down) { - if (test->GetIFF() == 0 || test->GetIFF() == ship->GetIFF()) - continue; - } - - Graphic* g = test->Rep(); - if (g) { - Rect r = g->ScreenRect(); - - if (r.x == 2000 && r.y == 2000 && r.w == 0 && r.h == 0) { - if (projector) { - Point loc = test->Location(); - projector->Transform(loc); - projector->Project(loc); - - r.x = (int) loc.x; - r.y = (int) loc.y; - } - } - - if (r.w < 20 || r.h < 20) - r.Inflate(20,20); - else - r.Inflate(10,10); - - if (r.Contains(x,y)) { - selection = test; - break; - } - } - } - } - - if (!selection && !shift_down) { - Graphic* g = ship->Rep(); - if (g) { - Rect r = g->ScreenRect(); - - if (r.Contains(x,y)) { - selection = ship; - } - } - } - } - - if (selection == ship && CameraDirector::GetCameraMode() != CameraDirector::MODE_ORBIT) - selection = 0; - - return selection; -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::SetHelm(bool approach) -{ - Point delta; - - // double-click on ship: set helm to approach - if (sim && approach) { - ListIter iter = sim->GetSelection(); - ++iter; - Ship* selection = iter.value(); - - if (selection != ship) { - delta = selection->Location() - ship->Location(); - delta.Normalize(); - } - } - - // double-click on space: set helm in direction - if (delta.length() < 1) { - int mx = Mouse::X(); - int my = Mouse::Y(); - - if (projector) { - double focal_dist = width / tan(projector->XAngle()); - - delta = projector->vpn() * focal_dist + - projector->vup() * -1 * (my-height/2) + - projector->vrt() * (mx-width/2); - - delta.Normalize(); - } - - else { - return; - } - } - - double az = atan2(fabs(delta.x), delta.z); - double el = asin(delta.y); - - if (delta.x < 0) - az *= -1; - - az += PI; - - if (az >= 2*PI) - az -= 2*PI; - - ship->SetHelmHeading(az); - ship->SetHelmPitch(el); -} - -// +====================================================================+ -// -// TACTICAL COMMUNICATIONS MENU: -// - -static Menu* main_menu = 0; -static Menu* view_menu = 0; -static Menu* emcon_menu = 0; - -static Menu* fighter_menu = 0; -static Menu* starship_menu = 0; -static Menu* action_menu = 0; -static Menu* formation_menu = 0; -static Menu* sensors_menu = 0; -static Menu* quantum_menu = 0; -static Menu* farcast_menu = 0; - -static Element* dst_elem = 0; - -enum VIEW_MENU { - VIEW_FORWARD = 1000, - VIEW_CHASE, - VIEW_PADLOCK, - VIEW_ORBIT, - VIEW_NAV, - VIEW_WEP, - VIEW_ENG, - VIEW_FLT, - VIEW_INS, - VIEW_CMD -}; - -const int QUANTUM = 2000; -const int FARCAST = 2001; - -void -TacticalView::Initialize() -{ - static int initialized = 0; - if (initialized) return; - - view_menu = new Menu(ContentBundle::GetInstance()->GetText("TacView.menu.view")); - view_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.forward"), VIEW_FORWARD); - view_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.chase"), VIEW_CHASE); - view_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.orbit"), VIEW_ORBIT); - view_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.padlock"), VIEW_PADLOCK); - - emcon_menu = new Menu(ContentBundle::GetInstance()->GetText("TacView.menu.emcon")); - - quantum_menu = new Menu(ContentBundle::GetInstance()->GetText("TacView.menu.quantum")); - farcast_menu = new Menu(ContentBundle::GetInstance()->GetText("TacView.menu.farcast")); - - main_menu = new Menu(ContentBundle::GetInstance()->GetText("TacView.menu.main")); - - action_menu = new Menu(ContentBundle::GetInstance()->GetText("TacView.menu.action")); - action_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.engage"), RadioMessage::ATTACK); - action_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.bracket"), RadioMessage::BRACKET); - action_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.escort"), RadioMessage::ESCORT); - action_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.identify"), RadioMessage::IDENTIFY); - action_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.hold"), RadioMessage::WEP_HOLD); - - formation_menu = new Menu(ContentBundle::GetInstance()->GetText("TacView.menu.formation")); - formation_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.diamond"), RadioMessage::GO_DIAMOND); - formation_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.spread"), RadioMessage::GO_SPREAD); - formation_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.box"), RadioMessage::GO_BOX); - formation_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.trail"), RadioMessage::GO_TRAIL); - - sensors_menu = new Menu(ContentBundle::GetInstance()->GetText("TacView.menu.emcon")); - sensors_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.emcon-1"), RadioMessage::GO_EMCON1); - sensors_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.emcon-2"), RadioMessage::GO_EMCON2); - sensors_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.emcon-3"), RadioMessage::GO_EMCON3); - sensors_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.probe"), RadioMessage::LAUNCH_PROBE); - - fighter_menu = new Menu(ContentBundle::GetInstance()->GetText("TacView.menu.context")); - fighter_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.action"), action_menu); - fighter_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.formation"), formation_menu); - fighter_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.sensors"), sensors_menu); - fighter_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.patrol"), RadioMessage::MOVE_PATROL); - fighter_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.cancel"), RadioMessage::RESUME_MISSION); - fighter_menu->AddItem("", 0); - fighter_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.rtb"), RadioMessage::RTB); - fighter_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.dock"), RadioMessage::DOCK_WITH); - fighter_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.farcast"), farcast_menu); - - starship_menu = new Menu(ContentBundle::GetInstance()->GetText("TacView.menu.context")); - starship_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.action"), action_menu); - starship_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.sensors"), sensors_menu); - starship_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.patrol"), RadioMessage::MOVE_PATROL); - starship_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.cancel"), RadioMessage::RESUME_MISSION); - starship_menu->AddItem("", 0); - starship_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.quantum"), quantum_menu); - starship_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.farcast"), farcast_menu); - - initialized = 1; -} - -void -TacticalView::Close() -{ - delete view_menu; - delete emcon_menu; - delete main_menu; - delete fighter_menu; - delete starship_menu; - delete action_menu; - delete formation_menu; - delete sensors_menu; - delete quantum_menu; - delete farcast_menu; -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::ProcessMenuItem(int action) -{ - Starshatter* stars = Starshatter::GetInstance(); - - switch (action) { - case RadioMessage::MOVE_PATROL: - show_move = true; - base_alt = 0; - move_alt = 0; - - if (msg_ship) base_alt = msg_ship->Location().y; - break; - - case RadioMessage::ATTACK: - case RadioMessage::BRACKET: - case RadioMessage::ESCORT: - case RadioMessage::IDENTIFY: - case RadioMessage::DOCK_WITH: - show_action = action; - break; - - case RadioMessage::WEP_HOLD: - case RadioMessage::RESUME_MISSION: - case RadioMessage::RTB: - case RadioMessage::GO_DIAMOND: - case RadioMessage::GO_SPREAD: - case RadioMessage::GO_BOX: - case RadioMessage::GO_TRAIL: - case RadioMessage::GO_EMCON1: - case RadioMessage::GO_EMCON2: - case RadioMessage::GO_EMCON3: - case RadioMessage::LAUNCH_PROBE: - if (msg_ship) { - Element* elem = msg_ship->GetElement(); - RadioMessage* msg = new RadioMessage(elem, ship, action); - if (msg) - RadioTraffic::Transmit(msg); - } - else if (ship) { - if (action == RadioMessage::GO_EMCON1) - ship->SetEMCON(1); - else if (action == RadioMessage::GO_EMCON2) - ship->SetEMCON(2); - else if (action == RadioMessage::GO_EMCON3) - ship->SetEMCON(3); - else if (action == RadioMessage::LAUNCH_PROBE) - ship->LaunchProbe(); - } - break; - - case VIEW_FORWARD: stars->PlayerCam(CameraDirector::MODE_COCKPIT); break; - case VIEW_CHASE: stars->PlayerCam(CameraDirector::MODE_CHASE); break; - case VIEW_PADLOCK: stars->PlayerCam(CameraDirector::MODE_TARGET); break; - case VIEW_ORBIT: stars->PlayerCam(CameraDirector::MODE_ORBIT); break; - - case VIEW_NAV: gamescreen->ShowNavDlg(); break; - case VIEW_WEP: gamescreen->ShowWeaponsOverlay(); break; - case VIEW_ENG: gamescreen->ShowEngDlg(); break; - case VIEW_INS: HUDView::GetInstance()->CycleHUDInst(); break; - case VIEW_FLT: gamescreen->ShowFltDlg(); break; - - case VIEW_CMD: if (ship && ship->IsStarship()) { - ship->CommandMode(); - } - break; - - case QUANTUM: if (sim) { - Ship* s = msg_ship; - - if (!s) - s = ship; - - if (s && s->GetQuantumDrive()) { - QuantumDrive* quantum = s->GetQuantumDrive(); - if (quantum) { - MenuItem* menu_item = menu_view->GetMenuItem(); - Text rgn_name = menu_item->GetText(); - SimRegion* rgn = sim->FindRegion(rgn_name); - - if (rgn) { - if (s == ship) { - quantum->SetDestination(rgn, Point(0,0,0)); - quantum->Engage(); - } - - else { - Element* elem = msg_ship->GetElement(); - RadioMessage* msg = new RadioMessage(elem, ship, RadioMessage::QUANTUM_TO); - if (msg) { - msg->SetInfo(rgn_name); - RadioTraffic::Transmit(msg); - } - } - } - } - } - } - break; - - case FARCAST: if (sim && msg_ship) { - MenuItem* menu_item = menu_view->GetMenuItem(); - Text rgn_name = menu_item->GetText(); - SimRegion* rgn = sim->FindRegion(rgn_name); - - if (rgn) { - Element* elem = msg_ship->GetElement(); - RadioMessage* msg = new RadioMessage(elem, ship, RadioMessage::FARCAST_TO); - if (msg) { - msg->SetInfo(rgn_name); - RadioTraffic::Transmit(msg); - } - } - } - break; - - default: - break; - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::BuildMenu() -{ - main_menu->ClearItems(); - quantum_menu->ClearItems(); - farcast_menu->ClearItems(); - emcon_menu->ClearItems(); - - if (!ship) - return; - - // prepare quantum and farcast menus: - ListIter iter = sim->GetRegions(); - while (++iter) { - SimRegion* rgn = iter.value(); - if (rgn != ship->GetRegion() && rgn->Type() != SimRegion::AIR_SPACE) - quantum_menu->AddItem(rgn->Name(), QUANTUM); - } - - if (ship->GetRegion()) { - ListIter iter = ship->GetRegion()->Ships(); - while (++iter) { - Ship* s = iter.value(); - - if (s && s->GetFarcaster()) { - Farcaster* farcaster = s->GetFarcaster(); - - // ensure that the farcaster is connected: - farcaster->ExecFrame(0); - - // now find the destination - const Ship* dest = farcaster->GetDest(); - - if (dest && dest->GetRegion()) { - SimRegion* rgn = dest->GetRegion(); - farcast_menu->AddItem(rgn->Name(), FARCAST); - } - } - } - } - - // build the main menu: - main_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.camera"), view_menu); - main_menu->AddItem("", 0); - main_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.instructions"), VIEW_INS); - main_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.navigation"), VIEW_NAV); - - if (ship->Design()->repair_screen) - main_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.engineering"), VIEW_ENG); - - if (ship->Design()->wep_screen) - main_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.weapons"), VIEW_WEP); - - if (ship->NumFlightDecks() > 0) - main_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.flight"), VIEW_FLT); - - emcon_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.emcon-1"), RadioMessage::GO_EMCON1); - emcon_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.emcon-2"), RadioMessage::GO_EMCON2); - emcon_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.emcon-3"), RadioMessage::GO_EMCON3); - - if (ship->GetProbeLauncher()) - emcon_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.probe"), RadioMessage::LAUNCH_PROBE); - - main_menu->AddItem("", 0); - main_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.sensors"), emcon_menu); - - if (sim && ship->GetQuantumDrive()) { - main_menu->AddItem("", 0); - main_menu->AddMenu(ContentBundle::GetInstance()->GetText("TacView.item.quantum"), quantum_menu); - } - - if (ship->IsStarship()) { - main_menu->AddItem("", 0); - main_menu->AddItem(ContentBundle::GetInstance()->GetText("TacView.item.command"), VIEW_CMD); - } -} - -// +--------------------------------------------------------------------+ - -void -TacticalView::DrawMenu() -{ - active_menu = 0; - - if (ship) - active_menu = main_menu; - - if (msg_ship) { - if (msg_ship->IsStarship()) - active_menu = starship_menu; - else if (msg_ship->IsDropship()) - active_menu = fighter_menu; - } - - if (menu_view) { - menu_view->SetBackColor(hud_color); - menu_view->SetTextColor(txt_color); - menu_view->SetMenu(active_menu); - menu_view->Refresh(); - } -} - -// +--------------------------------------------------------------------+ - -bool -TacticalView::GetMouseLoc3D() -{ - int mx = Mouse::X(); - int my = Mouse::Y(); - - if (projector) { - double focal_dist = width / tan(projector->XAngle()); - Point focal_vect = projector->vpn() * focal_dist + - projector->vup() * -1 * (my-height/2) + - projector->vrt() * (mx-width/2); - - focal_vect.Normalize(); - - if (Keyboard::KeyDown(VK_SHIFT)) { - if (Mouse::RButton()) - return true; - - if (fabs(focal_vect.x) > fabs(focal_vect.z)) { - double dx = move_loc.x - projector->Pos().x; - double t = -1 * ((projector->Pos().x - dx) / focal_vect.x); - - if (t > 0) { - Point p = projector->Pos() + focal_vect * t; - move_alt = p.y - base_alt; - } - } - else { - double dz = move_loc.z - projector->Pos().z; - double t = -1 * ((projector->Pos().z - dz) / focal_vect.z); - Point p = projector->Pos() + focal_vect * t; - - if (t > 0) { - Point p = projector->Pos() + focal_vect * t; - move_alt = p.y - base_alt; - } - } - - if (move_alt > 25e3) - move_alt = 25e3; - else if (move_alt < -25e3) - move_alt = -25e3; - - return true; - } - else { - if (fabs(focal_vect.y) > 1e-5) { - if (Mouse::RButton()) - return true; - - bool clamp = false; - double t = -1 * ((projector->Pos().y - base_alt) / focal_vect.y); - - while (t <= 0 && my < height-1) { - my++; - clamp = true; - - focal_vect = projector->vpn() * focal_dist + - projector->vup() * -1 * (my-height/2) + - projector->vrt() * (mx-width/2); - - focal_vect.Normalize(); - t = -1 * ((projector->Pos().y - base_alt) / focal_vect.y); - } - - if (t > 0) { - if (clamp) - Mouse::SetCursorPos(mx, my); - - move_loc = projector->Pos() + focal_vect * t; - } - - return true; - } - } - } - - return false; -} - -void -TacticalView::DrawMove() -{ - if (!projector || !show_move || !msg_ship) return; - - Point origin = msg_ship->Location(); - - if (GetMouseLoc3D()) { - Point dest = move_loc; - - double distance = (dest - origin).length(); - - projector->Transform(origin); - projector->Project(origin); - - int x0 = (int) origin.x; - int y0 = (int) origin.y; - - projector->Transform(dest); - projector->Project(dest); - - int x = (int) dest.x; - int y = (int) dest.y; - - window->DrawEllipse(x-10, y-10, x+10, y+10, Color::White); - window->DrawLine(x0, y0, x, y, Color::White); - - char range[32]; - Rect range_rect(x+12, y-8, 120, 20); - - if (fabs(move_alt) > 1) { - dest = move_loc; - dest.y += move_alt; - distance = (dest - msg_ship->Location()).length(); - - projector->Transform(dest); - projector->Project(dest); - - int x1 = (int) dest.x; - int y1 = (int) dest.y; - - window->DrawEllipse(x1-10, y1-10, x1+10, y1+10, Color::White); - window->DrawLine(x0, y0, x1, y1, Color::White); - window->DrawLine(x1, y1, x, y, Color::White); - - range_rect.x = x1+12; - range_rect.y = y1-8; - } - - FormatNumber(range, distance); - font->SetColor(Color::White); - font->DrawText(range, 0, range_rect, DT_LEFT | DT_SINGLELINE); - font->SetColor(txt_color); - } -} - -void -TacticalView::SendMove() -{ - if (!projector || !show_move || !msg_ship) return; - - if (GetMouseLoc3D()) { - Element* elem = msg_ship->GetElement(); - RadioMessage* msg = new RadioMessage(elem, ship, RadioMessage::MOVE_PATROL); - Point dest = move_loc; - dest.y += move_alt; - msg->SetLocation(dest); - RadioTraffic::Transmit(msg); - HUDSounds::PlaySound(HUDSounds::SND_TAC_ACCEPT); - } -} - -// +--------------------------------------------------------------------+ - -static int invalid_action = false; - -void -TacticalView::DrawAction() -{ - if (!projector || !show_action || !msg_ship) return; - - Point origin = msg_ship->Location(); - projector->Transform(origin); - projector->Project(origin); - - int x0 = (int) origin.x; - int y0 = (int) origin.y; - - int mx = mouse_action.x; - int my = mouse_action.y; - int r = 10; - - int enemy = 2; - if (ship->GetIFF() > 1) - enemy = 1; - - Ship* tgt = WillSelectAt(mx, my); - int tgt_iff = 0; - - if (tgt) - tgt_iff = tgt->GetIFF(); - - Color c = Color::White; - - switch (show_action) { - case RadioMessage::ATTACK: - case RadioMessage::BRACKET: - c = Ship::IFFColor(enemy); - if (tgt) { - if (tgt_iff == ship->GetIFF() || tgt_iff == 0) - r = 0; - } - break; - - case RadioMessage::ESCORT: - case RadioMessage::DOCK_WITH: - c = ship->MarkerColor(); - if (tgt) { - if (tgt_iff == enemy) - r = 0; - - // must have a hangar to dock with... - if (show_action == RadioMessage::DOCK_WITH && tgt->GetHangar() == 0) - r = 0; - } - break; - - default: - if (tgt) { - if (tgt_iff == ship->GetIFF()) - r = 0; - } - break; - } - - if (tgt && r) { - if ((Clock::GetInstance()->RealTime()/200) & 1) - r = 20; - else - r = 15; - } - - if (r) { - invalid_action = false; - window->DrawEllipse(mx-r, my-r, mx+r, my+r, c); - } - - else { - invalid_action = true; - window->DrawLine(mx-10, my-10, mx+10, my+10, c); - window->DrawLine(mx+10, my-10, mx-10, my+10, c); - } - - window->DrawLine(x0, y0, mx, my, c); -} - -void -TacticalView::SendAction() -{ - if (!show_action || !msg_ship || invalid_action) { - HUDSounds::PlaySound(HUDSounds::SND_TAC_REJECT); - return; - } - - int mx = mouse_action.x; - int my = mouse_action.y; - - Ship* tgt = WillSelectAt(mx, my); - - if (tgt) { - Element* elem = msg_ship->GetElement(); - RadioMessage* msg = new RadioMessage(elem, ship, show_action); - - /*** - Element* tgt_elem = tgt->GetElement(); - - if (tgt_elem) { - for (int i = 1; i <= tgt_elem->NumShips(); i++) - msg->AddTarget(tgt_elem->GetShip(i)); - } - else { - msg->AddTarget(tgt); - } - ***/ - - msg->AddTarget(tgt); - - RadioTraffic::Transmit(msg); - HUDSounds::PlaySound(HUDSounds::SND_TAC_ACCEPT); - } - else { - HUDSounds::PlaySound(HUDSounds::SND_TAC_REJECT); - } -} - - diff --git a/Stars45/TacticalView.h b/Stars45/TacticalView.h deleted file mode 100644 index 448a5cc..0000000 --- a/Stars45/TacticalView.h +++ /dev/null @@ -1,119 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Radio Communications HUD Overlay -*/ - -#ifndef TacticalView_h -#define TacticalView_h - -#include "Types.h" -#include "View.h" -#include "Color.h" -#include "SimObject.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Font; -class Ship; -class RadioMessage; -class CameraView; -class Projector; -class HUDView; -class Menu; -class MenuItem; -class MenuView; -class GameScreen; - -// +--------------------------------------------------------------------+ - -class TacticalView : public View, -public SimObserver -{ -public: - TacticalView(Window* c, GameScreen* parent); - virtual ~TacticalView(); - - // Operations: - virtual void Refresh(); - virtual void OnWindowMove(); - virtual void ExecFrame(); - virtual void UseProjector(Projector* p); - - virtual void DoMouseFrame(); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - static void SetColor(Color c); - - static void Initialize(); - static void Close(); - - static TacticalView* GetInstance() { return tac_view; } - -protected: - virtual bool SelectAt(int x, int y); - virtual bool SelectRect(const Rect& r); - virtual Ship* WillSelectAt(int x, int y); - virtual void SetHelm(bool approach); - - virtual void DrawMouseRect(); - virtual void DrawSelection(Ship* seln); - virtual void DrawSelectionInfo(Ship* seln); - virtual void DrawSelectionList(ListIter seln); - - virtual void BuildMenu(); - virtual void DrawMenu(); - virtual void ProcessMenuItem(int action); - - virtual void DrawMove(); - virtual void SendMove(); - virtual bool GetMouseLoc3D(); - - virtual void DrawAction(); - virtual void SendAction(); - - GameScreen* gamescreen; - CameraView* camview; - Projector* projector; - - int width, height; - double xcenter, ycenter; - - int shift_down; - int mouse_down; - int right_down; - int show_move; - int show_action; - - Point move_loc; - double base_alt; - double move_alt; - - POINT mouse_action; - POINT mouse_start; - Rect mouse_rect; - - Font* font; - Sim* sim; - Ship* ship; - Ship* msg_ship; - Text current_sector; - - Menu* active_menu; - MenuView* menu_view; - - static TacticalView* tac_view; -}; - -#endif // TacticalView_h - diff --git a/Stars45/Term.cpp b/Stars45/Term.cpp deleted file mode 100644 index acd2c74..0000000 --- a/Stars45/Term.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Implementation of the Term class -*/ - - -#include "Term.h" -#include "Utils.h" - -// +-------------------------------------------------------------------+ - -Term* -error(char* s1, char* s2) -{ - Print("ERROR: "); - if (s1) Print(s1); - if (s2) Print(s2); - Print("\n\n"); - return 0; -} - -// +-------------------------------------------------------------------+ - -void TermBool::print(int level) { if (level > 0) Print(val? "true" : "false"); else Print("..."); } -void TermNumber::print(int level){ if (level > 0) Print("%g", val); else Print("..."); } -void TermText::print(int level) { if (level > 0) Print("\"%s\"", val.data()); else Print("..."); } - -// +-------------------------------------------------------------------+ - -TermArray::TermArray(TermList* elist) -{ - elems = elist; -} - -TermArray::~TermArray() -{ - if (elems) elems->destroy(); - delete elems; -} - -void -TermArray::print(int level) -{ - if (level > 1) { - Print("("); - - if (elems) { - for (int i = 0; i < elems->size(); i++) { - elems->at(i)->print(level-1); - if (i < elems->size() -1) - Print(", "); - } - } - - Print(") "); - } - else Print("(...) "); -} - -// +-------------------------------------------------------------------+ - -TermStruct::TermStruct(TermList* elist) -{ - elems = elist; -} - -TermStruct::~TermStruct() -{ - if (elems) elems->destroy(); - delete elems; -} - -void -TermStruct::print(int level) -{ - if (level > 1) { - Print("{"); - - if (elems) { - for (int i = 0; i < elems->size(); i++) { - elems->at(i)->print(level-1); - if (i < elems->size() -1) - Print(", "); - } - } - - Print("} "); - } - else Print("{...} "); -} - -// +-------------------------------------------------------------------+ - -TermDef::~TermDef() -{ - delete mname; - delete mval; -} - -void -TermDef::print(int level) -{ - if (level >= 0) { - mname->print(level); - Print(": "); - mval->print(level-1); - } - else Print("..."); -} - -// +-------------------------------------------------------------------+ diff --git a/Stars45/Term.h b/Stars45/Term.h deleted file mode 100644 index 79e2fc3..0000000 --- a/Stars45/Term.h +++ /dev/null @@ -1,171 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Declaration of the Abstract Syntax Tree classes -*/ - - -#ifndef TERM_H -#define TERM_H - -#include "Text.h" -#include "List.h" - -// +-------------------------------------------------------------------+ - -class Term; -class TermBool; -class TermNumber; -class TermText; -class TermArray; -class TermDef; -class TermStruct; - -// +-------------------------------------------------------------------+ - -class Term -{ -public: - static const char* TYPENAME() { return "Term"; } - - Term() { } - virtual ~Term() { } - - virtual int operator==(const Term& rhs) const { return 0; } - - virtual void print(int level=10) { } - - // conversion tests - virtual Term* touch() { return this; } - virtual TermBool* isBool() { return 0; } - virtual TermNumber* isNumber() { return 0; } - virtual TermText* isText() { return 0; } - virtual TermArray* isArray() { return 0; } - virtual TermDef* isDef() { return 0; } - virtual TermStruct* isStruct() { return 0; } -}; - -Term* error(char*, char* = 0); - -// +-------------------------------------------------------------------+ - -typedef List TermList; -typedef ListIter TermListIter; - -// +-------------------------------------------------------------------+ - -class TermBool : public Term -{ -public: - static const char* TYPENAME() { return "TermBool"; } - - TermBool(bool v) : val(v) { } - - virtual void print(int level=10); - virtual TermBool* isBool() { return this; } - bool value() const { return val; } - -private: - bool val; -}; - -// +-------------------------------------------------------------------+ - -class TermNumber : public Term -{ -public: - static const char* TYPENAME() { return "TermNumber"; } - - TermNumber(double v) : val(v) { } - - virtual void print(int level=10); - virtual TermNumber* isNumber() { return this; } - double value() const { return val; } - -private: - double val; -}; - -// +-------------------------------------------------------------------+ - -class TermText : public Term -{ -public: - static const char* TYPENAME() { return "TermText"; } - - TermText(const Text& v) : val(v) { } - - virtual void print(int level=10); - virtual TermText* isText() { return this; } - Text value() const { return val; } - -private: - Text val; -}; - -// +-------------------------------------------------------------------+ - -class TermArray : public Term -{ -public: - static const char* TYPENAME() { return "TermArray"; } - - TermArray(TermList* elist); - virtual ~TermArray(); - - virtual void print(int level=10); - virtual TermArray* isArray() { return this; } - TermList* elements() { return elems; } - -private: - TermList* elems; -}; - -// +-------------------------------------------------------------------+ - -class TermStruct : public Term -{ -public: - static const char* TYPENAME() { return "TermStruct"; } - - TermStruct(TermList* elist); - virtual ~TermStruct(); - - virtual void print(int level=10); - - virtual TermStruct* isStruct() { return this; } - TermList* elements() { return elems; } - -private: - TermList* elems; -}; - -// +-------------------------------------------------------------------+ - -class TermDef : public Term -{ -public: - static const char* TYPENAME() { return "TermDef"; } - - TermDef(TermText* n, Term* v) : mname(n), mval(v) { } - virtual ~TermDef(); - - virtual void print(int level=10); - virtual TermDef* isDef() { return this; } - - virtual TermText* name() { return mname; } - virtual Term* term() { return mval; } - -private: - TermText* mname; - Term* mval; -}; - -#endif diff --git a/Stars45/Terrain.cpp b/Stars45/Terrain.cpp deleted file mode 100644 index 4d0a5f9..0000000 --- a/Stars45/Terrain.cpp +++ /dev/null @@ -1,559 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "Terrain.h" -#include "TerrainApron.h" -#include "TerrainClouds.h" -#include "TerrainLayer.h" -#include "TerrainPatch.h" -#include "TerrainRegion.h" -#include "Water.h" - -#include "CameraView.h" -#include "Projector.h" -#include "Scene.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Game.h" -#include "MachineInfo.h" - -// +--------------------------------------------------------------------+ - -int Terrain::detail_level = 3; // default = MEDIUM DETAIL - -const int PATCH_SIZE = 16; - -// +--------------------------------------------------------------------+ - -Terrain::Terrain(TerrainRegion* trgn) -: region(trgn), patches(0), water_patches(0), water(0), -aprons(0), clouds(0), terrain_normals(0) -{ - detail_frame = 0; - datapath = "Galaxy/"; - terrain_texture = 0; - apron_texture = 0; - water_texture = 0; - - for (int i = 0; i < 2; i++) { - cloud_texture[i] = 0; - shade_texture[i] = 0; - noise_texture[i] = 0; - } - - if (region) { - scale = region->LateralScale(); - mtnscale = region->MountainScale(); - - ListIter iter = region->GetLayers(); - while (++iter) { - TerrainLayer* orig = iter.value(); - TerrainLayer* copy = new TerrainLayer; - *copy = *orig; - layers.append(copy); - } - - layers.sort(); - } - - else { - scale = 1; - mtnscale = 1; - } -} - -// +--------------------------------------------------------------------+ - -Terrain::~Terrain() -{ - int i, j; - - if (patches) - for (i = 0; i < subdivisions; i++) - for (j = 0; j < subdivisions; j++) - GRAPHIC_DESTROY(patches[i*subdivisions+j]); - - if (water_patches) - for (i = 0; i < subdivisions; i++) - for (j = 0; j < subdivisions; j++) - GRAPHIC_DESTROY(water_patches[i*subdivisions+j]); - - if (aprons) - for (i = 0; i < 8; i++) - GRAPHIC_DESTROY(aprons[i]); - - if (clouds) - for (i = 0; i < nclouds; i++) - GRAPHIC_DESTROY(clouds[i]); - - if (water) - for (i = 0; i < 6; i++) - delete water[i]; - - delete [] aprons; - delete [] clouds; - delete [] patches; - delete [] water; - delete [] terrain_normals; - - terrain_patch.ClearImage(); - terrain_apron.ClearImage(); - - layers.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -Terrain::BuildTerrain() -{ - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(datapath); - loader->LoadBitmap( region->PatchName(), terrain_patch); - loader->LoadBitmap( region->ApronName(), terrain_apron); - loader->LoadTexture(region->PatchTexture(), terrain_texture); - loader->LoadTexture(region->ApronTexture(), apron_texture); - if (region->WaterTexture().length()) { - loader->LoadTexture(region->WaterTexture(), water_texture); - - if (region->EnvironmentTexture(0).length() > 0) { - loader->LoadTexture(region->EnvironmentTexture(0), env_texture[0]); - loader->LoadTexture(region->EnvironmentTexture(1), env_texture[1]); - loader->LoadTexture(region->EnvironmentTexture(2), env_texture[2]); - loader->LoadTexture(region->EnvironmentTexture(3), env_texture[3]); - loader->LoadTexture(region->EnvironmentTexture(4), env_texture[4]); - loader->LoadTexture(region->EnvironmentTexture(5), env_texture[5]); - } - } - - loader->LoadTexture(region->CloudsHigh(), cloud_texture[0], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture(region->CloudsLow(), cloud_texture[1], Bitmap::BMP_TRANSLUCENT); - loader->LoadTexture(region->ShadesLow(), shade_texture[1], Bitmap::BMP_TRANSLUCENT); - - if (region->DetailTexture0().length()) - loader->LoadTexture(region->DetailTexture0(),noise_texture[0], Bitmap::BMP_TRANSLUCENT, false, true); - - if (region->DetailTexture1().length()) - loader->LoadTexture(region->DetailTexture1(),noise_texture[1], Bitmap::BMP_TRANSLUCENT, false, true); - - subdivisions = terrain_patch.Width() / PATCH_SIZE; - patch_size = terrain_patch.Width() / subdivisions; - - BuildNormals(); - - int i, j; - int ntiles = terrain_patch.Width()/2 * terrain_patch.Height()/2; - double dx = scale * patch_size; - double dz = scale * patch_size; - double offset = -subdivisions/2; - - if (water_texture) { - water = new Water*[6]; - for (i = 0; i < 6; i++) { - water[i] = new Water(); - int n = (1<Init(n, (float) (scale*patch_size), 90.0f); - } - } - - // load tile textures: - for (i = 0; i < layers.size(); i++) { - TerrainLayer* layer = layers.at(i); - - if (i < layers.size()-1) - layer->max_height = layers.at(i+1)->min_height; - else - layer->max_height = 1e6; - - if (layer->tile_name.length()) - loader->LoadTexture(layer->tile_name, layer->tile_texture); - - if (layer->detail_name.length()) - loader->LoadTexture(layer->detail_name, layer->detail_texture); - } - - patches = new TerrainPatch*[subdivisions*subdivisions]; - - if (water_texture) - water_patches = new TerrainPatch*[subdivisions*subdivisions]; - - for (i = 0; i < subdivisions; i++) { - for (j = 0; j < subdivisions; j++) { - int j1 = subdivisions - j; - Rect rect(j * patch_size, i * patch_size, patch_size, patch_size); - Point p1((j1 + offset )*dx, 0, (i + offset )*dz); - Point p2((j1 + offset+1)*dx, mtnscale, (i + offset+1)*dz); - - int index = i*subdivisions+j; - patches[index] = new TerrainPatch(this, &terrain_patch, rect, p1, p2); - - if (water_texture && patches[index]->MinHeight() < 3) - water_patches[index] = new TerrainPatch(this, rect, p1, p2, 30); - - else if (water_patches != 0) - water_patches[index] = 0; - } - } - - int a = 0; - dx = scale * terrain_patch.Width(); - dz = scale * terrain_patch.Height(); - offset = -3.0/2; - double xoffset = offset + 1.0/16.0; - - aprons = new TerrainApron*[8]; - - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - int j1 = 2 - j; - if (i != 1 || j1 != 1) { - Rect rect(j * subdivisions, i * subdivisions, subdivisions, subdivisions); - Point p1((j1 + xoffset )*dx, 0, (i + offset )*dz); - Point p2((j1 + xoffset+1)*dx, mtnscale, (i + offset+1)*dz); - - aprons[a++] = new TerrainApron(this, &terrain_apron, rect, p1, p2); - } - } - } - - Weather::STATE state = region->GetWeather().State(); - - if (state == Weather::HIGH_CLOUDS || state == Weather::MODERATE_CLOUDS) { - double altitude = region->CloudAltHigh(); - nclouds = 9; - - if (state == Weather::MODERATE_CLOUDS) - nclouds *= 2; - - clouds = new TerrainClouds*[nclouds]; - - a = 0; - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - clouds[a] = new TerrainClouds(this, 0); - - double xloc = (j-1) * 75000 + (rand()/32768.0 - 0.5) * 50000; - double yloc = (i-1) * 75000 + (rand()/32768.0 - 0.5) * 50000; - - clouds[a]->MoveTo(Point(xloc, altitude, yloc)); - a++; - } - } - - if (state == Weather::MODERATE_CLOUDS) { - altitude = region->CloudAltLow(); - - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - clouds[a] = new TerrainClouds(this, 1); - - double xloc = (j-1) * 75000 + (rand()/32768.0 - 0.5) * 50000; - double yloc = (i-1) * 75000 + (rand()/32768.0 - 0.5) * 50000; - - clouds[a]->MoveTo(Point(xloc, altitude, yloc)); - a++; - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Terrain::BuildNormals() -{ - if (terrain_normals) { - delete [] terrain_normals; - terrain_normals = 0; - } - - int i, x, y; - - int w = terrain_patch.Width(); - int h = terrain_patch.Height(); - Color* pix = terrain_patch.HiPixels(); - BYTE* alt = new BYTE[h*w]; - int nverts = w * h; - double scale = region->MountainScale() / (region->LateralScale() * 2.0); - - terrain_normals = new Vec3B[nverts]; - - ZeroMemory(terrain_normals, sizeof(Vec3B) * nverts); - - for (i = 0; i < w; i++) { - alt [ i] = 0; - alt [(h-1)*w + i] = 0; - terrain_normals[ i] = Vec3B(128,128,255); - terrain_normals[(h-1)*w + i] = Vec3B(128,128,255); - } - - for (i = 0; i < h; i++) { - alt [i*w ] = 0; - alt [i*w + (w-1)] = 0; - terrain_normals[i*w ] = Vec3B(128,128,255); - terrain_normals[i*w + (w-1)] = Vec3B(128,128,255); - } - - for (y = 1; y < h-1; y++) { - for (x = 1; x < w-1; x++) { - alt[y*w+x] = (BYTE) pix[y*w+x].Red(); - } - } - - for (y = 1; y < h-1; y++) { - for (x = 1; x < w-1; x++) { - double dx = (alt[y*w + (x-1)] - alt[y*w + (x+1)]) * scale + - (alt[(y-1)*w + (x-1)] - alt[(y-1)*w + (x+1)]) * scale * 0.5 + - (alt[(y+1)*w + (x-1)] - alt[(y+1)*w + (x+1)]) * scale * 0.5; - - double dy = (alt[(y-1)*w + x ] - alt[(y+1)*w + x ]) * scale + - (alt[(y-1)*w + (x-1)] - alt[(y+1)*w + (x-1)]) * scale * 0.5 + - (alt[(y-1)*w + (x+1)] - alt[(y+1)*w + (x+1)]) * scale * 0.5; - - Point norm(dx,dy,1); - norm.Normalize(); - - Vec3B* tnorm = &terrain_normals[y*w + x]; - - tnorm->x = (BYTE) (norm.x * 127 + 128); - tnorm->y = (BYTE) (norm.y * 127 + 128); - tnorm->z = (BYTE) (norm.z * 127 + 128); - - double foo = dx/dy; - } - } - - delete [] alt; -} - -// +--------------------------------------------------------------------+ - -void -Terrain::Activate(Scene& scene) -{ - int i, j; - - StarSystem* system = region->System(); - if (system) - datapath = system->GetDataPath(); - - region->GetWeather().Update(); - - if (!patches) - BuildTerrain(); - - if (patches) { - for (i = 0; i < subdivisions; i++) - for (j = 0; j < subdivisions; j++) - if (patches[i*subdivisions+j]) - scene.AddGraphic(patches[i*subdivisions+j]); - } - - if (water_patches) { - for (i = 0; i < subdivisions; i++) - for (j = 0; j < subdivisions; j++) - if (water_patches[i*subdivisions+j]) - scene.AddGraphic(water_patches[i*subdivisions+j]); - } - - if (aprons) { - for (i = 0; i < 8; i++) - if (aprons[i]) - scene.AddGraphic(aprons[i]); - } - - if (clouds) { - for (i = 0; i < nclouds; i++) - if (clouds[i]) - scene.AddGraphic(clouds[i]); - } -} - -void -Terrain::Deactivate(Scene& scene) -{ - int i, j; - - if (patches) { - for (i = 0; i < subdivisions; i++) { - for (j = 0; j < subdivisions; j++) { - TerrainPatch* p = patches[i*subdivisions+j]; - - if (p) { - p->DeletePrivateData(); - scene.DelGraphic(p); - } - } - } - } - - if (water_patches) { - for (i = 0; i < subdivisions; i++) { - for (j = 0; j < subdivisions; j++) { - TerrainPatch* p = water_patches[i*subdivisions+j]; - - if (p) { - p->DeletePrivateData(); - scene.DelGraphic(p); - } - } - } - } - - if (aprons) { - for (i = 0; i < 8; i++) - if (aprons[i]) - scene.DelGraphic(aprons[i]); - } - - if (clouds) { - for (i = 0; i < nclouds; i++) - if (clouds[i]) - scene.DelGraphic(clouds[i]); - } - - StarSystem* system = region->System(); - - // restore sunlight color and brightness on exit: - if (system) { - system->RestoreTrueSunColor(); - } -} - -// +--------------------------------------------------------------------+ - -void -Terrain::ExecFrame(double seconds) -{ - if (water) { - for (int i = 0; i < 6; i++) { - if (water[i]) - water[i]->CalcWaves(seconds); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Terrain::SelectDetail(Projector* projector) -{ - if (!patches) - return; - - if (detail_frame >= Game::GetInstance()->Frame()) - return; - - // compute detail map: - int x, z; - - for (z = 0; z < subdivisions; z++) { - for (x = 0; x < subdivisions; x++) { - TerrainPatch* patch = patches[z*subdivisions + x]; - int ndetail = 0; - Point loc = patch->Location(); - float radius = patch->Radius(); - - if (loc.length() < 2*radius) { - ndetail = detail_level; - } - - else { - double threshold = 4; //16; - - for (int level = 1; level <= detail_level; level++) { - double feature_size = radius / (1 << level); - - if (projector->ApparentRadius(loc, (float) feature_size) > threshold) - ndetail = level; - } - } - - patch->SetDetailLevel(ndetail); - - if (water_patches) { - patch = water_patches[z*subdivisions + x]; - if (patch) - patch->SetDetailLevel(ndetail); - } - } - } - - // compute fog fade level: - double hour = region->DayPhase(); - - if (hour < 12) - fog_fade = (hour) / 12.0; - else - fog_fade = (24-hour) / 12.0; - - fog_fade = fog_fade * (1-region->HazeFade()) + region->HazeFade(); - - detail_frame = Game::GetInstance()->Frame(); -} - -// +--------------------------------------------------------------------+ - -double -Terrain::Height(double x, double y) const -{ - double h = 0; - - if (patches) { - int ix = (int) floor(x / (patch_size * scale)); - int iy = (int) floor(y / (patch_size * scale)); - - double px = x - ix * patch_size * scale; - double py = y - iy * patch_size * scale; - - ix = subdivisions/2 - ix; - iy = subdivisions/2 + iy; - - TerrainPatch* patch = 0; - - if (ix >= 0 && ix < subdivisions && - iy >= 0 && iy < subdivisions) - patch = patches[iy*subdivisions+ix]; - - if (patch) - h = patch->Height(px, py); - } - - if (water_patches && h < 30) - h = 30; - - return h; -} - -// +--------------------------------------------------------------------+ - -void -Terrain::SetDetailLevel(int detail) -{ - if (detail >= 1 && detail <= 4) { - - // limit detail on low memory machines: - if (detail > 3 && MachineInfo::GetTotalRam() < 64) - detail = 3; - - detail_level = detail; - } -} - -// +--------------------------------------------------------------------+ - -bool -Terrain::IsFirstPatch(TerrainPatch* p) const -{ - return (patches && *patches == p); -} \ No newline at end of file diff --git a/Stars45/Terrain.h b/Stars45/Terrain.h deleted file mode 100644 index 2420dca..0000000 --- a/Stars45/Terrain.h +++ /dev/null @@ -1,118 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Test pseudo-random terrain heightfield, based on Solid -*/ - -#ifndef Terrain_h -#define Terrain_h - -#include "Types.h" -#include "Graphic.h" -#include "Geometry.h" -#include "Bitmap.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Projector; -class Scene; -class TerrainApron; -class TerrainClouds; -class TerrainLayer; -class TerrainPatch; -class TerrainRegion; -class Water; - -// +--------------------------------------------------------------------+ - -struct Vec3B -{ - Vec3B() { } - Vec3B(BYTE a, BYTE b, BYTE c) : x(a), y(b), z(c) { } - - BYTE x, y, z; -}; - -// +--------------------------------------------------------------------+ - -class Terrain -{ -public: - Terrain(TerrainRegion* region); - virtual ~Terrain(); - - virtual void Activate(Scene& scene); - virtual void Deactivate(Scene& scene); - - virtual void SelectDetail(Projector* proj); - virtual void BuildTerrain(); - virtual void BuildNormals(); - - virtual void ExecFrame(double seconds); - - double Height(double x, double y) const; - - const Vec3B* Normals() const { return terrain_normals; } - TerrainRegion* GetRegion() { return region; } - double FogFade() const { return fog_fade; } - - Bitmap* Texture() { return terrain_texture; } - Bitmap* ApronTexture() { return apron_texture; } - Bitmap* WaterTexture() { return water_texture; } - Bitmap** EnvironmentTexture() { return env_texture; } - Bitmap* TileTexture(int n) { return tiles[n]; } - Bitmap* CloudTexture(int n) { return cloud_texture[n]; } - Bitmap* ShadeTexture(int n) { return shade_texture[n]; } - Bitmap* DetailTexture(int n) { return noise_texture[n]; } - Water* GetWater(int level) { return water[level]; } - List& GetLayers() { return layers; } - - bool IsFirstPatch(TerrainPatch* p) const; - - static int DetailLevel() { return detail_level; } - static void SetDetailLevel(int detail); - -protected: - TerrainRegion* region; - TerrainPatch** patches; - TerrainPatch** water_patches; - Water** water; - TerrainApron** aprons; - TerrainClouds** clouds; - int nclouds; - - Bitmap terrain_patch; - Bitmap terrain_apron; - Bitmap* terrain_texture; - Bitmap* apron_texture; - Bitmap* water_texture; - Bitmap* env_texture[6]; - Bitmap* tiles[256]; - Bitmap* cloud_texture[2]; - Bitmap* shade_texture[2]; - Bitmap* noise_texture[2]; - - Vec3B* terrain_normals; - List layers; - - Text datapath; - double scale; - double mtnscale; - int subdivisions; - int patch_size; - DWORD detail_frame; - double fog_fade; - - static int detail_level; -}; - -#endif // Terrain_h - diff --git a/Stars45/TerrainApron.cpp b/Stars45/TerrainApron.cpp deleted file mode 100644 index 6c605cf..0000000 --- a/Stars45/TerrainApron.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "Terrain.h" -#include "TerrainApron.h" -#include "TerrainRegion.h" - -#include "CameraView.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Game.h" -#include "Light.h" -#include "Scene.h" - -// +====================================================================+ - -const int PATCH_SIZE = 17; -const int HALF_PATCH_SIZE = 8; -const int MAX_VERTS = PATCH_SIZE * PATCH_SIZE; -const int NUM_INDICES_TRI = 3; - -// +--------------------------------------------------------------------+ - -TerrainApron::TerrainApron(Terrain* terr,const Bitmap* patch, const Rect& r, -const Point& p1, const Point& p2) -: terrain(terr), rect(r) -{ - size = fabs(p2.x - p1.x); - scale = size / (PATCH_SIZE-1); - mtnscale = 1.3 * (p2.y - p1.y); - base = p1.y; - - terrain_width = patch->Width(); - - loc = (p1 + p2) * 0.5; - loc.y = base; - - radius = (float) (size * 0.75); - heights = new float[MAX_VERTS]; - - float* pHeight = heights; - - int i, j; - - for (i = 0; i < PATCH_SIZE; i++) { - int ty = rect.y + i; - - if (ty < 0) - ty = 0; - - if (ty > patch->Height()-1) - ty = patch->Height()-1; - - for (j = 0; j < PATCH_SIZE; j++) { - int tx = rect.x + (PATCH_SIZE-1 - j); - - if (tx < 0) - tx = 0; - - if (tx > patch->Width()-1) - tx = patch->Width()-1; - - *pHeight++ = (float) (patch->GetColor(tx,ty).Red() * mtnscale); - } - } -} - -// +--------------------------------------------------------------------+ - -TerrainApron::~TerrainApron() -{ - delete [] heights; -} - -// +--------------------------------------------------------------------+ - -void -TerrainApron::SetScales(double s, double m, double b) -{ - scale = s; - mtnscale = m; - base = b; -} - -// +--------------------------------------------------------------------+ - -bool -TerrainApron::BuildApron() -{ - int i, j; - - int detail_size = PATCH_SIZE-1; - int ds1 = PATCH_SIZE; - int nverts = MAX_VERTS; - int npolys = detail_size * detail_size * 2; - - model = new Model; - model->SetLuminous(true); - model->SetDynamic(true); - - Material* mtl = new Material; - mtl->Ka = ColorValue(0.5f, 0.5f, 0.5f); - mtl->Kd = ColorValue(0.3f, 0.6f, 0.2f); - mtl->Ks = Color::Black; - - mtl->tex_diffuse = terrain->ApronTexture(); - strcpy_s(mtl->name, "Terrain Apron"); - - model->GetMaterials().append(mtl); - - Surface* s = new Surface; - VertexSet* vset = 0; - - if (s) { - s->SetName("default"); - s->CreateVerts(nverts); - s->CreatePolys(npolys); - s->AddIndices(npolys*NUM_INDICES_TRI); - - vset = s->GetVertexSet(); - - ZeroMemory(vset->loc, nverts * sizeof(Vec3)); - ZeroMemory(vset->diffuse, nverts * sizeof(DWORD)); - ZeroMemory(vset->specular, nverts * sizeof(DWORD)); - ZeroMemory(vset->tu, nverts * sizeof(float)); - ZeroMemory(vset->tv, nverts * sizeof(float)); - ZeroMemory(vset->rw, nverts * sizeof(float)); - - - // initialize vertices - Vec3* pVert = vset->loc; - float* pTu = vset->tu; - float* pTv = vset->tv; - double dt = (1.0/3.0) / (double) detail_size; - double tu0 = (double) rect.x / rect.w / 3.0 + (1.0/3.0); - double tv0 = (double) rect.y / rect.h / 3.0; - - for (i = 0; i < ds1; i++) { - for (j = 0; j < ds1; j++) { - *pVert++ = Vec3((float) (j* scale - (HALF_PATCH_SIZE*scale)), - (float) (heights[i*PATCH_SIZE + j]), - (float) (i* scale - (HALF_PATCH_SIZE*scale))); - - *pTu++ = (float) (tu0 - j*dt); - *pTv++ = (float) (tv0 + i*dt); - } - } - - // create the polys - for (i = 0; i < npolys; i++) { - Poly* p = s->GetPolys() + i; - p->nverts = 3; - p->vertex_set = vset; - p->material = mtl; - p->visible = 1; - p->sortval = 0; - } - - int index = 0; - - // build main patch polys: - for (i = 0; i < detail_size; i++) { - for (j = 0; j < detail_size; j++) { - // first triangle - Poly* p = s->GetPolys() + index++; - p->verts[0] = (ds1 * (i ) + (j )); - p->verts[1] = (ds1 * (i ) + (j+1)); - p->verts[2] = (ds1 * (i+1) + (j+1)); - - // second triangle - p = s->GetPolys() + index++; - p->verts[0] = (ds1 * (i ) + (j )); - p->verts[1] = (ds1 * (i+1) + (j+1)); - p->verts[2] = (ds1 * (i+1) + (j )); - } - } - - // update the verts and colors of each poly: - for (i = 0; i < npolys; i++) { - Poly* p = s->GetPolys() + i; - Plane& plane = p->plane; - WORD* v = p->verts; - - plane = Plane(vset->loc[v[0]] + loc, - vset->loc[v[1]] + loc, - vset->loc[v[2]] + loc); - } - - // create continguous segments for each material: - s->Normalize(); - - Segment* segment = new Segment(npolys, s->GetPolys(), mtl, model); - s->GetSegments().append(segment); - - model->AddSurface(s); - - - // copy vertex normals: - Vec3 normal = Vec3(0, 1, 0); - - for (i = 0; i < ds1; i++) { - for (j = 0; j < ds1; j++) { - vset->nrm[i*ds1+j] = normal; - } - } - } - - return true; -} - -// +--------------------------------------------------------------------+ - -int -TerrainApron::CollidesWith(Graphic& o) -{ - return 0; -} - -// +--------------------------------------------------------------------+ - -void -TerrainApron::Update() -{ -} - -// +--------------------------------------------------------------------+ - -void -TerrainApron::Illuminate(Color ambient, List& lights) -{ - if (!model || model->NumVerts() < 1) return; - Surface* s = model->GetSurfaces().first(); - if (!s) return; - - // clear the solid lights to ambient: - VertexSet* vset = s->GetVertexSet(); - int nverts = vset->nverts; - DWORD aval = ambient.Value(); - - for (int i = 0; i < nverts; i++) { - vset->diffuse[i] = aval; - } - - TerrainRegion* trgn = terrain->GetRegion(); - bool eclipsed = false; - - // for each light: - ListIter iter = lights; - while (++iter) { - Light* light = iter.value(); - - if (light->CastsShadow()) - eclipsed = light->Location().y < -100; - - if (!light->CastsShadow() || !eclipsed) { - Vec3 vl = light->Location(); - vl.Normalize(); - - for (int i = 0; i < nverts; i++) { - Vec3& nrm = vset->nrm[i]; - double val = 0; - - if (light->IsDirectional()) { - double gain = vl * nrm; - - if (gain > 0) { - val = light->Intensity() * (0.85 * gain); - - if (val > 1) - val = 1; - } - } - - if (val > 0.01) - vset->diffuse[i] = ((light->GetColor().dim(val)) + vset->diffuse[i]).Value(); - } - } - } - - InvalidateSurfaceData(); -} - -// +--------------------------------------------------------------------+ - -void -TerrainApron::Render(Video* video, DWORD flags) -{ - if (!video || (flags & RENDER_ADDITIVE) || (flags & RENDER_ADD_LIGHT)) return; - - if (!model) - BuildApron(); - - if (scene) { - Illuminate(scene->Ambient(), scene->Lights()); - } - - double visibility = terrain->GetRegion()->GetWeather().Visibility(); - FLOAT fog_density = (FLOAT) (terrain->GetRegion()->FogDensity() * 2.5e-5 * 1/visibility); - - video->SetRenderState(Video::LIGHTING_ENABLE, false); - video->SetRenderState(Video::SPECULAR_ENABLE, false); - video->SetRenderState(Video::FOG_ENABLE, true); - video->SetRenderState(Video::FOG_COLOR, terrain->GetRegion()->FogColor().Value()); - video->SetRenderState(Video::FOG_DENSITY, *((DWORD*) &fog_density)); - - Solid::Render(video, flags); - - video->SetRenderState(Video::LIGHTING_ENABLE, true); - video->SetRenderState(Video::SPECULAR_ENABLE, true); - video->SetRenderState(Video::FOG_ENABLE, false); -} - -// +--------------------------------------------------------------------+ - -int -TerrainApron::CheckRayIntersection(Point Q, Point w, double len, Point& ipt, bool ttpas) -{ - // compute leading edge of ray: - Point sun = Q + w*len; - - if (sun.y < loc.y) - return 1; - - return 0; -} diff --git a/Stars45/TerrainApron.h b/Stars45/TerrainApron.h deleted file mode 100644 index b83089b..0000000 --- a/Stars45/TerrainApron.h +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A Single Edge Section of a Terrain Object -*/ - -#ifndef TerrainApron_h -#define TerrainApron_h - -#include "Types.h" -#include "Solid.h" - -// +--------------------------------------------------------------------+ - -class Terrain; - -// +--------------------------------------------------------------------+ - -class TerrainApron : public Solid -{ -public: - TerrainApron(Terrain* terrain, - const Bitmap* patch, const Rect& rect, - const Point& p1, const Point& p2); - virtual ~TerrainApron(); - - virtual void Render(Video* video, DWORD flags); - virtual void Update(); - - virtual int CollidesWith(Graphic& o); - virtual bool Luminous() const { return false; } - virtual bool Translucent() const { return false; } - - // accessors: - double Scale() const { return scale; } - double MountainScale() const { return mtnscale; } - double SeaLevel() const { return base; } - void SetScales(double scale, double mtnscale, double base); - - void Illuminate(Color ambient, List& lights); - virtual int CheckRayIntersection(Point pt, Point vpn, double len, Point& ipt, - bool treat_translucent_polys_as_solid=true); - -protected: - virtual bool BuildApron(); - - Terrain* terrain; - int nverts; - int npolys; - int terrain_width; - - Rect rect; - float* heights; - - double scale; - double mtnscale; - double base; - double size; -}; - - -#endif // TerrainApron_h - diff --git a/Stars45/TerrainClouds.cpp b/Stars45/TerrainClouds.cpp deleted file mode 100644 index 6c7bde1..0000000 --- a/Stars45/TerrainClouds.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "TerrainClouds.h" -#include "Terrain.h" -#include "TerrainRegion.h" - -#include "Light.h" -#include "CameraView.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Game.h" -#include "Fix.h" -#include "Scene.h" - -// +--------------------------------------------------------------------+ - -TerrainClouds::TerrainClouds(Terrain* terr, int t) -: terrain(terr), type(t) -{ - nverts = 0; - npolys = 0; - mverts = 0; - verts = 0; - polys = 0; - - loc = Point(0, 15000, 0); - radius = (float) (25000.0f); - - BuildClouds(); -} - -// +--------------------------------------------------------------------+ - -TerrainClouds::~TerrainClouds() -{ - delete [] mverts; - delete verts; - delete [] polys; -} - -// +--------------------------------------------------------------------+ - -static const double BANK_SIZE = 20000; -static const int CIRRUS_BANKS = 4; -static const int CUMULUS_BANKS = 4; - -void -TerrainClouds::BuildClouds() -{ - if (type == 0) { - nbanks = CIRRUS_BANKS; - nverts = 4 * nbanks; - npolys = 2 * nbanks; - } - else { - nbanks = CUMULUS_BANKS; - nverts = 8 * nbanks; - npolys = 3 * nbanks; - } - - Bitmap* cloud_texture = terrain->CloudTexture(type); - Bitmap* shade_texture = terrain->ShadeTexture(type); - - strcpy_s(mtl_cloud.name, "cloud"); - mtl_cloud.Ka = Color::White; - mtl_cloud.Kd = Color::White; - mtl_cloud.luminous = true; - mtl_cloud.blend = Material::MTL_TRANSLUCENT; - mtl_cloud.tex_diffuse = cloud_texture; - - strcpy_s(mtl_shade.name, "shade"); - mtl_shade.Ka = Color::White; - mtl_shade.Kd = Color::White; - mtl_shade.luminous = true; - mtl_shade.blend = Material::MTL_TRANSLUCENT; - mtl_shade.tex_diffuse = shade_texture; - - verts = new VertexSet(nverts); - mverts = new Vec3[nverts]; - polys = new Poly[npolys]; - - verts->nverts = nverts; - - // initialize vertices - Vec3* pVert = mverts; - float* pTu = verts->tu; - float* pTv = verts->tv; - - int i, j, n; - double az = 0; - double r = 0; - - for (n = 0; n < nbanks; n++) { - double xloc = r * cos(az); - double yloc = r * sin(az); - double alt = rand() / 32.768; - - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - *pVert = Vec3((float) ((2*j-1) * BANK_SIZE + xloc), - (float) (alt), - (float) ((2*i-1) * BANK_SIZE + yloc)); - - *pTu++ = (float) (-j); - *pTv++ = (float) ( i); - - float dist = pVert->length(); - if (dist > radius) - radius = dist; - - pVert++; - } - } - - if (type > 0) { - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - *pVert = Vec3((float) ((2*j-1) * BANK_SIZE + xloc), - (float) (alt-100), - (float) ((2*i-1) * BANK_SIZE + yloc)); - - *pTu++ = (float) (-j); - *pTv++ = (float) ( i); - - float dist = pVert->length(); - if (dist > radius) - radius = dist; - - pVert++; - } - } - } - - az += (0.66 + rand()/32768.0) * 0.25 * PI; - - if (r < BANK_SIZE) - r += BANK_SIZE; - else if (r < 1.75*BANK_SIZE) - r += BANK_SIZE/4; - else - r += BANK_SIZE/8; - } - - // create the polys - for (i = 0; i < npolys; i++) { - Poly* p = polys + i; - p->nverts = 4; - p->vertex_set = verts; - p->material = (i<4*nbanks) ? &mtl_cloud : &mtl_shade; - p->visible = 1; - p->sortval = (i<4*nbanks) ? 1 : 2; - } - - // build main patch polys: (facing down) - Poly* p = polys; - - int stride = 4; - if (type > 0) - stride = 8; - - // clouds: - for (n = 0; n < nbanks; n++) { - p->verts[0] = 0 + n*stride; - p->verts[1] = 1 + n*stride; - p->verts[2] = 3 + n*stride; - p->verts[3] = 2 + n*stride; - p++; - - // reverse side: (facing up) - p->verts[0] = 0 + n*stride; - p->verts[3] = 1 + n*stride; - p->verts[2] = 3 + n*stride; - p->verts[1] = 2 + n*stride; - p++; - } - - // shades: - if (type > 0) { - for (n = 0; n < nbanks; n++) { - p->verts[0] = 4 + n*stride; - p->verts[1] = 5 + n*stride; - p->verts[2] = 7 + n*stride; - p->verts[3] = 6 + n*stride; - p++; - } - } - - // update the verts and colors of each poly: - for (i = 0; i < npolys; i++) { - Poly* p = polys + i; - WORD* v = p->verts; - - p->plane = Plane(mverts[v[0]], - mverts[v[1]], - mverts[v[2]]); - } -} - -// +--------------------------------------------------------------------+ - -void -TerrainClouds::Update() -{ - if (!nverts || !mverts || !verts) - return; - - for (int i = 0; i < nverts; ++i) - verts->loc[i] = mverts[i] + loc; -} - -// +--------------------------------------------------------------------+ - -void -TerrainClouds::Illuminate(Color ambient, List& lights) -{ - int i, n; - - if (terrain) { - DWORD cloud_color = terrain->GetRegion()->CloudColor().Value() | Color(0,0,0,255).Value(); - DWORD shade_color = terrain->GetRegion()->ShadeColor().Value() | Color(0,0,0,255).Value(); - - int stride = 4; - if (type > 0) - stride = 8; - - for (i = 0; i < nbanks; i++) { - for (n = 0; n < 4; n++) { - verts->diffuse[stride*i + n] = cloud_color; - verts->specular[stride*i + n] = 0xff000000; - } - - if (type > 0) { - for (; n < 8; n++) { - verts->diffuse[stride*i + n] = shade_color; - verts->specular[stride*i + n] = 0xff000000; - } - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -TerrainClouds::Render(Video* video, DWORD flags) -{ - if ((flags & Graphic::RENDER_ALPHA) == 0) - return; - - if (video && life && polys && npolys && verts) { - if (scene) - Illuminate(scene->Ambient(), scene->Lights()); - - video->SetRenderState(Video::FOG_ENABLE, false); - video->DrawPolys(npolys, polys); - } -} diff --git a/Stars45/TerrainClouds.h b/Stars45/TerrainClouds.h deleted file mode 100644 index dcabaa3..0000000 --- a/Stars45/TerrainClouds.h +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A Single Edge Section of a Terrain Object -*/ - -#ifndef TerrainClouds_h -#define TerrainClouds_h - -#include "Types.h" -#include "Graphic.h" -#include "Geometry.h" -#include "Polygon.h" - -// +--------------------------------------------------------------------+ - -class Terrain; -class TerrainRegion; - -// +--------------------------------------------------------------------+ - -class TerrainClouds : public Graphic -{ -public: - TerrainClouds(Terrain* terr, int type); - virtual ~TerrainClouds(); - - virtual void Render(Video* video, DWORD flags); - virtual void Update(); - - // accessors: - virtual int CollidesWith(Graphic& o) { return 0; } - virtual bool Luminous() const { return true; } - virtual bool Translucent() const { return true; } - - void Illuminate(Color ambient, List& lights); - -protected: - void BuildClouds(); - - Terrain* terrain; - Vec3* mverts; - VertexSet* verts; - Poly* polys; - Material mtl_cloud; - Material mtl_shade; - - int type; - int nbanks; - int nverts; - int npolys; -}; - - -#endif // TerrainClouds_h - diff --git a/Stars45/TerrainHaze.cpp b/Stars45/TerrainHaze.cpp deleted file mode 100644 index 590b357..0000000 --- a/Stars45/TerrainHaze.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "Terrain.h" -#include "TerrainHaze.h" -#include "TerrainRegion.h" - -#include "Light.h" -#include "CameraView.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Game.h" - -// +====================================================================+ - -static Bitmap terrain_texture; - -// +--------------------------------------------------------------------+ - -TerrainHaze::TerrainHaze() -: tregion(0) -{ -} - -// +--------------------------------------------------------------------+ - -TerrainHaze::~TerrainHaze() -{ -} - -// +--------------------------------------------------------------------+ - -void -TerrainHaze::Render(Video* video, DWORD flags) -{ - if (flags & RENDER_ADDITIVE) - return; - - if (model) { - if (!Luminous()) { - SetLuminous(true); - model->SetDynamic(true); - } - - Surface* surface = model->GetSurfaces().first(); - - if (!surface) return; - - int i; - DWORD sky = 0; - DWORD fog = 0; - - if (tregion) { - sky = tregion->SkyColor().Value(); - fog = tregion->FogColor().Value(); - } - - // clear the solid lights to ambient: - VertexSet* vset = surface->GetVertexSet(); - - for (i = 0; i < vset->nverts; i++) { - if (vset->loc[i].y > 0) - vset->diffuse[i] = sky; - else - vset->diffuse[i] = fog; - } - - InvalidateSurfaceData(); - Solid::Render(video, flags); - } -} - -// +--------------------------------------------------------------------+ - -int -TerrainHaze::CheckRayIntersection(Point Q, Point w, double len, Point& ipt, bool ttpas) -{ - return 0; -} diff --git a/Stars45/TerrainHaze.h b/Stars45/TerrainHaze.h deleted file mode 100644 index 3cf0d44..0000000 --- a/Stars45/TerrainHaze.h +++ /dev/null @@ -1,45 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Atmospheric fog along the horizon -*/ - -#ifndef TerrainHaze_h -#define TerrainHaze_h - -#include "Types.h" -#include "Solid.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class TerrainRegion; - -// +--------------------------------------------------------------------+ - -class TerrainHaze : public Solid -{ -public: - TerrainHaze(); - virtual ~TerrainHaze(); - - virtual void Render(Video* video, DWORD flags); - - virtual int CheckRayIntersection(Point pt, Point vpn, double len, Point& ipt, - bool treat_translucent_polys_as_solid=true); - - virtual void UseTerrainRegion(TerrainRegion* tr) { tregion = tr; } - -protected: - TerrainRegion* tregion; -}; - -#endif // TerrainHaze_h - diff --git a/Stars45/TerrainLayer.h b/Stars45/TerrainLayer.h deleted file mode 100644 index 8327da4..0000000 --- a/Stars45/TerrainLayer.h +++ /dev/null @@ -1,62 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A blended detail texture applied to a terrain patch - through a specific range of altitudes -*/ - -#ifndef TerrainLayer_h -#define TerrainLayer_h - -#include "Types.h" -#include "Bitmap.h" - -// +--------------------------------------------------------------------+ - -class Terrain; -class TerrainRegion; - -// +--------------------------------------------------------------------+ - -class TerrainLayer -{ - friend class Terrain; - friend class TerrainRegion; - -public: - static const char* TYPENAME() { return "TerrainLayer"; } - - TerrainLayer() : tile_texture(0), detail_texture(0), min_height(0), max_height(-1) { } - ~TerrainLayer() { } - - int operator < (const TerrainLayer& t) const { return min_height < t.min_height; } - int operator <= (const TerrainLayer& t) const { return min_height <= t.min_height; } - int operator == (const TerrainLayer& t) const { return min_height == t.min_height; } - - // accessors: - const char* GetTileName() const { return tile_name; } - const char* GetDetailName() const { return detail_name; } - Bitmap* GetTileTexture() const { return tile_texture; } - Bitmap* GetDetailTexture() const { return detail_texture; } - double GetMinHeight() const { return min_height; } - double GetMaxHeight() const { return max_height; } - -private: - Text tile_name; - Text detail_name; - Bitmap* tile_texture; - Bitmap* detail_texture; - double min_height; - double max_height; -}; - - -#endif // TerrainLayer_h - diff --git a/Stars45/TerrainPatch.cpp b/Stars45/TerrainPatch.cpp deleted file mode 100644 index af70e0f..0000000 --- a/Stars45/TerrainPatch.cpp +++ /dev/null @@ -1,1112 +0,0 @@ -/* 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 - - - OVERVIEW - ======== -*/ - -#include "Terrain.h" -#include "TerrainLayer.h" -#include "TerrainPatch.h" -#include "TerrainRegion.h" -#include "Sim.h" - -#include "Light.h" -#include "CameraView.h" -#include "Projector.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Game.h" -#include "Scene.h" -#include "Water.h" - -// +====================================================================+ - -// #define DEBUG_DETAIL 1 - -// +====================================================================+ - -const int MAX_DETAIL = 4; -const int PATCH_SIZE = 17; -const int HALF_PATCH_SIZE = 8; -const int MAX_VERTS = PATCH_SIZE * PATCH_SIZE; - -static bool illuminating = false; - -// +--------------------------------------------------------------------+ - -TerrainPatch::TerrainPatch(Terrain* terr,const Bitmap* patch, const Rect& r, -const Point& p1, const Point& p2) -: ndetail(0), terrain(terr), rect(r), water(0), min_height(1e9), max_height(-1e9) -{ - luminous = true; // we will do our own lighting - own_model = false; // manage the model lifetimes in this derived class - - max_detail = Terrain::DetailLevel(); - scale = fabs(p1.x - p2.x) / (PATCH_SIZE-1); - mtnscale = p2.y - p1.y; - base = p1.y; - size = p2.x - p1.x; - - ZeroMemory(detail_levels, sizeof(detail_levels)); - - terrain_width = patch->Width(); - - loc = (p1 + p2) * 0.5; - loc.y = base; - - radius = (float) (size * 0.75); - heights = new float[MAX_VERTS]; - - float* pHeight = heights; - int tscale = rect.w / (PATCH_SIZE-1); - int i, j; - - for (i = 0; i < PATCH_SIZE; i++) { - int ty = rect.y + i * tscale; - - if (ty < 0) - ty = 0; - - if (ty > patch->Height()-1) - ty = patch->Height()-1; - - for (j = 0; j < PATCH_SIZE; j++) { - int tx = rect.x + (PATCH_SIZE-1 - j) * tscale; - - if (tx < 0) - tx = 0; - - if (tx > patch->Width()-1) - tx = patch->Width()-1; - - int red = patch->GetColor(tx,ty).Red(); - float alt = (float) (red * mtnscale); - - if (alt < min_height) - min_height = alt; - if (alt > max_height) - max_height = alt; - - if (terrain->WaterTexture() && red < 2) - alt = -5000.0f; - - *pHeight++ = alt; - } - } - - Material* mtl = new Material; - mtl->Ka = ColorValue(0.5f, 0.5f, 0.5f); - mtl->Kd = ColorValue(0.3f, 0.6f, 0.2f); - mtl->Ks = Color::Black; - - mtl->tex_diffuse = terrain->Texture(); - - materials.append(mtl); - - List& layers = terrain->GetLayers(); - for (i = 0; i < layers.size(); i++) { - Bitmap* tex0 = layers.at(i)->GetTileTexture(); - Bitmap* tex1 = 0; - Bitmap* texd = layers.at(i)->GetDetailTexture(); - - if (i < layers.size()-1) - tex1 = layers.at(i+1)->GetTileTexture(); - - if (!texd) - texd = terrain->DetailTexture(0); - - mtl = new Material; - mtl->Ka = ColorValue(0.5f, 0.5f, 0.5f); - mtl->Kd = ColorValue(0.3f, 0.6f, 0.2f); - mtl->Ks = Color::Black; - - if ((i & 1) != 0) { - mtl->tex_diffuse = tex1; - mtl->tex_alternate = tex0; - } - else { - mtl->tex_diffuse = tex0; - mtl->tex_alternate = tex1; - } - - mtl->tex_detail = texd; - - materials.append(mtl); - } - - for (i = 0; i <= max_detail; i++) - BuildDetailLevel(i); - - model = detail_levels[1]; -} - -// +--------------------------------------------------------------------+ - -TerrainPatch::TerrainPatch(Terrain* terr, -const Rect& r, -const Point& p1, -const Point& p2, -double sea_level) -: ndetail(0), terrain(terr), rect(r), water(0) -{ - luminous = true; // water is lit by the graphics engine - own_model = false; // manage the model lifetimes in this derived class - - max_detail = Terrain::DetailLevel(); - scale = fabs(p1.x - p2.x) / (PATCH_SIZE-1); - mtnscale = 0; - base = sea_level; - size = p2.x - p1.x; - - ZeroMemory(detail_levels, sizeof(detail_levels)); - - terrain_width = 0; - - loc = (p1 + p2) * 0.5; - loc.y = base; - - radius = (float) (size * 0.75); - heights = new float[MAX_VERTS]; - - float* pHeight = heights; - int i, j; - - for (i = 0; i < PATCH_SIZE; i++) { - for (j = 0; j < PATCH_SIZE; j++) { - *pHeight++ = (float) sea_level; - } - } - - Material* mtl = new Material; - mtl->Ka = Color::Gray; - mtl->Kd = Color::White; - mtl->Ks = Color::White; - mtl->power = 30.0f; - mtl->shadow = false; - mtl->tex_diffuse = terrain->WaterTexture(); - //strcpy_s(mtl->shader, "WaterReflections"); - materials.append(mtl); - - water = terrain->GetWater(1); - - for (i = 0; i <= max_detail; i++) - BuildDetailLevel(i); - - model = detail_levels[1]; -} - -// +--------------------------------------------------------------------+ - -TerrainPatch::~TerrainPatch() -{ - delete [] heights; - - for (int i = 0; i < MAX_LOD; i++) { - Model* m = detail_levels[i]; - - if (m) { - m->GetMaterials().clear(); - delete m; - } - } - - materials.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -TerrainPatch::SetScales(double s, double m, double b) -{ - scale = s; - mtnscale = m; - base = b; -} - -// +--------------------------------------------------------------------+ - -static int mcomp(const void* a, const void* b) -{ - Poly* pa = (Poly*) a; - Poly* pb = (Poly*) b; - - if (pa->sortval == pb->sortval) - return 0; - - if (pa->sortval < pb->sortval) - return 1; - - return -1; -} - - -static void bisect(VertexSet* vset, int v[4]) -{ - double d1 = fabs(vset->loc[ v[0] ].y - - vset->loc[ v[3] ].y); - - double d2 = fabs(vset->loc[ v[1] ].y - - vset->loc[ v[2] ].y); - - if (d2 < 0.7*d1) { - int odd[4] = { v[1], v[3], v[0], v[2] }; - for (int i = 0; i < 4; i++) - v[i] = odd[i]; - } -} - -bool -TerrainPatch::BuildDetailLevel(int level) -{ - int i, j; - - int detail_size = 1 << level; - int ds1 = detail_size+1; - - if (detail_size > PATCH_SIZE) - return false; - - Model* model = new Model; - detail_levels[level] = model; - - model->SetLuminous(luminous); - model->SetDynamic(true); - - const int NUM_STRIPS = 4; - const int NUM_INDICES_TRI = 3; - const int NUM_INDICES_QUAD = 6; - - int nverts = ds1*ds1 + ds1*2*NUM_STRIPS; - int npolys = detail_size*detail_size*2; - int strip_len = detail_size; - int total = npolys + strip_len*NUM_STRIPS; - - if (water) { - nverts = ds1*ds1; - strip_len = 0; - total = npolys; - } - - Surface* s = new Surface; - VertexSet* vset = 0; - - if (s) { - s->SetName("default"); - s->CreateVerts(nverts); - s->CreatePolys(total); - s->AddIndices(npolys*NUM_INDICES_TRI + strip_len*NUM_STRIPS*NUM_INDICES_QUAD); - - vset = s->GetVertexSet(); - if (!water) - vset->CreateAdditionalTexCoords(); - - ZeroMemory(vset->loc, nverts * sizeof(Vec3)); - ZeroMemory(vset->diffuse, nverts * sizeof(DWORD)); - ZeroMemory(vset->specular, nverts * sizeof(DWORD)); - ZeroMemory(vset->tu, nverts * sizeof(float)); - ZeroMemory(vset->tv, nverts * sizeof(float)); - if (!water) { - ZeroMemory(vset->tu1, nverts * sizeof(float)); - ZeroMemory(vset->tv1, nverts * sizeof(float)); - } - ZeroMemory(vset->rw, nverts * sizeof(float)); - - // initialize vertices - Vec3* pVert = vset->loc; - float* pTu = vset->tu; - float* pTv = vset->tv; - float* pTu1 = vset->tu1; - float* pTv1 = vset->tv1; - DWORD* pSpec = vset->specular; - - int dscale = (PATCH_SIZE-1)/detail_size; - double dt = 0.0625 / (ds1-1); // terrain texture scale - double dtt = 2.0000 / (ds1-1); // tile texture scale - double tu0 = (double) rect.x / rect.w / 16.0 + 1.0/16.0; - double tv0 = (double) rect.y / rect.h / 16.0; - - // surface verts - for (i = 0; i < ds1; i++) { - for (j = 0; j < ds1; j++) { - *pVert = Vec3((float) (j* scale * dscale - (HALF_PATCH_SIZE*scale)), - (float) (heights[i*dscale*PATCH_SIZE + j*dscale]), - (float) (i* scale * dscale - (HALF_PATCH_SIZE*scale))); - - if (level >= 2) { - *pTu++ = (float) (-j*dtt); - *pTv++ = (float) ( i*dtt); - - if (level >= 4 && !water) { - *pTu1++ = (float) (-j*dtt*3); - *pTv1++ = (float) ( i*dtt*3); - } - - *pSpec++ = BlendValue(pVert->y); - } - - else { - *pTu++ = (float) (tu0 - j*dt); - *pTv++ = (float) (tv0 + i*dt); - } - - pVert++; - } - } - - if (!water) { - // strip 1 & 2 verts - for (i = 0; i < ds1; i += detail_size) { - for (j = 0; j < ds1; j++) { - Vec3 vl = Vec3((float) (j* scale * dscale - (HALF_PATCH_SIZE*scale)), - (float) (heights[i*dscale*PATCH_SIZE + j*dscale]), - (float) (i* scale * dscale - (HALF_PATCH_SIZE*scale))); - - *pVert++ = vl; - - DWORD blend = 0; - - if (level >= 2) { - blend = BlendValue(vl.y); - - *pSpec++ = blend; - *pTu++ = (float) (-j*dtt); - *pTv++ = (float) ( i*dtt); - } - - else { - *pTu++ = (float) (tu0 - j*dt); - *pTv++ = (float) (tv0 + i*dt); - } - - vl.y = -5000.0f; - - *pVert++ = vl; - - if (level >= 2) { - *pSpec++ = blend; - *pTu++ = (float) (-j*dtt); - *pTv++ = (float) ( i*dtt); - } - - else { - *pTu++ = (float) (tu0 - j*dt); - *pTv++ = (float) (tv0 + i*dt); - } - } - } - - // strip 3 & 4 verts - for (j = 0; j < ds1; j += detail_size) { - for (i = 0; i < ds1; i++) { - Vec3 vl = Vec3((float) (j* scale * dscale - (HALF_PATCH_SIZE*scale)), - (float) (heights[i*dscale*PATCH_SIZE + j*dscale]), - (float) (i* scale * dscale - (HALF_PATCH_SIZE*scale))); - - *pVert++ = vl; - - DWORD blend = 0; - - if (level >= 2) { - blend = BlendValue(vl.y); - - *pSpec++ = blend; - *pTu++ = (float) (-j*dtt); - *pTv++ = (float) ( i*dtt); - } - - else { - *pTu++ = (float) (tu0 - j*dt); - *pTv++ = (float) (tv0 + i*dt); - } - - vl.y = -5000.0f; - - *pVert++ = vl; - - if (level >= 2) { - *pSpec++ = blend; - *pTu++ = (float) (-j*dtt); - *pTv++ = (float) ( i*dtt); - } - - else { - *pTu++ = (float) (tu0 - j*dt); - *pTv++ = (float) (tv0 + i*dt); - } - } - } - } - - Material* m = materials.first(); - - // initialize the polys - for (i = 0; i < npolys; i++) { - Poly* p = s->GetPolys() + i; - p->nverts = 3; - p->vertex_set = vset; - p->visible = 1; - p->sortval = 0; - p->material = m; - - if (level >= 2 && !water) { - p->material = materials.at(1); - p->sortval = 1; - } - } - - for (i = npolys; i < total; i++) { - Poly* p = s->GetPolys() + i; - p->nverts = 4; - p->vertex_set = vset; - p->visible = 1; - p->sortval = 0; - p->material = m; - } - - int index = 0; - - // build main patch polys: - for (i = 0; i < detail_size; i++) { - for (j = 0; j < detail_size; j++) { - int v[4] = { - (ds1 * (i ) + (j )), - (ds1 * (i ) + (j+1)), - (ds1 * (i+1) + (j )), - (ds1 * (i+1) + (j+1)) }; - - bisect(vset, v); - - // first triangle - Poly* p = s->GetPolys() + index++; - p->verts[0] = v[0]; - p->verts[1] = v[1]; - p->verts[2] = v[3]; - - if (level >= 2 && !water) { - int layer = CalcLayer(p) + 1; - p->material = materials.at(layer); - p->sortval = layer; - } - - // second triangle - p = s->GetPolys() + index++; - p->verts[0] = v[0]; - p->verts[1] = v[3]; - p->verts[2] = v[2]; - - if (level >= 2 && !water) { - int layer = CalcLayer(p) + 1; - p->material = materials.at(layer); - p->sortval = layer; - } - } - } - - // build vertical edge strip polys: - - if (!water) { - for (i = 0; i < NUM_STRIPS; i++) { - Poly* p = s->GetPolys() + npolys + i*strip_len; - int base_index = ds1*ds1 + ds1*2*i; - - for (j = 0; j < strip_len; j++) { - int v = base_index + j * 2; - p->nverts = 4; - - if (i == 1 || i == 2) { - p->verts[0] = v; - p->verts[1] = v+2; - p->verts[2] = v+3; - p->verts[3] = v+1; - } - - else { - p->verts[0] = v; - p->verts[1] = v+1; - p->verts[2] = v+3; - p->verts[3] = v+2; - } - - if (level >= 2) { - int layer = CalcLayer(p) + 1; - p->material = materials.at(layer); - p->sortval = layer; - } - - p++; - } - } - } - - // update the poly planes: - for (i = 0; i < total; i++) { - Poly* p = s->GetPolys() + i; - Plane& plane = p->plane; - WORD* v = p->verts; - - plane = Plane(vset->loc[v[0]] + loc, - vset->loc[v[1]] + loc, - vset->loc[v[2]] + loc); - } - - s->Normalize(); - - // create continguous segments for each material: - // sort the polys by material index: - qsort((void*) s->GetPolys(), s->NumPolys(), sizeof(Poly), mcomp); - - // then assign them to cohesive segments: - Segment* segment = 0; - Poly* spolys = s->GetPolys(); - - for (int n = 0; n < s->NumPolys(); n++) { - if (segment && segment->material == spolys[n].material) { - segment->npolys++; - } - else { - segment = 0; - } - - if (!segment) { - segment = new Segment; - - segment->npolys = 1; - segment->polys = &spolys[n]; - segment->material = segment->polys->material; - segment->model = model; - - s->GetSegments().append(segment); - } - } - - Solid::EnableCollision(false); - model->AddSurface(s); - Solid::EnableCollision(true); - - // copy vertex normals: - const Vec3B* tnorms = terrain->Normals(); - - for (i = 0; i < ds1; i++) { - for (j = 0; j < ds1; j++) { - - if (water) { - vset->nrm[i*ds1+j] = Point(0,1,0); - } - - // blend adjacent normals: - else if (dscale > 1) { - Point normal; - - // but don't blend more than 16 normals per vertex: - int step = 1; - if (dscale > 4) - step = dscale / 4; - - for (int dy = -dscale/2; dy < dscale/2; dy += step) { - for (int dx = -dscale/2; dx < dscale/2; dx += step) { - int ix = rect.x + (ds1-1-j)*dscale + dx; - int iy = rect.y + i*dscale + dy; - - if (ix < 0) ix = 0; - if (ix > terrain_width-1) ix = terrain_width-1; - if (iy < 0) iy = 0; - if (iy > terrain_width-1) iy = terrain_width-1; - - Vec3B vbn = tnorms[iy*terrain_width + ix]; - normal += Point((128-vbn.x)/127.0, (vbn.z-128)/127.0, (vbn.y-128)/127.0); - } - } - - normal.Normalize(); - vset->nrm[i*ds1+j] = normal; - } - - // just copy the one normal: - else { - Vec3B vbn = tnorms[(rect.y + i*dscale)*terrain_width + (rect.x + (ds1-1-j) * dscale)]; - Point normal = Point((128-vbn.x)/127.0, (vbn.z-128)/127.0, (vbn.y-128)/127.0); - vset->nrm[i*ds1+j] = normal; - } - } - } - - if (!water) { - pVert = &vset->nrm[ds1*ds1]; - - // strip 1 & 2 verts - for (i = 0; i < ds1; i += detail_size) { - for (j = 0; j < ds1; j++) { - Vec3 vn = vset->nrm[i*ds1 + j]; - - *pVert++ = vn; - *pVert++ = vn; - } - } - - // strip 3 & 4 verts - for (j = 0; j < ds1; j += detail_size) { - for (i = 0; i < ds1; i++) { - Vec3 vn = vset->nrm[i*ds1 + j]; - - *pVert++ = vn; - *pVert++ = vn; - } - } - } - } - - if (level > max_detail) - max_detail = level; - - return true; -} - -// +--------------------------------------------------------------------+ - -DWORD -TerrainPatch::BlendValue(double y) -{ - if (terrain && y >= 0 && !water) { - // find the proper layer: - for (int i = 0; i < terrain->GetLayers().size(); i++) { - TerrainLayer* layer = terrain->GetLayers().at(i); - - if (y >= layer->GetMinHeight() && y < layer->GetMaxHeight()) { - double scale = (y-layer->GetMinHeight()) / (layer->GetMaxHeight()-layer->GetMinHeight()); - - if (scale < 0.2) - scale = 0; - else if (scale > 0.8) - scale = 1; - else - scale = (scale - 0.2) / 0.6; - - if ((i & 1) == 0) { - scale = 1 - scale; - } - - DWORD val = (DWORD) (scale*255); - - return val << 24; - } - } - } - - return 0; -} - -int -TerrainPatch::CalcLayer(Poly* poly) -{ - if (terrain && poly) { - if (water) - return 0; - - double y = 1e6; - - for (int i = 0; i < poly->nverts; i++) { - double h = poly->vertex_set->loc[ poly->verts[i] ].y; - - if (h >= 0 && h < y) { - y = h; - } - } - - if (y <= terrain->GetLayers().first()->GetMinHeight()) - return 0; - - for (int i = 0; i < terrain->GetLayers().size(); i++) { - TerrainLayer* layer = terrain->GetLayers().at(i); - - if (y >= layer->GetMinHeight() && y < layer->GetMaxHeight()) { - return i; - } - } - } - - return -1; -} - -// +--------------------------------------------------------------------+ - -void -TerrainPatch::UpdateSurfaceWaves(Vec3& eyePos) -{ - if (water && model && model->NumVerts() > 1) { - Surface* s = model->GetSurfaces().first(); - if (s) { - VertexSet* vset = s->GetVertexSet(); - for (int i = 0; i < vset->nverts; i++) - vset->loc[i].y = 0.0f; - - water->UpdateSurface(eyePos, vset); - } - } -} - -// +--------------------------------------------------------------------+ - -int -TerrainPatch::CollidesWith(Graphic& o) -{ - return 0; -} - -// +--------------------------------------------------------------------+ - -void -TerrainPatch::SelectDetail(Projector* projector) -{ - // This is where all the work is done, - // Delegate to the overall terrain to - // compute a detail level for every patch: - - if (terrain) { - terrain->SelectDetail(projector); - } - - // Build detail levels on demand: - - if (detail_levels[ndetail] == 0) - BuildDetailLevel(ndetail); -} - -void -TerrainPatch::SetDetailLevel(int nd) -{ - if (nd >= 0 && nd <= max_detail) { - if (ndetail != nd) - DeletePrivateData(); - - ndetail = nd; - - // build detail levels on demand: - if (detail_levels[ndetail] == 0) - BuildDetailLevel(ndetail); - - model = detail_levels[ndetail]; - - if (water) - water = terrain->GetWater(ndetail); - } -} - -// +--------------------------------------------------------------------+ - -void -TerrainPatch::Illuminate(Color ambient, List& lights) -{ - if (!model || model->NumVerts() < 1) return; - Surface* s = model->GetSurfaces().first(); - if (!s) return; - - illuminating = true; - - // clear the solid lights to ambient: - VertexSet* vset = s->GetVertexSet(); - int nverts = vset->nverts; - DWORD aval = ambient.Value(); - - for (int i = 0; i < nverts; i++) { - vset->diffuse[i] = aval; - } - - TerrainRegion* trgn = terrain->GetRegion(); - bool eclipsed = false; - bool first = terrain->IsFirstPatch(this); - - if (trgn && !first) { - eclipsed = trgn->IsEclipsed(); - } - - // for sun and back lights: - ListIter iter = lights; - while (++iter) { - Light* light = iter.value(); - - if (!light->IsDirectional()) // only do sun and - continue; // back lights - - if (light->CastsShadow() && first) { - eclipsed = light->Location().y < -100 || // has sun set, or - - scene->IsLightObscured(vset->loc[0], // is sun in eclipse - light->Location(), // by orbital body - radius); // such as a moon? - } - - if (!light->CastsShadow() || !eclipsed) { - Vec3 vl = light->Location(); - vl.Normalize(); - - for (int i = 0; i < nverts; i++) { - Vec3& nrm = vset->nrm[i]; - double val = 0; - double gain = vl * nrm; - - if (gain > 0) { - val = light->Intensity() * (0.85 * gain); - - if (val > 1) - val = 1; - } - - if (val > 0.01) - vset->diffuse[i] = ((light->GetColor().dim(val)) + vset->diffuse[i]).Value(); - } - } - } - - // combine blend weights: - if (ndetail >= 2) { - for (int i = 0; i < nverts; i++) { - vset->diffuse[i] = vset->specular[i] | (vset->diffuse[i] & 0x00ffffff); - } - } - - if (trgn && first) { - trgn->SetEclipsed(eclipsed); - } - - InvalidateSurfaceData(); - illuminating = false; -} - -// +--------------------------------------------------------------------+ - -void -TerrainPatch::Render(Video* video, DWORD flags) -{ - if (max_height < 0) - return; - - if (flags & RENDER_ADDITIVE) - return; - - if (!model) - model = detail_levels[0]; - - if (scene) { - /*** - *** TWO PASS LIGHTING FOR TERRAIN SHADOWS DOESN'T - *** WORK - IT MESSES UP THE HARDWARE FOG CALCS - *** - *** PLUS, IT'S INCREDIBLY SLOW!!! - ***/ - - if ((flags & RENDER_ADD_LIGHT) != 0) - return; - - if (water) { - Vec3 vec(0, 0, 0); - UpdateSurfaceWaves(vec); - Illuminate(scene->Ambient(), scene->Lights()); - } - else { - Illuminate(scene->Ambient(), scene->Lights()); - } - } - else { - if ((flags & RENDER_ADD_LIGHT) != 0) - return; - } - - Bitmap* details[16]; - ZeroMemory(details, sizeof(details)); - - if (ndetail < 3) { - for (int i = 0; i < 16 && i < materials.size(); i++) { - Material* mtl = materials[i]; - - if (mtl->tex_detail) { - details[i] = mtl->tex_detail; - mtl->tex_detail = 0; - } - } - } - - double visibility = terrain->GetRegion()->GetWeather().Visibility(); - FLOAT fog_density = (FLOAT) (terrain->GetRegion()->FogDensity() * 2.5e-5 * 1/visibility); - - video->SetRenderState(Video::LIGHTING_ENABLE, false); - video->SetRenderState(Video::SPECULAR_ENABLE, false); //water != 0); - video->SetRenderState(Video::FOG_ENABLE, true); - video->SetRenderState(Video::FOG_COLOR, terrain->GetRegion()->FogColor().Value()); - video->SetRenderState(Video::FOG_DENSITY, *((DWORD*) &fog_density)); - - // Too bad this doesn't work right. But it makes the - // ground mostly disappear. :-( - // - //video->SetRenderState(Video::Z_BIAS, -2); - - Solid::Render(video, flags); - - video->SetRenderState(Video::LIGHTING_ENABLE, true); - video->SetRenderState(Video::SPECULAR_ENABLE, true); - video->SetRenderState(Video::FOG_ENABLE, false); - //video->SetRenderState(Video::Z_BIAS, 0); - - if (ndetail < 3) { - for (int i = 0; i < 16 && i < materials.size(); i++) { - Material* mtl = materials[i]; - - if (details[i] && !mtl->tex_detail) { - mtl->tex_detail = details[i]; - } - } - } -} - -// +--------------------------------------------------------------------+ - -int -TerrainPatch::CheckRayIntersection(Point obj_pos, Point dir, double len, Point& ipt, bool ttpas) -{ - Point light_pos = obj_pos + dir * len; - int impact = light_pos.y < -100; - - // Special case for illumination - - // just check if sun is above or below the horizon: - - if (illuminating || impact) { - return impact; - } - - if (obj_pos.x != 0 || obj_pos.y != 0 || obj_pos.z != 0) { - return impact; - } - - // the rest of this code is only used for eclipsing - // the solar lens flare: - - // check right angle spherical distance: - Point d0 = loc; - Point d1 = d0.cross(dir); - double dlen = d1.length(); // distance of point from line - - if (dlen > radius) // clean miss - return 0; // (no impact) - - // make sure some part of this patch falls between - // the camera and the sun: - - Point closest = loc + dir * radius; - - if (closest * dir < 0) - return 0; - - // probable hit at this point... - // test for polygon intersection: - if (!model) - return 0; - - Surface* s = model->GetSurfaces().first(); - - if (!s) - return 0; - - - // transform ray into object space: - Matrix xform(Orientation()); - - Vec3 tmp = dir; - - dir.x = tmp * Vec3(xform(0,0), xform(0,1), xform(0,2)); - dir.y = tmp * Vec3(xform(1,0), xform(1,1), xform(1,2)); - dir.z = tmp * Vec3(xform(2,0), xform(2,1), xform(2,2)); - - tmp = obj_pos-loc; - - obj_pos.x = tmp * Vec3(xform(0,0), xform(0,1), xform(0,2)); - obj_pos.y = tmp * Vec3(xform(1,0), xform(1,1), xform(1,2)); - obj_pos.z = tmp * Vec3(xform(2,0), xform(2,1), xform(2,2)); - - double min = 2 * len; - - // check each polygon: - Poly* p = s->GetPolys(); - - for (int i = 0; i < s->NumPolys(); i++) { - Point v = p->plane.normal; - double d = p->plane.distance; - - double denom = dir*v; - - if (denom < -1.0e-5) { - Point P = v * d; - double ilen = ((P-obj_pos)*v)/denom; - - if (ilen > 0 && ilen < min) { - Point intersect = obj_pos + dir * ilen; - - if (p->Contains(intersect)) { - ipt = intersect; - min = ilen; - impact = 1; - } - } - } - - p++; - } - - // xform impact point back into world coordinates: - - if (impact) { - ipt = (ipt * Orientation()) + loc; - } - - return impact; -} - -// +--------------------------------------------------------------------+ - -double -TerrainPatch::Height(double x, double z) const -{ - if (water) return base; - - double height = 0; - - x /= scale; - z /= scale; - - int x0 = (int) x; - int z0 = (int) z; - - if (x0 >= 0 && x0 < PATCH_SIZE && z0 >= 0 && z0 < PATCH_SIZE) { - double dx = x-x0; - double dz = z-z0; - - double h[4]; - - h[0] = heights[(z0*PATCH_SIZE + x0)]; - h[1] = heights[((z0+1)*PATCH_SIZE + x0)]; - h[2] = heights[(z0*PATCH_SIZE + x0+1)]; - h[3] = heights[((z0+1)*PATCH_SIZE + x0+1)]; - - // if level, just return height of one vertex: - if (h[0] == h[1] && h[1] == h[2] && h[2] == h[3]) { - height = h[0]; - } - - // if sloped, interpolate between vertex heights: - else { - double hl = h[0]*(1-dz) + h[1]*dz; - double hr = h[2]*(1-dz) + h[3]*dz; - - height = hl*(1-dx) + hr*dx + 5; // fudge - } - } - - if (height < 0) - height = 0; - - return height; -} diff --git a/Stars45/TerrainPatch.h b/Stars45/TerrainPatch.h deleted file mode 100644 index db91833..0000000 --- a/Stars45/TerrainPatch.h +++ /dev/null @@ -1,93 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - A Single Multi-LOD Section of a Terrain Object -*/ - -#ifndef TerrainPatch_h -#define TerrainPatch_h - -#include "Types.h" -#include "Solid.h" -#include "Geometry.h" -#include "Polygon.h" - -// +--------------------------------------------------------------------+ - -class Projector; -class Terrain; -class Water; - -// +--------------------------------------------------------------------+ - -class TerrainPatch : public Solid -{ -public: - TerrainPatch(Terrain* terrain, - const Bitmap* patch, const Rect& rect, - const Point& p1, const Point& p2); - TerrainPatch(Terrain* terrain, const Rect& rect, - const Point& p1, const Point& p2, - double sea_level); - virtual ~TerrainPatch(); - - virtual void SelectDetail(Projector* projector); - virtual void Render(Video* video, DWORD flags); - - virtual int CollidesWith(Graphic& o); - - // accessors: - double Scale() const { return scale; } - double MountainScale() const { return mtnscale; } - double SeaLevel() const { return base; } - double MinHeight() const { return min_height; } - double MaxHeight() const { return max_height; } - bool IsWater() const { return water != 0; } - - void UpdateSurfaceWaves(Vec3& eyePos); - - void SetScales(double scale, double mtnscale, double base); - void SetDetailLevel(int nd); - - virtual int CheckRayIntersection(Point pt, Point vpn, double len, Point& ipt, - bool treat_translucent_polys_as_solid=true); - - double Height(double x, double y) const; - DWORD BlendValue(double y); - int CalcLayer(Poly* p); - void Illuminate(Color ambient, List& lights); - -protected: - virtual bool BuildDetailLevel(int level); - - enum { MAX_LOD=8 }; - - Terrain* terrain; - int patch_size; - int ndetail; - int max_detail; - int terrain_width; - - Rect rect; - float* heights; - Model* detail_levels[MAX_LOD]; - List materials; - Water* water; - - double scale; - double mtnscale; - double base; - double size; - float min_height; - float max_height; -}; - -#endif // TerrainPatch_h - diff --git a/Stars45/TerrainRegion.cpp b/Stars45/TerrainRegion.cpp deleted file mode 100644 index 0a05df0..0000000 --- a/Stars45/TerrainRegion.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Various Heavenly Bodies -*/ - -#include "TerrainRegion.h" -#include "Sky.h" -#include "TerrainHaze.h" -#include "TerrainLayer.h" -#include "Sim.h" -#include "Grid.h" -#include "CameraDirector.h" -#include "HUDView.h" - -#include "Game.h" -#include "Sound.h" -#include "Solid.h" -#include "Sprite.h" -#include "Light.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Scene.h" -#include "ParseUtil.h" - -// +====================================================================+ - -TerrainRegion::TerrainRegion(StarSystem* s, const char* n, double r, Orbital* p) -: OrbitalRegion(s, n, 0.0, r, 0.0, p), -scale(10e3), -mtnscale(1e3), -fog_density(0), -fog_scale(0), -day_phase(0), -eclipsed(false) -{ - type = TERRAIN; - - if (primary) { - orbit = primary->Radius(); - period = primary->Rotation(); - } - - clouds_alt_high = 12.0e3; - clouds_alt_low = 8.0e3; - - Update(); -} - -// +--------------------------------------------------------------------+ - -TerrainRegion::~TerrainRegion() -{ - layers.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -TerrainRegion::Update() -{ - if (system && primary) { - phase = primary->RotationPhase(); - loc = primary->Location() + Point((double) (orbit * cos(phase)), - (double) (orbit * sin(phase)), - 0); - } - - if (rep) - rep->MoveTo(loc.OtherHand()); - - // calc day phase: - OrbitalBody* star = system->Bodies()[0]; - - Point tvpn = Location() - primary->Location(); - Point tvst = star->Location() - primary->Location(); - - tvpn.Normalize(); - tvst.Normalize(); - - day_phase = acos(tvpn * tvst) + PI; - - Point meridian = tvpn.cross(tvst); - - if (meridian.z < 0) { - day_phase = 2*PI - day_phase; - } - - day_phase *= 24 / (2*PI); - - if (!system || system->ActiveRegion() != this) - return; - - // set sky color: - int base_hour = (int) day_phase; - double fraction = day_phase - base_hour; - - sky_color[24] = Color::Scale(sky_color[base_hour], sky_color[base_hour+1], fraction); - sun_color[24] = Color::Scale(sun_color[base_hour], sun_color[base_hour+1], fraction); - fog_color[24] = Color::Scale(fog_color[base_hour], fog_color[base_hour+1], fraction); - ambient[24] = Color::Scale(ambient[base_hour], ambient[base_hour+1], fraction); - overcast[24] = Color::Scale(overcast[base_hour], overcast[base_hour+1], fraction); - cloud_color[24] = Color::Scale(cloud_color[base_hour], cloud_color[base_hour+1], fraction); - shade_color[24] = Color::Scale(shade_color[base_hour], shade_color[base_hour+1], fraction); - - CameraDirector* cam_dir = CameraDirector::GetInstance(); - Sim* sim = Sim::GetSim(); - double alt = 0; - double dim = 1; - - if (cam_dir && cam_dir->GetCamera()) - alt = cam_dir->GetCamera()->Pos().y; - - if (alt > 0) { - if (alt < TERRAIN_ALTITUDE_LIMIT) { - if (weather.Ceiling() > 0) { - fog_color[24] = overcast[24]; - sky_color[24] = overcast[24]; - dim = 0.125; - - /*** - if (alt < weather.Ceiling()) { - sky_color[24] = overcast[24]; - dim = 0.125; - } - else if (alt < weather.Ceiling() + 500) { - double thick = (weather.Ceiling() + 500.0 - alt) / 500.0; - sky_color[24] = sky_color[24] * (1.0 - thick); - sky_color[24] += overcast[24] * thick; - - dim = 1 - thick * 0.875; - } - else { - sky_color[24] = sky_color[24] * (1 - alt/TERRAIN_ALTITUDE_LIMIT); - } - ***/ - } - - else { - sky_color[24] = sky_color[24] * (1 - alt/TERRAIN_ALTITUDE_LIMIT); - } - } - else { - sky_color[24] = Color::Black; - } - } - - if (system) { - system->SetSunlight(sun_color[24], dim); - system->SetBacklight(sky_color[24], dim); - - HUDView* hud = HUDView::GetInstance(); - if (hud) { - Color night_vision = hud->Ambient(); - sky_color[24] += night_vision * 0.15; - } - } -} - -// +--------------------------------------------------------------------+ - -void -TerrainRegion::LoadSkyColors(const char* bmp_name) -{ - Bitmap sky_colors_bmp; - - DataLoader* loader = DataLoader::GetLoader(); - loader->LoadBitmap(bmp_name, sky_colors_bmp); - - int max_color = sky_colors_bmp.Width(); - - if (max_color > 24) - max_color = 24; - - for (int i = 0; i < 25; i++) { - sun_color[i] = Color::White; - sky_color[i] = Color::Black; - fog_color[i] = Color::White; - ambient[i] = Color::DarkGray; - cloud_color[i] = Color::White; - shade_color[i] = Color::Gray; - } - - for (int i = 0; i < max_color; i++) - sky_color[i] = sky_colors_bmp.GetColor(i, 0); - - if (sky_colors_bmp.Height() > 1) - for (int i = 0; i < max_color; i++) - fog_color[i].Set(sky_colors_bmp.GetColor(i, 1).Value() | Color(0,0,0,255).Value()); - - if (sky_colors_bmp.Height() > 2) - for (int i = 0; i < max_color; i++) - ambient[i] = sky_colors_bmp.GetColor(i, 2); - - if (sky_colors_bmp.Height() > 3) - for (int i = 0; i < max_color; i++) - sun_color[i] = sky_colors_bmp.GetColor(i, 3); - - if (sky_colors_bmp.Height() > 4) - for (int i = 0; i < max_color; i++) - overcast[i] = sky_colors_bmp.GetColor(i, 4); - - if (sky_colors_bmp.Height() > 5) - for (int i = 0; i < max_color; i++) - cloud_color[i] = sky_colors_bmp.GetColor(i, 5); - - if (sky_colors_bmp.Height() > 6) - for (int i = 0; i < max_color; i++) - shade_color[i] = sky_colors_bmp.GetColor(i, 6); -} - -// +--------------------------------------------------------------------+ - -void -TerrainRegion::AddLayer(double h, const char* tile, const char* detail) -{ - TerrainLayer* layer = new TerrainLayer; - - layer->min_height = h; - layer->tile_name = tile; - - if (detail && *detail) - layer->detail_name = detail; - - layers.append(layer); -} - -const Text& -TerrainRegion::EnvironmentTexture(int face) const -{ - switch (face) { - case 0: return env_texture_positive_x; - - case 1: if (env_texture_negative_x.length() > 0) - return env_texture_negative_x; - return env_texture_positive_x; - - case 2: return env_texture_positive_y; - - case 3: if (env_texture_negative_y.length() > 0) - return env_texture_negative_y; - return env_texture_positive_y; - - case 4: if (env_texture_positive_z.length() > 0) - return env_texture_positive_z; - return env_texture_positive_x; - - case 5: if (env_texture_negative_z.length() > 0) - return env_texture_negative_z; - if (env_texture_positive_z.length() > 0) - return env_texture_positive_z; - return env_texture_positive_x; - } - - return env_texture_positive_x; -} - diff --git a/Stars45/TerrainRegion.h b/Stars45/TerrainRegion.h deleted file mode 100644 index 5f84bab..0000000 --- a/Stars45/TerrainRegion.h +++ /dev/null @@ -1,125 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Various heavenly bodies -*/ - -#ifndef TerrainRegion_h -#define TerrainRegion_h - -#include "Types.h" -#include "StarSystem.h" -#include "Weather.h" - -// +--------------------------------------------------------------------+ - -const double TERRAIN_ALTITUDE_LIMIT = 35e3; - -class TerrainLayer; - -// +--------------------------------------------------------------------+ - -class TerrainRegion : public OrbitalRegion -{ - friend class StarSystem; - -public: - TerrainRegion(StarSystem* sys, const char* n, double r, Orbital* prime=0); - virtual ~TerrainRegion(); - - // operations: - virtual void Update(); - - // accessors: - const Text& PatchName() const { return patch_name; } - const Text& PatchTexture() const { return patch_texture; } - const Text& ApronName() const { return apron_name; } - const Text& ApronTexture() const { return apron_texture; } - const Text& WaterTexture() const { return water_texture; } - const Text& DetailTexture0() const { return noise_tex0; } - const Text& DetailTexture1() const { return noise_tex1; } - const Text& HazeName() const { return haze_name; } - const Text& CloudsHigh() const { return clouds_high; } - const Text& ShadesHigh() const { return shades_high; } - const Text& CloudsLow() const { return clouds_low; } - const Text& ShadesLow() const { return shades_low; } - const Text& EnvironmentTexture(int n) const; - - Color SunColor() const { return sun_color[24]; } - Color SkyColor() const { return sky_color[24]; } - Color FogColor() const { return fog_color[24]; } - Color Ambient() const { return ambient[24]; } - Color Overcast() const { return overcast[24]; } - Color CloudColor() const { return cloud_color[24];} - Color ShadeColor() const { return shade_color[24];} - - double LateralScale() const { return scale; } - double MountainScale() const { return mtnscale; } - double FogDensity() const { return fog_density; } - double FogScale() const { return fog_scale; } - double DayPhase() const { return day_phase; } - double HazeFade() const { return haze_fade; } - double CloudAltHigh() const { return clouds_alt_high; } - double CloudAltLow() const { return clouds_alt_low; } - Weather& GetWeather() { return weather; } - List& GetLayers() { return layers; } - - bool IsEclipsed() const { return eclipsed; } - void SetEclipsed(bool e) { eclipsed = e; } - - void LoadSkyColors(const char* bmp_name); - void AddLayer(double h, const char* tile, const char* detail=0); - -protected: - Text patch_name; - Text patch_texture; - Text apron_name; - Text apron_texture; - Text water_texture; - Text env_texture_positive_x; - Text env_texture_negative_x; - Text env_texture_positive_y; - Text env_texture_negative_y; - Text env_texture_positive_z; - Text env_texture_negative_z; - Text noise_tex0; - Text noise_tex1; - Text haze_name; - Text clouds_high; - Text clouds_low; - Text shades_high; - Text shades_low; - - Color sun_color[25]; - Color sky_color[25]; - Color fog_color[25]; - Color ambient[25]; - Color overcast[25]; - Color cloud_color[25]; - Color shade_color[25]; - - double scale; - double mtnscale; - - double fog_density; - double fog_scale; - double day_phase; - double haze_fade; - double clouds_alt_high; - double clouds_alt_low; - - Weather weather; - bool eclipsed; - - List layers; -}; - -#endif // TerrainRegion_h - diff --git a/Stars45/TexCubeDX9.cpp b/Stars45/TexCubeDX9.cpp deleted file mode 100644 index c2e5a89..0000000 --- a/Stars45/TexCubeDX9.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Direct3D Texture Cache -*/ - -#include "TexCubeDX9.h" -#include "VideoDX9.h" -#include "Bitmap.h" -#include "Color.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -void VideoDX9Error(const char* msg, HRESULT err); - -#ifndef RELEASE -#define RELEASE(x) if (x) { x->Release(); x=NULL; } -#endif - -// +--------------------------------------------------------------------+ - -TexCubeDX9::TexCubeDX9(VideoDX9* v) -: video(v), texture(0) -{ - d3d = video->Direct3D(); - d3ddevice = video->D3DDevice(); - - for (int i = 0; i < 6; i++) { - faces[i] = 0; - last_modified[i] = 0; - } -} - -TexCubeDX9::~TexCubeDX9() -{ - RELEASE(texture); -} - -// +--------------------------------------------------------------------+ - -bool -TexCubeDX9::LoadTexture(Bitmap* bmp, int face_index) -{ - if (!d3ddevice) return false; - - if (faces[face_index] == bmp && last_modified[face_index] >= bmp->LastModified()) - return true; // already loaded and hasn't been modified - - HRESULT hr = D3D_OK; - - // create the texture, if necessary - if (!texture) { - hr = d3ddevice->CreateCubeTexture(bmp->Width(), - 1, // one mip level - 0, // no specific usage - D3DFMT_A8R8G8B8, // format matching Color::rgba - D3DPOOL_MANAGED, - &texture, - 0); - - if (FAILED(hr) || !texture) { - VideoDX9Error("LoadTexture - could not create cube texture", hr); - return false; - } - } - - // lock the surface for writing - D3DLOCKED_RECT locked_rect; - D3DCUBEMAP_FACES face = (D3DCUBEMAP_FACES) face_index; - hr = texture->LockRect(face, 0, &locked_rect, 0, 0); - - if (FAILED(hr)) { - VideoDX9Error("LoadTexture - could not lock texture surface", hr); - RELEASE(texture); - return false; - } - - // load the bitmap into the texture surface - for (int i = 0; i < bmp->Height(); i++) { - BYTE* src = (BYTE*) (bmp->HiPixels() + i * bmp->Width()); - BYTE* dst = (BYTE*) locked_rect.pBits + i * locked_rect.Pitch; - - CopyMemory(dst, src, bmp->Width() * sizeof(Color)); - } - - // unlock the surface - texture->UnlockRect(face, 0); - - faces[face_index] = bmp; - last_modified[face_index] = bmp->LastModified(); - - return true; -} - -// +--------------------------------------------------------------------+ - -IDirect3DCubeTexture9* -TexCubeDX9::GetTexture() -{ - if (texture) { - // need to refresh anything? - for (int i = 0; i < 6; i++) { - if (faces[i] && last_modified[i] < faces[i]->LastModified()) { - LoadTexture(faces[i], i); - } - } - } - - return texture; -} diff --git a/Stars45/TexCubeDX9.h b/Stars45/TexCubeDX9.h deleted file mode 100644 index 0b1b5ee..0000000 --- a/Stars45/TexCubeDX9.h +++ /dev/null @@ -1,48 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Direct 3D Texture Cube for Env Mapping -*/ - -#ifndef TexCubeDX9_h -#define TexCubeDX9_h - -#include "Bitmap.h" - -// +--------------------------------------------------------------------+ - -class Video; -class VideoDX9; -class Bitmap; -struct VD3D_texture_format; - -// +--------------------------------------------------------------------+ - -class TexCubeDX9 -{ -public: - TexCubeDX9(VideoDX9* video); - virtual ~TexCubeDX9(); - - IDirect3DCubeTexture9* GetTexture(); - bool LoadTexture(Bitmap* bmp, int face); - -private: - VideoDX9* video; - IDirect3D9* d3d; - IDirect3DDevice9* d3ddevice; - - IDirect3DCubeTexture9* texture; - Bitmap* faces[6]; - DWORD last_modified[6]; -}; - -#endif // TexCubeDX9_h - diff --git a/Stars45/TexDX9.cpp b/Stars45/TexDX9.cpp deleted file mode 100644 index b2c5b2b..0000000 --- a/Stars45/TexDX9.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Direct3D Texture Cache -*/ - -#include "TexDX9.h" -#include "VideoDX9.h" -#include "Bitmap.h" -#include "Color.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -void VideoDX9Error(const char* msg, HRESULT err); - -#define TEXDX9_VERBOSE 0 -#define DX9_TEXTURE_CACHE_SIZE 256 - -#ifndef RELEASE -#define RELEASE(x) if (x) { x->Release(); x=NULL; } -#endif - -// +--------------------------------------------------------------------+ - -void -TexCacheDX9Entry::Release() -{ - RELEASE(texture); -} - -// +--------------------------------------------------------------------+ - -void -TexCacheDX9Entry::Unload() -{ - RELEASE(texture); - bitmap_id = 0; - used_last = 0; - last_modified = 0; -} - -// +--------------------------------------------------------------------+ - -TexCacheDX9::TexCacheDX9(VideoDX9* v) -: video(v), count(0), mru(0) -{ - d3d = video->Direct3D(); - d3ddevice = video->D3DDevice(); - - // clear the texture cache - cache = new TexCacheDX9Entry[DX9_TEXTURE_CACHE_SIZE]; - vidmem = video->VidMemFree(); -} - -TexCacheDX9::~TexCacheDX9() -{ - int used = 0; - - if (cache) { - for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++) { - if (cache[i].bitmap_id) - used++; - cache[i].Unload(); - } - - delete [] cache; - cache = 0; - } - - Print("TexCacheDX9: final used count = %d\n", used); -} - -// +--------------------------------------------------------------------+ - -bool -TexCacheDX9::LoadTexture(Bitmap* bmp, TexCacheDX9Entry* entry) -{ - if (!d3ddevice) return false; - - HRESULT hr = D3D_OK; - - // create the texture, if necessary - if (!entry->texture || entry->bitmap_id != bmp->Handle()) { - hr = d3ddevice->CreateTexture(bmp->Width(), - bmp->Height(), - 1, // one mip level - 0, // no specific usage - D3DFMT_A8R8G8B8, // format matching Color::rgba - D3DPOOL_MANAGED, - &entry->texture, - 0); - - if (FAILED(hr) || !entry->texture) { - VideoDX9Error("LoadTexture - could not create texture", hr); - return false; - } - } - - // lock the surface for writing - D3DLOCKED_RECT locked_rect; - hr = entry->texture->LockRect(0, &locked_rect, 0, 0); - - if (FAILED(hr)) { - VideoDX9Error("LoadTexture - could not lock texture surface", hr); - entry->Unload(); - return false; - } - - // load the bitmap into the texture surface - for (int i = 0; i < bmp->Height(); i++) { - BYTE* src = (BYTE*) (bmp->HiPixels() + i * bmp->Width()); - BYTE* dst = (BYTE*) locked_rect.pBits + i * locked_rect.Pitch; - - CopyMemory(dst, src, bmp->Width() * sizeof(Color)); - } - - // unlock the surface - entry->texture->UnlockRect(0); - - entry->last_modified = bmp->LastModified(); - vidmem = video->VidMemFree(); - return true; -} - -// +--------------------------------------------------------------------+ - -void -TexCacheDX9::CreateNormalMap(int index, float amp) -{ - if (d3ddevice && cache[index].texture && !cache[index].normal) { - HRESULT hr = D3D_OK; - TexCacheDX9Entry* entry = &cache[index]; - Bitmap* bmp = Bitmap::GetBitmapByID(entry->bitmap_id); - - IDirect3DTexture9* normal_map = 0; - - // create the normal map texture - hr = d3ddevice->CreateTexture(bmp->Width(), - bmp->Height(), - 1, // one mip levels - 0, // no specific usage - D3DFMT_A8R8G8B8, // format matching Color::rgba - D3DPOOL_MANAGED, - &normal_map, - 0); - - if (FAILED(hr) || !normal_map) { - VideoDX9Error("CreateNormalMap - could not create texture", hr); - return; - } - - D3DXComputeNormalMap(normal_map, entry->texture ,NULL, 0, D3DX_CHANNEL_RED, amp); - - entry->texture->Release(); - entry->texture = normal_map; - entry->normal = true; - - // The D3DX function destroys the alpha channel data - // when it builds the normal map. We want the original - // height data stored in the alpha channel, so we need - // to add it back in now. - - // lock the surface for writing - D3DLOCKED_RECT locked_rect; - hr = normal_map->LockRect(0, &locked_rect, 0, 0); - - if (FAILED(hr)) { - VideoDX9Error("CreateNormalMap - could not insert height channel", hr); - return; - } - - // load the bitmap into the texture surface - for (int i = 0; i < bmp->Height(); i++) { - BYTE* src = (BYTE*) (bmp->HiPixels() + i * bmp->Width()); - BYTE* dst = (BYTE*) locked_rect.pBits + i * locked_rect.Pitch; - - src += 2; // red channel - dst += 3; // alpha channel - - for (int n = 0; n < bmp->Width(); n++) { - *dst = *src; - - dst += 4; - src += 4; - } - } - - // unlock the surface - normal_map->UnlockRect(0); - } -} - -// +--------------------------------------------------------------------+ - -IDirect3DTexture9* -TexCacheDX9::FindTexture(Bitmap* bmp) -{ - int avail = -1; - - if (!bmp) - return 0; - - // check most recently used: - if (cache[mru].bitmap_id == bmp->Handle()) { - cache[mru].used_last = frame_number; - - // need to refresh? - if (cache[mru].last_modified < bmp->LastModified()) { - LoadTexture(bmp, &cache[mru]); - cache[mru].normal = false; - } - - return cache[mru].texture; - } - - // find cache entry, or first free: - for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++) - if (cache[i].bitmap_id == bmp->Handle()) { - cache[i].used_last = frame_number; - mru = i; - - // need to refresh? - if (cache[mru].last_modified < bmp->LastModified()) { - LoadTexture(bmp, &cache[mru]); - cache[mru].normal = false; - } - - return cache[i].texture; - } - else if (avail < 0 && cache[i].bitmap_id == 0) - avail = i; - - // no free space - if (avail < 0) - if (FreeUpCache()) - return FindTexture(bmp); - else - return 0; - - TexCacheDX9Entry* entry = &cache[avail]; - entry->bitmap_id = bmp->Handle(); - entry->used_last = frame_number; - - if (LoadTexture(bmp, entry)) { -#if TEXDX9_VERBOSE - Print(" Tex %3d: id=%2d, size=%3d, type=%d, hTex=%3d, frame=%6d vmf=%8d\n", - avail, bmp->Handle(), bmp->Width(), bmp->Type(), - cache[avail].texture, cache[avail].used_last, vidmem); -#endif - mru = avail; - cache[mru].normal = false; - return entry->texture; - } - else { - // failed to load texture, - // erase cache entry: - entry->Unload(); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -IDirect3DTexture9* -TexCacheDX9::FindNormalMap(Bitmap* bmp, float amp) -{ - int avail = -1; - - if (!bmp) - return 0; - - // check most recently used: - if (cache[mru].bitmap_id == bmp->Handle()) { - cache[mru].used_last = frame_number; - - // need to refresh? - if (cache[mru].last_modified < bmp->LastModified()) { - LoadTexture(bmp, &cache[mru]); - cache[mru].normal = false; - } - - if (!cache[mru].normal) - CreateNormalMap(mru, amp); - - return cache[mru].texture; - } - - // find cache entry, or first free: - for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++) - if (cache[i].bitmap_id == bmp->Handle()) { - cache[i].used_last = frame_number; - mru = i; - - // need to refresh? - if (cache[i].last_modified < bmp->LastModified()) { - LoadTexture(bmp, &cache[mru]); - cache[i].normal = false; - } - - if (!cache[i].normal) - CreateNormalMap(i, amp); - - return cache[i].texture; - } - else if (avail < 0 && cache[i].bitmap_id == 0) - avail = i; - - // no free space - if (avail < 0) - if (FreeUpCache()) - return FindTexture(bmp); - else - return 0; - - TexCacheDX9Entry* entry = &cache[avail]; - entry->bitmap_id = bmp->Handle(); - entry->used_last = frame_number; - - if (LoadTexture(bmp, entry)) { -#if TEXDX9_VERBOSE - Print(" Tex %3d: id=%2d, size=%3d, type=%d, hTex=%3d, frame=%6d vmf=%8d\n", - avail, bmp->Handle(), bmp->Width(), bmp->Type(), - cache[avail].texture, cache[avail].used_last, vidmem); -#endif - mru = avail; - CreateNormalMap(mru, amp); - return entry->texture; - } - else { - // failed to load texture, - // erase cache entry: - entry->Unload(); - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -int -TexCacheDX9::FreeLRU(int tries) -{ - int unloaded = 0; - - while (tries--) { - int oldest = -1; - DWORD old = frame_number; - - for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++) { - DWORD ul = cache[i].used_last; - - if (ul && ul < old && ul != frame_number) { - old = ul; - oldest = i; - } - } - - if (oldest >= 0) { - cache[oldest].Unload(); - unloaded++; - } - else - break; - } - - vidmem = video->VidMemFree(); - -#if TEXDX9_VERBOSE - Print(" FreeLRU() frame=%6d unloaded=%2d vmf=%8d\n", frame_number, unloaded, vidmem); -#endif - - return unloaded; -} - -// +--------------------------------------------------------------------+ - -int -TexCacheDX9::FreeUpCache() -{ - int unloaded = 0; - - for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++) { - if (cache[i].used_last && cache[i].used_last < frame_number) { - cache[i].Unload(); - unloaded++; - } - } - - vidmem = video->VidMemFree(); - - Print(" FreeUpCache() frame=%6d unloaded=%2d vmf=%8d\n", frame_number, unloaded, vidmem); - - return unloaded; -} - -// +--------------------------------------------------------------------+ - -void -TexCacheDX9::InvalidateCache() -{ - for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++) { - cache[i].Unload(); - cache[i].normal = false; - } - - vidmem = video->VidMemFree(); -} diff --git a/Stars45/TexDX9.h b/Stars45/TexDX9.h deleted file mode 100644 index 247b1ad..0000000 --- a/Stars45/TexDX9.h +++ /dev/null @@ -1,78 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Direct 3D Texture Cache -*/ - -#ifndef TexDX9_h -#define TexDX9_h - -#include "Bitmap.h" - -// +--------------------------------------------------------------------+ - -class Video; -class VideoDX9; -class Bitmap; -struct VD3D_texture_format; - -// +--------------------------------------------------------------------+ - -struct TexCacheDX9Entry -{ - TexCacheDX9Entry() : bitmap_id(0), texture(0), used_last(0), - last_modified(0), normal(false) { } - - void Release(); - void Unload(); - - HANDLE bitmap_id; - IDirect3DTexture9* texture; - DWORD used_last; - DWORD last_modified; - bool normal; -}; - -// +--------------------------------------------------------------------+ - -class TexCacheDX9 -{ -public: - TexCacheDX9(VideoDX9* video); - virtual ~TexCacheDX9(); - - void FrameNumber(int n) { frame_number = n; } - IDirect3DTexture9* FindTexture(Bitmap* bmp); - IDirect3DTexture9* FindNormalMap(Bitmap* bmp, float amp=1); - bool LoadTexture(Bitmap* bmp, TexCacheDX9Entry* entry); - void InvalidateCache(); - - int count; - -private: - int FreeLRU(int tries=4); - int FreeUpCache(); - void CreateNormalMap(int index, float amp=1); - - VideoDX9* video; - IDirect3D9* d3d; - IDirect3DDevice9* d3ddevice; - - DWORD vidmem; - - int bad_frame; - DWORD frame_number; - - int mru; - TexCacheDX9Entry* cache; -}; - -#endif // TexDX9_h - diff --git a/Stars45/Thruster.cpp b/Stars45/Thruster.cpp deleted file mode 100644 index 3852516..0000000 --- a/Stars45/Thruster.cpp +++ /dev/null @@ -1,594 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon class -*/ - -#include "Thruster.h" -#include "Component.h" -#include "Drive.h" -#include "FlightComp.h" -#include "SystemDesign.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Sim.h" -#include "CameraDirector.h" -#include "AudioConfig.h" -#include "Random.h" - -#include "Light.h" -#include "Bitmap.h" -#include "Sound.h" -#include "DataLoader.h" -#include "ContentBundle.h" -#include "Bolt.h" -#include "Sprite.h" -#include "Game.h" - -// +----------------------------------------------------------------------+ - -static Sound* thruster_resource = 0; -static Sound* thruster_sound = 0; - -extern Bitmap* drive_flare_bitmap[8]; -extern Bitmap* drive_trail_bitmap[8]; - -#define CLAMP(x, a, b) if (x < (a)) x = (a); else if (x > (b)) x = (b); - -// +----------------------------------------------------------------------+ - -ThrusterPort::ThrusterPort(int t, const Point& l, DWORD f, float s) - : type(t), loc(l), flare(0), trail(0), fire(f), burn(0), scale(s) -{ } - -ThrusterPort::~ThrusterPort() -{ - GRAPHIC_DESTROY(flare); - GRAPHIC_DESTROY(trail); -} - -// +----------------------------------------------------------------------+ - -static int sys_value = 2; - -// +----------------------------------------------------------------------+ - -Thruster::Thruster(int dtype, double max_thrust, float flare_scale) - : System(DRIVE, dtype, "Thruster", sys_value, - max_thrust, max_thrust, max_thrust), - ship(0), thrust(1.0f), scale(flare_scale), - avail_x(1.0f), avail_y(1.0f), avail_z(1.0f) -{ - name = ContentBundle::GetInstance()->GetText("sys.thruster"); - abrv = ContentBundle::GetInstance()->GetText("sys.thruster.abrv"); - - power_flags = POWER_WATTS; - - ZeroMemory(burn, sizeof(burn)); - - emcon_power[0] = 50; - emcon_power[1] = 50; - emcon_power[2] = 100; -} - -// +----------------------------------------------------------------------+ - -Thruster::Thruster(const Thruster& t) - : System(t), ship(0), - thrust(1.0f), scale(t.scale), - avail_x(1.0f), avail_y(1.0f), avail_z(1.0f) -{ - power_flags = POWER_WATTS; - Mount(t); - - ZeroMemory(burn, sizeof(burn)); - - if (subtype != Drive::STEALTH) { - for (int i = 0; i < t.ports.size(); i++) { - ThrusterPort* p = t.ports[i]; - CreatePort(p->type, p->loc, p->fire, p->scale); - } - } -} - -// +--------------------------------------------------------------------+ - -Thruster::~Thruster() -{ - ports.destroy(); - - if (thruster_sound && thruster_sound->IsPlaying()) { - thruster_sound->Stop(); - } -} - -// +--------------------------------------------------------------------+ - -void -Thruster::Initialize() -{ - static int initialized = 0; - if (initialized) return; - - DataLoader* loader = DataLoader::GetLoader(); - - const int SOUND_FLAGS = Sound::LOCALIZED | - Sound::LOC_3D | - Sound::LOOP | - Sound::LOCKED; - - loader->SetDataPath("Sounds/"); - loader->LoadSound("thruster.wav", thruster_resource, SOUND_FLAGS); - loader->SetDataPath(0); - - if (thruster_resource) - thruster_resource->SetMaxDistance(15.0e3f); - - initialized = 1; -} - -void -Thruster::Close() -{ - delete thruster_resource; - thruster_resource = 0; - - if (thruster_sound) { - thruster_sound->Stop(); - thruster_sound->Release(); - } -} - -// +--------------------------------------------------------------------+ - -void -Thruster::Orient(const Physical* rep) -{ - System::Orient(rep); - - bool hide_all = false; - if (!ship || (ship->IsAirborne() && ship->Class() != Ship::LCA)) { - hide_all = true; - } - - if (ship->Rep() && ship->Rep()->Hidden()) { - hide_all = true; - } - - if (thrust <= 0) { - hide_all = true; - } - - const Matrix& orientation = rep->Cam().Orientation(); - Point ship_loc = rep->Location(); - - for (int i = 0; i < ports.size(); i++) { - ThrusterPort* p = ports[i]; - - Point projector = (p->loc * orientation) + ship_loc; - - if (p->flare) - p->flare->MoveTo(projector); - - if (p->trail) { - double intensity = p->burn; - - if (intensity > 0.5 && !hide_all) { - Bolt* t = (Bolt*) p->trail; - double len = -50 * p->scale * intensity; - - t->Show(); - - switch (p->type) { - case LEFT: t->SetEndPoints(projector, projector + rep->Cam().vrt() * len); break; - case RIGHT: t->SetEndPoints(projector, projector - rep->Cam().vrt() * len); break; - case AFT: t->SetEndPoints(projector, projector + rep->Cam().vpn() * len); break; - case FORE: t->SetEndPoints(projector, projector - rep->Cam().vpn() * len); break; - case BOTTOM: t->SetEndPoints(projector, projector + rep->Cam().vup() * len); break; - case TOP: t->SetEndPoints(projector, projector - rep->Cam().vup() * len); break; - default: t->Hide(); break; - } - } - else { - p->trail->Hide(); - if (p->flare) - p->flare->Hide(); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Thruster::ExecFrame(double seconds) -{ - System::ExecFrame(seconds); - - if (ship) { - double rr = 0, pr = 0, yr = 0; - double rd = 0, pd = 0, yd = 0; - - double agility = 1; - double stability = 1; - - FlightComp* flcs = ship->GetFLCS(); - - if (flcs) { - if (!flcs->IsPowerOn() || flcs->Status() < DEGRADED) { - agility = 0.3; - stability = 0.0; - } - } - - // check for thruster damage here: - if (components.size() >= 3) { - int stat = components[0]->Status(); - if (stat == Component::NOMINAL) - avail_x = 1.0f; - else if (stat == Component::DEGRADED) - avail_x = 0.5f; - else - avail_x = 0.0f; - - stat = components[1]->Status(); - if (stat == Component::NOMINAL) - avail_z = 1.0f; - else if (stat == Component::DEGRADED) - avail_z = 0.5f; - else - avail_z = 0.0f; - - stat = components[2]->Status(); - if (stat == Component::NOMINAL) - avail_y = 1.0f; - else if (stat == Component::DEGRADED) - avail_y = 0.5f; - else - avail_y = 0.0f; - } - - // thrust limited by power distribution: - thrust = energy/capacity; - energy = 0.0f; - - if (thrust < 0) - thrust = 0.0f; - - agility *= thrust; - stability *= thrust; - - rr = roll_rate * agility * avail_y; - pr = pitch_rate * agility * avail_y; - yr = yaw_rate * agility * avail_x; - - rd = roll_drag * stability * avail_y; - pd = pitch_drag * stability * avail_y; - yd = yaw_drag * stability * avail_x; - - ship->SetAngularRates(rr,pr,yr); - ship->SetAngularDrag (rd,pd,yd); - } -} - -// +--------------------------------------------------------------------+ - -void -Thruster::SetShip(Ship* s) -{ - const double ROLL_SPEED = PI * 0.0400; - const double PITCH_SPEED = PI * 0.0250; - const double YAW_SPEED = PI * 0.0250; - - ship = s; - - if (ship) { - ShipDesign* design = (ShipDesign*) ship->Design(); - - trans_x = design->trans_x; - trans_y = design->trans_y; - trans_z = design->trans_z; - - roll_drag = design->roll_drag; - pitch_drag = design->pitch_drag; - yaw_drag = design->yaw_drag; - - roll_rate = (float) (design->roll_rate * PI / 180); - pitch_rate = (float) (design->pitch_rate * PI / 180); - yaw_rate = (float) (design->yaw_rate * PI / 180); - - double agility = design->agility; - - if (roll_rate == 0) roll_rate = (float) (agility * ROLL_SPEED); - if (pitch_rate == 0) pitch_rate = (float) (agility * PITCH_SPEED); - if (yaw_rate == 0) yaw_rate = (float) (agility * YAW_SPEED); - } -} - -// +--------------------------------------------------------------------+ - -double -Thruster::TransXLimit() -{ - return trans_x * avail_x; -} - -double -Thruster::TransYLimit() -{ - return trans_y * avail_y; -} - -double -Thruster::TransZLimit() -{ - return trans_z * avail_z; -} - -// +--------------------------------------------------------------------+ - -void -Thruster::ExecTrans(double x, double y, double z) -{ - if (!ship || (ship->IsAirborne() && ship->Class() != Ship::LCA)) { - if (thruster_sound && thruster_sound->IsPlaying()) - thruster_sound->Stop(); - - for (int i = 0; i < ports.size(); i++) { - ThrusterPort* p = ports[i]; - if (p->flare) p->flare->Hide(); - if (p->trail) p->trail->Hide(); - } - - return; - } - - bool sound_on = false; - bool show_flare = true; - - if (ship->Rep() && ship->Rep()->Hidden()) - show_flare = false; - - if (ship->Class() == Ship::LCA && - ship->IsAirborne() && - ship->Velocity().length() < 250 && - ship->AltitudeAGL() > ship->Radius()/2) { - - sound_on = true; - IncBurn(BOTTOM, TOP); - } - - else if (!ship->IsAirborne()) { - double tx_limit = ship->Design()->trans_x; - double ty_limit = ship->Design()->trans_y; - double tz_limit = ship->Design()->trans_z; - - if (x < -0.15 * tx_limit) IncBurn(RIGHT, LEFT); - else if (x > 0.15 * tx_limit) IncBurn(LEFT, RIGHT); - else DecBurn(LEFT, RIGHT); - - if (y < -0.15 * ty_limit) IncBurn(FORE, AFT); - else if (y > 0.15 * ty_limit) IncBurn(AFT, FORE); - else DecBurn(FORE, AFT); - - if (z < -0.15 * tz_limit) IncBurn(TOP, BOTTOM); - else if (z > 0.15 * tz_limit) IncBurn(BOTTOM, TOP); - else DecBurn(TOP, BOTTOM); - - double r, p, y; - ship->GetAngularThrust(r, p, y); - - // Roll seems to have the opposite sign from - // the pitch and yaw thrust factors. Not sure why. - - if (r > 0) IncBurn(ROLL_L, ROLL_R); - else if (r < 0) IncBurn(ROLL_R, ROLL_L); - else DecBurn(ROLL_R, ROLL_L); - - if (y < 0) IncBurn(YAW_L, YAW_R); - else if (y > 0) IncBurn(YAW_R, YAW_L); - else DecBurn(YAW_R, YAW_L); - - if (p < 0) IncBurn(PITCH_D, PITCH_U); - else if (p > 0) IncBurn(PITCH_U, PITCH_D); - else DecBurn(PITCH_U, PITCH_D); - } - - else { - for (int i = 0; i < 12; i++) { - burn[i] -= 0.1f; - if (burn[i] < 0) - burn[i] = 0.0f; - } - } - - for (int i = 0; i < ports.size(); i++) { - ThrusterPort* p = ports[i]; - - if (p->fire) { - p->burn = 0; - - int flag = 1; - - for (int n = 0; n < 12; n++) { - if ((p->fire & flag) != 0 && burn[n] > p->burn) - p->burn = burn[n]; - - flag <<= 1; - } - } - - else { - p->burn = burn[p->type]; - } - - if (p->burn > 0 && thrust > 0) { - sound_on = true; - - if (show_flare) { - Sprite* flare_rep = (Sprite*) p->flare; - if (flare_rep) { - flare_rep->Show(); - flare_rep->SetShade(1); - } - - if (p->trail) { - Bolt* t = (Bolt*) p->trail; - t->Show(); - t->SetShade(1); - } - } - } - else { - if (p->flare) p->flare->Hide(); - if (p->trail) p->trail->Hide(); - } - } - - // thruster sound: - if (ship && ship == Sim::GetSim()->GetPlayerShip() && ports.size() > 0) { - CameraDirector* cam_dir = CameraDirector::GetInstance(); - - // no sound when paused! - if (!Game::GetInstance()->Paused() && cam_dir && cam_dir->GetCamera()) { - if (!thruster_sound) { - if (thruster_resource) - thruster_sound = thruster_resource->Duplicate(); - } - - if (thruster_sound) { - if (sound_on) { - Point cam_loc = cam_dir->GetCamera()->Pos(); - double dist = (ship->Location() - cam_loc).length(); - - long max_vol = AudioConfig::EfxVolume(); - long volume = -2000; - - if (volume > max_vol) - volume = max_vol; - - if (dist < thruster_sound->GetMaxDistance()) { - thruster_sound->SetLocation(ship->Location()); - thruster_sound->SetVolume(volume); - thruster_sound->Play(); - } - else if (thruster_sound->IsPlaying()) { - thruster_sound->Stop(); - } - } - else if (thruster_sound->IsPlaying()) { - thruster_sound->Stop(); - } - } - } - } - - ship->SetTransX(x * thrust); - ship->SetTransY(y * thrust); - ship->SetTransZ(z * thrust); -} - -// +--------------------------------------------------------------------+ - -void -Thruster::AddPort(int type, const Point& loc, DWORD fire, float flare_scale) -{ - if (flare_scale == 0) flare_scale = scale; - ThrusterPort* port = new ThrusterPort(type, loc, fire, flare_scale); - ports.append(port); -} - -void -Thruster::CreatePort(int type, const Point& loc, DWORD fire, float flare_scale) -{ - Bitmap* flare_bmp = drive_flare_bitmap[subtype]; - Bitmap* trail_bmp = drive_trail_bitmap[subtype]; - - if (subtype != Drive::STEALTH) { - Sprite* flare_rep = new Sprite(flare_bmp); - flare_rep->Scale(flare_scale * 0.667f); - flare_rep->SetShade(0); - - Bolt* trail_rep = new Bolt(flare_scale * 30, flare_scale * 8, trail_bmp, true); - - ThrusterPort* port = new ThrusterPort(type, loc, fire, flare_scale); - port->flare = flare_rep; - port->trail = trail_rep; - ports.append(port); - } -} - -// +--------------------------------------------------------------------+ - -int -Thruster::NumThrusters() const -{ - return ports.size(); -} - -Graphic* -Thruster::Flare(int engine) const -{ - if (engine >= 0 && engine < ports.size()) - return ports[engine]->flare; - - return 0; -} - -Graphic* -Thruster::Trail(int engine) const -{ - if (engine >= 0 && engine < ports.size()) - return ports[engine]->trail; - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Thruster::IncBurn(int inc, int dec) -{ - burn[inc] += 0.1f; - if (burn[inc] > 1) - burn[inc] = 1.0f; - - burn[dec] -= 0.1f; - if (burn[dec] < 0) - burn[dec] = 0.0f; -} - -void -Thruster::DecBurn(int a, int b) -{ - burn[a] -= 0.1f; - if (burn[a] < 0) - burn[a] = 0.0f; - - burn[b] -= 0.1f; - if (burn[b] < 0) - burn[b] = 0.0f; -} - -// +----------------------------------------------------------------------+ - -double -Thruster::GetRequest(double seconds) const -{ - if (!power_on) - return 0; - - for (int i = 0; i < 12; i++) - if (burn[i] != 0) - return power_level * sink_rate * seconds; - - return 0; -} - diff --git a/Stars45/Thruster.h b/Stars45/Thruster.h deleted file mode 100644 index 7db4a8f..0000000 --- a/Stars45/Thruster.h +++ /dev/null @@ -1,96 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Conventional Thruster (system) class -*/ - -#ifndef Thruster_h -#define Thruster_h - -#include "Types.h" -#include "System.h" -#include "Geometry.h" - -// +--------------------------------------------------------------------+ - -class Ship; - -// +--------------------------------------------------------------------+ - -struct ThrusterPort { - static const char* TYPENAME() { return "ThrusterPort"; } - - ThrusterPort(int t, const Point& l, DWORD f, float s); - ~ThrusterPort(); - - int type; - DWORD fire; - float burn; - float scale; - Point loc; - Graphic* flare; - Graphic* trail; -}; - -// +--------------------------------------------------------------------+ - -class Thruster : public System -{ -public: - static const char* TYPENAME() { return "Thruster"; } - - enum Constants { - LEFT, RIGHT, FORE, AFT, TOP, BOTTOM, - YAW_L, YAW_R, PITCH_D, PITCH_U, ROLL_L, ROLL_R - }; - - Thruster(int dtype, double thrust, float flare_scale=0); - Thruster(const Thruster& rhs); - virtual ~Thruster(); - - static void Initialize(); - static void Close(); - - virtual void ExecFrame(double seconds); - virtual void ExecTrans(double x, double y, double z); - virtual void SetShip(Ship* s); - - virtual double TransXLimit(); - virtual double TransYLimit(); - virtual double TransZLimit(); - - virtual void AddPort(int type, const Point& loc, DWORD fire, float flare_scale=0); - virtual void CreatePort(int type, const Point& loc, DWORD fire, float flare_scale); - - int NumThrusters() const; - Graphic* Flare(int engine) const; - Graphic* Trail(int engine) const; - virtual void Orient(const Physical* rep); - virtual double GetRequest(double seconds) const; - -protected: - void IncBurn(int inc, int dec); - void DecBurn(int a, int b); - - Ship* ship; - float thrust; - float scale; - float burn[12]; - - float avail_x, avail_y, avail_z; - float trans_x, trans_y, trans_z; - float roll_rate, pitch_rate, yaw_rate; - float roll_drag, pitch_drag, yaw_drag; - - List ports; -}; - -#endif // Thruster_h - diff --git a/Stars45/Token.cpp b/Stars45/Token.cpp deleted file mode 100644 index 2cc97b5..0000000 --- a/Stars45/Token.cpp +++ /dev/null @@ -1,544 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Scanner class implementation -*/ - -#include "Token.h" -#include "Reader.h" -#include "Text.h" - -#include - -// +-------------------------------------------------------------------+ - -bool Token::hidecom = true; -char Token::combeg[3] = "//"; -char Token::comend[3] = "\n"; -char Token::altbeg[3] = "/*"; -char Token::altend[3] = "*/"; -Dictionary Token::keymap; - -// +-------------------------------------------------------------------+ - -Token::Token() - : mType(Undefined), mKey(0), mLine(0), mColumn(0) -{ - mLength = 0; - mSymbol[0] = '\0'; -} - -Token::Token(const Token& rhs) - : mType(rhs.mType), mKey(rhs.mKey), mLine(rhs.mLine), mColumn(rhs.mColumn) -{ - mLength = rhs.mLength; - if (mLength < 8) { - strcpy_s(mSymbol, rhs.mSymbol); - } - else { - mFullSymbol = new char[mLength + 1]; - strcpy(mFullSymbol, rhs.mFullSymbol); - } -} - -Token::Token(int t) - : mType(t), mKey(0), mLine(0), mColumn(0) -{ - mLength = 0; - mSymbol[0] = '\0'; -} - -Token::Token(const char* s, int t, int k, int l, int c) - : mType(t), mKey(k), mLine(l), mColumn(c) -{ - mLength = strlen(s); - if (mLength < 8) { - strcpy_s(mSymbol, s); - } - else { - mFullSymbol = new char[mLength + 1]; - strcpy(mFullSymbol, s); - } -} - -Token::Token(const Text& s, int t, int k, int l, int c) - : mType(t), mKey(k), mLine(l), mColumn(c) -{ - mLength = s.length(); - if (mLength < 8) { - strcpy_s(mSymbol, s.data()); - } - else { - mFullSymbol = new char[mLength + 1]; - strcpy(mFullSymbol, s.data()); - } -} - -Token::~Token() -{ - if (mLength >= 8) - delete [] mFullSymbol; -} - -// +-------------------------------------------------------------------+ - -void -Token::close() -{ - keymap.clear(); -} - -// +-------------------------------------------------------------------+ - -Token& -Token::operator = (const Token& rhs) -{ - if (mLength >= 8) - delete [] mFullSymbol; - - mLength = rhs.mLength; - if (mLength < 8) { - strcpy_s(mSymbol, rhs.mSymbol); - } - else { - mFullSymbol = new char[mLength + 1]; - strcpy(mFullSymbol, rhs.mFullSymbol); - } - - mType = rhs.mType; - mKey = rhs.mKey; - mLine = rhs.mLine; - mColumn = rhs.mColumn; - - return *this; -} - -// +-------------------------------------------------------------------+ - -bool -Token::match(const Token& ref) const -{ - if (mType == ref.mType) { // if types match - if (ref.mLength == 0) // if no symbol to match - return true; // match! - - else if (mLength == ref.mLength) { // else if symbols match - if (mLength < 8) { - if (!strcmp(mSymbol, ref.mSymbol)) - return true; // match! - } - else { - if (!strcmp(mFullSymbol, ref.mFullSymbol)) - return true; // match! - } - } - } - - return false; -} - -// +-------------------------------------------------------------------+ - -Text -Token::symbol() const -{ - if (mLength < 8) - return Text(mSymbol); - else - return Text(mFullSymbol); -} - -// +-------------------------------------------------------------------+ - -void -Token::addKey(const Text& k, int v) -{ - keymap.insert(k, v); -} - -// +-------------------------------------------------------------------+ - -void -Token::addKeys(Dictionary& keys) -{ - DictionaryIter iter = keys; - while (++iter) - keymap.insert(iter.key(), iter.value()); -} - -// +-------------------------------------------------------------------+ - -bool -Token::findKey(const Text& k, int& v) -{ - if (keymap.contains(k)) { - v = keymap.find(k, 0); - return true; - } - else - return false; -} - -// +-------------------------------------------------------------------+ - -void -Token::comments(const Text& begin, const Text& end) -{ - combeg[0] = begin(0); - if (begin.length() > 1) combeg[1] = begin(1); - else combeg[1] = '\0'; - - comend[0] = end(0); - if (end.length() > 1) comend[1] = end(1); - else comend[1] = '\0'; -} - -// +-------------------------------------------------------------------+ - -void -Token::altComments(const Text& begin, const Text& end) -{ - altbeg[0] = begin(0); - if (begin.length() > 1) altbeg[1] = begin(1); - else altbeg[1] = '\0'; - - altend[0] = end(0); - if (end.length() > 1) altend[1] = end(1); - else altend[1] = '\0'; -} - -// +-------------------------------------------------------------------+ - -Text -Token::typestr() const -{ - Text t = "Unknown"; - switch (type()) { - case Undefined: t = "Undefined"; break; - case Keyword: t = "Keyword"; break; - case AlphaIdent: t = "AlphaIdent"; break; - case SymbolicIdent: t = "SymbolicIdent"; break; - case Comment: t = "Comment"; break; - case IntLiteral: t = "IntLiteral"; break; - case FloatLiteral: t = "FloatLiteral"; break; - case StringLiteral: t = "StringLiteral"; break; - case CharLiteral: t = "CharLiteral"; break; - case Dot: t = "Dot"; break; - case Comma: t = "Comma"; break; - case Colon: t = "Colon"; break; - case Semicolon: t = "Semicolon"; break; - case LParen: t = "LParen"; break; - case RParen: t = "RParen"; break; - case LBracket: t = "LBracket"; break; - case RBracket: t = "RBracket"; break; - case LBrace: t = "LBrace"; break; - case RBrace: t = "RBrace"; break; - case EOT: t = "EOT"; break; - case LastTokenType: t = "LastTokenType"; break; - } - - return t; -} - -// +-------------------------------------------------------------------+ - -Text -Token::describe(const Text& tok) -{ - Text d; - - switch (tok(0)) { - case '.' : d = "Token::Dot"; break; - case ',' : d = "Token::Comma"; break; - case ';' : d = "Token::Semicolon"; break; - case '(' : d = "Token::LParen"; break; - case ')' : d = "Token::RParen"; break; - case '[' : d = "Token::LBracket"; break; - case ']' : d = "Token::RBracket"; break; - case '{' : d = "Token::LBrace"; break; - case '}' : d = "Token::RBrace"; break; - default : break; - } - - if (d.length() == 0) { - if (isalpha(tok(0))) - d = "\"" + tok + "\", Token::AlphaIdent"; - else if (isdigit(tok(0))) { - if (tok.contains(".")) - d = "\"" + tok + "\", Token::FloatLiteral"; - else - d = "\"" + tok + "\", Token::IntLiteral"; - } - else - d = "\"" + tok + "\", Token::SymbolicIdent"; - } - - return d; -} - -// +-------------------------------------------------------------------+ - -Scanner::Scanner(Reader* r) - : reader(r), str(0), index(0), old_index(0), - length(0), line(0), old_line(0), lineStart(0) -{ } - -Scanner::Scanner(const Scanner& rhs) - : index(rhs.index), old_index(rhs.old_index), length(rhs.length), - reader(rhs.reader), - line(rhs.line), old_line(0), lineStart(rhs.lineStart) -{ - str = new char [strlen(rhs.str) + 1]; - strcpy(str, rhs.str); -} - -Scanner::Scanner(const Text& s) - : reader(0), index(0), old_index(0), length(s.length()), line(0), - old_line(0), lineStart(0) -{ - str = new char [s.length() + 1]; - strcpy(str, s.data()); -} - -Scanner::~Scanner() -{ - delete [] str; -} - -// +-------------------------------------------------------------------+ - -Scanner& -Scanner::operator = (const Scanner& rhs) -{ - delete [] str; - str = new char [strlen(rhs.str) + 1]; - strcpy(str, rhs.str); - - index = rhs.index; - old_index = rhs.old_index; - length = rhs.length; - line = rhs.line; - old_line = rhs.old_line; - lineStart = rhs.lineStart; - - return *this; -} - -// +-------------------------------------------------------------------+ - -void -Scanner::Load(const Text& s) -{ - delete [] str; - str = new char [s.length() + 1]; - strcpy(str, s.data()); - - index = 0; - old_index = 0; - best = Token(); - length = s.length(); - line = 0; - old_line = 0; - lineStart = 0; -} - -// +-------------------------------------------------------------------+ - -Token -Scanner::Get(Need need) -{ - int type = Token::EOT; - old_index = index; - old_line = line; - - eos = str + length; - p = str + index; - - if (p >= eos) { - if (need == Demand && reader) { - Load(reader->more()); - if (length > 0) - return Get(need); - } - return Token("", type, 0, line, 0); - } - - while (isspace(*p) && p < eos) { // skip initial white space - if (*p == '\n') { - line++; - lineStart = p - str; - } - p++; - } - - if (p >= eos) { - if (need == Demand && reader) { - Load(reader->more()); - if (length > 0) - return Get(need); - } - return Token("", type, 0, line, 0); - } - - Token result; - size_t start = p - str; - - if (*p == '"' || *p == '\'') { // special case for quoted tokens - - if (*p == '"') type = Token::StringLiteral; - else type = Token::CharLiteral; - - char match = *p; - while (++p < eos) { - if (*p == match) { // find matching quote - if (*(p-1) != '\\') { // if not escaped - p++; // token includes matching quote - break; - } - } - } - } - - // generic delimited comments - else if (*p == Token::comBeg(0) && - (!Token::comBeg(1) || *(p+1) == Token::comBeg(1))) { - type = Token::Comment; - while (++p < eos) { - if (*p == Token::comEnd(0) && - (!Token::comEnd(1) || *(p+1) == Token::comEnd(1))) { - p++; if (Token::comEnd(1)) p++; - break; - } - } - } - - // alternate form delimited comments - else if (*p == Token::altBeg(0) && - (!Token::altBeg(1) || *(p+1) == Token::altBeg(1))) { - type = Token::Comment; - while (++p < eos) { - if (*p == Token::altEnd(0) && - (!Token::altEnd(1) || *(p+1) == Token::altEnd(1))) { - p++; if (Token::altEnd(1)) p++; - break; - } - } - } - - else if (*p == '.') type = Token::Dot; - else if (*p == ',') type = Token::Comma; - else if (*p == ';') type = Token::Semicolon; - else if (*p == '(') type = Token::LParen; - else if (*p == ')') type = Token::RParen; - else if (*p == '[') type = Token::LBracket; - else if (*p == ']') type = Token::RBracket; - else if (*p == '{') type = Token::LBrace; - else if (*p == '}') type = Token::RBrace; - - // use lexical sub-parser for ints and floats - else if (isdigit(*p)) - type = GetNumeric(); - - else if (IsSymbolic(*p)) { - type = Token::SymbolicIdent; - while (IsSymbolic(*p)) p++; - } - - else { - type = Token::AlphaIdent; - while (IsAlpha(*p)) p++; - } - - size_t extent = (p - str) - start; - - if (extent < 1) extent = 1; // always get at least one character - - index = start + extent; // advance the cursor - int col = start - lineStart; - if (line == 0) col++; - - char* buf = new char [extent + 1]; - strncpy(buf, str + start, extent); - buf[extent] = '\0'; - - if (type == Token::Comment && Token::hidecom) { - delete [] buf; - if (Token::comEnd(0) == '\n') { - line++; - lineStart = p - str; - } - return Get(need); - } - - if (type == Token::AlphaIdent || // check for keyword - type == Token::SymbolicIdent) { - int val; - if (Token::findKey(Text(buf), val)) - result = Token(buf, Token::Keyword, val, line+1, col); - } - - if (result.mType != Token::Keyword) - result = Token(buf, type, 0, line+1, col); - - if (line+1 > (size_t) best.mLine || - (line+1 == (size_t) best.mLine && col > best.mColumn)) - best = result; - - delete [] buf; - return result; -} - -// +-------------------------------------------------------------------+ - -int -Scanner::GetNumeric() -{ - int type = Token::IntLiteral; // assume int - - if (*p == '0' && *(p+1) == 'x') { // check for hex: - p += 2; - while (isxdigit(*p)) p++; - return type; - } - - while (isdigit(*p) || *p == '_') p++; // whole number part - - if (*p == '.') { p++; // optional fract part - type = Token::FloatLiteral; // implies float - - while (isdigit(*p) || *p == '_') p++; // fractional part - } - - if (*p == 'E' || *p == 'e') { p++; // optional exponent - if (*p == '+' || *p == '-') p++; // which may be signed - while (isdigit(*p)) p++; - - type = Token::FloatLiteral; // implies float - } - - return type; -} - -// +-------------------------------------------------------------------+ - -bool -Scanner::IsAlpha(char c) -{ - return (isalpha(*p) || isdigit(*p) || (*p == '_'))?true:false; -} - -// +-------------------------------------------------------------------+ - -bool -Scanner::IsSymbolic(char c) -{ - const char* s = "+-*/\\<=>~!@#$%^&|:"; - return strchr(s, c)?true:false; -} diff --git a/Stars45/Token.h b/Stars45/Token.h deleted file mode 100644 index bd3723b..0000000 --- a/Stars45/Token.h +++ /dev/null @@ -1,145 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Scanner class definition -*/ - -#ifndef Token_h -#define Token_h - -#include "Text.h" -#include "Dictionary.h" - -#pragma warning( disable : 4237) - -// +-------------------------------------------------------------------+ - -class Reader; -class Token; -class Scanner; - -// +-------------------------------------------------------------------+ - -class Token -{ - friend class Scanner; - -public: - // keywords must be alphanumeric identifiers or symbolic identifiers - enum Types { Undefined, Keyword, AlphaIdent, SymbolicIdent, Comment, - IntLiteral, FloatLiteral, StringLiteral, CharLiteral, - Dot, Comma, Colon, Semicolon, - LParen, RParen, LBracket, RBracket, LBrace, RBrace, - EOT, LastTokenType }; - - enum Alias { CompoundSeparator = Dot, - ItemSeparator = Comma, - StatementTerminator = Semicolon, - TypeIndicator = Colon, - Lambda = LastTokenType + 1 }; - - Token(); - Token(const Token& rhs); - Token(int t); - Token(const char* s, int t, int k=0, int l=0, int c=0); - Token(const Text& s, int t, int k=0, int l=0, int c=0); - ~Token(); - - Token& operator = (const Token& rhs); - - bool match(const Token& ref) const; - - Text symbol() const; - int type() const { return mType; } - int key() const { return mKey; } - int line() const { return mLine; } - int column() const { return mColumn; } - - Text typestr() const; - - static Text describe(const Text& tok); - static void addKey(const Text& k, int v); - static void addKeys(Dictionary& keys); - static bool findKey(const Text& k, int& v); - static void comments(const Text& begin, const Text& end); - static void altComments(const Text& begin, const Text& end); - static void hideComments(bool hide = true) { hidecom = hide; } - - static char comBeg(unsigned int i) { return combeg[i]; } - static char comEnd(unsigned int i) { return comend[i]; } - static char altBeg(unsigned int i) { return altbeg[i]; } - static char altEnd(unsigned int i) { return altend[i]; } - - static void close(); - -protected: - int mLength; - union { - char mSymbol[8]; - char* mFullSymbol; - }; - int mType; - int mKey; - int mLine; - int mColumn; - - static bool hidecom; - static char combeg[3]; - static char comend[3]; - static char altbeg[3]; - static char altend[3]; - - static Dictionary keymap; -}; - -// +-------------------------------------------------------------------+ - -class Scanner -{ -public: - Scanner(Reader* r = 0); - Scanner(const Text& s); - Scanner(const Scanner& rhs); - virtual ~Scanner(); - - Scanner& operator = (const Scanner& rhs); - - void Load(const Text& s); - - enum Need { Demand, Request }; - virtual Token Get(Need n = Demand); - - void PutBack() { index = old_index; line = old_line; } - int GetCursor() { return index; } - int GetLine() { return line; } - void Reset(int c, int l) { index = old_index = c; line = old_line = l; } - Token Best() const { return best; } - -protected: - virtual int GetNumeric(); - virtual bool IsSymbolic(char c); - virtual bool IsAlpha(char c); - - Reader* reader; - char* str; - - const char* p; - const char* eos; - - size_t index; - size_t old_index; - Token best; - size_t length; - size_t line; - size_t old_line; - size_t lineStart; -}; - -#endif // TOKEN_H diff --git a/Stars45/TrackIR.cpp b/Stars45/TrackIR.cpp deleted file mode 100644 index 87dd937..0000000 --- a/Stars45/TrackIR.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - TrackIR head tracker interface class -*/ - -#include "TrackIR.h" -#include "NPClient.h" -#include "NPClientWraps.h" - -#include "GameWinDX9.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -const double TRACK_TOP = -8000; -const double TRACK_BOTTOM = 8000; -const double TRACK_LEFT = 16000; -const double TRACK_RIGHT = -16000; -const double TRACK_XYZ = 24000; - -// +--------------------------------------------------------------------+ - -static Text GetDllFromRegistry() -{ - Text dllLoc; - BYTE dllBuf[1024]; - DWORD dllLen = 0; - HKEY hkey = 0; - - ZeroMemory(dllBuf, sizeof(dllBuf)); - - RegOpenKeyEx(HKEY_CURRENT_USER, - "Software\\NaturalPoint\\NATURALPOINT\\NPClient Location", - 0, - KEY_QUERY_VALUE, - &hkey); - - if (hkey) { - dllLen = 1024; - - LONG result = - RegQueryValueEx(hkey, - "Path", - NULL, - NULL, - dllBuf, - &dllLen); - - if (result == ERROR_SUCCESS && dllLen > 0) - dllLoc = (const char*) dllBuf; - - RegCloseKey(hkey); - } - - return dllLoc; -} - -static const char* NPErrString(NPRESULT r) -{ - switch (r) { - case NP_OK: return "OK"; - case NP_ERR_DEVICE_NOT_PRESENT: return "Device not present"; - case NP_ERR_UNSUPPORTED_OS: return "Unsupported O/S"; - case NP_ERR_INVALID_ARG: return "Invalid argument"; - case NP_ERR_DLL_NOT_FOUND: return "NaturalPoint DLL not found"; - case NP_ERR_NO_DATA: return "No data available"; - case NP_ERR_INTERNAL_DATA: return "Internal error"; - } - - return "Unknown error code"; -} - -// +--------------------------------------------------------------------+ - -TrackIR::TrackIR() : -running(false), frame_signature(0), -az(0), el(0), x(0), y(0), z(0) -{ - Print("*** NaturalPoint Game Client Initialization ***\n"); - - // Hook up the NaturalPoint game client DLL using the wrapper module - NPRESULT result; - Text dllPath = GetDllFromRegistry(); - - // Initialize the NPClient interface - result = NPClient_Init(dllPath); - if (result == NP_OK) { - Print("NPClient - Initialize successful.\n"); - } - else { - Print("NPClient - Unable to initialize interface: %s\n", NPErrString(result)); - return; - } - - // Register the app's window handle - result = NP_RegisterWindowHandle(GameWinDX9::GetInstance()->GetHWND()); - - if (result == NP_OK) { - Print("NPClient - Window handle registration successful.\n"); - } - else { - Print("NPClient - Error registering window handle: %s\n", NPErrString(result)); - return; - } - - // Query the NaturalPoint software version - unsigned short wNPClientVer; - result = NP_QueryVersion( &wNPClientVer ); - - if (result == NP_OK) { - Print("NPClient - NaturalPoint software version: %d.%02d\n", (wNPClientVer >> 8), (wNPClientVer & 0x00FF)); - } - else { - Print("NPClient - Error querying NaturalPoint software version: %s\n", NPErrString(result)); - } - - - // It is *required* that your application registers the Developer ID - // assigned by NaturalPoint! - - // Your assigned developer ID needs to be inserted below! -#define NP_DEVELOPER_ID 6401 - - // NOTE : The title of your project must show up - // in the list of supported titles shown in the Profiles - // tab of the TrackIR software, if it does not then the - // TrackIR software will *not* transmit data to your - // application. If your title is not present in the list, - // you may need to have the TrackIR software perform a - // game list update (to download support for new Developer IDs) - // using the menu item under the "Help" or "Update" menu. - - NP_RegisterProgramProfileID(NP_DEVELOPER_ID); - - unsigned int DataFields = 0; - DataFields |= NPPitch; - DataFields |= NPYaw; - - NP_RequestData(DataFields); - - result = NP_StopCursor(); - if (result == NP_OK) - Print("NPClient - Cursor stopped.\n"); - else - Print("NPClient - Error stopping cursor: %s\n", NPErrString(result)); - - - result = NP_StartDataTransmission(); - if (result == NP_OK) { - Print("NPClient - Data transmission started.\n"); - running = true; - } - else { - Print("NPClient - Error starting data transmission: %s\n", NPErrString(result)); - } - -} - -TrackIR::~TrackIR() -{ - if (running) { - Print("NaturalPoint Game Client Shutdown\n"); - - NP_StopDataTransmission(); - NP_UnregisterWindowHandle(); - } -} - -// +--------------------------------------------------------------------+ - -DWORD -TrackIR::ExecFrame() -{ - TRACKIRDATA tid; - - // Go get the latest data - NPRESULT result = NP_GetData( &tid ); - - if (result == NP_OK) { - // Got data to process ... - running = true; - - // compare the last frame signature to the current one - // if they are not the same then new data has arrived since then - - if (tid.wNPStatus == NPSTATUS_REMOTEACTIVE) { - if (frame_signature != tid.wPFrameSignature) { - double pitch = tid.fNPPitch; - double yaw = tid.fNPYaw; - - if (pitch < 0) { - el = pitch / TRACK_TOP; - } - else { - el = -pitch / TRACK_BOTTOM; - } - - if (yaw < 0) { - az = yaw / TRACK_RIGHT; - } - else { - az = -yaw / TRACK_LEFT; - } - - x = tid.fNPX / TRACK_XYZ * -1; - y = tid.fNPY / TRACK_XYZ; - z = tid.fNPZ / TRACK_XYZ * -1; - - if (z < -0.25) z = -0.25; - - frame_signature = tid.wPFrameSignature; - } - else { - // Either there is no tracking data, the user has - // paused the trackIR, or the call happened before - // the TrackIR was able to update the interface - // with new data - - az *= 0.75; - el *= 0.75; - x *= 0.75; - y *= 0.75; - z *= 0.75; - - result = NP_ERR_NO_DATA; - } - } - else { - // The user has set the device out of trackIR Enhanced Mode - // and into Mouse Emulation mode with the hotkey - result = NP_ERR_NO_DATA; - running = false; - } - } - - return result; -} diff --git a/Stars45/TrackIR.h b/Stars45/TrackIR.h deleted file mode 100644 index c402f10..0000000 --- a/Stars45/TrackIR.h +++ /dev/null @@ -1,52 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - TrackIR head tracker interface class -*/ - -#ifndef TrackIR_h -#define TrackIR_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class TrackIR -{ -public: - TrackIR(); - ~TrackIR(); - - DWORD ExecFrame(); - - bool IsRunning() const { return running; } - double GetAzimuth() const { return az; } - double GetElevation() const { return el; } - - double GetX() const { return x; } - double GetY() const { return y; } - double GetZ() const { return z; } - -protected: - - bool running; - DWORD stale_frames; - DWORD frame_signature; - - double az; - double el; - - double x; // vrt - double y; // vup - double z; // vpn (i think) -}; - -#endif // TrackIR_h - diff --git a/Stars45/Trail.cpp b/Stars45/Trail.cpp deleted file mode 100644 index a29deca..0000000 --- a/Stars45/Trail.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Missile Trail representation class -*/ - -#include "Trail.h" -#include "Weapon.h" -#include "Sim.h" - -#include "Clock.h" -#include "Light.h" -#include "Bitmap.h" -#include "DataLoader.h" -#include "Sound.h" -#include "Video.h" - -// +--------------------------------------------------------------------+ - -Trail::Trail(Bitmap* tex, int n) -: ntrail(0), length0(0), length1(0), texture(tex), maxtrail(n), dim(1) -{ - trans = true; - luminous = true; - - mtl.Kd = Color::White; - mtl.tex_diffuse = texture; - mtl.tex_emissive = texture; - mtl.blend = Video::BLEND_ADDITIVE; - mtl.luminous = true; - - if (maxtrail < 4) maxtrail = 512; - trail = new Point[maxtrail]; - verts = new VertexSet(maxtrail*2); - verts->Clear(); - verts->nverts = 0; - - for (int i = 0; i < maxtrail*2; i++) { - verts->diffuse[i] = D3DCOLOR_RGBA(255,255,255,255); - verts->specular[i] = D3DCOLOR_RGBA( 0, 0, 0,255); - verts->tu[i] = 0.0f; - verts->tv[i] = (i & 1) ? 1.0f : 0.0f; - } - - polys = new Poly[maxtrail]; - - for (int i = 0; i < maxtrail; i++) { - polys[i].vertex_set = verts; - polys[i].nverts = 4; - polys[i].material = &mtl; - } - - npolys = 0; - nverts = 0; - width = 6; - length = 0; - dim = 3; - - last_point_time = 0; -} - -Trail::~Trail() -{ - delete [] trail; - delete [] polys; - delete verts; -} - -void -Trail::UpdateVerts(const Point& cam_pos) -{ - if (ntrail < 2) return; - - int bright = 255 - dim*ntrail; - - Point head = trail[1] + loc; - Point tail = trail[0] + loc; - Point vcam = cam_pos - head; - Point vtmp = vcam.cross(head-tail); - vtmp.Normalize(); - Point vlat = vtmp * (width + (0.1 * width * ntrail)); - - verts->loc[0] = tail - vlat; - verts->loc[1] = tail + vlat; - verts->diffuse[0] = 0; - verts->diffuse[1] = 0; - - for (int i = 0; i < ntrail-1; i++) { - bright+=dim; - Point head = trail[i+1] + loc; - Point tail = trail[i] + loc; - Point vcam = cam_pos - head; - Point vtmp = vcam.cross(head-tail); - vtmp.Normalize(); - - float trail_width = (float) (width + (ntrail-i) * width * 0.1); - if (i == ntrail-2) trail_width = (float) (width * 0.7); - Point vlat = vtmp * trail_width; - - verts->loc[2*i+2] = head - vlat; - verts->loc[2*i+3] = head + vlat; - - if (bright <= 0) { - verts->diffuse[2*i+2] = 0; - verts->diffuse[2*i+3] = 0; - } - else { - verts->diffuse[2*i+2] = D3DCOLOR_RGBA(bright,bright,bright,bright); - verts->diffuse[2*i+3] = D3DCOLOR_RGBA(bright,bright,bright,bright); - } - } -} - -void -Trail::Render(Video* video, DWORD flags) -{ - if (!npolys) return; - - if ((flags & RENDER_ADDITIVE) == 0) - return; - - if (video && life) { - const Camera* cam = video->GetCamera(); - - if (cam) - UpdateVerts(cam->Pos()); - - video->DrawPolys(npolys, polys); - } -} - -void -Trail::AddPoint(const Point& v) -{ - if (ntrail >= maxtrail-1) return; - - double real_time = Clock::GetInstance()->RealTime() / 1000.0; - - if (ntrail == 0) { - radius = 1000; - } - else { - radius = (float) Point(v-loc).length(); - } - - // just adjust the last point: - if (ntrail > 1 && real_time - last_point_time < 0.05) { - trail[ntrail-1] = v; - } - - // add a new point: - else { - last_point_time = real_time; - trail[ntrail++] = v; - - nverts += 2; - verts->nverts = nverts; - - if (ntrail > 1) { - length0 = length1; - length1 = length0 + (trail[ntrail-1]-trail[ntrail-2]).length(); - - polys[npolys].vertex_set = verts; - polys[npolys].nverts = 4; - - polys[npolys].verts[0] = nverts-4; - polys[npolys].verts[1] = nverts-2; - polys[npolys].verts[2] = nverts-1; - polys[npolys].verts[3] = nverts-3; - - float tu1 = (float) length1 / 250.0f; - - verts->tu[2*ntrail-1] = tu1; - verts->tu[2*ntrail-2] = tu1; - - npolys++; - } - } -} - -double -Trail::AverageLength() -{ - double avg = 0; - - for (int i = 0; i < ntrail-1; i++) - avg += (trail[i+1]-trail[i]).length(); - avg /= ntrail; - - return avg; -} - diff --git a/Stars45/Trail.h b/Stars45/Trail.h deleted file mode 100644 index 8f90470..0000000 --- a/Stars45/Trail.h +++ /dev/null @@ -1,59 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Missile Trail (Graphic) class -*/ - -#ifndef Trail_h -#define Trail_h - -#include "Types.h" -#include "Geometry.h" -#include "Polygon.h" -#include "SimObject.h" -#include "Graphic.h" - -// +--------------------------------------------------------------------+ - -class Trail : public Graphic -{ -public: - Trail(Bitmap* tex, int n=512); - virtual ~Trail(); - - virtual void UpdateVerts(const Point& cam_pos); - virtual void Render(Video* video, DWORD flags); - virtual void AddPoint(const Point& v); - virtual double AverageLength(); - - virtual void SetWidth(double w) { width = w; } - virtual void SetDim(int d) { dim = d; } - -protected: - int ntrail; - int maxtrail; - Point* trail; - - double length; - double width; - int dim; - - int npolys, nverts; - Poly* polys; - VertexSet* verts; - Bitmap* texture; - Material mtl; - - double length0, length1; - double last_point_time; -}; - -#endif // Trail_h - diff --git a/Stars45/Types.h b/Stars45/Types.h deleted file mode 100644 index edd47ba..0000000 --- a/Stars45/Types.h +++ /dev/null @@ -1,65 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Basic Type Definitions -*/ - -#ifndef Types_h -#define Types_h - -// +--------------------------------------------------------------------+ - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers -#define STRICT 1 - -// Works with Windows 2000 and later and Windows 98 or later -#undef _WIN32_IE -#undef WINVER -#undef _WIN32_WINDOWS -#undef _WIN32_WINNT -#define WINVER 0x0500 -#define _WIN32_WINDOWS 0x0410 -#define _WIN32_WINNT 0x0500 - -//#if !defined(HMONITOR_DECLARED) -// #define HMONITOR_DECLARED -// DECLARE_HANDLE(HMONITOR); -//#endif - -#include -#include -#include -#include -#include -#include -#include -#include - - -// Enable extra D3D debugging in debug builds if using the debug DirectX runtime. -// This makes D3D objects work well in the debugger watch window, but slows down -// performance slightly. -#if defined(DEBUG) | defined(_DEBUG) -#define D3D_DEBUG_INFO -#endif - -// Direct3D includes -#include -#include - -// DirectSound includes -#include -#include -#include - -// +--------------------------------------------------------------------+ - -#endif // Types_h - diff --git a/Stars45/Universe.h b/Stars45/Universe.h deleted file mode 100644 index f8e9fdd..0000000 --- a/Stars45/Universe.h +++ /dev/null @@ -1,31 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract Universe class -*/ - -#ifndef Universe_h -#define Universe_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class Universe -{ -public: - Universe() { } - virtual ~Universe() { } - - virtual void ExecFrame(double seconds) { } -}; - -#endif // Universe_h - diff --git a/Stars45/VersionInfo.cpp.conf b/Stars45/VersionInfo.cpp.conf deleted file mode 100644 index adaad2c..0000000 --- a/Stars45/VersionInfo.cpp.conf +++ /dev/null @@ -1,9 +0,0 @@ -/* 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. - */ - -#include "VersionInfo.h" - -const char* versionInfo = "@VERSION@"; diff --git a/Stars45/VersionInfo.h b/Stars45/VersionInfo.h deleted file mode 100644 index 44c55dc..0000000 --- a/Stars45/VersionInfo.h +++ /dev/null @@ -1,12 +0,0 @@ -/* 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. - */ - -#ifndef VersionInfo_H -#define VersionInfo_H - -extern const char* versionInfo; - -#endif // VersionInfo_H diff --git a/Stars45/VidDlg.cpp b/Stars45/VidDlg.cpp deleted file mode 100644 index 8a4e4ed..0000000 --- a/Stars45/VidDlg.cpp +++ /dev/null @@ -1,544 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#include "GameWinDX9.h" -#include "VidDlg.h" -#include "BaseScreen.h" -#include "Starshatter.h" -#include "Ship.h" -#include "Terrain.h" -#include "CameraDirector.h" - -#include "DataLoader.h" -#include "Button.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "VideoSettings.h" -#include "Keyboard.h" -#include "MachineInfo.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(VidDlg, OnTexSize); -DEF_MAP_CLIENT(VidDlg, OnMode); -DEF_MAP_CLIENT(VidDlg, OnDetail); -DEF_MAP_CLIENT(VidDlg, OnTexture); -DEF_MAP_CLIENT(VidDlg, OnGamma); -DEF_MAP_CLIENT(VidDlg, OnApply); -DEF_MAP_CLIENT(VidDlg, OnCancel); -DEF_MAP_CLIENT(VidDlg, OnAudio); -DEF_MAP_CLIENT(VidDlg, OnVideo); -DEF_MAP_CLIENT(VidDlg, OnOptions); -DEF_MAP_CLIENT(VidDlg, OnControls); -DEF_MAP_CLIENT(VidDlg, OnMod); - -// +--------------------------------------------------------------------+ - -VidDlg::VidDlg(Screen* s, FormDef& def, BaseScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -selected_mode(0), selected_detail(0), new_gamma(128), orig_gamma(128), -selected_card(0), selected_tex_size(0), selected_render(0), selected_texture(0), -mode(0), tex_size(0), detail(0), texture(0), gamma(0), shadows(0), spec_maps(0), -bump_maps(0), lens_flare(0), corona(0), nebula(0), dust(0), -apply(0), cancel(0), vid_btn(0), aud_btn(0), ctl_btn(0), opt_btn(0), mod_btn(0), -closed(true) -{ - stars = Starshatter::GetInstance(); - - Init(def); - orig_gamma = Video::GetInstance()->GammaLevel(); -} - -VidDlg::~VidDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -VidDlg::RegisterControls() -{ - if (apply) - return; - - mode = (ComboBox*) FindControl(203); - REGISTER_CLIENT(EID_SELECT, mode, VidDlg, OnMode); - - tex_size = (ComboBox*) FindControl(204); - REGISTER_CLIENT(EID_SELECT, tex_size, VidDlg, OnTexSize); - - detail = (ComboBox*) FindControl(205); - REGISTER_CLIENT(EID_SELECT, detail, VidDlg, OnDetail); - - texture = (ComboBox*) FindControl(206); - REGISTER_CLIENT(EID_SELECT, texture, VidDlg, OnTexture); - - gamma = (Slider*) FindControl(215); - - if (gamma) { - gamma->SetRangeMin(32); - gamma->SetRangeMax(224); - gamma->SetStepSize(16); - - REGISTER_CLIENT(EID_CLICK, gamma, VidDlg, OnGamma); - } - - lens_flare = (ComboBox*) FindControl(211); - corona = (ComboBox*) FindControl(212); - nebula = (ComboBox*) FindControl(213); - dust = (ComboBox*) FindControl(214); - shadows = (ComboBox*) FindControl(222); - spec_maps = (ComboBox*) FindControl(223); - bump_maps = (ComboBox*) FindControl(224); - - apply = (Button*) FindControl(1); - REGISTER_CLIENT(EID_CLICK, apply, VidDlg, OnApply); - - cancel = (Button*) FindControl(2); - REGISTER_CLIENT(EID_CLICK, cancel, VidDlg, OnCancel); - - vid_btn = (Button*) FindControl(901); - REGISTER_CLIENT(EID_CLICK, vid_btn, VidDlg, OnVideo); - - aud_btn = (Button*) FindControl(902); - REGISTER_CLIENT(EID_CLICK, aud_btn, VidDlg, OnAudio); - - ctl_btn = (Button*) FindControl(903); - REGISTER_CLIENT(EID_CLICK, ctl_btn, VidDlg, OnControls); - - opt_btn = (Button*) FindControl(904); - REGISTER_CLIENT(EID_CLICK, opt_btn, VidDlg, OnOptions); - - mod_btn = (Button*) FindControl(905); - if (mod_btn) - REGISTER_CLIENT(EID_CLICK, mod_btn, VidDlg, OnMod); -} - -// +--------------------------------------------------------------------+ - -void -VidDlg::Show() -{ - FormWindow::Show(); - - if (closed) { - bool fullscreen = true; - - if (stars) { - selected_render = 9; - selected_card = 0; - - int n = GameWinDX9::GetInstance()->MaxTexSize(); - - for (int i = 0; i < 7; i++) { - if (n <= pow(2.0f, i+6)) { - selected_tex_size = i; - break; - } - } - - Video* video = Video::GetInstance(); - - if (video) { - if (shadows) - shadows->SetSelection(video->IsShadowEnabled()); - - if (spec_maps) - spec_maps->SetSelection(video->IsSpecMapEnabled()); - - if (bump_maps) - bump_maps->SetSelection(video->IsBumpMapEnabled()); - - fullscreen = video->IsFullScreen(); - } - - if (lens_flare) - lens_flare->SetSelection(stars->LensFlare()); - - if (corona) - corona->SetSelection(stars->Corona()); - - if (nebula) - nebula->SetSelection(stars->Nebula()); - - if (dust) - dust->SetSelection(stars->Dust()); - } - - selected_detail = Terrain::DetailLevel() - 2; - selected_texture = true; - - if (mode) { - BuildModeList(); - mode->SetSelection(selected_mode); - mode->SetEnabled(fullscreen); - } - - if (tex_size) - tex_size->SetSelection(selected_tex_size); - - if (detail) - detail->SetSelection(selected_detail); - - if (texture) - texture->SetSelection(selected_texture); - - if (gamma) { - orig_gamma = Video::GetInstance()->GammaLevel(); - gamma->SetValue(orig_gamma); - } - } - - if (vid_btn) vid_btn->SetButtonState(1); - if (aud_btn) aud_btn->SetButtonState(0); - if (ctl_btn) ctl_btn->SetButtonState(0); - if (opt_btn) opt_btn->SetButtonState(0); - if (mod_btn) mod_btn->SetButtonState(0); - - closed = false; -} - -// +--------------------------------------------------------------------+ - -void -VidDlg::ExecFrame() -{ - if (Keyboard::KeyDown(VK_RETURN)) { - OnApply(0); - } -} - -// +--------------------------------------------------------------------+ - -void -VidDlg::OnMode(AWEvent* event) -{ - selected_mode = mode->GetSelectedIndex(); -} - -void -VidDlg::OnTexSize(AWEvent* event) -{ - selected_tex_size = tex_size->GetSelectedIndex(); -} - -void -VidDlg::OnDetail(AWEvent* event) -{ - selected_detail = detail->GetSelectedIndex(); -} - -void -VidDlg::OnTexture(AWEvent* event) -{ - selected_texture = texture->GetSelectedIndex(); -} - -void -VidDlg::OnGamma(AWEvent* event) -{ - int g = gamma->GetValue(); - if (g >= 0 && g <= 255) { - new_gamma = g; - Video::GetInstance()->SetGammaLevel(g); - } -} - -// +--------------------------------------------------------------------+ - -void VidDlg::OnAudio(AWEvent* event) { manager->ShowAudDlg(); } -void VidDlg::OnVideo(AWEvent* event) { manager->ShowVidDlg(); } -void VidDlg::OnOptions(AWEvent* event) { manager->ShowOptDlg(); } -void VidDlg::OnControls(AWEvent* event) { manager->ShowCtlDlg(); } -void VidDlg::OnMod(AWEvent* event) { manager->ShowModDlg(); } - -// +--------------------------------------------------------------------+ - -void -VidDlg::OnApply(AWEvent* event) -{ - manager->ApplyOptions(); -} - -void -VidDlg::OnCancel(AWEvent* event) -{ - manager->CancelOptions(); -} - -// +--------------------------------------------------------------------+ - -void -VidDlg::Apply() -{ - if (closed) return; - - int w = 800; - int h = 600; - int d = 32; - int a = 1; - int g = 128; - int t = 2048; - float bias = 0; - - const char* mode_desc = mode->GetSelectedItem(); - - if (strstr(mode_desc, "800 x 600")) { - w = 800; - h = 600; - } - else if (strstr(mode_desc, "1024 x 768")) { - w = 1024; - h = 768; - } - else if (strstr(mode_desc, "1152 x 864")) { - w = 1152; - h = 864; - } - else if (strstr(mode_desc, "1280 x 800")) { - w = 1280; - h = 800; - } - else if (strstr(mode_desc, "1280 x 960")) { - w = 1280; - h = 960; - } - else if (strstr(mode_desc, "1280 x 1024")) { - w = 1280; - h = 1024; - } - else if (strstr(mode_desc, "1366 x 768")) { - w = 1366; - h = 768; - } - else if (strstr(mode_desc, "1440 x 900")) { - w = 1440; - h = 900; - } - else if (strstr(mode_desc, "1600 x 900")) { - w = 1600; - h = 900; - } - else if (strstr(mode_desc, "1600 x 1200")) { - w = 1600; - h = 1200; - } - else if (strstr(mode_desc, "1680 x 1050")) { - w = 1680; - h = 1050; - } - else if (strstr(mode_desc, "1920 x 1080")) { - w = 1920; - h = 1080; - } - else if (strstr(mode_desc, "2560 x 1080")) { - w = 2560; - h = 1080; - } - else if (strstr(mode_desc, "3440 x 1440")) { - w = 3440; - h = 1440; - } - - if (strstr(mode_desc, "x 16")) - d = 16; - else if (strstr(mode_desc, "x 32")) - d = 32; - - if (selected_tex_size) - t = (int) pow(2.0f, selected_tex_size + 6); - - bool video_change = false; - - Video* video = Video::GetInstance(); - if (video) { - const VideoSettings* vs = video->GetVideoSettings(); - - if (vs) - bias = vs->depth_bias; - - if (video->IsFullScreen()) { - if (video->Width() != w) - video_change = true; - - if (video->Height() != h) - video_change = true; - - if (video->Depth() != d) - video_change = true; - } - else if (vs) { - w = vs->fullscreen_mode.width; - h = vs->fullscreen_mode.height; - - if (vs->fullscreen_mode.format == VideoMode::FMT_R5G6B5 || - vs->fullscreen_mode.format == VideoMode::FMT_R5G5B5) - d = 16; - else - d = 32; - } - - if (GameWinDX9::GetInstance()->MaxTexSize() != t) - video_change = true; - } - - FILE* f = 0; - - if (video_change) - fopen_s(&f, "video2.cfg", "wb"); - else - fopen_s(&f, "video.cfg", "wb"); - - if (gamma) { - new_gamma = gamma->GetValue(); - } - - if (f) { - fprintf(f, "VIDEO\n\n"); - fprintf(f, "width: %4d\n", w); - fprintf(f, "height: %4d\n", h); - fprintf(f, "depth: %4d\n", d); - fprintf(f, "\n"); - fprintf(f, "max_tex: %d\n", (int) pow(2.0f, 6 + selected_tex_size)); - fprintf(f, "primary3D: %s\n", (a>0)?"true":"false"); - fprintf(f, "gamma: %4d\n", new_gamma); - fprintf(f, "\n"); - fprintf(f, "terrain_detail_level: %d\n", selected_detail + 2); - fprintf(f, "terrain_texture_enable: %s\n", selected_texture ? "true" : "false"); - fprintf(f, "\n"); - fprintf(f, "shadows: %s\n", shadows->GetSelectedIndex() ? "true" : "false"); - fprintf(f, "spec_maps: %s\n", spec_maps->GetSelectedIndex() ? "true" : "false"); - fprintf(f, "bump_maps: %s\n", bump_maps->GetSelectedIndex() ? "true" : "false"); - fprintf(f, "bias: %f\n", bias); - fprintf(f, "\n"); - fprintf(f, "flare: %s\n", lens_flare->GetSelectedIndex() ? "true" : "false"); - fprintf(f, "corona: %s\n", corona->GetSelectedIndex() ? "true" : "false"); - fprintf(f, "nebula: %s\n", nebula->GetSelectedIndex() ? "true" : "false"); - fprintf(f, "dust: %d\n", dust->GetSelectedIndex()); - - if (CameraDirector::GetRangeLimit() != 300e3) - fprintf(f, " cam_range_max: %f,\n", CameraDirector::GetRangeLimit()); - - fclose(f); - } - - Starshatter* stars = Starshatter::GetInstance(); - - if (stars) { - if (video_change) - stars->RequestChangeVideo(); - else - stars->LoadVideoConfig("video.cfg"); - } - - closed = true; -} - -void -VidDlg::Cancel() -{ - Video::GetInstance()->SetGammaLevel(orig_gamma); - closed = true; -} - -// +--------------------------------------------------------------------+ - -void -VidDlg::BuildModeList() -{ - char mode_desc[32]; - Starshatter* stars = Starshatter::GetInstance(); - Video* video = Video::GetInstance(); - - mode->ClearItems(); - selected_mode = 0; - - if (video->IsModeSupported( 800, 600, 16)) mode->AddItem("800 x 600 x 16"); - if (video->IsModeSupported( 800, 600, 32)) mode->AddItem("800 x 600 x 32"); - - if (video->IsModeSupported(1024, 768, 16)) mode->AddItem("1024 x 768 x 16"); - if (video->IsModeSupported(1024, 768, 32)) mode->AddItem("1024 x 768 x 32"); - - if (video->IsModeSupported(1152, 864, 16)) mode->AddItem("1152 x 864 x 16"); - if (video->IsModeSupported(1152, 864, 32)) mode->AddItem("1152 x 864 x 32"); - - if (video->IsModeSupported(1280, 800, 16)) mode->AddItem("1280 x 800 x 16"); - if (video->IsModeSupported(1280, 800, 32)) mode->AddItem("1280 x 800 x 32"); - - if (video->IsModeSupported(1280, 960, 16)) mode->AddItem("1280 x 960 x 16"); - if (video->IsModeSupported(1280, 960, 32)) mode->AddItem("1280 x 960 x 32"); - - if (video->IsModeSupported(1280,1024, 16)) mode->AddItem("1280 x 1024 x 16"); - if (video->IsModeSupported(1280,1024, 32)) mode->AddItem("1280 x 1024 x 32"); - - if (video->IsModeSupported(1366, 768, 16)) mode->AddItem("1366 x 768 x 16"); - if (video->IsModeSupported(1366, 768, 32)) mode->AddItem("1366 x 768 x 32"); - - if (video->IsModeSupported(1440, 900, 16)) mode->AddItem("1440 x 900 x 16"); - if (video->IsModeSupported(1440, 900, 32)) mode->AddItem("1440 x 900 x 32"); - - if (video->IsModeSupported(1600, 900, 16)) mode->AddItem("1600 x 900 x 16"); - if (video->IsModeSupported(1600, 900, 32)) mode->AddItem("1600 x 900 x 32"); - - if (video->IsModeSupported(1600,1200, 16)) mode->AddItem("1600 x 1200 x 16"); - if (video->IsModeSupported(1600,1200, 32)) mode->AddItem("1600 x 1200 x 32"); - - if (video->IsModeSupported(1680,1050, 16)) mode->AddItem("1680 x 1050 x 16"); - if (video->IsModeSupported(1680,1050, 32)) mode->AddItem("1680 x 1050 x 32"); - - if (video->IsModeSupported(1920,1080, 16)) mode->AddItem("1920 x 1080 x 16"); - if (video->IsModeSupported(1920,1080, 32)) mode->AddItem("1920 x 1080 x 32"); - - if (stars && video) { - switch (video->Width()) { - case 800: strcpy_s(mode_desc, "800 x 600 x "); break; - default: - case 1024: strcpy_s(mode_desc, "1024 x 768 x "); break; - case 1152: strcpy_s(mode_desc, "1152 x 864 x "); break; - case 1280: - if (video->Height() < 900) - strcpy_s(mode_desc, "1280 x 800 x "); - if (video->Height() < 1000) - strcpy_s(mode_desc, "1280 x 960 x "); - else - strcpy_s(mode_desc, "1280 x 1024 x "); - break; - case 1366: strcpy_s(mode_desc, "1366 x 768 x "); break; - case 1440: strcpy_s(mode_desc, "1440 x 900 x "); break; - case 1600: - if (video->Height() < 1000) - strcpy_s(mode_desc, "1600 x 900 x "); - else - strcpy_s(mode_desc, "1600 x 1200 x "); - break; - case 1680: strcpy_s(mode_desc, "1680 x 1050 x "); break; - case 1920: strcpy_s(mode_desc, "1920 x 1080 x "); break; - case 2560: strcpy_s(mode_desc, "2560 x 1080 x "); break; - case 3440: strcpy_s(mode_desc, "3440 x 1440 x "); break; - } - - switch (video->Depth()) { - default: - case 8: strcat_s(mode_desc, "8"); break; - case 16: strcat_s(mode_desc, "16"); break; - case 32: strcat_s(mode_desc, "32"); break; - } - - for (int i = 0; i < mode->GetCount(); i++) { - if (!strcmp(mode->GetItem(i), mode_desc)) - selected_mode = i; - } - } -} diff --git a/Stars45/VidDlg.h b/Stars45/VidDlg.h deleted file mode 100644 index 0b6e918..0000000 --- a/Stars45/VidDlg.h +++ /dev/null @@ -1,106 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Main Menu Dialog Active Window class -*/ - -#ifndef VidDlg_h -#define VidDlg_h - -#include "Types.h" -#include "FormWindow.h" -#include "Bitmap.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Font.h" - -// +--------------------------------------------------------------------+ - -class BaseScreen; -class Starshatter; - -// +--------------------------------------------------------------------+ - -class VidDlg : public FormWindow -{ -public: - VidDlg(Screen* s, FormDef& def, BaseScreen* mgr); - virtual ~VidDlg(); - - virtual void RegisterControls(); - virtual void Show(); - virtual void ExecFrame(); - - // Operations: - virtual void OnTexSize(AWEvent* event); - virtual void OnMode(AWEvent* event); - virtual void OnDetail(AWEvent* event); - virtual void OnTexture(AWEvent* event); - virtual void OnGamma(AWEvent* event); - - virtual void Apply(); - virtual void Cancel(); - - virtual void OnApply(AWEvent* event); - virtual void OnCancel(AWEvent* event); - - virtual void OnAudio(AWEvent* event); - virtual void OnVideo(AWEvent* event); - virtual void OnOptions(AWEvent* event); - virtual void OnControls(AWEvent* event); - virtual void OnMod(AWEvent* event); - -protected: - virtual void BuildModeList(); - - BaseScreen* manager; - Starshatter* stars; - - ComboBox* mode; - ComboBox* tex_size; - ComboBox* detail; - ComboBox* texture; - - ComboBox* shadows; - ComboBox* bump_maps; - ComboBox* spec_maps; - - ComboBox* lens_flare; - ComboBox* corona; - ComboBox* nebula; - ComboBox* dust; - - Slider* gamma; - - Button* aud_btn; - Button* vid_btn; - Button* opt_btn; - Button* ctl_btn; - Button* mod_btn; - - Button* apply; - Button* cancel; - - int selected_render; - int selected_card; - int selected_tex_size; - int selected_mode; - int selected_detail; - int selected_texture; - int new_gamma; - int orig_gamma; - - bool closed; -}; - -#endif // VidDlg_h - diff --git a/Stars45/Video.cpp b/Stars45/Video.cpp deleted file mode 100644 index 368f50c..0000000 --- a/Stars45/Video.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract Video Interface (singleton definition) -*/ - -#include "Video.h" -#include "VideoSettings.h" - -// +--------------------------------------------------------------------+ - -Video* Video::video_instance = 0; - -// +--------------------------------------------------------------------+ - -Video::Video() -{ - status = VIDEO_OK; - video_instance = this; - - shadow_enabled = true; - bump_enabled = true; - spec_enabled = true; - - camera = 0; -} - -Video::~Video() -{ - if (video_instance == this) - video_instance = 0; -} - -// +--------------------------------------------------------------------+ - -bool -Video::IsWindowed() const -{ - const VideoSettings* vs = GetVideoSettings(); - - if (vs) - return vs->IsWindowed(); - - return false; -} - -bool -Video::IsFullScreen() const -{ - const VideoSettings* vs = GetVideoSettings(); - - if (vs) - return !vs->IsWindowed(); - - return true; -} diff --git a/Stars45/Video.h b/Stars45/Video.h deleted file mode 100644 index 87cf1f9..0000000 --- a/Stars45/Video.h +++ /dev/null @@ -1,241 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract Video Interface -*/ - -#ifndef Video_h -#define Video_h - -#include "Geometry.h" -#include "Color.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Video; -struct VideoMode; -class VideoSettings; -class VideoPrivateData; - -class Bitmap; -class Camera; -struct Rect; -struct Poly; -struct Material; -struct VertexSet; -class Light; -class Solid; -class Surface; - -// +--------------------------------------------------------------------+ - -struct RenderStats -{ - int nframe; - int nverts; - int npolys; - int nlines; - - int ncalls; - - int total_verts; - int total_polys; - int total_lines; - - void Clear() { nverts = npolys = nlines = ncalls = - total_verts = total_polys = total_lines = 0; } -}; - -// +--------------------------------------------------------------------+ - -class Video -{ -public: - enum STATUS { VIDEO_OK, VIDEO_ERR, VIDEO_BAD_PARM }; - - enum RENDER_STATE { - FILL_MODE, - SHADE_MODE, - LIGHTING_ENABLE, - Z_ENABLE, - Z_WRITE_ENABLE, - Z_BIAS, - TEXTURE_FILTER, - DITHER_ENABLE, - SPECULAR_ENABLE, - FOG_ENABLE, - FOG_COLOR, - FOG_DENSITY, - STENCIL_ENABLE, - TEXTURE_WRAP, - LIGHTING_PASS, - - RENDER_STATE_MAX - }; - - enum BLEND_TYPE { - BLEND_SOLID = 1, - BLEND_ALPHA = 2, - BLEND_ADDITIVE = 4, - BLEND_FORCE_DWORD = 0x7fffffff, - }; - - enum SHADE_TYPE { - SHADE_FLAT = 1, - SHADE_GOURAUD = 2, - SHADE_PHONG = 3, - SHADE_FORCE_DWORD = 0x7fffffff, - }; - - enum FILL_TYPE { - FILL_POINT = 1, - FILL_WIREFRAME = 2, - FILL_SOLID = 3, - FILL_FORCE_DWORD = 0x7fffffff, - }; - - enum FILTER_TYPE { - FILTER_NONE = 1, - FILTER_LINEAR = 2, - FILTER_MIPMAP = 3, - FILTER_MIPLINEAR = 4, - FILTER_TRILINEAR = 6, - FILTER_FORCE_DWORD = 0x7fffffff, - }; - - enum PROJECTION_TYPE { - PROJECTION_PERSPECTIVE = 1, - PROJECTION_ORTHOGONAL = 2, - PROJECTION_FORCE_DWORD = 0x7fffffff, - }; - - Video(); - virtual ~Video(); - - STATUS Status() const { return status; } - virtual const VideoSettings* - GetVideoSettings() const { return 0; } - virtual bool SetVideoSettings(const VideoSettings* vs) { return false; } - virtual bool Reset(const VideoSettings* vs) { return false; } - - virtual bool SetBackgroundColor(Color c) { return false; } - virtual bool SetGammaLevel(int g) { return true; } - virtual bool SetObjTransform(const Matrix& o, const Point& l){ return false; } - - virtual int Width() const { return 0; } - virtual int Height() const { return 0; } - virtual int Depth() const { return 0; } - - virtual void RecoverSurfaces() { } - - virtual bool ClearAll() { return false; } - virtual bool ClearDepthBuffer() { return false; } - virtual bool Present() { return false; } - virtual bool Pause() { return false; } - virtual bool Resume() { return false; } - - virtual bool IsWindowed() const; - virtual bool IsFullScreen() const; - virtual bool IsModeSupported(int width, int height, int bpp) - const { return true; } - virtual bool IsHardware() const { return false; } - virtual bool IsHardwareTL() const { return false; } - virtual int ZDepth() const { return 0; } - virtual DWORD VidMemFree() const { return 0; } - virtual int D3DLevel() const { return 0; } - virtual int MaxTexSize() const { return 256; } - virtual int MaxTexAspect() const { return 0; } - virtual int GammaLevel() const { return 190; } - - virtual bool IsShadowEnabled() const { return shadow_enabled; } - virtual bool IsBumpMapEnabled() const { return bump_enabled; } - virtual bool IsSpecMapEnabled() const { return spec_enabled; } - - virtual void SetShadowEnabled(bool e) { shadow_enabled = e; } - virtual void SetBumpMapEnabled(bool e) { bump_enabled = e; } - virtual void SetSpecMapEnabled(bool e) { spec_enabled = e; } - - virtual bool Capture(Bitmap& bmp) { return false; } - virtual bool GetWindowRect(Rect& r) { return false; } - virtual bool SetWindowRect(const Rect& r) { return false; } - virtual bool SetViewport(int x, int y, int w, int h) { return false; } - virtual bool SetCamera(const Camera* cam) { camera = cam; - return false; } - virtual bool SetProjection(float fov, - float znear=1.0f, - float zfar=1.0e6f, - DWORD type=PROJECTION_PERSPECTIVE) { return false; } - virtual bool SetEnvironment(Bitmap** faces) { return false; } - virtual bool SetAmbient(Color c) { return false; } - virtual bool SetLights(const List& lights) { return false; } - virtual bool SetRenderState(RENDER_STATE state, DWORD value) { return false; } - virtual bool SetBlendType(int blend_type) { return false; } - virtual bool StartFrame() { return false; } - virtual bool EndFrame() { return false; } - - virtual bool DrawPolys(int npolys, Poly* p) { return false; } - virtual bool DrawScreenPolys(int npolys, Poly* p, int blend=0) { return false; } - virtual bool DrawSolid(Solid* s, DWORD blend_modes=0xf) { return false; } - virtual bool DrawShadow(Solid* s, int nverts, Vec3* verts, bool vis=false) - { return false; } - virtual bool DrawLines(int nlines, Vec3* v, Color c, int blend=0) { return false; } - virtual bool DrawScreenLines(int nlines, float* v, Color c, int blend=0) - { return false; } - virtual bool DrawPoints(VertexSet* v) { return false; } - virtual bool DrawPolyOutline(Poly* p) { return false; } - virtual bool UseMaterial(Material* m) { return false; } - - virtual bool UseXFont(const char* name, int size, bool b, bool i) { return false; } - virtual bool DrawText(const char* text, int count, const Rect& rect, - DWORD format, Color c) { return false; } - - virtual void PreloadTexture(Bitmap* bmp) { } - virtual void PreloadSurface(Surface* s) { } - virtual void InvalidateCache() { } - - const Camera* GetCamera() const { return camera; } - const RenderStats& GetStats() const { return stats; } - static Video* GetInstance() { return video_instance; } - -protected: - STATUS status; - RenderStats stats; - const Camera* camera; - - bool shadow_enabled; - bool bump_enabled; - bool spec_enabled; - - static Video* video_instance; -}; - -// +--------------------------------------------------------------------+ - -class VideoPrivateData -{ -public: - VideoPrivateData() : valid(false) { } - virtual ~VideoPrivateData() { } - - virtual int GetType() const { return 0; } - - virtual bool IsValid() const { return valid; } - virtual void Invalidate() { valid = false; } - virtual void Validate() { valid = true; } - -protected: - bool valid; -}; - -// +--------------------------------------------------------------------+ - -#endif // Video_h - diff --git a/Stars45/VideoDX9.cpp b/Stars45/VideoDX9.cpp deleted file mode 100644 index cf7ed68..0000000 --- a/Stars45/VideoDX9.cpp +++ /dev/null @@ -1,3618 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Direct3D Video class for DirectX 9 -*/ - -#include "VideoDX9.h" -#include "VideoDX9Enum.h" -#include "VideoDX9VertexBuffer.h" -#include "TexDX9.h" -#include "TexCubeDX9.h" -#include "Camera.h" -#include "Color.h" -#include "DataLoader.h" -#include "Polygon.h" -#include "Light.h" -#include "Solid.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -char* D3DErrStr(HRESULT dderr); -void VideoDX9Error(const char* msg, HRESULT dderr); -static TexCacheDX9* texcache = 0; -static TexCubeDX9* environment_cube = 0; -static bool surface_has_tangent_data = false; -static Light* main_light; -static Light* back_light; -static D3DXMATRIX matrixWorld; -static D3DXMATRIX matrixView; -static D3DXMATRIX matrixProj; -static D3DXMATRIX matrixWorldInverse; - -extern int VD3D_describe_things; - -#ifndef RELEASE -#define RELEASE(x) if (x) { x->Release(); x=NULL; } -#endif - -#ifndef F2DW -#define F2DW(x) (*(DWORD*)(&x)) -#endif - -#ifndef DW2I -#define DW2I(x) (*(int*)(&x)) -#endif - -// +--------------------------------------------------------------------+ - -typedef HRESULT (WINAPI * LPDDCE)(GUID FAR *, LPVOID *, REFIID , IUnknown FAR *); - -static D3DMATRIX identity_matrix = { - FLOAT(1.0), FLOAT(0.0), FLOAT(0.0), FLOAT(0.0), - FLOAT(0.0), FLOAT(1.0), FLOAT(0.0), FLOAT(0.0), - FLOAT(0.0), FLOAT(0.0), FLOAT(1.0), FLOAT(0.0), - FLOAT(0.0), FLOAT(0.0), FLOAT(0.0), FLOAT(1.0) -}; - -// +--------------------------------------------------------------------+ - -List model_clients; - -class VideoDX9SurfaceData : public VideoPrivateData -{ -public: - VideoDX9SurfaceData(Model* m) : model(m), vertex_buffer(0), index_buffer(0) { - if (!model_clients.contains(model)) - model_clients.append(model); - } - - virtual ~VideoDX9SurfaceData() { - model_clients.remove(model); - - delete vertex_buffer; - delete index_buffer; - } - - enum { TYPE = 9001 }; - virtual int GetType() const { return TYPE; } - - Model* model; - VideoDX9VertexBuffer* vertex_buffer; - VideoDX9IndexBuffer* index_buffer; -}; - -class VideoDX9SegmentData : public VideoPrivateData -{ -public: - VideoDX9SegmentData() : first_vert(0), num_verts(0), first_index(0), num_tris(0) { } - virtual ~VideoDX9SegmentData() { } - - enum { TYPE = 9002 }; - virtual int GetType() const { return TYPE; } - - int first_vert; - int num_verts; - int first_index; - int num_tris; -}; - -// +--------------------------------------------------------------------+ - -static int d3dstate_table[] = { - D3DRS_FILLMODE, // FILL_MODE - D3DRS_SHADEMODE, // SHADE_MODE - D3DRS_LIGHTING, // LIGHTING_ENABLE - D3DRS_ZENABLE, // Z_ENABLE - D3DRS_ZWRITEENABLE, // Z_WRITE_ENABLE - D3DRS_DEPTHBIAS, // Z_BIAS - 0, // TEXTURE_FILTER - D3DRS_DITHERENABLE, // DITHER_ENABLE - D3DRS_SPECULARENABLE, // SPECULAR_ENABLE - D3DRS_FOGENABLE, // FOG_ENABLE - D3DRS_FOGCOLOR, // FOG_COLOR - D3DRS_FOGDENSITY, // FOG_DENSITY - D3DRS_STENCILENABLE, // STENCIL_ENABLE - 0x11111111, // TEXTURE_WRAP (special case) - 0 // LIGHTING_PASS -}; - -static const int NUM_SCREEN_VERTS = 1024; -static const int NUM_SCREEN_INDICES = NUM_SCREEN_VERTS * 2; - -// +--------------------------------------------------------------------+ - -struct VideoDX9ScreenVertex -{ - FLOAT sx, sy, sz, rhw; - DWORD diffuse; - FLOAT tu, tv; - - static DWORD FVF; -}; - -DWORD VideoDX9ScreenVertex::FVF = D3DFVF_XYZRHW | -D3DFVF_DIFFUSE | -D3DFVF_TEX1; - -struct VideoDX9NormalVertex -{ - FLOAT x, y, z; - FLOAT nx, ny, nz; - FLOAT t0u, t0v; - FLOAT t1u, t1v; - FLOAT tx, ty, tz; - FLOAT bx, by, bz; - - static DWORD FVF; -}; - -DWORD VideoDX9NormalVertex::FVF = 0; - -// Global Vertex Declaration shared by shaders -D3DVERTEXELEMENT9 videoDX9NormalVertexElements[] = -{ - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, - { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, - { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 }, - { 0, 40, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 2 }, - { 0, 52, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 3 }, - D3DDECL_END() -}; - -struct VideoDX9SolidVertex -{ - FLOAT x, y, z; - FLOAT nx, ny, nz; - FLOAT tu, tv; - - static DWORD FVF; -}; - -DWORD VideoDX9SolidVertex::FVF = D3DFVF_XYZ | -D3DFVF_NORMAL | -D3DFVF_TEX1 | -D3DFVF_TEXCOORDSIZE2(0); - -struct VideoDX9LuminousVertex -{ - FLOAT x, y, z; - DWORD diffuse; - FLOAT tu, tv; - - static DWORD FVF; -}; - -DWORD VideoDX9LuminousVertex::FVF = D3DFVF_XYZ | -D3DFVF_DIFFUSE | -D3DFVF_TEX1 | -D3DFVF_TEXCOORDSIZE2(0); - -struct VideoDX9DetailVertex -{ - FLOAT x, y, z; - DWORD diffuse; - DWORD specular; - FLOAT tu, tv; - FLOAT tu1, tv1; - - static DWORD FVF; -}; - -DWORD VideoDX9DetailVertex::FVF = D3DFVF_XYZ | -D3DFVF_DIFFUSE | -D3DFVF_SPECULAR | -D3DFVF_TEX2; - -struct VideoDX9LineVertex -{ - FLOAT x, y, z; - DWORD diffuse; - - static DWORD FVF; -}; - -DWORD VideoDX9LineVertex::FVF = D3DFVF_XYZ | -D3DFVF_DIFFUSE; - -enum { - DX9_STRATEGY_NONE, - DX9_STRATEGY_SIMPLE, - DX9_STRATEGY_GLOW, - DX9_STRATEGY_SPECMAP, - DX9_STRATEGY_EMISSIVE, - DX9_STRATEGY_SPEC_EMISSIVE, - DX9_STRATEGY_BLEND, - DX9_STRATEGY_BLEND_DETAIL -}; - -// +--------------------------------------------------------------------+ - -static VideoDX9* video_dx9_instance = 0; - -VideoDX9::VideoDX9(const HWND& window, VideoSettings* vs) -: width(0), height(0), bpp(0), hwnd(window), surface(0), -d3d(0), d3ddevice(0), device_lost(false), fade(0), -zdepth(0), gamma(128), num_verts(0), first_vert(0), -current_texture(0), screen_vbuf(0), screen_ibuf(0), -font_verts(0), font_indices(0), font_nverts(0), -nlights(0), use_material(0), d3dx_font(0), -segment_material(0), strategy(0), passes(0), -screen_line_verts(0), line_verts(0), -vertex_declaration(0), -magic_fx(0), magic_fx_code(0), magic_fx_code_len(0) -{ - video_dx9_instance = this; - - Print("\n********************************\n"); - Print("* Direct 3D version 9 *\n"); - Print("********************************\n\n"); - - status = VIDEO_ERR; - HRESULT err = E_OUTOFMEMORY; - - d3d = Direct3DCreate9(D3D_SDK_VERSION); - dx9enum = new VideoDX9Enum(d3d); - - if (d3d && dx9enum) { - if (vs) { - dx9enum->req_fullscreen = vs->is_windowed ? false : true; - dx9enum->req_windowed = vs->is_windowed ? true : false; - dx9enum->min_stencil_bits = vs->shadows ? 8 : 0; - dx9enum->uses_depth_buffer = true; - } - else { - dx9enum->req_fullscreen = video_settings.is_windowed ? false : true; - dx9enum->req_windowed = video_settings.is_windowed ? true : false; - dx9enum->min_stencil_bits = video_settings.shadows ? 8 : 0; - dx9enum->uses_depth_buffer = true; - } - - err = dx9enum->Enumerate(); - - if (FAILED(err)) { - VideoDX9Error("(ctor) could not enumerate dx9 properties", err); - delete dx9enum; - return; - } - } - else { - VideoDX9Error("(ctor) could not create enumerator", err); - return; - } - - SetVideoSettings(vs); - - if (video_settings.is_windowed) - dx9enum->SuggestWindowSettings(&video_settings); - else - dx9enum->SuggestFullscreenSettings(&video_settings); - - SetupParams(); - - if (VD3D_describe_things > 2) { - Print("\nD3DPRESENT_PARAMETERS:\n"); - Print(" BackBufferWidth: %d\n", d3dparams.BackBufferWidth); - Print(" BackBufferHeight: %d\n", d3dparams.BackBufferHeight); - Print(" BackBufferCount: %d\n", d3dparams.BackBufferCount); - Print(" BackBufferFormat: %s\n", VideoDX9DisplayMode::D3DFormatToString(d3dparams.BackBufferFormat)); - Print(" Multisample Type: %d\n", d3dparams.MultiSampleType); - Print(" Multisample Qual: %d\n", d3dparams.MultiSampleQuality); - Print(" Swap Effect: %d\n", d3dparams.SwapEffect); - Print(" Device Window: %08X\n", d3dparams.hDeviceWindow); - Print(" Windowed: %s\n", d3dparams.Windowed ? "true" : "false"); - Print(" Enable Depth/Stencil: %s\n", d3dparams.EnableAutoDepthStencil ? "true" : "false"); - Print(" Depth/Stencil Format: %s\n", VideoDX9DisplayMode::D3DFormatToString(d3dparams.AutoDepthStencilFormat)); - Print(" Flags: %08X\n", d3dparams.Flags); - Print(" Fullscreen Refresh: %d Hz\n", d3dparams.FullScreen_RefreshRateInHz); - - switch (d3dparams.PresentationInterval) { - case D3DPRESENT_INTERVAL_IMMEDIATE: - Print(" Present Interval: IMMEDIATE\n"); - break; - - case D3DPRESENT_INTERVAL_DEFAULT: - Print(" Present Interval: DEFAULT\n"); - break; - - case D3DPRESENT_INTERVAL_ONE: - Print(" Present Interval: ONE\n"); - break; - - case D3DPRESENT_INTERVAL_TWO: - Print(" Present Interval: TWO\n"); - break; - - case D3DPRESENT_INTERVAL_THREE: - Print(" Present Interval: THREE\n"); - break; - - case D3DPRESENT_INTERVAL_FOUR: - Print(" Present Interval: FOUR\n"); - break; - - default: - Print(" Present Interval: Unknown (%d)\n", d3dparams.PresentationInterval); - break; - } - - Print("\n"); - } - - Print(" Creating Video Device for HWND = %08x\n", window); - - err = d3d->CreateDevice(D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - window, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - &d3dparams, - &d3ddevice); - - if (FAILED(err)) { - VideoDX9Error("(ctor) could not create device", err); - return; - } - - width = video_settings.GetWidth(); - height = video_settings.GetHeight(); - bpp = video_settings.GetDepth(); - - shadow_enabled = vs->shadows; - bump_enabled = vs->bumpmaps; - spec_enabled = vs->specmaps; - - render_state[FILL_MODE] = FILL_SOLID; - render_state[SHADE_MODE] = SHADE_GOURAUD; - render_state[Z_ENABLE] = false; - render_state[Z_WRITE_ENABLE] = false; - render_state[Z_BIAS] = 0; - render_state[TEXTURE_FILTER] = FILTER_LINEAR; - render_state[DITHER_ENABLE] = false; - render_state[SPECULAR_ENABLE] = true; - render_state[FOG_ENABLE] = false; - render_state[FOG_COLOR] = 0; - render_state[FOG_DENSITY] = 0; - render_state[STENCIL_ENABLE] = false; - render_state[TEXTURE_WRAP] = true; - render_state[LIGHTING_PASS] = 0; - - SetGammaLevel(video_settings.GetGammaLevel()); - - ZeroMemory(&rect, sizeof(rect)); - - if (!texcache) - texcache = new TexCacheDX9(this); - - if (texcache) - texcache->count++; - - if (VD3D_describe_things > 0) { - DWORD vmf = VidMemFree() / (1024 * 1024); - Print(" Available Texture Memory: %d MB\n\n", vmf); - } - - if (CreateBuffers()) { - d3ddevice->SetRenderState(D3DRS_ALPHATESTENABLE, false); - d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - d3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); - - status = VIDEO_OK; - } - - ZeroMemory(font_name, 64); - font_size = 0; - font_bold = false; - font_ital = false; -} - -// +--------------------------------------------------------------------+ - -VideoDX9::~VideoDX9() -{ - DestroyBuffers(); - - texcache->count--; - if (!texcache->count) { - delete texcache; - texcache = 0; - } - - delete environment_cube; - delete dx9enum; - - RELEASE(d3dx_font); - RELEASE(d3ddevice); - RELEASE(d3d); - - if (magic_fx_code) - delete [] magic_fx_code; - - Print(" VideoDX9: shutdown\n"); - video_dx9_instance = 0; -} - -IDirect3DDevice9* -VideoDX9::GetD3DDevice9() -{ - if (video_dx9_instance) - return video_dx9_instance->d3ddevice; - - return 0; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::SetupParams() -{ - if (!dx9enum || dx9enum->NumAdapters() < 1) { - status = VIDEO_ERR; - return false; - } - - int adapter_index = video_settings.GetAdapterIndex(); - - if (adapter_index < 0 || adapter_index >= dx9enum->NumAdapters()) { - ::Print("WARNING: VideoDX9 could not select adapter %d (max=%d)\n", - adapter_index, dx9enum->NumAdapters()); - - adapter_index = 0; - } - - dx9enum->SelectAdapter(adapter_index); - - d3dparams.Windowed = video_settings.IsWindowed(); - d3dparams.BackBufferCount = 2; - d3dparams.MultiSampleType = D3DMULTISAMPLE_NONE; - d3dparams.MultiSampleQuality = 0; - d3dparams.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dparams.EnableAutoDepthStencil = dx9enum->uses_depth_buffer; - d3dparams.hDeviceWindow = hwnd; - - if (dx9enum->uses_depth_buffer) { - d3dparams.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; - d3dparams.AutoDepthStencilFormat = (D3DFORMAT) video_settings.GetDepthStencilFormat(); - } - else { - d3dparams.Flags = 0; - } - - d3dparams.Flags |= D3DPRESENTFLAG_DEVICECLIP; - - if (video_settings.IsWindowed()) { - d3dparams.BackBufferWidth = video_settings.window_width; - d3dparams.BackBufferHeight = video_settings.window_height; - d3dparams.BackBufferFormat = (D3DFORMAT) video_settings.GetBackBufferFormat(); - d3dparams.FullScreen_RefreshRateInHz = 0; - d3dparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - } - else { - d3dparams.BackBufferWidth = video_settings.GetWidth(); - d3dparams.BackBufferHeight = video_settings.GetHeight(); - d3dparams.BackBufferFormat = (D3DFORMAT) video_settings.GetBackBufferFormat(); - d3dparams.FullScreen_RefreshRateInHz = video_settings.GetRefreshRate(); - d3dparams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - } - - return true; -} - - -bool -VideoDX9::IsModeSupported(int w, int h, int b) const -{ - if (dx9enum) - return dx9enum->IsModeSupported(w, h, b); - - return false; -} - -bool -VideoDX9::SetVideoSettings(const VideoSettings* vs) -{ - // custom video settings: - if (vs) { - if (vs != &video_settings) - CopyMemory(&video_settings, vs, sizeof(VideoSettings)); - } - - // default video settings: - else { - ZeroMemory(&video_settings, sizeof(VideoSettings)); - - video_settings.fullscreen_mode.width = 800; - video_settings.fullscreen_mode.height = 600; - video_settings.fullscreen_mode.format = VideoMode::FMT_X8R8G8B8; - } - - return true; -} - -bool -VideoDX9::Reset(const VideoSettings* vs) -{ - if (!d3ddevice || !SetVideoSettings(vs)) { - status = VIDEO_ERR; - return false; - } - - bool using_x_font = (d3dx_font != 0); - - RELEASE(d3dx_font); - InvalidateCache(); - DestroyBuffers(); - SetupParams(); - - HRESULT hr = d3ddevice->Reset(&d3dparams); - - if (FAILED(hr)) { - VideoDX9Error("could not reset d3d device", hr); - status = VIDEO_ERR; - return false; - } - - // Store render target surface desc - IDirect3DSurface9* back_buffer; - d3ddevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &back_buffer); - back_buffer->GetDesc(&back_buffer_desc); - RELEASE(back_buffer); - - width = video_settings.GetWidth(); - height = video_settings.GetHeight(); - bpp = video_settings.GetDepth(); - - shadow_enabled = vs->shadows; - bump_enabled = vs->bumpmaps; - spec_enabled = vs->specmaps; - - - if (CreateBuffers()) { - d3ddevice->SetRenderState(D3DRS_ALPHATESTENABLE, false); - d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - d3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); - - D3DVIEWPORT9 view; - - hr = d3ddevice->GetViewport(&view); - if (SUCCEEDED(hr)) { - rect.x = view.X; - rect.y = view.Y; - rect.w = view.Width; - rect.h = view.Height; - } - - if (using_x_font) - UseXFont(font_name, font_size, font_bold, font_ital); - - status = VIDEO_OK; - } - - return status == VIDEO_OK; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::CreateBuffers() -{ - if (d3ddevice) { - UINT vertex_size = sizeof(VideoDX9ScreenVertex); - UINT index_size = sizeof(WORD); - - if (!screen_vbuf) { - screen_vbuf = new VideoDX9VertexBuffer( - this, - NUM_SCREEN_VERTS, - vertex_size, - VideoDX9ScreenVertex::FVF, - D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY); - } - - if (!screen_ibuf) { - screen_ibuf = new VideoDX9IndexBuffer( - this, - NUM_SCREEN_INDICES, - D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY); - } - - screen_line_verts = new VideoDX9ScreenVertex[256]; - line_verts = new VideoDX9LineVertex[512]; - - // create effects: - LPD3DXBUFFER code_buffer = 0; - DataLoader* loader = DataLoader::GetLoader(); - HRESULT hr = E_FAIL; - - hr = d3ddevice->CreateVertexDeclaration(videoDX9NormalVertexElements, - &vertex_declaration); - - // The E - We want to load our shader from the standard filesystem by default, to allow for better modding. - if (video_settings.use_effects && !magic_fx_code) { - FILE* f; - ::fopen_s(&f, "magic.fx", "rb"); - - if (f) { - ::fseek(f, 0, SEEK_END); - magic_fx_code_len = ftell(f); - ::fseek(f, 0, SEEK_SET); - - magic_fx_code = new BYTE[magic_fx_code_len+1]; - if (magic_fx_code) { - ::fread(magic_fx_code, magic_fx_code_len, 1, f); - magic_fx_code[magic_fx_code_len] = 0; - } - ::fclose(f); - } else if (loader) { - magic_fx_code_len = loader->LoadBuffer("magic.fx", magic_fx_code, true, true); - } - } - - if (video_settings.use_effects && magic_fx_code && magic_fx_code_len) { - hr = D3DXCreateEffect(d3ddevice, - magic_fx_code, - magic_fx_code_len, - 0, 0, 0, 0, - &magic_fx, - &code_buffer); - - if (code_buffer) { - ::Print("ERROR - Failed to compile 'magic.fx'\n"); - ::Print((const char*) code_buffer->GetBufferPointer()); - ::Print("\n\n"); - RELEASE(code_buffer); - } - } - } - - return screen_vbuf && screen_ibuf; -} - -bool -VideoDX9::DestroyBuffers() -{ - if (line_verts) { - delete line_verts; - line_verts = 0; - } - - if (screen_line_verts) { - delete screen_line_verts; - screen_line_verts = 0; - } - - if (screen_vbuf) { - delete screen_vbuf; - screen_vbuf = 0; - } - - if (screen_ibuf) { - delete screen_ibuf; - screen_ibuf = 0; - } - - if (font_verts) { - delete [] font_verts; - font_verts = 0; - } - - if (font_indices) { - delete [] font_indices; - font_indices = 0; - } - - font_nverts = 0; - - RELEASE(vertex_declaration); - RELEASE(magic_fx); - - return true; -} - -// +--------------------------------------------------------------------+ - -DWORD -VideoDX9::VidMemFree() const -{ - UINT result = 0; - - if (d3ddevice) - result = d3ddevice->GetAvailableTextureMem(); - - return result; -} - -int -VideoDX9::MaxTexSize() const -{ - if (d3d && dx9enum && dx9enum->GetAdapterInfo()) { - VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType()); - - if (dev_info) { - return (int) dev_info->caps.MaxTextureWidth; - } - } - - return 0; -} - -int -VideoDX9::MaxTexAspect() const -{ - if (d3d && dx9enum && dx9enum->GetAdapterInfo()) { - VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType()); - - if (dev_info) { - return (int) dev_info->caps.MaxTextureAspectRatio; - } - } - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -VideoDX9::RecoverSurfaces() -{ - Print("VideoDX9::RecoverSurfaces()\n"); - - HRESULT hr = D3D_OK; - - surface = 0; - - hr = d3ddevice->TestCooperativeLevel(); - - if (hr == D3DERR_DEVICELOST) { - // This means that some app took exclusive mode access - // we need to sit in a loop till we get back to the right mode. - Print("D3DERR_DEVICELOST\n"); - - do { - Sleep(500); - hr = d3ddevice->TestCooperativeLevel(); - } while (hr == D3DERR_DEVICELOST); - } - - if (hr == D3DERR_DEVICENOTRESET) { - if (Reset(&video_settings)) - hr = S_OK; - } - - if (SUCCEEDED(hr)) { - Print("* Invalidating Texture Cache\n"); - // Re-fill the contents of textures which just got restored: - InvalidateCache(); - - device_lost = false; - } - - Print("* Vid Mem Free: %8d\n", VidMemFree()); - Print("* Recover Surfaces Complete.\n\n"); -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::SetBackgroundColor(Color c) -{ - background = c; - return true; -} - -//----------------------------------------------------------------------------- -// RampValue -// -// The gamma function with inputs in [0,255], scaled to a range with the -// default range appropriate for D3DGAMMARAMP. -// -inline WORD -RampValue(UINT i, double recip_gamma, double fade) -{ - return (WORD) (65535.0 * fade * pow((double)i/255.f, recip_gamma)); -} - -//----------------------------------------------------------------------------- -// ReciprocalGamma -// -// Given a gamma corrected i in [0,255], return 1/gamma -// -inline float -ReciprocalGamma(UINT i) -{ - return logf(i/255.f)/logf(0.5f); -} - -//----------------------------------------------------------------------------- -// GammaValue -// -// Given a gamma corrected color channel value in [0,255], return the gamma. -// -inline float -GammaValue(UINT i) -{ - return logf(0.5f)/logf(i/255.f); -} - -bool -VideoDX9::SetGammaLevel(int g) -{ - HRESULT hr = E_FAIL; - double f = Color::GetFade(); - - if (gamma != g || fade != f) { - if (d3ddevice) { - //::Print("VideoDX9 - SetGammaLevel(%d) fade = %f\n", g, f); - - // compute 1/gamma - float recip_gray = ReciprocalGamma(g); - - // compute i**(1/gamma) for all i and scale to range - for (UINT i = 0; i < 256; i++) { - int val = RampValue(i, recip_gray, f); - - gamma_ramp.red[i] = val; - gamma_ramp.green[i] = val; - gamma_ramp.blue[i] = val; - } - - d3ddevice->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, &gamma_ramp); - hr = D3D_OK; - } - - gamma = g; - fade = f; - } - - return SUCCEEDED(hr); -} - -bool -VideoDX9::SetObjTransform(const Matrix& orient, const Point& loc) -{ - HRESULT hr = E_FAIL; - - if (d3ddevice) { - D3DMATRIX world_matrix; - CreateD3DMatrix(world_matrix, orient, loc); - hr = d3ddevice->SetTransform(D3DTS_WORLD, &world_matrix); - - matrixWorld = world_matrix; - D3DXMatrixInverse(&matrixWorldInverse, 0, &matrixWorld); - } - - return SUCCEEDED(hr); -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::ClearAll() -{ - HRESULT err; - - err = d3ddevice->Clear(0, - NULL, - D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, - background.Value(), - 1.0f, - 0); - - if (FAILED(err)) { - static int report = 10; - if (report > 0) { - VideoDX9Error("Failed to clear device", err); - report--; - } - } - - return true; -} - -bool -VideoDX9::ClearDepthBuffer() -{ - HRESULT err; - - err = d3ddevice->Clear(0, - NULL, - D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, - 0, - 1.0f, - 0); - - if (FAILED(err)) { - static int report = 10; - if (report > 0) { - VideoDX9Error("Failed to clear depth buffer", err); - report--; - } - } - - return true; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::Present() -{ - // Show the frame on the primary surface. - HRESULT err = d3ddevice->Present( NULL, NULL, NULL, NULL ); - - if (FAILED(err)) { - if (err == D3DERR_DEVICELOST) { - device_lost = true; - } - - else { - static int report = 10; - if (report > 0) { - VideoDX9Error("Could not present frame", err); - report--; - } - } - } - - return true; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::Pause() -{ - return true; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::Resume() -{ - return true; -} - -// +--------------------------------------------------------------------+ - -void -VideoDX9::PreloadSurface(Surface* s) -{ - if (s) - PrepareSurface(s); -} - -void -VideoDX9::PreloadTexture(Bitmap* tex) -{ - if (texcache && tex) - texcache->FindTexture(tex); -} - -void -VideoDX9::InvalidateCache() -{ - ListIter iter = model_clients; - while (++iter) { - // remove each model from the list... - Model* model = iter.removeItem(); - - // ...so that the buffer destructor doesn't - // do it and mess up the iterator. - model->DeletePrivateData(); - } - - if (texcache) - texcache->InvalidateCache(); -} - -// +--------------------------------------------------------------------+ - -void -VideoDX9::CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Point& p) -{ - result._11 = (float) m.elem[0][0]; - result._12 = (float) m.elem[1][0]; - result._13 = (float) m.elem[2][0]; - result._14 = 0.0f; - - result._21 = (float) m.elem[0][1]; - result._22 = (float) m.elem[1][1]; - result._23 = (float) m.elem[2][1]; - result._24 = 0.0f; - - result._31 = (float) m.elem[0][2]; - result._32 = (float) m.elem[1][2]; - result._33 = (float) m.elem[2][2]; - result._34 = 0.0f; - - result._41 = (float) p.x; - result._42 = (float) p.y; - result._43 = (float) p.z; - result._44 = 1.0f; -} - -void -VideoDX9::CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Vec3& v) -{ - result._11 = (float) m.elem[0][0]; - result._12 = (float) m.elem[1][0]; - result._13 = (float) m.elem[2][0]; - result._14 = 0.0f; - - result._21 = (float) m.elem[0][1]; - result._22 = (float) m.elem[1][1]; - result._23 = (float) m.elem[2][1]; - result._24 = 0.0f; - - result._31 = (float) m.elem[0][2]; - result._32 = (float) m.elem[1][2]; - result._33 = (float) m.elem[2][2]; - result._34 = 0.0f; - - result._41 = v.x; - result._42 = v.y; - result._43 = v.z; - result._44 = 1.0f; -} - -void -VideoDX9::CreateD3DMaterial(D3DMATERIAL9& result, const Material& mtl) -{ - CopyMemory(&result.Diffuse, &mtl.Kd, sizeof(D3DCOLORVALUE)); - CopyMemory(&result.Ambient, &mtl.Ka, sizeof(D3DCOLORVALUE)); - CopyMemory(&result.Specular, &mtl.Ks, sizeof(D3DCOLORVALUE)); - CopyMemory(&result.Emissive, &mtl.Ke, sizeof(D3DCOLORVALUE)); - - result.Power = mtl.power; -} - - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::Capture(Bitmap& bmp) -{ - if (d3ddevice) { - HRESULT hr = E_FAIL; - LPDIRECT3DSURFACE9 pSurf=NULL, pTempSurf=NULL; - D3DSURFACE_DESC desc; - D3DDISPLAYMODE dm; - - // get display dimensions - // this will be the dimensions of the front buffer - hr = d3ddevice->GetDisplayMode(0, &dm); - - if (FAILED(hr)) - VideoDX9Error("VideoDX9::Capture - Can't get display mode!", hr); - - desc.Width = dm.Width; - desc.Height = dm.Height; - desc.Format = D3DFMT_A8R8G8B8; - - hr = d3ddevice->CreateOffscreenPlainSurface( - desc.Width, - desc.Height, - desc.Format, - D3DPOOL_SYSTEMMEM, - &pTempSurf, - NULL); - - if (FAILED(hr)) { - VideoDX9Error("VideoDX9::Capture - Cannot create offscreen buffer 1", hr); - return false; - } - - hr = d3ddevice->GetFrontBufferData(0, pTempSurf); - - if (FAILED(hr)) { - RELEASE(pTempSurf); - VideoDX9Error("VideoDX9::Capture - Can't get front buffer", hr); - return false; - } - - - if (video_settings.IsWindowed()) { - POINT pt={0, 0}; - RECT srcRect; - - // capture only the client area of the screen: - ::GetClientRect(hwnd, &srcRect); - ::ClientToScreen(hwnd, (LPPOINT) &srcRect); - srcRect.right += srcRect.left; - srcRect.bottom += srcRect.top; - - desc.Width = srcRect.right - srcRect.left; - desc.Height = srcRect.bottom - srcRect.top; - desc.Format = D3DFMT_A8R8G8B8; // this is what we get from the screen, so stick with it - - // NB we can't lock the back buffer direct because it's no created that way - // and to do so hits performance, so copy to another surface - // Must be the same format as the source surface - hr = d3ddevice->CreateOffscreenPlainSurface( - desc.Width, - desc.Height, - desc.Format, - D3DPOOL_DEFAULT, - &pSurf, - NULL); - - if (FAILED(hr)) { - RELEASE(pSurf); - VideoDX9Error("VideoDX9::Capture - Cannot create offscreen buffer 2", hr); - return false; - } - - // Copy - hr = d3ddevice->UpdateSurface(pTempSurf, &srcRect, pSurf, &pt); - - if (FAILED(hr)) { - RELEASE(pTempSurf); - RELEASE(pSurf); - VideoDX9Error("VideoDX9::Capture - Cannot update surface", hr); - return false; - } - - RELEASE(pTempSurf); - pTempSurf = pSurf; - pSurf = NULL; - } - - D3DLOCKED_RECT lockedRect; - hr = pTempSurf->LockRect(&lockedRect, NULL, - D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); - - if (FAILED(hr)) { - VideoDX9Error("VideoDX9::Capture - can't lock rect", hr); - RELEASE(pTempSurf); - return false; - } - - // Allocate color buffer - DWORD* buffer = new DWORD[desc.Width * desc.Height]; - BYTE* src = (BYTE*) lockedRect.pBits; - BYTE* dst = (BYTE*) buffer; - Color clr; - - for (DWORD y = 0; y < desc.Height; y++) { - BYTE *pRow = src; - - for (DWORD x = 0; x < desc.Width; x++) { - switch(desc.Format) { - case D3DFMT_R5G6B5: - clr = Color::Unformat(*((WORD*) (pRow))); - - *dst++ = (BYTE) clr.Red(); - *dst++ = (BYTE) clr.Green(); - *dst++ = (BYTE) clr.Blue(); - *dst++ = 255; - break; - - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - *dst++ = pRow[0]; // R - *dst++ = pRow[1]; // G - *dst++ = pRow[2]; // B - *dst++ = 255; - - pRow += 4; - break; - - case D3DFMT_R8G8B8: - *dst++ = pRow[0]; // R - *dst++ = pRow[1]; // G - *dst++ = pRow[2]; // B - *dst++ = 255; - - pRow += 3; - break; - } - - } - - src += lockedRect.Pitch; - } - - bmp.CopyHighColorImage(desc.Width, desc.Height, buffer); - - delete [] buffer; - - RELEASE(pTempSurf); - RELEASE(pSurf); - - return SUCCEEDED(hr); - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::GetWindowRect(Rect& r) -{ - if (d3ddevice && (rect.w < 1 || rect.h < 1)) { - D3DVIEWPORT9 view; - HRESULT hr = d3ddevice->GetViewport(&view); - if (SUCCEEDED(hr)) { - rect.x = view.X; - rect.y = view.Y; - rect.w = view.Width; - rect.h = view.Height; - } - } - - r = rect; - return true; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::SetWindowRect(const Rect& r) -{ - return SetViewport(r.x, r.y, r.w, r.h); -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::SetViewport(int x, int y, int w, int h) -{ - if (!d3d || !d3ddevice) - return false; - - HRESULT hr; - - // set up the viewport according to args: - D3DVIEWPORT9 view; - - view.X = x; - view.Y = y; - view.Width = w; - view.Height = h; - view.MinZ = 0.0f; - view.MaxZ = 1.0f; - - hr = d3ddevice->SetViewport(&view); - if (FAILED(hr)) { - VideoDX9Error("could not initialize viewport", hr); - return false; - } - - // set up the render state: - for (int i = FILL_MODE; i < TEXTURE_WRAP; i++) { - if (d3dstate_table[i]) { - d3ddevice->SetRenderState((D3DRENDERSTATETYPE) d3dstate_table[i], render_state[i]); - } - } - - d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - - rect.x = x; - rect.y = y; - rect.w = w; - rect.h = h; - - return true; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::SetAmbient(Color c) -{ - ambient = c; - return true; -} - -bool -VideoDX9::SetLights(const List& lights) -{ - if (d3ddevice) { - main_light = 0; - back_light = 0; - - ListIter iter = (List&) lights; - int index = -1; - - while (++iter) { - Light* light = iter.value(); - - if (light->IsActive()) { - D3DLIGHT9 d3d_light; - ZeroMemory(&d3d_light, sizeof(d3d_light)); - d3d_light.Type = (D3DLIGHTTYPE) light->Type(); - - if (light->Type() == Light::LIGHT_DIRECTIONAL) { - Point light_location = light->Location(); - d3d_light.Direction.x = (float) (-light_location.x); - d3d_light.Direction.y = (float) (-light_location.y); - d3d_light.Direction.z = (float) (-light_location.z); - - if (d3d_light.Direction.x == 0 && - d3d_light.Direction.y == 0 && - d3d_light.Direction.z == 0) { - - d3d_light.Direction.y = -1; - } - - if (light->CastsShadow()) { - if (!main_light || light->Intensity() > main_light->Intensity()) - main_light = light; - } - else if (!back_light) { - back_light = light; - } - } - else { - d3d_light.Position.x = (float) ( light->Location().x); - d3d_light.Position.y = (float) ( light->Location().y); - d3d_light.Position.z = (float) ( light->Location().z); - } - - float r = (light->GetColor().Red() / 255.0f) * light->Intensity(); - float g = (light->GetColor().Green() / 255.0f) * light->Intensity(); - float b = (light->GetColor().Blue() / 255.0f) * light->Intensity(); - - d3d_light.Diffuse.r = r; - d3d_light.Diffuse.g = g; - d3d_light.Diffuse.b = b; - - d3d_light.Specular.r = r; - d3d_light.Specular.g = g; - d3d_light.Specular.b = b; - - d3d_light.Range = light->Intensity() * 10.0f; - d3d_light.Attenuation0 = 0.1f; - d3d_light.Attenuation1 = 0.7f; - d3d_light.Attenuation2 = 0.0f; - - index++; - d3ddevice->SetLight(index, &d3d_light); - d3ddevice->LightEnable(index, TRUE); - } - } - - // turn off any unused lights from before: - while (nlights > index+1) { - d3ddevice->LightEnable(--nlights, FALSE); - } - - nlights = index + 1; - - return true; - } - - return false; -} - -bool -VideoDX9::SetCamera(const Camera* cam) -{ - if (d3ddevice) { - camera = cam; - - D3DMATRIX m; - CreateD3DMatrix(m, cam->Orientation(), cam->Pos()); - d3ddevice->SetTransform(D3DTS_VIEW, &m); - matrixView = m; - - return true; - } - - return false; -} - -bool -VideoDX9::SetProjection(float fov, float znear, float zfar, DWORD type) -{ - if (d3ddevice && zfar > znear) { - D3DMATRIX m; - float h, w, Q; - - double width = (float) (rect.w); - double height = (float) (rect.h); - ZeroMemory(&m, sizeof(m)); - - /*** - *** PERSPECTIVE PROJECTION: - ***/ - - if (type == PROJECTION_PERSPECTIVE) { - double xscale = width / fov; - double yscale = height / fov; - - double maxscale = xscale; - if (yscale > xscale) maxscale = yscale; - - double xangle = atan(fov/2 * maxscale/xscale); - - w = (float) (2/tan(xangle)); // 1/tan(x) == cot(x) - h = (float) (w * width/height); - Q = zfar/(zfar - znear); - - m._11 = w; - m._22 = h; - m._33 = Q; - m._43 = -Q*znear; - m._34 = 1; - } - - /*** - *** ORTHOGONAL PROJECTION: - ***/ - - else if (type == PROJECTION_ORTHOGONAL) { - m._11 = (float) (fov/width); - m._22 = (float) (fov/height); - m._33 = (float) (1/(zfar-znear)); - m._43 = (float) (znear/(znear-zfar)); - m._44 = (float) (1); - } - - else { - return false; - } - - d3ddevice->SetTransform(D3DTS_PROJECTION, &m); - matrixProj = m; - - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::SetEnvironment(Bitmap** faces) -{ - if (environment_cube && !faces) { - delete environment_cube; - environment_cube = 0; - return true; - } - - if (!environment_cube) { - environment_cube = new TexCubeDX9(this); - } - - if (environment_cube) { - bool ok = true; - for (int i = 0; i < 6; i++) - ok = ok && environment_cube->LoadTexture(faces[i], i); - return ok; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::SetRenderState(RENDER_STATE state, DWORD value) -{ - if (!d3ddevice) - return false; - - if (render_state[state] == value || d3dstate_table[state] == 0) { - render_state[state] = value; - return true; - } - - HRESULT hr = E_FAIL; - - // special case for texture wrapping: - if (state == TEXTURE_WRAP) { - DWORD wrap = D3DTADDRESS_CLAMP; - - if (value) - wrap = D3DTADDRESS_WRAP; - - hr = d3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSU, wrap); - hr = d3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSV, wrap); - } - - // special case for fog enable: - else if (state == FOG_ENABLE) { - if (value) { - hr = d3ddevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP); - hr = d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE); - } - - hr = d3ddevice->SetRenderState(D3DRS_FOGENABLE, value); - } - - // special case for z bias - else if (state == Z_BIAS) { - if (value) { - FLOAT bias_scale = 1.0f; - FLOAT depth_bias = (FLOAT) (DW2I(value) / -10000.0); - - hr = d3ddevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(bias_scale)); - hr = d3ddevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW(depth_bias)); - } - else { - hr = d3ddevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); - hr = d3ddevice->SetRenderState(D3DRS_DEPTHBIAS, 0); - } - } - - // set default z func along with z enable - else if (state == Z_ENABLE) { - hr = d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - hr = d3ddevice->SetRenderState(D3DRS_ZENABLE, value); - } - - // all other render states: - else { - hr = d3ddevice->SetRenderState((D3DRENDERSTATETYPE) d3dstate_table[state], value); - } - - if (FAILED(hr)) { - VideoDX9Error("could not SetRenderState", hr); - return false; - } - else { - render_state[state] = value; - } - - return true; -} - -bool -VideoDX9::SetBlendType(int blend_type) -{ - if (blend_type == current_blend_state) - return true; - - switch (blend_type) { - default: - // map misc blend types to SOLID - // and fall through to that case - - blend_type = BLEND_SOLID; - - case BLEND_SOLID: - d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false); - break; - - case BLEND_ALPHA: - d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true); - d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - break; - - case BLEND_ADDITIVE: - d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true); - d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); - d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); - break; - } - - current_blend_state = blend_type; - return true; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::StartFrame() -{ - if (device_lost) { - RecoverSurfaces(); - - if (status != VIDEO_OK) - return false; - } - - stats.Clear(); - - HRESULT err = 0; - static int frame_number = 1; - static int report_errs = 100; - - stats.nframe = frame_number; - texcache->FrameNumber(frame_number++); - - // update gamma ramp for global fade value: - SetGammaLevel(gamma); - - ClearAll(); - - err = d3ddevice->BeginScene(); - - if (FAILED(err)) { - if (report_errs > 0) { - report_errs--; - VideoDX9Error("could not begin scene", err); - } - - return false; - } - - scene_active = 1; - current_blend_state = -1; - - SetRenderState(LIGHTING_PASS, 0); - SetRenderState(STENCIL_ENABLE, false); - - return true; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::EndFrame() -{ - HRESULT err = 0; - - if (scene_active) { - err = d3ddevice->EndScene(); - - if (FAILED(err)) { - VideoDX9Error("could not end scene", err); - return false; - } - } - - scene_active = 0; - return true; -} - -// +--------------------------------------------------------------------+ - -static DWORD ColorModulate(DWORD a, DWORD b) -{ - float a0 = (float) ((a ) & 0xff)/255.0f; - float a1 = (float) ((a>> 8) & 0xff)/255.0f; - float a2 = (float) ((a>>16) & 0xff)/255.0f; - float a3 = (float) ((a>>24) & 0xff)/255.0f; - - float b0 = (float) ((b ) & 0xff)/255.0f; - float b1 = (float) ((b>> 8) & 0xff)/255.0f; - float b2 = (float) ((b>>16) & 0xff)/255.0f; - float b3 = (float) ((b>>24) & 0xff)/255.0f; - - return (DWORD) ((BYTE)(a3*b3*255.0f) << 24) | - ((BYTE)(a2*b2*255.0f) << 16) | - ((BYTE)(a1*b1*255.0f) << 8) | - ((BYTE)(a0*b0*255.0f)); -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::PopulateScreenVerts(VertexSet* vset) -{ - if (!vset || !screen_vbuf) - return false; - - num_verts = vset->nverts; - - VideoDX9ScreenVertex* v = (VideoDX9ScreenVertex*) screen_vbuf->Lock(num_verts); - - if (v) { - first_vert = screen_vbuf->GetNextVert(); - - for (int i = 0; i < num_verts; i++) { - v->sx = vset->s_loc[i].x; - v->sy = vset->s_loc[i].y; - v->sz = vset->s_loc[i].z; - v->rhw = vset->rw[i]; - - v->diffuse = vset->diffuse[i]; - - v->tu = vset->tu[i]; - v->tv = vset->tv[i]; - - v++; - } - - screen_vbuf->Unlock(); - return true; - } - - Print(" VideoDX9: could not lock screen vbuf for %d verts.\n", num_verts); - return false; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::DrawPolys(int npolys, Poly* polys) -{ - bool result = false; - - if (d3ddevice && polys && npolys > 0) { - // screen space polys: - if (polys->vertex_set->space == VertexSet::SCREEN_SPACE) - return DrawScreenPolys(npolys, polys); - - // world space polys: - stats.ncalls++; - - VertexSet* vset = polys->vertex_set; - int nverts = vset->nverts; - bool luminous = false; - bool detail = false; - DWORD fvf = 0; - void* verts = 0; - int vsize = 0; - WORD* indices = new WORD[npolys*6]; - - if (polys->material) { - luminous = polys->material->luminous; - } - - if (vset->tu1 != 0) { - VideoDX9DetailVertex* v = new VideoDX9DetailVertex[nverts]; - verts = v; - vsize = sizeof(VideoDX9DetailVertex); - fvf = VideoDX9DetailVertex::FVF; - - for (int i = 0; i < nverts; i++) { - v->x = vset->loc[i].x; - v->y = vset->loc[i].y; - v->z = vset->loc[i].z; - - v->diffuse = vset->diffuse[i]; - v->specular = vset->specular[i]; - - v->tu = vset->tu[i]; - v->tv = vset->tv[i]; - v->tu1 = vset->tu1[i]; - v->tv1 = vset->tv1[i]; - - v++; - } - } - - else if (luminous) { - VideoDX9LuminousVertex* v = new VideoDX9LuminousVertex[nverts]; - verts = v; - vsize = sizeof(VideoDX9LuminousVertex); - fvf = VideoDX9LuminousVertex::FVF; - - for (int i = 0; i < nverts; i++) { - v->x = vset->loc[i].x; - v->y = vset->loc[i].y; - v->z = vset->loc[i].z; - - v->diffuse = vset->diffuse[i]; - - v->tu = vset->tu[i]; - v->tv = vset->tv[i]; - - v++; - } - } - - else { - VideoDX9SolidVertex* v = new VideoDX9SolidVertex[nverts]; - verts = v; - vsize = sizeof(VideoDX9SolidVertex); - fvf = VideoDX9SolidVertex::FVF; - - for (int i = 0; i < nverts; i++) { - v->x = vset->loc[i].x; - v->y = vset->loc[i].y; - v->z = vset->loc[i].z; - - v->nx = vset->nrm[i].x; - v->ny = vset->nrm[i].y; - v->nz = vset->nrm[i].z; - - v->tu = vset->tu[i]; - v->tv = vset->tv[i]; - - v++; - } - } - - if (verts && indices) { - HRESULT hr = E_FAIL; - - // fill index array - int num_indices = 0; - int num_tris = 0; - - WORD* s = indices; - Poly* p = polys; - - for (int i = 0; i < npolys; i++) { - if (p->nverts == 3) { - num_indices += 3; - num_tris += 1; - - *s++ = p->verts[0]; - *s++ = p->verts[1]; - *s++ = p->verts[2]; - } - - else if (p->nverts == 4) { - num_indices += 6; - num_tris += 2; - - *s++ = p->verts[0]; - *s++ = p->verts[1]; - *s++ = p->verts[2]; - - *s++ = p->verts[0]; - *s++ = p->verts[2]; - *s++ = p->verts[3]; - } - - p++; - } - - hr = d3ddevice->SetTransform(D3DTS_WORLD, &identity_matrix); - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(fvf); - - // send primitives to the device - Material* mtl = polys->material; - IDirect3DTexture9* texture = 0; - - if (mtl && texcache && mtl->tex_diffuse) { - texture = texcache->FindTexture(mtl->tex_diffuse); - } - - if (current_texture != texture) { - hr = d3ddevice->SetTexture(0, texture); - current_texture = texture; - } - - if (mtl && texcache && mtl->tex_detail) { - texture = texcache->FindTexture(mtl->tex_detail); - hr = d3ddevice->SetTexture(1, texture); - } - - if (mtl && !luminous) { - D3DMATERIAL9 d3dmtl; - CreateD3DMaterial(d3dmtl, *mtl); - - hr = d3ddevice->SetMaterial(&d3dmtl); - hr = d3ddevice->SetRenderState(D3DRS_AMBIENT, ambient.Value()); - } - - // set render states and select buffers - SetRenderState(FILL_MODE, D3DFILL_SOLID); - SetRenderState(LIGHTING_ENABLE, luminous ? FALSE : TRUE); - SetBlendType(mtl->blend); - - d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - - d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - - hr = d3ddevice->DrawIndexedPrimitiveUP( - D3DPT_TRIANGLELIST, - 0, - nverts, - num_tris, - indices, - D3DFMT_INDEX16, - verts, - vsize); - - if (FAILED(hr)) { - static int report = 10; - if (report-- > 0) - VideoDX9Error("Could not draw 3D polys.", hr); - } - - delete [] verts; - delete [] indices; - - if (SUCCEEDED(hr)) { - stats.nverts += nverts; - stats.npolys += num_tris; - result = true; - } - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::DrawScreenPolys(int npolys, Poly* polys, int blend) -{ - bool result = false; - HRESULT hr = E_FAIL; - - if (d3ddevice && polys && npolys > 0 && screen_vbuf && screen_ibuf) { - stats.ncalls++; - - // fill screen vertex buffer - if (!PopulateScreenVerts(polys->vertex_set)) - return false; - - // fill screen index buffer - int num_indices = 0; - int num_tris = 0; - - // count the number of indices needed for these polys - for (int i = 0; i < npolys; i++) { - Poly* p = polys + i; - - if (p->nverts == 3) { - num_indices += 3; - num_tris += 1; - } - - else if (p->nverts == 4) { - num_indices += 6; - num_tris += 2; - } - } - - WORD* screen_indices = screen_ibuf->Lock(num_indices); - int first_index = screen_ibuf->GetNextIndex(); - - if (!screen_indices) { - Print(" VideoDX9: could not lock screen ibuf for %d indices.\n", num_indices); - return false; - } - - // copy the indices into the locked index buffer - WORD* s = screen_indices; - Poly* p = polys; - - for (int i = 0; i < npolys; i++) { - if (p->nverts == 3) { - *s++ = p->verts[0] + first_vert; - *s++ = p->verts[1] + first_vert; - *s++ = p->verts[2] + first_vert; - } - else if (p->nverts == 4) { - *s++ = p->verts[0] + first_vert; - *s++ = p->verts[1] + first_vert; - *s++ = p->verts[2] + first_vert; - - *s++ = p->verts[0] + first_vert; - *s++ = p->verts[2] + first_vert; - *s++ = p->verts[3] + first_vert; - } - - p++; - } - - screen_ibuf->Unlock(); - - // set render states and select buffers - SetRenderState(FILL_MODE, D3DFILL_SOLID); - SetRenderState(Z_ENABLE, D3DZB_FALSE); - SetRenderState(Z_WRITE_ENABLE, D3DZB_FALSE); - SetRenderState(LIGHTING_ENABLE, FALSE); - SetBlendType(blend); - - d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - - d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - // send primitives to the device - Material* mtl = polys->material; - IDirect3DTexture9* texture = 0; - - if (mtl && texcache && mtl->tex_diffuse) { - texture = texcache->FindTexture(mtl->tex_diffuse); - } - - if (current_texture != texture) { - hr = d3ddevice->SetTexture(0, texture); - current_texture = texture; - } - - screen_vbuf->Select(0); - screen_ibuf->Select(); - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9ScreenVertex::FVF); - - hr = d3ddevice->DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - 0, - first_vert, - num_verts, - first_index, - num_tris); - - if (FAILED(hr)) { - static int report = 10; - if (report-- > 0) - VideoDX9Error("Could not draw screen polys.", hr); - } - else { - stats.nverts += num_verts; - stats.npolys += num_tris; - result = true; - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::DrawSolid(Solid* s, DWORD blend_modes) -{ - bool result = false; - HRESULT hr = E_FAIL; - - if (d3ddevice && s && s->GetModel()) { - Model* model = s->GetModel(); - Matrix orient = s->Orientation(); - orient.Transpose(); - - D3DMATRIX world_matrix; - CreateD3DMatrix(world_matrix, orient, s->Location()); - d3ddevice->SetTransform(D3DTS_WORLD, &world_matrix); - matrixWorld = world_matrix; - D3DXMatrixInverse(&matrixWorldInverse, 0, &matrixWorld); - - ListIter surf_iter = model->GetSurfaces(); - while (++surf_iter) { - Surface* surf = surf_iter.value(); - - if (surf->IsHidden() || surf->IsSimplified()) - continue; - - if (PrepareSurface(surf)) { - result = true; - - VideoDX9SurfaceData* surf_data = (VideoDX9SurfaceData*) surf->GetVideoPrivateData(); - surf_data->vertex_buffer->Select(0); - surf_data->index_buffer->Select(); - - ListIter seg_iter = surf->GetSegments(); - while (++seg_iter) { - Segment* segment = seg_iter.value(); - Material* mtl = segment->material; - - if (mtl && (blend_modes & mtl->blend)) { - result = result && DrawSegment(segment); - } - } - } - } - } - - surface_has_tangent_data = false; - - return result; -} - -bool -VideoDX9::DrawSegment(Segment* segment) -{ - bool result = false; - bool detail = false; - bool luminous = false; - HRESULT hr = E_FAIL; - - if (segment && segment->video_data) { - stats.ncalls++; - - VideoDX9SegmentData* seg_data = (VideoDX9SegmentData*) segment->video_data; - int first_vert = seg_data->first_vert; - int num_verts = seg_data->num_verts; - int first_index = seg_data->first_index; - int num_tris = seg_data->num_tris; - - if (segment->model) - luminous = segment->model->IsLuminous(); - - // set render states and select buffers - d3ddevice->SetRenderState(D3DRS_AMBIENT, ambient.Value()); - - Material* mtl = segment->material; - - if (use_material) - mtl = use_material; - - if (segment->polys && segment->polys->vertex_set && segment->polys->vertex_set->tu1) - detail = true; - - // send primitives to the device - if (detail) { - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9DetailVertex::FVF); - } - - else if (luminous) { - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9LuminousVertex::FVF); - } - - else if (surface_has_tangent_data && vertex_declaration) { - hr = d3ddevice->SetVertexDeclaration(vertex_declaration); - hr = d3ddevice->SetVertexShader(NULL); - } - - else { - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9SolidVertex::FVF); - } - - if (render_state[FILL_MODE] == FILL_WIREFRAME) { - PrepareMaterial(mtl); - SetupPass(0); - - for (int i = 0; i < segment->npolys; i++) { - DrawPolyOutline(segment->polys + i); - } - } - - else if (luminous) { - PrepareMaterial(mtl); - - SetRenderState(FILL_MODE, D3DFILL_SOLID); - SetRenderState(LIGHTING_ENABLE, FALSE); - SetBlendType(mtl->blend); - - for (int pass = 0; pass < passes; pass++) { - SetupPass(pass); - - hr = d3ddevice->DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - 0, - first_vert, - num_verts, - first_index, - num_tris); - } - - d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - } - - else { - PrepareMaterial(mtl); - - if (strategy == DX9_STRATEGY_GLOW && render_state[LIGHTING_PASS] > 0) { - hr = 0; - } - - else if (magic_fx && strategy < DX9_STRATEGY_BLEND && !detail) { - DWORD vs_version = 0; - DWORD ps_version = 0; - bool shaders_ok = false; - - VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType()); - - if (dev_info) { - vs_version = video_settings.enable_vs ? dev_info->caps.VertexShaderVersion : 0; - ps_version = video_settings.enable_ps ? dev_info->caps.PixelShaderVersion : 0; - - if (vs_version >= D3DVS_VERSION(1,1)) - shaders_ok = true; - } - - if (surface_has_tangent_data && vertex_declaration) { - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetVertexDeclaration(vertex_declaration); - } - - else { - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9SolidVertex::FVF); - } - - bool would_bump = !IsBumpMapEnabled() && mtl->bump > 0.5; - - bool will_bump = IsBumpMapEnabled() && surface_has_tangent_data && shaders_ok && camera; - - bool do_pix = will_bump && render_state[LIGHTING_PASS] == 0; - bool do_bump = will_bump && render_state[LIGHTING_PASS] > 0; - - D3DXMATRIX matrixWVP = matrixWorld * matrixView * matrixProj; - - D3DXVECTOR4 eyePos( (float) camera->Pos().x, (float) camera->Pos().y, (float) camera->Pos().z, 1.0f); - - D3DXVECTOR4 eyeObj; - D3DXVec4Transform(&eyeObj, &eyePos, &matrixWorldInverse); - - D3DXVECTOR4 lightPos(100.0f, 100.0f, 100.0f, 1.0f); - D3DXVECTOR4 lightColor(1,1,1,1); - D3DXVECTOR4 ambientColor(0,0,0,1); - - ambientColor.x = ambient.fRed(); - ambientColor.y = ambient.fGreen(); - ambientColor.z = ambient.fBlue(); - - if (main_light && (render_state[LIGHTING_PASS] > 0 || mtl->blend > Material::MTL_SOLID)) { - lightPos.x = (float) main_light->Location().x; - lightPos.y = (float) main_light->Location().y; - lightPos.z = (float) main_light->Location().z; - - if (mtl->tex_bumpmap && do_bump) - D3DXVec4Transform(&lightPos, &lightPos, &matrixWorldInverse); - - lightColor.x = main_light->GetColor().fRed() * main_light->Intensity(); - lightColor.y = main_light->GetColor().fGreen() * main_light->Intensity(); - lightColor.z = main_light->GetColor().fBlue() * main_light->Intensity(); - lightColor.w = 1.0f; - } - - else if (back_light && render_state[LIGHTING_PASS] == 0) { - lightPos.x = (float) back_light->Location().x; - lightPos.y = (float) back_light->Location().y; - lightPos.z = (float) back_light->Location().z; - - lightColor.x = back_light->GetColor().fRed() * back_light->Intensity(); - lightColor.y = back_light->GetColor().fGreen() * back_light->Intensity(); - lightColor.z = back_light->GetColor().fBlue() * back_light->Intensity(); - lightColor.w = 1.0f; - } - - D3DXVECTOR4 lightDir = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f) - lightPos; - D3DXVec4Normalize(&lightDir, &lightDir); - - magic_fx->SetMatrix("wvp", &matrixWVP); - magic_fx->SetMatrix("world", &matrixWorld); - magic_fx->SetMatrix("view", &matrixView); - magic_fx->SetMatrix("proj", &matrixProj); - magic_fx->SetMatrix("worldInv", &matrixWorldInverse); - - magic_fx->SetVector("light1Pos", &lightPos); - magic_fx->SetVector("light1Dir", &lightDir); - magic_fx->SetVector("light1Color", &lightColor); - magic_fx->SetVector("ambientColor", &ambientColor); - magic_fx->SetVector("eyeObj", &eyeObj); - - FLOAT base_bias = (FLOAT) (DW2I(render_state[Z_BIAS]) / -10000.0); - magic_fx->SetFloat("bias", base_bias + video_settings.depth_bias); - - ColorValue orig_ks = mtl->Ks; - - if (would_bump && mtl->specular_value >= 0.5) - mtl->Ks = mtl->Ks * 0.3; - - magic_fx->SetValue("Ka", &mtl->Ka, sizeof(ColorValue)); - magic_fx->SetValue("Kd", &mtl->Kd, sizeof(ColorValue)); - magic_fx->SetValue("Ke", &mtl->Ke, sizeof(ColorValue)); - magic_fx->SetValue("Ks", &mtl->Ks, sizeof(ColorValue)); - magic_fx->SetFloat("Ns", mtl->power); - - if (would_bump && mtl->specular_value >= 0.5) - mtl->Ks = orig_ks; - - if (mtl->tex_diffuse) { - IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_diffuse); - magic_fx->SetTexture("tex_d", texture); - } else { - magic_fx->SetTexture("tex_d", 0); - } - - if (mtl->tex_emissive) { - IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_emissive); - magic_fx->SetTexture("tex_e", texture); - } else { - magic_fx->SetTexture("tex_e", 0); - } - - if (mtl->tex_specular && IsSpecMapEnabled()) { - IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_specular); - magic_fx->SetTexture("tex_s", texture); - } else { - magic_fx->SetTexture("tex_s", 0); - } - - if (mtl->tex_bumpmap && do_bump) { - IDirect3DTexture9* texture = texcache->FindNormalMap(mtl->tex_bumpmap, mtl->bump); - magic_fx->SetTexture("tex_n", texture); - magic_fx->SetFloat("offsetAmp", mtl->bump / mtl->tex_bumpmap->Height()); - } else if (mtl->tex_bumpmap && !do_bump) { - IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_bumpmap); - magic_fx->SetTexture("tex_x", texture); - } else { - magic_fx->SetTexture("tex_x", 0); - } - - const char* mtl_shader = mtl->GetShader(render_state[LIGHTING_PASS]); - D3DXHANDLE hnd_shader = 0; - - if (mtl_shader) { - if (!strcmp(mtl_shader, "null")) - return true; - - hnd_shader = magic_fx->GetTechniqueByName(mtl_shader); - } - - if (hnd_shader) { - hr = magic_fx->SetTechnique(hnd_shader); - } else { - if (will_bump) { - if (mtl->tex_specular && IsSpecMapEnabled()) { - if (mtl->tex_bumpmap && do_bump) { - if (ps_version >= D3DPS_VERSION(2,0)) - hr = magic_fx->SetTechnique("BumpSpecMapPix"); - else - hr = magic_fx->SetTechnique("BumpSpecMap"); - } else if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) { - if (ps_version >= D3DPS_VERSION(2,0)) - hr = magic_fx->SetTechnique("EmissiveSpecMapPix"); - else - hr = magic_fx->SetTechnique("EmissiveSpecularTexture"); - } else { - if (ps_version >= D3DPS_VERSION(2,0)) - hr = magic_fx->SetTechnique("SpecMapPix"); - else - hr = magic_fx->SetTechnique("SpecularTexture"); - } - } else { - if (mtl->tex_bumpmap && do_bump) { - if (ps_version >= D3DPS_VERSION(2,0)) - hr = magic_fx->SetTechnique("BumpMapPix"); - else - hr = magic_fx->SetTechnique("BumpMap"); - } else if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) { - if (ps_version >= D3DPS_VERSION(2,0)) - hr = magic_fx->SetTechnique("EmissivePix"); - else - hr = magic_fx->SetTechnique("EmissiveTexture"); - } else { - if (ps_version >= D3DPS_VERSION(2,0)) - hr = magic_fx->SetTechnique("SimplePix"); - else - hr = magic_fx->SetTechnique("SimpleTexture"); - } - } - } - - else if (texcache && mtl->tex_diffuse) { - if (mtl->tex_specular && IsSpecMapEnabled()) { - if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) { - hr = magic_fx->SetTechnique("EmissiveSpecularTexture"); - } else { - hr = magic_fx->SetTechnique("SpecularTexture"); - } - } - - else { - if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) { - hr = magic_fx->SetTechnique("EmissiveTexture"); - } else { - hr = magic_fx->SetTechnique("SimpleTexture"); - } - } - } else { - hr = magic_fx->SetTechnique("SimpleMaterial"); - } - } - - if (environment_cube != 0 && magic_fx->IsParameterUsed("env_cube", hnd_shader)) { - D3DXMATRIX env_matrix; - D3DXMatrixIdentity(&env_matrix); - - magic_fx->SetMatrix("env_matrix", &env_matrix); - magic_fx->SetTexture("env_cube", environment_cube->GetTexture()); - } - - if (render_state[STENCIL_ENABLE]) { - d3ddevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); - d3ddevice->SetRenderState(D3DRS_STENCILREF, 0x01); - d3ddevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATER); - } else { - d3ddevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - } - - if (render_state[LIGHTING_PASS] > 0) { - current_blend_state = 100; - SetBlendType(BLEND_ADDITIVE); - SetRenderState(Z_WRITE_ENABLE, FALSE); - } else { - current_blend_state = 100; - SetBlendType(mtl->blend); - } - - UINT nPasses = 0; - - hr = magic_fx->Begin(&nPasses, 0); - - for (UINT i = 0; i < nPasses; i++) { - hr = magic_fx->BeginPass(i); - - hr = d3ddevice->DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - 0, - first_vert, - num_verts, - first_index, - num_tris); - - hr = magic_fx->EndPass(); - } - - hr = magic_fx->End(); - } else { - for (int pass = 0; pass < passes; pass++) { - SetupPass(pass); - - hr = d3ddevice->DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - 0, - first_vert, - num_verts, - first_index, - num_tris); - - if (detail) { - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9DetailVertex::FVF); - } else if (luminous) { - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9LuminousVertex::FVF); - } else if (surface_has_tangent_data && vertex_declaration) { - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetVertexDeclaration(vertex_declaration); - } else { - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9SolidVertex::FVF); - } - } - } - } - - if (FAILED(hr)) { - static int report = 10; - if (report-- > 0) - VideoDX9Error("Could not draw solid polys.", hr); - } else { - stats.nverts += num_verts; - stats.npolys += num_tris; - result = true; - } - } - - return result; -} - -bool -VideoDX9::DrawPolyOutline(Poly* p) -{ - if (d3ddevice && p && p->nverts >= 3) { - static VideoDX9LineVertex verts[8]; - - int nlines = p->nverts; - VertexSet* vset = p->vertex_set; - WORD index = 0; - Color color = Color::Black; - HRESULT hr = E_FAIL; - - ZeroMemory(verts, sizeof(verts)); - - if (p->material) - color = p->material->Kd.ToColor(); - - for (int i = 0; i < p->nverts; i++) { - index = p->verts[i]; - - verts[i].x = vset->loc[index].x; - verts[i].y = vset->loc[index].y; - verts[i].z = vset->loc[index].z; - verts[i].diffuse = color.Value(); - } - - // last vertex, to close the loop - index = p->verts[0]; - int i = p->nverts; - - verts[i].x = vset->loc[index].x; - verts[i].y = vset->loc[index].y; - verts[i].z = vset->loc[index].z; - verts[i].diffuse = color.Value(); - - current_texture = 0; - - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9LineVertex::FVF); - hr = d3ddevice->SetTexture(0, 0); - hr = d3ddevice->DrawPrimitiveUP( - D3DPT_LINESTRIP, - nlines, - verts, - sizeof(VideoDX9LineVertex)); - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::DrawShadow(Solid* s, int nverts, Vec3* shadow_verts, bool visible) -{ - bool result = false; - HRESULT hr = E_FAIL; - - if (d3ddevice && s && nverts && shadow_verts && IsShadowEnabled()) { - Matrix orient = s->Orientation(); - orient.Transpose(); - - D3DMATRIX world_matrix; - CreateD3DMatrix(world_matrix, orient, s->Location()); - d3ddevice->SetTransform(D3DTS_WORLD, &world_matrix); - matrixWorld = world_matrix; - - // show shadow outlines: - if (visible) { - static VideoDX9LineVertex verts[4]; - - d3ddevice->SetRenderState(D3DRS_ZENABLE, TRUE); - d3ddevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - d3ddevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); - d3ddevice->SetRenderState(D3DRS_LIGHTING, FALSE); - d3ddevice->SetVertexShader(NULL); - d3ddevice->SetFVF(VideoDX9LineVertex::FVF); - d3ddevice->SetTexture(0, 0); - - SetBlendType(BLEND_ALPHA); - - for (int i = 0; i < nverts; i+=3) { - DWORD c = 0xa0ffff80; - - verts[0].x = shadow_verts[i+0].x; - verts[0].y = shadow_verts[i+0].y; - verts[0].z = shadow_verts[i+0].z; - verts[0].diffuse = c; - - verts[1].x = shadow_verts[i+1].x; - verts[1].y = shadow_verts[i+1].y; - verts[1].z = shadow_verts[i+1].z; - verts[1].diffuse = c; - - verts[2].x = shadow_verts[i+2].x; - verts[2].y = shadow_verts[i+2].y; - verts[2].z = shadow_verts[i+2].z; - verts[2].diffuse = c; - - verts[3].x = shadow_verts[i+0].x; - verts[3].y = shadow_verts[i+0].y; - verts[3].z = shadow_verts[i+0].z; - verts[3].diffuse = c; - - hr = d3ddevice->DrawPrimitiveUP( - D3DPT_LINESTRIP, - 3, - verts, - sizeof(VideoDX9LineVertex)); - } - - // restore lighting state - d3ddevice->SetRenderState(D3DRS_LIGHTING, render_state[LIGHTING_ENABLE]); - } - - // render shadows into stencil buffer: - - // Disable z-buffer writes (note: z-testing still occurs), and enable the - // stencil-buffer - d3ddevice->SetRenderState(D3DRS_ZENABLE, TRUE); - d3ddevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - d3ddevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); - - // Dont bother with interpolating color - d3ddevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); - - // Set up stencil compare fuction, reference value, and masks. - // Stencil test passes if ((ref & mask) cmpfn (stencil & mask)) is true. - // Note: since we set up the stencil-test to always pass, the STENCILFAIL - // renderstate is really not needed. - d3ddevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS ); - d3ddevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); - d3ddevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP ); - - // If z-test passes, inc/decrement stencil buffer value - d3ddevice->SetRenderState(D3DRS_STENCILREF, 0x1 ); - d3ddevice->SetRenderState(D3DRS_STENCILMASK, 0xff ); - d3ddevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xff ); - d3ddevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR ); - - // Make sure that no pixels get drawn to the frame buffer - d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE ); - d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO ); - d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE ); - - d3ddevice->SetVertexShader(NULL); - d3ddevice->SetFVF(D3DFVF_XYZ); - - // Draw front-side of shadow volume in stencil/z only - hr = d3ddevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, nverts/3, shadow_verts, sizeof(Vec3)); - - // Now reverse cull order so back sides of shadow volume are written. - d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW ); - - // Decrement stencil buffer value - d3ddevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR ); - - // Draw back-side of shadow volume in stencil/z only - hr = d3ddevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, nverts/3, shadow_verts, sizeof(Vec3)); - - // restore render states - d3ddevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); - d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); - d3ddevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); - d3ddevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - - // force restore of current blend type - int type = current_blend_state; - current_blend_state = 100; - SetBlendType(type); - - result = SUCCEEDED(hr); - } - - return result; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::DrawLines(int nlines, Vec3* points, Color c, int blend) -{ - bool result = false; - - if (d3ddevice && points && nlines > 0 && nlines <= 256) { - stats.ncalls++; - - VideoDX9LineVertex* verts = line_verts; - - if (verts) { - HRESULT hr = E_FAIL; - - for (int i = 0; i < 2*nlines; i++) { - VideoDX9LineVertex* v = verts + i; - Vec3* p = points + i; - - v->x = p->x; - v->y = p->y; - v->z = p->z; - v->diffuse = c.Value(); - } - - hr = d3ddevice->SetTransform(D3DTS_WORLD, &identity_matrix); - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9LineVertex::FVF); - - DWORD old_lighting = render_state[LIGHTING_ENABLE]; - - // untextured lines: - if (current_texture) { - d3ddevice->SetTexture(0, 0); - current_texture = 0; - } - - SetRenderState(LIGHTING_ENABLE, FALSE); - SetBlendType(blend); - - hr = d3ddevice->DrawPrimitiveUP( - D3DPT_LINELIST, - nlines, - verts, - sizeof(VideoDX9LineVertex)); - - if (FAILED(hr)) { - static int report = 10; - if (report-- > 0) - VideoDX9Error("Could not draw 3D lines.", hr); - } - - SetRenderState(LIGHTING_ENABLE, old_lighting); - - if (SUCCEEDED(hr)) { - stats.nverts += 2*nlines; - stats.nlines += nlines; - result = true; - } - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::DrawScreenLines(int nlines, float* points, Color c, int blend) -{ - bool result = false; - - if (d3ddevice && points && nlines > 0 && nlines <= 64) { - stats.ncalls++; - - VideoDX9ScreenVertex* verts = screen_line_verts; - - if (verts) { - HRESULT hr = E_FAIL; - - for (int i = 0; i < 2*nlines; i++) { - VideoDX9ScreenVertex* v = verts + i; - - v->sx = points[2*i + 0]; - v->sy = points[2*i + 1]; - v->sz = 0.0f; - v->rhw = 1.0f; - v->diffuse = c.Value(); - v->tu = 0.0f; - v->tv = 0.0f; - } - - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9ScreenVertex::FVF); - - if (FAILED(hr)) { - static int report = 10; - if (report-- > 0) - VideoDX9Error("Could not set FVF for screen lines.", hr); - } - - else { - if (current_texture != 0) { - hr = d3ddevice->SetTexture(0, 0); - current_texture = 0; - } - - SetRenderState(FILL_MODE, D3DFILL_SOLID); - SetRenderState(Z_ENABLE, D3DZB_FALSE); - SetRenderState(LIGHTING_ENABLE, FALSE); - SetBlendType(blend); - - hr = d3ddevice->DrawPrimitiveUP( - D3DPT_LINELIST, - nlines, - verts, - sizeof(VideoDX9ScreenVertex)); - - if (FAILED(hr)) { - static int report = 10; - if (report-- > 0) - VideoDX9Error("Could not draw screen lines.", hr); - } - } - - if (SUCCEEDED(hr)) { - stats.nverts += 2*nlines; - stats.nlines += nlines; - result = true; - } - } - } - - return result; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::DrawPoints(VertexSet* vset) -{ - if (vset && vset->nverts) { - HRESULT hr = E_FAIL; - - int nverts = vset->nverts; - VideoDX9LineVertex* verts = new VideoDX9LineVertex[nverts]; - - if (verts) { - for (int i = 0; i < nverts; i++) { - VideoDX9LineVertex* v = verts + i; - Vec3* p = vset->loc + i; - - v->x = p->x; - v->y = p->y; - v->z = p->z; - v->diffuse = vset->diffuse[i]; - } - - SetRenderState(LIGHTING_ENABLE, FALSE); - - hr = d3ddevice->SetTransform(D3DTS_WORLD, &identity_matrix); - hr = d3ddevice->SetVertexShader(NULL); - hr = d3ddevice->SetFVF(VideoDX9LineVertex::FVF); - hr = d3ddevice->SetTexture(0, 0); - hr = d3ddevice->DrawPrimitiveUP( - D3DPT_POINTLIST, - nverts, - verts, - sizeof(VideoDX9LineVertex)); - - delete [] verts; - return true; - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::UseMaterial(Material* m) -{ - use_material = m; - return true; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::UseXFont(const char* name, int size, bool bold, bool ital) -{ - if (d3ddevice && name && *name && size > 4) { - RELEASE(d3dx_font); - - strcpy_s(font_name, name); - font_size = size; - font_bold = bold; - font_ital = ital; - - HRESULT hr = E_FAIL; - HDC hdc = GetDC(NULL); - int nLogPixelsY = GetDeviceCaps(hdc, LOGPIXELSY); - - ReleaseDC(NULL, hdc); - - int nHeight = -size * nLogPixelsY / 72; - - hr = D3DXCreateFont(d3ddevice, // D3D device - nHeight, // Height - 0, // Width - bold ? FW_BOLD : FW_NORMAL, // Weight - 1, // MipLevels, 0 = autogen mipmaps - ital, // Italic - DEFAULT_CHARSET, // CharSet - OUT_DEFAULT_PRECIS, // OutputPrecision - DEFAULT_QUALITY, // Quality - DEFAULT_PITCH | FF_DONTCARE, // PitchAndFamily - name, // pFaceName - &d3dx_font); // ppFont - - if (SUCCEEDED(hr)) { - return true; - } - } - - RELEASE(d3dx_font); - return false; -} - -bool -VideoDX9::DrawText(const char* text, int count, const Rect& rect, DWORD format, Color c) -{ - if (d3ddevice && text && *text && d3dx_font) { - RECT r; - r.left = rect.x; - r.top = rect.y; - r.right = rect.x + rect.w; - r.bottom = rect.y + rect.h; - - d3dx_font->DrawText(0, text, count, &r, format, c.Value()); - } - - return false; -} - -// +--------------------------------------------------------------------+ - -bool -VideoDX9::PrepareSurface(Surface* surf) -{ - if (surf) { - int nverts = surf->NumVerts(); - int nindices = surf->NumIndices(); - bool detail = surf->GetVertexSet()->tu1 != 0; - bool luminous = false; - DWORD dynamic = 0; - - if (surf->GetModel()) { - luminous = surf->GetModel()->IsLuminous(); - dynamic = surf->GetModel()->IsDynamic() ? D3DUSAGE_DYNAMIC : 0; - } - - surface_has_tangent_data = !luminous && (surf->GetVertexSet()->tangent && surf->GetVertexSet()->binormal); - - VideoDX9SurfaceData* surf_data = (VideoDX9SurfaceData*) surf->GetVideoPrivateData(); - - if (!surf_data) { - surf_data = new VideoDX9SurfaceData(surf->GetModel()); - - surface_has_tangent_data = false; - - if (surf->GetVertexSet()->tangent && surf->GetVertexSet()->binormal) { - surface_has_tangent_data = true; - surf_data->vertex_buffer = new VideoDX9VertexBuffer( - this, - nverts, - sizeof(VideoDX9NormalVertex), - 0, // not an FVF vertex buffer - dynamic | D3DUSAGE_WRITEONLY); - } - - else if (detail) { - surf_data->vertex_buffer = new VideoDX9VertexBuffer( - this, - nverts, - sizeof(VideoDX9DetailVertex), - VideoDX9DetailVertex::FVF, - dynamic | D3DUSAGE_WRITEONLY); - } - - else if (luminous) { - surf_data->vertex_buffer = new VideoDX9VertexBuffer( - this, - nverts, - sizeof(VideoDX9LuminousVertex), - VideoDX9LuminousVertex::FVF, - dynamic | D3DUSAGE_WRITEONLY); - } - - else { - surf_data->vertex_buffer = new VideoDX9VertexBuffer( - this, - nverts, - sizeof(VideoDX9SolidVertex), - VideoDX9SolidVertex::FVF, - dynamic | D3DUSAGE_WRITEONLY); - } - - surf_data->index_buffer = new VideoDX9IndexBuffer( - this, - nindices, - dynamic | D3DUSAGE_WRITEONLY); - - if (!surf_data->vertex_buffer || !surf_data->index_buffer) { - Print("VideoDX9: Unable to prepare surface '%s'\n", surf->Name()); - delete surf_data; - return false; - } - - surf->SetVideoPrivateData(surf_data); - } - - if (surf_data && !surf_data->IsValid()) { - if (detail) { - VideoDX9DetailVertex* v = (VideoDX9DetailVertex*) surf_data->vertex_buffer->Lock(nverts); - - if (v) { - const VertexSet* vset = surf->GetVertexSet(); - for (int i = 0; i < nverts; i++) { - v->x = vset->loc[i].x; - v->y = vset->loc[i].y; - v->z = vset->loc[i].z; - - v->diffuse = vset->diffuse[i]; - v->specular = vset->specular[i]; - - v->tu = vset->tu[i]; - v->tv = vset->tv[i]; - v->tu1 = vset->tu1[i]; - v->tv1 = vset->tv1[i]; - - v++; - } - - surf_data->vertex_buffer->Unlock(); - } - } - - else if (luminous) { - VideoDX9LuminousVertex* v = (VideoDX9LuminousVertex*) surf_data->vertex_buffer->Lock(nverts); - - if (v) { - const VertexSet* vset = surf->GetVertexSet(); - for (int i = 0; i < nverts; i++) { - v->x = vset->loc[i].x; - v->y = vset->loc[i].y; - v->z = vset->loc[i].z; - - v->diffuse = vset->diffuse[i]; - - v->tu = vset->tu[i]; - v->tv = vset->tv[i]; - - v++; - } - - surf_data->vertex_buffer->Unlock(); - } - } - - else if (surface_has_tangent_data) { - VideoDX9NormalVertex* v = (VideoDX9NormalVertex*) surf_data->vertex_buffer->Lock(nverts); - - if (v) { - const VertexSet* vset = surf->GetVertexSet(); - for (int i = 0; i < nverts; i++) { - v->x = vset->loc[i].x; - v->y = vset->loc[i].y; - v->z = vset->loc[i].z; - - v->nx = vset->nrm[i].x; - v->ny = vset->nrm[i].y; - v->nz = vset->nrm[i].z; - - v->t0u = vset->tu[i]; - v->t0v = vset->tv[i]; - v->t1u = vset->tu[i]; - v->t1v = vset->tv[i]; - - v->tx = vset->tangent[i].x; - v->ty = vset->tangent[i].y; - v->tz = vset->tangent[i].z; - - v->bx = vset->binormal[i].x; - v->by = vset->binormal[i].y; - v->bz = vset->binormal[i].z; - - v++; - } - - surf_data->vertex_buffer->Unlock(); - } - } - - else { - VideoDX9SolidVertex* v = (VideoDX9SolidVertex*) surf_data->vertex_buffer->Lock(nverts); - - if (v) { - const VertexSet* vset = surf->GetVertexSet(); - for (int i = 0; i < nverts; i++) { - v->x = vset->loc[i].x; - v->y = vset->loc[i].y; - v->z = vset->loc[i].z; - - v->nx = vset->nrm[i].x; - v->ny = vset->nrm[i].y; - v->nz = vset->nrm[i].z; - - v->tu = vset->tu[i]; - v->tv = vset->tv[i]; - - v++; - } - - surf_data->vertex_buffer->Unlock(); - } - } - - WORD* indices = surf_data->index_buffer->Lock(nindices); - - if (indices) { - // copy the indices into the locked index buffer - WORD* s = indices; - Poly* p = surf->GetPolys(); - - for (int i = 0; i < surf->NumPolys(); i++) { - if (p->nverts == 3) { - *s++ = p->verts[0]; - *s++ = p->verts[2]; - *s++ = p->verts[1]; - } - else if (p->nverts == 4) { - *s++ = p->verts[0]; - *s++ = p->verts[2]; - *s++ = p->verts[1]; - - *s++ = p->verts[0]; - *s++ = p->verts[3]; - *s++ = p->verts[2]; - } - - p++; - } - - surf_data->index_buffer->Unlock(); - } - - surf_data->Validate(); - } - - int first_index = 0; - - ListIter seg_iter = surf->GetSegments(); - while (++seg_iter) { - Segment* segment = seg_iter.value(); - - if (!segment->video_data) { - VideoDX9SegmentData* seg_data = new VideoDX9SegmentData; - - int num_tris = 0; - for (int i = 0; i < segment->npolys; i++) - num_tris += segment->polys[i].nverts-2; - - seg_data->first_vert = 0; - seg_data->num_verts = surf->NumVerts(); - seg_data->first_index = first_index; - seg_data->num_tris = num_tris; - - segment->video_data = seg_data; - - first_index += num_tris * 3; - } - } - } - - return true; -} - -// +--------------------------------------------------------------------+ - -int -VideoDX9::PrepareMaterial(Material* m) -{ - segment_material = m; - strategy = 0; - passes = 0; - - if (m) { - int max_stages = 1; - int max_textures = 1; - bool multiply_add = false; - bool dotproduct3 = false; - bool vertexshader = false; - bool pixelshader = false; - DWORD vs_version = 0; - DWORD ps_version = 0; - - VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType()); - - if (dev_info) { - max_stages = (int) dev_info->caps.MaxTextureBlendStages; - max_textures = (int) dev_info->caps.MaxSimultaneousTextures; - multiply_add = (dev_info->caps.TextureOpCaps & D3DTEXOPCAPS_MULTIPLYADD) ? true : false; - dotproduct3 = (dev_info->caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) ? true : false; - - vs_version = video_settings.enable_vs ? dev_info->caps.VertexShaderVersion : 0; - ps_version = video_settings.enable_ps ? dev_info->caps.PixelShaderVersion : 0; - - vertexshader = vs_version >= D3DVS_VERSION(1,1); - pixelshader = ps_version >= D3DPS_VERSION(2,0); - } - - strategy = DX9_STRATEGY_SIMPLE; - passes = 1; - - if (m->tex_alternate) { - if (m->tex_detail && max_textures > 2 && max_stages > 4) - strategy = DX9_STRATEGY_BLEND_DETAIL; - - else if (max_textures > 1 && max_stages > 3) - strategy = DX9_STRATEGY_BLEND; - } - - else if (m->tex_emissive && (!m->tex_diffuse || m->tex_diffuse == m->tex_emissive)) { - strategy = DX9_STRATEGY_GLOW; - } - - else if (IsSpecMapEnabled() && m->tex_specular && !m->tex_emissive) { - strategy = DX9_STRATEGY_SPECMAP; - - if (max_textures < 2 || max_stages < 2 || !multiply_add) - passes = 2; - } - - else if ((!IsSpecMapEnabled() || !m->tex_specular) && m->tex_emissive) { - strategy = DX9_STRATEGY_EMISSIVE; - - if (max_textures < 2 || max_stages < 2) - passes = 2; - } - - else if (IsSpecMapEnabled() && m->tex_specular && m->tex_emissive) { - strategy = DX9_STRATEGY_SPEC_EMISSIVE; - - if (max_textures < 2 || max_stages < 2) - passes = 3; - - else if (max_textures < 3 || max_stages < 3 || !multiply_add) - passes = 2; - } - } - - return passes; -} - -bool -VideoDX9::SetupPass(int pass) -{ - if (pass < 0 || pass >= passes) - return false; - - if (pass == 0) { - D3DMATERIAL9 d3dmtl; - IDirect3DTexture9* texture_0 = 0; - IDirect3DTexture9* texture_1 = 0; - IDirect3DTexture9* texture_2 = 0; - Bitmap* tex_bmp_0 = 0; - Bitmap* tex_bmp_1 = 0; - Bitmap* tex_bmp_2 = 0; - ColorValue orig_spec = segment_material->Ks; - HRESULT hr = E_FAIL; - - if (segment_material->tex_specular && passes > 1) - segment_material->Ks = Color::Black; - - CreateD3DMaterial(d3dmtl, *segment_material); - segment_material->Ks = orig_spec; - - hr = d3ddevice->SetMaterial(&d3dmtl); - - if (strategy == DX9_STRATEGY_SIMPLE) { - tex_bmp_0 = segment_material->tex_diffuse; - } - - else if (strategy == DX9_STRATEGY_BLEND) { - tex_bmp_0 = segment_material->tex_diffuse; - tex_bmp_1 = segment_material->tex_alternate; - } - - else if (strategy == DX9_STRATEGY_BLEND_DETAIL) { - tex_bmp_0 = segment_material->tex_diffuse; - tex_bmp_1 = segment_material->tex_alternate; - tex_bmp_2 = segment_material->tex_detail; - } - - else if (strategy == DX9_STRATEGY_SPECMAP) { - if (passes == 1) { - tex_bmp_0 = segment_material->tex_diffuse; - tex_bmp_1 = segment_material->tex_specular; - } - else { - tex_bmp_0 = segment_material->tex_diffuse; - } - } - - else if (strategy == DX9_STRATEGY_EMISSIVE && passes == 1 || - strategy == DX9_STRATEGY_SPEC_EMISSIVE && passes == 2) { - if (segment_material->tex_diffuse) { - tex_bmp_0 = segment_material->tex_diffuse; - tex_bmp_1 = segment_material->tex_emissive; - } - else { - tex_bmp_0 = segment_material->tex_emissive; - } - } - - else { - tex_bmp_0 = segment_material->tex_emissive; - } - - if (texcache && tex_bmp_0) { - texture_0 = texcache->FindTexture(tex_bmp_0); - - hr = d3ddevice->SetTexture(0, texture_0); - current_texture = texture_0; - - if (tex_bmp_1) { - texture_1 = texcache->FindTexture(tex_bmp_1); - hr = d3ddevice->SetTexture(1, texture_1); - - if (tex_bmp_2) { - texture_2 = texcache->FindTexture(tex_bmp_2); - hr = d3ddevice->SetTexture(2, texture_2); - } - } - } - else { - hr = d3ddevice->SetTexture(0, 0); - current_texture = 0; - } - - SetBlendType(segment_material->blend); - - if (texture_0 && texture_1 && strategy == DX9_STRATEGY_BLEND) { - d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); - - d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); - - d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA); - d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); - - d3ddevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - - d3ddevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); - } - - else if (texture_0 && texture_1 && texture_2 && strategy == DX9_STRATEGY_BLEND_DETAIL) { - d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(2, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); - - d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); - d3ddevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); - - d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA); - d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); - - d3ddevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA); - d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(2, D3DTSS_TEXCOORDINDEX, 1); - - d3ddevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(3, D3DTSS_COLORARG1, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(3, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - d3ddevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(3, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - } - - else if (texture_0 && strategy == DX9_STRATEGY_GLOW) { - d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - } - - else if (texture_0) { - d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - } - - if (texture_1 && strategy == DX9_STRATEGY_SPECMAP) { - d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); - - d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); - d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MULTIPLYADD); - d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_SPECULAR); - d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - } - - else if (texture_1 && strategy == DX9_STRATEGY_EMISSIVE) { - d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); - - d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); - d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD); - d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - } - - else if (texture_1 && strategy == DX9_STRATEGY_SPEC_EMISSIVE) { - d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); - - d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); - d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD); - d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); - d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - } - - else if (strategy < DX9_STRATEGY_BLEND) { - d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - } - } - - else if (pass == 1) { - D3DMATERIAL9 d3dmtl; - IDirect3DTexture9* texture = 0; - Bitmap* tex_bmp = 0; - ColorValue orig_Ka = segment_material->Ka; - ColorValue orig_Kd = segment_material->Kd; - HRESULT hr = E_FAIL; - - if (segment_material->tex_specular) { - segment_material->Ka = Color::Black; - segment_material->Kd = Color::Black; - } - - CreateD3DMaterial(d3dmtl, *segment_material); - - segment_material->Ka = orig_Ka; - segment_material->Kd = orig_Kd; - - hr = d3ddevice->SetMaterial(&d3dmtl); - - if (strategy == DX9_STRATEGY_SPECMAP || - strategy == DX9_STRATEGY_SPEC_EMISSIVE) { - tex_bmp = segment_material->tex_specular; - d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_SPECULAR); - } - - else if (strategy == DX9_STRATEGY_EMISSIVE) { - tex_bmp = segment_material->tex_emissive; - d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - } - - d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - if (texcache && tex_bmp) { - texture = texcache->FindTexture(tex_bmp); - hr = d3ddevice->SetTexture(0, texture); - current_texture = texture; - - SetBlendType(BLEND_ADDITIVE); - } - } - - if (render_state[STENCIL_ENABLE]) { - d3ddevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); - d3ddevice->SetRenderState(D3DRS_STENCILREF, 0x01); - d3ddevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATER); - } - else { - d3ddevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - } - - if (render_state[LIGHTING_PASS] > 0) { - SetBlendType(BLEND_ADDITIVE); - SetRenderState(Z_WRITE_ENABLE, FALSE); - } - - return true; -} - - -// +--------------------------------------------------------------------+ - -void -VideoDX9Error(const char* msg, HRESULT err) -{ - Print(" VideoDX9: %s. [%s]\n", msg, D3DErrStr(err)); -} - -char* D3DErrStr(HRESULT hr) -{ - static char errstrbuf[128]; - - switch (hr) { - default: - sprintf_s(errstrbuf, "Unrecognized error value = %08x.", hr); - return errstrbuf; - - case D3D_OK: - return "No error."; - - case D3DERR_WRONGTEXTUREFORMAT: - return "Wrong texture format."; - - case D3DERR_UNSUPPORTEDCOLOROPERATION: - return "Unsupported color operation."; - - case D3DERR_UNSUPPORTEDCOLORARG: - return "Unsupported color argument."; - - case D3DERR_UNSUPPORTEDALPHAOPERATION: - return "Unsupported alpha operation."; - - case D3DERR_UNSUPPORTEDALPHAARG: - return "Unsupported alpha argument."; - - case D3DERR_TOOMANYOPERATIONS: - return "Too many operations."; - - case D3DERR_CONFLICTINGTEXTUREFILTER: - return "Conflicting texture filter."; - - case D3DERR_UNSUPPORTEDFACTORVALUE: - return "Unsupported factor value."; - - case D3DERR_CONFLICTINGRENDERSTATE: - return "Conflicting render state."; - - case D3DERR_UNSUPPORTEDTEXTUREFILTER: - return "Unsupported texture filter."; - - case D3DERR_CONFLICTINGTEXTUREPALETTE: - return "Conflicting texture palette."; - - case D3DERR_DRIVERINTERNALERROR: - return "Driver internal error."; - - - case D3DERR_NOTFOUND: - return "Resource was not found."; - - case D3DERR_MOREDATA: - return "More data?"; - - case D3DERR_DEVICELOST: - return "Device lost."; - - case D3DERR_DEVICENOTRESET: - return "Device is not reset."; - - case D3DERR_NOTAVAILABLE: - return "Not available."; - - case D3DERR_OUTOFVIDEOMEMORY: - return "Out of video memory."; - - case E_OUTOFMEMORY: - return "Out of system memory."; - - case D3DERR_INVALIDDEVICE: - return "Invalid device selection."; - - case D3DERR_INVALIDCALL: - return "Invalid call or parameter."; - - case D3DERR_DRIVERINVALIDCALL: - return "Driver invalid call."; - - case D3DERR_WASSTILLDRAWING: - return "The device was still drawing."; - - case D3DOK_NOAUTOGEN: - return "Autogeneration is not supported by this device."; - - } -} - diff --git a/Stars45/VideoDX9.h b/Stars45/VideoDX9.h deleted file mode 100644 index 9166495..0000000 --- a/Stars45/VideoDX9.h +++ /dev/null @@ -1,194 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Direct3D and Direct3D Video classes for DirectX 7 -*/ - -#ifndef VideoDX9_h -#define VideoDX9_h - -#include "Video.h" -#include "VideoSettings.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class VideoDX9; -class VideoDX9Enum; -class VideoDX9VertexBuffer; -class VideoDX9IndexBuffer; -struct VideoDX9ScreenVertex; -class Surface; -class Segment; - -struct VideoDX9ScreenVertex; -struct VideoDX9SolidVertex; -struct VideoDX9LuminousVertex; -struct VideoDX9LineVertex; - - -// +--------------------------------------------------------------------+ - -class VideoDX9 : public Video -{ -public: - VideoDX9(const HWND& window, VideoSettings* vs); - virtual ~VideoDX9(); - - virtual const VideoSettings* - GetVideoSettings() const { return &video_settings; } - virtual bool SetVideoSettings(const VideoSettings* vs); - - virtual bool SetBackgroundColor(Color c); - virtual bool SetGammaLevel(int g); - virtual bool SetObjTransform(const Matrix& o, const Point& l); - - virtual bool SetupParams(); - virtual bool Reset(const VideoSettings* vs); - - virtual bool StartFrame(); - virtual bool EndFrame(); - - virtual int Width() const { return width; } - virtual int Height() const { return height; } - virtual int Depth() const { return bpp; } - - virtual void RecoverSurfaces(); - - virtual bool ClearAll(); - virtual bool ClearDepthBuffer(); - virtual bool Present(); - virtual bool Pause(); - virtual bool Resume(); - - virtual IDirect3D9* Direct3D() const { return d3d; } - virtual IDirect3DDevice9* D3DDevice() const { return d3ddevice; } - static IDirect3DDevice9* GetD3DDevice9(); - - virtual bool IsModeSupported(int width, int height, int bpp) const; - virtual bool IsHardware() const { return true; } - virtual int ZDepth() const { return zdepth; } - virtual DWORD VidMemFree() const; - virtual int D3DLevel() const { return 9; } - virtual int MaxTexSize() const; - virtual int MaxTexAspect() const; - virtual int GammaLevel() const { return gamma; } - - virtual bool Capture(Bitmap& bmp); - virtual bool GetWindowRect(Rect& r); - virtual bool SetWindowRect(const Rect& r); - virtual bool SetViewport(int x, int y, int w, int h); - virtual bool SetCamera(const Camera* cam); - virtual bool SetEnvironment(Bitmap** faces); - virtual bool SetAmbient(Color c); - virtual bool SetLights(const List& lights); - virtual bool SetProjection(float fov, - float znear=1.0f, - float zfar=1.0e6f, - DWORD type=PROJECTION_PERSPECTIVE); - virtual bool SetRenderState(RENDER_STATE state, DWORD value); - virtual bool SetBlendType(int blend_type); - - virtual bool DrawPolys(int npolys, Poly* p); - virtual bool DrawScreenPolys(int npolys, Poly* p, int blend=0); - virtual bool DrawSolid(Solid* s, DWORD blend_modes=0xf); - virtual bool DrawShadow(Solid* s, int nverts, Vec3* verts, bool vis=false); - virtual bool DrawLines(int nlines, Vec3* v, Color c, int blend=0); - virtual bool DrawScreenLines(int nlines, float* v, Color c, int blend=0); - virtual bool DrawPoints(VertexSet* v); - virtual bool DrawPolyOutline(Poly* p); - virtual bool UseMaterial(Material* m); - - virtual bool UseXFont(const char* name, int size, bool b, bool i); - virtual bool DrawText(const char* text, int count, const Rect& rect, - DWORD format, Color c); - - virtual void PreloadTexture(Bitmap* bmp); - virtual void PreloadSurface(Surface* s); - virtual void InvalidateCache(); - - static void CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Point& p); - static void CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Vec3& v); - static void CreateD3DMaterial(D3DMATERIAL9& result, const Material& mtl); - -private: - bool CreateBuffers(); - bool DestroyBuffers(); - bool PopulateScreenVerts(VertexSet* vset); - bool PrepareSurface(Surface* s); - bool DrawSegment(Segment* s); - - int PrepareMaterial(Material* m); - bool SetupPass(int n); - - HWND hwnd; - int width; - int height; - int bpp; - int gamma; - int zdepth; - Color background; - - VideoDX9Enum* dx9enum; - VideoSettings video_settings; - - IDirect3D9* d3d; - IDirect3DDevice9* d3ddevice; - D3DPRESENT_PARAMETERS d3dparams; - D3DSURFACE_DESC back_buffer_desc; - bool device_lost; - - BYTE* surface; - - DWORD texture_format[3]; - D3DGAMMARAMP gamma_ramp; - double fade; - - Rect rect; - - IDirect3DVertexDeclaration9* vertex_declaration; - ID3DXEffect* magic_fx; - BYTE* magic_fx_code; - int magic_fx_code_len; - - IDirect3DTexture9* current_texture; - int current_blend_state; - int scene_active; - DWORD render_state[RENDER_STATE_MAX]; - Material* use_material; - - Material* segment_material; - int strategy; - int passes; - - ID3DXFont* d3dx_font; - char font_name[64]; - int font_size; - bool font_bold; - bool font_ital; - - Color ambient; - int nlights; - - int first_vert; - int num_verts; - - VideoDX9VertexBuffer* screen_vbuf; - VideoDX9IndexBuffer* screen_ibuf; - VideoDX9ScreenVertex* font_verts; - WORD* font_indices; - int font_nverts; - - VideoDX9ScreenVertex* screen_line_verts; - VideoDX9LineVertex* line_verts; -}; - -#endif // VideoDX9_h - diff --git a/Stars45/VideoDX9Enum.cpp b/Stars45/VideoDX9Enum.cpp deleted file mode 100644 index c254513..0000000 --- a/Stars45/VideoDX9Enum.cpp +++ /dev/null @@ -1,1063 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Direct3D Video class for DirectX 9 -*/ - -#include "VideoDX9Enum.h" -#include "VideoSettings.h" -#include "Color.h" -#include "Utils.h" - -// +--------------------------------------------------------------------+ - -char* DDErrStr(HRESULT dderr); -void VideoDX9Error(const char* msg, HRESULT dderr); -int VD3D_describe_things; - -#ifndef RELEASE -#define RELEASE(x) if (x) { x->Release(); x=NULL; } -#endif - - -// +--------------------------------------------------------------------+ - -static UINT GetBitsPerPixel(D3DFORMAT fmt) -{ - switch (fmt) { - case D3DFMT_A8R8G8B8: return 32; - case D3DFMT_X8R8G8B8: return 32; - case D3DFMT_A2B10G10R10: return 32; - case D3DFMT_A2R10G10B10: return 32; - case D3DFMT_R8G8B8: return 24; - case D3DFMT_R5G6B5: return 16; - case D3DFMT_X1R5G5B5: return 16; - case D3DFMT_A1R5G5B5: return 16; - case D3DFMT_A4R4G4B4: return 16; - case D3DFMT_A8R3G3B2: return 16; - case D3DFMT_X4R4G4B4: return 16; - case D3DFMT_R3G3B2: return 8; - default: return 0; - } -} - -// +--------------------------------------------------------------------+ - -static UINT GetColorChannelBits(D3DFORMAT fmt) -{ - switch (fmt) { - case D3DFMT_A2B10G10R10: return 10; - case D3DFMT_A2R10G10B10: return 10; - case D3DFMT_R8G8B8: return 8; - case D3DFMT_A8R8G8B8: return 8; - case D3DFMT_X8R8G8B8: return 8; - case D3DFMT_R5G6B5: return 6; - case D3DFMT_X1R5G5B5: return 5; - case D3DFMT_A1R5G5B5: return 5; - case D3DFMT_A4R4G4B4: return 4; - case D3DFMT_R3G3B2: return 2; - case D3DFMT_A8R3G3B2: return 2; - case D3DFMT_X4R4G4B4: return 4; - default: return 0; - } -} - -// +--------------------------------------------------------------------+ - -static UINT GetAlphaChannelBits(D3DFORMAT fmt) -{ - switch (fmt) { - case D3DFMT_R8G8B8: return 0; - case D3DFMT_A8R8G8B8: return 8; - case D3DFMT_X8R8G8B8: return 0; - case D3DFMT_R5G6B5: return 0; - case D3DFMT_X1R5G5B5: return 0; - case D3DFMT_A1R5G5B5: return 1; - case D3DFMT_A4R4G4B4: return 4; - case D3DFMT_R3G3B2: return 0; - case D3DFMT_A8R3G3B2: return 8; - case D3DFMT_X4R4G4B4: return 0; - case D3DFMT_A2B10G10R10: return 2; - case D3DFMT_A2R10G10B10: return 2; - default: return 0; - } -} - -// +--------------------------------------------------------------------+ - -static UINT GetDepthBits(D3DFORMAT fmt) -{ - switch (fmt) { - case D3DFMT_D16: return 16; - case D3DFMT_D15S1: return 15; - case D3DFMT_D24X8: return 24; - case D3DFMT_D24S8: return 24; - case D3DFMT_D24X4S4: return 24; - case D3DFMT_D32: return 32; - default: return 0; - } -} - -// +--------------------------------------------------------------------+ - -static UINT GetStencilBits(D3DFORMAT fmt) -{ - switch (fmt) { - case D3DFMT_D16: return 0; - case D3DFMT_D15S1: return 1; - case D3DFMT_D24X8: return 0; - case D3DFMT_D24S8: return 8; - case D3DFMT_D24X4S4: return 4; - case D3DFMT_D32: return 0; - default: return 0; - } -} - -// +--------------------------------------------------------------------+ -// -// This routine prints a text description of the indicated driver -// into the error log file. - -static void DescribeGUID(GUID* lpGUID) -{ - if (lpGUID) - Print(" GUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", - lpGUID->Data1, lpGUID->Data2, lpGUID->Data3, - lpGUID->Data4[0], lpGUID->Data4[1], - lpGUID->Data4[2], lpGUID->Data4[3], - lpGUID->Data4[4], lpGUID->Data4[5], - lpGUID->Data4[6], lpGUID->Data4[7]); - else - Print(" GUID IS NULL!\n"); -} - - -// +--------------------------------------------------------------------+ - -VideoDX9Enum::VideoDX9Enum(IDirect3D9* d3d9) -{ - if (d3d9) { - d3d = d3d9; - d3d->AddRef(); - } - - min_width = 640; - min_height = 480; - min_color_bits = 5; - min_alpha_bits = 0; - min_depth_bits = 16; - min_stencil_bits = 0; - - uses_depth_buffer = false; - uses_mixed_vp = false; - req_windowed = false; - req_fullscreen = false; - - adapter_index = 0; -} - -VideoDX9Enum::~VideoDX9Enum() -{ - adapter_info_list.destroy(); - RELEASE(d3d); -} - -void -VideoDX9Enum::SetDirect3D9(IDirect3D9* d3d9) -{ - RELEASE(d3d); - - if (d3d9) { - d3d = d3d9; - d3d->AddRef(); - } -} - - -// +--------------------------------------------------------------------+ - -void -VideoDX9Enum::SelectAdapter(int index) -{ - if (index >= 0 && index < adapter_info_list.size()) - adapter_index = index; -} - -VideoDX9AdapterInfo* -VideoDX9Enum::GetAdapterInfo() -{ - if (adapter_index >= 0 && adapter_index < adapter_info_list.size()) - return adapter_info_list[adapter_index]; - - return 0; -} - -VideoDX9DeviceInfo* -VideoDX9Enum::GetDeviceInfo(DWORD devtype) -{ - if (adapter_index >= 0 && adapter_index < adapter_info_list.size()) { - VideoDX9AdapterInfo* adapter = adapter_info_list[adapter_index]; - - if (adapter) { - ListIter iter = adapter->device_info_list; - while (++iter) { - VideoDX9DeviceInfo* dev_info = iter.value(); - - if (dev_info->device_type == (D3DDEVTYPE) devtype) - return dev_info; - } - } - } - - return 0; -} - -bool -VideoDX9Enum::IsModeSupported(int w, int h, int b) const -{ - if (adapter_index >= 0 && adapter_index < adapter_info_list.size()) { - VideoDX9AdapterInfo* adapter = adapter_info_list[adapter_index]; - - ListIter mode_iter = adapter->display_mode_list; - while (++mode_iter) { - VideoDX9DisplayMode* mode = mode_iter.value(); - - if (mode->width == (UINT) w && - mode->height == (UINT) h && - GetBitsPerPixel(mode->format) == (UINT) b) { - - return true; - } - } - } - - return false; -} - -// +--------------------------------------------------------------------+ - -HRESULT -VideoDX9Enum::Enumerate() -{ - HRESULT hr = E_FAIL; - - if (!d3d) - return hr; - - if (VD3D_describe_things > 0) { - Print("Video DX9 Enumerate Adapters and Devices\n"); - Print("----------------------------------------\n\n"); - } - - allowed_adapter_format_list.push_back(D3DFMT_X8R8G8B8); - allowed_adapter_format_list.push_back(D3DFMT_X1R5G5B5); - allowed_adapter_format_list.push_back(D3DFMT_R5G6B5); - allowed_adapter_format_list.push_back(D3DFMT_A2R10G10B10); - - VideoDX9AdapterInfo* adapter_info = 0; - std::vector adapter_format_list; - UINT num_adapters = d3d->GetAdapterCount(); - - for (UINT ordinal = 0; ordinal < num_adapters; ordinal++) { - adapter_info = new VideoDX9AdapterInfo; - if (!adapter_info) - return E_OUTOFMEMORY; - - adapter_info->adapter_ordinal = ordinal; - d3d->GetAdapterIdentifier(ordinal, 0, &adapter_info->adapter_identifier); - - // Get list of all display modes on this adapter. - // Also build a temporary list of all display adapter formats. - adapter_format_list.clear(); - - for (size_t iaaf = 0; iaaf < allowed_adapter_format_list.size(); iaaf++) { - D3DFORMAT allowed_adapter_format = allowed_adapter_format_list[iaaf]; - UINT num_adapter_modes = d3d->GetAdapterModeCount(ordinal, allowed_adapter_format); - - for (UINT mode = 0; mode < num_adapter_modes; mode++) { - D3DDISPLAYMODE display_mode; - d3d->EnumAdapterModes(ordinal, allowed_adapter_format, mode, &display_mode); - - if (display_mode.Width < min_width || - display_mode.Height < min_height || - GetColorChannelBits(display_mode.Format) < min_color_bits) { - continue; - } - - VideoDX9DisplayMode* dx9_display_mode = new VideoDX9DisplayMode(display_mode); - - if (!dx9_display_mode) { - delete adapter_info; - return E_OUTOFMEMORY; - } - - adapter_info->display_mode_list.append(dx9_display_mode); - - bool contains_display_mode = false; - for (auto afli = adapter_format_list.begin(); afli != adapter_format_list.end(); ++afli) { - if (*afli == display_mode.Format) { - contains_display_mode = true; - break; - } - } - if (!contains_display_mode) - adapter_format_list.push_back(display_mode.Format); - - } - } - - // Sort displaymode list - adapter_info->display_mode_list.sort(); - - if (VD3D_describe_things > 0) { - Print("Adapter %d. %s\n", ordinal, adapter_info->adapter_identifier.Description); - DescribeGUID(&adapter_info->adapter_identifier.DeviceIdentifier); - - if (VD3D_describe_things > 4) { - ListIter m_iter = adapter_info->display_mode_list; - while (++m_iter) { - VideoDX9DisplayMode* m = m_iter.value(); - - Print(" Mode %3d %s\n", m_iter.index(), m->GetDescription()); - } - - Print("\n"); - } - } - - // Get info for each device on this adapter - if (FAILED(hr = EnumerateDevices(adapter_info, adapter_format_list))) { - delete adapter_info; - return hr; - } - - // If at least one device on this adapter is available and compatible - // with the app, add the adapterInfo to the list - if (adapter_info->device_info_list.size() == 0) - delete adapter_info; - else - adapter_info_list.append(adapter_info); - - if (VD3D_describe_things > 0) { - Print("\n"); - } - } - - return S_OK; -} - -// +--------------------------------------------------------------------+ - -HRESULT -VideoDX9Enum::EnumerateDevices(VideoDX9AdapterInfo* adapter_info, std::vector& adapter_format_list) -{ - HRESULT hr = E_FAIL; - const D3DDEVTYPE dtypes[3] = { D3DDEVTYPE_HAL, D3DDEVTYPE_SW, D3DDEVTYPE_REF }; - const char* dtypestr[3] = { "D3DDEVTYPE_HAL", "D3DDEVTYPE_SW", "D3DDEVTYPE_REF" }; - VideoDX9DeviceInfo* device_info = 0; - - for (int i = 0; i < 3; i++ ) { - device_info = new VideoDX9DeviceInfo; - if (!device_info) - return E_OUTOFMEMORY; - - device_info->adapter_ordinal = adapter_info->adapter_ordinal; - device_info->device_type = dtypes[i]; - - if (FAILED(d3d->GetDeviceCaps(adapter_info->adapter_ordinal, - device_info->device_type, - &device_info->caps))) { - delete device_info; - continue; - } - - if (VD3D_describe_things > 1) { - Print(" Device %d - %s\n", i, dtypestr[i]); - Print(" Max Texture Width: %d\n", device_info->caps.MaxTextureWidth); - Print(" Max Texture Height: %d\n", device_info->caps.MaxTextureHeight); - } - - // Get info for each device combo on this device - if (FAILED(hr = EnumerateDeviceCombos(device_info, adapter_format_list))) { - delete device_info; - return hr; - } - - // make sure at least one devicecombo for this device was found - if (device_info->device_combo_list.size() < 1) { - delete device_info; - continue; - } - - adapter_info->device_info_list.append(device_info); - } - - return S_OK; -} - -// +--------------------------------------------------------------------+ - -HRESULT -VideoDX9Enum::EnumerateDeviceCombos(VideoDX9DeviceInfo* device_info, std::vector& adapter_format_list) -{ - const D3DFORMAT back_buffer_formats[] = { - D3DFMT_A8R8G8B8, - D3DFMT_X8R8G8B8, - D3DFMT_R8G8B8, - D3DFMT_R5G6B5, - D3DFMT_A1R5G5B5, - D3DFMT_X1R5G5B5 - }; - - bool is_windowed[] = { false, true }; - - // See which adapter formats are supported by this device - D3DFORMAT a_fmt; - for (size_t i = 0; i < adapter_format_list.size(); i++) { - a_fmt = adapter_format_list[i]; - - D3DFORMAT b_fmt; - for (int n = 0; n < 6; n++) { - b_fmt = back_buffer_formats[n]; - - if (GetAlphaChannelBits(b_fmt) < min_alpha_bits) - continue; - - bool win; - for (int w = 0; w < 2; w++) { - win = is_windowed[w]; - - if (!win && req_windowed) - continue; - - if (win && req_fullscreen) - continue; - - if (FAILED(d3d->CheckDeviceType(device_info->adapter_ordinal, - device_info->device_type, - a_fmt, - b_fmt, - win))) { - continue; - } - - // At this point, we have an adapter/device/adapterformat/backbufferformat/iswindowed - // DeviceCombo that is supported by the system. We still need to confirm that it's - // compatible with the app, and find one or more suitable depth/stencil buffer format, - // multisample type, vertex processing type, and present interval. - - VideoDX9DeviceCombo* device_combo = 0; - device_combo = new VideoDX9DeviceCombo; - if (!device_combo) - return E_OUTOFMEMORY; - - device_combo->adapter_ordinal = device_info->adapter_ordinal; - device_combo->device_type = device_info->device_type; - device_combo->adapter_format = a_fmt; - device_combo->back_buffer_format = b_fmt; - device_combo->is_windowed = win; - - if (uses_depth_buffer) { - BuildDepthStencilFormatList(device_combo); - if (device_combo->depth_stencil_fmt_list.size() < 1) { - delete device_combo; - continue; - } - } - - BuildMultiSampleTypeList(device_combo); - if (device_combo->multisample_type_list.size() < 1) { - delete device_combo; - continue; - } - - BuildDSMSConflictList(device_combo); - - BuildVertexProcessingTypeList(device_info, device_combo); - if (device_combo->vertex_processing_list.size() < 1) { - delete device_combo; - continue; - } - - BuildPresentIntervalList(device_info, device_combo); - - device_info->device_combo_list.append(device_combo); - } - } - } - - return S_OK; -} - -void -VideoDX9Enum::BuildDepthStencilFormatList(VideoDX9DeviceCombo* device_combo) -{ - const D3DFORMAT depth_stencil_formats[] = { - D3DFMT_D32, - D3DFMT_D24S8, - D3DFMT_D24X4S4, - D3DFMT_D24X8, - D3DFMT_D16, - D3DFMT_D15S1, - }; - - for (int i = 0; i < 6; i++) { - D3DFORMAT fmt = depth_stencil_formats[i]; - - if (GetDepthBits(fmt) < min_depth_bits) - continue; - - if (GetStencilBits(fmt) < min_stencil_bits) - continue; - - if (SUCCEEDED(d3d->CheckDeviceFormat(device_combo->adapter_ordinal, - device_combo->device_type, - device_combo->adapter_format, - D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, - fmt))) { - - if (SUCCEEDED(d3d->CheckDepthStencilMatch(device_combo->adapter_ordinal, - device_combo->device_type, - device_combo->adapter_format, - device_combo->back_buffer_format, - fmt))) { - - device_combo->depth_stencil_fmt_list.push_back(fmt); - } - } - } -} - -void -VideoDX9Enum::BuildMultiSampleTypeList(VideoDX9DeviceCombo* device_combo) -{ - const D3DMULTISAMPLE_TYPE multisample_type_array[] = { - D3DMULTISAMPLE_NONE, - D3DMULTISAMPLE_NONMASKABLE, - D3DMULTISAMPLE_2_SAMPLES, - D3DMULTISAMPLE_3_SAMPLES, - D3DMULTISAMPLE_4_SAMPLES, - D3DMULTISAMPLE_5_SAMPLES, - D3DMULTISAMPLE_6_SAMPLES, - D3DMULTISAMPLE_7_SAMPLES, - D3DMULTISAMPLE_8_SAMPLES, - D3DMULTISAMPLE_9_SAMPLES, - D3DMULTISAMPLE_10_SAMPLES, - D3DMULTISAMPLE_11_SAMPLES, - D3DMULTISAMPLE_12_SAMPLES, - D3DMULTISAMPLE_13_SAMPLES, - D3DMULTISAMPLE_14_SAMPLES, - D3DMULTISAMPLE_15_SAMPLES, - D3DMULTISAMPLE_16_SAMPLES, - }; - - for (int i = 0; i < 17; i++) { - D3DMULTISAMPLE_TYPE multisample_type = multisample_type_array[i]; - DWORD multisample_qual = 0; - - if (SUCCEEDED(d3d->CheckDeviceMultiSampleType(device_combo->adapter_ordinal, - device_combo->device_type, - device_combo->back_buffer_format, - device_combo->is_windowed, - multisample_type, - &multisample_qual))) { - - device_combo->multisample_type_list.push_back(multisample_type); - device_combo->multisample_qual_list.push_back(multisample_qual); - } - } -} - -void -VideoDX9Enum::BuildDSMSConflictList(VideoDX9DeviceCombo* device_combo) -{ - for (size_t i = 0; i < device_combo->depth_stencil_fmt_list.size(); i++) { - D3DFORMAT depth_format = (D3DFORMAT) device_combo->depth_stencil_fmt_list[i]; - - for (size_t n = 0; n < device_combo->multisample_type_list.size(); n++) { - D3DMULTISAMPLE_TYPE multisample_type = (D3DMULTISAMPLE_TYPE) device_combo->multisample_type_list[n]; - - if (FAILED(d3d->CheckDeviceMultiSampleType(device_combo->adapter_ordinal, - device_combo->device_type, - depth_format, - device_combo->is_windowed, - multisample_type, - NULL))) { - - VideoDX9FormatConflict* conflict = new VideoDX9FormatConflict; - - conflict->ds_format = depth_format; - conflict->multisample_type = multisample_type; - - device_combo->conflict_list.append(conflict); - } - } - } -} - -void -VideoDX9Enum::BuildVertexProcessingTypeList(VideoDX9DeviceInfo* device_info, VideoDX9DeviceCombo* device_combo) -{ - if ((device_info->caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0) { - if ((device_info->caps.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0) { - device_combo->vertex_processing_list.push_back(PURE_HARDWARE_VP); - } - - device_combo->vertex_processing_list.push_back(HARDWARE_VP); - - if (uses_mixed_vp) { - device_combo->vertex_processing_list.push_back(MIXED_VP); - } - } - - device_combo->vertex_processing_list.push_back(SOFTWARE_VP); -} - -void -VideoDX9Enum::BuildPresentIntervalList(VideoDX9DeviceInfo* device_info, VideoDX9DeviceCombo* device_combo) -{ - const DWORD present_interval_array[] = { - D3DPRESENT_INTERVAL_IMMEDIATE, - D3DPRESENT_INTERVAL_DEFAULT, - D3DPRESENT_INTERVAL_ONE, - D3DPRESENT_INTERVAL_TWO, - D3DPRESENT_INTERVAL_THREE, - D3DPRESENT_INTERVAL_FOUR, - }; - - for (int i = 0; i < 6; i++) { - DWORD interval = present_interval_array[i]; - - if (device_combo->is_windowed && i > 2) { - // none of the remaining intervals are supported in windowed mode. - break; - } - - // Note that D3DPRESENT_INTERVAL_DEFAULT is zero, so you - // can't do a caps check for it -- it is always available. - - if (interval == D3DPRESENT_INTERVAL_DEFAULT || - (device_info->caps.PresentationIntervals & interval)) { - - device_combo->present_interval_list.push_back(interval); - } - } -} - -bool -VideoDX9Enum::SuggestWindowSettings(VideoSettings* vs) -{ - if (!vs) - return false; - - // Get display mode of primary adapter (which is assumed to be where the window - // will appear) - D3DDISPLAYMODE desktop_display_mode; - d3d->GetAdapterDisplayMode(0, &desktop_display_mode); - - VideoDX9AdapterInfo* best_adapter_info = 0; - VideoDX9DeviceInfo* best_device_info = 0; - VideoDX9DeviceCombo* best_device_combo = 0; - int best_adapter_index = 0; - int best_device_index = 0; - - ListIter a_iter = adapter_info_list; - while (++a_iter) { - VideoDX9AdapterInfo* adapter_info = a_iter.value(); - - ListIter d_iter = adapter_info->device_info_list; - while (++d_iter) { - VideoDX9DeviceInfo* device_info = d_iter.value(); - - ListIter c_iter = device_info->device_combo_list; - while (++c_iter) { - VideoDX9DeviceCombo* device_combo = c_iter.value(); - - bool formats_match = (device_combo->back_buffer_format == device_combo->adapter_format); - - if (!device_combo->is_windowed) - continue; - - if (device_combo->adapter_format != desktop_display_mode.Format) - continue; - - // If we haven't found a compatible DeviceCombo yet, or if this set - // is better (because it's a HAL, and/or because formats match better), - // save it - if (best_device_combo == NULL || - best_device_combo->device_type != D3DDEVTYPE_HAL && device_combo->device_type == D3DDEVTYPE_HAL || - device_combo->device_type == D3DDEVTYPE_HAL && formats_match) { - - best_adapter_info = adapter_info; - best_adapter_index = a_iter.index(); - best_device_info = device_info; - best_device_index = d_iter.index(); - best_device_combo = device_combo; - - if (device_combo->device_type == D3DDEVTYPE_HAL && formats_match) { - // This windowed device combo looks great -- take it - goto EndWindowedDeviceComboSearch; - } - - // Otherwise keep looking for a better windowed device combo - } - } - } - } - -EndWindowedDeviceComboSearch: - if (best_device_combo == NULL) - return false; - - VideoDeviceInfo* win_device = &vs->windowed_device; - - vs->is_windowed = true; - vs->windowed_mode.width = desktop_display_mode.Width; - vs->windowed_mode.height = desktop_display_mode.Height; - vs->windowed_mode.refresh = desktop_display_mode.RefreshRate; - vs->windowed_mode.format = desktop_display_mode.Format; - - win_device->adapter_index = best_adapter_index; - win_device->device_index = best_device_index; - win_device->device_type = best_device_info->device_type; - win_device->back_buffer_format = best_device_combo->back_buffer_format; - win_device->depth_buffer_bits = GetDepthBits((D3DFORMAT) best_device_combo->depth_stencil_fmt_list[0]); - win_device->depth_stencil_format = best_device_combo->depth_stencil_fmt_list[0]; - win_device->multisample_type = best_device_combo->multisample_type_list[0]; - win_device->multisample_qual = best_device_combo->multisample_qual_list[0]; - win_device->vertex_processing = best_device_combo->vertex_processing_list[0]; - - return true; -} - -bool -VideoDX9Enum::SuggestFullscreenSettings(VideoSettings* vs) -{ - if (!vs) - return false; - - WORD desired_width = vs->fullscreen_mode.width; - WORD desired_height = vs->fullscreen_mode.height; - - // For fullscreen, default to first HAL DeviceCombo that supports the current desktop - // display mode, or any display mode if HAL is not compatible with the desktop mode, or - // non-HAL if no HAL is available - D3DDISPLAYMODE desktop_display_mode; - D3DDISPLAYMODE best_desktop_display_mode; - - best_desktop_display_mode.Width = 0; - best_desktop_display_mode.Height = 0; - best_desktop_display_mode.Format = D3DFMT_UNKNOWN; - best_desktop_display_mode.RefreshRate = 0; - - VideoDX9AdapterInfo* best_adapter_info = 0; - VideoDX9DeviceInfo* best_device_info = 0; - VideoDX9DeviceCombo* best_device_combo = 0; - int best_adapter_index = 0; - int best_device_index = 0; - - ListIter a_iter = adapter_info_list; - while (++a_iter) { - VideoDX9AdapterInfo* adapter_info = a_iter.value(); - d3d->GetAdapterDisplayMode(adapter_info->adapter_ordinal, &desktop_display_mode); - - ListIter d_iter = adapter_info->device_info_list; - while (++d_iter) { - VideoDX9DeviceInfo* device_info = d_iter.value(); - - ListIter c_iter = device_info->device_combo_list; - while (++c_iter) { - VideoDX9DeviceCombo* device_combo = c_iter.value(); - - bool bAdapterMatchesBB = (device_combo->back_buffer_format == device_combo->adapter_format); - bool bAdapterMatchesDesktop = (device_combo->adapter_format == desktop_display_mode.Format); - - if (device_combo->is_windowed) - continue; - - // If we haven't found a compatible set yet, or if this set - // is better (because it's a HAL, and/or because formats match better), - // save it - if (best_device_combo == NULL || - best_device_combo->device_type != D3DDEVTYPE_HAL && device_info->device_type == D3DDEVTYPE_HAL || - device_combo->device_type == D3DDEVTYPE_HAL && best_device_combo->adapter_format != desktop_display_mode.Format && bAdapterMatchesDesktop || - device_combo->device_type == D3DDEVTYPE_HAL && bAdapterMatchesDesktop && bAdapterMatchesBB ) { - - best_desktop_display_mode = desktop_display_mode; - best_adapter_info = adapter_info; - best_device_info = device_info; - best_device_combo = device_combo; - - if (device_info->device_type == D3DDEVTYPE_HAL && bAdapterMatchesDesktop && bAdapterMatchesBB) { - // This fullscreen device combo looks great -- take it - goto EndFullscreenDeviceComboSearch; - } - - // Otherwise keep looking for a better fullscreen device combo - } - } - } - } - -EndFullscreenDeviceComboSearch: - if (best_device_combo == NULL) - return false; - - // Need to find a display mode on the best adapter that uses best_device_combo->adapter_format - // and is as close to best_desktop_display_mode's res as possible - VideoDX9DisplayMode best_display_mode; - - ListIter m_iter = best_adapter_info->display_mode_list; - while (++m_iter) { - VideoDX9DisplayMode* display_mode = m_iter.value(); - - if (display_mode->format != best_device_combo->adapter_format) - continue; - - if (display_mode->width == desired_width && //best_desktop_display_mode.Width && - display_mode->height == desired_height && //best_desktop_display_mode.Height && - display_mode->refresh == best_desktop_display_mode.RefreshRate) { - - // found a perfect match, so stop - best_display_mode = *display_mode; - break; - } - else if (display_mode->width == desired_width && //best_desktop_display_mode.Width && - display_mode->height == desired_height && //best_desktop_display_mode.Height && - display_mode->refresh > best_desktop_display_mode.RefreshRate) { - // refresh rate doesn't match, but width/height match, so keep this - // and keep looking - best_display_mode = *display_mode; - } - else if (display_mode->width == desired_width) { //best_desktop_display_mode.Width) { - // width matches, so keep this and keep looking - best_display_mode = *display_mode; - } - else if (best_display_mode.width == 0) - { - // we don't have anything better yet, so keep this and keep looking - best_display_mode = *display_mode; - } - } - - VideoDeviceInfo* fs_device = &vs->fullscreen_device; - - vs->is_windowed = false; - vs->fullscreen_mode.width = best_display_mode.width; - vs->fullscreen_mode.height = best_display_mode.height; - vs->fullscreen_mode.refresh = best_display_mode.refresh; - vs->fullscreen_mode.format = best_display_mode.format; - - fs_device->adapter_index = best_adapter_index; - fs_device->device_index = best_device_index; - fs_device->device_type = best_device_info->device_type; - fs_device->back_buffer_format = best_device_combo->back_buffer_format; - fs_device->depth_buffer_bits = GetDepthBits((D3DFORMAT) best_device_combo->depth_stencil_fmt_list[0]); - fs_device->depth_stencil_format = best_device_combo->depth_stencil_fmt_list[0]; - fs_device->multisample_type = best_device_combo->multisample_type_list[0]; - fs_device->multisample_qual = best_device_combo->multisample_qual_list[0]; - fs_device->vertex_processing = best_device_combo->vertex_processing_list[0]; - - return true; -} - - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -VideoDX9DisplayMode::VideoDX9DisplayMode() -: width(0), height(0), refresh(0), format(D3DFMT_UNKNOWN) -{ } - -VideoDX9DisplayMode::VideoDX9DisplayMode(const VideoDX9DisplayMode& m) -: width(m.width), height(m.height), refresh(m.refresh), format(m.format) -{ } - -VideoDX9DisplayMode::VideoDX9DisplayMode(const D3DDISPLAYMODE& m) -: width(m.Width), height(m.Height), refresh(m.RefreshRate), format(m.Format) -{ } - -int -VideoDX9DisplayMode::operator<(const VideoDX9DisplayMode& m) const -{ - if (width < m.width) - return 1; - - if (width > m.width) - return 0; - - if (height < m.height) - return 1; - - if (height > m.height) - return 0; - - if (format < m.format) - return 1; - - if (format > m.format) - return 0; - - if (refresh < m.refresh) - return 1; - - return 0; -} - -int -VideoDX9DisplayMode::operator<=(const VideoDX9DisplayMode& m) const -{ - // if less than ... - if (*this < m) - return 1; - - // ... or equal to ... - if (width == m.width && - height == m.height && - format == m.format && - refresh == m.refresh) - return 1; - - // must be greater than - return 0; -} - -const char* -VideoDX9DisplayMode::GetDescription() const -{ - static char desc[32]; - - sprintf_s(desc, "%4d x %4d %-12s %d Hz", //-V576 - width, - height, - D3DFormatToString(format), - refresh); - - return desc; -} - -const char* -VideoDX9DisplayMode::D3DFormatToString(D3DFORMAT format) -{ - const char* str = "Unknown Format"; - - switch (format) { - case D3DFMT_UNKNOWN: str = "UNKNOWN"; break; - case D3DFMT_R8G8B8: str = "R8G8B8"; break; - case D3DFMT_A8R8G8B8: str = "A8R8G8B8"; break; - case D3DFMT_X8R8G8B8: str = "X8R8G8B8"; break; - case D3DFMT_R5G6B5: str = "R5G6B5"; break; - case D3DFMT_X1R5G5B5: str = "X1R5G5B5"; break; - case D3DFMT_A1R5G5B5: str = "A1R5G5B5"; break; - case D3DFMT_A4R4G4B4: str = "A4R4G4B4"; break; - case D3DFMT_R3G3B2: str = "R3G3B2"; break; - case D3DFMT_A8: str = "A8"; break; - case D3DFMT_A8R3G3B2: str = "A8R3G3B2"; break; - case D3DFMT_X4R4G4B4: str = "X4R4G4B4"; break; - case D3DFMT_A2B10G10R10: str = "A2B10G10R10"; break; - case D3DFMT_A8B8G8R8: str = "A8B8G8R8"; break; - case D3DFMT_X8B8G8R8: str = "X8B8G8R8"; break; - case D3DFMT_G16R16: str = "G16R16"; break; - case D3DFMT_A2R10G10B10: str = "A2R10G10B10"; break; - case D3DFMT_A16B16G16R16: str = "A16B16G16R16"; break; - case D3DFMT_A8P8: str = "A8P8"; break; - case D3DFMT_P8: str = "P8"; break; - case D3DFMT_L8: str = "L8"; break; - case D3DFMT_A8L8: str = "A8L8"; break; - case D3DFMT_A4L4: str = "A4L4"; break; - case D3DFMT_V8U8: str = "V8U8"; break; - case D3DFMT_L6V5U5: str = "L6V5U5"; break; - case D3DFMT_X8L8V8U8: str = "X8L8V8U8"; break; - case D3DFMT_Q8W8V8U8: str = "Q8W8V8U8"; break; - case D3DFMT_V16U16: str = "V16U16"; break; - case D3DFMT_A2W10V10U10: str = "A2W10V10U10"; break; - case D3DFMT_UYVY: str = "UYVY"; break; - case D3DFMT_YUY2: str = "YUY2"; break; - case D3DFMT_DXT1: str = "DXT1"; break; - case D3DFMT_DXT2: str = "DXT2"; break; - case D3DFMT_DXT3: str = "DXT3"; break; - case D3DFMT_DXT4: str = "DXT4"; break; - case D3DFMT_DXT5: str = "DXT5"; break; - case D3DFMT_D16_LOCKABLE: str = "D16_LOCKABLE"; break; - case D3DFMT_D32: str = "D32"; break; - case D3DFMT_D15S1: str = "D15S1"; break; - case D3DFMT_D24S8: str = "D24S8"; break; - case D3DFMT_D24X8: str = "D24X8"; break; - case D3DFMT_D24X4S4: str = "D24X4S4"; break; - case D3DFMT_D16: str = "D16"; break; - case D3DFMT_L16: str = "L16"; break; - case D3DFMT_VERTEXDATA: str = "VERTEXDATA"; break; - case D3DFMT_INDEX16: str = "INDEX16"; break; - case D3DFMT_INDEX32: str = "INDEX32"; break; - case D3DFMT_Q16W16V16U16: str = "Q16W16V16U16"; break; - case D3DFMT_MULTI2_ARGB8: str = "MULTI2_ARGB8"; break; - case D3DFMT_R16F: str = "R16F"; break; - case D3DFMT_G16R16F: str = "G16R16F"; break; - case D3DFMT_A16B16G16R16F: str = "A16B16G16R16F"; break; - case D3DFMT_R32F: str = "R32F"; break; - case D3DFMT_G32R32F: str = "G32R32F"; break; - case D3DFMT_A32B32G32R32F: str = "A32B32G32R32F"; break; - case D3DFMT_CxV8U8: str = "CxV8U8"; break; - default: str = "Unknown format"; break; - } - - return str; -} - - -// +--------------------------------------------------------------------+ - -VideoDX9AdapterInfo::VideoDX9AdapterInfo() -: adapter_ordinal(0) -{ - ZeroMemory(&adapter_identifier, sizeof(adapter_identifier)); -} - -VideoDX9AdapterInfo::~VideoDX9AdapterInfo() -{ - display_mode_list.destroy(); - device_info_list.destroy(); -} - -const char* -VideoDX9AdapterInfo::GetDescription() const -{ - return adapter_identifier.Description; -} - -// +--------------------------------------------------------------------+ - -VideoDX9DeviceInfo::VideoDX9DeviceInfo() -: adapter_ordinal(0), device_type(D3DDEVTYPE_HAL) -{ - ZeroMemory(&caps, sizeof(caps)); -} - -VideoDX9DeviceInfo::~VideoDX9DeviceInfo() -{ - device_combo_list.destroy(); -} - -// +--------------------------------------------------------------------+ - -VideoDX9DeviceCombo::VideoDX9DeviceCombo() -: adapter_ordinal(0), device_type(D3DDEVTYPE_HAL), -adapter_format((D3DFORMAT) 0), -back_buffer_format((D3DFORMAT) 0), -is_windowed(false) -{ -} - -VideoDX9DeviceCombo::~VideoDX9DeviceCombo() -{ - conflict_list.destroy(); -} diff --git a/Stars45/VideoDX9Enum.h b/Stars45/VideoDX9Enum.h deleted file mode 100644 index 91279aa..0000000 --- a/Stars45/VideoDX9Enum.h +++ /dev/null @@ -1,184 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Direct3D and Direct3D Video classes for DirectX 7 -*/ - -#ifndef VideoDX9Enum_h -#define VideoDX9Enum_h - -#include - -#include "Video.h" -#include "List.h" -#include - -// +--------------------------------------------------------------------+ - -class VideoDX9Enum; -struct VideoDX9DisplayMode; -struct VideoDX9AdapterInfo; -struct VideoDX9DeviceInfo; -struct VideoDX9DSMSConflict; -struct VideoDX9DeviceCombo; -class VideoSettings; - -// +--------------------------------------------------------------------+ - -class VideoDX9Enum -{ -public: - enum VP_TYPE { - SOFTWARE_VP, - MIXED_VP, - HARDWARE_VP, - PURE_HARDWARE_VP - }; - - VideoDX9Enum(IDirect3D9* d3d9); - ~VideoDX9Enum(); - - void SetDirect3D9(IDirect3D9* d3d9); - - HRESULT Enumerate(); - bool SuggestWindowSettings(VideoSettings* vs); - bool SuggestFullscreenSettings(VideoSettings* vs); - - int NumAdapters() const { return adapter_info_list.size(); } - void SelectAdapter(int index); - VideoDX9AdapterInfo* GetAdapterInfo(); - VideoDX9DeviceInfo* GetDeviceInfo(DWORD devtype); - - bool IsModeSupported(int width, int height, int bpp) const; - - UINT min_width; - UINT min_height; - UINT min_color_bits; - UINT min_alpha_bits; - UINT min_depth_bits; - UINT min_stencil_bits; - - bool uses_depth_buffer; - bool uses_mixed_vp; - bool req_windowed; - bool req_fullscreen; - -private: - HRESULT EnumerateDevices(VideoDX9AdapterInfo* adapter_info, std::vector& adapter_format_list); - HRESULT EnumerateDeviceCombos(VideoDX9DeviceInfo* device_info, std::vector& adapter_format_list); - - void BuildDepthStencilFormatList(VideoDX9DeviceCombo* device_combo); - void BuildMultiSampleTypeList(VideoDX9DeviceCombo* device_combo); - void BuildDSMSConflictList(VideoDX9DeviceCombo* device_combo); - void BuildVertexProcessingTypeList(VideoDX9DeviceInfo* device_info, VideoDX9DeviceCombo* device_combo); - void BuildPresentIntervalList(VideoDX9DeviceInfo* device_info, VideoDX9DeviceCombo* device_combo); - - IDirect3D9* d3d; - std::vector allowed_adapter_format_list; - - List adapter_info_list; - int adapter_index; -}; - - -// +--------------------------------------------------------------------+ - -struct VideoDX9AdapterInfo -{ - static const char* TYPENAME() { return "VideoDX9AdapterInfo"; } - - VideoDX9AdapterInfo(); - ~VideoDX9AdapterInfo(); - - const char* GetDescription() const; - - int adapter_ordinal; - D3DADAPTER_IDENTIFIER9 adapter_identifier; - List display_mode_list; - List device_info_list; -}; - - -// +--------------------------------------------------------------------+ - -struct VideoDX9DisplayMode -{ - static const char* TYPENAME() { return "VideoDX9DisplayMode"; } - - VideoDX9DisplayMode(); - VideoDX9DisplayMode(const VideoDX9DisplayMode& m); - VideoDX9DisplayMode(const D3DDISPLAYMODE& m); - - int operator<(const VideoDX9DisplayMode& m) const; - int operator<=(const VideoDX9DisplayMode& m) const; - - const char* GetDescription() const; - static const char* D3DFormatToString(D3DFORMAT format); - - UINT width; - UINT height; - UINT refresh; - D3DFORMAT format; -}; - - -// +--------------------------------------------------------------------+ - -struct VideoDX9DeviceInfo -{ - static const char* TYPENAME() { return "VideoDX9DeviceInfo"; } - - VideoDX9DeviceInfo(); - ~VideoDX9DeviceInfo(); - - int adapter_ordinal; - D3DDEVTYPE device_type; - D3DCAPS9 caps; - List device_combo_list; -}; - - -// +--------------------------------------------------------------------+ - -struct VideoDX9FormatConflict -{ - static const char* TYPENAME() { return "VideoDX9FormatConflict"; } - - D3DFORMAT ds_format; - D3DMULTISAMPLE_TYPE multisample_type; -}; - - -// +--------------------------------------------------------------------+ - -struct VideoDX9DeviceCombo -{ - VideoDX9DeviceCombo(); - ~VideoDX9DeviceCombo(); - - int adapter_ordinal; - D3DDEVTYPE device_type; - D3DFORMAT adapter_format; - D3DFORMAT back_buffer_format; - bool is_windowed; - - std::vector vertex_processing_list; - std::vector depth_stencil_fmt_list; - std::vector multisample_type_list; - std::vector multisample_qual_list; - std::vector present_interval_list; - - List conflict_list; -}; - -// +--------------------------------------------------------------------+ - -#endif // VideoDX9Enum_h - diff --git a/Stars45/VideoDX9VertexBuffer.cpp b/Stars45/VideoDX9VertexBuffer.cpp deleted file mode 100644 index 6febba5..0000000 --- a/Stars45/VideoDX9VertexBuffer.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Direct3D Video class for DirectX 9 -*/ - -#include "VideoDX9VertexBuffer.h" -#include "Color.h" - -// +--------------------------------------------------------------------+ - -void VideoDX9Error(const char* msg, HRESULT dderr); -extern int VD3D_describe_things; - -#ifndef RELEASE -#define RELEASE(x) if (x) { x->Release(); x=NULL; } -#endif - -// +--------------------------------------------------------------------+ - -VideoDX9VertexBuffer::VideoDX9VertexBuffer(VideoDX9* dx9, -UINT nverts, -UINT vsize, -DWORD format, -DWORD usage) -: video(dx9), vertex_buffer(0), -num_verts(nverts), num_locked(0), vert_size(vsize), next_vert(0), -is_dynamic(false) -{ - UINT len = num_verts * vert_size; - - if (video && len) { - is_dynamic = (usage & D3DUSAGE_DYNAMIC) ? true : false; - D3DPOOL pool = is_dynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; - - HRESULT hr = video->D3DDevice()->CreateVertexBuffer(len, - usage, - format, - pool, - &vertex_buffer, - 0); - - if (FAILED(hr)) { - static int report = 10; - if (report) { - VideoDX9Error("Could not create vertex buffer.", hr); - report--; - } - - num_verts = 0; - vert_size = 0; - next_vert = 0; - } - } -} - -VideoDX9VertexBuffer::~VideoDX9VertexBuffer() -{ - RELEASE(vertex_buffer); -} - -// +--------------------------------------------------------------------+ - -BYTE* -VideoDX9VertexBuffer::Lock(UINT count) -{ - if (vertex_buffer && count <= num_verts) { - DWORD flags = 0; - - if (count == 0) - count = num_verts; - - if (is_dynamic) { - flags = D3DLOCK_NOOVERWRITE; - - if (next_vert + count > num_verts) { - next_vert = 0; - flags = D3DLOCK_DISCARD; - } - } - - void* result = 0; - HRESULT hr = 0; - - hr = vertex_buffer->Lock(next_vert * vert_size, - count * vert_size, - &result, - flags); - - if (SUCCEEDED(hr)) { - num_locked = count; - return (BYTE*) result; - } - } - - return 0; -} - -void -VideoDX9VertexBuffer::Unlock() -{ - if (vertex_buffer && num_locked > 0) { - vertex_buffer->Unlock(); - - next_vert += num_locked; - num_locked = 0; - } -} - -bool -VideoDX9VertexBuffer::Select(int stream) -{ - if (video && vertex_buffer) { - HRESULT hr = E_FAIL; - - if (num_locked > 0) - Unlock(); - - hr = video->D3DDevice()->SetStreamSource(stream, - vertex_buffer, - 0, - vert_size); - - if (SUCCEEDED(hr)) - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -UINT -VideoDX9VertexBuffer::GetNumVerts() const -{ - return num_verts; -} - -UINT -VideoDX9VertexBuffer::GetVertSize() const -{ - return vert_size; -} - -UINT -VideoDX9VertexBuffer::GetNextVert() const -{ - return next_vert; -} - - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - - -VideoDX9IndexBuffer::VideoDX9IndexBuffer(VideoDX9* dx9, -UINT nind, -DWORD usage) -: video(dx9), index_buffer(0), -num_indices(nind), num_locked(0), next_index(0), -is_dynamic(false) -{ - UINT len = num_indices * sizeof(WORD); - - if (video && len) { - is_dynamic = (usage & D3DUSAGE_DYNAMIC) ? true : false; - D3DPOOL pool = is_dynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; - - HRESULT hr = video->D3DDevice()->CreateIndexBuffer(len, - usage, - D3DFMT_INDEX16, - pool, - &index_buffer, - 0); - - if (FAILED(hr)) { - static int report = 10; - if (report) { - VideoDX9Error("Could not create index buffer.", hr); - report--; - } - - num_indices = 0; - next_index = 0; - } - } -} - -VideoDX9IndexBuffer::~VideoDX9IndexBuffer() -{ - RELEASE(index_buffer); -} - -// +--------------------------------------------------------------------+ - -WORD* -VideoDX9IndexBuffer::Lock(UINT count) -{ - if (index_buffer && count <= num_indices) { - DWORD flags = 0; - - if (count == 0) - count = num_indices; - - if (is_dynamic) { - flags = D3DLOCK_NOOVERWRITE; - - if (next_index + count > num_indices) { - next_index = 0; - flags = D3DLOCK_DISCARD; - } - } - - void* result = 0; - HRESULT hr = 0; - - hr = index_buffer->Lock(next_index * 2, - count * 2, - &result, - flags); - - if (SUCCEEDED(hr)) { - num_locked = count; - return (WORD*) result; - } - } - - return 0; -} - -void -VideoDX9IndexBuffer::Unlock() -{ - if (index_buffer && num_locked > 0) { - index_buffer->Unlock(); - - next_index += num_locked; - num_locked = 0; - } -} - -bool -VideoDX9IndexBuffer::Select() -{ - if (video && index_buffer) { - if (num_locked > 0) - Unlock(); - - HRESULT hr = video->D3DDevice()->SetIndices(index_buffer); - - if (SUCCEEDED(hr)) - return true; - } - - return false; -} - -// +--------------------------------------------------------------------+ - -UINT -VideoDX9IndexBuffer::GetNumIndices() const -{ - return num_indices; -} - -UINT -VideoDX9IndexBuffer::GetNextIndex() const -{ - return next_index; -} - diff --git a/Stars45/VideoDX9VertexBuffer.h b/Stars45/VideoDX9VertexBuffer.h deleted file mode 100644 index 035bb88..0000000 --- a/Stars45/VideoDX9VertexBuffer.h +++ /dev/null @@ -1,78 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Vertex and Index Buffer classes for DirectX 9 -*/ - -#ifndef VideoDX9VertexBuffer_h -#define VideoDX9VertexBuffer_h - -#include "VideoDX9.h" - -// +--------------------------------------------------------------------+ - -class VideoDX9VertexBuffer -{ -public: - VideoDX9VertexBuffer(VideoDX9* dx9, - UINT num_verts, - UINT vert_size, - DWORD format, - DWORD usage); - ~VideoDX9VertexBuffer(); - - BYTE* Lock(UINT count); - void Unlock(); - bool Select(int stream=0); - - UINT GetNumVerts() const; - UINT GetVertSize() const; - UINT GetNextVert() const; - -private: - VideoDX9* video; - IDirect3DVertexBuffer9* vertex_buffer; - - UINT num_verts; - UINT num_locked; - UINT vert_size; - UINT next_vert; - bool is_dynamic; -}; - -// +--------------------------------------------------------------------+ - -class VideoDX9IndexBuffer -{ -public: - VideoDX9IndexBuffer(VideoDX9* dx9, - UINT num_indices, - DWORD usage); - ~VideoDX9IndexBuffer(); - - WORD* Lock(UINT count); - void Unlock(); - bool Select(); - - UINT GetNumIndices() const; - UINT GetNextIndex() const; - -private: - VideoDX9* video; - IDirect3DIndexBuffer9* index_buffer; - - UINT num_indices; - UINT num_locked; - UINT next_index; - bool is_dynamic; -}; - -#endif // VideoDX9VertexBuffer_h - diff --git a/Stars45/VideoFactory.cpp b/Stars45/VideoFactory.cpp deleted file mode 100644 index 68da591..0000000 --- a/Stars45/VideoFactory.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Video and Polygon Renderer Factory class -*/ - -#include "VideoFactory.h" - -#include "VideoDX9.h" -#include "SoundD3D.h" - -// +--------------------------------------------------------------------+ - -VideoFactory::VideoFactory(HWND h) -: hwnd(h), video(0), audio(0) -{ } - -VideoFactory::~VideoFactory() -{ } - -// +--------------------------------------------------------------------+ - -Video* -VideoFactory::CreateVideo(VideoSettings* vs) -{ - if (!video) { - video = (Video*) new VideoDX9(hwnd, vs); - - if (!video) { - delete video; - video = 0; - } - } - - return video; -} - -// +--------------------------------------------------------------------+ - -void -VideoFactory::DestroyVideo(Video* v) -{ - if (v == video) { - delete video; - video = 0; - } -} - -// +--------------------------------------------------------------------+ - -SoundCard* -VideoFactory::CreateSoundCard() -{ - if (!audio) { - audio = new SoundCardD3D(hwnd); - Sound::UseSoundCard(audio); - } - - return audio; -} - - diff --git a/Stars45/VideoFactory.h b/Stars45/VideoFactory.h deleted file mode 100644 index 8c1c50d..0000000 --- a/Stars45/VideoFactory.h +++ /dev/null @@ -1,41 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Video Factory class -*/ - -#ifndef VideoFactory_h -#define VideoFactory_h - -#include "Types.h" -#include "Video.h" -#include "SoundCard.h" - -// +--------------------------------------------------------------------+ - -class VideoFactory -{ -public: - VideoFactory(HWND h); - virtual ~VideoFactory(); - - virtual Video* CreateVideo(VideoSettings* vs); - virtual void DestroyVideo(Video* video); - virtual SoundCard* CreateSoundCard(); - -private: - HWND hwnd; - - Video* video; - SoundCard* audio; -}; - -#endif // VideoFactory_h - diff --git a/Stars45/VideoSettings.cpp b/Stars45/VideoSettings.cpp deleted file mode 100644 index 9ef43b9..0000000 --- a/Stars45/VideoSettings.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Video Settings class implementation -*/ - -#include "VideoSettings.h" - -// +--------------------------------------------------------------------+ - -VideoSettings::VideoSettings() -{ - fullscreen_mode.width = 1024; - fullscreen_mode.height = 768; - fullscreen_mode.refresh = 75; - fullscreen_mode.format = VideoMode::FMT_X8R8G8B8; - - windowed_mode.width = 1280; - windowed_mode.height = 720; - windowed_mode.refresh = 0; - windowed_mode.format = VideoMode::FMT_NONE; - - window_width = 1280; - window_height = 720; - - gamma = 128; - is_windowed = false; - use_effects = true; - shadows = true; - bumpmaps = true; - specmaps = true; - max_detail = 4; - enable_vs = true; - enable_ps = true; - depth_bias = 0; -} - -VideoSettings::~VideoSettings() -{ } - -// +--------------------------------------------------------------------+ - -int -VideoSettings::GetGammaLevel() const -{ - return gamma; -} - -bool -VideoSettings::IsWindowed() const -{ - return is_windowed; -} - -bool -VideoSettings::UseEffects() const -{ - return use_effects; -} - -int -VideoSettings::GetWidth() const -{ - if (is_windowed) - return window_width; - - return fullscreen_mode.width; -} - -int -VideoSettings::GetHeight() const -{ - if (is_windowed) - return window_height; - - return fullscreen_mode.height; -} - -int -VideoSettings::GetDepth() const -{ - int fmt = 0; - int bpp = 0; - - if (is_windowed) - fmt = windowed_mode.format; - else - fmt = fullscreen_mode.format; - - switch (fmt) { - default: - case VideoMode::FMT_NONE: bpp = 0; break; - case VideoMode::FMT_R5G5B5: bpp = 15; break; - case VideoMode::FMT_R5G6B5: bpp = 16; break; - case VideoMode::FMT_R8G8B8: bpp = 24; break; - case VideoMode::FMT_X8R8G8B8: bpp = 32; break; - } - - return bpp; -} - -int -VideoSettings::GetPixSize() const -{ - int fmt = 0; - int pix = 0; - - if (is_windowed) - fmt = windowed_mode.format; - else - fmt = fullscreen_mode.format; - - switch (fmt) { - default: - case VideoMode::FMT_NONE: pix = 0; break; - case VideoMode::FMT_R5G5B5: pix = 2; break; - case VideoMode::FMT_R5G6B5: pix = 2; break; - case VideoMode::FMT_R8G8B8: pix = 3; break; - case VideoMode::FMT_X8R8G8B8: pix = 4; break; - } - - return pix; -} - -int -VideoSettings::GetRefreshRate() const -{ - if (is_windowed) - return windowed_mode.refresh; - - return fullscreen_mode.refresh; -} - -// +--------------------------------------------------------------------+ - -const char* -VideoSettings::GetModeDescription() const -{ - if (is_windowed) - return windowed_mode.GetDescription(); - - return fullscreen_mode.GetDescription(); -} - -// +--------------------------------------------------------------------+ - -int -VideoSettings::GetVertexProcessing() const -{ - if (is_windowed) - return windowed_device.vertex_processing; - - return fullscreen_device.vertex_processing; -} - -int -VideoSettings::GetDepthBufferBits() const -{ - if (is_windowed) - return windowed_device.depth_buffer_bits; - - return fullscreen_device.depth_buffer_bits; -} - -int -VideoSettings::GetAdapterIndex() const -{ - if (is_windowed) - return windowed_device.adapter_index; - - return fullscreen_device.adapter_index; -} - -int -VideoSettings::GetDeviceIndex() const -{ - if (is_windowed) - return windowed_device.device_index; - - return fullscreen_device.device_index; -} - -DWORD -VideoSettings::GetDeviceType() const -{ - if (is_windowed) - return windowed_device.device_type; - - return fullscreen_device.device_type; -} - -DWORD -VideoSettings::GetDepthStencilFormat() const -{ - if (is_windowed) - return windowed_device.depth_stencil_format; - - return fullscreen_device.depth_stencil_format; -} - -DWORD -VideoSettings::GetBackBufferFormat() const -{ - if (is_windowed) - return windowed_device.back_buffer_format; - - return fullscreen_device.back_buffer_format; -} - -const char* -VideoSettings::GetAdapterDesc() const -{ - if (is_windowed) - return windowed_device.adapter_desc; - - return fullscreen_device.adapter_desc; -} - -const char* -VideoSettings::GetDeviceDesc() const -{ - if (is_windowed) - return windowed_device.device_desc; - - return fullscreen_device.device_desc; -} - - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -const char* -VideoMode::GetDescription() const -{ - static char desc[32]; - - int bpp = 0; - switch (format) { - default: - case VideoMode::FMT_NONE: bpp = 0; break; - case VideoMode::FMT_R5G5B5: bpp = 15; break; - case VideoMode::FMT_R5G6B5: bpp = 16; break; - case VideoMode::FMT_R8G8B8: bpp = 24; break; - case VideoMode::FMT_X8R8G8B8: bpp = 32; break; - } - - sprintf_s(desc, "%d x %d x %d", width, height, bpp); - return desc; -} - -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ -// +--------------------------------------------------------------------+ - -VideoDeviceInfo::VideoDeviceInfo() -{ - ZeroMemory(this, sizeof(VideoDeviceInfo)); - - vertex_processing = VideoSettings::VTX_HARDWARE; - depth_buffer_bits = 32; -} - -VideoDeviceInfo::~VideoDeviceInfo() -{ -} diff --git a/Stars45/VideoSettings.h b/Stars45/VideoSettings.h deleted file mode 100644 index b9e74e4..0000000 --- a/Stars45/VideoSettings.h +++ /dev/null @@ -1,132 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Video Settings class -*/ - -#ifndef VideoSettings_h -#define VideoSettings_h - -#include "Types.h" -#include "Video.h" - -// +--------------------------------------------------------------------+ - -struct VideoMode -{ - enum Format { - FMT_NONE = 0, - FMT_R5G5B5 = 24, - FMT_R5G6B5 = 23, - FMT_R8G8B8 = 20, - FMT_X8R8G8B8 = 22 - }; - - VideoMode() : width(0), height(0), refresh(0), format(0) { } - VideoMode(int w, int h, Format f, int r=0) : width(w), height(h), refresh(r), format(f) { } - - int operator == (const VideoMode& m) const { return m.width == width && - m.height == height && - m.format == format; } - int operator != (const VideoMode& m) const { return m.width != width || - m.height != height || - m.format != format; } - - const char* GetDescription() const; - - int width; - int height; - int refresh; - int format; -}; - -// +--------------------------------------------------------------------+ - -struct VideoDeviceInfo -{ - VideoDeviceInfo(); - ~VideoDeviceInfo(); - - int vertex_processing; - int depth_buffer_bits; - int adapter_index; - int device_index; - DWORD device_type; - DWORD depth_stencil_format; - DWORD back_buffer_format; - DWORD multisample_type; - DWORD multisample_qual; - char adapter_desc[128]; - char device_desc[128]; -}; - -// +--------------------------------------------------------------------+ - -class VideoSettings -{ -public: - enum VertexProcessing { - VTX_SOFTWARE, - VTX_MIXED, - VTX_HARDWARE, - VTX_PURE - }; - - VideoSettings(); - ~VideoSettings(); - - // accessor methods - - int GetGammaLevel() const; - bool IsWindowed() const; - bool UseEffects() const; - int GetWidth() const; - int GetHeight() const; - int GetDepth() const; - int GetPixSize() const; - int GetRefreshRate() const; - - const char* GetModeDescription() const; - - int GetVertexProcessing() const; - int GetDepthBufferBits() const; - int GetAdapterIndex() const; - int GetDeviceIndex() const; - DWORD GetDeviceType() const; - DWORD GetDepthStencilFormat() const; - DWORD GetBackBufferFormat() const; - const char* GetAdapterDesc() const; - const char* GetDeviceDesc() const; - - // properties - - int gamma; - bool is_windowed; - bool use_effects; - VideoMode fullscreen_mode; - VideoMode windowed_mode; - int window_width; - int window_height; - VideoDeviceInfo fullscreen_device; - VideoDeviceInfo windowed_device; - - // feature set - - bool shadows; - bool bumpmaps; - bool specmaps; - int max_detail; - DWORD enable_vs; - DWORD enable_ps; - float depth_bias; -}; - -#endif // VideoSettings_h - diff --git a/Stars45/View.h b/Stars45/View.h deleted file mode 100644 index e986417..0000000 --- a/Stars45/View.h +++ /dev/null @@ -1,51 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Abstract View class -*/ - -#ifndef View_h -#define View_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -class Window; - -// +--------------------------------------------------------------------+ - -class View -{ - friend class Window; - -public: - static const char* TYPENAME() { return "View"; } - - View(Window* c) : window(c) { } - virtual ~View() { } - - int operator == (const View& that) const { return this == &that; } - - // Operations: - virtual void Refresh() { } - virtual void OnWindowMove() { } - virtual void OnShow() { } - virtual void OnHide() { } - - virtual void SetWindow(Window* w) { window = w; OnWindowMove(); } - virtual Window* GetWindow() { return window; } - -protected: - Window* window; -}; - -#endif // View_h - diff --git a/Stars45/Water.cpp b/Stars45/Water.cpp deleted file mode 100644 index 5509938..0000000 --- a/Stars45/Water.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Water surface effect w/ reflection and caustics -*/ - -#include "Water.h" -#include "Random.h" - -// +--------------------------------------------------------------------+ - -struct WATER_REFRACT -{ - // Vrefract = (V + refract * N) * norm - float refract; - float refractNorm; - DWORD diffuse; -}; - -struct WATER_SURFACE -{ - float height; - Vec3 normal; -}; - -// +--------------------------------------------------------------------+ - -#if defined(_X86) && !defined(_WIN64) -inline int f2i(float flt) -{ - volatile int n; - - __asm - { - fld flt - fistp n - } - - return n; -} -#else -inline int f2i(float flt) -{ - return (int) flt; -} -#endif - - -// +--------------------------------------------------------------------+ - -static WATER_REFRACT RefractionTable[512]; -static bool refractInit = false; - -static const int WAVE_SIZE = 256; -static const DWORD WAVE_MASK = 0xff; - -// +--------------------------------------------------------------------+ - -Water::Water() -: size(0), depth(0), scaleTex(1), avgHeight(0), -nVertices(0), surface(0), waves(0) -{ -} - -Water::~Water() -{ - delete [] surface; - delete [] waves; -} - -// +--------------------------------------------------------------------+ - -void -Water::Init(int n, float s, float d) -{ - size = s; - depth = d; - scaleTex = 1/size; - - // Calculate number of vertices - nVertices = n; - - // Create refraction table - if (!refractInit) { - WATER_REFRACT* refract = &RefractionTable[256]; - - for (UINT u = 0; u < 256; u++) { - float fCos0 = (float) u / (float) 256.0f; - float f0 = acosf(fCos0); - float fSin0 = sinf(f0); - - float fSin1 = fSin0 / 1.333f; // water - float f1 = asinf(fSin1); - float fCos1 = cosf(f1); - - refract[u].refract = fSin0 / fSin1 * fCos1 - fCos0; - refract[u].refractNorm = - fSin1 / fSin0; - refract[u].diffuse = ((((0xff - u)*(0xff - u)*(0xff - u)) << 8) & 0xff000000); - - RefractionTable[u] = RefractionTable[256]; - } - - refractInit = true; - } - - // Create maps - if (surface) - delete [] surface; - - surface = new WATER_SURFACE[n*n]; - ZeroMemory(surface, n*n * sizeof(WATER_SURFACE)); - - if (waves) - delete [] waves; - - waves = new float[WAVE_SIZE*4]; - - double f = 1.0 / (double) WAVE_SIZE; - for (int i = 0; i < WAVE_SIZE; i++) { - double s0 = sin(2*PI*i*f); - double s1 = sin(4*PI*i*f); - double s2 = sin(6*PI*i*f); - double s3 = sin(8*PI*i*f); - - waves[0*WAVE_SIZE + i] = (float) (1.8 * s0*s0 - 0.9); - waves[1*WAVE_SIZE + i] = (float) (1.6 * s1*s1 - 0.8); - waves[2*WAVE_SIZE + i] = (float) (0.4 * s2); - waves[3*WAVE_SIZE + i] = (float) (0.8 * s3*s3 - 0.4); - } - - for (int i = 0; i < 4; i++) { - offsets[i] = (float) Random(0, WAVE_SIZE); - } - - offsets[4] = 12.45f; - offsets[5] = 14.23f; - offsets[6] = 16.72f; - offsets[7] = 20.31f; -} - -// +--------------------------------------------------------------------+ - -void -Water::CalcWaves(double seconds) -{ - int i, n[4]; - UINT SIZE = nVertices; - UINT STEP = WAVE_SIZE / (SIZE-1); - UINT STEP2 = STEP/2; - UINT AREA = SIZE * SIZE; - UINT x, y; - - for (i = 0; i < 4; i++) { - n[i] = (int) offsets[i]; - } - - WATER_SURFACE* pSurf = surface; - - // compute heights - for (y = 0; y < SIZE; y++) { - for (x = 0; x < SIZE; x++) { - float h = 0; - h += waves[ ((n[0] + x*STEP - - y*STEP2) & WAVE_MASK) + 0*WAVE_SIZE ]; - h += waves[ ((n[1] + x*STEP2 - + y*STEP) & WAVE_MASK) + 1*WAVE_SIZE ]; - h += waves[ ((n[2] + x*STEP) & WAVE_MASK) + 2*WAVE_SIZE ]; - h += waves[ ((n[3] + y*STEP) & WAVE_MASK) + 3*WAVE_SIZE ]; - - pSurf->height = h * depth; - pSurf++; - } - } - - // compute normals - UINT uXN, uX0, uXP; - UINT uYN, uY0, uYP; - - uYP = AREA - SIZE; - uY0 = 0; - uYN = SIZE; - - for (y = 0; y < SIZE; y++) { - uXP = SIZE - 1; - uX0 = 0; - uXN = 1; - - for (x = 0; x < SIZE; x++) { - Vec3 vecN; - float f; - - f = surface[uXN + uYN].height - surface[uXP + uYP].height; vecN.x = vecN.z = f; - f = surface[uX0 + uYN].height - surface[uX0 + uYP].height; vecN.z += f; - f = surface[uXP + uYN].height - surface[uXN + uYP].height; vecN.x -= f; vecN.z += f; - f = surface[uXN + uY0].height - surface[uXP + uY0].height; vecN.x += f; - - vecN.y = -15.0f * depth; - vecN.Normalize(); - - surface[uX0 + uY0].normal = vecN * -1.0f; - - uXP = uX0; - uX0 = uXN; - uXN = (uXN + 1) % SIZE; - } - - uYP = uY0; - uY0 = uYN; - uYN = (uYN + SIZE) % AREA; - } - - // update offsets - for (i = 0; i < 4; i++) { - offsets[i] += (float) (offsets[i+4] * seconds); - - if (offsets[i] > WAVE_SIZE) - offsets[i] -= WAVE_SIZE; - } - -} - -// +--------------------------------------------------------------------+ - -void -Water::UpdateSurface(Vec3& eyePos, VertexSet* vset) -{ - UINT SIZE = nVertices; - UINT AREA = SIZE * SIZE; - UINT x, y; - - WATER_SURFACE* pSurf = surface; - Vec3* pLoc = vset->loc; - Vec3* pNorm = vset->nrm; - DWORD* pDiff = vset->diffuse; - float* pTu = vset->tu; - float* pTv = vset->tv; - - float fInc = 1.0f / (float) (SIZE-1); - float fx = 0.0f; - float fz = 0.0f; - - for (y = 0; y < SIZE; y++) { - for (x = 0; x < SIZE; x++) { - // update vertex height and normal - pLoc->y += pSurf->height; - *pNorm = pSurf->normal; - - /* - // Update texture coords and diffuse based upon refraction - Vec3 vec = eyePos - *pLoc; - vec.Normalize(); - - WATER_REFRACT *pRefract; - pRefract = RefractionTable + 256 + f2i(vec.dot(*pNorm) * 255.0f); - - *pDiff = pRefract->diffuse; - - // compute apparent displacement - Vec3 vecD = (pSurf->normal * pRefract->refract + vec) * pRefract->refractNorm; - Vec3 vecP = *pLoc; - vecP.y -= depth; - - // perturb texture coords - float fB = vecD * vecP * 2.0f; - float fD = fB * fB - depth; - float fScale = (-fB + sqrtf(fD)) * 0.5f; - - *pTu = vecD.x * fScale + fx; - *pTv = vecD.z * fScale + fz; - */ - - fx += fInc; - pSurf++; - pLoc++; - pNorm++; - pDiff++; - pTu++; - pTv++; - } - - fx = 0.0f; - fz += fInc; - } -} - - diff --git a/Stars45/Water.h b/Stars45/Water.h deleted file mode 100644 index 0dfe6eb..0000000 --- a/Stars45/Water.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Water surface effect w/ reflection and refraction -*/ - -#ifndef Water_h -#define Water_h - -#include "Geometry.h" -#include "Polygon.h" -#include "Color.h" - -// +--------------------------------------------------------------------+ - -struct WATER_SURFACE; - -// +--------------------------------------------------------------------+ - -class Water -{ -public: - Water(); - virtual ~Water(); - - virtual void Init(int nVerts, float size, float depth); - virtual void CalcWaves(double seconds); - virtual void UpdateSurface(Vec3& eyePos, VertexSet* vset); - -protected: - float size; - float depth; - float scaleTex; - float avgHeight; - - DWORD nVertices; - - WATER_SURFACE* surface; - float* waves; - float offsets[16]; -}; - -// +--------------------------------------------------------------------+ - -#endif // Water_h - diff --git a/Stars45/Wave.h b/Stars45/Wave.h deleted file mode 100644 index 441f323..0000000 --- a/Stars45/Wave.h +++ /dev/null @@ -1,51 +0,0 @@ -/* 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 - -*/ - -#ifndef Wave_h -#define Wave_h - -#include "Types.h" - -// +--------------------------------------------------------------------+ - -struct WAVE_HEADER -{ - DWORD RIFF; - DWORD file_len; - DWORD WAVE; -}; - -struct WAVE_FMT -{ - DWORD FMT; - DWORD chunk_size; - WORD wFormatTag; - WORD nChannels; - DWORD nSamplesPerSec; - DWORD nAvgBytesPerSec; - WORD nBlockAlign; - WORD wBitsPerSample; -}; - -struct WAVE_FACT -{ - DWORD FACT; - DWORD chunk_size; -}; - -struct WAVE_DATA -{ - DWORD DATA; - DWORD chunk_size; -}; - -// +--------------------------------------------------------------------+ - -#endif // Wave_h - diff --git a/Stars45/Weapon.cpp b/Stars45/Weapon.cpp deleted file mode 100644 index b5a0fd3..0000000 --- a/Stars45/Weapon.cpp +++ /dev/null @@ -1,1184 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon class -*/ - -#include "Weapon.h" -#include "Shot.h" -#include "Drone.h" -#include "Contact.h" -#include "Ship.h" -#include "Sim.h" -#include "SimEvent.h" -#include "Random.h" - -#include "NetGame.h" -#include "NetUtil.h" - -#include "Game.h" -#include "Clock.h" -#include "ContentBundle.h" -#include "Solid.h" - -// +----------------------------------------------------------------------+ - -Weapon::Weapon(WeaponDesign* d, int nmuz, Vec3* muzzles, double az, double el) - : System(WEAPON, d->type, d->name, d->value, d->capacity, d->capacity, - d->recharge_rate), - design(d), group(d->group), ammo(-1), ripple_count(0), - aim_azimuth((float) az), aim_elevation((float) el), - old_azimuth(0.0f), old_elevation(0.0f), aim_time(0), - enabled(true), refire(0.0f), - mass(d->carry_mass), resist(d->carry_resist), - guided(d->guided), shot_speed(d->speed), - active_barrel(0), locked(false), centered(false), firing(false), blocked(false), - index(0), target(0), subtarget(0), beams(0), orders(MANUAL), - control(SINGLE_FIRE), sweep(SWEEP_TIGHT), turret(0), turret_base(0) -{ - ZeroMemory(visible_stores, sizeof(visible_stores)); - - if (design->primary) - abrv = ContentBundle::GetInstance()->GetText("sys.weapon.primary.abrv"); - else - abrv = ContentBundle::GetInstance()->GetText("sys.weapon.secondary.abrv"); - - nbarrels = nmuz; - - if (nbarrels > MAX_BARRELS) - nbarrels = MAX_BARRELS; - - if (nbarrels == 0 && design->nbarrels > 0) { - nbarrels = design->nbarrels; - - for (int i = 0; i < nbarrels; i++) - muzzle_pts[i] = rel_pts[i] = design->muzzle_pts[i] * design->scale; - - ammo = design->ammo * nbarrels; - } - else if (nbarrels == 1 && design->nstores > 0) { - nbarrels = design->nstores; - - for (int i = 0; i < nbarrels; i++) - muzzle_pts[i] = rel_pts[i] = (muzzles[0] + design->attachments[i]); - - ammo = nbarrels; - } - else { - for (int i = 0; i < nbarrels; i++) - muzzle_pts[i] = rel_pts[i] = muzzles[i]; - - ammo = design->ammo * nbarrels; - } - - if (design->syncro) - active_barrel = -1; - - emcon_power[0] = 0; - emcon_power[1] = 0; - emcon_power[2] = 100; - - aim_az_max = design->aim_az_max; - aim_az_min = design->aim_az_min; - aim_az_rest = design->aim_az_rest; - - aim_el_max = design->aim_el_max; - aim_el_min = design->aim_el_min; - aim_el_rest = design->aim_el_rest; -} - -// +----------------------------------------------------------------------+ - -Weapon::Weapon(const Weapon& w) - : System(w), design(w.design), ammo(-1), ripple_count(0), - enabled(true), refire(0.0f), - mass(w.mass), resist(w.resist), - aim_azimuth(w.aim_azimuth), aim_elevation(w.aim_elevation), - old_azimuth(0.0f), old_elevation(0.0f), aim_time(0), - guided(w.guided), shot_speed(w.shot_speed), - active_barrel(0), locked(false), centered(false), firing(false), blocked(false), - target(0), subtarget(0), beams(0), orders(MANUAL), - control(SINGLE_FIRE), sweep(SWEEP_TIGHT), group(w.group), - aim_az_max(w.aim_az_max), aim_az_min(w.aim_az_min), aim_az_rest(w.aim_az_rest), - aim_el_max(w.aim_el_max), aim_el_min(w.aim_el_min), aim_el_rest(w.aim_el_rest), - turret(0), turret_base(0) -{ - Mount(w); - ZeroMemory(visible_stores, sizeof(visible_stores)); - - nbarrels = w.nbarrels; - - for (int i = 0; i < nbarrels; i++) { - muzzle_pts[i] = rel_pts[i] = w.muzzle_pts[i]; - } - - ammo = design->ammo * nbarrels; - - if (design->syncro) - active_barrel = -1; - - if (design->beam) { - beams = new Shot* [nbarrels]; - ZeroMemory(beams, sizeof(Shot*) * nbarrels); - } - - if (aim_az_rest >= 2*PI) - aim_az_rest = design->aim_az_rest; - - if (aim_el_rest >= 2*PI) - aim_el_rest = design->aim_el_rest; -} - -// +--------------------------------------------------------------------+ - -Weapon::~Weapon() -{ - if (beams) { - for (int i = 0; i < nbarrels; i++) { - if (beams[i]) { - Ignore(beams[i]); - delete beams[i]; - beams[i] = 0; - } - } - - delete [] beams; - } - - GRAPHIC_DESTROY(turret); - GRAPHIC_DESTROY(turret_base); - - for (int i = 0; i < MAX_BARRELS; i++) - GRAPHIC_DESTROY(visible_stores[i]); -} - -// +--------------------------------------------------------------------+ - -bool -Weapon::IsPrimary() const -{ - return design->primary; -} - -bool -Weapon::IsDrone() const -{ - return design->drone; -} - -bool -Weapon::IsDecoy() const -{ - return design->decoy_type != 0; -} - -bool -Weapon::IsProbe() const -{ - return design->probe != 0; -} - -bool -Weapon::IsMissile() const -{ - return !design->primary; -} - -bool -Weapon::IsBeam() const -{ - return design->beam; -} - -// +--------------------------------------------------------------------+ - -Shot* -Weapon::GetBeam(int i) -{ - if (beams && i >= 0 && i < nbarrels) - return beams[i]; - - return 0; -} - -// +--------------------------------------------------------------------+ - -void -Weapon::SetOwner(Ship* s) -{ - ship = s; - - if (design->turret_model) { - Solid* t = new Solid; - t->UseModel(design->turret_model); - turret = t; - } - - if (design->turret_base_model) { - Solid* t = new Solid; - t->UseModel(design->turret_base_model); - turret_base = t; - } - - if (!design->primary && - design->visible_stores && - ammo == nbarrels && - design->shot_model != 0) - { - for (int i = 0; i < nbarrels; i++) { - Solid* s = new Solid; - s->UseModel(design->shot_model); - - visible_stores[i] = s; - } - } -} - -Solid* -Weapon::GetTurret() -{ - return turret; -} - -Solid* -Weapon::GetTurretBase() -{ - return turret_base; -} - -Solid* -Weapon::GetVisibleStore(int i) -{ - if (i >= 0 && i < MAX_BARRELS) - return visible_stores[i]; - - return 0; -} - -void -Weapon::SetAmmo(int a) -{ - if (a >= 0) { - if (active_barrel >= 0 && design->visible_stores) { - while (a < ammo) { - if (active_barrel >= nbarrels) - active_barrel = 0; - - if (visible_stores[active_barrel]) { - GRAPHIC_DESTROY(visible_stores[active_barrel]); - active_barrel++; - ammo--; - } - } - } - - ammo = a; - } -} - -// +--------------------------------------------------------------------+ - -void -Weapon::ExecFrame(double seconds) -{ - System::ExecFrame(seconds); - - if (refire > 0) - refire -= (float) seconds; - - locked = false; - centered = false; - - if (!ship) - return; - - if (orders == POINT_DEFENSE && enabled) - SelectTarget(); - - if (beams && !target) { - for (int i = 0; i < nbarrels; i++) { - if (beams[i]) { - // aim beam straight: - Aim(); - SetBeamPoints(false); - return; - } - } - } - - if (design->self_aiming) { - Track(target, subtarget); - } - else if (turret) { - ZeroAim(); - } - - if (ship->CheckFire()) - return; - - // aim beam at target: - bool aim_beams = false; - - if (beams) { - for (int i = 0; i < nbarrels; i++) { - if (beams[i]) { - aim_beams = true; - SetBeamPoints(true); - break; - } - } - } - - if (!aim_beams) { - if (ripple_count > 0) { - if (Fire()) - ripple_count--; - } - - else if (locked && !blocked) { - if (!ship->IsHostileTo(target)) - return; - - if (orders == AUTO && centered) { - if (energy >= design->charge && - (ammo < 0 || target && target->Integrity() >= 1) && - objective.length() < design->max_range) - Fire(); - } - - else if (orders == POINT_DEFENSE) { - if (energy >= design->min_charge && - (ammo < 0 || target && target->Integrity() >= 1) && - objective.length() < design->max_range) - Fire(); - } - } - } -} - -// +----------------------------------------------------------------------+ - -void -Weapon::Distribute(double delivered_energy, double seconds) -{ - if (UsesWatts()) { - if (seconds < 0.01) - seconds = 0.01; - - // convert Joules to Watts: - energy = (float) (delivered_energy/seconds); - } - - else if (!Game::GetInstance()->Paused()) { - energy += (float) (delivered_energy * 1.25); - - if (energy > capacity) - energy = capacity; - - else if (energy < 0) - energy = 0.0f; - } -} - - -// +--------------------------------------------------------------------+ - -bool -Weapon::Update(SimObject* obj) -{ - if (obj == target) { - target = 0; - } - - else if (beams) { - for (int i = 0; i < nbarrels; i++) - if (obj == beams[i]) - beams[i] = 0; - } - - return SimObserver::Update(obj); -} - -const char* -Weapon::GetObserverName() const -{ - static char name[256]; - sprintf_s(name, "Weapon %s", design->name.data()); - return name; -} - -// +--------------------------------------------------------------------+ - -void -Weapon::SetFiringOrders(int o) -{ - if (o >= MANUAL && o <= POINT_DEFENSE) - orders = o; -} - -void -Weapon::SetControlMode(int m) -{ - if (m >= SINGLE_FIRE && m <= SALVO_FIRE) - control = m; -} - -void -Weapon::SetSweep(int s) -{ - if (s >= SWEEP_NONE && s <= SWEEP_WIDE) - sweep = s; -} - -// +--------------------------------------------------------------------+ - -bool -Weapon::CanTarget(DWORD classification) const -{ - return (design->target_type & classification) ? true : false; -} - -// +--------------------------------------------------------------------+ - -void -Weapon::SetTarget(SimObject* targ, System* sub) -{ - // check self targeting: - if (targ == (SimObject*) ship) - return; - - // check target class filter: - if (targ) { - switch (targ->Type()) { - case SimObject::SIM_SHIP: { - Ship* tgt_ship = (Ship*) targ; - - if ((tgt_ship->Class() & design->target_type) == 0) - return; - } - break; - - case SimObject::SIM_SHOT: - return; - - case SimObject::SIM_DRONE: { - if ((design->target_type & Ship::DRONE) == 0) - return; - } - break; - - default: - return; - } - } - - // if ok, target this object: - if (target != targ) { - target = targ; - - if (target) - Observe(target); - } - - subtarget = sub; -} - -// +--------------------------------------------------------------------+ - -void -Weapon::SelectTarget() -{ - bool select_locked = false; - SimObject* targ = 0; - double dist = 1e9; - double az = 0; - double el = 0; - - if (ammo && enabled && (availability > crit_level)) { - ZeroAim(); - - ListIter contact = ship->ContactList(); - - // lock onto any threatening shots first (if we can): - if (design->target_type & Ship::DRONE) { - while (++contact) { - Shot* c_shot = contact->GetShot(); - - if (c_shot && contact->Threat(ship)) { - - // distance from self to target: - double distance = Point(c_shot->Location() - muzzle_pts[0]).length(); - - if (distance > design->min_range && - distance < design->max_range && - distance < dist) { - // check aim basket: - select_locked = CanLockPoint(c_shot->Location(), az, el); - - if (select_locked) { - targ = c_shot; - dist = distance; - } - } - } - } - } - - // lock onto a threatening ship only if it is (much) closer: - dist *= 0.2; - contact.reset(); - while (++contact) { - Ship* c_ship = contact->GetShip(); - - if (!c_ship) continue; - - // can we lock onto this target? - if ((c_ship->IsRogue() || c_ship->GetIFF() > 0 && c_ship->GetIFF() != ship->GetIFF()) && - (c_ship->Class() & design->target_type) && - c_ship->Weapons().size() > 0) { - // distance from self to target: - double distance = Point(c_ship->Location() - muzzle_pts[0]).length(); - - if (distance < design->max_range && distance < dist) { - // check aim basket: - select_locked = CanLockPoint(c_ship->Location(), az, el); - - if (select_locked) { - targ = c_ship; - dist = distance; - } - } - } - } - } - - if (!ammo || !enabled) { - SetTarget(0,0); - locked = false; - } - - else { - SetTarget(targ, 0); - } -} - -// +--------------------------------------------------------------------+ - -int -Weapon::Track(SimObject* targ, System* sub) -{ - if (ammo && enabled && (availability > crit_level)) { - firing = 0; - Aim(); - } - else if (turret) { - ZeroAim(); - } - - return locked; -} - -// +--------------------------------------------------------------------+ - -Shot* -Weapon::Fire() -{ - if (Game::GetInstance()->Paused()) - return 0; - - if (ship && ship->CheckFire()) - return 0; - - if (ship->IsStarship() && target && !centered) - return 0; - - if (beams && active_barrel >= 0 && active_barrel < nbarrels && beams[active_barrel]) - return 0; - - Shot* shot = 0; - - if (ammo && enabled && - (refire <= 0) && (energy > design->min_charge) && - (availability > crit_level)) { - - refire = design->refire_delay; - - NetGame* net_game = NetGame::GetInstance(); - bool net_client = net_game ? net_game->IsClient() : false; - - // all barrels - if (active_barrel < 0) { - if (net_client || IsPrimary()) - NetUtil::SendWepTrigger(this, nbarrels); - - if (!net_game || IsPrimary()) { - for (int i = 0; i < nbarrels; i++) - shot = FireBarrel(i); - } - - else if (net_game && net_game->IsServer() && IsMissile()) { - for (int i = 0; i < nbarrels; i++) { - shot = FireBarrel(i); - NetUtil::SendWepRelease(this, shot); - } - } - } - - // single barrel - else { - if (net_client || IsPrimary()) - NetUtil::SendWepTrigger(this, nbarrels); - - if (!net_game || IsPrimary()) { - shot = FireBarrel(active_barrel++); - } - - else if (net_game && net_game->IsServer() && IsMissile()) { - shot = FireBarrel(active_barrel++); - NetUtil::SendWepRelease(this, shot); - } - - if (active_barrel >= nbarrels) { - active_barrel = 0; - refire += design->salvo_delay; - } - } - - if (design->ripple_count > 0 && ripple_count <= 0) - ripple_count = design->ripple_count-1; - - if (status != NOMINAL) - refire *= 2; - } - - return shot; -} - -// +--------------------------------------------------------------------+ - -Shot* -Weapon::NetFirePrimary(SimObject* tgt, System* sub, int count) -{ - Shot* shot = 0; - - if (!IsPrimary() || Game::GetInstance()->Paused()) - return shot; - - if (active_barrel < 0 || active_barrel >= nbarrels) - active_barrel = 0; - - target = tgt; - subtarget = sub; - aim_time = 0; - - for (int i = 0; i < count; i++) { - shot = FireBarrel(active_barrel++); - - if (active_barrel >= nbarrels) { - active_barrel = 0; - refire += design->salvo_delay; - } - } - - if (target) - Observe(target); - - return shot; -} - -Shot* -Weapon::NetFireSecondary(SimObject* tgt, System* sub, DWORD objid) -{ - Shot* shot = 0; - - if (IsPrimary() || Game::GetInstance()->Paused()) - return shot; - - if (active_barrel < 0 || active_barrel >= nbarrels) - active_barrel = 0; - - target = tgt; - subtarget = sub; - aim_time = 0; - - shot = FireBarrel(active_barrel++); - - if (active_barrel >= nbarrels) { - active_barrel = 0; - refire += design->salvo_delay; - } - - if (shot) - shot->SetObjID(objid); - - if (target) - Observe(target); - - return shot; -} - -// +--------------------------------------------------------------------+ - -Shot* -Weapon::FireBarrel(int n) -{ - const Point& base_vel = ship->Velocity(); - Shot* shot = 0; - SimRegion* region = ship->GetRegion(); - - if (!region || n < 0 || n >= nbarrels || Game::GetInstance()->Paused()) - return 0; - - firing = 1; - Aim(); - - Camera rail_cam; - rail_cam.Clone(aim_cam); - - Point shotpos = muzzle_pts[n]; - if (design->length > 0) - shotpos = shotpos + aim_cam.vpn() * design->length; - - // guns may be slewed towards target: - if (design->primary) { - shot = CreateShot(shotpos, aim_cam, design, ship); - - if (shot) { - shot->SetVelocity(shot->Velocity() + base_vel); - } - } - - // missiles always launch in rail direction: - else { - // unless they are on a mobile launcher - if (turret && design->self_aiming) { - shot = CreateShot(shotpos, aim_cam, design, ship); - shot->SetVelocity(base_vel); - } - else { - shot = CreateShot(shotpos, rail_cam, design, ship); - if (shot /* && !turret */) { - Matrix orient = ship->Cam().Orientation(); - if (aim_azimuth != 0) orient.Yaw(aim_azimuth); - if (aim_elevation != 0) orient.Pitch(aim_elevation); - - Point eject = design->eject * orient; - shot->SetVelocity(base_vel + eject); - } - } - - if (shot && visible_stores[n]) { - GRAPHIC_DESTROY(visible_stores[n]); - } - } - - if (shot) { - if (ammo > 0) - ammo--; - - if (guided && target) - shot->SeekTarget(target, subtarget); - - float shot_load; - if (energy > design->charge) - shot_load = design->charge; - else - shot_load = energy; - - energy -= shot_load; - shot->SetCharge(shot_load * availability); - - if (target && design->flak && !design->guided) { - double speed = shot->Velocity().length(); - double range = (target->Location() - shot->Location()).length(); - - if (range > design->min_range && range < design->max_range) { - shot->SetFuse(range / speed); - } - } - - region->InsertObject(shot); - - if (beams) { - beams[n] = shot; - Observe(beams[n]); - - // aim beam at target: - SetBeamPoints(true); - } - - if (ship) { - ShipStats* stats = ShipStats::Find(ship->Name()); - - if (design->primary) - stats->AddGunShot(); - else if (design->decoy_type == 0 && design->damage > 0) - stats->AddMissileShot(); - } - } - - return shot; -} - -Shot* -Weapon::CreateShot(const Point& loc, const Camera& cam, WeaponDesign* dsn, const Ship* own) -{ - if (dsn->drone) - return new Drone(loc, cam, dsn, own); - - else - return new Shot(loc, cam, dsn, own); -} - -// +--------------------------------------------------------------------+ - -void -Weapon::Orient(const Physical* rep) -{ - System::Orient(rep); - - const Matrix& orientation = rep->Cam().Orientation(); - Point loc = rep->Location(); - - // align graphics with camera: - if (turret) { - if (!design->self_aiming) - ZeroAim(); - - const Matrix& aim = aim_cam.Orientation(); - - turret->MoveTo(mount_loc); - turret->SetOrientation(aim); - - if (turret_base) { - Matrix base = orientation; - - if (design->turret_axis == 1) { - base.Pitch(aim_elevation); - base.Pitch(old_elevation); - } - else { - base.Yaw(aim_azimuth); - base.Yaw(old_azimuth); - } - - turret_base->MoveTo(mount_loc); - turret_base->SetOrientation(base); - } - - for (int i = 0; i < nbarrels; i++) { - muzzle_pts[i] = (rel_pts[i] * aim) + mount_loc; - - if (visible_stores[i]) { - visible_stores[i]->SetOrientation(aim); - visible_stores[i]->MoveTo(muzzle_pts[i]); - } - } - } - else { - for (int i = 0; i < nbarrels; i++) { - muzzle_pts[i] = (rel_pts[i] * orientation) + loc; - - if (visible_stores[i]) { - visible_stores[i]->SetOrientation(orientation); - visible_stores[i]->MoveTo(muzzle_pts[i]); - } - } - } -} - -// +--------------------------------------------------------------------+ - -void -Weapon::SetBeamPoints(bool aim) -{ - for (int i = 0; i < nbarrels; i++) { - if (beams && beams[i]) { - Point from = muzzle_pts[i]; - Point to; - double len = design->length; - - if (len < 1 || len > 1e7) - len = design->max_range; - - if (len < 1) - len = 3e5; - - else if (len > 1e7) - len = 1e7; - - // always use the aim cam, to enforce slew_rate - to = from + aim_cam.vpn() * len; - - beams[i]->SetBeamPoints(from, to); - } - } -} - -// +--------------------------------------------------------------------+ - -void -Weapon::Aim() -{ - locked = false; - centered = false; - - FindObjective(); - - if (target) { - double az = 0; - double el = 0; - - locked = CanLockPoint(obj_w, az, el, &objective); - - double spread_az = design->spread_az; - double spread_el = design->spread_el; - - // beam sweep target: - if (design->beam) { - double factor = 0; - double az_phase = 0; - double el_phase = 0; - - if (target->Type() == SimObject::SIM_SHIP) { - Ship* s = (Ship*) target; - - if (s->IsStarship()) { - switch (sweep) { - default: - case SWEEP_NONE: factor = 0; break; - case SWEEP_TIGHT: factor = 1; break; - case SWEEP_WIDE: factor = 2; break; - } - } - } - - if (factor > 0) { - factor *= atan2(target->Radius(), (double) objective.z); - - for (int i = 0; i < nbarrels; i++) { - if (beams && beams[i]) { - az_phase = sin(beams[i]->Life() * 0.4 * PI); - el_phase = sin(beams[i]->Life() * 1.0 * PI); - break; - } - } - - az += factor * spread_az * az_phase; - el += factor * spread_el * el_phase * 0.25; - } - } - - else if (!design->beam) { - if (spread_az > 0) - az += Random(-spread_az, spread_az); - - if (spread_el > 0) - el += Random(-spread_el, spread_el); - } - - AimTurret(az, -el); - - // check range for guided weapons: - if (locked && guided) { - double range = objective.length(); - - if (range > design->max_track) - locked = false; - - else if (range > design->max_range) { - if (firing) { - if (RandomChance(1,4)) // 1 in 4 chance of locking anyway - locked = false; - } - else { - locked = false; - } - } - } - - if (locked) { - Point tloc = target->Location(); - tloc = Transform(tloc); - - if (tloc.z > 1) { - az = atan2(fabs(tloc.x), tloc.z); - el = atan2(fabs(tloc.y), tloc.z); - - double firing_cone = 10*DEGREES; - - if (orders == MANUAL) - firing_cone = 30*DEGREES; - - if (az < firing_cone && el < firing_cone) - centered = true; - } - } - } - else { - AimTurret(aim_az_rest, -aim_el_rest); - } -} - -void -Weapon::FindObjective() -{ - ZeroAim(); - - if (!target || !design->self_aiming) { - objective = Point(); - return; - } - - obj_w = target->Location(); - - if (subtarget) { - obj_w = subtarget->MountLocation(); - } - else if (target->Type() == SimObject::SIM_SHIP) { - Ship* tgt_ship = (Ship*) target; - - if (tgt_ship->IsGroundUnit()) - obj_w += Point(0,150,0); - } - - if (!design->beam && shot_speed > 0) { - // distance from self to target: - double distance = Point(obj_w - muzzle_pts[0]).length(); - - // TRUE shot speed is relative to ship speed: - Point eff_shot_vel = ship->Velocity() + aim_cam.vpn() * shot_speed - target->Velocity(); - double eff_shot_speed = eff_shot_vel.length(); - - // time to reach target: - double time = distance / eff_shot_speed; - - // where the target will be when the shot reaches it: - obj_w += (target->Velocity() - ship->Velocity()) * time + - target->Acceleration() * 0.25 * time * time; - } - - // transform into camera coords: - objective = Transform(obj_w); -} - -Point -Weapon::Transform(const Point& pt) -{ - Point result; - - Point obj_t = pt - aim_cam.Pos(); - result.x = obj_t * aim_cam.vrt(); - result.y = obj_t * aim_cam.vup(); - result.z = obj_t * aim_cam.vpn(); - - return result; -} - -bool -Weapon::CanLockPoint(const Point& test, double& az, double& el, Point* obj) -{ - Point pt = Transform(test); - bool locked = true; - - // first compute az: - if (fabs(pt.z) < 0.1) pt.z = 0.1; - az = atan(pt.x / pt.z); - if (pt.z < 0) az -= PI; - if (az < -PI) az += 2*PI; - - // then, rotate target into az-coords to compute el: - Camera tmp; - tmp.Clone(aim_cam); - aim_cam.Yaw(az); - pt = Transform(test); - aim_cam.Clone(tmp); - - if (fabs(pt.z) < 0.1) pt.z = 0.1; - el = atan(pt.y / pt.z); - - if (obj) *obj = pt; - - // is the target in the basket? - // clamp if necessary: - - if (az > aim_az_max) { - az = aim_az_max; - locked = false; - } - else if (az < aim_az_min) { - az = aim_az_min; - locked = false; - } - - if (el > aim_el_max) { - el = aim_el_max; - locked = false; - } - else if (el < aim_el_min) { - el = aim_el_min; - locked = false; - } - - if (IsDrone() && guided) { - double firing_cone = 10*DEGREES; - - if (orders == MANUAL) - firing_cone = 20*DEGREES; - - if (az < firing_cone && el < firing_cone) - locked = true; - } - - return locked; -} - -// +--------------------------------------------------------------------+ - -void -Weapon::AimTurret(double az, double el) -{ - double seconds = (Clock::GetInstance()->GameTime() - aim_time) / 1000.0; - - // don't let the weapon turn faster than turret slew rate: - double max_turn = design->slew_rate * seconds; - - if (fabs(az-old_azimuth) > max_turn) { - if (az > old_azimuth) - az = old_azimuth + max_turn; - else - az = old_azimuth - max_turn; - } - - if (fabs(el-old_elevation) > PI/2 * seconds) { - if (el > old_elevation) - el = old_elevation + max_turn; - else - el = old_elevation - max_turn; - } - - aim_cam.Yaw(az); - aim_cam.Pitch(el); - - old_azimuth = (float) az; - old_elevation = (float) el; - - aim_time = Clock::GetInstance()->GameTime(); -} - -void -Weapon::ZeroAim() -{ - aim_cam.Clone(ship->Cam()); - if (aim_azimuth != 0) aim_cam.Yaw(aim_azimuth); - if (aim_elevation != 0) aim_cam.Pitch(aim_elevation); - - aim_cam.MoveTo(muzzle_pts[0]); -} diff --git a/Stars45/Weapon.h b/Stars45/Weapon.h deleted file mode 100644 index d8e0082..0000000 --- a/Stars45/Weapon.h +++ /dev/null @@ -1,203 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon (gun or missile launcher) class -*/ - -#ifndef Weapon_h -#define Weapon_h - -#include "Types.h" -#include "SimObject.h" -#include "System.h" -#include "WeaponDesign.h" -#include "Geometry.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Weapon; -class Ship; -class Shot; - -class Solid; - -// +--------------------------------------------------------------------+ - -class Weapon : public System, public SimObserver -{ -public: - static const char* TYPENAME() { return "Weapon"; } - - enum Constants { MAX_BARRELS=8 }; - enum Orders { MANUAL, AUTO, POINT_DEFENSE }; - enum Control { SINGLE_FIRE, RIPPLE_FIRE, SALVO_FIRE }; - enum Sweep { SWEEP_NONE, SWEEP_TIGHT, SWEEP_WIDE }; - - Weapon(WeaponDesign* d, int nmuz, Vec3* muzzles, double az=0, double el=0); - Weapon(const Weapon& rhs); - virtual ~Weapon(); - - int operator==(const Weapon& w) const { return this == &w; } - - int Track(SimObject* targ, System* sub); - Shot* Fire(); - Shot* NetFirePrimary(SimObject* targ, System* sub, int count); - Shot* NetFireSecondary(SimObject* targ, System* sub, DWORD objid); - void SetTarget(SimObject* t, System* sub); - void SelectTarget(); - bool CanTarget(DWORD classification) const; - SimObject* GetTarget() const { return target; } - System* GetSubTarget() const { return subtarget; } - void SetFiringOrders(int o); - int GetFiringOrders() const { return orders; } - void SetControlMode(int m); - int GetControlMode() const { return control; } - void SetSweep(int s); - int GetSweep() const { return sweep; } - - void Enable() { enabled = true; } - void Disable() { enabled = false; } - - const WeaponDesign* Design() const { return design; } - const char* Group() const { return group; } - int Enabled() const { return enabled; } - int Ammo() const { return ammo; } - int Guided() const { return guided; } - int Locked() const { return locked; } - float Velocity() const { return shot_speed; } - float Mass() const { return mass*ammo; } - float Resistance()const { return resist*ammo; } - Shot* GetBeam(int i); - - // needed to set proper ammo level when joining multiplayer in progress: - void SetAmmo(int a); - - bool IsPrimary() const; - bool IsDrone() const; - bool IsDecoy() const; - bool IsProbe() const; - bool IsMissile() const; - bool IsBeam() const; - - virtual void ExecFrame(double factor); - virtual void Orient(const Physical* rep); - virtual void Distribute(double delivered_energy, double seconds); - - const Ship* Owner() const { return ship; } - void SetOwner(Ship* ship); - int GetIndex() const { return index; } - void SetIndex(int n) { index = n; } - - Point GetAimVector() const { return aim_cam.vpn(); } - void SetAzimuth(double a) { aim_azimuth = (float) a; } - double GetAzimuth() const { return aim_azimuth; } - void SetElevation(double e) { aim_elevation = (float) e; } - double GetElevation() const { return aim_elevation; } - - void SetRestAzimuth(double a) { aim_az_rest = (float) a; } - double GetRestAzimuth() const { return aim_az_rest; } - void SetRestElevation(double e) { aim_el_rest = (float) e; } - double GetRestElevation() const { return aim_el_rest; } - - void SetAzimuthMax(double a) { aim_az_max = (float) a; } - double GetAzimuthMax() const { return aim_az_max; } - void SetAzimuthMin(double a) { aim_az_min = (float) a; } - double GetAzimuthMin() const { return aim_az_min; } - - void SetElevationMax(double e) { aim_el_max = (float) e; } - double GetElevationMax() const { return aim_el_max; } - void SetElevationMin(double e) { aim_el_min = (float) e; } - double GetElevationMin() const { return aim_el_min; } - - void SetGroup(const char* n) { group = n; } - - bool IsBlockedFriendly() const { return blocked; } - void SetBlockedFriendly(bool b) { blocked = b; } - - Solid* GetTurret(); - Solid* GetTurretBase(); - Solid* GetVisibleStore(int i); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - -protected: - Shot* FireBarrel(int n); - Shot* CreateShot(const Point& loc, const Camera& cam, WeaponDesign* dsn, const Ship* owner); - - void SetBeamPoints(bool aim=false); - void Aim(); - void AimTurret(double az, double el); - void ZeroAim(); - void FindObjective(); - Point Transform(const Point& pt); - bool CanLockPoint(const Point& test, double& az, double& el, Point* obj=0); - - // data members: - WeaponDesign* design; - Text group; - Point muzzle_pts[MAX_BARRELS]; - Point rel_pts[MAX_BARRELS]; - Solid* turret; - Solid* turret_base; - Solid* visible_stores[MAX_BARRELS]; - int nbarrels; - int active_barrel; - - float refire; - int ammo; - int ripple_count; - - // carrying costs per shot: - float mass; - float resist; - - // for targeting computer: - int guided; - bool enabled; - bool locked; - bool centered; - bool firing; - bool blocked; - float shot_speed; - - int index; - - int orders; - int control; - int sweep; - - SimObject* target; - System* subtarget; - - Point objective; - Point obj_w; - Camera aim_cam; - float aim_azimuth; - float aim_elevation; - float old_azimuth; - float old_elevation; - - // auto-aiming arc - float aim_az_max; // maximum deflection in azimuth - float aim_az_min; // minimum deflection in azimuth - float aim_az_rest; // azimuth of turret at rest - float aim_el_max; // maximum deflection in elevation - float aim_el_min; // minimum deflection in elevation - float aim_el_rest; // elevation of turret at rest - - DWORD aim_time; - - Shot** beams; -}; - -#endif // Weapon_h - diff --git a/Stars45/WeaponDesign.cpp b/Stars45/WeaponDesign.cpp deleted file mode 100644 index aa116b0..0000000 --- a/Stars45/WeaponDesign.cpp +++ /dev/null @@ -1,725 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon Design parameters class -*/ - -#include "WeaponDesign.h" -#include "ShipDesign.h" -#include "Weapon.h" - -#include "Game.h" -#include "ContentBundle.h" -#include "Sprite.h" -#include "Light.h" -#include "Bitmap.h" -#include "Solid.h" -#include "Sound.h" -#include "DataLoader.h" - -#include "ParseUtil.h" - -// +--------------------------------------------------------------------+ - -static List catalog; -static List mod_catalog; -static bool degrees; - -#define GET_DEF_BOOL(x) if(defname==(#x))GetDefBool(design->x,pdef,filename) -#define GET_DEF_TEXT(x) if(defname==(#x))GetDefText(design->x,pdef,filename) -#define GET_DEF_NUM(x) if(defname==(#x))GetDefNumber(design->x,pdef,filename) - -// +--------------------------------------------------------------------+ - -WeaponDesign::WeaponDesign() -{ - type = 0; - secret = 0; - drone = 0; - primary = 0; - beam = 0; - flak = 0; - guided = 0; - self_aiming = 0; - syncro = 0; - value = 0; - decoy_type = 0; - probe = 0; - target_type = 0; - - visible_stores = 0; - nstores = 0; - nbarrels = 0; - - recharge_rate = 0.0f; - refire_delay = 0.0f; - salvo_delay = 0.0f; - charge = 0.0f; - min_charge = 0.0f; - carry_mass = 0.0f; - carry_resist = 0.0f; - - speed = 0.0f; - life = 0.0f; - mass = 0.0f; - drag = 0.0f; - thrust = 0.0f; - roll_rate = 0.0f; - pitch_rate = 0.0f; - yaw_rate = 0.0f; - roll_drag = 0.0f; - pitch_drag = 0.0f; - yaw_drag = 0.0f; - - min_range = 0.0f; - max_range = 0.0f; - max_track = 0.0f; - - graphic_type = 0; - width = 0; - length = 0; - - scale = 1.0f; - explosion_scale = 0.0f; - light = 0.0f; - light_color = Color::White; - flash_scale = 0.0f; - flare_scale = 0.0f; - - spread_az = 0.0f; - spread_el = 0.0f; - - beauty_img = 0; - turret_model = 0; - turret_base_model = 0; - animation = 0; - anim_length = 0; - shot_img = 0; - shot_model = 0; - trail_img = 0; - flash_img = 0; - flare_img = 0; - sound_resource = 0; - - ammo = -1; - ripple_count = 0; - capacity = 100.0f; - damage = 1.0f; - damage_type = 0; - penetration = 1.0f; - firing_cone = 0.0f; - aim_az_max = 1.5f; - aim_az_min = -1.5f; - aim_az_rest = 0.0f; - aim_el_max = 1.5f; - aim_el_min = -1.5f; - aim_el_rest = 0.0f; - slew_rate = (float) (60*DEGREES); - turret_axis = 0; - lethal_radius = 500.0f; - integrity = 100.0f; - - eject = Vec3(0.0f, -100.0f, 0.0f); - - det_range = 0.0f; - det_count = 0; - det_spread = (float) (PI/8); - - trail_length = 0; - trail_width = 0; - trail_dim = 0; - - for (int i = 0; i < MAX_STORES; i++) { - muzzle_pts[i] = Vec3(0,0,0); - attachments[i] = Vec3(0,0,0); - } -} - -WeaponDesign::~WeaponDesign() -{ - delete turret_model; - delete turret_base_model; - delete shot_model; - delete sound_resource; -} - -// +--------------------------------------------------------------------+ - -void -WeaponDesign::Initialize(const char* filename) -{ - Print("Loading Weapon Designs '%s'\n", filename); - LoadDesign("Weapons/", filename); -} - -// +--------------------------------------------------------------------+ - -void -WeaponDesign::Close() -{ - catalog.destroy(); - mod_catalog.destroy(); -} - -void -WeaponDesign::ClearModCatalog() -{ - mod_catalog.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -WeaponDesign::LoadDesign(const char* path, const char* filename, bool mod) -{ - // Load Design File: - DataLoader* loader = DataLoader::GetLoader(); - loader->SetDataPath(path); - - BYTE* block; - int blocklen = loader->LoadBuffer(filename, block, true); - - Parser parser(new BlockReader((const char*) block, blocklen)); - Term* term = parser.ParseTerm(); - - if (!term) { - Print("ERROR: could not parse '%s'\n", filename); - return; - } - else { - TermText* file_type = term->isText(); - if (!file_type || file_type->value() != "WEAPON") { - Print("ERROR: invalid weapon design file '%s'\n", filename); - return; - } - } - - int type = 1; - degrees = false; - - do { - delete term; - - term = parser.ParseTerm(); - - if (term) { - TermDef* def = term->isDef(); - if (def) { - Text defname = def->name()->value(); - defname.setSensitive(false); - - if (defname == "primary" || - defname == "missile" || - defname == "drone" || - defname == "beam") { - - if (!def->term() || !def->term()->isStruct()) { - Print("WARNING: weapon structure missing in '%s'\n", filename); - } - else { - TermStruct* val = def->term()->isStruct(); - WeaponDesign* design = new WeaponDesign; - - design->type = type++; - if (defname == "primary") { - design->primary = true; - } - - else if (defname == "beam") { - design->primary = true; - design->beam = true; - design->guided = true; - - design->spread_az = 0.15f; - design->spread_el = 0.15f; - - } - - else if (defname == "drone") { - design->drone = true; - design->penetration = 5.0f; - } - - else { // missile - design->penetration = 5.0f; - } - - float sound_min_dist = 1.0f; - float sound_max_dist = 100.0e3f; - - for (int i = 0; i < val->elements()->size(); i++) { - TermDef* pdef = val->elements()->at(i)->isDef(); - if (pdef) { - defname = pdef->name()->value(); - defname.setSensitive(false); - - GET_DEF_TEXT(name); - else GET_DEF_TEXT(group); - else GET_DEF_TEXT(description); - else GET_DEF_NUM (guided); - else GET_DEF_BOOL(self_aiming); - else GET_DEF_BOOL(flak); - else GET_DEF_BOOL(syncro); - else GET_DEF_BOOL(visible_stores); - else GET_DEF_NUM (value); - - else if (defname==("degrees")) { - GetDefBool(degrees,pdef,filename); - } - - else if (defname==("secret")) { - GetDefBool(design->secret,pdef,filename); - } - - else if (defname==("aim_az_max")) { - GetDefNumber(design->aim_az_max,pdef,filename); - if (degrees) design->aim_az_max *= (float) DEGREES; - design->aim_az_min = 0.0f - design->aim_az_max; - } - - else if (defname==("aim_el_max")) { - GetDefNumber(design->aim_el_max,pdef,filename); - if (degrees) design->aim_el_max *= (float) DEGREES; - design->aim_el_min = 0.0f - design->aim_el_max; - } - - else if (defname==("aim_az_min")) { - GetDefNumber(design->aim_az_min,pdef,filename); - if (degrees) design->aim_az_min *= (float) DEGREES; - } - - else if (defname==("aim_el_min")) { - GetDefNumber(design->aim_el_min,pdef,filename); - if (degrees) design->aim_el_min *= (float) DEGREES; - } - - else if (defname==("aim_az_rest")) { - GetDefNumber(design->aim_az_rest,pdef,filename); - if (degrees) design->aim_az_rest *= (float) DEGREES; - } - - else if (defname==("aim_el_rest")) { - GetDefNumber(design->aim_el_rest,pdef,filename); - if (degrees) design->aim_el_rest *= (float) DEGREES; - } - - else if (defname==("spread_az")) { - GetDefNumber(design->spread_az,pdef,filename); - if (degrees) design->spread_az *= (float) DEGREES; - } - - else if (defname==("spread_el")) { - GetDefNumber(design->spread_el,pdef,filename); - if (degrees) design->spread_el *= (float) DEGREES; - } - - else GET_DEF_NUM (capacity); - else GET_DEF_NUM (recharge_rate); - else GET_DEF_NUM (refire_delay); - else GET_DEF_NUM (salvo_delay); - else GET_DEF_NUM (ammo); - else GET_DEF_NUM (ripple_count); - else GET_DEF_NUM (charge); - else GET_DEF_NUM (min_charge); - else GET_DEF_NUM (carry_mass); - else GET_DEF_NUM (carry_resist); - else GET_DEF_NUM (damage); - else GET_DEF_NUM (penetration); - else GET_DEF_NUM (speed); - else GET_DEF_NUM (life); - else GET_DEF_NUM (mass); - else GET_DEF_NUM (drag); - else GET_DEF_NUM (thrust); - else GET_DEF_NUM (roll_rate); - else GET_DEF_NUM (pitch_rate); - else GET_DEF_NUM (yaw_rate); - else GET_DEF_NUM (roll_drag); - else GET_DEF_NUM (pitch_drag); - else GET_DEF_NUM (yaw_drag); - else GET_DEF_NUM (lethal_radius); - else GET_DEF_NUM (integrity); - - else GET_DEF_NUM (det_range); - else GET_DEF_NUM (det_count); - else GET_DEF_NUM (det_spread); - else GET_DEF_TEXT(det_child); - - else GET_DEF_NUM (slew_rate); - - else GET_DEF_NUM (min_range); - else GET_DEF_NUM (max_range); - else GET_DEF_NUM (max_track); - - else GET_DEF_NUM (graphic_type); - else GET_DEF_NUM (width); - else GET_DEF_NUM (length); - else GET_DEF_NUM (scale); - else GET_DEF_NUM (explosion_scale); - else GET_DEF_NUM (light); - else GET_DEF_NUM (flash_scale); - else GET_DEF_NUM (flare_scale); - - else GET_DEF_NUM (trail_length); - else GET_DEF_NUM (trail_width); - else GET_DEF_NUM (trail_dim); - - else GET_DEF_TEXT(beauty); - else GET_DEF_TEXT(bitmap); - else GET_DEF_TEXT(turret); - else GET_DEF_TEXT(turret_base); - else GET_DEF_TEXT(model); - else GET_DEF_TEXT(trail); - else GET_DEF_TEXT(flash); - else GET_DEF_TEXT(flare); - else GET_DEF_TEXT(sound); - else GET_DEF_BOOL(probe); - else GET_DEF_NUM (turret_axis); - else GET_DEF_NUM (target_type); - - else if (defname == "animation") { - if (design->anim_length < 16) { - GetDefText(design->anim_frames[design->anim_length++], pdef, filename); - } - else { - Print("WARNING: too many animation frames for weapon '%s' in '%s'\n", - (const char*) design->name, filename); - } - } - - else if (defname == "light_color") - GetDefColor(design->light_color, pdef, filename); - - else if (defname == "sound_min_dist") - GetDefNumber(sound_min_dist,pdef,filename); - - else if (defname == "sound_max_dist") - GetDefNumber(sound_max_dist,pdef,filename); - - else if (defname == "muzzle") { - if (design->nbarrels < MAX_STORES) { - Vec3 a; - GetDefVec(a, pdef, filename); - design->muzzle_pts[design->nbarrels++] = a; - } - else { - Print("WARNING: too many muzzles for weapon '%s' in '%s'\n", - (const char*) design->name, filename); - } - } - - else if (defname == "attachment") { - if (design->nstores < MAX_STORES) { - Vec3 a; - GetDefVec(a, pdef, filename); - design->attachments[design->nstores++] = a; - } - else { - Print("WARNING: too many attachments for weapon '%s' in '%s'\n", - (const char*) design->name, filename); - } - } - - else if (defname == "eject") - GetDefVec(design->eject,pdef,filename); - - else if (defname == "decoy") { - char typestr[32]; - GetDefText(typestr, pdef, filename); - design->decoy_type = ShipDesign::ClassForName(typestr); - } - - else if (defname == "damage_type") { - char typestr[32]; - GetDefText(typestr, pdef, filename); - - if (!_stricmp(typestr, "normal")) - design->damage_type = DMG_NORMAL; - - else if (!_stricmp(typestr, "emp")) - design->damage_type = DMG_EMP; - - else if (!_stricmp(typestr, "power")) - design->damage_type = DMG_POWER; - - else - Print("WARNING: unknown weapon damage type '%s' in '%s'\n", - typestr, filename); - } - - - else { - Print("WARNING: parameter '%s' ignored in '%s'\n", - defname.data(), filename); - } - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - val->elements()->at(i)->print(); - } - } - - if (design->description.length()) { - design->description = ContentBundle::GetInstance()->GetText(design->description); - } - - if (design->anim_length > 0) { - design->animation = new Bitmap[design->anim_length]; - for (int i = 0; i < design->anim_length; i++) { - Bitmap* p = design->animation + i; - loader->LoadBitmap(design->anim_frames[i], *p, Bitmap::BMP_TRANSLUCENT); - p->MakeTexture(); - } - } - - else if (design->bitmap.length()) { - loader->LoadTexture(design->bitmap, design->shot_img, Bitmap::BMP_TRANSLUCENT); - } - - if (design->beauty.length()) { - loader->LoadTexture(design->beauty, design->beauty_img, Bitmap::BMP_TRANSLUCENT); - } - - if (design->turret.length()) { - Text p; - Text t = design->turret; - const char* s = strrchr(t.data(), '/'); - - if (s) { - p = Text(path) + t.substring(0, s-t.data()+1); - t = t.substring(s-t.data()+1, t.length()); - } - else { - s = strrchr(t.data(), '\\'); - - if (s) { - p = Text(path) + t.substring(0, s-t.data()+1); - t = t.substring(s-t.data()+1, t.length()); - } - } - - if (p.length()) - loader->SetDataPath(p); - - design->turret_model = new Model; - design->turret_model->Load(t, design->scale); - - if (design->turret_base.length()) { - t = design->turret_base; - s = strrchr(t.data(), '/'); - - if (s) { - p = Text(path) + t.substring(0, s-t.data()+1); - t = t.substring(s-t.data()+1, t.length()); - } - else { - s = strrchr(t.data(), '\\'); - - if (s) { - p = Text(path) + t.substring(0, s-t.data()+1); - t = t.substring(s-t.data()+1, t.length()); - } - } - - if (p.length()) - loader->SetDataPath(p); - - design->turret_base_model = new Model; - design->turret_base_model->Load(t, design->scale); - } - - loader->SetDataPath(path); - } - - if (design->model.length()) { - Text p; - Text t = design->model; - const char* s = strrchr(t.data(), '/'); - - if (s) { - p = Text(path) + t.substring(0, s-t.data()+1); - t = t.substring(s-t.data()+1, t.length()); - } - else { - s = strrchr(t.data(), '\\'); - - if (s) { - p = Text(path) + t.substring(0, s-t.data()+1); - t = t.substring(s-t.data()+1, t.length()); - } - } - - if (p.length()) - loader->SetDataPath(p); - - design->shot_model = new Model; - design->shot_model->Load(t, design->scale); - - loader->SetDataPath(path); - } - - if (design->trail.length()) { - loader->LoadTexture(design->trail, design->trail_img, Bitmap::BMP_TRANSLUCENT); - } - - if (design->flash.length()) { - loader->LoadTexture(design->flash, design->flash_img, Bitmap::BMP_TRANSLUCENT); - } - - if (design->flare.length()) { - loader->LoadTexture(design->flare, design->flare_img, Bitmap::BMP_TRANSLUCENT); - } - - if (design->sound.length()) { - int SOUND_FLAGS = Sound::LOCALIZED | Sound::LOC_3D; - - if (design->beam) - SOUND_FLAGS = Sound::LOCALIZED | Sound::LOC_3D | Sound::LOCKED; - - if (strstr(path, "Mods") == 0) - loader->SetDataPath("Sounds/"); - loader->LoadSound(design->sound, design->sound_resource, SOUND_FLAGS); - loader->SetDataPath(path); - - if (design->sound_resource) { - design->sound_resource->SetMinDistance(sound_min_dist); - design->sound_resource->SetMaxDistance(sound_max_dist); - } - } - - if (design->max_range == 0.0f) - design->max_range = design->speed * design->life; - - if (design->max_track == 0.0f) - design->max_track = 3.0f * design->max_range; - - if (design->probe && design->lethal_radius < 1e3) - design->lethal_radius = 50e3f; - - if (design->beam) - design->flak = false; - - if (design->self_aiming) { - if (fabs(design->aim_az_max) > design->firing_cone) - design->firing_cone = (float) fabs(design->aim_az_max); - - if (fabs(design->aim_az_min) > design->firing_cone) - design->firing_cone = (float) fabs(design->aim_az_min); - - if (fabs(design->aim_el_max) > design->firing_cone) - design->firing_cone = (float) fabs(design->aim_el_max); - - if (fabs(design->aim_el_min) > design->firing_cone) - design->firing_cone = (float) fabs(design->aim_el_min); - } - - if (mod) - mod_catalog.append(design); - else - catalog.append(design); - } - } - - else - Print("WARNING: unknown definition '%s' in '%s'\n", - def->name()->value().data(), filename); - } - else { - Print("WARNING: term ignored in '%s'\n", filename); - term->print(); - } - } - } - while (term); - - loader->ReleaseBuffer(block); - loader->SetDataPath(0); -} - -// +--------------------------------------------------------------------+ - -WeaponDesign* -WeaponDesign::Get(int type) -{ - WeaponDesign test; - test.type = type; - - WeaponDesign* result = catalog.find(&test); - - if (!result) - result = mod_catalog.find(&test); - - return result; -} - -// +--------------------------------------------------------------------+ - -WeaponDesign* -WeaponDesign::Find(const char* name) -{ - for (int i = 0; i < catalog.size(); i++) { - WeaponDesign* d = catalog.at(i); - - if (d->name == name) { - return d; - } - } - - for (int i = 0; i < mod_catalog.size(); i++) { - WeaponDesign* d = mod_catalog.at(i); - - if (d->name == name) { - return d; - } - } - - Print("WeaponDesign: no catalog entry for design '%s', checking mods...\n", name); - return WeaponDesign::FindModDesign(name); -} - -WeaponDesign* -WeaponDesign::FindModDesign(const char* name) -{ - Text fname = name; - fname += ".def"; - - LoadDesign("Mods/Weapons/", fname, true); - - for (int i = 0; i < mod_catalog.size(); i++) { - WeaponDesign* d = mod_catalog.at(i); - - if (d->name == name) { - Print("WeaponDesign: found mod weapon '%s'\n", d->name.data()); - return d; - } - } - - Print("WeaponDesign: no mod found for design '%s'\n", name); - return 0; -} - -// +--------------------------------------------------------------------+ - -int -WeaponDesign::GetDesignList(List& designs) -{ - designs.clear(); - - for (int i = 0; i < catalog.size(); i++) { - WeaponDesign* design = catalog[i]; - designs.append(&design->name); - } - - for (int i = 0; i < mod_catalog.size(); i++) { - WeaponDesign* design = mod_catalog[i]; - designs.append(&design->name); - } - - return designs.size(); -} diff --git a/Stars45/WeaponDesign.h b/Stars45/WeaponDesign.h deleted file mode 100644 index 712d220..0000000 --- a/Stars45/WeaponDesign.h +++ /dev/null @@ -1,186 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon (gun or missile launcher) Design parameters class -*/ - -#ifndef WeaponDesign_h -#define WeaponDesign_h - -#include "Types.h" -#include "Geometry.h" -#include "Color.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Bitmap; -class Model; -class Sound; - -// +--------------------------------------------------------------------+ - -class WeaponDesign -{ -public: - static const char* TYPENAME() { return "WeaponDesign"; } - - enum CONSTANTS { - DMG_NORMAL=0, - DMG_EMP =1, - DMG_POWER =2, - MAX_STORES=8 - }; - - WeaponDesign(); - ~WeaponDesign(); - int operator == (const WeaponDesign& rhs) const { return (type == rhs.type) || - (name == rhs.name); } - - static void Initialize(const char* filename); - static void Close(); - - static WeaponDesign* Get(int type); - static WeaponDesign* Find(const char* name); - static WeaponDesign* FindModDesign(const char* name); - static void ClearModCatalog(); - static int GetDesignList(List& designs); - - // identification: - int type; // unique id - Text name; - Text group; - Text description; // background info for tactical reference - bool secret; // don't display in the tactical reference - - bool drone; // visible to sensors? - bool primary; // laser or missile? - bool beam; // if laser, beam or bolt? - bool self_aiming; // turret or fixed? - bool syncro; // fire all barrels? - bool flak; // splash damage - int guided; // straight, pure pursuit, lead pursuit - int value; // AI importance of system - int decoy_type; // Ship Classifcation of decoy signature - bool probe; // is sensor probe? - DWORD target_type; // bitmask of acceptable target classes - - // for turrets: - Vec3 muzzle_pts[MAX_STORES]; // default turret muzzle points - int nbarrels; // number of barrels on the turret - - // for missile hard points: - bool visible_stores; // are external stores visible? - Vec3 attachments[MAX_STORES]; // attachment points on the rail - int nstores; // number of stores on this hard point - Vec3 eject; // eject velocity from rail in 3D - - // auto-aiming arc - float firing_cone; // maximum deflection in any orientation - float aim_az_max; // maximum deflection in azimuth - float aim_az_min; // minimum deflection in azimuth - float aim_az_rest; // azimuth of turret at rest - float aim_el_max; // maximum deflection in elevation - float aim_el_min; // minimum deflection in elevation - float aim_el_rest; // elevation of turret at rest - float slew_rate; // max rate of turret slew in rad/sec - int turret_axis; // 0=az 1=el 2=not supported - - // functional parameters: - float capacity; // full charge (joules) - float recharge_rate; // watts - float refire_delay; // seconds - mechanical limit - float salvo_delay; // seconds - ai refire time - int ammo; - int ripple_count; // number of rounds per salvo - - // carrying costs per shot: - float charge; // energy cost of full charge - float min_charge; // minimum energy needed to fire - float carry_mass; - float carry_resist; - - // shot parameters: - int damage_type; // 0: normal, 1: EMP, 2: power drain - float damage; // if beam, damage per second; - // else, damage per shot. - float penetration; // ability to pierce shields, 1 is default - float speed; - float life; - float mass; - float drag; - float thrust; - float roll_rate; - float pitch_rate; - float yaw_rate; - float roll_drag; - float pitch_drag; - float yaw_drag; - float integrity; // hit points for drones = 100 - float lethal_radius; // detonation range for missiles - - float det_range; // detonation range for cluster weapons - Text det_child; // type of submunition - int det_count; // number of submunitions - float det_spread; // spread of submunition deployment - - // HUD parameters: - float min_range; - float max_range; - float max_track; - - // shot representation: - int graphic_type; // sprite or blob? - float width; // blob width - float length; // blob length - float scale; // sprite scale - float explosion_scale; // scale factor for damage to this drone - float light; // light emitted by shot - Color light_color; // color of light emitted by shot - float flash_scale; // size of muzzle flash sprite - float flare_scale; // size of drive flare sprite - - float spread_az; // spread range in radians - float spread_el; // spread range in radians - - Text anim_frames[16]; - int anim_length; - Text beauty; - Text bitmap; - Text model; - Text turret; - Text turret_base; - Text trail; - Text flash; - Text flare; - Text sound; - - Bitmap* beauty_img; - Bitmap* animation; - Bitmap* shot_img; - Bitmap* trail_img; - Bitmap* flash_img; - Bitmap* flare_img; - Model* shot_model; - Model* turret_model; - Model* turret_base_model; - Sound* sound_resource; - - int trail_length; - float trail_width; - int trail_dim; - -private: - static void LoadDesign(const char* path, const char* filename, bool mod=false); -}; - -#endif // WeaponDesign_h - diff --git a/Stars45/WeaponGroup.cpp b/Stars45/WeaponGroup.cpp deleted file mode 100644 index 5519c68..0000000 --- a/Stars45/WeaponGroup.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon Control Category (Group) class -*/ - -#include "WeaponGroup.h" -#include "Ship.h" - -// +----------------------------------------------------------------------+ - -WeaponGroup::WeaponGroup(const char* n) - : selected(0), trigger(false), orders(Weapon::MANUAL), - control(Weapon::SINGLE_FIRE), sweep(Weapon::SWEEP_TIGHT), - mass(0.0f), resist(0.0f), name(n), ammo(0) -{ } - -// +--------------------------------------------------------------------+ - -WeaponGroup::~WeaponGroup() -{ - weapons.destroy(); -} - -// +--------------------------------------------------------------------+ - -void -WeaponGroup::SetName(const char* n) -{ - name = n; -} - -void -WeaponGroup::SetAbbreviation(const char* a) -{ - abrv = a; -} - -// +--------------------------------------------------------------------+ - -bool -WeaponGroup::IsPrimary() const -{ - if (weapons.size() > 0) - return weapons[0]->IsPrimary(); - - return false; -} - -bool -WeaponGroup::IsDrone() const -{ - if (weapons.size() > 0) - return weapons[0]->IsDrone(); - - return false; -} - -bool -WeaponGroup::IsDecoy() const -{ - if (weapons.size() > 0) - return weapons[0]->IsDecoy(); - - return false; -} - -bool -WeaponGroup::IsProbe() const -{ - if (weapons.size() > 0) - return weapons[0]->IsProbe(); - - return false; -} - -bool -WeaponGroup::IsMissile() const -{ - if (weapons.size() > 0) - return weapons[0]->IsMissile(); - - return false; -} - -bool -WeaponGroup::IsBeam() const -{ - if (weapons.size() > 0) - return weapons[0]->IsBeam(); - - return false; -} - -// +--------------------------------------------------------------------+ - -void -WeaponGroup::AddWeapon(Weapon* w) -{ - weapons.append(w); -} - -int -WeaponGroup::NumWeapons() const -{ - return weapons.size(); -} - -List& -WeaponGroup::GetWeapons() -{ - return weapons; -} - -bool -WeaponGroup::Contains(const Weapon* w) const -{ - return weapons.contains(w)?true:false; -} - -// +--------------------------------------------------------------------+ - -void -WeaponGroup::SelectWeapon(int n) -{ - if (n >= 0 && n < weapons.size()) - selected = n; -} - -void -WeaponGroup::CycleWeapon() -{ - selected++; - - if (selected >= weapons.size()) - selected = 0; -} - -Weapon* -WeaponGroup::GetWeapon(int n) const -{ - if (n >= 0 && n < weapons.size()) - return weapons[n]; - - return 0; -} - -Weapon* -WeaponGroup::GetSelected() const -{ - return weapons[selected]; -} - -bool -WeaponGroup::CanTarget(DWORD tgt_class) const -{ - if (selected >= 0 && selected < weapons.size()) - return weapons[selected]->CanTarget(tgt_class); - - return false; -} - -// +--------------------------------------------------------------------+ - -void -WeaponGroup::ExecFrame(double seconds) -{ - ammo = 0; - mass = 0.0f; - resist = 0.0f; - - ListIter iter = weapons; - while (++iter) { - Weapon* w = iter.value(); - w->ExecFrame(seconds); - - ammo += w->Ammo(); - mass += w->Mass(); - resist += w->Resistance(); - } -} - -void -WeaponGroup::CheckAmmo() -{ - ammo = 0; - mass = 0.0f; - resist = 0.0f; - - ListIter iter = weapons; - while (++iter) { - Weapon* w = iter.value(); - - ammo += w->Ammo(); - mass += w->Mass(); - resist += w->Resistance(); - } -} - -// +--------------------------------------------------------------------+ - -void -WeaponGroup::SetTarget(SimObject* target, System* subtarget) -{ - ListIter w = weapons; - while (++w) - w->SetTarget(target, subtarget); -} - -SimObject* -WeaponGroup::GetTarget() const -{ - SimObject* target = 0; - - if (weapons.size()) - target = weapons[0]->GetTarget(); - - return target; -} - -System* -WeaponGroup::GetSubTarget() const -{ - System* subtarget = 0; - - if (weapons.size()) - subtarget = weapons[0]->GetSubTarget(); - - return subtarget; -} - -void -WeaponGroup::DropTarget() -{ - ListIter w = weapons; - while (++w) - w->SetTarget(0, 0); -} - -// +--------------------------------------------------------------------+ - -WeaponDesign* -WeaponGroup::GetDesign() const -{ - if (selected >= 0 && selected < weapons.size()) - return (WeaponDesign*) weapons[selected]->Design(); - - return 0; -} - -// +--------------------------------------------------------------------+ - -int -WeaponGroup::Status() const -{ - int status = System::NOMINAL; - int critical = true; - - ListIter iter = (List&) weapons; // cast-away const - while (++iter) { - Weapon* w = iter.value(); - - if (w->Status() < System::NOMINAL) - status = System::DEGRADED; - - if (w->Status() > System::CRITICAL) - critical = false; - } - - if (critical) - return System::CRITICAL; - - return status; -} - -// +--------------------------------------------------------------------+ - -void -WeaponGroup::SetFiringOrders(int o) -{ - orders = o; - - ListIter w = weapons; - while (++w) - w->SetFiringOrders(orders); -} - -void -WeaponGroup::SetControlMode(int m) -{ - control = m; - - ListIter w = weapons; - while (++w) - w->SetControlMode(control); -} - -void -WeaponGroup::SetSweep(int s) -{ - sweep = s; - - ListIter w = weapons; - while (++w) - w->SetSweep(sweep); -} - -// +--------------------------------------------------------------------+ - -void -WeaponGroup::PowerOff() -{ - ListIter w = weapons; - while (++w) - w->PowerOff(); -} - -void -WeaponGroup::PowerOn() -{ - ListIter w = weapons; - while (++w) - w->PowerOn(); -} - -// +--------------------------------------------------------------------+ - -int -WeaponGroup::Value() const -{ - int result = 0; - - for (int i = 0; i < weapons.size(); i++) { - const Weapon* w = weapons[i]; - result += w->Value(); - } - - return result; -} diff --git a/Stars45/WeaponGroup.h b/Stars45/WeaponGroup.h deleted file mode 100644 index 7b2b1bd..0000000 --- a/Stars45/WeaponGroup.h +++ /dev/null @@ -1,105 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Weapon Control Category (Group) class -*/ - -#ifndef WeaponGroup_h -#define WeaponGroup_h - -#include "Types.h" -#include "Weapon.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class WeaponGroup -{ -public: - static const char* TYPENAME() { return "WeaponGroup"; } - - WeaponGroup(const char* name); - ~WeaponGroup(); - - void ExecFrame(double factor); - - // identification: - const char* Name() const { return name; } - const char* Abbreviation() const { return abrv; } - void SetName(const char* n); - void SetAbbreviation(const char* a); - - bool IsPrimary() const; - bool IsDrone() const; - bool IsDecoy() const; - bool IsProbe() const; - bool IsMissile() const; - bool IsBeam() const; - int Value() const; - - // weapon list: - void AddWeapon(Weapon* w); - int NumWeapons() const; - List& GetWeapons(); - bool Contains(const Weapon* w) const; - - // weapon selection: - void SelectWeapon(int n); - void CycleWeapon(); - Weapon* GetWeapon(int n) const; - Weapon* GetSelected() const; - - // operations: - bool GetTrigger() const { return trigger; } - void SetTrigger(bool t=true) { trigger = t; } - int Ammo() const { return ammo; } - float Mass() const { return mass; } - float Resistance() const { return resist; } - void CheckAmmo(); - - void SetTarget(SimObject* t, System* sub=0); - SimObject* GetTarget() const; - System* GetSubTarget() const; - void DropTarget(); - void SetFiringOrders(int o); - int GetFiringOrders() const { return orders; } - void SetControlMode(int m); - int GetControlMode() const { return control; } - void SetSweep(int s); - int GetSweep() const { return sweep; } - int Status() const; - - WeaponDesign* GetDesign() const; - bool CanTarget(DWORD tgt_class) const; - - void PowerOn(); - void PowerOff(); - -protected: - // Displayable name: - Text name; - Text abrv; - - List weapons; - - int selected; - bool trigger; - int ammo; - - int orders; - int control; - int sweep; - - float mass; - float resist; -}; - -#endif // WeaponGroup_h - diff --git a/Stars45/Weather.cpp b/Stars45/Weather.cpp deleted file mode 100644 index b894b3e..0000000 --- a/Stars45/Weather.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Manages local weather conditions according to the system stardate -*/ - -#include "Weather.h" -#include "StarSystem.h" -#include "Game.h" -#include "ContentBundle.h" - -// +--------------------------------------------------------------------+ - -Weather::Weather() -{ - state = CLEAR; - period = 7 * 20 * 3600; - ceiling = 0; - visibility = 1; - - for (int i = 0; i < NUM_STATES; i++) - chances[i] = 0; - - chances[0] = 1; -} - -// +--------------------------------------------------------------------+ - -Weather::~Weather() -{ } - -// +--------------------------------------------------------------------+ - -void -Weather::SetChance(int n, double c) -{ - if (n >= 0 && n < NUM_STATES) { - if (c > 1 && c <= 100) - chances[n] = c / 100; - - else if (c < 1) - chances[n] = c; - } -} - -void -Weather::NormalizeChances() -{ - double total = 0; - - for (int i = 1; i < NUM_STATES; i++) - total += chances[i]; - - if (total <= 1) { - chances[0] = 1 - total; - } - - else { - chances[0] = 0; - - for (int i = 1; i < NUM_STATES; i++) - chances[i] /= total; - } - - int index = 0; - double level = 0; - - for (int i = 0; i < NUM_STATES; i++) { - if (chances[i] > 0) { - level += chances[i]; - - active_states[index] = (STATE) i; - thresholds[index] = level; - - index++; - } - } - - while (index < NUM_STATES) - thresholds[index++] = 10; -} - -// +--------------------------------------------------------------------+ - -void -Weather::Update() -{ - NormalizeChances(); - - double weather = (sin(StarSystem::Stardate() * 2 * PI / period)+1)/2; - - state = active_states[0]; - - for (int i = 1; i < NUM_STATES; i++) { - if (weather > thresholds[i-1] && weather <= thresholds[i]) { - state = active_states[i]; - break; - } - } - - switch (state) { - default: - case CLEAR: - ceiling = 0; - visibility = 1.0; - break; - - case HIGH_CLOUDS: - ceiling = 0; - visibility = 0.9; - break; - - case MODERATE_CLOUDS: - ceiling = 0; - visibility = 0.8; - break; - - case OVERCAST: - ceiling = 6000; - visibility = 0.7; - break; - - case FOG: - ceiling = 3500; - visibility = 0.6; - break; - - case STORM: - ceiling = 7500; - visibility = 0.5; - break; - } -} - -// +--------------------------------------------------------------------+ - -Text -Weather::Description() const -{ - Text description; - - switch (state) { - default: - case CLEAR: - description = ContentBundle::GetInstance()->GetText("weather.clear"); - break; - - case HIGH_CLOUDS: - description = ContentBundle::GetInstance()->GetText("weather.high-clouds"); - break; - - case MODERATE_CLOUDS: - description = ContentBundle::GetInstance()->GetText("weather.partly-cloudy"); - break; - - case OVERCAST: - description = ContentBundle::GetInstance()->GetText("weather.overcast"); - break; - - case FOG: - description = ContentBundle::GetInstance()->GetText("weather.fog"); - break; - - case STORM: - description = ContentBundle::GetInstance()->GetText("weather.storm"); - break; - } - - return description; -} \ No newline at end of file diff --git a/Stars45/Weather.h b/Stars45/Weather.h deleted file mode 100644 index e10da74..0000000 --- a/Stars45/Weather.h +++ /dev/null @@ -1,66 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Manages local weather conditions according to the system stardate -*/ - -#ifndef Weather_h -#define Weather_h - -#include "Types.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class Weather -{ -public: - Weather(); - virtual ~Weather(); - - enum STATE { CLEAR, - HIGH_CLOUDS, - MODERATE_CLOUDS, - OVERCAST, - FOG, - STORM, - - NUM_STATES - }; - - virtual void Update(); - - // accessors: - STATE State() const { return state; } - Text Description() const; - double Period() const { return period; } - double Chance(STATE s) const { return chances[(int)s]; } - double Ceiling() const { return ceiling; } - double Visibility() const { return visibility; } - - void SetPeriod(double p) { period = p; } - void SetChance(int n, double c); - -protected: - void NormalizeChances(); - - STATE state; - double period; - double chances[NUM_STATES]; - double ceiling; - double visibility; - - STATE active_states[NUM_STATES]; - double thresholds[NUM_STATES]; -}; - - -#endif // Weather_h - diff --git a/Stars45/WebBrowser.cpp b/Stars45/WebBrowser.cpp deleted file mode 100644 index fba3d71..0000000 --- a/Stars45/WebBrowser.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Helper class to find and launch user's default web browser -*/ - -#include "WebBrowser.h" - -// +--------------------------------------------------------------------+ - -WebBrowser::WebBrowser() -{ - FindDefaultBrowser(); - FindOpenCommand(); -} - -WebBrowser::~WebBrowser() -{ -} - -// +--------------------------------------------------------------------+ - - -void -WebBrowser::OpenURL(const char* url) -{ - if (url) { - char cmdline[256]; - - if (command.contains("%1")) { - strcpy_s(cmdline, command.replace("%1", url).data()); - } - else { - strcpy_s(cmdline, Text(command + " " + url).data()); - } - - STARTUPINFO s; - ZeroMemory(&s, sizeof(s)); - s.cb = sizeof(s); - - PROCESS_INFORMATION pi; - ZeroMemory(&pi, sizeof(pi)); - - if (CreateProcess(NULL, cmdline, 0, 0, 0, 0, 0, 0, &s, &pi)) { - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - } - else { - ::Print("Unable to launch web browser for url '%s'\n", url); - } - } -} - -// +--------------------------------------------------------------------+ - -void -WebBrowser::FindDefaultBrowser() -{ - HKEY hkey; - char value[256] = ""; - DWORD dwSize; - - ZeroMemory(value, 256); - - if (RegOpenKeyEx(HKEY_CLASSES_ROOT, - ".html", - 0, - KEY_READ, - &hkey) == ERROR_SUCCESS) { - - dwSize = 256; - RegQueryValueEx(hkey, - "", - NULL, - NULL, - (LPBYTE) value, - &dwSize); - - RegCloseKey(hkey); - - if (dwSize > 0) { - ::Print("Default Web Browser: %s\n", value); - browser = value; - } - } -} - -// +--------------------------------------------------------------------+ - -void -WebBrowser::FindOpenCommand() -{ - HKEY hkey; - char value[256] = ""; - DWORD dwSize; - - ZeroMemory(value, 256); - - if (RegOpenKeyEx(HKEY_CLASSES_ROOT, - browser + "\\shell\\open\\command", - 0, - KEY_READ, - &hkey) == ERROR_SUCCESS) { - - dwSize = 256; - RegQueryValueEx(hkey, - "", - NULL, - NULL, - (LPBYTE) value, - &dwSize); - - RegCloseKey(hkey); - - if (dwSize > 0) { - ::Print("Browser Shell Open Command: %s\n", value); - command = value; - } - } -} - -// +--------------------------------------------------------------------+ - - diff --git a/Stars45/WebBrowser.h b/Stars45/WebBrowser.h deleted file mode 100644 index 6ea731f..0000000 --- a/Stars45/WebBrowser.h +++ /dev/null @@ -1,45 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Helper class to find and launch user's default web browser -*/ - -#ifndef WebBrowser_h -#define WebBrowser_h - -#include "Types.h" -#include "List.h" -#include "Text.h" - -// +--------------------------------------------------------------------+ - -class WebBrowser -{ -public: - static const char* TYPENAME() { return "WebBrowser"; } - - WebBrowser(); - virtual ~WebBrowser(); - - virtual void OpenURL(const char* url); - -protected: - void FindDefaultBrowser(); - void FindOpenCommand(); - - Text browser; - Text command; -}; - -// +--------------------------------------------------------------------+ - -#endif // WebBrowser_h - - diff --git a/Stars45/WepView.cpp b/Stars45/WepView.cpp deleted file mode 100644 index 2da3b61..0000000 --- a/Stars45/WepView.cpp +++ /dev/null @@ -1,529 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Tactical HUD Overlay -*/ - -#include "WepView.h" -#include "HUDView.h" -#include "HUDSounds.h" -#include "Ship.h" -#include "Computer.h" -#include "NavSystem.h" -#include "Drive.h" -#include "Power.h" -#include "Shield.h" -#include "Contact.h" -#include "ShipDesign.h" -#include "Shot.h" -#include "Drone.h" -#include "Weapon.h" -#include "Sim.h" -#include "StarSystem.h" -#include "WeaponGroup.h" - -#include "CameraView.h" -#include "Color.h" -#include "Window.h" -#include "Video.h" -#include "Screen.h" -#include "DataLoader.h" -#include "Scene.h" -#include "FontMgr.h" -#include "Graphic.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Clock.h" -#include "FormatUtil.h" - -static Bitmap tac_left; -static Bitmap tac_right; -static Bitmap tac_button; -static Bitmap tac_man; -static Bitmap tac_aut; -static Bitmap tac_def; - -static BYTE* tac_left_shade; -static BYTE* tac_right_shade; -static BYTE* tac_button_shade; -static BYTE* tac_man_shade; -static BYTE* tac_aut_shade; -static BYTE* tac_def_shade; - -static Color hud_color = Color::Black; -static Color txt_color = Color::Black; - -static bool mouse_in = false; - -static Font* hud_font = 0; -static Font* big_font = 0; - -// +--------------------------------------------------------------------+ - -WepView* WepView::wep_view = 0; - -// +--------------------------------------------------------------------+ - -WepView::WepView(Window* c) -: View(c), sim(0), ship(0), target(0), active_region(0), -transition(false), mode(0), mouse_down(0) -{ - wep_view = this; - - sim = Sim::GetSim(); - - HUDView::PrepareBitmap("TAC_left.pcx", tac_left, tac_left_shade); - HUDView::PrepareBitmap("TAC_right.pcx", tac_right, tac_right_shade); - HUDView::PrepareBitmap("TAC_button.pcx", tac_button, tac_button_shade); - HUDView::PrepareBitmap("MAN.pcx", tac_man, tac_man_shade); - HUDView::PrepareBitmap("AUTO.pcx", tac_aut, tac_aut_shade); - HUDView::PrepareBitmap("DEF.pcx", tac_def, tac_def_shade); - - tac_left.SetType(Bitmap::BMP_TRANSLUCENT); - tac_right.SetType(Bitmap::BMP_TRANSLUCENT); - tac_man.SetType(Bitmap::BMP_TRANSLUCENT); - tac_aut.SetType(Bitmap::BMP_TRANSLUCENT); - tac_def.SetType(Bitmap::BMP_TRANSLUCENT); - - OnWindowMove(); - - hud_font = FontMgr::Find("HUD"); - big_font = FontMgr::Find("GUI"); - - hud = HUDView::GetInstance(); - if (hud) - SetColor(hud->GetHUDColor()); -} - -WepView::~WepView() -{ - tac_left.ClearImage(); - tac_right.ClearImage(); - tac_button.ClearImage(); - tac_man.ClearImage(); - tac_aut.ClearImage(); - tac_def.ClearImage(); - - delete [] tac_left_shade; - delete [] tac_right_shade; - delete [] tac_button_shade; - delete [] tac_man_shade; - delete [] tac_aut_shade; - delete [] tac_def_shade; - - tac_left_shade = 0; - tac_right_shade = 0; - tac_button_shade = 0; - tac_man_shade = 0; - tac_aut_shade = 0; - tac_def_shade = 0; - - wep_view = 0; -} - -void -WepView::OnWindowMove() -{ - width = window->Width(); - height = window->Height(); - xcenter = (width / 2.0) - 0.5; - ycenter = (height / 2.0) + 0.5; - - int btn_loc = width/2 - 147 - 45; - int man_loc = width/2 - 177 - 16; - int aut_loc = width/2 - 145 - 16; - int def_loc = width/2 - 115 - 16; - - int index = 0; - - for (int i = 0; i < MAX_WEP; i++) { - btn_rect[index++] = Rect(btn_loc, 30, 90, 20); - btn_rect[index++] = Rect(man_loc, 56, 32, 8); - btn_rect[index++] = Rect(aut_loc, 56, 32, 8); - btn_rect[index++] = Rect(def_loc, 56, 32, 8); - - btn_loc += 98; - man_loc += 98; - aut_loc += 98; - def_loc += 98; - } -} - -// +--------------------------------------------------------------------+ - -bool -WepView::Update(SimObject* obj) -{ - if (obj == ship) { - ship = 0; - target = 0; - } - else if (obj == target) { - target = 0; - } - - return SimObserver::Update(obj); -} - -const char* -WepView::GetObserverName() const -{ - return "WepView"; -} - -// +--------------------------------------------------------------------+ - -void -WepView::Refresh() -{ - sim = Sim::GetSim(); - if (!sim || !hud || hud->GetHUDMode() == HUDView::HUD_MODE_OFF) - return; - - if (ship != sim->GetPlayerShip()) { - ship = sim->GetPlayerShip(); - - if (ship) { - if (ship->Life() == 0 || ship->IsDying() || ship->IsDead()) { - ship = 0; - } - else { - Observe(ship); - } - } - } - - if (mode < 1) - return; - - if (ship) { - // no tactical overlay for fighters: - if (ship->Design() && !ship->Design()->wep_screen) { - mode = 0; - return; - } - - // no hud in transition: - if (ship->InTransition()) { - transition = true; - return; - } - - else if (transition) { - transition = false; - RestoreOverlay(); - } - - if (target != ship->GetTarget()) { - target = ship->GetTarget(); - if (target) Observe(target); - } - - DrawOverlay(); - } - else { - if (target) { - target = 0; - } - } -} - -// +--------------------------------------------------------------------+ - -void -WepView::ExecFrame() -{ - int hud_mode = 1; - - // update the position of HUD elements that are - // part of the 3D scene (like fpm and lcos sprites) - - if (hud) { - if (hud_color != hud->GetHUDColor()) { - hud_color = hud->GetHUDColor(); - SetColor(hud_color); - } - - if (hud->GetHUDMode() == HUDView::HUD_MODE_OFF) - hud_mode = 0; - } - - if (ship && !transition && mode > 0 && hud_mode > 0) { - if (mode > 0) { - DoMouseFrame(); - } - } -} - -// +--------------------------------------------------------------------+ - -void -WepView::SetOverlayMode(int m) -{ - if (mode != m) { - mode = m; - - if (hud) - hud->SetOverlayMode(mode); - - RestoreOverlay(); - } -} - -void -WepView::CycleOverlayMode() -{ - SetOverlayMode(!mode); -} - -void -WepView::RestoreOverlay() -{ - if (mode > 0) { - HUDSounds::PlaySound(HUDSounds::SND_WEP_DISP); - } - - else { - HUDSounds::PlaySound(HUDSounds::SND_WEP_MODE); - } -} - -// +--------------------------------------------------------------------+ - -void -WepView::SetColor(Color c) -{ - HUDView* hud = HUDView::GetInstance(); - - if (hud) { - hud_color = hud->GetHUDColor(); - txt_color = hud->GetTextColor(); - } - else { - hud_color = c; - txt_color = c; - } - - HUDView::ColorizeBitmap(tac_left, tac_left_shade, hud_color); - HUDView::ColorizeBitmap(tac_right, tac_right_shade, hud_color); - HUDView::ColorizeBitmap(tac_button, tac_button_shade, hud_color); - HUDView::ColorizeBitmap(tac_man, tac_man_shade, hud_color); - HUDView::ColorizeBitmap(tac_aut, tac_aut_shade, hud_color); - HUDView::ColorizeBitmap(tac_def, tac_def_shade, hud_color); -} - -// +--------------------------------------------------------------------+ - -void -WepView::DrawOverlay() -{ - int cx = width/2; - int cy = 0; - int w = tac_left.Width(); - int h = tac_left.Height(); - - window->DrawBitmap(cx-w, cy, cx, cy+h, &tac_left, Video::BLEND_ALPHA); - window->DrawBitmap(cx, cy, cx+w, cy+h, &tac_right, Video::BLEND_ALPHA); - - if (ship) { - List& weapons = ship->Weapons(); - for (int i = 0; i < MAX_WEP; i++) { - if (weapons.size() > i) { - // draw main fire button: - Rect r = btn_rect[i*4]; - - w = tac_button.Width(); - h = tac_button.Height(); - cx = r.x + r.w/2 - w/2; - cy = r.y + r.h/2 - h/2; - - r.Deflate(5,5); - - big_font->SetColor(txt_color); - window->SetFont(big_font); - window->DrawBitmap(cx, cy, cx+w, cy+h, &tac_button, Video::BLEND_ALPHA); - window->DrawText(weapons[i]->Name(), 0, r, DT_SINGLELINE | DT_CENTER); - - r.Inflate(5,5); - - // draw firing orders: - int o = weapons[i]->GetFiringOrders(); - w = tac_man.Width(); - h = tac_man.Height(); - - Color c0 = Color::Gray; - Color c1 = Color::White; - - r = btn_rect[i*4 + 1]; - cx = r.x + r.w/2 - w/2; - cy = r.y + r.h/2 - h/2; - window->FadeBitmap(cx, cy, cx+w, cy+h, &tac_man, (o==0 ? c1 : c0), Video::BLEND_ALPHA); - - r = btn_rect[i*4 + 2]; - cx = r.x + r.w/2 - w/2; - cy = r.y + r.h/2 - h/2; - window->FadeBitmap(cx, cy, cx+w, cy+h, &tac_aut, (o==1 ? c1 : c0), Video::BLEND_ALPHA); - - r = btn_rect[i*4 + 3]; - cx = r.x + r.w/2 - w/2; - cy = r.y + r.h/2 - h/2; - window->FadeBitmap(cx, cy, cx+w, cy+h, &tac_def, (o==2 ? c1 : c0), Video::BLEND_ALPHA); - } - } - - Rect tgt_rect; - tgt_rect.x = width/2 + 73; - tgt_rect.y = 74; - tgt_rect.w = 100; - tgt_rect.h = 15; - - Text subtxt; - Color stat = hud_color; - static DWORD blink = Clock::GetInstance()->RealTime(); - - if (ship->GetTarget()) { - if (ship->GetSubTarget()) { - int blink_delta = Clock::GetInstance()->RealTime() - blink; - - System* sys = ship->GetSubTarget(); - subtxt = sys->Abbreviation(); - switch (sys->Status()) { - case System::DEGRADED: stat = Color(255,255, 0); break; - case System::CRITICAL: - case System::DESTROYED: stat = Color(255, 0, 0); break; - case System::MAINT: - if (blink_delta < 250) - stat = Color(8,8,8); - break; - } - - if (blink_delta > 500) - blink = Clock::GetInstance()->RealTime(); - } - - else - subtxt = ship->GetTarget()->Name(); - } - else { - subtxt = "NO TGT"; - } - - subtxt.toUpper(); - - hud_font->SetColor(stat); - window->SetFont(hud_font); - window->DrawText(subtxt.data(), subtxt.length(), tgt_rect, DT_SINGLELINE | DT_CENTER); - } -} - -// +--------------------------------------------------------------------+ - -void -WepView::DoMouseFrame() -{ - static int mouse_down = false; - static int mouse_down_x = 0; - static int mouse_down_y = 0; - - int x = Mouse::X(); - int y = Mouse::Y(); - - // coarse-grained test: is mouse in overlay at all? - if (x < width/2-256 || x > width/2+256 || y > 90) { - mouse_in = false; - return; - } - - mouse_in = true; - - if (Mouse::LButton()) { - if (!mouse_down) { - mouse_down = true; - mouse_down_x = x; - mouse_down_y = y; - } - - // check weapons buttons: - int max_wep = ship->Weapons().size(); - - if (max_wep > MAX_WEP) - max_wep = MAX_WEP; - - for (int i = 0; i < max_wep; i++) { - int index = i * 4; - - if (CheckButton(index, mouse_down_x, mouse_down_y)) { - ship->FireWeapon(i); - return; - } - - else if (CheckButton(index + 1, mouse_down_x, mouse_down_y)) { - ship->Weapons()[i]->SetFiringOrders(Weapon::MANUAL); - return; - } - - else if (CheckButton(index + 2, mouse_down_x, mouse_down_y)) { - ship->Weapons()[i]->SetFiringOrders(Weapon::AUTO); - return; - } - - else if (CheckButton(index + 3, mouse_down_x, mouse_down_y)) { - ship->Weapons()[i]->SetFiringOrders(Weapon::POINT_DEFENSE); - return; - } - } - } - - else if (mouse_down) { - mouse_down = false; - mouse_down_x = 0; - mouse_down_y = 0; - - // check subtarget buttons: - if (ship->GetTarget()) { - Rect r(width/2+50, 70, 20, 20); - if (r.Contains(x,y)) { - CycleSubTarget(-1); - return; - } - - r.x = width/2 + 180; - if (r.Contains(x,y)) { - CycleSubTarget(1); - return; - } - } - } -} - -bool -WepView::CheckButton(int index, int x, int y) -{ - if (index >= 0 && index < MAX_BTN) { - return btn_rect[index].Contains(x,y)?true:false; - } - - return false; -} - -void -WepView::CycleSubTarget(int direction) -{ - if (ship->GetTarget() == 0 || ship->GetTarget()->Type() != SimObject::SIM_SHIP) - return; - - ship->CycleSubTarget(direction); -} - -bool -WepView::IsMouseLatched() -{ - return mouse_in; -} diff --git a/Stars45/WepView.h b/Stars45/WepView.h deleted file mode 100644 index 0a3b8d8..0000000 --- a/Stars45/WepView.h +++ /dev/null @@ -1,87 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - View class for Tactical HUD Overlay -*/ - -#ifndef WepView_h -#define WepView_h - -#include "Types.h" -#include "View.h" -#include "Projector.h" -#include "Bitmap.h" -#include "Font.h" -#include "System.h" -#include "SimObject.h" - -// +--------------------------------------------------------------------+ - -class Graphic; -class Sprite; -class Ship; -class Contact; -class HUDView; - -// +--------------------------------------------------------------------+ - -class WepView : public View, -public SimObserver -{ -public: - WepView(Window* c); - virtual ~WepView(); - - // Operations: - virtual void Refresh(); - virtual void OnWindowMove(); - virtual void ExecFrame(); - virtual void SetOverlayMode(int mode); - virtual int GetOverlayMode() const { return mode; } - virtual void CycleOverlayMode(); - - virtual void RestoreOverlay(); - - virtual bool Update(SimObject* obj); - virtual const char* GetObserverName() const; - - static WepView* GetInstance() { return wep_view; } - static void SetColor(Color c); - - static bool IsMouseLatched(); - -protected: - void DrawOverlay(); - - void DoMouseFrame(); - bool CheckButton(int index, int x, int y); - void CycleSubTarget(int direction); - - int mode; - int transition; - int mouse_down; - int width, height, aw, ah; - double xcenter, ycenter; - - Sim* sim; - Ship* ship; - SimObject* target; - HUDView* hud; - - enum { MAX_WEP = 4, MAX_BTN = 16 }; - Rect btn_rect[MAX_BTN]; - - SimRegion* active_region; - - static WepView* wep_view; -}; - -#endif // WepView_h - diff --git a/Stars45/Window.cpp b/Stars45/Window.cpp deleted file mode 100644 index c04d45b..0000000 --- a/Stars45/Window.cpp +++ /dev/null @@ -1,934 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Window class -*/ - -#include "Window.h" -#include "Bitmap.h" -#include "Color.h" -#include "Fix.h" -#include "Font.h" -#include "Polygon.h" -#include "Screen.h" -#include "Video.h" -#include "View.h" - -static VertexSet vset4(4); - -// +--------------------------------------------------------------------+ - -Window::Window(Screen* s, int ax, int ay, int aw, int ah) - : screen(s), rect(ax, ay, aw, ah), shown(true), font(0) -{ } - -// +--------------------------------------------------------------------+ - -Window::~Window() -{ - view_list.destroy(); -} - -// +--------------------------------------------------------------------+ - -bool -Window::AddView(View* v) -{ - if (!v) return false; - - if (!view_list.contains(v)) - view_list.append(v); - - return true; -} - -bool -Window::DelView(View* v) -{ - if (!v) return false; - - return view_list.remove(v) == v; -} - -void -Window::MoveTo(const Rect& r) -{ - if (rect.x == r.x && - rect.y == r.y && - rect.w == r.w && - rect.h == r.h) - return; - - rect = r; - - ListIter v = view_list; - while (++v) - v->OnWindowMove(); -} - -// +--------------------------------------------------------------------+ - -void -Window::Paint() -{ - ListIter v = view_list; - while (++v) - v->Refresh(); -} - -// +--------------------------------------------------------------------+ - -static inline void swap(int& a, int& b) { int tmp=a; a=b; b=tmp; } -static inline void sort(int& a, int& b) { if (a>b) swap(a,b); } -static inline void swap(double& a, double& b) { double tmp=a; a=b; b=tmp; } -static inline void sort(double& a, double& b) { if (a>b) swap(a,b); } - -Rect -Window::ClipRect(const Rect& r) -{ - Rect clip_rect = r; - - clip_rect.x += rect.x; - clip_rect.y += rect.y; - - if (clip_rect.x < rect.x) { - clip_rect.w -= rect.x - clip_rect.x; - clip_rect.x = rect.x; - } - - if (clip_rect.y < rect.y) { - clip_rect.h -= rect.y - clip_rect.y; - clip_rect.y = rect.y; - } - - if (clip_rect.x + clip_rect.w > rect.x + rect.w) - clip_rect.w = rect.x + rect.w - clip_rect.x; - - if (clip_rect.y + clip_rect.h > rect.y + rect.h) - clip_rect.h = rect.y + rect.h - clip_rect.y; - - return clip_rect; -} - -// +--------------------------------------------------------------------+ - -bool -Window::ClipLine(int& x1, int& y1, int& x2, int& y2) -{ - // vertical lines: - if (x1==x2) { - clip_vertical: - sort(y1,y2); - if (x1 < 0 || x1 >= rect.w) return false; - if (y1 < 0) y1 = 0; - if (y2 >= rect.h) y2 = rect.h; - return true; - } - - // horizontal lines: - if (y1==y2) { - clip_horizontal: - sort(x1,x2); - if (y1 < 0 || y1 >= rect.h) return false; - if (x1 < 0) x1 = 0; - if (x2 > rect.w) x2 = rect.w; - return true; - } - - // general lines: - - // sort left to right: - if (x1 > x2) { - swap(x1,x2); - swap(y1,y2); - } - - double m = (double)(y2-y1) / (double)(x2-x1); - double b = (double) y1 - (m * x1); - - // clip: - if (x1 < 0) { x1 = 0; y1 = (int) b; } - if (x1 >= rect.w) return false; - if (x2 < 0) return false; - if (x2 > rect.w-1) { x2 = rect.w-1; y2 = (int) (m * x2 + b); } - - if (y1 < 0 && y2 < 0) return false; - if (y1 >= rect.h && y2 >= rect.h) return false; - - if (y1 < 0) { y1 = 0; x1 = (int) (-b/m); } - if (y1 >= rect.h) { y1 = rect.h-1; x1 = (int) ((y1-b)/m); } - if (y2 < 0) { y2 = 0; x2 = (int) (-b/m); } - if (y2 >= rect.h) { y2 = rect.h-1; x2 = (int) ((y2-b)/m); } - - if (x1 == x2) - goto clip_vertical; - - if (y1 == y2) - goto clip_horizontal; - - return true; -} - -// +--------------------------------------------------------------------+ - -bool -Window::ClipLine(double& x1, double& y1, double& x2, double& y2) -{ - // vertical lines: - if (x1==x2) { - clip_vertical: - sort(y1,y2); - if (x1 < 0 || x1 >= rect.w) return false; - if (y1 < 0) y1 = 0; - if (y2 >= rect.h) y2 = rect.h; - return true; - } - - // horizontal lines: - if (y1==y2) { - clip_horizontal: - sort(x1,x2); - if (y1 < 0 || y1 >= rect.h) return false; - if (x1 < 0) x1 = 0; - if (x2 > rect.w) x2 = rect.w; - return true; - } - - // general lines: - - // sort left to right: - if (x1 > x2) { - swap(x1,x2); - swap(y1,y2); - } - - double m = (double)(y2-y1) / (double)(x2-x1); - double b = (double) y1 - (m * x1); - - // clip: - if (x1 < 0) { x1 = 0; y1 = b; } - if (x1 >= rect.w) return false; - if (x2 < 0) return false; - if (x2 > rect.w-1) { x2 = rect.w-1; y2 = (m * x2 + b); } - - if (y1 < 0 && y2 < 0) return false; - if (y1 >= rect.h && y2 >= rect.h) return false; - - if (y1 < 0) { y1 = 0; x1 = (-b/m); } - if (y1 >= rect.h) { y1 = rect.h-1; x1 = ((y1-b)/m); } - if (y2 < 0) { y2 = 0; x2 = (-b/m); } - if (y2 >= rect.h) { y2 = rect.h-1; x2 = ((y2-b)/m); } - - if (x1 == x2) - goto clip_vertical; - - if (y1 == y2) - goto clip_horizontal; - - return true; -} - -// +--------------------------------------------------------------------+ - -void -Window::DrawLine(int x1, int y1, int x2, int y2, Color color, int blend) -{ - if (!screen || !screen->GetVideo()) return; - - if (ClipLine(x1,y1,x2,y2)) { - float points[4]; - - points[0] = (float) (rect.x + x1); - points[1] = (float) (rect.y + y1); - points[2] = (float) (rect.x + x2); - points[3] = (float) (rect.y + y2); - - Video* video = screen->GetVideo(); - video->DrawScreenLines(1, points, color, blend); - } -} - -// +--------------------------------------------------------------------+ - -void -Window::DrawRect(int x1, int y1, int x2, int y2, Color color, int blend) -{ - if (!screen || !screen->GetVideo()) return; - - sort(x1,x2); - sort(y1,y2); - - if (x1 > rect.w || x2 < 0 || y1 > rect.h || y2 < 0) - return; - - float points[16]; - - points[ 0] = (float) (rect.x + x1); - points[ 1] = (float) (rect.y + y1); - points[ 2] = (float) (rect.x + x2); - points[ 3] = (float) (rect.y + y1); - - points[ 4] = (float) (rect.x + x2); - points[ 5] = (float) (rect.y + y1); - points[ 6] = (float) (rect.x + x2); - points[ 7] = (float) (rect.y + y2); - - points[ 8] = (float) (rect.x + x2); - points[ 9] = (float) (rect.y + y2); - points[10] = (float) (rect.x + x1); - points[11] = (float) (rect.y + y2); - - points[12] = (float) (rect.x + x1); - points[13] = (float) (rect.y + y2); - points[14] = (float) (rect.x + x1); - points[15] = (float) (rect.y + y1); - - Video* video = screen->GetVideo(); - video->DrawScreenLines(4, points, color, blend); -} - -void -Window::DrawRect(const Rect& r, Color color, int blend) -{ - DrawRect(r.x, r.y, r.x+r.w, r.y+r.h, color, blend); -} - -// +--------------------------------------------------------------------+ - -void -Window::FillRect(int x1, int y1, int x2, int y2, Color color, int blend) -{ - if (!screen || !screen->GetVideo()) return; - - sort(x1,x2); - sort(y1,y2); - - if (x1 > rect.w || x2 < 0 || y1 > rect.h || y2 < 0) - return; - - vset4.space = VertexSet::SCREEN_SPACE; - for (int i = 0; i < 4; i++) { - vset4.diffuse[i] = color.Value(); - } - - vset4.s_loc[0].x = (float) (rect.x + x1) - 0.5f; - vset4.s_loc[0].y = (float) (rect.y + y1) - 0.5f; - vset4.s_loc[0].z = 0.0f; - vset4.rw[0] = 1.0f; - vset4.tu[0] = 0.0f; - vset4.tv[0] = 0.0f; - - vset4.s_loc[1].x = (float) (rect.x + x2) - 0.5f; - vset4.s_loc[1].y = (float) (rect.y + y1) - 0.5f; - vset4.s_loc[1].z = 0.0f; - vset4.rw[1] = 1.0f; - vset4.tu[1] = 1.0f; - vset4.tv[1] = 0.0f; - - vset4.s_loc[2].x = (float) (rect.x + x2) - 0.5f; - vset4.s_loc[2].y = (float) (rect.y + y2) - 0.5f; - vset4.s_loc[2].z = 0.0f; - vset4.rw[2] = 1.0f; - vset4.tu[2] = 1.0f; - vset4.tv[2] = 1.0f; - - vset4.s_loc[3].x = (float) (rect.x + x1) - 0.5f; - vset4.s_loc[3].y = (float) (rect.y + y2) - 0.5f; - vset4.s_loc[3].z = 0.0f; - vset4.rw[3] = 1.0f; - vset4.tu[3] = 0.0f; - vset4.tv[3] = 1.0f; - - Poly poly(0); - poly.nverts = 4; - poly.vertex_set = &vset4; - poly.verts[0] = 0; - poly.verts[1] = 1; - poly.verts[2] = 2; - poly.verts[3] = 3; - - Video* video = screen->GetVideo(); - video->DrawScreenPolys(1, &poly, blend); -} - -void -Window::FillRect(const Rect& r, Color color, int blend) -{ - FillRect(r.x, r.y, r.x+r.w, r.y+r.h, color, blend); -} - -// +--------------------------------------------------------------------+ - -void -Window::DrawLines(int nPts, POINT* pts, Color color, int blend) -{ - if (nPts < 2 || nPts > 16) - return; - - if (!screen || !screen->GetVideo()) - return; - - float f[64]; - int n = 0; - - for (int i = 0; i < nPts-1; i++) { - f[n++] = (float) rect.x + pts[i].x; - f[n++] = (float) rect.y + pts[i].y; - f[n++] = (float) rect.x + pts[i+1].x; - f[n++] = (float) rect.y + pts[i+1].y; - } - - Video* video = screen->GetVideo(); - video->DrawScreenLines(nPts-1, f, color, blend); -} - -void -Window::DrawPoly(int nPts, POINT* pts, Color color, int blend) -{ - if (nPts < 3 || nPts > 8) - return; - - if (!screen || !screen->GetVideo()) - return; - - float f[32]; - int n = 0; - - for (int i = 0; i < nPts-1; i++) { - f[n++] = (float) rect.x + pts[i].x; - f[n++] = (float) rect.y + pts[i].y; - f[n++] = (float) rect.x + pts[i+1].x; - f[n++] = (float) rect.y + pts[i+1].y; - } - - f[n++] = (float) rect.x + pts[nPts-1].x; - f[n++] = (float) rect.y + pts[nPts-1].y; - f[n++] = (float) rect.x + pts[0].x; - f[n++] = (float) rect.y + pts[0].y; - - Video* video = screen->GetVideo(); - video->DrawScreenLines(nPts, f, color, blend); -} - -void -Window::FillPoly(int nPts, POINT* pts, Color color, int blend) -{ - if (nPts < 3 || nPts > 4) - return; - - if (!screen || !screen->GetVideo()) - return; - - vset4.space = VertexSet::SCREEN_SPACE; - for (int i = 0; i < nPts; i++) { - vset4.diffuse[i] = color.Value(); - vset4.s_loc[i].x = (float) (rect.x + pts[i].x) - 0.5f; - vset4.s_loc[i].y = (float) (rect.y + pts[i].y) - 0.5f; - vset4.s_loc[i].z = 0.0f; - vset4.rw[i] = 1.0f; - vset4.tu[i] = 0.0f; - vset4.tv[i] = 0.0f; - } - - Poly poly(0); - poly.nverts = nPts; - poly.vertex_set = &vset4; - poly.verts[0] = 0; - poly.verts[1] = 1; - poly.verts[2] = 2; - poly.verts[3] = 3; - - Video* video = screen->GetVideo(); - video->DrawScreenPolys(1, &poly, blend); -} - -// +--------------------------------------------------------------------+ - -void -Window::DrawBitmap(int x1, int y1, int x2, int y2, Bitmap* img, int blend) -{ - Rect clip_rect; - clip_rect.w = rect.w; - clip_rect.h = rect.h; - - ClipBitmap(x1,y1,x2,y2,img,Color::White,blend,clip_rect); -} - -void -Window::FadeBitmap(int x1, int y1, int x2, int y2, Bitmap* img, Color c, int blend) -{ - Rect clip_rect; - clip_rect.w = rect.w; - clip_rect.h = rect.h; - - ClipBitmap(x1,y1,x2,y2,img,c,blend,clip_rect); -} - -void -Window::ClipBitmap(int x1, int y1, int x2, int y2, Bitmap* img, Color c, int blend, const Rect& clip_rect) -{ - if (!screen || !screen->GetVideo() || !img) return; - - Rect clip = clip_rect; - - // clip the clip rect to the window rect: - if (clip.x < 0) { - clip.w -= clip.x; - clip.x = 0; - } - - if (clip.x + clip.w > rect.w) { - clip.w -= (clip.x + clip.w - rect.w); - } - - if (clip.y < 0) { - clip.h -= clip.y; - clip.y = 0; - } - - if (clip.y + clip.h > rect.h) { - clip.h -= (clip.y + clip.h - rect.h); - } - - // now clip the bitmap to the validated clip rect: - sort(x1,x2); - sort(y1,y2); - - if (x1 > clip.x + clip.w || x2 < clip.x || y1 > clip.y + clip.h || y2 < clip.y) - return; - - vset4.space = VertexSet::SCREEN_SPACE; - for (int i = 0; i < 4; i++) { - vset4.diffuse[i] = c.Value(); - } - - float u1 = 0.0f; - float u2 = 1.0f; - float v1 = 0.0f; - float v2 = 1.0f; - float iw = (float) (x2-x1); - float ih = (float) (y2-y1); - int x3 = clip.x + clip.w; - int y3 = clip.y + clip.h; - - if (x1 < clip.x) { - u1 = (clip.x - x1) / iw; - x1 = clip.x; - } - - if (x2 > x3) { - u2 = 1.0f - (x2 - x3) / iw; - x2 = x3; - } - - if (y1 < clip.y) { - v1 = (clip.y - y1) / ih; - y1 = clip.y; - } - - if (y2 > y3) { - v2 = 1.0f - (y2 - y3) / ih; - y2 = y3; - } - - vset4.s_loc[0].x = (float) (rect.x + x1) - 0.5f; - vset4.s_loc[0].y = (float) (rect.y + y1) - 0.5f; - vset4.s_loc[0].z = 0.0f; - vset4.rw[0] = 1.0f; - vset4.tu[0] = u1; - vset4.tv[0] = v1; - - vset4.s_loc[1].x = (float) (rect.x + x2) - 0.5f; - vset4.s_loc[1].y = (float) (rect.y + y1) - 0.5f; - vset4.s_loc[1].z = 0.0f; - vset4.rw[1] = 1.0f; - vset4.tu[1] = u2; - vset4.tv[1] = v1; - - vset4.s_loc[2].x = (float) (rect.x + x2) - 0.5f; - vset4.s_loc[2].y = (float) (rect.y + y2) - 0.5f; - vset4.s_loc[2].z = 0.0f; - vset4.rw[2] = 1.0f; - vset4.tu[2] = u2; - vset4.tv[2] = v2; - - vset4.s_loc[3].x = (float) (rect.x + x1) - 0.5f; - vset4.s_loc[3].y = (float) (rect.y + y2) - 0.5f; - vset4.s_loc[3].z = 0.0f; - vset4.rw[3] = 1.0f; - vset4.tu[3] = u1; - vset4.tv[3] = v2; - - Material mtl; - mtl.tex_diffuse = img; - - Poly poly(0); - poly.nverts = 4; - poly.vertex_set = &vset4; - poly.material = &mtl; - poly.verts[0] = 0; - poly.verts[1] = 1; - poly.verts[2] = 2; - poly.verts[3] = 3; - - Video* video = screen->GetVideo(); - - video->SetRenderState(Video::TEXTURE_WRAP, 0); - video->DrawScreenPolys(1, &poly, blend); - video->SetRenderState(Video::TEXTURE_WRAP, 1); -} - -// +--------------------------------------------------------------------+ - -void -Window::TileBitmap(int x1, int y1, int x2, int y2, Bitmap* img, int blend) -{ - if (!screen || !screen->GetVideo()) return; - if (!img || !img->Width() || !img->Height()) return; - - vset4.space = VertexSet::SCREEN_SPACE; - for (int i = 0; i < 4; i++) { - vset4.diffuse[i] = Color::White.Value(); - } - - float xscale = (float) rect.w / (float) img->Width(); - float yscale = (float) rect.h / (float) img->Height(); - - vset4.s_loc[0].x = (float) (rect.x + x1) - 0.5f; - vset4.s_loc[0].y = (float) (rect.y + y1) - 0.5f; - vset4.s_loc[0].z = 0.0f; - vset4.rw[0] = 1.0f; - vset4.tu[0] = 0.0f; - vset4.tv[0] = 0.0f; - - vset4.s_loc[1].x = (float) (rect.x + x2) - 0.5f; - vset4.s_loc[1].y = (float) (rect.y + y1) - 0.5f; - vset4.s_loc[1].z = 0.0f; - vset4.rw[1] = 1.0f; - vset4.tu[1] = xscale; - vset4.tv[1] = 0.0f; - - vset4.s_loc[2].x = (float) (rect.x + x2) - 0.5f; - vset4.s_loc[2].y = (float) (rect.y + y2) - 0.5f; - vset4.s_loc[2].z = 0.0f; - vset4.rw[2] = 1.0f; - vset4.tu[2] = xscale; - vset4.tv[2] = yscale; - - vset4.s_loc[3].x = (float) (rect.x + x1) - 0.5f; - vset4.s_loc[3].y = (float) (rect.y + y2) - 0.5f; - vset4.s_loc[3].z = 0.0f; - vset4.rw[3] = 1.0f; - vset4.tu[3] = 0.0f; - vset4.tv[3] = yscale; - - Material mtl; - mtl.tex_diffuse = img; - - Poly poly(0); - poly.nverts = 4; - poly.vertex_set = &vset4; - poly.material = &mtl; - poly.verts[0] = 0; - poly.verts[1] = 1; - poly.verts[2] = 2; - poly.verts[3] = 3; - - Video* video = screen->GetVideo(); - video->DrawScreenPolys(1, &poly, blend); -} - -// +--------------------------------------------------------------------+ - -static float ellipse_pts[256]; - -void -Window::DrawEllipse(int x1, int y1, int x2, int y2, Color color, int blend) -{ - Video* video = screen->GetVideo(); - - if (!video) - return; - - sort(x1,x2); - sort(y1,y2); - - if (x1 > rect.w || x2 < 0 || y1 > rect.h || y2 < 0) - return; - - double w2 = (x2-x1)/2.0; - double h2 = (y2-y1)/2.0; - double cx = rect.x + x1 + w2; - double cy = rect.y + y1 + h2; - double r = w2; - int ns = 4; - int np = 0; - - if (h2 > r) - r = h2; - - if (r > 2*ns) - ns = (int) (r/2); - - if (ns > 64) - ns = 64; - - double theta = 0; - double dt = (PI/2) / ns; - - // quadrant 1 (lower right): - if (cx < (rect.x+rect.w) && cy < (rect.y + rect.h)) { - theta = 0; - np = 0; - - for (int i = 0; i < ns; i++) { - double ex1 = x1 + w2 + cos(theta) * w2; - double ey1 = y1 + h2 + sin(theta) * h2; - - theta += dt; - - double ex2 = x1 + w2 + cos(theta) * w2; - double ey2 = y1 + h2 + sin(theta) * h2; - - if (ClipLine(ex1, ey1, ex2, ey2)) { - ellipse_pts[np++] = (float) (rect.x + ex1); - ellipse_pts[np++] = (float) (rect.y + ey1); - ellipse_pts[np++] = (float) (rect.x + ex2); - ellipse_pts[np++] = (float) (rect.y + ey2); - } - } - - video->DrawScreenLines(np/4, ellipse_pts, color, blend); - } - - // quadrant 2 (lower left): - if (cx > rect.x && cy < (rect.y + rect.h)) { - theta = 90*DEGREES; - np = 0; - - for (int i = 0; i < ns; i++) { - double ex1 = x1 + w2 + cos(theta) * w2; - double ey1 = y1 + h2 + sin(theta) * h2; - - theta += dt; - - double ex2 = x1 + w2 + cos(theta) * w2; - double ey2 = y1 + h2 + sin(theta) * h2; - - if (ClipLine(ex1, ey1, ex2, ey2)) { - ellipse_pts[np++] = (float) (rect.x + ex1); - ellipse_pts[np++] = (float) (rect.y + ey1); - ellipse_pts[np++] = (float) (rect.x + ex2); - ellipse_pts[np++] = (float) (rect.y + ey2); - } - } - - video->DrawScreenLines(np/4, ellipse_pts, color, blend); - } - - // quadrant 3 (upper left): - if (cx > rect.x && cy > rect.y) { - theta = 180*DEGREES; - np = 0; - - for (int i = 0; i < ns; i++) { - double ex1 = x1 + w2 + cos(theta) * w2; - double ey1 = y1 + h2 + sin(theta) * h2; - - theta += dt; - - double ex2 = x1 + w2 + cos(theta) * w2; - double ey2 = y1 + h2 + sin(theta) * h2; - - if (ClipLine(ex1, ey1, ex2, ey2)) { - ellipse_pts[np++] = (float) (rect.x + ex1); - ellipse_pts[np++] = (float) (rect.y + ey1); - ellipse_pts[np++] = (float) (rect.x + ex2); - ellipse_pts[np++] = (float) (rect.y + ey2); - } - } - - video->DrawScreenLines(np/4, ellipse_pts, color, blend); - } - - // quadrant 4 (upper right): - if (cx < (rect.x+rect.w) && cy > rect.y) { - theta = 270*DEGREES; - np = 0; - - for (int i = 0; i < ns; i++) { - double ex1 = x1 + w2 + cos(theta) * w2; - double ey1 = y1 + h2 + sin(theta) * h2; - - theta += dt; - - double ex2 = x1 + w2 + cos(theta) * w2; - double ey2 = y1 + h2 + sin(theta) * h2; - - if (ClipLine(ex1, ey1, ex2, ey2)) { - ellipse_pts[np++] = (float) (rect.x + ex1); - ellipse_pts[np++] = (float) (rect.y + ey1); - ellipse_pts[np++] = (float) (rect.x + ex2); - ellipse_pts[np++] = (float) (rect.y + ey2); - } - } - - video->DrawScreenLines(np/4, ellipse_pts, color, blend); - } - -} - -void -Window::FillEllipse(int x1, int y1, int x2, int y2, Color color, int blend) -{ - Video* video = screen->GetVideo(); - - if (!video) - return; - - sort(x1,x2); - sort(y1,y2); - - if (x1 > rect.w || x2 < 0 || y1 > rect.h || y2 < 0) - return; - - double w2 = (x2-x1)/2.0; - double h2 = (y2-y1)/2.0; - double cx = x1 + w2; - double cy = y1 + h2; - double r = w2; - int ns = 4; - int np = 0; - - if (h2 > r) - r = h2; - - if (r > 2*ns) - ns = (int) (r/2); - - if (ns > 64) - ns = 64; - - double theta = -PI / 2; - double dt = PI / ns; - - for (int i = 0; i < ns; i++) { - double ex1 = cos(theta) * w2; - double ey1 = sin(theta) * h2; - - theta += dt; - - double ex2 = cos(theta) * w2; - double ey2 = sin(theta) * h2; - - POINT pts[4]; - - pts[0].x = (int) (cx - ex1); - pts[0].y = (int) (cy + ey1); - - pts[1].x = (int) (cx + ex1); - pts[1].y = (int) (cy + ey1); - - pts[2].x = (int) (cx + ex2); - pts[2].y = (int) (cy + ey2); - - pts[3].x = (int) (cx - ex2); - pts[3].y = (int) (cy + ey2); - - if (pts[0].x > rect.w && pts[3].x > rect.w) - continue; - - if (pts[1].x < 0 && pts[2].x < 0) - continue; - - if (pts[0].y > rect.h) - return; - - if (pts[2].y < 0) - continue; - - if (pts[0].x < 0) pts[0].x = 0; - if (pts[3].x < 0) pts[3].x = 0; - if (pts[1].x > rect.w) pts[1].x = rect.w; - if (pts[2].x > rect.w) pts[2].x = rect.w; - - if (pts[0].y < 0) pts[0].y = 0; - if (pts[1].y < 0) pts[1].y = 0; - if (pts[2].y > rect.h) pts[2].y = rect.h; - if (pts[3].y > rect.h) pts[3].y = rect.h; - - FillPoly(4, pts, color, blend); - } -} - -// +--------------------------------------------------------------------+ - -void -Window::Print(int x1, int y1, const char* fmt, ...) -{ - if (!font || x1<0 || y1<0 || x1>=rect.w || y1>=rect.h || !fmt) - return; - - x1 += rect.x; - y1 += rect.y; - - char msgbuf[512]; - vsprintf_s(msgbuf, fmt, (char *)(&fmt+1)); - font->DrawString(msgbuf, strlen(msgbuf), x1, y1, rect); -} - -void -Window::DrawText(const char* txt, int count, Rect& txt_rect, DWORD flags) -{ - if (!font) - return; - - if (txt && !count) - count = strlen(txt); - - // clip the rect: - Rect clip_rect = txt_rect; - - if (clip_rect.x < 0) { - int dx = -clip_rect.x; - clip_rect.x += dx; - clip_rect.w -= dx; - } - - if (clip_rect.y < 0) { - int dy = -clip_rect.y; - clip_rect.y += dy; - clip_rect.h -= dy; - } - - if (clip_rect.w < 1 || clip_rect.h < 1) - return; - - if (clip_rect.x + clip_rect.w > rect.w) - clip_rect.w = rect.w - clip_rect.x; - - if (clip_rect.y + clip_rect.h > rect.h) - clip_rect.h = rect.h - clip_rect.y; - - clip_rect.x += rect.x; - clip_rect.y += rect.y; - - if (font && txt && count) { - font->DrawText(txt, count, clip_rect, flags); - font->SetAlpha(1); - } - - // if calc only, update the rectangle: - if (flags & DT_CALCRECT) { - txt_rect.h = clip_rect.h; - txt_rect.w = clip_rect.w; - } -} - diff --git a/Stars45/Window.h b/Stars45/Window.h deleted file mode 100644 index f9a143f..0000000 --- a/Stars45/Window.h +++ /dev/null @@ -1,103 +0,0 @@ -/* 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 - - - OVERVIEW - ======== - Window class (a region of a screen or buffer) -*/ - -#ifndef Window_h -#define Window_h - -#include "Types.h" -#include "Geometry.h" -#include "List.h" - -// +--------------------------------------------------------------------+ - -class Color; -class Bitmap; -class Font; -class Screen; -class View; - -// +--------------------------------------------------------------------+ - -class Window -{ - friend class Screen; - -public: - static const char* TYPENAME() { return "Window"; } - - Window(Screen* s, int ax, int ay, int aw, int ah); - virtual ~Window(); - - int operator == (const Window& that) const { return this == &that; } - - // Screen dimensions: - Screen* GetScreen() const { return screen; } - const Rect& GetRect() const { return rect; } - int X() const { return rect.x; } - int Y() const { return rect.y; } - int Width() const { return rect.w; } - int Height() const { return rect.h; } - - // Operations: - virtual void Paint(); - virtual void Show() { shown = true; } - virtual void Hide() { shown = false; } - virtual bool IsShown() const { return shown; } - - virtual void MoveTo(const Rect& r); - - virtual bool AddView(View* v); - virtual bool DelView(View* v); - - Rect ClipRect(const Rect& r); - bool ClipLine(int& x1, int& y1, int& x2, int& y2); - bool ClipLine(double& x1, double& y1, double& x2, double& y2); - - void DrawLine(int x1, int y1, int x2, int y2, Color color, int blend=0); - void DrawRect(int x1, int y1, int x2, int y2, Color color, int blend=0); - void DrawRect(const Rect& r, Color color, int blend=0); - void FillRect(int x1, int y1, int x2, int y2, Color color, int blend=0); - void FillRect(const Rect& r, Color color, int alpha=0); - void DrawBitmap(int x1, int y1, int x2, int y2, Bitmap* img, int blend=0); - void FadeBitmap(int x1, int y1, int x2, int y2, Bitmap* img, Color c, int blend); - void ClipBitmap(int x1, int y1, int x2, int y2, Bitmap* img, Color c, int blend, const Rect& clip); - void TileBitmap(int x1, int y1, int x2, int y2, Bitmap* img, int blend=0); - void DrawLines(int nPts, POINT* pts, Color color, int blend=0); - void DrawPoly(int nPts, POINT* pts, Color color, int blend=0); - void FillPoly(int nPts, POINT* pts, Color color, int blend=0); - - void DrawEllipse(int x1, int y1, int x2, int y2, Color color, int blend=0); - void FillEllipse(int x1, int y1, int x2, int y2, Color color, int blend=0); - - // text methods: - void SetFont(Font* f) { font = f; } - Font* GetFont() const { return font; } - - void Print(int x1, int y1, const char* fmt, ...); - void DrawText(const char* txt, int count, Rect& txt_rect, DWORD flags); - -protected: - // translate screen coords into window relative coords - virtual void ScreenToWindow(int& x, int& y) { } - virtual void ScreenToWindow(Rect& r) { } - - Rect rect; - Screen* screen; - bool shown; - Font* font; - - List view_list; -}; - -#endif // Window_h - diff --git a/Stars45/WndProc.cpp b/Stars45/WndProc.cpp deleted file mode 100644 index 1f068b3..0000000 --- a/Stars45/WndProc.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* 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. -*/ - -#include "WndProc.h" - -#include "GameWinDX9.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "Types.h" - - -#ifndef WM_MOUSEWHEEL -#define WM_MOUSEWHEEL 0x20A -#endif - - -LRESULT CALLBACK -WndProc(HWND hwnd, UINT message, WPARAM uParam, LPARAM lParam) -{ - auto game = GameWinDX9::GetInstance(); - switch (message) { - case WM_SYSKEYDOWN: - if (uParam == VK_TAB || uParam == VK_F4) - return DefWindowProc(hwnd, message, uParam, lParam); - return 0; - - case WM_MENUCHAR: - return MNC_CLOSE << 16; - - case WM_ACTIVATEAPP: - // Keep track of whether or not the app is in the foreground - if (game) - game->Activate(uParam?true:false); - break; - - case WM_PAINT: - if (!game || !game->OnPaint()) - return DefWindowProc(hwnd, message, uParam, lParam); - break; - - case WM_SETCURSOR: - if (game && game->ShowMouse()) { - return DefWindowProc(hwnd, message, uParam, lParam); - } - else { - // hide the windows mouse cursor - SetCursor(NULL); - return 1; - } - break; - - case WM_ENTERSIZEMOVE: - // Halt frame movement while the app is sizing or moving - if (game) - game->Pause(true); - break; - - case WM_SIZE: - // Pick up possible changes to window style due to maximize, etc. - if (game && game->hwnd != NULL ) { - game->window_style = GetWindowLong(game->hwnd, GWL_STYLE ); - - if (uParam == SIZE_MINIMIZED) { - game->Pause(true); // Pause while we're minimized - game->is_minimized = true; - game->is_maximized = false; - } - - else if (uParam == SIZE_MAXIMIZED) { - if (game->is_minimized) - game->Pause(false); // Unpause since we're no longer minimized - - game->is_minimized = false; - game->is_maximized = true; - game->ResizeVideo(); - } - - else if (uParam == SIZE_RESTORED) { - if (game->is_maximized) { - game->is_maximized = false; - game->ResizeVideo(); - } - - else if (game->is_minimized) { - game->Pause(false); // Unpause since we're no longer minimized - game->is_minimized = false; - game->ResizeVideo(); - } - else { - // If we're neither maximized nor minimized, the window size - // is changing by the user dragging the window edges. In this - // case, we don't reset the device yet -- we wait until the - // user stops dragging, and a WM_EXITSIZEMOVE message comes. - } - } - } - break; - - case WM_EXITSIZEMOVE: - if (game) { - game->Pause(false); - game->ResizeVideo(); - } - break; - - case WM_ENTERMENULOOP: - if (game) - game->Pause(true); - break; - - case WM_EXITMENULOOP: - if (game) - game->Pause(false); - break; - - case WM_KEYDOWN: - BufferKey(uParam); - return 0; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - case WM_MOUSEMOVE: - Mouse::x = LOWORD(lParam); - Mouse::y = HIWORD(lParam); - break; - - case WM_LBUTTONDOWN: - Mouse::l = 1; - break; - - case WM_LBUTTONDBLCLK: - Mouse::l = 2; - break; - - case WM_LBUTTONUP: - Mouse::l = 0; - break; - - case WM_MBUTTONDOWN: - Mouse::m = 1; - break; - - case WM_MBUTTONDBLCLK: - Mouse::m = 2; - break; - - case WM_MBUTTONUP: - Mouse::m = 0; - break; - - case WM_RBUTTONDOWN: - Mouse::r = 1; - break; - - case WM_RBUTTONDBLCLK: - Mouse::r = 2; - break; - - case WM_RBUTTONUP: - Mouse::r = 0; - break; - - case WM_MOUSEWHEEL: - { - int w = (int) (uParam >> 16); - if (w > 32000) w -= 65536; - Mouse::w += w; - } - break; - - case WM_CLOSE: - if (game) // && game->Server()) - game->Exit(); - break; - - default: - return DefWindowProc(hwnd, message, uParam, lParam); - } - - return 0; -} - - -const int MAX_KEY_BUF = 512; -static int vkbuf[MAX_KEY_BUF]; -static int vkshiftbuf[MAX_KEY_BUF]; -static int vkins = 0; -static int vkext = 0; - - -void -FlushKeys() -{ - Keyboard::FlushKeys(); - vkins = vkext = 0; -} - - -void -BufferKey(int vkey) -{ - if (vkey < 1) return; - - int shift = 0; - - if (GetAsyncKeyState(VK_SHIFT)) - shift |= 1; - - if (GetAsyncKeyState(VK_CONTROL)) - shift |= 2; - - if (GetAsyncKeyState(VK_MENU)) - shift |= 4; - - vkbuf[vkins] = vkey; - vkshiftbuf[vkins++] = shift; - - if (vkins >= MAX_KEY_BUF) - vkins = 0; - - if (vkins == vkext) { - vkext++; - if (vkext >= MAX_KEY_BUF) - vkext = 0; - } -} - - -int -GetKey() -{ - if (vkins == vkext) return 0; - - int result = vkbuf[vkext++]; - if (vkext >= MAX_KEY_BUF) - vkext = 0; - - return result; -} - - -int -GetKeyPlus(int& key, int& shift) -{ - if (vkins == vkext) return 0; - - key = vkbuf[vkext]; - shift = vkshiftbuf[vkext++]; - - if (vkext >= MAX_KEY_BUF) - vkext = 0; - - return key; -} diff --git a/Stars45/WndProc.h b/Stars45/WndProc.h deleted file mode 100644 index 715ebef..0000000 --- a/Stars45/WndProc.h +++ /dev/null @@ -1,21 +0,0 @@ -/* 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. -*/ - -#ifndef WndProc_h -#define WndProc_h - -#include "Types.h" - - -LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); -void FlushKeys(); -void BufferKey(int vkey); -int GetKey(); -int GetKeyPlus(int& key, int& shift); -void ProcessKeyMessage(); - - -#endif // WndProc_h diff --git a/Stars45/resource.h b/Stars45/resource.h deleted file mode 100644 index 4dd9864..0000000 --- a/Stars45/resource.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef resource_h -#define resource_h - -#define Stars 100 - -#endif // resource_h -- cgit v1.1