summaryrefslogtreecommitdiffhomepage
path: root/Stars45
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2022-04-01 21:23:39 +0200
committerAki <please@ignore.pl>2022-04-01 21:23:39 +0200
commit3c487c5cd69c53d6fea948643c0a76df03516605 (patch)
tree72730c7b8b26a5ef8fc9a987ec4c16129efd5aac /Stars45
parent8f353abd0bfe18baddd8a8250ab7c4f2d1c83a6e (diff)
downloadstarshatter-3c487c5cd69c53d6fea948643c0a76df03516605.zip
starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.gz
starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.bz2
Moved Stars45 to StarsEx
Diffstat (limited to 'Stars45')
-rw-r--r--Stars45/ActiveWindow.cpp1000
-rw-r--r--Stars45/ActiveWindow.h324
-rw-r--r--Stars45/Archive.cpp589
-rw-r--r--Stars45/Archive.h89
-rw-r--r--Stars45/Asteroid.cpp114
-rw-r--r--Stars45/Asteroid.h34
-rw-r--r--Stars45/AudDlg.cpp199
-rw-r--r--Stars45/AudDlg.h78
-rw-r--r--Stars45/AudioConfig.cpp382
-rw-r--r--Stars45/AudioConfig.h70
-rw-r--r--Stars45/AwardDlg.cpp151
-rw-r--r--Stars45/AwardDlg.h58
-rw-r--r--Stars45/AwardShowDlg.cpp157
-rw-r--r--Stars45/AwardShowDlg.h62
-rw-r--r--Stars45/BaseScreen.h82
-rw-r--r--Stars45/Bitmap.cpp1616
-rw-r--r--Stars45/Bitmap.h123
-rw-r--r--Stars45/Bmp.cpp251
-rw-r--r--Stars45/Bmp.h77
-rw-r--r--Stars45/Bolt.cpp173
-rw-r--r--Stars45/Bolt.h64
-rw-r--r--Stars45/Button.cpp685
-rw-r--r--Stars45/Button.h120
-rw-r--r--Stars45/CMakeLists.txt348
-rw-r--r--Stars45/Callsign.cpp100
-rw-r--r--Stars45/Callsign.h28
-rw-r--r--Stars45/Camera.cpp210
-rw-r--r--Stars45/Camera.h60
-rw-r--r--Stars45/CameraDirector.cpp1194
-rw-r--r--Stars45/CameraDirector.h155
-rw-r--r--Stars45/CameraView.cpp800
-rw-r--r--Stars45/CameraView.h113
-rw-r--r--Stars45/Campaign.cpp2339
-rw-r--r--Stars45/Campaign.h281
-rw-r--r--Stars45/CampaignMissionFighter.cpp2154
-rw-r--r--Stars45/CampaignMissionFighter.h120
-rw-r--r--Stars45/CampaignMissionRequest.cpp37
-rw-r--r--Stars45/CampaignMissionRequest.h83
-rw-r--r--Stars45/CampaignMissionStarship.cpp1403
-rw-r--r--Stars45/CampaignMissionStarship.h106
-rw-r--r--Stars45/CampaignPlan.h57
-rw-r--r--Stars45/CampaignPlanAssignment.cpp156
-rw-r--r--Stars45/CampaignPlanAssignment.h49
-rw-r--r--Stars45/CampaignPlanEvent.cpp1274
-rw-r--r--Stars45/CampaignPlanEvent.h71
-rw-r--r--Stars45/CampaignPlanMission.cpp372
-rw-r--r--Stars45/CampaignPlanMission.h57
-rw-r--r--Stars45/CampaignPlanMovement.cpp166
-rw-r--r--Stars45/CampaignPlanMovement.h43
-rw-r--r--Stars45/CampaignPlanStrategic.cpp481
-rw-r--r--Stars45/CampaignPlanStrategic.h58
-rw-r--r--Stars45/CampaignSaveGame.cpp733
-rw-r--r--Stars45/CampaignSaveGame.h68
-rw-r--r--Stars45/CampaignSituationReport.cpp414
-rw-r--r--Stars45/CampaignSituationReport.h58
-rw-r--r--Stars45/CarrierAI.cpp398
-rw-r--r--Stars45/CarrierAI.h63
-rw-r--r--Stars45/Clock.cpp143
-rw-r--r--Stars45/Clock.h54
-rw-r--r--Stars45/CmdDlg.cpp182
-rw-r--r--Stars45/CmdDlg.h82
-rw-r--r--Stars45/CmdForceDlg.cpp715
-rw-r--r--Stars45/CmdForceDlg.h68
-rw-r--r--Stars45/CmdIntelDlg.cpp392
-rw-r--r--Stars45/CmdIntelDlg.h75
-rw-r--r--Stars45/CmdMissionsDlg.cpp324
-rw-r--r--Stars45/CmdMissionsDlg.h64
-rw-r--r--Stars45/CmdMsgDlg.cpp90
-rw-r--r--Stars45/CmdMsgDlg.h53
-rw-r--r--Stars45/CmdOrdersDlg.cpp138
-rw-r--r--Stars45/CmdOrdersDlg.h55
-rw-r--r--Stars45/CmdTheaterDlg.cpp214
-rw-r--r--Stars45/CmdTheaterDlg.h61
-rw-r--r--Stars45/CmdTitleDlg.cpp76
-rw-r--r--Stars45/CmdTitleDlg.h55
-rw-r--r--Stars45/CmpCompleteDlg.cpp106
-rw-r--r--Stars45/CmpCompleteDlg.h49
-rw-r--r--Stars45/CmpFileDlg.cpp189
-rw-r--r--Stars45/CmpFileDlg.h63
-rw-r--r--Stars45/CmpLoadDlg.cpp116
-rw-r--r--Stars45/CmpLoadDlg.h45
-rw-r--r--Stars45/CmpSceneDlg.cpp186
-rw-r--r--Stars45/CmpSceneDlg.h67
-rw-r--r--Stars45/CmpSelectDlg.cpp609
-rw-r--r--Stars45/CmpSelectDlg.h92
-rw-r--r--Stars45/CmpnScreen.cpp636
-rw-r--r--Stars45/CmpnScreen.h136
-rw-r--r--Stars45/Color.cpp680
-rw-r--r--Stars45/Color.h294
-rw-r--r--Stars45/CombatAction.cpp350
-rw-r--r--Stars45/CombatAction.h204
-rw-r--r--Stars45/CombatAssignment.cpp66
-rw-r--r--Stars45/CombatAssignment.h56
-rw-r--r--Stars45/CombatEvent.cpp151
-rw-r--r--Stars45/CombatEvent.h121
-rw-r--r--Stars45/CombatGroup.cpp1590
-rw-r--r--Stars45/CombatGroup.h230
-rw-r--r--Stars45/CombatRoster.cpp91
-rw-r--r--Stars45/CombatRoster.h47
-rw-r--r--Stars45/CombatUnit.cpp384
-rw-r--r--Stars45/CombatUnit.h132
-rw-r--r--Stars45/CombatZone.cpp280
-rw-r--r--Stars45/CombatZone.h102
-rw-r--r--Stars45/Combatant.cpp170
-rw-r--r--Stars45/Combatant.h72
-rw-r--r--Stars45/ComboBox.cpp432
-rw-r--r--Stars45/ComboBox.h104
-rw-r--r--Stars45/ComboList.cpp436
-rw-r--r--Stars45/ComboList.h91
-rw-r--r--Stars45/Component.cpp175
-rw-r--r--Stars45/Component.h99
-rw-r--r--Stars45/Computer.cpp92
-rw-r--r--Stars45/Computer.h40
-rw-r--r--Stars45/ConfirmDlg.cpp148
-rw-r--r--Stars45/ConfirmDlg.h63
-rw-r--r--Stars45/Contact.cpp364
-rw-r--r--Stars45/Contact.h90
-rw-r--r--Stars45/ContentBundle.cpp194
-rw-r--r--Stars45/ContentBundle.h56
-rw-r--r--Stars45/CtlDlg.cpp460
-rw-r--r--Stars45/CtlDlg.h118
-rw-r--r--Stars45/D3DXImage.cpp221
-rw-r--r--Stars45/D3DXImage.h42
-rw-r--r--Stars45/DataLoader.cpp1015
-rw-r--r--Stars45/DataLoader.h85
-rw-r--r--Stars45/DebriefDlg.cpp373
-rw-r--r--Stars45/DebriefDlg.h80
-rw-r--r--Stars45/Debris.cpp218
-rw-r--r--Stars45/Debris.h42
-rw-r--r--Stars45/DetailSet.cpp225
-rw-r--r--Stars45/DetailSet.h72
-rw-r--r--Stars45/Director.h43
-rw-r--r--Stars45/DisplayView.cpp237
-rw-r--r--Stars45/DisplayView.h70
-rw-r--r--Stars45/Drive.cpp500
-rw-r--r--Stars45/Drive.h92
-rw-r--r--Stars45/DriveSprite.cpp141
-rw-r--r--Stars45/DriveSprite.h46
-rw-r--r--Stars45/Drone.cpp194
-rw-r--r--Stars45/Drone.h68
-rw-r--r--Stars45/DropShipAI.cpp120
-rw-r--r--Stars45/DropShipAI.h46
-rw-r--r--Stars45/EditBox.cpp448
-rw-r--r--Stars45/EditBox.h91
-rw-r--r--Stars45/Element.cpp665
-rw-r--r--Stars45/Element.h171
-rw-r--r--Stars45/Encrypt.cpp168
-rw-r--r--Stars45/Encrypt.h37
-rw-r--r--Stars45/EngDlg.cpp1042
-rw-r--r--Stars45/EngDlg.h105
-rw-r--r--Stars45/EventDispatch.cpp273
-rw-r--r--Stars45/EventDispatch.h61
-rw-r--r--Stars45/EventTarget.h58
-rw-r--r--Stars45/ExceptionHandler.cpp431
-rw-r--r--Stars45/ExitDlg.cpp150
-rw-r--r--Stars45/ExitDlg.h59
-rw-r--r--Stars45/Explosion.cpp609
-rw-r--r--Stars45/Explosion.h83
-rw-r--r--Stars45/FadeView.cpp133
-rw-r--r--Stars45/FadeView.h54
-rw-r--r--Stars45/Farcaster.cpp287
-rw-r--r--Stars45/Farcaster.h91
-rw-r--r--Stars45/FighterAI.cpp1832
-rw-r--r--Stars45/FighterAI.h84
-rw-r--r--Stars45/FighterTacticalAI.cpp561
-rw-r--r--Stars45/FighterTacticalAI.h55
-rw-r--r--Stars45/FirstTimeDlg.cpp145
-rw-r--r--Stars45/FirstTimeDlg.h55
-rw-r--r--Stars45/Fix.cpp22
-rw-r--r--Stars45/Fix.h120
-rw-r--r--Stars45/FlightComp.cpp303
-rw-r--r--Stars45/FlightComp.h62
-rw-r--r--Stars45/FlightDeck.cpp1185
-rw-r--r--Stars45/FlightDeck.h194
-rw-r--r--Stars45/FlightPlanner.cpp370
-rw-r--r--Stars45/FlightPlanner.h50
-rw-r--r--Stars45/FltDlg.cpp1084
-rw-r--r--Stars45/FltDlg.h80
-rw-r--r--Stars45/Font.cpp1229
-rw-r--r--Stars45/Font.h142
-rw-r--r--Stars45/FontMgr.cpp56
-rw-r--r--Stars45/FontMgr.h49
-rw-r--r--Stars45/FormDef.cpp1268
-rw-r--r--Stars45/FormDef.h331
-rw-r--r--Stars45/FormWindow.cpp807
-rw-r--r--Stars45/FormWindow.h76
-rw-r--r--Stars45/FormatUtil.cpp335
-rw-r--r--Stars45/FormatUtil.h46
-rw-r--r--Stars45/Galaxy.cpp281
-rw-r--r--Stars45/Galaxy.h73
-rw-r--r--Stars45/Game.cpp292
-rw-r--r--Stars45/Game.h117
-rw-r--r--Stars45/GameScreen.cpp1251
-rw-r--r--Stars45/GameScreen.h191
-rw-r--r--Stars45/GameWinDX9.cpp662
-rw-r--r--Stars45/GameWinDX9.h79
-rw-r--r--Stars45/Geometry.cpp696
-rw-r--r--Stars45/Geometry.h303
-rw-r--r--Stars45/Graphic.cpp168
-rw-r--r--Stars45/Graphic.h138
-rw-r--r--Stars45/Grid.cpp90
-rw-r--r--Stars45/Grid.h49
-rw-r--r--Stars45/GroundAI.cpp189
-rw-r--r--Stars45/GroundAI.h60
-rw-r--r--Stars45/HUDSounds.cpp116
-rw-r--r--Stars45/HUDSounds.h45
-rw-r--r--Stars45/HUDView.cpp4373
-rw-r--r--Stars45/HUDView.h217
-rw-r--r--Stars45/Hangar.cpp932
-rw-r--r--Stars45/Hangar.h126
-rw-r--r--Stars45/HardPoint.cpp102
-rw-r--r--Stars45/HardPoint.h81
-rw-r--r--Stars45/Hoop.cpp154
-rw-r--r--Stars45/Hoop.h44
-rw-r--r--Stars45/IA3D.H128
-rw-r--r--Stars45/ImageBox.cpp296
-rw-r--r--Stars45/ImageBox.h70
-rw-r--r--Stars45/ImgView.cpp77
-rw-r--r--Stars45/ImgView.h50
-rw-r--r--Stars45/Instruction.cpp568
-rw-r--r--Stars45/Instruction.h165
-rw-r--r--Stars45/Intel.cpp44
-rw-r--r--Stars45/Intel.h36
-rw-r--r--Stars45/JoyDlg.cpp229
-rw-r--r--Stars45/JoyDlg.h55
-rw-r--r--Stars45/Joystick.cpp914
-rw-r--r--Stars45/Joystick.h82
-rw-r--r--Stars45/KeyDlg.cpp197
-rw-r--r--Stars45/KeyDlg.h64
-rw-r--r--Stars45/KeyMap.cpp825
-rw-r--r--Stars45/KeyMap.h180
-rw-r--r--Stars45/Keyboard.cpp215
-rw-r--r--Stars45/Keyboard.h73
-rw-r--r--Stars45/LandingGear.cpp278
-rw-r--r--Stars45/LandingGear.h65
-rw-r--r--Stars45/Layout.cpp249
-rw-r--r--Stars45/Layout.h64
-rw-r--r--Stars45/Light.cpp70
-rw-r--r--Stars45/Light.h95
-rw-r--r--Stars45/ListBox.cpp1332
-rw-r--r--Stars45/ListBox.h169
-rw-r--r--Stars45/LoadDlg.cpp76
-rw-r--r--Stars45/LoadDlg.h40
-rw-r--r--Stars45/LoadScreen.cpp160
-rw-r--r--Stars45/LoadScreen.h63
-rw-r--r--Stars45/Locale_ss.cpp234
-rw-r--r--Stars45/Locale_ss.h52
-rw-r--r--Stars45/MCIWave.cpp150
-rw-r--r--Stars45/MCIWave.h24
-rw-r--r--Stars45/MachineInfo.cpp823
-rw-r--r--Stars45/MachineInfo.h41
-rw-r--r--Stars45/Main.cpp150
-rw-r--r--Stars45/MapView.cpp3482
-rw-r--r--Stars45/MapView.h222
-rw-r--r--Stars45/Menu.cpp141
-rw-r--r--Stars45/Menu.h123
-rw-r--r--Stars45/MenuDlg.cpp273
-rw-r--r--Stars45/MenuDlg.h85
-rw-r--r--Stars45/MenuScreen.cpp1073
-rw-r--r--Stars45/MenuScreen.h198
-rw-r--r--Stars45/MenuView.cpp331
-rw-r--r--Stars45/MenuView.h76
-rw-r--r--Stars45/Mfd.cpp1405
-rw-r--r--Stars45/Mfd.h103
-rw-r--r--Stars45/Mission.cpp2160
-rw-r--r--Stars45/Mission.h425
-rw-r--r--Stars45/MissionEvent.cpp872
-rw-r--r--Stars45/MissionEvent.h166
-rw-r--r--Stars45/MissionTemplate.cpp844
-rw-r--r--Stars45/MissionTemplate.h116
-rw-r--r--Stars45/ModConfig.cpp373
-rw-r--r--Stars45/ModConfig.h74
-rw-r--r--Stars45/ModDlg.cpp342
-rw-r--r--Stars45/ModDlg.h93
-rw-r--r--Stars45/ModInfo.cpp290
-rw-r--r--Stars45/ModInfo.h121
-rw-r--r--Stars45/ModInfoDlg.cpp113
-rw-r--r--Stars45/ModInfoDlg.h64
-rw-r--r--Stars45/MotionController.h230
-rw-r--r--Stars45/Mouse.cpp190
-rw-r--r--Stars45/Mouse.h74
-rw-r--r--Stars45/MouseController.cpp245
-rw-r--r--Stars45/MouseController.h69
-rw-r--r--Stars45/MsnDlg.cpp303
-rw-r--r--Stars45/MsnDlg.h72
-rw-r--r--Stars45/MsnEditDlg.cpp895
-rw-r--r--Stars45/MsnEditDlg.h115
-rw-r--r--Stars45/MsnEditNavDlg.cpp298
-rw-r--r--Stars45/MsnEditNavDlg.h77
-rw-r--r--Stars45/MsnElemDlg.cpp804
-rw-r--r--Stars45/MsnElemDlg.h98
-rw-r--r--Stars45/MsnEventDlg.cpp414
-rw-r--r--Stars45/MsnEventDlg.h85
-rw-r--r--Stars45/MsnNavDlg.cpp102
-rw-r--r--Stars45/MsnNavDlg.h53
-rw-r--r--Stars45/MsnObjDlg.cpp315
-rw-r--r--Stars45/MsnObjDlg.h67
-rw-r--r--Stars45/MsnPkgDlg.cpp335
-rw-r--r--Stars45/MsnPkgDlg.h65
-rw-r--r--Stars45/MsnSelectDlg.cpp498
-rw-r--r--Stars45/MsnSelectDlg.h80
-rw-r--r--Stars45/MsnWepDlg.cpp515
-rw-r--r--Stars45/MsnWepDlg.h85
-rw-r--r--Stars45/MultiController.cpp128
-rw-r--r--Stars45/MultiController.h67
-rw-r--r--Stars45/MusicDirector.cpp519
-rw-r--r--Stars45/MusicDirector.h115
-rw-r--r--Stars45/MusicTrack.cpp272
-rw-r--r--Stars45/MusicTrack.h76
-rw-r--r--Stars45/NPClient.h190
-rw-r--r--Stars45/NPClientWraps.cpp256
-rw-r--r--Stars45/NPClientWraps.h33
-rw-r--r--Stars45/NavAI.cpp621
-rw-r--r--Stars45/NavAI.h73
-rw-r--r--Stars45/NavDlg.cpp1125
-rw-r--r--Stars45/NavDlg.h118
-rw-r--r--Stars45/NavLight.cpp187
-rw-r--r--Stars45/NavLight.h66
-rw-r--r--Stars45/NavSystem.cpp112
-rw-r--r--Stars45/NavSystem.h54
-rw-r--r--Stars45/NetAddrDlg.cpp158
-rw-r--r--Stars45/NetAddrDlg.h59
-rw-r--r--Stars45/NetAdminChat.cpp120
-rw-r--r--Stars45/NetAdminChat.h32
-rw-r--r--Stars45/NetAdminServer.cpp884
-rw-r--r--Stars45/NetAdminServer.h90
-rw-r--r--Stars45/NetAuth.cpp204
-rw-r--r--Stars45/NetAuth.h50
-rw-r--r--Stars45/NetBrokerClient.cpp237
-rw-r--r--Stars45/NetBrokerClient.h42
-rw-r--r--Stars45/NetChat.cpp51
-rw-r--r--Stars45/NetChat.h51
-rw-r--r--Stars45/NetClientConfig.cpp331
-rw-r--r--Stars45/NetClientConfig.h72
-rw-r--r--Stars45/NetClientDlg.cpp430
-rw-r--r--Stars45/NetClientDlg.h79
-rw-r--r--Stars45/NetData.cpp1451
-rw-r--r--Stars45/NetData.h965
-rw-r--r--Stars45/NetFileServlet.cpp117
-rw-r--r--Stars45/NetFileServlet.h49
-rw-r--r--Stars45/NetGame.cpp328
-rw-r--r--Stars45/NetGame.h126
-rw-r--r--Stars45/NetGameClient.cpp1068
-rw-r--r--Stars45/NetGameClient.h86
-rw-r--r--Stars45/NetGameServer.cpp1202
-rw-r--r--Stars45/NetGameServer.h89
-rw-r--r--Stars45/NetLobby.cpp628
-rw-r--r--Stars45/NetLobby.h288
-rw-r--r--Stars45/NetLobbyClient.cpp807
-rw-r--r--Stars45/NetLobbyClient.h103
-rw-r--r--Stars45/NetLobbyDlg.cpp473
-rw-r--r--Stars45/NetLobbyDlg.h88
-rw-r--r--Stars45/NetLobbyServer.cpp1361
-rw-r--r--Stars45/NetLobbyServer.h118
-rw-r--r--Stars45/NetPacket.cpp354
-rw-r--r--Stars45/NetPacket.h73
-rw-r--r--Stars45/NetPassDlg.cpp141
-rw-r--r--Stars45/NetPassDlg.h57
-rw-r--r--Stars45/NetPlayer.cpp468
-rw-r--r--Stars45/NetPlayer.h97
-rw-r--r--Stars45/NetServerConfig.cpp470
-rw-r--r--Stars45/NetServerConfig.h101
-rw-r--r--Stars45/NetServerDlg.cpp177
-rw-r--r--Stars45/NetServerDlg.h63
-rw-r--r--Stars45/NetUnitDlg.cpp641
-rw-r--r--Stars45/NetUnitDlg.h92
-rw-r--r--Stars45/NetUser.cpp115
-rw-r--r--Stars45/NetUser.h111
-rw-r--r--Stars45/NetUtil.cpp422
-rw-r--r--Stars45/NetUtil.h55
-rw-r--r--Stars45/OptDlg.cpp320
-rw-r--r--Stars45/OptDlg.h86
-rw-r--r--Stars45/PCX.CPP514
-rw-r--r--Stars45/Panic.cpp50
-rw-r--r--Stars45/Panic.h19
-rw-r--r--Stars45/ParseUtil.cpp479
-rw-r--r--Stars45/ParseUtil.h51
-rw-r--r--Stars45/Parser.cpp307
-rw-r--r--Stars45/Parser.h45
-rw-r--r--Stars45/Particles.cpp262
-rw-r--r--Stars45/Particles.h85
-rw-r--r--Stars45/Pcx.h67
-rw-r--r--Stars45/Physical.cpp774
-rw-r--r--Stars45/Physical.h204
-rw-r--r--Stars45/PlanScreen.cpp392
-rw-r--r--Stars45/PlanScreen.h107
-rw-r--r--Stars45/Player.cpp1553
-rw-r--r--Stars45/Player.h186
-rw-r--r--Stars45/PlayerDlg.cpp389
-rw-r--r--Stars45/PlayerDlg.h85
-rw-r--r--Stars45/PngImage.cpp255
-rw-r--r--Stars45/PngImage.h47
-rw-r--r--Stars45/Polygon.cpp738
-rw-r--r--Stars45/Polygon.h158
-rw-r--r--Stars45/Power.cpp299
-rw-r--r--Stars45/Power.h61
-rw-r--r--Stars45/Projector.cpp473
-rw-r--r--Stars45/Projector.h105
-rw-r--r--Stars45/QuantumDrive.cpp245
-rw-r--r--Stars45/QuantumDrive.h72
-rw-r--r--Stars45/QuantumFlash.cpp173
-rw-r--r--Stars45/QuantumFlash.h59
-rw-r--r--Stars45/QuantumView.cpp317
-rw-r--r--Stars45/QuantumView.h72
-rw-r--r--Stars45/QuitView.cpp302
-rw-r--r--Stars45/QuitView.h63
-rw-r--r--Stars45/RLoc.cpp86
-rw-r--r--Stars45/RLoc.h70
-rw-r--r--Stars45/RadioHandler.cpp557
-rw-r--r--Stars45/RadioHandler.h52
-rw-r--r--Stars45/RadioMessage.cpp163
-rw-r--r--Stars45/RadioMessage.h154
-rw-r--r--Stars45/RadioTraffic.cpp392
-rw-r--r--Stars45/RadioTraffic.h64
-rw-r--r--Stars45/RadioView.cpp641
-rw-r--r--Stars45/RadioView.h88
-rw-r--r--Stars45/RadioVox.cpp248
-rw-r--r--Stars45/RadioVox.h58
-rw-r--r--Stars45/Random.cpp146
-rw-r--r--Stars45/Random.h34
-rw-r--r--Stars45/Reader.cpp109
-rw-r--r--Stars45/Reader.h67
-rw-r--r--Stars45/Res.cpp26
-rw-r--r--Stars45/Res.h36
-rw-r--r--Stars45/RichTextBox.cpp452
-rw-r--r--Stars45/RichTextBox.h64
-rw-r--r--Stars45/Scene.cpp258
-rw-r--r--Stars45/Scene.h75
-rw-r--r--Stars45/Screen.cpp160
-rw-r--r--Stars45/Screen.h64
-rw-r--r--Stars45/ScrollWindow.cpp629
-rw-r--r--Stars45/ScrollWindow.h131
-rw-r--r--Stars45/SeekerAI.cpp255
-rw-r--r--Stars45/SeekerAI.h72
-rw-r--r--Stars45/Sensor.cpp849
-rw-r--r--Stars45/Sensor.h85
-rw-r--r--Stars45/Sha1.cpp589
-rw-r--r--Stars45/Sha1.h89
-rw-r--r--Stars45/Shadow.cpp174
-rw-r--r--Stars45/Shadow.h69
-rw-r--r--Stars45/Shield.cpp258
-rw-r--r--Stars45/Shield.h76
-rw-r--r--Stars45/ShieldRep.cpp248
-rw-r--r--Stars45/ShieldRep.h47
-rw-r--r--Stars45/Ship.cpp5313
-rw-r--r--Stars45/Ship.h582
-rw-r--r--Stars45/ShipAI.cpp1360
-rw-r--r--Stars45/ShipAI.h152
-rw-r--r--Stars45/ShipCtrl.cpp339
-rw-r--r--Stars45/ShipCtrl.h58
-rw-r--r--Stars45/ShipDesign.cpp3702
-rw-r--r--Stars45/ShipDesign.h291
-rw-r--r--Stars45/ShipKiller.cpp261
-rw-r--r--Stars45/ShipKiller.h54
-rw-r--r--Stars45/ShipSolid.cpp94
-rw-r--r--Stars45/ShipSolid.h51
-rw-r--r--Stars45/Shot.cpp625
-rw-r--r--Stars45/Shot.h128
-rw-r--r--Stars45/Sim.cpp3814
-rw-r--r--Stars45/Sim.h329
-rw-r--r--Stars45/SimEvent.cpp261
-rw-r--r--Stars45/SimEvent.h162
-rw-r--r--Stars45/SimObject.cpp148
-rw-r--r--Stars45/SimObject.h98
-rw-r--r--Stars45/Skin.cpp172
-rw-r--r--Stars45/Skin.h91
-rw-r--r--Stars45/Sky.cpp723
-rw-r--r--Stars45/Sky.h104
-rw-r--r--Stars45/Slider.cpp555
-rw-r--r--Stars45/Slider.h106
-rw-r--r--Stars45/Solid.cpp2476
-rw-r--r--Stars45/Solid.h312
-rw-r--r--Stars45/Sound.cpp284
-rw-r--r--Stars45/Sound.h149
-rw-r--r--Stars45/SoundCard.cpp103
-rw-r--r--Stars45/SoundCard.h76
-rw-r--r--Stars45/SoundD3D.cpp1296
-rw-r--r--Stars45/SoundD3D.h162
-rw-r--r--Stars45/Sprite.cpp378
-rw-r--r--Stars45/Sprite.h89
-rw-r--r--Stars45/StarServer.cpp436
-rw-r--r--Stars45/StarServer.h74
-rw-r--r--Stars45/StarSystem.cpp1953
-rw-r--r--Stars45/StarSystem.h321
-rw-r--r--Stars45/Stars.icobin2998 -> 0 bytes
-rw-r--r--Stars45/Stars.rc.conf39
-rw-r--r--Stars45/Starshatter.cpp2838
-rw-r--r--Stars45/Starshatter.h219
-rw-r--r--Stars45/StarshipAI.cpp821
-rw-r--r--Stars45/StarshipAI.h61
-rw-r--r--Stars45/StarshipTacticalAI.cpp280
-rw-r--r--Stars45/StarshipTacticalAI.h46
-rw-r--r--Stars45/SteerAI.cpp451
-rw-r--r--Stars45/SteerAI.h124
-rw-r--r--Stars45/System.cpp397
-rw-r--r--Stars45/System.h173
-rw-r--r--Stars45/SystemDesign.cpp166
-rw-r--r--Stars45/SystemDesign.h53
-rw-r--r--Stars45/TacRefDlg.cpp688
-rw-r--r--Stars45/TacRefDlg.h100
-rw-r--r--Stars45/TacticalAI.cpp957
-rw-r--r--Stars45/TacticalAI.h90
-rw-r--r--Stars45/TacticalView.cpp1494
-rw-r--r--Stars45/TacticalView.h119
-rw-r--r--Stars45/Term.cpp119
-rw-r--r--Stars45/Term.h171
-rw-r--r--Stars45/Terrain.cpp559
-rw-r--r--Stars45/Terrain.h118
-rw-r--r--Stars45/TerrainApron.cpp334
-rw-r--r--Stars45/TerrainApron.h70
-rw-r--r--Stars45/TerrainClouds.cpp267
-rw-r--r--Stars45/TerrainClouds.h63
-rw-r--r--Stars45/TerrainHaze.cpp88
-rw-r--r--Stars45/TerrainHaze.h45
-rw-r--r--Stars45/TerrainLayer.h62
-rw-r--r--Stars45/TerrainPatch.cpp1112
-rw-r--r--Stars45/TerrainPatch.h93
-rw-r--r--Stars45/TerrainRegion.cpp264
-rw-r--r--Stars45/TerrainRegion.h125
-rw-r--r--Stars45/TexCubeDX9.cpp118
-rw-r--r--Stars45/TexCubeDX9.h48
-rw-r--r--Stars45/TexDX9.cpp416
-rw-r--r--Stars45/TexDX9.h78
-rw-r--r--Stars45/Thruster.cpp594
-rw-r--r--Stars45/Thruster.h96
-rw-r--r--Stars45/Token.cpp544
-rw-r--r--Stars45/Token.h145
-rw-r--r--Stars45/TrackIR.cpp245
-rw-r--r--Stars45/TrackIR.h52
-rw-r--r--Stars45/Trail.cpp199
-rw-r--r--Stars45/Trail.h59
-rw-r--r--Stars45/Types.h65
-rw-r--r--Stars45/Universe.h31
-rw-r--r--Stars45/VersionInfo.cpp.conf9
-rw-r--r--Stars45/VersionInfo.h12
-rw-r--r--Stars45/VidDlg.cpp544
-rw-r--r--Stars45/VidDlg.h106
-rw-r--r--Stars45/Video.cpp63
-rw-r--r--Stars45/Video.h241
-rw-r--r--Stars45/VideoDX9.cpp3618
-rw-r--r--Stars45/VideoDX9.h194
-rw-r--r--Stars45/VideoDX9Enum.cpp1063
-rw-r--r--Stars45/VideoDX9Enum.h184
-rw-r--r--Stars45/VideoDX9VertexBuffer.cpp279
-rw-r--r--Stars45/VideoDX9VertexBuffer.h78
-rw-r--r--Stars45/VideoFactory.cpp69
-rw-r--r--Stars45/VideoFactory.h41
-rw-r--r--Stars45/VideoSettings.cpp273
-rw-r--r--Stars45/VideoSettings.h132
-rw-r--r--Stars45/View.h51
-rw-r--r--Stars45/Water.cpp293
-rw-r--r--Stars45/Water.h53
-rw-r--r--Stars45/Wave.h51
-rw-r--r--Stars45/Weapon.cpp1184
-rw-r--r--Stars45/Weapon.h203
-rw-r--r--Stars45/WeaponDesign.cpp725
-rw-r--r--Stars45/WeaponDesign.h186
-rw-r--r--Stars45/WeaponGroup.cpp346
-rw-r--r--Stars45/WeaponGroup.h105
-rw-r--r--Stars45/Weather.cpp177
-rw-r--r--Stars45/Weather.h66
-rw-r--r--Stars45/WebBrowser.cpp131
-rw-r--r--Stars45/WebBrowser.h45
-rw-r--r--Stars45/WepView.cpp529
-rw-r--r--Stars45/WepView.h87
-rw-r--r--Stars45/Window.cpp934
-rw-r--r--Stars45/Window.h103
-rw-r--r--Stars45/WndProc.cpp259
-rw-r--r--Stars45/WndProc.h21
-rw-r--r--Stars45/resource.h6
570 files changed, 0 insertions, 184206 deletions
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 <vector>
-#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<View> v_iter = view_list;
- while (++v_iter) {
- View* view = v_iter.value();
- view->OnShow();
- }
-
- ListIter<ActiveWindow> 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<View> v_iter = view_list;
- while (++v_iter) {
- View* view = v_iter.value();
- view->OnHide();
- }
-
- ListIter<ActiveWindow> 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<View> 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<DWORD>& min_x,
-const std::vector<DWORD>& min_y,
-const std::vector<float>& weight_x,
-const std::vector<float>& 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<float>& min_x,
-const std::vector<float>& min_y,
-const std::vector<float>& weight_x,
-const std::vector<float>& 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<View> 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<ActiveWindow> 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<AWMap> 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<ActiveWindow> 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<ActiveWindow> 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 <vector>
-#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<DWORD>& min_x,
- const std::vector<DWORD>& min_y,
- const std::vector<float>& weight_x,
- const std::vector<float>& weight_y);
- virtual void UseLayout(const std::vector<float>& min_x,
- const std::vector<float>& min_y,
- const std::vector<float>& weight_x,
- const std::vector<float>& 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<ActiveWindow>& 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<ActiveWindow> children;
- List<AWMap> 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 <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <io.h>
-#include <stdio.h>
-#include <time.h>
-
-#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<Text> mod_asteroids;
- loader->SetDataPath("Mods/Galaxy/Asteroids/");
- loader->ListFiles("*.mag", mod_asteroids);
-
- ListIter<Text> 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> 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<b2) ? a2 : b2;
-
- if (r2 > 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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<Contact> 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<Ship> 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<Ship> 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<Ship> 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<Ship> 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<Ship> 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<Graphic> 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<Light> 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<Graphic> 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<Light> 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> 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> 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<Graphic> 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<Graphic> 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<Graphic> 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<Graphic> 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<Graphic> 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> 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> 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<Graphic> 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<Campaign> 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<Campaign> 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<Campaign> 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>&
-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<Text> 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<CampaignPlan> 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<CombatZone> 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<Combatant> 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<CombatAction> 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<MissionInfo> 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<MissionInfo> 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<CampaignPlan> 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<CombatGroup> 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> 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<CombatGroup>& groups)
-{
- if (g->Type() == type && g->IntelLevel() > Intel::RESERVE) {
- if (!near_group || g->GetAssignedZone() == near_group->GetAssignedZone())
- groups.append(g);
- }
-
- ListIter<CombatGroup> 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<CombatGroup> groups;
-
- ListIter<Combatant> 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<CombatGroup>& 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<CombatGroup> subgroup = g->GetComponents();
- while (++subgroup)
- FindStrikeTargets(subgroup.value(), strike_group, groups);
-}
-
-CombatGroup*
-Campaign::FindStrikeTarget(int iff, CombatGroup* strike_group)
-{
- CombatGroup* result = 0;
-
- List<CombatGroup> groups;
-
- ListIter<Combatant> 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<CombatAction> 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<Combatant> 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<CombatUnit>& units)
-{
- if (g) {
- ListIter<CombatUnit> unit = g->GetUnits();
- while (++unit) {
- CombatUnit* u = unit.value();
-
- if (u->Count() - u->DeadCount() > 0)
- units.append(u);
- }
-
- ListIter<CombatGroup> comp = g->GetComponents();
- while (++comp) {
- CombatGroup* g2 = comp.value();
-
- if (!g2->IsReserve())
- GetCombatUnits(g2, units);
- }
- }
-}
-
-int
-Campaign::GetAllCombatUnits(int iff, List<CombatUnit>& units)
-{
- units.clear();
-
- ListIter<Combatant> 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<MissionInfo> 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<MissionInfo>& GetMissionList() { return missions; }
- List<Combatant>& GetCombatants() { return combatants; }
- List<CombatZone>& GetZones() { return zones; }
- List<StarSystem>& GetSystemList() { return systems; }
- List<CombatAction>& GetActions() { return actions; }
- List<CombatEvent>& 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<CombatUnit>& units);
-
- static void Initialize();
- static void Close();
- static Campaign* GetCampaign();
- static List<Campaign>&
- 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<Combatant> combatants;
- List<StarSystem> systems;
- List<CombatZone> zones;
- List<CampaignPlan> planners;
- List<MissionInfo> missions;
- List<TemplateList> templates;
- List<CombatAction> actions;
- List<CombatEvent> 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<CombatGroup> 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<CombatZone> z_iter = campaign->GetZones();
- while (++z_iter) {
- CombatZone* z = z_iter.value();
-
- ListIter<ZoneForce> iter = z->GetForces();
- while (++iter) {
- ZoneForce* force = iter.value();
- ListIter<CombatGroup> 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<CombatUnit>& 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<MissionElement> 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<MissionElement> patrols;
-
- ListIter<MissionElement> 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<CombatZone>& 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<CombatUnit>& 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<CombatUnit>& 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<Instruction> 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<Instruction> 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<MissionElement> 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<MissionElement> 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<CombatGroup> 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> 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<CombatZone> z = campaign->GetZones();
- while (++z) {
- ListIter<ZoneForce> iter = z->GetForces();
- while (++iter) {
- ZoneForce* force = iter.value();
- ListIter<CombatGroup> 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<MissionElement> 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<CombatUnit>& 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<MissionElement> 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<CombatZone>& 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<MissionElement> 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<CombatGroup> groups;
- ListIter<CombatGroup> 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<MissionElement> 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<Combatant> 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<CombatZone> zone = campaign->GetZones();
- while (++zone) {
- ProcessZone(c, zone.value());
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-CampaignPlanAssignment::BuildZoneList(CombatGroup* g, CombatZone* zone, List<CombatGroup>& groups)
-{
- if (!g)
- return;
-
- if (g->GetAssignedZone() == zone)
- groups.append(g);
-
- ListIter<CombatGroup> iter = g->GetComponents();
- while (++iter)
- BuildZoneList(iter.value(), zone, groups);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-CampaignPlanAssignment::BuildAssetList(const int* pref,
-List<CombatGroup>& groups,
-List<CombatGroup>& assets)
-{
- if (!pref)
- return;
-
- while (*pref) {
- ListIter<CombatGroup> g = groups;
- while (++g) {
- if (g->Type() == *pref && g->CountUnits() > 0)
- assets.append(g.value());
- }
-
- pref++;
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-CampaignPlanAssignment::ProcessZone(Combatant* c, CombatZone* zone)
-{
- List<CombatGroup> groups;
- BuildZoneList(c->GetForce(), zone, groups);
-
- ZoneForce* force = zone->FindForce(c->GetIFF());
-
- // defensive assignments:
- ListIter<CombatGroup> def = force->GetDefendList();
- while (++def) {
- List<CombatGroup> assets;
- BuildAssetList(CombatGroup::PreferredDefender(def->Type()), groups, assets);
-
- ListIter<CombatGroup> g = assets;
- while (++g) {
- CombatAssignment* a = new
- CombatAssignment(Mission::DEFEND,
- def.value(),
- g.value());
-
- if (a)
- g->GetAssignments().append(a);
- }
- }
-
- // offensive assignments:
- ListIter<CombatGroup> tgt = force->GetTargetList();
- while (++tgt) {
- CombatGroup* target = tgt.value();
-
- List<CombatGroup> assets;
- BuildAssetList(CombatGroup::PreferredAttacker(tgt->Type()), groups, assets);
-
- ListIter<CombatGroup> 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<CombatGroup>& list);
- virtual void BuildAssetList(const int* pref, List<CombatGroup>& avail, List<CombatGroup>& 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<CombatAction> 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<Text> iter = action->AssetKills();
- while (++iter) {
- Text* name = iter.value();
- CombatUnit* asset = g->FindUnit(*name);
-
- if (asset) {
- int value_killed = asset->Kill(1);
-
- ListIter<Combatant> 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<Text> iter = action->TargetKills();
- while (++iter) {
- Text* name = iter.value();
- CombatUnit* target = g->FindUnit(*name);
-
- if (target) {
- int value_killed = target->Kill(1);
-
- ListIter<Combatant> 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<Combatant> 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<CombatAssignment>& alist)
-{
- if (!g) return;
-
- alist.append(g->GetAssignments());
-
- ListIter<CombatGroup> iter = g->GetComponents();
- while (++iter)
- FindAssignments(iter.value(), alist);
-}
-
-CombatAssignment*
-CampaignPlanEvent::ChooseAssignment(CombatGroup* g)
-{
- List<CombatAssignment> 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<MissionInfo>& 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<CombatAction> 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<CombatAssignment> assignments;
- assignments.append(player_group->GetAssignments());
-
- if (player_group->Type() == CombatGroup::WING) {
- ListIter<CombatGroup> 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<CombatUnit> 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<CombatUnit> 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<CombatUnit> 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<CombatZone> zone = campaign->GetZones();
- while (++zone)
- zone->Clear();
-
- ListIter<Combatant> 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<CombatGroup> iter = g->GetComponents();
- while (++iter)
- PlaceGroup(iter.value());
-}
-
-// +--------------------------------------------------------------------+
-
-void
-CampaignPlanStrategic::ScoreCombatant(Combatant* c)
-{
- // prep lists:
- c->GetDefendList().clear();
- c->GetTargetList().clear();
-
- ScoreDefensible(c);
-
- ListIter<Combatant> 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<CombatGroup> 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<CombatGroup> iter = g->GetComponents();
- while (++iter) {
- ScoreTarget(c, iter.value());
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-CampaignPlanStrategic::ScoreNeeds(Combatant* c)
-{
- ListIter<CombatZone> 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<CombatGroup> 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<CombatGroup> tgt = force->GetTargetList();
- while (++tgt) {
- int attacker_type = *CombatGroup::PreferredAttacker(tgt->Type());
- force->AddNeed(attacker_type, tgt->Value());
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-CampaignPlanStrategic::BuildGroupList(CombatGroup* g, List<CombatGroup>& groups)
-{
- if (!g || g->IsReserve())
- return;
-
- if (g->IsAssignable())
- groups.append(g);
-
- ListIter<CombatGroup> iter = g->GetComponents();
- while (++iter)
- BuildGroupList(iter.value(), groups);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-CampaignPlanStrategic::AssignZones(Combatant* c)
-{
- // find the list of assignable groups, in priority order:
- List<CombatGroup> groups;
- BuildGroupList(c->GetForce(), groups);
- groups.sort();
-
- // for each group, assign a zone:
- ListIter<CombatGroup> 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<CombatZone> possible_zones;
-
- if (g->IsZoneLocked()) {
- current_zone = g->GetAssignedZone();
- current_force = current_zone->FindForce(g->GetIFF());
- }
-
- else {
- ListIter<CombatZone> 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<CombatGroup> squadron = g->GetComponents();
- while (++squadron) {
- squadron->SetAssignedZone(assigned_zone);
- assigned_force->AddNeed(squadron->Type(), -(squadron->Value()));
-
- if (squadron->Type() == CombatGroup::WING) {
- ListIter<CombatGroup> 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<CombatZone> possible_zones;
-
- if (g->IsZoneLocked()) {
- current_zone = g->GetAssignedZone();
- current_force = current_zone->FindForce(g->GetIFF());
- }
-
- else {
- ListIter<CombatZone> 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<CombatGroup> 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<CombatGroup>& 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<Campaign>& 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<CombatAction> 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<Campaign>& 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<Combatant> 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<CombatAction> 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<CombatEvent> 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<Text> 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<Text>& 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<Text>& 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<MissionElement> 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<Instruction> nav = player->NavList();
- while (++nav) {
- if (rgn0 != nav->RegionName())
- rgn1 = nav->RegionName();
- }
-
- ListIter<MissionElement> 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<Element> 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<Element> assigned;
- ListIter<Element> 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<Element> 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<ShipLoad> sl = (List<ShipLoad>&) 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 <chrono>
-
-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<inner_clock::duration>(delta * m_compression);
- m_real_elapsed += delta;
- const std::chrono::duration<double> 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<double> skip {seconds};
- m_game_elapsed += std::chrono::duration_cast<inner_clock::duration>(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<elapsed_duration>(m_game_elapsed).count();
-}
-
-
-Clock::count_type
-Clock::RealTime() const
-{
- return std::chrono::duration_cast<elapsed_duration>(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 <chrono>
-
-
-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<Combatant>& 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<CombatGroup>& 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<CombatGroup>& 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<CombatUnit> 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<CombatGroup>& 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<Combatant> 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<CombatGroup> 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<Combatant>& 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<CombatEvent>& 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("<font Limerick12><color ffff80>");
- info += event->Title();
- info += "<font Verdana><color ffffff>\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<MissionInfo>& 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<MissionInfo>& 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("<font Limerick12><color ffff80>");
- desc += info->name;
- desc += "<font Verdana><color ffffff>\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("<font Limerick12><color ffff80>");
- orders += ContentBundle::GetInstance()->GetText("CmdOrdersDlg.situation");
- orders += "\n<font Verdana><color ffffff>";
- if (*campaign->Situation())
- orders += campaign->Situation();
- else
- orders += campaign->Description();
-
- orders += "\n\n<font Limerick12><color ffff80>";
- orders += ContentBundle::GetInstance()->GetText("CmdOrdersDlg.orders");
- orders += "\n<font Verdana><color ffffff>";
- 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<Text> 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 <mutex>
-
-#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<std::mutex> 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("<font Limerick12><color ffffff>") +
- campaign->Name() +
- Text("<font Verdana>\n\n") +
- Text("<color ffff80>") +
- ContentBundle::GetInstance()->GetText("CmpSelectDlg.scenario") +
- Text("<color ffffff>\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("<font Limerick12><color ffffff>") +
- campaign->Name() +
- Text("<font Verdana>\n\n") +
- Text("<color ffff80>") +
- ContentBundle::GetInstance()->GetText("CmpSelectDlg.scenario") +
- Text("<color ffffff>\n\t") +
- campaign->Description() +
- Text("\n\n<color ffff80>") +
- ContentBundle::GetInstance()->GetText("CmpSelectDlg.campaign-time") +
- Text("<color ffffff>\n\t") +
- time_buf +
- Text("\n\n<color ffff80>") +
- ContentBundle::GetInstance()->GetText("CmpSelectDlg.assignment") +
- Text("<color ffffff>\n\t");
-
- if (campaign->GetPlayerGroup())
- desc += campaign->GetPlayerGroup()->GetDescription();
- else
- desc += "n/a";
-
- desc += Text("\n\n<color ffff80>") +
- ContentBundle::GetInstance()->GetText("CmpSelectDlg.team-score") +
- Text("<color ffffff>\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<std::mutex> lock(sync);
- return !loading;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-CmpSelectDlg::ShowNewCampaigns()
-{
- const std::lock_guard<std::mutex> 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<Campaign> 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<std::mutex> 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<Text> 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<std::mutex> 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<Campaign>& 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<std::mutex> 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<std::mutex> 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<Campaign>& 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 <mutex>
-
-#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<Bitmap> 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<<campaign->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<Campaign>& 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<CombatEvent> 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.rshift)|(g<<format.gshift)|(b<<format.bshift)|(a<<format.ashift);
-
- }
-
- else if (standard_format) {
- return rgba;
- }
-
- else {
- DWORD r = Red() >>format.rdown;
- DWORD g = Green()>>format.gdown;
- DWORD b = Blue() >>format.bdown;
- DWORD a = Alpha()>>format.adown;
-
- return (r<<format.rshift)|(g<<format.gshift)|(b<<format.bshift)|(a<<format.ashift);
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-Color
-Color::Faded() const
-{
- if (fade != 1.0) {
- double step = (1.0 - fade);
-
- DWORD r = ((int) ((fRed() - (fRed() - fade_color.fRed()) * step)*255.0));
- DWORD g = ((int) ((fGreen() - (fGreen() - fade_color.fGreen())* step)*255.0));
- DWORD b = ((int) ((fBlue() - (fBlue() - fade_color.fBlue()) * step)*255.0));
- DWORD a = Alpha();
-
- return Color((BYTE) r, (BYTE) g, (BYTE) b, (BYTE) a);
-
- }
-
- else {
- return *this;
- }
-}
-
-// +--------------------------------------------------------------------+
-
-DWORD
-Color::Unfaded() const
-{
- if (standard_format) {
- return rgba;
- }
-
- if (format.pal) {
- return Index();
- }
- else {
- DWORD r = Red() >>format.rdown;
- DWORD g = Green()>>format.gdown;
- DWORD b = Blue() >>format.bdown;
- DWORD a = Alpha()>>format.adown;
-
- return (r<<format.rshift)|(g<<format.gshift)|(b<<format.bshift)|(a<<format.ashift);
- }
-}
-
-// +--------------------------------------------------------------------+
-
-DWORD
-Color::TextureFormat(int keep_alpha) const
-{
- if (texture_format[texture_alpha_level].pal) {
- return Index();
- }
- else if (rgba == 0) {
- return 0;
- }
- else {
- ColorFormat& tf = texture_format[texture_alpha_level];
-
- DWORD r = Red();
- DWORD g = Green();
- DWORD b = Blue();
- DWORD a = 0;
-
- if (keep_alpha) {
- a = Alpha()>>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<<tf.rshift)|(g<<tf.gshift)|(b<<tf.bshift)|(a<<tf.ashift);
- }
-}
-
-// +--------------------------------------------------------------------+
-
-Color
-Color::ShadeColor(int shade) const
-{
- double fr = fRed(), sr = fr;
- double fg = fGreen(), sg = fg;
- double fb = fBlue(), sb = fb;
- double range = SHADE_LEVELS;
-
- // first shade:
- if (shade < SHADE_LEVELS) { // shade towards black
- sr = fr * (shade/range);
- sg = fg * (shade/range);
- sb = fb * (shade/range);
- }
- else if (shade > 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<<r)-1)<<rs),
- gdown(8-g), gshift(gs), gmask(((1<<g)-1)<<gs),
- bdown(8-b), bshift(bs), bmask(((1<<b)-1)<<bs),
- adown(8-a), ashift(as), amask(((1<<a)-1)<<as) { }
-
- int pal;
- int bpp;
- BYTE rdown, rshift;
- BYTE gdown, gshift;
- BYTE bdown, bshift;
- BYTE adown, ashift;
-
- DWORD rmask;
- DWORD gmask;
- DWORD bmask;
- DWORD amask;
-};
-
-// +--------------------------------------------------------------------+
-
-class Color
-{
- friend class ColorIndex;
- friend class ColorValue;
-
-public:
- static const char* TYPENAME() { return "Color"; }
-
- enum Misc { SHADE_LEVELS = 64 }; // max 128!
- enum Mask { RMask = 0x00ff0000,
- GMask = 0x0000ff00,
- BMask = 0x000000ff,
- AMask = 0xff000000,
- RGBMask = 0x00ffffff };
- enum Shift { RShift = 16,
- GShift = 8,
- BShift = 0,
- AShift = 24 };
-
- Color() : rgba(0) { }
- Color(const Color& c) : rgba(c.rgba) { }
- Color(BYTE r, BYTE g, BYTE b, BYTE a=255) {
- rgba = (r<<RShift)|(g<<GShift)|(b<<BShift)|(a<<AShift); }
-
- Color(BYTE index);
-
- Color& operator= (const Color& c) { rgba = c.rgba; return *this; }
- int operator==(const Color& c) const { return rgba == c.rgba; }
- int operator!=(const Color& c) const { return rgba != c.rgba; }
- Color& operator+=(const Color& c); // simple summation
-
- Color operator+(DWORD d) const;
-
- Color operator+(const Color& c) const; // color alpha blending
- Color operator*(const Color& c) const; // color modulation
- Color operator*(double scale) const;
- Color dim(double scale) const;
-
- void Set(DWORD value) { rgba = value; }
- void Set(BYTE r, BYTE g, BYTE b, BYTE a=255) {
- rgba = (r<<RShift)|(g<<GShift)|(b<<BShift)|(a<<AShift); }
-
- DWORD Value() const { return rgba; }
-
- void SetRed(BYTE r) { rgba = (rgba & ~RMask) | (r << RShift); }
- void SetGreen(BYTE g) { rgba = (rgba & ~GMask) | (g << GShift); }
- void SetBlue(BYTE b) { rgba = (rgba & ~BMask) | (b << BShift); }
- void SetAlpha(BYTE a) { rgba = (rgba & ~AMask) | (a << AShift); }
-
- DWORD Red() const { return (rgba & RMask) >> 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<CombatActionReq> iter = pThis->requirements;
- while (++iter) {
- CombatActionReq* r = iter.value();
- bool ok = false;
-
- if (r->action > 0) {
- ListIter<CombatAction> 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<Text>& AssetKills() { return asset_kills; }
- int TargetType() const { return target_type; }
- int TargetId() const { return target_id; }
- int TargetIFF() const { return target_iff; }
- List<Text>& 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<Text> asset_kills;
- int target_type;
- int target_id;
- int target_iff;
- List<Text> target_kills;
-
- List<CombatActionReq> 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<CombatGroup> 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<CombatUnit> 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<CombatGroup> 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<CombatGroup> iter = components;
- while (++iter) {
- CombatGroup* g = iter.value();
- g->SetAssignedZone(z);
- }
-}
-
-void
-CombatGroup::ClearUnlockedZones()
-{
- if (!zone_lock)
- assigned_zone = 0;
-
- ListIter<CombatGroup> 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<CombatGroup> 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<CombatUnit> unit = units;
- while (++unit)
- val += unit->GetValue();
-
- ListIter<CombatGroup> comp = components;
- while (++comp)
- val += comp->CalcValue();
-
- value = val;
- return value;
-}
-
-int
-CombatGroup::CountUnits() const
-{
- int n = 0;
-
- CombatGroup* g = (CombatGroup*) this;
-
- ListIter<CombatUnit> unit = g->units;
- while (++unit)
- n += unit->Count() - unit->DeadCount();
-
- CombatGroup* pThis = ((CombatGroup*) this);
- pThis->live_comp.clear();
- ListIter<CombatGroup> 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<CombatGroup> 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<CombatUnit> live;
-
- ListIter<CombatUnit> 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<CombatGroup> 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<CombatUnit> live;
-
- ListIter<CombatUnit> 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<CombatUnit> 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<CombatGroup> comp = components;
- while (++comp)
- comp->AssignRegion(rgn);
-
- ListIter<CombatUnit> 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<CombatUnit> 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<CombatUnit> 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<CombatUnit> 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<CombatUnit> 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<CombatUnit> u = g->GetUnits();
- while (++u) {
- SaveCombatUnit(f, u.value());
- }
-
- fprintf(f, " }\n");
-
- ListIter<CombatGroup> 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<CombatGroup>& GetComponents() { return components; }
- List<CombatGroup>& GetLiveComponents() { return live_comp; }
- List<CombatUnit>& 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<CombatAssignment>& 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<CombatUnit> units;
- List<CombatGroup> components;
- List<CombatGroup> 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<CombatAssignment> 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<Text> 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<CombatGroup> 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<CombatGroup> 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<CombatUnit> u_iter = group->GetUnits();
- while (++u_iter) {
- CombatUnit* u = u_iter.value();
- value_killed += u->Kill(u->LiveCount());
- }
-
- ListIter<CombatGroup> 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<CombatGroup> 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<CombatUnit>& 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<CombatUnit> 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<ZoneForce> 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<CombatZone> zonelist;
-
-List<CombatZone>&
-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<Text>& GetRegions() { return regions; }
- List<ZoneForce>& GetForces() { return forces; }
-
- ZoneForce* FindForce(int iff);
- ZoneForce* MakeForce(int iff);
-
- void Clear();
-
- static List<CombatZone>&
- Load(const char* filename);
-
-private:
- // attributes:
- Text name;
- Text system;
- List<Text> regions;
- List<ZoneForce> forces;
-};
-
-// +--------------------------------------------------------------------+
-
-class ZoneForce
-{
-public:
- ZoneForce(int i);
-
- int GetIFF() { return iff; }
- List<CombatGroup>& GetGroups() { return groups; }
- List<CombatGroup>& GetTargetList() { return target_list; }
- List<CombatGroup>& 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<CombatGroup> groups;
- List<CombatGroup> defend_list;
- List<CombatGroup> 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<CombatGroup> 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<CombatGroup>& GetTargetList() { return target_list; }
- List<CombatGroup>& GetDefendList() { return defend_list; }
- List<Mission>& 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<CombatGroup> target_list;
- List<CombatGroup> defend_list;
- List<Mission> 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<Text> 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 <algorithm>
-
-#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<Text> 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<Text> item)
-{
- while (++item)
- items.append(new Text(*item));
-}
-
-void ComboList::SetItems(ListIter<Text> 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<Text> item_list);
- virtual void SetItems(ListIter<Text> 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<Text> 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<Text> bundles;
-
- loader->SetDataPath("Content/");
- loader->ListFiles("content*", bundles);
-
- ListIter<Text> 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<Text> 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<DataArchive> 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<DataArchive> 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<DataArchive> 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<Text>& 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<Text> &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<Text>& 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<Text>& list, bool recurse=false);
- int ListArchiveFiles(const char* archive, const char* filter, List<Text>& 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<Text>& 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<SimEvent> 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<Graphic> 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<Graphic> rep[MAX_DETAIL];
- List<Point> off[MAX_DETAIL];
- double rad[MAX_DETAIL];
-
- List<Point> spin;
- List<Point> 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<DisplayElement> 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<DisplayElement> 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<DisplayElement>
- 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 <algorithm>
-
-#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<DrivePort> 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<Instruction> 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<Instruction> navpt = flight_plan;
- while (++navpt) {
- index++;
- if (navpt.value() == n)
- return index;
- }
- }
-
- return 0;
-}
-
-// +----------------------------------------------------------------------+
-
-List<Instruction>&
-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<Element> 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<Ship> 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<Instruction> 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<Instruction>& 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<Ship> ships;
- List<Text> ship_names;
- List<Text> instructions;
- List<Instruction> objectives;
- List<Instruction> 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<PowerSource> 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<System> 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<System> iter = ship->RepairQueue();
- while (++iter) {
- double time_remaining = 0;
- char etr[20];
-
- System* sys = iter.value();
-
- ListIter<Component> 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<Component> 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<Component> 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<System>& 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<Component> 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<System>& 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<System> 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<System> 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<System> 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<System> 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<System> 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<Component>& 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<Component>& 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<Component> 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<System> route_list;
-
- PowerSource* selected_source;
- List<System> 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<EventTarget> 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<EventTarget> 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 <algorithm>
-
-#include <windows.h>
-#include <imagehlp.h>
-
-#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<Ship> 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<Ship> 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<Ship> 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<Ship> 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<WeaponGroup> g_iter = starship->Weapons();
- while (++g_iter) {
- WeaponGroup* group = g_iter.value();
-
- ListIter<Weapon> 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<Contact> 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<WeaponGroup>& weps)
-{
- weps.clear();
-
- if (tgt) {
- ListIter<WeaponGroup> 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<WeaponGroup> 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<WeaponGroup> 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<Contact> 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<WeaponGroup> g_iter = s->Weapons();
- while (++g_iter) {
- WeaponGroup* w = g_iter.value();
-
- if (w->Ammo() && w->CanTarget(target->Class())) {
- ListIter<Weapon> 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<WeaponGroup>& 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<int>(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<<Precision) { }
- fix(double d) : val(static_cast<long>(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<<Precision); return *this; }
- fix& operator=(double d) { val = static_cast<long>(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<<Precision); return r; }
- fix operator-(int n) const { fix r; r.val = val-(n<<Precision); return r; }
- fix operator*(int n) const { fix r; r.val = val*n; return r; }
- fix operator/(int n) const { fix r; r.val = val/n; return r; }
- fix& operator+=(int n) { val+=(n<<Precision); return *this; }
- fix& operator-=(int n) { val-=(n<<Precision); return *this; }
- fix& operator*=(int n) { val*=n; return *this; }
- fix& operator/=(int n) { val/=n; return *this; }
-
- fix operator+(double d) const { fix f(d); return (*this)+f; }
- fix operator-(double d) const { fix f(d); return (*this)-f; }
- fix operator*(double d) const { fix f(d); return (*this)*f; }
- fix operator/(double d) const { fix f(d); return (*this)/f; }
- fix& operator+=(double d) { fix f(d); val+=f.val; return *this; }
- fix& operator-=(double d) { fix f(d); val-=f.val; return *this; }
- fix& operator*=(double d) { val*=static_cast<long>(d); return *this; }
- fix& operator/=(double d) { val/=static_cast<long>(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<InboundSlot> 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<InboundSlot> 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<InboundSlot>& 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<InboundSlot> 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<Instruction> 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<ShipLoad> sl = (List<ShipLoad>&) 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<Element> 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<ShipLoad> sl = (List<ShipLoad>&) 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<FontItem> 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<FontItem> 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<FontItem> 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<CtrlDef>
-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 <vector>
-#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<DWORD> x_mins;
- std::vector<DWORD> y_mins;
- std::vector<float> x_weights;
- std::vector<float> 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<Text> items;
- List<ColumnDef> 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<CtrlDef> GetControls() const;
-
-protected:
- void ParseCtrlDef(CtrlDef* ctrl, TermStruct* val);
- void ParseColumnDef(CtrlDef* ctrl, TermStruct* val);
- void ParseLayoutDef(LayoutDef* def, TermStruct* val);
-
- CtrlDef defctrl;
- List<CtrlDef> 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<CtrlDef> 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<ActiveWindow> 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<ActiveWindow> 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<Text> mod_galaxies;
- loader->SetDataPath("Mods/Galaxy/");
- loader->ListFiles("*.def", mod_galaxies);
-
- ListIter<Text> 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<StarSystem> sys = systems;
- while (++sys) {
- sys->ExecFrame();
- }
-}
-
-// +--------------------------------------------------------------------+
-
-StarSystem*
-Galaxy::GetSystem(const char* name)
-{
- ListIter<StarSystem> sys = systems;
- while (++sys) {
- if (!strcmp(sys->Name(), name))
- return sys.value();
- }
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-StarSystem*
-Galaxy::FindSystemByRegion(const char* rgn_name)
-{
- ListIter<StarSystem> 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<StarSystem>& GetSystemList() { return systems; }
- List<Star>& 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<StarSystem> systems;
- List<Star> 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 <stdio.h>
-#include <string.h>
-
-#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<Contact> 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<WeaponGroup> 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> 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 && xtarg<width-1 && ytarg>0 && ytarg<height-1) {
- double range = Point(t->Location() - 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<WeaponGroup> 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 && xtarg<width-1 && ytarg>0 && ytarg<height-1) {
- double range = Point(t->Location() - 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<PowerSource> 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<Drive> 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<Weapon> 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<Computer> 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<FlightDeck> 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<Instruction> 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<Ship> 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<OrbitalBody> 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<OrbitalBody> 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<Element>& 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<Element>& 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<Surface> 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<Element> 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<Element> 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<Element> 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 <dinput.h>
-
-#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<steps) w1+=1; w = -sqr(w1/steps); }
- else if (KeyDownMap(KEY_ROLL_RIGHT)) { if (w1<steps) w1+=1; w = sqr(w1/steps); }
-
- // roll:
- if (KeyDownMap(KEY_YAW_LEFT)) { if (r1<steps) r1+=1; r = sqr(r1/steps); }
- else if (KeyDownMap(KEY_YAW_RIGHT)) { if (r1<steps) r1+=1; r = -sqr(r1/steps); }
- else w1 = 0;
- }
-
- // else roll and yaw are NOT swapped ---------------------
- else {
- // roll:
- if (KeyDownMap(KEY_ROLL_LEFT)) { if (r1<steps) r1+=1; r = sqr(r1/steps); }
- else if (KeyDownMap(KEY_ROLL_RIGHT)) { if (r1<steps) r1+=1; r = -sqr(r1/steps); }
-
- // yaw left-right
- if (KeyDownMap(KEY_YAW_LEFT)) { if (w1<steps) w1+=1; w = -sqr(w1/steps); }
- else if (KeyDownMap(KEY_YAW_RIGHT)) { if (w1<steps) w1+=1; w = sqr(w1/steps); }
- else w1 = 0;
- }
-
- // pitch --------------------------------------------------
- if (KeyDownMap(KEY_PITCH_UP)) { if (p1<steps) p1+=1; p = -sqr(p1/steps); }
- else if (KeyDownMap(KEY_PITCH_DOWN)) { if (p1<steps) p1+=1; p = sqr(p1/steps); }
- else p1 = 0;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Joystick::ProcessAxes(double joy_x, double joy_y, double joy_r, double joy_t)
-{
- int roll_enable = 0;
-
- joy_y *= -1;
- joy_t = 1 - joy_t;
-
- if (map[KEY_ROLL_ENABLE])
- roll_enable = action[map[KEY_ROLL_ENABLE] - KEY_JOY_1];
-
- // if roll and yaw are swapped --------------------------
- if (swapped) {
- if (roll_enable) {
- w = joy_x;
- r = joy_r;
- }
- else {
- w = joy_r;
- r = -joy_x;
- }
- }
-
- // else roll and yaw are NOT swapped ---------------------
- else {
- if (roll_enable) {
- w = joy_r;
- r = joy_x;
- }
- else {
- w = joy_x;
- r = -joy_r;
- }
- }
-
- p = joy_y;
-
- // read throttle:
- if (throttle) {
- static double init_throttle = -1;
- static bool latch_throttle = false;
-
- if (init_throttle < 0)
- init_throttle = joy_t;
- else if (init_throttle != joy_t)
- latch_throttle = true;
-
- if (latch_throttle)
- t = joy_t;
- else
- t = 0;
- }
- else {
- t = 0;
- }
-}
-
-void
-Joystick::ProcessHat(int i, DWORD joy_pov)
-{
- if (i < 0 || i > 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<long unsigned int>(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 (w1<steps) w1+=1; w = -sqr(w1/steps); }
- else if (KeyDownMap(KEY_ROLL_RIGHT)) { if (w1<steps) w1+=1; w = sqr(w1/steps); }
-
- // another way to yaw:
- if (KeyDownMap(KEY_ROLL_ENABLE)) {
- if (KeyDownMap(KEY_YAW_LEFT)) { if (w1<steps) w1+=1; w = -sqr(w1/steps); }
- else if (KeyDownMap(KEY_YAW_RIGHT)) { if (w1<steps) w1+=1; w = sqr(w1/steps); }
- else w1 = 0;
- }
-
- // roll:
- else {
- if (KeyDownMap(KEY_YAW_LEFT)) { if (r1<steps) r1+=1; r = sqr(r1/steps); }
- else if (KeyDownMap(KEY_YAW_RIGHT)) { if (r1<steps) r1+=1; r = -sqr(r1/steps); }
- else r1 = 0;
- }
- }
-
- // else roll and yaw are NOT swapped ---------------------
- else {
- // roll:
- if (KeyDownMap(KEY_ROLL_LEFT)) { if (r1<steps) r1+=1; r = sqr(r1/steps); }
- else if (KeyDownMap(KEY_ROLL_RIGHT)) { if (r1<steps) r1+=1; r = -sqr(r1/steps); }
-
- // another way to roll:
- if (KeyDownMap(KEY_ROLL_ENABLE)) {
- if (KeyDownMap(KEY_YAW_LEFT)) { if (r1<steps) r1+=1; r = sqr(r1/steps); }
- else if (KeyDownMap(KEY_YAW_RIGHT)) { if (r1<steps) r1+=1; r = -sqr(r1/steps); }
- else r1 = 0;
- }
-
- // yaw left-right
- else {
- if (KeyDownMap(KEY_YAW_LEFT)) { if (w1<steps) w1+=1; w = -sqr(w1/steps); }
- else if (KeyDownMap(KEY_YAW_RIGHT)) { if (w1<steps) w1+=1; w = sqr(w1/steps); }
- else w1 = 0;
- }
- }
-
- // if pitch is inverted ----------------------------------
- if (inverted) {
- if (KeyDownMap(KEY_PITCH_DOWN)) { if (p1<steps) p1+=1; p = -sqr(p1/steps); }
- else if (KeyDownMap(KEY_PITCH_UP)) { if (p1<steps) p1+=1; p = sqr(p1/steps); }
- else p1 = 0;
- }
-
- // else pitch is NOT inverted ----------------------------
- else {
- if (KeyDownMap(KEY_PITCH_UP)) { if (p1<steps) p1+=1; p = -sqr(p1/steps); }
- else if (KeyDownMap(KEY_PITCH_DOWN)) { if (p1<steps) p1+=1; p = sqr(p1/steps); }
- else p1 = 0;
- }
-
- if (KeyDownMap(KEY_CENTER)) c = 1;
-
- // actions
- if (KeyDownMap(KEY_ACTION_0)) action[0] = 1;
- if (KeyDownMap(KEY_ACTION_1)) action[1] = 1;
- if (KeyDownMap(KEY_ACTION_2)) action[2] = 1;
- if (KeyDownMap(KEY_ACTION_3)) action[3] = 1;
-}
-
-// +--------------------------------------------------------------------+
-
-
-
diff --git a/Stars45/Keyboard.h b/Stars45/Keyboard.h
deleted file mode 100644
index b218160..0000000
--- a/Stars45/Keyboard.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
- ========
- Keyboard Input class
-*/
-
-#ifndef Keyboard_h
-#define Keyboard_h
-
-#include "MotionController.h"
-
-// +--------------------------------------------------------------------+
-
-class Keyboard : public MotionController
-{
-public:
- static const char* TYPENAME() { return "Keyboard"; }
-
- Keyboard();
- virtual ~Keyboard();
-
- // 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 c; }
-
- // 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 void FlushKeys();
-
- static Keyboard* GetInstance();
-
-protected:
- double x,y,z,p,r,w,t;
- double p1, r1, w1;
- int c;
- int action[MotionController::MaxActions];
-
- static int map[KEY_MAP_SIZE];
- static int alt[KEY_MAP_SIZE];
-};
-
-// +--------------------------------------------------------------------+
-
-#endif // Keyboard_h
-
diff --git a/Stars45/LandingGear.cpp b/Stars45/LandingGear.cpp
deleted file mode 100644
index f5fa00b..0000000
--- a/Stars45/LandingGear.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/* Starshatter: The Open Source Project
- Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors
- Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors
- Copyright (c) 1997-2006, Destroyer Studios LLC.
-
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- LandingGear System class
-*/
-
-#include "LandingGear.h"
-#include "Ship.h"
-#include "Sim.h"
-#include "AudioConfig.h"
-
-#include "DataLoader.h"
-#include "Physical.h"
-#include "Scene.h"
-#include "Sound.h"
-#include "Game.h"
-#include "ContentBundle.h"
-
-static Sound* gear_transit_sound = 0;
-
-// +----------------------------------------------------------------------+
-
-LandingGear::LandingGear()
-: System(MISC_SYSTEM, 0, "Landing Gear", 1, 1, 1, 1),
-state(GEAR_UP), transit(0), ngear(0), clearance(0)
-{
- name = ContentBundle::GetInstance()->GetText("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<DWORD> cell_x;
- std::vector<DWORD> cell_y;
-
- ScaleWeights();
- CalcCells(panel->Width(), panel->Height(), cell_x, cell_y);
-
- ListIter<ActiveWindow> 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<DWORD>& cell_x, std::vector<DWORD>& 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<DWORD>& min_x,
-const std::vector<DWORD>& min_y,
-const std::vector<float>& weight_x,
-const std::vector<float>& 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<float>& min_x,
-const std::vector<float>& min_y,
-const std::vector<float>& weight_x,
-const std::vector<float>& 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<DWORD>& min_x,
- const std::vector<DWORD>& min_y,
- const std::vector<float>& weight_x,
- const std::vector<float>& weight_y);
-
- virtual void SetConstraints(const std::vector<float>& min_x,
- const std::vector<float>& min_y,
- const std::vector<float>& weight_x,
- const std::vector<float>& 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<DWORD>& cell_x, std::vector<DWORD>& cell_y);
-
- std::vector<DWORD> cols;
- std::vector<DWORD> rows;
- std::vector<float> col_weights;
- std::vector<float> 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<ListBoxCell> 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<ListBoxItem> 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<ListBoxCell> 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<ListBoxColumn> 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<ListBoxItem> 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<ListBoxItem> 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<ListBoxItem> items;
- List<ListBoxColumn> 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<Locale> 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<Locale> 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>&
-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<Locale>& 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 <chrono>
-
-#include "MachineInfo.h"
-#include "Utils.h"
-
-#define DIRECTINPUT_VERSION 0x0700
-
-#include <stdio.h>
-#include <ddraw.h>
-#include <d3d9.h>
-#include <dinput.h>
-#include <winver.h>
-
-// +--------------------------------------------------------------------+
-
-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<double> 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<StarSystem>& 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<OrbitalBody> 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<OrbitalBody> planet = star->Satellites();
- while (++planet) {
- planets.append(planet.value());
-
- ListIter<OrbitalBody> moon = planet->Satellites();
- while (++moon) {
- planets.append(moon.value());
- }
- }
-
- ListIter<OrbitalRegion> 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<StarSystem> 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<Text> 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<Text>& 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<MissionElement> 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<Orbital> 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<Ship> 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<MissionElement> 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<Orbital> 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<Ship> 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<MissionElement> 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<Orbital> 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<Ship> 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<StarSystem> 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<Orbital> 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<Orbital> 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<Orbital> 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<MissionElement> elem = mission->GetElements();
- while (++elem) {
- MissionElement* e = elem.value();
-
- if (!e->IsSquadron() && (editor || e->GetIFF() == mission->Team())) {
- ListIter<Instruction> 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<Instruction> 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> 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<StarSystem> 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<StarSystem> 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<Star> 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<OrbitalBody> star = system->Bodies();
- while (++star) {
- int p_orb = 1;
-
- ListIter<OrbitalBody> planet = star->Satellites();
- while (++planet) {
- DrawOrbital(*planet, p_orb++);
-
- int m_orb = 1;
-
- ListIter<OrbitalBody> moon = planet->Satellites();
- while (++moon) {
- DrawOrbital(*moon, m_orb++);
-
- ListIter<OrbitalRegion> region = moon->Regions();
- while (++region) {
- DrawOrbital(*region, 1);
- }
- }
-
- ListIter<OrbitalRegion> region = planet->Regions();
- while (++region) {
- DrawOrbital(*region, 1);
- }
- }
-
- ListIter<OrbitalRegion> 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 = (cx<cy) ? cx : cy;
- r = rgn->Radius() * 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<Combatant> iter = campaign->GetCombatants();
- while (++iter) {
- Combatant* combatant = iter.value();
- DrawCombatGroup(combatant->GetForce(), rep);
- }
- }
-
- else if (mission && rgn) {
- // draw the elements in this region:
- ListIter<MissionElement> 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<Contact> 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<Ship> 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<SimRegion> r_iter = sim->GetRegions();
- while (++r_iter) {
- SimRegion* r = r_iter.value();
-
- if (r != simrgn) {
- ListIter<Ship> 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 = (cx<cy) ? cx : cy;
- r = system->Radius() * 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<Combatant> 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 = (cx<cy) ? cx : cy;
- r = rgn->Radius() * 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 = (cx<cy) ? cx : cy;
- r = rgn->Radius() * 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<Instruction>& 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 = (cx<cy) ? cx : cy;
- r = system->Radius() * 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<CombatGroup> 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 = (cx<cy) ? cx : cy;
- r = rgn->Radius() * 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<CombatGroup> 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<Ship> 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 = (cx<cy) ? cx : cy;
- r = system->Radius() * 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<MissionElement> 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 = (cx<cy) ? cx : cy;
- r = system->Radius() * 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<Instruction>& 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<StarSystem>& 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<StarSystem>& 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<Text>& result);
- void SetupScroll(Orbital* s);
-
- double GetMinRadius(int type);
-
- Text title;
- Rect rect;
- Campaign* campaign;
- Mission* mission;
- List<StarSystem> system_list;
- StarSystem* system;
- List<Orbital> stars;
- List<Orbital> planets;
- List<Orbital> 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<MenuItem> GetItems() { return items; }
-
-protected:
- Text title;
- List<MenuItem> 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<Menu> 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<MenuItem> 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<MenuItem> 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<MenuItem> 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<Contact> 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> 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> 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<int>(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<MissionElement> 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<MissionElement> 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<MissionElement> 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<MissionEvent> 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<float> 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<float> 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<StarSystem> 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<MissionElement> 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<MissionLoad> 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<Instruction> 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<Instruction> 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<Text> i_iter = elem->Instructions();
- while (++i_iter) {
- s += " instr: \"";
- s += SafeString(*i_iter.value());
- s += "\"\n";
- }
- }
-
- if (elem->Ships().size()) {
- ListIter<MissionShip> 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<MissionEvent> 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<Instruction> 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<StarSystem>& GetSystemList() { return system_list; }
- const char* GetRegion() const { return region; }
-
- List<MissionElement>& GetElements() { return elements; }
- virtual MissionElement* FindElement(const char* name);
- virtual void AddElement(MissionElement* elem);
-
- List<MissionEvent>& 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<StarSystem> system_list;
-
- List<MissionElement> elements;
- List<MissionEvent> 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<Instruction>& Objectives() { return objectives; }
- List<Text>& Instructions() { return instructions; }
- List<Instruction>& NavList() { return navlist; }
- List<MissionLoad>& Loadouts() { return loadouts; }
- List<MissionShip>& 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<Instruction> objectives;
- List<Text> instructions;
- List<Instruction> navlist;
- List<MissionLoad> loadouts;
- List<MissionShip> 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<SimRegion> iter = sim->GetRegions();
- while (++iter) {
- SimRegion* rgn = iter.value();
-
- ListIter<Ship> 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<MissionEvent> 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<MissionEvent> 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<MissionEvent> 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<WeaponGroup> g_iter = ship->Weapons();
- while (++g_iter) {
- ListIter<Weapon> 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<Instruction> 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<Instruction> 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<CombatGroup>& 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<CombatGroup> 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<CombatGroup> group_list;
- static int combat_group_index = 0;
-
- if (campaign) {
- ListIter<Combatant> 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<MissionCallsign> c_iter = callsigns;
- while (++c_iter) {
- MissionCallsign* c = c_iter.value();
- if (c->Name() == name) {
- name = c->Callsign();
- break;
- }
- }
-
- ListIter<MissionAlias> a_iter = aliases;
- while (++a_iter) {
- MissionAlias* a = a_iter.value();
- if (a->Name() == name)
- return a->Element();
- }
-
- ListIter<MissionElement> 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<MissionElement> iter = elements;
- while (++iter) {
- MissionElement* elem = iter.value();
-
- ListIter<Instruction> 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<MissionAlias> aliases;
- List<MissionCallsign> 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<Text> 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<Text> 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<Text> 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<Text> 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<Text> 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<ModInfo> 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<Text>& EnabledMods() { return enabled; }
- List<Text>& DisabledMods() { return disabled; }
- List<ModInfo>& GetModInfoList() { return mods; }
-
- ModInfo* GetModInfo(const char* filename);
-
-private:
- List<Text> enabled;
- List<Text> disabled;
- List<ModInfo> 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<Text> iter_d = config->DisabledMods();
- while (++iter_d) {
- Text* t = iter_d.value();
- lst_disabled->AddItem(*t);
- }
-
- ListIter<Text> 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<ModCampaign>& 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<ModCampaign> 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<Instruction> 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<StarSystem> 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<OrbitalRegion> regions;
- regions.append(sys->AllRegions());
- regions.sort();
-
- i = 0;
- ListIter<OrbitalRegion> 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<MissionElement> 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<MissionEvent> 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<ActiveWindow> 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<StarSystem> 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<OrbitalRegion> regions;
- regions.append(sys->AllRegions());
- regions.sort();
-
- ListIter<OrbitalRegion> 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<MissionElement>& 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<MissionElement>& 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<MissionEvent>& 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<MissionEvent>& 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<StarSystem> 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<OrbitalRegion> regions;
- regions.append(sys->AllRegions());
- regions.sort();
-
- i = 0;
- ListIter<OrbitalRegion> 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<StarSystem> 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<OrbitalRegion> regions;
- regions.append(sys->AllRegions());
- regions.sort();
-
- ListIter<OrbitalRegion> 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<OrbitalRegion> regions;
- regions.append(sys->AllRegions());
- regions.sort();
-
- ListIter<OrbitalRegion> 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<MissionElement> 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<MissionElement> 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<MissionElement> 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<Text> 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<ShipLoad>& 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<Skin> 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<MissionElement> 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<Instruction>& 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<MissionElement>& 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<StarSystem> iter = mission->GetSystemList();
- while (++iter) {
- StarSystem* sys = iter.value();
-
- ListIter<OrbitalRegion> 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<Skin> 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<MissionElement> 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<Instruction> 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<Instruction> 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<MissionElement> 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<MissionElement> 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<Campaign> 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<Campaign> 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<MissionInfo> 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<MissionInfo> iter = campaign->GetMissionList();
- while (++iter) {
- cmb_campaigns->AddItem(iter->name);
- }
- }
-
- else if (lst_missions) {
- lst_missions->ClearItems();
-
- ListIter<MissionInfo> 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<MissionInfo>& 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("<font Limerick12><color ffffff>");
- d += info->name;
- d += "<font Verdana>\n\n<color ffff80>";
- d += ContentBundle::GetInstance()->GetText("MsnSelectDlg.mission-type");
- d += "<color ffffff>\n\t";
- d += Mission::RoleName(info->type);
- d += "\n\n<color ffff80>";
- d += ContentBundle::GetInstance()->GetText("MsnSelectDlg.scenario");
- d += "<color ffffff>\n\t";
- d += info->description;
- d += "\n\n<color ffff80>";
- d += ContentBundle::GetInstance()->GetText("MsnSelectDlg.location");
- d += "<color ffffff>\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<color ffff80>";
- d += ContentBundle::GetInstance()->GetText("MsnSelectDlg.start-time");
- d += "<color ffffff>\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<ShipLoad> sl = (List<ShipLoad>&) 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<HardPoint> 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<ShipLoad> 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<MissionLoad> 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<ShipLoad> sl = (List<ShipLoad>&) 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<MissionLoad> 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 <mutex>
-
-#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<std::mutex> 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<Text> files;
- loader->ListFiles("*.ogg", files, true);
-
- if (files.size() == 0) {
- loader->UseFileSystem(old_file_system);
- no_music = true;
- return;
- }
-
- no_music = false;
-
- ListIter<Text> 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<std::mutex> 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<Text>* 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<Text>* 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 <mutex>
-
-#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<Text> menu_tracks;
- List<Text> intro_tracks;
- List<Text> brief_tracks;
- List<Text> debrief_tracks;
- List<Text> promote_tracks;
- List<Text> flight_tracks;
- List<Text> combat_tracks;
- List<Text> launch_tracks;
- List<Text> recovery_tracks;
- List<Text> victory_tracks;
- List<Text> defeat_tracks;
- List<Text> 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<Ship> 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<OrbitalBody> 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<OrbitalBody> planet = star->Satellites();
- while (++planet) {
- planets.append(planet.value());
-
- ListIter<OrbitalBody> moon = planet->Satellites();
- while (++moon) {
- planets.append(moon.value());
- }
- }
- }
-
- ListIter<OrbitalRegion> 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<MissionElement> 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<Orbital> 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<Orbital> 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<OrbitalRegion> 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<StarSystem> 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<Orbital> 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<OrbitalRegion> 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<MissionElement> 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<SimRegion> r_iter = sim->GetRegions();
- while (++r_iter) {
- SimRegion* rgn = r_iter.value();
-
- ListIter<Ship> 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<Orbital> stars;
- List<Orbital> planets;
- List<OrbitalRegion> regions;
- List<Ship> 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 = "<div style=\"overflow-y:scroll; height:240px; padding-right:4pt; padding-left:4pt; padding-bottom:4pt; padding-top:4pt; margin:4pt;\">\n";
-
- int nchat = 0;
- NetLobbyServer* lobby = NetLobbyServer::GetInstance();
- if (lobby) {
- content += "\n<table width=\"90%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
-
- ListIter<NetChatEntry> iter = lobby->GetChat();
- while (++iter) {
- NetChatEntry* c = iter.value();
-
- content += " <tr><td nowrap width=\"130\" class=\"tiny\">";
- content += FormatTimeString(c->GetTime());
- content += "</td><td nowrap width=\"80\" class=\"tiny\">";
- content += c->GetUser();
- content += "</td><td class=\"tiny\">";
- content += c->GetMessage();
- content += "</td></tr>\n";
- }
-
- content += "</table>\n\n";
- }
-
- content += "</div>\n<div class=\"content\">\n\
-<form name=\"chatForm\" method=\"post\"action=\"/chat\">\n\
-<table border=\"0\">\n\
- <tr>\n\
- <td valign=\"middle\">&nbsp;&nbsp;<input type=\"text\" name=\"msg\" size=\"80\"></td>\n\
- <td valign=\"middle\">&nbsp;&nbsp;<input type=\"submit\" value=\"Send\"></td>\n\
- </tr>\n\
- <tr>\n\
- <td colspan=\"2\" valign=\"middle\" class=\"std\">&nbsp;&nbsp;<a href=\"/chat\">Refresh</a>\
-&nbsp;&nbsp;&#183;&nbsp;&nbsp;<a href=\"/chat?action=save\">Save</a>&nbsp;&nbsp;&#183;&nbsp;&nbsp;<a href=\"/chat?action=clear\">Clear</a></td>\n\
- </tr>\n\
-</table>\n\
-</form>\n\
-</div>\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") +
- "<body><br>You are already logged in.<br>" +
- 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") +
- "<body><br>You have successfully logged in.<br>" +
- 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 =
- " <table border=\"0\" cellspacing=\"0\" cellpadding=\"4\" align=\"left\" width =\"100%\">\n\
- <tr>\n\
- <td width=\"100\">&nbsp;&nbsp;</td>\n\
- <td valign=\"top\" align=\"left\" width=\"400\"><br><br>\n\
- <span class=\"subhead\">Welcome to the Starshatter Server!</span><br><br>\n\
- <span class=\"std\">Login to access the server <b>";
-
- NetServerConfig* config = NetServerConfig::GetInstance();
- if (config)
- content += config->Name();
- else
- content += "server";
-
- content += "</b></span><br>\n\
- <form name=\"loginForm\" method=\"get\" action=\"/login\">\n\
- <table border=\"0\" cellspacing=\"0\" cellpadding=\"4\" width=\"100\">\n\
- <tr>\n\
- <td align=\"left\" valign=\"middle\" width=\"80\"><span class=\"std\">Username:</span></td>\n\
- <td align=\"left\" valign=\"middle\"><input type=\"text\" name=\"user\" size=\"25\"></td>\n\
- </tr>\n\
- <tr>\n\
- <td align=\"left\" valign=\"middle\" width=\"80\"><span class=\"std\">Password:</span></td>\n\
- <td align=\"left\" valign=\"middle\"><input type=\"password\" name=\"pass\" size=\"25\"></td>\n\
- </tr>\n\
- <tr>\n\
- <td>&nbsp;</td>\n\
- <td align=\"right\"><input type=\"submit\" value=\"Login\"></td>\n\
- </tr>\n\
- </table>\n\
- </form>\n\
- <td>&nbsp;</td>\n\
- </tr>\n\
-</table>\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() +
- "<div class=\"content\"><b>The Starshatter Server will restart in three (3) seconds.</b><br></div>" +
- 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() +
- "<div class=\"content\"><b>The Starshatter Server will shutdown in three (3) seconds.</b><br></div>" +
- 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") +
- "<body><br>Unknown Action.<br>" +
- 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 =
- "<script LANGUAGE=\"JavaScript\">\n\
-<!--\n\
-function doConfirm() {\n\
-return confirm(\"Are you sure you want to ban this player?\");\n\
-}\n\
-// -->\n\
-</script>\n\
-<div class=\"content\">\n\
-<table border=\"0\" width=\"95%\">\n\
- <tr class=\"heading\">\n\
- <td nowrap valign=\"middle\" align=\"left\">\n\
- <span class=\"heading\">&nbsp;User List</span>\n\
- </td>\n\
- </tr>\n\
-</table>\n\n";
-
- content +=
- " <table border=\"0\" width=\"95%\" class=\"std\">\n\
- <tr>\n\
- <td nowrap width=\"1%\">&nbsp;</td>\n\
- <td nowrap width=\"20%\" valign=\"middle\" align=\"left\"><b>Name</b></td>\n\
- <td nowrap width=\"10%\" valign=\"middle\" align=\"left\"><b>Address</b></td>\n\
- <td nowrap width=\"10%\" valign=\"middle\" align=\"center\"><b>Is Host</b></td>\n\
- <td nowrap width=\"20%\" valign=\"middle\" align=\"left\"><b>Squadron</b></td>\n\
- <td nowrap width=\"20%\" valign=\"middle\" align=\"center\"><b>Stats</b></td>\n\
- <td nowrap width=\"19%\" valign=\"middle\" align=\"center\"><b>Ban</b></td>\n\
- <td></td>\n\
-</tr>\n";
-
- NetLobbyServer* lobby = NetLobbyServer::GetInstance();
-
- if (lobby) {
- ListIter<NetUser> 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 += "<tr>\n<td nowrap width=\"1%\">&nbsp;</td>\n\
- <td nowrap valign=\"middle\" align=\"left\">";
- content += u->Name();
- content += "</td><td nowrap valign=\"middle\" align=\"left\">";
- content += addr_dotted;
- content += "</td><td nowrap valign=\"middle\" align=\"center\">";
- content += u->IsHost() ? "*" : "&nbsp;";
- content += "</td><td nowrap valign=\"middle\" align=\"left\">";
- content += u->Squadron();
- content += "</td><td nowrap valign=\"middle\" align=\"center\">";
- content += user_stats;
- content += "</td><td nowrap valign=\"middle\" align=\"center\">";
- content += "<a onclick=\"return doConfirm()\" href=\"/ban?name=";
- content += HttpRequest::EncodeParam(u->Name());
- content += "&addr=";
- content += addr_hex;
- content += "\">BAN</a></td></tr>\n";
- }
- }
-
- content += " </table>\n\n";
-
- content += "</div>\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<NetUser> 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() +
- "<div class=\"content\">User Banned.<br></div>" +
- 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<NetChatEntry>
-NetAdminServer::GetChat()
-{
- NetLobbyServer* lobby = NetLobbyServer::GetInstance();
-
- if (lobby)
- return lobby->GetChat();
-
- static List<NetChatEntry> 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<NetUser>&
-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<NetUser> iter = admin_users;
- while (++iter) {
- NetUser* u = iter.value();
- if (u->GetSessionID() == id)
- return u;
- }
-
- return 0;
-}
-
-void
-NetAdminServer::DoSyncedCheck()
-{
- ListIter<NetUser> iter = admin_users;
- while (++iter) {
- NetUser* u = iter.value();
-
- bool found = false;
-
- ListIter<HttpSession> 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 = "<html>\n<head>\n<title>Starshatter Server";
-
- if (title && *title) {
- head += " - ";
- head += title;
- }
-
- head += "</title>\n<style type=\"text/css\" media=\"screen\">\n";
- head += GetCSS();
- head += "</style>\n</head>\n";
-
- return head;
-}
-
-Text
-NetAdminServlet::GetBody()
-{
- return GetTitleBar(GetStatLine()) +
- GetContent() +
- GetBodyClose();
-}
-
-Text
-NetAdminServlet::GetTitleBar(const char* statline, const char* onload)
-{
- Text bar = "<body ";
-
- if (onload && *onload)
- bar += onload;
-
- bar += " leftmargin=\"0\" topmargin=\"0\" marginwidth=\"0\" marginheight=\"0\">\n\
-<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"100%\" class=\"top-bar\">\n\
- <tr height=\"50\">\n\
- <td>&nbsp;</td>\n\
- <td valign=\"middle\" align=\"left\">\n\
- <span class=\"topbarsmall\">Administration Console</span><br>\n";
-
- if (statline) {
- bar += "<a href=\"/home\">";
- }
-
- bar += "<span class=\"topbarbig\">Starshatter Server ";
- bar += versionInfo;
- bar += "</span>";
-
- if (statline) {
- bar += "</a>";
- }
-
- bar += "\n\
- </td>\n\
- </tr>\n\
- <tr class=\"top-line\">\n\
- <td colspan=\"2\">";
-
- if (statline && *statline)
- bar += statline;
- else
- bar += "&nbsp;";
-
- bar += "</td>\n\
- </tr>\n\
-</table>\n\n";
-
- return bar;
-}
-
-Text
-NetAdminServlet::GetStatLine()
-{
- NetServerConfig* config = NetServerConfig::GetInstance();
-
- Text line =
- " <table width=\"100%\" cellspacing=\"0\" cellpadding=\"2\" border=\"0\">\n\
- <tr>\n\
- <td nowrap width=\"33%\" class=\"top-line\" align=\"left\">\n\
- <span class=\"status\">&nbsp;&nbsp;Connected to <b>";
-
- char buffer[256];
- sprintf_s(buffer, "%s:%d", config->Name().data(), config->GetAdminPort());
- line += buffer;
-
- line += "</b></span>\n\
- </td>\n\
- <td nowrap width=\"34%\" class=\"top-line\" align=\"center\">\n\
- <span class=\"status\">Server Mode: <b>";
-
- 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 += "</b></span>\n\
- </td>\n\
- <td nowrap width=\"33%\" class=\"top-line\" align=\"right\">\n\
- <span class=\"status\">";
-
- line += FormatTimeString();
-
- line += "&nbsp;&nbsp;</span>\n\
- </td>\n\
- </tr>\n\
- </table>\n";
-
- return line;
-}
-
-Text
-NetAdminServlet::GetContent()
-{
- Text content =
- "<script LANGUAGE=\"JavaScript\">\n\
-<!--\n\
-function doConfirm() {\n\
-return confirm(\"Are you sure you want to do this?\");\n\
-}\n\
-// -->\n\
-</script>\n\
-<div class=\"content\">\n\
-<table border=\"0\" width=\"95%\">\n\
- <tr class=\"heading\">\n\
- <td nowrap valign=\"middle\" align=\"left\">\n\
- <span class=\"heading\">&nbsp;Game Admin Functions</span>\n\
- </td>\n\
- </tr>\n\
-</table>\n\n\
-<table border=\"0\" width=\"95%\">\n\
- <tr>\n\
- <td nowrap width=\"1%\">&nbsp;</td>\n\
- <td nowrap width=\"33%\" valign=\"middle\" align=\"left\">\n\
- <a href=\"/chat\">Lobby Chat</a>\n\
- </td>\n\
- <td nowrap width=\"33%\" valign=\"middle\" align=\"left\">\n\
- <a href=\"/home\">Mission List</a>\n\
- </td>\n\
- <td></td>\n\
- </tr>\n\
- <tr>\n\
- <td nowrap width=\"1%\">&nbsp;</td>\n\
- <td nowrap width=\"33%\" valign=\"middle\" align=\"left\">\n\
- <a href=\"/file?name=errlog.txt\">View Error Log</a>\n\
- </td>\n\
- <td nowrap width=\"33%\" valign=\"middle\" align=\"left\">\n\
- <a href=\"/users\">Player List</a>\n\
- </td>\n\
- <td></td>\n\
- </tr>\n\
- <tr>\n\
- <td nowrap width=\"1%\">&nbsp;</td>\n\
- <td nowrap width=\"33%\" valign=\"middle\" align=\"left\">\n\
- <a href=\"/file?name=serverlog.txt\">View Server Log</a>\n\
- </td>\n\
- <td nowrap width=\"33%\" valign=\"middle\" align=\"left\">\n\
- <a href=\"/home\">Ban List</a>\n\
- </td>\n\
- <td></td>\n\
- </tr>\n\
- <tr>\n\
- <td nowrap width=\"1%\">&nbsp;</td>\n\
- <td nowrap width=\"33%\" valign=\"middle\" align=\"left\"></td>\n\
- <td nowrap width=\"33%\" valign=\"middle\" align=\"left\"></td>\n\
- <td></td>\n\
-</tr>\n\
-</table>\n\n";
-
- content +=
- " <table border=\"0\" width=\"95%\">\n\
- <tr class=\"heading\">\n\
- <td nowrap valign=\"middle\" align=\"left\">\n\
- <span class=\"heading\">&nbsp;Server Admin Functions</span>\n\
- </td>\n\
- </tr>\n\
-</table>\n\n\
-<table border=\"0\" width=\"95%\">\n\
- <tr>\n\
- <td nowrap width=\"1%\">&nbsp;</td>\n\
- <td nowrap width=\"33%\" valign=\"middle\" align=\"left\">\n\
- <a onclick=\"return doConfirm()\" href=\"/server?action=restart\">Restart Server</a>\n\
- </td>\n\
- <td nowrap width=\"33%\" valign=\"middle\" align=\"left\">\n\
- <a onclick=\"return doConfirm()\" href=\"/server?action=shutdown\">Shutdown Server</a>\n\
- </td>\n\
- <td></td>\n\
-</tr>\n\
-</table>\n\n";
-
- content += "</div>\n\n";
- content += GetCopyright();
- return content;
-}
-
-Text
-NetAdminServlet::GetBodyClose()
-{
- return "\n\n</body>\n</html>\n";
-}
-
-Text
-NetAdminServlet::GetCopyright()
-{
- return "<br><span class=\"copy\">&nbsp;&nbsp;&nbsp;&nbsp;Copyright &copy; 1997-2004 Destroyer Studios. All rights reserved.</span><br>";
-}
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<NetUser>& GetUsers();
-
- virtual NetUser* FindUserBySession(Text id);
-
- virtual void AddChat(NetUser* user, const char* msg);
- ListIter<NetChatEntry> 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<NetUser> 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<ModInfo>& mods = config->GetModInfoList();
- ListIter<ModInfo> 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<NetServerInfo>& 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<NetServerInfo>& 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<NetServerInfo> 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<NetServerInfo> 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<NetServerInfo>& 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<NetServerInfo> 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<NetServerInfo> 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<NetPlayer> 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<NetJoinAnnounce> 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<NetJoinAnnounce> 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<SimRegion> rgn_iter = sim->GetRegions();
- while (++rgn_iter) {
- SimRegion* rgn = rgn_iter.value();
-
- ListIter<Ship> 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<NetPlayer> 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<Ship> iter = ships;
- while (++iter) {
- Ship* s = iter.value();
- s->SetRespawnCount(0);
- }
-
- zombies.destroy();
- ships.clear();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-NetGameServer::ExecFrame()
-{
- NetGame::ExecFrame();
- CheckSessions();
-
- ListIter<SimRegion> rgn_iter = sim->GetRegions();
- while (++rgn_iter) {
- SimRegion* rgn = rgn_iter.value();
-
- ListIter<Ship> 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<NetPlayer> 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<NetPlayer> 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<Ship> 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<NetPlayer> 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<NetPlayer> 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<NetPlayer> 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<NetPlayer> 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<Ship> 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<NetPlayer> 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<Ship> ships;
- List<NetPlayer> 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<NetUser>&
-NetLobby::GetUsers()
-{
- return users;
-}
-
-List<ModInfo>&
-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<NetLobbyParam>& 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<NetChatEntry>&
-NetLobby::GetChat()
-{
- return chat_log;
-}
-
-void
-NetLobby::ClearChat()
-{
- chat_log.destroy();
-}
-
-// +-------------------------------------------------------------------+
-
-List<NetCampaignInfo>&
-NetLobby::GetCampaigns()
-{
- return campaigns;
-}
-
-// +-------------------------------------------------------------------+
-
-void
-NetLobby::AddUnitMap(MissionElement* elem, int index)
-{
- if (elem)
- unit_map.append(new NetUnitEntry(elem, index));
-}
-
-List<NetUnitEntry>&
-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<Campaign> 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<MissionElement> 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<NetUser>& GetUsers();
-
- virtual List<ModInfo>& 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<NetChatEntry>&
- GetChat();
- virtual void ClearChat();
- virtual void SaveChat() { }
- virtual DWORD GetStartTime() const { return start_time; }
-
- virtual List<NetCampaignInfo>&
- GetCampaigns();
-
- virtual void AddUnitMap(MissionElement* elem, int index=0);
- virtual List<NetUnitEntry>&
- 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<NetLobbyParam>& params);
-
- NetLink* link;
- NetUser* local_user;
- List<NetUser> users;
- List<NetChatEntry> chat_log;
- List<NetCampaignInfo> campaigns;
- List<NetUnitEntry> unit_map;
- Text machine_info;
- List<ModInfo> 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<MissionInfo> 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<NetChatEntry>&
-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<NetUser>&
-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<ModInfo>&
-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<NetUnitEntry>&
-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<NetCampaignInfo>&
-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<NetLobbyParam> 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<NetLobbyParam> 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<NetLobbyParam> 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<NetLobbyParam> 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<NetLobbyParam> 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<NetLobbyParam> 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<NetLobbyParam> 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<NetLobbyParam> 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<NetChatEntry>&
- GetChat();
-
- NetAddr GetServerAddr() const { return addr; }
- virtual bool IsHost() const { return host; }
- virtual bool IsClient() const { return true; }
-
- virtual List<NetUser>& GetUsers();
- virtual List<NetCampaignInfo>& GetCampaigns();
- virtual List<NetUnitEntry>& GetUnitMap();
- virtual void MapUnit(int n, const char* user, bool lock=false);
- virtual void SelectMission(DWORD id);
- virtual Mission* GetSelectedMission();
-
- virtual List<ModInfo>& 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<MissionInfo> 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<NetUser> 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<NetChatEntry> 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<NetCampaignInfo>& campaigns = net_lobby->GetCampaigns();
-
- if (campaigns.size()) {
- ListIter<NetCampaignInfo> 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<MissionInfo> 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<NetCampaignInfo>& 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<NetCampaignInfo>& 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<NetCampaignInfo>& 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<MissionInfo> iter = c->missions;
- while (++iter) {
- MissionInfo* m = iter.value();
- lst_missions->AddItem(m->name);
- }
- }
- }
- }
-}
-
-void
-NetLobbyDlg::OnMissionSelect(AWEvent* event)
-{
- if (net_lobby) {
- List<NetCampaignInfo>& 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<Campaign> c_iter = Campaign::GetAllCampaigns();
- while (++c_iter && !mission_id) {
- Campaign* campaign = c_iter.value();
-
- if (campaign->GetCampaignId() == Campaign::MULTIPLAYER_MISSIONS) {
- ListIter<MissionInfo> 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<Campaign> 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<MissionInfo> m_iter = campaign->GetMissionList();
- while (++m_iter) {
- MissionInfo* m = m_iter.value();
- c->missions.append(m);
- }
- }
- }
- }
-
- ModConfig* config = ModConfig::GetInstance();
- List<ModInfo>& mods = config->GetModInfoList();
-
- server_mods.clear();
- server_mods.append(mods);
-
- net_lobby_server = this;
-}
-
-NetLobbyServer::~NetLobbyServer()
-{
- ListIter<NetUser> 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<ModInfo>& 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<Campaign> c_iter = Campaign::GetAllCampaigns();
- while (++c_iter && !mission_id) {
- Campaign* campaign = c_iter.value();
-
- if (campaign->GetCampaignId() == Campaign::MULTIPLAYER_MISSIONS) {
- ListIter<MissionInfo> 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<NetUser> 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<NetUser> 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<NetUser> 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<NetUser> iter = users;
- while (++iter) {
- NetUser* u = iter.value();
- SendData(u, NET_LOBBY_MISSION_SELECT, buffer);
- }
-}
-
-// +-------------------------------------------------------------------+
-
-List<NetUnitEntry>&
-NetLobbyServer::GetUnitMap()
-{
- if (!mission) {
- unit_map.destroy();
- return unit_map;
- }
-
- List<NetUnitEntry> units;
- ListIter<MissionElement> 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<NetUnitEntry> map_iter = GetUnitMap();
- while (++map_iter) {
- NetUnitEntry* unit = map_iter.value();
- reply += unit->GetDescription();
- }
-
- ListIter<NetUser> 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<NetUnitEntry> map_iter = GetUnitMap();
- while (++map_iter) {
- NetUnitEntry* unit = map_iter.value();
- reply += unit->GetDescription();
- }
-
- ListIter<NetUser> u_iter = users;
- while (++u_iter) {
- NetUser* u = u_iter.value();
- SendData(u, NET_LOBBY_UNIT_LIST, reply);
- }
-}
-
-void
-NetLobbyServer::SendUnits()
-{
- Text content;
-
- ListIter<NetUnitEntry> map_iter = GetUnitMap();
- while (++map_iter) {
- NetUnitEntry* unit = map_iter.value();
- content += unit->GetDescription();
- }
-
- ListIter<NetUser> 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<NetUnitEntry> 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<ModInfo>& mods = config->GetModInfoList();
- ListIter<ModInfo> 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<NetLobbyParam> 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<NetLobbyParam> 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<NetChatEntry> 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<NetUser> 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<NetLobbyParam> 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<Campaign> 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<MissionInfo> 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<NetLobbyParam> 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<NetUnitEntry> 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<NetLobbyParam> 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<NetUnitEntry>&
- 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<Text> 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 <algorithm>
-
-#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<WeaponGroup> iter = ship->Weapons();
- while (++iter) {
- WeaponGroup* group = iter.value();
-
- ListIter<Weapon> 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<NetAddr> 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<Text> 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<NetAddr> banned_addrs;
- List<Text> 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<NetUnitEntry> iter = net_lobby->GetUnitMap();
- List<NetUnitEntry>& units = iter.container();
- List<NetUser>& 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<NetUser> available_users;
-
- NetUser* u = net_lobby->GetLocalUser();
- if (u) {
- bool assigned = false;
- ListIter<NetUnitEntry> iter = net_lobby->GetUnitMap();
- while (++iter) {
- NetUnitEntry* unit = iter.value();
- if (unit->GetUserName() == u->Name())
- assigned = true;
- }
-
- if (!assigned)
- available_users.append(u);
- }
-
- ListIter<NetUser> iter = net_lobby->GetUsers();
- while (++iter) {
- NetUser* u = iter.value();
- bool assigned = false;
- ListIter<NetUnitEntry> 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<NetUnitEntry> iter = net_lobby->GetUnitMap();
- List<NetUnitEntry>& units = iter.container();
- List<NetUser>& 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<NetChatEntry> 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-// +--------------------------------------------------------------------+
-
-#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<imagebytes; i++) {
- 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;
- }
-
- *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<imagebytes; i++) {
- if (mode == BYTEMODE) {
- abyte = *fp++;
-
- if (abyte > 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 <sstream>
-#include <string>
-
-#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<DWORD>& 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<float>& 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 <vector>
-#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<DWORD>& array, TermDef* def, const char* file);
-bool GetDefArray(std::vector<float>& 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 <stdio.h>
-#include <stdlib.h>
-
-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<AwardInfo> rank_table;
-static List<AwardInfo> 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<AwardInfo> 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<AwardInfo> 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<AwardInfo> 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<AwardInfo> iter = rank_table;
- while (++iter) {
- AwardInfo* award = iter.value();
- if (award->id == rank)
- return award->desc;
- }
-
- return "";
-}
-
-int
-Player::RankFromName(const char* name)
-{
- ListIter<AwardInfo> 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<AwardInfo> 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<AwardInfo> 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<AwardInfo> 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<AwardInfo> 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<AwardInfo> 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<AwardInfo> 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> player_roster;
-static Player* current_player = 0;
-
-List<Player>&
-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<Player> 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<Player> 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<Player>& 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<Player>& 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<Player>& 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<Player>& 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<Player>& 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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<System> 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<System>& 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<System> 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 <algorithm>
-
-#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<Ship> 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<Ship> 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<Ship> 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<MenuItem> 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<SimRegion> rgn_list;
-
- ListIter<SimRegion> 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<Contact> 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<Contact> 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<SimObject>& 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<SimObject> 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<RadioMessage> 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 <mutex>
-
-#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<MenuItem> 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<Element> 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<std::mutex> 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 <mutex>
-
-#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 <mutex>
-
-#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<RadioVox> 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<std::mutex> 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<std::mutex> 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<Sound> 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 <stdio.h>
-#include <fstream>
-#include <ctype.h>
-#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<Graphic> 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<Light> 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<Graphic> 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<Graphic>& Background() { return background; }
- List<Graphic>& Foreground() { return foreground; }
- List<Graphic>& Graphics() { return graphics; }
- List<Graphic>& Sprites() { return sprites; }
- List<Light>& 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<Graphic> background;
- List<Graphic> foreground;
- List<Graphic> graphics;
- List<Graphic> sprites;
- List<Light> 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<Window> 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<Window> 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> 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<Shot> 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> 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<Shot> threat_iter(ship->GetThreatList());
- while (++threat_iter) {
- ProcessContact(threat_iter.value(), az1, az2);
- }
-
- ListIter<Drone> drone_iter(ship->GetRegion()->Drones());
- while (++drone_iter) {
- ProcessContact(drone_iter.value(), az1, az2);
- }
-
- List<Contact>& track_list = ship->GetRegion()->TrackList(ship->GetIFF());
- ListIter<Contact> 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<Contact> iter(contacts);
- while (++iter) {
- Contact* c = iter.value();
- if (c->GetShip() == s)
- return c;
- }
-
- return 0;
-}
-
-Contact*
-Sensor::FindContact(Shot* s)
-{
- ListIter<Contact> 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> contact(ship->ContactList());
-
- List<TargetOffset> 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<TargetOffset> 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> 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> 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> 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<Contact> 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 <paulej@acm.org>
-* 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 <paulej@acm.org>
-* 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<Surface> 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<FlightDeck> 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<Bitmap>& 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<WeaponGroup> g = weapons;
- while (++g) {
- ListIter<Weapon> 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<WeaponGroup> g = weapons;
- while (++g) {
- ListIter<Weapon> 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<Contact>&
-Ship::ContactList()
-{
- if (region)
- return region->TrackList(GetIFF());
-
- static List<Contact> empty_contact_list;
- return empty_contact_list;
-}
-
-Contact*
-Ship::FindContact(SimObject* s) const
-{
- if (!s) return 0;
-
- ListIter<Contact> 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<Ship> 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<WeaponGroup> 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<Weapon> 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<Component> 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<Weapon> 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<Contact> 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<Weapon> 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<Weapon> 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<Instruction>&
-Ship::GetFlightPlan()
-{
- if (element)
- return element->GetFlightPlan();
-
- static List<Instruction> 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<WeaponGroup> 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<System> 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<Ship> 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<Contact> 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<System> 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<System> 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<System> 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<WeaponGroup> g = weapons;
- while (++g) {
- ListIter<Weapon> 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<WeaponGroup> g = weapons;
- while (++g) {
- ListIter<Weapon> 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<WeaponGroup> g = weapons;
- while (++g) {
- ListIter<Weapon> 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<WeaponGroup> g = weapons;
- while (++g) {
- ListIter<Weapon> 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<Shadow> 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<Contact> 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<System> 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<WeaponGroup> 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<System> 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<Weapon>& 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<Shot>&
-Ship::GetActiveDecoys()
-{
- return decoy_list;
-}
-
-List<Shot>&
-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<System> 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<System> 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<System> 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<System> 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<Component> 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<System> 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<System> 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<Bitmap>& 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<Shot>& GetActiveDecoys();
- virtual void AddActiveDecoy(Drone* d);
- virtual int* GetLoadout() { return loadout; }
-
- List<Shot>& 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<Contact>& 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<Instruction>& 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<System>& 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<System>& Systems() { return systems; }
- List<WeaponGroup>& Weapons() { return weapons; }
- List<Drive>& Drives() { return drives; }
- List<Computer>& Computers() { return computers; }
- List<FlightDeck>& FlightDecks() { return flight_decks; }
- List<PowerSource>& Reactors() { return reactors; }
- List<NavLight>& 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<Shot> decoy_list;
- List<Shot> threat_list;
-
- List<System> systems;
- List<PowerSource> reactors;
- List<WeaponGroup> weapons;
- List<Drive> drives;
- List<Computer> computers;
- List<FlightDeck> flight_decks;
- List<NavLight> navlights;
- List<System> 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<Ship> 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<Ship> 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> 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<Debris> 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<Asteroid> 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<ShipCatalogEntry> catalog;
-static List<ShipCatalogEntry> 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<Text> detail[4];
-static List<Point> 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<Material> 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<Text> 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<ShipLoad> 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<Text> 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<Text> list;
- DataLoader* loader = DataLoader::GetLoader();
- bool oldfs = loader->IsFileSystemEnabled();
-
- loader->UseFileSystem(true);
- loader->SetDataPath(path);
- loader->ListArchiveFiles(archive, "*.def", list);
-
- ListIter<Text> 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<ShipCatalogEntry> 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<Skin> iter = e->design->skins;
-
- while (++iter) {
- Skin* skin = iter.value();
- if (*skin->Path())
- iter.removeItem();
- }
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-int
-ShipDesign::GetDesignList(int type, List<Text>& 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<Text>& 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<Model> models[4];
- List<Point> offsets[4];
- float feature_size[4];
- List<Point> spin_rates;
-
- // player selectable skins:
- List<Skin> 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<PowerSource> reactors;
- List<Weapon> weapons;
- List<HardPoint> hard_points;
- List<Drive> drives;
- List<Computer> computers;
- List<FlightDeck> flight_decks;
- List<NavLight> 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<ShipLoad> loadouts;
- List<Bitmap> map_sprites;
- List<ShipSquadron> 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<System> 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<Model> all_models;
- //List<Bitmap> all_textures;
-
- ListIter<MissionElement> 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<Model>& models = (List<Model>&) design->models[i]; // cast-away const
-
- ListIter<Model> 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<Surface> 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<Bitmap> 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<StarSystem> iter = mission->GetSystemList();
- while (++iter) {
- StarSystem* sys = iter.value();
-
- // insert objects from star system:
- ListIter<OrbitalBody> star = sys->Bodies();
- while (++star) {
- ListIter<OrbitalBody> planet = star->Satellites();
- while (++planet) {
- ListIter<OrbitalBody> moon = planet->Satellites();
- while (++moon) {
- ListIter<OrbitalRegion> 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<OrbitalRegion> 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<OrbitalRegion> 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<SimRegion> iter = regions;
- while (++iter) {
- SimRegion* rgn = iter.value();
- OrbitalRegion* orb = rgn->GetOrbitalRegion();
-
- if (orb) {
- ListIter<Text> 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<MissionElement> 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<ShipLoad> 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<Instruction> 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<Text> instr = msn_elem->Instructions();
- while (++instr) {
- element->AddInstruction(*instr);
- }
- }
-
- ListIter<Instruction> 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<ShipLoad> 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<MissionLoad> l = msn_elem->Loadouts();
- while (++l) {
- if ((l->GetShip() == i) || (l->GetShip() < 0 && loadout == 0)) {
- if (l->GetName().length()) {
- ListIter<ShipLoad> 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<WeaponGroup> 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<MissionEvent> 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<Element> 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<Element>& 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<SimRegion> 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<SimRegion> rgn = regions;
- while (++rgn && !ship)
- ship = rgn->FindShipByObjID(objid);
-
- return ship;
-}
-
-Shot*
-Sim::FindShotByObjID(DWORD objid)
-{
- Shot* shot = 0;
-
- ListIter<SimRegion> rgn = regions;
- while (++rgn && !shot)
- shot = rgn->FindShotByObjID(objid);
-
- return shot;
-}
-
-// +--------------------------------------------------------------------+
-
-Orbital*
-Sim::FindOrbitalBody(const char* name)
-{
- Orbital* body = 0;
-
- if (mission) {
- ListIter<StarSystem> 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<SimRegion> rgn = regions;
- while (++rgn) {
- rgn->ShowGrid(show);
- }
-
- grid_shown = show?true:false;
-}
-
-bool
-Sim::GridShown() const
-{
- return grid_shown;
-}
-
-// +--------------------------------------------------------------------+
-
-List<StarSystem>&
-Sim::GetSystemList()
-{
- if (mission)
- return mission->GetSystemList();
-
- static List<StarSystem> 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<SimRegion> 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<Ship>
-Sim::GetSelection()
-{
- if (active_region)
- return active_region->GetSelection();
-
- static List<Ship> 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<SimRegion> rgn = regions;
- while (++rgn)
- if (rgn->name == name)
- return rgn.value();
-
- return 0;
-}
-
-SimRegion*
-Sim::FindRegion(OrbitalRegion* orgn)
-{
- ListIter<SimRegion> 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<SimRegion> 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<SimRegion> rgn = regions;
- while (++rgn && !result) {
- if (rgn->IsOrbital()) {
- OrbitalRegion* orgn = rgn->GetOrbitalRegion();
- if (orgn) {
- ListIter<OrbitalRegion> 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<Element> elem = elements;
- while (++elem)
- if (!elem->IsSquadron())
- elem->ExecFrame(seconds);
-
- ListIter<SimRegion> 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<Element> 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<MissionEvent> 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<SimHyper> 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<FlightDeck> 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<Ship> riders;
- ListIter<Ship> 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<SimSplash> iter = splashlist;
- while (++iter) {
- SimSplash* splash = iter.value();
-
- if (!splash->rgn)
- continue;
-
- // damage ships:
- ListIter<Ship> 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> 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<MissionEvent> 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<MissionEvent> 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<Element> 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<MissionElement>
-Sim::GetMissionElements()
-{
- mission_elements.destroy();
-
- ListIter<Element> 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<Instruction> 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<SimRegion> iter = regions;
- while (++iter && !hangar) {
- SimRegion* rgn = iter.value();
-
- ListIter<Ship> 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<Ship>
-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> ship = ships;
- while (++ship)
- ship->Activate(sim->scene);
-
- ListIter<Shot> shot = shots;
- while (++shot)
- shot->Activate(sim->scene);
-
- ListIter<Explosion> exp = explosions;
- while (++exp)
- exp->Activate(sim->scene);
-
- ListIter<Debris> deb = debris;
- while (++deb)
- deb->Activate(sim->scene);
-
- ListIter<Asteroid> 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> ship = ships;
- while (++ship)
- ship->Deactivate(sim->scene);
-
- ListIter<Shot> shot = shots;
- while (++shot)
- shot->Deactivate(sim->scene);
-
- ListIter<Explosion> exp = explosions;
- while (++exp)
- exp->Deactivate(sim->scene);
-
- ListIter<Debris> deb = debris;
- while (++deb)
- deb->Deactivate(sim->scene);
-
- ListIter<Asteroid> 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<Asteroid> 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> 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> 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<Explosion> 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> 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> 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> 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> 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> 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<Asteroid> 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<Ship> kill_list;
-
- int s_index = 0;
-
- ListIter<Ship> 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<Ship> 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> 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<Asteroid> 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<Ship> killed(kill_list);
- while (++killed) {
- Ship* kill = killed.value();
- kill->DeathSpiral();
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-SimRegion::CrashShips()
-{
- if (type != AIR_SPACE || NetGame::IsNetGameClient())
- return;
-
- ListIter<Ship> 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> 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> 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> 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> 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> shot_iter = shots;
- while (++shot_iter && !shot) {
- Shot* test = shot_iter.value();
- if (test->GetObjID() == objid)
- shot = test;
- }
-
- if (!shot) {
- ListIter<Drone> 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> 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<Contact>&
-SimRegion::TrackList(int iff)
-{
- if (iff >= 0 && iff < 5)
- return track_database[iff];
-
- static List<Contact> empty;
- return empty;
-}
-
-void
-SimRegion::UpdateTracks(double seconds)
-{
- for (int i = 0; i < 5; i++) {
- ListIter<Contact> 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> 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<FlightDeck>& 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<MissionEvent>& GetEvents() { return events; }
- List<SimRegion>& 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<StarSystem>& GetSystemList();
- Scene* GetScene() { return &scene; }
- Ship* GetPlayerShip();
- Element* GetPlayerElement();
- Orbital* FindOrbitalBody(const char* name);
-
- void SetSelection(Ship* s);
- bool IsSelected(Ship* s);
- ListIter<Ship> 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<Element>& GetElements() { return elements; }
-
- int GetAssignedElements(Element* elem, List<Element>& 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<MissionElement> 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<SimRegion> regions;
- List<SimRegion> rgn_queue;
- List<SimHyper> jumplist;
- List<SimSplash> splashlist;
- List<Element> elements;
- List<Element> finished;
- List<MissionEvent> events;
- List<MissionElement> 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<Ship>& Ships() { return ships; }
- List<Ship>& Carriers() { return carriers; }
- List<Shot>& Shots() { return shots; }
- List<Drone>& Drones() { return drones; }
- List<Debris>& Rocks() { return debris; }
- List<Asteroid>& Roids() { return asteroids; }
- List<Explosion>& Explosions() { return explosions; }
- List<SimRegion>& Links() { return links; }
- StarSystem* System() { return star_system; }
-
- Point Location() const { return location; }
-
- void SetSelection(Ship* s);
- bool IsSelected(Ship* s);
- ListIter<Ship> GetSelection();
- void ClearSelection();
- void AddSelection(Ship* s);
-
- List<Contact>& 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<Ship> ships;
- List<Ship> carriers;
- List<Ship> selection;
- List<Ship> dead_ships;
- List<Shot> shots;
- List<Drone> drones;
- List<Explosion> explosions;
- List<Debris> debris;
- List<Asteroid> asteroids;
- List<Contact> track_database[5];
- List<SimRegion> 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<ShipStats> 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<SimEvent> 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<ShipStats> 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<SimEvent>&
- 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<SimEvent> 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<SimObject> 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<SimObserver> 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<SimObserver> 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<SimObject> 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<SkinCell> 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<SkinCell> 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<Material> 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<Surface> 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<Surface> s1_iter = model->surfaces;
- while (++s1_iter && !contact) {
- Surface* s1 = s1_iter.value();
-
- ListIter<Surface> 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<Surface> 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<Surface> 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<Light>& lights)
-{
- List<Light> active_lights;
- ListIter<Light> 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<Surface> 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<Surface> iter = model->GetSurfaces();
- while (++iter) {
- Surface* s = iter.value();
-
- ListIter<Segment> 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<Bitmap>& textures)
-{
- if (model)
- model->GetAllTextures(textures);
-}
-
-void
-Model::GetAllTextures(List<Bitmap>& textures)
-{
- ListIter<Material> 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<Material> 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<Surface> 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<Bitmap> 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<Segment> 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<Material> 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<Surface> surf_iter = surfaces;
- while (++surf_iter) {
- Surface* surf = surf_iter.value();
-
- ListIter<Segment> 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<Surface> 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<Surface> 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<Poly> polys;
- SelectPolys(polys, m2);
-
- ListIter<Poly> 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<Surface> iter = surfaces;
-
- while (++iter) {
- Surface* s = iter.value();
- s->ScaleBy(factor);
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Model::Normalize()
-{
- ListIter<Surface> iter = surfaces;
-
- while (++iter) {
- Surface* s = iter.value();
- s->Normalize();
- }
-}
-
-void
-Model::SelectPolys(List<Poly>& polys, Vec3 loc)
-{
- ListIter<Surface> iter = surfaces;
-
- while (++iter) {
- Surface* s = iter.value();
- s->SelectPolys(polys, loc);
- }
-}
-
-void
-Model::SelectPolys(List<Poly>& polys, Material* m)
-{
- ListIter<Surface> iter = surfaces;
-
- while (++iter) {
- Surface* s = iter.value();
- s->SelectPolys(polys, m);
- }
-}
-
-void
-Model::ComputeTangents()
-{
- ListIter<Surface> iter = surfaces;
-
- while (++iter) {
- Surface* s = iter.value();
- s->ComputeTangents();
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Model::DeletePrivateData()
-{
- ListIter<Surface> iter = surfaces;
- while (++iter) {
- Surface* s = iter.value();
- VideoPrivateData* vpd = s->GetVideoPrivateData();
-
- if (vpd) {
- delete vpd;
- s->SetVideoPrivateData(0);
- }
-
- ListIter<Segment> 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<Segment> 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<Poly> 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<Poly>& 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<Poly>& 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<Bitmap>& 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<Light>& lights);
- List<Shadow>& 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<Shadow> 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<Surface>& GetSurfaces() { return surfaces; }
- List<Material>& GetMaterials() { return materials; }
- const Material* FindMaterial(const char* mtl_name) const;
- const Material* ReplaceMaterial(const Material* mtl);
- void GetAllTextures(List<Bitmap>& textures);
-
- Poly* AddPolys(int nsurf, int npolys, int nverts);
- void ExplodeMesh();
- void OptimizeMesh();
- void OptimizeMaterials();
- void ScaleBy(double factor);
-
- void Normalize();
- void SelectPolys(List<Poly>&, Material* mtl);
- void SelectPolys(List<Poly>&, 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<Surface> surfaces;
- List<Material> 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<Segment>& 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<Poly>&, Material* mtl);
- void SelectPolys(List<Poly>&, 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<Segment> 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 <mutex>
-
-#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<std::mutex> lock(sync);
-
- ListIter<Sound> 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<std::mutex> 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 <mutex>
-
-#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<Sound> 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 <objbase.h>
-#include <cguid.h>
-#include <mmsystem.h>
-#include <dsound.h>
-
-#include <mutex>
-
-#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<Sound> 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<std::mutex> lock(sync);
-
- ListIter<Sound> 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<std::mutex> lock(sync);
-
- ListIter<Sound> iter = sounds;
- while (++iter) {
- Sound* s = iter.value();
-
- if (s->IsReady())
- s->Play();
- }
-
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-SoundCardD3D::StopSoundEffects()
-{
- const std::lock_guard<std::mutex> lock(sync);
-
- DWORD ok_sounds = (Sound::INTERFACE | Sound::OGGVORBIS | Sound::RESOURCE);
-
- ListIter<Sound> 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<std::mutex> 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, &current_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 <mutex>
-
-//#define DIRECT_SOUND_3D
-#include "SoundCard.h"
-#include "Sound.h"
-#include "Camera.h"
-#include <stdio.h>
-#include <dsound.h>
-#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 <iostream>
-
-
-#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<Text> 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<OrbitalBody> star = bodies;
- while (++star) {
- CreateBody(*star);
-
- ListIter<OrbitalBody> planet = star->Satellites();
- while (++planet) {
- CreateBody(*planet);
-
- ListIter<OrbitalBody> 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<OrbitalBody> 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<OrbitalBody> planet = star->Satellites();
- while (++planet) {
- GRAPHIC_DESTROY(planet->rep);
-
- ListIter<OrbitalBody> 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<OrbitalBody> 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<OrbitalBody> planet = star->Satellites();
- while (++planet) {
- scene.AddGraphic(planet->rep);
-
- ListIter<OrbitalBody> 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<OrbitalBody> 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<OrbitalBody> planet = star->Satellites();
- while (++planet) {
- if (planet->rep && planet->rep->GetScene())
- planet->rep->GetScene()->DelGraphic(planet->rep);
-
- ListIter<OrbitalBody> 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<OrbitalBody> 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<OrbitalBody> 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<OrbitalBody> star = bodies;
- while (++star)
- star->Update();
-
- ListIter<OrbitalRegion> 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<OrbitalBody> 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<OrbitalBody> 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<OrbitalBody> 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<OrbitalBody> star = bodies;
- while (++star) {
- if (!_stricmp(star->Name(), name))
- return star.value();
-
- ListIter<OrbitalRegion> star_rgn = star->Regions();
- while (++star_rgn) {
- if (!_stricmp(star_rgn->Name(), name))
- return star_rgn.value();
- }
-
- ListIter<OrbitalBody> planet = star->Satellites();
- while (++planet) {
- if (!_stricmp(planet->Name(), name))
- return planet.value();
-
- ListIter<OrbitalRegion> planet_rgn = planet->Regions();
- while (++planet_rgn) {
- if (!_stricmp(planet_rgn->Name(), name))
- return planet_rgn.value();
- }
-
- ListIter<OrbitalBody> moon = planet->Satellites();
- while (++moon) {
- if (!_stricmp(moon->Name(), name))
- return moon.value();
-
- ListIter<OrbitalRegion> moon_rgn = moon->Regions();
- while (++moon_rgn) {
- if (!_stricmp(moon_rgn->Name(), name))
- return moon_rgn.value();
- }
- }
- }
- }
-
- ListIter<OrbitalRegion> 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<OrbitalRegion> region = all_regions;
- while (++region) {
- if (!_stricmp(region->Name(), name))
- return region.value();
- }
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-StarSystem::HasLinkTo(StarSystem* s) const
-{
- ListIter<OrbitalRegion> iter = ((StarSystem*) this)->all_regions;
- while (++iter) {
- OrbitalRegion* rgn = iter.value();
-
- ListIter<Text> 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<Light> 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<Light> 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<Light> 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<OrbitalBody> 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<OrbitalRegion> 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<OrbitalBody> 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<OrbitalBody>& Bodies() { return bodies; }
- List<OrbitalRegion>& Regions() { return regions; }
- List<OrbitalRegion>& 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<Light> sun_lights;
- List<Light> back_lights;
-
- Graphic* point_stars;
- Solid* poly_stars;
- Solid* nebula;
- Solid* haze;
-
- List<OrbitalBody> bodies;
- List<OrbitalRegion> regions;
- List<OrbitalRegion> 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<OrbitalRegion> 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<OrbitalRegion> 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<OrbitalBody> 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<OrbitalBody> 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<Text>& Links() { return links; }
-
-protected:
- double grid;
- double inclination;
- int asteroids;
- List<Text> links;
-};
-
-#endif // StarSystem_h
-
diff --git a/Stars45/Stars.ico b/Stars45/Stars.ico
deleted file mode 100644
index 69980ca..0000000
--- a/Stars45/Stars.ico
+++ /dev/null
Binary files 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 <winres.h>
-
-#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<Campaign>& list = Campaign::GetAllCampaigns();
- Campaign* c = 0;
- Text saved = CampaignSaveGame::GetResumeFile();
-
-
- // resume saved game?
- if (saved.length()) {
- CampaignSaveGame savegame;
- savegame.Load(saved);
- c = savegame.GetCampaign();
- }
-
- // start training campaign?
- else if (p->Trained() < 255) {
- c = list[0];
- c->Load();
- }
-
- // start new dynamic campaign sequence?
- else {
- c = list[1];
- c->Load();
- }
-
- if (c)
- Campaign::SelectCampaign(c->Name());
-
- Mouse::Show(false);
- SetGameMode(CLOD_MODE);
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-Starshatter::UseFileSystem()
-{
- return use_file_system;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::OpenTacticalReference()
-{
- if (menuscreen && game_mode == MENU_MODE) {
- menuscreen->ShowLoadDlg();
-
- LoadDlg* load_dlg = menuscreen->GetLoadDlg();
-
- if (load_dlg && load_dlg->IsShown()) {
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.tac-ref");
- load_progress = 1;
- catalog_index = 0;
- }
- else {
- menuscreen->ShowTacRefDlg();
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::SetGameMode(int m)
-{
- if (game_mode == m)
- return;
-
- const char* mode_name[] = {
- "MENU_MODE", // main menu
- "CLOD_MODE", // loading campaign
- "CMPN_MODE", // operational command for dynamic campaign
- "PREP_MODE", // loading mission info for planning
- "PLAN_MODE", // mission briefing
- "LOAD_MODE", // loading mission into simulator
- "PLAY_MODE", // active simulation
- "EXIT_MODE" // shutting down
- };
-
- if (m >= MENU_MODE && m <= EXIT_MODE)
- Print(">>> Starshatter::SetGameMode(%d) (%s)\n", m, mode_name[m]);
- else
- Print(">>> Starshatter::SetGameMode(%d) (UNKNOWN MODE)\n", m);
-
- MouseController* mouse_con = MouseController::GetInstance();
- if (mouse_con)
- mouse_con->SetActive(false);
-
- if (m == CLOD_MODE || m == PREP_MODE || m == LOAD_MODE) {
- load_step = 0;
- load_progress = 0;
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.general");
- paused = true;
- }
-
- else if (m == CMPN_MODE) {
- load_step = 0;
- load_progress = 100;
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.complete");
- paused = false;
- }
-
- else if (m == PLAY_MODE) {
- Print(" Starting Game...\n");
-
- player_ship = 0;
- load_progress = 100;
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.complete");
-
- if (!world) {
- CreateWorld();
- InstantiateMission();
- }
-
- if (gamescreen)
- gamescreen->SetFieldOfView(field_of_view);
-
- HUDView::ClearMessages();
- RadioView::ClearMessages();
-
- Clock::GetInstance()->SetTimeCompression(1.0);
- Pause(false);
-
- Print(" Stardate: %.1f\n", StarSystem::GetBaseTime());
- }
-
- else if (m == PLAN_MODE) {
- if (game_mode == PLAY_MODE) {
- Print(" Returning to Plan Mode...\n");
- if (soundcard)
- soundcard->StopSoundEffects();
-
- StopNetGame();
- Pause(true);
- Print(" Stardate: %.1f\n", StarSystem::GetBaseTime());
- }
- }
-
- else if (m == MENU_MODE) {
- Print(" Returning to Main Menu...\n");
-
- if (game_mode == PLAN_MODE || game_mode == PLAY_MODE) {
- if (soundcard)
- soundcard->StopSoundEffects();
-
- StopNetGame();
- }
-
- paused = true;
- }
-
- if (m == EXIT_MODE) {
- Print(" Shutting Down (Returning to Windows)...\n");
-
- if (game_mode == PLAN_MODE || game_mode == PLAY_MODE) {
- if (soundcard)
- soundcard->StopSoundEffects();
-
- StopNetGame();
- }
-
- Print(" Stardate: %.1f\n", StarSystem::GetBaseTime());
- Print(" Bitmap Cache Footprint: %d KB\n", Bitmap::CacheMemoryFootprint() / 1024);
-
- paused = true;
- }
-
- FlushKeys();
- game_mode = m;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-Starshatter::ChangeVideo()
-{
- bool result = false;
-
- if (menuscreen) {
- delete menuscreen;
- menuscreen = 0;
- }
-
- if (loadscreen) {
- delete loadscreen;
- loadscreen = 0;
- }
-
- if (planscreen) {
- delete planscreen;
- planscreen = 0;
- }
-
- if (gamescreen) {
- delete gamescreen;
- gamescreen = 0;
- }
-
- if (cmpnscreen) {
- delete cmpnscreen;
- cmpnscreen = 0;
- }
-
- loader->SetDataPath(0);
-
- LoadVideoConfig("video2.cfg");
-
- result = ResetVideo();
-
- InitMouse();
-
- req_change_video = false;
- video_changed = true;
-
- return result;
-}
-
-bool
-Starshatter::ResizeVideo()
-{
- if (GameWinDX9::ResizeVideo()) {
- InitMouse();
- Mouse::Show(true);
-
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::CreateWorld()
-{
- RadioTraffic::Initialize();
- RadioView::Initialize();
- RadioVox::Initialize();
- QuantumView::Initialize();
- QuitView::Initialize();
- TacticalView::Initialize();
-
- // create world
- if (!world) {
- Sim* sim = new Sim(input);
- world = sim;
- Print(" World Created.\n");
- }
-
- cam_dir = CameraDirector::GetInstance();
-}
-
-void
-Starshatter::InstantiateMission()
-{
- current_mission = 0;
-
- if (Campaign::GetCampaign()) {
- current_mission = Campaign::GetCampaign()->GetMission();
- }
-
- Sim* sim = (Sim*) world;
-
- if (sim) {
- bool dynamic = false;
- Campaign* campaign = Campaign::GetCampaign();
-
- if (campaign && campaign->IsDynamic())
- dynamic = true;
-
- sim->UnloadMission();
- sim->LoadMission(current_mission);
- sim->ExecMission();
- sim->SetTestMode(test_mode && !dynamic ? true : false);
-
- Print(" Mission Instantiated.\n");
- }
-}
-
-// +--------------------------------------------------------------------+
-
-int
-Starshatter::KeyDown(int action) const
-{
- int k = Joystick::KeyDownMap(action) ||
- Keyboard::KeyDownMap(action);
-
- return k;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-Starshatter::GameLoop()
-{
- cam_dir = CameraDirector::GetInstance();
-
- if (active && paused) {
- // Route Events to EventTargets
- EventDispatch* ed = EventDispatch::GetInstance();
- if (ed)
- ed->Dispatch();
-
- UpdateWorld();
- GameState();
- UpdateScreen();
- CollectStats();
-
- /***
- static DWORD vmf_time = 0;
-
- if (real_time() - vmf_time > 5000) {
- vmf_time = real_time();
- DWORD vmf = video->VidMemFree() / (1024 * 1024);
- ::Print("\n###### %02d:%02d - Video Memory Free: %d MB\n\n",
- vmf_time / 60000,
- vmf_time / 1000,
- vmf);
- }
- ***/
- }
-
- Game::GameLoop();
- return false; // must return false to keep processing
- // true tells the outer loop to sleep until a
- // windows event is available
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::UpdateWorld()
-{
- Galaxy* galaxy = Galaxy::GetInstance();
- if (galaxy) galaxy->ExecFrame();
-
- // Cutscene missions have a tendency to mess with the stardate
- // to manage time-of-day and camera effects. It's a bad idea to
- // evaluate campaign actions and events while the cutscene is
- // changing the time base.
- if (!cutscene_mission) {
- Campaign* campaign = Campaign::GetCampaign();
- if (campaign) campaign->ExecFrame();
- }
-
- if (paused) {
- if (world)
- world->ExecFrame(0);
- }
-
- else {
- Drive::StartFrame();
-
- if (world)
- world->ExecFrame(Clock::GetInstance()->Delta());
- }
-
- if (game_mode == PLAY_MODE || InCutscene()) {
- if (cam_dir) {
- if (head_tracker && head_tracker->IsRunning() && !InCutscene()) {
- head_tracker->ExecFrame();
- cam_dir->VirtualHead(head_tracker->GetAzimuth(), head_tracker->GetElevation());
- cam_dir->VirtualHeadOffset(head_tracker->GetX(), head_tracker->GetY(), head_tracker->GetZ());
- }
-
- cam_dir->ExecFrame(Clock::GetInstance()->GuiDelta());
- }
-
- Sim* sim = Sim::GetSim();
- SimRegion* rgn = sim ? sim->GetActiveRegion() : 0;
-
- if (rgn) {
- ListIter<Ship> iter = rgn->Ships();
- while (++iter) {
- Ship* s = iter.value();
- s->SelectDetail(Clock::GetInstance()->Delta());
- }
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::GameState()
-{
- if (splash) {
- static bool quick_splash = false;
-
- if (GetKey() != 0)
- quick_splash = true;
-
- if (quick_splash) {
- splash->FadeIn(0);
- splash->StopHold();
- splash->FadeOut(0);
- }
-
- if (splash->Done()) {
- splash = 0; // this will get deleted along with gamewin
- splash_index++;
-
- if (gamewin) {
- screen->DelWindow(gamewin);
- delete gamewin;
- gamewin = 0;
- }
-
- if (splash_index < 2) {
- Ship::Initialize();
- Galaxy::Initialize();
- SetupSplash();
- }
- else {
- CombatRoster::Initialize();
- Campaign::Initialize();
- SetupMenuScreen();
- }
-
- FlushKeys();
- }
- }
-
- else if (game_mode == MENU_MODE) {
- bool campaign_select = false;
-
- if (cmpnscreen) {
- campaign_select = cmpnscreen->IsShown();
- cmpnscreen->Hide();
- }
-
- if (gamescreen)
- gamescreen->Hide();
-
- if (planscreen)
- planscreen->Hide();
-
- if (loadscreen)
- loadscreen->Hide();
-
- if (!menuscreen) {
- SetupMenuScreen();
- }
- else {
- menuscreen->Show();
-
- if (campaign_select)
- menuscreen->ShowCmpSelectDlg();
- }
-
- if (MusicDirector::GetInstance() &&
- MusicDirector::GetInstance()->GetMode() != MusicDirector::CREDITS)
- MusicDirector::SetMode(MusicDirector::MENU);
-
- DoMenuScreenFrame();
- }
-
- else if (game_mode == CLOD_MODE ||
- game_mode == PREP_MODE ||
- game_mode == LOAD_MODE) {
- if (menuscreen)
- menuscreen->Hide();
-
- if (planscreen)
- planscreen->Hide();
-
- if (cmpnscreen)
- cmpnscreen->Hide();
-
- if (!loadscreen)
- SetupLoadScreen();
- else
- loadscreen->Show();
-
- if (game_mode == CLOD_MODE)
- MusicDirector::SetMode(MusicDirector::MENU);
- else
- MusicDirector::SetMode(MusicDirector::BRIEFING);
-
- DoLoadScreenFrame();
- }
-
- else if (game_mode == PLAN_MODE) {
- if (menuscreen)
- menuscreen->Hide();
-
- if (cmpnscreen)
- menuscreen->Hide();
-
- if (loadscreen)
- loadscreen->Hide();
-
- if (gamescreen)
- gamescreen->Hide();
-
- if (!planscreen)
- SetupPlanScreen();
- else
- planscreen->Show();
-
- Player* p = Player::GetCurrentPlayer();
- if (p && p->ShowAward()) {
- if (!planscreen->IsAwardShown())
- planscreen->ShowAwardDlg();
- }
-
- else if (ShipStats::NumStats()) {
- if (!planscreen->IsDebriefShown()) {
- planscreen->ShowDebriefDlg();
- show_missions = true;
- }
- }
-
- else {
- if (!planscreen->IsMsnShown() && !planscreen->IsNavShown())
- planscreen->ShowMsnDlg();
- }
-
- MusicDirector::SetMode(MusicDirector::BRIEFING);
-
- DoPlanScreenFrame();
- }
-
-
- else if (game_mode == CMPN_MODE) {
- if (menuscreen)
- menuscreen->Hide();
-
- if (planscreen)
- planscreen->Hide();
-
- if (loadscreen)
- loadscreen->Hide();
-
- if (gamescreen)
- gamescreen->Hide();
-
- if (!cmpnscreen)
- SetupCmpnScreen();
- else
- cmpnscreen->Show();
-
- DoCmpnScreenFrame();
- }
-
- else if (game_mode == PLAY_MODE) {
- if (menuscreen)
- menuscreen->Hide();
-
- if (cmpnscreen)
- cmpnscreen->Hide();
-
- if (planscreen)
- planscreen->Hide();
-
- if (loadscreen)
- loadscreen->Hide();
-
- if (!gamescreen)
- SetupGameScreen();
- else
- gamescreen->Show();
-
- DoGameScreenFrame();
- }
-
- if (game_mode == EXIT_MODE) {
- exit_time -= Clock::GetInstance()->GuiDelta();
-
- if (exit_time <= 0)
- Game::Exit();
- }
-
- if (net_lobby)
- net_lobby->ExecFrame();
-
- if (music_dir)
- music_dir->ExecFrame();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::DoMenuScreenFrame()
-{
- if (!Mouse::RButton()) {
- Mouse::SetCursor(Mouse::ARROW);
- Mouse::Show(true);
- }
-
- if (time_til_change > 0)
- time_til_change -= Clock::GetInstance()->GuiDelta();
-
- if (!menuscreen)
- return;
-
- if (KeyDown(KEY_EXIT)) {
- if (time_til_change <= 0) {
- time_til_change = 0.5;
-
- if (!exit_latch && !menuscreen->CloseTopmost()) {
- menuscreen->ShowExitDlg();
- }
- }
-
- exit_latch = true;
- }
- else {
- exit_latch = false;
- }
-
- LoadDlg* load_dlg = menuscreen->GetLoadDlg();
-
- if (load_dlg && load_dlg->IsShown()) {
- // load all ship designs in the standard catalog
- if (catalog_index < ShipDesign::StandardCatalogSize()) {
- ShipDesign::PreloadCatalog(catalog_index++);
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.tac-ref");
-
- if (load_progress < 95)
- load_progress++;
- }
-
- else {
- menuscreen->ShowTacRefDlg();
- }
- }
-
- if (show_missions) {
- if (net_lobby)
- menuscreen->ShowNetLobbyDlg();
- else
- menuscreen->ShowMsnSelectDlg();
-
- show_missions = false;
- }
-
- menuscreen->ExecFrame();
-
- if (req_change_video) {
- ChangeVideo();
- SetupMenuScreen();
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::DoPlanScreenFrame()
-{
- Mouse::SetCursor(Mouse::ARROW);
-
- if (time_til_change > 0)
- time_til_change -= Clock::GetInstance()->GuiDelta();
-
- if (KeyDown(KEY_EXIT)) {
- if (time_til_change <= 0) {
- time_til_change = 1;
-
- if (!exit_latch && !planscreen->CloseTopmost()) {
- Campaign* campaign = Campaign::GetCampaign();
- if (campaign && (campaign->IsDynamic() || campaign->IsTraining()))
- SetGameMode(CMPN_MODE);
- else
- SetGameMode(MENU_MODE);
- }
- }
-
- exit_latch = true;
- }
- else {
- exit_latch = false;
- }
-
- planscreen->ExecFrame();
- show_missions = true;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::DoCmpnScreenFrame()
-{
- Mouse::SetCursor(Mouse::ARROW);
-
- if (time_til_change > 0)
- time_til_change -= Clock::GetInstance()->GuiDelta();
-
- exit_latch = KeyDown(KEY_EXIT) ? true : false;
-
- if (InCutscene() && player_ship) {
- // warp effect:
- if (player_ship->WarpFactor() > 1) {
- if (player_ship->WarpFactor() > field_of_view)
- cmpnscreen->SetFieldOfView(player_ship->WarpFactor());
- else
- cmpnscreen->SetFieldOfView(field_of_view);
- }
-
- else {
- if (cmpnscreen->GetFieldOfView() != field_of_view)
- cmpnscreen->SetFieldOfView(field_of_view);
- }
- }
-
- if (InCutscene() && exit_latch) {
- time_til_change = 1;
- EndCutscene();
- EndMission();
- cmpnscreen->SetFieldOfView(field_of_view);
- }
-
- else if (time_til_change <= 0 && exit_latch) {
- time_til_change = 1;
-
- if (!cmpnscreen || !cmpnscreen->CloseTopmost()) {
- SetGameMode(MENU_MODE);
- }
- }
-
- // time control for campaign mode:
- else if (game_mode == CMPN_MODE) {
- if (time_til_change <= 0) {
- if (KeyDown(KEY_PAUSE)) {
- time_til_change = 1;
- Pause(!paused);
- }
-
- else if (KeyDown(KEY_TIME_COMPRESS)) {
- time_til_change = 1;
- double compression = Clock::GetInstance()->TimeCompression() * 2;
- if (compression > 8.0)
- compression = 8.0;
- Clock::GetInstance()->SetTimeCompression(compression);
- }
-
- else if (KeyDown(KEY_TIME_EXPAND)) {
- time_til_change = 1;
- double compression = Clock::GetInstance()->TimeCompression() / 2;
- if (compression < 0.5)
- compression = 0.5;
- Clock::GetInstance()->SetTimeCompression(compression);
- }
- }
- }
-
- if (show_missions && !InCutscene()) {
- cmpnscreen->ShowCmdMissionsDlg();
- show_missions = false;
- }
-
- cmpnscreen->ExecFrame();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::DoLoadScreenFrame()
-{
- Mouse::Show(false);
- Mouse::SetCursor(Mouse::ARROW);
-
- if (game_mode == CLOD_MODE) {
- CmpLoadDlg* dlg = loadscreen->GetCmpLoadDlg();
-
- switch (load_step) {
- case 0:
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.campaign");
- load_progress = 1;
- catalog_index = 0;
- break;
-
- case 1:
- // load all ship designs in the standard catalog
- if (catalog_index < ShipDesign::StandardCatalogSize()) {
- ShipDesign::PreloadCatalog(catalog_index++);
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.campaign");
-
- if (load_progress < 80)
- load_progress++;
-
- load_step = 0; // force return to current step on next frame
- }
- else {
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.start");
- load_progress = 80;
- }
- break;
-
- case 2:
- if (Campaign::GetCampaign())
- Campaign::GetCampaign()->Start();
- break;
-
- default:
- if (dlg && load_progress < 100) {
- load_progress++;
- }
- else {
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.ready");
- load_progress = 100;
- SetGameMode(CMPN_MODE);
- }
- break;
- }
- }
- else {
- switch (load_step) {
- case 0:
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.drives");
- load_progress = 0;
- break;
-
- case 1:
- Drive::Initialize();
- LandingGear::Initialize();
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.explosions");
- load_progress = 5;
- break;
-
- case 2:
- Explosion::Initialize();
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.systems");
- load_progress = 10;
- break;
-
- case 3:
- FlightDeck::Initialize();
- NavLight::Initialize();
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.ships");
- load_progress = 15;
- break;
-
- case 4:
- Ship::Initialize();
- Shot::Initialize();
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.hud");
- load_progress = 20;
- break;
-
- case 5:
- MFD::Initialize();
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.menus");
- load_progress = 25;
- break;
-
- case 6:
- RadioTraffic::Initialize();
- RadioView::Initialize();
- TacticalView::Initialize();
-
- if (!gamescreen && game_mode != PREP_MODE)
- SetupGameScreen();
-
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.mission");
- load_progress = 65;
- break;
-
- case 7:
- if (game_mode == PREP_MODE) {
- if (Campaign::GetCampaign())
- Campaign::GetCampaign()->GetMission();
- SetGameMode(PLAN_MODE);
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.loaded");
- load_progress = 100;
- Button::PlaySound(4);
- }
- else {
- CreateWorld();
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.simulation");
- load_progress = 75;
- }
- break;
-
- case 8:
- InstantiateMission();
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.viewscreen");
- load_progress = 90;
- break;
-
- default:
- SetGameMode(PLAY_MODE);
- load_activity = ContentBundle::GetInstance()->GetText("Starshatter.load.ready");
- load_progress = 100;
- break;
- }
- }
-
- load_step++;
- loadscreen->ExecFrame();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::PlayerCam(int mode)
-{
- if (player_ship && !player_ship->InTransition() && player_ship->GetFlightPhase() >= Ship::LOCKED) {
- gamescreen->CloseTopmost();
- if (mode == CameraDirector::MODE_DROP) {
- player_ship->DropCam(15, 0);
- cam_dir->SetShip(player_ship);
- cam_dir->SetMode(CameraDirector::MODE_DROP, 0);
- }
-
- else {
- cam_dir->SetMode(mode);
-
- if (mode == CameraDirector::MODE_ORBIT) {
- MouseController* mouse_con = MouseController::GetInstance();
- if (mouse_con)
- mouse_con->SetActive(false);
- }
- }
- }
-}
-
-void
-Starshatter::ViewSelection()
-{
- Sim* sim = (Sim*) world;
- List<Ship>& seln = sim->GetSelection().container();
-
- if (cam_dir) {
- if (seln.isEmpty())
- cam_dir->SetViewObject(player_ship);
-
- else if (seln.size() == 1)
- cam_dir->SetViewObject(seln[0]);
-
- else
- cam_dir->SetViewObjectGroup(seln);
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::DoGameScreenFrame()
-{
- Sim* sim = (Sim*) world;
-
- if (!gamescreen || !sim)
- return;
-
- if (InCutscene()) {
- if (player_ship) {
- // warp effect:
- if (player_ship->WarpFactor() > 1) {
- if (player_ship->WarpFactor() > field_of_view)
- gamescreen->SetFieldOfView(player_ship->WarpFactor());
- else
- gamescreen->SetFieldOfView(field_of_view);
- }
-
- else {
- if (gamescreen->GetFieldOfView() != field_of_view)
- gamescreen->SetFieldOfView(field_of_view);
- }
- }
-
- gamescreen->FrameRate(Clock::GetInstance()->Rate());
- gamescreen->ExecFrame();
-
- if (KeyDown(KEY_EXIT)) {
- gamescreen->SetFieldOfView(field_of_view);
- exit_latch = true;
- time_til_change = 1;
-
- sim->SkipCutscene();
- }
-
- return;
- }
-
- if (time_til_change > 0)
- time_til_change -= Clock::GetInstance()->GuiDelta();
-
- if (exit_latch && !KeyDown(KEY_EXIT))
- exit_latch = false;
-
- DoMouseFrame();
-
- HUDView* hud_view = HUDView::GetInstance();
-
- // changing to a new ship?
- if (player_ship != sim->GetPlayerShip()) {
- gamescreen->HideNavDlg();
- gamescreen->HideFltDlg();
- gamescreen->HideEngDlg();
-
- Ship* new_player = sim->GetPlayerShip();
-
- if (new_player) {
- if (new_player->IsDropship() && Ship::GetFlightModel() < 2 && Ship::GetControlModel() < 1)
- input->SwapYawRoll(true);
- else
- input->SwapYawRoll(false);
-
- if (hud_view) {
- hud_view->SetHUDMode(HUDView::HUD_MODE_TAC);
- hud_view->HideHUDWarn();
- }
- }
- }
-
- player_ship = sim->GetPlayerShip();
-
- if (player_ship) {
- // warp effect:
- if (player_ship->WarpFactor() > 1) {
- if (player_ship->WarpFactor() > field_of_view)
- gamescreen->SetFieldOfView(player_ship->WarpFactor());
- else
- gamescreen->SetFieldOfView(field_of_view);
- }
-
- else {
- if (gamescreen->GetFieldOfView() != field_of_view)
- gamescreen->SetFieldOfView(field_of_view);
- }
-
- gamescreen->ShowExternal();
-
- if (CameraDirector::GetCameraMode() >= CameraDirector::MODE_ORBIT && !player_ship->InTransition())
- tactical = true;
- else
- tactical = false;
-
- if (player_ship->InTransition())
- gamescreen->CloseTopmost();
- }
-
- if (chat_mode) {
- DoChatMode();
- }
-
- else {
- DoGameKeys();
- }
-
- gamescreen->FrameRate(Clock::GetInstance()->Rate());
- gamescreen->ExecFrame();
-
- if (Clock::GetInstance()->GameTime() - time_mark > 60000) {
- time_mark = Clock::GetInstance()->GameTime();
- minutes++;
- if (minutes > 60)
- Print(" TIME %2d:%02d:00\n", minutes/60, minutes%60);
- else
- Print(" TIME %2d:00\n", minutes);
- }
-}
-
-void
-Starshatter::DoGameKeys()
-{
- Sim* sim = (Sim*) world;
- HUDView* hud_view = HUDView::GetInstance();
-
- if (time_til_change <= 0) {
- if (KeyDown(KEY_CAM_BRIDGE)) {
- PlayerCam(CameraDirector::MODE_COCKPIT);
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_CAM_VIRT)) {
- PlayerCam(CameraDirector::MODE_VIRTUAL);
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_CAM_CHASE)) {
- PlayerCam(CameraDirector::MODE_CHASE);
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_CAM_DROP)) {
- PlayerCam(CameraDirector::MODE_DROP);
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_CAM_EXTERN)) {
- PlayerCam(CameraDirector::MODE_ORBIT);
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_TARGET_PADLOCK)) {
- PlayerCam(CameraDirector::MODE_TARGET);
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_SWAP_ROLL_YAW)) {
- input->SwapYawRoll(!input->GetSwapYawRoll());
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_ZOOM_WIDE)) {
- time_til_change = 0.5;
- if (gamescreen->GetFieldOfView() <= 2)
- field_of_view = 3; // wide
- else
- field_of_view = 2; // normal
-
- // don't mess with fov during warp:
- if (player_ship && player_ship->WarpFactor() <= 1)
- gamescreen->SetFieldOfView(field_of_view);
- }
-
- else if (!exit_latch && KeyDown(KEY_EXIT)) {
- exit_latch = true;
- time_til_change = 0.5;
-
- if (!gamescreen->CloseTopmost()) {
- QuitView* quit = QuitView::GetInstance();
- if (quit)
- quit->ShowMenu();
- else
- SetGameMode(Starshatter::PLAN_MODE);
- }
- }
-
- else if (KeyDown(KEY_PAUSE)) {
- Pause(!paused);
- time_til_change = 0.5;
- }
-
-
- else if (KeyDown(KEY_TIME_COMPRESS)) {
- time_til_change = 0.5;
- if (NetGame::IsNetGame())
- Clock::GetInstance()->SetTimeCompression(1.0);
- else {
- double compression = Clock::GetInstance()->TimeCompression() * 2;
- if (compression > 4.0)
- compression = 4.0;
- Clock::GetInstance()->SetTimeCompression(compression);
- }
- }
-
- else if (KeyDown(KEY_TIME_EXPAND)) {
- time_til_change = 0.5;
-
- if (NetGame::IsNetGame())
- Clock::GetInstance()->SetTimeCompression(1.0);
- else {
- double compression = Clock::GetInstance()->TimeCompression() / 2;
- if (compression < 0.5)
- compression = 0.5;
- Clock::GetInstance()->SetTimeCompression(compression);
- }
- }
-
- else if (KeyDown(KEY_TIME_SKIP)) {
- time_til_change = 0.5;
-
- if (player_ship && !NetGame::IsNetGame()) {
- player_ship->TimeSkip();
- }
- }
-
- else if (KeyDown(KEY_COMMAND_MODE)) {
- if (player_ship) {
- time_til_change = 0.5;
- player_ship->CommandMode();
- }
- }
-
- /*** For Debug Convenience Only: ***/
- else if (KeyDown(KEY_INC_STARDATE)) {
- StarSystem::SetBaseTime(StarSystem::GetBaseTime() + 600, true);
- }
-
- else if (KeyDown(KEY_DEC_STARDATE)) {
- StarSystem::SetBaseTime(StarSystem::GetBaseTime() - 600, true);
- }
- /***/
- }
-
- if (gamescreen && time_til_change <= 0) {
- if (KeyDown(KEY_MFD1)) {
- gamescreen->CycleMFDMode(0);
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_MFD2)) {
- gamescreen->CycleMFDMode(1);
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_MFD3)) {
- gamescreen->CycleMFDMode(2);
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_MFD4)) {
- gamescreen->CycleMFDMode(3);
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_RADIO_MENU)) {
- RadioView* radio_view = RadioView::GetInstance();
- if (radio_view) {
- if (radio_view->IsMenuShown())
- radio_view->CloseMenu();
- else
- radio_view->ShowMenu();
- }
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_QUANTUM_MENU)) {
- QuantumView* quantum_view = QuantumView::GetInstance();
- if (quantum_view) {
- if (quantum_view->IsMenuShown())
- quantum_view->CloseMenu();
- else
- quantum_view->ShowMenu();
- }
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_CAM_VIEW_SELECTION)) {
- time_til_change = 0.5;
- ViewSelection();
- }
-
- else if (KeyDown(KEY_HUD_MODE)) {
- time_til_change = 0.5;
- if (hud_view)
- hud_view->CycleHUDMode();
- }
-
- else if (KeyDown(KEY_HUD_COLOR)) {
- time_til_change = 0.5;
- if (hud_view)
- hud_view->CycleHUDColor();
- }
-
- else if (KeyDown(KEY_HUD_WARN)) {
- time_til_change = 0.5;
- if (hud_view)
- hud_view->CycleHUDWarn();
- }
-
- else if (KeyDown(KEY_HUD_INST)) {
- time_til_change = 0.5;
- if (hud_view)
- hud_view->CycleHUDInst();
- }
-
- else if (KeyDown(KEY_SELF_DESTRUCT)) {
- time_til_change = 0.5;
-
- if (player_ship && !player_ship->InTransition()) {
- double damage = player_ship->Design()->scuttle;
-
- if (NetGame::IsNetGameClient()) {
- NetUtil::SendSelfDestruct(player_ship, damage);
- }
- else {
- Point scuttle_loc = player_ship->Location() + RandomDirection() * player_ship->Radius();
- player_ship->InflictDamage(damage, 0, 1, scuttle_loc);
- }
-
- if (player_ship->Integrity() < 1) {
- ::Print(" %s 0-0-0-Destruct-0\n\n", player_ship->Name());
-
- ShipStats* s = ShipStats::Find(player_ship->Name());
- if (s)
- s->AddEvent(SimEvent::DESTROYED, player_ship->Name());
-
- player_ship->DeathSpiral();
- }
- }
- }
- }
-
- if (gamescreen && player_ship && time_til_change <= 0 && !::GetAsyncKeyState(VK_SHIFT) && !::GetAsyncKeyState(VK_MENU)) {
- if (KeyDown(KEY_NAV_DLG)) {
- gamescreen->ShowNavDlg();
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_WEP_DLG)) {
- if (player_ship && player_ship->Design()->wep_screen)
- gamescreen->ShowWeaponsOverlay();
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_FLT_DLG)) {
- if (player_ship && player_ship->NumFlightDecks() > 0)
- gamescreen->ShowFltDlg();
- time_til_change = 0.5;
- }
-
- else if (KeyDown(KEY_ENG_DLG)) {
- if (player_ship && player_ship->Design()->repair_screen)
- gamescreen->ShowEngDlg();
- time_til_change = 0.5;
- }
- }
-
- if (cam_dir) {
- double spin = (PI/2) * Clock::GetInstance()->Delta(); // Game::GetInstance()->GetClock()->GuiDelta();
-
- if (KeyDown(KEY_CAM_EXT_PLUS_AZ))
- cam_dir->ExternalAzimuth(spin);
-
- else if (KeyDown(KEY_CAM_EXT_MINUS_AZ))
- cam_dir->ExternalAzimuth(-spin);
-
- if (KeyDown(KEY_CAM_EXT_PLUS_EL))
- cam_dir->ExternalElevation(spin);
-
- else if (KeyDown(KEY_CAM_EXT_MINUS_EL))
- cam_dir->ExternalElevation(-spin);
-
- if (KeyDown(KEY_CAM_VIRT_PLUS_AZ))
- cam_dir->VirtualAzimuth(-spin);
-
- else if (KeyDown(KEY_CAM_VIRT_MINUS_AZ))
- cam_dir->VirtualAzimuth(spin);
-
- if (KeyDown(KEY_CAM_VIRT_PLUS_EL))
- cam_dir->VirtualElevation(spin);
-
- else if (KeyDown(KEY_CAM_VIRT_MINUS_EL))
- cam_dir->VirtualElevation(-spin);
-
- if (KeyDown(KEY_CAM_EXT_PLUS_RANGE)){
- if (!gamescreen->IsNavShown()) {
- cam_dir->ExternalRange((float) (1 + 1.5 * Clock::GetInstance()->Delta())); // 1.1f);
- }
- }
-
- else if (KeyDown(KEY_CAM_EXT_MINUS_RANGE)) {
- if (!gamescreen->IsNavShown()) {
- cam_dir->ExternalRange((float) (1 - 1.5 * Clock::GetInstance()->Delta())); // 0.9f);
- }
- }
-
- if (tactical && !gamescreen->IsFormShown()) {
- if (Mouse::Wheel()) {
- int w = Mouse::Wheel();
-
- if (w < 0) {
- while (w < 0) {
- cam_dir->ExternalRange(1.25f);
- w += 120;
- }
- }
- else {
- while (w > 0) {
- cam_dir->ExternalRange(0.75f);
- w -= 120;
- }
- }
- }
-
- else if (Mouse::LButton() && Mouse::RButton()) {
- if (mouse_dy < 0)
- cam_dir->ExternalRange(0.85f);
- else if (mouse_dy > 0)
- cam_dir->ExternalRange(1.15f);
- }
-
- else if (Mouse::MButton() && time_til_change <= 0) {
- time_til_change = 0.5;
- ViewSelection();
- }
-
- else {
- if (mouse_dx || mouse_dy) {
- if (CameraDirector::GetCameraMode() == CameraDirector::MODE_VIRTUAL) {
- cam_dir->VirtualAzimuth( mouse_dx * 0.2 * DEGREES);
- cam_dir->VirtualElevation(mouse_dy * 0.2 * DEGREES);
- }
- else {
- cam_dir->ExternalAzimuth( mouse_dx * 0.2 * DEGREES);
- cam_dir->ExternalElevation(mouse_dy * 0.2 * DEGREES);
- }
- }
- }
- }
- }
-
- // radio message hot keys:
- static bool comm_key = false;
-
- if (KeyDown(KEY_COMM_ATTACK_TGT)) {
- if (!comm_key)
- RadioTraffic::SendQuickMessage(player_ship, RadioMessage::ATTACK);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_COMM_ESCORT_TGT)) {
- if (!comm_key)
- RadioTraffic::SendQuickMessage(player_ship, RadioMessage::ESCORT);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_COMM_WEP_FREE)) {
- if (!comm_key)
- RadioTraffic::SendQuickMessage(player_ship, RadioMessage::WEP_FREE);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_COMM_WEP_HOLD)) {
- if (!comm_key)
- RadioTraffic::SendQuickMessage(player_ship, RadioMessage::FORM_UP);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_COMM_COVER_ME)) {
- if (!comm_key)
- RadioTraffic::SendQuickMessage(player_ship, RadioMessage::COVER_ME);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_COMM_SKIP_NAV)) {
- if (!comm_key)
- RadioTraffic::SendQuickMessage(player_ship, RadioMessage::SKIP_NAVPOINT);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_COMM_RETURN_TO_BASE)) {
- if (!comm_key)
- RadioTraffic::SendQuickMessage(player_ship, RadioMessage::RTB);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_COMM_CALL_INBOUND)) {
- if (!comm_key)
- RadioTraffic::SendQuickMessage(player_ship, RadioMessage::CALL_INBOUND);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_COMM_REQUEST_PICTURE)) {
- if (!comm_key)
- RadioTraffic::SendQuickMessage(player_ship, RadioMessage::REQUEST_PICTURE);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_COMM_REQUEST_SUPPORT)) {
- if (!comm_key)
- RadioTraffic::SendQuickMessage(player_ship, RadioMessage::REQUEST_SUPPORT);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_CHAT_BROADCAST)) {
- if (!comm_key)
- SetChatMode(CHAT_BROADCAST);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_CHAT_TEAM)) {
- if (!comm_key)
- SetChatMode(CHAT_TEAM);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_CHAT_WING)) {
- if (!comm_key)
- SetChatMode(CHAT_WING);
- comm_key = true;
- }
-
- else if (KeyDown(KEY_CHAT_UNIT) && sim->GetSelection().container().size()) {
- if (!comm_key)
- SetChatMode(CHAT_UNIT);
- comm_key = true;
- }
-
- else {
- comm_key = false;
- }
-}
-
-void
-Starshatter::DoChatMode()
-{
- Player* p = Player::GetCurrentPlayer();
- bool send_chat = false;
- Text name = "Player";
-
- if (player_ship)
- name = player_ship->Name();
-
- if (p)
- name = p->Name();
-
- if (chat_text.length()) {
- if (chat_text[0] >= '0' && chat_text[0] <= '9') {
- if (p) {
- chat_text = p->ChatMacro(chat_text[0] - '0');
- send_chat = true;
- }
- }
- }
-
- if (KeyDown(KEY_EXIT)) {
- SetChatMode(0);
- time_til_change = 0.5;
- }
-
- else if (send_chat || Keyboard::KeyDown(VK_RETURN)) {
- switch (chat_mode) {
- default:
- case CHAT_BROADCAST:
- {
- NetUtil::SendChat(0, name, chat_text);
- }
- break;
-
- case CHAT_TEAM:
- if (player_ship) {
- NetUtil::SendChat(player_ship->GetIFF()+1, name, chat_text);
- }
- break;
-
- case CHAT_WING:
- if (player_ship) {
- Element* elem = player_ship->GetElement();
- if (elem) {
- for (int i = 1; i <= elem->NumShips(); i++) {
- Ship* s = elem->GetShip(i);
- if (s && s != player_ship)
- NetUtil::SendChat(s->GetObjID(), name, chat_text);
- }
- }
- }
- break;
-
- case CHAT_UNIT:
- {
- Sim* sim = Sim::GetSim();
- ListIter<Ship> seln = sim->GetSelection();
-
- while (++seln) {
- Ship* s = seln.value();
- if (s != player_ship)
- NetUtil::SendChat(s->GetObjID(), name, chat_text);
- }
- }
- break;
- }
-
- HUDView::Message("%s> %s", name.data(), chat_text.data());
-
- SetChatMode(0);
- time_til_change = 0.5;
- }
-
- else {
- int key = 0;
- int shift = 0;
-
- while (GetKeyPlus(key, shift)) {
- if (key >= 'A' && key <= 'Z') {
- if (shift & 1)
- chat_text += (char) key;
- else
- chat_text += (char) tolower(key);
- }
- else {
- switch (key) {
- case VK_BACK:
- chat_text = chat_text.substring(0, chat_text.length()-1);
- break;
-
- case VK_SPACE: chat_text += ' '; break;
- case '0': if (shift & 1) chat_text += ')'; else chat_text += '0'; break;
- case '1': if (shift & 1) chat_text += '!'; else chat_text += '1'; break;
- case '2': if (shift & 1) chat_text += '@'; else chat_text += '2'; break;
- case '3': if (shift & 1) chat_text += '#'; else chat_text += '3'; break;
- case '4': if (shift & 1) chat_text += '$'; else chat_text += '4'; break;
- case '5': if (shift & 1) chat_text += '%'; else chat_text += '5'; break;
- case '6': if (shift & 1) chat_text += '^'; else chat_text += '6'; break;
- case '7': if (shift & 1) chat_text += '&'; else chat_text += '7'; break;
- case '8': if (shift & 1) chat_text += '*'; else chat_text += '8'; break;
- case '9': if (shift & 1) chat_text += '('; else chat_text += '9'; break;
- case 186: if (shift & 1) chat_text += ':'; else chat_text += ';'; break;
- case 187: if (shift & 1) chat_text += '+'; else chat_text += '='; break;
- case 188: if (shift & 1) chat_text += '<'; else chat_text += ','; break;
- case 189: if (shift & 1) chat_text += '_'; else chat_text += '-'; break;
- case 190: if (shift & 1) chat_text += '>'; else chat_text += '.'; break;
- case 191: if (shift & 1) chat_text += '?'; else chat_text += '/'; break;
- case 192: if (shift & 1) chat_text += '~'; else chat_text += '`'; break;
- case 219: if (shift & 1) chat_text += '{'; else chat_text += '['; break;
- case 221: if (shift & 1) chat_text += '}'; else chat_text += ']'; break;
- case 220: if (shift & 1) chat_text += '|'; else chat_text += '\\'; break;
- case 222: if (shift & 1) chat_text += '"'; else chat_text += '\''; break;
- }
- }
- }
- }
-}
-
-void
-Starshatter::SetChatMode(int mode)
-{
- if (mode >= 0 && mode <= 4 && mode != chat_mode) {
- chat_text = "";
-
- if (!NetGame::IsNetGame()) {
- chat_mode = 0;
- }
- else {
- chat_mode = mode;
-
- // flush input before reading chat message:
- if (chat_mode) {
- FlushKeys();
- }
-
- // flush input before sampling flight controls:
- else {
- for (int i = 1; i < 255; i++) {
- Keyboard::KeyDown(i);
- }
- }
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::DoMouseFrame()
-{
- EventDispatch* event_dispatch = EventDispatch::GetInstance();
- if (event_dispatch && event_dispatch->GetCapture())
- return;
-
- mouse_dx = 0;
- mouse_dy = 0;
-
- static int old_mouse_x = 0;
- static int old_mouse_y = 0;
-
- if (!spinning && Mouse::RButton()) {
- spinning = true;
- old_mouse_x = Mouse::X();
- old_mouse_y = Mouse::Y();
- mouse_x = Mouse::X();
- mouse_y = Mouse::Y();
- Mouse::Show(false);
- }
-
- else if (spinning) {
- if (!Mouse::RButton()) {
- spinning = false;
-
- if (tactical) {
- Mouse::Show(true);
- Mouse::SetCursor(Mouse::ARROW);
- }
-
- Mouse::SetCursorPos(old_mouse_x, old_mouse_y);
- }
-
- else {
- mouse_dx = Mouse::X() - mouse_x;
- mouse_dy = Mouse::Y() - mouse_y;
-
- Mouse::SetCursorPos(mouse_x, mouse_y);
- }
- }
-
- else if (cutscene || !player_ship) {
- Mouse::Show(false);
- return;
- }
-
- // hide mouse cursor when mouse controller is actively steering:
- else if (mouse_input && mouse_input->Active()) {
- if (mouse_input->Selector() == 1) {
- Mouse::Show(false);
- }
-
- else if (mouse_input->Selector() == 2) {
- Mouse::Show(true);
- Mouse::SetCursor(Mouse::CROSS);
- }
- }
-
- else {
- HUDView* hud_view = HUDView::GetInstance();
-
- if (hud_view && hud_view->GetHUDMode() != HUDView::HUD_MODE_OFF) {
- Mouse::Show(true);
- Mouse::SetCursor(Mouse::ARROW);
- }
- }
-
- if (gamescreen && gamescreen->IsFormShown())
- return;
-
- TacticalView* tac_view = TacticalView::GetInstance();
-
- if (tac_view)
- tac_view->DoMouseFrame();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::SetupSplash()
-{
- Color::SetFade(0);
-
- if (gamewin) {
- screen->DelWindow(gamewin);
- delete gamewin;
- gamewin = 0;
- }
-
- switch (splash_index) {
- case 0:
- splash_image.ClearImage();
- loader->SetDataPath(0);
- loader->LoadBitmap("matrix.pcx", splash_image);
- break;
-
- case 1:
- default:
- splash_image.ClearImage();
- loader->SetDataPath(0);
- loader->LoadBitmap("studio.pcx", splash_image);
- break;
- }
-
- int screen_width = GetScreenWidth();
- int screen_height = GetScreenHeight();
-
- gamewin = new Window(screen, 0, 0, screen_width, screen_height);
- splash = new FadeView(gamewin, 2, 2, 2);
-
- gamewin->AddView(splash);
- gamewin->AddView(new ImgView(gamewin, &splash_image));
- screen->AddWindow(gamewin);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::SetupMenuScreen()
-{
- if (menuscreen) {
- delete menuscreen;
- menuscreen = 0;
- }
-
- menuscreen = new MenuScreen();
- menuscreen->Setup(screen);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::SetupCmpnScreen()
-{
- if (cmpnscreen) {
- delete cmpnscreen;
- cmpnscreen = 0;
- }
-
- cmpnscreen = new CmpnScreen();
- cmpnscreen->Setup(screen);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::SetupPlanScreen()
-{
- if (planscreen) {
- delete planscreen;
- planscreen = 0;
- }
-
- planscreen = new PlanScreen();
- planscreen->Setup(screen);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::SetupLoadScreen()
-{
- if (loadscreen) {
- delete loadscreen;
- loadscreen = 0;
- }
-
- loadscreen = new LoadScreen();
- loadscreen->Setup(screen);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::SetupGameScreen()
-{
- if (gamescreen) {
- delete gamescreen;
- gamescreen = 0;
- }
-
- gamescreen = new GameScreen();
- gamescreen->Setup(screen);
- gamescreen->SetFieldOfView(field_of_view);
-
- // initialize player_ship's MFD choices:
- Player::SelectPlayer(Player::GetCurrentPlayer());
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::LoadVideoConfig(const char* filename)
-{
- // set up defaults:
- int screen_width = 1280;
- int screen_height = 720;
- int screen_depth = 32;
- int gamma = 128;
- int terrain_detail_level = 3;
- bool shadows_enabled = true;
- bool spec_maps_enabled = true;
- bool bump_maps_enabled = true;
- bool vertex_shader = true;
- bool pixel_shader = true;
- float depth_bias = video_settings->depth_bias;
-
- max_tex_size = 2048;
-
- if (MachineInfo::GetCpuSpeed() >= 1000 && MachineInfo::GetTotalRam() > 128)
- terrain_detail_level = 4;
-
- Terrain::SetDetailLevel(terrain_detail_level);
-
- // read the config file:
- BYTE* block = 0;
- int blocklen = 0;
-
- FILE* f = ::fopen(filename, "rb");
-
- if (f) {
- ::fseek(f, 0, SEEK_END);
- blocklen = ftell(f);
- ::fseek(f, 0, SEEK_SET);
-
- block = new BYTE[blocklen+1];
- block[blocklen] = 0;
-
- ::fread(block, blocklen, 1, f);
- ::fclose(f);
- }
-
- if (blocklen == 0)
- return;
-
- Parser parser(new BlockReader((const char*) block, blocklen));
- Term* term = parser.ParseTerm();
-
- if (!term) {
- Print("ERROR: could not parse '%s'.\n", filename);
- exit(-3);
- }
- else {
- TermText* file_type = term->isText();
- if (!file_type || file_type->value() != "VIDEO") {
- Print("WARNING: invalid %s file. Using defaults\n", filename);
- return;
- }
- }
-
- do {
- delete term;
-
- term = parser.ParseTerm();
-
- if (term) {
- TermDef* def = term->isDef();
- if (def) {
- if (def->name()->value() == "width") {
- int w;
- GetDefNumber(w, def, filename);
-
- switch (w) {
- case 800:
- screen_width = 800;
- screen_height = 600;
- break;
-
- case 1024:
- screen_width = 1024;
- screen_height = 768;
- break;
-
- case 1152:
- screen_width = 1152;
- screen_height = 864;
- break;
-
- case 1280:
- screen_width = 1280;
- screen_height = 960;
- break;
-
- case 1440:
- screen_width = 1440;
- screen_height = 900;
- break;
-
- default:
- screen_width = w;
- screen_height = (w*3)/4;
- break;
- }
- }
-
- else if (def->name()->value() == "height") {
- int h;
- GetDefNumber(h, def, filename);
-
- if (screen_width == 1280 && (h == 800 || h == 1024))
- screen_height = h;
- else if (screen_width == 1600 && (h == 900 || h == 1200))
- screen_height = h;
- }
-
- else if (def->name()->value() == "depth" ||
- def->name()->value() == "bpp") {
-
- int bpp;
- GetDefNumber(bpp, def, filename);
-
- switch (bpp) {
- case 8:
- case 16:
- case 24:
- case 32:
- screen_depth = bpp;
- break;
-
- default:
- Print("WARNING: Invalid screen bpp (%d) in '%s'\n", bpp, filename);
- screen_depth = 8;
- break;
- }
- }
-
- else if (def->name()->value() == "max_tex") {
- int n;
- GetDefNumber(n, def, filename);
- if (n >= 64 && n <= 4096)
- max_tex_size = n;
- }
-
- else if (def->name()->value() == "gamma") {
- int level;
- GetDefNumber(level, def, filename);
- if (level >= 0 && level <= 255)
- gamma = level;
- }
-
- else if (def->name()->value() == "terrain_detail_level") {
- GetDefNumber(terrain_detail_level, def, filename);
- Terrain::SetDetailLevel(terrain_detail_level);
- }
-
- else if (def->name()->value() == "terrain_texture_enable") {
- bool enable;
- GetDefBool(enable, def, filename);
-
- // no longer supported!
- }
-
- else if (def->name()->value() == "shadows") {
- GetDefBool(shadows_enabled, def, filename);
- }
-
- else if (def->name()->value() == "spec_maps") {
- GetDefBool(spec_maps_enabled, def, filename);
- }
-
- else if (def->name()->value() == "bump_maps") {
- GetDefBool(bump_maps_enabled, def, filename);
- }
-
- else if (def->name()->value() == "vertex_shader") {
- GetDefBool(vertex_shader, def, filename);
- }
-
- else if (def->name()->value() == "pixel_shader") {
- GetDefBool(pixel_shader, def, filename);
- }
-
- else if (def->name()->value().contains("bias")) {
- GetDefNumber(depth_bias, def, filename);
- }
-
- else if (def->name()->value() == "flare") {
- bool b;
- GetDefBool(b, def, filename);
- lens_flare = b;
- }
-
- else if (def->name()->value() == "corona") {
- bool b;
- GetDefBool(b, def, filename);
- corona = b;
- }
-
- else if (def->name()->value() == "nebula") {
- bool b;
- GetDefBool(b, def, filename);
- nebula = b;
- }
-
- else if (def->name()->value() == "dust") {
- GetDefNumber(dust, def, filename);
- }
-
- else if (def->name()->value().indexOf("cam_range") == 0) {
- double range_max = 0;
- GetDefNumber(range_max, def, filename);
- CameraDirector::SetRangeLimit(range_max);
- }
- }
- else {
- Print("WARNING: term ignored in '%s'\n", filename);
- term->print();
- }
- }
- }
- while (term);
-
- loader->ReleaseBuffer(block);
-
- if (video_settings) {
- video_settings->fullscreen_mode.width = screen_width;
- video_settings->fullscreen_mode.height = screen_height;
-
- if (screen_depth == 16)
- video_settings->fullscreen_mode.format = VideoMode::FMT_R5G6B5;
- else
- video_settings->fullscreen_mode.format = VideoMode::FMT_X8R8G8B8;
-
- video_settings->gamma = gamma;
- video_settings->shadows = shadows_enabled;
- video_settings->specmaps = spec_maps_enabled;
- video_settings->bumpmaps = bump_maps_enabled;
- video_settings->enable_vs = vertex_shader;
- video_settings->enable_ps = pixel_shader;
- video_settings->depth_bias = depth_bias;
- }
-
- if (video) {
- video->SetShadowEnabled(shadows_enabled);
- video->SetSpecMapEnabled(spec_maps_enabled);
- video->SetBumpMapEnabled(bump_maps_enabled);
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::SaveVideoConfig(const char* filename)
-{
- if (!video_settings)
- return;
-
- FILE* f = fopen(filename, "wb");
- if (f) {
- fprintf(f, "VIDEO\n\n");
- fprintf(f, "width: %4d\n", video_settings->fullscreen_mode.width);
- fprintf(f, "height: %4d\n", video_settings->fullscreen_mode.height);
- fprintf(f, "depth: %4d\n", video_settings->fullscreen_mode.format == VideoMode::FMT_R5G6B5 ? 16 : 32);
- fprintf(f, "\n");
- fprintf(f, "max_tex: %4d\n", max_tex_size);
- fprintf(f, "primary3D: %s\n", "true");
- fprintf(f, "gamma: %4d\n", video_settings->gamma);
- fprintf(f, "\n");
- fprintf(f, "terrain_detail_level: %d\n", Terrain::DetailLevel());
- fprintf(f, "terrain_texture_enable: %true\n");
- fprintf(f, "\n");
-
- fprintf(f, "shadows: %s\n", video_settings->shadows ? "true" : "false");
- fprintf(f, "spec_maps: %s\n", video_settings->specmaps ? "true" : "false");
- fprintf(f, "bump_maps: %s\n", video_settings->bumpmaps ? "true" : "false");
- fprintf(f, "bias: %f\n", video_settings->depth_bias);
- fprintf(f, "\n");
-
- fprintf(f, "flare: %s\n", lens_flare ? "true" : "false");
- fprintf(f, "corona: %s\n", corona ? "true" : "false");
- fprintf(f, "nebula: %s\n", nebula ? "true" : "false");
- fprintf(f, "dust: %d\n", dust);
-
- if (CameraDirector::GetRangeLimit() != 300e3)
- fprintf(f, " cam_range_max: %f,\n", CameraDirector::GetRangeLimit());
-
- fclose(f);
- }
-
- video_changed = false;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Starshatter::ExecCutscene(const char* msn_file, const char* path)
-{
- if (InCutscene() || !msn_file || !*msn_file) return;
-
- if (!world)
- CreateWorld();
-
- cutscene_mission = new Mission(0);
- cutscene_basetime = StarSystem::GetBaseTime();
-
- if (cutscene_mission->Load(msn_file, path)) {
- Sim* sim = (Sim*) world;
-
- if (sim) {
- bool dynamic = false;
- Campaign* campaign = Campaign::GetCampaign();
-
- if (campaign && campaign->IsDynamic())
- dynamic = true;
-
- sim->UnloadMission();
- sim->LoadMission(cutscene_mission, true); // attempt to preload the tex cache
- sim->ExecMission();
- sim->ShowGrid(false);
- player_ship = sim->GetPlayerShip();
-
- Print(" Cutscene Instantiated.\n");
-
- UpdateWorld();
- }
- }
- else {
- delete cutscene_mission;
- cutscene_mission = 0;
- cutscene_basetime = 0;
- }
-}
-
-void
-Starshatter::BeginCutscene()
-{
- Sim* sim = Sim::GetSim();
-
- if (cutscene == 0 && !sim->IsNetGame()) {
- HUDView* hud_view = HUDView::GetInstance();
- if (hud_view)
- hud_view->SetHUDMode(HUDView::HUD_MODE_OFF);
-
- if (sim->GetPlayerShip())
- sim->GetPlayerShip()->SetControls(0);
-
- AudioConfig* audio_cfg = AudioConfig::GetInstance();
-
- if (audio_cfg) {
- cut_efx_volume = audio_cfg->GetEfxVolume();
- cut_wrn_volume = audio_cfg->GetWrnVolume();
- }
-
- Ship::SetFlightModel(Ship::FM_ARCADE);
- }
-
- cutscene++;
-}
-
-void
-Starshatter::EndCutscene()
-{
- cutscene--;
-
- if (cutscene == 0) {
- DisplayView* disp_view = DisplayView::GetInstance();
- if (disp_view)
- disp_view->ClearDisplay();
-
- HUDView* hud_view = HUDView::GetInstance();
- if (hud_view)
- hud_view->SetHUDMode(HUDView::HUD_MODE_TAC);
-
- Sim* sim = Sim::GetSim();
- if (sim->GetPlayerShip())
- sim->GetPlayerShip()->SetControls(sim->GetControls());
-
- if (cam_dir) {
- cam_dir->SetViewOrbital(0);
- CameraDirector::SetRangeLimits(10, CameraDirector::GetRangeLimit());
- cam_dir->SetOrbitPoint(PI/4,PI/4,1);
- cam_dir->SetOrbitRates(0,0,0);
- }
-
- AudioConfig* audio_cfg = AudioConfig::GetInstance();
-
- if (audio_cfg) {
- audio_cfg->SetEfxVolume(cut_efx_volume);
- audio_cfg->SetWrnVolume(cut_wrn_volume);
- }
-
- Player* p = Player::GetCurrentPlayer();
- if (p)
- Ship::SetFlightModel(p->FlightModel());
- }
-}
-
-void
-Starshatter::EndMission()
-{
- if (cutscene_mission) {
- Sim* sim = Sim::GetSim();
-
- if (sim && sim->GetMission() == cutscene_mission) {
- ShipStats::Initialize();
- sim->UnloadMission();
-
- // restore world clock (true => absolute time reference)
- if (cutscene_basetime != 0)
- StarSystem::SetBaseTime(cutscene_basetime, true);
-
- delete cutscene_mission;
- cutscene_mission = 0;
- cutscene_basetime = 0;
-
- return;
- }
- }
-
- SetGameMode(Starshatter::PLAN_MODE);
-}
-
-Mission*
-Starshatter::GetCutsceneMission() const
-{
- return cutscene_mission;
-}
-
-const char*
-Starshatter::GetSubtitles() const
-{
- if (cutscene_mission)
- return cutscene_mission->Subtitles();
-
- return "";
-}
-
-// +--------------------------------------------------------------------+
-
-int
-Starshatter::GetLobbyMode()
-{
- return lobby_mode;
-}
-
-void
-Starshatter::SetLobbyMode(int mode)
-{
- lobby_mode = mode;
-}
-
-void
-Starshatter::StartLobby()
-{
- if (!net_lobby) {
- if (lobby_mode == NET_LOBBY_SERVER) {
- NetServerConfig::Initialize();
- NetServerConfig* server_config = NetServerConfig::GetInstance();
-
- if (server_config)
- net_lobby = new NetLobbyServer;
- }
-
- else {
- NetClientConfig* client_config = NetClientConfig::GetInstance();
- if (client_config)
- client_config->Login();
-
- net_lobby = NetLobby::GetInstance();
- }
- }
-
- lobby_mode = NET_LOBBY_CLIENT;
-}
-
-void
-Starshatter::StopLobby()
-{
- if (net_lobby) {
- if (net_lobby->IsServer()) {
- delete net_lobby;
- NetServerConfig::Close();
- }
-
- else {
- NetClientConfig* client_config = NetClientConfig::GetInstance();
- if (client_config)
- client_config->Logout();
- }
-
- net_lobby = 0;
- }
-
- lobby_mode = NET_LOBBY_CLIENT;
-}
-
-void
-Starshatter::StopNetGame()
-{
- // local server:
- NetLobby* lobby = NetLobby::GetInstance();
-
- if (lobby && lobby->IsServer()) {
- lobby->GameStop();
- }
-
- // client connected to remote server:
- else {
- NetClientConfig* config = NetClientConfig::GetInstance();
- if (config && config->GetHostRequest()) {
- config->Login();
-
- NetLobbyClient* conn = config->GetConnection();
-
- if (conn) {
- conn->GameStop();
- conn->SelectMission(0);
- }
- }
- }
-}
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<Ship> 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<WeaponGroup> iter = ship->Weapons();
- while (++iter) {
- WeaponGroup* group = iter.value();
-
- ListIter<Weapon> 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<WeaponGroup> 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<WeaponGroup> g_iter = tgt_ship->Weapons();
- while (++g_iter) {
- WeaponGroup* g = g_iter.value();
-
- if (g->GetDesign() && g->GetDesign()->turret_model) {
- ListIter<Weapon> 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<Weapon> 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<WeaponGroup> g_iter = tgt_ship->Weapons();
- while (++g_iter && !tgt_point_defense) {
- WeaponGroup* g = g_iter.value();
-
- if (g->CanTarget(1)) {
- ListIter<Weapon> 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 <algorithm>
-
-#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<Contact> 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<Contact> 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<SimRegion>& 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<Element> 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<s.brake)?brake:s.brake);
-}
-
-Steer Steer::operator*(double f) const
-{
- return Steer(yaw*f, pitch*f, roll*f, brake);
-}
-
-Steer Steer::operator/(double f) const
-{
- return Steer(yaw/f, pitch/f, roll/f, brake);
-}
-
-
-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;
-}
-
-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<Component> c = (List<Component>&) 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<ComponentDesign> 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<Component> 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<Component> 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<Component> 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<Component>& 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<Component> 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> 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<ComponentDesign> components;
-
- static List<SystemDesign> 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<Text> designs;
-
- for (int n = 0; n < 16; n++) {
- int type = 1 << n;
- ShipDesign::GetDesignList(type, designs);
-
- ListIter<Text> 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<Text> designs;
-
- WeaponDesign::GetDesignList(designs);
-
- ListIter<Text> 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> 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> 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<Ship> ward_threats;
-
- ListIter<Contact> 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<Ship> 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<Contact> 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> 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<Ship> 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<Contact> 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<Ship> 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<Contact> 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>& 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>& 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<Ship> 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<SimRegion> 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<Ship> 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<Ship> 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<Term> TermList;
-typedef ListIter<Term> 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<TerrainLayer> 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<<i) + 1;
- water[i]->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<TerrainLayer>& 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<TerrainLayer> 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<Light>& 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<Light> 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<Light>& 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<Light>& 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<Light>& 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<TerrainLayer>& 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<Light>& 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<Light> 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<Light>& 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<Material> 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<TerrainLayer>& 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<TerrainLayer> 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<ThrusterPort> 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 <ctype.h>
-
-// +-------------------------------------------------------------------+
-
-bool Token::hidecom = true;
-char Token::combeg[3] = "//";
-char Token::comend[3] = "\n";
-char Token::altbeg[3] = "/*";
-char Token::altend[3] = "*/";
-Dictionary<int> 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<int>& keys)
-{
- DictionaryIter<int> 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<int>& 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<int> 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 <windows.h>
-#include <windowsx.h>
-#include <assert.h>
-#include <math.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-
-
-// 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 <d3d9.h>
-#include <d3dx9.h>
-
-// DirectSound includes
-#include <mmsystem.h>
-#include <mmreg.h>
-#include <dsound.h>
-
-// +--------------------------------------------------------------------+
-
-#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<Light>& 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> 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<Model> 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<Light>& lights)
-{
- if (d3ddevice) {
- main_light = 0;
- back_light = 0;
-
- ListIter<Light> iter = (List<Light>&) 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<Surface> 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<Segment> 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<Segment> 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<Light>& 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<VideoDX9DeviceInfo> 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<VideoDX9DisplayMode> 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<D3DFORMAT> 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<VideoDX9DisplayMode> 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<D3DFORMAT>& 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<D3DFORMAT>& 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<VideoDX9AdapterInfo> a_iter = adapter_info_list;
- while (++a_iter) {
- VideoDX9AdapterInfo* adapter_info = a_iter.value();
-
- ListIter<VideoDX9DeviceInfo> d_iter = adapter_info->device_info_list;
- while (++d_iter) {
- VideoDX9DeviceInfo* device_info = d_iter.value();
-
- ListIter<VideoDX9DeviceCombo> 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<VideoDX9AdapterInfo> a_iter = adapter_info_list;
- while (++a_iter) {
- VideoDX9AdapterInfo* adapter_info = a_iter.value();
- d3d->GetAdapterDisplayMode(adapter_info->adapter_ordinal, &desktop_display_mode);
-
- ListIter<VideoDX9DeviceInfo> d_iter = adapter_info->device_info_list;
- while (++d_iter) {
- VideoDX9DeviceInfo* device_info = d_iter.value();
-
- ListIter<VideoDX9DeviceCombo> 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<VideoDX9DisplayMode> 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 <d3d9.h>
-
-#include "Video.h"
-#include "List.h"
-#include <vector>
-
-// +--------------------------------------------------------------------+
-
-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<D3DFORMAT>& adapter_format_list);
- HRESULT EnumerateDeviceCombos(VideoDX9DeviceInfo* device_info, std::vector<D3DFORMAT>& 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<D3DFORMAT> allowed_adapter_format_list;
-
- List<VideoDX9AdapterInfo> 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<VideoDX9DisplayMode> display_mode_list;
- List<VideoDX9DeviceInfo> 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<VideoDX9DeviceCombo> 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<int> vertex_processing_list;
- std::vector<D3DFORMAT> depth_stencil_fmt_list;
- std::vector<D3DMULTISAMPLE_TYPE> multisample_type_list;
- std::vector<DWORD> multisample_qual_list;
- std::vector<DWORD> present_interval_list;
-
- List<VideoDX9FormatConflict> 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> 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<WeaponDesign> catalog;
-static List<WeaponDesign> 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<Text>& 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<Text>& 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<Weapon>&
-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<Weapon> 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<Weapon> 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<Weapon> 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<Weapon> 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<Weapon> iter = (List<Weapon>&) 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<Weapon> w = weapons;
- while (++w)
- w->SetFiringOrders(orders);
-}
-
-void
-WeaponGroup::SetControlMode(int m)
-{
- control = m;
-
- ListIter<Weapon> w = weapons;
- while (++w)
- w->SetControlMode(control);
-}
-
-void
-WeaponGroup::SetSweep(int s)
-{
- sweep = s;
-
- ListIter<Weapon> w = weapons;
- while (++w)
- w->SetSweep(sweep);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-WeaponGroup::PowerOff()
-{
- ListIter<Weapon> w = weapons;
- while (++w)
- w->PowerOff();
-}
-
-void
-WeaponGroup::PowerOn()
-{
- ListIter<Weapon> 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<Weapon>& 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<Weapon> 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<WeaponGroup>& 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<View> v = view_list;
- while (++v)
- v->OnWindowMove();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Window::Paint()
-{
- ListIter<View> 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> 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